{
  "version": 3,
  "sources": ["../src/index.ts", "../src/service.ts"],
  "sourcesContent": ["// Public API\n\n// Re-export useful types from @yak-io/javascript for consumers\nexport type {\n  ChatConfigProvider,\n  GraphQLRequest,\n  RESTRequest,\n  Theme,\n  ThemeColors,\n  ToolAdapter,\n  ToolCallEvent,\n  ToolCallHandler,\n  TriggerButtonConfig,\n  UserIdentity,\n  VoiceMachine,\n  VoiceState,\n  WidgetMode,\n  WidgetPosition,\n  YakServerAdapterConfig,\n  YakToolset,\n} from \"@yak-io/javascript\";\n// Re-export tool composition + logging utilities\nexport {\n  createYakServerAdapter,\n  createYakToolset,\n  disableYakLogging,\n  enableYakLogging,\n  isYakLoggingEnabled,\n} from \"@yak-io/javascript\";\nexport type {\n  ToolCallEventHandler,\n  YakApi,\n  YakProviderOptions,\n  YakState,\n} from \"./service.js\";\nexport { createYakProvider } from \"./service.js\";\n", "import {\n  type ChatConfigProvider,\n  INITIAL_VOICE_MACHINE,\n  logger,\n  type Theme,\n  type ToolCallEvent,\n  type ToolCallHandler,\n  type TriggerButtonConfig,\n  type UserIdentity,\n  type VoiceMachine,\n  type WidgetMode,\n  YakEmbed,\n} from \"@yak-io/javascript\";\n\n// \u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type ToolCallEventHandler = (event: ToolCallEvent) => void;\n\nexport type YakProviderOptions = {\n  appId: string;\n  mode?: WidgetMode;\n  getConfig?: ChatConfigProvider;\n  onToolCall?: ToolCallHandler;\n  theme?: Theme;\n  onRedirect?: (path: string) => void;\n  disableRestartButton?: boolean;\n  /**\n   * Privacy opt-out: stop sending any page context (URL, title, visible text)\n   * to the assistant. The widget still works; it just won't be aware of the\n   * current page.\n   */\n  disablePageContent?: boolean;\n  trigger?: boolean | TriggerButtonConfig;\n  /**\n   * Signed end-user identity. When supplied, the widget persists conversations\n   * server-side keyed to this user and surfaces a history pane. The `hash` must\n   * be HMAC-SHA256(apiSecret, id) computed on the integrator's backend \u2014 never\n   * expose `apiSecret` to the browser. Omit for anonymous mode (no persistence).\n   * Use `setUser()` to change it after setup (login/logout).\n   */\n  user?: UserIdentity;\n};\n\nexport type YakState = {\n  isOpen: boolean;\n  isReady: boolean;\n  chatLoading: boolean;\n  voiceMachine: VoiceMachine;\n  voiceLoading: boolean;\n};\n\n/** Handle for controlling the Yak widget \u2014 chat + voice \u2014 from Angular. */\nexport type YakApi = {\n  /** Whether the chat panel is currently open. */\n  readonly isOpen: boolean;\n  /** Whether the chat iframe is ready to receive messages. */\n  readonly isReady: boolean;\n  /** Whether the chat is opening but not yet interactive (`isOpen && !isReady`). */\n  readonly chatLoading: boolean;\n  /** Current voice state-machine snapshot. `idle` when mode is `chat`. */\n  readonly voiceMachine: VoiceMachine;\n  /** Whether the voice session is establishing its connection (`state === \"connecting\"`). */\n  readonly voiceLoading: boolean;\n  /** Open the chat panel. */\n  open: () => void;\n  /** Close the chat panel. */\n  close: () => void;\n  /** Open the chat panel and send a specific prompt. */\n  openWithPrompt: (prompt: string) => void;\n  /** Start a voice session. Must be invoked from a user gesture. */\n  voiceStart: () => Promise<void>;\n  /** Stop the current voice session. */\n  voiceStop: () => Promise<void>;\n  /** Toggle voice: start if idle/error, stop if active. */\n  voiceToggle: () => Promise<void>;\n  /**\n   * Set or clear the signed end-user identity after setup. Call on login\n   * (`setUser({ id, hash })`) and logout (`setUser(undefined)`). Switching to a\n   * different id or logging out rotates the stored session token; the first\n   * login after anonymous use keeps it so pre-login history can be claimed.\n   */\n  setUser: (user?: UserIdentity) => void;\n  /** Subscribe to tool-call completion events; returns an unsubscribe function. */\n  subscribeToToolEvents: (handler: ToolCallEventHandler) => () => void;\n  /** Subscribe to chat + voice state changes. */\n  subscribeToState: (handler: (state: YakState) => void) => () => void;\n  /** Mount the widget into the DOM. */\n  mount: () => void;\n  /** Tear down the widget and remove its listeners. */\n  destroy: () => void;\n};\n\n// \u2500\u2500 Provider factory \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Creates a yak widget (chat + voice) for Angular.\n * Call `mount()` in `ngOnInit` and `destroy()` in `ngOnDestroy`.\n */\nexport function createYakProvider(options: YakProviderOptions): YakApi {\n  let _isOpen = false;\n  let _isReady = false;\n  let _voiceMachine: VoiceMachine = INITIAL_VOICE_MACHINE;\n  const toolEventSubscribers = new Set<ToolCallEventHandler>();\n  const stateSubscribers = new Set<(state: YakState) => void>();\n\n  const notifyState = () => {\n    const snap: YakState = {\n      isOpen: _isOpen,\n      isReady: _isReady,\n      chatLoading: _isOpen && !_isReady,\n      voiceMachine: _voiceMachine,\n      voiceLoading: _voiceMachine.state === \"connecting\",\n    };\n    for (const subscriber of stateSubscribers) {\n      try {\n        subscriber(snap);\n      } catch (err) {\n        logger.warn(\"Error in state subscriber:\", err);\n      }\n    }\n  };\n\n  const handleToolCallComplete = (event: ToolCallEvent) => {\n    logger.debug(\"Tool call completed, notifying subscribers:\", {\n      name: event.name,\n      ok: event.ok,\n      subscriberCount: toolEventSubscribers.size,\n    });\n    for (const handler of toolEventSubscribers) {\n      try {\n        handler(event);\n      } catch (err) {\n        logger.warn(\"Error in tool event subscriber:\", err);\n      }\n    }\n  };\n\n  const resolvedRedirect =\n    options.onRedirect ??\n    (typeof window !== \"undefined\" ? (path: string) => window.location.assign(path) : undefined);\n\n  const embed = new YakEmbed({\n    appId: options.appId,\n    mode: options.mode,\n    theme: options.theme,\n    trigger: options.trigger ?? false,\n    getConfig: options.getConfig,\n    onToolCall: options.onToolCall,\n    onRedirect: resolvedRedirect,\n    options: {\n      disableRestartButton: options.disableRestartButton,\n      disablePageContent: options.disablePageContent,\n    },\n    onToolCallComplete: handleToolCallComplete,\n    user: options.user,\n  });\n\n  embed.onStateChange((state) => {\n    _isOpen = state.isOpen;\n    _isReady = state.isReady;\n    notifyState();\n  });\n  embed.onVoiceStateChange((m) => {\n    _voiceMachine = m;\n    notifyState();\n  });\n\n  // Fetch chat config on first open\n  if (options.getConfig) {\n    const getConfig = options.getConfig;\n    let configFetched = false;\n\n    embed.onStateChange((state) => {\n      if (state.isOpen && !configFetched) {\n        configFetched = true;\n        logger.debug(\"Getting chat config\");\n\n        Promise.resolve(getConfig())\n          .then((config) => {\n            logger.debug(\n              `Chat config loaded with ${config.tools?.tools.length ?? 0} tools and ${config.routes?.routes.length ?? 0} routes`\n            );\n            embed.getClient().updateConfig({ chatConfig: config });\n          })\n          .catch((err) => {\n            logger.warn(\"Error getting chat config:\", err);\n            configFetched = false;\n          });\n      }\n    });\n  }\n\n  const voiceStart = async () => {\n    try {\n      await embed.voiceStart();\n    } catch (err) {\n      logger.warn(\"Voice start failed\", err);\n    }\n  };\n\n  return {\n    get isOpen() {\n      return _isOpen;\n    },\n    get isReady() {\n      return _isReady;\n    },\n    get chatLoading() {\n      return _isOpen && !_isReady;\n    },\n    get voiceMachine() {\n      return _voiceMachine;\n    },\n    get voiceLoading() {\n      return _voiceMachine.state === \"connecting\";\n    },\n    open: () => embed.open(),\n    close: () => embed.close(),\n    openWithPrompt: (prompt: string) => embed.openWithPrompt(prompt),\n    voiceStart,\n    voiceStop: () => embed.voiceStop(),\n    voiceToggle: () => embed.voiceToggle(),\n    setUser: (user?: UserIdentity) => {\n      // Core clears/rotates the session token when the id changes; we only forward.\n      embed.getClient().updateConfig({ user });\n      embed.getVoiceSession()?.updateConfig({ user });\n    },\n    subscribeToToolEvents: (handler: ToolCallEventHandler) => {\n      toolEventSubscribers.add(handler);\n      return () => {\n        toolEventSubscribers.delete(handler);\n      };\n    },\n    subscribeToState: (handler: (state: YakState) => void) => {\n      stateSubscribers.add(handler);\n      return () => {\n        stateSubscribers.delete(handler);\n      };\n    },\n    mount: () => embed.mount(),\n    destroy: () => embed.destroy(),\n  };\n}\n"],
  "mappings": "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",
  "names": ["import_javascript"]
}
