Error in `local_mocked_bindings(..., .package = .package)`: Can't find binding for `file.exists` and `normalizePath`

test_that("FileChannelSessionStore persists session state and index metadata", {
session <- ChatSession$new(model = "mock:test", registry = registry)
participants = list(list(sender_id = "u1", sender_name = "Alice"))
loaded <- store$load_session("test:session", registry = registry)
test_that("ChannelRuntime reuses shared group sessions and keeps sender identity", {
parse_request = function(headers = NULL, body = NULL, ...) {
chat_scope = if (identical(body$chat_type, "direct")) "per_sender" else "shared_chat"
send_text = function(message, text, ...) {
self$sent[[length(self$sent) + 1L]] <- list(
list(text = "reply one", tool_calls = NULL, finish_reason = "stop"),
list(text = "reply two", tool_calls = NULL, finish_reason = "stop")
loaded <- store$load_session(first$results[[1]]$session_key, registry = registry)
expect_match(loaded$get_history()[[1]]$content, "Alice", fixed = TRUE)
expect_match(loaded$get_history()[[3]]$content, "Bob", fixed = TRUE)
test_that("ChannelRuntime deduplicates repeated event ids", {
self$sent[[length(self$sent) + 1L]] <- text
MockModel$new(list(list(text = "reply once", tool_calls = NULL, finish_reason = "stop")))
test_that("ChannelRuntime sends local attachments referenced in final reply text", {
writeBin(as.raw(c(0x89, 0x50, 0x4E, 0x47)), tmp_png)
self$sent_text[[length(self$sent_text) + 1L]] <- text
send_attachment = function(message, path, ...) {
self$sent_attachments[[length(self$sent_attachments) + 1L]] <- path
text = paste("Done. File saved to", tmp_png),
result <- runtime$handle_request("test", body = list())
expect_equal(adapter$sent_attachments[[1]], normalizePath(tmp_png, winslash = "/", mustWork = FALSE))
expect_equal(result$results[[1]]$attachments[[1]]$path, normalizePath(tmp_png, winslash = "/", mustWork = FALSE))
test_that("channel_extract_local_paths recognizes Windows absolute paths", {
channel_extract_local_paths("Done. File saved to C:/Users/test/output.png"),
file.exists = function(path) identical(path, "C:/Users/test/output.png"),
normalizePath = function(path, winslash = "/", mustWork = FALSE) path,
test_that("ChannelRuntime sends attachments from structured tool artifacts even without path in final text", {
super$initialize(provider = "mock", model_id = "artifact-model")
tool_calls = list(list(id = "tc1", name = "make_image", arguments = list())),
format_tool_result = function(tool_call_id, tool_name, result) {
list(role = "tool", tool_call_id = tool_call_id, name = tool_name, content = result)
attr(out, "aisdk_artifacts") <- list(list(path = normalizePath(tmp_png, winslash = "/", mustWork = FALSE)))
test_that("ChannelRuntime warns when reply claims attachment success without actual attachment delivery", {
test_that("ChannelRuntime can create child sessions linked to a parent", {
parent <- ChatSession$new(model = "mock:child-model", registry = registry)
store$save_session("parent", parent, record = list(channel_id = "test"))
child_key <- runtime$create_child_session("parent", child_session_key = "parent:child:1")
child <- store$load_session("parent:child:1", registry = registry)
test_that("FeishuChannelAdapter handles challenge and message events", {
test_that("FeishuChannelAdapter validates signature and decrypts encrypted events", {
sender = list(sender_id = list(open_id = "ou_2")),
cipher <- openssl::aes_cbc_encrypt(charToRaw(inner_payload), key = key_raw, iv = iv)
test_that("FeishuChannelAdapter fails closed on invalid signature", {
body <- jsonlite::toJSON(list(encrypt = "bogus"), auto_unbox = TRUE, null = "null")
test_that("FeishuChannelAdapter formats inbound file messages with attachment metadata", {
writeLines(c("%PDF-1.4", "Mock PDF Title", "Abstract section"), tmp_pdf)
download_resource_fn = function(message_id, file_key, type, file_name) {
normalizePath(tmp_pdf, winslash = "/", mustWork = FALSE)
sender = list(sender_id = list(open_id = "ou_file")),
expect_equal(parsed$messages[[1]]$attachments[[1]]$local_path, normalizePath(tmp_pdf, winslash = "/", mustWork = FALSE))
session <- create_chat_session(model = MockModel$new())
expect_match(formatted, "document_context_begin", fixed = TRUE)
expect_match(formatted, "document_name: paper.pdf", fixed = TRUE)
test_that("channel_extract_pdf_pages prefers the R backend when it has text", {
pages = list(list(page = 1L, text = "R backend text")),
pages = list(list(page = 1L, text = "Python backend text")),
test_that("channel_extract_pdf_pages falls back to Python when the R backend is empty", {
pages = list(list(page = 1L, text = "")),
test_that("channel_build_document_record keeps preview text when PDF extraction is empty", {
preview = "Preview title\n\nPreview abstract"
list(page_count = 0L, pages = list(), extractor = NULL)
expect_match(record$summary, "Preview title", fixed = TRUE)
expect_match(record$chunks[[1]], "Preview abstract", fixed = TRUE)
test_that("channel_apply_skill_routing preloads skill-creator for capability requests", {
dir.create(skill_dir, recursive = TRUE, showWarnings = FALSE)
dir.create(skill_path, recursive = TRUE, showWarnings = FALSE)
"description: Create and improve reusable skills",
"Use this workflow to create reusable skills."
agent <- channel_resolve_agent(agent = NULL, skills = skill_dir, model = "mock:test")
routed <- channel_apply_skill_routing("原始提示", message, agent = agent, session = NULL)
expect_match(routed, "routing_hint_begin", fixed = TRUE)
expect_match(routed, "skill-creator", fixed = TRUE)
expect_match(routed, "Use this workflow to create reusable skills.", fixed = TRUE)
test_that("Feishu document context is injected on follow-up reference instead of raw full-file history", {
writeLines(c("%PDF-1.4", "Paper Title", "Abstract text line 1", "Abstract text line 2"), tmp_pdf)
header = list(event_type = "im.message.receive_v1", event_id = "evt-file-ctx"),
expect_true(grepl("document_context_begin", file_prompt, fixed = TRUE))
expect_match(prepared_followup$text, "document_context_begin", fixed = TRUE)
expect_match(prepared_followup$text, "document_name: paper.pdf", fixed = TRUE)
test_that("Feishu webhook handler returns challenge and processes inbound events", {
MockModel$new(list(list(text = "feishu reply", tool_calls = NULL, finish_reason = "stop")))
send_text_fn = function(message, text, ...) {
sent[[length(sent) + 1L]] <<- list(chat_id = message$chat_id, text = text)
send_status_fn = function(message, status, text = NULL, ...) {
statuses[[length(statuses) + 1L]] <<- list(
body = list(type = "url_verification", challenge = "abc", token = "token-1")
sender = list(sender_id = list(open_id = "ou_1")),
test_that("Feishu upload success accepts integer code 0 responses", {