{"version":3,"sources":["../../src/llm/openai-provider.ts","../../src/llm/gateway-provider.ts","../../src/llm/factory.ts"],"sourcesContent":["// ---------------------------------------------------------------------------\n// @agentx/sdk — OpenAI Provider\n// ---------------------------------------------------------------------------\n// Direct OpenAI-compatible chat completions with SSE streaming.\n// Supports: OpenAI, DeepSeek, and any /v1/chat/completions endpoint.\n// ---------------------------------------------------------------------------\n\nimport type { ChatRequest, ChatStreamEvent, LLMProvider } from '../agent-loop/types'\nimport type { OpenAIProviderConfig } from './types'\n\nconst DEFAULT_ENDPOINT = 'https://api.openai.com/v1'\n\ninterface SSEData {\n  choices?: {\n    index: number\n    delta?: {\n      content?: string\n      tool_calls?: {\n        index: number\n        id?: string\n        function?: { name?: string; arguments?: string }\n      }[]\n    }\n    finish_reason?: string | null\n  }[]\n  usage?: {\n    prompt_tokens: number\n    completion_tokens: number\n    total_tokens: number\n  }\n}\n\nexport class OpenAIProvider implements LLMProvider {\n  private config: Required<OpenAIProviderConfig>\n\n  /** Model the provider is configured with (used by AgentLoop when no explicit ctx.model) */\n  get model(): string | undefined {\n    return this.config.model\n  }\n\n  constructor(config: OpenAIProviderConfig) {\n    this.config = {\n      endpoint: config.endpoint ?? DEFAULT_ENDPOINT,\n      model: config.model,\n      apiKey: config.apiKey,\n      temperature: config.temperature ?? 0.7,\n      maxTokens: config.maxTokens ?? 4096,\n      timeoutMs: config.timeoutMs ?? 60_000,\n    }\n  }\n\n  async *chatStream(request: ChatRequest, signal?: AbortSignal): AsyncGenerator<ChatStreamEvent> {\n    const endpoint = `${this.config.endpoint}/chat/completions`\n\n    const body = JSON.stringify({\n      model: request.model || this.config.model,\n      messages: request.messages,\n      tools: request.tools,\n      temperature: request.temperature ?? this.config.temperature,\n      max_tokens: request.maxTokens ?? this.config.maxTokens,\n      stream: true,\n      stream_options: { include_usage: true },\n    })\n\n    let response: Response\n    try {\n      response = await fetch(endpoint, {\n        method: 'POST',\n        headers: {\n          'Content-Type': 'application/json',\n          'Authorization': `Bearer ${this.config.apiKey}`,\n        },\n        body,\n        signal,\n      })\n    } catch (err) {\n      if ((err as Error).name === 'AbortError') {\n        yield { type: 'error', error: new Error('Request aborted') }\n      } else {\n        yield { type: 'error', error: err instanceof Error ? err : new Error(String(err)) }\n      }\n      return\n    }\n\n    if (!response.ok) {\n      let errorText = ''\n      try { errorText = await response.text() } catch { /* ignore */ }\n      yield { type: 'error', error: new Error(`HTTP ${response.status}: ${errorText}`) }\n      return\n    }\n\n    const reader = response.body?.getReader()\n    if (!reader) {\n      yield { type: 'error', error: new Error('No response body') }\n      return\n    }\n\n    const decoder = new TextDecoder()\n    let buffer = ''\n\n    // DeepSeek/OpenAI 流式 tool_calls: 首 chunk 带 id+name, 后续参数增量 chunk 只带 index。\n    // 维护 index→id 映射, 使 delta 能关联到 start 的真实 callId, 否则 arguments 会被丢弃。\n    const callIdsByIndex = new Map<number, string>()\n\n    try {\n      while (true) {\n        const { done, value } = await reader.read()\n        if (done) break\n\n        buffer += decoder.decode(value, { stream: true })\n        const lines = buffer.split('\\n')\n        buffer = lines.pop() ?? ''\n\n        for (const line of lines) {\n          const trimmed = line.trim()\n          if (!trimmed || !trimmed.startsWith('data:')) continue\n\n          const dataStr = trimmed.slice(5).trim()\n          if (dataStr === '[DONE]') {\n            continue\n          }\n\n          let data: SSEData\n          try {\n            data = JSON.parse(dataStr)\n          } catch {\n            continue\n          }\n\n          if (data.usage) {\n            yield {\n              type: 'done',\n              usage: {\n                promptTokens: data.usage.prompt_tokens,\n                completionTokens: data.usage.completion_tokens,\n                totalTokens: data.usage.total_tokens,\n              },\n            }\n            continue\n          }\n\n          const choice = data.choices?.[0]\n          if (!choice) continue\n\n          if (choice.delta?.content) {\n            yield { type: 'text_delta', content: choice.delta.content }\n          }\n\n          if (choice.delta?.tool_calls) {\n            for (const tc of choice.delta.tool_calls) {\n              if (tc.id) callIdsByIndex.set(tc.index, tc.id)\n              if (tc.id && tc.function?.name) {\n                yield { type: 'tool_call_start', callId: tc.id, name: tc.function.name }\n              }\n              if (tc.function?.arguments) {\n                yield {\n                  type: 'tool_call_delta',\n                  callId: tc.id ?? callIdsByIndex.get(tc.index) ?? `call_${tc.index}`,\n                  arguments: tc.function.arguments,\n                }\n              }\n            }\n          }\n\n          if (choice.finish_reason === 'stop' && !data.usage) {\n            yield {\n              type: 'done',\n              usage: { promptTokens: 0, completionTokens: 0, totalTokens: 0 },\n            }\n          }\n        }\n      }\n    } catch (err) {\n      if ((err as Error).name !== 'AbortError') {\n        yield { type: 'error', error: err instanceof Error ? err : new Error(String(err)) }\n      }\n    } finally {\n      reader.releaseLock()\n    }\n  }\n}\n","// ---------------------------------------------------------------------------\n// @agentx/sdk — Gateway Provider\n// ---------------------------------------------------------------------------\n// Routes LLM requests through AgentX Gateway for multi-tenant SaaS mode.\n// Gateway handles: auth, rate limiting, API key injection, usage tracking.\n// API Key never appears in the browser.\n// ---------------------------------------------------------------------------\n\nimport type { ChatRequest, ChatStreamEvent, LLMProvider } from '../agent-loop/types'\nimport type { GatewayProviderConfig } from './types'\n\ninterface GatewaySSEData {\n  choices?: {\n    index: number\n    delta?: {\n      content?: string\n      tool_calls?: {\n        index: number\n        id?: string\n        function?: { name?: string; arguments?: string }\n      }[]\n    }\n    finish_reason?: string | null\n  }[]\n  usage?: {\n    prompt_tokens: number\n    completion_tokens: number\n    total_tokens: number\n  }\n  error?: { message: string; code?: string }\n}\n\nexport class GatewayProvider implements LLMProvider {\n  private config: Required<Omit<GatewayProviderConfig, 'model' | 'tenantKeyId'>>\n    & Pick<GatewayProviderConfig, 'model' | 'tenantKeyId'>\n\n  /** Model the provider is configured with (used by AgentLoop when no explicit ctx.model) */\n  get model(): string | undefined {\n    return this.config.model\n  }\n\n  constructor(config: GatewayProviderConfig) {\n    this.config = {\n      gatewayUrl: config.gatewayUrl.replace(/\\/$/, ''),\n      accessToken: config.accessToken,\n      keySource: config.keySource ?? 'platform',\n      model: config.model,\n      tenantKeyId: config.tenantKeyId,\n      temperature: config.temperature ?? 0.7,\n      maxTokens: config.maxTokens ?? 4096,\n      timeoutMs: config.timeoutMs ?? 120_000,\n    }\n  }\n\n  async *chatStream(request: ChatRequest, signal?: AbortSignal): AsyncGenerator<ChatStreamEvent> {\n    const endpoint = `${this.config.gatewayUrl}/api/v1/chat/completions`\n\n    const body: Record<string, unknown> = {\n      model: request.model || this.config.model || 'gpt-4o',\n      messages: request.messages,\n      stream: true,\n      key_source: this.config.keySource,\n    }\n    if (request.tools && request.tools.length > 0) body.tools = request.tools\n    if (request.temperature !== undefined) body.temperature = request.temperature\n    if (request.maxTokens !== undefined) body.max_tokens = request.maxTokens\n    if (this.config.tenantKeyId) body.tenant_key_id = this.config.tenantKeyId\n\n    let response: Response\n    try {\n      response = await fetch(endpoint, {\n        method: 'POST',\n        headers: {\n          'Content-Type': 'application/json',\n          'Authorization': `Bearer ${this.config.accessToken}`,\n        },\n        body: JSON.stringify(body),\n        signal,\n      })\n    } catch (err) {\n      if ((err as Error).name === 'AbortError') {\n        yield { type: 'error', error: new Error('Request aborted') }\n      } else {\n        yield { type: 'error', error: err instanceof Error ? err : new Error(String(err)) }\n      }\n      return\n    }\n\n    if (!response.ok) {\n      let errorMsg = `Gateway HTTP ${response.status}`\n      try {\n        const errBody = await response.json() as { error?: string; message?: string }\n        errorMsg = errBody.error || errBody.message || errorMsg\n      } catch { /* use default */ }\n\n      yield { type: 'error', error: new Error(errorMsg) }\n      return\n    }\n\n    const reader = response.body?.getReader()\n    if (!reader) {\n      yield { type: 'error', error: new Error('No response body from gateway') }\n      return\n    }\n\n    const decoder = new TextDecoder()\n    let buffer = ''\n\n    // DeepSeek/OpenAI 流式 tool_calls: 首 chunk 带 id+name, 后续参数增量 chunk 只带 index。\n    // 维护 index→id 映射, 使 delta 能关联到 start 的真实 callId, 否则 arguments 会被丢弃。\n    const callIdsByIndex = new Map<number, string>()\n\n    try {\n      while (true) {\n        const { done, value } = await reader.read()\n        if (done) break\n\n        buffer += decoder.decode(value, { stream: true })\n        const lines = buffer.split('\\n')\n        buffer = lines.pop() ?? ''\n\n        for (const line of lines) {\n          const trimmed = line.trim()\n          if (!trimmed || !trimmed.startsWith('data:')) continue\n\n          const dataStr = trimmed.slice(5).trim()\n          if (dataStr === '[DONE]') continue\n\n          let data: GatewaySSEData\n          try { data = JSON.parse(dataStr) } catch { continue }\n\n          if (data.error) {\n            yield { type: 'error', error: new Error(data.error.message) }\n            return\n          }\n\n          if (data.usage) {\n            yield {\n              type: 'done',\n              usage: {\n                promptTokens: data.usage.prompt_tokens,\n                completionTokens: data.usage.completion_tokens,\n                totalTokens: data.usage.total_tokens,\n              },\n            }\n            continue\n          }\n\n          const choice = data.choices?.[0]\n          if (!choice) continue\n\n          if (choice.delta?.content) {\n            yield { type: 'text_delta', content: choice.delta.content }\n          }\n\n          if (choice.delta?.tool_calls) {\n            for (const tc of choice.delta.tool_calls) {\n              if (tc.id) callIdsByIndex.set(tc.index, tc.id)\n              if (tc.id && tc.function?.name) {\n                yield { type: 'tool_call_start', callId: tc.id, name: tc.function.name }\n              }\n              if (tc.function?.arguments) {\n                yield {\n                  type: 'tool_call_delta',\n                  callId: tc.id ?? callIdsByIndex.get(tc.index) ?? `call_${tc.index}`,\n                  arguments: tc.function.arguments,\n                }\n              }\n            }\n          }\n\n          if (choice.finish_reason === 'stop' && !data.usage) {\n            yield {\n              type: 'done',\n              usage: { promptTokens: 0, completionTokens: 0, totalTokens: 0 },\n            }\n          }\n        }\n      }\n    } catch (err) {\n      if ((err as Error).name !== 'AbortError') {\n        yield { type: 'error', error: err instanceof Error ? err : new Error(String(err)) }\n      }\n    } finally {\n      reader.releaseLock()\n    }\n  }\n}\n","// ---------------------------------------------------------------------------\n// @agentx/sdk — Provider Factory\n// ---------------------------------------------------------------------------\n// Creates the appropriate LLMProvider based on config.\n// ---------------------------------------------------------------------------\n\nimport type { LLMProvider } from '../agent-loop/types'\nimport type { ProviderFactoryConfig } from './types'\nimport { OpenAIProvider } from './openai-provider'\nimport { GatewayProvider } from './gateway-provider'\n\nexport function createLLMProvider(config: ProviderFactoryConfig): LLMProvider {\n  switch (config.type) {\n    case 'gateway':\n      if (!config.gatewayUrl || !config.accessToken) {\n        throw new Error('GatewayProvider requires gatewayUrl and accessToken')\n      }\n      return new GatewayProvider({\n        gatewayUrl: config.gatewayUrl,\n        accessToken: config.accessToken,\n        model: config.model,\n        keySource: config.keySource,\n        tenantKeyId: config.tenantKeyId,\n        temperature: config.temperature,\n        maxTokens: config.maxTokens,\n        timeoutMs: config.timeoutMs,\n      })\n\n    case 'openai':\n      if (!config.apiKey) {\n        throw new Error('OpenAIProvider requires apiKey')\n      }\n      return new OpenAIProvider({\n        apiKey: config.apiKey,\n        endpoint: config.endpoint,\n        model: config.model ?? 'gpt-4o',\n        temperature: config.temperature,\n        maxTokens: config.maxTokens,\n        timeoutMs: config.timeoutMs,\n      })\n\n    case 'direct':\n      if (!config.apiKey) {\n        throw new Error('Direct provider requires apiKey')\n      }\n      return new OpenAIProvider({\n        apiKey: config.apiKey,\n        endpoint: config.endpoint,\n        model: config.model ?? 'gpt-4o',\n        temperature: config.temperature,\n        maxTokens: config.maxTokens,\n        timeoutMs: config.timeoutMs,\n      })\n\n    default:\n      throw new Error(`Unknown provider type: ${(config as { type: string }).type}`)\n  }\n}\n"],"mappings":"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","names":[]}