chore: rebuild CentOS7 release package

This commit is contained in:
shiyue
2026-06-26 11:17:47 +08:00
parent c387c92e4b
commit 756b9651f9
7 changed files with 1267 additions and 16 deletions

View File

@@ -24,6 +24,7 @@ if (args[0] !== 'app-server') {
const threads = new Map();
const pendingServerRequests = new Map();
const resumeMismatchThreads = new Set();
let nextServerRequestId = 1;
let mcpReloadCount = 0;
@@ -64,6 +65,12 @@ function tokenUsage(text) {
};
}
function retryScenarioKey(text, marker) {
return new RegExp(marker.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'i').test(String(text || ''))
? marker
: String(text || '');
}
function collaborationSummary(params = {}) {
const collaborationMode = params.collaborationMode;
const settings = collaborationMode?.settings || {};
@@ -623,8 +630,9 @@ function startTurn(params) {
}
if (/codexapp capacity retry/i.test(text)) {
const attempts = (thread.capacityRetryAttempts.get(text) || 0) + 1;
thread.capacityRetryAttempts.set(text, attempts);
const retryKey = retryScenarioKey(text, 'codexapp capacity retry');
const attempts = (thread.capacityRetryAttempts.get(retryKey) || 0) + 1;
thread.capacityRetryAttempts.set(retryKey, attempts);
if (attempts <= 2) {
if (attempts === 2) emitPartialCapacityOutput(thread, turnId);
emitCapacityError(thread, turnId);
@@ -633,8 +641,9 @@ function startTurn(params) {
}
if (/codexapp reconnect retry/i.test(text)) {
const attempts = (thread.reconnectRetryAttempts.get(text) || 0) + 1;
thread.reconnectRetryAttempts.set(text, attempts);
const retryKey = retryScenarioKey(text, 'codexapp reconnect retry');
const attempts = (thread.reconnectRetryAttempts.get(retryKey) || 0) + 1;
thread.reconnectRetryAttempts.set(retryKey, attempts);
if (attempts === 1) {
emitPartialCapacityOutput(thread, turnId);
send({
@@ -650,6 +659,17 @@ function startTurn(params) {
}
}
if (/codexapp retry thread mismatch/i.test(text)) {
const retryKey = retryScenarioKey(text, 'codexapp retry thread mismatch');
const attempts = (thread.capacityRetryAttempts.get(retryKey) || 0) + 1;
thread.capacityRetryAttempts.set(retryKey, attempts);
if (attempts === 1) {
resumeMismatchThreads.add(thread.id);
emitCapacityError(thread, turnId);
return { turn: { id: turnId, status: 'running', items: [] } };
}
}
if (/collaboration/i.test(text)) {
completeTurn(thread, turnId, `collaboration mode: ${collaborationSummary(params)}`);
return { turn: { id: turnId, status: 'running', items: [] } };
@@ -787,6 +807,11 @@ function handleRequest(message) {
return;
}
if (method === 'thread/resume') {
if (params.threadId && resumeMismatchThreads.delete(params.threadId)) {
const thread = ensureThread(null, params);
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);
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;

View File

@@ -1311,17 +1311,21 @@ async function main() {
/自动重试/.test(msg.message || '')
), 10000);
assert(/Codex 服务暂时繁忙/.test(codexAppCapacityRetryNotice.message || ''), 'Codex App transient capacity failure should announce automatic retry');
assert(/第 1\/2 次/.test(codexAppCapacityRetryNotice.message || ''), 'Codex App transient retry should start at attempt 1');
assert(/从中断处继续/.test(codexAppCapacityRetryNotice.message || ''), 'Codex App retry after a started turn should announce continuation mode');
const codexAppPartialCapacityRetryNotice = await nextMessage(messages, ws, (msg) => (
msg.type === 'system_message' &&
msg.sessionId === codexAppSession.sessionId &&
/自动重试/.test(msg.message || '')
), 10000);
assert(/第 2\/2 次/.test(codexAppPartialCapacityRetryNotice.message || ''), 'Codex App transient retry should continue after partial output');
assert(/从中断处继续/.test(codexAppPartialCapacityRetryNotice.message || ''), 'Codex App partial-output retry should stay in continuation mode');
await nextMessage(messages, ws, (msg) => msg.type === 'done' && msg.sessionId === codexAppSession.sessionId, 20000);
const storedCodexAppAfterCapacityRetry = JSON.parse(fs.readFileSync(path.join(sessionsDir, `${codexAppSession.sessionId}.json`), 'utf8'));
const codexAppCapacityRetryUsers = storedCodexAppAfterCapacityRetry.messages.filter((message) => message.role === 'user' && message.content === codexAppRetryText);
assert(codexAppCapacityRetryUsers.length === 1, 'Codex App transient retry should not duplicate the user message');
assert(storedCodexAppAfterCapacityRetry.messages.some((message) => message.role === 'assistant' && /codexapp capacity retry prompt/.test(String(message.content || ''))), 'Codex App transient retry should persist the successful assistant response');
assert(storedCodexAppAfterCapacityRetry.messages.some((message) => message.role === 'assistant' && /继续上一轮/.test(String(message.content || ''))), 'Codex App transient retry should ask the model to continue instead of replaying the original prompt');
const codexAppReconnectRetryText = 'codexapp reconnect retry prompt';
ws.send(JSON.stringify({ type: 'message', text: codexAppReconnectRetryText, sessionId: codexAppSession.sessionId, mode: 'yolo', agent: 'codexapp' }));
@@ -1331,11 +1335,40 @@ async function main() {
/自动重试/.test(msg.message || '')
), 10000);
assert(/Codex 服务暂时繁忙/.test(codexAppReconnectRetryNotice.message || ''), 'Codex App reconnect failure should announce automatic retry');
assert(/第 1\/2 次/.test(codexAppReconnectRetryNotice.message || ''), 'Codex App retry counter should reset after the previous retry succeeds');
assert(/从中断处继续/.test(codexAppReconnectRetryNotice.message || ''), 'Codex App reconnect retry after a started turn should announce continuation mode');
await nextMessage(messages, ws, (msg) => msg.type === 'done' && msg.sessionId === codexAppSession.sessionId, 20000);
const storedCodexAppAfterReconnectRetry = JSON.parse(fs.readFileSync(path.join(sessionsDir, `${codexAppSession.sessionId}.json`), 'utf8'));
const codexAppReconnectRetryUsers = storedCodexAppAfterReconnectRetry.messages.filter((message) => message.role === 'user' && message.content === codexAppReconnectRetryText);
assert(codexAppReconnectRetryUsers.length === 1, 'Codex App reconnect retry should not duplicate the user message');
assert(storedCodexAppAfterReconnectRetry.messages.some((message) => message.role === 'assistant' && /codexapp reconnect retry prompt/.test(String(message.content || ''))), 'Codex App reconnect retry should persist the successful assistant response');
assert(storedCodexAppAfterReconnectRetry.messages.some((message) => message.role === 'assistant' && /继续上一轮/.test(String(message.content || ''))), 'Codex App reconnect retry should continue the interrupted turn instead of replaying the original prompt');
const codexAppThreadBeforeMismatch = storedCodexAppAfterReconnectRetry.codexAppThreadId;
assert(codexAppThreadBeforeMismatch, 'Codex App retry mismatch regression needs an existing app-server thread');
const codexAppRetryMismatchText = 'codexapp retry thread mismatch prompt';
ws.send(JSON.stringify({ type: 'message', text: codexAppRetryMismatchText, sessionId: codexAppSession.sessionId, mode: 'yolo', agent: 'codexapp' }));
const codexAppRetryMismatchNotice = await nextMessage(messages, ws, (msg) => (
msg.type === 'system_message' &&
msg.sessionId === codexAppSession.sessionId &&
/自动重试/.test(msg.message || '')
), 10000);
assert(/Codex 服务暂时繁忙/.test(codexAppRetryMismatchNotice.message || ''), 'Codex App thread mismatch retry should first announce automatic retry');
assert(/第 1\/2 次/.test(codexAppRetryMismatchNotice.message || ''), 'Codex App retry counter should reset for the next independent retryable turn');
assert(/从中断处继续/.test(codexAppRetryMismatchNotice.message || ''), 'Codex App thread mismatch retry should also be a continuation retry');
const codexAppRetryMismatchError = await nextMessage(messages, ws, (msg) => (
msg.type === 'error' &&
msg.sessionId === codexAppSession.sessionId &&
/不同线程/.test(msg.message || '') &&
/上下文丢失/.test(msg.message || '')
), 20000);
assert(/已停止/.test(codexAppRetryMismatchError.message || ''), 'Codex App retry should stop when resume returns a different thread');
await nextMessage(messages, ws, (msg) => msg.type === 'done' && msg.sessionId === codexAppSession.sessionId, 20000);
const storedCodexAppAfterRetryMismatch = JSON.parse(fs.readFileSync(path.join(sessionsDir, `${codexAppSession.sessionId}.json`), 'utf8'));
assert(storedCodexAppAfterRetryMismatch.codexAppThreadId === codexAppThreadBeforeMismatch, 'Codex App retry mismatch must not replace the persisted app-server thread id');
const codexAppRetryMismatchUsers = storedCodexAppAfterRetryMismatch.messages.filter((message) => message.role === 'user' && message.content === codexAppRetryMismatchText);
assert(codexAppRetryMismatchUsers.length === 1, 'Codex App retry mismatch should not duplicate the user message');
assert(!storedCodexAppAfterRetryMismatch.messages.some((message) => message.role === 'assistant' && /codexapp retry thread mismatch prompt/.test(String(message.content || ''))), 'Codex App retry mismatch should not persist a successful assistant response on the wrong thread');
ws.send(JSON.stringify({ type: 'message', text: '/goal improve benchmark coverage', sessionId: codexAppSession.sessionId, mode: 'yolo', agent: 'codexapp' }));
const codexAppGoalSet = await nextMessage(messages, ws, (msg) => msg.type === 'system_message' && msg.sessionId === codexAppSession.sessionId && /Goal active/.test(msg.message || '') && /improve benchmark coverage/.test(msg.message || ''));