fix(codex): preserve context config in remote sessions (#1633)

This commit is contained in:
NightWatcher314
2026-09-06 14:19:44 +08:00
committed by GitHub
parent b85c72f09f
commit 97b1dd4c34
6 changed files with 141 additions and 6 deletions
+52
View File
@@ -8,6 +8,9 @@ const harness = vi.hoisted(() => ({
registerRequestCalls: [] as string[],
requestHandlers: new Map<string, (params: unknown) => Promise<unknown> | unknown>(),
initializeCalls: [] as unknown[],
configReadCalls: [] as unknown[],
configReadResponse: { config: {} } as { config: Record<string, unknown> },
failConfigRead: false,
setFeatureEnablementCalls: [] as unknown[],
failSetFeatureEnablement: false,
listCollaborationModeCalls: 0,
@@ -116,6 +119,14 @@ vi.mock('./codexAppServerClient', () => {
return { protocolVersion: 1 };
}
async readConfig(params: unknown): Promise<{ config: Record<string, unknown> }> {
harness.configReadCalls.push(params);
if (harness.failConfigRead) {
throw new Error('config/read unsupported');
}
return harness.configReadResponse;
}
setNotificationHandler(handler: ((method: string, params: unknown) => void) | null): void {
this.notificationHandler = handler;
harness.dispatchNotification = handler;
@@ -1393,6 +1404,9 @@ describe('codexRemoteLauncher', () => {
harness.registerRequestCalls = [];
harness.requestHandlers = new Map();
harness.initializeCalls = [];
harness.configReadCalls = [];
harness.configReadResponse = { config: {} };
harness.failConfigRead = false;
harness.setFeatureEnablementCalls = [];
harness.failSetFeatureEnablement = false;
harness.listCollaborationModeCalls = 0;
@@ -1505,6 +1519,10 @@ describe('codexRemoteLauncher', () => {
experimentalApi: true
}
}]);
expect(harness.configReadCalls).toEqual([{
cwd: '/tmp/hapi-update',
includeLayers: false
}]);
expect(harness.setFeatureEnablementCalls).toEqual([{ enablement: { goals: true } }]);
expect(harness.notifications.map((entry) => entry.method)).toEqual([
'turn/started',
@@ -1517,6 +1535,40 @@ describe('codexRemoteLauncher', () => {
expect(session.thinking).toBe(false);
});
it('forwards effective Codex context settings for fresh and resumed threads', async () => {
harness.configReadResponse = {
config: {
model_context_window: 400_000,
model_auto_compact_token_limit: 300_000
}
};
const fresh = createSessionStub();
await codexRemoteLauncher(fresh.session as never);
expect(harness.startThreadParams[0]?.config).toMatchObject({
model_context_window: 400_000,
model_auto_compact_token_limit: 300_000
});
harness.startThreadParams = [];
const resumed = createSessionStub();
resumed.session.sessionId = 'thread-existing';
await codexRemoteLauncher(resumed.session as never);
expect(harness.resumeThreadParams[0]?.config).toMatchObject({
model_context_window: 400_000,
model_auto_compact_token_limit: 300_000
});
});
it('keeps remote sessions working when config/read is unavailable', async () => {
harness.failConfigRead = true;
const { session } = createSessionStub();
await expect(codexRemoteLauncher(session as never)).resolves.toBe('exit');
expect(harness.startThreadParams[0]?.config).not.toHaveProperty('model_context_window');
expect(harness.startThreadParams[0]?.config).not.toHaveProperty('model_auto_compact_token_limit');
});
it('uses the native skill catalog for completion and structured turn input', async () => {
const { session, rpcHandlers } = createSessionStub(['$hapi inspect']);