/** * LLM Client — execução real de modelos via HTTP (fetch nativo, zero deps). * * Abstrai providers em ModelAdapter (OpenAI-compatible + Anthropic) e expõe * um cliente único que o runtime usa para produzir artefatos de verdade. * * Configuração via env: * IZANAGI_OPENAI_API_KEY (ou OPENAI_API_KEY) — provider "openai" * IZANAGI_OPENAI_BASE_URL — override (ex.: proxy/offline) * IZANAGI_ANTHROPIC_API_KEY (ou ANTHROPIC_API_KEY) — provider "anthropic" * IZANAGI_OPENROUTER_API_KEY (ou OPENROUTER_API_KEY) — provider "openrouter" * IZANAGI_OLLAMA_ENABLED=1 (ou IZANAGI_OLLAMA_BASE_URL) — provider "ollama" (default http://localhost:11434/v1) * IZANAGI_LMSTUDIO_ENABLED=1 (ou IZANAGI_LMSTUDIO_BASE_URL) — provider "lmstudio" (default http://localhost:1234/v1) * IZANAGI_CUSTOM_BASE_URL / IZANAGI_CUSTOM_API_KEY — provider "custom" (qualquer endpoint OpenAI-compatible) * IZANAGI_LLM_TIMEOUT_MS — timeout por chamada (default 120s) * * Ollama e LM Studio expõem endpoint OpenAI-compatible nativamente * (`/v1/chat/completions`) — por isso reaproveitam o mesmo wire format do * OpenAI em vez de um protocolo próprio. Não exigem API key (rodam * localmente), mas por isso mesmo exigem opt-in explícito via *_ENABLED ou * *_BASE_URL — sem isso, "configured" ficaria sempre true e quebraria o modo * headless de quem nunca configurou nada. Uma eventual falha de conexão * (servidor local não está de pé) aparece como erro de rede real na primeira * chamada — não é um provider fake. * * ZERO-CONFIG: além dos providers acima (que exigem chave ou servidor local), * o cliente registra os CLIs de agente já instalados e autenticados na máquina * (`claude` -> provider `claude-cli`, ver runtime/llm/agent-cli.ts). Detectado * o binário no PATH, `izanagi run` executa trabalho de verdade sem nenhuma * chave de API e sem modelo local. Desligue com IZANAGI_AGENT_CLI_DISABLED=1. * * Sem chave, sem servidor local e sem CLI de agente, o framework continua 100% * funcional em modo headless (gera prompt) — o executor apenas informa que não * está configurado. * * Cache-Aware Prompt Compression (CAPC): o system prompt pode carregar o * delimitador `` (ver runtime/llm/prompt-cache.ts). * A detecção é AUTOMÁTICA dentro de cada adapter — nenhum chamador precisa * mudar: Anthropic ganha blocos com cache_control no prefixo estático quando * ele atinge o piso de 1024 tokens; providers OpenAI-compatible recebem o * conteúdo estável primeiro (prefix caching automático, wire format inalterado). */ /** Reexports públicos das utilidades de cache (mesma heurística, fonte única). */ export { DYNAMIC_MARKER, MIN_CACHEABLE_TOKENS, splitStaticDynamic, joinWithoutMarker, estimateStaticTokens, isPromptCacheEligible } from './prompt-cache.js'; /** Reexports públicos do executor sem chave (CLI de agente já autenticado na máquina). */ export { AgentCLIAdapter, AGENT_CLI_PROVIDERS, KNOWN_AGENT_CLI_PROVIDERS, AGENT_CLI_OVERHEAD_TOKENS, AGENT_CLI_TOKENS_PER_NODE, AGENT_CLI_MIN_RECOMMENDED_BUDGET, AGENT_CLI_MIN_BUDGET_WITH_TOOLS, AGENT_CLI_TOKENS_PER_NODE_WITH_TOOLS, measuredTokensPerNode, recommendedBudget, AGENT_CLI_SPECS, KNOWN_AGENT_CLI_SPECS, availableAgentCLIProviders, agentCLIStatus, claudeCLISpec, defaultAgentCLIAdapters, findExecutable, toolPolicyFromEnv, currentDepth, type AgentCLISpec, type AgentCLIToolPolicy, } from './agent-cli.js'; /** Reexports públicos do AgentDiet (observation masking determinístico). */ export { dietHistory, summarizeObservation, MIN_TURNS, RECENT_WINDOW, MAX_OBS_CHARS } from './session-diet.js'; export interface CompletionMessage { role: 'system' | 'user' | 'assistant'; content: string; } export interface CompletionOptions { model: string; system?: string; messages: CompletionMessage[]; maxTokens?: number; temperature?: number; /** * AgentDiet (observation masking): quando true, aplica `dietHistory()` ao * histórico ANTES de despachar ao adapter — observações antigas e longas * (fora da janela recente) viram resumos sintéticos de 1 linha; mensagens * 'system' e a janela recente ficam byte-a-byte. Default (ausente/false): * histórico segue intacto, comportamento idêntico ao pré-AgentDiet. */ diet?: boolean; /** * Sinal de cancelamento do run. Combinado com o timeout HTTP interno: a * requisicao aborta pelo que vier primeiro. Sem isto, cancelar um run * deixava as requisicoes em voo ate o timeout delas. */ signal?: AbortSignal; /** * Teto de custo desta chamada, em USD. Só tem efeito em providers que * aceitam teto por chamada (hoje: os CLIs de agente, via `--max-budget-usd`). * Providers HTTP ignoram: a API não expõe onde aplicar isso. */ maxCostUsd?: number; /** * Política de tools do subprocesso, para providers de CLI de agente: * `none` (default, nenhuma tool), `read` (leitura do repositório) ou * `write` (leitura + escrita de arquivo). Ignorada por providers HTTP. */ toolPolicy?: 'none' | 'read' | 'write'; /** * Agente nativo do host que deve assumir a sessão (passthrough opcional * para CLIs de agente, ex.: `--agent architect`). Ignorado por HTTP. */ agent?: string; } export interface CompletionResult { text: string; tokens: number; latencyMs: number; model: string; provider: string; /** * Tokens servidos do cache de prompt pelo provider (quando reportado): * Anthropic `cache_read_input_tokens`, OpenAI `prompt_tokens_details.cached_tokens`, * Google `usageMetadata.cachedContentTokenCount`. Ausente = provider não reportou. */ cachedTokens?: number; /** * Custo REAL desta chamada em USD, quando o provider o reporta (hoje: CLI de * agente, campo `total_cost_usd`). Ausente = ninguém mediu, e o chamador * deve continuar estimando por tabela de preço. Um número medido e um * número estimado não podem ocupar o mesmo campo sem se confundirem. */ costUsd?: number; } export interface ModelAdapter { readonly provider: string; readonly configured: boolean; complete(opts: CompletionOptions): Promise; } /** Provider OpenAI (e qualquer API compatível via base URL). */ export declare class OpenAIAdapter implements ModelAdapter { readonly provider = "openai"; private readonly apiKey; private readonly baseUrl; constructor(apiKey?: string, baseUrl?: string); get configured(): boolean; complete(opts: CompletionOptions): Promise; } /** Provider OpenRouter — roteador multi-modelo OpenAI-compatible, requer API key própria. */ export declare class OpenRouterAdapter implements ModelAdapter { readonly provider = "openrouter"; private readonly apiKey; private readonly baseUrl; constructor(apiKey?: string, baseUrl?: string); get configured(): boolean; complete(opts: CompletionOptions): Promise; } /** * Provider Ollama — modelo local, endpoint OpenAI-compatible nativo * (`/v1/chat/completions`, disponível desde a v0.1.x do Ollama). Sem API key * — mas "configured" NÃO pode ser sempre true por padrão: isso quebraria o * modo headless existente (zero env vars → `izanagi run` deveria simular, * não tentar bater numa porta local que ninguém pediu para usar). Exige opt-in * explícito: IZANAGI_OLLAMA_ENABLED=1 ou IZANAGI_OLLAMA_BASE_URL setado. */ export declare class OllamaAdapter implements ModelAdapter { readonly provider = "ollama"; private readonly baseUrl; private readonly enabled; constructor(baseUrl?: string, enabled?: boolean); get configured(): boolean; complete(opts: CompletionOptions): Promise; } /** Provider LM Studio — modelo local, mesmo raciocínio do Ollama (endpoint OpenAI-compatible, sem key, opt-in explícito). */ export declare class LMStudioAdapter implements ModelAdapter { readonly provider = "lmstudio"; private readonly baseUrl; private readonly enabled; constructor(baseUrl?: string, enabled?: boolean); get configured(): boolean; complete(opts: CompletionOptions): Promise; } /** * Provider "custom" — qualquer endpoint OpenAI-compatible que não seja um dos * nomeados acima (proxy interno, gateway próprio, outro runtime local). Ao * contrário de Ollama/LM Studio, não tem base URL default: sem * IZANAGI_CUSTOM_BASE_URL configurado, fica "not configured" de propósito — * não há endpoint sensato a assumir. */ export declare class CustomOpenAICompatibleAdapter implements ModelAdapter { readonly provider = "custom"; private readonly apiKey; private readonly baseUrl; constructor(apiKey?: string, baseUrl?: string); get configured(): boolean; complete(opts: CompletionOptions): Promise; } /** Provider Anthropic (Messages API) com prompt caching no prefixo estático. */ export declare class AnthropicAdapter implements ModelAdapter { readonly provider = "anthropic"; private readonly apiKey; private readonly baseUrl; constructor(apiKey?: string, baseUrl?: string); get configured(): boolean; /** * System → wire format cache-aware: * - estático >= MIN_CACHEABLE_TOKENS (1024): array de blocos, com * cache_control ephemeral APENAS no prefixo estático (o sufixo dinâmico * fica num bloco separado, fora do cache); * - caso contrário: string simples exatamente como antes (retrocompatível — * o provider ignoraria o header abaixo do piso de qualquer forma). * Sem system, o campo segue ausente do payload. */ private static systemToWire; complete(opts: CompletionOptions): Promise; } /** Provider Google (Gemini — API OpenAI-compatible via generativelanguage). */ export declare class GoogleAdapter implements ModelAdapter { readonly provider = "google"; private readonly apiKey; private readonly baseUrl; constructor(apiKey?: string, baseUrl?: string); get configured(): boolean; complete(opts: CompletionOptions): Promise; } /** * Cliente único: resolve o adapter do provider e executa. * * CAPC é automático: se o `system` contiver ``, cada * adapter aplica a estratégia de cache do seu provider por conta própria * (blocos cache_control no Anthropic, prefixo estável nos OpenAI-compatible, * system_instruction estável no Google). Chamadores existentes (run/chat/ * dashboard/arena) não precisam de NENHUMA mudança — basta incluir o * delimitador no system quando houver parte volátil. */ export declare class LLMClient { private readonly adapters; constructor(adapters?: ModelAdapter[]); /** Se algum adapter está configurado (tem API key). */ get configured(): boolean; /** Providers configurados (com chave). */ configuredProviders(): string[]; isConfigured(provider: string): boolean; complete(provider: string, opts: CompletionOptions): Promise; } //# sourceMappingURL=client.d.ts.map