import type { BackendAdmissionClass, ContextPolicy, GroundingBundle, InvokeFailureKind, Orchestrator as OrchestratorConfig, OutputContract, RunMetadata } from '@mmnto/totem'; import { TotemOrchestratorError } from '@mmnto/totem'; export type RuntimeInvokeRoute = 'sdk' | 'cli-fallback' | 'configured-shell' | 'quota-model-fallback'; /** * Byte-bounded process text retained in memory until the CLI seam applies * secret masking. This is intentionally distinct from core's persisted * `BoundedTextEvidence`: shell execution must never claim raw text is masked. */ export interface RuntimeBoundedTextEvidence { encoding: 'utf-8'; head: string; tail?: string; observedBytes: number; retainedBytes: number; limitBytes: number; truncated: boolean; } export interface RuntimeProcessEvidence { exitCode: number | null; signal: NodeJS.Signals | null; timedOut: boolean; timeoutMs?: number; stdout?: RuntimeBoundedTextEvidence; stderr?: RuntimeBoundedTextEvidence; } /** Raw, bounded invocation evidence. `runOrchestrator` masks it before persistence. */ export interface RuntimeInvokeAttemptEvidence { sequence: number; route: RuntimeInvokeRoute; provider: string; model: string; status: 'succeeded' | 'failed'; durationMs: number; failureKind?: InvokeFailureKind; providerStatus?: number; providerCode?: string; process?: RuntimeProcessEvidence; } export interface OrchestratorResult { content: string; inputTokens: number | null; outputTokens: number | null; durationMs: number; finishReason?: string; /** * Tokens read from prompt cache on this call (mmnto/totem#1291 Phase 2). Populated by * providers that support prompt caching when `enableContextCaching` is true * and a cache hit occurred. Null when caching wasn't requested or the * provider doesn't support it. Distinct from `inputTokens`, which counts * cached + uncached + ephemeral combined for the request as a whole. */ cacheReadInputTokens?: number | null; /** * Tokens written to prompt cache on this call (mmnto/totem#1291 Phase 2). Populated * only when a cache miss occurred and the provider wrote a new cache entry. * Null otherwise. */ cacheCreationInputTokens?: number | null; /** * Raw bounded execution provenance. Present only when transport provenance * is material (configured shell or a fallback leg); masked before artifacts * are persisted. */ attempts?: RuntimeInvokeAttemptEvidence[]; } export interface OrchestratorInvokeOptions { prompt: string; /** * Optional persistent system context that providers may cache (mmnto/totem#1291 * Proposal 217). When provided AND `enableContextCaching` is true, * Anthropic providers (Phase 2) will mark this with a `cache_control: * ephemeral` directive so subsequent calls within the TTL window read * from prompt cache instead of paying full input-token cost. Backward * compatible: when omitted, the call shape is identical to today * (single user message, no caching). */ systemPrompt?: string; model: string; cwd: string; tag: string; totemDir: string; /** LLM temperature: 0 = deterministic, 0.7 = creative. Caller sets per use case. */ temperature?: number; /** * Whether to request provider-native prompt caching (mmnto/totem#1291 Phase 2). * Threaded through from `orchestrator.enableContextCaching` config. When * true AND `systemPrompt` is provided, the provider implementation MAY * emit a cache directive. When false (default), providers behave exactly * as today. */ enableContextCaching?: boolean; /** * Cache TTL in seconds (mmnto/totem#1291 Phase 2). 300 = 5min (Anthropic default * ephemeral), 3600 = 1h (Anthropic extended cache). Only consulted by * providers that support caching when `enableContextCaching` is true. */ cacheTTL?: number; /** Neutral task identity for routing/telemetry. Defaults to `tag` at the CLI seam — `tag` stays the UI/cache key. */ task?: string; /** The delivered grounding identity (mmnto-ai/totem#2101), reconciled with `artifact.bundle` at the CLI seam. */ groundingBundle?: GroundingBundle; /** Requested admission class — gated against `orchestrator.capabilities.admissionClasses` BEFORE any invoke. */ backendAdmissionClass?: BackendAdmissionClass; /** Advisory context policy (budget unit: input tokens). Recorded, never enforced here. */ contextPolicy?: ContextPolicy; /** Caller-declared output contract. Read by #2103 post-checks, never by providers. */ outputContract?: OutputContract; /** Caller identity metadata, recorded verbatim into the run artifact. */ runMetadata?: RunMetadata; } /** A provider-bound function that invokes an LLM and returns the result. */ export type InvokeOrchestrator = (options: OrchestratorInvokeOptions) => Promise; /** * Stable invocation failure surface consumed by run-artifact persistence and * review-fan diagnostics. Process text in `attempts` is bounded but not yet * DLP-masked; callers must not persist it directly. */ export declare class OrchestratorInvokeError extends TotemOrchestratorError { readonly code: "ORCHESTRATOR_UNAVAILABLE"; readonly kind: InvokeFailureKind; readonly attempts: RuntimeInvokeAttemptEvidence[]; failureArtifactHash?: string; constructor(message: string, kind: InvokeFailureKind, attempts: RuntimeInvokeAttemptEvidence[], options?: { cause?: unknown; failureArtifactHash?: string; recoveryHint?: string; }); } export interface InvokeFailureContext { timedOut?: boolean; spawnFailed?: boolean; exitCode?: number | null; signal?: NodeJS.Signals | null; } /** * Deterministically classify an invocation failure. Structured process facts * and provider status/code win over message heuristics; unmatched failures * remain fail-honest as `unknown`. */ export declare function classifyInvokeFailure(err: unknown, context?: InvokeFailureContext): InvokeFailureKind; /** * Normalize any provider throw at the invocation boundary. Existing structured * errors retain identity; legacy Totem/provider errors remain available as the * cause and keep their recovery hint while gaining typed attempt evidence. */ export declare function toOrchestratorInvokeError(args: { err: unknown; provider: string; model: string; route: RuntimeInvokeRoute; durationMs: number; }): OrchestratorInvokeError; /** * Detect the active package manager from the `npm_config_user_agent` env var * (set by npm, pnpm, yarn, and bun when running scripts). Falls back to `npm`. */ export declare function detectPackageManager(): string; /** * Detect whether an error is a rate-limit / quota-exhaustion response. * Used by both Gemini and Anthropic orchestrators to normalize QuotaError. */ export declare function isQuotaError(err: unknown): boolean; export declare const KNOWN_PROVIDERS: readonly ["gemini", "anthropic", "openai", "ollama", "shell"]; /** * Parse a `provider:model` string into its components. * If the prefix before the first colon is a known provider, splits it out. * Otherwise, returns the full string as the model with the default provider. */ export declare function parseModelString(value: string, defaultProvider: string): { provider: string; model: string; }; /** * Validate a model name string against shell-safety gates. Single source of * truth for both `resolveOrchestrator` (config-load, raw provider:model * input) and `invokeShellOrchestrator` (shell-interpolation, post-parse * stripped model input). * * Two gates applied to the input string as-is: * 1. **Leading-dash reject.** Blocks shell-option tricks like `--exec`. * 2. **Allow-list regex.** `MODEL_NAME_RE` restricts to word chars, * dots, slashes, colons, underscores, and hyphens — covers every * model identifier used in practice (provider-qualified, namespace/ * model, ollama quantized tags). * * Gates 1 + 2 are safe to apply at ANY stage — raw `provider:model` strings * and stripped model-portions both pass the same allow-list. The post-parse * "model-portion not empty and not dash-prefixed" check (Gate 3) lives * inline in `resolveOrchestrator` where the split happens, NOT in this * shared helper — applying it to an already-stripped model causes a * double-parse that falsely rejects valid names like `foo:-bar` that were * safe pre-split (Shield catch on mmnto/totem#1429 GCA round 2). * * CR catch on mmnto/totem#1429 round 1: exporting only the regex created * a drift vector where the shell path could diverge from the config path. * This helper closes that vector for the checks that BOTH paths need. */ export declare function assertValidModelName(rawModel: string): void; export interface ResolvedOrchestrator { parsed: { provider: string; model: string; }; invoke: InvokeOrchestrator; qualifiedModel: string; } /** * Parse and validate a model string, resolve cross-provider routing, * and return the appropriate invoker. Centralizes the validation logic * to guarantee symmetric validation across primary and fallback paths. */ export declare function resolveOrchestrator(rawModel: string, baseProvider: string, baseInvoke: InvokeOrchestrator): ResolvedOrchestrator; /** Map provider names to their CLI command templates. {file} and {model} are replaced at runtime. */ export declare const CLI_FALLBACK_COMMANDS: Readonly>; /** * Create an orchestrator invoker bound to the given provider config. * SDK-based providers are wrapped with CLI fallback logic: if the SDK * or API key is missing but the provider's CLI is on PATH, Totem falls * back to the shell orchestrator automatically. */ export declare function createOrchestrator(config: OrchestratorConfig): InvokeOrchestrator; //# sourceMappingURL=orchestrator.d.ts.map