Skip to content

[Feature] synchronize Claude Code agent definitions during proxy startup #2200

Description

@brunoflma

Area

Service lifecycle

What are you trying to accomplish?

Keep the generated Claude Code agent roster synchronized with the live OpenCodex configuration whenever the proxy daemon starts, including background starts and service restarts.

What prevents this today?

The files ~/.claude/agents/ocx-*.md are derived artifacts from config.json / subagentModels. In the current dev path, injectClaudeAgentDefs() runs at the explicit ocx claude launch and syncClaudeAgentDefsBestEffort() runs after selected Management API mutations. A manual edit to config.json, a Task Scheduler/background service start, or a plain proxy restart does not necessarily execute either hook.

That leaves stale or orphaned definitions loaded by Claude Code even though the live config is already correct. We observed a dead ocx-gemini-3-6-flash.md surviving while config pointed to the replacement model until a supported API mutation forced a sync.

What should OpenCodex do?

During the idempotent proxy startup/ensure routine, reconcile the owned ocx-*.md files from the current config and context-window map. The startup hook should:

  • write definitions for the current enabled subagentModels roster;
  • remove stale files previously owned by OpenCodex;
  • respect claudeCode.enabled and claudeCode.injectAgents disablement;
  • remain best-effort so provider discovery failure does not prevent the proxy from starting;
  • be safe to run repeatedly on every daemon/service start.

Example usage or interface

  1. Edit config.json so subagentModels replaces gpt-5.6-sol with gemini-3.7-flash.
  2. Start or restart the proxy through Task Scheduler / ocx restart.
  3. Before invoking Claude Code, ~/.claude/agents/ocx-gemini-3-7-flash.md should exist and the old ocx-gpt-5-6-sol.md should be gone.
  4. Running the same start again should produce the same files without duplicates or churn.

Alternatives or workarounds

The current workaround is to repeat a supported Management API mutation (for example PUT /api/subagent-models with the already-saved list) or invoke ocx claude before using Claude Code. Both are surprising for a daemon/service workflow and do not repair the roster at the moment a background service becomes healthy.

Additional context

The launch-time injection implementation is in src/claude/agents-inject.ts; current call sites are src/cli/claude.ts, src/server/system-env.ts, and selected management routes. The gap is the absence of an idempotent startup hook in the proxy start/ensure path. The issue was re-verified against the v2.28.0 migration stack (commit c0dcef24) after typecheck and migration-focused tests passed.

Related lifecycle/config synchronization code should be reused rather than adding a second roster format.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requestproxyHTTP proxy, routing, reverse-proxy / management auth

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions