export type Message = import("../types").Message; export type ToolDef = import("../types").ToolDef; export type ParsedEnvelope = { action: "tool_call" | "final_answer"; toolName?: string | undefined; toolArguments?: Record | undefined; answer?: string | undefined; usage: import("../types").Usage | null; model?: string | null | undefined; costUsd?: number | undefined; }; /** * The JSON envelope the CLI is constrained to (claude `--json-schema`). `tool_call` carries the * name + args; `final_answer` carries prose. A closed `action` enum is the discriminator. * @type {string} */ export const ENVELOPE_SCHEMA: string; /** * One tool's signature line for the manifest. Protocol-agnostic. * @param {ToolDef} t * @returns {string} */ export function toolLine(t: ToolDef): string; /** * Build the tool-mode system prompt: the caller's own system stance (if any) + the tool manifest + * the envelope contract. The contract text is load-bearing — the step-2 probe showed a weak model * that BELIEVES it must execute the tool itself answers in prose ("I attempted… I failed"), so the * prompt states plainly that EMITTING the envelope IS the call and "attempting/failing" is not a * thing it can do. Protocol-agnostic (the envelope vocabulary is shared across CLIs). * @param {string|null} baseSystem - the caller's system message content, or null. * @param {ToolDef[]} tools * @returns {string} */ export function buildToolSystemPrompt(baseSystem: string | null, tools: ToolDef[]): string; /** * Render the Loop's OpenAI-shaped transcript into a plain-text conversation a CLI can read. The * load-bearing part: assistant `tool_calls` and `role:'tool'` results must SURVIVE (the default * `_formatPrompt` drops them), and each result must trace to the call that produced it (id → name). * Protocol-agnostic. The system message is excluded here — it rides the CLI's system-prompt flag. * @param {Message[]} messages * @returns {string} */ export function renderTranscript(messages: Message[]): string; /** * Map the claude `--output-format json` OUTER envelope's usage / model / cost onto neutral shapes. * Shared by tool-mode {@link CLAUDE_TOOL_PROTOCOL.parseResult} and the plain-text `_parseClaudeJson` * preset so the claude usage contract (token tiers, `modelUsage` first-key, `total_cost_usd`) lives * in exactly ONE place — a future CLI format change touches this function, not two copies. * @param {any} outer - the parsed outer CLI envelope (already validated non-null by the caller). * @returns {{usage: import('../types').Usage|null, model: string|null, costUsd?: number}} */ export function mapClaudeMeta(outer: any): { usage: import("../types").Usage | null; model: string | null; costUsd?: number; }; export namespace CLAUDE_TOOL_PROTOCOL { let name: string; /** * The extra CLI args for one tool-mode turn, appended after the caller's base args (`-p --model X`). * `--tools ''` + `--strict-mcp-config` strip the CLI's own tools/MCP to a bare brain (step 1); * `--setting-sources ''` suppresses cwd CLAUDE.md/memory/settings auto-discovery — a MEASURED * ~18× cost drop (37,423 → 2,026 tokens/turn, step 2), load-bearing for a subscription strategy; * `--system-prompt` REPLACES the CLI's prompt (vs --append); `--json-schema` + `--output-format * json` force the parseable envelope. * @param {string} systemPrompt * @returns {string[]} */ function turnArgs(systemPrompt: string): string[]; /** * Parse claude's `--output-format json` stdout into a neutral {@link ParsedEnvelope}. A malformed * or error envelope is a LOUD `ProviderError` — NEVER a silent fall-through to prose (the whole * point is that a broken tool turn cannot masquerade as a final answer, the BA-6 failure shape). * @param {string} stdout * @returns {ParsedEnvelope} */ function parseResult(stdout: string): ParsedEnvelope; namespace probe { let system: string; let user: string; function isCapable(parsed: ParsedEnvelope): boolean; } } /** Resolve a `toolProtocol` option to an adapter. Claude-only for now; unknown names throw. */ export function resolveToolProtocol(name: any): { name: string; /** * The extra CLI args for one tool-mode turn, appended after the caller's base args (`-p --model X`). * `--tools ''` + `--strict-mcp-config` strip the CLI's own tools/MCP to a bare brain (step 1); * `--setting-sources ''` suppresses cwd CLAUDE.md/memory/settings auto-discovery — a MEASURED * ~18× cost drop (37,423 → 2,026 tokens/turn, step 2), load-bearing for a subscription strategy; * `--system-prompt` REPLACES the CLI's prompt (vs --append); `--json-schema` + `--output-format * json` force the parseable envelope. * @param {string} systemPrompt * @returns {string[]} */ turnArgs(systemPrompt: string): string[]; /** * Parse claude's `--output-format json` stdout into a neutral {@link ParsedEnvelope}. A malformed * or error envelope is a LOUD `ProviderError` — NEVER a silent fall-through to prose (the whole * point is that a broken tool turn cannot masquerade as a final answer, the BA-6 failure shape). * @param {string} stdout * @returns {ParsedEnvelope} */ parseResult(stdout: string): ParsedEnvelope; /** * Capability-probe assets. The probe mirrors REAL-TASK shape — a question whose answer the model * cannot know, with a tool that yields it, and NO "call the tool" instruction — because a trivial * "call capability_ping" instruction is a FALSE POSITIVE: haiku emits it 4/4 yet fails real tasks * 0/5 (proven in `poc/clipipe-tools-04-capability-probe.mjs`). The question shape sorts cleanly: * sonnet CAPABLE 4/4, haiku INCAPABLE 0/4, stable. Capable iff it emits a `tool_call` for the tool. */ probe: { system: string; user: string; /** @param {ParsedEnvelope} parsed @returns {boolean} */ isCapable: (parsed: ParsedEnvelope) => boolean; }; };