跳到內容

Tool Errors 與 Timeouts

Tool failure 可能發生在多個 layer。應區分 expected application-domain result、SDK handler failure、serialization/transport failure 與 runtime timeout。

TOOL_HANDLER_NOT_FOUND 是 browser-side:SDK 找不到 handler,會將 error result 回給 agent。TOOL_NOT_FOUND 則表示 Core ToolRegistry 找不到 requested tool;TOOL_ARGS_INVALID 表示 agent args 不是 object 或不符合 schema;TOOL_TIMEOUT 表示 Core 等待 result 超時。Recovery 詳見 Error Codes

Tool 正常執行,但 action 無法完成時回傳 structured error:

return {
error: {
code: "NO_ACTIVE_SELECTION",
message: "Select text before using replace_selection.",
details: {
documentId: activeDocument.id,
},
retryable: true,
},
};

這是 normal result,SDK 會送給 agent,不會因此自動呼叫 session.onError()

適合用於:

  • resource missing;
  • current UI state invalid;
  • permission denial;
  • user cancellation;
  • version conflict;
  • validation failure。

沒有 named、inline 或 generic handler 時,SDK 產生包含 TOOL_HANDLER_NOT_FOUND 的 error result 並送給 agent。通常是 integration bug:

  • tool 在 skills.tools 但未實作;
  • definition 與 registration name 不一致;
  • resumed page 未 restore handlers;
  • component cleanup 太早;
  • handler 註冊在另一個 session object。

Selected handler throw/reject 時,SDK catch 並轉成 TOOL_HANDLER_ERROR result。

session.onTool("save", async () => {
throw new Error("Database unavailable");
});

Raw exception 不會讓 SDK event listener crash,agent 會收到 normalized failure。

需要 stack trace 或更完整 diagnostics 時,請在 handler 內先 application log,因 serialized error result 會保持精簡。

取得 result 後,SDK 會呼叫 bridge submit_tool_result。Request 失敗時 session emit SDK error:

session.onError((error) => {
if (error.code === "SUBMIT_TOOL_RESULT_FAILED") {
showToolTransportFailure();
}
});

可能原因:

  • Extension/native/Core disconnect;
  • handler pending 時 session ended;
  • Core 已 timeout 該 request;
  • result 無法 clone/serialize;
  • runtime 拒絕 request ID。

Agent 可能無法繼續。不要盲目 retry 有 side effect 的 handler,因 operation 可能已完成,只是 result delivery 失敗。

timeoutMs: 60_000

省略時 Core 目前預設 60 秒。Timeout 控制 runtime 等 result 的時間,不會強制停止 page JavaScript。

Handler late resolve 時:

  1. application side effect 可能已完成;
  2. Core 可能已 fail 或繼續 turn;
  3. result submission 可能失敗;
  4. session 可能 emit SUBMIT_TOOL_RESULT_FAILED 或 runtime session error。

Handler 應在 deadline 前 settle,並自行實作 cancellation/cleanup。

Provider command timeout 與 App Tool formal timeout

Section titled “Provider command timeout 與 App Tool formal timeout”

Provider 的 shell 或 terminal 可能在 Core 的 timeoutMs deadline 前停止等待 pedelec-cli --thread-id <pedelec_thread_id> tool-call。這是 ambiguous transport failure,不代表 App Tool 已失敗。若 Agent 沒有收到完整 structured Pedelec response,可以用完全相同的 tool name 與語意完全相同的 arguments exact retry;Core 會 join 仍在執行的 invocation,或 replay 最近完成但尚未確認 delivery 的 result。不要改 arguments,也不要無限 retry。

Core 到達 App Tool 的 timeoutMs 時,會回傳正式的 TOOL_TIMEOUT structured error。收到 TOOL_TIMEOUT 代表原 invocation 已結束,不是繼續同一 invocation 的 in-flight retry 指示。只有 IPC delivery 未確認的 result 可能在短時間內 replay;成功 delivery 的 result 不會作為一般 deduplication cache 保留。

請回傳 plain JSON-compatible values。問題範例:

return document.body; // DOM node
return () => 1; // function
return { value: 1n }; // BigInt
return cyclicObject; // cycle
return new Map(); // 意圖結構會丟失
return new File(...); // browser object,不是 compact JSON

轉換:

return {
html: document.body.innerHTML,
entries: [...map.entries()],
size: file.size,
name: file.name,
};

也要留意 payload size。Large result 增加 bridge cost,也可能超過 local IPC/message limit。大型 artifact 應只回傳 application-owned ID。

Schema 改善 agent output,但不會讓 args 變可信。Routine bad input 應回 domain error,不要 throw:

function validateMoveArgs(raw: unknown) {
if (!raw || typeof raw !== "object") return null;
const value = raw as Record<string, unknown>;
if (typeof value.shapeId !== "string") return null;
if (typeof value.x !== "number" || !Number.isFinite(value.x)) return null;
if (typeof value.y !== "number" || !Number.isFinite(value.y)) return null;
return { shapeId: value.shapeId, x: value.x, y: value.y };
}
session.onTool("move_shape", (raw) => {
const args = validateMoveArgs(raw);
if (!args) {
return {
error: {
code: "INVALID_TOOL_ARGS",
message: "shapeId, x, and y are required.",
},
};
}
return scene.move(args);
});
Failure 適合 automatic retry?
Read-only tool 在 execution 前 transport failed Connection recovery 後有時可以
Domain validation error 不可;需改 input
User cancelled 除非使用者重新要求,否則不可
Handler 在 side effect 前 throw Operation 已知 idempotent 時可能可以
Mutation 後 result submission failed 通常不可;先 reconcile state
收到完整 Pedelec response 前的 ambiguous provider command/transport timeout 可以 exact retry;Core 會 join 或 replay 同一 logical invocation
已收到正式 TOOL_TIMEOUT 不要當成 in-flight retry;先 reconcile 可能的 side effect
Stale UI lifecycle 不可;agent 應先讀 current state

需要安全 retry 的 tool 可加入 idempotency key 或 expected-version field。

記錄足以診斷但不洩漏 secret 的 correlation data:

console.error("tool failed", {
sessionId: ctx.sessionId,
turnId: ctx.turnId,
toolRequestId: ctx.toolRequestId,
tool: ctx.tool,
code: error.code,
});

Tool args 可能包含 private page/user data,不要預設完整 logging。

精確型別與 signature 請看 Tools API Reference