feat: complete Codex App capabilities and rebuild release

This commit is contained in:
shiyue
2026-08-20 13:37:23 +08:00
parent d7dc32e924
commit 19c1601351
8 changed files with 756 additions and 54 deletions

View File

@@ -102,6 +102,7 @@ function ensureThread(threadId, params = {}) {
capacityRetryAttempts: new Map(),
reconnectRetryAttempts: new Map(),
goal: null,
threadStartWebSearchMode: params.config?.web_search || null,
});
}
const thread = threads.get(id);
@@ -537,9 +538,12 @@ function completeTurnWithoutTerminalNotification(thread, turnId, text) {
thread.steers = [];
}
function completeGoalBackgroundTurn(thread, objective) {
function completeGoalBackgroundTurn(thread, objective, turnNumber = 1, totalTurns = 1) {
const turnId = `goal-turn-${crypto.randomUUID()}`;
const text = `Goal background output: ${objective}`;
const itemId = `goal-agent-msg-${turnNumber}`;
const text = turnNumber === 1
? `Goal background output: ${objective}`
: `Goal continuation output ${turnNumber}: ${objective}`;
thread.activeTurnId = turnId;
send({
method: 'turn/started',
@@ -553,7 +557,7 @@ function completeGoalBackgroundTurn(thread, objective) {
params: {
threadId: thread.id,
turnId,
itemId: 'goal-agent-msg',
itemId,
delta: text,
},
});
@@ -564,13 +568,24 @@ function completeGoalBackgroundTurn(thread, objective) {
turnId,
completedAtMs: Date.now(),
item: {
id: 'goal-agent-msg',
id: itemId,
type: 'agentMessage',
text,
status: 'completed',
},
},
});
if (turnNumber >= totalTurns && thread.goal) {
thread.goal = {
...thread.goal,
status: 'complete',
updatedAt: Date.now(),
};
send({
method: 'thread/goal/updated',
params: { threadId: thread.id, goal: thread.goal },
});
}
send({
method: 'thread/tokenUsage/updated',
params: {
@@ -591,6 +606,9 @@ function completeGoalBackgroundTurn(thread, objective) {
},
});
thread.activeTurnId = null;
if (turnNumber < totalTurns) {
setTimeout(() => completeGoalBackgroundTurn(thread, objective, turnNumber + 1, totalTurns), 120);
}
}
function requestClient(method, params, callback) {
@@ -667,6 +685,9 @@ function completeMcpToolTurn(thread, turnId) {
ok: true,
currentConversationId: env.CC_WEB_SOURCE_SESSION_ID || urlSourceSessionId,
sourceHopCount: env.CC_WEB_CROSS_HOP_COUNT || urlSourceHopCount,
threadStartWebSearchMode: thread.threadStartWebSearchMode || null,
threadConfigMethod: thread.lastThreadConfigMethod || null,
webSearchMode: thread.config?.web_search || null,
hasCcwebMcpConfig: Boolean(ccwebConfig),
hasProjectMcpConfig: Boolean(projectConfig),
ccwebType: ccwebConfig?.type || (ccwebConfig?.url ? 'streamable_http' : (ccwebConfig?.command ? 'stdio' : null)),
@@ -1092,19 +1113,42 @@ function handleRequest(message) {
}
if (method === 'thread/start') {
const thread = ensureThread(null, params);
thread.lastThreadConfigMethod = 'thread/start';
send({ id, result: { thread: threadPayload(thread), model: params.model || 'gpt-5.5', cwd: thread.cwd, modelProvider: 'mock', approvalPolicy: params.approvalPolicy || 'never', approvalsReviewer: 'user', sandbox: params.sandbox || 'danger-full-access' } });
return;
}
if (method === 'thread/resume') {
if (params.threadId && resumeMismatchThreads.delete(params.threadId)) {
const thread = ensureThread(null, params);
thread.lastThreadConfigMethod = 'thread/start';
send({ id, result: { thread: threadPayload(thread), model: params.model || 'gpt-5.5', cwd: thread.cwd, modelProvider: 'mock', approvalPolicy: params.approvalPolicy || 'never', approvalsReviewer: 'user', sandbox: params.sandbox || 'danger-full-access' } });
return;
}
const thread = ensureThread(params.threadId, params);
thread.lastThreadConfigMethod = 'thread/resume';
send({ id, result: { thread: threadPayload(thread), model: params.model || 'gpt-5.5', cwd: thread.cwd, modelProvider: 'mock', approvalPolicy: params.approvalPolicy || 'never', approvalsReviewer: 'user', sandbox: params.sandbox || 'danger-full-access' } });
return;
}
if (method === 'thread/compact/start') {
const thread = ensureThread(params.threadId, params);
const compactTurnId = `app-compact-${crypto.randomUUID()}`;
thread.lastCompactionTurnId = compactTurnId;
send({
method: 'thread/compacted',
params: {
threadId: thread.id,
turnId: compactTurnId,
},
});
send({
id,
result: {
threadId: thread.id,
turnId: compactTurnId,
},
});
return;
}
if (method === 'thread/goal/get') {
const thread = ensureThread(params.threadId, params);
send({ id, result: { goal: thread.goal } });
@@ -1130,10 +1174,11 @@ function handleRequest(message) {
params: { threadId: thread.id, goal: thread.goal },
});
setTimeout(() => {
send({ id, result: { goal: thread.goal } });
if (params.objective) {
setTimeout(() => completeGoalBackgroundTurn(thread, objective), 50);
}
send({ id, result: { goal: thread.goal } });
if (params.objective) {
const totalTurns = /improve benchmark coverage/i.test(objective) ? 2 : 1;
setTimeout(() => completeGoalBackgroundTurn(thread, objective, 1, totalTurns), 50);
}
}, 250);
return;
}