orca/src/shared/agent-process-recognition.ts

93 lines
2.6 KiB
TypeScript

import { TUI_AGENT_CONFIG } from './tui-agent-config'
import type { AgentType } from './agent-status-types'
import type { TuiAgent } from './types'
export type RecognizedAgentProcess = {
agent: TuiAgent
processName: string
}
const EXTENSION_RE = /\.(?:exe|cmd|bat|ps1)$/i
function normalizeProcessName(processName: string | null | undefined): string {
if (!processName) {
return ''
}
const unquoted = processName.trim().replace(/^["']|["']$/g, '')
const basename = unquoted.split(/[\\/]/).pop() ?? unquoted
return basename.toLowerCase().replace(EXTENSION_RE, '')
}
function firstCommandToken(command: string): string {
return command.trim().split(/\s+/)[0] ?? ''
}
const PROCESS_TO_AGENT = new Map<string, TuiAgent>()
const AGENT_TYPE_IDS = new Set<TuiAgent>()
for (const [agent, config] of Object.entries(TUI_AGENT_CONFIG) as [
TuiAgent,
(typeof TUI_AGENT_CONFIG)[TuiAgent]
][]) {
AGENT_TYPE_IDS.add(agent)
for (const candidate of [
config.expectedProcess,
config.detectCmd,
firstCommandToken(config.launchCmd)
]) {
const normalized = normalizeProcessName(candidate)
if (normalized) {
PROCESS_TO_AGENT.set(normalized, agent)
}
}
}
function agentForNormalizedProcess(normalized: string): TuiAgent | undefined {
const exact = PROCESS_TO_AGENT.get(normalized)
if (exact) {
return exact
}
// Why: node-pty can report Codex's packaged platform binary
// (for example codex-aarch64-ap) instead of the launch command.
if (normalized.startsWith('codex-')) {
return PROCESS_TO_AGENT.get('codex')
}
return undefined
}
export function isExpectedAgentProcess(
processName: string | null | undefined,
expectedProcess: string
): boolean {
const normalizedProcess = normalizeProcessName(processName)
const normalizedExpected = normalizeProcessName(expectedProcess)
if (!normalizedProcess || !normalizedExpected) {
return false
}
return (
normalizedProcess === normalizedExpected ||
normalizedProcess.startsWith(`${normalizedExpected}.`)
)
}
export function recognizeAgentProcess(
processName: string | null | undefined
): RecognizedAgentProcess | null {
const normalized = normalizeProcessName(processName)
const agent = agentForNormalizedProcess(normalized)
if (!agent) {
return null
}
return { agent, processName: normalized }
}
export function isRecognizedAgentType(agentType: AgentType | null | undefined): boolean {
if (typeof agentType !== 'string') {
return false
}
return (
AGENT_TYPE_IDS.has(agentType as TuiAgent) ||
agentForNormalizedProcess(normalizeProcessName(agentType)) !== undefined
)
}