Files
pikasTech-agentrun/src/selftest/fake-codex-app-server.ts
T
2026-05-29 16:27:26 +08:00

127 lines
5.3 KiB
TypeScript

import * as readline from "node:readline";
const rl = readline.createInterface({ input: process.stdin, crlfDelay: Infinity });
const mode = process.env.AGENTRUN_FAKE_CODEX_MODE ?? "success";
let threadCounter = 0;
let turnCounter = 0;
let observedThreadModel = false;
for await (const line of rl) {
const trimmed = String(line).trim();
if (trimmed.length === 0) continue;
const message = JSON.parse(trimmed) as { id?: number; method?: string; params?: Record<string, unknown> };
if (message.method === "initialize") {
if (mode === "invalid-json") {
process.stdout.write('{"token":"test-token-material"\n');
process.exit(0);
}
respond(message.id, { serverInfo: { name: "fake-codex-app-server", version: "self-test" } });
continue;
}
if (message.method === "thread/start") {
observedThreadModel = Object.hasOwn(message.params ?? {}, "model");
if (mode === "reject-unexpected-model" && observedThreadModel) {
respond(message.id, null, { code: -32000, message: "thread/start unexpectedly included model" });
continue;
}
if (mode === "require-explicit-model" && message.params?.model !== "gpt-5.5") {
respond(message.id, null, { code: -32000, message: "thread/start did not include expected model" });
continue;
}
threadCounter += 1;
const thread = { id: `thread_selftest_${threadCounter}` };
notify("thread/started", { thread });
respond(message.id, { thread });
continue;
}
if (message.method === "thread/resume") {
observedThreadModel = Object.hasOwn(message.params ?? {}, "model");
if (mode === "reject-unexpected-model" && observedThreadModel) {
respond(message.id, null, { code: -32000, message: "thread/resume unexpectedly included model" });
continue;
}
if (mode === "require-explicit-model" && message.params?.model !== "gpt-5.5") {
respond(message.id, null, { code: -32000, message: "thread/resume did not include expected model" });
continue;
}
const thread = { id: String(message.params?.threadId ?? "thread_selftest_resumed") };
notify("thread/started", { thread });
respond(message.id, { thread });
continue;
}
if (message.method === "turn/start") {
if (mode === "reject-unexpected-model" && (observedThreadModel || Object.hasOwn(message.params ?? {}, "model"))) {
respond(message.id, null, { code: -32000, message: "turn/start unexpectedly included model" });
continue;
}
if (mode === "require-explicit-model" && message.params?.model !== "gpt-5.5") {
respond(message.id, null, { code: -32000, message: "turn/start did not include expected model" });
continue;
}
if (mode === "missing-turn-result") {
respond(message.id, {});
continue;
}
if (mode === "provider-503-rpc-error") {
respond(message.id, null, { code: -32000, message: "responseStreamDisconnected: HTTP 503 Service Unavailable from provider" });
continue;
}
if (mode === "missing-terminal") {
turnCounter += 1;
const turn = { id: `turn_selftest_${turnCounter}`, status: "running" };
notify("turn/started", { turn });
respond(message.id, { turn });
continue;
}
if (mode === "provider-503-terminal") {
turnCounter += 1;
const turn = { id: `turn_selftest_${turnCounter}`, status: "failed", error: { message: "HTTP 503 Service Unavailable" } };
notify("turn/started", { turn: { id: turn.id, status: "running" } });
notify("turn/completed", { turn });
respond(message.id, { turn });
continue;
}
if (mode === "provider-503-retry-event") {
turnCounter += 1;
const turn = {
id: `turn_selftest_${turnCounter}`,
status: "failed",
error: {
message: "unexpected status 503 Service Unavailable: Service temporarily unavailable",
codexErrorInfo: { responseStreamDisconnected: { httpStatusCode: 503 } },
},
};
notify("turn/started", { turn: { id: turn.id, status: "running" } });
notify("error", {
willRetry: true,
error: {
message: "Reconnecting... 1/5",
codexErrorInfo: { responseStreamDisconnected: { httpStatusCode: 503 } },
additionalDetails: "unexpected status 503 Service Unavailable: Service temporarily unavailable, url: https://hyueapi.com/responses",
},
});
notify("turn/completed", { turn });
respond(message.id, { turn });
continue;
}
turnCounter += 1;
const turn = { id: `turn_selftest_${turnCounter}`, status: "completed" };
notify("turn/started", { turn });
notify("item/agentMessage/delta", { itemId: "msg_selftest", delta: "fake codex stdio reply" });
notify("item/commandExecution/outputDelta", { itemId: "cmd_selftest", delta: "Authorization: Bearer test-token\n" });
notify("turn/completed", { turn });
respond(message.id, { turn });
continue;
}
respond(message.id, null, { code: -32601, message: `unsupported fake method ${message.method ?? "unknown"}` });
}
function respond(id: number | undefined, result: unknown, error?: unknown): void {
if (id === undefined) return;
process.stdout.write(`${JSON.stringify(error ? { id, error } : { id, result })}\n`);
}
function notify(method: string, params: unknown): void {
process.stdout.write(`${JSON.stringify({ method, params })}\n`);
}