import { removeOverriddenAgentSessionArgs, resolveAgentSessionOptionLaunch } from './agent-session-option-launch' import type { SessionOptionValue } from './native-chat-session-options' import { getTuiAgentLaunchCommand, TUI_AGENT_CONFIG } from './tui-agent-config' import { planAgentCliArgsSuffix, quoteStartupArg, tokenizeStartupCommand, type AgentStartupShell } from './tui-agent-startup-shell' import type { TuiAgent } from './tui-agent' export type ResolvedAgentLaunchCommand = | { ok: true command: string commandWithoutSessionOptions: string appliedSessionOptions: Record } | { ok: false; error: string } export function resolveAgentLaunchCommand(args: { agent: TuiAgent cmdOverrides: Partial> platform: NodeJS.Platform shell: AgentStartupShell agentArgs?: string | null sessionOptions?: Record sessionOptionsOverrideAgentArgs?: boolean isRemote?: boolean }): ResolvedAgentLaunchCommand { const override = args.cmdOverrides[args.agent] const command = override || getTuiAgentLaunchCommand(TUI_AGENT_CONFIG[args.agent], args.platform, { isRemote: args.isRemote }) const suffix = planAgentCliArgsSuffix(args.agentArgs, args.shell) if (!suffix.ok) { return suffix } const trailingTokens = args.agentArgs?.trim() ? tokenizeStartupCommand(args.agentArgs.trim(), args.shell) : { ok: true as const, tokens: [], spans: [] } if (!trailingTokens.ok) { return { ok: false, error: `CLI arguments are invalid: ${trailingTokens.error}` } } const resolvedOptions = resolveAgentSessionOptionLaunch( args.agent, args.sessionOptions, args.sessionOptionsOverrideAgentArgs ? [] : trailingTokens.tokens, !args.sessionOptionsOverrideAgentArgs ) if (override && args.sessionOptionsOverrideAgentArgs) { const overrideTokens = tokenizeStartupCommand(override, args.shell) if (!overrideTokens.ok) { return { ok: false, error: `Agent command override is invalid: ${overrideTokens.error}` } } const commandOverrideOptions = resolveAgentSessionOptionLaunch( args.agent, args.sessionOptions, overrideTokens.tokens, false ) if ( Object.entries(resolvedOptions.appliedValues).some( ([key, value]) => commandOverrideOptions.appliedValues[key] !== value ) ) { return { ok: false, error: 'Agent command override conflicts with the requested launch preferences. Remove model or effort flags from the command override.' } } } const optionSuffix = resolvedOptions.args.map((arg) => quoteStartupArg(arg, args.shell)).join(' ') const commandWithoutSessionOptions = suffix.suffix ? `${command} ${suffix.suffix}` : command const commandWithOptions = optionSuffix ? `${command} ${optionSuffix}` : command const overrideTokens = args.sessionOptionsOverrideAgentArgs ? insertBeforeTerminator( removeOverriddenAgentSessionArgs(args.agent, args.sessionOptions, trailingTokens.tokens), resolvedOptions.args ) : [] const commandWithOverrides = overrideTokens.length ? `${command} ${overrideTokens.map((token) => quoteStartupArg(token, args.shell)).join(' ')}` : command return { ok: true, command: args.sessionOptionsOverrideAgentArgs ? commandWithOverrides : suffix.suffix ? `${commandWithOptions} ${suffix.suffix}` : commandWithOptions, commandWithoutSessionOptions, appliedSessionOptions: resolvedOptions.appliedValues } } function insertBeforeTerminator(tokens: readonly string[], inserted: readonly string[]): string[] { const terminator = tokens.indexOf('--') if (terminator === -1) { return [...tokens, ...inserted] } return [...tokens.slice(0, terminator), ...inserted, ...tokens.slice(terminator)] }