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:
+40
-1
@@ -6,10 +6,49 @@ import test from "node:test";
|
||||
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
||||
import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
|
||||
import {
|
||||
APPROVAL_ONBOARDING_EXAMPLES, RemoteBridge, bridgeAuthToolResult, createBridgeMcpServer,
|
||||
APPROVAL_ONBOARDING_EXAMPLES, RemoteBridge, bridgeAuthToolResult, bridgeWriteOutcomeUncertainResult, createBridgeMcpServer,
|
||||
syncBundledSkillForLegacyUpdate,
|
||||
} from "../src/bridge.js";
|
||||
|
||||
test("bridge write timeout fallback remains structured and forbids retries", () => {
|
||||
const result = bridgeWriteOutcomeUncertainResult("approval_process_batch", {
|
||||
action: "approve",
|
||||
items: [{ approvalId: "approval-one" }, { approvalId: "approval-two" }],
|
||||
});
|
||||
assert.equal(result?.structuredContent.result.status, "outcome_uncertain");
|
||||
assert.equal(result?.structuredContent.result.uncertain, 2);
|
||||
assert.equal(result?.structuredContent.result.retryable, false);
|
||||
assert.equal(result?.structuredContent.result.requiresRelist, true);
|
||||
assert.equal(result?.structuredContent.result.results.length, 2);
|
||||
assert.match(result?.content[0]?.text ?? "", /禁止自动重试/);
|
||||
assert.equal(bridgeWriteOutcomeUncertainResult("approval_list_todos", {}), undefined);
|
||||
});
|
||||
|
||||
test("stdio bridge converts a remote batch timeout into a structured uncertain outcome", async () => {
|
||||
const root = mkdtempSync(join(tmpdir(), "ding-bridge-write-timeout-"));
|
||||
const statePath = join(root, "session.json");
|
||||
writeFileSync(statePath, JSON.stringify({
|
||||
client: { client_id: "bridge-client" },
|
||||
tokens: { access_token: "fresh-access", savedAt: Date.now(), expires_in: 900 },
|
||||
}));
|
||||
const bridge = new RemoteBridge("https://approval.example.test/mcp", statePath, async () => {
|
||||
throw new Error("network should not be used by the injected client");
|
||||
});
|
||||
(bridge as unknown as { client: { callTool(): Promise<unknown>; close(): Promise<void> } }).client = {
|
||||
async callTool() { throw new Error("Request timed out"); },
|
||||
async close() {},
|
||||
};
|
||||
|
||||
const result = await bridge.call("approval_process_batch", {
|
||||
action: "approve",
|
||||
items: [{ approvalId: "approval-one" }],
|
||||
});
|
||||
assert.equal(result.structuredContent.result.status, "outcome_uncertain");
|
||||
assert.equal(result.structuredContent.result.uncertain, 1);
|
||||
assert.equal(result.structuredContent.result.retryable, false);
|
||||
assert.match(result.content[0].text, /重新列出实时待办核对/);
|
||||
});
|
||||
|
||||
test("legacy updater post-install syncs the complete bundled Skill", () => {
|
||||
const root = mkdtempSync(join(tmpdir(), "ding-bridge-skill-sync-"));
|
||||
const bundled = join(root, "package", "skill", "dingtalk-approval");
|
||||
|
||||
Reference in New Issue
Block a user