mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 00:02:31 +00:00
fix(orchestration): derive inject's agent guidance from the recognized-agent roster (#15874)
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> Co-authored-by: vam <a@a.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
vam
parent
6faaf3af74
commit
deae7212d9
@@ -0,0 +1,31 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { buildInjectRejectionMessage } from './orchestration-inject-rejection-message'
|
||||
import { TUI_AGENT_CONFIG } from '../../../../shared/tui-agent-config'
|
||||
import { recognizeAgentProcess } from '../../../../shared/agent-process-recognition'
|
||||
|
||||
describe('buildInjectRejectionMessage', () => {
|
||||
const message = buildInjectRejectionMessage('term_a')
|
||||
|
||||
it('keeps the substring callers and scripts match on', () => {
|
||||
expect(message).toContain('Cannot dispatch --inject to terminal term_a')
|
||||
expect(message).toContain('no recognized agent detected')
|
||||
})
|
||||
|
||||
it('names every agent Orca recognizes, including agy', () => {
|
||||
expect(message).toMatch(/\bagy\b/)
|
||||
for (const config of Object.values(TUI_AGENT_CONFIG)) {
|
||||
expect(message).toContain(config.expectedProcess)
|
||||
}
|
||||
})
|
||||
|
||||
it('lists only names detection actually resolves, deduped and sorted', () => {
|
||||
const listed = (/\(([^)]+)\)/.exec(message)?.[1] ?? '').split(', ')
|
||||
|
||||
expect(listed.length).toBeGreaterThan(0)
|
||||
expect(new Set(listed).size).toBe(listed.length)
|
||||
expect([...listed].sort()).toEqual(listed)
|
||||
for (const name of listed) {
|
||||
expect(recognizeAgentProcess(name)).not.toBeNull()
|
||||
}
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,16 @@
|
||||
import { TUI_AGENT_CONFIG } from '../../../../shared/tui-agent-config'
|
||||
|
||||
// Why: the old five-name example read as an allowlist (#15125); derive from the field detection keys on so it cannot drift.
|
||||
// Not filtered by `disabledTuiAgents` — that gates Orca's launchers, not detection, so a hand-started disabled agent still injects.
|
||||
const RECOGNIZED_AGENT_PROCESS_NAMES = [
|
||||
...new Set(Object.values(TUI_AGENT_CONFIG).map((config) => config.expectedProcess))
|
||||
].sort()
|
||||
|
||||
export function buildInjectRejectionMessage(terminal: string): string {
|
||||
return (
|
||||
`Cannot dispatch --inject to terminal ${terminal}: no recognized agent detected. ` +
|
||||
`Orca detects these agent CLIs (${RECOGNIZED_AGENT_PROCESS_NAMES.join(', ')}). ` +
|
||||
'Start one in the terminal and let it finish launching, ' +
|
||||
'or dispatch without --inject and send the prompt manually.'
|
||||
)
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import type { RpcContext } from '../core'
|
||||
import { createOrchestrationRpcHarness } from './orchestration-rpc-test-harness'
|
||||
import type { OrchestrationDb } from '../../orchestration/db'
|
||||
import type { OrcaRuntimeService } from '../../orca-runtime'
|
||||
import { buildInjectRejectionMessage } from './orchestration-inject-rejection-message'
|
||||
|
||||
describe('orchestration RPC methods', () => {
|
||||
const h = createOrchestrationRpcHarness()
|
||||
@@ -389,7 +390,7 @@ describe('orchestration RPC methods', () => {
|
||||
to: 'term_a',
|
||||
inject: true
|
||||
})
|
||||
).rejects.toThrow('no recognized agent detected')
|
||||
).rejects.toThrow(buildInjectRejectionMessage('term_a'))
|
||||
})
|
||||
|
||||
it('rejects dispatch to occupied terminal', async () => {
|
||||
|
||||
@@ -27,6 +27,7 @@ import {
|
||||
resolveBareOrchestrationRecipient,
|
||||
type SendRecipientWarning
|
||||
} from './orchestration-recipient-routing'
|
||||
import { buildInjectRejectionMessage } from './orchestration-inject-rejection-message'
|
||||
import { resolveRunScope } from './orchestration-run-scope'
|
||||
import { ORCHESTRATION_RUN_METHODS } from './orchestration-runs'
|
||||
import { ORCHESTRATION_WORKER_METHODS } from './orchestration-worker-methods'
|
||||
@@ -1643,11 +1644,7 @@ export const ORCHESTRATION_METHODS: RpcMethod[] = [
|
||||
if (params.inject) {
|
||||
const hasAgent = await runtime.isTerminalRunningAgent(to)
|
||||
if (!hasAgent) {
|
||||
throw new Error(
|
||||
`Cannot dispatch --inject to terminal ${to}: no recognized agent detected. ` +
|
||||
'Start an agent CLI (e.g. claude, codex, gemini, droid, cursor) in the terminal first, ' +
|
||||
'or dispatch without --inject and send the prompt manually.'
|
||||
)
|
||||
throw new Error(buildInjectRejectionMessage(to))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -360,6 +360,22 @@ describe('agent process recognition', () => {
|
||||
expect(isAgentForegroundWrapperProcess('vim.exe')).toBe(false)
|
||||
})
|
||||
|
||||
it('recognizes the Antigravity CLI from bare, POSIX and Windows command lines', () => {
|
||||
const agy = { agent: 'antigravity', processName: 'agy' }
|
||||
|
||||
expect(recognizeAgentProcess('agy')).toEqual(agy)
|
||||
expect(recognizeAgentProcess('/Users/dev/.local/bin/agy')).toEqual(agy)
|
||||
expect(recognizeAgentProcess(String.raw`C:\Users\dev\AppData\Local\agy\bin\agy.exe`)).toEqual(
|
||||
agy
|
||||
)
|
||||
expect(
|
||||
recognizeAgentProcessFromCommandLine(
|
||||
String.raw`"C:\Users\dev\AppData\Local\agy\bin\agy.exe" --dangerously-skip-permissions`
|
||||
)
|
||||
).toEqual(agy)
|
||||
expect(recognizeAgentProcessFromCommandLine('agy --dangerously-skip-permissions')).toEqual(agy)
|
||||
})
|
||||
|
||||
it('recognizes versioned Grok process names observed from the installed CLI', () => {
|
||||
expect(recognizeAgentProcess('grok-0.2.51')).toEqual({
|
||||
agent: 'grok',
|
||||
|
||||
Reference in New Issue
Block a user