Merge origin/main into chore/nanoclaw-recursive-room

This commit is contained in:
Eyejoker
2026-03-20 03:48:29 +09:00
37 changed files with 4268 additions and 146 deletions

119
runners/codex-runner/pnpm-lock.yaml generated Normal file
View File

@@ -0,0 +1,119 @@
lockfileVersion: '9.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
importers:
.:
dependencies:
'@openai/codex-sdk':
specifier: ^0.115.0
version: 0.115.0
devDependencies:
'@types/node':
specifier: ^22.10.7
version: 22.19.15
typescript:
specifier: ^5.7.3
version: 5.9.3
packages:
'@openai/codex-sdk@0.115.0':
resolution: {integrity: sha512-BPoPhim0uUm3rzugY7JFaFJ+rPG/wMRhvKNFii//Dp3kTb+gFy3jrip7ijXqhswsnqXM3nwTiv7kYHt1+TMUPg==}
engines: {node: '>=18'}
'@openai/codex@0.115.0':
resolution: {integrity: sha512-uu689DHUzvuPcb39hJ+7fqy++TAvY32w9VggDpcz3HS0Sx0WadWoAPPcMK547P2T6AqfMsAtA8kspkR3tqErOg==}
engines: {node: '>=16'}
hasBin: true
'@openai/codex@0.115.0-darwin-arm64':
resolution: {integrity: sha512-wTWV+YlDTL0y0mL+FMmbzhilm+dPkbIZTe/lH3LwBzcEMhgSGLsPdZLfAiMND4wFE21HS7H0pjMogNQEMLQmqg==}
engines: {node: '>=16'}
cpu: [arm64]
os: [darwin]
'@openai/codex@0.115.0-darwin-x64':
resolution: {integrity: sha512-EPzgymU4CFp83qjv29wXFwhWib3zC8g6SLTJGh2OpcJiOYyLY0bO53FB+QchL1jC9gm1uLyD5j5F3ddI0AbjIg==}
engines: {node: '>=16'}
cpu: [x64]
os: [darwin]
'@openai/codex@0.115.0-linux-arm64':
resolution: {integrity: sha512-40+SCyI+LvVx/iX30qH7dTQzWt9MZxDaK2E6YRB4hoYej5UALrhkFNzweHa5uvqvhmqGZCuagZOYB8285eGCgw==}
engines: {node: '>=16'}
cpu: [arm64]
os: [linux]
'@openai/codex@0.115.0-linux-x64':
resolution: {integrity: sha512-+6eRd2p4KMrhQvuF7XpjYIdCA2Ok2LbhOq+ywZdLpHbmwQ/Yynd0gJ/Q90xCeo2vloCwl9WsbsiVVSahG5FyWg==}
engines: {node: '>=16'}
cpu: [x64]
os: [linux]
'@openai/codex@0.115.0-win32-arm64':
resolution: {integrity: sha512-yaYhQ0kPL9Kithmrr1vh5A4c+gqAMhMZeA/htTtkpWW8RQkmwgcYYpX/Ky2cEzu0w51pvxQQy63LgHftc+pg1Q==}
engines: {node: '>=16'}
cpu: [arm64]
os: [win32]
'@openai/codex@0.115.0-win32-x64':
resolution: {integrity: sha512-wtYf2HJCB+p+Uj7o1W08fRgZMzKCVGRQ4YdSfLRNfF4wwPqX5XsK9blsv7brukn5J9lclYxagiR6qGvbfHbD7w==}
engines: {node: '>=16'}
cpu: [x64]
os: [win32]
'@types/node@22.19.15':
resolution: {integrity: sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg==}
typescript@5.9.3:
resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
engines: {node: '>=14.17'}
hasBin: true
undici-types@6.21.0:
resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
snapshots:
'@openai/codex-sdk@0.115.0':
dependencies:
'@openai/codex': 0.115.0
'@openai/codex@0.115.0':
optionalDependencies:
'@openai/codex-darwin-arm64': '@openai/codex@0.115.0-darwin-arm64'
'@openai/codex-darwin-x64': '@openai/codex@0.115.0-darwin-x64'
'@openai/codex-linux-arm64': '@openai/codex@0.115.0-linux-arm64'
'@openai/codex-linux-x64': '@openai/codex@0.115.0-linux-x64'
'@openai/codex-win32-arm64': '@openai/codex@0.115.0-win32-arm64'
'@openai/codex-win32-x64': '@openai/codex@0.115.0-win32-x64'
'@openai/codex@0.115.0-darwin-arm64':
optional: true
'@openai/codex@0.115.0-darwin-x64':
optional: true
'@openai/codex@0.115.0-linux-arm64':
optional: true
'@openai/codex@0.115.0-linux-x64':
optional: true
'@openai/codex@0.115.0-win32-arm64':
optional: true
'@openai/codex@0.115.0-win32-x64':
optional: true
'@types/node@22.19.15':
dependencies:
undici-types: 6.21.0
typescript@5.9.3: {}
undici-types@6.21.0: {}

View File

@@ -170,5 +170,5 @@ export function isAppServerTurnFinished(state: AppServerTurnState): boolean {
export function getAppServerTurnResult(
state: AppServerTurnState,
): string | null {
return state.finalAnswer || state.latestAgentMessage;
return state.finalAnswer;
}

View File

@@ -0,0 +1,83 @@
import { describe, expect, it } from 'vitest';
import {
createInitialAppServerTurnState,
getAppServerTurnResult,
reduceAppServerTurnState,
} from '../src/app-server-state.js';
describe('codex app-server turn state', () => {
it('prefers final_answer over commentary when building final output', () => {
let state = createInitialAppServerTurnState();
state = reduceAppServerTurnState(state, {
method: 'item/completed',
params: {
item: {
type: 'agentMessage',
phase: 'commentary',
text: '중간 설명입니다.',
},
},
});
state = reduceAppServerTurnState(state, {
method: 'item/completed',
params: {
item: {
type: 'agentMessage',
phase: 'final_answer',
text: '최종 답변입니다.',
},
},
});
expect(getAppServerTurnResult(state)).toBe('최종 답변입니다.');
});
it('does not treat commentary-only messages as a final output', () => {
const state = reduceAppServerTurnState(createInitialAppServerTurnState(), {
method: 'item/completed',
params: {
item: {
type: 'agentMessage',
phase: 'commentary',
text: '작업 중 상태입니다.',
},
},
});
expect(state.latestAgentMessage).toBe('작업 중 상태입니다.');
expect(getAppServerTurnResult(state)).toBeNull();
});
it('records compaction completion from contextCompaction items', () => {
const state = reduceAppServerTurnState(createInitialAppServerTurnState(), {
method: 'item/completed',
params: {
item: {
type: 'contextCompaction',
id: 'ctx_1',
},
},
});
expect(state.compactionCompleted).toBe(true);
});
it('captures upstream HTTP status from app-server error events', () => {
const state = reduceAppServerTurnState(createInitialAppServerTurnState(), {
method: 'error',
params: {
error: {
message: 'Too many requests',
codexErrorInfo: {
httpStatusCode: 429,
},
},
},
});
expect(state.errorMessage).toBe('Too many requests (HTTP 429)');
});
});