

























@@ -24,6 +24,15 @@ describe("acp prompt cwd prefix", () => {
2424return {};
2525});
262627+function chatSendPayload(requestSpy: { mock: { calls: unknown[][] } }, index = 0) {
28+const call = requestSpy.mock.calls[index];
29+expect(call?.[0]).toBe("chat.send");
30+expect(call?.[2]).toEqual({ timeoutMs: null });
31+expect(typeof call?.[1]).toBe("object");
32+expect(call?.[1]).not.toBeNull();
33+return call?.[1] as Record<string, unknown>;
34+}
35+2736async function runPromptAndCaptureRequest(
2837options: {
2938cwd?: string;
@@ -78,79 +87,44 @@ describe("acp prompt cwd prefix", () => {
78877988it("redacts home directory in prompt prefix", async () => {
8089const requestSpy = await runPromptWithCwd(path.join(os.homedir(), "openclaw-test"));
81-expect(requestSpy).toHaveBeenCalledWith(
82-"chat.send",
83-expect.objectContaining({
84-message: expect.stringMatching(/\[Working directory: ~[\\/]openclaw-test\]/),
85-}),
86-{ timeoutMs: null },
87-);
90+const payload = chatSendPayload(requestSpy);
91+expect(typeof payload.message).toBe("string");
92+expect(payload.message).toMatch(/\[Working directory: ~[\\/]openclaw-test\]/);
8893});
89949095it("keeps backslash separators when cwd uses them", async () => {
9196const requestSpy = await runPromptWithCwd(`${os.homedir()}\\openclaw-test`);
92-expect(requestSpy).toHaveBeenCalledWith(
93-"chat.send",
94-expect.objectContaining({
95-message: expect.stringContaining("[Working directory: ~\\openclaw-test]"),
96-}),
97-{ timeoutMs: null },
98-);
97+const payload = chatSendPayload(requestSpy);
98+expect(payload.message).toContain("[Working directory: ~\\openclaw-test]");
9999});
100100101101it("injects system provenance metadata when enabled", async () => {
102102const requestSpy = await runPromptAndCaptureRequest({ provenanceMode: "meta" });
103-expect(requestSpy).toHaveBeenCalledWith(
104-"chat.send",
105-expect.objectContaining({
106-systemInputProvenance: {
107-kind: "external_user",
108-originSessionId: TEST_SESSION_ID,
109-sourceChannel: "acp",
110-sourceTool: "openclaw_acp",
111-},
112-systemProvenanceReceipt: undefined,
113-}),
114-{ timeoutMs: null },
115-);
103+const payload = chatSendPayload(requestSpy);
104+expect(payload.systemInputProvenance).toEqual({
105+kind: "external_user",
106+originSessionId: TEST_SESSION_ID,
107+sourceChannel: "acp",
108+sourceTool: "openclaw_acp",
109+});
110+expect(payload.systemProvenanceReceipt).toBeUndefined();
116111});
117112118113it("injects a system provenance receipt when requested", async () => {
119114const requestSpy = await runPromptAndCaptureRequest({ provenanceMode: "meta+receipt" });
120-expect(requestSpy).toHaveBeenCalledWith(
121-"chat.send",
122-expect.objectContaining({
123-systemInputProvenance: {
124-kind: "external_user",
125-originSessionId: TEST_SESSION_ID,
126-sourceChannel: "acp",
127-sourceTool: "openclaw_acp",
128-},
129-systemProvenanceReceipt: expect.stringContaining("[Source Receipt]"),
130-}),
131-{ timeoutMs: null },
132-);
133-expect(requestSpy).toHaveBeenCalledWith(
134-"chat.send",
135-expect.objectContaining({
136-systemProvenanceReceipt: expect.stringContaining("bridge=openclaw-acp"),
137-}),
138-{ timeoutMs: null },
139-);
140-expect(requestSpy).toHaveBeenCalledWith(
141-"chat.send",
142-expect.objectContaining({
143-systemProvenanceReceipt: expect.stringContaining(`originSessionId=${TEST_SESSION_ID}`),
144-}),
145-{ timeoutMs: null },
146-);
147-expect(requestSpy).toHaveBeenCalledWith(
148-"chat.send",
149-expect.objectContaining({
150-systemProvenanceReceipt: expect.stringContaining(`targetSession=${TEST_SESSION_KEY}`),
151-}),
152-{ timeoutMs: null },
153-);
115+const payload = chatSendPayload(requestSpy);
116+expect(payload.systemInputProvenance).toEqual({
117+kind: "external_user",
118+originSessionId: TEST_SESSION_ID,
119+sourceChannel: "acp",
120+sourceTool: "openclaw_acp",
121+});
122+expect(typeof payload.systemProvenanceReceipt).toBe("string");
123+const receipt = payload.systemProvenanceReceipt as string;
124+expect(receipt).toContain("[Source Receipt]");
125+expect(receipt).toContain("bridge=openclaw-acp");
126+expect(receipt).toContain(`originSessionId=${TEST_SESSION_ID}`);
127+expect(receipt).toContain(`targetSession=${TEST_SESSION_KEY}`);
154128});
155129156130it("retries without provenance when the gateway rejects admin-only provenance fields", async () => {
@@ -180,28 +154,17 @@ describe("acp prompt cwd prefix", () => {
180154181155await expect(agent.prompt(TEST_PROMPT)).rejects.toThrow("stop-after-send");
182156expect(requestSpy).toHaveBeenCalledTimes(2);
183-expect(requestSpy).toHaveBeenNthCalledWith(
184-1,
185-"chat.send",
186-expect.objectContaining({
187-systemInputProvenance: {
188-kind: "external_user",
189-originSessionId: TEST_SESSION_ID,
190-sourceChannel: "acp",
191-sourceTool: "openclaw_acp",
192-},
193-systemProvenanceReceipt: expect.stringContaining("[Source Receipt]"),
194-}),
195-{ timeoutMs: null },
196-);
197-expect(requestSpy).toHaveBeenNthCalledWith(
198-2,
199-"chat.send",
200-expect.not.objectContaining({
201-systemInputProvenance: expect.anything(),
202-systemProvenanceReceipt: expect.anything(),
203-}),
204-{ timeoutMs: null },
205-);
157+const firstPayload = chatSendPayload(requestSpy, 0);
158+expect(firstPayload.systemInputProvenance).toEqual({
159+kind: "external_user",
160+originSessionId: TEST_SESSION_ID,
161+sourceChannel: "acp",
162+sourceTool: "openclaw_acp",
163+});
164+expect(firstPayload.systemProvenanceReceipt).toContain("[Source Receipt]");
165+166+const retryPayload = chatSendPayload(requestSpy, 1);
167+expect(retryPayload.systemInputProvenance).toBeUndefined();
168+expect(retryPayload.systemProvenanceReceipt).toBeUndefined();
206169});
207170});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。