/**
 * Tool-call log entry construction — shared by the Anthropic and OpenAI loops.
 *
 * Both backends record every tool invocation in a `ToolCallEntry[]` that the
 * provider exposes as `metadata.toolCalls`. Centralizing entry construction
 * keeps error capture consistent: a failed call records a structured `error`
 * (and `errorCode` when the thrown error carried a JSON-RPC code) rather than
 * encoding the failure only inside the `output` string.
 */
import { boundToolOutput } from "./tool-output-bound.js";
/**
 * Build a log entry for a completed tool call.
 *
 * `output` is the (possibly truncated) content the model actually saw. `error`
 * is set when the MCP server returned an `isError` result — the error text
 * lives in `output`, and recording it on `error` lets assertions and telemetry
 * read it without re-parsing the output. When `bound.truncated` is set, the
 * entry records that the model saw a truncated copy plus the original size, so
 * a degraded run is distinguishable from a clean one.
 */
export function toolResultEntry(name, input, output, error, bound, timing) {
    return {
        name,
        input,
        output,
        ...(error !== undefined ? { error } : {}),
        ...(bound?.truncated
            ? { truncated: true, originalOutputLength: bound.originalLength }
            : {}),
        ...(timing !== undefined
            ? { durationMs: timing.durationMs, turnIndex: timing.turnIndex }
            : {}),
    };
}
/**
 * Bound a tool result, record it, and return the content to feed back to the
 * model. Shared by every tool-loop backend so the context-window guard is
 * transport-agnostic: the raw content is capped at `maxOutputChars`, the
 * (possibly truncated) copy is appended to `log`, and a truncation is logged
 * to stderr so a degraded run is visible. Returns the bounded content.
 */
export function recordBoundedToolResult(log, name, input, rawContent, error, maxOutputChars, timing) {
    const bound = boundToolOutput(rawContent, maxOutputChars);
    if (bound.truncated) {
        console.warn(`[mcp-tool-provider] Truncated "${name}" tool output ` +
            `(${bound.originalLength} chars) to fit the model context window`);
    }
    log.push(toolResultEntry(name, input, bound.content, error, bound, timing));
    return bound.content;
}
/**
 * Build a log entry for a tool call that threw before returning a result
 * (transport failure, protocol error). MCP `McpError`s carry a numeric
 * JSON-RPC `code` (e.g. `-32602`); capture it as `errorCode` when present.
 */
export function toolErrorEntry(name, input, err, timing) {
    const message = err instanceof Error ? err.message : String(err);
    const code = err.code;
    return {
        name,
        input,
        output: `Error: ${message}`,
        error: message,
        ...(typeof code === "number" ? { errorCode: code } : {}),
        ...(timing !== undefined
            ? { durationMs: timing.durationMs, turnIndex: timing.turnIndex }
            : {}),
    };
}
