import * as _opencode_ai_sdk_v2 from '@opencode-ai/sdk/v2'; import * as _ai_sdk_provider from '@ai-sdk/provider'; import { ProviderV3, LanguageModelV3, LanguageModelV3CallOptions, LanguageModelV3Content, LanguageModelV3Usage, SharedV3Warning, LanguageModelV3StreamPart, LoadAPIKeyError, APICallError, LanguageModelV3Prompt, LanguageModelV3FinishReason } from '@ai-sdk/provider'; /** * Options for creating a client manager. */ interface ClientManagerOptions { hostname?: string; port?: number; baseUrl?: string; autoStartServer?: boolean; serverTimeout?: number; cwd?: string; clientOptions?: OpencodeClientOptions; client?: OpencodeClient; logger?: Logger | false; } /** * Manages the OpenCode server and client lifecycle. * Uses singleton pattern to ensure only one server instance per process. */ declare class OpencodeClientManager { private static instance; private client; private server; private options; private logger; private initPromise; private isDisposed; private cleanupHandlersRegistered; private cleanupHandlers; private constructor(); /** * Get the singleton instance of the client manager. */ static getInstance(options?: ClientManagerOptions): OpencodeClientManager; /** * Create a standalone (non-singleton) client manager instance. * Use this when you need isolated client managers, e.g. for concurrent * sessions pointing at different servers. */ static createInstance(options: ClientManagerOptions): OpencodeClientManager; /** * Reset the singleton instance. * Used primarily for testing. */ static resetInstance(): void; /** * Update options for the client manager. */ private updateOptions; /** * Get or create the OpenCode client. * Will start the server if autoStartServer is true and server isn't running. */ getClient(): Promise; /** * Initialize the client and optionally the server. */ private initializeClient; /** * Check if an OpenCode server is running at the given URL. */ private isServerRunning; /** * Build client options with manager-owned baseUrl and directory. */ private createManagedClientOptions; /** * Get the server URL. */ getServerUrl(): string; /** * Check if the server was started by this manager. */ isServerManaged(): boolean; /** * Dispose of the client manager, stopping the server if managed. */ dispose(): Promise; /** * Register cleanup handlers for process exit. */ private registerCleanupHandlers; private unregisterCleanupHandlers; } /** * Create a client manager instance. * This is a convenience function that returns a singleton. */ declare function createClientManager(options?: ClientManagerOptions): OpencodeClientManager; /** * Create a client manager from provider settings. */ declare function createClientManagerFromSettings(settings: OpencodeProviderSettings, logger?: Logger | false): OpencodeClientManager; /** * Model ID format for OpenCode provider. * Can be: * - "providerID/modelID" (e.g., "anthropic/claude-opus-4-5-20251101") * - "modelID" (e.g., "claude-opus-4-5-20251101" - uses default provider) */ type OpencodeModelId = string; /** * OpenCode SDK client instance. */ type OpencodeClient = _opencode_ai_sdk_v2.OpencodeClient; /** * Full createOpencodeClient() options from OpenCode SDK. */ type OpencodeCreateClientOptions = NonNullable[0]>; /** * Provider passthrough options for createOpencodeClient(). * baseUrl and directory are managed by provider settings and model settings. */ type OpencodeClientOptions = Omit; /** * Logger interface for the OpenCode provider. */ interface Logger { warn: (message: string) => void; error: (message: string) => void; debug?: (message: string) => void; } /** * OpenCode session permission action. */ type OpencodePermissionAction = "allow" | "deny" | "ask"; /** * OpenCode session permission rule. */ interface OpencodePermissionRule { permission: string; pattern: string; action: OpencodePermissionAction; } /** * OpenCode permission ruleset. */ type OpencodePermissionRuleset = OpencodePermissionRule[]; /** * Settings for individual model instances. */ interface OpencodeSettings { /** * Resume an existing session by ID. * If not provided, a new session will be created on first request. */ sessionId?: string; /** * Force creation of a new session, even if one already exists. * @default false */ createNewSession?: boolean; /** * Title for newly created sessions. * @default "AI SDK Session" */ sessionTitle?: string; /** * Agent to use for requests. * Options: "build", "plan", "general", "explore", or custom agent name. */ agent?: string; /** * Custom system prompt to use. * This overrides the default agent system prompt. */ systemPrompt?: string; /** * Enable or disable specific tools. * Keys are tool names, values are boolean (enabled/disabled). * @example { "Bash": true, "Write": false } * @deprecated OpenCode v2 merges tools with permissions for most flows. */ tools?: Record; /** * Session permission ruleset. * Applied when creating a new session. */ permission?: OpencodePermissionRuleset; /** * OpenCode variant identifier. */ variant?: string; /** * Working directory for file operations. * @default process.cwd() * @deprecated Use `directory` for per-request routing. */ cwd?: string; /** * Request directory for OpenCode API calls. * If not provided, falls back to `cwd` and then SDK defaults. */ directory?: string; /** * Number of OpenCode retries for JSON schema output formatting. */ outputFormatRetryCount?: number; /** * Logger instance or false to disable logging. */ logger?: Logger | false; /** * Enable verbose logging. * @default false */ verbose?: boolean; } /** * Provider-level settings applied to all model instances. */ interface OpencodeProviderSettings { /** * Hostname for the OpenCode server. * @default "127.0.0.1" */ hostname?: string; /** * Port for the OpenCode server. * @default 4096 */ port?: number; /** * Full URL to the OpenCode server. * If provided, overrides hostname and port. */ baseUrl?: string; /** * Automatically start the OpenCode server if not running. * @default true */ autoStartServer?: boolean; /** * Timeout in milliseconds for server startup. * @default 10000 */ serverTimeout?: number; /** * Additional createOpencodeClient() options to pass through to the SDK. * Use this for custom headers, auth, fetch, serializers, validators, * transformers, throwOnError, and RequestInit-compatible options. * * `baseUrl` and `directory` are managed by provider/model settings. */ clientOptions?: OpencodeClientOptions; /** * Preconfigured OpenCode SDK client instance. * When provided, this client is used directly and server management is * bypassed. */ client?: OpencodeClient; /** * Custom client manager instance. * When provided, this manager is used instead of the shared singleton. * Use OpencodeClientManager.createInstance() to create isolated managers * for concurrent multi-session usage. */ clientManager?: OpencodeClientManager; /** * Default settings applied to all model instances. * Can be overridden per-model. */ defaultSettings?: OpencodeSettings; } /** * Provider interface for OpenCode. */ interface OpencodeProvider extends ProviderV3 { /** * Create a language model instance. * @param modelId - Model ID in format "providerID/modelID" or "modelID" * @param settings - Optional settings for this model instance */ (modelId: OpencodeModelId, settings?: OpencodeSettings): LanguageModelV3; /** * Create a language model instance. * @param modelId - Model ID in format "providerID/modelID" or "modelID" * @param settings - Optional settings for this model instance */ languageModel(modelId: OpencodeModelId, settings?: OpencodeSettings): LanguageModelV3; /** * Alias for languageModel(). * @param modelId - Model ID in format "providerID/modelID" or "modelID" * @param settings - Optional settings for this model instance */ chat(modelId: OpencodeModelId, settings?: OpencodeSettings): LanguageModelV3; /** * Dispose provider resources (for example managed OpenCode server processes). */ dispose(): Promise; } /** * Parsed model ID containing provider and model components. */ interface ParsedModelId { providerID: string; modelID: string; } /** * Per-request provider options for `providerOptions.opencode`. */ interface OpencodeProviderOptions { /** * User message ID to send to OpenCode for this request. * Must start with "msg_". */ messageID?: string; } /** * Metadata returned in provider responses. */ interface OpencodeProviderMetadata { opencode: { sessionId: string; messageId?: string; approvalRequestId?: string; cost?: number; reasoning?: string; }; } /** * Tool state tracking for streaming. */ interface ToolStreamState { callId: string; toolName: string; inputStarted: boolean; inputClosed: boolean; callEmitted: boolean; resultEmitted: boolean; emittedAttachmentIds: Set; lastInput?: string; } /** * Accumulated usage data during streaming. */ interface StreamingUsage { inputTokens: number; outputTokens: number; reasoningTokens: number; cachedInputTokens: number; cachedWriteTokens: number; totalCost: number; } /** * Create an OpenCode provider. * * @param options - Provider settings * @returns OpenCode provider instance * * @example * ```ts * import { createOpencode } from 'ai-sdk-provider-opencode-sdk'; * * const opencode = createOpencode(); * const model = opencode('anthropic/claude-opus-4-5-20251101'); * * // Or with settings * const opencode = createOpencode({ * hostname: 'localhost', * port: 4096, * defaultSettings: { agent: 'build' } * }); * ``` */ declare function createOpencode(options?: OpencodeProviderSettings): OpencodeProvider; /** * Default OpenCode provider instance. * * @example * ```ts * import { opencode } from 'ai-sdk-provider-opencode-sdk'; * * const model = opencode('anthropic/claude-opus-4-5-20251101'); * ``` */ declare const opencode: OpencodeProvider; /** * Common model shortcuts for convenience. * Model IDs sourced from official documentation: * - Anthropic: https://platform.claude.com/docs/en/about-claude/models/overview * - Google: https://ai.google.dev/gemini-api/docs/models * - OpenAI: https://platform.openai.com/docs/models */ declare const OpencodeModels: { readonly "claude-sonnet-4-5": "anthropic/claude-sonnet-4-5-20250929"; readonly "claude-haiku-4-5": "anthropic/claude-haiku-4-5-20251001"; readonly "claude-opus-4-5": "anthropic/claude-opus-4-5-20251101"; readonly "gpt-4o": "openai/gpt-4o"; readonly "gpt-4o-mini": "openai/gpt-4o-mini"; readonly "gemini-3-pro": "google/gemini-3-pro-preview"; readonly "gemini-2.5-flash": "google/gemini-2.5-flash"; readonly "gemini-2.5-pro": "google/gemini-2.5-pro"; readonly "gemini-2.0-flash": "google/gemini-2.0-flash"; }; type OpencodeModelShortcut = keyof typeof OpencodeModels; /** * OpenCode Language Model implementation of LanguageModelV3. */ declare class OpencodeLanguageModel implements LanguageModelV3 { readonly specificationVersion: "v3"; readonly modelId: string; readonly provider = "opencode"; /** * OpenCode doesn't support URL-based file inputs. * All files must be base64 encoded. */ readonly supportedUrls: Record; private readonly settings; private readonly logger; private readonly clientManager; private sessionId; private sessionInitPromise; private repliedApprovalIdsBySession; private parsedModelId; constructor(options: { modelId: string; settings: OpencodeSettings; clientManager: OpencodeClientManager; }); /** * Non-streaming generation. */ doGenerate(options: LanguageModelV3CallOptions): Promise<{ content: LanguageModelV3Content[]; finishReason: _ai_sdk_provider.LanguageModelV3FinishReason; usage: LanguageModelV3Usage; providerMetadata: { opencode: { sessionId: string; messageId: string | undefined; cost: number; }; }; request: { body: { parts: ({ type: "text"; text: string; } | { type: "file"; mime: string; url: string; filename?: string; })[]; messageID?: string | undefined; variant?: string | undefined; system?: string | undefined; format?: { type: "json_schema"; schema: Record; retryCount?: number; } | undefined; tools?: Record | undefined; agent?: string | undefined; model?: { providerID: string; modelID: string; } | undefined; directory?: string | undefined; sessionID: string; }; }; warnings: SharedV3Warning[]; }>; /** * Streaming generation. */ doStream(options: LanguageModelV3CallOptions): Promise<{ stream: ReadableStream; request?: { body?: unknown; }; response?: { headers?: Record; }; }>; private getRequestDirectory; private getResponseFormat; private buildPromptRequestBody; private replyToPendingApprovals; private getPendingApprovalResponses; private getRepliedApprovalIdsForSession; /** * Get or create a session for this model instance. */ private getOrCreateSession; /** * Extract content in AI SDK format from OpenCode parts. */ private extractContentFromParts; private extractToolParts; private convertFilePartToContent; /** * Extract usage information from step-finish parts. */ private extractUsageFromParts; /** * Get the current session ID. */ getSessionId(): string | undefined; } /** * Validation result with warnings. */ interface ValidationResult { value: T; warnings: string[]; } /** * Validate OpencodeSettings. */ declare function validateSettings(settings: OpencodeSettings | undefined, logger?: Logger | false): ValidationResult; /** * Validate OpencodeProviderSettings. */ declare function validateProviderSettings(settings: OpencodeProviderSettings | undefined, logger?: Logger | false): ValidationResult; /** * Validate model ID format. * @returns Object with providerID and modelID, or null if invalid. */ declare function validateModelId(modelId: string, logger?: Logger | false): { providerID: string; modelID: string; } | null; /** * Check if a session ID is valid. * Session IDs are typically UUIDs or similar alphanumeric strings. */ declare function isValidSessionId(sessionId: string): boolean; /** * Merge settings with defaults. */ declare function mergeSettings(defaults: OpencodeSettings | undefined, overrides: OpencodeSettings | undefined): OpencodeSettings; /** * Metadata for OpenCode errors. */ interface OpencodeErrorMetadata { sessionId?: string; messageId?: string; statusCode?: number; isRetryable: boolean; errorType?: string; timeoutMs?: number; } /** * Check if an error is an authentication error. */ declare function isAuthenticationError(error: unknown): boolean; /** * Check if an error is a timeout error. */ declare function isTimeoutError(error: unknown): boolean; /** * Check if an error is an abort error (user cancelled). */ declare function isAbortError(error: unknown): boolean; /** * Check if an error indicates output length exceeded. */ declare function isOutputLengthError(error: unknown): boolean; /** * Create an authentication error from an OpenCode error. */ declare function createAuthenticationError(error: unknown): LoadAPIKeyError; /** * Create an API call error from an OpenCode error. */ declare function createAPICallError(error: unknown, metadata?: Partial): APICallError; /** * Create a timeout error. */ declare function createTimeoutError(timeoutMs: number, operation?: string): APICallError; /** * Extract error message from unknown error. */ declare function extractErrorMessage(error: unknown): string; /** * Wrap an error in an appropriate AI SDK error type. */ declare function wrapError(error: unknown, metadata?: Partial): Error; /** * Default console-based logger. */ declare const defaultLogger: Logger; /** * Silent logger that discards all messages. */ declare const silentLogger: Logger; /** * Get a logger instance. * @param logger - Logger instance, false to disable, or undefined for default * @param verbose - Enable verbose/debug logging */ declare function getLogger(logger: Logger | false | undefined, verbose?: boolean): Logger; /** * Create a verbose logger that prefixes all messages with a context. */ declare function createContextLogger(baseLogger: Logger, context: string): Logger; /** * Log a warning about an unsupported feature. */ declare function logUnsupportedFeature(logger: Logger, feature: string, details?: string): void; /** * Log a warning about an unsupported parameter. */ declare function logUnsupportedParameter(logger: Logger, parameter: string, value?: unknown): void; /** * Log unsupported call options. * Returns an array of warning messages for inclusion in the response. */ declare function logUnsupportedCallOptions(logger: Logger, options: { temperature?: number; topP?: number; topK?: number; frequencyPenalty?: number; presencePenalty?: number; stopSequences?: string[]; seed?: number; maxTokens?: number; }): string[]; /** * Input part types for OpenCode SDK. * Based on SessionPromptData.body.parts in the SDK. */ interface TextPartInput { id?: string; type: "text"; text: string; synthetic?: boolean; ignored?: boolean; } interface FilePartInput { id?: string; type: "file"; mime: string; filename?: string; url: string; } type OpencodePartInput = TextPartInput | FilePartInput; /** * Result of converting AI SDK messages to OpenCode format. */ interface ConversionResult { parts: OpencodePartInput[]; systemPrompt?: string; warnings: string[]; } /** * Convert AI SDK prompt to OpenCode format. */ declare function convertToOpencodeMessages(prompt: LanguageModelV3Prompt, options?: { logger?: Logger | false; mode?: { type: "regular"; } | { type: "object-json"; schema?: unknown; }; includeToolApprovalResponsesAsContext?: boolean; }): ConversionResult; /** * Extract the text content from an array of parts. */ declare function extractTextFromParts(parts: OpencodePartInput[]): string; /** * Tool name used by OpenCode to return structured output. */ declare const STRUCTURED_OUTPUT_TOOL: "StructuredOutput"; /** * OpenCode event types (from SDK types.gen.ts). */ interface EventMessagePartUpdated { type: "message.part.updated"; properties: { part: Part; delta?: string; }; } interface EventMessageUpdated { type: "message.updated"; properties: { info: Message; }; } interface EventSessionStatus { type: "session.status"; properties: { sessionID: string; status: { type: "idle"; } | { type: "busy"; } | { type: "retry"; attempt: number; message: string; next: number; }; }; } interface EventSessionIdle { type: "session.idle"; properties: { sessionID: string; }; } interface EventPermissionAsked { type: "permission.asked"; properties: { id: string; sessionID: string; permission: string; patterns: string[]; metadata?: Record; always?: string[]; tool?: { messageID: string; callID: string; }; }; } interface EventQuestionAsked { type: "question.asked"; properties: { id: string; sessionID: string; questions: Array<{ header: string; question: string; options: Array<{ label: string; description: string; }>; multiple?: boolean; custom?: boolean; }>; tool?: { messageID: string; callID: string; }; }; } interface EventMessagePartDelta { type: "message.part.delta"; properties: { sessionID: string; messageID: string; partID: string; field: string; delta: string; }; } type OpencodeEvent = EventMessagePartUpdated | EventMessageUpdated | EventMessagePartDelta | EventSessionStatus | EventSessionIdle | EventPermissionAsked | EventQuestionAsked | { type: string; properties: unknown; }; /** * Part types from OpenCode SDK. */ interface TextPart { id: string; sessionID: string; messageID: string; type: "text"; text: string; synthetic?: boolean; ignored?: boolean; } interface ReasoningPart { id: string; sessionID: string; messageID: string; type: "reasoning"; text: string; } interface FilePart { id: string; sessionID: string; messageID: string; type: "file"; mime: string; filename?: string; url: string; source?: { type?: string; path?: string; uri?: string; [key: string]: unknown; }; } interface ToolPart { id: string; sessionID: string; messageID: string; type: "tool"; callID: string; tool: string; state: ToolState; } interface ToolStatePending { status: "pending"; input: Record; raw: string; } interface ToolStateRunning { status: "running"; input: Record; title?: string; time: { start: number; }; } interface ToolStateCompleted { status: "completed"; input: Record; output: string; title: string; time: { start: number; end: number; }; attachments?: FilePart[]; } interface ToolStateError { status: "error"; input: Record; error: string; time: { start: number; end: number; }; } type ToolState = ToolStatePending | ToolStateRunning | ToolStateCompleted | ToolStateError; interface StepFinishPart { id: string; sessionID: string; messageID: string; type: "step-finish"; reason: string; cost: number; tokens: { input: number; output: number; reasoning: number; cache: { read: number; write: number; }; }; } type Part = TextPart | ReasoningPart | ToolPart | StepFinishPart | FilePart | { type: string; sessionID: string; messageID: string; [key: string]: unknown; }; interface Message { id: string; sessionID: string; role: "user" | "assistant"; error?: { name: string; data?: unknown; }; finish?: string; } /** * State for tracking streaming progress. */ interface StreamState { textPartId: string | undefined; textStarted: boolean; reasoningPartId: string | undefined; reasoningStarted: boolean; toolStates: Map; usage: StreamingUsage; lastTextContent: string; lastReasoningContent: string; messageRoles: Map; permissionRequests: Set; questionRequests: Set; } /** * Create initial stream state. */ declare function createStreamState(): StreamState; /** * Check if an event is for a specific session. */ declare function isEventForSession(event: OpencodeEvent, sessionId: string): boolean; /** * Check if an event indicates the session is complete. */ declare function isSessionComplete(event: OpencodeEvent, sessionId: string): boolean; /** * Convert an OpenCode event to AI SDK stream parts. */ declare function convertEventToStreamParts(event: OpencodeEvent, state: StreamState, logger?: Logger | false): LanguageModelV3StreamPart[]; /** * Create the final stream parts to close out the stream. */ declare function createFinishParts(state: StreamState, finishReason: LanguageModelV3FinishReason, sessionId: string, messageId?: string): LanguageModelV3StreamPart[]; /** * Create stream start part with warnings. */ declare function createStreamStartPart(warnings: string[]): LanguageModelV3StreamPart; /** * Message info from OpenCode SDK. */ interface MessageInfo { error?: { name: string; data?: unknown; }; finish?: string; } /** * Map OpenCode message info to AI SDK finish reason. */ declare function mapOpencodeFinishReason(message: MessageInfo | undefined): LanguageModelV3FinishReason; /** * Map an error object to a finish reason. */ declare function mapErrorToFinishReasonFromUnknown(error: unknown): LanguageModelV3FinishReason; /** * Determine if a message has tool calls. * Used to determine 'tool-calls' finish reason. */ declare function hasToolCalls(parts: Array<{ type: string; }>): boolean; export { type ClientManagerOptions, type ConversionResult, type EventMessagePartUpdated, type EventMessageUpdated, type EventPermissionAsked, type EventQuestionAsked, type EventSessionIdle, type EventSessionStatus, type FilePart, type FilePartInput, type Logger, type Message, type MessageInfo, type OpencodeClient, OpencodeClientManager, type OpencodeClientOptions, type OpencodeCreateClientOptions, type OpencodeEvent, OpencodeLanguageModel, type OpencodeModelId, type OpencodeModelShortcut, OpencodeModels, type OpencodePartInput, type OpencodePermissionAction, type OpencodePermissionRule, type OpencodePermissionRuleset, type OpencodeProvider, type OpencodeProviderMetadata, type OpencodeProviderOptions, type OpencodeProviderSettings, type OpencodeSettings, type ParsedModelId, type Part, type ReasoningPart, STRUCTURED_OUTPUT_TOOL, type StepFinishPart, type StreamState, type StreamingUsage, type TextPart, type TextPartInput, type ToolPart, type ToolState, type ToolStateCompleted, type ToolStateError, type ToolStatePending, type ToolStateRunning, type ToolStreamState, convertEventToStreamParts, convertToOpencodeMessages, createAPICallError, createAuthenticationError, createClientManager, createClientManagerFromSettings, createContextLogger, createFinishParts, createOpencode, createStreamStartPart, createStreamState, createTimeoutError, defaultLogger, extractErrorMessage, extractTextFromParts, getLogger, hasToolCalls, isAbortError, isAuthenticationError, isEventForSession, isOutputLengthError, isSessionComplete, isTimeoutError, isValidSessionId, logUnsupportedCallOptions, logUnsupportedFeature, logUnsupportedParameter, mapErrorToFinishReasonFromUnknown, mapOpencodeFinishReason, mergeSettings, opencode, silentLogger, validateModelId, validateProviderSettings, validateSettings, wrapError };