{"version":3,"sources":["../../src/core/client.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import type { UseSomaOptions, SomaMessage, SomaStreamEvent } from '../types'\n\nexport interface SomaCoreClientState {\n  messages: SomaMessage[]\n  isConnected: boolean\n  isStreaming: boolean\n  streamContent: string\n}\n\nexport type SomaStateChangeListener = (state: SomaCoreClientState) => void\n\nexport class SomaCoreClient {\n  private options: UseSomaOptions\n  private ws: WebSocket | null = null\n  private ready = false\n  private pending: string[] = []\n\n  public messages: SomaMessage[] = []\n  public isConnected = false\n  public isStreaming = false\n  public streamContent = ''\n\n  private streamRef = ''\n  private contentRef = ''\n  private thinkingRef = ''\n  private historyLoaded = false\n  private listeners: Set<SomaStateChangeListener> = new Set()\n\n  constructor(options: UseSomaOptions) {\n    this.options = options\n  }\n\n  public subscribe(listener: SomaStateChangeListener): () => void {\n    this.listeners.add(listener)\n    listener(this.getState())\n    return () => {\n      this.listeners.delete(listener)\n    }\n  }\n\n  public getState(): SomaCoreClientState {\n    return {\n      messages: [...this.messages],\n      isConnected: this.isConnected,\n      isStreaming: this.isStreaming,\n      streamContent: this.streamContent,\n    }\n  }\n\n  private notify() {\n    const state = this.getState()\n    for (const listener of this.listeners) {\n      listener(state)\n    }\n  }\n\n  public updateOptions(newOptions: Partial<UseSomaOptions>) {\n    this.options = { ...this.options, ...newOptions }\n  }\n\n  /**\n   * Auth headers for REST calls.\n   *\n   * Prefer the `authHeaders` factory when provided (it is the documented escape\n   * hatch for custom auth, e.g. `x-api-key`). Otherwise fall back to the legacy\n   * `Authorization: Bearer <apiKey>` used by the rest of the core client.\n   */\n  private restHeaders(): Record<string, string> {\n    if (this.options.authHeaders) return this.options.authHeaders()\n    const { apiKey } = this.options\n    return apiKey ? { Authorization: `Bearer ${apiKey}` } : {}\n  }\n\n  private get wsUrl(): string {\n    const { baseUrl = '', wsPath = '/agent-ws' } = this.options\n    if (baseUrl) {\n      const proto = baseUrl.startsWith('https') ? 'wss' : 'ws'\n      const cleanHost = baseUrl.replace(/^https?:\\/\\//, '')\n      return `${proto}://${cleanHost}${wsPath}`\n    }\n    if (typeof window !== 'undefined') {\n      const proto = window.location.protocol === 'https:' ? 'wss' : 'ws'\n      return `${proto}://${window.location.host}${wsPath}`\n    }\n    return `ws://localhost:4000${wsPath}`\n  }\n\n  public async loadHistory(): Promise<void> {\n    const { agentId, conversationId = `dm:${agentId}`, apiKey, baseUrl = '' } = this.options\n    if (this.historyLoaded || !apiKey || !conversationId) return\n    this.historyLoaded = true\n\n    const api = baseUrl ? `${baseUrl}/api/conversations/${encodeURIComponent(conversationId)}` : ''\n    if (!api) return\n\n    try {\n      const res = await fetch(api, {\n        headers: { Authorization: `Bearer ${apiKey}` },\n      })\n      if (res.ok) {\n        const data = await res.json()\n        if (data.messages?.length) {\n          this.messages = data.messages.map((m: any) => ({\n            id: m.id || crypto.randomUUID(),\n            role: m.role,\n            content: m.content,\n            thinking: m.thinking,\n            tools: m.tools,\n            timestamp: new Date(m.timestamp || Date.now()),\n          }))\n          this.notify()\n        }\n      }\n    } catch {\n      /* offline or backend unavailable */\n    }\n  }\n\n  /**\n   * Delete a conversation on the backend (soft-delete).\n   * Maps to `DELETE /api/conversations/:id`.\n   *\n   * @param conversationId optional — defaults to the client's `conversationId`.\n   * @returns true if the backend confirmed the deletion, false otherwise.\n   *\n   * @remarks\n   * This clears the local session state (messages + any in-flight stream/pending\n   * buffers). It does NOT close the WebSocket or change the active `cid` — the\n   * server may still append to the deleted conversation until you reconnect. If\n   * you need to \"delete and start fresh\", call `disconnect()` and then\n   * `updateOptions({ conversationId: '<new-id>' })` before `connect()`.\n   */\n  public async deleteConversation(conversationId?: string): Promise<boolean> {\n    const { agentId, conversationId: defaultCid = `dm:${agentId}`, baseUrl = '' } = this.options\n    const id = conversationId || defaultCid\n    if (!baseUrl || !id) return false\n\n    try {\n      const res = await fetch(`${baseUrl}/api/conversations/${encodeURIComponent(id)}`, {\n        method: 'DELETE',\n        headers: this.restHeaders(),\n      })\n      if (!res.ok) {\n        if (res.status === 401 || res.status === 403) {\n          this.options.onAuthError?.(res.status)\n        }\n        return false\n      }\n      this.resetSession()\n      this.notify()\n      return true\n    } catch {\n      return false\n    }\n  }\n\n  /**\n   * Reset local state after a successful delete: clears messages, history flag,\n   * in-flight stream buffers, streaming flag and queued (pending) prompts.\n   */\n  private resetSession(): void {\n    this.messages = []\n    this.historyLoaded = false\n    this.streamRef = ''\n    this.contentRef = ''\n    this.thinkingRef = ''\n    this.streamContent = ''\n    this.isStreaming = false\n    this.pending = []\n  }\n\n  public connect(): void {\n    if (this.ws?.readyState === WebSocket.OPEN) return\n\n    this.loadHistory()\n\n    const { agentId, conversationId = `dm:${agentId}`, apiKey } = this.options\n    const ws = new WebSocket(this.wsUrl)\n    ws.binaryType = 'arraybuffer'\n\n    ws.onopen = () => {\n      ws.send(\n        JSON.stringify({\n          type: 'init',\n          uid: agentId,\n          cid: conversationId,\n          token: apiKey || '',\n        })\n      )\n    }\n\n    ws.onmessage = (event) => {\n      try {\n        let raw: string\n        if (typeof event.data === 'string') {\n          raw = event.data\n        } else if (event.data instanceof ArrayBuffer) {\n          raw = new TextDecoder().decode(event.data)\n        } else if (event.data instanceof Blob) {\n          event.data\n            .text()\n            .then((text: string) => this.processMessage(text, ws))\n            .catch(() => {})\n          return\n        } else {\n          return\n        }\n        this.processMessage(raw, ws)\n      } catch (e) {\n        console.error('[SomaCoreClient] onmessage error:', e)\n      }\n    }\n\n    ws.onclose = () => {\n      this.isConnected = false\n      this.ready = false\n      this.notify()\n    }\n\n    ws.onerror = () => {\n      this.options.onError?.('Connection error')\n    }\n\n    this.ws = ws\n  }\n\n  private processMessage(raw: string, ws: WebSocket) {\n    const d: SomaStreamEvent = JSON.parse(raw)\n    switch (d.type) {\n      case 'ready':\n        this.ready = true\n        this.isConnected = true\n        this.notify()\n        for (const text of this.pending) {\n          ws.send(JSON.stringify({ type: 'prompt', text }))\n        }\n        this.pending = []\n        break\n\n      case 'thinking_start':\n        this.isStreaming = true\n        this.thinkingRef = ''\n        this.notify()\n        break\n\n      case 'thinking':\n        this.thinkingRef += d.text\n        this.options.onThinking?.(d.text)\n        this.notify()\n        break\n\n      case 'thinking_end':\n        break\n\n      case 'delta':\n        this.streamRef += d.text\n        this.contentRef = this.streamRef\n        this.streamContent = this.streamRef\n        this.options.onDelta?.(d.text)\n        this.notify()\n        break\n\n      case 'tool':\n        this.options.onTool?.(d.name, d.input)\n        break\n\n      case 'done': {\n        this.isStreaming = false\n        const content = this.contentRef || this.streamRef\n        const thinking = this.thinkingRef.trim() || undefined\n\n        if (content || thinking) {\n          this.messages.push({\n            id: crypto.randomUUID(),\n            role: 'assistant',\n            content: content || '(sin respuesta)',\n            thinking,\n            timestamp: new Date(),\n          })\n          this.contentRef = ''\n          this.streamRef = ''\n          this.thinkingRef = ''\n          this.streamContent = ''\n        }\n        this.notify()\n        this.options.onDone?.()\n        break\n      }\n\n      case 'cancelled': {\n        this.isStreaming = false\n        const content = this.contentRef || this.streamRef || ''\n        if (content) {\n          this.messages.push({\n            id: crypto.randomUUID(),\n            role: 'assistant',\n            content: content + '\\n\\n_⏹️ Cancelado_',\n            thinking: this.thinkingRef.trim() || undefined,\n            timestamp: new Date(),\n          })\n          this.contentRef = ''\n          this.streamRef = ''\n          this.thinkingRef = ''\n          this.streamContent = ''\n        }\n        this.notify()\n        this.options.onCancelled?.()\n        break\n      }\n\n      case 'error':\n        this.isStreaming = false\n        this.notify()\n        this.options.onError?.(d.message)\n        break\n    }\n  }\n\n  public send(text: string): void {\n    this.messages.push({\n      id: crypto.randomUUID(),\n      role: 'user',\n      content: text,\n      timestamp: new Date(),\n    })\n    this.notify()\n\n    if (this.ready && this.ws?.readyState === WebSocket.OPEN) {\n      this.ws.send(JSON.stringify({ type: 'prompt', text }))\n    } else {\n      this.pending.push(text)\n      this.connect()\n    }\n  }\n\n  public cancel(): void {\n    if (this.ws?.readyState === WebSocket.OPEN) {\n      this.ws.send(JSON.stringify({ type: 'cancel' }))\n    }\n  }\n\n  public reconnect(): void {\n    this.disconnect()\n    this.connect()\n  }\n\n  public disconnect(): void {\n    if (this.ws) {\n      this.ws.close()\n      this.ws = null\n    }\n    this.ready = false\n    this.isConnected = false\n    this.notify()\n  }\n}\n"]}