@emblemvault/hustle-react 1.0.0

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.
Files changed (38) hide show
  1. package/README.md +225 -0
  2. package/dist/browser/hustle-react.js +14705 -0
  3. package/dist/browser/hustle-react.js.map +1 -0
  4. package/dist/components/index.cjs +3170 -0
  5. package/dist/components/index.cjs.map +1 -0
  6. package/dist/components/index.d.cts +58 -0
  7. package/dist/components/index.d.ts +58 -0
  8. package/dist/components/index.js +3143 -0
  9. package/dist/components/index.js.map +1 -0
  10. package/dist/hooks/index.cjs +695 -0
  11. package/dist/hooks/index.cjs.map +1 -0
  12. package/dist/hooks/index.d.cts +46 -0
  13. package/dist/hooks/index.d.ts +46 -0
  14. package/dist/hooks/index.js +691 -0
  15. package/dist/hooks/index.js.map +1 -0
  16. package/dist/hustle-S48t4lTZ.d.cts +222 -0
  17. package/dist/hustle-S48t4lTZ.d.ts +222 -0
  18. package/dist/index.cjs +3588 -0
  19. package/dist/index.cjs.map +1 -0
  20. package/dist/index.d.cts +229 -0
  21. package/dist/index.d.ts +229 -0
  22. package/dist/index.js +3547 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/plugin-BUg7vMxe.d.cts +172 -0
  25. package/dist/plugin-BUg7vMxe.d.ts +172 -0
  26. package/dist/plugins/index.cjs +1235 -0
  27. package/dist/plugins/index.cjs.map +1 -0
  28. package/dist/plugins/index.d.cts +192 -0
  29. package/dist/plugins/index.d.ts +192 -0
  30. package/dist/plugins/index.js +1225 -0
  31. package/dist/plugins/index.js.map +1 -0
  32. package/dist/providers/index.cjs +694 -0
  33. package/dist/providers/index.cjs.map +1 -0
  34. package/dist/providers/index.d.cts +46 -0
  35. package/dist/providers/index.d.ts +46 -0
  36. package/dist/providers/index.js +691 -0
  37. package/dist/providers/index.js.map +1 -0
  38. package/package.json +87 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/pluginRegistry.ts","../../src/hooks/usePlugins.ts","../../src/providers/HustleProvider.tsx"],"names":["useState","useEffect","useCallback","value","error"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Plugin Registry\n *\n * Manages plugin storage and state in localStorage.\n *\n * Storage model:\n * - Installed plugins are GLOBAL (hustle-plugins) - install once, available everywhere\n * - Enabled/disabled state is INSTANCE-SCOPED (hustle-plugin-state-{instanceId})\n *\n * Executor functions are serialized as strings (executorCode) and\n * reconstituted at runtime via new Function().\n *\n * SECURITY TODO: Add signature verification before executing stored code.\n * Plugins should be signed by trusted publishers and verified before\n * any eval/Function execution occurs.\n */\n\nimport type {\n StoredPlugin,\n HustlePlugin,\n HydratedPlugin,\n ToolExecutor,\n PluginHooks,\n SerializedToolDefinition,\n SerializedHooks,\n} from '../types';\n\n/**\n * Storage keys:\n * - PLUGINS_KEY: Global list of installed plugins (not instance-scoped)\n * - getEnabledStateKey: Per-instance enabled/disabled states\n */\nconst PLUGINS_KEY = 'hustle-plugins';\n\nfunction getEnabledStateKey(instanceId: string): string {\n return `hustle-plugin-state-${instanceId}`;\n}\n\ntype PluginChangeCallback = (plugins: StoredPlugin[]) => void;\n\n/** Stored enabled state per instance */\ntype EnabledState = Record<string, boolean>;\n\n/**\n * Serialize a function to a string for storage\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction serializeFunction(fn: (...args: any[]) => any): string {\n return fn.toString();\n}\n\n/**\n * Deserialize a function string back to executable function\n *\n * FIXME: Add signature verification before execution\n * This is a security-sensitive operation that executes stored code.\n */\nfunction deserializeExecutor(code: string): ToolExecutor {\n // Extract function body - handles arrow functions and regular functions\n // The stored code is the full function: \"(args) => { ... }\" or \"async (args) => { ... }\"\n // We wrap it in parentheses and eval to get the function reference\n try {\n // eslint-disable-next-line no-eval\n return eval(`(${code})`) as ToolExecutor;\n } catch (err) {\n console.error('[Hustle] Failed to deserialize executor:', err);\n // Return a no-op executor that reports the error\n return async () => ({ error: 'Failed to deserialize executor', code });\n }\n}\n\n/**\n * Deserialize a hook function string\n *\n * FIXME: Add signature verification before execution\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction deserializeHook<T extends (...args: any[]) => any>(code: string): T {\n try {\n // eslint-disable-next-line no-eval\n return eval(`(${code})`) as T;\n } catch (err) {\n console.error('[Hustle] Failed to deserialize hook:', err);\n return (() => {}) as T;\n }\n}\n\n/**\n * Serialize a plugin's executors to executorCode strings\n */\nfunction serializePluginTools(\n tools: HustlePlugin['tools'],\n executors: HustlePlugin['executors']\n): SerializedToolDefinition[] {\n if (!tools) return [];\n\n return tools.map((tool) => ({\n ...tool,\n executorCode: executors?.[tool.name]\n ? serializeFunction(executors[tool.name])\n : undefined,\n }));\n}\n\n/**\n * Serialize plugin hooks to code strings\n */\nfunction serializeHooks(hooks: PluginHooks | undefined): SerializedHooks | undefined {\n if (!hooks) return undefined;\n\n const serialized: SerializedHooks = {};\n\n if (hooks.onRegister) {\n serialized.onRegisterCode = serializeFunction(hooks.onRegister);\n }\n if (hooks.beforeRequest) {\n serialized.beforeRequestCode = serializeFunction(hooks.beforeRequest);\n }\n if (hooks.afterResponse) {\n serialized.afterResponseCode = serializeFunction(hooks.afterResponse);\n }\n if (hooks.onError) {\n serialized.onErrorCode = serializeFunction(hooks.onError);\n }\n\n return Object.keys(serialized).length > 0 ? serialized : undefined;\n}\n\n/**\n * Hydrate a stored plugin - reconstitute executors from executorCode\n *\n * FIXME: Add signature verification before execution\n */\nexport function hydratePlugin(stored: StoredPlugin): HydratedPlugin {\n // Reconstitute executors from executorCode strings\n const executors: Record<string, ToolExecutor> = {};\n\n if (stored.tools) {\n for (const tool of stored.tools) {\n if (tool.executorCode) {\n executors[tool.name] = deserializeExecutor(tool.executorCode);\n }\n }\n }\n\n // Reconstitute hooks from hooksCode strings\n let hooks: PluginHooks | undefined;\n\n if (stored.hooksCode) {\n hooks = {};\n if (stored.hooksCode.onRegisterCode) {\n hooks.onRegister = deserializeHook(stored.hooksCode.onRegisterCode);\n }\n if (stored.hooksCode.beforeRequestCode) {\n hooks.beforeRequest = deserializeHook(stored.hooksCode.beforeRequestCode);\n }\n if (stored.hooksCode.afterResponseCode) {\n hooks.afterResponse = deserializeHook(stored.hooksCode.afterResponseCode);\n }\n if (stored.hooksCode.onErrorCode) {\n hooks.onError = deserializeHook(stored.hooksCode.onErrorCode);\n }\n }\n\n return {\n ...stored,\n executors: Object.keys(executors).length > 0 ? executors : undefined,\n hooks,\n };\n}\n\n/**\n * Plugin Registry class\n *\n * Manages plugin persistence with:\n * - Global plugin installations (with serialized executorCode)\n * - Instance-scoped enabled/disabled state\n */\nclass PluginRegistry {\n private listeners: Map<string, Set<PluginChangeCallback>> = new Map();\n\n /**\n * Get listeners for a specific instance\n */\n private getListeners(instanceId: string): Set<PluginChangeCallback> {\n if (!this.listeners.has(instanceId)) {\n this.listeners.set(instanceId, new Set());\n }\n return this.listeners.get(instanceId)!;\n }\n\n /**\n * Load installed plugins (global)\n */\n private loadInstalledPlugins(): Omit<StoredPlugin, 'enabled'>[] {\n if (typeof window === 'undefined') return [];\n try {\n const stored = localStorage.getItem(PLUGINS_KEY);\n return stored ? JSON.parse(stored) : [];\n } catch {\n return [];\n }\n }\n\n /**\n * Save installed plugins (global)\n * Serializes executors as executorCode strings\n */\n private saveInstalledPlugins(plugins: Omit<StoredPlugin, 'enabled'>[]): void {\n if (typeof window === 'undefined') return;\n localStorage.setItem(PLUGINS_KEY, JSON.stringify(plugins));\n }\n\n /**\n * Load enabled state for an instance\n */\n private loadEnabledState(instanceId: string): EnabledState {\n if (typeof window === 'undefined') return {};\n try {\n const stored = localStorage.getItem(getEnabledStateKey(instanceId));\n return stored ? JSON.parse(stored) : {};\n } catch {\n return {};\n }\n }\n\n /**\n * Save enabled state for an instance\n */\n private saveEnabledState(state: EnabledState, instanceId: string): void {\n if (typeof window === 'undefined') return;\n localStorage.setItem(getEnabledStateKey(instanceId), JSON.stringify(state));\n }\n\n /**\n * Load plugins with instance-specific enabled state\n * Combines global plugin list with per-instance enabled state\n */\n loadFromStorage(instanceId: string = 'default'): StoredPlugin[] {\n const installed = this.loadInstalledPlugins();\n const enabledState = this.loadEnabledState(instanceId);\n\n return installed.map((plugin) => ({\n ...plugin,\n // Default to enabled if no state exists for this instance\n enabled: enabledState[plugin.name] ?? true,\n }));\n }\n\n /**\n * Register a new plugin (global - available to all instances)\n * Serializes executors as executorCode for persistence\n *\n * @param plugin The plugin to install\n * @param enabled Initial enabled state for this instance (default: true)\n * @param instanceId Instance to set initial enabled state for\n */\n register(plugin: HustlePlugin, enabled = true, instanceId: string = 'default'): void {\n // Add to global installed list with serialized executors\n const installed = this.loadInstalledPlugins();\n const existing = installed.findIndex((p) => p.name === plugin.name);\n\n const storedPlugin: Omit<StoredPlugin, 'enabled'> = {\n name: plugin.name,\n version: plugin.version,\n description: plugin.description,\n tools: serializePluginTools(plugin.tools, plugin.executors),\n hooksCode: serializeHooks(plugin.hooks),\n installedAt: new Date().toISOString(),\n };\n\n if (existing >= 0) {\n installed[existing] = storedPlugin;\n } else {\n installed.push(storedPlugin);\n }\n\n this.saveInstalledPlugins(installed);\n\n // Set initial enabled state for this instance\n const enabledState = this.loadEnabledState(instanceId);\n enabledState[plugin.name] = enabled;\n this.saveEnabledState(enabledState, instanceId);\n\n this.notifyListeners(instanceId);\n }\n\n /**\n * Unregister a plugin (global - removes from all instances)\n */\n unregister(pluginName: string, instanceId: string = 'default'): void {\n // Remove from global list\n const installed = this.loadInstalledPlugins().filter((p) => p.name !== pluginName);\n this.saveInstalledPlugins(installed);\n\n // Clean up enabled state for this instance\n const enabledState = this.loadEnabledState(instanceId);\n delete enabledState[pluginName];\n this.saveEnabledState(enabledState, instanceId);\n\n this.notifyListeners(instanceId);\n }\n\n /**\n * Enable or disable a plugin (instance-scoped)\n */\n setEnabled(pluginName: string, enabled: boolean, instanceId: string = 'default'): void {\n const enabledState = this.loadEnabledState(instanceId);\n enabledState[pluginName] = enabled;\n this.saveEnabledState(enabledState, instanceId);\n this.notifyListeners(instanceId);\n }\n\n /**\n * Check if a plugin is installed (global)\n */\n isRegistered(pluginName: string): boolean {\n return this.loadInstalledPlugins().some((p) => p.name === pluginName);\n }\n\n /**\n * Get a specific plugin with instance-specific enabled state\n */\n getPlugin(pluginName: string, instanceId: string = 'default'): StoredPlugin | undefined {\n return this.loadFromStorage(instanceId).find((p) => p.name === pluginName);\n }\n\n /**\n * Get all enabled plugins for an instance (hydrated with executors)\n */\n getEnabledPlugins(instanceId: string = 'default'): HydratedPlugin[] {\n return this.loadFromStorage(instanceId).filter((p) => p.enabled).map(hydratePlugin);\n }\n\n /**\n * Subscribe to plugin changes for a specific instance\n */\n onChange(callback: PluginChangeCallback, instanceId: string = 'default'): () => void {\n const listeners = this.getListeners(instanceId);\n listeners.add(callback);\n return () => listeners.delete(callback);\n }\n\n /**\n * Notify all listeners for a specific instance\n */\n private notifyListeners(instanceId: string = 'default'): void {\n const plugins = this.loadFromStorage(instanceId);\n const listeners = this.getListeners(instanceId);\n listeners.forEach((cb) => cb(plugins));\n }\n\n /**\n * Clear enabled state for an instance (plugins remain installed globally)\n */\n clear(instanceId: string = 'default'): void {\n if (typeof window === 'undefined') return;\n localStorage.removeItem(getEnabledStateKey(instanceId));\n this.notifyListeners(instanceId);\n }\n\n /**\n * Clear all installed plugins globally\n */\n clearAll(): void {\n if (typeof window === 'undefined') return;\n localStorage.removeItem(PLUGINS_KEY);\n // Note: This doesn't clear instance-specific enabled states\n }\n}\n\n// Singleton instance\nexport const pluginRegistry = new PluginRegistry();\n\nexport default pluginRegistry;\n","'use client';\n\n/**\n * usePlugins Hook\n *\n * Manages plugin state with localStorage persistence and cross-tab sync.\n * Supports instance-scoped storage for multiple HustleProviders.\n */\n\nimport { useState, useEffect, useCallback } from 'react';\nimport { pluginRegistry, hydratePlugin } from '../utils/pluginRegistry';\nimport type { StoredPlugin, HustlePlugin, HydratedPlugin } from '../types';\n\n// Re-export hydratePlugin for convenience\nexport { hydratePlugin };\n\n/**\n * Get the storage key for a given instance\n */\nfunction getStorageKey(instanceId: string): string {\n return `hustle-plugins-${instanceId}`;\n}\n\n/**\n * Return type for usePlugins hook\n */\nexport interface UsePluginsReturn {\n /** All registered plugins (with enabled state) */\n plugins: StoredPlugin[];\n /** Only enabled plugins (hydrated with executors) */\n enabledPlugins: HydratedPlugin[];\n /** Register a new plugin */\n registerPlugin: (plugin: HustlePlugin) => void;\n /** Unregister a plugin by name */\n unregisterPlugin: (name: string) => void;\n /** Enable a plugin */\n enablePlugin: (name: string) => void;\n /** Disable a plugin */\n disablePlugin: (name: string) => void;\n /** Check if a plugin is registered */\n isRegistered: (name: string) => boolean;\n /** Check if a plugin is enabled */\n isEnabled: (name: string) => boolean;\n}\n\n/**\n * Hook for managing plugins\n *\n * @param instanceId - Optional instance ID for scoping plugin storage (defaults to 'default')\n *\n * @example\n * ```tsx\n * const { plugins, registerPlugin, enabledPlugins } = usePlugins();\n *\n * // Install a plugin\n * registerPlugin(myPlugin);\n *\n * // Check enabled plugins\n * console.log('Active tools:', enabledPlugins.flatMap(p => p.tools));\n * ```\n */\nexport function usePlugins(instanceId: string = 'default'): UsePluginsReturn {\n const [plugins, setPlugins] = useState<StoredPlugin[]>([]);\n\n // Load initial plugins and subscribe to changes\n useEffect(() => {\n // Load initial state\n setPlugins(pluginRegistry.loadFromStorage(instanceId));\n\n // Subscribe to registry changes for this instance\n const unsubscribe = pluginRegistry.onChange(setPlugins, instanceId);\n\n // Listen to storage events for cross-tab sync\n const storageKey = getStorageKey(instanceId);\n const handleStorage = (e: StorageEvent) => {\n if (e.key === storageKey) {\n setPlugins(pluginRegistry.loadFromStorage(instanceId));\n }\n };\n window.addEventListener('storage', handleStorage);\n\n return () => {\n unsubscribe();\n window.removeEventListener('storage', handleStorage);\n };\n }, [instanceId]);\n\n // Register a new plugin\n const registerPlugin = useCallback((plugin: HustlePlugin) => {\n pluginRegistry.register(plugin, true, instanceId);\n }, [instanceId]);\n\n // Unregister a plugin\n const unregisterPlugin = useCallback((name: string) => {\n pluginRegistry.unregister(name, instanceId);\n }, [instanceId]);\n\n // Enable a plugin\n const enablePlugin = useCallback((name: string) => {\n pluginRegistry.setEnabled(name, true, instanceId);\n }, [instanceId]);\n\n // Disable a plugin\n const disablePlugin = useCallback((name: string) => {\n pluginRegistry.setEnabled(name, false, instanceId);\n }, [instanceId]);\n\n // Check if plugin is registered\n const isRegistered = useCallback(\n (name: string) => plugins.some(p => p.name === name),\n [plugins]\n );\n\n // Check if plugin is enabled\n const isEnabled = useCallback(\n (name: string) => plugins.some(p => p.name === name && p.enabled),\n [plugins]\n );\n\n // Get enabled plugins with hydrated executors\n const enabledPlugins = plugins.filter(p => p.enabled).map(hydratePlugin);\n\n return {\n plugins,\n enabledPlugins,\n registerPlugin,\n unregisterPlugin,\n enablePlugin,\n disablePlugin,\n isRegistered,\n isEnabled,\n };\n}\n\nexport default usePlugins;\n","'use client';\n\nimport React, {\n createContext,\n useContext,\n useState,\n useEffect,\n useCallback,\n useMemo,\n useRef,\n} from 'react';\nimport { HustleIncognitoClient } from 'hustle-incognito';\nimport { useEmblemAuthOptional } from '@emblemvault/emblem-auth-react';\nimport { usePlugins } from '../hooks/usePlugins';\nimport type {\n Model,\n ChatOptions,\n StreamOptions,\n StreamChunk,\n StreamWithResponse,\n ChatResponse,\n Attachment,\n HustleContextValue,\n HustleProviderProps,\n ChatMessage,\n HydratedPlugin,\n} from '../types';\n\n/**\n * Hustle context - undefined when not within provider\n */\nconst HustleContext = createContext<HustleContextValue | undefined>(undefined);\n\n/**\n * Default Hustle API URL\n */\nconst DEFAULT_HUSTLE_API_URL = 'https://agenthustle.ai';\n\n/**\n * Module-level counter for auto-generating instance IDs.\n * Resets on page load, but render order is deterministic.\n */\nlet instanceCounter = 0;\n\n/**\n * Track mounted instances without explicit IDs for dev warnings\n */\nconst mountedAutoInstances = new Set<string>();\n\n/**\n * HustleProvider - Provides Hustle SDK functionality to the app\n *\n * Supports two authentication modes:\n *\n * **Mode 1: Auth SDK (default)** - Uses EmblemAuthProvider context for authentication\n * ```tsx\n * <EmblemAuthProvider appId=\"your-app-id\">\n * <HustleProvider>\n * <App />\n * </HustleProvider>\n * </EmblemAuthProvider>\n * ```\n *\n * **Mode 2: Direct API Key** - Uses provided apiKey/vaultId (no EmblemAuthProvider needed)\n * ```tsx\n * <HustleProvider apiKey=\"your-key\" vaultId=\"your-vault\">\n * <App />\n * </HustleProvider>\n * ```\n */\nexport function HustleProvider({\n children,\n hustleApiUrl = DEFAULT_HUSTLE_API_URL,\n debug = false,\n instanceId: explicitInstanceId,\n apiKey,\n vaultId,\n}: HustleProviderProps) {\n // Generate stable instance ID - explicit or auto-generated based on mount order\n const [resolvedInstanceId] = useState(() => {\n if (explicitInstanceId) {\n return explicitInstanceId;\n }\n // Auto-generate based on mount order\n const autoId = `instance-${++instanceCounter}`;\n mountedAutoInstances.add(autoId);\n return autoId;\n });\n\n // Track if this is an auto-generated instance for cleanup\n const isAutoInstance = !explicitInstanceId;\n\n // Dev warning for multiple auto-generated instances\n useEffect(() => {\n if (isAutoInstance && mountedAutoInstances.size > 1 && process.env.NODE_ENV !== 'production') {\n console.warn(\n `[Hustle] Multiple HustleProviders detected without explicit instanceId. ` +\n `For stable settings persistence, consider adding instanceId prop:\\n` +\n ` <HustleProvider instanceId=\"my-chat-name\">`\n );\n }\n\n // Cleanup on unmount\n return () => {\n if (isAutoInstance) {\n mountedAutoInstances.delete(resolvedInstanceId);\n }\n };\n }, [isAutoInstance, resolvedInstanceId]);\n\n // Determine if we're using API key mode\n const isApiKeyMode = Boolean(apiKey && vaultId);\n\n // Get auth context - using optional hook that returns null when not in EmblemAuthProvider\n // This hook is always called (React rules) but returns null when outside provider\n const authContext = useEmblemAuthOptional();\n\n // Extract auth values - in API key mode, we don't need auth context\n const authSDK = isApiKeyMode ? null : authContext?.authSDK ?? null;\n const isAuthenticated = isApiKeyMode\n ? true // API key mode is always considered authenticated\n : authContext?.isAuthenticated ?? false;\n\n // Get plugins with instance scoping\n const { enabledPlugins } = usePlugins(resolvedInstanceId);\n\n // State\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [models, setModels] = useState<Model[]>([]);\n\n // Track registered plugins to avoid re-registering\n const registeredPluginsRef = useRef<Set<string>>(new Set());\n\n // Settings storage key - scoped to instance\n const SETTINGS_KEY = `hustle-settings-${resolvedInstanceId}`;\n\n // Load initial settings from localStorage\n const loadSettings = () => {\n if (typeof window === 'undefined') return { selectedModel: '', systemPrompt: '', skipServerPrompt: false };\n try {\n const stored = localStorage.getItem(SETTINGS_KEY);\n if (stored) {\n return JSON.parse(stored);\n }\n } catch {\n // Ignore parse errors\n }\n return { selectedModel: '', systemPrompt: '', skipServerPrompt: false };\n };\n\n const initialSettings = loadSettings();\n\n // Settings state (initialized from localStorage)\n const [selectedModel, setSelectedModelState] = useState<string>(initialSettings.selectedModel);\n const [systemPrompt, setSystemPromptState] = useState<string>(initialSettings.systemPrompt);\n const [skipServerPrompt, setSkipServerPromptState] = useState<boolean>(initialSettings.skipServerPrompt);\n\n // Persist settings to localStorage\n const saveSettings = useCallback((settings: { selectedModel: string; systemPrompt: string; skipServerPrompt: boolean }) => {\n if (typeof window === 'undefined') return;\n try {\n localStorage.setItem(SETTINGS_KEY, JSON.stringify(settings));\n } catch {\n // Ignore storage errors\n }\n }, []);\n\n // Wrapped setters that also persist\n const setSelectedModel = useCallback((value: string) => {\n setSelectedModelState(value);\n saveSettings({ selectedModel: value, systemPrompt, skipServerPrompt });\n }, [systemPrompt, skipServerPrompt, saveSettings]);\n\n const setSystemPrompt = useCallback((value: string) => {\n setSystemPromptState(value);\n saveSettings({ selectedModel, systemPrompt: value, skipServerPrompt });\n }, [selectedModel, skipServerPrompt, saveSettings]);\n\n const setSkipServerPrompt = useCallback((value: boolean) => {\n setSkipServerPromptState(value);\n saveSettings({ selectedModel, systemPrompt, skipServerPrompt: value });\n }, [selectedModel, systemPrompt, saveSettings]);\n\n // Debug logger\n const log = useCallback(\n (message: string, ...args: unknown[]) => {\n if (debug) {\n console.log(`[Hustle] ${message}`, ...args);\n }\n },\n [debug]\n );\n\n /**\n * Create the Hustle client\n * Supports two modes:\n * - Mode 1 (Auth SDK): Uses authSDK from EmblemAuthProvider context\n * - Mode 2 (API Key): Uses direct apiKey/vaultId props\n */\n const client = useMemo(() => {\n // Mode 2: API Key mode\n if (isApiKeyMode && apiKey && vaultId) {\n log('Creating HustleIncognitoClient with API key');\n\n try {\n const hustleClient = new HustleIncognitoClient({\n apiKey,\n vaultId,\n hustleApiUrl,\n debug,\n });\n\n // Subscribe to events\n hustleClient.on('tool_start', (event: unknown) => {\n log('Tool start:', event);\n });\n\n hustleClient.on('tool_end', (event: unknown) => {\n log('Tool end:', event);\n });\n\n hustleClient.on('stream_end', (event: unknown) => {\n log('Stream end:', event);\n });\n\n return hustleClient;\n } catch (err) {\n log('Failed to create client:', err);\n setError(err instanceof Error ? err : new Error('Failed to create Hustle client'));\n return null;\n }\n }\n\n // Mode 1: Auth SDK mode\n if (!authSDK || !isAuthenticated) {\n log('Client not created - auth not ready');\n return null;\n }\n\n log('Creating HustleIncognitoClient with auth SDK');\n\n try {\n const hustleClient = new HustleIncognitoClient({\n sdk: authSDK,\n hustleApiUrl,\n debug,\n });\n\n // Subscribe to events (use any for SDK event types)\n hustleClient.on('tool_start', (event: unknown) => {\n log('Tool start:', event);\n });\n\n hustleClient.on('tool_end', (event: unknown) => {\n log('Tool end:', event);\n });\n\n hustleClient.on('stream_end', (event: unknown) => {\n log('Stream end:', event);\n });\n\n return hustleClient;\n } catch (err) {\n log('Failed to create client:', err);\n setError(err instanceof Error ? err : new Error('Failed to create Hustle client'));\n return null;\n }\n }, [isApiKeyMode, apiKey, vaultId, authSDK, isAuthenticated, hustleApiUrl, debug, log]);\n\n // Is ready when client exists\n const isReady = client !== null;\n\n /**\n * Register enabled plugins with the client\n */\n useEffect(() => {\n if (!client) return;\n\n const registerPlugins = async () => {\n // Get the set of enabled plugin names\n const enabledNames = new Set(enabledPlugins.map(p => p.name));\n\n // Unregister plugins that were disabled\n for (const name of registeredPluginsRef.current) {\n if (!enabledNames.has(name)) {\n log('Unregistering plugin:', name);\n try {\n await client.unuse(name);\n registeredPluginsRef.current.delete(name);\n log('Plugin unregistered:', name);\n } catch (err) {\n log('Failed to unregister plugin:', name, err);\n }\n }\n }\n\n // Register new plugins\n for (const plugin of enabledPlugins) {\n if (!registeredPluginsRef.current.has(plugin.name)) {\n log('Registering plugin:', plugin.name);\n try {\n // The SDK's use() method registers the plugin\n if (plugin.executors || plugin.hooks) {\n // Cast to SDK's expected type (our types are compatible but TS is strict)\n await client.use({\n name: plugin.name,\n version: plugin.version,\n tools: plugin.tools,\n executors: plugin.executors,\n hooks: plugin.hooks,\n } as Parameters<typeof client.use>[0]);\n registeredPluginsRef.current.add(plugin.name);\n log('Plugin registered:', plugin.name);\n } else {\n log('Plugin has no executors/hooks, skipping registration:', plugin.name);\n }\n } catch (err) {\n log('Failed to register plugin:', plugin.name, err);\n }\n }\n }\n };\n\n registerPlugins();\n }, [client, enabledPlugins, log]);\n\n /**\n * Load available models\n */\n const loadModels = useCallback(async (): Promise<Model[]> => {\n if (!client) {\n log('Cannot load models - client not ready');\n return [];\n }\n\n log('Loading models');\n setIsLoading(true);\n\n try {\n const modelList = await client.getModels();\n setModels(modelList as Model[]);\n log('Loaded models:', modelList.length);\n return modelList as Model[];\n } catch (err) {\n log('Failed to load models:', err);\n setError(err instanceof Error ? err : new Error('Failed to load models'));\n return [];\n } finally {\n setIsLoading(false);\n }\n }, [client, log]);\n\n /**\n * Load models when client becomes ready\n */\n useEffect(() => {\n if (client) {\n loadModels();\n }\n }, [client, loadModels]);\n\n /**\n * Send a chat message (non-streaming)\n */\n const chat = useCallback(\n async (options: ChatOptions): Promise<ChatResponse> => {\n if (!client) {\n throw new Error('Hustle client not ready. Please authenticate first.');\n }\n\n log('Chat request:', options.messages.length, 'messages');\n setIsLoading(true);\n setError(null);\n\n try {\n // Build the messages array, prepending system prompt if provided\n const effectiveSystemPrompt = options.systemPrompt || systemPrompt;\n const messagesWithSystem: ChatMessage[] = [];\n\n if (effectiveSystemPrompt) {\n messagesWithSystem.push({ role: 'system', content: effectiveSystemPrompt });\n }\n messagesWithSystem.push(...options.messages);\n\n // Build the options object for the SDK\n const sdkOptions: Record<string, unknown> = {\n messages: messagesWithSystem,\n processChunks: true,\n };\n\n // In API key mode, we need to pass vaultId with each request\n if (isApiKeyMode && vaultId) {\n sdkOptions.vaultId = vaultId;\n }\n\n if (options.model || selectedModel) {\n sdkOptions.model = options.model || selectedModel;\n }\n if (options.overrideSystemPrompt ?? skipServerPrompt) {\n sdkOptions.overrideSystemPrompt = true;\n }\n if (options.attachments) {\n sdkOptions.attachments = options.attachments;\n }\n\n // Call the SDK - it accepts an options object\n const response = await (client as unknown as { chat: (opts: Record<string, unknown>) => Promise<unknown> }).chat(sdkOptions);\n log('Chat response received');\n return response as ChatResponse;\n } catch (err) {\n log('Chat error:', err);\n const error = err instanceof Error ? err : new Error('Chat request failed');\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [client, isApiKeyMode, vaultId, selectedModel, systemPrompt, skipServerPrompt, log]\n );\n\n /**\n * Send a chat message with streaming response\n */\n const chatStreamImpl = useCallback(\n (options: StreamOptions): StreamWithResponse => {\n if (!client) {\n // Return a stream with error that yields an error\n return {\n [Symbol.asyncIterator]: async function* () {\n yield { type: 'error', value: { message: 'Hustle client not ready. Please authenticate first.' } } as StreamChunk;\n },\n response: Promise.resolve({ content: '', messageId: undefined }),\n };\n }\n\n log('Chat stream request:', options.messages.length, 'messages');\n setError(null);\n\n // Build the messages array, prepending system prompt if provided\n const effectiveSystemPrompt = options.systemPrompt || systemPrompt;\n const messagesWithSystem: ChatMessage[] = [];\n\n if (effectiveSystemPrompt) {\n messagesWithSystem.push({ role: 'system', content: effectiveSystemPrompt });\n }\n messagesWithSystem.push(...options.messages);\n\n // Build the options object for the SDK\n const sdkOptions: Record<string, unknown> = {\n messages: messagesWithSystem,\n processChunks: options.processChunks ?? true,\n };\n\n // In API key mode, we need to pass vaultId with each request\n if (isApiKeyMode && vaultId) {\n sdkOptions.vaultId = vaultId;\n }\n\n if (options.model || selectedModel) {\n sdkOptions.model = options.model || selectedModel;\n }\n if (options.overrideSystemPrompt ?? skipServerPrompt) {\n sdkOptions.overrideSystemPrompt = true;\n }\n if (options.attachments) {\n sdkOptions.attachments = options.attachments;\n }\n\n // Get the stream from the client (cast through unknown for SDK compatibility)\n const stream = client.chatStream(sdkOptions as unknown as Parameters<typeof client.chatStream>[0]);\n\n // Wrap to add logging and type conversion, preserving .response property\n return {\n [Symbol.asyncIterator]: async function* () {\n try {\n for await (const chunk of stream) {\n // Type guard for chunk with type property\n const typedChunk = chunk as { type?: string; value?: unknown };\n\n if (typedChunk.type === 'text') {\n const textValue = typedChunk.value as string;\n log('Stream text chunk:', textValue?.substring(0, 50));\n yield { type: 'text', value: textValue } as StreamChunk;\n } else if (typedChunk.type === 'tool_call') {\n log('Stream tool call:', typedChunk.value);\n yield { type: 'tool_call', value: typedChunk.value } as StreamChunk;\n } else if (typedChunk.type === 'tool_result') {\n log('Stream tool result');\n yield { type: 'tool_result', value: typedChunk.value } as StreamChunk;\n } else if (typedChunk.type === 'error') {\n const errorValue = typedChunk.value as { message?: string };\n log('Stream error:', errorValue);\n setError(new Error(errorValue?.message || 'Stream error'));\n yield { type: 'error', value: { message: errorValue?.message || 'Stream error' } } as StreamChunk;\n } else {\n // Pass through unknown chunk types\n yield chunk as StreamChunk;\n }\n }\n } catch (err) {\n log('Stream error:', err);\n const error = err instanceof Error ? err : new Error('Stream failed');\n setError(error);\n yield { type: 'error', value: { message: error.message } } as StreamChunk;\n }\n },\n // Forward the response promise from the SDK stream (includes afterResponse hook modifications)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n response: (stream as any).response as Promise<ChatResponse>,\n };\n },\n [client, isApiKeyMode, vaultId, selectedModel, systemPrompt, skipServerPrompt, log]\n );\n\n /**\n * Upload a file\n */\n const uploadFile = useCallback(\n async (file: File): Promise<Attachment> => {\n if (!client) {\n throw new Error('Hustle client not ready. Please authenticate first.');\n }\n\n log('Uploading file:', file.name);\n setIsLoading(true);\n\n try {\n const attachment = await client.uploadFile(file);\n log('File uploaded:', attachment);\n return attachment as Attachment;\n } catch (err) {\n log('Upload error:', err);\n const error = err instanceof Error ? err : new Error('File upload failed');\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [client, log]\n );\n\n // Context value\n const value: HustleContextValue = {\n // Instance ID for scoped storage\n instanceId: resolvedInstanceId,\n\n // Auth mode\n isApiKeyMode,\n\n // State\n isReady,\n isLoading,\n error,\n models,\n\n // Client (for advanced use)\n client,\n\n // Chat methods\n chat,\n chatStream: chatStreamImpl,\n\n // File upload\n uploadFile,\n\n // Data fetching\n loadModels,\n\n // Settings\n selectedModel,\n setSelectedModel,\n systemPrompt,\n setSystemPrompt,\n skipServerPrompt,\n setSkipServerPrompt,\n };\n\n return (\n <HustleContext.Provider value={value}>\n {children}\n </HustleContext.Provider>\n );\n}\n\n/**\n * Hook to access Hustle context\n * Must be used within HustleProvider (which must be within EmblemAuthProvider)\n *\n * @example\n * ```tsx\n * function ChatComponent() {\n * const { isReady, chat, chatStream } = useHustle();\n *\n * if (!isReady) {\n * return <div>Please connect to start chatting</div>;\n * }\n *\n * // Use chat or chatStream...\n * }\n * ```\n */\nexport function useHustle(): HustleContextValue {\n const context = useContext(HustleContext);\n if (context === undefined) {\n throw new Error('useHustle must be used within a HustleProvider (which requires EmblemAuthProvider)');\n }\n return context;\n}\n"]}
@@ -0,0 +1,222 @@
1
+ import { HustleIncognitoClient } from 'hustle-incognito';
2
+
3
+ /**
4
+ * Hustle Types for Hustle Incognito SDK integration
5
+ * These types mirror the HustleIncognitoClient types for use in React components
6
+ */
7
+
8
+ /**
9
+ * Chat message structure
10
+ */
11
+ interface ChatMessage {
12
+ role: 'system' | 'user' | 'assistant';
13
+ content: string;
14
+ }
15
+ /**
16
+ * Tool call information
17
+ */
18
+ interface ToolCall {
19
+ toolCallId: string;
20
+ toolName: string;
21
+ args?: Record<string, unknown>;
22
+ }
23
+ /**
24
+ * Tool result information
25
+ */
26
+ interface ToolResult {
27
+ toolCallId: string;
28
+ toolName?: string;
29
+ result: unknown;
30
+ }
31
+ /**
32
+ * File attachment for chat
33
+ */
34
+ interface Attachment {
35
+ url: string;
36
+ name: string;
37
+ type?: string;
38
+ size?: number;
39
+ }
40
+ /**
41
+ * Available AI model
42
+ */
43
+ interface Model {
44
+ id: string;
45
+ name: string;
46
+ context_length: number;
47
+ pricing?: {
48
+ prompt?: string;
49
+ completion?: string;
50
+ };
51
+ }
52
+ /**
53
+ * Options for chat requests
54
+ */
55
+ interface ChatOptions {
56
+ messages: ChatMessage[];
57
+ model?: string;
58
+ systemPrompt?: string;
59
+ overrideSystemPrompt?: boolean;
60
+ attachments?: Attachment[];
61
+ }
62
+ /**
63
+ * Stream options (extends ChatOptions)
64
+ */
65
+ interface StreamOptions extends ChatOptions {
66
+ processChunks?: boolean;
67
+ }
68
+ /**
69
+ * Streaming chunk types
70
+ */
71
+ type StreamChunk = {
72
+ type: 'text';
73
+ value: string;
74
+ } | {
75
+ type: 'tool_call';
76
+ value: ToolCall;
77
+ } | {
78
+ type: 'tool_result';
79
+ value: ToolResult;
80
+ } | {
81
+ type: 'error';
82
+ value: {
83
+ message: string;
84
+ };
85
+ };
86
+ /**
87
+ * Stream with response promise (for accessing hook-processed content)
88
+ */
89
+ interface StreamWithResponse extends AsyncIterable<StreamChunk> {
90
+ /** Promise that resolves to the complete response after streaming (includes afterResponse hook modifications) */
91
+ response: Promise<ChatResponse>;
92
+ }
93
+ /**
94
+ * Complete chat response
95
+ */
96
+ interface ChatResponse {
97
+ content: string;
98
+ messageId?: string;
99
+ toolCalls?: ToolCall[];
100
+ toolResults?: ToolResult[];
101
+ usage?: {
102
+ total_tokens?: number;
103
+ prompt_tokens?: number;
104
+ completion_tokens?: number;
105
+ };
106
+ reasoning?: {
107
+ thinking?: string;
108
+ categories?: string[];
109
+ };
110
+ devToolsInfo?: {
111
+ toolCount?: number;
112
+ qualifiedCategories?: string[];
113
+ };
114
+ pathInfo?: {
115
+ thresholdReached?: boolean;
116
+ totalTokens?: number;
117
+ threshold?: number;
118
+ messageRetentionCount?: number;
119
+ summary?: string;
120
+ summaryEndIndex?: number;
121
+ };
122
+ }
123
+ /**
124
+ * Tool start event payload
125
+ */
126
+ interface ToolStartEvent {
127
+ toolCallId: string;
128
+ toolName: string;
129
+ args?: Record<string, unknown>;
130
+ }
131
+ /**
132
+ * Tool end event payload
133
+ */
134
+ interface ToolEndEvent {
135
+ toolCallId: string;
136
+ result: unknown;
137
+ }
138
+ /**
139
+ * Stream end event payload
140
+ */
141
+ interface StreamEndEvent {
142
+ response: ChatResponse;
143
+ }
144
+ /**
145
+ * Configuration for HustleProvider
146
+ */
147
+ interface HustleConfig {
148
+ /** Hustle API endpoint */
149
+ hustleApiUrl?: string;
150
+ /** Enable debug logging */
151
+ debug?: boolean;
152
+ }
153
+ /**
154
+ * Context value exposed by HustleProvider
155
+ */
156
+ interface HustleContextValue {
157
+ instanceId: string;
158
+ isApiKeyMode: boolean;
159
+ isReady: boolean;
160
+ isLoading: boolean;
161
+ error: Error | null;
162
+ models: Model[];
163
+ client: HustleIncognitoClient | null;
164
+ chat: (options: ChatOptions) => Promise<ChatResponse>;
165
+ chatStream: (options: StreamOptions) => StreamWithResponse;
166
+ uploadFile: (file: File) => Promise<Attachment>;
167
+ loadModels: () => Promise<Model[]>;
168
+ selectedModel: string;
169
+ setSelectedModel: (model: string) => void;
170
+ systemPrompt: string;
171
+ setSystemPrompt: (prompt: string) => void;
172
+ skipServerPrompt: boolean;
173
+ setSkipServerPrompt: (skip: boolean) => void;
174
+ }
175
+ /**
176
+ * Props for HustleProvider component
177
+ */
178
+ interface HustleProviderProps extends HustleConfig {
179
+ children: React.ReactNode;
180
+ /**
181
+ * Unique identifier for this provider instance.
182
+ * Used to scope settings persistence (localStorage) when multiple
183
+ * HustleProviders exist in the same app.
184
+ *
185
+ * If not provided, an auto-generated ID based on mount order is used.
186
+ * For stable persistence with multiple providers, explicit IDs are recommended.
187
+ *
188
+ * @example
189
+ * ```tsx
190
+ * <HustleProvider instanceId="trading-assistant">
191
+ * <TradingChat />
192
+ * </HustleProvider>
193
+ * <HustleProvider instanceId="support-bot">
194
+ * <SupportChat />
195
+ * </HustleProvider>
196
+ * ```
197
+ */
198
+ instanceId?: string;
199
+ /**
200
+ * Direct API key for authentication (API Key Mode).
201
+ * When provided along with `vaultId`, the provider will use direct API key
202
+ * authentication instead of the Emblem Auth SDK.
203
+ *
204
+ * Use this when you want to manage authentication yourself or when not
205
+ * using EmblemAuthProvider.
206
+ *
207
+ * @example
208
+ * ```tsx
209
+ * <HustleProvider apiKey="your-key" vaultId="your-vault">
210
+ * <HustleChat />
211
+ * </HustleProvider>
212
+ * ```
213
+ */
214
+ apiKey?: string;
215
+ /**
216
+ * Vault ID for API key authentication.
217
+ * Required when using `apiKey` prop for direct authentication.
218
+ */
219
+ vaultId?: string;
220
+ }
221
+
222
+ export type { Attachment as A, ChatMessage as C, HustleConfig as H, Model as M, StreamOptions as S, ToolCall as T, ToolResult as a, ChatOptions as b, StreamChunk as c, ChatResponse as d, ToolStartEvent as e, ToolEndEvent as f, StreamEndEvent as g, HustleContextValue as h, HustleProviderProps as i };
@@ -0,0 +1,222 @@
1
+ import { HustleIncognitoClient } from 'hustle-incognito';
2
+
3
+ /**
4
+ * Hustle Types for Hustle Incognito SDK integration
5
+ * These types mirror the HustleIncognitoClient types for use in React components
6
+ */
7
+
8
+ /**
9
+ * Chat message structure
10
+ */
11
+ interface ChatMessage {
12
+ role: 'system' | 'user' | 'assistant';
13
+ content: string;
14
+ }
15
+ /**
16
+ * Tool call information
17
+ */
18
+ interface ToolCall {
19
+ toolCallId: string;
20
+ toolName: string;
21
+ args?: Record<string, unknown>;
22
+ }
23
+ /**
24
+ * Tool result information
25
+ */
26
+ interface ToolResult {
27
+ toolCallId: string;
28
+ toolName?: string;
29
+ result: unknown;
30
+ }
31
+ /**
32
+ * File attachment for chat
33
+ */
34
+ interface Attachment {
35
+ url: string;
36
+ name: string;
37
+ type?: string;
38
+ size?: number;
39
+ }
40
+ /**
41
+ * Available AI model
42
+ */
43
+ interface Model {
44
+ id: string;
45
+ name: string;
46
+ context_length: number;
47
+ pricing?: {
48
+ prompt?: string;
49
+ completion?: string;
50
+ };
51
+ }
52
+ /**
53
+ * Options for chat requests
54
+ */
55
+ interface ChatOptions {
56
+ messages: ChatMessage[];
57
+ model?: string;
58
+ systemPrompt?: string;
59
+ overrideSystemPrompt?: boolean;
60
+ attachments?: Attachment[];
61
+ }
62
+ /**
63
+ * Stream options (extends ChatOptions)
64
+ */
65
+ interface StreamOptions extends ChatOptions {
66
+ processChunks?: boolean;
67
+ }
68
+ /**
69
+ * Streaming chunk types
70
+ */
71
+ type StreamChunk = {
72
+ type: 'text';
73
+ value: string;
74
+ } | {
75
+ type: 'tool_call';
76
+ value: ToolCall;
77
+ } | {
78
+ type: 'tool_result';
79
+ value: ToolResult;
80
+ } | {
81
+ type: 'error';
82
+ value: {
83
+ message: string;
84
+ };
85
+ };
86
+ /**
87
+ * Stream with response promise (for accessing hook-processed content)
88
+ */
89
+ interface StreamWithResponse extends AsyncIterable<StreamChunk> {
90
+ /** Promise that resolves to the complete response after streaming (includes afterResponse hook modifications) */
91
+ response: Promise<ChatResponse>;
92
+ }
93
+ /**
94
+ * Complete chat response
95
+ */
96
+ interface ChatResponse {
97
+ content: string;
98
+ messageId?: string;
99
+ toolCalls?: ToolCall[];
100
+ toolResults?: ToolResult[];
101
+ usage?: {
102
+ total_tokens?: number;
103
+ prompt_tokens?: number;
104
+ completion_tokens?: number;
105
+ };
106
+ reasoning?: {
107
+ thinking?: string;
108
+ categories?: string[];
109
+ };
110
+ devToolsInfo?: {
111
+ toolCount?: number;
112
+ qualifiedCategories?: string[];
113
+ };
114
+ pathInfo?: {
115
+ thresholdReached?: boolean;
116
+ totalTokens?: number;
117
+ threshold?: number;
118
+ messageRetentionCount?: number;
119
+ summary?: string;
120
+ summaryEndIndex?: number;
121
+ };
122
+ }
123
+ /**
124
+ * Tool start event payload
125
+ */
126
+ interface ToolStartEvent {
127
+ toolCallId: string;
128
+ toolName: string;
129
+ args?: Record<string, unknown>;
130
+ }
131
+ /**
132
+ * Tool end event payload
133
+ */
134
+ interface ToolEndEvent {
135
+ toolCallId: string;
136
+ result: unknown;
137
+ }
138
+ /**
139
+ * Stream end event payload
140
+ */
141
+ interface StreamEndEvent {
142
+ response: ChatResponse;
143
+ }
144
+ /**
145
+ * Configuration for HustleProvider
146
+ */
147
+ interface HustleConfig {
148
+ /** Hustle API endpoint */
149
+ hustleApiUrl?: string;
150
+ /** Enable debug logging */
151
+ debug?: boolean;
152
+ }
153
+ /**
154
+ * Context value exposed by HustleProvider
155
+ */
156
+ interface HustleContextValue {
157
+ instanceId: string;
158
+ isApiKeyMode: boolean;
159
+ isReady: boolean;
160
+ isLoading: boolean;
161
+ error: Error | null;
162
+ models: Model[];
163
+ client: HustleIncognitoClient | null;
164
+ chat: (options: ChatOptions) => Promise<ChatResponse>;
165
+ chatStream: (options: StreamOptions) => StreamWithResponse;
166
+ uploadFile: (file: File) => Promise<Attachment>;
167
+ loadModels: () => Promise<Model[]>;
168
+ selectedModel: string;
169
+ setSelectedModel: (model: string) => void;
170
+ systemPrompt: string;
171
+ setSystemPrompt: (prompt: string) => void;
172
+ skipServerPrompt: boolean;
173
+ setSkipServerPrompt: (skip: boolean) => void;
174
+ }
175
+ /**
176
+ * Props for HustleProvider component
177
+ */
178
+ interface HustleProviderProps extends HustleConfig {
179
+ children: React.ReactNode;
180
+ /**
181
+ * Unique identifier for this provider instance.
182
+ * Used to scope settings persistence (localStorage) when multiple
183
+ * HustleProviders exist in the same app.
184
+ *
185
+ * If not provided, an auto-generated ID based on mount order is used.
186
+ * For stable persistence with multiple providers, explicit IDs are recommended.
187
+ *
188
+ * @example
189
+ * ```tsx
190
+ * <HustleProvider instanceId="trading-assistant">
191
+ * <TradingChat />
192
+ * </HustleProvider>
193
+ * <HustleProvider instanceId="support-bot">
194
+ * <SupportChat />
195
+ * </HustleProvider>
196
+ * ```
197
+ */
198
+ instanceId?: string;
199
+ /**
200
+ * Direct API key for authentication (API Key Mode).
201
+ * When provided along with `vaultId`, the provider will use direct API key
202
+ * authentication instead of the Emblem Auth SDK.
203
+ *
204
+ * Use this when you want to manage authentication yourself or when not
205
+ * using EmblemAuthProvider.
206
+ *
207
+ * @example
208
+ * ```tsx
209
+ * <HustleProvider apiKey="your-key" vaultId="your-vault">
210
+ * <HustleChat />
211
+ * </HustleProvider>
212
+ * ```
213
+ */
214
+ apiKey?: string;
215
+ /**
216
+ * Vault ID for API key authentication.
217
+ * Required when using `apiKey` prop for direct authentication.
218
+ */
219
+ vaultId?: string;
220
+ }
221
+
222
+ export type { Attachment as A, ChatMessage as C, HustleConfig as H, Model as M, StreamOptions as S, ToolCall as T, ToolResult as a, ChatOptions as b, StreamChunk as c, ChatResponse as d, ToolStartEvent as e, ToolEndEvent as f, StreamEndEvent as g, HustleContextValue as h, HustleProviderProps as i };