@blocknote/xl-ai 0.37.0 → 0.38.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.
@@ -7,7 +7,7 @@
7
7
  (unless the user explicitly asks you otherwise to add or delete other blocks).
8
8
 
9
9
  The user now asks you to do the following:`},{role:"user",content:t.userPrompt}]:ht({...r,userPrompt:t.userPrompt,isEmptyDocument:o})}};function gt(e){let t,o=!1;return e.descendants((r,n)=>o?!1:(r.isText&&(o=!0,t=n),!0)),t}function F(e){var s;const t=T.getPmSchema(e),{modification:o}=t.marks,r=[],n=new C.Transform(e.before);for(let a=0;a<e.steps.length;a++){const i=e.steps[a],c=new C.Mapping(e.mapping.maps.slice(0,a)).invert();if(i.structure){if(i instanceof C.ReplaceStep){if(i.to!==i.from+1||i.slice.openStart!==0||i.slice.openEnd!==1||i.slice.content.size!==2)throw new Error("Structure change is not in expected format (ReplaceStep)")}else if(i instanceof C.ReplaceAroundStep){if(i.insert!==1||i.slice.size!==2||i.gapTo!==i.to-1||i.gapFrom!==i.from+1)throw new Error("Structure change is not in expected format (ReplaceAroundStep)")}else throw new Error("Step is not a ReplaceStep or ReplaceAroundStep");const b=c.map(i.from),g=i.slice.content.firstChild,k=n.doc.resolve(n.mapping.map(b)).nodeAfter;let w=g.marks||[];g.type!==k.type&&(w=o.create({type:"nodeType",previousValue:k.type.name,newValue:g.type.name}).addToSet(w));const H=new Set([...Object.keys(g.attrs),...Object.keys(k.attrs)]);for(const M of H)g.attrs[M]!==k.attrs[M]&&(w=o.create({type:"attr",attrName:M,previousValue:k.attrs[M],newValue:g.attrs[M]}).addToSet(w));const _=n.steps.length;n.setNodeMarkup(n.mapping.map(b),g.type,g.attrs,w),r.push({prosemirrorSteps:n.steps.slice(_),selection:void 0,type:"replace"});continue}if(!(i instanceof C.ReplaceStep))throw new Error("Step is not a ReplaceStep");const u=c.map(i.from),f=c.map(i.to);if(i.slice.openStart>0||i.slice.openEnd>0)throw new Error("Slice has openStart or openEnd > 0, but structure=false");r.push({prosemirrorSteps:[],selection:{anchor:n.mapping.map(u),head:n.mapping.map(f)},type:"select"});const l=i.slice.content.textBetween(0,i.slice.size),m=l===n.doc.textBetween(n.mapping.map(u),n.mapping.map(f));let p;if(m)p=i.slice.content.size;else if(l.length===0)p=i.slice.content.size;else{const b=gt(i.slice.content);if(b===void 0)throw new Error("unexpected: no first character found");p=b+1}let h=n.mapping.map(f);const d=n.mapping.map(f);let S=!0;for(let b=p;b<=i.slice.content.size;b++){const g=S&&u!==f,k=n.steps.length;if(g){const _=n.doc.resolve(n.mapping.map(u));(s=_.nodeAfter)!=null&&s.isBlock&&n.addNodeMark(_.pos,t.mark("deletion",{})),n.addMark(_.pos,h,t.mark("deletion",{})),h=n.mapping.map(f)}const w=new R.Slice(i.slice.content.cut(0,b),0,0);n.replace(d,h,w).addMark(d,d+w.content.size,t.mark("insertion",{})),n.doc.nodesBetween(d,d+w.content.size,(_,M)=>M<d||M>d+w.content.size?!0:(_.isBlock&&n.addNodeMark(M,t.mark("insertion",{})),!1)),h=n.mapping.slice(k).map(h);const H=q.TextSelection.near(n.doc.resolve(d+w.content.size),-1);r.push({prosemirrorSteps:n.steps.slice(k),selection:{anchor:H.from,head:H.from},type:g?"replace":"insert"}),S=!1}}return r}async function re(e){const t=Math.random()*.3+.85;if(e.type==="select")await new Promise(o=>setTimeout(o,100*t));else if(e.type==="insert")await new Promise(o=>setTimeout(o,10*t));else if(e.type==="replace")await new Promise(o=>setTimeout(o,200*t));else throw new T.UnreachableCaseError(e.type)}function ne(e,t){e.setMeta("addToHistory",!1),t.selection&&e.setMeta("aiAgent",{selection:{anchor:t.selection.anchor,head:t.selection.head}});for(const o of t.prosemirrorSteps)if(e.maybeStep(o).failed)throw new Error("failed to apply step");return e}function kt(e,t,o){const r=new C.Transform(t);for(const a of e){const i=new C.ReplaceStep(r.mapping.map(a.fromA),r.mapping.map(a.toA),o.slice(a.fromB,a.toB));r.step(i)}const n=r.mapping.invert();let s=r.doc.content.findDiffStart(o.content);for(;s!==null;){const a=o.resolve(s).nodeAfter,i=r.doc.resolve(s).nodeAfter;if(!a||!i)throw new Error("diffNode not found");const c=!a.isLeaf&&a.content.eq(i.content),u=c?1:Math.min(a.nodeSize,i.nodeSize),f=s+u,l=n.map(s),m=n.map(f);let p=e.length;for(let d=0;d<e.length;d++)if(e[d].fromA>=m){p=d;break}e.splice(p,0,{fromA:l,toA:m,fromB:s,toB:f,deleted:[],inserted:[],type:c?"node-type-or-attr-update":"mark-update"}),r.step(new C.ReplaceStep(s,f,o.slice(s,f),c));const h=r.doc.content.findDiffStart(o.content);if(h===s)throw new Error("diffStart not moving");s=h}return e}const pe=(e,t)=>{const o=new Set,r=new Set;e.descendants(a=>{a.type.name==="tableCell"&&o.add(JSON.stringify(a.toJSON()))}),t.descendants(a=>{a.type.name==="tableCell"&&r.add(JSON.stringify(a.toJSON()))});const n=new Set([...o].filter(a=>r.has(a)));return{encodeCharacter:a=>a,encodeNodeStart:a=>{if(a.type.name==="tableCell"){const i=JSON.stringify(a.toJSON());return n.has(i)?i:a.type.name}return a.type.name},encodeNodeEnd:a=>{if(a.type.name==="tableCell"){const i=JSON.stringify(a.toJSON());return n.has(i)?i:-1}return-1},compareTokens:(a,i)=>a===i}};function G(e,t,o=!1,r,n){const s=T.getNodeById(e.id,t),a=new C.Transform(t);T.updateBlockTr(a,s.posBeforeNode,e.block,r,n);let i=a.doc,c=K.ChangeSet.create(t,void 0,pe(t,i));if(c=c.addSteps(i,a.mapping.maps,0),o&&c.changes.length>0){const l=c.changes[c.changes.length-1],m=l.toA-l.fromA,p=l.toB-l.fromB;if(m>p){const h=t.slice(l.fromA+p,l.toA);a.step(new C.ReplaceStep(l.toB,l.toB,h)),i=a.doc,c=K.ChangeSet.create(c.startDoc,void 0,pe(c.startDoc,i)),c=c.addSteps(i,a.mapping.maps,0)}}const u=[],f=K.simplifyChanges(c.changes,i);for(let l=0;l<f.length;l++){const m=f[l],p=i.slice(m.fromB,m.toB);if(p.openEnd===1&&p.openStart===0&&(m.type="node-type-or-attr-update",p.size>2)){const h={fromA:m.fromA,toA:m.fromA+1,fromB:m.fromB,toB:m.fromB+1,deleted:[],inserted:[],type:"node-type-or-attr-update"},d={fromA:m.fromA+1,toA:m.toA,fromB:m.fromB+1,toB:m.toB,deleted:[],inserted:[]};f.splice(l,1,h,d),l++}}kt(f,t,i);for(let l=0;l<f.length;l++){const m=f[l],p=i.slice(m.fromB,m.toB);if(p.openEnd>0&&p.size>1)throw new Error("unexpected, openEnd > 0 and size > 1, this should have been split into two steps");l===f.length-1&&o&&m.type==="mark-update"||u.push(new C.ReplaceStep(m.fromA,m.toA,p,m.type==="node-type-or-attr-update"))}return u}function bt(e,t){if(!e||!Array.isArray(e)||e.length===0)return{ok:!1,error:"blocks is required"};const o=[];for(const r of e){const n=t(r);if(!n.ok)return{ok:!1,error:`Invalid block: ${n.error}`};o.push(n.value)}return{ok:!0,value:o}}function se(e){return(t,o)=>{const r=typeof e.schema=="function"?e.schema(t):e.schema;return{name:"add",description:e.description,parameters:{type:"object",properties:{referenceId:{type:"string",description:"MUST be an id of a block in the document"},position:{type:"string",enum:["before","after"],description:"`after` to add blocks AFTER (below) the block with `referenceId`, `before` to add the block BEFORE (above)"},blocks:{items:r.block,type:"array"}},required:["referenceId","position","blocks"],$defs:r.$defs},validate:n=>{if(n.type!=="add")return{ok:!1,error:"invalid operation type"};if(n.position!=="before"&&n.position!=="after")return{ok:!1,error:"invalid position"};if(!n.referenceId||!n.blocks)return{ok:!1,error:"referenceId and blocks are required"};let s=n.referenceId;if(o.idsSuffixed){if(!(s!=null&&s.endsWith("$")))return{ok:!1,error:"referenceId must end with $"};s=s.slice(0,-1)}if(!t.getBlock(s))return{ok:!1,error:"referenceId not found"};const i=bt(n.blocks,c=>e.validateBlock(c,t));return i.ok?{ok:!0,value:{type:n.type,referenceId:s,position:n.position,blocks:i.value}}:i},execute:async function*(n){var i;let s=[];const a={};for await(const c of n){if(c.isUpdateToPreviousOperation||(s=[]),c.operation.type!=="add"){yield c;continue}const u=c.operation,f=await e.toJSONToolCall(t,{...c,operation:u});if(f&&!(c.isPossiblyPartial&&oe(f.blocks[f.blocks.length-1]))){for(let l=0;l<f.blocks.length;l++){const m=f.blocks[l],p=t.prosemirrorState.tr;let h=[];if(l<s.length){const d=await e.rebaseTool(s[l],t),b=G({id:s[l],block:m},d.doc,!1).map(g=>g.map(d.invertMap));for(const g of b)p.step(g.map(p.mapping));h=F(p),h=h.filter(g=>g.type!=="select")}else{const d=u.position==="after"?a[u.referenceId]:void 0,S=T.insertBlocks(p,[m],l>0?s[l-1]:d||u.referenceId,l>0?"after":u.position);s.push(...S.map(b=>b.id)),h=F(p)}h.find(d=>d.type==="replace");for(const d of h)o.withDelays&&await re(d),t.transact(S=>{ne(S,d)}),(i=o.onBlockUpdate)==null||i.call(o,s[l])}c.isPossiblyPartial||u.position==="after"&&(a[u.referenceId]=s[s.length-1])}}}}}}function ie(e){return(t,o)=>{const r=typeof e.schema=="function"?e.schema(t):e.schema;return{name:"update",description:e.description,parameters:{type:"object",properties:{id:{type:"string",description:"id of block to update"},block:r.block},required:["id","block"],$defs:r.$defs},validate:n=>{if(n.type!=="update")return{ok:!1,error:"invalid operation type"};if(!n.id)return{ok:!1,error:"id is required"};let s=n.id;if(o.idsSuffixed){if(!(s!=null&&s.endsWith("$")))return{ok:!1,error:"id must end with $"};s=s.slice(0,-1)}if(!n.block)return{ok:!1,error:"block is required"};const a=t.getBlock(s);if(!a)return console.error("BLOCK NOT FOUND",s),{ok:!1,error:"block not found"};const i=e.validateBlock(n.block,t,a.type);return i.ok?{ok:!0,value:{type:n.type,id:s,block:i.value}}:i},execute:async function*(n){var c;let a=50;const i=o.updateSelection?{from:T.trackPosition(t,o.updateSelection.from),to:T.trackPosition(t,o.updateSelection.to)}:void 0;for await(const u of n){if(u.operation.type!=="update"){yield u;continue}const f=u.operation;if(u.isPossiblyPartial){const k=JSON.stringify(f.block).length;if(k<a)continue;a=k+50}else a=50;const l=await e.rebaseTool(f.id,t),m=i?l.invertMap.invert().map(i.from()):void 0,p=i?l.invertMap.invert().map(i.to()):void 0,h=await e.toJSONToolCall(t,u);if(!h)continue;const d=G(h,l.doc,u.isPossiblyPartial,m,p);if(d.length===1&&u.isPossiblyPartial)continue;const S=d.map(k=>k.map(l.invertMap)),b=new C.Transform(t.prosemirrorState.doc);for(const k of S)b.step(k.map(b.mapping));const g=F(b);for(const k of g)o.withDelays&&await re(k),t.transact(w=>{ne(w,k)}),(c=o.onBlockUpdate)==null||c.call(o,f.id)}}}}}const ae=(e,t)=>({name:"delete",description:"Delete a block",parameters:{type:"object",properties:{id:{type:"string",description:"id of block to delete"}},required:["id"]},validate:o=>{if(o.type!=="delete")return{ok:!1,error:"invalid operation type"};if(!o.id)return{ok:!1,error:"id is required"};let r=o.id;if(t.idsSuffixed){if(!(r!=null&&r.endsWith("$")))return{ok:!1,error:"id must end with $"};r=r.slice(0,-1)}return e.getBlock(r)?{ok:!0,value:{type:"delete",id:r}}:{ok:!1,error:"block not found"}},execute:async function*(o){var r;for await(const n of o){if(n.operation.type!=="delete"){yield n;continue}const s=n.operation,a=e.prosemirrorState.tr;T.removeAndInsertBlocks(a,[s.id],[]);const i=F(a);for(const c of i)t.withDelays&&await re(c),e.transact(u=>{ne(u,c)}),(r=t.onBlockUpdate)==null||r.call(t,s.id)}}});function fe(e){const t=e.lastIndexOf("<"),o=e.lastIndexOf(">");let r=e;if(t>o&&(r=e.substring(0,t),!r.trim()))return;const n=r.match(/&[a-zA-Z0-9]*$/);n&&(r=r.substring(0,r.length-n[0].length));const i=new DOMParser().parseFromString(`<div>${r}</div>`,"text/html").body.firstChild;return i?i.innerHTML:""}function J(e){let t;if(D.applySuggestions(e.prosemirrorState,o=>{t=o}),!t)throw new Error("applySuggestionsTr is not set");return t}function V(e,t){const o=t.mapping.invert();return{doc:t.doc,tr:()=>new C.Transform(t.doc),invertMap:o,rebaseTr:r=>{if(r.steps.length===0)throw new Error("No steps to apply");let n=e.prosemirrorState.tr;for(const s of r.steps){const a=s.map(o);if(!a)throw new Error("Step is not mapped");n=n.step(a)}return n}}}async function me(e,t){var u;const o=J(t),r=T.getBlock(o.doc,e);if(!r)throw new Error("block not found");const n=await t.blocksToHTMLLossy([{...r,children:[]}]),s=(u=window.__TEST_OPTIONS)==null?void 0:u.mockID,a=await t.tryParseHTMLToBlocks(n);if(window.__TEST_OPTIONS&&(window.__TEST_OPTIONS.mockID=s),a.length!==1)throw new Error("html diff invalid block count");const i=a[0];if(i.id=e,G({id:e,block:i},o.doc).length)throw new Error("html diff");return V(t,o)}function he(e){return typeof e!="string"?{ok:!1,error:"block must be a string"}:{ok:!0,value:e}}const Q={add:se({description:"Insert new blocks",schema:{block:{type:"string",description:"html of block (MUST be a single HTML element)"}},validateBlock:he,rebaseTool:me,toJSONToolCall:async(e,t)=>{var n;const o=(n=window.__TEST_OPTIONS)==null?void 0:n.mockID,r=(await Promise.all(t.operation.blocks.map(async s=>{const a=t.isPossiblyPartial?fe(s):s;return a?(await e.tryParseHTMLToBlocks(a)).map(i=>(delete i.id,i)):[]}))).flat();if(window.__TEST_OPTIONS&&(window.__TEST_OPTIONS.mockID=o),r.length!==0)return{...t.operation,blocks:r}}}),update:ie({description:"Update a block",schema:{block:{type:"string",description:"html of block (MUST be a single HTML element)"}},validateBlock:he,rebaseTool:me,toJSONToolCall:async(e,t)=>{const o=t.isPossiblyPartial?fe(t.operation.block):t.operation.block;if(!o)return;const r=(await e.tryParseHTMLToBlocks(o))[0];return window.__TEST_OPTIONS&&(window.__TEST_OPTIONS.mockID=void 0),delete r.id,{...t.operation,block:r}}}),delete:ae};function St(e,t,o,r,n){const s={add:!0,update:!0,delete:!0,...o};return[...s.update?[Q.update(e,{idsSuffixed:!0,withDelays:t,updateSelection:r,onBlockUpdate:n})]:[],...s.add?[Q.add(e,{idsSuffixed:!0,withDelays:t,onBlockUpdate:n})]:[],...s.delete?[Q.delete(e,{idsSuffixed:!0,withDelays:t,onBlockUpdate:n})]:[]]}const Le={getStreamTools:St,defaultPromptBuilder:yt,promptHelpers:{getDataForPromptNoSelection:Ie,getDataForPromptWithSelection:_e}};async function Ee(e,t){const{userPrompt:o,useSelection:r,deleteEmptyCursorBlock:n,stream:s,onStart:a,withDelays:i,dataFormat:c,previousResponse:u,...f}={maxRetries:2,deleteEmptyCursorBlock:!0,stream:!0,withDelays:!0,dataFormat:Le,...t},l=t.promptBuilder??c.defaultPromptBuilder,m=c.getStreamTools,p=r?void 0:e.getTextCursorPosition().block,h=p&&n&&oe(p)&&E(e.document).length>0?p.id:void 0,d=r?e.getSelectionCutBlocks():void 0;let S;u&&(S=u.messages.map(w=>w.role==="user"&&typeof w.content=="string"?{role:"system",content:`USER_MESSAGE: ${w.content}`}:w),S.push({role:"system",content:`ASSISTANT_MESSAGE: These are the operations returned by a previous LLM call:
10
- `+JSON.stringify(await u.llmResult.getGeneratedOperations())}));const b=await l(e,{selectedBlocks:d==null?void 0:d.blocks,userPrompt:o,excludeBlockIds:h?[h]:void 0,previousMessages:S}),g=m(e,i,t.defaultStreamTools,d?{from:d._meta.startPos,to:d._meta.endPos}:void 0,t.onBlockUpdate);let k;return s?k=await ct(g,{messages:b,...f},()=>{h&&e.removeBlocks([h]),a==null||a()}):(k=await it(g,{messages:b,...f}),h&&e.removeBlocks([h]),a==null||a()),new pt(b,k,g)}async function Ne(e,t){const o=e.getTextCursorPosition().block.id,r=E(e.document,{cursorBlockId:o}),n=await x(P(r),async c=>({...c,children:void 0})),a=Y(e,n).filter(c=>"cursor"in c||!(t.excludeBlockIds||[]).includes(c.id));return{jsonBlocks:N(a)}}async function Ae(e,t){const o=await x(P(t.selectedBlocks),async n=>n);return{jsonSelectedBlocks:N(o),jsonDocument:(await x(P(e.document),async n=>({...n,id:void 0,children:void 0}))).map(({block:n})=>({block:n}))}}function wt(e){return[{role:"system",content:`You're manipulating a selected part of a text document using JSON blocks.
10
+ `+JSON.stringify(await u.llmResult.getGeneratedOperations())}));const b=await l(e,{selectedBlocks:d==null?void 0:d.blocks,userPrompt:o,excludeBlockIds:h?[h]:void 0,previousMessages:S}),g=m(e,i,t.defaultStreamTools,d?{from:d._meta.startPos,to:d._meta.endPos}:void 0,t.onBlockUpdate);let k;return s?k=await ct(g,{messages:b,...f},()=>{h&&e.getBlock(h)&&e.removeBlocks([h]),a==null||a()}):(k=await it(g,{messages:b,...f}),h&&e.getBlock(h)&&e.removeBlocks([h]),a==null||a()),new pt(b,k,g)}async function Ne(e,t){const o=e.getTextCursorPosition().block.id,r=E(e.document,{cursorBlockId:o}),n=await x(P(r),async c=>({...c,children:void 0})),a=Y(e,n).filter(c=>"cursor"in c||!(t.excludeBlockIds||[]).includes(c.id));return{jsonBlocks:N(a)}}async function Ae(e,t){const o=await x(P(t.selectedBlocks),async n=>n);return{jsonSelectedBlocks:N(o),jsonDocument:(await x(P(e.document),async n=>({...n,id:void 0,children:void 0}))).map(({block:n})=>({block:n}))}}function wt(e){return[{role:"system",content:`You're manipulating a selected part of a text document using JSON blocks.
11
11
  Make sure to follow the json schema provided and always include the trailing $ in ids.
12
12
  This is the selection as an array of JSON blocks:`},{role:"system",content:JSON.stringify(e.jsonSelectedBlocks)},{role:"system",content:"This is the entire document (INCLUDING the selected text), find the selected text in there to understand the context:"},{role:"system",content:JSON.stringify(e.jsonDocument)},{role:"system",content:"The user asks you to do the following:"},{role:"user",content:e.userPrompt}]}function Tt(e){return[{role:"system",content:`You're manipulating a text document using JSON blocks.
13
13
  Make sure to follow the json schema provided. When referencing ids they MUST be EXACTLY the same (including the trailing $).