fix: keep large approval batches observable
CI / Client installer (macos-latest) (push) Canceled after 0s
CI / Client installer (ubuntu-latest) (push) Canceled after 0s
CI / Client installer (windows-latest) (push) Canceled after 0s
CI / test (22) (push) Canceled after 0s
CI / test (24) (push) Canceled after 0s
CI / release-smoke (push) Canceled after 0s
CI / Client installer (macos-latest) (push) Canceled after 0s
CI / Client installer (ubuntu-latest) (push) Canceled after 0s
CI / Client installer (windows-latest) (push) Canceled after 0s
CI / test (22) (push) Canceled after 0s
CI / test (24) (push) Canceled after 0s
CI / release-smoke (push) Canceled after 0s
This commit is contained in:
+44
-1
@@ -37,6 +37,8 @@ export const APPROVAL_ONBOARDING_EXAMPLES = [
|
||||
"先列出待办,我确认后同意指定的几张",
|
||||
] as const;
|
||||
|
||||
const REMOTE_WRITE_TIMEOUT_MS = 45_000;
|
||||
|
||||
class AuthRequired extends Error {
|
||||
constructor(readonly challenge: NonNullable<BridgeState["device"]>) { super("需要钉钉登录"); }
|
||||
}
|
||||
@@ -83,7 +85,14 @@ export class RemoteBridge {
|
||||
return this.withCallSlot(async () => {
|
||||
try {
|
||||
const client = await this.remoteClient();
|
||||
return this.appendOnboarding(await client.callTool({ name, arguments: args }));
|
||||
try {
|
||||
const options = name === "approval_process_batch" ? { timeout: REMOTE_WRITE_TIMEOUT_MS } : undefined;
|
||||
return this.appendOnboarding(await client.callTool({ name, arguments: args }, undefined, options));
|
||||
} catch (error) {
|
||||
const uncertain = bridgeWriteOutcomeUncertainResult(name, args);
|
||||
if (uncertain) return uncertain;
|
||||
throw error;
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof AuthRequired) return this.authResult(error.challenge);
|
||||
throw error;
|
||||
@@ -362,6 +371,40 @@ export function bridgeAuthToolResult(result: BridgeLoginResult) {
|
||||
return { content, structuredContent: { result } };
|
||||
}
|
||||
|
||||
export function bridgeWriteOutcomeUncertainResult(name: string, args: Record<string, unknown>) {
|
||||
if (name !== "approval_process_batch") return undefined;
|
||||
const requestedItems = Array.isArray(args.items)
|
||||
? args.items.filter((item): item is Record<string, unknown> => Boolean(item) && typeof item === "object" && !Array.isArray(item))
|
||||
: [];
|
||||
const selectionUsed = requestedItems.length === 0 && typeof args.selectionId === "string";
|
||||
const message = "审批写请求超过 bridge 等待时间或连接中断,操作可能已经到达网关;禁止自动重试,请重新列出实时待办核对。";
|
||||
const results = requestedItems.map((item, index) => ({
|
||||
index: index + 1,
|
||||
...(typeof item.approvalId === "string" ? { approvalId: item.approvalId } : {}),
|
||||
status: "outcome_uncertain",
|
||||
outcomeUncertain: true,
|
||||
success: false,
|
||||
message,
|
||||
}));
|
||||
const result = {
|
||||
action: args.action,
|
||||
status: "outcome_uncertain",
|
||||
outcomeUncertain: true,
|
||||
total: selectionUsed ? null : requestedItems.length,
|
||||
uncertain: selectionUsed ? null : requestedItems.length,
|
||||
...(selectionUsed ? { targetCount: "unknown" } : {}),
|
||||
succeeded: 0,
|
||||
failed: 0,
|
||||
results,
|
||||
requiresRelist: true,
|
||||
retryable: false,
|
||||
};
|
||||
return {
|
||||
content: [{ type: "text" as const, text: `${message}\n${JSON.stringify(result)}` }],
|
||||
structuredContent: { result },
|
||||
};
|
||||
}
|
||||
|
||||
function isAuthenticationFailure(error: unknown): boolean {
|
||||
const record = error && typeof error === "object" ? error as Record<string, unknown> : {};
|
||||
const status = Number(record.status ?? record.statusCode ?? record.code);
|
||||
|
||||
Reference in New Issue
Block a user