import { AgentName, AutonomyLevel, ModelProfile } from "../types/config.js"; import { AgentContext } from "../agents/base.js"; import { Decision } from "../types/decisions.js"; import { Escalation } from "../types/escalation.js"; export type BackendType = "llm" | "agent"; export interface BackendRequest { persona: AgentName; workflow: string; task: string; context: AgentContext; autonomy: AutonomyLevel; } export interface Artifact { path: string; content: string; operation: "create" | "update" | "delete"; } export interface TokenUsage { input_tokens: number; output_tokens: number; total_tokens: number; estimated_cost_usd: number; } export interface BackendResult { success: boolean; output: string; artifacts: Artifact[]; decisions: Decision[]; escalations: Escalation[]; usage: TokenUsage; error?: string; } export interface IntelligenceBackend { readonly name: string; readonly type: BackendType; isAvailable(): Promise; execute(request: BackendRequest): Promise; } export interface LLMBackendConfig { base_url: string; model_profile: ModelProfile; model?: string; timeout_ms?: number; } export interface OllamaLocalConfig extends LLMBackendConfig { base_url: string; model_profile: ModelProfile; model?: string; timeout_ms?: number; } export interface OllamaCloudConfig extends LLMBackendConfig { base_url: string; api_key_env: string; model_profile: ModelProfile; model?: string; timeout_ms?: number; } export interface OpencodeBackendConfig { enabled: boolean; executable?: string; } export interface BackendConfigSection { provider: "auto" | "opencode" | "ollama-local" | "ollama-cloud"; fallback?: "opencode" | "ollama-local" | "ollama-cloud"; agent_backends: { opencode?: OpencodeBackendConfig; }; llm_backends: { "ollama-local"?: OllamaLocalConfig; "ollama-cloud"?: OllamaCloudConfig; }; } export const DEFAULT_BACKEND_CONFIG: BackendConfigSection = { provider: "auto", agent_backends: { opencode: { enabled: true }, }, llm_backends: { "ollama-local": { base_url: "http://localhost:11434", model_profile: "balanced", }, "ollama-cloud": { base_url: "", api_key_env: "OLLAMA_CLOUD_API_KEY", model_profile: "quality", timeout_ms: 60000, }, }, }; export class BackendUnavailableError extends Error { readonly backendName: string; readonly agentName?: string; constructor(backendName: string, agentName?: string) { const agentMsg = agentName ? ` (agent: ${agentName})` : ""; super( `Intelligence backend "${backendName}" is not available${agentMsg}. ` + `Configure one of:\n` + ` 1. Install opencode: npm i -g opencode\n` + ` 2. Run Ollama locally: ollama serve\n` + ` 3. Set OLLAMA_CLOUD_API_KEY for remote inference` ); this.name = "BackendUnavailableError"; this.backendName = backendName; this.agentName = agentName; } } export function emptyTokenUsage(): TokenUsage { return { input_tokens: 0, output_tokens: 0, total_tokens: 0, estimated_cost_usd: 0 }; } export function emptyBackendResult(error?: string): BackendResult { return { success: false, output: "", artifacts: [], decisions: [], escalations: [], usage: emptyTokenUsage(), error, }; }