@blocknote/xl-ai 0.31.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.
- package/LICENSE +373 -0
- package/dist/blocknote-xl-ai.cjs +20 -0
- package/dist/blocknote-xl-ai.cjs.map +1 -0
- package/dist/blocknote-xl-ai.js +2918 -0
- package/dist/blocknote-xl-ai.js.map +1 -0
- package/dist/locales.cjs +2 -0
- package/dist/locales.cjs.map +1 -0
- package/dist/locales.js +1424 -0
- package/dist/locales.js.map +1 -0
- package/dist/style.css +1 -0
- package/dist/webpack-stats.json +1 -0
- package/package.json +127 -0
- package/src/AIExtension.ts +419 -0
- package/src/api/LLMRequest.ts +236 -0
- package/src/api/LLMResponse.ts +64 -0
- package/src/api/formats/PromptBuilder.ts +46 -0
- package/src/api/formats/base-tools/createAddBlocksTool.ts +296 -0
- package/src/api/formats/base-tools/createUpdateBlockTool.ts +269 -0
- package/src/api/formats/base-tools/delete.ts +111 -0
- package/src/api/formats/base-tools/util/validateBlockArray.ts +32 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Add/__msw_snapshots__/albert-etalab.chat/neuralmagic/Meta-Llama-3.1-70B-Instruct-FP8 (non-streaming)/Add heading (h1) and code block_1_112bacb4ae22459e8e8b87c510a5a1ab.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Add/__msw_snapshots__/albert-etalab.chat/neuralmagic/Meta-Llama-3.1-70B-Instruct-FP8 (non-streaming)/add a list (end)_1_fd2cdf7edb597b5eee87ae1b4c9d8a9e.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Add/__msw_snapshots__/albert-etalab.chat/neuralmagic/Meta-Llama-3.1-70B-Instruct-FP8 (non-streaming)/add a new paragraph (end)_1_f9f8cec49b3218519501c03ff5c4a3ba.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Add/__msw_snapshots__/albert-etalab.chat/neuralmagic/Meta-Llama-3.1-70B-Instruct-FP8 (non-streaming)/add a new paragraph (start)_1_d152c585ba7d2fa6e68b1d4b063f266c.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Add/__msw_snapshots__/albert-etalab.chat/neuralmagic/Meta-Llama-3.1-70B-Instruct-FP8 (streaming)/add a new paragraph (start)_1_ae61114b97c12fbf57d14d6c64ffd647.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Add/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (non-streaming)/Add heading (h1) and code block_1_c9a31b6237ae08647b85c7348edd052f.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Add/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (non-streaming)/Add heading and code block_1_c9a31b6237ae08647b85c7348edd052f.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Add/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (non-streaming)/add a list (end)_1_db45f2ba8778e15e8a5f7a320508be46.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Add/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (non-streaming)/add a new paragraph (end)_1_f3eaf50ddad718f55acaa05dcc1a2809.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Add/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (non-streaming)/add a new paragraph (start)_1_33db3205ea17e8f6ea3a5e2728b6f10e.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Add/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (streaming)/Add heading (h1) and code block_1_5790f7702887daff99c884204e6ae3df.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Add/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (streaming)/Add heading and code block_1_5790f7702887daff99c884204e6ae3df.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Add/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (streaming)/add a list (end)_1_321607ef45a4235ca02c411097005de2.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Add/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (streaming)/add a new paragraph (end)_1_709e808af3f5fb39418413416804a03e.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Add/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (streaming)/add a new paragraph (start)_1_034fd3f9b57eba789a6449d5ff3714c4.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Add/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/Add heading (h1) and code block_1_084f72a77d80ec6bb6cd2081b3b1d301.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Add/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/Add heading and code block_1_084f72a77d80ec6bb6cd2081b3b1d301.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Add/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/add a list (end)_1_5c081c7846ad89b59477ceda44c2a349.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Add/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/add a new paragraph (end)_1_97770b1d0462a25cfacd049807a59110.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Add/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/add a new paragraph (start)_1_ecf9943025fd7f7183aac8d86c4e0b6c.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Add/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/Add heading (h1) and code block_1_b19471ad74a7a4bf4b288369edf35407.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Add/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/Add heading and code block_1_b19471ad74a7a4bf4b288369edf35407.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Add/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/add a list (end)_1_8105f57bbca898c1626edd5cd33308ed.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Add/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/add a new paragraph (end)_1_2f4aa2dfa4f6046506c9e133c5d60e76.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Add/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/add a new paragraph (start)_1_7352df4919df344c441fb32b5cdae62b.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Combined/__msw_snapshots__/albert-etalab.chat/neuralmagic/Meta-Llama-3.1-70B-Instruct-FP8 (non-streaming)/add and update paragraph_1_861b7da5f0734c4350466fb42da57dfe.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Combined/__msw_snapshots__/albert-etalab.chat/neuralmagic/Meta-Llama-3.1-70B-Instruct-FP8 (non-streaming)/add paragraph and update selection_1_4821f5b399d9ebc5b564c530740345ea.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Combined/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (non-streaming)/add and update paragraph_1_0d6f9f822d5ba2310e9cb3b5330d1ef0.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Combined/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (non-streaming)/add paragraph and update selection_1_0ca431ee9c56812e10198e60552a536f.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Combined/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (streaming)/add and update paragraph_1_96cb428c4df1b42645632abe5969170c.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Combined/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (streaming)/add paragraph and update selection_1_04f9e76ff73eff953288564e5385dbd4.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Combined/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/add and update paragraph_1_80b906ff9d95e8b88b30c4efd246dc4b.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Combined/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/add paragraph and update selection_1_f5cd402d603bead3d759ebb5485f39c3.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Combined/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/add and update paragraph_1_e0a277e6c9c61c532876788f8c914f42.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Combined/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/add paragraph and update selection_1_fc5837fa3ab53d1a511a8092a926d87d.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Delete/__msw_snapshots__/albert-etalab.chat/neuralmagic/Meta-Llama-3.1-70B-Instruct-FP8 (non-streaming)/delete first block_1_ba835c26344e8e2082ee1f404bacb992.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Delete/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (non-streaming)/delete first block_1_d857ced55373d86233599394800f1a63.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Delete/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (streaming)/delete first block_1_f88ee2c9e0a85200bb5550e4502fc0e5.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Delete/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/delete first block_1_c2ce81529453c6009b31fc3e2d3f8aea.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Delete/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/delete first block_1_90f8de8d41648f556395ecf223aa0e6e.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/albert-etalab.chat/neuralmagic/Meta-Llama-3.1-70B-Instruct-FP8 (non-streaming)/drop mark and link and change text within mark_1_953804d0569e88c225ebe8711ac1d209.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/albert-etalab.chat/neuralmagic/Meta-Llama-3.1-70B-Instruct-FP8 (non-streaming)/drop mark and link_1_9cfdcdc629e0d2c8ba65e699037e007c.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/albert-etalab.chat/neuralmagic/Meta-Llama-3.1-70B-Instruct-FP8 (non-streaming)/modify nested content_1_595e0413e677a7d0e1cf7024e2cdbf11.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/albert-etalab.chat/neuralmagic/Meta-Llama-3.1-70B-Instruct-FP8 (non-streaming)/modify parent content_1_8a40e8e484dd5e6352b3019e81255567.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/albert-etalab.chat/neuralmagic/Meta-Llama-3.1-70B-Instruct-FP8 (non-streaming)/plain source block, add mention_1_03e2c4dfae2ceb146b12fc9a266da98e.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/albert-etalab.chat/neuralmagic/Meta-Llama-3.1-70B-Instruct-FP8 (non-streaming)/standard update_1_f65e23072a2f6be046fc618e0dbf3949.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/albert-etalab.chat/neuralmagic/Meta-Llama-3.1-70B-Instruct-FP8 (non-streaming)/styles + ic in source block, remove mark_1_3e4d4d1ba3f4c2e80cb1d38f35425665.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/albert-etalab.chat/neuralmagic/Meta-Llama-3.1-70B-Instruct-FP8 (non-streaming)/styles + ic in source block, remove mention_1_7c0c0ebbf2e5eb36903b25d3e63f2a96.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/albert-etalab.chat/neuralmagic/Meta-Llama-3.1-70B-Instruct-FP8 (non-streaming)/styles + ic in source block, replace content_1_f8c8827fbecd6977bdb2e5152b493530.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/albert-etalab.chat/neuralmagic/Meta-Llama-3.1-70B-Instruct-FP8 (non-streaming)/styles + ic in source block, update mention prop_1_f4e5d300be72cb5a6c2ef33c32ce7325.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/albert-etalab.chat/neuralmagic/Meta-Llama-3.1-70B-Instruct-FP8 (non-streaming)/styles + ic in source block, update text_1_388a274079ba06bcec0049a35278fc01.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/albert-etalab.chat/neuralmagic/Meta-Llama-3.1-70B-Instruct-FP8 (non-streaming)/styles + ic in target block, add mark (paragraph)_1_c7be52683c9d405365815f334ed1f4db.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/albert-etalab.chat/neuralmagic/Meta-Llama-3.1-70B-Instruct-FP8 (non-streaming)/styles + ic in target block, add mark (word)_1_9bc0da43041ca4b3a188fbdfd9562bae.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/albert-etalab.chat/neuralmagic/Meta-Llama-3.1-70B-Instruct-FP8 (non-streaming)/translate selection_1_6f0c6d98d9a99081b01869826a538c74.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/albert-etalab.chat/neuralmagic/Meta-Llama-3.1-70B-Instruct-FP8 (non-streaming)/turn paragraphs into list_1_122467a8b6979ad2a47b0417976218a9.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/albert-etalab.chat/neuralmagic/Meta-Llama-3.1-70B-Instruct-FP8 (non-streaming)/update block type and content_1_ace9cde890d5c4b2a131f8867e7b5596.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/albert-etalab.chat/neuralmagic/Meta-Llama-3.1-70B-Instruct-FP8 (non-streaming)/update block type_1_d356646093fb778e9c8bce47f7133ef8.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (non-streaming)/drop mark and link and change text within mark_1_6b9ad94993b0b3dc39ee8fab8057b967.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (non-streaming)/drop mark and link_1_bde418f70f7c93522d3cff713cb6e8b2.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (non-streaming)/modify nested content_1_6d6efada9f514cd6b5d479b784960905.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (non-streaming)/modify parent content_1_0b00b5e42872d9f249427436ed23ca40.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (non-streaming)/plain source block, add mention_1_a0f2a68ef2f46c1a3c014966a1d41463.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (non-streaming)/standard update_1_69863686209bcd70d5d432c6c5646ec6.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (non-streaming)/styles + ic in source block, remove mark_1_26a2249225e49ac962f2ffc4d186f048.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (non-streaming)/styles + ic in source block, remove mention_1_8a9dfa091990b0ea68d8b5e600e5ded4.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (non-streaming)/styles + ic in source block, replace content_1_b5da218448fab4a6144aee7b49fe7cfd.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (non-streaming)/styles + ic in source block, update mention prop_1_93cd31cde8f8a9d7bcc6ec163bd82e32.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (non-streaming)/styles + ic in source block, update text_1_98388769d4b6c534a448363e38006369.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (non-streaming)/styles + ic in target block, add mark (paragraph)_1_039df897cf40b1464a3e77597698630f.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (non-streaming)/styles + ic in target block, add mark (word)_1_ecfba97d707a7df556c8be55a94491bd.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (non-streaming)/translate selection_1_674d4ec4b8af2ac528ec90892731f67a.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (non-streaming)/turn paragraphs into list_1_1ec910c96203d1d86b7dcce97e352e91.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (non-streaming)/update block type and content_1_56b6b0d7b3b4585a4ca5598979ccc319.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (non-streaming)/update block type_1_cec06b764f3e6538c0a0baeb04d60587.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (streaming)/drop mark and link and change text within mark_1_60a05ae4a6b034fe6eaafb2b7bfb9638.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (streaming)/drop mark and link_1_df81f4ea9e9cda25c1ef6b1d0de62e6e.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (streaming)/modify nested content_1_c473102de44b6890149109c418f224a7.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (streaming)/modify parent content_1_c8cc1e445e2ea3a61af98fae49719bb2.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (streaming)/plain source block, add mention_1_e6db90ec1ad4b48b7e225a5ef7b7ea08.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (streaming)/standard update_1_afb308d981984d812bf89191d498ddac.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (streaming)/styles + ic in source block, remove mark_1_7d6962e90a2fb300f8efab2620d77389.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (streaming)/styles + ic in source block, remove mention_1_a13d0c4ae92fddfbcbef8c619c092951.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (streaming)/styles + ic in source block, replace content_1_8d4842fb70ad278064faa2c3c6efa73e.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (streaming)/styles + ic in source block, update mention prop_1_70a3e6c68033303f4dce207ea802bba9.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (streaming)/styles + ic in source block, update text_1_3f639531f292bf1edb20bbb65c6ad0e0.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (streaming)/styles + ic in target block, add mark (paragraph)_1_ca41f979b0669b1a9285363b55a53b23.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (streaming)/styles + ic in target block, add mark (word)_1_f3cba828671b95cae0b485ad554942cd.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (streaming)/translate selection_1_54ec8515dd6ab214d8b92c5cf4f09529.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (streaming)/turn paragraphs into list_1_ec7bd4074c354be223256a9d0ab17e64.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (streaming)/update block type and content_1_d0dca6e4fab1bc2c56ba2099e199fb05.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/groq.chat/llama-3.3-70b-versatile (streaming)/update block type_1_18c554c2e45b6f5a1f491396916dcb46.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/drop mark and link and change text within mark_1_feb4bd702156a044fe3c72729f12d83c.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/drop mark and link_1_1e8bbd364a267db768002ed243692a79.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/modify nested content_1_b48a9c33b3a0d37850bd38f4c95b310f.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/modify parent content_1_b8c66592925ae0e551a329b7b2f3b3e2.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/plain source block, add mention_1_196e976a8d5748fd3b667cc39b96cc4d.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/standard update_1_62ccc02aa192415d17e9a1f5c53dffb1.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/styles + ic in source block, remove mark_1_ab9642000a9e81712bf7bf3292769536.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/styles + ic in source block, remove mention_1_aedf9aba96ec8de63204dc0bd079cce0.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/styles + ic in source block, replace content_1_4032f8de849b4d06146cea086f5faee0.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/styles + ic in source block, update mention prop_1_37c8ad3a742c0e37960ee3c688ecff05.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/styles + ic in source block, update text_1_34b0f8d08eec54b64843fe3f13048db5.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/styles + ic in target block, add mark (paragraph)_1_15ae85e2a52e28738a9cd2f4585a5e87.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/styles + ic in target block, add mark (word)_1_49c10b96b8a5342b3afe37277f0b2ec0.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/translate selection_1_83bf8aa261516bf197d1391294bbcb06.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/turn paragraphs into list_1_5aa207db4b8600962363d2352bf0b1c4.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/update block type and content_1_fa30ce9145d3237fa4a0b86a61965fb3.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/update block type_1_e5c648bb981ba9ce20b93054446c721d.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/drop mark and link and change text within mark_1_148394a5f5658c93445adc9e68410296.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/drop mark and link_1_b61d90f1021054f8bcf1258cf9d11fe4.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/modify nested content_1_6dcc3499f6996bd4b16327d079c23b21.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/modify parent content_1_efbe6b2b8f77c628de12b4ae99dc6939.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/plain source block, add mention_1_c3ec555a7988880acc8c448befdc501d.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/standard update_1_7f328ec2574aff0eba83678fedea486a.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/styles + ic in source block, remove mark_1_2246a490805512b4459ec130c3f7b028.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/styles + ic in source block, remove mention_1_089c1b96e5eef0e337d6ae0646f3670d.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/styles + ic in source block, replace content_1_1b70479170637ef990c696b81982a9ff.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/styles + ic in source block, update mention prop_1_8fc18a40e2b4ccc90a9be4a3a826572b.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/styles + ic in source block, update text_1_7187509500683cd511ef79bc79adf45e.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/styles + ic in target block, add mark (paragraph)_1_263f9c25f7a85f762b255a3778136737.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/styles + ic in target block, add mark (word)_1_030b36dcdf89ff60ac373c9797f5caa8.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/translate selection_1_8cfca4c1847085a8a31be1818346738e.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/turn paragraphs into list_1_2f31610c836b996af773c3856634d5c3.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/update block type and content_1_6bc68512d0085273aa59c32b20ff22b9.json +15 -0
- package/src/api/formats/html-blocks/__snapshots__/htmlBlocks.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/update block type_1_171c87db8855dba2d6bbcd06ae45fbb5.json +15 -0
- package/src/api/formats/html-blocks/defaultHTMLPromptBuilder.ts +172 -0
- package/src/api/formats/html-blocks/htmlBlocks.test.ts +132 -0
- package/src/api/formats/html-blocks/htmlBlocks.ts +74 -0
- package/src/api/formats/html-blocks/htmlPromptData.ts +53 -0
- package/src/api/formats/html-blocks/tools/getPartialHTML.test.ts +76 -0
- package/src/api/formats/html-blocks/tools/getPartialHTML.ts +47 -0
- package/src/api/formats/html-blocks/tools/index.ts +112 -0
- package/src/api/formats/html-blocks/tools/rebaseTool.ts +56 -0
- package/src/api/formats/html-blocks/tools/validate.ts +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Add/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/Add heading (h1) and code block_1_4b13d164d4335cc9e201d217c288f3a0.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Add/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/add a list (end)_1_2e1b3d58032f40317616d76bf4fea81c.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Add/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/add a new paragraph (end)_1_4267ae57d44c64aa8b70a89aab67f159.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Add/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/add a new paragraph (start)_1_9d50ec65e996e7a56294ea29bc698367.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Add/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/Add heading (h1) and code block_1_8c55f5cd009ab351956e1b40605abc34.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Add/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/add a list (end)_1_eabec381f0f6973116f9e49dc86810d4.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Add/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/add a new paragraph (end)_1_018cc4d3757dfb60819403609f61a74d.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Add/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/add a new paragraph (start)_1_aeee8d53d8e28d27a45229e9f04bfd02.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Combined/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/add and update paragraph_1_46911433377fbe117de27b4ebef430f5.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Combined/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/add paragraph and update selection_1_caeb25fbcd6743ad509ab18526f09180.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Combined/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/add and update paragraph_1_049c64f71763963c05852957cdcd40bd.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Combined/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/add paragraph and update selection_1_d7907adc86da5742363bfc4422e490e6.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Delete/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/delete first block_1_5515f1ecee9bd348f415319f4a843add.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Delete/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/delete first block_1_7c35b931bd8677fa1920b9e5f8128f4a.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/clear block formatting_1_25bc98ef490234deedb61e16a00d439e.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/drop mark and link and change text within mark_1_c94d4dbaf7e20ccafc3a87f8933afd6a.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/drop mark and link_1_164602425b43f343ccbfb3c2f1509b58.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/modify nested content_1_60470c62411dbe76f9d1ebb97160e62c.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/modify parent content_1_603268f548d2c26969d79e4e170bd524.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/plain source block, add mention_1_dc3adc84764ea9dd8f20a906a4633334.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/standard update_1_6330ddde52ebd48c1e8914a970ad7849.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/styles + ic in source block, remove mark_1_aa396a89a86700c7c1531127331c95b9.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/styles + ic in source block, remove mention_1_e1de4a145c9a98804f8d1fd1ae811da4.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/styles + ic in source block, replace content_1_ce587e62f1783dd0652ffea5d558fda6.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/styles + ic in source block, update mention prop_1_c2fb024d9d7218c5051012323c39fa0d.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/styles + ic in source block, update text_1_e2f62ab4415528c63105a90c35e202f3.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/styles + ic in target block, add mark (paragraph)_1_fb966bb5f366d489cd267e48a7455c72.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/styles + ic in target block, add mark (word)_1_10409eb8f8e256c2c07ee05c2558a2a9.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/translate selection_1_e06a86826098274cfb35046f8f5f67a5.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/turn paragraphs into list_1_c704dd8060467f285e008fcfa10bd3b9.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/update block prop and content_1_be4a66aa5ee43a3fd916166e56052ad0.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/update block prop_1_697c8f64d854e5a824cb735c81d9b7ea.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/update block type and content_1_6b93af6e60c455fec9f8bde5b44e587d.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (non-streaming)/update block type_1_fd7ea265becc91c2e55258021a82a016.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/clear block formatting_1_e9409ed44af8d5b1f3ec7d3b7125386a.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/drop mark and link and change text within mark_1_35579261c0f297cf664524f0c5e08ff1.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/drop mark and link_1_d7303b2c5a80c7a016ba6caa2ae7be04.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/modify nested content_1_55d150e200dccb9c1ac1b325aa8d5a43.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/modify parent content_1_34fba8f0eb2af6cd8d1af416390d9dc4.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/plain source block, add mention_1_ae41cefb5832864a8a9b2e67c04c65b4.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/standard update_1_a7a20bf9510adbbafe889498aa22f0ce.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/styles + ic in source block, remove mark_1_db2880a42dbde80ff9950f502ef1ab8f.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/styles + ic in source block, remove mention_1_48523af48bae8448f99a3d4108bb8a55.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/styles + ic in source block, replace content_1_024c55cd1b3177f362a2d606090ca19a.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/styles + ic in source block, update mention prop_1_549dd0fe54084e4a98588be963db9361.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/styles + ic in source block, update text_1_dbf2fb610e354e0daa60de0cbdd77aba.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/styles + ic in target block, add mark (paragraph)_1_8369c3cd3da93d0e734ed7092c0acf40.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/styles + ic in target block, add mark (word)_1_7033d19147879fada8c8142ee2be4803.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/translate selection_1_3f8ef537734ef9b7d2142c49bde8cbdd.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/turn paragraphs into list_1_f8fd91cad88cfec6db2a906b564d39d3.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/update block prop and content_1_708c779a29da274a24e34cea53755e3b.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/update block prop_1_67d9ce65ebaaf76b1dde8492176299fc.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/update block type and content_1_f9b7241b0cb9e9e098e13a58b47bfa62.json +15 -0
- package/src/api/formats/json/__snapshots__/json.test.ts/Update/__msw_snapshots__/openai.chat/gpt-4o-2024-08-06 (streaming)/update block type_1_dbb1b2b807becf642bb03a71e34b8e21.json +15 -0
- package/src/api/formats/json/defaultJSONPromptBuilder.ts +100 -0
- package/src/api/formats/json/errorHandling.test.ts +94 -0
- package/src/api/formats/json/json.test.ts +127 -0
- package/src/api/formats/json/json.ts +71 -0
- package/src/api/formats/json/jsonPromptData.ts +60 -0
- package/src/api/formats/json/tools/index.ts +62 -0
- package/src/api/formats/json/tools/jsontools.test.ts +122 -0
- package/src/api/formats/json/tools/validate.ts +107 -0
- package/src/api/formats/markdown-blocks/defaultMarkdownPromptBuilder.ts +111 -0
- package/src/api/formats/markdown-blocks/markdownBlocks.test.ts +138 -0
- package/src/api/formats/markdown-blocks/markdownBlocks.ts +71 -0
- package/src/api/formats/markdown-blocks/markdownPromptData.ts +51 -0
- package/src/api/formats/markdown-blocks/tools/index.ts +82 -0
- package/src/api/formats/markdown-blocks/tools/rebaseTool.ts +35 -0
- package/src/api/formats/markdown-blocks/tools/validate.ts +15 -0
- package/src/api/formats/tests/sharedTestCases.ts +151 -0
- package/src/api/formats/tests/validateTestEnvironment.test.ts +81 -0
- package/src/api/index.ts +45 -0
- package/src/api/promptHelpers/addCursorPosition.ts +34 -0
- package/src/api/promptHelpers/convertBlocks.ts +13 -0
- package/src/api/promptHelpers/flattenBlocks.ts +13 -0
- package/src/api/promptHelpers/index.ts +13 -0
- package/src/api/promptHelpers/suffixIds.ts +11 -0
- package/src/api/promptHelpers/trimEmptyBlocks.ts +25 -0
- package/src/api/schema/JSONSchema.ts +8 -0
- package/src/api/schema/__snapshots__/schemaToJSONSchema.test.ts.snap +235 -0
- package/src/api/schema/mergeSchema.ts +121 -0
- package/src/api/schema/schemaToJSONSchema.test.ts +12 -0
- package/src/api/schema/schemaToJSONSchema.ts +306 -0
- package/src/blocknoteAIClient/client.ts +75 -0
- package/src/components/AIMenu/AIMenu.tsx +142 -0
- package/src/components/AIMenu/AIMenuController.tsx +42 -0
- package/src/components/AIMenu/BlockPositioner.tsx +75 -0
- package/src/components/AIMenu/PromptSuggestionMenu.tsx +131 -0
- package/src/components/AIMenu/getDefaultAIMenuItems.tsx +288 -0
- package/src/components/FormattingToolbar/AIToolbarButton.tsx +45 -0
- package/src/components/SuggestionMenu/getAISlashMenuItems.tsx +47 -0
- package/src/i18n/dictionary.ts +11 -0
- package/src/i18n/locales/ar.ts +73 -0
- package/src/i18n/locales/de.ts +73 -0
- package/src/i18n/locales/en.ts +71 -0
- package/src/i18n/locales/es.ts +73 -0
- package/src/i18n/locales/fr.ts +73 -0
- package/src/i18n/locales/hr.ts +73 -0
- package/src/i18n/locales/index.ts +20 -0
- package/src/i18n/locales/is.ts +73 -0
- package/src/i18n/locales/it.ts +73 -0
- package/src/i18n/locales/ja.ts +73 -0
- package/src/i18n/locales/ko.ts +73 -0
- package/src/i18n/locales/nl.ts +73 -0
- package/src/i18n/locales/no.ts +73 -0
- package/src/i18n/locales/pl.ts +73 -0
- package/src/i18n/locales/pt.ts +73 -0
- package/src/i18n/locales/ru.ts +73 -0
- package/src/i18n/locales/sk.ts +73 -0
- package/src/i18n/locales/uk.ts +73 -0
- package/src/i18n/locales/vi.ts +73 -0
- package/src/i18n/locales/zh-tw.ts +73 -0
- package/src/i18n/locales/zh.ts +73 -0
- package/src/i18n/useAIDictionary.ts +8 -0
- package/src/index.ts +15 -0
- package/src/locales.ts +1 -0
- package/src/plugins/AgentCursorPlugin.ts +101 -0
- package/src/prosemirror/__snapshots__/agent.test.ts.snap +702 -0
- package/src/prosemirror/__snapshots__/changeset.test.ts.snap +1047 -0
- package/src/prosemirror/__snapshots__/rebaseTool.test.ts.snap +154 -0
- package/src/prosemirror/agent.test.ts +271 -0
- package/src/prosemirror/agent.ts +311 -0
- package/src/prosemirror/changeset.test.ts +95 -0
- package/src/prosemirror/changeset.ts +340 -0
- package/src/prosemirror/fragmentUtil.test.ts +85 -0
- package/src/prosemirror/fragmentUtil.ts +20 -0
- package/src/prosemirror/rebaseTool.test.ts +96 -0
- package/src/prosemirror/rebaseTool.ts +79 -0
- package/src/streamTool/README.md +12 -0
- package/src/streamTool/asTool.ts +44 -0
- package/src/streamTool/callLLMWithStreamTools.ts +352 -0
- package/src/streamTool/filterNewOrUpdatedOperations.test.ts +158 -0
- package/src/streamTool/filterNewOrUpdatedOperations.ts +64 -0
- package/src/streamTool/filterValidOperations.test.ts +104 -0
- package/src/streamTool/filterValidOperations.ts +47 -0
- package/src/streamTool/jsonSchema.ts +78 -0
- package/src/streamTool/preprocess.test.ts +207 -0
- package/src/streamTool/preprocess.ts +73 -0
- package/src/streamTool/streamTool.ts +94 -0
- package/src/streamTool/toValidatedOperations.test.ts +98 -0
- package/src/streamTool/toValidatedOperations.ts +49 -0
- package/src/style.css +33 -0
- package/src/testUtil/cases/addOperationTestCases.ts +89 -0
- package/src/testUtil/cases/combinedOperationsTestCases.ts +59 -0
- package/src/testUtil/cases/deleteOperationTestCases.ts +16 -0
- package/src/testUtil/cases/editors/blockFormatting.ts +33 -0
- package/src/testUtil/cases/editors/formattingAndMentions.ts +83 -0
- package/src/testUtil/cases/editors/simpleEditor.ts +56 -0
- package/src/testUtil/cases/editors/tables.ts +49 -0
- package/src/testUtil/cases/index.ts +110 -0
- package/src/testUtil/cases/schemas/mention.ts +34 -0
- package/src/testUtil/cases/updateOperationTestCases.ts +832 -0
- package/src/testUtil/suggestChangesTestUtil.ts +13 -0
- package/src/testUtil/testAIModels.ts +30 -0
- package/src/util/emptyBlock.ts +8 -0
- package/src/util/stream.ts +66 -0
- package/src/util/trimArray.ts +26 -0
- package/types/src/AIExtension.d.ts +127 -0
- package/types/src/api/LLMRequest.d.ts +116 -0
- package/types/src/api/LLMResponse.d.ts +51 -0
- package/types/src/api/formats/PromptBuilder.d.ts +31 -0
- package/types/src/api/formats/base-tools/createAddBlocksTool.d.ts +60 -0
- package/types/src/api/formats/base-tools/createUpdateBlockTool.d.ts +63 -0
- package/types/src/api/formats/base-tools/delete.d.ts +13 -0
- package/types/src/api/formats/base-tools/util/validateBlockArray.d.ts +3 -0
- package/types/src/api/formats/html-blocks/defaultHTMLPromptBuilder.d.ts +2 -0
- package/types/src/api/formats/html-blocks/htmlBlocks.d.ts +33 -0
- package/types/src/api/formats/html-blocks/htmlBlocks.test.d.ts +1 -0
- package/types/src/api/formats/html-blocks/htmlPromptData.d.ts +22 -0
- package/types/src/api/formats/html-blocks/tools/getPartialHTML.d.ts +14 -0
- package/types/src/api/formats/html-blocks/tools/getPartialHTML.test.d.ts +1 -0
- package/types/src/api/formats/html-blocks/tools/index.d.ts +23 -0
- package/types/src/api/formats/html-blocks/tools/rebaseTool.d.ts +7 -0
- package/types/src/api/formats/html-blocks/tools/validate.d.ts +2 -0
- package/types/src/api/formats/json/defaultJSONPromptBuilder.d.ts +2 -0
- package/types/src/api/formats/json/errorHandling.test.d.ts +1 -0
- package/types/src/api/formats/json/json.d.ts +33 -0
- package/types/src/api/formats/json/json.test.d.ts +1 -0
- package/types/src/api/formats/json/jsonPromptData.d.ts +34 -0
- package/types/src/api/formats/json/tools/index.d.ts +23 -0
- package/types/src/api/formats/json/tools/jsontools.test.d.ts +1 -0
- package/types/src/api/formats/json/tools/validate.d.ts +3 -0
- package/types/src/api/formats/markdown-blocks/defaultMarkdownPromptBuilder.d.ts +2 -0
- package/types/src/api/formats/markdown-blocks/markdownBlocks.d.ts +33 -0
- package/types/src/api/formats/markdown-blocks/markdownBlocks.test.d.ts +1 -0
- package/types/src/api/formats/markdown-blocks/markdownPromptData.d.ts +22 -0
- package/types/src/api/formats/markdown-blocks/tools/index.d.ts +23 -0
- package/types/src/api/formats/markdown-blocks/tools/rebaseTool.d.ts +8 -0
- package/types/src/api/formats/markdown-blocks/tools/validate.d.ts +2 -0
- package/types/src/api/formats/tests/sharedTestCases.d.ts +10 -0
- package/types/src/api/formats/tests/validateTestEnvironment.test.d.ts +1 -0
- package/types/src/api/index.d.ts +75 -0
- package/types/src/api/promptHelpers/addCursorPosition.d.ts +12 -0
- package/types/src/api/promptHelpers/convertBlocks.d.ts +5 -0
- package/types/src/api/promptHelpers/flattenBlocks.d.ts +2 -0
- package/types/src/api/promptHelpers/index.d.ts +12 -0
- package/types/src/api/promptHelpers/suffixIds.d.ts +1 -0
- package/types/src/api/promptHelpers/trimEmptyBlocks.d.ts +5 -0
- package/types/src/api/schema/JSONSchema.d.ts +8 -0
- package/types/src/api/schema/mergeSchema.d.ts +7 -0
- package/types/src/api/schema/schemaToJSONSchema.d.ts +80 -0
- package/types/src/api/schema/schemaToJSONSchema.test.d.ts +1 -0
- package/types/src/blocknoteAIClient/client.d.ts +38 -0
- package/types/src/components/AIMenu/AIMenu.d.ts +7 -0
- package/types/src/components/AIMenu/AIMenuController.d.ts +5 -0
- package/types/src/components/AIMenu/BlockPositioner.d.ts +7 -0
- package/types/src/components/AIMenu/PromptSuggestionMenu.d.ts +13 -0
- package/types/src/components/AIMenu/getDefaultAIMenuItems.d.ts +7 -0
- package/types/src/components/FormattingToolbar/AIToolbarButton.d.ts +1 -0
- package/types/src/components/SuggestionMenu/getAISlashMenuItems.d.ts +6 -0
- package/types/src/i18n/dictionary.d.ts +4 -0
- package/types/src/i18n/locales/ar.d.ts +2 -0
- package/types/src/i18n/locales/de.d.ts +2 -0
- package/types/src/i18n/locales/en.d.ts +77 -0
- package/types/src/i18n/locales/es.d.ts +2 -0
- package/types/src/i18n/locales/fr.d.ts +2 -0
- package/types/src/i18n/locales/hr.d.ts +2 -0
- package/types/src/i18n/locales/index.d.ts +20 -0
- package/types/src/i18n/locales/is.d.ts +2 -0
- package/types/src/i18n/locales/it.d.ts +2 -0
- package/types/src/i18n/locales/ja.d.ts +2 -0
- package/types/src/i18n/locales/ko.d.ts +2 -0
- package/types/src/i18n/locales/nl.d.ts +2 -0
- package/types/src/i18n/locales/no.d.ts +2 -0
- package/types/src/i18n/locales/pl.d.ts +2 -0
- package/types/src/i18n/locales/pt.d.ts +2 -0
- package/types/src/i18n/locales/ru.d.ts +2 -0
- package/types/src/i18n/locales/sk.d.ts +2 -0
- package/types/src/i18n/locales/uk.d.ts +2 -0
- package/types/src/i18n/locales/vi.d.ts +2 -0
- package/types/src/i18n/locales/zh-tw.d.ts +2 -0
- package/types/src/i18n/locales/zh.d.ts +2 -0
- package/types/src/i18n/useAIDictionary.d.ts +77 -0
- package/types/src/index.d.ts +12 -0
- package/types/src/locales.d.ts +1 -0
- package/types/src/plugins/AgentCursorPlugin.d.ts +15 -0
- package/types/src/prosemirror/agent.d.ts +20 -0
- package/types/src/prosemirror/agent.test.d.ts +1 -0
- package/types/src/prosemirror/changeset.d.ts +19 -0
- package/types/src/prosemirror/changeset.test.d.ts +1 -0
- package/types/src/prosemirror/fragmentUtil.d.ts +5 -0
- package/types/src/prosemirror/fragmentUtil.test.d.ts +1 -0
- package/types/src/prosemirror/rebaseTool.d.ts +36 -0
- package/types/src/prosemirror/rebaseTool.test.d.ts +1 -0
- package/types/src/streamTool/asTool.d.ts +15 -0
- package/types/src/streamTool/callLLMWithStreamTools.d.ts +74 -0
- package/types/src/streamTool/filterNewOrUpdatedOperations.d.ts +20 -0
- package/types/src/streamTool/filterNewOrUpdatedOperations.test.d.ts +1 -0
- package/types/src/streamTool/filterValidOperations.d.ts +21 -0
- package/types/src/streamTool/filterValidOperations.test.d.ts +1 -0
- package/types/src/streamTool/jsonSchema.d.ts +22 -0
- package/types/src/streamTool/preprocess.d.ts +22 -0
- package/types/src/streamTool/preprocess.test.d.ts +1 -0
- package/types/src/streamTool/streamTool.d.ts +80 -0
- package/types/src/streamTool/toValidatedOperations.d.ts +17 -0
- package/types/src/streamTool/toValidatedOperations.test.d.ts +1 -0
- package/types/src/testUtil/cases/addOperationTestCases.d.ts +2 -0
- package/types/src/testUtil/cases/combinedOperationsTestCases.d.ts +2 -0
- package/types/src/testUtil/cases/deleteOperationTestCases.d.ts +2 -0
- package/types/src/testUtil/cases/editors/blockFormatting.d.ts +553 -0
- package/types/src/testUtil/cases/editors/formattingAndMentions.d.ts +553 -0
- package/types/src/testUtil/cases/editors/simpleEditor.d.ts +1105 -0
- package/types/src/testUtil/cases/editors/tables.d.ts +553 -0
- package/types/src/testUtil/cases/index.d.ts +45 -0
- package/types/src/testUtil/cases/schemas/mention.d.ts +562 -0
- package/types/src/testUtil/cases/updateOperationTestCases.d.ts +6 -0
- package/types/src/testUtil/suggestChangesTestUtil.d.ts +3 -0
- package/types/src/testUtil/testAIModels.d.ts +5 -0
- package/types/src/util/emptyBlock.d.ts +2 -0
- package/types/src/util/stream.d.ts +16 -0
- package/types/src/util/trimArray.d.ts +1 -0
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BlockNoteEditor,
|
|
3
|
+
BlockNoteExtension,
|
|
4
|
+
UnreachableCaseError,
|
|
5
|
+
} from "@blocknote/core";
|
|
6
|
+
import {
|
|
7
|
+
applySuggestions,
|
|
8
|
+
revertSuggestions,
|
|
9
|
+
suggestChanges,
|
|
10
|
+
} from "@blocknote/prosemirror-suggest-changes";
|
|
11
|
+
import { APICallError, LanguageModel, RetryError } from "ai";
|
|
12
|
+
import { Plugin, PluginKey } from "prosemirror-state";
|
|
13
|
+
import { fixTablesKey } from "prosemirror-tables";
|
|
14
|
+
import { createStore, StoreApi } from "zustand/vanilla";
|
|
15
|
+
import { doLLMRequest, LLMRequestOptions } from "./api/LLMRequest.js";
|
|
16
|
+
import { LLMResponse } from "./api/LLMResponse.js";
|
|
17
|
+
import { PromptBuilder } from "./api/formats/PromptBuilder.js";
|
|
18
|
+
import { LLMFormat, llmFormats } from "./api/index.js";
|
|
19
|
+
import { createAgentCursorPlugin } from "./plugins/AgentCursorPlugin.js";
|
|
20
|
+
import { Fragment, Slice } from "prosemirror-model";
|
|
21
|
+
|
|
22
|
+
type MakeOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
|
|
23
|
+
|
|
24
|
+
type ReadonlyStoreApi<T> = Pick<
|
|
25
|
+
StoreApi<T>,
|
|
26
|
+
"getState" | "getInitialState" | "subscribe"
|
|
27
|
+
>;
|
|
28
|
+
|
|
29
|
+
type AIPluginState = {
|
|
30
|
+
// zustand design considerations:
|
|
31
|
+
// - moved this to a nested object to have better typescript typing
|
|
32
|
+
// - if we'd do this without a nested object, then we could easily set "wrong" values,
|
|
33
|
+
// because "setState" takes a partial object (unless the second parameter "replace" = true),
|
|
34
|
+
// and thus we'd lose typescript's typing help
|
|
35
|
+
|
|
36
|
+
aiMenuState:
|
|
37
|
+
| ({
|
|
38
|
+
/**
|
|
39
|
+
* The ID of the block that the AI menu is opened at.
|
|
40
|
+
* This changes as the AI is making changes to the document
|
|
41
|
+
*/
|
|
42
|
+
blockId: string;
|
|
43
|
+
} & (
|
|
44
|
+
| {
|
|
45
|
+
status: "error";
|
|
46
|
+
error: any;
|
|
47
|
+
}
|
|
48
|
+
| {
|
|
49
|
+
status: "user-input" | "thinking" | "ai-writing" | "user-reviewing";
|
|
50
|
+
}
|
|
51
|
+
))
|
|
52
|
+
| "closed";
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The previous response from the LLM, used for multi-step LLM calls
|
|
56
|
+
*/
|
|
57
|
+
llmResponse?: LLMResponse;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* configuration options for LLM calls that are shared across all calls by default
|
|
62
|
+
*/
|
|
63
|
+
type GlobalLLMRequestOptions = {
|
|
64
|
+
/**
|
|
65
|
+
* The default language model to use for LLM calls
|
|
66
|
+
*/
|
|
67
|
+
model: LanguageModel;
|
|
68
|
+
/**
|
|
69
|
+
* Whether to stream the LLM response
|
|
70
|
+
* @default true
|
|
71
|
+
*/
|
|
72
|
+
stream?: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* The default data format to use for LLM calls
|
|
75
|
+
* html format is recommended, the other formats are experimental
|
|
76
|
+
* @default llmFormats.html
|
|
77
|
+
*/
|
|
78
|
+
dataFormat?: LLMFormat;
|
|
79
|
+
/**
|
|
80
|
+
* A function that can be used to customize the prompt sent to the LLM
|
|
81
|
+
* @default the default prompt builder for the selected {@link dataFormat}
|
|
82
|
+
*/
|
|
83
|
+
promptBuilder?: PromptBuilder;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const PLUGIN_KEY = new PluginKey(`blocknote-ai-plugin`);
|
|
87
|
+
|
|
88
|
+
export class AIExtension extends BlockNoteExtension {
|
|
89
|
+
private previousRequestOptions: LLMRequestOptions | undefined;
|
|
90
|
+
|
|
91
|
+
public static name(): string {
|
|
92
|
+
return "ai";
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// internal store including setters
|
|
96
|
+
private readonly _store = createStore<AIPluginState>()((_set) => ({
|
|
97
|
+
aiMenuState: "closed",
|
|
98
|
+
}));
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Returns a read-only zustand store with the state of the AI Extension
|
|
102
|
+
*/
|
|
103
|
+
public get store() {
|
|
104
|
+
// externally, don't expose setters (if we want to do so, expose `set` methods seperately)
|
|
105
|
+
return this._store as ReadonlyStoreApi<AIPluginState>;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Returns a zustand store with the global configuration of the AI Extension.
|
|
110
|
+
* These options are used by default across all LLM calls when calling {@link doLLMRequest}
|
|
111
|
+
*/
|
|
112
|
+
public readonly options: ReturnType<
|
|
113
|
+
ReturnType<
|
|
114
|
+
typeof createStore<
|
|
115
|
+
MakeOptional<Required<GlobalLLMRequestOptions>, "promptBuilder">
|
|
116
|
+
>
|
|
117
|
+
>
|
|
118
|
+
>;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* @internal use `createAIExtension` instead
|
|
122
|
+
*/
|
|
123
|
+
constructor(
|
|
124
|
+
public readonly editor: BlockNoteEditor<any, any, any>,
|
|
125
|
+
options: GlobalLLMRequestOptions & {
|
|
126
|
+
/**
|
|
127
|
+
* The name and color of the agent cursor
|
|
128
|
+
*
|
|
129
|
+
* @default { name: "AI", color: "#8bc6ff" }
|
|
130
|
+
*/
|
|
131
|
+
agentCursor?: { name: string; color: string };
|
|
132
|
+
},
|
|
133
|
+
) {
|
|
134
|
+
super();
|
|
135
|
+
|
|
136
|
+
this.options = createStore<
|
|
137
|
+
MakeOptional<Required<GlobalLLMRequestOptions>, "promptBuilder">
|
|
138
|
+
>()((_set) => ({
|
|
139
|
+
dataFormat: llmFormats.html,
|
|
140
|
+
stream: true,
|
|
141
|
+
...options,
|
|
142
|
+
}));
|
|
143
|
+
|
|
144
|
+
this.addProsemirrorPlugin(
|
|
145
|
+
new Plugin({
|
|
146
|
+
key: PLUGIN_KEY,
|
|
147
|
+
filterTransaction: (tr) => {
|
|
148
|
+
const menuState = this.store.getState().aiMenuState;
|
|
149
|
+
|
|
150
|
+
if (menuState !== "closed" && menuState.status === "ai-writing") {
|
|
151
|
+
if (tr.getMeta(fixTablesKey)?.fixTables) {
|
|
152
|
+
// the fixtables plugin causes the steps between of the AI Agent to become invalid
|
|
153
|
+
// so we need to prevent it from running
|
|
154
|
+
// (we might need to filter out other / or maybe any transactions during the writing phase)
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return true;
|
|
159
|
+
},
|
|
160
|
+
}),
|
|
161
|
+
);
|
|
162
|
+
this.addProsemirrorPlugin(suggestChanges());
|
|
163
|
+
this.addProsemirrorPlugin(
|
|
164
|
+
createAgentCursorPlugin(
|
|
165
|
+
options.agentCursor || { name: "AI", color: "#8bc6ff" },
|
|
166
|
+
),
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Open the AI menu at a specific block
|
|
172
|
+
*/
|
|
173
|
+
public openAIMenuAtBlock(blockID: string) {
|
|
174
|
+
this.editor.setForceSelectionVisible(true);
|
|
175
|
+
this.editor.isEditable = false;
|
|
176
|
+
this._store.setState({
|
|
177
|
+
aiMenuState: {
|
|
178
|
+
blockId: blockID,
|
|
179
|
+
status: "user-input",
|
|
180
|
+
},
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Close the AI menu
|
|
186
|
+
*/
|
|
187
|
+
public closeAIMenu() {
|
|
188
|
+
this.previousRequestOptions = undefined;
|
|
189
|
+
this._store.setState({
|
|
190
|
+
aiMenuState: "closed",
|
|
191
|
+
llmResponse: undefined,
|
|
192
|
+
});
|
|
193
|
+
this.editor.setForceSelectionVisible(false);
|
|
194
|
+
this.editor.isEditable = true;
|
|
195
|
+
this.editor.focus();
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Accept the changes made by the LLM
|
|
200
|
+
*/
|
|
201
|
+
public acceptChanges() {
|
|
202
|
+
// This is slightly convoluted, to try to maintain the undo history as much as possible
|
|
203
|
+
// The idea is that the LLM call has appended a number of updates to the document, moving the document from state `A` to state `C`
|
|
204
|
+
// But we want the undo history to skip all of the intermediate states and go straight from `C` to `A`
|
|
205
|
+
// To do this, we capture the document state `C` (post-LLM call), and then reject the suggestions to recover the original document state `A`
|
|
206
|
+
// Then we create an intermediate state `B` that captures the diff between `A` and `C`
|
|
207
|
+
// Then we apply the suggestions to `B` to get the final state `C`
|
|
208
|
+
// This causes the undo history to skip `B` and go straight from `C` back to `A`
|
|
209
|
+
|
|
210
|
+
// Capture the document state `C'` (post-LLM call with all suggestions still in the document)
|
|
211
|
+
const markedUpDocument = this.editor.prosemirrorState.doc;
|
|
212
|
+
|
|
213
|
+
// revert the suggestions to get back to the original document state `A`
|
|
214
|
+
this.editor.exec((state, dispatch) => {
|
|
215
|
+
return revertSuggestions(state, (tr) => {
|
|
216
|
+
dispatch?.(tr.setMeta("addToHistory", false));
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
// Create an intermediate state `B` that captures the diff between the original document and the marked up document
|
|
221
|
+
this.editor.exec((state, dispatch) => {
|
|
222
|
+
const tr = state.tr;
|
|
223
|
+
tr.replace(
|
|
224
|
+
0,
|
|
225
|
+
tr.doc.content.size,
|
|
226
|
+
new Slice(Fragment.from(markedUpDocument), 0, 0),
|
|
227
|
+
);
|
|
228
|
+
const nextState = state.apply(tr);
|
|
229
|
+
// Apply the suggestions to the intermediate state `B` to get the final state `C`
|
|
230
|
+
return applySuggestions(nextState, (resultTr) => {
|
|
231
|
+
dispatch?.(
|
|
232
|
+
tr.replace(
|
|
233
|
+
0,
|
|
234
|
+
tr.doc.content.size,
|
|
235
|
+
new Slice(Fragment.from(resultTr.doc), 0, 0),
|
|
236
|
+
),
|
|
237
|
+
);
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
// If in collaboration mode, merge the changes back into the original yDoc
|
|
242
|
+
this.editor.forkYDocPlugin?.merge({ keepChanges: true });
|
|
243
|
+
|
|
244
|
+
this.closeAIMenu();
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Reject the changes made by the LLM
|
|
249
|
+
*/
|
|
250
|
+
public rejectChanges() {
|
|
251
|
+
// Revert the suggestions to get back to the original document
|
|
252
|
+
this.editor.exec((state, dispatch) => {
|
|
253
|
+
return revertSuggestions(state, (tr) => {
|
|
254
|
+
// Do so without adding to history (so the last undo step is just prior to the LLM call)
|
|
255
|
+
dispatch?.(tr.setMeta("addToHistory", false));
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
// If in collaboration mode, discard the changes and revert to the original yDoc
|
|
260
|
+
this.editor.forkYDocPlugin?.merge({ keepChanges: false });
|
|
261
|
+
this.closeAIMenu();
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Retry the previous LLM call.
|
|
266
|
+
*
|
|
267
|
+
* Only valid if the current status is "error"
|
|
268
|
+
*/
|
|
269
|
+
public async retry() {
|
|
270
|
+
const state = this.store.getState().aiMenuState;
|
|
271
|
+
if (
|
|
272
|
+
state === "closed" ||
|
|
273
|
+
state.status !== "error" ||
|
|
274
|
+
!this.previousRequestOptions
|
|
275
|
+
) {
|
|
276
|
+
throw new Error("retry() is only valid when a previous response failed");
|
|
277
|
+
}
|
|
278
|
+
if (
|
|
279
|
+
state.error instanceof APICallError ||
|
|
280
|
+
state.error instanceof RetryError
|
|
281
|
+
) {
|
|
282
|
+
// retry the previous call as-is, as there was a network error
|
|
283
|
+
return this.callLLM(this.previousRequestOptions);
|
|
284
|
+
} else {
|
|
285
|
+
// an error occurred while parsing / executing the previous LLM call
|
|
286
|
+
// give the LLM a chance to fix the error
|
|
287
|
+
// (Possible improvement: maybe this should be a system prompt instead of the userPrompt)
|
|
288
|
+
const errorMessage =
|
|
289
|
+
state.error instanceof Error
|
|
290
|
+
? state.error.message
|
|
291
|
+
: String(state.error);
|
|
292
|
+
|
|
293
|
+
return this.callLLM({
|
|
294
|
+
userPrompt: `An error occured: ${errorMessage}
|
|
295
|
+
Please retry the previous user request.`,
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Update the status of a call to an LLM
|
|
302
|
+
*
|
|
303
|
+
* @warning This method should usually only be used for advanced use-cases
|
|
304
|
+
* if you want to implement how an LLM call is executed. Usually, you should
|
|
305
|
+
* use {@link doLLMRequest} instead which will handle the status updates for you.
|
|
306
|
+
*/
|
|
307
|
+
public setAIResponseStatus(
|
|
308
|
+
status:
|
|
309
|
+
| "user-input"
|
|
310
|
+
| "thinking"
|
|
311
|
+
| "ai-writing"
|
|
312
|
+
| "user-reviewing"
|
|
313
|
+
| {
|
|
314
|
+
status: "error";
|
|
315
|
+
error: any;
|
|
316
|
+
},
|
|
317
|
+
) {
|
|
318
|
+
const aiMenuState = this.store.getState().aiMenuState;
|
|
319
|
+
if (aiMenuState === "closed") {
|
|
320
|
+
return; // TODO: log error?
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
if (status === "ai-writing") {
|
|
324
|
+
this.editor.setForceSelectionVisible(false);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
if (typeof status === "object") {
|
|
328
|
+
if (status.status !== "error") {
|
|
329
|
+
throw new UnreachableCaseError(status.status);
|
|
330
|
+
}
|
|
331
|
+
this._store.setState({
|
|
332
|
+
aiMenuState: {
|
|
333
|
+
status: status.status,
|
|
334
|
+
error: status.error,
|
|
335
|
+
blockId: aiMenuState.blockId,
|
|
336
|
+
},
|
|
337
|
+
});
|
|
338
|
+
} else {
|
|
339
|
+
this._store.setState({
|
|
340
|
+
aiMenuState: {
|
|
341
|
+
status: status,
|
|
342
|
+
blockId: aiMenuState.blockId,
|
|
343
|
+
},
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Execute a call to an LLM and apply the result to the editor
|
|
350
|
+
*/
|
|
351
|
+
public async callLLM(opts: MakeOptional<LLMRequestOptions, "model">) {
|
|
352
|
+
this.setAIResponseStatus("thinking");
|
|
353
|
+
this.editor.forkYDocPlugin?.fork();
|
|
354
|
+
|
|
355
|
+
let ret: LLMResponse | undefined;
|
|
356
|
+
try {
|
|
357
|
+
const requestOptions = {
|
|
358
|
+
...this.options.getState(),
|
|
359
|
+
...opts,
|
|
360
|
+
previousResponse: this.store.getState().llmResponse,
|
|
361
|
+
};
|
|
362
|
+
this.previousRequestOptions = requestOptions;
|
|
363
|
+
|
|
364
|
+
ret = await doLLMRequest(this.editor, {
|
|
365
|
+
...requestOptions,
|
|
366
|
+
onStart: () => {
|
|
367
|
+
this.setAIResponseStatus("ai-writing");
|
|
368
|
+
opts.onStart?.();
|
|
369
|
+
},
|
|
370
|
+
onBlockUpdate: (blockId: string) => {
|
|
371
|
+
// NOTE: does this setState with an anon object trigger unnecessary re-renders?
|
|
372
|
+
this._store.setState({
|
|
373
|
+
aiMenuState: {
|
|
374
|
+
blockId,
|
|
375
|
+
status: "ai-writing",
|
|
376
|
+
},
|
|
377
|
+
});
|
|
378
|
+
opts.onBlockUpdate?.(blockId);
|
|
379
|
+
},
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
this._store.setState({
|
|
383
|
+
llmResponse: ret,
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
await ret.execute();
|
|
387
|
+
|
|
388
|
+
this.setAIResponseStatus("user-reviewing");
|
|
389
|
+
} catch (e) {
|
|
390
|
+
// TODO in error state, should we discard the forked document?
|
|
391
|
+
|
|
392
|
+
this.setAIResponseStatus({
|
|
393
|
+
status: "error",
|
|
394
|
+
error: e,
|
|
395
|
+
});
|
|
396
|
+
// eslint-disable-next-line no-console
|
|
397
|
+
console.warn("Error calling LLM", e);
|
|
398
|
+
}
|
|
399
|
+
return ret;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Create a new AIExtension instance, this can be passed to the BlockNote editor via the `extensions` option
|
|
405
|
+
*/
|
|
406
|
+
export function createAIExtension(
|
|
407
|
+
options: ConstructorParameters<typeof AIExtension>[1],
|
|
408
|
+
) {
|
|
409
|
+
return (editor: BlockNoteEditor<any, any, any>) => {
|
|
410
|
+
return new AIExtension(editor, options);
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* Return the AIExtension instance from the editor
|
|
416
|
+
*/
|
|
417
|
+
export function getAIExtension(editor: BlockNoteEditor<any, any, any>) {
|
|
418
|
+
return editor.extension(AIExtension);
|
|
419
|
+
}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { BlockNoteEditor } from "@blocknote/core";
|
|
2
|
+
import { CoreMessage, generateObject, LanguageModelV1, streamObject } from "ai";
|
|
3
|
+
import {
|
|
4
|
+
generateOperations,
|
|
5
|
+
streamOperations,
|
|
6
|
+
} from "../streamTool/callLLMWithStreamTools.js";
|
|
7
|
+
import { isEmptyParagraph } from "../util/emptyBlock.js";
|
|
8
|
+
import { LLMResponse } from "./LLMResponse.js";
|
|
9
|
+
import type { PromptBuilder } from "./formats/PromptBuilder.js";
|
|
10
|
+
import { htmlBlockLLMFormat } from "./formats/html-blocks/htmlBlocks.js";
|
|
11
|
+
import { LLMFormat } from "./index.js";
|
|
12
|
+
|
|
13
|
+
export type LLMRequestOptions = {
|
|
14
|
+
/**
|
|
15
|
+
* The language model to use for the LLM call (AI SDK)
|
|
16
|
+
*
|
|
17
|
+
* (when invoking `callLLM` via the `AIExtension` this will default to the
|
|
18
|
+
* model set in the `AIExtension` options)
|
|
19
|
+
*/
|
|
20
|
+
model: LanguageModelV1;
|
|
21
|
+
/**
|
|
22
|
+
* The user prompt to use for the LLM call
|
|
23
|
+
*/
|
|
24
|
+
userPrompt: string;
|
|
25
|
+
/**
|
|
26
|
+
* Previous response from the LLM, used for multi-step LLM calls
|
|
27
|
+
*
|
|
28
|
+
* (populated automatically when invoking `callLLM` via the `AIExtension` class)
|
|
29
|
+
*/
|
|
30
|
+
previousResponse?: LLMResponse;
|
|
31
|
+
/**
|
|
32
|
+
* The default data format to use for LLM calls
|
|
33
|
+
* "html" is recommended, the other formats are experimental
|
|
34
|
+
* @default html format (`llm.html`)
|
|
35
|
+
*/
|
|
36
|
+
dataFormat?: LLMFormat;
|
|
37
|
+
/**
|
|
38
|
+
* The `PromptBuilder` to use for the LLM call
|
|
39
|
+
*
|
|
40
|
+
* (A PromptBuilder is a function that takes a BlockNoteEditor and details about the user's prompt
|
|
41
|
+
* and turns it into an AI SDK `CoreMessage` array to be passed to the LLM)
|
|
42
|
+
*
|
|
43
|
+
* @default provided by the format (e.g. `llm.html.defaultPromptBuilder`)
|
|
44
|
+
*/
|
|
45
|
+
promptBuilder?: PromptBuilder;
|
|
46
|
+
/**
|
|
47
|
+
* The maximum number of retries for the LLM call
|
|
48
|
+
*
|
|
49
|
+
* @default 2
|
|
50
|
+
*/
|
|
51
|
+
maxRetries?: number;
|
|
52
|
+
/**
|
|
53
|
+
* Whether to use the editor selection for the LLM call
|
|
54
|
+
*
|
|
55
|
+
* @default true
|
|
56
|
+
*/
|
|
57
|
+
useSelection?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Defines whether the LLM can add, update, or delete blocks
|
|
60
|
+
*
|
|
61
|
+
* @default { add: true, update: true, delete: true }
|
|
62
|
+
*/
|
|
63
|
+
defaultStreamTools?: {
|
|
64
|
+
/** Enable the add tool (default: true) */
|
|
65
|
+
add?: boolean;
|
|
66
|
+
/** Enable the update tool (default: true) */
|
|
67
|
+
update?: boolean;
|
|
68
|
+
/** Enable the delete tool (default: true) */
|
|
69
|
+
delete?: boolean;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Whether to stream the LLM response or not
|
|
73
|
+
*
|
|
74
|
+
* When streaming, we use the AI SDK `streamObject` function,
|
|
75
|
+
* otherwise, we use the AI SDK `generateObject` function.
|
|
76
|
+
*
|
|
77
|
+
* @default true
|
|
78
|
+
*/
|
|
79
|
+
stream?: boolean;
|
|
80
|
+
/**
|
|
81
|
+
* If the user's cursor is in an empty paragraph, automatically delete it when the AI
|
|
82
|
+
* is starting to write.
|
|
83
|
+
*
|
|
84
|
+
* (This is used when a user starts typing `/ai` in an empty block)
|
|
85
|
+
*
|
|
86
|
+
* @default true
|
|
87
|
+
*/
|
|
88
|
+
deleteEmptyCursorBlock?: boolean;
|
|
89
|
+
/**
|
|
90
|
+
* Callback when a specific block is updated by the LLM
|
|
91
|
+
*
|
|
92
|
+
* (used by `AIExtension` to update the `AIMenu` position)
|
|
93
|
+
*/
|
|
94
|
+
onBlockUpdate?: (blockId: string) => void;
|
|
95
|
+
/**
|
|
96
|
+
* Callback when the AI Agent starts writing
|
|
97
|
+
*/
|
|
98
|
+
onStart?: () => void;
|
|
99
|
+
/**
|
|
100
|
+
* Whether to add delays between text update operations, to make the AI simulate a human typing
|
|
101
|
+
*
|
|
102
|
+
* @default true
|
|
103
|
+
*/
|
|
104
|
+
withDelays?: boolean;
|
|
105
|
+
/**
|
|
106
|
+
* Additional options to pass to the AI SDK `generateObject` function
|
|
107
|
+
* (only used when `stream` is `false`)
|
|
108
|
+
*/
|
|
109
|
+
_generateObjectOptions?: Partial<Parameters<typeof generateObject<any>>[0]>;
|
|
110
|
+
/**
|
|
111
|
+
* Additional options to pass to the AI SDK `streamObject` function
|
|
112
|
+
* (only used when `stream` is `true`)
|
|
113
|
+
*/
|
|
114
|
+
_streamObjectOptions?: Partial<Parameters<typeof streamObject<any>>[0]>;
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Execute an LLM call
|
|
119
|
+
*
|
|
120
|
+
* @param editor - The BlockNoteEditor the LLM should operate on
|
|
121
|
+
* @param opts - The options for the LLM call (@link {CallLLMOptions})
|
|
122
|
+
* @returns A `LLMResponse` object containing the LLM response which can be applied to the editor
|
|
123
|
+
*/
|
|
124
|
+
export async function doLLMRequest(
|
|
125
|
+
editor: BlockNoteEditor<any, any, any>,
|
|
126
|
+
opts: LLMRequestOptions,
|
|
127
|
+
): Promise<LLMResponse> {
|
|
128
|
+
const {
|
|
129
|
+
userPrompt,
|
|
130
|
+
useSelection,
|
|
131
|
+
deleteEmptyCursorBlock,
|
|
132
|
+
stream,
|
|
133
|
+
onStart,
|
|
134
|
+
withDelays,
|
|
135
|
+
dataFormat,
|
|
136
|
+
previousResponse,
|
|
137
|
+
...rest
|
|
138
|
+
} = {
|
|
139
|
+
maxRetries: 2,
|
|
140
|
+
deleteEmptyCursorBlock: true,
|
|
141
|
+
stream: true,
|
|
142
|
+
withDelays: true,
|
|
143
|
+
dataFormat: htmlBlockLLMFormat,
|
|
144
|
+
...opts,
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const promptBuilder = opts.promptBuilder ?? dataFormat.defaultPromptBuilder;
|
|
148
|
+
const getStreamTools = dataFormat.getStreamTools;
|
|
149
|
+
|
|
150
|
+
const cursorBlock = useSelection
|
|
151
|
+
? undefined
|
|
152
|
+
: editor.getTextCursorPosition().block;
|
|
153
|
+
|
|
154
|
+
const deleteCursorBlock: string | undefined =
|
|
155
|
+
cursorBlock && deleteEmptyCursorBlock && isEmptyParagraph(cursorBlock)
|
|
156
|
+
? cursorBlock.id
|
|
157
|
+
: undefined;
|
|
158
|
+
|
|
159
|
+
const selectionInfo = useSelection
|
|
160
|
+
? editor.getSelectionCutBlocks()
|
|
161
|
+
: undefined;
|
|
162
|
+
|
|
163
|
+
let previousMessages: CoreMessage[] | undefined = undefined;
|
|
164
|
+
|
|
165
|
+
if (previousResponse) {
|
|
166
|
+
previousMessages = previousResponse.messages;
|
|
167
|
+
/*
|
|
168
|
+
We currently insert these messages as "assistant" string messages.
|
|
169
|
+
When using Tools, the "official" pattern for this is to use a "tool_result" message.
|
|
170
|
+
We might need to switch to this, but it would require more research whether:
|
|
171
|
+
- we maybe should switch to streamText / generateText instead of streamObject / generateObject
|
|
172
|
+
(this has built in access to `response.messages` on the AI SDK level)
|
|
173
|
+
- but, we need to make research whether tool calls are always way to go.
|
|
174
|
+
generateObject / streamObject can also use structured outputs, and this
|
|
175
|
+
might be yielding better results than tool calls.
|
|
176
|
+
|
|
177
|
+
For now, this approach works ok.
|
|
178
|
+
*/
|
|
179
|
+
previousMessages.push({
|
|
180
|
+
role: "assistant",
|
|
181
|
+
content:
|
|
182
|
+
"These are the operations returned by a previous LLM call: \n" +
|
|
183
|
+
JSON.stringify(
|
|
184
|
+
await previousResponse.llmResult.getGeneratedOperations(),
|
|
185
|
+
),
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const messages = await promptBuilder(editor, {
|
|
190
|
+
selectedBlocks: selectionInfo?.blocks,
|
|
191
|
+
userPrompt,
|
|
192
|
+
excludeBlockIds: deleteCursorBlock ? [deleteCursorBlock] : undefined,
|
|
193
|
+
previousMessages,
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
const streamTools = getStreamTools(
|
|
197
|
+
editor,
|
|
198
|
+
withDelays,
|
|
199
|
+
opts.defaultStreamTools,
|
|
200
|
+
selectionInfo
|
|
201
|
+
? { from: selectionInfo._meta.startPos, to: selectionInfo._meta.endPos }
|
|
202
|
+
: undefined,
|
|
203
|
+
opts.onBlockUpdate,
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
let response:
|
|
207
|
+
| Awaited<ReturnType<typeof generateOperations<any>>>
|
|
208
|
+
| Awaited<ReturnType<typeof streamOperations<any>>>;
|
|
209
|
+
|
|
210
|
+
if (stream) {
|
|
211
|
+
response = await streamOperations(
|
|
212
|
+
streamTools,
|
|
213
|
+
{
|
|
214
|
+
messages,
|
|
215
|
+
...rest,
|
|
216
|
+
},
|
|
217
|
+
() => {
|
|
218
|
+
if (deleteCursorBlock) {
|
|
219
|
+
editor.removeBlocks([deleteCursorBlock]);
|
|
220
|
+
}
|
|
221
|
+
onStart?.();
|
|
222
|
+
},
|
|
223
|
+
);
|
|
224
|
+
} else {
|
|
225
|
+
response = await generateOperations(streamTools, {
|
|
226
|
+
messages,
|
|
227
|
+
...rest,
|
|
228
|
+
});
|
|
229
|
+
if (deleteCursorBlock) {
|
|
230
|
+
editor.removeBlocks([deleteCursorBlock]);
|
|
231
|
+
}
|
|
232
|
+
onStart?.();
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return new LLMResponse(messages, response, streamTools);
|
|
236
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { CoreMessage } from "ai";
|
|
2
|
+
import { OperationsResult } from "../streamTool/callLLMWithStreamTools.js";
|
|
3
|
+
import { StreamTool, StreamToolCall } from "../streamTool/streamTool.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Result of an LLM call with stream tools that apply changes to a BlockNote Editor
|
|
7
|
+
*/
|
|
8
|
+
export class LLMResponse {
|
|
9
|
+
/**
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
constructor(
|
|
13
|
+
/**
|
|
14
|
+
* The messages sent to the LLM
|
|
15
|
+
*/
|
|
16
|
+
public readonly messages: CoreMessage[],
|
|
17
|
+
/**
|
|
18
|
+
* Result of the underlying LLM call. Use this to access operations the LLM decided to execute, but without applying them.
|
|
19
|
+
* (usually this is only used for advanced used cases or debugging)
|
|
20
|
+
*/
|
|
21
|
+
public readonly llmResult: OperationsResult<any>,
|
|
22
|
+
|
|
23
|
+
private readonly streamTools: StreamTool<any>[],
|
|
24
|
+
) {}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Apply the operations to the editor and return a stream of results.
|
|
28
|
+
*
|
|
29
|
+
* (this method consumes underlying streams in `llmResult`)
|
|
30
|
+
*/
|
|
31
|
+
async *applyToolCalls() {
|
|
32
|
+
let currentStream: AsyncIterable<{
|
|
33
|
+
operation: StreamToolCall<StreamTool<any>[]>;
|
|
34
|
+
isUpdateToPreviousOperation: boolean;
|
|
35
|
+
isPossiblyPartial: boolean;
|
|
36
|
+
}> = this.llmResult.operationsSource;
|
|
37
|
+
for (const tool of this.streamTools) {
|
|
38
|
+
currentStream = tool.execute(currentStream);
|
|
39
|
+
}
|
|
40
|
+
yield* currentStream;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Helper method to apply all operations to the editor if you're not interested in intermediate operations and results.
|
|
45
|
+
*
|
|
46
|
+
* (this method consumes underlying streams in `llmResult`)
|
|
47
|
+
*/
|
|
48
|
+
public async execute() {
|
|
49
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
50
|
+
for await (const _result of this.applyToolCalls()) {
|
|
51
|
+
// no op
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @internal
|
|
57
|
+
*/
|
|
58
|
+
public async _logToolCalls() {
|
|
59
|
+
for await (const toolCall of this.llmResult.operationsSource) {
|
|
60
|
+
// eslint-disable-next-line no-console
|
|
61
|
+
console.log(JSON.stringify(toolCall, null, 2));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|