/** * Shared tool-runner — wires timeout/fallback, Ollama generate, envelope, * residency probe, and NDJSON logging so each tool handler stays thin. * * Tools describe *what* they want; the runner handles *how*. */ import type { GenerateRequest } from "../ollama.js"; import type { Tier } from "../tiers.js"; import type { Envelope } from "../envelope.js"; import type { RunContext } from "../runContext.js"; export interface RunToolInput { tool: string; tier: Tier; ctx: RunContext; allowFallback?: boolean; /** Build the generate request for the given (possibly-fallback) tier. */ build: (tier: Tier, model: string) => GenerateRequest; /** Turn the raw model response into the tool's result shape. */ parse: (raw: string) => T; /** Optional extra warnings from guardrails (e.g. stripped citations). */ warnings?: string[]; /** * Override `think` on the generate request. If unset, inherits whatever * build() set. Recommended: tools set it explicitly per shape via * THINK_BY_SHAPE so Qwen 3 thinking behavior is predictable. Non-thinking * models (hermes3:8b) ignore the field. */ think?: boolean; /** * Optional per-call model override (atom tools only — added v2.3.0). When * set, the FIRST attempt on the requested tier runs against this model * instead of the tier-resolved default. On timeout, fallback retries * resolve their model from the fallback tier — NOT this override. The * caller-asked model is propagated to `envelope.model_requested` so * receipt-backed orchestrators can detect substitution by comparing * `model_requested` vs `model`. */ modelOverride?: string; /** * R-019 (v2.6.0) — optional per-call tier-budget override in milliseconds. * * When set, this value replaces the active profile's per-tier `timeouts` * for THIS call only — applied uniformly to every tier the cascade visits * (initial + any fallback). Other callers and tool invocations are * unaffected. When omitted, the profile defaults govern byte-identically * to pre-R-019 behavior. * * Validated upstream at the schema layer (e.g. extract.ts * `tier_budget_ms_override`) — this field is the runner-internal channel * and trusts its caller. Bounds are not re-checked here. * * Motivating use case: research-os synth prose `--planner-timeout-ms` * (R-018) was missing its target mechanism because the R-018 wrapper sits * outside the MCP call and never sees structured TIER_TIMEOUT responses. * Threading the operator's budget through here makes the inner * `runWithTimeoutAndFallback` honor the operator's intent. */ tierBudgetMsOverride?: number; /** * F2b (v2.9) — optional per-call backend directive. * * 'cloud' escalates THIS call to Ollama Cloud: it is the only way a call * reaches cloud in standby mode (OLLAMA_API_KEY set, OLLAMA_CLOUD_PRIMARY * unset), a no-op under cloud-primary (cloud is already the default), * and a hard CLOUD_NOT_CONFIGURED refusal when no cloud is configured — * the call is never silently served local while claiming escalation. * 'local' pins THIS call local (zero egress) even under cloud-primary. * Omitted → the mode default. Envelope `backend`/`degraded`/ * `degrade_reason` carry the provenance either way. */ backend?: "cloud" | "local"; } export declare function runTool(input: RunToolInput): Promise>; //# sourceMappingURL=runner.d.ts.map