Merge remote-tracking branch 'origin/master' into worktree/web-session-model-selector
# Conflicts: # .agents/notes/implemented/architecture/2026-07-15-llm-model-catalog-and-acp-selection.i18n.yaml # .agents/notes/implemented/architecture/2026-07-23-client-plugin-loading-model.i18n.yaml # apps/cli/src/web.ts # apps/web/tests/session-title.snapshot.ts # apps/web/tests/smoke-fixture.e2e.ts # packages/client/connection/src/client/api.ts # packages/client/connection/src/client/fixture.ts # packages/client/connection/src/client/index.ts # packages/client/runtime/src/client/index.ts # packages/client/runtime/src/client/sessions/conversation.ts # packages/client/runtime/src/client/sessions/session.ts # packages/client/runtime/tests/fake-api.ts # packages/client/ui-conversation/src/client/contract/slots.ts # packages/client/ui-conversation/src/client/index.ts # packages/client/ui-conversation/src/client/skeleton/ConversationRoot.tsx # packages/client/ui-conversation/src/client/skeleton/InputBar.module.css # packages/client/ui-conversation/src/client/skeleton/InputBar.tsx # packages/client/ui-conversation/tests/chat-stats-bash-sample.spec.tsx # packages/client/ui-conversation/tests/chat-toolview-slot.spec.tsx # packages/client/ui-conversation/tests/chat-view.spec.tsx # packages/client/ui-conversation/tests/gate-branch-tails.spec.tsx # packages/client/ui-conversation/tests/skeleton-branches.spec.tsx # packages/client/ui-conversation/tests/skeleton.spec.tsx # packages/host/apiproxy/README.md # packages/host/apiproxy/src/api-proxy.ts # packages/host/apiproxy/src/api/rpc.schema.ts # packages/host/apiproxy/src/api/rpc.ts # packages/host/apiproxy/tests/api-proxy-models.spec.ts # packages/host/apiproxy/tests/rpc-schemas.spec.ts # packages/host/runtime/README.md # packages/llm/llm-deepseek/README.md # scripts/translation-pairing.manifest.json # tsconfig.client.json
This commit is contained in:
@@ -13,7 +13,7 @@ import { apply, inject } from '../src/client/index.ts'
|
||||
|
||||
const SID = 'selector-session' as SessionId
|
||||
|
||||
async function bench() {
|
||||
async function bench(hasBinding = true) {
|
||||
const ctx = new Context()
|
||||
await ctx.plugin(SlotsService).await()
|
||||
const slots = ctx.get('slots') as SlotsService
|
||||
@@ -31,7 +31,7 @@ async function bench() {
|
||||
value: { selected: target },
|
||||
})),
|
||||
}
|
||||
ctx.provide('sessions', { manager: { get: () => session } })
|
||||
ctx.provide('sessions', { binding: () => hasBinding ? { session } : undefined })
|
||||
ctx.provide('conversation', {})
|
||||
return { ctx, slots, session }
|
||||
}
|
||||
@@ -44,7 +44,7 @@ describe('model-selector browser plugin', () => {
|
||||
it('fails loud when the conversation control slot is not declared', async () => {
|
||||
const ctx = new Context()
|
||||
await ctx.plugin(SlotsService).await()
|
||||
ctx.provide('sessions', { manager: { get: vi.fn() } })
|
||||
ctx.provide('sessions', { binding: vi.fn() })
|
||||
ctx.provide('conversation', {})
|
||||
await expect(ctx.plugin({ inject: [...inject], apply }))
|
||||
.rejects.toThrow(/slot "conversation\.composer\.control" is not declared/)
|
||||
@@ -72,6 +72,14 @@ describe('model-selector browser plugin', () => {
|
||||
.resolves.toBe(false)
|
||||
})
|
||||
|
||||
it('fails loud when slot injection resolves no Session binding', async () => {
|
||||
const { ctx, slots } = await bench(false)
|
||||
await ctx.plugin({ inject: [...inject], apply }).await()
|
||||
const entry = slots.entries('conversation.composer.control')[0]
|
||||
expect(() => (entry?.inject as (sessionId: SessionId) => unknown)(SID))
|
||||
.toThrow(`ui-model-selector: session "${SID}" resolved no binding`)
|
||||
})
|
||||
|
||||
it('unregisters the occupant when its plugin fiber is disposed', async () => {
|
||||
const { ctx, slots } = await bench()
|
||||
const fiber = ctx.plugin({ inject: [...inject], apply })
|
||||
|
||||
Reference in New Issue
Block a user