{"version":3,"sources":["../../src/react/FeedbackButton.tsx","../../src/react/FeedbackPanel.tsx","../../src/react/ModelStatus.tsx","../../src/react/EdgeworkContext.tsx"],"names":["useState","useCallback","jsx","jsxs","error"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * FeedbackButton - Simple thumbs up/down feedback buttons\n *\n * Collects user feedback for RLHF training of local models.\n */\n\nimport React, { useState, useCallback } from 'react';\n\nexport interface FeedbackButtonProps {\n  /** Unique identifier for the message being rated */\n  messageId: string;\n  /** Callback when feedback is submitted */\n  onFeedback?: (messageId: string, rating: 'positive' | 'negative') => void;\n  /** Current feedback state (if controlled) */\n  currentFeedback?: 'positive' | 'negative' | null;\n  /** Size of the buttons */\n  size?: 'sm' | 'md' | 'lg';\n  /** Disabled state */\n  disabled?: boolean;\n  /** Custom class names */\n  className?: string;\n}\n\nconst sizeClasses = {\n  sm: 'w-6 h-6 text-sm',\n  md: 'w-8 h-8 text-base',\n  lg: 'w-10 h-10 text-lg',\n};\n\n/**\n * Simple feedback buttons for collecting user preferences\n */\nexport function FeedbackButton({\n  messageId,\n  onFeedback,\n  currentFeedback,\n  size = 'md',\n  disabled = false,\n  className = '',\n}: FeedbackButtonProps): React.ReactElement {\n  const [localFeedback, setLocalFeedback] = useState<\n    'positive' | 'negative' | null\n  >(null);\n  const [isSubmitting, setIsSubmitting] = useState(false);\n\n  const feedback = currentFeedback ?? localFeedback;\n\n  const handleFeedback = useCallback(\n    async (rating: 'positive' | 'negative') => {\n      if (disabled || isSubmitting) return;\n\n      setIsSubmitting(true);\n      try {\n        // Toggle off if clicking same button\n        const newRating = feedback === rating ? null : rating;\n\n        if (currentFeedback === undefined) {\n          setLocalFeedback(newRating);\n        }\n\n        if (newRating && onFeedback) {\n          onFeedback(messageId, newRating);\n        }\n      } finally {\n        setIsSubmitting(false);\n      }\n    },\n    [messageId, onFeedback, feedback, currentFeedback, disabled, isSubmitting]\n  );\n\n  const buttonBase = `\n    inline-flex items-center justify-center rounded-full\n    transition-all duration-200 ease-in-out\n    focus:outline-none focus:ring-2 focus:ring-offset-2\n    disabled:opacity-50 disabled:cursor-not-allowed\n  `;\n\n  const sizeClass = sizeClasses[size];\n\n  return (\n    <div className={`inline-flex items-center gap-1 ${className}`}>\n      {/* Thumbs Up */}\n      <button\n        type=\"button\"\n        onClick={() => handleFeedback('positive')}\n        disabled={disabled || isSubmitting}\n        aria-label=\"Good response\"\n        aria-pressed={feedback === 'positive'}\n        className={`\n          ${buttonBase}\n          ${sizeClass}\n          ${\n            feedback === 'positive'\n              ? 'bg-green-500/20 text-green-500 ring-2 ring-green-500/50'\n              : 'bg-gray-100 dark:bg-gray-800 text-gray-500 hover:bg-green-100 dark:hover:bg-green-900/30 hover:text-green-600'\n          }\n        `}\n      >\n        <ThumbsUpIcon className=\"w-4 h-4\" />\n      </button>\n\n      {/* Thumbs Down */}\n      <button\n        type=\"button\"\n        onClick={() => handleFeedback('negative')}\n        disabled={disabled || isSubmitting}\n        aria-label=\"Unhelpful response\"\n        aria-pressed={feedback === 'negative'}\n        className={`\n          ${buttonBase}\n          ${sizeClass}\n          ${\n            feedback === 'negative'\n              ? 'bg-red-500/20 text-red-500 ring-2 ring-red-500/50'\n              : 'bg-gray-100 dark:bg-gray-800 text-gray-500 hover:bg-red-100 dark:hover:bg-red-900/30 hover:text-red-600'\n          }\n        `}\n      >\n        <ThumbsDownIcon className=\"w-4 h-4\" />\n      </button>\n    </div>\n  );\n}\n\n// Simple SVG icons (no external dependencies)\nfunction ThumbsUpIcon({ className = '' }: { className?: string }) {\n  return (\n    <svg\n      className={className}\n      viewBox=\"0 0 24 24\"\n      fill=\"none\"\n      stroke=\"currentColor\"\n      strokeWidth={2}\n      strokeLinecap=\"round\"\n      strokeLinejoin=\"round\"\n    >\n      <path d=\"M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3\" />\n    </svg>\n  );\n}\n\nfunction ThumbsDownIcon({ className = '' }: { className?: string }) {\n  return (\n    <svg\n      className={className}\n      viewBox=\"0 0 24 24\"\n      fill=\"none\"\n      stroke=\"currentColor\"\n      strokeWidth={2}\n      strokeLinecap=\"round\"\n      strokeLinejoin=\"round\"\n    >\n      <path d=\"M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17\" />\n    </svg>\n  );\n}\n","/**\n * FeedbackPanel - Detailed feedback collection panel\n *\n * Provides a more detailed feedback interface with categories and comments.\n */\n\nimport React, { useState, useCallback } from 'react';\n\nexport interface FeedbackPanelProps {\n  /** Unique identifier for the message being rated */\n  messageId: string;\n  /** The text content being evaluated */\n  content?: string;\n  /** Callback when feedback is submitted */\n  onSubmit?: (feedback: DetailedFeedback) => void;\n  /** Callback to close the panel */\n  onClose?: () => void;\n  /** Show content preview */\n  showPreview?: boolean;\n  /** Custom class names */\n  className?: string;\n}\n\nexport interface DetailedFeedback {\n  messageId: string;\n  rating: 'positive' | 'negative';\n  categories: FeedbackCategory[];\n  comment?: string;\n  timestamp: string;\n}\n\ntype FeedbackCategory =\n  | 'accurate'\n  | 'helpful'\n  | 'clear'\n  | 'creative'\n  | 'inaccurate'\n  | 'unhelpful'\n  | 'confusing'\n  | 'inappropriate';\n\nconst POSITIVE_CATEGORIES: { id: FeedbackCategory; label: string }[] = [\n  { id: 'accurate', label: 'Accurate' },\n  { id: 'helpful', label: 'Helpful' },\n  { id: 'clear', label: 'Clear' },\n  { id: 'creative', label: 'Creative' },\n];\n\nconst NEGATIVE_CATEGORIES: { id: FeedbackCategory; label: string }[] = [\n  { id: 'inaccurate', label: 'Inaccurate' },\n  { id: 'unhelpful', label: 'Not helpful' },\n  { id: 'confusing', label: 'Confusing' },\n  { id: 'inappropriate', label: 'Inappropriate' },\n];\n\n/**\n * Detailed feedback collection panel\n */\nexport function FeedbackPanel({\n  messageId,\n  content,\n  onSubmit,\n  onClose,\n  showPreview = true,\n  className = '',\n}: FeedbackPanelProps): React.ReactElement {\n  const [rating, setRating] = useState<'positive' | 'negative' | null>(null);\n  const [selectedCategories, setSelectedCategories] = useState<\n    Set<FeedbackCategory>\n  >(new Set());\n  const [comment, setComment] = useState('');\n  const [isSubmitting, setIsSubmitting] = useState(false);\n  const [submitted, setSubmitted] = useState(false);\n\n  const categories =\n    rating === 'positive' ? POSITIVE_CATEGORIES : NEGATIVE_CATEGORIES;\n\n  const toggleCategory = useCallback((category: FeedbackCategory) => {\n    setSelectedCategories((prev) => {\n      const next = new Set(prev);\n      if (next.has(category)) {\n        next.delete(category);\n      } else {\n        next.add(category);\n      }\n      return next;\n    });\n  }, []);\n\n  const handleSubmit = useCallback(async () => {\n    if (!rating || isSubmitting) return;\n\n    setIsSubmitting(true);\n    try {\n      const feedback: DetailedFeedback = {\n        messageId,\n        rating,\n        categories: Array.from(selectedCategories),\n        comment: comment.trim() || undefined,\n        timestamp: new Date().toISOString(),\n      };\n\n      if (onSubmit) {\n        await onSubmit(feedback);\n      }\n\n      setSubmitted(true);\n    } finally {\n      setIsSubmitting(false);\n    }\n  }, [messageId, rating, selectedCategories, comment, onSubmit, isSubmitting]);\n\n  if (submitted) {\n    return (\n      <div\n        className={`p-4 bg-gray-50 dark:bg-gray-900 rounded-lg ${className}`}\n      >\n        <div className=\"text-center\">\n          <div className=\"text-green-500 text-2xl mb-2\">✓</div>\n          <p className=\"text-gray-700 dark:text-gray-300 font-medium\">\n            Thank you for your feedback!\n          </p>\n          <p className=\"text-gray-500 dark:text-gray-400 text-sm mt-1\">\n            Your input helps improve the model.\n          </p>\n          {onClose && (\n            <button\n              onClick={onClose}\n              className=\"mt-4 px-4 py-2 text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100\"\n            >\n              Close\n            </button>\n          )}\n        </div>\n      </div>\n    );\n  }\n\n  return (\n    <div\n      className={`p-4 bg-gray-50 dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-700 ${className}`}\n    >\n      {/* Header */}\n      <div className=\"flex items-center justify-between mb-4\">\n        <h3 className=\"text-sm font-medium text-gray-900 dark:text-gray-100\">\n          Rate this response\n        </h3>\n        {onClose && (\n          <button\n            onClick={onClose}\n            className=\"text-gray-400 hover:text-gray-600 dark:hover:text-gray-300\"\n            aria-label=\"Close\"\n          >\n            ✕\n          </button>\n        )}\n      </div>\n\n      {/* Content Preview */}\n      {showPreview && content && (\n        <div className=\"mb-4 p-3 bg-white dark:bg-gray-800 rounded border border-gray-200 dark:border-gray-700\">\n          <p className=\"text-sm text-gray-600 dark:text-gray-400 line-clamp-3\">\n            {content}\n          </p>\n        </div>\n      )}\n\n      {/* Rating Selection */}\n      <div className=\"flex gap-3 mb-4\">\n        <button\n          onClick={() => {\n            setRating('positive');\n            setSelectedCategories(new Set());\n          }}\n          className={`\n            flex-1 py-2 px-4 rounded-lg border-2 transition-all\n            ${\n              rating === 'positive'\n                ? 'border-green-500 bg-green-50 dark:bg-green-900/20 text-green-700 dark:text-green-400'\n                : 'border-gray-200 dark:border-gray-700 hover:border-green-300 dark:hover:border-green-700'\n            }\n          `}\n        >\n          <span className=\"text-lg\" aria-hidden=\"true\">\n            +\n          </span>\n          <span className=\"ml-2 text-sm font-medium\">Helpful</span>\n        </button>\n        <button\n          onClick={() => {\n            setRating('negative');\n            setSelectedCategories(new Set());\n          }}\n          className={`\n            flex-1 py-2 px-4 rounded-lg border-2 transition-all\n            ${\n              rating === 'negative'\n                ? 'border-red-500 bg-red-50 dark:bg-red-900/20 text-red-700 dark:text-red-400'\n                : 'border-gray-200 dark:border-gray-700 hover:border-red-300 dark:hover:border-red-700'\n            }\n          `}\n        >\n          <span className=\"text-lg\" aria-hidden=\"true\">\n            -\n          </span>\n          <span className=\"ml-2 text-sm font-medium\">Not Helpful</span>\n        </button>\n      </div>\n\n      {/* Category Selection */}\n      {rating && (\n        <>\n          <div className=\"mb-4\">\n            <label className=\"block text-xs font-medium text-gray-500 dark:text-gray-400 mb-2\">\n              What made it {rating === 'positive' ? 'helpful' : 'unhelpful'}?\n              (optional)\n            </label>\n            <div className=\"flex flex-wrap gap-2\">\n              {categories.map(({ id, label }) => (\n                <button\n                  key={id}\n                  onClick={() => toggleCategory(id)}\n                  className={`\n                    px-3 py-1 text-sm rounded-full border transition-all\n                    ${\n                      selectedCategories.has(id)\n                        ? rating === 'positive'\n                          ? 'border-green-500 bg-green-100 dark:bg-green-900/30 text-green-700 dark:text-green-400'\n                          : 'border-red-500 bg-red-100 dark:bg-red-900/30 text-red-700 dark:text-red-400'\n                        : 'border-gray-300 dark:border-gray-600 text-gray-600 dark:text-gray-400 hover:border-gray-400 dark:hover:border-gray-500'\n                    }\n                  `}\n                >\n                  {label}\n                </button>\n              ))}\n            </div>\n          </div>\n\n          {/* Comment */}\n          <div className=\"mb-4\">\n            <label className=\"block text-xs font-medium text-gray-500 dark:text-gray-400 mb-2\">\n              Additional comments (optional)\n            </label>\n            <textarea\n              value={comment}\n              onChange={(e) => setComment(e.target.value)}\n              placeholder=\"Tell us more...\"\n              aria-label=\"Additional feedback comments\"\n              className=\"w-full p-2 text-sm border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 placeholder:text-gray-400 focus:outline-none focus:ring-2 focus:ring-blue-500\"\n              rows={2}\n            />\n          </div>\n\n          {/* Submit */}\n          <button\n            onClick={handleSubmit}\n            disabled={isSubmitting}\n            className={`\n              w-full py-2 px-4 rounded-lg font-medium transition-all\n              ${\n                isSubmitting\n                  ? 'bg-gray-300 dark:bg-gray-700 text-gray-500 cursor-not-allowed'\n                  : 'bg-blue-500 hover:bg-blue-600 text-white'\n              }\n            `}\n          >\n            {isSubmitting ? 'Submitting...' : 'Submit Feedback'}\n          </button>\n        </>\n      )}\n    </div>\n  );\n}\n","/**\n * ModelStatus - Display model download and inference status\n *\n * Shows download progress, model readiness, and inference stats.\n */\n\nimport React from 'react';\n\nexport interface ModelStatusProps {\n  /** Model identifier */\n  modelId: string;\n  /** Download progress (0-100) */\n  downloadProgress?: number;\n  /** Whether the model is ready for inference */\n  isReady: boolean;\n  /** Whether currently generating */\n  isGenerating?: boolean;\n  /** Current inference speed (tokens/sec) */\n  tokensPerSecond?: number;\n  /** Storage used by the model (bytes) */\n  storageUsed?: number;\n  /** Inference backend being used */\n  backend?: 'webgpu' | 'wasm' | 'cpu';\n  /** Whether SIMD is enabled */\n  simdEnabled?: boolean;\n  /** Error message if any */\n  error?: string;\n  /** Compact display mode */\n  compact?: boolean;\n  /** Custom class names */\n  className?: string;\n}\n\n/**\n * Format bytes to human-readable string\n */\nfunction formatBytes(bytes: number): string {\n  if (bytes === 0) return '0 B';\n  const k = 1024;\n  const sizes = ['B', 'KB', 'MB', 'GB'];\n  const i = Math.floor(Math.log(bytes) / Math.log(k));\n  return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;\n}\n\n/**\n * Model status indicator component\n */\nexport function ModelStatus({\n  modelId,\n  downloadProgress,\n  isReady,\n  isGenerating = false,\n  tokensPerSecond,\n  storageUsed,\n  backend,\n  simdEnabled,\n  error,\n  compact = false,\n  className = '',\n}: ModelStatusProps): React.ReactElement {\n  // Determine status\n  const isDownloading =\n    downloadProgress !== undefined && downloadProgress < 100;\n\n  if (compact) {\n    return (\n      <div className={`inline-flex items-center gap-2 text-sm ${className}`}>\n        {/* Status indicator */}\n        <span\n          className={`w-2 h-2 rounded-full ${\n            error\n              ? 'bg-red-500'\n              : isGenerating\n              ? 'bg-yellow-500 animate-pulse'\n              : isReady\n              ? 'bg-green-500'\n              : isDownloading\n              ? 'bg-blue-500 animate-pulse'\n              : 'bg-gray-400'\n          }`}\n        />\n\n        {/* Model name */}\n        <span className=\"text-gray-700 dark:text-gray-300 font-medium\">\n          {modelId}\n        </span>\n\n        {/* Status text */}\n        <span className=\"text-gray-500 dark:text-gray-400\">\n          {error\n            ? 'Error'\n            : isGenerating\n            ? `${tokensPerSecond?.toFixed(1) ?? '?'} tok/s`\n            : isReady\n            ? 'Ready'\n            : isDownloading\n            ? `${downloadProgress}%`\n            : 'Not loaded'}\n        </span>\n      </div>\n    );\n  }\n\n  return (\n    <div\n      className={`p-4 bg-gray-50 dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-700 ${className}`}\n    >\n      {/* Header */}\n      <div className=\"flex items-center justify-between mb-3\">\n        <div className=\"flex items-center gap-2\">\n          <span\n            className={`w-3 h-3 rounded-full ${\n              error\n                ? 'bg-red-500'\n                : isGenerating\n                ? 'bg-yellow-500 animate-pulse'\n                : isReady\n                ? 'bg-green-500'\n                : isDownloading\n                ? 'bg-blue-500 animate-pulse'\n                : 'bg-gray-400'\n            }`}\n          />\n          <h3 className=\"font-medium text-gray-900 dark:text-gray-100\">\n            {modelId}\n          </h3>\n        </div>\n\n        {/* Backend badge */}\n        {backend && (\n          <span className=\"px-2 py-0.5 text-xs font-medium rounded-full bg-gray-200 dark:bg-gray-700 text-gray-600 dark:text-gray-400\">\n            {backend.toUpperCase()}\n            {simdEnabled && ' + SIMD'}\n          </span>\n        )}\n      </div>\n\n      {/* Error message */}\n      {error && (\n        <div className=\"mb-3 p-2 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded text-sm text-red-600 dark:text-red-400\">\n          {error}\n        </div>\n      )}\n\n      {/* Download progress */}\n      {isDownloading && (\n        <div className=\"mb-3\">\n          <div className=\"flex justify-between text-xs text-gray-500 dark:text-gray-400 mb-1\">\n            <span>Downloading...</span>\n            <span>{downloadProgress}%</span>\n          </div>\n          <div className=\"h-2 bg-gray-200 dark:bg-gray-700 rounded-full overflow-hidden\">\n            {}\n            <div\n              className=\"h-full bg-blue-500 transition-all duration-300 ease-out\"\n              style={{ width: `${downloadProgress}%` }}\n            />\n          </div>\n        </div>\n      )}\n\n      {/* Stats */}\n      {isReady && (\n        <div className=\"grid grid-cols-2 gap-3 text-sm\">\n          {/* Inference speed */}\n          <div className=\"p-2 bg-white dark:bg-gray-800 rounded border border-gray-200 dark:border-gray-700\">\n            <div className=\"text-xs text-gray-500 dark:text-gray-400 mb-0.5\">\n              Speed\n            </div>\n            <div className=\"font-medium text-gray-900 dark:text-gray-100\">\n              {isGenerating\n                ? `${tokensPerSecond?.toFixed(1) ?? '—'} tok/s`\n                : 'Idle'}\n            </div>\n          </div>\n\n          {/* Storage */}\n          {storageUsed !== undefined && (\n            <div className=\"p-2 bg-white dark:bg-gray-800 rounded border border-gray-200 dark:border-gray-700\">\n              <div className=\"text-xs text-gray-500 dark:text-gray-400 mb-0.5\">\n                Storage\n              </div>\n              <div className=\"font-medium text-gray-900 dark:text-gray-100\">\n                {formatBytes(storageUsed)}\n              </div>\n            </div>\n          )}\n        </div>\n      )}\n\n      {/* Status text for not loaded */}\n      {!isReady && !isDownloading && !error && (\n        <p className=\"text-sm text-gray-500 dark:text-gray-400\">\n          Model not loaded. Call{' '}\n          <code className=\"px-1 py-0.5 bg-gray-200 dark:bg-gray-700 rounded text-xs\">\n            init()\n          </code>{' '}\n          to start.\n        </p>\n      )}\n    </div>\n  );\n}\n","/**\n * EdgeworkContext - React context for Edgework SDK\n *\n * Provides SDK instance and state management for React applications.\n */\n\nimport React, {\n  createContext,\n  useContext,\n  useEffect,\n  useState,\n  useCallback,\n  useMemo,\n} from 'react';\nimport type { Edgework } from '../index';\nimport type { GenerateResult, ChatMessage, DownloadProgress } from '../types';\n\nexport interface EdgeworkContextValue {\n  /** SDK instance (null until initialized) */\n  sdk: Edgework | null;\n  /** Whether the SDK is initialized */\n  isInitialized: boolean;\n  /** Whether the model is ready for inference */\n  isReady: boolean;\n  /** Whether currently generating */\n  isGenerating: boolean;\n  /** Download progress during model loading */\n  downloadProgress: DownloadProgress | null;\n  /** Current error if any */\n  error: Error | null;\n  /** Initialize the SDK */\n  initialize: () => Promise<void>;\n  /** Generate text */\n  generate: (prompt: string) => Promise<GenerateResult | null>;\n  /** Chat with messages */\n  chat: (messages: ChatMessage[]) => Promise<GenerateResult | null>;\n  /** Submit feedback for RLHF */\n  submitFeedback: (\n    messageHash: string,\n    rating: 'positive' | 'negative'\n  ) => Promise<void>;\n}\n\nconst EdgeworkContext = createContext<EdgeworkContextValue | null>(null);\n\nexport interface EdgeworkProviderProps {\n  /** Model to use */\n  model: string;\n  /** Children components */\n  children: React.ReactNode;\n  /** Auto-initialize on mount */\n  autoInit?: boolean;\n  /** Storage backend preference */\n  storageBackend?: 'opfs' | 'indexeddb' | 'memory';\n  /** Enable RLHF */\n  enableRLHF?: boolean;\n  /** User ID for personalization */\n  userId?: string;\n}\n\n/**\n * Provider component for Edgework SDK\n */\nexport function EdgeworkProvider({\n  model,\n  children,\n  autoInit = false,\n  storageBackend = 'opfs',\n  enableRLHF = true,\n  userId,\n}: EdgeworkProviderProps): React.ReactElement {\n  const [sdk, setSdk] = useState<Edgework | null>(null);\n  const [isInitialized, setIsInitialized] = useState(false);\n  const [isReady, setIsReady] = useState(false);\n  const [isGenerating, setIsGenerating] = useState(false);\n  const [downloadProgress, setDownloadProgress] =\n    useState<DownloadProgress | null>(null);\n  const [error, setError] = useState<Error | null>(null);\n\n  // Initialize SDK\n  const initialize = useCallback(async () => {\n    if (isInitialized || sdk) return;\n\n    try {\n      setError(null);\n\n      // Dynamic import to avoid SSR issues\n      const { Edgework } = await import('../index');\n\n      const instance = await Edgework.init({\n        model,\n        storageBackend,\n        enableRLHF,\n        userId,\n        onProgress: (progress) => {\n          setDownloadProgress(progress);\n        },\n      });\n\n      setSdk(instance);\n      setIsInitialized(true);\n      setIsReady(true);\n    } catch (err) {\n      const error = err instanceof Error ? err : new Error(String(err));\n      setError(error);\n      console.error('[EdgeworkContext] Initialization failed:', error);\n    }\n  }, [model, storageBackend, enableRLHF, userId, isInitialized, sdk]);\n\n  // Auto-initialize\n  useEffect(() => {\n    if (autoInit && !isInitialized && !sdk) {\n      initialize();\n    }\n  }, [autoInit, isInitialized, sdk, initialize]);\n\n  // Generate text\n  const generate = useCallback(\n    async (prompt: string): Promise<GenerateResult | null> => {\n      if (!sdk || !isReady) {\n        console.warn('[EdgeworkContext] SDK not ready');\n        return null;\n      }\n\n      try {\n        setIsGenerating(true);\n        setError(null);\n        const result = await sdk.generate(prompt);\n        return result;\n      } catch (err) {\n        const error = err instanceof Error ? err : new Error(String(err));\n        setError(error);\n        console.error('[EdgeworkContext] Generate failed:', error);\n        return null;\n      } finally {\n        setIsGenerating(false);\n      }\n    },\n    [sdk, isReady]\n  );\n\n  // Chat with messages\n  const chat = useCallback(\n    async (messages: ChatMessage[]): Promise<GenerateResult | null> => {\n      if (!sdk || !isReady) {\n        console.warn('[EdgeworkContext] SDK not ready');\n        return null;\n      }\n\n      try {\n        setIsGenerating(true);\n        setError(null);\n        const result = await sdk.chat(messages);\n        return result;\n      } catch (err) {\n        const error = err instanceof Error ? err : new Error(String(err));\n        setError(error);\n        console.error('[EdgeworkContext] Chat failed:', error);\n        return null;\n      } finally {\n        setIsGenerating(false);\n      }\n    },\n    [sdk, isReady]\n  );\n\n  // Submit feedback\n  const submitFeedback = useCallback(\n    async (\n      messageHash: string,\n      rating: 'positive' | 'negative'\n    ): Promise<void> => {\n      if (!sdk) {\n        console.warn('[EdgeworkContext] SDK not initialized');\n        return;\n      }\n\n      try {\n        await sdk.feedback(messageHash, rating);\n      } catch (err) {\n        console.error('[EdgeworkContext] Feedback failed:', err);\n      }\n    },\n    [sdk]\n  );\n\n  // Memoized context value\n  const value = useMemo<EdgeworkContextValue>(\n    () => ({\n      sdk,\n      isInitialized,\n      isReady,\n      isGenerating,\n      downloadProgress,\n      error,\n      initialize,\n      generate,\n      chat,\n      submitFeedback,\n    }),\n    [\n      sdk,\n      isInitialized,\n      isReady,\n      isGenerating,\n      downloadProgress,\n      error,\n      initialize,\n      generate,\n      chat,\n      submitFeedback,\n    ]\n  );\n\n  return (\n    <EdgeworkContext.Provider value={value}>\n      {children}\n    </EdgeworkContext.Provider>\n  );\n}\n\n/**\n * Hook to use Edgework SDK in components\n */\nexport function useEdgework(): EdgeworkContextValue {\n  const context = useContext(EdgeworkContext);\n  if (!context) {\n    throw new Error('useEdgework must be used within an EdgeworkProvider');\n  }\n  return context;\n}\n"]}