import type { AgentProcessSpawner, AgentSpawnConfig, Backend, McpComposition } from '../../agent-adapter/types.js'; import type { NormalizedEvent } from '../../agent-adapter/normalize/event-types.js'; import type { AgentResult, ChatNoticeLevel, ContextUsage, NoticeAction } from '../../core/types/agent-types.js'; export interface AgentConfig { model: string; backend: Backend; mode: string | null; /** Opaque rate-limit provider identity; for PI it also selects the request protocol. */ provider?: string | null; extraEnv?: Record; extraOption?: Record; /** DR-0012: Claude adapter mode (print/tui). Only meaningful for backend='claude'. */ claudeBackend?: 'print' | 'tui'; /** Thinking level from the profile (backend-native value: claude → --effort, pi → --thinking). * null/undefined → nothing is passed. */ thinking?: string | null; } export interface RunObserver { onEvent(event: NormalizedEvent): void; onClose?(): void | Promise; } export interface RunAgentOptions { profileName?: string | null; /** Backend resume target (Claude `--resume` / PI `--session`). null → fresh (backend self-assigns * its own id). Decoupled from {@link trackSessionId}. */ sessionId?: string | null; /** Stable Cortex tracking id (UI-facing identity) — surfaced as CORTEX_SESSION_ID only; does NOT * drive backend resume. Defaults to `sessionId` when unset (threads / legacy callers). */ trackSessionId?: string | null; sessionKey?: string | null; channel?: string; files?: unknown[]; /** Best-effort synchronous event observers; failures are logged and ignored. */ observers?: RunObserver[]; /** Synchronous event sinks whose write or close failure aborts the run. */ requiredSinks?: RunObserver[]; /** Explicit background policy. Undefined preserves the legacy thread-keyed decision. */ awaitBackground?: boolean; /** Completion-only disables ambient caps and waits until continuation or process termination. */ backgroundWaitPolicy?: 'bounded' | 'completion-only'; /** Absolute working directory resolved by the caller for the backend process. */ cwd?: string; /** Optional containment-aware process boundary for daemon-free runs. */ processSpawner?: AgentProcessSpawner; /** Pre-resolved spawn input used when identity must hash the exact object before launch. */ preparedSpawnConfig?: AgentSpawnConfig; /** Absolute backend CLI path frozen by a trial policy. Absent resolves the CLI from PATH. */ cliPath?: string; /** Compiled benchmark policy guard for this role; present replaces the ambient hook surface. */ benchmarkPolicyGuard?: AgentSpawnConfig['benchmarkPolicyGuard']; /** Benchmark thread slot this step runs as. Selects the trial's compiled role before the spawn * config is built, and is never written into it. */ benchmarkAgentSlot?: string; /** Exact allowlisted child environment for an isolated trial; replaces host inheritance. */ pinnedEnv?: NodeJS.ProcessEnv; /** Absolute trial deadline a backend derives its in-process call budget from (§5.6 P5). */ benchmarkDeadlineEpochMs?: number; /** Concrete MCP config paths frozen by a one-shot run config. */ mcpConfigPaths?: string[]; /** Suppress hooks for an isolated one-shot role. */ disableHooks?: boolean; /** Explicit streaming policy for runs that must not load watched daemon settings. */ streamDeltas?: boolean; /** Suppress legacy transcript logs when a required journal is configured. */ captureTranscriptLogs?: boolean; /** Keep unavailable backend accounting null for provenance-sensitive runs. */ preserveUnreportedAccounting?: boolean; /** Disable ambient global rules for a frozen role prompt. */ loadCortexRules?: boolean; /** Disable daemon cost-store writes while preserving streamed cost records. */ recordCost?: boolean; callbackSource?: string | null; scheduleTaskId?: string | null; isUserInitiated?: boolean; project?: string; trigger?: string; /** Cortex execution context surfaced to the MCP server child as CORTEX_THREAD_ID/PROFILE/PROJECT/SESSION_NAME env vars. * Read by the cortex_context / cortex_schedule_* MCP tools so LLMs can self-discover their thread and target schedules * at the current thread / session without guessing IDs. */ threadId?: string | null; sessionName?: string | null; /** Cortex execution record id, surfaced as CORTEX_EXECUTION_ID to subprocess env. */ executionId?: string | null; /** Explicit MCP privilege surface for the spawned backend. */ mcpComposition?: McpComposition; /** Legacy thread-surface selector. Accepted for existing callers and resolved when the explicit * composition is absent. */ useCoreMcp?: boolean; /** Recursion depth of the owning thread, surfaced to the spawned agent as CORTEX_THREAD_DEPTH * so the thread_start MCP tool can forward it for the depth guard. */ threadDepth?: number | null; /** Owning dispatch task id/project, surfaced as CORTEX_TASK_ID / CORTEX_TASK_PROJECT so * `cortex-task spawn` can infer the current task as the parent of a child task. */ taskId?: string | null; taskProject?: string | null; taskGeneration?: string | null; onProgress?: ((progress: any) => void) | null; onContextUsage?: ((usage: ContextUsage) => void | Promise) | null; /** A complete assistant text block. `blockId` ties it to prior deltas; `noticeLevel` turns * system-authored text into semantic chat chrome without changing plain platform output. */ onAssistantMessage?: ((msg: string, blockId?: string, noticeLevel?: ChatNoticeLevel, noticeAction?: NoticeAction) => void) | null; /** An incremental text chunk of a block still being generated (never the accumulated total). * Opt-in: callers that leave it unset receive complete messages only, exactly as before. */ onAssistantDelta?: ((text: string, blockId: string) => void) | null; onToolUse?: ((name: string, input: any, toolUseId: string) => void) | null; onToolResult?: ((toolUseId: string, content: string, isError: boolean) => void) | null; onFallback?: (current: AgentConfig, next: AgentConfig, result: AgentResult | null, error?: Error) => Promise; [key: string]: any; } /** * Build the gateway sub-path for a PI provider's models.json override, following the gateway's URL * convention `/m//`. The `mode` selects the gateway route (gateway.yaml owns the * upstream + keys); the `provider` is both the PI `--provider` and the gateway endpoint segment. * * `provider` is required for pi profiles (validated at load time — no default, no fallback). Returns * undefined when `mode` is absent — the PI adapter then falls back to the default `/` path * (direct per-provider routing, no `/m/` mode indirection). * * Keeping this derivation in code (not in the profile) means profiles only carry the logical * `mode` name; no gateway path string leaks into profiles.json. */ export declare function buildPiGatewaySubPath(mode: string | null, provider: string): string | undefined; /** Plugins that load only for sessions originating from a specific platform channel. * Mirrors the channel-gated MCP loading (loadFeishuMcp = channel.startsWith('feishu:')): * the cortex-feishu skill bundle is only relevant when the user is working inside Feishu, * so it is stripped from non-Feishu sessions even when listed in an agent's pluginDirs. */ export declare const CHANNEL_SCOPED_PLUGINS: ReadonlyArray<{ plugin: string; channelPrefix: string; }>; /** Drop channel-scoped plugin dirs whose channel prefix the current session does not match. * Non-scoped plugins always pass through. Matched by the plugin dir's final path segment * (basename) so substrings like `cortex-feishu-x` are not affected. */ export declare function filterChannelScopedPlugins(dirs: string[] | undefined, channel: string | undefined): string[] | undefined; export declare function buildAgentSpawnConfig(options: RunAgentOptions, config: AgentConfig, anthropicBaseUrl: string | undefined): AgentSpawnConfig;