Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions .agents/skills/codex-update-compat/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
name: codex-update-compat
description: Upgrade Codex in this repository and resolve compatibility regressions caused by app-server schema/protocol changes. Use when bumping Codex/npm package versions, regenerating `src/app-server` types, fixing TypeScript errors after update, repairing event mappings, and updating tests/snapshots to match new Codex behavior (especially model list, thread/session fields, sandbox policy shape, and tool/event notifications).
---

# Codex Update Compat

Use this workflow to safely upgrade Codex and close update-induced regressions.

## Workflow

1. Inspect update scope before changing code.
Run:
```bash
git log --oneline -n 5
git show --name-only --oneline -n 1
```
Focus first on `package.json`, `package-lock.json`, and generated `src/app-server/**` changes.

2. Run typecheck and tests immediately.
Run:
```bash
npm run typecheck
npm test
```
Treat type errors as the migration guide for required protocol changes.

3. Fix runtime compatibility in source files.
Typical hotspots:
- `src/CodexAcpClient.ts`: thread start/resume params and initialize capabilities
- `src/AgentMode.ts`: sandbox policy shape changes
- `src/CodexEventHandler.ts`: new/changed server notifications
- `src/CodexAcpServer.ts`: history replay for new `ThreadItem` variants
- `src/CodexToolCallMapper.ts`: mapping new tool-like items to ACP events

4. Fix test fixtures and snapshots.
Update typed fixtures for new required fields instead of weakening types.
Then update snapshots only after behavior is intentionally verified.

5. Re-run targeted suites, then full checks.
Run focused tests for touched behavior, then:
```bash
npm run typecheck
npm test
```

## Non-Trivial Changes: Ask Before Finalizing

When migration requires behavior decisions (not only schema fixes), ask the user first. Examples:
- Enabling/disabling experimental flags (`persistExtendedHistory`, `experimentalApi`)
- User-visible messaging changes for new events (e.g., model reroute wording)
- Converting integration tests to mocks or skipping env-dependent tests

## Event Mapping Rule

Do not silently drop new event/item variants if they should be visible to users.
Map them to ACP updates:
- Tool-like operations -> `tool_call` / `tool_call_update`
- Informational reasoning/infra events -> `agent_thought_chunk` (if user-meaningful)
- Internal/noise events -> explicit no-op case (documented in switch)

## References

For common break patterns and ready fixes, read:
- `references/codex-update-playbook.md`
4 changes: 4 additions & 0 deletions .agents/skills/codex-update-compat/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
interface:
display_name: "Codex Update Compat"
short_description: "Upgrade Codex and resolve compatibility"
default_prompt: "Update Codex, run typecheck/tests, and fix app-server compatibility regressions."
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Codex Update Playbook

Use this checklist when Codex version bumps cause compile/test breakage.

## Common Type Breakages

1. New required model fields.
Symptoms:
- `Property 'hidden' is missing in type ...`
Fix:
- Add `hidden: false` (or expected value) in all `Model` fixtures.

2. Thread shape expansion.
Symptoms:
- Missing `status`, `agentNickname`, `agentRole`, `name` in `Thread`.
Fix:
- Add these fields in test fixtures and mocks.

3. Thread item schema changes.
Symptoms:
- `agentMessage` missing `phase`.
Fix:
- Add `phase: null` unless specific phase is required by test.

4. Rate limits payload changes.
Symptoms:
- Missing `limitId` / `limitName` in `RateLimitSnapshot`.
Fix:
- Include `limitId` and `limitName` under `rateLimits` snapshot object.
- If notification wrapper changed, map from new shape in handler.

5. Sandbox policy contract changes.
Symptoms:
- Missing `access` for read-only or `readOnlyAccess` for workspace-write policy.
Fix:
- Provide required nested objects in policy fixtures and runtime mapping.

6. Thread start/resume required flags.
Symptoms:
- Missing `persistExtendedHistory`.
Fix:
- Set explicitly in `threadStart` and `threadResume` params.
- Keep `false` unless user confirms enabling experimental behavior.

## Event Compatibility Patterns

1. New tool-like items/events.
Approach:
- Add mapper function in `CodexToolCallMapper.ts`.
- Emit `tool_call` on start and `tool_call_update` on completion.
- Include meaningful `kind`, `title`, and `rawInput`.

2. Streaming/progressive session events.
Approach:
- Keep stable `toolCallId`.
- First event: `tool_call`, subsequent events: `tool_call_update`.
- Completion event should set `status: completed` or `failed`.

3. Informational infra events (e.g., model reroute).
Approach:
- Emit `agent_thought_chunk` with concise user-readable text.

## Test Strategy

1. Fix types first (`npm run typecheck`).
2. Run focused tests for touched event/file.
3. Update snapshots only after confirming expected behavior.
4. Run full suite at end.

## Known Env-Dependent Failures

Authentication integration tests may fail on CI/local machines due OS keychain restrictions:
- examples: `failed to save api key`, `logout failed`, `Operation not permitted`.
Treat separately from migration regressions.
56 changes: 28 additions & 28 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"license": "ISC",
"type": "module",
"devDependencies": {
"@openai/codex": "^0.99.0",
"@openai/codex": "^0.106.0",
"@types/node": "^24.10.1",
"mcp-hello-world": "^1.1.2",
"tsx": "^4.20.6",
Expand Down
6 changes: 5 additions & 1 deletion src/AgentMode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ export class AgentMode {
"Read-only",
"Requires approval to edit files and run commands.",
"on-request",
{"type": "readOnly"},
{
"type": "readOnly",
"access": {"type": "fullAccess"}
Comment thread
AlexandrSuhinin marked this conversation as resolved.
},
"read-only"
);
static readonly Agent = new AgentMode(
Expand All @@ -34,6 +37,7 @@ export class AgentMode {
{
type: "workspaceWrite",
writableRoots: [],
readOnlyAccess: {"type": "fullAccess"},
networkAccess: false,
excludeTmpdirEnvVar: false,
excludeSlashTmp: false
Expand Down
5 changes: 4 additions & 1 deletion src/CodexAcpClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ export class CodexAcpClient {
modelProvider: this.getModelProvider(),
path: null,
personality: null,
persistExtendedHistory: false,
Comment thread
AlexandrSuhinin marked this conversation as resolved.
threadId: request.sessionId,
});
const codexModels = await this.fetchAvailableModels();
Expand All @@ -217,6 +218,7 @@ export class CodexAcpClient {
modelProvider: this.getModelProvider(),
path: null,
personality: null,
persistExtendedHistory: false,
threadId: request.sessionId,
});
const codexModels = await this.fetchAvailableModels();
Expand All @@ -243,7 +245,8 @@ export class CodexAcpClient {
developerInstructions: null,
personality: null,
ephemeral: null,
experimentalRawEvents: false
experimentalRawEvents: false,
persistExtendedHistory: false
});

const codexModels = await this.fetchAvailableModels();
Expand Down
3 changes: 3 additions & 0 deletions src/CodexAcpServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {logger} from "./Logger";
import {isExtMethodRequest} from "./AcpExtensions";
import {
createCommandExecutionUpdate,
createDynamicToolCallUpdate,
createFileChangeUpdate,
createMcpToolCallUpdate,
} from "./CodexToolCallMapper";
Expand Down Expand Up @@ -401,6 +402,8 @@ export class CodexAcpServer implements acp.Agent {
return [await createCommandExecutionUpdate(item)];
case "mcpToolCall":
return [await createMcpToolCallUpdate(item)];
case "dynamicToolCall":
return [await createDynamicToolCallUpdate(item)];
case "collabAgentToolCall":
return [this.createCollabAgentToolCallUpdate(item)];
case "webSearch":
Expand Down
Loading