fix: route Keil gateway prompts to Codex stdio (#471)
Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
@@ -2202,6 +2202,12 @@ function detectReadOnlyRunnerIntent(message, options = {}) {
|
||||
reason: "Code Agent 安全边界不读取或输出 secret、token、kubeconfig、密码、私钥或环境变量原文。"
|
||||
};
|
||||
}
|
||||
if (isPcGatewayCodexToolRequest(text)) {
|
||||
return {
|
||||
kind: "none",
|
||||
toolName: "codex-stdio.pc-gateway-wrapper"
|
||||
};
|
||||
}
|
||||
const m3IoIntent = detectM3IoIntent(text);
|
||||
if (m3IoIntent) {
|
||||
return m3IoIntent;
|
||||
@@ -2221,6 +2227,14 @@ function detectReadOnlyRunnerIntent(message, options = {}) {
|
||||
return { kind: "none" };
|
||||
}
|
||||
|
||||
function isPcGatewayCodexToolRequest(text) {
|
||||
const value = String(text ?? "");
|
||||
const mentionsGatewayTool = /(?:\/app\/tools\/hwlab-gateway-shell\.mjs|hwlab-gateway-shell\.mjs|hardware\.invoke\.shell|PC\s*gateway|gws_DESKTOP-[A-Z0-9-]+|cap_windows_cmd_exec|res_windows_host)/iu.test(value);
|
||||
const mentionsWindowsCommand = /(?:Windows\s+cmd|cmd\s*\/c|shell\.exec|hostname|PowerShell|powershell)/iu.test(value);
|
||||
const mentionsWindowsSkill = /(?:C:\\Users\\liang\\\.agents\\skills|\.agents[\\/]+skills|keil-cli\.py|\bKeil\b|MDK-ARM|\.uvprojx|F:\\Work\\constart|job-status)/iu.test(value);
|
||||
return mentionsGatewayTool && (mentionsWindowsCommand || mentionsWindowsSkill);
|
||||
}
|
||||
|
||||
function detectExternalNetworkIntent(text) {
|
||||
const value = String(text ?? "").trim();
|
||||
if (!value) return null;
|
||||
|
||||
@@ -1889,6 +1889,73 @@ test("Code Agent PC gateway prompt reaches Codex stdio instead of internal hardw
|
||||
}
|
||||
});
|
||||
|
||||
test("Code Agent Keil gateway prompt is not blocked by M3 IO intent guard", async () => {
|
||||
const calls = [];
|
||||
let providerCalled = false;
|
||||
const fakeCodex = await createFakeCodexCommand();
|
||||
const codexHome = await prepareFakeCodexHome();
|
||||
const registry = createCodeAgentSessionRegistry();
|
||||
const manager = createCodexStdioSessionManager({
|
||||
idFactory: () => "ses_keil_gateway_stdio",
|
||||
createRpcClient: async () => createFakeAppServerClient({
|
||||
calls,
|
||||
responses: ["已通过 PC gateway 调用 Windows Keil skill,success=true,return_code=0,生成 FREQ_Controller_FW.hex。"]
|
||||
})
|
||||
});
|
||||
|
||||
try {
|
||||
const payload = await handleCodeAgentChat(
|
||||
{
|
||||
conversationId: "cnv_keil_gateway_stdio",
|
||||
traceId: "trc_keil_gateway_stdio",
|
||||
projectId: "prj_mvp_topology",
|
||||
message: String.raw`请用 /app/tools/hwlab-gateway-shell.mjs 通过 PC gateway 调用 Windows cmd,进入 C:\Users\liang\.agents\skills\keil,然后运行 py -3 keil-cli.py build -p "F:\Work\constart\projects\71-00075-11\FirmWare\MDK-ARM\FREQ_Controller_FW.uvprojx" -t FREQ_Controller_FW;如果返回 job id,请用 py -3 keil-cli.py job-status <job_id> 轮询到终态。`
|
||||
},
|
||||
{
|
||||
now: () => "2026-05-24T14:35:00.000Z",
|
||||
env: {
|
||||
PATH: process.env.PATH,
|
||||
OPENAI_API_KEY: "test-openai-key-material",
|
||||
CODEX_HOME: codexHome,
|
||||
HWLAB_CODE_AGENT_PROVIDER: "codex-stdio",
|
||||
HWLAB_CODE_AGENT_MODEL: "gpt-test",
|
||||
HWLAB_CODE_AGENT_CODEX_COMMAND: fakeCodex.command,
|
||||
HWLAB_CODE_AGENT_CODEX_STDIO_ENABLED: "1",
|
||||
HWLAB_CODE_AGENT_CODEX_STDIO_SUPERVISOR: "repo-owned",
|
||||
HWLAB_CODE_AGENT_CODEX_SANDBOX: "danger-full-access",
|
||||
HWLAB_CODE_AGENT_WORKSPACE: process.cwd(),
|
||||
HWLAB_CODE_AGENT_OPENAI_BASE_URL: "http://172.26.26.227:17680/v1/responses"
|
||||
},
|
||||
sessionRegistry: registry,
|
||||
codexStdioManager: manager,
|
||||
callProvider: async () => {
|
||||
providerCalled = true;
|
||||
throw new Error("text fallback must not be used");
|
||||
},
|
||||
m3IoSkillRequestJson: async () => {
|
||||
throw new Error("Keil gateway prompt must not be routed to M3 IO");
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
validateCodeAgentChatSchema(payload);
|
||||
assert.equal(payload.status, "completed");
|
||||
assert.equal(payload.provider, "codex-stdio");
|
||||
assert.equal(payload.responseType, undefined);
|
||||
assert.notEqual(payload.capabilityLevel, HWLAB_M3_IO_CAPABILITY_LEVELS.blocked);
|
||||
assert.equal(providerCalled, false);
|
||||
const turn = calls.find((call) => call.method === "turn/start");
|
||||
assert.ok(turn, "Codex stdio turn/start should be called");
|
||||
assert.match(turn.args.prompt, /\/app\/tools\/hwlab-gateway-shell\.mjs/u);
|
||||
assert.match(turn.args.prompt, /keil-cli\.py build/u);
|
||||
assert.match(turn.args.prompt, /job-status/u);
|
||||
assert.match(turn.args.prompt, /FREQ_Controller_FW\.uvprojx/u);
|
||||
} finally {
|
||||
await rm(fakeCodex.root, { recursive: true, force: true });
|
||||
await rm(codexHome, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
function delay(ms) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user