UNPKG

@nanocollective/nanocoder

Version:

A local-first CLI coding agent that brings the power of agentic coding tools like Claude Code and Gemini CLI to local models or controlled APIs like OpenRouter

108 lines 4.17 kB
/** * TYPE PRESERVATION STRATEGY EXPLAINED * ===================================== * * "Preserving types" does NOT mean keeping everything as objects/arrays in memory. * It means: * * 1. When receiving LLM responses (which can be ANY type): * - We accept unknown types (string, object, array, null, undefined) * - We convert to string ONLY for PARSING OPERATIONS * - We preserve the original type in the tool call structure * * 2. When storing ToolCall.arguments: * - MUST preserve as Record<string, unknown> (object type) * - NOT convert to string * - Enables direct property access without JSON.parse * * 3. When displaying/writing to disk: * - Convert to string for display/storage operations * - Use JSON.stringify for objects/arrays * - Use String() for primitives * * The confusion comes from mixing up: * - "Preserve types in memory" (CRITICAL: ToolCall.arguments stays as object) * - "Convert to string for processing" (NECESSARY: Parser expects strings) * * This formatter handles the INCOMING data, then the parser handles the * conversion to ToolCall format with type preservation. */ import type { ToolCall } from '../types/index.js'; /** * Result of normalizing an LLM response * Contains the raw response, processed content, extracted tool calls, and metadata */ export interface NormalizedResponse { /** The original response from the LLM (unknown type for maximum flexibility) */ raw: unknown; /** The content after normalization (always a string for parsing) */ content: string; /** Any tool calls extracted during normalization */ toolCalls: ToolCall[]; /** Metadata about the response for debugging and strategy selection */ metadata: ResponseMetadata; } /** * Metadata about the normalized response * Used for: * - Debugging and logging * - Selecting the best parsing strategy * - Error handling and recovery */ export interface ResponseMetadata { /** Whether response contained markdown code blocks */ hasCodeBlocks: boolean; /** Whether response contained XML tags */ hasXMLTags: boolean; /** Whether response contained JSON tool call structures */ hasJSONBlocks: boolean; /** Confidence level in the response type classification */ confidence: 'high' | 'medium' | 'low'; /** Detected response format */ detectedFormat: 'plain' | 'json' | 'xml' | 'mixed' | 'unknown'; /** Whether response appears to be malformed */ isMalformed: boolean; /** Detected error if malformed */ malformedError?: string; } /** * Main entry point for normalizing LLM responses * * This function handles all possible LLM response types: * - Plain strings (most common) * - JSON objects (with/without tool_calls field) * - Arrays (line-based content) * - Null/undefined (error responses) * - Mixed content (text + tool calls embedded) * * @param response - The raw response from the LLM (can be any type) * @param options - Configuration options * @returns A normalized response with content and extracted tool calls */ export declare function normalizeLLMResponse(response: unknown, options?: NormalizeOptions): Promise<NormalizedResponse>; /** * Formats a normalized response for debugging * * @param response - Normalized response to format * @returns Formatted string for debugging */ export declare function formatNormalizedResponse(response: NormalizedResponse): string; /** * Checks if a response is complete and ready for processing * * A response is complete if: * 1. It has content * 2. It has low confidence (means no tool calls were found, so no further processing needed) * 3. It's not malformed * * @param response - Normalized response to check * @returns True if response is complete */ export declare function isResponseComplete(response: NormalizedResponse): boolean; export interface NormalizeOptions { /** If true, keeps the raw object structure instead of JSON.stringify */ preserveRawTypes?: boolean; /** If true, extracts tool calls from mixed content (text + tool calls) */ allowMixedContent?: boolean; } //# sourceMappingURL=response-formatter.d.ts.map