@standardagents/openai 0.10.0-dev.ffffff
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.txt +48 -0
- package/dist/index.d.ts +177 -0
- package/dist/index.js +1218 -0
- package/dist/index.js.map +1 -0
- package/package.json +52 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/OpenAIProvider.ts","../src/transformers.ts","../src/icons.ts","../src/providerOptions.ts","../src/index.ts"],"sourcesContent":["import type OpenAI from 'openai';\nimport type {\n LLMProviderInterface as Provider,\n ProviderFactoryConfig,\n ProviderRequest,\n ProviderResponse,\n ProviderStreamChunk,\n ModelCapabilities,\n ProviderModelInfo,\n ToolDefinition,\n ToolArgs,\n ToolTenvs,\n InspectedRequest,\n} from '@standardagents/spec';\nimport { ProviderError, defineTool } from '@standardagents/spec';\nimport { z } from 'zod';\nimport {\n buildCreateParams,\n transformResponse,\n createStreamState,\n processStreamEvent,\n createErrorChunk,\n DEFAULT_REASONING_LEVELS,\n truncateBase64,\n} from './transformers';\nimport { getOpenAIIconDataUri } from './icons';\n\n// Re-export ProviderError for consumers\nexport { ProviderError };\n\n/**\n * OpenAI model info from their API\n */\ninterface OpenAIModelInfo {\n id: string;\n object: string;\n created: number;\n owned_by: string;\n}\n\n/**\n * OpenAI provider implementation for Standard Agents\n *\n * Uses the Responses API for all requests (stateless mode).\n * Supports: gpt-4o, gpt-4-turbo, gpt-3.5-turbo, o1, o3, o4-mini, etc.\n */\nexport class OpenAIProvider implements Provider {\n readonly name = 'openai';\n readonly specificationVersion = '1' as const;\n\n private client: OpenAI | null = null;\n private config: ProviderFactoryConfig;\n\n /** Cache for models list to avoid repeated API calls */\n private static modelsCache: OpenAIModelInfo[] | null = null;\n private static modelsCacheTime = 0;\n private static readonly CACHE_TTL = 5 * 60 * 1000; // 5 minutes\n\n constructor(config: ProviderFactoryConfig) {\n this.config = config;\n }\n\n private async getClient(): Promise<OpenAI> {\n if (!this.client) {\n const { default: OpenAI } = await import('openai');\n this.client = new OpenAI({\n apiKey: this.config.apiKey,\n baseURL: this.config.baseUrl,\n timeout: this.config.timeout,\n });\n }\n return this.client;\n }\n\n supportsModel(modelId: string): boolean {\n return (\n modelId.startsWith('gpt-') ||\n modelId.startsWith('o1') ||\n modelId.startsWith('o3') ||\n modelId.startsWith('o4') ||\n modelId.startsWith('dall-e') ||\n modelId.startsWith('chatgpt-')\n );\n }\n\n /**\n * Get the icon for this provider as a data URI.\n * Always returns the OpenAI icon since all models are from OpenAI.\n */\n getIcon(_modelId?: string): string {\n return getOpenAIIconDataUri();\n }\n\n // ============================================================================\n // Model Capabilities\n // ============================================================================\n\n /**\n * Hardcoded capability mappings for OpenAI models.\n * OpenAI doesn't provide a capabilities API, so these are manually maintained.\n */\n private static readonly MODEL_CAPABILITIES: Record<string, ModelCapabilities> = {\n 'gpt-4o': {\n supportsImages: true,\n supportsToolCalls: true,\n supportsStreaming: true,\n supportsJsonMode: true,\n maxContextTokens: 128000,\n maxOutputTokens: 16384,\n },\n 'gpt-4o-mini': {\n supportsImages: true,\n supportsToolCalls: true,\n supportsStreaming: true,\n supportsJsonMode: true,\n maxContextTokens: 128000,\n maxOutputTokens: 16384,\n },\n 'gpt-4-turbo': {\n supportsImages: true,\n supportsToolCalls: true,\n supportsStreaming: true,\n supportsJsonMode: true,\n maxContextTokens: 128000,\n maxOutputTokens: 4096,\n },\n 'gpt-4': {\n supportsImages: false,\n supportsToolCalls: true,\n supportsStreaming: true,\n supportsJsonMode: true,\n maxContextTokens: 8192,\n maxOutputTokens: 4096,\n },\n 'gpt-3.5-turbo': {\n supportsImages: false,\n supportsToolCalls: true,\n supportsStreaming: true,\n supportsJsonMode: true,\n maxContextTokens: 16385,\n maxOutputTokens: 4096,\n },\n 'o1': {\n supportsImages: true,\n supportsToolCalls: true,\n supportsStreaming: true,\n supportsJsonMode: true,\n maxContextTokens: 200000,\n maxOutputTokens: 100000,\n reasoningLevels: { 0: null, 33: 'low', 66: 'medium', 100: 'high' },\n },\n 'o1-preview': {\n supportsImages: true,\n supportsToolCalls: false,\n supportsStreaming: true,\n supportsJsonMode: false,\n maxContextTokens: 128000,\n maxOutputTokens: 32768,\n reasoningLevels: { 0: null, 33: 'low', 66: 'medium', 100: 'high' },\n },\n 'o1-mini': {\n supportsImages: false,\n supportsToolCalls: false,\n supportsStreaming: true,\n supportsJsonMode: false,\n maxContextTokens: 128000,\n maxOutputTokens: 65536,\n reasoningLevels: { 0: null, 33: 'low', 66: 'medium', 100: 'high' },\n },\n 'o3-mini': {\n supportsImages: false,\n supportsToolCalls: true,\n supportsStreaming: true,\n supportsJsonMode: true,\n maxContextTokens: 200000,\n maxOutputTokens: 100000,\n reasoningLevels: { 0: null, 33: 'low', 66: 'medium', 100: 'high' },\n },\n 'o4-mini': {\n supportsImages: true,\n supportsToolCalls: true,\n supportsStreaming: true,\n supportsJsonMode: true,\n maxContextTokens: 200000,\n maxOutputTokens: 100000,\n reasoningLevels: { 0: null, 33: 'low', 66: 'medium', 100: 'high' },\n },\n };\n\n /**\n * Get capabilities for a specific model.\n * Uses hardcoded mappings since OpenAI doesn't provide a capabilities API.\n */\n async getModelCapabilities(modelId: string): Promise<ModelCapabilities | null> {\n // Exact match first\n if (OpenAIProvider.MODEL_CAPABILITIES[modelId]) {\n return { ...OpenAIProvider.MODEL_CAPABILITIES[modelId] };\n }\n\n // Prefix match (e.g., 'gpt-4o-2024-11-20' matches 'gpt-4o')\n for (const [prefix, caps] of Object.entries(OpenAIProvider.MODEL_CAPABILITIES)) {\n if (modelId.startsWith(prefix)) {\n return { ...caps };\n }\n }\n\n // Default capabilities for unknown OpenAI models\n return {\n supportsImages: false,\n supportsToolCalls: true,\n supportsStreaming: true,\n supportsJsonMode: true,\n maxContextTokens: 8192,\n maxOutputTokens: 4096,\n };\n }\n\n /**\n * Human-readable names and descriptions for models.\n * Used to enrich API response data.\n */\n private static readonly MODEL_METADATA: Record<string, { name: string; description: string }> = {\n 'gpt-4o': { name: 'GPT-4o', description: 'Most capable GPT-4 model with vision' },\n 'gpt-4o-mini': { name: 'GPT-4o Mini', description: 'Fast and affordable GPT-4o variant' },\n 'gpt-4-turbo': { name: 'GPT-4 Turbo', description: 'GPT-4 Turbo with vision' },\n 'gpt-4': { name: 'GPT-4', description: 'Original GPT-4 model' },\n 'gpt-3.5-turbo': { name: 'GPT-3.5 Turbo', description: 'Fast and cost-effective' },\n 'o1': { name: 'o1', description: 'Advanced reasoning model' },\n 'o1-preview': { name: 'o1 Preview', description: 'Preview reasoning model' },\n 'o1-mini': { name: 'o1 Mini', description: 'Smaller reasoning model' },\n 'o3-mini': { name: 'o3 Mini', description: 'Latest compact reasoning model' },\n 'o4-mini': { name: 'o4 Mini', description: 'Next-gen compact reasoning model' },\n 'chatgpt-4o-latest': { name: 'ChatGPT-4o Latest', description: 'Latest ChatGPT model' },\n };\n\n /**\n * Prefixes for chat-capable models (filter out embeddings, tts, whisper, dall-e, etc.)\n */\n private static readonly CHAT_MODEL_PREFIXES = ['gpt-', 'o1', 'o3', 'o4', 'chatgpt-'];\n\n // ============================================================================\n // Provider-Embedded Tools\n // ============================================================================\n\n /**\n * Provider-embedded tools using defineTool().\n * These are OpenAI's built-in tools that execute on OpenAI's servers.\n * The execute function is a no-op since execution is handled by the provider.\n */\n private static readonly TOOLS: Record<string, ToolDefinition<any, ToolArgs | null, ToolTenvs | null>> = {\n web_search: defineTool({\n description: 'Search the web for up-to-date information with citations',\n args: z.object({\n query: z.string().describe('Search query'),\n searchContextSize: z.enum(['low', 'medium', 'high']).default('medium').describe('Amount of context to gather'),\n }),\n execute: async (_state, _args) => {\n // Execution handled by OpenAI - this is a passthrough\n return { status: 'success', result: 'Handled by OpenAI' };\n },\n tenvs: z.object({\n userLocation: z.string().optional().describe('User location for relevant results'),\n }),\n executionMode: 'provider',\n executionProvider: 'openai',\n }),\n\n file_search: defineTool({\n description: 'Search through uploaded files using vector embeddings',\n args: z.object({\n query: z.string().describe('Search query'),\n }),\n execute: async (_state, _args) => {\n return { status: 'success', result: 'Handled by OpenAI' };\n },\n tenvs: z.object({\n vectorStoreId: z.string().describe('OpenAI Vector Store ID'),\n }),\n executionMode: 'provider',\n executionProvider: 'openai',\n }),\n\n code_interpreter: defineTool({\n description: 'Execute Python code in a sandboxed environment',\n args: z.object({\n code: z.string().describe('Python code to execute'),\n }),\n execute: async (_state, _args) => {\n return { status: 'success', result: 'Handled by OpenAI' };\n },\n tenvs: z.object({\n containerId: z.string().optional().describe('Code interpreter container ID'),\n }),\n executionMode: 'provider',\n executionProvider: 'openai',\n }),\n\n image_generation: defineTool({\n description: 'Generate images using GPT-image-1',\n args: z.object({\n prompt: z.string().describe('Image generation prompt'),\n quality: z.enum(['standard', 'hd']).default('standard').describe('Image quality'),\n size: z.enum(['1024x1024', '1792x1024', '1024x1792']).default('1024x1024').describe('Image size'),\n }),\n execute: async (_state, _args) => {\n return { status: 'success', result: 'Handled by OpenAI' };\n },\n executionMode: 'provider',\n executionProvider: 'openai',\n }),\n };\n\n /**\n * Which tools are available for each model.\n */\n private static readonly MODEL_TOOLS: Record<string, string[]> = {\n 'gpt-4o': ['web_search', 'file_search', 'code_interpreter', 'image_generation'],\n 'gpt-4o-mini': ['web_search', 'file_search', 'code_interpreter'],\n 'o1': ['web_search', 'code_interpreter'],\n 'o3-mini': ['web_search', 'code_interpreter'],\n 'o4-mini': ['web_search', 'file_search', 'code_interpreter', 'image_generation'],\n };\n\n /**\n * Get tools embedded in this provider.\n * These are OpenAI's built-in tools with tenv requirements.\n *\n * @param modelId - Optional filter to get tools available for a specific model\n * @returns Record of tool name to tool definition\n */\n getTools(modelId?: string): Record<string, ToolDefinition<any, ToolArgs | null, ToolTenvs | null>> {\n // For OpenAI, return all tools by default - most modern models support all provider tools\n // If a specific model has restrictions, we can filter, but default to returning all\n if (!modelId) {\n return { ...OpenAIProvider.TOOLS };\n }\n\n // Check if we have model-specific restrictions\n let toolNames = OpenAIProvider.MODEL_TOOLS[modelId];\n if (!toolNames) {\n for (const [prefix, tools] of Object.entries(OpenAIProvider.MODEL_TOOLS)) {\n if (modelId.startsWith(prefix)) {\n toolNames = tools;\n break;\n }\n }\n }\n\n // If no specific mapping found, return all tools (OpenAI default)\n if (!toolNames) {\n return { ...OpenAIProvider.TOOLS };\n }\n\n const result: Record<string, ToolDefinition<any, ToolArgs | null, ToolTenvs | null>> = {};\n for (const name of toolNames) {\n if (OpenAIProvider.TOOLS[name]) {\n result[name] = OpenAIProvider.TOOLS[name];\n }\n }\n return result;\n }\n\n /**\n * Fetch models from OpenAI API with caching.\n */\n private async fetchModelsWithCache(): Promise<OpenAIModelInfo[]> {\n const now = Date.now();\n\n // Return cached data if still valid\n if (\n OpenAIProvider.modelsCache &&\n now - OpenAIProvider.modelsCacheTime < OpenAIProvider.CACHE_TTL\n ) {\n return OpenAIProvider.modelsCache;\n }\n\n // Fetch from OpenAI API\n const client = await this.getClient();\n const response = await client.models.list();\n\n // Convert to array (the response is a Page object)\n const models: OpenAIModelInfo[] = [];\n for await (const model of response) {\n models.push(model as OpenAIModelInfo);\n }\n\n OpenAIProvider.modelsCache = models;\n OpenAIProvider.modelsCacheTime = now;\n\n return models;\n }\n\n /**\n * Check if a model ID is a chat-capable model.\n */\n private isChatModel(modelId: string): boolean {\n return OpenAIProvider.CHAT_MODEL_PREFIXES.some((prefix) => modelId.startsWith(prefix));\n }\n\n /**\n * Get human-readable name for a model.\n */\n private getModelName(modelId: string): string {\n // Check exact match first\n if (OpenAIProvider.MODEL_METADATA[modelId]) {\n return OpenAIProvider.MODEL_METADATA[modelId].name;\n }\n\n // Check prefix match\n for (const [prefix, meta] of Object.entries(OpenAIProvider.MODEL_METADATA)) {\n if (modelId.startsWith(prefix + '-')) {\n return `${meta.name} (${modelId.slice(prefix.length + 1)})`;\n }\n }\n\n // Fallback: format the ID nicely\n return modelId\n .split('-')\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(' ');\n }\n\n /**\n * Get description for a model.\n */\n private getModelDescription(modelId: string): string {\n // Check exact match first\n if (OpenAIProvider.MODEL_METADATA[modelId]) {\n return OpenAIProvider.MODEL_METADATA[modelId].description;\n }\n\n // Check prefix match\n for (const [prefix, meta] of Object.entries(OpenAIProvider.MODEL_METADATA)) {\n if (modelId.startsWith(prefix + '-')) {\n return meta.description;\n }\n }\n\n return '';\n }\n\n /**\n * Map OpenAI model info to ProviderModelInfo.\n */\n private mapToProviderModelInfo(model: OpenAIModelInfo): ProviderModelInfo {\n // Get capabilities for context length\n const caps = OpenAIProvider.MODEL_CAPABILITIES[model.id];\n let contextLength = caps?.maxContextTokens;\n\n // If no exact match, try prefix match\n if (!contextLength) {\n for (const [prefix, prefixCaps] of Object.entries(OpenAIProvider.MODEL_CAPABILITIES)) {\n if (model.id.startsWith(prefix)) {\n contextLength = prefixCaps.maxContextTokens;\n break;\n }\n }\n }\n\n return {\n id: model.id,\n name: this.getModelName(model.id),\n description: this.getModelDescription(model.id),\n contextLength,\n iconId: this.getIcon(model.id),\n };\n }\n\n /**\n * Get list of available models from OpenAI.\n * Fetches from the OpenAI API with caching.\n *\n * @param filter - Optional search string to filter models by name/id\n */\n async getModels(filter?: string): Promise<ProviderModelInfo[]> {\n try {\n const rawModels = await this.fetchModelsWithCache();\n\n // Filter to chat models only and map to ProviderModelInfo\n let models = rawModels\n .filter((m) => this.isChatModel(m.id))\n .map((m) => this.mapToProviderModelInfo(m))\n .sort((a, b) => {\n // Sort by name for consistent ordering\n return a.name.localeCompare(b.name);\n });\n\n if (filter) {\n const lowerFilter = filter.toLowerCase();\n models = models.filter(\n (m) =>\n m.id.toLowerCase().includes(lowerFilter) ||\n m.name.toLowerCase().includes(lowerFilter) ||\n (m.description && m.description.toLowerCase().includes(lowerFilter))\n );\n }\n\n return models;\n } catch (error) {\n console.error('Failed to fetch models from OpenAI:', error);\n return [];\n }\n }\n\n // ============================================================================\n // Generation Methods\n // ============================================================================\n\n async generate(request: ProviderRequest): Promise<ProviderResponse> {\n const client = await this.getClient();\n\n try {\n const params = buildCreateParams(request, DEFAULT_REASONING_LEVELS);\n\n const response = await client.responses.create(\n { ...params, stream: false },\n { signal: request.signal }\n );\n\n return transformResponse(response);\n } catch (error) {\n throw this.toProviderError(error);\n }\n }\n\n async stream(request: ProviderRequest): Promise<AsyncIterable<ProviderStreamChunk>> {\n const client = await this.getClient();\n const self = this;\n\n try {\n const params = buildCreateParams(request, DEFAULT_REASONING_LEVELS);\n\n // DEBUG: Log transformed input to see what's actually being sent\n console.log('[OpenAI] Sending request with', Array.isArray(params.input) ? params.input.length : 1, 'input items:');\n if (Array.isArray(params.input)) {\n for (const item of params.input) {\n const itemType = (item as any).type || (item as any).role || 'unknown';\n const hasImage = JSON.stringify(item).includes('input_image');\n console.log(` - ${itemType}${hasImage ? ' (has image)' : ''}`);\n }\n }\n\n const stream = await client.responses.create(\n { ...params, stream: true },\n { signal: request.signal }\n );\n\n return {\n async *[Symbol.asyncIterator]() {\n const state = createStreamState();\n\n try {\n for await (const event of stream) {\n const chunks = processStreamEvent(event, state);\n for (const chunk of chunks) {\n yield chunk;\n }\n }\n } catch (error) {\n const providerError = self.toProviderError(error);\n yield createErrorChunk(providerError.message, providerError.code);\n }\n },\n };\n } catch (error) {\n throw this.toProviderError(error);\n }\n }\n\n // ============================================================================\n // Error Handling\n // ============================================================================\n\n private toProviderError(error: unknown): ProviderError {\n if (error instanceof ProviderError) {\n return error;\n }\n\n if (error instanceof Error) {\n const anyError = error as any;\n const status = anyError.status || anyError.statusCode;\n const retryAfter = anyError.headers?.['retry-after']\n ? parseInt(anyError.headers['retry-after'], 10)\n : undefined;\n\n if (status === 429) {\n return new ProviderError(error.message, 'rate_limit', status, retryAfter);\n }\n if (status === 401 || status === 403) {\n return new ProviderError(error.message, 'auth_error', status);\n }\n if (status === 400) {\n return new ProviderError(error.message, 'invalid_request', status);\n }\n if (status >= 500) {\n return new ProviderError(error.message, 'server_error', status);\n }\n if (error.name === 'AbortError' || anyError.code === 'ETIMEDOUT') {\n return new ProviderError(error.message, 'timeout');\n }\n\n return new ProviderError(error.message, 'unknown', status);\n }\n\n return new ProviderError(String(error), 'unknown');\n }\n\n // ============================================================================\n // Inspection\n // ============================================================================\n\n /**\n * Transform a ProviderRequest to OpenAI Responses API format for inspection.\n * Returns the exact request body that would be sent to OpenAI, with base64 data truncated.\n */\n async inspectRequest(request: ProviderRequest): Promise<InspectedRequest> {\n const params = buildCreateParams(request, DEFAULT_REASONING_LEVELS);\n\n return {\n body: truncateBase64(params as unknown as Record<string, unknown>),\n messagesPath: 'input',\n metadata: {\n endpoint: 'responses.create',\n },\n };\n }\n}\n","/**\n * Discrete transformer functions for OpenAI Responses API provider.\n * These functions convert between Standard Agent types and OpenAI Responses API types.\n * Kept as pure functions for easy testing.\n */\n\nimport type {\n ProviderRequest,\n ProviderResponse,\n ProviderMessage,\n ProviderTool,\n ProviderToolCallPart,\n ProviderFinishReason,\n ProviderUsage,\n ProviderStreamChunk,\n ContentPart,\n ImageUrlPart,\n ProviderReasoningDetail,\n ProviderGeneratedImage,\n} from '@standardagents/spec';\nimport { mapReasoningLevel } from '@standardagents/spec';\nimport type OpenAI from 'openai';\n\n// ============================================================================\n// Type aliases for OpenAI Responses API types\n// ============================================================================\n\ntype ResponseInputItem = OpenAI.Responses.ResponseInputItem;\ntype ResponseInput = OpenAI.Responses.ResponseInput;\ntype ResponseOutputItem = OpenAI.Responses.ResponseOutputItem;\ntype FunctionTool = OpenAI.Responses.FunctionTool;\ntype ResponseCreateParams = OpenAI.Responses.ResponseCreateParams;\ntype Response = OpenAI.Responses.Response;\ntype ResponseStreamEvent = OpenAI.Responses.ResponseStreamEvent;\n\n/**\n * Content type for function call output with multimodal content.\n * Note: The OpenAI API accepts arrays here, but the SDK types only allow strings.\n * We serialize this to JSON for type safety.\n */\ntype FunctionCallOutputContent =\n | { type: 'input_text'; text: string }\n | { type: 'input_image'; image_url: string; detail?: 'auto' | 'low' | 'high' };\n\n/** Default reasoning level mapping for OpenAI o-series models */\nexport const DEFAULT_REASONING_LEVELS: Record<number, string | null> = {\n 0: null,\n 33: 'low',\n 66: 'medium',\n 100: 'high',\n};\n\n/**\n * OpenAI built-in tool names that are executed by OpenAI on their side.\n * These should NOT be sent as function_call items - their results come back\n * as native response types (e.g., image_generation_call, web_search_call).\n */\nexport const OPENAI_NATIVE_TOOLS = new Set([\n 'image_generation',\n 'web_search',\n 'code_interpreter',\n 'file_search',\n]);\n\n// ============================================================================\n// Input Content Transformers\n// ============================================================================\n\n/**\n * Transform a single content part to Responses API input format.\n */\nexport function transformContentPart(\n part: ContentPart\n): OpenAI.Responses.ResponseInputContent {\n if (part.type === 'text') {\n return { type: 'input_text', text: part.text };\n }\n if (part.type === 'image') {\n // Guard against undefined data (e.g., file not loaded)\n const data = part.data || '';\n const imageUrl = data.startsWith('data:')\n ? data\n : `data:${part.mediaType || 'image/png'};base64,${data}`;\n return {\n type: 'input_image',\n image_url: imageUrl,\n detail: part.detail || 'auto',\n };\n }\n // Handle image_url format (stored format uses this instead of 'image')\n if (part.type === 'image_url') {\n // TypeScript narrows to ImageUrlPart here\n const url = part.image_url?.url || '';\n const detail = part.image_url?.detail || 'auto';\n // If URL is a path (not data URI or http), it needs to be loaded separately\n // For now, just pass through - the inspect endpoint should load the data\n return {\n type: 'input_image',\n image_url: url,\n detail,\n };\n }\n // File parts\n // Guard against undefined data\n const fileData = part.data || '';\n return {\n type: 'input_file',\n filename: part.filename,\n file_data: fileData.startsWith('data:')\n ? fileData\n : `data:${part.mediaType || 'application/octet-stream'};base64,${fileData}`,\n };\n}\n\n/**\n * Transform message content (string or parts array) to Responses API format.\n */\nexport function transformMessageContent(\n content: string | ContentPart[]\n): string | OpenAI.Responses.ResponseInputContent[] {\n if (typeof content === 'string') {\n return content;\n }\n return content.map(transformContentPart);\n}\n\n// ============================================================================\n// Message Transformers\n// ============================================================================\n\n/**\n * Transform a user message to Responses API input item.\n */\nexport function transformUserMessage(\n msg: ProviderMessage & { role: 'user' }\n): OpenAI.Responses.EasyInputMessage {\n const content = transformMessageContent(msg.content);\n return {\n role: 'user',\n content: typeof content === 'string' ? content : content,\n };\n}\n\n/**\n * Transform an assistant message to Responses API input item.\n * Assistant messages from previous turns need special handling.\n */\nexport function transformAssistantMessage(\n msg: ProviderMessage & { role: 'assistant' }\n): ResponseInputItem[] {\n const items: ResponseInputItem[] = [];\n\n // Add assistant message if there's content OR if there are tool calls\n // The assistant message helps the model understand turn structure\n const hasToolCalls = msg.toolCalls && msg.toolCalls.length > 0;\n if (msg.content || hasToolCalls) {\n items.push({\n type: 'message',\n role: 'assistant',\n content: msg.content\n ? [{ type: 'output_text', text: msg.content }]\n : [], // Empty content array when only tool calls\n } as OpenAI.Responses.ResponseOutputMessage);\n }\n\n // Add reasoning if present\n // OpenAI expects each reasoning item to be passed back EXACTLY as received.\n // Multiple reasoning items can exist with different IDs - we must group by ID\n // and create separate ResponseReasoningItem for each.\n if (msg.reasoning || msg.reasoningDetails) {\n // Group reasoning details by ID - each unique ID becomes a separate reasoning item\n const reasoningItemsById = new Map<string, OpenAI.Responses.ResponseReasoningItem>();\n\n // Default ID for details without explicit IDs - all such details go into one item\n const defaultId = `rs_${crypto.randomUUID().replace(/-/g, '').slice(0, 24)}`;\n\n // Get or create a reasoning item for a given ID\n const getOrCreateItem = (id: string): OpenAI.Responses.ResponseReasoningItem => {\n let item = reasoningItemsById.get(id);\n if (!item) {\n item = {\n id,\n type: 'reasoning',\n summary: [],\n };\n reasoningItemsById.set(id, item);\n }\n return item;\n };\n\n // Process reasoning details - group by ID\n if (msg.reasoningDetails) {\n for (const detail of msg.reasoningDetails) {\n // Use explicit ID if provided, otherwise use the shared default ID\n // This ensures details without IDs all go into the same reasoning item\n const itemId = detail.id || defaultId;\n const item = getOrCreateItem(itemId);\n\n if (detail.type === 'encrypted' && detail.data) {\n // Each reasoning item gets its own encrypted_content\n item.encrypted_content = detail.data;\n } else if (detail.type === 'summary' && detail.text) {\n item.summary.push({ type: 'summary_text', text: detail.text });\n } else if (detail.type === 'text' && detail.text) {\n // Text-based reasoning details are added to summary\n item.summary.push({ type: 'summary_text', text: detail.text });\n }\n }\n }\n\n // Handle legacy msg.reasoning field (string) - associate with first item or create new\n if (msg.reasoning && typeof msg.reasoning === 'string') {\n if (reasoningItemsById.size > 0) {\n // Add to the first existing item\n const firstItem = reasoningItemsById.values().next().value;\n if (firstItem) {\n firstItem.summary.unshift({ type: 'summary_text', text: msg.reasoning });\n }\n } else {\n // No existing items - create a new one with the default ID\n const newItem = getOrCreateItem(defaultId);\n newItem.summary = [{ type: 'summary_text', text: msg.reasoning }];\n }\n }\n\n // Push all reasoning items - preserves each item's ID and encrypted_content\n for (const item of reasoningItemsById.values()) {\n items.push(item);\n }\n }\n\n // Add tool calls if present\n // Note: image_generation is included as function_call for history reconstruction,\n // even though OpenAI executes it. This allows us to return the result as\n // function_call_output with the image, which the model can \"see\" in stateless mode.\n if (msg.toolCalls && msg.toolCalls.length > 0) {\n for (const tc of msg.toolCalls) {\n // Skip other native OpenAI tools (web_search, code_interpreter, etc.)\n // but include image_generation as a pseudo-function-call\n if (OPENAI_NATIVE_TOOLS.has(tc.name) && tc.name !== 'image_generation') {\n continue;\n }\n items.push({\n type: 'function_call',\n call_id: tc.id,\n name: tc.name,\n arguments: JSON.stringify(tc.arguments),\n } as OpenAI.Responses.ResponseFunctionToolCall);\n }\n }\n\n return items;\n}\n\n/**\n * Transform a tool result message to Responses API input items.\n *\n * For image_generation (OpenAI's native tool), we treat it as a pseudo-function-call\n * in history reconstruction. This allows us to return the generated image as a\n * function_call_output with input_image content, which the model can \"see\" in\n * stateless mode. (The actual image_generation_call format requires stored IDs.)\n *\n * For other tools, returns standard function_call_output.\n */\nexport function transformToolMessage(\n msg: ProviderMessage & { role: 'tool' }\n): ResponseInputItem[] {\n // Standard function call output\n let output: string;\n\n if (typeof msg.content === 'string') {\n output = msg.content;\n } else if ('type' in msg.content) {\n if (msg.content.type === 'text') {\n output = msg.content.text;\n } else if (msg.content.type === 'error') {\n output = `Error: ${msg.content.error}`;\n } else {\n output = JSON.stringify(msg.content);\n }\n } else {\n output = JSON.stringify(msg.content);\n }\n\n // Handle image attachments from any tool (not just image_generation)\n // OpenAI API accepts function_call_output with array content including images.\n // See: https://platform.openai.com/docs/guides/function-calling#formatting-results\n if (msg.attachments?.length) {\n const imageAttachments = msg.attachments.filter(a => a.type === 'image' && a.data);\n if (imageAttachments.length > 0) {\n const outputContent: FunctionCallOutputContent[] = [];\n\n // Add text content first (ResponseInputText format)\n if (output) {\n outputContent.push({\n type: 'input_text',\n text: output,\n });\n }\n\n // Add image content (ResponseInputImage format)\n for (const attachment of imageAttachments) {\n const attachmentData = attachment.data || '';\n const imageData = attachmentData.startsWith('data:')\n ? attachmentData\n : `data:${attachment.mediaType || 'image/png'};base64,${attachmentData}`;\n\n outputContent.push({\n type: 'input_image',\n image_url: imageData,\n detail: 'auto',\n });\n }\n\n // Return array content directly - OpenAI API supports this for multimodal output\n // The SDK types are narrower than what the API accepts, so we use type assertion\n return [{\n type: 'function_call_output',\n call_id: msg.toolCallId,\n output: outputContent as unknown as string,\n }];\n }\n }\n\n return [{\n type: 'function_call_output',\n call_id: msg.toolCallId,\n output,\n }];\n}\n\n/**\n * Transform an array of ProviderMessages to Responses API input format.\n * Returns both the input items and extracted system instructions.\n */\nexport function transformMessages(messages: ProviderMessage[]): {\n input: ResponseInput;\n instructions: string | undefined;\n} {\n let instructions: string | undefined;\n const input: ResponseInput = [];\n\n for (const msg of messages) {\n switch (msg.role) {\n case 'system':\n // System messages become instructions\n instructions = instructions\n ? `${instructions}\\n\\n${msg.content}`\n : msg.content;\n break;\n\n case 'user':\n input.push(transformUserMessage(msg));\n break;\n\n case 'assistant':\n input.push(...transformAssistantMessage(msg));\n break;\n\n case 'tool':\n input.push(...transformToolMessage(msg));\n break;\n }\n }\n\n return { input, instructions };\n}\n\n// ============================================================================\n// Tool Transformers\n// ============================================================================\n\n/**\n * Native OpenAI tool types for the Responses API.\n */\ntype NativeToolType = OpenAI.Responses.Tool;\n\n/**\n * Transform a single ProviderTool to Responses API function tool.\n */\nexport function transformTool(tool: ProviderTool): FunctionTool {\n // OpenAI requires additionalProperties: false in all function schemas with strict: true\n // Ensure we always have a valid schema, even for tools with no parameters\n const inputParams = tool.function.parameters as Record<string, unknown> | null | undefined;\n\n let parameters: Record<string, unknown>;\n if (inputParams && typeof inputParams === 'object') {\n // Add additionalProperties: false to existing schema\n parameters = {\n ...inputParams,\n additionalProperties: false,\n };\n } else {\n // Tools with no parameters need a valid empty schema\n parameters = {\n type: 'object',\n properties: {},\n required: [],\n additionalProperties: false,\n };\n }\n\n return {\n type: 'function',\n name: tool.function.name,\n description: tool.function.description || undefined,\n parameters,\n strict: true,\n };\n}\n\n/**\n * Transform an array of ProviderTools to Responses API format.\n * Separates function tools (for local execution) from native tools (executed by OpenAI).\n *\n * @returns Object with functionTools (regular tools) and nativeTools (OpenAI built-ins)\n */\nexport function transformTools(tools: ProviderTool[]): {\n functionTools: FunctionTool[];\n nativeTools: NativeToolType[];\n} {\n const functionTools: FunctionTool[] = [];\n const nativeTools: NativeToolType[] = [];\n\n for (const tool of tools) {\n const toolName = tool.function.name;\n\n // Debug: Log tool transformation\n console.log(`[transformTools] Tool \"${toolName}\": executionMode=${tool.executionMode}, isNativeTool=${OPENAI_NATIVE_TOOLS.has(toolName)}`);\n\n // Check if this is an OpenAI native tool\n if (tool.executionMode === 'provider' && OPENAI_NATIVE_TOOLS.has(toolName)) {\n // Add as native tool type\n console.log(`[transformTools] Adding \"${toolName}\" as native tool`);\n nativeTools.push({ type: toolName } as NativeToolType);\n } else {\n // Regular function tool\n console.log(`[transformTools] Adding \"${toolName}\" as function tool`);\n functionTools.push(transformTool(tool));\n }\n }\n\n console.log(`[transformTools] Result: ${functionTools.length} function tools, ${nativeTools.length} native tools`);\n return { functionTools, nativeTools };\n}\n\n/**\n * Legacy function for backward compatibility - transforms all tools as function tools.\n * @deprecated Use transformTools() which properly handles native tools\n */\nexport function transformToolsLegacy(tools: ProviderTool[]): FunctionTool[] {\n return tools.map(transformTool);\n}\n\n/**\n * Transform tool choice option to Responses API format.\n */\nexport function transformToolChoice(\n choice: ProviderRequest['toolChoice']\n): ResponseCreateParams['tool_choice'] {\n if (choice === 'auto') {\n return 'auto';\n }\n if (choice === 'none') {\n return 'none';\n }\n if (choice === 'required') {\n return 'required';\n }\n if (typeof choice === 'object' && 'name' in choice) {\n return { type: 'function', name: choice.name };\n }\n return 'auto';\n}\n\n// ============================================================================\n// Response Transformers\n// ============================================================================\n\n/**\n * Map Responses API status/incomplete_details to Provider finish reason.\n */\nexport function mapFinishReason(response: Response): ProviderFinishReason {\n if (response.status === 'failed') {\n return 'error';\n }\n if (response.status === 'incomplete') {\n if (response.incomplete_details?.reason === 'max_output_tokens') {\n return 'length';\n }\n if (response.incomplete_details?.reason === 'content_filter') {\n return 'content_filter';\n }\n }\n\n // Check if there are function calls in the output\n const hasToolCalls = response.output.some(\n (item) => item.type === 'function_call'\n );\n if (hasToolCalls) {\n return 'tool_calls';\n }\n\n return 'stop';\n}\n\n/**\n * Extract text content from response output items.\n */\nexport function extractTextContent(output: ResponseOutputItem[]): string | null {\n const textParts: string[] = [];\n\n for (const item of output) {\n if (item.type === 'message' && item.role === 'assistant') {\n for (const content of item.content) {\n if (content.type === 'output_text') {\n textParts.push(content.text);\n }\n }\n }\n }\n\n return textParts.length > 0 ? textParts.join('') : null;\n}\n\n/**\n * Extract reasoning content from response output items.\n */\nexport function extractReasoningContent(output: ResponseOutputItem[]): {\n reasoning: string | null;\n reasoningDetails: ProviderReasoningDetail[] | undefined;\n} {\n let reasoning: string | null = null;\n const reasoningDetails: ProviderReasoningDetail[] = [];\n\n for (const item of output) {\n if (item.type === 'reasoning') {\n // Capture the original reasoning ID for multi-turn context (OpenAI uses rs_xxx format)\n const reasoningId = item.id;\n\n // Extract summary text\n if (item.summary && item.summary.length > 0) {\n const summaryText = item.summary\n .map((s) => s.text)\n .join('\\n');\n reasoning = reasoning ? `${reasoning}\\n${summaryText}` : summaryText;\n reasoningDetails.push({ type: 'summary', id: reasoningId, text: summaryText });\n }\n\n // Note: ResponseReasoningItem from OpenAI SDK only exposes summary and encrypted_content\n // There's no public `content` array in the SDK type - text reasoning comes via streaming events\n\n // Extract encrypted content for stateless multi-turn\n if (item.encrypted_content) {\n reasoningDetails.push({ type: 'encrypted', id: reasoningId, data: item.encrypted_content });\n }\n }\n }\n\n return {\n reasoning,\n reasoningDetails: reasoningDetails.length > 0 ? reasoningDetails : undefined,\n };\n}\n\n/**\n * Extract tool calls from response output items.\n */\nexport function extractToolCalls(\n output: ResponseOutputItem[]\n): ProviderToolCallPart[] | undefined {\n const toolCalls: ProviderToolCallPart[] = [];\n\n for (const item of output) {\n if (item.type === 'function_call') {\n let parsedArgs: Record<string, unknown> = {};\n try {\n parsedArgs = item.arguments ? JSON.parse(item.arguments) : {};\n } catch {\n // Keep empty object on parse failure\n }\n\n toolCalls.push({\n id: item.call_id,\n name: item.name,\n arguments: parsedArgs,\n });\n }\n }\n\n return toolCalls.length > 0 ? toolCalls : undefined;\n}\n\n/**\n * Extract generated images from image_generation_call output items.\n */\nexport function extractProviderImages(\n output: ResponseOutputItem[]\n): ProviderGeneratedImage[] | undefined {\n const images: ProviderGeneratedImage[] = [];\n\n for (const item of output) {\n if (item.type === 'image_generation_call' && item.result) {\n images.push({\n id: item.id,\n toolName: 'image_generation',\n data: item.result,\n mediaType: 'image/png',\n // Note: OpenAI SDK ImageGenerationCall doesn't expose revised_prompt\n });\n }\n }\n\n return images.length > 0 ? images : undefined;\n}\n\n/**\n * Transform Responses API usage to Provider usage format.\n */\nexport function transformUsage(\n usage: Response['usage'] | undefined\n): ProviderUsage {\n if (!usage) {\n return {\n promptTokens: 0,\n completionTokens: 0,\n totalTokens: 0,\n };\n }\n\n return {\n promptTokens: usage.input_tokens || 0,\n completionTokens: usage.output_tokens || 0,\n totalTokens: usage.total_tokens || 0,\n reasoningTokens: usage.output_tokens_details?.reasoning_tokens,\n cachedTokens: usage.input_tokens_details?.cached_tokens,\n };\n}\n\n/**\n * Transform a complete Responses API response to ProviderResponse.\n */\nexport function transformResponse(response: Response): ProviderResponse {\n const content = extractTextContent(response.output);\n const { reasoning, reasoningDetails } = extractReasoningContent(response.output);\n const toolCalls = extractToolCalls(response.output);\n const images = extractProviderImages(response.output);\n\n return {\n content,\n reasoning,\n reasoningDetails,\n toolCalls,\n images,\n finishReason: mapFinishReason(response),\n usage: transformUsage(response.usage),\n metadata: {\n model: response.model,\n provider: 'openai',\n requestId: response.id,\n },\n };\n}\n\n// ============================================================================\n// Request Builder\n// ============================================================================\n\n/**\n * Build a Responses API create request from a ProviderRequest.\n */\nexport function buildCreateParams(\n request: ProviderRequest,\n reasoningLevels: Record<number, string | null> = DEFAULT_REASONING_LEVELS\n): ResponseCreateParams {\n const { input, instructions } = transformMessages(request.messages);\n\n const params: ResponseCreateParams = {\n model: request.model,\n input,\n store: false, // Always stateless\n };\n\n if (instructions) {\n params.instructions = instructions;\n }\n\n // Tools\n if (request.tools && request.tools.length > 0) {\n const { functionTools, nativeTools } = transformTools(request.tools);\n\n // Check if any native tools were already used in this conversation\n // If so, exclude them from the tools list to avoid confusing the model\n // (The model sees them as function_call/function_call_output in history,\n // but having them also available as native tools causes regeneration loops)\n const usedNativeTools = new Set<string>();\n for (const msg of request.messages) {\n if (msg.role === 'tool' && msg.toolName && OPENAI_NATIVE_TOOLS.has(msg.toolName)) {\n usedNativeTools.add(msg.toolName);\n }\n }\n\n // Filter out native tools that were already used\n const availableNativeTools = nativeTools.filter(tool => {\n const toolType = (tool as { type: string }).type;\n if (usedNativeTools.has(toolType)) {\n console.log(`[buildCreateParams] Excluding native tool \"${toolType}\" - already used in conversation`);\n return false;\n }\n return true;\n });\n\n // Combine function tools and native OpenAI tools\n // Native tools (image_generation, web_search, etc.) must be added as their native types\n params.tools = [\n ...functionTools,\n ...availableNativeTools,\n ];\n\n // Include web search results if web_search tool is available\n const hasWebSearch = availableNativeTools.some(\n tool => (tool as { type: string }).type === 'web_search'\n );\n if (hasWebSearch) {\n params.include = params.include || [];\n if (!params.include.includes('web_search_call.results')) {\n params.include.push('web_search_call.results');\n }\n }\n\n if (request.toolChoice !== undefined) {\n params.tool_choice = transformToolChoice(request.toolChoice);\n }\n\n if (request.parallelToolCalls !== undefined) {\n params.parallel_tool_calls = request.parallelToolCalls;\n }\n }\n\n // Generation parameters\n if (request.maxOutputTokens !== undefined) {\n params.max_output_tokens = request.maxOutputTokens;\n }\n\n if (request.temperature !== undefined) {\n params.temperature = request.temperature;\n }\n\n if (request.topP !== undefined) {\n params.top_p = request.topP;\n }\n\n // Reasoning (o-series models)\n if (request.reasoning?.level !== undefined) {\n const effort = mapReasoningLevel(request.reasoning.level, reasoningLevels);\n if (effort) {\n params.reasoning = {\n effort: effort as 'low' | 'medium' | 'high',\n summary: 'auto',\n };\n\n // Include encrypted reasoning for stateless multi-turn\n // Note: reasoning.summary is not a valid include value - summaries come by default\n params.include = params.include || [];\n if (!params.include.includes('reasoning.encrypted_content')) {\n params.include.push('reasoning.encrypted_content');\n }\n }\n }\n\n // Response format\n if (request.responseFormat) {\n if (request.responseFormat.type === 'json') {\n if (request.responseFormat.schema) {\n params.text = {\n format: {\n type: 'json_schema',\n name: 'response',\n schema: request.responseFormat.schema,\n strict: true,\n },\n };\n } else {\n params.text = {\n format: { type: 'json_object' },\n };\n }\n }\n }\n\n // Merge provider-specific options (but don't let them override our managed include array)\n if (request.providerOptions) {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { include: _providerInclude, ...otherOptions } = request.providerOptions as Record<string, unknown>;\n Object.assign(params, otherOptions);\n // Note: We intentionally ignore providerOptions.include - the include array is managed\n // by buildCreateParams based on reasoning settings. User-provided include values like\n // 'reasoning.summary' are invalid and would cause API errors.\n }\n\n return params;\n}\n\n// ============================================================================\n// Stream State and Chunk Transformers\n// ============================================================================\n\nexport interface StreamState {\n toolCalls: Map<string, { id: string; name: string; arguments: string }>;\n imageGenerations: Map<string, { id: string; status: string }>;\n webSearches: Map<string, { id: string; status: string }>;\n reasoningContent: string;\n hasContent: boolean;\n hasReasoning: boolean;\n currentItemId: string | null;\n imageIndex: number;\n}\n\nexport function createStreamState(): StreamState {\n return {\n toolCalls: new Map(),\n imageGenerations: new Map(),\n webSearches: new Map(),\n reasoningContent: '',\n hasContent: false,\n hasReasoning: false,\n currentItemId: null,\n imageIndex: 0,\n };\n}\n\n/**\n * Process a stream event and return provider stream chunks.\n */\nexport function processStreamEvent(\n event: ResponseStreamEvent,\n state: StreamState\n): ProviderStreamChunk[] {\n const chunks: ProviderStreamChunk[] = [];\n\n switch (event.type) {\n // Text content streaming\n case 'response.output_text.delta':\n state.hasContent = true;\n chunks.push({ type: 'content-delta', delta: event.delta });\n break;\n\n case 'response.output_text.done':\n // Content done is emitted at the end\n break;\n\n // Reasoning streaming\n case 'response.reasoning.delta':\n state.hasReasoning = true;\n // ResponseReasoningDeltaEvent has `delta` property (typed as unknown)\n if (typeof event.delta === 'string') {\n state.reasoningContent += event.delta;\n chunks.push({ type: 'reasoning-delta', delta: event.delta });\n }\n break;\n\n case 'response.reasoning.done':\n // Reasoning done is emitted at the end\n break;\n\n // Function call and image generation streaming\n case 'response.output_item.added':\n if (event.item.type === 'function_call') {\n state.toolCalls.set(event.item.call_id, {\n id: event.item.call_id,\n name: event.item.name,\n arguments: '',\n });\n chunks.push({\n type: 'tool-call-start',\n id: event.item.call_id,\n name: event.item.name,\n });\n } else if (event.item.type === 'image_generation_call') {\n // Track image generation for when it completes\n console.log(`[processStreamEvent] image_generation_call added: id=${event.item.id}, status=${event.item.status}`);\n state.imageGenerations.set(event.item.id, {\n id: event.item.id,\n status: event.item.status,\n });\n } else if (event.item.type === 'web_search_call') {\n // Track web search for when it completes\n console.log(`[processStreamEvent] web_search_call added: id=${event.item.id}, status=${event.item.status}`);\n state.webSearches.set(event.item.id, {\n id: event.item.id,\n status: event.item.status,\n });\n }\n break;\n\n case 'response.output_item.done':\n // Handle completed image generation\n if (event.item.type === 'image_generation_call') {\n console.log(`[processStreamEvent] image_generation_call done: id=${event.item.id}, status=${event.item.status}, hasResult=${!!event.item.result}, resultLength=${event.item.result?.length || 0}`);\n // Emit image when we have result data - don't require status to be 'completed'\n // OpenAI may return status='generating' even when the result is ready\n if (event.item.result) {\n const imageIndex = state.imageIndex;\n state.imageIndex++;\n console.log(`[processStreamEvent] Emitting image-done chunk #${imageIndex}, id=${event.item.id}`);\n chunks.push({\n type: 'image-done',\n index: imageIndex,\n image: {\n id: event.item.id,\n toolName: 'image_generation',\n data: event.item.result,\n mediaType: 'image/png',\n // Note: OpenAI SDK ImageGenerationCall doesn't expose revised_prompt\n },\n });\n }\n // Clean up tracking\n state.imageGenerations.delete(event.item.id);\n } else if (event.item.type === 'web_search_call') {\n // Handle completed web search\n console.log(`[processStreamEvent] web_search_call done: id=${event.item.id}, status=${event.item.status}`);\n // Extract search actions if available (requires include: ['web_search_call.results'])\n const webSearchItem = event.item as any; // Type assertion needed as SDK types may not include action\n const actions: Array<{\n type: 'search' | 'open_page' | 'find';\n query?: string;\n url?: string;\n pattern?: string;\n sources?: Array<{ type: 'url'; url: string; title?: string }>;\n }> = [];\n\n if (webSearchItem.action) {\n actions.push({\n type: webSearchItem.action.type,\n query: webSearchItem.action.query,\n url: webSearchItem.action.url,\n pattern: webSearchItem.action.pattern,\n sources: webSearchItem.action.sources,\n });\n }\n\n chunks.push({\n type: 'web-search-done',\n result: {\n id: event.item.id,\n status: event.item.status,\n actions: actions.length > 0 ? actions : undefined,\n },\n });\n\n // Clean up tracking\n state.webSearches.delete(event.item.id);\n }\n break;\n\n case 'response.function_call_arguments.delta': {\n // SDK uses item_id, not call_id - find by iterating tracked tool calls\n const deltaToolCall = Array.from(state.toolCalls.values()).find(\n (tc) => tc.id === event.item_id\n );\n if (deltaToolCall) {\n deltaToolCall.arguments += event.delta;\n chunks.push({\n type: 'tool-call-delta',\n id: deltaToolCall.id,\n argumentsDelta: event.delta,\n });\n }\n break;\n }\n\n case 'response.function_call_arguments.done': {\n // SDK uses item_id, not call_id - find by iterating tracked tool calls\n const doneToolCall = Array.from(state.toolCalls.values()).find(\n (tc) => tc.id === event.item_id\n );\n if (doneToolCall) {\n let parsedArgs: Record<string, unknown> = {};\n try {\n parsedArgs = doneToolCall.arguments\n ? JSON.parse(doneToolCall.arguments)\n : {};\n } catch {\n // Keep empty object on parse failure\n }\n chunks.push({\n type: 'tool-call-done',\n id: doneToolCall.id,\n arguments: parsedArgs,\n });\n }\n break;\n }\n\n // Response completion\n case 'response.completed': {\n if (state.hasContent) {\n chunks.push({ type: 'content-done' });\n }\n if (state.hasReasoning) {\n chunks.push({ type: 'reasoning-done' });\n }\n\n // Extract reasoning details (including encrypted content) for multi-turn continuity\n const { reasoningDetails } = extractReasoningContent(event.response.output);\n\n chunks.push({\n type: 'finish',\n finishReason: mapFinishReason(event.response),\n usage: transformUsage(event.response.usage),\n reasoningDetails,\n });\n break;\n }\n\n case 'response.failed':\n chunks.push({\n type: 'error',\n error: event.response.error?.message || 'Response generation failed',\n code: event.response.error?.code,\n });\n break;\n\n case 'response.incomplete': {\n if (state.hasContent) {\n chunks.push({ type: 'content-done' });\n }\n if (state.hasReasoning) {\n chunks.push({ type: 'reasoning-done' });\n }\n\n // Extract reasoning details even for incomplete responses\n const { reasoningDetails: incompleteReasoningDetails } = extractReasoningContent(event.response.output);\n\n chunks.push({\n type: 'finish',\n finishReason: mapFinishReason(event.response),\n usage: transformUsage(event.response.usage),\n reasoningDetails: incompleteReasoningDetails,\n });\n break;\n }\n\n // Ignore other events\n default:\n break;\n }\n\n return chunks;\n}\n\n/**\n * Create error chunk.\n */\nexport function createErrorChunk(error: string, code?: string): ProviderStreamChunk {\n return { type: 'error', error, code };\n}\n\n// ============================================================================\n// Inspection Utilities\n// ============================================================================\n\n/**\n * Check if a string looks like base64 data that should be truncated.\n * Matches data URIs and long strings with base64-like character patterns.\n */\nfunction isBase64Like(str: string): boolean {\n // Data URIs (data:image/png;base64,...)\n if (str.startsWith('data:')) return true;\n\n // Very long strings (>200 chars) that look like base64\n // Base64 only contains A-Z, a-z, 0-9, +, /, and = for padding\n if (str.length > 200) {\n const base64Pattern = /^[A-Za-z0-9+/]+=*$/;\n // Check first 200 chars to avoid regex on huge strings\n return base64Pattern.test(str.substring(0, 200));\n }\n\n return false;\n}\n\n/**\n * Truncate a base64 string for display, preserving the start and showing length.\n */\nfunction truncateBase64String(str: string, maxLength: number = 50): string {\n if (str.length <= maxLength) return str;\n\n const preview = str.substring(0, maxLength);\n return `${preview}...[truncated, ${str.length.toLocaleString()} chars]`;\n}\n\n/**\n * Recursively truncate base64 data in an object for inspection.\n * Detects base64 strings (data URIs and long base64-like strings) and truncates them.\n *\n * @param obj - The object to process\n * @param maxLength - Maximum length for base64 preview (default 50)\n * @returns A new object with base64 data truncated\n */\nexport function truncateBase64<T>(obj: T, maxLength: number = 50): T {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n // Handle strings\n if (typeof obj === 'string') {\n if (isBase64Like(obj)) {\n return truncateBase64String(obj, maxLength) as T;\n }\n return obj;\n }\n\n // Handle arrays\n if (Array.isArray(obj)) {\n return obj.map(item => truncateBase64(item, maxLength)) as T;\n }\n\n // Handle objects\n if (typeof obj === 'object') {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n result[key] = truncateBase64(value, maxLength);\n }\n return result as T;\n }\n\n // Return primitives as-is\n return obj;\n}\n","/**\n * OpenAI icon as SVG string.\n * Embedded directly to avoid external dependencies.\n */\nexport const OPENAI_ICON = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"48\" height=\"48\" viewBox=\"0 0 48 48\" fill=\"none\">\n<rect width=\"48\" height=\"48\" rx=\"24\" fill=\"white\"/>\n<path d=\"M19.3418 18.5599V14.7599C19.3418 14.4399 19.4608 14.1998 19.7382 14.04L27.3102 9.63997C28.3409 9.03999 29.5699 8.76014 30.8383 8.76014C35.5954 8.76014 38.6085 12.4802 38.6085 16.4401C38.6085 16.72 38.6085 17.04 38.5687 17.3601L30.7194 12.72C30.2437 12.4401 29.7678 12.4401 29.2922 12.72L19.3418 18.5599ZM37.0226 33.36V24.2799C37.0226 23.7197 36.7846 23.3197 36.309 23.0398L26.3586 17.1998L29.6093 15.3197C29.8868 15.1599 30.1247 15.1599 30.4022 15.3197L37.9741 19.7197C40.1547 20.9999 41.6213 23.7197 41.6213 26.3596C41.6213 29.3995 39.8375 32.1999 37.0226 33.36ZM17.0029 25.3601L13.7522 23.4402C13.4748 23.2804 13.3557 23.0402 13.3557 22.7202V13.9203C13.3557 9.64039 16.6065 6.40016 21.0069 6.40016C22.6722 6.40016 24.2179 6.96029 25.5265 7.96025L17.7168 12.5204C17.2412 12.8003 17.0033 13.2002 17.0033 13.7605L17.0029 25.3601ZM24 29.44L19.3418 26.8001V21.2003L24 18.5604L28.6578 21.2003V26.8001L24 29.44ZM26.993 41.6002C25.3278 41.6002 23.7821 41.04 22.4735 40.0402L30.2831 35.4799C30.7588 35.2001 30.9967 34.8001 30.9967 34.2399V22.6399L34.2873 24.5598C34.5646 24.7196 34.6837 24.9597 34.6837 25.2798V34.0797C34.6837 38.3596 31.3931 41.6002 26.993 41.6002ZM17.5975 32.6802L10.0255 28.2803C7.84493 27.0001 6.37833 24.2803 6.37833 21.6404C6.37833 18.5604 8.20193 15.8004 11.0164 14.6403V23.7602C11.0164 24.3204 11.2544 24.7204 11.73 25.0003L21.641 30.8001L18.3902 32.6802C18.1129 32.84 17.8749 32.84 17.5975 32.6802ZM17.1617 39.2402C12.682 39.2402 9.39151 35.8402 9.39151 31.6401C9.39151 31.3201 9.43125 31.0001 9.47066 30.68L17.2803 35.2402C17.7559 35.5201 18.2319 35.5201 18.7074 35.2402L28.6578 29.4404V33.2404C28.6578 33.5605 28.5388 33.8005 28.2614 33.9604L20.6894 38.3604C19.6586 38.9603 18.4301 39.2402 17.1617 39.2402ZM26.993 44C31.7899 44 35.7936 40.5601 36.7057 36C41.1457 34.8399 44 30.6399 44 26.36C44 23.5598 42.8108 20.8401 40.6701 18.88C40.8683 18.0399 40.9872 17.1998 40.9872 16.3602C40.9872 10.6403 36.3885 6.35998 31.0763 6.35998C30.0062 6.35998 28.9754 6.51979 27.9446 6.88001C26.1604 5.11992 23.7025 4 21.0069 4C16.2101 4 12.2064 7.4398 11.2943 12C6.8543 13.1601 4 17.3601 4 21.6399C4 24.4401 5.18916 27.1599 7.32995 29.1199C7.13174 29.96 7.01277 30.8001 7.01277 31.6398C7.01277 37.3597 11.6114 41.6399 16.9236 41.6399C17.9938 41.6399 19.0246 41.4801 20.0554 41.1199C21.8392 42.88 24.2971 44 26.993 44Z\" fill=\"black\"/>\n</svg>`;\n\n/**\n * Convert SVG string to data URI for use in img src.\n */\nexport function svgToDataUri(svg: string): string {\n const encoded = encodeURIComponent(svg)\n .replace(/'/g, '%27')\n .replace(/\"/g, '%22');\n return `data:image/svg+xml,${encoded}`;\n}\n\n/**\n * Get the OpenAI icon as a data URI.\n */\nexport function getOpenAIIconDataUri(): string {\n return svgToDataUri(OPENAI_ICON);\n}\n","/**\n * OpenAI provider options schema.\n *\n * Defines typed providerOptions for OpenAI models, providing\n * TypeScript autocompletion and runtime validation.\n *\n * @see https://platform.openai.com/docs/api-reference/chat/create\n * @module\n */\n\nimport { z } from 'zod';\n\n/**\n * OpenAI provider options schema.\n *\n * These options are passed directly to the OpenAI API and control\n * various aspects of request handling and generation.\n *\n * @example\n * ```typescript\n * providerOptions: {\n * service_tier: 'default',\n * user: 'user-123',\n * seed: 42,\n * }\n * ```\n */\nexport const openaiProviderOptions = z.object({\n /** Service tier for request: 'auto', 'default', or 'flex' */\n service_tier: z.enum(['auto', 'default', 'flex']).optional(),\n\n /** User identifier for abuse monitoring */\n user: z.string().optional(),\n\n /** Seed for deterministic outputs (beta feature) */\n seed: z.number().int().optional(),\n\n /** Frequency penalty (-2.0 to 2.0) - reduces repetition of tokens */\n frequency_penalty: z.number().min(-2).max(2).optional(),\n\n /** Presence penalty (-2.0 to 2.0) - encourages new topics */\n presence_penalty: z.number().min(-2).max(2).optional(),\n\n /** Whether to return log probabilities of output tokens */\n logprobs: z.boolean().optional(),\n\n /** Number of most likely tokens to return at each position (0-20) */\n top_logprobs: z.number().int().min(0).max(20).optional(),\n\n /** Whether to store the completion for future reference */\n store: z.boolean().optional(),\n\n /** Metadata for stored completions */\n metadata: z.record(z.string(), z.string()).optional(),\n}).passthrough(); // Allow unknown keys for forward compatibility\n\n/**\n * TypeScript type for OpenAI provider options.\n * Inferred from the Zod schema for type-safe usage.\n */\nexport type OpenAIProviderOptions = z.infer<typeof openaiProviderOptions>;\n","import type { ProviderFactoryWithOptions, ProviderFactoryConfig } from '@standardagents/spec';\nimport { OpenAIProvider } from './OpenAIProvider';\nimport { openaiProviderOptions } from './providerOptions';\n\n/**\n * OpenAI provider factory for Standard Agents\n *\n * Includes typed providerOptions for OpenAI-specific configuration.\n *\n * @example\n * ```typescript\n * import { defineModel } from '@standardagents/builder';\n * import { openai } from '@standardagents/openai';\n *\n * export default defineModel({\n * name: 'gpt-4o',\n * provider: openai,\n * model: 'gpt-4o',\n * inputPrice: 2.5,\n * outputPrice: 10,\n * capabilities: {\n * supportsImages: true,\n * supportsToolCalls: true,\n * supportsJsonMode: true,\n * maxContextTokens: 128000,\n * },\n * providerOptions: {\n * service_tier: 'default',\n * },\n * });\n * ```\n */\nexport const openai: ProviderFactoryWithOptions<typeof openaiProviderOptions> =\n Object.assign(\n (config: ProviderFactoryConfig) => new OpenAIProvider(config),\n { providerOptions: openaiProviderOptions }\n );\n\n// Re-export the provider options schema and types\nexport { openaiProviderOptions, type OpenAIProviderOptions } from './providerOptions';\n\n// Re-export the provider class for advanced usage\nexport { OpenAIProvider } from './OpenAIProvider';\n"],"mappings":"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","names":["z"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@standardagents/openai",
|
|
3
|
+
"version": "0.10.0-dev.ffffff",
|
|
4
|
+
"private": false,
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "restricted",
|
|
7
|
+
"registry": "https://registry.npmjs.org/"
|
|
8
|
+
},
|
|
9
|
+
"type": "module",
|
|
10
|
+
"description": "OpenAI provider for Standard Agents",
|
|
11
|
+
"main": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"import": "./dist/index.js"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"README.md"
|
|
22
|
+
],
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"openai": "^4.77.0",
|
|
25
|
+
"zod": "^4.3.5"
|
|
26
|
+
},
|
|
27
|
+
"peerDependencies": {
|
|
28
|
+
"@standardagents/spec": "^0.10.0"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"tsup": "^8.3.5",
|
|
32
|
+
"typescript": "^5.9.0",
|
|
33
|
+
"@standardagents/spec": "0.10.0"
|
|
34
|
+
},
|
|
35
|
+
"keywords": [
|
|
36
|
+
"standardagents",
|
|
37
|
+
"openai",
|
|
38
|
+
"provider",
|
|
39
|
+
"ai",
|
|
40
|
+
"llm",
|
|
41
|
+
"gpt"
|
|
42
|
+
],
|
|
43
|
+
"author": "FormKit Inc.",
|
|
44
|
+
"license": "UNLICENSED",
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "tsup",
|
|
47
|
+
"dev": "tsup --watch",
|
|
48
|
+
"typecheck": "tsc --noEmit",
|
|
49
|
+
"test": "cd ../.. && vitest --dir packages/openai",
|
|
50
|
+
"test:run": "cd ../.. && vitest run --dir packages/openai"
|
|
51
|
+
}
|
|
52
|
+
}
|