Files
boss/tests/remote-runtime-adapter.test.ts

134 lines
5.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import test from "node:test";
import assert from "node:assert/strict";
import { normalizeRemoteExecutionResultForTesting } from "../src/lib/execution/remote-runtime-adapter.ts";
test("RemoteRuntimeAdapter 会把 local-agent 回写标准化成统一结果", () => {
const normalized = normalizeRemoteExecutionResultForTesting({
status: "completed",
dispatchExecutionId: "dx-1",
targetProjectId: "project-1",
targetThreadId: "thread-1",
rawThreadReply: " 链路正常 ",
replyBody: " 主 Agent 汇总:链路正常 ",
});
assert.equal(normalized.status, "completed");
assert.equal(normalized.dispatchExecutionId, "dx-1");
assert.equal(normalized.targetProjectId, "project-1");
assert.equal(normalized.targetThreadId, "thread-1");
assert.equal(normalized.targetUrl, undefined);
assert.equal(normalized.targetApp, undefined);
assert.equal(normalized.rawThreadReply, "链路正常");
assert.equal(normalized.replyBody, "主 Agent 汇总:链路正常");
});
test("RemoteRuntimeAdapter 会保留 browser/desktop 控制结果的目标信息", () => {
const browser = normalizeRemoteExecutionResultForTesting({
status: "completed",
replyBody: "浏览器控制已完成",
targetUrl: " https://example.com/dashboard ",
});
const desktop = normalizeRemoteExecutionResultForTesting({
status: "completed",
replyBody: "桌面控制已完成",
targetApp: " 微信 ",
});
assert.equal(browser.targetUrl, "https://example.com/dashboard");
assert.equal(browser.targetApp, undefined);
assert.equal(desktop.targetUrl, undefined);
assert.equal(desktop.targetApp, "微信");
});
test("RemoteRuntimeAdapter 会忽略空白字段并保留失败状态", () => {
const normalized = normalizeRemoteExecutionResultForTesting({
status: "failed",
dispatchExecutionId: " ",
targetProjectId: " project-2 ",
targetThreadId: "",
rawThreadReply: " ",
errorMessage: " MODEL_CALL_FAILED ",
});
assert.equal(normalized.status, "failed");
assert.equal(normalized.dispatchExecutionId, undefined);
assert.equal(normalized.targetProjectId, "project-2");
assert.equal(normalized.targetThreadId, undefined);
assert.equal(normalized.rawThreadReply, undefined);
assert.equal(normalized.errorMessage, "MODEL_CALL_FAILED");
});
test("RemoteRuntimeAdapter 会把线程环境脏回复改写成失败", () => {
const normalized = normalizeRemoteExecutionResultForTesting({
status: "completed",
replyBody:
"我不能直接把当前会话环境从只读改回可写。cwd 我可以在命令里指向 /Users/kris/code/gptpluscontrol但真正卡住的是只读权限。",
});
assert.equal(normalized.status, "failed");
assert.equal(normalized.replyBody, undefined);
assert.equal(normalized.rawThreadReply, undefined);
assert.match(normalized.errorMessage ?? "", /THREAD_ENVIRONMENT_INVALID/);
});
test("RemoteRuntimeAdapter 会把 Codex CLI 启动日志泄漏改写成内部执行失败", () => {
const normalized = normalizeRemoteExecutionResultForTesting({
status: "failed",
errorMessage: [
"OpenAI Codex v0.114.0 (research preview)",
"--------",
"workdir: /Users/kris/code/boss",
"model: gpt-5.4",
"provider: openai",
"approval: never",
"sandbox: workspace-write [workdir, /tmp, $TMPDIR, /Users/kris/.codex/memories]",
"session id: 019da4e5-9b1d-7dc1-8aa5-a74a74b6b021",
"--------",
"user",
"同步完成记得要和我说,以后也是这样。",
"mcp: chrome-devtools starting",
].join("\n"),
});
assert.equal(normalized.status, "failed");
assert.equal(normalized.replyBody, undefined);
assert.equal(normalized.rawThreadReply, undefined);
assert.equal(normalized.errorMessage, "MASTER_CODEX_NODE_OUTPUT_LEAKED");
});
test("RemoteRuntimeAdapter 会把执行提示词片段泄漏改写成内部执行失败", () => {
const normalized = normalizeRemoteExecutionResultForTesting({
status: "failed",
errorMessage: [
"管理员全局主提示词:",
"你是 Boss 控制台的主 Agent。",
"回复风格:像专业职业经理人,先给结论,再给推进动作。",
"",
"用户私有主提示词:",
"默认中文回复。",
"",
"当前对话附加提示词:",
"同步项目目标和版本记录后记得告诉我。",
"",
"当前消息:",
"同步完成记得要和我说,以后也是这样。",
].join("\n"),
});
assert.equal(normalized.status, "failed");
assert.equal(normalized.replyBody, undefined);
assert.equal(normalized.rawThreadReply, undefined);
assert.equal(normalized.errorMessage, "MASTER_CODEX_NODE_OUTPUT_LEAKED");
});
test("RemoteRuntimeAdapter 不会误杀包含路径和 sandbox 描述的有效线程回复", () => {
const normalized = normalizeRemoteExecutionResultForTesting({
status: "completed",
replyBody:
"已经把配置写到 /Users/kris/code/gptpluscontrol/.env.local接下来如果线上仍受 sandbox 限制,我们再切到服务器验证。",
});
assert.equal(normalized.status, "completed");
assert.match(normalized.replyBody ?? "", /gptpluscontrol/);
});