{"_id":"@danjari/blocknote-ai-extension","_rev":"3-c772afd925d7e057c08433c1fa16fc16","name":"@danjari/blocknote-ai-extension","dist-tags":{"latest":"1.0.0"},"versions":{"0.1.0":{"name":"@danjari/blocknote-ai-extension","version":"0.1.0","keywords":["react","javascript","editor","typescript","prosemirror","wysiwyg","rich-text-editor","notion","block-based","ai","slash-commands"],"license":"MIT","_id":"@danjari/blocknote-ai-extension@0.1.0","maintainers":[{"name":"danjari","email":"mm12515@nyu.edu"}],"homepage":"https://github.com/TypeCellOS/BlockNote","bugs":{"url":"https://github.com/TypeCellOS/BlockNote/issues"},"dist":{"shasum":"874bb6e8cce65911e1ed139305d95d9fba459a1d","tarball":"https://registry.npmjs.org/@danjari/blocknote-ai-extension/-/blocknote-ai-extension-0.1.0.tgz","fileCount":42,"integrity":"sha512-2fu4uKEcRHYZibQFzZYErCjO0bdE4H7Gvv+hUTDOyFHQH1rmmwKfZa4lolSXxNn35YP2P5IftpdOEE8Yk7vM1A==","signatures":[{"sig":"MEQCIGBPvGNw+BHBUndc2oIDzXl64x+gbwzEN1EJpec+oS4eAiAM7iaxDmh17sWLk1zGg89XW4MR7t46fpa6DpJLtTH6AQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":60746},"main":"./dist/ai-slash.cjs","type":"module","types":"./types/src/index.d.ts","module":"./dist/ai-slash.js","source":"src/index.ts","exports":{".":{"types":"./types/src/index.d.ts","import":"./dist/ai-slash.js","require":"./dist/ai-slash.cjs"},"./theme.css":{"style":"./dist/style.css","import":"./dist/style.css","require":"./dist/style.css"}},"gitHead":"7248b02a5737f01d34323a1776182aa23d7271c1","private":false,"scripts":{"dev":"vite --config vite.dev.config.ts","lint":"eslint src --max-warnings 0","test":"vitest --run","build":"tsc && vite build","clean":"rimraf dist && rimraf types","serve":"vite preview --port 3001","preview":"vite preview","test-watch":"vitest watch","prepublishOnly":"npm run build"},"_npmUser":{"name":"danjari","email":"mm12515@nyu.edu"},"repository":{"url":"git+https://github.com/TypeCellOS/BlockNote.git","type":"git","directory":"packages/extensions/ai-slash"},"_npmVersion":"10.8.2","description":"AI-powered slash commands extension for BlockNote editor","directories":{},"sideEffects":["*.css"],"_nodeVersion":"20.18.2","dependencies":{"@blocknote/core":"^0.35.0"},"eslintConfig":{"extends":["../../.eslintrc.json"]},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.3.4","react":"^19.1.0","eslint":"^8.10.0","rimraf":"^5.0.5","vitest":"^2.0.3","typescript":"^5.3.3","@types/react":"^19.1.0"},"peerDependencies":{"react":"^19.1.0"},"_npmOperationalInternal":{"tmp":"tmp/blocknote-ai-extension_0.1.0_1754425717527_0.5061614687180995","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@danjari/blocknote-ai-extension","version":"0.1.1","keywords":["react","javascript","editor","typescript","prosemirror","wysiwyg","rich-text-editor","notion","block-based","ai","slash-commands"],"license":"MIT","_id":"@danjari/blocknote-ai-extension@0.1.1","maintainers":[{"name":"danjari","email":"mm12515@nyu.edu"}],"homepage":"https://github.com/TypeCellOS/BlockNote","bugs":{"url":"https://github.com/TypeCellOS/BlockNote/issues"},"dist":{"shasum":"2adcea36908ba8c2f0743f7e9894a20b64ae28ce","tarball":"https://registry.npmjs.org/@danjari/blocknote-ai-extension/-/blocknote-ai-extension-0.1.1.tgz","fileCount":42,"integrity":"sha512-OG2WMurh79qtEBPYJbdP4djSxjKP0zUYFE+P1o4+Ziz/a6KfMYevIMSq+SNuUf2pnhI3wgs1eGHSZ5RvEkI+Cw==","signatures":[{"sig":"MEUCIBBH91UyNo6rbqn/WULlkzxPRl+kMW0pffGhF1HPQoclAiEAlN+Ndrah+j/fH3JWMFGHqRDsn30p/vHZBhwDIOsjG5o=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":60759},"main":"./dist/ai-slash.cjs","type":"module","types":"./types/index.d.ts","module":"./dist/ai-slash.js","source":"src/index.ts","exports":{".":{"types":"./types/index.d.ts","import":"./dist/ai-slash.js","require":"./dist/ai-slash.cjs"},"./theme.css":{"style":"./dist/style.css","import":"./dist/style.css","require":"./dist/style.css"}},"gitHead":"2d81af724b9c3e2b81c905a14f929208fb0db9db","private":false,"scripts":{"dev":"vite --config vite.dev.config.ts","lint":"eslint src --max-warnings 0","test":"vitest --run","build":"tsc && vite build","clean":"rimraf dist && rimraf types","serve":"vite preview --port 3001","preview":"vite preview","test-watch":"vitest watch","prepublishOnly":"npm run build"},"_npmUser":{"name":"danjari","email":"mm12515@nyu.edu"},"repository":{"url":"git+https://github.com/TypeCellOS/BlockNote.git","type":"git","directory":"packages/extensions/ai-slash"},"_npmVersion":"10.8.2","description":"AI-powered slash commands extension for BlockNote editor","directories":{},"sideEffects":["*.css"],"_nodeVersion":"20.18.2","dependencies":{"@blocknote/core":"^0.35.0"},"eslintConfig":{"extends":["../../.eslintrc.json"]},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.3.4","react":"^19.1.0","eslint":"^8.10.0","rimraf":"^5.0.5","vitest":"^2.0.3","typescript":"^5.3.3","@types/react":"^19.1.0"},"peerDependencies":{"react":"^19.1.0"},"_npmOperationalInternal":{"tmp":"tmp/blocknote-ai-extension_0.1.1_1754428393594_0.6735610772377021","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@danjari/blocknote-ai-extension","homepage":"https://github.com/TypeCellOS/BlockNote","private":false,"publishConfig":{"access":"public"},"sideEffects":["*.css"],"repository":{"type":"git","url":"git+https://github.com/TypeCellOS/BlockNote.git","directory":"packages/extensions/ai-slash"},"license":"MIT","version":"1.0.0","keywords":["react","javascript","editor","typescript","prosemirror","wysiwyg","rich-text-editor","notion","block-based","ai","slash-commands","blocknote","extension","artificial-intelligence","chatgpt","openai","claude","gemini"],"description":"AI-powered slash commands extension for BlockNote editor. Add ChatGPT, Claude, and Gemini AI capabilities to your BlockNote editor with custom slash commands like /explain, /summarize, /quiz-me, and /diagram.","author":{"name":"mooudjahidmoussa"},"type":"module","source":"src/index.ts","types":"./types/index.d.ts","main":"./dist/ai-slash.cjs","module":"./dist/ai-slash.js","exports":{".":{"types":"./types/index.d.ts","import":"./dist/ai-slash.js","require":"./dist/ai-slash.cjs"},"./theme.css":{"import":"./dist/style.css","require":"./dist/style.css","style":"./dist/style.css"}},"scripts":{"dev":"vite --config vite.dev.config.ts","build":"tsc && vite build","preview":"vite preview","serve":"vite preview --port 3001","lint":"eslint src --max-warnings 0","test":"vitest --run","test-watch":"vitest watch","clean":"rimraf dist && rimraf types","prepublishOnly":"npm run build"},"dependencies":{"@blocknote/core":"^0.35.0"},"peerDependencies":{"react":"^19.1.0"},"devDependencies":{"@types/react":"^19.1.0","eslint":"^8.10.0","react":"^19.1.0","rimraf":"^5.0.5","typescript":"^5.3.3","vite":"^5.3.4","vitest":"^2.0.3"},"eslintConfig":{"extends":["../../.eslintrc.json"]},"_id":"@danjari/blocknote-ai-extension@1.0.0","gitHead":"4cdcbb3da6c1e91b0aff9e1070f1694142e3ca9a","bugs":{"url":"https://github.com/TypeCellOS/BlockNote/issues"},"_nodeVersion":"20.18.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-GdSJr5Lmr4Rxz90xRxHP6/DR5xlcyqLg5IXfyFrwAggcfibTRqRWONpvNeJ/bMhjREvIZOtDRrUYfXkASe4lwg==","shasum":"8f9f7d8ddf8540389a633a73dc79a7c8933670e5","tarball":"https://registry.npmjs.org/@danjari/blocknote-ai-extension/-/blocknote-ai-extension-1.0.0.tgz","fileCount":42,"unpackedSize":71301,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCMjKGldweUQLWj1Lc50Nl4Isj4WhL1Nqlh4nG++C1giwIhAJm+Z+aiJulbaKiY9P7MBK8io+3H7S46Rzre02D6AKeR"}]},"_npmUser":{"name":"danjari","email":"mm12515@nyu.edu"},"directories":{},"maintainers":[{"name":"danjari","email":"mm12515@nyu.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/blocknote-ai-extension_1.0.0_1754438479016_0.513981302393397"},"_hasShrinkwrap":false}},"time":{"created":"2025-08-05T20:28:37.395Z","modified":"2025-08-06T00:01:19.373Z","0.1.0":"2025-08-05T20:28:37.694Z","0.1.1":"2025-08-05T21:13:13.781Z","1.0.0":"2025-08-06T00:01:19.199Z"},"bugs":{"url":"https://github.com/TypeCellOS/BlockNote/issues"},"license":"MIT","homepage":"https://github.com/TypeCellOS/BlockNote","keywords":["react","javascript","editor","typescript","prosemirror","wysiwyg","rich-text-editor","notion","block-based","ai","slash-commands","blocknote","extension","artificial-intelligence","chatgpt","openai","claude","gemini"],"repository":{"type":"git","url":"git+https://github.com/TypeCellOS/BlockNote.git","directory":"packages/extensions/ai-slash"},"description":"AI-powered slash commands extension for BlockNote editor. Add ChatGPT, Claude, and Gemini AI capabilities to your BlockNote editor with custom slash commands like /explain, /summarize, /quiz-me, and /diagram.","maintainers":[{"name":"danjari","email":"mm12515@nyu.edu"}],"readme":"# BlockNote AI Slash Extension\n\nAI-powered slash commands extension for BlockNote editor (use case for Synapsed ). This extension adds AI functionality to BlockNote while maintaining full compatibility with all existing features.\n\n## ✨ Features\n\n- **AI Slash Commands**: `/explain`, `/quiz-me`, `/summarize`, `/diagram`\n- **Full BlockNote Compatibility**: All existing commands work alongside AI commands\n- **Event-Driven Architecture**: Clean separation between UI and AI logic\n- **Streaming Support**: Real-time AI response streaming\n- **Synapsed Theme**: Custom styling with indigo accent colors\n- **TypeScript Support**: Full type safety\n\n## 🚀 Quick Start\n\n### Installation\n\n```bash\nnpm install @danjari/blocknote-ai-extension\n```\n\n### When to Add AI APIs\n\n**Phase 1: Development & Testing (Current)**\n\n- ✅ Use simulated responses for testing\n- ✅ Focus on UI/UX and command structure\n- ✅ Test with the BlockNote playground\n- ✅ Verify all commands work correctly\n\n**Phase 2: AI Integration (Next Step)**\n\n- 🔄 Replace simulated responses with real AI APIs\n- 🔄 Add error handling and fallbacks\n- 🔄 Implement streaming for real-time responses\n- 🔄 Add user authentication and rate limiting\n\n**Phase 3: Production (Final)**\n\n- 🎯 Deploy with production AI services\n- 🎯 Add monitoring and analytics\n- 🎯 Implement caching and optimization\n- 🎯 Add advanced features like conversation history\n\n### Basic Usage\n\n```javascript\nimport { BlockNoteEditor, getDefaultSlashMenuItems } from \"@blocknote/core\";\nimport { BlockNoteView } from \"@blocknote/react\";\nimport {\n  getAISlashMenuItems,\n  createAIStreamingUtils,\n} from \"@danjari/blocknote-ai-extension\";\n\n// Create AI command handler\nfunction handleAICommand(action, payload) {\n  console.log(\"AI Command:\", action, payload);\n\n  // Connect to your AI API here\n  switch (action) {\n    case \"explain\":\n      // Call your AI API for explanation\n      break;\n    case \"quiz-me\":\n      // Generate quiz\n      break;\n    case \"summarize\":\n      // Summarize content\n      break;\n    case \"diagram\":\n      // Create diagram\n      break;\n  }\n}\n\n// Create editor with AI commands\nconst editor = new BlockNoteEditor({\n  slashMenuItems: [\n    ...getDefaultSlashMenuItems(editor), // All original BlockNote commands\n    ...getAISlashMenuItems(editor, handleAICommand), // AI commands\n  ],\n});\n\n// Set up streaming utilities\nconst streamingUtils = createAIStreamingUtils(editor);\n\n// Render the editor\nfunction MyEditor() {\n  return <BlockNoteView editor={editor} />;\n}\n```\n\n## 🎯 Available Commands\n\n### Original BlockNote Commands (All Work!)\n\n- `/paragraph` - Regular text block\n- `/heading` - Heading (H1, H2, H3)\n- `/bulletListItem` - Bullet list item\n- `/numberedListItem` - Numbered list item\n- `/quote` - Quote block\n- `/code` - Code block\n- `/image` - Image block\n- `/table` - Table\n- `/divider` - Horizontal divider\n- And many more...\n\n### AI Commands (New!)\n\n- `/explain` 🤖 - Explain selected text\n- `/quiz-me` 🤖 - Generate quiz based on content\n- `/summarize` 🤖 - Summarize selected text\n- `/diagram` 🤖 - Create diagram from content\n\n## 🔧 API Reference\n\n### `getAISlashMenuItems(editor, emitAICommand)`\n\nReturns AI slash menu items for the BlockNote editor.\n\n**Parameters:**\n\n- `editor` - BlockNote editor instance\n- `emitAICommand` - Function to handle AI commands\n\n**Returns:** Array of slash menu items\n\n**Example:**\n\n```javascript\nconst menuItems = getAISlashMenuItems(editor, (action, payload) => {\n  console.log(\"AI Command:\", action, payload);\n});\n```\n\n### `createAIStreamingUtils(editor)`\n\nCreates streaming utilities for real-time AI responses.\n\n**Parameters:**\n\n- `editor` - BlockNote editor instance\n\n**Returns:** AIStreamingUtils instance\n\n**Example:**\n\n```javascript\nconst streamingUtils = createAIStreamingUtils(editor);\n\n// Start streaming AI response\nstreamingUtils.startStreaming(\"quote\", \"AI is thinking...\");\n\n// Update streaming content\nstreamingUtils.updateStreaming(\"This is the AI response...\");\n\n// Finish streaming\nstreamingUtils.finishStreaming();\n```\n\n### `useAISlash(config)`\n\nReact hook for AI functionality.\n\n**Parameters:**\n\n- `config` - Configuration object (optional)\n\n**Returns:** AI hook with event emitter\n\n**Example:**\n\n```javascript\nconst aiSlash = useAISlash({\n  callbacks: {\n    onAICommand: (event) => {\n      console.log(\"AI Command:\", event.action, event.payload);\n    },\n    onStream: (chunk) => {\n      console.log(\"Stream chunk:\", chunk);\n    },\n  },\n});\n```\n\n## 🔗 Complete Integration Example\n\n```javascript\nimport { BlockNoteEditor, getDefaultSlashMenuItems } from \"@blocknote/core\";\nimport { BlockNoteView } from \"@blocknote/react\";\nimport {\n  getAISlashMenuItems,\n  createAIStreamingUtils,\n  useAISlash,\n} from \"@danjari/blocknote-ai-extension\";\n\nfunction MyAIEditor() {\n  // Set up streaming utilities\n  const [streamingUtils, setStreamingUtils] = useState(null);\n\n  // AI command handler\n  const handleAICommand = async (action, payload) => {\n    console.log(\"AI Command:\", action, payload);\n\n    // Start streaming indicator\n    if (streamingUtils) {\n      streamingUtils.startStreaming(\"quote\", \"AI is thinking...\");\n    }\n\n    try {\n      // Call your AI API\n      const response = await fetch(\"/api/ai/\" + action, {\n        method: \"POST\",\n        headers: { \"Content-Type\": \"application/json\" },\n        body: JSON.stringify({\n          text: payload.selectedText,\n          action: action,\n        }),\n      });\n\n      const data = await response.json();\n\n      // Update streaming content\n      if (streamingUtils) {\n        streamingUtils.updateStreaming(data.content);\n        streamingUtils.finishStreaming();\n      }\n    } catch (error) {\n      console.error(\"AI API error:\", error);\n      if (streamingUtils) {\n        streamingUtils.finishStreaming();\n      }\n    }\n  };\n\n  // Create editor\n  const editor = useMemo(() => {\n    const editorInstance = new BlockNoteEditor({\n      slashMenuItems: [\n        ...getDefaultSlashMenuItems(editorInstance), // All original commands\n        ...getAISlashMenuItems(editorInstance, handleAICommand), // AI commands\n      ],\n    });\n\n    // Set up streaming utilities\n    setStreamingUtils(createAIStreamingUtils(editorInstance));\n\n    return editorInstance;\n  }, []);\n\n  return <BlockNoteView editor={editor} />;\n}\n```\n\n## 🎨 Theming\n\nThe extension includes Synapsed theme with indigo accent colors:\n\n```css\n:root {\n  --bn-synapsed-accent-color: #6366f1;\n  --bn-synapsed-font-family: \"Inter\", sans-serif;\n}\n```\n\nImport the theme CSS:\n\n```javascript\nimport \"@danjari/blocknote-ai-extension/theme.css\";\n```\n\n## 📦 Exports\n\n```javascript\nimport {\n  // Main functions\n  useAISlash,\n  getAISlashMenuItems,\n  createAIStreamingUtils,\n  AIStreamingUtils,\n\n  // Theme\n  defaultSynapsedTheme,\n  generateSynapsedThemeCSS,\n  getDefaultSynapsedThemeCSS,\n\n  // Types\n  AICommandAction,\n  AICommandPayload,\n  AISlashConfig,\n  AISlashHook,\n  AISlashMenuItem,\n  SynapsedTheme,\n} from \"@danjari/blocknote-ai-extension\";\n```\n\n## 🧪 Testing\n\n### Run the test suite:\n\n```bash\nnpm test\n```\n\n### Test manually:\n\n```bash\n# Test extension functionality\nnode test-extension.js\n\n# Test compatibility with BlockNote\nnode test-compatibility.js\n\n# Test all commands\nnode test-all-commands.js\n\n# View integration example\nnode integration-example.js\n```\n\n### Browser Testing:\n\nOpen `simple-test.html` in your browser to test the extension in a web environment.\n\n### Interactive Testing in BlockNote Playground:\n\n1. **Start the BlockNote playground:**\n\n   ```bash\n   cd /path/to/blocknote\n   pnpm run dev\n   ```\n\n2. **Navigate to your example:**\n\n   - Open `http://localhost:5177/`\n   - Look for \"Custom AI Slash Extension\" in the AI section\n   - Click to load your extension\n\n3. **Test your commands:**\n   - Type `/` to see the slash menu\n   - Try `/explain`, `/quiz-me`, `/summarize`, `/diagram`\n   - Verify responses appear in the editor\n\n## 🚀 Deployment\n\n### Pre-deployment Checklist:\n\n1. **Build the extension:**\n\n   ```bash\n   npm run build\n   ```\n\n2. **Test in production environment:**\n\n   ```bash\n   npm run preview\n   ```\n\n3. **Verify all commands work:**\n\n   - Test all AI commands (`/explain`, `/quiz-me`, `/summarize`, `/diagram`)\n   - Ensure BlockNote commands still work\n   - Check TypeScript compilation\n\n4. **Test with your AI integration:**\n   - Connect to your AI APIs\n   - Test response handling\n   - Verify streaming works\n\n### Production Integration:\n\n```javascript\n// Production-ready AI command handler\nconst handleAICommand = async (action, payload) => {\n  try {\n    // Call your production AI API\n    const response = await fetch(\"/api/ai/\" + action, {\n      method: \"POST\",\n      headers: {\n        \"Content-Type\": \"application/json\",\n        Authorization: `Bearer ${process.env.AI_API_KEY}`,\n      },\n      body: JSON.stringify({\n        text: payload.selectedText,\n        action: action,\n        userId: getCurrentUserId(), // Add user context\n        sessionId: getSessionId(), // Add session tracking\n      }),\n    });\n\n    if (!response.ok) {\n      throw new Error(`AI API error: ${response.status}`);\n    }\n\n    const data = await response.json();\n    return data.content;\n  } catch (error) {\n    console.error(\"AI command failed:\", error);\n    return `Sorry, I couldn't process that request. Please try again.`;\n  }\n};\n```\n\n### Environment Variables:\n\n```bash\n# Required for production\nAI_API_KEY=your_ai_api_key_here\nAI_API_ENDPOINT=https://api.your-ai-service.com\nAI_MODEL=gpt-4 # or your preferred model\n\n# Optional\nAI_MAX_TOKENS=1000\nAI_TEMPERATURE=0.7\nAI_TIMEOUT=30000\n```\n\n## 🤖 AI Integration Guide\n\n### Step 1: Choose Your AI Provider\n\n**OpenAI (Recommended for beginners):**\n\n```javascript\n// OpenAI integration\nconst openaiResponse = await fetch(\n  \"https://api.openai.com/v1/chat/completions\",\n  {\n    method: \"POST\",\n    headers: {\n      Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,\n      \"Content-Type\": \"application/json\",\n    },\n    body: JSON.stringify({\n      model: \"gpt-4\",\n      messages: [\n        { role: \"system\", content: \"You are a helpful AI assistant.\" },\n        { role: \"user\", content: `Explain this: ${payload.selectedText}` },\n      ],\n      max_tokens: 1000,\n    }),\n  },\n);\n```\n\n**Anthropic Claude:**\n\n```javascript\n// Claude integration\nconst claudeResponse = await fetch(\"https://api.anthropic.com/v1/messages\", {\n  method: \"POST\",\n  headers: {\n    \"x-api-key\": process.env.ANTHROPIC_API_KEY,\n    \"Content-Type\": \"application/json\",\n    \"anthropic-version\": \"2023-06-01\",\n  },\n  body: JSON.stringify({\n    model: \"claude-3-sonnet-20240229\",\n    max_tokens: 1000,\n    messages: [\n      { role: \"user\", content: `Explain this: ${payload.selectedText}` },\n    ],\n  }),\n});\n```\n\n**Google Gemini:**\n\n```javascript\n// Gemini integration\nconst geminiResponse = await fetch(\n  `https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key=${process.env.GEMINI_API_KEY}`,\n  {\n    method: \"POST\",\n    headers: { \"Content-Type\": \"application/json\" },\n    body: JSON.stringify({\n      contents: [\n        {\n          parts: [{ text: `Explain this: ${payload.selectedText}` }],\n        },\n      ],\n    }),\n  },\n);\n```\n\n### Step 2: Implement Command-Specific Logic\n\n```javascript\nconst handleAICommand = async (action, payload) => {\n  const selectedText = payload.selectedText || \"current content\";\n\n  switch (action) {\n    case \"explain\":\n      return await callAI(`Explain this text in simple terms: ${selectedText}`);\n\n    case \"summarize\":\n      return await callAI(\n        `Summarize this text in 2-3 sentences: ${selectedText}`,\n      );\n\n    case \"quiz-me\":\n      return await callAI(\n        `Create 3 multiple choice questions based on this text: ${selectedText}`,\n      );\n\n    case \"diagram\":\n      return await callAI(\n        `Create a mermaid diagram based on this text: ${selectedText}`,\n      );\n\n    default:\n      return \"Unknown AI command\";\n  }\n};\n\nasync function callAI(prompt) {\n  // Your AI API call here\n  const response = await fetch(\"/api/ai\", {\n    method: \"POST\",\n    headers: { \"Content-Type\": \"application/json\" },\n    body: JSON.stringify({ prompt }),\n  });\n\n  const data = await response.json();\n  return data.content;\n}\n```\n\n### Step 3: Add Streaming Support\n\n```javascript\n// For real-time streaming responses\nconst handleAICommandWithStreaming = async (action, payload) => {\n  const streamingUtils = createAIStreamingUtils(editor);\n\n  // Start streaming indicator\n  streamingUtils.startStreaming(\"quote\", \"AI is thinking...\");\n\n  try {\n    // Call your streaming AI API\n    const response = await fetch(\"/api/ai/stream\", {\n      method: \"POST\",\n      headers: { \"Content-Type\": \"application/json\" },\n      body: JSON.stringify({ action, payload }),\n    });\n\n    const reader = response.body.getReader();\n    let accumulatedContent = \"\";\n\n    while (true) {\n      const { done, value } = await reader.read();\n      if (done) break;\n\n      const chunk = new TextDecoder().decode(value);\n      accumulatedContent += chunk;\n\n      // Update streaming content\n      streamingUtils.updateStreaming(accumulatedContent);\n    }\n\n    // Finish streaming\n    streamingUtils.finishStreaming();\n  } catch (error) {\n    console.error(\"Streaming error:\", error);\n    streamingUtils.finishStreaming();\n  }\n};\n```\n\n### Step 4: Error Handling & Fallbacks\n\n```javascript\nconst handleAICommandWithFallback = async (action, payload) => {\n  try {\n    // Primary AI service\n    return await callPrimaryAI(action, payload);\n  } catch (error) {\n    console.warn(\"Primary AI failed, trying fallback:\", error);\n\n    try {\n      // Fallback AI service\n      return await callFallbackAI(action, payload);\n    } catch (fallbackError) {\n      console.error(\"All AI services failed:\", fallbackError);\n\n      // Return helpful error message\n      return `Sorry, I'm having trouble processing your request right now. Please try again in a moment.`;\n    }\n  }\n};\n```\n\n## ✅ Compatibility\n\n**✅ Full BlockNote Compatibility**\n\n- All original slash commands work\n- All block types supported\n- All formatting options available\n- No breaking changes\n\n**✅ AI Commands**\n\n- Properly grouped under \"AI\" category\n- No conflicts with existing commands\n- Follow BlockNote command structure\n- Type-safe implementation\n\n## 🔧 Development\n\n### Building the extension:\n\n```bash\nnpm run build\n```\n\n### Development mode:\n\n```bash\nnpm run dev\n```\n\n### Preview:\n\n```bash\nnpm run preview\n```\n\n## 📄 License\n\nMIT License - see [LICENSE](LICENSE) file for details.\n\n## 🤝 Contributing\n\n1. Fork the repository\n2. Create a feature branch\n3. Make your changes\n4. Add tests\n5. Submit a pull request\n\n## 🚀 Roadmap\n\n- [ ] Interactive quiz blocks\n- [ ] More AI commands\n- [ ] Custom AI model support\n- [ ] Advanced streaming features\n- [ ] Collaborative AI features\n","readmeFilename":"README.md","author":{"name":"mooudjahidmoussa"}}