mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 16:47:34 +00:00
* feat(native-chat): combine model and options into one picker Setting a model and its effort took two menus that each closed on a pick. * feat(native-chat): close the model picker on an effort pick Effort is the last thing set before typing. * fix(native-chat): write the picker's kept rows after commit React Doctor rejects a ref written in render, and a discarded render could leave a row behind. * fix(native-chat): open the picker once per /model or /effort, tooltip only when informative The session kept a slash command's picker request, and the picker remounted open from it whenever a question or approval card gave the composer back. The request is now consumed when the picker sees it, and open state lives in the popover, which unmounts with the pill, so it comes back closed. The pill's hover tooltip only named the categories the pill already shows, and the picker covered it on click. It now shows only the disabled reason or the not-confirmed note. Also drops the removed Options key from the locale test and covers the new short effort labels. --------- Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
110 lines
3.8 KiB
TypeScript
110 lines
3.8 KiB
TypeScript
import { readFile, writeFile } from 'node:fs/promises'
|
|
import { buildShellCommandFromArgv } from '../../src/shared/tui-agent-startup-shell'
|
|
import { test, expect } from './helpers/orca-app'
|
|
import { ensureTerminalVisible, waitForActiveWorktree, waitForSessionReady } from './helpers/store'
|
|
import {
|
|
execInTerminal,
|
|
waitForActivePaneHookDescriptor,
|
|
waitForActivePanePtyId,
|
|
waitForActiveTerminalManager
|
|
} from './helpers/terminal'
|
|
|
|
test('OMP model picker dispatches its advertised command and adopts the host report', async ({
|
|
orcaPage,
|
|
electronApp
|
|
}, testInfo) => {
|
|
test.skip(process.platform === 'win32', 'POSIX PTY capture fixture')
|
|
await waitForSessionReady(orcaPage)
|
|
await waitForActiveWorktree(orcaPage)
|
|
await ensureTerminalVisible(orcaPage)
|
|
await waitForActiveTerminalManager(orcaPage)
|
|
const descriptor = await waitForActivePaneHookDescriptor(orcaPage)
|
|
const ptyId = await waitForActivePanePtyId(orcaPage)
|
|
const output = testInfo.outputPath('model-command.txt')
|
|
const script = testInfo.outputPath('capture.cjs')
|
|
await writeFile(
|
|
script,
|
|
`const fs = require('node:fs'); let data = ''; process.stdin.setRawMode(true); process.stdin.on('data', chunk => { data += chunk; fs.writeFileSync(${JSON.stringify(output)}, data); });`
|
|
)
|
|
await execInTerminal(
|
|
orcaPage,
|
|
ptyId,
|
|
buildShellCommandFromArgv([process.execPath, script], 'posix')
|
|
)
|
|
await electronApp.evaluate(({ ipcMain }) => {
|
|
ipcMain.removeHandler('git:discoverCommitMessageModels')
|
|
ipcMain.handle('git:discoverCommitMessageModels', () => ({
|
|
success: true,
|
|
catalogOrigin: 'probe',
|
|
models: [
|
|
{ id: 'anthropic/claude-sonnet-4-5', label: 'Sonnet 4.5' },
|
|
{ id: 'anthropic/claude-sonnet-4-6', label: 'Sonnet 4.6' }
|
|
]
|
|
}))
|
|
})
|
|
await orcaPage.evaluate(async ({ paneKey, worktreeId }) => {
|
|
const settings = await window.api.settings.set({ experimentalNativeChat: true })
|
|
const store = window.__store
|
|
if (!store) {
|
|
throw new Error('Store unavailable')
|
|
}
|
|
store.setState({ settings })
|
|
const state = store.getState()
|
|
state.setAgentStatus(
|
|
paneKey,
|
|
{
|
|
state: 'idle',
|
|
prompt: '',
|
|
agentType: 'omp',
|
|
model: 'anthropic/claude-sonnet-4-5',
|
|
modelSwitchCommand: 'orca-model'
|
|
},
|
|
'OMP',
|
|
undefined,
|
|
{ worktreeId }
|
|
)
|
|
const [tabId] = paneKey.split(':')
|
|
const tab = (state.unifiedTabsByWorktree[worktreeId] ?? []).find(
|
|
(tab) => tab.contentType === 'terminal' && tab.entityId === tabId
|
|
)
|
|
if (!tab) {
|
|
throw new Error('Terminal tab unavailable')
|
|
}
|
|
state.toggleTabViewMode(tab.id)
|
|
}, descriptor)
|
|
const picker = orcaPage.getByRole('button', { name: 'Model Sonnet 4.5', exact: true })
|
|
await expect(picker).toBeVisible()
|
|
await picker.click()
|
|
await expect(orcaPage.getByRole('option', { name: 'Sonnet 4.6', exact: true })).toBeVisible()
|
|
await orcaPage.screenshot({
|
|
animations: 'disabled',
|
|
path: testInfo.outputPath('omp-model-choices.png')
|
|
})
|
|
await orcaPage.getByRole('option', { name: 'Sonnet 4.6', exact: true }).click()
|
|
await expect
|
|
.poll(async () => readFile(output, 'utf8').catch(() => ''))
|
|
.toContain('/orca-model anthropic/claude-sonnet-4-6')
|
|
await orcaPage.evaluate(({ paneKey, worktreeId }) => {
|
|
window.__store?.getState().setAgentStatus(
|
|
paneKey,
|
|
{
|
|
state: 'idle',
|
|
prompt: '',
|
|
agentType: 'omp',
|
|
model: 'anthropic/claude-sonnet-4-6',
|
|
modelSwitchCommand: 'orca-model'
|
|
},
|
|
'OMP',
|
|
undefined,
|
|
{ worktreeId }
|
|
)
|
|
}, descriptor)
|
|
await expect(
|
|
orcaPage.getByRole('button', { name: 'Model Sonnet 4.6', exact: true })
|
|
).toBeVisible()
|
|
await orcaPage.screenshot({
|
|
animations: 'disabled',
|
|
path: testInfo.outputPath('omp-model-reported.png')
|
|
})
|
|
})
|