From f97be048b3df86ead99ce150ba2c3306a622ceee Mon Sep 17 00:00:00 2001 From: akazwz <50396286+akazwz@users.noreply.github.com> Date: Sun, 30 Aug 2026 14:23:03 -0700 Subject: [PATCH 1/2] refactor(agent): split codex and claude code runtimes from acp --- .github/workflows/docker.yml | 6 +- AGENTS.md | 11 +- .../src/components/session-select/options.ts | 14 +- .../src/components/sidebar/session-item.vue | 27 +- .../src/composables/api/useChat.chat-api.ts | 2 - apps/web/src/composables/api/useChat.types.ts | 11 +- apps/web/src/composables/useACPOAuth.ts | 409 - .../web/src/composables/useACPRuntime.test.ts | 10 +- apps/web/src/composables/useACPRuntime.ts | 2 +- .../src/composables/useAgentModelCatalog.ts | 198 + .../web/src/composables/useOnboarding.test.ts | 18 +- apps/web/src/composables/useOnboarding.ts | 10 +- apps/web/src/i18n/locales/en.json | 123 +- apps/web/src/i18n/locales/ja.json | 123 +- apps/web/src/i18n/locales/zh.json | 123 +- .../bots/components/acp-managed-fields.vue | 114 +- .../pages/bots/components/acp-setup-panel.vue | 13 +- .../bots/components/add-bot-agent-dialog.vue | 56 +- .../pages/bots/components/agent-type-pill.vue | 6 +- .../pages/bots/components/agent-type.test.ts | 35 +- .../src/pages/bots/components/agent-type.ts | 19 +- .../{bot-acp.vue => bot-agents.vue} | 269 +- .../pages/bots/components/bot-overview.vue | 2 +- .../pages/bots/components/bot-settings.vue | 3 +- .../pages/bots/components/schedule-editor.vue | 6 +- .../components/schedule-execution-fields.vue | 71 +- .../bots/components/settings-acp-detail.vue | 525 +- .../settings-direct-agent-detail.vue | 422 + .../settings-interaction-card.test.ts | 46 +- .../components/settings-interaction-card.vue | 18 +- apps/web/src/pages/bots/detail.vue | 12 +- apps/web/src/pages/bots/new.test.ts | 36 - apps/web/src/pages/bots/new.vue | 46 +- .../home/components/chat-pane-send.test.ts | 4 - .../pages/home/components/chat-pane-send.ts | 8 +- .../src/pages/home/components/chat-pane.vue | 463 +- .../pages/home/components/composer-dock.vue | 23 +- .../pages/home/components/message-item.vue | 14 +- .../tool-call-detail-apply-patch.vue | 24 +- .../home/components/tool-call-registry.ts | 54 +- apps/web/src/pages/home/index.vue | 31 +- apps/web/src/pages/onboarding/session.test.ts | 41 +- apps/web/src/pages/onboarding/session.ts | 47 +- .../src/pages/onboarding/steps/Step4Bot.vue | 372 +- .../pages/onboarding/steps/Step5Complete.vue | 2 +- .../web/src/store/bot-create-progress.test.ts | 32 +- apps/web/src/store/bot-create-progress.ts | 26 +- apps/web/src/store/chat-list.test.ts | 629 +- apps/web/src/store/chat-list.ts | 74 +- apps/web/src/store/chat-list.utils.ts | 8 +- apps/web/src/store/chat-selection.ts | 2 +- apps/web/src/store/chat/acp-defaults.test.ts | 51 - .../store/chat/acp-runtime-registry.test.ts | 2 +- .../src/store/chat/acp-runtime-registry.ts | 4 +- apps/web/src/store/chat/bootstrap.ts | 38 +- apps/web/src/store/chat/commands.ts | 23 +- ...roller.ts => external-agent-controller.ts} | 62 +- ...defaults.ts => external-agent-defaults.ts} | 51 +- ...ion.ts => external-agent-orchestration.ts} | 120 +- ...sessions.ts => external-agent-sessions.ts} | 103 +- ...p-staging.ts => external-agent-staging.ts} | 244 +- apps/web/src/store/chat/send.ts | 12 +- apps/web/src/store/chat/targets.ts | 29 +- apps/web/src/store/chat/types.ts | 24 +- apps/web/src/store/chat/views.ts | 18 +- apps/web/src/store/workdirs.ts | 6 +- apps/web/src/store/workspace-tabs.test.ts | 53 +- apps/web/src/store/workspace-tabs.ts | 14 +- apps/web/src/utils/acp-slash-commands.ts | 4 +- apps/web/src/utils/acp/agent-icon.test.ts | 22 - apps/web/src/utils/acp/agent-icon.ts | 12 +- apps/web/src/utils/acp/hermes.test.ts | 73 - apps/web/src/utils/acp/hermes.ts | 121 - apps/web/src/utils/acp/index.ts | 3 +- apps/web/src/utils/acp/metadata.test.ts | 136 +- apps/web/src/utils/acp/metadata.ts | 90 - apps/web/src/utils/acp/setup-fields.test.ts | 20 - apps/web/src/utils/acp/setup-fields.ts | 52 +- apps/web/src/utils/api-error.test.ts | 6 +- apps/web/src/utils/bot-agent.ts | 114 +- cmd/agent/http_providers.go | 48 +- cmd/agent/module.go | 3 +- cmd/gen-codex-protocol/main.go | 66 + cmd/internal/core/module.go | 6 +- cmd/internal/core/providers.go | 90 +- db/postgres/migrations/0001_init.down.sql | 6 +- db/postgres/migrations/0001_init.up.sql | 100 +- .../0144_external_agent_runtimes.down.sql | 100 + .../0144_external_agent_runtimes.up.sql | 301 + .../0145_agent_session_state.down.sql | 65 + .../0145_agent_session_state.up.sql | 115 + .../0146_agent_turn_markers.down.sql | 23 + .../migrations/0146_agent_turn_markers.up.sql | 30 + db/postgres/queries/agent_credentials.sql | 6 +- ...sion_state.sql => agent_session_state.sql} | 114 +- db/postgres/queries/bot_agents.sql | 4 + db/postgres/queries/messages.sql | 61 +- db/postgres/queries/sessions.sql | 35 +- db/postgres/queries/tool_approval.sql | 7 +- db/postgres/queries/user_input.sql | 7 +- docker/Dockerfile.workspace | 4 +- docker/toolkit/bin/claude | 34 + docker/toolkit/bin/claude-agent-acp | 27 - docker/toolkit/bin/codex | 2 +- docker/toolkit/bin/codex-acp | 27 - docker/toolkit/bin/hermes-acp | 51 - docker/toolkit/install.sh | 97 +- docker/workspace-contract.json | 2 +- eslint.config.mjs | 4 +- internal/agent/adapter/acpprofile/catalog.go | 3 + .../agent/adapter/acpprofile/catalog_test.go | 29 +- .../agent/adapter/acpsession/source_test.go | 39 - .../{acpsession => agentsession}/source.go | 7 +- .../{acpsession => agentsession}/state.go | 334 +- .../state_postgres_integration_test.go | 90 +- .../application/requested_skills_test.go | 1 + .../application/resolver_acp_contextview.go | 93 - .../resolver_runtime_contextview.go | 93 + ...o => resolver_runtime_contextview_test.go} | 60 +- .../application/runtime_alignment_test.go | 12 +- .../{acp_context.go => runtime_context.go} | 156 +- ...ontext_test.go => runtime_context_test.go} | 102 +- .../agent/application/runtime_decision.go | 49 +- internal/agent/application/service.go | 82 +- internal/agent/application/service_acp.go | 1423 - .../service_acp_active_prompt_test.go | 124 - .../agent/application/service_acp_mode.go | 4 +- .../agent/application/service_acp_test.go | 215 +- ...> service_external_agent_active_prompt.go} | 117 +- .../application/service_external_fork.go | 107 + .../application/service_run_lifecycle_test.go | 2 + .../application/service_runtime_abort.go | 3 +- .../application/service_runtime_abort_test.go | 14 +- .../application/service_runtime_support.go | 641 + .../agent/application/service_runtime_turn.go | 995 + .../service_session_workdir_test.go | 4 + internal/agent/application/service_store.go | 24 +- internal/agent/application/service_stream.go | 34 +- .../agent/application/service_stream_test.go | 5 +- internal/agent/application/service_test.go | 32 +- internal/agent/application/service_title.go | 1 + .../application/service_tool_approval.go | 51 +- internal/agent/application/service_trigger.go | 147 +- .../service_trigger_lifecycle_test.go | 13 +- .../agent/application/service_trigger_test.go | 2 + .../agent/application/service_user_input.go | 73 +- .../application/service_user_input_test.go | 15 +- .../application/service_workspace_target.go | 6 +- .../agent/application/session_service_test.go | 12 +- internal/agent/application/tool_closure.go | 38 +- .../agent/application/tool_closure_test.go | 26 + internal/agent/application/turn_admission.go | 5 + .../agent/application/turn_admission_test.go | 2 + internal/agent/application/turn_discuss.go | 17 +- .../application/turn_inject_ownership_test.go | 2 + .../agent/application/turn_service_test.go | 2 + internal/agent/context/fragment/types.go | 4 +- internal/agent/context/fragment/view.go | 6 +- internal/agent/decision/approval/policy.go | 2 +- internal/agent/decision/feedback/feedback.go | 2 +- internal/agent/decision/input/elicitation.go | 585 + internal/agent/decision/input/service.go | 30 +- internal/agent/decision/input/service_test.go | 27 +- internal/agent/decision/input/types.go | 10 +- internal/agent/event/event.go | 4 + internal/agent/runtime/acp/AGENTS.md | 164 +- internal/agent/runtime/acp/client/client.go | 7 +- .../agent/runtime/acp/client/client_test.go | 299 +- .../agent/runtime/acp/client/codex_config.go | 423 - .../acp/client/codex_container_live_test.go | 346 - .../agent/runtime/acp/client/connection.go | 14 - .../agent/runtime/acp/client/elicitation.go | 697 +- .../runtime/acp/client/elicitation_test.go | 158 - .../agent/runtime/acp/client/events_test.go | 2 +- .../agent/runtime/acp/client/hermes_config.go | 221 - .../runtime/acp/client/hermes_config_test.go | 181 - .../runtime/acp/client/managed_config.go | 85 - .../runtime/acp/client/model_selector.go | 11 +- .../runtime/acp/client/model_selector_test.go | 34 +- .../agent/runtime/acp/client/output_limit.go | 12 +- internal/agent/runtime/acp/client/process.go | 147 +- .../agent/runtime/acp/client/process_test.go | 457 +- .../agent/runtime/acp/client/runtime_state.go | 581 +- .../runtime/acp/client/runtime_state_test.go | 516 +- internal/agent/runtime/acp/client/session.go | 248 +- .../runtime/acp/client/session_capture.go | 291 - .../acp/client/session_capture_limit_test.go | 105 - .../runtime/acp/client/session_context.go | 64 - .../acp/client/session_context_test.go | 35 +- .../runtime/acp/client/session_format.go | 239 - .../runtime/acp/client/session_receipt.go | 270 - .../runtime/acp/client/session_restore.go | 227 - .../agent/runtime/acp/client/session_spool.go | 767 - .../client/session_spool_lifecycle_test.go | 91 - .../agent/runtime/acp/client/session_state.go | 150 - .../acp/client/session_state_spool_test.go | 42 - internal/agent/runtime/acp/client/terminal.go | 5 +- .../agent/runtime/acp/client/terminal_test.go | 4 +- .../agent/runtime/acp/client/transcript.go | 332 +- internal/agent/runtime/acp/driver.go | 203 + internal/agent/runtime/acp/profile/profile.go | 450 +- .../agent/runtime/acp/profile/profile_test.go | 175 +- .../runtime/acp/profile/runtime_storage.go | 341 +- internal/agent/runtime/acp/session_pool.go | 731 +- .../agent/runtime/acp/sessionpool_test.go | 685 +- .../agent/runtime/agentprocess/process.go | 141 + .../session_state.go => agentstate/state.go} | 56 +- .../agent/runtime/claudecode/checkpoint.go | 399 + .../runtime/claudecode/checkpoint_test.go | 442 + .../runtime/claudecode/claudecfg/config.go | 55 + internal/agent/runtime/claudecode/driver.go | 486 + internal/agent/runtime/claudecode/process.go | 38 + internal/agent/runtime/claudecode/protocol.go | 236 + .../claudecode/protocolref/VERSION.json | 6 + internal/agent/runtime/claudecode/tools.go | 81 + internal/agent/runtime/claudecode/turn.go | 538 + .../agent/runtime/claudecode/turn_test.go | 244 + internal/agent/runtime/codex/appserver.go | 421 + internal/agent/runtime/codex/auth.go | 108 + .../agent/runtime/codex/codexcfg/config.go | 51 + internal/agent/runtime/codex/config.go | 57 + internal/agent/runtime/codex/conn.go | 255 + internal/agent/runtime/codex/driver.go | 719 + internal/agent/runtime/codex/elicitation.go | 360 + internal/agent/runtime/codex/lifecycle.go | 227 + .../agent/runtime/codex/lifecycle_test.go | 230 + internal/agent/runtime/codex/process.go | 33 + .../runtime/codex/protocol/methods.gen.go | 238 + .../agent/runtime/codex/protocol/protocol.go | 253 + .../runtime/codex/protocol/roundtrip_test.go | 401 + .../agent/runtime/codex/protocol/types.gen.go | 1638 ++ .../runtime/codex/protocol/unions.gen.go | 2001 ++ .../agent/runtime/codex/protocolgen/emit.go | 302 + .../runtime/codex/protocolgen/emit_methods.go | 77 + .../runtime/codex/protocolgen/emit_unions.go | 148 + .../runtime/codex/protocolgen/generate.go | 113 + .../agent/runtime/codex/protocolgen/naming.go | 86 + .../runtime/codex/protocolgen/resolve.go | 320 + .../agent/runtime/codex/protocolgen/schema.go | 282 + .../ChatgptAuthTokensRefreshResponse.json | 23 + .../schema/ClientNotification.json | 22 + ...mmandExecutionRequestApprovalResponse.json | 116 + .../FileChangeRequestApprovalResponse.json | 47 + .../McpServerElicitationRequestResponse.json | 29 + .../PermissionsRequestApprovalResponse.json | 322 + .../protocolgen/schema/ServerRequest.json | 2079 ++ .../schema/ToolRequestUserInputResponse.json | 34 + .../codex/protocolgen/schema/VERSION.json | 16 + .../codex_app_server_protocol.v2.schemas.json | 22847 ++++++++++++++++ .../agent/runtime/codex/protocolgen/subset.go | 82 + internal/agent/runtime/codex/tools.go | 155 + internal/agent/runtime/codex/turn.go | 717 + internal/agent/runtime/codex/userinput.go | 179 + internal/agent/runtime/external/credential.go | 23 + internal/agent/runtime/external/external.go | 291 + internal/agent/runtime/external/transcript.go | 345 + internal/agent/runtime/session/commands.go | 8 +- .../runtime/session/decision_route_test.go | 7 +- internal/agent/runtime/session/fence.go | 15 +- internal/agent/runtime/session/manager.go | 195 +- internal/agent/runtime/session/recovery.go | 40 +- .../agent/runtime/session/recovery_test.go | 85 +- internal/agent/runtime/session/state.go | 12 + internal/agent/runtime/session/types.go | 11 +- internal/agent/runtime/toolmount/toolmount.go | 132 + internal/agent/tool/acp_agents.go | 9 +- internal/agent/tool/ask_user.go | 9 +- internal/agent/tool/schedule.go | 4 +- internal/agent/tool/usage_test.go | 10 +- internal/agent/turn/grpctransport/feedback.go | 24 +- .../turn/grpctransport/transport_test.go | 14 +- internal/agent/view/uimessage.go | 5 + internal/agent/view/uimessage_adapter.go | 1 + internal/agent/view/uimessage_stream.go | 14 + internal/agent/view/uimessage_test.go | 8 + internal/agentcredential/service.go | 78 +- .../service_postgres_integration_test.go | 4 +- internal/agentcredential/service_test.go | 3 +- internal/agentcredential/types.go | 15 +- internal/apperror/error.go | 156 +- internal/arch/arch_test.go | 14 + internal/botagents/service.go | 282 +- internal/botagents/service_test.go | 80 +- internal/botagents/types.go | 17 +- internal/botbackup/import.go | 6 +- internal/botbackup/service.go | 20 +- internal/botbackup/service_test.go | 12 +- internal/bots/acp_metadata_test.go | 8 +- internal/channel/inbound/channel.go | 212 +- internal/channel/inbound/channel_test.go | 8 +- .../channel/inbound/new_confirmation_test.go | 135 +- internal/channel/inbound/result_render.go | 4 +- internal/chat/message/service.go | 52 +- internal/chat/message/service_test.go | 6 +- internal/chat/message/types.go | 17 +- internal/chat/thread/service.go | 225 +- internal/chat/thread/service_test.go | 38 +- internal/command/result.go | 4 +- ...{collector_acp.go => collector_runtime.go} | 50 +- .../{render_acp.go => render_runtime.go} | 48 +- ...der_acp_test.go => render_runtime_test.go} | 86 +- internal/contextview/selector.go | 2 +- ...r_acp_test.go => selector_runtime_test.go} | 26 +- ...ession_state_migration_integration_test.go | 146 - ...ession_state_migration_integration_test.go | 187 + .../bot_agents_migration_integration_test.go | 133 + ...ion_artifact_migration_integration_test.go | 25 +- .../db/postgres/sqlc/agent_credentials.sql.go | 22 +- ...tate.sql.go => agent_session_state.sql.go} | 490 +- internal/db/postgres/sqlc/bot_agents.sql.go | 22 +- internal/db/postgres/sqlc/messages.sql.go | 96 +- internal/db/postgres/sqlc/models.go | 33 + internal/db/postgres/sqlc/sessions.sql.go | 98 +- .../db/postgres/sqlc/tool_approval.sql.go | 122 +- internal/db/postgres/sqlc/user_input.sql.go | 134 +- ...un_finishing_migration_integration_test.go | 3 + internal/db/store/queries.go | 43 +- internal/db/team_migrate_integration_test.go | 36 + internal/handlers/acp.go | 16 +- internal/handlers/acp_claude_code_oauth.go | 519 - .../handlers/acp_claude_code_oauth_test.go | 151 - internal/handlers/acp_codex_device_oauth.go | 536 - internal/handlers/acp_codex_oauth.go | 459 - internal/handlers/acp_codex_oauth_test.go | 892 - internal/handlers/acp_feedback.go | 163 - internal/handlers/acp_feedback_test.go | 50 - internal/handlers/acp_runtime.go | 29 +- internal/handlers/acp_runtime_test.go | 70 +- internal/handlers/acp_test.go | 22 +- internal/handlers/agent_credentials.go | 43 +- internal/handlers/bot_agents.go | 69 +- internal/handlers/bot_response_test.go | 12 +- internal/handlers/external_agent_codex.go | 184 + internal/handlers/external_agent_feedback.go | 146 + internal/handlers/local_channel.go | 24 +- internal/handlers/message.go | 12 +- internal/handlers/provider_oauth.go | 10 +- internal/handlers/session.go | 299 +- internal/handlers/session_create_test.go | 71 +- internal/handlers/session_delete_test.go | 2 +- internal/handlers/session_update_test.go | 64 +- internal/handlers/users.go | 221 +- internal/handlers/users_acp_config_test.go | 507 - .../handlers/users_create_bot_stream_test.go | 87 +- internal/i18n/locales/en.json | 2 +- internal/i18n/locales/ja.json | 2 +- internal/i18n/locales/zh.json | 2 +- internal/mcp/http_tools.go | 7 + internal/mcp/http_tools_test.go | 27 + internal/runtimefence/activator.go | 4 +- internal/runtimefence/fence.go | 5 +- internal/runtimefence/postgres.go | 43 +- .../runtimefence/postgres_integration_test.go | 2 +- internal/runtimefence/postgres_test.go | 18 +- internal/runtimekind/runtimekind.go | 186 + internal/schedule/execution.go | 99 +- internal/schedule/execution_test.go | 42 +- internal/schedule/service.go | 21 +- internal/schedule/types.go | 15 +- ...t_concurrency_postgres_integration_test.go | 4 +- internal/settings/service.go | 92 +- internal/settings/service_test.go | 34 +- internal/settings/types.go | 8 +- internal/toolcontext/context.go | 19 +- internal/workspace/bridgesvc/env_test.go | 14 +- internal/workspace/bridgesvc/reverse_http.go | 11 +- internal/workspace/contract.go | 13 +- internal/workspace/dataio.go | 53 +- internal/workspace/dataio_test.go | 73 +- mise.toml | 8 + packages/icons/icons/hermes-agent.svg | 1 - packages/icons/scripts/manifest.ts | 1 - packages/icons/src/icons/HermesAgent.vue | 25 - packages/icons/src/index.ts | 1 - packages/sdk/src/@pinia/colada.gen.ts | 181 +- packages/sdk/src/index.ts | 4 +- packages/sdk/src/sdk.gen.ts | 99 +- packages/sdk/src/types.gen.ts | 569 +- scripts/codex-schema-sync.sh | 52 + scripts/ui-alpha-baseline.json | 1 - scripts/ui-app-baseline.json | 1 - spec/docs.go | 802 +- spec/swagger.json | 802 +- spec/swagger.yaml | 573 +- 384 files changed, 50785 insertions(+), 23327 deletions(-) delete mode 100644 apps/web/src/composables/useACPOAuth.ts create mode 100644 apps/web/src/composables/useAgentModelCatalog.ts rename apps/web/src/pages/bots/components/{bot-acp.vue => bot-agents.vue} (68%) create mode 100644 apps/web/src/pages/bots/components/settings-direct-agent-detail.vue delete mode 100644 apps/web/src/store/chat/acp-defaults.test.ts rename apps/web/src/store/chat/{acp-controller.ts => external-agent-controller.ts} (76%) rename apps/web/src/store/chat/{acp-defaults.ts => external-agent-defaults.ts} (61%) rename apps/web/src/store/chat/{acp-orchestration.ts => external-agent-orchestration.ts} (66%) rename apps/web/src/store/chat/{acp-sessions.ts => external-agent-sessions.ts} (72%) rename apps/web/src/store/chat/{acp-staging.ts => external-agent-staging.ts} (59%) delete mode 100644 apps/web/src/utils/acp/agent-icon.test.ts delete mode 100644 apps/web/src/utils/acp/hermes.test.ts delete mode 100644 apps/web/src/utils/acp/hermes.ts create mode 100644 cmd/gen-codex-protocol/main.go create mode 100644 db/postgres/migrations/0144_external_agent_runtimes.down.sql create mode 100644 db/postgres/migrations/0144_external_agent_runtimes.up.sql create mode 100644 db/postgres/migrations/0145_agent_session_state.down.sql create mode 100644 db/postgres/migrations/0145_agent_session_state.up.sql create mode 100644 db/postgres/migrations/0146_agent_turn_markers.down.sql create mode 100644 db/postgres/migrations/0146_agent_turn_markers.up.sql rename db/postgres/queries/{acp_session_state.sql => agent_session_state.sql} (83%) create mode 100755 docker/toolkit/bin/claude delete mode 100755 docker/toolkit/bin/claude-agent-acp delete mode 100755 docker/toolkit/bin/codex-acp delete mode 100755 docker/toolkit/bin/hermes-acp delete mode 100644 internal/agent/adapter/acpsession/source_test.go rename internal/agent/adapter/{acpsession => agentsession}/source.go (83%) rename internal/agent/adapter/{acpsession => agentsession}/state.go (68%) rename internal/agent/adapter/{acpsession => agentsession}/state_postgres_integration_test.go (88%) delete mode 100644 internal/agent/application/resolver_acp_contextview.go create mode 100644 internal/agent/application/resolver_runtime_contextview.go rename internal/agent/application/{resolver_acp_contextview_test.go => resolver_runtime_contextview_test.go} (58%) rename internal/agent/application/{acp_context.go => runtime_context.go} (64%) rename internal/agent/application/{acp_context_test.go => runtime_context_test.go} (75%) delete mode 100644 internal/agent/application/service_acp.go delete mode 100644 internal/agent/application/service_acp_active_prompt_test.go rename internal/agent/application/{service_acp_active_prompt.go => service_external_agent_active_prompt.go} (59%) create mode 100644 internal/agent/application/service_external_fork.go create mode 100644 internal/agent/application/service_runtime_support.go create mode 100644 internal/agent/application/service_runtime_turn.go create mode 100644 internal/agent/decision/input/elicitation.go delete mode 100644 internal/agent/runtime/acp/client/codex_config.go delete mode 100644 internal/agent/runtime/acp/client/codex_container_live_test.go delete mode 100644 internal/agent/runtime/acp/client/elicitation_test.go delete mode 100644 internal/agent/runtime/acp/client/hermes_config.go delete mode 100644 internal/agent/runtime/acp/client/hermes_config_test.go delete mode 100644 internal/agent/runtime/acp/client/session_capture.go delete mode 100644 internal/agent/runtime/acp/client/session_capture_limit_test.go delete mode 100644 internal/agent/runtime/acp/client/session_format.go delete mode 100644 internal/agent/runtime/acp/client/session_receipt.go delete mode 100644 internal/agent/runtime/acp/client/session_restore.go delete mode 100644 internal/agent/runtime/acp/client/session_spool.go delete mode 100644 internal/agent/runtime/acp/client/session_spool_lifecycle_test.go delete mode 100644 internal/agent/runtime/acp/client/session_state.go delete mode 100644 internal/agent/runtime/acp/client/session_state_spool_test.go create mode 100644 internal/agent/runtime/acp/driver.go create mode 100644 internal/agent/runtime/agentprocess/process.go rename internal/agent/runtime/{acp/session_state.go => agentstate/state.go} (72%) create mode 100644 internal/agent/runtime/claudecode/checkpoint.go create mode 100644 internal/agent/runtime/claudecode/checkpoint_test.go create mode 100644 internal/agent/runtime/claudecode/claudecfg/config.go create mode 100644 internal/agent/runtime/claudecode/driver.go create mode 100644 internal/agent/runtime/claudecode/process.go create mode 100644 internal/agent/runtime/claudecode/protocol.go create mode 100644 internal/agent/runtime/claudecode/protocolref/VERSION.json create mode 100644 internal/agent/runtime/claudecode/tools.go create mode 100644 internal/agent/runtime/claudecode/turn.go create mode 100644 internal/agent/runtime/claudecode/turn_test.go create mode 100644 internal/agent/runtime/codex/appserver.go create mode 100644 internal/agent/runtime/codex/auth.go create mode 100644 internal/agent/runtime/codex/codexcfg/config.go create mode 100644 internal/agent/runtime/codex/config.go create mode 100644 internal/agent/runtime/codex/conn.go create mode 100644 internal/agent/runtime/codex/driver.go create mode 100644 internal/agent/runtime/codex/elicitation.go create mode 100644 internal/agent/runtime/codex/lifecycle.go create mode 100644 internal/agent/runtime/codex/lifecycle_test.go create mode 100644 internal/agent/runtime/codex/process.go create mode 100644 internal/agent/runtime/codex/protocol/methods.gen.go create mode 100644 internal/agent/runtime/codex/protocol/protocol.go create mode 100644 internal/agent/runtime/codex/protocol/roundtrip_test.go create mode 100644 internal/agent/runtime/codex/protocol/types.gen.go create mode 100644 internal/agent/runtime/codex/protocol/unions.gen.go create mode 100644 internal/agent/runtime/codex/protocolgen/emit.go create mode 100644 internal/agent/runtime/codex/protocolgen/emit_methods.go create mode 100644 internal/agent/runtime/codex/protocolgen/emit_unions.go create mode 100644 internal/agent/runtime/codex/protocolgen/generate.go create mode 100644 internal/agent/runtime/codex/protocolgen/naming.go create mode 100644 internal/agent/runtime/codex/protocolgen/resolve.go create mode 100644 internal/agent/runtime/codex/protocolgen/schema.go create mode 100644 internal/agent/runtime/codex/protocolgen/schema/ChatgptAuthTokensRefreshResponse.json create mode 100644 internal/agent/runtime/codex/protocolgen/schema/ClientNotification.json create mode 100644 internal/agent/runtime/codex/protocolgen/schema/CommandExecutionRequestApprovalResponse.json create mode 100644 internal/agent/runtime/codex/protocolgen/schema/FileChangeRequestApprovalResponse.json create mode 100644 internal/agent/runtime/codex/protocolgen/schema/McpServerElicitationRequestResponse.json create mode 100644 internal/agent/runtime/codex/protocolgen/schema/PermissionsRequestApprovalResponse.json create mode 100644 internal/agent/runtime/codex/protocolgen/schema/ServerRequest.json create mode 100644 internal/agent/runtime/codex/protocolgen/schema/ToolRequestUserInputResponse.json create mode 100644 internal/agent/runtime/codex/protocolgen/schema/VERSION.json create mode 100644 internal/agent/runtime/codex/protocolgen/schema/codex_app_server_protocol.v2.schemas.json create mode 100644 internal/agent/runtime/codex/protocolgen/subset.go create mode 100644 internal/agent/runtime/codex/tools.go create mode 100644 internal/agent/runtime/codex/turn.go create mode 100644 internal/agent/runtime/codex/userinput.go create mode 100644 internal/agent/runtime/external/credential.go create mode 100644 internal/agent/runtime/external/external.go create mode 100644 internal/agent/runtime/external/transcript.go create mode 100644 internal/agent/runtime/toolmount/toolmount.go rename internal/contextview/{collector_acp.go => collector_runtime.go} (57%) rename internal/contextview/{render_acp.go => render_runtime.go} (54%) rename internal/contextview/{render_acp_test.go => render_runtime_test.go} (50%) rename internal/contextview/{selector_acp_test.go => selector_runtime_test.go} (78%) delete mode 100644 internal/db/acp_session_state_migration_integration_test.go create mode 100644 internal/db/agent_session_state_migration_integration_test.go rename internal/db/postgres/sqlc/{acp_session_state.sql.go => agent_session_state.sql.go} (67%) delete mode 100644 internal/handlers/acp_claude_code_oauth.go delete mode 100644 internal/handlers/acp_claude_code_oauth_test.go delete mode 100644 internal/handlers/acp_codex_device_oauth.go delete mode 100644 internal/handlers/acp_codex_oauth.go delete mode 100644 internal/handlers/acp_codex_oauth_test.go delete mode 100644 internal/handlers/acp_feedback.go delete mode 100644 internal/handlers/acp_feedback_test.go create mode 100644 internal/handlers/external_agent_codex.go create mode 100644 internal/handlers/external_agent_feedback.go delete mode 100644 internal/handlers/users_acp_config_test.go create mode 100644 internal/runtimekind/runtimekind.go delete mode 100644 packages/icons/icons/hermes-agent.svg delete mode 100644 packages/icons/src/icons/HermesAgent.vue create mode 100755 scripts/codex-schema-sync.sh diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 3ed1f94d77..7e7eb9697e 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -201,15 +201,13 @@ jobs: if: steps.should-build.outputs.skip != 'true' && env.PUSH != 'true' && matrix.image == 'workspace' && matrix.platform == 'linux/amd64' run: | docker run --rm memoh-ci-workspace:debian sh -eux -c ' - grep -q "\"contract_version\": 2" /opt/memoh/workspace-contract.json + grep -q "\"contract_version\": 3" /opt/memoh/workspace-contract.json ldd --version >/dev/null node --version python3 --version uv --version test -x /opt/memoh/toolkit/bin/codex - test -x /opt/memoh/toolkit/bin/codex-acp - test -x /opt/memoh/toolkit/bin/claude-agent-acp - test -x /opt/memoh/toolkit/bin/hermes-acp + test -x /opt/memoh/toolkit/bin/claude test -x /opt/memoh/toolkit/display/bin/a11y-cli sh -n /opt/memoh/scripts/display-prepare.sh sh -n /opt/memoh/scripts/display-apply-style.sh diff --git a/AGENTS.md b/AGENTS.md index ac9596d828..61a48acd2e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -81,9 +81,14 @@ Memoh/ │ │ ├── decision/ # User input, tool approval, and stable user-facing feedback │ │ ├── event/ # Agent events and transport payload vocabulary │ │ ├── runtime/ # Runtime implementations -│ │ │ ├── acp/ # ACP pool, client process manager, and profiles +│ │ │ ├── acp/ # ACP pool, client process manager, and the generic custom-agent profile +│ │ │ ├── claudecode/ # Claude Code direct runtime (external.Driver) +│ │ │ ├── codex/ # Codex direct runtime (external.Driver) +│ │ │ ├── external/ # Neutral Driver port between the application layer and external runtimes │ │ │ ├── native/ # Twilight AI native runtime, prompts, streaming, hooks, and guards -│ │ │ └── session/ # Per-thread runtime state and control +│ │ │ ├── agentstate/ # External Agent session publication heads and state storage port +│ │ │ ├── session/ # Per-thread runtime state and control +│ │ │ └── toolmount/ # Memoh tool gateway mounts for direct runtimes │ │ ├── sessionmode/ # Session mode resolution │ │ ├── tool/ # Native tool providers (package name remains tools) │ │ ├── message.go # Send message tool @@ -387,7 +392,7 @@ PostgreSQL migrations live in `db/postgres/migrations/`: The codebase has grown beyond the original agent/channel/container core. When working near these areas, read the local `AGENTS.md` and treat the corresponding `internal/` package as the source of truth; do not guess tool or schema details. -- **ACP (`internal/agent/runtime/acp/`)** — runtime pool, client process manager, profiles, and OAuth integration for external ACP agents such as Claude Code and Codex. Stable user-facing ACP errors live in `internal/agent/decision/feedback/`. +- **External coding-agent runtimes (`internal/agent/runtime/external/`, `codex/`, `claudecode/`)** — the neutral `external.Driver` port plus the direct Codex and Claude Code runtimes (pinned protocol assets, device-code/OAuth login, native thread resume/fork, Memoh tool gateway mounts via `toolmount/`). **ACP (`internal/agent/runtime/acp/`)** is the generic channel for custom user-supplied ACP agents (single generic profile with a managed launch command), folded into the same driver port. Stable user-facing runtime errors live in `internal/agent/decision/feedback/`. - **Skill Packages (`internal/skillpackages/`, `internal/supermarket/`)** — Supermarket Package discovery and installation state. Installed Packages expand into immutable Registry Skills in the selected workspace target. - **User input / `ask_user` (`internal/agent/decision/input/`)** — lets the in-process agent ask the user a question mid-conversation and wait for an answer. - **Bot backup / import / export (`internal/botbackup/`)** — archive-based bot portability with preview and merge/replace/skip strategies. diff --git a/apps/web/src/components/session-select/options.ts b/apps/web/src/components/session-select/options.ts index b71c19b150..1d9441ec5d 100644 --- a/apps/web/src/components/session-select/options.ts +++ b/apps/web/src/components/session-select/options.ts @@ -2,8 +2,9 @@ import type { SessionSession } from '@memohai/sdk' import type { SearchableSelectOption } from '@/components/searchable-select-popover/index.vue' import type { BotWorkdir } from '@/composables/api/useWorkdirs' import type { SessionKind } from './session-kind-icon.vue' -import { acpAgentDisplayName, normalizeACPAgentID } from '@/utils/acp' -import { normalizedRuntimeType, normalizedSessionMode } from '@/store/chat-list.utils' +import { acpAgentDisplayName } from '@/utils/acp' +import { sessionAgentProvider } from '@/utils/bot-agent' +import { isAgentRuntimeType, normalizedRuntimeType, normalizedSessionMode } from '@/store/chat-list.utils' // The per-row mark the picker paints beside a session title. export interface SessionMark { @@ -29,8 +30,11 @@ export function sessionTitle(session: SessionSession, labels: SessionSelectLabel } export function sessionMark(session: SessionSession, labels: SessionSelectLabels): SessionMark { - const agentId = normalizeACPAgentID( - session.runtime_metadata?.acp_agent_id ?? session.metadata?.acp_agent_id, + const runtimeType = normalizedRuntimeType(session) + const agentId = sessionAgentProvider( + runtimeType, + session.runtime_metadata, + session.metadata, ) // Schedule wins over the ACP mark here, unlike the sidebar row: this picker // exists to tell schedule-owned sessions apart from ordinary chats, and a @@ -38,7 +42,7 @@ export function sessionMark(session: SessionSession, labels: SessionSelectLabels if (normalizedSessionMode(session) === 'schedule') { return { kind: 'schedule', agentId, label: labels.schedule } } - if (normalizedRuntimeType(session) === 'acp_agent') { + if (isAgentRuntimeType(runtimeType)) { return { kind: 'acp', agentId, label: acpAgentDisplayName(agentId, labels.agent) } } return NO_MARK diff --git a/apps/web/src/components/sidebar/session-item.vue b/apps/web/src/components/sidebar/session-item.vue index 7213a94fe7..1200b62ab9 100644 --- a/apps/web/src/components/sidebar/session-item.vue +++ b/apps/web/src/components/sidebar/session-item.vue @@ -15,17 +15,17 @@ @keydown.enter.prevent="$emit('select', session)" @keydown.space.prevent="$emit('select', session)" > -