mirror of
https://github.com/stablyai/orca.git
synced 2026-11-02 18:17:36 +00:00
* feat(native-chat): choose which agents open as a chat Settings → Chat gets a Providers list. Each agent the host can open as a chat has a switch; off opens that agent in a terminal instead. Only choices the user makes are saved. Unchosen: Claude and Codex on, others on when their CLI is installed on this computer. The renderer's route and the host's launch-mode decision both read one rule, so the tab menu, shortcuts, CLI, orchestration and relayed phone launches agree. * fix: keep chat provider settings with the other chat settings types * test: route input carries this computer's detected agents * fix(chat): resolve provider choices from their owning computer * test(chat): use checked native inventory fixtures * Fix launch preparation lifetime and execution host startup * fix(chat): keep unchosen providers on without discovery * test(chat): type provider routing fixtures against store contracts * test(chat): align shared launch fixture with private settings reader * test(chat): give the structured-session RPC fixture the private settings reader The host now reads saved chat choices through requireStore().getSettings(); the shared RPC fixture only had getClientSettings, so the launch-mode reader saw no settings and create support refused Claude. The fixture now follows each test's client settings. * fix: preserve provider choice and cached native inventory
90 lines
3.0 KiB
TypeScript
90 lines
3.0 KiB
TypeScript
import { describe, expect, it, vi } from 'vitest'
|
|
import type { AgentLaunchIntent } from '../../shared/agent-launch-intent'
|
|
import { executeAgentLaunch } from './agent-launch-executor'
|
|
|
|
function harness() {
|
|
const readSettings = vi.fn(() => {
|
|
throw new Error('settings_not_needed_for_refusal')
|
|
})
|
|
const createSupport = vi.fn(async () => {
|
|
throw new Error('support_not_needed_for_refusal')
|
|
})
|
|
const createTerminal = vi.fn(async () => ({ handle: 'term_new' }))
|
|
const deliverPrompt = vi.fn(async () => true)
|
|
const createWorktree = vi.fn(async () => ({
|
|
worktreeId: 'wt_new',
|
|
connectionId: null,
|
|
startupTerminalHandle: 'term_new'
|
|
}))
|
|
return {
|
|
readSettings,
|
|
createTerminal,
|
|
deliverPrompt,
|
|
createWorktree,
|
|
run: (intent: AgentLaunchIntent) =>
|
|
executeAgentLaunch({
|
|
intent,
|
|
runtime: {
|
|
requireStore: () => ({ getSettings: readSettings }),
|
|
getStructuredAgentSessionCreateSupport: createSupport
|
|
},
|
|
surfaces: {
|
|
createTerminalAgent: createTerminal,
|
|
createStructuredSession: async () => {
|
|
throw new Error('structured_not_expected')
|
|
},
|
|
deliverTerminalPrompt: deliverPrompt
|
|
},
|
|
workspaces: {
|
|
createWorktree,
|
|
createFolderWorkspace: async () => {
|
|
throw new Error('folder_create_not_expected')
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
const reused: AgentLaunchIntent = {
|
|
agent: 'opencode',
|
|
target: { kind: 'existing', worktree: 'folder:private' },
|
|
reuseTerminal: { handle: 'term_existing' },
|
|
prompt: { text: 'Read only', delivery: 'submit' },
|
|
sessionOptions: { model: 'private-proof/model-b' }
|
|
}
|
|
const creating: AgentLaunchIntent = {
|
|
...reused,
|
|
reuseTerminal: undefined,
|
|
target: { kind: 'create-worktree', create: { repo: 'id:private', name: 'task' } }
|
|
}
|
|
|
|
describe('OpenCode model preferences on unsupported launch placements', () => {
|
|
it.each([reused, creating])(
|
|
'refuses before reading settings or creating or delivering',
|
|
async (intent) => {
|
|
const h = harness()
|
|
await expect(h.run(intent)).rejects.toMatchObject({ code: 'capability_unsupported' })
|
|
expect(h.readSettings).not.toHaveBeenCalled()
|
|
expect(h.createTerminal).not.toHaveBeenCalled()
|
|
expect(h.createWorktree).not.toHaveBeenCalled()
|
|
expect(h.deliverPrompt).not.toHaveBeenCalled()
|
|
}
|
|
)
|
|
|
|
it('preserves prompt delivery to a reused terminal without model preferences', async () => {
|
|
const h = harness()
|
|
expect((await h.run({ ...reused, sessionOptions: undefined })).outcome).toEqual({
|
|
kind: 'terminal',
|
|
handle: 'term_existing'
|
|
})
|
|
expect(h.deliverPrompt).toHaveBeenCalledOnce()
|
|
expect(h.createWorktree).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('preserves ordinary worktree creation without model preferences', async () => {
|
|
const h = harness()
|
|
expect((await h.run({ ...creating, sessionOptions: undefined })).worktreeId).toBe('wt_new')
|
|
expect(h.createWorktree).toHaveBeenCalledOnce()
|
|
})
|
|
})
|