feat(llm): route adapters by provider
This commit is contained in:
@@ -230,10 +230,10 @@ describe('acp bridge — disposal & HMR safety', () => {
|
||||
// queryable, with its session still in the store.
|
||||
const harness = await makeBridgeHarness({ storageDir, script: [] })
|
||||
const handleA = await harness.ctx.agents.create({
|
||||
agentId: AgentId('sib-a'), sessionId: SessionId('sib-a'), agentOptions: { model: 'mock' },
|
||||
agentId: AgentId('sib-a'), sessionId: SessionId('sib-a'), agentOptions: { provider: 'mock', model: 'mock' },
|
||||
})
|
||||
const handleB = await harness.ctx.agents.create({
|
||||
agentId: AgentId('sib-b'), sessionId: SessionId('sib-b'), agentOptions: { model: 'mock' },
|
||||
agentId: AgentId('sib-b'), sessionId: SessionId('sib-b'), agentOptions: { provider: 'mock', model: 'mock' },
|
||||
})
|
||||
expect(harness.ctx.agents.get(AgentId('sib-a'))).toBe(handleA.agent)
|
||||
expect(harness.ctx.agents.get(AgentId('sib-b'))).toBe(handleB.agent)
|
||||
@@ -262,7 +262,7 @@ describe('acp bridge — disposal & HMR safety', () => {
|
||||
const harness = await makeBridgeHarness({ storageDir, script: [textResponse('ok')] })
|
||||
harness.ctx.on('agent/disposed', () => { throw new Error('boom disposed listener') })
|
||||
const handle = await harness.ctx.agents.create({
|
||||
agentId: AgentId('guard-a'), sessionId: SessionId('guard-a'), agentOptions: { model: 'mock' },
|
||||
agentId: AgentId('guard-a'), sessionId: SessionId('guard-a'), agentOptions: { provider: 'mock', model: 'mock' },
|
||||
})
|
||||
handle.agent.send([{ type: 'text', text: 'go' }])
|
||||
await handle.agent.whenIdle()
|
||||
@@ -283,7 +283,7 @@ describe('acp bridge — disposal & HMR safety', () => {
|
||||
// observe the same quiescence boundary.
|
||||
const harness = await makeBridgeHarness({ storageDir, script: ['hang'] })
|
||||
const handle = await harness.ctx.agents.create({
|
||||
agentId: AgentId('conc-a'), sessionId: SessionId('conc-a'), agentOptions: { model: 'mock' },
|
||||
agentId: AgentId('conc-a'), sessionId: SessionId('conc-a'), agentOptions: { provider: 'mock', model: 'mock' },
|
||||
})
|
||||
// Drive a turn that hangs in the model stream, so the loop is mid-turn when
|
||||
// disposed — its exit runs a final session/flush we can gate to hold the
|
||||
|
||||
@@ -27,7 +27,7 @@ describe('acp bridge — demux & config edges', () => {
|
||||
await harness.client.newSession({ cwd: process.cwd(), mcpServers: [] })
|
||||
const before = harness.updates.length
|
||||
|
||||
const { agent: foreign } = await harness.ctx.agents.create({ agentId: AgentId('foreign'), sessionId: SessionId('foreign-session'), agentOptions: { model: 'mock' } })
|
||||
const { agent: foreign } = await harness.ctx.agents.create({ agentId: AgentId('foreign'), sessionId: SessionId('foreign-session'), agentOptions: { provider: 'mock', model: 'mock' } })
|
||||
foreign.send([{ type: 'text', text: 'hi' }])
|
||||
await foreign.whenIdle()
|
||||
await new Promise(r => setTimeout(r, 10))
|
||||
|
||||
@@ -155,7 +155,7 @@ export interface BridgeHarness {
|
||||
* The bridge's `apply` receives the agent-side `Stream` via `config.stream`;
|
||||
* the test holds the `ClientSideConnection`.
|
||||
*
|
||||
* Pass `config: { model: undefined }` to override the default `model: 'mock'`
|
||||
* Pass `config: { model: undefined }` to override the default mock target
|
||||
* (the model key is dropped entirely when explicitly undefined).
|
||||
*/
|
||||
export async function makeBridgeHarness(options: {
|
||||
@@ -282,10 +282,11 @@ export async function makeBridgeHarness(options: {
|
||||
})
|
||||
|
||||
// Wire the bridge (agent side) and the client (test side). The test config
|
||||
// can override `model` (including to undefined): default to 'mock' unless the
|
||||
// caller explicitly set the key (even to undefined), so a `{ model: undefined }`
|
||||
// override means "no model at all".
|
||||
// can override either route field (including to undefined). Default both to
|
||||
// `mock` unless the caller explicitly set that key, so `{ model: undefined }`
|
||||
// still means "no model at all".
|
||||
const cfg: AcpConfig = { stream: agentStream, ...options.config }
|
||||
if (!(options.config && 'provider' in options.config)) cfg.provider = 'mock'
|
||||
if (!(options.config && 'model' in options.config)) cfg.model = 'mock'
|
||||
// Mount the bridge the way production does: as a cordis PLUGIN (via
|
||||
// `ctx.plugin` with the real `inject`), NOT `AcpPlugin.apply(ctx, cfg)`
|
||||
|
||||
@@ -804,5 +804,6 @@ describe('agentOptions', () => {
|
||||
it('includes only the fields present in config', () => {
|
||||
expect(agentOptions({})).toEqual({})
|
||||
expect(agentOptions({ model: 'm' })).toEqual({ model: 'm' })
|
||||
expect(agentOptions({ provider: 'p', model: 'm' })).toEqual({ provider: 'p', model: 'm' })
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user