Phase 003: remove the coding-agent and ekko-agent runtimes
Every chat session now runs through the Hermes bridge, so the three chat chains become feature-equivalent instead of three partially-maintained dispatch paths. Keeping the coding-agent and in-house agent runtimes alive meant every bridge change had to be mirrored into two more runtimes that had already drifted. Historical rows are read, not migrated: sessions stored with the retired source normalize to cli on load, workflow graphs naming the retired agents keep loading and run on the bridge, and the visible-source check plus SOURCE_LABELS still recognize the old value so those sessions stay listed. The public surface follows the code: the OpenAPI generator and the MCP chat-run tool schema drop the six retired entry fields so external callers are not told about runtimes that no longer exist. harness-check gains a RETIRED_RUNTIME scan so the residual check is a mechanical gate instead of a manual grep, with the two surviving read-side compat sites recorded with reasons. Refs: docs/phases/phase_003.md
This commit is contained in:
@@ -2,7 +2,6 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
const handleBridgeRunMock = vi.hoisted(() => vi.fn(async () => {}))
|
||||
const resumeBridgeRunMock = vi.hoisted(() => vi.fn(async () => {}))
|
||||
const handleCodingAgentRunMock = vi.hoisted(() => vi.fn(async () => {}))
|
||||
const loadSessionStateFromDbMock = vi.hoisted(() => vi.fn())
|
||||
const ensureReadyMock = vi.hoisted(() => vi.fn())
|
||||
const sessionCommandMocks = vi.hoisted(() => ({
|
||||
@@ -30,10 +29,6 @@ vi.mock('../../packages/server/src/services/hermes/run-chat/load-state', () => (
|
||||
resolveRunSource: vi.fn((source?: string) => source || 'cli'),
|
||||
}))
|
||||
|
||||
vi.mock('../../packages/server/src/services/hermes/run-chat/handle-coding-agent-run', () => ({
|
||||
handleCodingAgentRun: handleCodingAgentRunMock,
|
||||
}))
|
||||
|
||||
vi.mock('../../packages/server/src/services/hermes/run-chat/session-command', () => sessionCommandMocks)
|
||||
|
||||
vi.mock('../../packages/server/src/services/hermes/agent-bridge', () => ({
|
||||
@@ -294,7 +289,7 @@ describe('ChatRunSocket queued bridge runs', () => {
|
||||
expect(call[6]).toBe(false)
|
||||
})
|
||||
|
||||
it('queues coding-agent messages while a coding-agent turn is active', async () => {
|
||||
it('queues messages carrying a retired legacy source while a turn is active', async () => {
|
||||
const { ChatRunSocket } = await import('../../packages/server/src/services/hermes/run-chat')
|
||||
const { handlers, io, namespace, socket } = makeServerHarness()
|
||||
const server = new ChatRunSocket(io as any)
|
||||
@@ -305,33 +300,31 @@ describe('ChatRunSocket queued bridge runs', () => {
|
||||
isAborting: false,
|
||||
events: [],
|
||||
queue: [],
|
||||
source: 'coding_agent',
|
||||
source: 'retired_source',
|
||||
})
|
||||
|
||||
await handlers.get('run')?.({
|
||||
session_id: 'session-1',
|
||||
input: 'queued codex follow-up',
|
||||
source: 'coding_agent',
|
||||
coding_agent_id: 'codex',
|
||||
queue_id: 'queue-codex',
|
||||
input: 'queued follow-up',
|
||||
source: 'retired_source',
|
||||
queue_id: 'queue-legacy',
|
||||
model: 'gpt-5-codex',
|
||||
provider: 'openai-codex',
|
||||
profile: 'default',
|
||||
})
|
||||
|
||||
expect(handleCodingAgentRunMock).not.toHaveBeenCalled()
|
||||
expect(handleBridgeRunMock).not.toHaveBeenCalled()
|
||||
expect((server as any).sessionMap.get('session-1').queue).toEqual([
|
||||
expect.objectContaining({
|
||||
queue_id: 'queue-codex',
|
||||
input: 'queued codex follow-up',
|
||||
source: 'coding_agent',
|
||||
codingAgentId: 'codex',
|
||||
queue_id: 'queue-legacy',
|
||||
input: 'queued follow-up',
|
||||
source: 'retired_source',
|
||||
}),
|
||||
])
|
||||
expect(namespace.to).toHaveBeenCalledWith('session:session-1')
|
||||
})
|
||||
|
||||
it('dequeues coding-agent messages when an external coding-agent run completes', async () => {
|
||||
it('dequeues messages carrying a retired legacy source on the bridge', async () => {
|
||||
const { ChatRunSocket } = await import('../../packages/server/src/services/hermes/run-chat')
|
||||
const { io, socket } = makeServerHarness()
|
||||
const server = new ChatRunSocket(io as any)
|
||||
@@ -341,27 +334,25 @@ describe('ChatRunSocket queued bridge runs', () => {
|
||||
isAborting: false,
|
||||
events: [],
|
||||
queue: [{
|
||||
queue_id: 'queue-codex',
|
||||
input: 'queued codex follow-up',
|
||||
source: 'coding_agent',
|
||||
codingAgentId: 'codex',
|
||||
queue_id: 'queue-legacy',
|
||||
input: 'queued follow-up',
|
||||
source: 'retired_source',
|
||||
model: 'gpt-5-codex',
|
||||
provider: 'openai-codex',
|
||||
profile: 'default',
|
||||
originSocketId: socket.id,
|
||||
}],
|
||||
source: 'coding_agent',
|
||||
source: 'retired_source',
|
||||
})
|
||||
|
||||
;(server as any).markExternalRunCompleted('session-1', 'run.completed')
|
||||
|
||||
await vi.waitFor(() => expect(handleCodingAgentRunMock).toHaveBeenCalled())
|
||||
const call = handleCodingAgentRunMock.mock.calls.at(-1)!
|
||||
await vi.waitFor(() => expect(handleBridgeRunMock).toHaveBeenCalled())
|
||||
const call = handleBridgeRunMock.mock.calls.at(-1)!
|
||||
expect(call[2]).toEqual(expect.objectContaining({
|
||||
input: 'queued codex follow-up',
|
||||
source: 'coding_agent',
|
||||
coding_agent_id: 'codex',
|
||||
queue_id: 'queue-codex',
|
||||
input: 'queued follow-up',
|
||||
source: 'retired_source',
|
||||
queue_id: 'queue-legacy',
|
||||
}))
|
||||
expect((server as any).sessionMap.get('session-1').queue).toEqual([])
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user