Files
boss/tests/fixtures/codex-app-server-runtime.mjs
2026-06-01 17:40:03 +08:00

714 lines
19 KiB
JavaScript

#!/usr/bin/env node
import readline from "node:readline";
const rl = readline.createInterface({ input: process.stdin });
const received = [];
let injectedItems = [];
let overloadedTurnStartEmitted = false;
function send(message) {
process.stdout.write(`${JSON.stringify(message)}\n`);
}
rl.on("line", (line) => {
const message = JSON.parse(line);
received.push(message);
if (message.method === "initialize") {
send({
id: message.id,
result: {
userAgent: "boss-test-codex-app-server",
platformFamily: "mac",
platformOs: "darwin",
},
});
return;
}
if (message.method === "initialized") {
return;
}
if (message.method === "model/list") {
send({
id: message.id,
result: {
data: [
{
id: "gpt-5.4",
model: "gpt-5.4",
displayName: "GPT-5.4",
description: "Deep reasoning model",
hidden: false,
supportedReasoningEfforts: ["low", "medium", "high"],
defaultReasoningEffort: "medium",
inputModalities: ["text", "image"],
supportsPersonality: true,
serviceTiers: [{ id: "default", displayName: "Default" }],
defaultServiceTier: "default",
isDefault: true,
},
{
id: "gpt-5.4-mini",
model: "gpt-5.4-mini",
displayName: "GPT-5.4 mini",
description: "Fast response model",
hidden: false,
supportedReasoningEfforts: ["none", "low"],
defaultReasoningEffort: "none",
inputModalities: ["text"],
supportsPersonality: true,
serviceTiers: [],
defaultServiceTier: null,
isDefault: false,
},
],
nextCursor: null,
},
});
return;
}
if (message.method === "modelProvider/capabilities/read") {
send({
id: message.id,
result: {
namespaceTools: true,
imageGeneration: true,
webSearch: true,
},
});
return;
}
if (message.method === "skills/list") {
send({
id: message.id,
result: {
data: [
{
cwd: "/Users/kris/code/boss",
skills: [
{
name: "image2-ui-prototype",
description: "Generate high fidelity UI prototypes",
path: "/Users/kris/.codex/skills/image2-ui-prototype/SKILL.md",
scope: "user",
enabled: true,
},
],
errors: [],
},
],
},
});
return;
}
if (message.method === "plugin/list") {
send({
id: message.id,
result: {
marketplaces: [
{
name: "local",
path: "/Users/kris/.codex/plugins/marketplace.json",
interface: null,
plugins: [
{
id: "github",
remotePluginId: null,
localVersion: "1.0.0",
name: "GitHub",
installed: true,
enabled: true,
keywords: ["repo"],
},
],
},
],
marketplaceLoadErrors: [],
featuredPluginIds: ["github"],
},
});
return;
}
if (message.method === "app/list") {
send({
id: message.id,
result: {
data: [
{
id: "canva",
name: "Canva",
description: "Design app",
isAccessible: true,
isEnabled: true,
pluginDisplayNames: ["Canva"],
},
],
nextCursor: null,
},
});
return;
}
if (message.method === "thread/resume") {
send({
id: message.id,
result: {
thread: {
id: message.params?.threadId ?? "thread-fixture",
name: "fixture thread",
},
},
});
return;
}
if (message.method === "thread/read") {
send({
id: message.id,
result: {
thread: {
id: message.params?.threadId,
name: "源线程",
},
items: [
{
type: "message",
role: "assistant",
content: [
{
type: "output_text",
text: "源线程最近结论:优先使用 app-server 协议。",
},
],
},
],
},
});
return;
}
if (message.method === "thread/inject_items") {
injectedItems = message.params?.items ?? [];
send({
id: message.id,
result: {
injected: injectedItems.length,
},
});
return;
}
if (message.method === "thread/start") {
send({
id: message.id,
result: {
thread: {
id: "thread-started-fixture",
name: "new fixture thread",
},
},
});
return;
}
if (message.method === "turn/start") {
if (
process.env.BOSS_CODEX_APP_SERVER_FIXTURE_OVERLOAD_ON_TURN_START === "1" &&
!overloadedTurnStartEmitted
) {
overloadedTurnStartEmitted = true;
send({
id: message.id,
error: {
code: -32001,
message: "Server overloaded; retry later.",
},
});
return;
}
const text = message.params?.input?.find?.((item) => item?.type === "text")?.text ?? "";
send({
id: message.id,
result: {
turn: {
id: "turn-fixture",
threadId: message.params?.threadId,
},
},
});
if (process.env.BOSS_CODEX_APP_SERVER_FIXTURE_EXIT_AFTER_TURN_START === "1") {
process.exit(0);
}
if (process.env.BOSS_CODEX_APP_SERVER_FIXTURE_EMIT_PROGRESS === "1") {
send({
method: "turn/plan/updated",
params: {
threadId: message.params?.threadId,
turnId: "turn-fixture",
plan: [
{ text: "读取 Codex 官方 app-server 协议", status: "completed" },
{ text: "执行 targeted/full test", status: "in_progress" },
],
},
});
send({
method: "turn/diff/updated",
params: {
threadId: message.params?.threadId,
turnId: "turn-fixture",
diff: {
changedFiles: 3,
additions: 181,
deletions: 52,
},
},
});
send({
method: "item/completed",
params: {
threadId: message.params?.threadId,
turnId: "turn-fixture",
item: {
type: "fileChange",
id: "file-change-1",
changes: [
{ path: "docs/protocol-snapshots/codex-app-server/codex-app-server-protocol-0.135.0.json" },
],
},
},
});
send({
method: "thread/started",
params: {
thread: {
id: "subagent-thread",
source: {
subAgent: {
thread_spawn: {
agent_nickname: "Mendel",
agent_role: "explorer",
},
},
},
},
},
});
}
if (process.env.BOSS_CODEX_APP_SERVER_FIXTURE_EMIT_GUARDIAN_EVENTS === "1") {
send({
id: "cmd-approval-1",
method: "item/commandExecution/requestApproval",
params: {
threadId: message.params?.threadId,
turnId: "turn-fixture",
itemId: "command-item-1",
startedAtMs: Date.now(),
reason: "需要确认命令执行",
command: "npm run build -- --token sk-secret-should-not-leak",
cwd: "/Users/kris/code/boss",
},
});
send({
method: "item/autoApprovalReview/started",
params: {
threadId: message.params?.threadId,
turnId: "turn-fixture",
reviewId: "review-1",
startedAtMs: Date.now(),
targetItemId: "command-item-1",
action: {
type: "command",
command: "npm run build -- --token sk-secret-should-not-leak",
cwd: "/Users/kris/code/boss",
},
review: {
status: "running",
riskLevel: "medium",
userAuthorization: null,
rationale: "contains a fake secret that must not be surfaced",
},
},
});
send({
method: "guardianWarning",
params: {
threadId: message.params?.threadId,
message: "检测到需要用户确认的命令执行。",
},
});
send({
method: "item/fileChange/patchUpdated",
params: {
threadId: message.params?.threadId,
turnId: "turn-fixture",
itemId: "file-change-item-1",
changes: [
{
path: "src/app/page.tsx",
kind: "update",
diff: "+ const secret = 'sk-secret-should-not-leak'",
},
{
path: "docs/architecture/codex_server_progress_card_cn.md",
kind: "add",
diff: "+ internal prompt should not leak",
},
],
},
});
send({
method: "item/autoApprovalReview/completed",
params: {
threadId: message.params?.threadId,
turnId: "turn-fixture",
reviewId: "review-1",
startedAtMs: Date.now(),
completedAtMs: Date.now(),
targetItemId: "command-item-1",
decisionSource: "auto_review",
action: {
type: "command",
command: "npm run build -- --token sk-secret-should-not-leak",
cwd: "/Users/kris/code/boss",
},
review: {
status: "approved",
riskLevel: "medium",
userAuthorization: null,
rationale: "contains a fake secret that must not be surfaced",
},
},
});
send({
method: "serverRequest/resolved",
params: {
requestId: "cmd-approval-1",
threadId: message.params?.threadId,
},
});
}
if (process.env.BOSS_CODEX_APP_SERVER_FIXTURE_EMIT_REALTIME_EVENTS === "1") {
send({
method: "thread/status/changed",
params: {
threadId: message.params?.threadId,
status: {
type: "active",
activeFlags: ["waitingOnApproval", "waitingOnUserInput"],
},
},
});
send({
method: "thread/realtime/started",
params: {
threadId: message.params?.threadId,
realtimeSessionId: "rt-session-1",
version: "v2",
},
});
send({
method: "thread/realtime/sdp",
params: {
threadId: message.params?.threadId,
sdp: "v=0 secret-sk-should-not-leak",
},
});
send({
method: "thread/realtime/transcript/delta",
params: {
threadId: message.params?.threadId,
role: "assistant",
delta: "正在分析 Codex ",
},
});
send({
method: "thread/realtime/transcript/done",
params: {
threadId: message.params?.threadId,
role: "assistant",
text: "正在分析 Codex App Server 实时事件。",
},
});
send({
method: "thread/realtime/outputAudio/delta",
params: {
threadId: message.params?.threadId,
audio: {
data: "audio-secret-payload",
sampleRate: 24000,
numChannels: 1,
samplesPerChannel: 480,
itemId: "audio-item-1",
},
},
});
send({
method: "thread/realtime/itemAdded",
params: {
threadId: message.params?.threadId,
item: {
type: "message",
text: "raw realtime item should not be persisted",
},
},
});
send({
method: "thread/realtime/closed",
params: {
threadId: message.params?.threadId,
reason: "completed",
},
});
}
if (process.env.BOSS_CODEX_APP_SERVER_FIXTURE_EMIT_RUNTIME_STATUS === "1") {
send({
method: "model/rerouted",
params: {
threadId: message.params?.threadId,
turnId: "turn-fixture",
fromModel: "gpt-5.4-mini",
toModel: "gpt-5.4",
reason: "highRiskCyberActivity",
},
});
send({
method: "thread/tokenUsage/updated",
params: {
threadId: message.params?.threadId,
turnId: "turn-fixture",
tokenUsage: {
total: {
totalTokens: 3000,
inputTokens: 2200,
cachedInputTokens: 300,
outputTokens: 650,
reasoningOutputTokens: 150,
},
last: {
totalTokens: 800,
inputTokens: 500,
cachedInputTokens: 120,
outputTokens: 260,
reasoningOutputTokens: 40,
},
modelContextWindow: 200000,
},
},
});
send({
method: "mcpServer/startupStatus/updated",
params: {
name: "github",
status: "failed",
error: "token=sk-secret-should-not-leak failed to start",
},
});
send({
method: "remoteControl/status/changed",
params: {
status: "connected",
serverName: "Mac Studio",
installationId: "install-secret-should-not-leak",
environmentId: "env-prod",
},
});
}
if (process.env.BOSS_CODEX_APP_SERVER_FIXTURE_EMIT_THREAD_CONFIG_EVENTS === "1") {
send({
method: "thread/goal/updated",
params: {
threadId: message.params?.threadId,
turnId: "turn-fixture",
goal: {
threadId: message.params?.threadId,
objective: "完成 App Server 线程目标同步",
status: "active",
tokenBudget: 120000,
tokensUsed: 4800,
timeUsedSeconds: 600,
createdAt: 1770000000,
updatedAt: 1770000300,
},
},
});
send({
method: "thread/settings/updated",
params: {
threadId: message.params?.threadId,
threadSettings: {
cwd: "/Users/kris/code/boss/secret-project",
approvalPolicy: "on-request",
approvalsReviewer: "user",
sandboxPolicy: {
type: "workspaceWrite",
writableRoots: ["/Users/kris/code/boss", "/Users/kris/.codex/memories"],
networkAccess: false,
excludeTmpdirEnvVar: false,
excludeSlashTmp: false,
},
activePermissionProfile: {
id: ":workspace",
extends: null,
},
model: "gpt-5.5",
modelProvider: "openai",
serviceTier: "fast",
effort: "low",
summary: "concise",
collaborationMode: {
mode: "plan",
settings: {
developer_instructions: "internal prompt should not leak",
model_instructions_file: "/Users/kris/.codex/secret-instructions.md",
},
},
personality: "pragmatic",
},
},
});
send({
method: "thread/compacted",
params: {
threadId: message.params?.threadId,
turnId: "turn-fixture",
},
});
}
if (process.env.BOSS_CODEX_APP_SERVER_FIXTURE_EMIT_ACCOUNT_NOTICE_EVENTS === "1") {
send({
method: "account/updated",
params: {
authMode: "chatgpt",
planType: "team",
},
});
send({
method: "account/rateLimits/updated",
params: {
rateLimits: {
limitId: "codex",
limitName: "Codex",
primary: {
usedPercent: 88,
windowDurationMins: 180,
resetsAt: 1770003600,
},
secondary: null,
credits: {
hasCredits: true,
unlimited: false,
balance: "120.5",
},
planType: "team",
rateLimitReachedType: null,
},
},
});
send({
method: "model/verification",
params: {
threadId: message.params?.threadId,
turnId: "turn-fixture",
verifications: ["trustedAccessForCyber"],
},
});
send({
method: "warning",
params: {
threadId: message.params?.threadId,
message: "模型切换提醒 token=sk-secret-should-not-leak",
},
});
send({
method: "configWarning",
params: {
summary: "项目配置已忽略",
details: "openai_base_url 不能放在项目配置里",
path: "/Users/kris/code/boss/.codex/config.toml",
},
});
send({
method: "deprecationNotice",
params: {
summary: "on-failure 已废弃",
details: "请改用 on-request",
},
});
}
send({
method: "item/agentMessage/delta",
params: {
threadId: message.params?.threadId,
turnId: "turn-fixture",
delta:
process.env.BOSS_CODEX_APP_SERVER_FIXTURE_INTER_THREAD === "1"
? `INTER_THREAD_INJECTED:${JSON.stringify(injectedItems)}`
: `APP_SERVER_REPLY:${text}`,
},
});
send({
method: "turn/completed",
params: {
threadId: message.params?.threadId,
turn: {
id: "turn-fixture",
status: "completed",
},
},
});
process.stderr.write(`${JSON.stringify({ received })}\n`);
return;
}
if (message.method === "turn/steer") {
const text = message.params?.input?.find?.((item) => item?.type === "text")?.text ?? "";
send({
id: message.id,
result: {
turn: {
id: message.params?.expectedTurnId,
threadId: message.params?.threadId,
},
},
});
send({
method: "item/agentMessage/delta",
params: {
threadId: message.params?.threadId,
turnId: message.params?.expectedTurnId,
delta:
process.env.BOSS_CODEX_APP_SERVER_FIXTURE_STEER === "1"
? `STEERED:${text}`
: `APP_SERVER_STEERED:${text}`,
},
});
send({
method: "turn/completed",
params: {
threadId: message.params?.threadId,
turn: {
id: message.params?.expectedTurnId,
status: "completed",
},
},
});
process.stderr.write(`${JSON.stringify({ received })}\n`);
return;
}
send({
id: message.id,
error: {
code: -32601,
message: `unknown method ${message.method}`,
},
});
});