revise 2.1.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/CHANGELOG.md +47 -1088
  2. package/LICENSE +24 -41
  3. package/README.md +103 -26
  4. package/agent.d.ts +139 -0
  5. package/chunks/chunk-U5X47PZ6.js +135 -0
  6. package/chunks/chunk-U6YKQBKL.js +15 -0
  7. package/chunks/chunk-ZLQVPMBN.js +1650 -0
  8. package/chunks/package-5SHL5FOJ.js +14 -0
  9. package/chunks/render-QD5VWKSV.js +109 -0
  10. package/cli-output.schema.json +1984 -0
  11. package/cli.js +3604 -0
  12. package/document.d.ts +320 -0
  13. package/docx.d.ts +73 -0
  14. package/errors.d.ts +14 -0
  15. package/index.d.ts +13 -967
  16. package/index.js +31 -1
  17. package/legacy/editor.d.ts +19 -0
  18. package/legacy/editor.js +16 -0
  19. package/legacy/server.d.ts +37 -0
  20. package/legacy/server.js +25 -0
  21. package/legacy/style.css +2 -0
  22. package/package.d.ts +23 -0
  23. package/package.json +49 -55
  24. package/render.d.ts +27 -0
  25. package/FONT-LICENSE-HAN-EXT-B.txt +0 -91
  26. package/FONT-LICENSE-KATEX.txt +0 -95
  27. package/FONT-LICENSE-LIBERATION.txt +0 -102
  28. package/FONT-LICENSE-NOTO-MULTILINGUAL.txt +0 -93
  29. package/FONT-LICENSE-NOTO-SANS-SC.txt +0 -93
  30. package/FONT-LICENSE-NOTO.txt +0 -94
  31. package/FONT-LICENSE-SOURCE-CODE-PRO.txt +0 -94
  32. package/FONT-LICENSE-SOURCE-SERIF-4.txt +0 -93
  33. package/THIRD-PARTY-NOTICES.md +0 -3376
  34. package/assets/historyMaterializeWorker-C4uxcZEh.js +0 -607
  35. package/backend.d.ts +0 -155
  36. package/backend.js +0 -3
  37. package/chunks/AgentPageRenderer-BFB0arQL.js +0 -1
  38. package/chunks/AgentPageRenderer-Dn6SaRjW.js +0 -1
  39. package/chunks/AttachmentDocumentImporter-BHDJAdky.js +0 -1
  40. package/chunks/AttachmentDocumentImporter-CxOZqzt1.js +0 -1
  41. package/chunks/BidiText-C8PBPSQY.js +0 -160
  42. package/chunks/ColorParserFull-BKH72fK8.js +0 -446
  43. package/chunks/DocumentMutator-4vBJQ74L.js +0 -31
  44. package/chunks/DocumentScrubber-COPepQKE.js +0 -1
  45. package/chunks/DocumentScrubber-Cf_QqHhF.js +0 -1
  46. package/chunks/DocumentScrubber-DS4LFDKS.js +0 -18
  47. package/chunks/DocumentStylesheet-byN5dtC6.js +0 -7
  48. package/chunks/DocxConverter-BCEB7jWY.js +0 -1083
  49. package/chunks/DocxConverter-C3NflpDr.js +0 -11
  50. package/chunks/DocxConverter-D9ZNn4nX.js +0 -11
  51. package/chunks/DocxGraft-Ba63IRP4.js +0 -1
  52. package/chunks/DocxGraft-DjERgl-z.js +0 -7
  53. package/chunks/DocxGraft-cYlmw4Ab.js +0 -1
  54. package/chunks/FileImporter-CHXj9sNX.js +0 -1
  55. package/chunks/FileImporter-DetvRoJc.js +0 -1
  56. package/chunks/HorizontalRuleOrnaments-gmUZ3R7Q.js +0 -3
  57. package/chunks/HtmlConverter-Sd9t49vH.js +0 -267
  58. package/chunks/ListNumbering-Qlu6AuRZ.js +0 -23
  59. package/chunks/MarkdownConverter-BdJgh8xt.js +0 -57
  60. package/chunks/MathRenderer-B0Y1h1JU.js +0 -62
  61. package/chunks/OdtConverter-BKtyx012.js +0 -1
  62. package/chunks/OdtConverter-Ce9j8PRt.js +0 -1
  63. package/chunks/OdtConverter-D709qfYb.js +0 -31
  64. package/chunks/ParagraphDiffAnalysis-DrmStvmz.js +0 -36
  65. package/chunks/PdfConverter-BA8XLTAM.js +0 -21
  66. package/chunks/PdfConverter-CkDClffR.js +0 -438
  67. package/chunks/PdfConverter-CxLxd-LJ.js +0 -21
  68. package/chunks/PdfImportService-CQCgsRX1.js +0 -2
  69. package/chunks/PdfImportService-xl7fstr-.js +0 -2
  70. package/chunks/RtfConverter-BZOnMUGH.js +0 -14
  71. package/chunks/RtfConverter-Bs81AfXt.js +0 -14
  72. package/chunks/RtfConverter-DfuE5olb.js +0 -45
  73. package/chunks/TableBorders-Cdkc62cX.js +0 -30
  74. package/chunks/TableGrid-DbroRucl.js +0 -12
  75. package/chunks/TextFileDecoder--rsVs3NR.js +0 -9
  76. package/chunks/TxtConverter-C-oiFUAp.js +0 -14
  77. package/chunks/UnicodeUtils-CXtusU4g.js +0 -10
  78. package/chunks/XmlConverter-C0FnrVYk.js +0 -70
  79. package/chunks/XmlConverter-CQa8baOF.js +0 -2
  80. package/chunks/XmlConverter-DjEYaIyf.js +0 -2
  81. package/chunks/__vite-browser-external-l0sNRNKZ.js +0 -0
  82. package/chunks/_commonjsHelpers-DaMA6jEr.js +0 -2
  83. package/chunks/_revise-sdk-lazy-harfbuzz-CDWdjF9f.js +0 -1
  84. package/chunks/_revise-sdk-lazy-harfbuzz-X8gnYTZL.js +0 -1
  85. package/chunks/ar-BdmGnaKI.js +0 -14
  86. package/chunks/backend-BIhAX-Gi.js +0 -484
  87. package/chunks/base64-Qx0OzT4p.js +0 -196
  88. package/chunks/browser-module-CFmqfGkE.js +0 -1791
  89. package/chunks/browser-module-CYGCfEyx.js +0 -3
  90. package/chunks/browser-module-DgvTMhpA.js +0 -3
  91. package/chunks/bundle.min-DRpfgV69.js +0 -782
  92. package/chunks/capture-BAJ2in5p.js +0 -9
  93. package/chunks/carrier-C5VZRMxZ.js +0 -6
  94. package/chunks/de-DldIXRFC.js +0 -14
  95. package/chunks/es-CnyKlSPK.js +0 -14
  96. package/chunks/footnoteFlatten-Bekh8ZfM.js +0 -6
  97. package/chunks/graftExport-CRRm1Oe_.js +0 -82
  98. package/chunks/html2canvas.esm-CntiHiYW.js +0 -997
  99. package/chunks/index-B1idHquf.js +0 -1094
  100. package/chunks/index-BWdRWxoH.js +0 -1807
  101. package/chunks/index-C-4H81OE.js +0 -378
  102. package/chunks/index-iZC8xN0t.js +0 -378
  103. package/chunks/index.es-Bwt05m_b.js +0 -5
  104. package/chunks/index.es-CI0QPo8w.js +0 -780
  105. package/chunks/index.es-DAQD57G4.js +0 -5
  106. package/chunks/jspdf.es.min-CnNRolk9.js +0 -77
  107. package/chunks/jspdf.es.min-DU74zN8b.js +0 -1792
  108. package/chunks/jspdf.es.min-DlTF8uTw.js +0 -77
  109. package/chunks/jszip.min-CPW0h1Kx.js +0 -476
  110. package/chunks/katex-DWj8TvwO.js +0 -1462
  111. package/chunks/pdf-BLWDCiFF.js +0 -1828
  112. package/chunks/persistInlineDocumentImages-DQj2iaqg.js +0 -1
  113. package/chunks/pseudoLocale-BoJwIubw.js +0 -1
  114. package/chunks/pseudoLocale-DWAm7Dpa.js +0 -1
  115. package/chunks/purify.es-BwLardii.js +0 -107
  116. package/chunks/serverDocumentSession-DASrQAbW.js +0 -15
  117. package/chunks/signatures-CBF7NZUy.js +0 -17
  118. package/chunks/tree-sitter-D6zWWUMP.js +0 -4
  119. package/chunks/wasmInline.generated-CBYFkdSM.js +0 -1
  120. package/chunks/web-tree-sitter-BXGZGnNj.js +0 -2
  121. package/full.js +0 -1
  122. package/root.d.ts +0 -5
  123. package/root.js +0 -2
  124. package/serverToolContract.d.ts +0 -391
  125. package/serverToolInputs.generated.d.ts +0 -250
  126. package/style.css +0 -1
@@ -1,15 +0,0 @@
1
- import{h as Co,y as De,i as vt,d as an,o as $o,m as Mo,r as cn,g as ln,a as Do,t as To,R as Ao,b as qo}from"./backend-BIhAX-Gi.js";import{D as It,P as Ro,i as Po,c as ye,f as ot,e as St,A as ne,b as xt,a as Bo,d as No,r as Lo,g as dn,h as Ct,j as Oo,k as He,l as Uo,m as jo,n as Fo,o as Eo,p as un,q as zo,s as Ho,t as hn,u as mn,v as Wo,w as Jo}from"./DocumentMutator-4vBJQ74L.js";import{i as Go,R as Vo}from"./DocumentStylesheet-byN5dtC6.js";import{s as Ko}from"./carrier-C5VZRMxZ.js";import*as ve from"yjs";import{b as Te}from"./TableGrid-DbroRucl.js";import{f as se,a as Ie,c as Xo,b as Yo,d as Zo,e as Qo}from"./index-B1idHquf.js";import{b as $t,c as er,a as tr}from"./base64-Qx0OzT4p.js";import"./ParagraphDiffAnalysis-DrmStvmz.js";import{c as nr}from"./UnicodeUtils-CXtusU4g.js";const or={count:()=>{},gauge:()=>{},distribution:()=>{}};class rr{constructor(e=50){this.tasks=new Map,this.intervalId=null,this.tickMs=e}schedule(e,n,o){const r=Date.now();this.tasks.set(e,{id:e,callback:o,delay:n,lastScheduledAt:r}),this.intervalId===null&&(this.intervalId=window.setInterval(()=>this.tick(),this.tickMs))}cancel(e){this.tasks.delete(e)&&this.tasks.size===0&&this.intervalId!==null&&(window.clearInterval(this.intervalId),this.intervalId=null)}tick(){const e=Date.now();for(const n of this.tasks.values())if(e-n.lastScheduledAt>=n.delay){this.tasks.delete(n.id);try{n.callback()}catch(o){console.error("[DebouncedTaskScheduler] Task error",o)}}this.tasks.size===0&&this.intervalId!==null&&(window.clearInterval(this.intervalId),this.intervalId=null)}}const sr=new rr;function ir(t,e,n){sr.schedule(t,e,n)}function gn(t){if(typeof atob=="function"){const e=atob(t),n=new Uint8Array(e.length);for(let o=0;o<e.length;o++)n[o]=e.charCodeAt(o);return n}return Uint8Array.from(Buffer.from(t,"base64"))}function pn(t,e){const n=ve;if(typeof n.applyUpdateV2=="function")try{n.applyUpdateV2(t,e)}catch(o){console.warn("[historyReplay] Failed to apply V2 update:",o)}}function fn(t,e){try{ve.applyUpdate(t,e),Co(t)||pn(t,e)}catch{pn(t,e)}}function ar(t,e,n=-1){const o=new ve.Doc({gc:!1});fn(o,gn(t));const r=n<0?e.length:n;for(let s=0;s<r&&s<e.length;s++)fn(o,gn(e[s]));return o}class cr{constructor(){this.worker=null,this.workerFailed=!1,this.nextRequestId=1,this.pendingRequests=new Map}async init(){if(!(this.worker||this.workerFailed))try{if(typeof window>"u"||typeof Worker>"u"){this.workerFailed=!0;return}this.worker=new Worker(new URL(""+new URL("../assets/historyMaterializeWorker-C4uxcZEh.js",import.meta.url).href,import.meta.url)),this.worker.onmessage=e=>{const n=e.data,o=this.pendingRequests.get(n.id);if(o){if(this.pendingRequests.delete(n.id),!n.success){o.reject(new Error(n.error||"Worker request failed"));return}n.kind==="filterDistinct"?o.resolve(n.distinctIds??[]):n.doc?o.resolve(n.doc):o.reject(new Error("Materialization failed"))}},this.worker.onerror=e=>{console.warn("[HistoryMaterializer] Worker error:",e);for(const[n,o]of this.pendingRequests)o.reject(new Error("Worker error")),this.pendingRequests.delete(n);this.workerFailed=!0,this.worker?.terminate(),this.worker=null}}catch(e){console.warn("[HistoryMaterializer] Failed to create worker:",e),this.workerFailed=!0}}async materialize(e,n,o=-1){if(await this.init(),this.worker&&!this.workerFailed)try{return await this.materializeViaWorker(e,n,o)}catch(r){console.warn("[HistoryMaterializer] Worker materialization failed, falling back:",r)}return this.materializeSync(e,n,o)}async computeDistinctContentIds(e,n){if(n.length===0)return[];if(await this.init(),!this.worker||this.workerFailed)return null;try{return await new Promise((o,r)=>{if(!this.worker){r(new Error("Worker not available"));return}const s=this.nextRequestId++;this.pendingRequests.set(s,{resolve:o,reject:r});const i={id:s,kind:"filterDistinct",segments:e,candidateIds:n};this.worker.postMessage(i),setTimeout(()=>{this.pendingRequests.has(s)&&(this.pendingRequests.delete(s),r(new Error("Worker timeout")))},6e4)})}catch(o){return console.warn("[HistoryMaterializer] Distinct-frame filtering failed:",o),null}}materializeToYDoc(e,n,o=-1){return ar(e,n,o)}materializeViaWorker(e,n,o){return new Promise((r,s)=>{if(!this.worker){s(new Error("Worker not available"));return}const i=this.nextRequestId++;this.pendingRequests.set(i,{resolve:r,reject:s});const a={id:i,snapshotB64:e,updatesB64:n,uptoIndex:o};this.worker.postMessage(a),setTimeout(()=>{this.pendingRequests.has(i)&&(this.pendingRequests.delete(i),s(new Error("Worker timeout")))},3e4)})}materializeSync(e,n,o){const r=this.materializeToYDoc(e,n,o);try{return De(r)}finally{r.destroy()}}dispose(){for(const[,e]of this.pendingRequests)e.reject(new Error("Materializer disposed"));this.pendingRequests.clear(),this.worker?.terminate(),this.worker=null}isWorkerAvailable(){return this.worker!==null&&!this.workerFailed}}const rt=new cr,Mt="https://app-api.revise-sdk.invalid";class lr{constructor(e=20){this.cache=new Map,this.maxSize=e}get(e){const n=this.cache.get(e);return n&&(this.cache.delete(e),this.cache.set(e,n)),n}set(e,n){if(this.cache.size>=this.maxSize&&!this.cache.has(e)){const o=this.cache.keys().next().value;o&&this.cache.delete(o)}this.cache.delete(e),this.cache.set(e,n)}clear(){this.cache.clear()}}class dr{constructor(e,n,o){this.tailDebounceMs=1200,this.docCache=new lr,this.totalUpdates=0,this.segments=[],this.loaded=!1,this.maxEndLoaded=0,this.loadLock=null,this.targetLocks=new Map,this.blobLocks=new Map,this.abortController=null,this.contentIds=[],this.updateTimestamps=new Map,this.contentTimestamps=[],this.chunkEndUpdateIds=[],this.chunkSegIdx=[],this.distinctContentIds=null,this.distinctSignature=null,this.changeObservers=[],this.disposed=!1,this.documentId=e,this.authToken=o?.authToken,this.tailTaskId=`history-tail-${Math.random().toString(36).slice(2)}`,this.abortController=new AbortController}onChange(e){return this.changeObservers.push(e),()=>{const n=this.changeObservers.indexOf(e);n>=0&&this.changeObservers.splice(n,1)}}async ensureLoaded(){if(this.loaded)return!0;if(this.disposed)return!1;if(!this.supportsServerHistory())return this.loaded=!0,!0;try{const e=`${Mt}/documents/${this.documentId}/history`,n=await this.fetchJson(e);return this.totalUpdates=this.readTotalUpdates(n),this.segments=this.parseFrames(n.frames),this.loaded=!0,this.recomputeDerivedData(),this.notifyChange(),!0}catch(e){return console.error("[UpdateHistoryManager] Failed to load update history:",{documentId:this.documentId,error:e instanceof Error?e.message:String(e)}),!1}}notifyDocUpdated(){this.disposed||!this.loaded||ir(this.tailTaskId,this.tailDebounceMs,()=>{this.refreshNewSegments()})}dispose(){this.disposed=!0,this.abortController?.abort(),this.abortController=null,this.changeObservers=[],this.docCache.clear(),this.segments=[],this.updateTimestamps.clear()}getTotalUpdates(){const e=this.segments[this.segments.length-1],n=this.contentIds[this.contentIds.length-1]??0;return Math.max(this.totalUpdates,e?.endUpdateId??0,n)}getContentCount(){return this.contentIds.length}getContentUpdateIds(){return this.contentIds.slice()}getDistinctContentUpdateIds(){return this.distinctContentIds&&this.distinctSignature===this.contentIdsSignature()?this.distinctContentIds.slice():null}contentIdsSignature(){const e=this.contentIds;return`${e.length}:${e[e.length-1]??0}`}async ensureDistinctFramesComputed(){}getWorkChunkCount(){return this.chunkEndUpdateIds.length}getWorkChunkEndUpdateIds(){return this.chunkEndUpdateIds.slice()}getTimestampForUpdateId(e){const n=this.updateTimestamps.get(Math.floor(e));return n&&Number.isFinite(n)&&n>0?n:null}getContentTimeline(){return{count:this.contentIds.length,timestamps:this.contentTimestamps.slice()}}getTimeAxisTicks(){let e;if(this.contentTimestamps.length>0?e=this.contentTimestamps.filter(P=>Number.isFinite(P)&&P>0):(e=Array.from(this.updateTimestamps.values()).filter(P=>Number.isFinite(P)&&P>0),e.sort((P,U)=>P-U)),e.length===0)return null;const n=e[0],o=e[e.length-1],r=o-n;if(r<=0)return{startTs:n,endTs:o,ticksTs:[]};const s=6e4,i=60*s,a=24*i,c=7*a;let u;r<i?u=5*s:r<a?u=i:r<30*a?u=a:u=c;const f=Math.floor(n/u)*u,$=[];let T=0,R=0;for(let P=f+u;P<o;P+=u){const U=P-u;for(;T<e.length&&e[T]<=U;)T++;for(R=Math.max(R,T);R<e.length&&e[R]<=P;)R++;R>T&&P>n&&$.push(P)}return{startTs:n,endTs:o,ticksTs:$}}getPauseMarkersForContent(e,n=10){const o=this.contentTimestamps;if(o.length<=1)return[];const r=Math.max(0,o[o.length-1]-o[0]);if(r<=0||e<=0)return[];const s=r*Math.max(1,n)/Math.max(1,e),i=[];let a=-1/0;for(let c=0;c<o.length-1;c++)o[c+1]-o[c]>=s&&o[c]-a>=s&&(i.push(c+1),a=o[c]);return i}async findLatestUpdateIdBeforeTimestamp(e){if(!await this.ensureLoaded()||!Number.isFinite(e)||e<=0||this.updateTimestamps.size===0)return null;const n=Array.from(this.updateTimestamps.entries()).filter(([,i])=>i>0).sort((i,a)=>i[1]-a[1]);if(n.length===0)return null;let o=0,r=n.length-1,s=null;for(;o<=r;){const i=o+r>>1;n[i][1]<=e?(s=n[i][0],o=i+1):r=i-1}return s??n[0][0]}async materializeAtContentIndex(e,n){if(!await this.ensureLoaded()||this.contentIds.length===0)return null;const o=Math.max(1,Math.min(this.contentIds.length,e));return this.materializeAt(this.contentIds[o-1],n)}async materializeAt(e,n){if(!await this.ensureLoaded()||this.segments.length===0)return null;const o=n?.excludePendingSuggestions===!0;e=Math.max(1,Math.min(this.getTotalUpdates(),e));const r=o?`update-${e}-accepted-only`:`update-${e}`,s=this.docCache.get(r);if(s)return s;await this.ensureHasSegmentFor(e);let i=this.getPlanForUpdateId(e);if(!i)return null;if(await this.ensureBlobsForSegmentStart(i.seg.startUpdateId),i=this.getPlanForUpdateId(e),!i?.seg.snapshotB64)return console.warn("[UpdateHistoryManager] Missing snapshot for segment",i?.seg.startUpdateId),null;const{seg:a}=i;try{const c=Math.min(a.updatesB64.length,a.frameOnly?a.updatesB64.length:e-a.startUpdateId+1);let u;if(o){const f=rt.materializeToYDoc(a.snapshotB64,a.updatesB64,c);try{const $=It.createSuggestionProjectionFromYDoc(f,"reject");try{u=$.doc}finally{$.ydoc.destroy()}}finally{f.destroy()}}else u=await rt.materialize(a.snapshotB64,a.updatesB64,c);return u&&this.docCache.set(r,u),u}catch(c){return console.error("[UpdateHistoryManager] Materialize failed:",{updateId:e,segmentRange:`${a.startUpdateId}-${a.endUpdateId}`,error:c instanceof Error?c.message:String(c)}),null}}async materializeChunkEnd(e,n){if(!await this.ensureLoaded()||this.chunkSegIdx.length===0)return null;const o=Math.max(0,Math.min(this.chunkSegIdx.length-1,Math.floor(e)-1)),r=n?.excludePendingSuggestions===!0?`chunk-end-${e}-accepted-only`:`chunk-end-${e}`,s=this.docCache.get(r);if(s)return s;const i=this.segments[this.chunkSegIdx[o]];await this.ensureBlobsForSegmentStart(i.startUpdateId);const a=await this.materializeAt(i.endUpdateId,n);return a&&this.docCache.set(r,a),a}async materializeChunkSnapshot(e,n){if(!await this.ensureLoaded()||this.chunkSegIdx.length===0)return null;const o=Math.max(0,Math.min(this.chunkSegIdx.length-1,Math.floor(e)-1)),r=this.segments[this.chunkSegIdx[o]];if(await this.ensureBlobsForSegmentStart(r.startUpdateId),!r.snapshotB64)return null;if(n?.excludePendingSuggestions){const s=rt.materializeToYDoc(r.snapshotB64,[],0);try{const i=It.createSuggestionProjectionFromYDoc(s,"reject");try{return i.doc}finally{i.ydoc.destroy()}}finally{s.destroy()}}return rt.materialize(r.snapshotB64,[],0)}async materializeChunkPair(e,n){if(!await this.ensureLoaded()||this.chunkSegIdx.length===0)return null;const o=Math.max(0,Math.min(this.chunkSegIdx.length-1,Math.floor(e)-1)),r=this.segments[this.chunkSegIdx[o]];await this.ensureBlobsForSegmentStart(r.startUpdateId);const s=await this.materializeAt(r.endUpdateId,n);if(!s)return null;if(o>0){const a=this.segments[this.chunkSegIdx[o-1]];await this.ensureBlobsForSegmentStart(a.startUpdateId);const c=await this.materializeAt(a.endUpdateId,n);if(c)return{base:c,target:s}}if(!r.snapshotB64)return null;const i=await this.materializeChunkSnapshot(e,n);return i?{base:i,target:s}:null}__getPlanForTest(e){return this.getPlanForUpdateId(e)}supportsServerHistory(){return this.documentId.length>8}async fetchJson(e){if(this.disposed)throw new Error("Manager disposed");const n={};this.authToken&&(n.Authorization=`Bearer ${this.authToken}`);const o=await fetch(e,{headers:n,credentials:"omit",signal:this.abortController?.signal});if(!o.ok)throw new Error(`HTTP ${o.status}`);return o.json()}readTotalUpdates(e){const n=Number(e.totalUpdates);return!Number.isFinite(n)||n<=0?this.totalUpdates:n}parseFrames(e){return e?e.filter(n=>Number.isFinite(n.updateId)&&Number.isFinite(n.sourceId)&&(n.source==="legacy"||n.source==="delta")).map(n=>({startUpdateId:Number(n.updateId),endUpdateId:Number(n.updateId),snapshotB64:"",updatesB64:[],meta:[{ts:Number(n.timestamp||0),content:!0,userId:n.userId??null,agentName:n.agentName??null}],frameSource:n.source,frameSourceId:Number(n.sourceId),frameOnly:!0})).sort((n,o)=>n.startUpdateId-o.startUpdateId):[]}async refreshNewSegments(){!this.supportsServerHistory()||this.disposed||!this.loaded||await this.withLoadLock(async()=>{const e=`${Mt}/documents/${this.documentId}/history`;try{const n=await this.fetchJson(e);this.totalUpdates=this.readTotalUpdates(n),this.segments=this.parseFrames(n.frames),this.recomputeDerivedData(),this.notifyChange()}catch(n){n.name!=="AbortError"&&console.warn("[UpdateHistoryManager] Failed to refresh segments:",n)}})}async ensureHasSegmentFor(e){if(!this.supportsServerHistory()||this.disposed||this.segments.some(r=>r.startUpdateId<=e&&e<=r.endUpdateId))return;const n=this.targetLocks.get(e);if(n)return n;const o=this.fetchSegmentContaining(e).finally(()=>{this.targetLocks.delete(e)});this.targetLocks.set(e,o),await o}async fetchSegmentContaining(e){if(this.disposed)return;const n=this.getPlanForUpdateId(e)?.seg;if(!n?.frameSource||n.frameSourceId==null)return;const o=new URLSearchParams({source:n.frameSource,sourceId:String(n.frameSourceId)});n.frameSource==="legacy"&&o.set("targetUpdateId",String(e));const r=`${Mt}/documents/${this.documentId}/history/frame?${o.toString()}`;try{const s=await this.fetchJson(r);n.snapshotB64=s.snapshotB64||"",n.updatesB64=s.updatesB64||[]}catch(s){s.name!=="AbortError"&&console.warn("[UpdateHistoryManager] Failed to fetch segment:",{updateId:e,error:s})}}async ensureBlobsForSegmentStart(e){const n=this.segments.find(r=>r.startUpdateId===e);if(n?.snapshotB64&&Array.isArray(n.updatesB64))return;let o=this.blobLocks.get(e);o||(o=this.fetchSegmentContaining(e).finally(()=>{this.blobLocks.delete(e)}),this.blobLocks.set(e,o)),await o}async withLoadLock(e){if(this.loadLock)return this.loadLock;this.loadLock=e();try{await this.loadLock}finally{this.loadLock=null}}mergeInSegments(e){if(e.length===0)return;const n=new Map;for(const o of this.segments)n.set(o.startUpdateId,o);for(const o of e){const r=n.get(o.startUpdateId);if(!r){n.set(o.startUpdateId,o);continue}n.set(o.startUpdateId,{startUpdateId:r.startUpdateId,endUpdateId:Math.max(r.endUpdateId,o.endUpdateId),snapshotB64:r.snapshotB64||o.snapshotB64,updatesB64:(o.updatesB64?.length||0)>=(r.updatesB64?.length||0)?o.updatesB64:r.updatesB64,meta:(o.meta?.length||0)>=(r.meta?.length||0)?o.meta:r.meta,frameSource:o.frameSource||r.frameSource,frameSourceId:o.frameSourceId??r.frameSourceId,frameOnly:o.frameOnly||r.frameOnly})}this.segments=Array.from(n.values()).sort((o,r)=>o.startUpdateId-r.startUpdateId),this.maxEndLoaded=0;for(const o of this.segments)o.endUpdateId>this.maxEndLoaded&&(this.maxEndLoaded=o.endUpdateId)}getPlanForUpdateId(e){if(this.segments.length===0)return null;let n=this.segments.find(r=>r.startUpdateId<=e&&e<=r.endUpdateId);if(!n){const r=this.segments[0],s=this.segments[this.segments.length-1];if(e<r.startUpdateId)n=r;else if(e>s.endUpdateId)n=s;else for(let i=0;i<this.segments.length-1;i++)if(e>this.segments[i].endUpdateId&&e<this.segments[i+1].startUpdateId){n=this.segments[i];break}}if(!n)return null;const o=Math.max(0,Math.min(n.updatesB64.length,e-n.startUpdateId+1));return{seg:n,upto:o}}recomputeDerivedData(){this.docCache.clear(),this.recomputeContentIds(),this.recomputeTimestamps(),this.recomputeChunks()}recomputeContentIds(){const e=[];for(let n=0;n<this.segments.length;n++){const o=this.segments[n];if(o.frameOnly){e.push(o.startUpdateId);continue}const r=o.meta,s=Math.max(o.updatesB64.length,r?.length||0),i=n<2;for(let a=0;a<s;a++)(r?.[a]?.content||i&&a===0)&&e.push(o.startUpdateId+a)}this.contentIds=e}recomputeTimestamps(){this.updateTimestamps.clear();for(const e of this.segments){const n=e.meta;if(n)for(let o=0;o<n.length;o++){const r=e.startUpdateId+o,s=Number(n[o]?.ts||0);s>0&&this.updateTimestamps.set(r,s)}}this.contentTimestamps=this.contentIds.map(e=>this.updateTimestamps.get(e)||0)}recomputeChunks(){const e=this.segments.length;if(e===0){this.chunkSegIdx=[],this.chunkEndUpdateIds=[];return}const n=[];for(let r=0;r<e;r++){if(this.segments[r].frameOnly){n.push(r);continue}const s=this.segments[r].meta,i=Array.isArray(s)&&s.some(c=>c?.content),a=r<2;(i||a)&&n.push(r)}const o=e-1;(n.length===0||n[n.length-1]!==o)&&n.push(o),this.chunkSegIdx=n,this.chunkEndUpdateIds=n.map(r=>this.segments[r].endUpdateId)}notifyChange(){if(!this.disposed)for(const e of this.changeObservers.slice())try{e()}catch(n){console.error("[UpdateHistoryManager] Observer error:",n)}}}const ur=()=>{},hr=async()=>{},mr=new Set;function Dt(t,e){for(const n of mr)try{n(t,e)}catch{}}const gr=new Proxy({track:(t,e)=>Dt(t,e),trackAgentToolInvoked:(t,e,n,o=!1)=>Dt("Agent Tool Invoked",{tool:t,documentId:e??void 0,directMode:o}),trackDocumentExported:(t,e,n)=>Dt("Document Exported",{documentId:t,format:e,source:n}),getCheckoutAttribution:()=>null,flush:hr},{get(t,e){return e in t?t[e]:ur}});class Wt{constructor(e,n,o,r){this.isViewingRevision=!1,this.documentChangeObservers=[],this.isReadOnly=!1,this.timeTravelActive=!1,this.viewModeObservers=[],this.historyOpen=!1,this.historyDiffEnabled=!0,this.historySelection={start:null,end:null},this.historyObservers=[],this.notesObservers=[],this.notesValue="",this.cleanupCallbacks=[],this.disposed=!1,this.historyManager=null,this.sharedWriteAccess=null,this.autocorrectEnabled=!0,this.suggestionDecisionsAllowed=!0,this.documentId=e,this.sharedStyleMigrationPermit=r?.sharedStyleMigrationPermit,this.authToken=r?.authToken,this.onTitleChange=o;const s=r?.disableProposalPersistence??!!r?.authToken;if(this.preprocessorSession=new Ro,vt(n)){const c=n;if(this.ydoc=an(c,this.sharedStyleMigrationPermit?{sharedStyles:this.sharedStyleMigrationPermit.formatGateConfirmed===!0&&this.sharedStyleMigrationPermit.exclusive===!0}:void 0),c.pendingDocxCarrier){const u=c.pendingDocxCarrier;delete c.pendingDocxCarrier,Ko(this.ydoc,u.bytes,{hash:u.hash})}c.pageless!==void 0&&this.ydoc.getMap("metadata").set("pageless",c.pageless),this.currentDocument=this.cloneDoc(c)}else{this.ydoc=n;const c=De(this.ydoc);this.currentDocument=this.cloneDoc(c)}Po(this.ydoc),vt(n)&&(this.sharedWriteAccess=!0),this.documentMutator=new It(De(this.ydoc),(c,u)=>this.updateWorkingDocument(c,u),this.onTitleChange,this.ydoc,e,s,this.preprocessorSession,{canRepairIdentity:()=>this.sharedWriteAccess===!0,deferIdentityRepair:!vt(n)}),this.documentMutator.identityRepairedOnConstruct&&(this.currentDocument=this.cloneDoc(De(this.ydoc))),this.notesValue=this.documentMutator.getDocumentNotes();try{this.documentMutator.backfillLiveSuggestionTreeRecords(),this.documentMutator.reconcileFootnotes(),this.documentMutator.migrateChromeOutOfContent(),this.documentMutator.migrateNotesOutOfContent(),this.documentMutator.migrateLegacyHeaderFooterMetadata(),this.documentMutator.migrateLegacyPageNumbers()}catch{}this.backfillStylesheetSidecar(),this.cleanupCallbacks.push($o(this.ydoc,c=>{console.warn(`[DocumentSession] repaired a duplicate seed: removed ${c.removedBlocks} blocks from ${c.losingClaims} losing seed(s)`)}));const i=this.ydoc.getMap("metadata"),a=c=>{if(c.keysChanged.has("notes")){const u=this.documentMutator.getDocumentNotes();u!==this.notesValue&&(this.notesValue=u,this.notifyNotesObservers())}};if(i.observe(a),this.cleanupCallbacks.push(()=>i.unobserve(a)),!r?.disableHistory){this.historyManager=new dr(this.documentId,this.ydoc,{authToken:this.authToken});const c=()=>{this.historyManager?.notifyDocUpdated()};this.ydoc.on("update",c),this.cleanupCallbacks.push(()=>this.ydoc.off("update",c))}}static fromDocRoot(e,n){return new Wt("no-id",e,n)}getDocumentId(){return this.documentId}dispose(){if(!this.disposed){this.disposed=!0;for(const e of this.cleanupCallbacks.splice(0))e();this.documentMutator.dispose(),this.historyManager?.dispose(),this.historyManager=null,this.documentChangeObservers=[],this.viewModeObservers=[],this.historyObservers=[],this.notesObservers=[]}}setReadOnly(){this.isReadOnly=!0}setReadWrite(){this.isReadOnly=!1}setSharedWriteAccess(e){const n=e&&this.sharedWriteAccess!==!0;this.sharedWriteAccess=e,n&&this.documentMutator.repairDocumentIdentity()&&this.notifyDocumentChange(this.documentMutator.getDocument(),{origin:"local"}),n&&this.sharedStyleMigrationPermit&&(Mo(this.ydoc,this.sharedStyleMigrationPermit),this.sharedStyleMigrationPermit=void 0)}setSuggestingMode(e){this.documentMutator.setSuggestingMode(e)}isSuggestingMode(){return this.documentMutator.isSuggestingMode()}getWorkingDocument(){return this.documentMutator.getDocument()}getDocumentWithoutPendingSuggestions(){return this.documentMutator.getLiveSuggestionIds().length>0?this.documentMutator.getDocumentWithRejectedSuggestions():this.getWorkingDocument()}getWorkingDocumentBeforePendingReview(){return this.getDocumentWithoutPendingSuggestions()}getDocumentWithPendingSuggestionsApplied(e){if(e?.conversationId!==void 0&&this.documentMutator.setDetachedSuggestionConversation(e.conversationId??null,e.serverDetachedSuggestions),this.documentMutator.getLiveSuggestionIds().length>0)return this.documentMutator.getDocumentWithAcceptedSuggestions();const n=this.documentMutator.getDetachedSuggestionStore(),o=n.getPendingSuggestions();if(o.size===0)return this.getWorkingDocument();const r=Array.from(o.keys()),s=n.materializeWithSuggestions(r);return De(s)}getCurrentDocument(){return this.currentDocument}updateWorkingDocument(e,n={origin:"unknown"}){!this.isViewingRevision&&!this.historyOpen&&(this.currentDocument=e),this.logUnresolvableLiveSuggestions(n),this.notifyDocumentChange(this.currentDocument,n)}logUnresolvableLiveSuggestions(e){const n=this.documentMutator.getLiveSuggestionIds();if(n.length===0)return;const o=this.documentMutator.getUnresolvableLiveSuggestionRecords(),r=o.filter(s=>s.source==="agent");this.documentId,e.origin,n.length,o.length,r.length}countPrunedByKey(e,n){return e.reduce((o,r)=>{const s=r[n]||"unknown";return o[s]=(o[s]??0)+1,o},{})}trackPrunedUnresolvableLiveSuggestions(e,n,o){const r=this.documentMutator.takeLastPrunedUnresolvableLiveSuggestions();if(r.length===0)return;const s=r.filter(a=>a.source==="agent").length,i={Document:this.documentId,Action:e,RequestedSuggestionCount:new Set(n).size,ResolvedSuggestionCount:o,PrunedSuggestionCount:r.length,PrunedAgentSuggestionCount:s,PrunedSuggestionTypes:this.countPrunedByKey(r,"type"),PrunedSuggestionSources:this.countPrunedByKey(r,"source"),PrunedSuggestions:r};gr.track("Live Suggestions Pruned",i)}onDocumentChange(e){return this.documentChangeObservers.push(e),()=>{const n=this.documentChangeObservers.indexOf(e);n>-1&&this.documentChangeObservers.splice(n,1)}}notifyDocumentChange(e,n={origin:"unknown"}){const o=e??this.getCurrentDocument();this.documentChangeObservers.forEach(r=>{try{r(o,n)}catch(s){console.error("Error in document change observer:",s)}})}exitRevisionView(){this.isViewingRevision=!1,this.currentDocument=this.getWorkingDocument(),this.notifyViewModeChange(),this.notifyDocumentChange()}getDocumentMutator(){return this.documentMutator}async getDocumentSnapshotAtOrBefore(e){if(!this.historyManager||!Number.isFinite(e)||e<=0)return null;const n=await this.historyManager.findLatestUpdateIdBeforeTimestamp(e);return n===null?null:this.historyManager.materializeAt(n,{excludePendingSuggestions:!0})}getDocumentNotes(){return this.notesValue}setDocumentNotes(e){if(this.isReadOnly)return;const n=typeof e=="string"?e:String(e??"");n!==this.notesValue&&(this.notesValue=n,this.documentMutator.setNotes(n),this.notifyNotesObservers())}onNotesChange(e){return this.notesObservers.push(e),()=>{const n=this.notesObservers.indexOf(e);n>=0&&this.notesObservers.splice(n,1)}}getPreprocessorSession(){return this.preprocessorSession}getRevisionManager(){return null}getYDoc(){return this.ydoc}registerRemoteOrigin(e){this.documentMutator.registerRemoteOrigin(e)}unregisterRemoteOrigin(e){this.documentMutator.unregisterRemoteOrigin(e)}setTimeTravelActive(e){this.timeTravelActive=!!e}isTimeTravelActive(){return this.timeTravelActive}onViewModeChange(e){return this.viewModeObservers.push(e),()=>{const n=this.viewModeObservers.indexOf(e);n>=0&&this.viewModeObservers.splice(n,1)}}openHistory(){this.historyOpen=!0,this.notifyHistoryChange()}closeHistory(){this.historyOpen=!1,this.notifyHistoryChange()}isHistoryOpen(){return this.historyOpen}setDiffEnabled(e){this.historyDiffEnabled=!!e,this.notifyHistoryChange()}isDiffEnabled(){return this.historyDiffEnabled}setSelection(e){this.historySelection={start:e.start??null,end:e.end??null},this.notifyHistoryChange()}getSelection(){return{...this.historySelection}}onHistoryStateChange(e){return this.historyObservers.push(e),()=>{const n=this.historyObservers.indexOf(e);n>=0&&this.historyObservers.splice(n,1)}}notifyHistoryChange(){for(const e of this.historyObservers.slice())try{e()}catch(n){console.error("[DocumentSession] History observer error:",n)}}backfillStylesheetSidecar(){try{const e=this.ydoc.getMap("metadata"),n=e.get("stylesXml");if(typeof n!="string"||n.length===0||e.get("stylesheet")!==void 0)return;import("./DocxConverter-BCEB7jWY.js").then(({DocxConverter:o})=>{if(this.isReadOnly||this.isViewingRevision||e.get("stylesheet")!==void 0)return;const r=o.resolveStylesheetFromStylesXml(n,this.currentDocument.pageLayout);r&&this.ydoc.transact(()=>{e.set("stylesheet",r)})}).catch(()=>{})}catch{}}notifyNotesObservers(){const e=this.getDocumentNotes();for(const n of this.notesObservers.slice())try{n(e)}catch(o){console.error("[DocumentSession] Notes observer error:",o)}}async applySelection(e){const n=this.historyManager;if(!n||!e)return;const o=this.historyDiffEnabled,r=this.historySelection;await n.ensureLoaded();const s=n.getTotalUpdates?.()||0;if(s<=0)return;const i=_=>Math.max(1,Math.min(s,Math.floor(_))),a=async _=>await n.materializeAt?.(i(_),{excludePendingSuggestions:!0}),c=()=>this.getDocumentWithoutPendingSuggestions(),u=_=>{try{e.getEditor?.()?.setDisplayDocument?.(_)}catch(g){console.error("[DocumentSession] Failed to set display document:",g)}},f=async _=>{const g=await a(_);if(g){try{e.clearDiffPresentation?.()}catch(y){console.error("[DocumentSession] Failed to clear diff presentation:",y)}u(g)}},$=async(_,g)=>{const y=await a(_),q=await a(g);!y||!q||(e.showDiffBetweenDocuments?.(y,q),u(q))},T=async _=>{const g=await a(_),y=c();!g||!y||(e.showDiffBetweenDocuments?.(g,y),u(y))},R=r.start,P=r.end;if(R!=null&&P!=null&&R!==P){const _=i(R),g=i(P),y=Math.min(_,g),q=Math.max(_,g);o?await $(y,q):await f(q);return}const U=typeof R=="number"?R:null;if(U==null)return;const D=i(U);if(D<=1){await f(1);return}if(o)if(D===s)try{const _=await a(s),g=c();JSON.stringify(_)===JSON.stringify(g)?s>1?await $(s-1,s):await f(1):await T(s)}catch{await T(s)}else D>1?await $(D-1,D):await f(D);else await f(D)}async showDiffBetweenHistoryUpdates(e,n,o){const r=this.historyManager;if(!r||!e)return!1;const s=Math.min(n,o),i=Math.max(n,o);if(!Number.isFinite(s)||!Number.isFinite(i)||s<=0||i<=s||!await r.ensureLoaded())return!1;const a=r.getTotalUpdates?.()??0;return i>a?!1:(this.openHistory(),this.setDiffEnabled(!0),this.setSelection({start:s,end:i}),await this.applySelection(e),!0)}notifyViewModeChange(){const e=this.isViewingRevision;this.viewModeObservers.forEach(n=>{try{n(e)}catch{}})}getStorageType(){return this.ydoc.getMap("metadata").get("storageType")}getParentFolderId(){const e=this.ydoc.getMap("metadata").get("parentFolderId");return typeof e=="string"&&e.length>0?e:null}getHistoryManager(){return this.historyManager}attachDemoHistoryManager(e){this.historyManager=e}async jumpToUpdateId(e){const n=await this.historyManager?.materializeAt(e,{excludePendingSuggestions:!0});return n?(this.currentDocument=this.cloneDoc(n),this.notifyDocumentChange(),!0):!1}async jumpToContentIndex(e){const n=this.historyManager;if(!n?.materializeAtContentIndex)return!1;const o=await n.materializeAtContentIndex(e,{excludePendingSuggestions:!0});return o?(this.currentDocument=this.cloneDoc(o),this.notifyDocumentChange(),!0):!1}cloneDoc(e){return JSON.parse(JSON.stringify(e))}getPagelessMode(){return this.documentMutator.getPagelessMode()}setPagelessMode(e){this.documentMutator.setPagelessMode(e)}getPageLayoutSettings(){return this.documentMutator.getPageLayoutSettings()}setPageLayoutSettings(e){this.documentMutator.setPageLayoutSettings(e)}getIndentStepPx(){return this.documentMutator.getIndentStepPx()}setAutocorrectEnabled(e){this.autocorrectEnabled=e}isAutocorrectEnabled(){return this.autocorrectEnabled}insertText(e,n,o,r){return this.documentMutator.insertText(e,n,o,r)}getAfterOperationSelection(){return this.documentMutator.getAfterOperationSelection()}insertFormattedText(e,n,o,r,s){return this.documentMutator.insertFormattedText(e,n,o,r,s)}deleteText(e,n,o,r){return this.documentMutator.deleteText(e,n,o,r)}deleteSelection(e,n,o,r){return this.documentMutator.deleteSelection(e,n,o,r)}deleteBlock(e,n,o){return this.documentMutator.deleteBlock(e,n,o)}deleteBlockById(e,n,o){return this.documentMutator.deleteBlockById(e,n,o)}insertBlock(e,n,o,r){return this.documentMutator.insertBlock(e,n,o,r)}insertBlockAfterId(e,n,o,r){return this.documentMutator.insertBlockAfterId(e,n,o,r)}insertBlockBeforeId(e,n,o,r){return this.documentMutator.insertBlockBeforeId(e,n,o,r)}insertBlockIntoParent(e,n,o,r){return this.documentMutator.insertBlockIntoParent(e,n,o,r)}insertBlockAtStart(e,n,o){return this.documentMutator.insertBlockAtStart(e,n,o)}insertBlockAtEnd(e,n,o){return this.documentMutator.insertBlockAtEnd(e,n,o)}updateBlock(e,n,o,r){return this.documentMutator.updateBlock(e,n,o,r)}updateBlockById(e,n,o,r){return this.documentMutator.updateBlockById(e,n,o,r)}replaceParagraphById(e,n,o,r){return this.documentMutator.replaceParagraphById(e,n,o,r)}toggleTodoItem(e,n,o,r,s){return this.documentMutator.toggleTodoItem(e,n,o,r,s)}toggleTodoItemById(e,n,o,r,s){return this.documentMutator.toggleTodoItemById(e,n,o,r,s)}setListItemIndent(e,n,o,r,s){return this.documentMutator.setListItemIndent(e,n,o,r,s)}splitParagraph(e,n){return this.documentMutator.splitParagraph(e,n)}applyFormatting(e,n,o,r,s){return this.documentMutator.applyFormatting(e,n,o,r,s)}setSelectionAfterOperation(e){this.documentMutator.setSelectionAfterOperation(e)}setFontFamily(e,n,o,r){return this.documentMutator.setFontFamily(e,n,o,r)}setFontSize(e,n,o,r){return this.documentMutator.setFontSize(e,n,o,r)}setLetterSpacing(e,n,o,r){return this.documentMutator.setLetterSpacing(e,n,o,r)}setTextColor(e,n,o,r){return this.documentMutator.setTextColor(e,n,o,r)}setBackgroundColor(e,n,o,r){return this.documentMutator.setBackgroundColor(e,n,o,r)}clearFormatting(e,n,o){return this.documentMutator.clearFormatting(e,n,o)}setLink(e,n,o,r){return this.documentMutator.setLink(e,n,o,r)}setCodeBlockLanguage(e,n){return this.documentMutator.setCodeBlockLanguage(e,n)}setCodeBlockRenderDiagram(e,n){return this.documentMutator.setCodeBlockRenderDiagram(e,n)}setCodeBlockShowDiagramSource(e,n){return this.documentMutator.setCodeBlockShowDiagramSource(e,n)}setMathBlockContent(e,n){return this.documentMutator.setMathBlockContent(e,n)}setMathBlockDisplayMode(e,n){return this.documentMutator.setMathBlockDisplayMode(e,n)}setMathBlockAlign(e,n){return this.documentMutator.setMathBlockAlign(e,n)}replaceParagraph(e,n,o,r){return this.documentMutator.replaceParagraph(e,n,o,r)}pasteParagraphs(e,n,o,r={}){return this.documentMutator.pasteParagraphs(e,n,o,r)}canUndo(){return this.documentMutator.canUndo()}canRedo(){return this.documentMutator.canRedo()}undo(){return this.documentMutator.undo()}redo(e){return this.documentMutator.redo(e)}getLiveSuggestionIdsBySource(e){return this.documentMutator.getLiveSuggestionIdsBySource(e)}getLiveSuggestionIdsByCommentThread(e){return this.documentMutator.getLiveSuggestionIdsByCommentThread(e)}getInlineSuggestionMetadataFromDocument(e){return this.documentMutator.getInlineSuggestionMetadataFromDocument(e)}setSuggestionDecisionsAllowed(e){this.suggestionDecisionsAllowed=e}canDecideSuggestions(){return this.suggestionDecisionsAllowed}refusedDecision(e){return{decision:e.decision,scope:e.scope,resolvedCount:0,initialSuggestionIds:[],attemptedSuggestionIds:[],attemptedSuggestionIdCount:0,prunedSuggestions:[]}}decideLiveSuggestions(e){return this.suggestionDecisionsAllowed?this.decideLiveSuggestionsUnchecked(e):this.refusedDecision(e)}decideLiveSuggestionsUnchecked(e){const n=this.documentMutator.decideLiveSuggestions(e);return this.trackPrunedUnresolvableLiveSuggestions(e.decision,n.attemptedSuggestionIds,n.resolvedCount),n}acceptLiveSuggestions(e){return this.decideLiveSuggestions({decision:"accept",scope:{kind:"ids",suggestionIds:e}}).resolvedCount}acceptLiveSuggestionsBySource(e){return this.decideLiveSuggestions({decision:"accept",scope:{kind:"source",source:e}})}nativeAgentLiveSuggestionIds(){return this.documentMutator.getLiveSuggestionIdsBySource("agent").filter(e=>Go(this.documentMutator.getInlineSuggestionMetadataFromDocument(e)?.agentName??this.documentMutator.getLiveSuggestion(e)?.agentName))}rollbackAgentSuggestions(e){const n=this.nativeAgentLiveSuggestionIds().map(i=>{const a=this.documentMutator.getInlineSuggestionMetadataFromDocument(i),c=this.documentMutator.getLiveSuggestion(i);return{suggestionId:i,agentConversationId:a?.agentConversationId??c?.agentConversationId,agentRequestId:a?.agentRequestId??c?.agentRequestId,agentTurn:a?.agentTurn??c?.agentTurn}}).filter(i=>i.agentConversationId===e.agentConversationId&&typeof i.agentRequestId=="number"&&typeof i.agentTurn=="number"),o=e.requestId??n.reduce((i,a)=>{const c=a.agentRequestId;return c>=e.currentRequestId?i:i===void 0||c>i?c:i},void 0);if(o===void 0)return{suggestionIds:[],resolvedCount:0};const r=n.filter(i=>e.turn===void 0&&i.agentRequestId>=o||e.turn!==void 0&&i.agentRequestId===o&&i.agentTurn===e.turn).map(i=>i.suggestionId);if(r.length===0)return{requestId:o,turn:e.turn,suggestionIds:[],resolvedCount:0};const s=this.decideLiveSuggestionsUnchecked({decision:"reject",scope:{kind:"ids",suggestionIds:r},historyOrigin:`agent-suggestion-rollback:${e.agentConversationId}:${o}:${e.turn??"all"}:by-${e.currentRequestId}:${e.currentTurn}`});return{requestId:o,turn:e.turn,suggestionIds:r,resolvedCount:s.resolvedCount}}setSuggestionAuthorName(e){this.documentMutator.setDefaultSuggestionAuthorName(e)}acceptLiveSuggestionsByAuthor(e){return this.suggestionDecisionsAllowed?this.documentMutator.acceptLiveSuggestionsByAuthor(e):this.refusedDecision({decision:"accept",scope:{kind:"author",authorName:e}})}rejectLiveSuggestionsByAuthor(e){return this.suggestionDecisionsAllowed?this.documentMutator.rejectLiveSuggestionsByAuthor(e):this.refusedDecision({decision:"reject",scope:{kind:"author",authorName:e}})}acceptLiveSuggestionsByKind(e){return this.suggestionDecisionsAllowed?this.documentMutator.acceptLiveSuggestionsByKind(e):this.refusedDecision({decision:"accept",scope:{kind:"suggestion-kind",suggestionKind:e}})}rejectLiveSuggestionsByKind(e){return this.suggestionDecisionsAllowed?this.documentMutator.rejectLiveSuggestionsByKind(e):this.refusedDecision({decision:"reject",scope:{kind:"suggestion-kind",suggestionKind:e}})}acceptAgentSuggestions(){return this.decideLiveSuggestions({decision:"accept",scope:{kind:"ids",suggestionIds:this.nativeAgentLiveSuggestionIds()}})}rejectLiveSuggestions(e){return this.decideLiveSuggestions({decision:"reject",scope:{kind:"ids",suggestionIds:e}}).resolvedCount}rejectLiveSuggestionsBySource(e){return this.decideLiveSuggestions({decision:"reject",scope:{kind:"source",source:e}})}rejectAgentSuggestions(){return this.decideLiveSuggestions({decision:"reject",scope:{kind:"ids",suggestionIds:this.nativeAgentLiveSuggestionIds()}})}beginGroup(e){this.documentMutator.beginGroup(e)}endGroup(){this.documentMutator.endGroup()}clearHistory(){this.documentMutator.clearHistory()}getHistoryInfo(){return this.documentMutator.getHistoryInfo()}setCurrentDocument(e){this.currentDocument=this.cloneDoc(e),this.notifyDocumentChange()}hasUncommittedChanges(){return!1}getDetachedSuggestionStore(){return this.documentMutator.getDetachedSuggestionStore()}clearLegacyDetachedSuggestionState(){this.documentMutator.clearLegacyDetachedSuggestionState()}migrateLegacyDetachedSuggestionsToLiveSuggestions(e){return this.documentMutator.migrateLegacyDetachedSuggestionsToLiveSuggestions(e)}applyAgentActions(e,n,o){return o?.startNewTurn!==!1&&this.preprocessorSession.startNewTurn(),this.documentMutator.applyAgentActions(e,n,{optimizeStyleFormatting:o?.optimizeStyleFormatting})}}const Tt=new Set(["edit_table_cells","import_attachment_into_document","insert_block","insert_footnote","replace_block","set_block_attribute","style_blocks","clear_formatting","append_to_paragraph","break_paragraph","join_paragraphs","replace","replace_all","replace_many","rollback_agent_suggestions","leave_comment","remove_blocks","remove_block","set_title","set_notes","set_page_layout","set_header_footer","insert_table_row","remove_table_row","insert_table_column","remove_table_column"]),pr=new Set(["pending","in_progress","completed","blocked","cancelled"]);function fr(t){if(t===void 0)return[];if(!Array.isArray(t)||!t.length||t.length>4)throw new Error("work must contain one to four independent work or completion calls; emit other independent calls normally in the same response.");return t.map(e=>{if(!e||typeof e.name!="string"||!e.name.trim()||["create_plan","update_plan"].includes(e.name)||!e.arguments||typeof e.arguments!="object"||Array.isArray(e.arguments))throw new Error("Each work call requires a non-plan tool name and an arguments object.");return{name:e.name,arguments:structuredClone(e.arguments)}})}function bn(t){if(!Array.isArray(t)||t.some(e=>typeof e!="string"||!e.trim()))throw new Error("steps must be an array of non-empty strings.");return t.map(e=>e.trim())}function yn(t,e,n){if(fr(n.work),e==="create_plan"){if(typeof n.objective!="string"||!n.objective.trim())throw new Error("objective is required.");const a=bn(n.steps);if(!a.length)throw new Error("A plan requires at least one step.");if(t.plan&&n.supersedes_plan_id!==t.plan.id)throw new Error(`To start a new task, explicitly set supersedes_plan_id to ${t.plan.id}. Use update_plan for steering the existing task.`);if(!t.plan&&n.supersedes_plan_id!=null)throw new Error("There is no plan to supersede.");const c=`plan_${t.nextPlanNumber}`;return{nextPlanNumber:t.nextPlanNumber+1,plan:{id:c,objective:n.objective.trim(),items:a.map((u,f)=>({id:`${c}_item_${f+1}`,step:u,status:"pending"}))}}}const o=t.plan;if(!o||n.plan_id!==o.id)throw new Error(`Use the current plan_id: ${o?.id??"no plan; call create_plan first"}.`);const r=n.add_steps===void 0?[]:bn(n.add_steps),s=n.updates===void 0?[]:n.updates;if(!Array.isArray(s))throw new Error("updates must be an array.");const i=new Set;for(const a of s){if(!a||typeof a!="object"||!o.items.some(c=>c.id===a.item_id)||!pr.has(a.status)||Object.keys(a).some(c=>!["item_id","status"].includes(c))||i.has(a.item_id))throw new Error("Each update requires a unique existing item_id and valid status. Step text is immutable; add a new item and cancel the old item to change a requirement.");i.add(a.item_id)}if(!s.length&&!r.length)throw new Error("Provide updates or add_steps.");return{nextPlanNumber:t.nextPlanNumber,plan:{...o,items:[...o.items.map(a=>({...a,status:s.find(c=>c.item_id===a.id)?.status??a.status})),...r.map((a,c)=>({id:`${o.id}_item_${o.items.length+c+1}`,step:a,status:"pending"}))]}}}const _n=50,br=32*1024;function yr(t,e){const n=[];if(Je(t.cell,c=>n.push(c.id)),n.length)return{id:t.cell.id,column:t.col,kind:"rich",truncated:!0,block_ids:t.cell.children.map(c=>c.id),text:`Contains nested tables. Read them with read_table: ${n.slice(0,20).join(", ")}. Read other nested blocks separately. This preview does not authorize replacement.`};const o=Bt(t.cell),r=lt(t.cell);let s={id:t.cell.id,column:t.col,kind:r?"empty":o?"text":"rich",row_span:t.rowSpan,col_span:t.colSpan,block_ids:de(t.cell)};const i=(o?.children.find(c=>c.text)??o?.children[0])?.marks,a=i?st(i):void 0;return s.formatting={cell:st(t.cell),...o?{paragraph:st(o),text_marks:a&&Object.keys(a).length?a:void 0}:{}},o||r?s.text=vn(t.cell):s.html=e?.(t.cell)??"Rich content; read nested blocks before editing.",JSON.stringify(s).length>2e4&&(s={id:t.cell.id,column:t.col,kind:s.kind,truncated:!0,text:"Content omitted: use cell_text with this cell_id, or read a nested block. This preview does not authorize replacement."}),s}const _r=/^(oxml|docx)/;function st(t){return Object.fromEntries(Object.entries(t).filter(([e])=>!["type","id","children"].includes(e)&&!_r.test(e)))}const kr=new Set(["bold","italic","underline","strikethrough","doubleStrikethrough","smallCaps","allCaps","hidden","letterSpacing","lang","code","superscript","subscript","fontSize","color","backgroundColor","fontFamily"]),wr=t=>JSON.stringify(Object.fromEntries(Object.entries(t).sort(([e],[n])=>e.localeCompare(n))));function de(t){if(!t||typeof t!="object")return[];const e=t;return[...e.id?[e.id]:[],...At(t).flatMap(de)]}function At(t){const e=t;return[e.children,e.notes,e.chrome].flatMap(n=>Array.isArray(n)?n:[])}const it=24e3,vr=2e3;function Ir(t,e,n,o,r){const s=n.map(f=>t.children[f].id),i=s.reduce((f,$)=>$.length>f.length?$:f,""),a=f=>({table_id:t.id,...f,column_start:e.cols,column_count:e.cols,continuation_revision:r}),c=a(o===null?{row_ids:s}:{row_start:e.rows,row_count:o}),u=f=>JSON.stringify(f).length-1;return Math.max(u({next_row:e.rows,next_read:c}),u({next_row:e.rows,next_column:e.cols,next_read:a({row_ids:[i]}),following_read:c,remaining_row_ids:s}))}function at(t,e,n){const o=Ae(t,String(e.table_id??"")),r={table_id:String(e.table_id??""),row_count:0,column_count:0,revision:"",columns:[],unplaced_cell_ids:[],rows:[],complete_cell_ids:[]};if(!o)return{...r,error:"Unknown table_id."};const s=Te(o);r.row_count=s.rows,r.column_count=s.cols,r.revision=ye([o.columnWidths,o.children.map(g=>[g.id,g.children.map(y=>[y.id,y.rowSpan,y.colSpan])])]),r.columns=Array.from({length:s.cols},(g,y)=>({column:y,empty:0,filled:0,covered:0}));for(let g=0;g<s.rows;g++)for(let y=0;y<s.cols;y++){const q=s.occupancy[g][y];q&&(q.row!==g||q.col!==y?r.columns[y].covered++:lt(q.cell)?r.columns[y].empty++:r.columns[y].filled++)}const i=o.children.flatMap(g=>g.children.filter(y=>!s.byId.has(y.id)).map(y=>y.id));r.unplaced_cell_count=i.length;let a=2;for(const g of i){if(r.unplaced_cell_ids.length>=100)break;const y=JSON.stringify(g).length+(r.unplaced_cell_ids.length?1:0);a+y>vr||(r.unplaced_cell_ids.push(g),a+=y)}const c=Number.isInteger(e.column_start)&&Number(e.column_start)>=0?Number(e.column_start):0;r.columns=r.columns.slice(c,c+100),c+100<s.cols&&(r.next_summary={table_id:o.id,mode:"summary",column_start:c+100});const u=e.mode??"rows";if(u==="summary")return r;if(u==="cell_text"){const g=s.byId.get(String(e.cell_id??""));if(!g)return{...r,error:"Unknown cell_id."};const y=ye(g.cell);if(e.continuation_revision!=null&&e.continuation_revision!==y)return{...r,error:"Cell changed since the previous window; restart at text_offset=0."};const q=e.text_offset??0,A=Cr(g.cell);if("error"in A)return{...r,error:A.error};const w=A.text;if(!Number.isInteger(q)||Number(q)<0||Number(q)>w.length)return{...r,error:"Invalid text_offset."};if(Number(q)>0&&/[\uDC00-\uDFFF]/u.test(w.charAt(Number(q))))return{...r,error:"text_offset splits a Unicode character."};const O=it-JSON.stringify({...r,revision:y,cell_id:g.cell.id,text:"",text_offset:Number(q),next_text_offset:w.length}).length,z=Math.min(w.length,Number(q)+8e3);let K=Number(q),d=0;for(;K<z;){const C=/[\uD800-\uDBFF]/.test(w.charAt(K))&&/[\uDC00-\uDFFF]/.test(w.charAt(K+1))?2:1;if(K+C>z)break;const ce=JSON.stringify(w.slice(K,K+C)).length-2;if(d+ce>O)break;d+=ce,K+=C}return K===Number(q)&&K<w.length?{...r,error:"This cell's text cannot fit beside the table summary within 24,000 characters."}:{...r,revision:y,cell_id:g.cell.id,text:w.slice(Number(q),K),text_offset:Number(q),...K<w.length?{next_text_offset:K}:{}}}if(u!=="rows")return{...r,error:"mode must be summary, rows, or cell_text."};if(e.continuation_revision!=null&&e.continuation_revision!==r.revision)return{...r,error:"Table geometry changed since the previous window; reread the summary and resume using stable row_ids."};const f=e.row_start??0,$=e.row_count??25,T=e.column_start??0,R=e.column_count??s.cols;if(![f,$,T,R].every(g=>Number.isInteger(g))||Number(f)<0||Number($)<1||Number($)>50||Number(T)<0||Number(R)<1)return{...r,error:"Invalid row or column window (maximum 50 rows)."};let P;if(e.row_ids!=null){if(!Array.isArray(e.row_ids)||!e.row_ids.length||e.row_ids.length>50||new Set(e.row_ids).size!==e.row_ids.length)return{...r,error:"row_ids requires 1-50 unique row IDs."};if(P=e.row_ids.map(g=>o.children.findIndex(y=>y.id===g)),P.some(g=>g<0))return{...r,error:"Unknown row_id; nothing read."}}else P=Array.from({length:Math.max(0,Math.min(Number($),s.rows-Number(f)))},(g,y)=>Number(f)+y);if(Number(T)>=s.cols)return{...r,error:`column_start is beyond the table's ${s.cols} columns.`};let U=JSON.stringify(r).length;const D=Ir(o,s,P,e.row_ids==null?Number($):null,r.revision);for(const g of P){const y={row_id:o.children[g].id,row_index:g,cells:[]},q=JSON.stringify({...y,cells:[]}).length+(r.rows.length?1:0);for(let A=Number(T);A<Math.min(s.cols,Number(T)+Number(R));A++){const w=s.occupancy[g][A];let O;w?w.row!==g||w.col!==A?O={id:"",column:A,kind:"covered",anchor_id:w.cell.id}:O=yr(w,n):O={id:"",column:A,kind:"unplaced"};const z=!!w&&w.row===g&&w.col===A&&!O.truncated&&!!(Bt(w.cell)||lt(w.cell)||n),K=(C,ce)=>(y.cells.length?1:q)+JSON.stringify(C).length+(ce?JSON.stringify(C.id).length+(r.complete_cell_ids.length?1:0):0);let d=K(O,z);if(U+d+D>it&&!r.rows.length&&!y.cells.length){if(O={id:O.id,column:A,kind:O.kind,truncated:!0,text:"Content omitted: this cell does not fit in a row window. Page its text with mode=cell_text and this cell_id, or read a nested block. This preview does not authorize replacement."},d=K(O,!1),U+d+D>it)return{...r,error:"This table window cannot fit even one cell preview within 24,000 characters. Read fewer columns with column_start and column_count, request fewer row_ids, or page one cell with mode=cell_text."};y.cells.push(O),U+=d;continue}if(U+d+D>it){if(r.rows.length){const ce=new Set(y.cells.map(me=>me.id));return r.complete_cell_ids=r.complete_cell_ids.filter(me=>!ce.has(me)),r.next_row=g,r.next_read={table_id:o.id,...e.row_ids==null?{row_start:g,row_count:Number($)}:{row_ids:P.slice(P.indexOf(g)).map(me=>o.children[me].id)},column_start:Number(T),column_count:Number(R),continuation_revision:r.revision},r}y.cells.length&&r.rows.push(y),r.next_row=g,r.next_column=A,r.next_read={table_id:o.id,row_ids:[o.children[g].id],column_start:A,column_count:Math.min(s.cols,Number(T)+Number(R))-A,continuation_revision:r.revision};const C=P.slice(P.indexOf(g)+1).map(ce=>o.children[ce].id);return e.row_ids==null&&g+1<s.rows?r.following_read={table_id:o.id,row_start:g+1,row_count:Number($),column_start:Number(T),column_count:Number(R),continuation_revision:r.revision}:C.length&&(r.following_read={table_id:o.id,row_ids:C,column_start:Number(T),column_count:Number(R),continuation_revision:r.revision}),r.remaining_row_ids=C,r}y.cells.push(O),U+=d,z&&r.complete_cell_ids.push(w.cell.id)}r.rows.push(y)}const _=P.at(-1);return e.row_ids==null&&_!==void 0&&_+1<s.rows&&(r.next_row=_+1,r.next_read={table_id:o.id,row_start:_+1,row_count:Number($),column_start:Number(T),column_count:Number(R),continuation_revision:r.revision}),r}function We(t,e,n){if(!e?.scopedTableIds?.length)return n;const o=new Set(n);for(const r of e.scopedTableIds){const s=Ae(t,r);if(!s)continue;for(const u of de(s))o.delete(u);const i=u=>{const f=u,$=f.id===r||At(u).map(i).some(Boolean);return $&&f.id&&o.delete(f.id),$};i(t);const a=Te(s);let c=!0;for(const u of a.cells){const f=e.cells[qt(r,s.children[u.row].id,u.col)];if(!f||!xr(s,a,u,f)){c=!1;continue}for(const $ of f.blockIds)o.add($)}if(c&&a.cells.length===s.children.reduce((u,f)=>u+f.children.length,0)){o.add(s.id);for(const u of s.children)o.add(u.id)}}for(const[r,s]of Object.entries(e.blocks??{})){const i=se(t,r),a=Ae(t,s.tableId);if(i?.id===r&&a&&de(a).includes(r)&&ye(i)===s.content)for(const c of s.blockIds)o.add(c)}return o}function kn(t,e,n,o){const r=se(t,o);!r||r.id!==o||(e.blocks??(e.blocks={}),e.blocks[o]={tableId:n,content:ye(r),blockIds:de(r)})}function Sr(t,e,n,o){const r=Ae(t,String(o.tableId??""));if(!r||e.geometries?.[r.id]!==at(t,{table_id:r.id,mode:"summary"}).revision)return!1;if(n==="insert_table_row"||n==="insert_table_column")return!0;const s=n==="remove_table_row"?o.rowIndex:o.columnIndex;if(!Number.isInteger(s)||Number(s)<0)return!1;const i=Te(r).cells.filter(c=>n==="remove_table_row"?c.row<=Number(s)&&c.row+c.rowSpan>Number(s):c.col<=Number(s)&&c.col+c.colSpan>Number(s)),a=We(t,e,new Set);return i.length>0&&i.every(c=>a.has(c.cell.id))}function wn(){return{cells:{}}}function Ae(t,e){const n=se(t,e);return n?.type==="table"&&n.id===e?n:null}function Je(t,e){if(!t||typeof t!="object")return;const n=t;n.type==="table"&&e(n);for(const o of At(t))Je(o,e)}const qt=(t,e,n)=>JSON.stringify([t,e,n]),Rt=(t,e)=>ye([e,t.columnWidths]),Pt=(t,e)=>JSON.stringify(t.children.slice(e.row,e.row+e.rowSpan).map(n=>n.id));function xr(t,e,n,o){return o.cellId===n.cell.id&&o.rowId===t.children[n.row].id&&o.column===n.col&&o.content===ye(n.cell)&&o.coveredRows===Pt(t,n)&&o.geometry===Rt(t,e.cols)&&o.rowSpan===n.rowSpan&&o.colSpan===n.colSpan}function ct(t,e,n,o){const r=Ae(t,n);if(!r)return;const s=Te(r),i=o?new Set(o):null,a=Rt(r,s.cols);for(const c of s.cells){if(i&&!i.has(c.cell.id))continue;const u=r.children[c.row].id;e.cells[qt(n,u,c.col)]={tableId:n,rowId:u,column:c.col,cellId:c.cell.id,rowSpan:c.rowSpan,colSpan:c.colSpan,geometry:a,coveredRows:Pt(r,c),content:ye(c.cell),blockIds:de(c.cell)}}}function Bt(t){if(t.children.length!==1)return null;const e=t.children[0];if(e.type!=="paragraph"||!e.children.every(o=>o.type==="text"))return null;let n;for(const o of e.children){const r=st(o.marks??{});if(Object.keys(r).some(i=>!kr.has(i)))return null;if(!o.text)continue;const s=wr(r);if(n!==void 0&&s!==n)return null;n=s}return e}function Cr(t){const e=[];for(const s of t.children)Je(s,i=>e.push(i.id));if(e.length)return{error:`Cell contains nested tables (${e.slice(0,20).join(", ")}). Read them with read_table(table_id=...) and read the cell's other blocks with read_specific_blocks; cell_text does not flatten nested tables.`};const n=[],o=s=>s.map(i=>i.type==="text"?i.text??"":"").join(""),r=s=>{if(s.type==="paragraph"){n.push(o(s.children));return}if(s.type==="list"){const a=[];for(const c of s.children){const u=Math.max(0,c.indentLevel??0);a.length=u+1;const f=u===0?s.startNumber??1:1;a[u]=a[u]===void 0?f:a[u]+1;const $=s.variant==="ordered"?`${a[u]}. `:s.variant==="todo"?c.checked?"[x] ":"[ ] ":"• ";n.push(`${" ".repeat(u)}${$}${o(c.children)}`)}return}const i=s;if(typeof i.content=="string"){n.push(i.content);return}if(Array.isArray(i.children)&&i.children.length){for(const a of i.children)r(a);return}n.push(`[${i.type}${i.id?` ${i.id}`:""}]`)};for(const s of t.children)r(s);return{text:n.join(`
2
- `)}}function vn(t){return t.children.map(e=>e.type==="paragraph"?e.children.map(n=>n.type==="text"?n.text:"").join(""):"").join(`
3
- `)}function lt(t){return t.children.every(e=>e.type==="paragraph"&&e.children.every(n=>n.type==="text"&&!n.text.replace(/[\s\u200b\u200c\u200d\ufeff]/gu,"")))}const In=t=>`<span>${t.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll(`
4
- `,"<br>").replaceAll(" ","&#9;")}</span>`;function Sn(t,e,n,o={}){const r={actions:[],targets:[],errors:[],skipped:[],unchanged:[]},s=n,i=T=>(r.errors.push({row_id:"",column:-1,reason:T}),r);if(!s||typeof s.table_id!="string")return i("table_id is required.");if(s.mode!=="fill_if_empty"&&s.mode!=="replace")return i("mode must be fill_if_empty or replace.");if(!Array.isArray(s.cells)||!s.cells.length||s.cells.length>_n)return i(`Provide 1-${_n} cells.`);if(new TextEncoder().encode(JSON.stringify(s)).length>br)return i("Cell-edit arguments exceed 32KiB; split the batch.");const a=Ae(t,s.table_id);if(!a)return i("Unknown table_id; read the current table first.");const c=Te(a),u=Rt(a,c.cols),f=new Set,$=new Map;for(const T of de(t))$.set(T,($.get(T)??0)+1);for(const T of s.cells){const R=T,P=typeof R?.row_id=="string"?R.row_id:"",U=typeof R?.column=="number"?R.column:-1,D=O=>({row_id:P,column:U,reason:O});if(!P||!Number.isInteger(U)||U<0||typeof R?.text!="string"){r.errors.push(D("Each item requires row_id, a zero-based integer column, and exact text."));continue}const _=qt(a.id,P,U);if(f.has(_)){r.errors.push(D("Duplicate target in batch."));continue}f.add(_);const g=a.children.findIndex(O=>O.id===P),y=c.occupancy[g]?.[U];if(!y||y.row!==g||y.col!==U){r.errors.push(D("Unknown row/column or covered merge position; target the anchor cell."));continue}const q=e.cells[_];if(!q){r.errors.push(D("Cell was not delivered in this request. Read it before editing."));continue}if(de(y.cell).some(O=>$.get(O)!==1)||$.get(P)!==1){r.errors.push(D("Duplicate document identity makes this target ambiguous; repair the malformed table before editing."));continue}if(q.cellId!==y.cell.id||q.rowSpan!==y.rowSpan||q.colSpan!==y.colSpan||q.coveredRows!==Pt(a,y)||q.geometry!==u){r.errors.push(D("Table geometry or anchor identity changed since delivery; reread."));continue}if(o.responseTurn!==void 0&&e.responseClaims?.turn===o.responseTurn&&e.responseClaims.cellIds.includes(y.cell.id)){r.errors.push(D("Another call in this response already edited this cell; inspect the result before editing again."));continue}if(o.hasForeignSuggestion?.(y.cell)){(s.mode==="fill_if_empty"?r.skipped:r.errors).push(D("Cell has a conflicting pending suggestion from another author; preserved."));continue}if(s.mode==="fill_if_empty"&&!lt(y.cell)){r.skipped.push(D("Cell is non-empty; preserved."));continue}if(q.content!==ye(y.cell)){r.errors.push(D("Cell changed after delivery; reread before replacing."));continue}const A=Bt(y.cell);if(!A){r.errors.push(D("Cell contains rich or multi-block content. Use its nested block IDs with the existing rich editing tools."));continue}const w=vn(y.cell);if(w===R.text){r.unchanged.push(D("Already equal."));continue}r.actions.push({name:"replace",arguments:{id:A.id,find:w?In(w):"",replace:In(R.text)}}),r.targets.push({row_id:P,column:U,cellId:y.cell.id,paragraphId:A.id})}return r.errors.length&&(r.actions=[],r.targets=[]),r}const xn=50,Cn=200,$n=5e3,$r=200,Mn=32*1024;function Dn(){return{version:1,nextTaskNumber:1,task:null}}const Mr=new TextEncoder;function Ge(t){return Mr.encode(t).length}function Tn(t,e,n="…"){if(Ge(t)<=e)return t;const o=Math.max(0,e-Ge(n));let r=0,s="";for(const i of t){const a=Ge(i);if(r+a>o)break;r+=a,s+=i}return s+n}function Dr(t,e){const n=t.replace(/[\u0000-\u001f\u007f]+/gu," ").replace(/\s+/gu," ").trim();return Tn(n,e)}const dt=t=>typeof t=="number"&&Number.isInteger(t)&&t>=0,Tr=t=>dt(t)&&t>0,ut=t=>typeof t=="string";function Ar(t,e,n){const o=Ge(e),r=o>Mn;return{requestId:t,text:r?Tn(e,Mn,""):e,originalBytes:o,truncated:r,...typeof n=="number"&&Number.isFinite(n)?{timestamp:n}:{}}}function qr(t){for(let e=t.length-1;e>=0;e--){const n=t[e];if(n.role!=="user")continue;const o=mt(n);if(o.trim())return`${n.requestId??"?"}|${n.timestamp??""}|${ye(o)}`}}const Rr=["task_kind","scope_row_start","scope_row_count","scope_columns","source_attachment_id"];function ht(t){return t==null?!1:typeof t=="string"?t.trim().length>0:Array.isArray(t)?t.length>0:!0}function mt(t){return typeof t.content=="string"?t.content:""}function Pr(t,e){const n=t.find(o=>o.role==="user"&&o.requestId===e&&mt(o).trim());if(n)return n;for(let o=t.length-1;o>=0;o--){const r=t[o];if(r.role==="user"&&mt(r).trim())return r}}function Br(t,e,n,o){const r=Rr.some($=>ht(n[$])),s=n.deliberate_blanks,i=ht(s);if(!r&&!i)return{state:t,declared:!1};const a=ut(n.table_id)?n.table_id:"",c=Ae(e,a);if(!c)return{error:"Unknown table_id; no task scope was recorded."};const u=Te(c);let f;if(r){const $=n.task_kind;if($!=="fill"&&$!=="transform")return{error:"Declaring a table task requires task_kind (fill or transform) together with scope_row_start, scope_row_count and scope_columns; no scope was recorded."};const T=n.scope_row_start,R=n.scope_row_count,P=n.scope_columns;if(!dt(T)||!Tr(R)||!Array.isArray(P)||!P.length)return{error:"A table task scope requires integer scope_row_start, scope_row_count >= 1 and a non-empty scope_columns array; no scope was recorded."};if(T+R>u.rows)return{error:`Task scope rows ${T}-${T+R-1} exceed the table's ${u.rows} rows; no scope was recorded.`};if(R>$n)return{error:`A table task scope may cover at most ${$n} rows; declare the scope in parts.`};if(!P.every(dt)||new Set(P).size!==P.length||P.some(d=>d>=u.cols))return{error:`scope_columns must be unique 0-based columns below ${u.cols}; no scope was recorded.`};let U;if(ht(n.source_attachment_id)){if(!ut(n.source_attachment_id)||!n.source_attachment_id.trim()||Ge(n.source_attachment_id)>200)return{error:"source_attachment_id must be a non-empty attachment ID; no scope was recorded."};if(o.attachmentExists&&!o.attachmentExists(n.source_attachment_id))return{error:`Attachment '${n.source_attachment_id}' is not available in this conversation; no scope was recorded.`};U=n.source_attachment_id}const D=c.children.slice(T,T+R).map(d=>d.id),_=t.task,g=_&&_.tableId===c.id&&_.kind===$,y=Pr(o.chatHistory,o.requestId),q=g?_.originRequest:Ar(typeof y?.requestId=="number"?y.requestId:o.requestId,y?mt(y):"",y?.timestamp),A=new Set(D),w=new Set(P),O=qr(o.chatHistory);let z=O;if(g){const d=new Set(c.children.map(te=>te.id)),C=_.rowIds.filter(te=>d.has(te)&&!A.has(te)),ce=_.columns.filter(te=>!w.has(te)),me=C.length>0||ce.length>0,_t=!me&&D.length===_.rowIds.length&&P.length===_.columns.length;if(me&&_.scopeUserMarker!==void 0&&_.scopeUserMarker===O)return{error:`This declaration would drop ${[C.length?`${C.length} rows`:"",ce.length?`columns ${ce.join(",")}`:""].filter(Boolean).join(" and ")} from the declared task scope without a newer user instruction. The task scope must cover the user's whole request: repeat the full scope (or omit the scope fields) and use row_start/row_count or row_ids for a smaller read window. The declared scope is unchanged.`};_t&&(z=_.scopeUserMarker??O)}const K=U??(g?_.sourceAttachmentId:void 0);f={id:g?_.id:`table_task_${t.nextTaskNumber}`,tableId:c.id,kind:$,rowIds:D,declaredRowStart:T,columns:[...P].sort((d,C)=>d-C),...K?{sourceAttachmentId:K}:{},deliberateBlanks:g?_.deliberateBlanks.filter(d=>A.has(d.rowId)&&w.has(d.column)):[],touchedCellIds:g?_.touchedCellIds:[],originRequest:q,...g&&_.latestSteering?{latestSteering:_.latestSteering}:{},declaredRequestId:o.requestId,lastActivityRequestId:o.requestId,...z?{scopeUserMarker:z}:{}}}else{const $=t.task;if(!$||$.tableId!==c.id)return{error:"deliberate_blanks require a declared task for this table; include task_kind and scope_* first."};f={...$,deliberateBlanks:[...$.deliberateBlanks],lastActivityRequestId:o.requestId}}if(i){if(!Array.isArray(s)||s.length>xn)return{error:`deliberate_blanks must be an array of at most ${xn} cells; no scope was recorded.`};const $=new Set(f.rowIds),T=new Set(f.columns),R=new Set,P=[];for(const D of s){const _=D,g=`${String(_?.row_id)}:${String(_?.column)}`;if(!_||!ut(_.row_id)||!dt(_.column)||!ut(_.reason)||!_.reason.trim())return{error:`Each deliberate blank needs row_id, column and a non-empty reason (${g}); no scope was recorded.`};if(!$.has(_.row_id)||!T.has(_.column))return{error:`Deliberate blank ${g} is outside the declared task scope; no scope was recorded.`};const y=c.children.findIndex(A=>A.id===_.row_id),q=u.occupancy[y]?.[_.column];if(!q||q.row!==y||q.col!==_.column)return{error:`Deliberate blank ${g} is a covered merge position or unplaced cell; name the anchor cell.`};if(R.has(g))return{error:`Duplicate deliberate blank ${g}; no scope was recorded.`};R.add(g),P.push({rowId:_.row_id,column:_.column,reason:Dr(_.reason,$r)})}const U=new Map(f.deliberateBlanks.map(D=>[`${D.rowId}:${D.column}`,D]));for(const D of P)U.set(`${D.rowId}:${D.column}`,D);if(U.size>Cn)return{error:`A task may record at most ${Cn} deliberate blanks; no scope was recorded.`};f.deliberateBlanks=[...U.values()]}return{state:{version:1,nextTaskNumber:f.id!==t.task?.id?t.nextTaskNumber+1:t.nextTaskNumber,task:f,...t.localEdits?{localEdits:t.localEdits}:{}},declared:!0}}function Nr(t,e){if(!e.cellIds.length)return t;const n=t.localEdits?.requestId===e.requestId?t.localEdits:{tables:{}},o={requestId:e.requestId,tables:{...n.tables,[e.tableId]:(n.tables[e.tableId]??0)+e.cellIds.length}},r=t.task;if(!r||r.tableId!==e.tableId)return{...t,localEdits:o};const s=[...new Set([...r.touchedCellIds,...e.cellIds])].slice(-5e3);return{...t,localEdits:o,task:{...r,touchedCellIds:s,lastActivityRequestId:e.requestId}}}const An=50,Lr="out_of_context_edit";function Or(t){const{toolCall:e,docBefore:n,isTargetAllowed:o}=t;if(e.name!=="remove_block")return null;const r=e.arguments;if(!r||typeof r!="object")return null;const s=r.through_end;if(s==null||s===!1)return null;if(s!==!0)return{toolCall:e,targetBlockIds:[],error:"remove_blocks through_end must be true when provided."};const i=r.id,a=r.count,c=r.ids,u=r.search_result_id;if(typeof i!="string"||i.trim().length===0)return{toolCall:e,targetBlockIds:[],error:"remove_blocks through_end requires a non-empty top-level id."};if(a!=null||c!=null||u!=null)return{toolCall:e,targetBlockIds:[],error:"remove_blocks through_end is mutually exclusive with count, ids, and search_result_id."};const f=i.trim(),$=Ie(n,f);if($<0||n.children[$]?.id!==f)return{toolCall:e,targetBlockIds:[],error:`remove_blocks through_end target '${f}' must be a current top-level block.`};if(!o(f))return{toolCall:e,targetBlockIds:[],error:`remove_blocks through_end start '${f}' is outside the request-level document context. Read or search for that boundary block first, then retry.`,errorCode:Lr};const T=n.children.slice($).map(R=>R.id).filter(R=>typeof R=="string"&&R.length>0);return{toolCall:{...e,arguments:{id:f,count:T.length}},targetBlockIds:T}}function Ur(t,e,n){if(t.name!=="remove_block")return{actions:[t]};const o=t.arguments;if(!o||typeof o!="object")return{actions:[],error:"remove_blocks requires object arguments"};const r=o.ids;if(r==null)return{actions:[t]};if(typeof o.id=="string")return{actions:[],error:"remove_blocks accepts either id + count or ids, not both."};if(!Array.isArray(r)||r.length===0)return{actions:[],error:"remove_blocks ids must be a non-empty array"};if(r.length>An)return{actions:[],error:`remove_blocks supports at most ${An} exact IDs per call`};const s=[],i=new Set;for(const c of r){if(typeof c!="string"||c.trim().length===0)return{actions:[],error:"remove_blocks ids must all be non-empty strings"};const u=c.trim();if(!i.has(u)){if(!se(e,u))return{actions:[],error:`remove_blocks target '${u}' was not found`};if(!n(u))return{actions:[],error:`remove_blocks target '${u}' is outside the request-level document context. Read or search for that block first, then retry the exact ID batch.`};i.add(u),s.push(u)}}const a=s.filter(c=>ot(e,c)).length;return a>0&&a<s.length?{actions:[],error:"Remove footnotes/endnotes separately from main-document blocks. Pass only note IDs in this batch so each note and its references are removed together."}:{actions:s.map((c,u)=>({id:`${t.id||"remove_block"}-${u+1}`,name:"remove_block",arguments:{id:c,count:1}}))}}function qn(t){const e=new URLSearchParams;t.query!==void 0&&e.set("q",t.query),e.set("includeContent","false");for(const n of["page","limit","currentFolderId","parentFolderId","sortBy","order"]){const o=t[n];o!=null&&o!==""&&e.set(n,String(o))}return t.includeFolders&&e.set("includeFolders","1"),e}function Rn(t,e=10){const n=t,o=Array.isArray(n?.items)?n.items:[],r=s=>typeof s=="number"&&Number.isFinite(s)&&s>=0;return{items:o,totalCount:r(n?.pagination?.totalCount)?n.pagination.totalCount:o.length,totalPages:r(n?.pagination?.totalPages)?n.pagination.totalPages:Math.max(1,Math.ceil(o.length/Math.max(1,e))),hasMore:n?.pagination?.hasMore===!0}}function Pn(t){return typeof t=="object"&&t!==null&&t.type==="doc"&&Array.isArray(t.children)}function jr(t,e=[]){const n=new ve.Doc;ve.applyUpdate(n,$t(t));for(const o of e)o&&ve.applyUpdate(n,$t(o));return De(n)}function Fr({content:t,yjsState:e,yjsUpdates:n,source:o}){const r=Array.isArray(n)?n.filter(s=>s.length>0):[];if(typeof e=="string"&&e.length>0||r.length>0)try{if(typeof e=="string"&&e.length>0)return jr(e,r);const s=Pn(t)?an(t):new ve.Doc;if(r.length>0){for(const i of r)ve.applyUpdate(s,$t(i));return De(s)}}catch(s){console.error(`[resolveDocRootFromSerializedState] Failed to decode yjs updates${o?` for ${o}`:""}`,s)}return Pn(t)?t:null}const Er="revise_conversations",zr=2,Bn="conversations",Ve="attachments";let Se=null;function Nn(){return typeof indexedDB<"u"}function Ln(t){return Se||(Se=new Promise((e,n)=>{if(!Nn()){n(new Error("IndexedDB not available"));return}const o=indexedDB.open(Er,t??zr);o.onerror=()=>{Se=null,n(o.error)},o.onblocked=()=>{console.warn("[LocalConversationStorage] Database upgrade blocked - close other tabs")},o.onsuccess=()=>{const r=o.result;if(!r.objectStoreNames.contains(Ve)){if(t!==void 0){r.close(),Se=null,n(new Error("Attachments store still missing after version bump"));return}console.warn("[LocalConversationStorage] Attachments store missing, bumping version to create it");const s=r.version+1;r.close(),Se=null,Ln(s).then(e).catch(n);return}r.onclose=()=>{Se=null},r.onerror=()=>{Se=null},e(r)},o.onupgradeneeded=r=>{const s=r.target.result;if(!s.objectStoreNames.contains(Bn)){const i=s.createObjectStore(Bn,{keyPath:"id"});i.createIndex("documentId","documentId",{unique:!1}),i.createIndex("updatedAt","updatedAt",{unique:!1})}s.objectStoreNames.contains(Ve)||s.createObjectStore(Ve,{keyPath:"id"}).createIndex("conversationId","conversationId",{unique:!1})}}),Se)}async function Hr(t){if(!Nn())return null;try{const e=await Ln();return new Promise((n,o)=>{const r=e.transaction(Ve,"readonly").objectStore(Ve).get(t);r.onsuccess=()=>{n(r.result??null)},r.onerror=()=>o(r.error)})}catch(e){return console.warn("[LocalConversationStorage] Failed to get attachment:",e),null}}const Nt=/(<img\b[^>]*?\bsrc\s*=\s*)(["'])([\s\S]*?)\2/gi,On=/(!\[[^\]]*\]\(\s*)(<[^>]+>|[^)\s]+)((?:\s+(?:"[^"]*"|'[^']*'|\([^)]*\)))?\s*\))/g;function gt(t){const e=t.trim();return e.startsWith("<")&&e.endsWith(">")?e.slice(1,-1).trim():e}function Wr(t){const e=new Set(["images.revise.io"]);for(const n of t.flatMap(o=>(o??"").split(",")))if(n.trim())try{e.add(new URL(n.includes("://")?n.trim():"https://"+n.trim()).host)}catch{}return e}function Jr(t,e,n){try{const o=new URL(gt(t),n);return!["http:","https:"].includes(o.protocol)||e.has(o.host)?!1:!n||o.origin!==new URL(n).origin}catch{return!1}}function Gr(t,e,n,o=!1){for(const r of t.matchAll(Nt)){const s=gt(r[3]);n(s)&&e.add(s)}if(o)for(const r of t.matchAll(On)){const s=gt(r[2]);n(s)&&e.add(s)}}function Vr(t){try{const e=new URL(t);if(e.hostname!=="upload.wikimedia.org")return t;const n=e.pathname.split("/");return n.length<8||n[1]!=="wikipedia"||n[2]!=="commons"||n[3]!=="thumb"?t:(e.pathname=["","wikipedia","commons",...n.slice(4,-1)].join("/"),e.toString())}catch{return t}}function Kr(t){return t.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function Xr(t,e){return t.replace(/<img\b[^>]*>/gi,n=>{const o=Array.from(n.matchAll(Nt))[0];if(!o)return n;const r=o[3].trim(),s=e.get(r);if(!s)return n;let i=n.replace(Nt,(c,u,f)=>`${u}${f}${s.url}${f}`);const a=[];return/\bdata-source-url\s*=/i.test(i)||a.push(`data-source-url="${Kr(r)}"`),s.naturalWidth&&s.naturalHeight&&!/\bdata-revise-natural-(?:width|height)\s*=/i.test(i)&&a.push(`data-revise-natural-width="${s.naturalWidth}"`,`data-revise-natural-height="${s.naturalHeight}"`),a.length>0&&(i=i.replace(/\s*\/?>$/,c=>` ${a.join(" ")}${c}`)),i})}function Un(t,e,n=!1){const o=n?t.replace(On,(r,s,i,a)=>{const c=e.get(gt(i));return c?s+"<"+c.url+">"+a:r}):t;return Xr(o,e)}const Yr="https://app-api.revise-sdk.invalid";function Zr(t){return Jr(t,Wr([""]),typeof window<"u"?window.location.href:void 0)}function jn(t){return typeof t=="number"&&Number.isInteger(t)&&t>0?t:void 0}async function Qr(t){try{const e=await fetch(`${Yr}/uploads/images/rehost`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({url:Vr(t)}),signal:AbortSignal.timeout(3e4)});if(!e.ok){let s=`Image copy request failed (HTTP ${e.status}).`;try{const i=await e.json();typeof i.error=="string"&&i.error.trim().length>0&&(s=i.error.trim())}catch{}return{ok:!1,failure:{url:t,status:e.status,message:s}}}const n=await e.json();if(typeof n.fileUrl!="string"||!n.fileUrl)return{ok:!1,failure:{url:t,status:e.status,message:"Image copy response did not include a file URL."}};const o=jn(n.width),r=jn(n.height);return{ok:!0,image:{url:n.fileUrl,...o&&r?{naturalWidth:o,naturalHeight:r}:{}}}}catch{return{ok:!1,failure:{url:t,message:"Image copy request could not reach Revise storage."}}}}const Fn=new Set(["insert_block","replace_block"]);function es(t){const e=new Set;for(const n of t??[]){if(!n?.name||!Fn.has(n.name))continue;const o=n.arguments?.content;for(const r of Array.isArray(o)?o:[o])typeof r=="string"&&Gr(r,e,Zr)}return e}async function ts(t){const e={attempted:0,rehosted:0,failedUrls:[],failures:[]};if(!Array.isArray(t)||t.length===0)return e;const n=es(t);if(n.size===0)return e;const o=new Map,r=[];await Promise.all([...n].map(async i=>{const a=await Qr(i);a.ok?o.set(i,a.image):r.push(a.failure)}));const s=[...n].filter(i=>!o.has(i));if(o.size===0)return{attempted:n.size,rehosted:0,failedUrls:s,failures:r};for(const i of t){if(!i?.name||!Fn.has(i.name))continue;const a=i.arguments;a&&(typeof a.content=="string"?a.content=Un(a.content,o):Array.isArray(a.content)&&(a.content=a.content.map(c=>typeof c=="string"?Un(c,o):c)))}return{attempted:n.size,rehosted:o.size,failedUrls:s,failures:r}}function ns(t,e){const n=t.children.flatMap((o,r)=>o.type==="paragraph"&&o.heading?[{index:r,level:o.heading,blockId:o.id,title:St(o).replace(/\s+/g," ").trim()}]:[]);return n.filter(o=>o.level<=e?.maxDepth).map(o=>({...o,endIndex:(n.find(r=>r.index>o.index&&(e?.flat||r.level<=o.level))?.index??t.children.length)-1}))}const os=new Set([8203,8204,8205,8288,65279]);function rs(){return{wordCount:0,paragraphCount:0,characterCount:0,hasVisibleText:!1,inWord:!1}}function En(t,e){for(let n=0;n<t.length;n+=1){const o=t.codePointAt(n);if(o===void 0||(o>65535&&(n+=1),os.has(o)))continue;const r=String.fromCodePoint(o);if(e.characterCount+=r.length,/\s/.test(r)){e.inWord=!1;continue}e.hasVisibleText=!0,e.inWord||(e.wordCount+=1,e.inWord=!0)}}function zn(t,e){if(!t||typeof t!="object")return;const n=t;if(n.type==="text"&&typeof n.text=="string"){En(n.text,e);return}if(n.type==="paragraph"&&(e.paragraphCount+=1),(n.type==="code"||n.type==="math")&&typeof n.content=="string"){En(n.content,e),e.inWord=!1;return}if(n.type==="placeholder"||n.type==="image"||n.type==="page-break"||n.type==="section-break"){e.inWord=!1;return}if(Array.isArray(n.children))for(const o of n.children)zn(o,e),o&&typeof o=="object"&&"type"in o&&o.type!=="text"&&(e.inWord=!1)}function ss(t){const e=rs();for(const o of t)zn(o,e),e.inWord=!1;const n={parts:[],paragraphCount:0,containsSentinel:!1};for(const o of t)Hn(o,n),n.parts.push(" ");return e.wordCount=nr(n.parts.join("")),e}const Ke="\0";function Hn(t,e){if(!t||typeof t!="object")return;const n=t;if(n.type==="text"&&typeof n.text=="string"){n.text.includes(Ke)&&(e.containsSentinel=!0),e.parts.push(n.text);return}if(n.type==="paragraph"&&(e.paragraphCount+=1),(n.type==="code"||n.type==="math")&&typeof n.content=="string"){n.content.includes(Ke)&&(e.containsSentinel=!0),e.parts.push(n.content,Ke);return}if(n.type==="placeholder"||n.type==="image"||n.type==="page-break"||n.type==="section-break"){e.parts.push(Ke);return}if(Array.isArray(n.children))for(const o of n.children)Hn(o,e),o&&typeof o=="object"&&"type"in o&&o.type!=="text"&&e.parts.push(Ke)}function Wn(t){return ss(t)}function Jn(t){const e=cn(t.pageLayout),n=Do(e);return{layout:Yo({pageWidth:n.pageWidth,pageHeight:n.pageHeight,pageMargin:e.marginLeftPx,pageMarginTop:e.marginTopPx,pageMarginRight:e.marginRightPx,pageMarginBottom:e.marginBottomPx,pageMarginLeft:e.marginLeftPx,availableWidth:Math.max(1,n.pageWidth-e.marginLeftPx-e.marginRightPx),textStartY:e.marginTopPx,indentStepPx:e.indentStepPx,blockSpacingPx:e.blockSpacingPx,hyphenationEnabled:e.hyphenationEnabled,lineNumbering:e.lineNumbering,columnCount:e.columnCount,columnGapPx:To(e.columnGapTwips),pageless:t.pageless===!0}),resolved:e}}function Gn(t){if(typeof document>"u")return null;const e=document.createElement("canvas").getContext("2d");if(!e)return null;const n=Xo(e),{layout:o}=Jn(t);return er(t,n,o)}function Vn(t,e){const n=new Map;if(!e||t.pageless===!0)return new Map;const o=(i,a)=>{if(!i||typeof a!="number"||!Number.isFinite(a))return;const c=Math.max(1,Math.floor(a)),u=n.get(i);if(!u){n.set(i,{min:c,max:c});return}u.min=Math.min(u.min,c),u.max=Math.max(u.max,c)};for(const i of e.fragments)o(i.blockId,i.pageNumber);for(const i of e.blocks)o(i.blockId,i.pageNumber);const r=cn(t.pageLayout),s=new Map;for(const[i,a]of n)s.set(i,{pageStart:ln(r,a.min-1),pageEnd:ln(r,a.max-1)});return s}function is(t,e){let n,o;for(const r of t){const s=e.get(r);s&&(n=n===void 0?s.pageStart:Math.min(n,s.pageStart),o=o===void 0?s.pageEnd:Math.max(o,s.pageEnd))}return n!==void 0&&o!==void 0?{pageStart:n,pageEnd:o}:void 0}function Kn(t,e,n,o){const r=Math.max(0,Math.min(e,t.children.length-1)),s=Math.max(0,Math.min(n,t.children.length-1));if(r>s||t.children.length===0)return null;const i=t.children.slice(r,s+1),a=t.children[r],c=t.children[s];if(!a?.id||!c?.id)return null;const u=Wn(i),f=i.map(T=>T.id).filter(Boolean),$=is(f,o);return{startIndex:r,endIndex:s,startBlockId:a.id,endBlockId:c.id,inclusive:!0,blockCount:i.length,wordCount:u.wordCount,paragraphCount:u.paragraphCount,characterCount:u.characterCount,...$?{pageStart:$.pageStart,pageEnd:$.pageEnd}:{}}}function as(t,e,n){const o=[],r=n?new Set(n):null;for(const s of ns(t,{maxDepth:3})){const i=s.index,a=s.endIndex,c=s.level;if(r&&!r.has(c))continue;const u=Kn(t,i,a,e);u&&o.push({startIndex:u.startIndex,endIndex:u.endIndex,startBlockId:u.startBlockId,endBlockId:u.endBlockId,headingLevel:c,title:s.title,wordCount:u.wordCount,paragraphCount:u.paragraphCount,characterCount:u.characterCount,...u.pageStart!==void 0?{pageStart:u.pageStart,pageEnd:u.pageEnd}:{}})}return o}function Xn(t,e){const n=e&&"layout"in e?e.layout??null:t.pageless===!0?null:Gn(t),o=Wn(t.children),r=t.pageless===!0?null:n,s=e?.includeSections===!0?Vn(t,n):new Map;return{inclusive:!0,totalBlocks:t.children.length,wordCount:o.wordCount,paragraphCount:o.paragraphCount,characterCount:o.characterCount,...r?{pageCount:r.pageCount}:{},...e?.includeFractionalPageCount===!0&&r?{fractionalPageCount:cs(t,r)}:{},...e?.includeSections===!0?{sections:as(t,s,e.headingLevels).map(i=>({...i,inclusive:!0,blockCount:i.endIndex-i.startIndex+1}))}:{}}}function cs(t,e){const{layout:n}=Jn(t);return tr(n,e)}function Yn(t){return typeof t!="string"?"":t.trim().replace(/^#+/,"")}function ls(t,e,n){const o=Gn(t),r=Vn(t,o),s=new Map;for(let c=0;c<t.children.length;c+=1){const u=t.children[c]?.id;u&&s.set(u,c)}const i=[],a=[];for(const c of e){const u=Yn(c.startBlockId),f=Yn(c.endBlockId??u),$=s.get(u),T=s.get(f);if(!u){a.push({error:"start_block_id is required."});continue}if($===void 0){a.push({startBlockId:u,endBlockId:f,error:`start_block_id "${u}" was not found.`});continue}if(T===void 0){a.push({startBlockId:u,endBlockId:f,error:`end_block_id "${f}" was not found.`});continue}if(T<$){a.push({startBlockId:u,endBlockId:f,error:`end_block_id "${f}" comes before start_block_id "${u}". Ranges must be forward and inclusive.`});continue}const R=Kn(t,$,T,r);if(!R){a.push({startBlockId:u,endBlockId:f,error:`Could not measure inclusive range "${u}"-"${f}".`});continue}i.push(R)}return{inclusive:!0,totalBlocks:t.children.length,ranges:i,errors:a}}const ds="The agent had trouble completing this request. Please try again.",Zn="Document session unavailable after waiting for document load",us="document_session_unavailable";class hs extends Error{constructor(e){super("Open the source document linked in the conversation to continue these edits."),this.sourceDocumentId=e,this.name="ForeignDocumentTargetError"}}const ms="InvalidAssistantResponseError",gs="Couldn't reach the server. Please check your connection and try again.",ps=["aborted without reason","bodystreambuffer was aborted","client.timeout","connection reset by peer","context canceled","context cancellation","context cancelled","context deadline exceeded","econnreset","etimedout","failed to fetch","failed to execute 'fetch'","fetch is aborted","gateway timeout","http error! status:","illegal access","illegal invocation","load failed","network request failed","socket hang up","upstream request timeout","while reading body"],fs=["function call is missing a thought_signature","does not support the effort parameter","response with id=","gemini api error: 400","xai api error: 404","anthropic api error: 400"],bs=["server_error","service_unavailable","server_is_overloaded","503 service unavailable","error in input stream"],ys=["context_length_exceeded","input token count exceeds","exceeds the context window","maximum number of tokens","maximum context length","prompt is too long","too many input tokens"],_s=['attachment "',"attachment not found","unable to download the file","failed to fetch attachment","expected a valid url","invalid 'input","image_url"],ks=['block id "',"document changed while","reference block","not found in document","not found in the document","insert_block"];function ws(t){const e=t.toLowerCase();return e.includes("network")||ps.some(n=>e.includes(n))}function vs(t){if(t?.name==="AbortError"||t instanceof DOMException&&t.code===20)return{isAbort:!0,isRateLimited:!1,isNetworkError:!1,kind:"abort",rawMessage:"",message:"",shouldRetryWithStableModel:!1,shouldTrackConversationError:!1};const e=t instanceof Error?t.message:typeof t?.toString=="function"?t.toString():String(t??""),n=e.toLowerCase(),o=e==="RATE_LIMITED"||t?.message==="RATE_LIMITED",r=t instanceof TypeError||ws(e),s=t instanceof Error&&t.name===ms,i=u=>u.some(f=>n.includes(f)),a=t instanceof hs?"document_target":o?"rate_limited":s?"invalid_assistant_response":e.trim().length===0?"unknown_empty":i(ys)?"context_limit":i(_s)?"attachment":n.includes(Zn.toLowerCase())?"document_loading":i(ks)?"document_state":i(fs)?"provider_protocol":i(bs)?"provider_transient":r?"connection":"unknown";let c;return o?c="Rate limit reached":s?c="The agent sent an invalid response. Please try again.":a==="connection"?c=gs:a==="provider_protocol"||a==="provider_transient"?c="The model service had trouble completing this request. Please try again.":a==="context_limit"?c="This request is too large for the model. Try a smaller request or attach fewer files.":a==="attachment"?c="The agent could not read one of the attached files.":a==="document_loading"?c="The document is still loading. Please wait a moment and try again.":a==="document_target"?c=e:a==="document_state"?c="Document state changed during the request.":a==="unknown_empty"?c="The agent stopped unexpectedly. Your prompt is saved.":c=ds,{isAbort:!1,isRateLimited:o,isNetworkError:r,kind:a,rawMessage:e,message:c,shouldRetryWithStableModel:a==="provider_protocol"||a==="provider_transient",shouldTrackConversationError:a!=="rate_limited"&&a!=="connection"&&a!=="document_loading"}}const Qn=[{name:"get_selection",description:"Read the host user's current semantic editor selection. Returns selected text, caret/range positions, portable target segments, active formatting, comment IDs, and pending suggestion IDs. Returns no viewport geometry. Use this when the host has not already supplied selection context.",inputSchema:{additionalProperties:!1,properties:{},type:"object"}},{name:"read_blocks_from_index",description:"Read consecutive blocks from a 0-based start index. Omit document_id for the current document, or pass a known document_id to read another document. If the user names or links a specific document and you know its ID, use this directly instead of search_documents. Client chooses count by budget. Use at most one read/search tool per turn.",inputSchema:{additionalProperties:!1,properties:{context_notes:{description:"Plain-text notes to carry forward from current context before this read/search. Use 'N/A' if none.",type:"string"},document_id:{description:"Optional document ID. Omit for the current document. Other documents are read-only sources: their block IDs cannot be used in mutation tools. To edit another document, ask the user to open it and continue there.",type:"string"},index:{description:"0-based start block index.",minimum:0,type:"integer"}},required:["index","context_notes"],type:"object"}},{name:"search_document",description:"Search text within one document. Call this when you need to locate specific wording, a term, a name, or every occurrence of something and you do not already know which blocks contain it — searching is how you find the target before editing it, and is cheaper and more reliable than reading through the document. Current-document results include a request-scoped search_result_id for the full unpaginated match set; pass it to replace, replace_block, style_blocks, or remove_blocks to target every match without paging through IDs. Omit document_id for the current document, or pass a known document_id to search within another document. If you instead need to read a document start-to-finish and already know its ID, prefer read_blocks_from_index with document_id. Displayed matches are paginated. Use at most one read/search tool per turn.",inputSchema:{additionalProperties:!1,properties:{context_notes:{description:"Plain-text notes to carry forward from current context before this read/search. Use 'N/A' if none.",type:"string"},document_id:{description:"Optional document ID. Omit for the current document. Other documents are read-only sources: their block IDs cannot be used in mutation tools. To edit another document, ask the user to open it and continue there.",type:"string"},page:{description:"0-based result page.",type:"integer"},queries:{description:"Search terms, max 20. Plain strings are case-insensitive; prefix regex patterns with 'regex:'.",items:{type:"string"},type:"array"}},required:["queries","page","context_notes"],type:"object"}},{name:"find_highlights",description:'Find highlighted text blocks, optionally by color. Call this whenever the request refers to highlighted text — "the highlighted parts", "what I marked", "the yellow bits" — before acting on it; highlights are not visible in loaded document content, so this is the only way to learn which blocks the user means. Matching blocks load next turn. Results are paginated at 25 blocks/page. Use at most one read/search tool per turn.',inputSchema:{additionalProperties:!1,properties:{color:{description:"Optional color filter.",enum:["yellow","orange","green","blue","purple","pink","gray"],type:"string"},context_notes:{description:"Plain-text notes to carry forward from current context before this read/search. Use 'N/A' if none.",type:"string"},page:{description:"0-based result page.",type:"integer"}},required:["page","context_notes"],type:"object"}},{name:"read_specific_blocks",description:"Read specific blocks by ID. Omit document_id for the current document, or pass a known document_id to read another document. If you already know both the document ID and block IDs, use this directly instead of search_documents. Use at most one read/search tool per turn.",inputSchema:{additionalProperties:!1,properties:{block_ids:{description:"Block IDs to read, max 50.",items:{type:"string"},type:"array"},context_notes:{description:"Plain-text notes to carry forward from current context before this read/search. Use 'N/A' if none.",type:"string"},document_id:{description:"Optional document ID. Omit for the current document. Other documents are read-only sources: their block IDs cannot be used in mutation tools. To edit another document, ask the user to open it and continue there.",type:"string"}},required:["block_ids","context_notes"],type:"object"}},{name:"read_table",description:"Read a bounded part of a table in the current document by table_id. Native agents receive row contents in the next document snapshot; other callers receive rows in this result. Results include coverage metadata and continuations. When a serialized window is partial, consume next_read and then following_read to avoid skipping columns or later rows. mode=summary returns dimensions, merged anchors/spans, per-column fill counts and missing ranges only: it delivers no cell contents and grants no edit rights. mode=rows (default) delivers rows by row_start/row_count or explicit row_ids, optionally limited to a column range; only delivered cells can be edited. mode=cell_text pages one oversized cell by cell_id/text_offset and continuation_revision; cell_text includes list markers and explicit non-text placeholders, and routes nested tables to their own read_table calls. Its windows are always read-only and never authorize whole-cell replacement; read a complete nested block with read_specific_blocks to edit that block. For cells not already fully delivered in a table seed or cell snapshot, read the needed rows, then batch edits with edit_table_cells. Do not re-read cells whose current contents are already delivered. Optionally declare the overall task scope (task_kind, scope_*, source_attachment_id) and deliberate_blanks so progress can be tracked across turns; scope is never inferred from a partial edit. Use at most one read/search tool per turn.",inputSchema:{additionalProperties:!1,properties:{cell_id:{description:"Cell ID for mode=cell_text.",type:"string"},column_count:{description:"Optional number of logical columns starting at column_start.",minimum:1,type:"integer"},column_start:{description:"Optional 0-based first logical column. Omit to read all columns. A partial column read authorizes edits only to the delivered cells, not the whole row.",minimum:0,type:"integer"},context_notes:{description:"Plain-text notes to carry forward from current context before this read/search. Use 'N/A' if none.",type:"string"},continuation_revision:{description:"Revision from the previous result continuation. Rejects continuation when cell text or table geometry changed, so stale and fresh windows are never combined.",type:"string"},deliberate_blanks:{description:"Optional in-scope cells intentionally left empty, each with a reason, so they are not reported as remaining work.",items:{additionalProperties:!1,properties:{column:{description:"0-based logical column.",minimum:0,type:"integer"},reason:{description:"Why the cell stays empty.",type:"string"},row_id:{description:"Stable row ID.",type:"string"}},required:["row_id","column","reason"],type:"object"},maxItems:50,type:"array"},mode:{description:"summary: metadata and counts only. rows (default when omitted): deliver row contents. cell_text: bounded text window of one oversized cell.",enum:["summary","rows","cell_text"],type:"string"},row_count:{description:"Rows to deliver for mode=rows. Defaults to 25; maximum 50.",maximum:50,minimum:1,type:"integer"},row_ids:{description:"Explicit stable row IDs (<tr id>) to deliver instead of row_start/row_count.",items:{type:"string"},maxItems:50,type:"array"},row_start:{description:"0-based first row for mode=rows, counting header rows. Ignored when row_ids is supplied.",minimum:0,type:"integer"},scope_columns:{description:"Optional declared task scope: 0-based logical columns the task writes.",items:{minimum:0,type:"integer"},type:"array"},scope_row_count:{description:"Optional declared task scope: number of rows covered by the user's whole request.",minimum:1,type:"integer"},scope_row_start:{description:"Optional declared task scope: first 0-based row covered by the user's whole request.",minimum:0,type:"integer"},source_attachment_id:{description:"Optional attachment ID the task copies or derives values from.",type:"string"},table_id:{description:"Table block ID in the current document.",type:"string"},task_kind:{description:"Optional task declaration. fill: populate empty cells. transform: rewrite existing cells (translate, shorten, etc.).",enum:["fill","transform"],type:"string"},text_offset:{description:"Character offset for mode=cell_text. Use the offset from the previous result's continuation.",minimum:0,type:"integer"}},required:["table_id","context_notes"],type:"object"}},{name:"measure_document",description:"Measure the current document without loading body text. Use this for total word count, paragraph count, block count, rendered page count, and paginated per-heading section measurements. Primary totals treat pending suggestions as accepted; when pending suggestions change counts, the result also reports the original review projection so you can reconcile the number visible in the user's editor view. Set include_sections=true for per-chapter/per-section counts and inclusive block ranges.",inputSchema:{additionalProperties:!1,properties:{heading_levels:{description:"Optional heading levels to include when include_sections is true. Defaults to h1, h2, and h3.",items:{enum:[1,2,3],type:"integer"},type:"array"},include_sections:{description:"Whether to include heading section measurements. Default false. Use true for per-chapter or per-section counts.",type:"boolean"},section_limit:{description:"Maximum heading sections to return when include_sections is true. Default and maximum 100.",maximum:100,minimum:1,type:"integer"},section_offset:{description:"Zero-based section offset when include_sections is true. Default 0. Use nextSectionOffset from the previous result to continue.",minimum:0,type:"integer"}},type:"object"}},{name:"measure_blocks",description:"Measure inclusive block ranges in the current document without loading document text. Use this for word counts, paragraph counts, block counts, and rendered page ranges. Block IDs may be passed with or without a leading #.",inputSchema:{additionalProperties:!1,properties:{mode:{description:"Range mode. Only inclusive is supported.",enum:["inclusive"],type:"string"},ranges:{description:"Inclusive block ranges to measure. Omit end_block_id to measure only start_block_id.",items:{additionalProperties:!1,properties:{end_block_id:{description:"Last block ID in the inclusive range. Omit to measure only the start block.",type:"string"},start_block_id:{description:"First block ID in the inclusive range.",type:"string"}},required:["start_block_id"],type:"object"},type:"array"}},required:["ranges"],type:"object"}},{name:"view_image",description:'View a document image by block ID when its <img> src is hidden. Viewing is only for seeing pixels; you do not need the hidden source to copy, move, or swap an image—write <img src="IMAGE_ID"> with its exact document id in insert_block or replace_block HTML.',inputSchema:{additionalProperties:!1,properties:{block_id:{description:"Image block ID.",type:"string"}},required:["block_id"],type:"object"}},{name:"insert_block",description:'Insert native block(s) before/after a reference block using HTML. A reference may be nested inside a table cell; inserting <img> (bare or wrapped by a paragraph/presentational span) next to that reference creates a native image block in the same cell. For a web-sourced image, use a verified direct raster URL returned by search for src; never guess or infer an image filename. Add data-source-url="..." to the <img> using the source webpage URL returned by web search, or the original image URL when no webpage URL is available; Revise preserves this provenance across later requests while rehosting the rendered image. For a live table of contents that automatically tracks document headings, insert <toc levels="3"></toc> (levels may be 1-6; omitting the attribute defaults to 3). Never build a table of contents from ordinary paragraphs, tabs, lists, or manually copied headings. For an Arabic/RTL live TOC, keep the toc block and set dir="rtl" and style="text-align:right" on it; direction:rtl and text-align:right also work through style_blocks. RTL places page numbers at the left edge. Do not replace a live TOC with a static table to adjust formatting. Put alignment directly in inserted HTML when needed. To cite inside new content, embed native notes inline: <sup data-footnote="Note body.">1</sup> creates a footnote in this same call (data-note-kind="endnote" for endnotes).',inputSchema:{additionalProperties:!1,properties:{content:{description:'HTML block elements to insert, e.g. <p>, <h1>, <ul>, <img>, <toc levels="3"></toc> (live table of contents), <page-break />, <hr /> (horizontal rule), <pre>. An image may be wrapped in a paragraph/span for alignment and display dimensions. For a web-sourced image, use a verified direct raster URL returned by search for src. Never guess or infer an image filename. Put its source webpage URL in data-source-url on the <img> (fall back to the original image URL). An image whose src is hidden is still usable: to copy or move it, write <img src="IMAGE_ID"> with its exact document id (dimensions and alt may be restated); the source is resolved automatically, so never ask the user for it.',items:{type:"string"},type:"array"},position:{description:"Insert before or after reference block.",enum:["before","after"],type:"string"},referenceId:{description:"Current reference block ID. For a blank document, pass an empty string with position=after; the editor resolves the blank insertion location. Never ask the user to type placeholder text. For a document with content, use an existing block ID.",type:"string"}},required:["content","position","referenceId"],type:"object"}},{name:"insert_footnote",description:"Insert a footnote: a numbered superscript reference placed right after the anchor text in a paragraph, plus the footnote body (rendered at the bottom of the page). Footnote bodies appear in the document as [^n] references with their own blocks — edit them with replace/replace_block and remove them with remove_blocks on the footnote block (removing a body also removes its reference).",inputSchema:{additionalProperties:!1,properties:{find:{description:"Anchor text inside the block; the reference is inserted right after it. Empty string appends at the end of the block.",type:"string"},id:{description:"Paragraph block ID that receives the reference.",type:"string"},kind:{description:"Note stream: footnote (per-page bottom area, numbered 1,2,3 — default) or endnote (grouped on its own page at the document end, numbered i,ii,iii).",enum:["footnote","endnote"],type:"string"},text:{description:"Footnote body text.",type:"string"}},required:["id","find","text"],type:"object"}},{name:"remove_blocks",description:"Remove native footnotes/endnotes by targeting the note ID or its body block ID with id + count=1; this removes the entire note and all its inline references while preserving the surrounding paragraph. To remove multiple notes, use ids containing only note/body IDs (do not mix with main-document block IDs or use a count range). For notes found by search, use their explicit IDs rather than search_result_id. Remove one or more blocks by a direct target (id, optionally with count), an explicit tail range (id + through_end=true), an exact nonconsecutive ID batch (ids), or every block in a full search_document result (search_result_id). through_end removes the starting top-level block and every block after it through the current end of the document; use it only when that entire tail must be removed. The starting id must have appeared in current request context, but through_end does not require reading every interior block. Other direct targets must have appeared in current request context. Prefer search_result_id for large or sparse match sets; search discovers candidates but never deletes them implicitly.",inputSchema:{additionalProperties:!1,properties:{count:{description:"Number of consecutive blocks. Only count blocks available in the current document context; never use the document total block count.",minimum:1,type:"integer"},id:{description:"First block ID to remove.",type:"string"},ids:{description:"Exact nonconsecutive block IDs to remove. Each ID must have appeared in document context during this request. Do not infer IDs from a query.",items:{type:"string"},maxItems:50,minItems:1,type:"array"},search_result_id:{description:"Request-scoped ID returned by search_document for the current document. Applies this operation to every block in the full unpaginated result set. Use instead of id or ids. Rerun search_document if the reference is unavailable or stale.",type:"string"},through_end:{description:"Set true with id to remove that top-level block and the entire document tail after it. Mutually exclusive with count, ids, and search_result_id. Omit unless the whole tail is intentionally in scope.",type:"boolean"}},type:"object"}},{name:"append_to_paragraph",description:"Append HTML content to a paragraph.",inputSchema:{additionalProperties:!1,properties:{content:{description:"HTML content to append.",type:"string"},id:{description:"Paragraph ID.",type:"string"}},required:["id","content"],type:"object"}},{name:"break_paragraph",description:"Split a paragraph at the first occurrence of substring; second paragraph starts there.",inputSchema:{additionalProperties:!1,properties:{id:{description:"Paragraph ID.",type:"string"},substring:{description:"Substring where split begins.",type:"string"}},required:["id","substring"],type:"object"}},{name:"join_paragraphs",description:"Join two adjacent paragraphs without rewriting their text. The second paragraph is appended to the first, preserving inline formatting from both paragraphs, then removed. Use this to repair an accidental paragraph break or hard return.",inputSchema:{additionalProperties:!1,properties:{firstId:{description:"ID of the first paragraph. This paragraph and its block formatting are preserved.",type:"string"},secondId:{description:"ID of the immediately following sibling paragraph. Its inline-formatted text is appended, then this block is removed.",type:"string"},separator:{description:"Text placed between the paragraphs. Defaults to one space between non-empty paragraphs. A non-empty separator replaces existing boundary whitespace so it is not duplicated. Pass an empty string to add nothing and preserve existing boundary whitespace.",type:"string"}},required:["firstId","secondId"],type:"object"}},{name:"replace_block",description:'Replace entire consecutive block(s) with HTML block(s), or apply the same one-block replacement independently to every block in a full search_document result via search_result_id. Use this only when the whole block must be replaced, its block type must change, or multiple consecutive blocks must become a different block structure. Prefer replace for ordinary wording, sentence, paragraph-text, typo, punctuation, or formatting-preserving edits—even when most or all visible text in one paragraph changes—because replace preserves block identity and untouched formatting. Preserve the existing block type unless the user asks to change it: use <pre language="..."> for code, <latex> for display math, and <latex-inline> for inline math. Put alignment in replacement HTML. For a web-sourced replacement image, use a verified direct raster URL returned by search for src; never guess or infer an image filename. Put its source webpage URL in data-source-url on the <img> (fall back to the original image URL).',inputSchema:{additionalProperties:!1,properties:{content:{description:'Replacement HTML block elements, e.g. <p>, <h1>, <ul>, <pre language="typescript">code</pre>, <img>, or <latex>E = mc^2</latex>. Match the original block type unless a type change was requested. For a web-sourced image, use a verified direct raster URL returned by search for src. Never guess or infer an image filename. Put its source webpage URL in data-source-url on the <img> (fall back to the original image URL). An image whose src is hidden is still usable: to copy or move it, write <img src="IMAGE_ID"> with its exact document id (dimensions and alt may be restated); the source is resolved automatically, so never ask the user for it.',items:{type:"string"},type:"array"},count:{description:"Number of consecutive sibling blocks to replace. Only count blocks available in the current document context; never use the document total block count.",minimum:1,type:"integer"},id:{description:"First block ID to replace.",type:"string"},search_result_id:{description:"Request-scoped ID returned by search_document for the current document. Applies this operation to every block in the full unpaginated result set. Use instead of id or ids. Rerun search_document if the reference is unavailable or stale.",type:"string"}},required:["content"],type:"object"}},{name:"style_blocks",description:'Style existing content with forgiving CSS-lite selectors and values. Use one bulk style_blocks call instead of per-block replace calls when matching content shares a selector or search result. Pass search_result_id to scope selectors to every block in the full unpaginated search_document result; * then means each matched block. Block selectors include *, #blockId, p, h1-h6, li, lists, tables, and descendants. Inline selectors such as span, b/strong, i/em, u, s/strike/del, code, sup, sub, mark, and a target text ranges; they may be scoped, for example p span, p b, or #blockId strong. Text color accepts CSS named colors, hex colors, and CSS color functions and stores an absolute hex color. For text highlighting, use backgroundColor with one of the seven canonical values yellow, orange, green, blue, purple, pink, or gray; other names and CSS colors normalize to this palette and may be the same color. A backgroundColor on a table-cell selector sets the cell fill; on text blocks or inline selectors it highlights text. Table-cell selectors apply text styles, alignment, and spacing to their descendant paragraphs. Examples: highlight all h3 headings orange with selectors="h3" and attrs=[{"name":"backgroundColor","value":"orange"}]; remove all bold with selectors="b" and attrs=[{"name":"fontWeight","value":"normal"}]; set the entire document to Century Schoolbook 14pt double-spaced with selectors="*" and fontFamily/fontSize/lineSpacing attrs; bold headings with selectors=["h1","h2","h3"] and fontWeight="bold".',inputSchema:{additionalProperties:!1,properties:{attrs:{description:"Use CSS/Revise names. Text colors accept CSS names, hex, or functions. Highlights: yellow, orange, green, blue, purple, pink, or gray. Supports text typography, block alignment, hanging indents, list presentation, image sizing with CSS lengths, and table/cell sizing with percentage widths. CSS maps to durable document equivalents; feedback lists approximations and unsupported values. Null resets.",items:{additionalProperties:!1,properties:{name:{description:"Attribute/style name, e.g. fontSize, font-size, fontFamily, text-align.",type:"string"},value:{description:"Value to set, or null to remove/reset.",oneOf:[{type:"string"},{type:"number"},{type:"boolean"},{type:"null"}]}},required:["name","value"],type:"object"},minItems:1,type:"array"},search_result_id:{description:"Request-scoped ID returned by search_document for the current document. Applies this operation to every block in the full unpaginated result set. Use instead of id or ids. Rerun search_document if the reference is unavailable or stale.",type:"string"},selectors:{description:'CSS-lite selectors over the document HTML: * (also all, document, or :root), #blockId, p, h1-h6, li, ul, ol, pre, latex, img, table, tr, td/th, div, p[data-style-id="StyleName"], and inline formatting tags span, b/strong, i/em, u, s/strike/del, code, sup, sub, mark, a. Simple descendants, general siblings, descendant wildcards, :first-child, and :nth-child(n) are accepted, e.g. table tr:first-child td, table td:nth-child(2) p, #blockId td p, #blockId *, #blockId ~ p, p span, p b, or #blockId strong. Inline selectors affect matching text ranges; span means all text in its scope. Arrays and comma grouping are allowed.',oneOf:[{type:"string"},{items:{type:"string"},minItems:1,type:"array"}]}},required:["selectors","attrs"],type:"object"}},{name:"clear_formatting",description:"Clear removable inline emphasis from paragraph/list-item target(s): bold, italic, underline, code, LaTeX, superscript/subscript, background highlight, and links. Preserve font family, font size, text color, and paragraph attributes.",inputSchema:{additionalProperties:!1,properties:{id:{description:"Target paragraph/list-item/list ID or IDs.",oneOf:[{type:"string"},{items:{type:"string"},minItems:1,type:"array"}]}},required:["id"],type:"object"}},{name:"set_title",description:"Change the document title",inputSchema:{additionalProperties:!1,properties:{title:{description:"The new document title",maxLength:300,type:"string"}},required:["title"],type:"object"}},{name:"set_page_layout",description:"Patch page or section layout: preset, size, margins, 1-3 columns, page numbers, spacing, pageless mode. ONLY the fields you pass change; everything else keeps its current or inherited value (a section keeps inheriting document-level settings for fields you don't pass). Pass sectionIndex to change one section; omit it to apply the passed fields to the document defaults and every section. Length fields must be strings with explicit px/in/cm units. Preset 'apa7' applies standard APA layout.",inputSchema:{additionalProperties:!1,properties:{blockSpacing:{description:'Vertical spacing between adjacent blocks, shown in the UI in inches or centimeters. Typical values are "0.08in" to "0.25in" (about "0.2cm" to "0.64cm"); do not use whole-inch values like "2in" or "4in" for normal paragraph spacing. Include an explicit unit: in, cm, or px (examples: "1in", "3cm", "72px"). Prefer in/cm for page layout values shown in the UI. Do not send bare numbers.',type:"string"},clearPageBorders:{description:"Set true to remove all page borders from the target section(s), including preserved Word art borders.",type:"boolean"},columnCount:{description:"Number of newspaper-style columns in the target section.",enum:[1,2,3],type:"integer"},columnGap:{description:'Gap between columns. Include an explicit unit: in, cm, or px (examples: "1in", "3cm", "72px"). Prefer in/cm for page layout values shown in the UI. Do not send bare numbers.',type:"string"},indentStep:{description:'Paragraph indent step. Include an explicit unit: in, cm, or px (examples: "1in", "3cm", "72px"). Prefer in/cm for page layout values shown in the UI. Do not send bare numbers.',type:"string"},margin:{description:'Uniform page margin applied to all sides. Include an explicit unit: in, cm, or px (examples: "1in", "3cm", "72px"). Prefer in/cm for page layout values shown in the UI. Do not send bare numbers.',type:"string"},marginBottom:{description:'Bottom page margin. Include an explicit unit: in, cm, or px (examples: "1in", "3cm", "72px"). Prefer in/cm for page layout values shown in the UI. Do not send bare numbers.',type:"string"},marginLeft:{description:'Left page margin. Include an explicit unit: in, cm, or px (examples: "1in", "3cm", "72px"). Prefer in/cm for page layout values shown in the UI. Do not send bare numbers.',type:"string"},marginRight:{description:'Right page margin. Include an explicit unit: in, cm, or px (examples: "1in", "3cm", "72px"). Prefer in/cm for page layout values shown in the UI. Do not send bare numbers.',type:"string"},marginTop:{description:'Top page margin. Include an explicit unit: in, cm, or px (examples: "1in", "3cm", "72px"). Prefer in/cm for page layout values shown in the UI. Do not send bare numbers.',type:"string"},noteMode:{description:"Bulk-convert existing native notes to this stream: footnotes (per-page areas, 1,2,3) or endnotes (own page at document end, i,ii,iii). Does not convert manually typed superscript numbers or note paragraphs; create native notes with their complete bodies and references first. Individual notes choose a stream at insert time.",enum:["footnotes","endnotes"],type:"string"},orientation:{description:"Page orientation.",enum:["portrait","landscape"],type:"string"},pageBorders:{additionalProperties:!1,description:"Native page border for the target section(s), rendered in the editor and PDF and preserved in DOCX. Replaces the whole border configuration; omitted sides have no border. To remove borders use clearPageBorders=true. Measurements are points (1/72 inch).",properties:{bottom:{additionalProperties:!1,properties:{color:{pattern:"^#[0-9a-fA-F]{6}$",type:"string"},spacePt:{maximum:31,minimum:0,type:"number"},style:{enum:["single","double","dotted","dashed"],type:"string"},widthPt:{maximum:12,minimum:.25,type:"number"}},required:["style","color","widthPt","spacePt"],type:"object"},display:{enum:["allPages","firstPage","notFirstPage"],type:"string"},left:{additionalProperties:!1,properties:{color:{pattern:"^#[0-9a-fA-F]{6}$",type:"string"},spacePt:{maximum:31,minimum:0,type:"number"},style:{enum:["single","double","dotted","dashed"],type:"string"},widthPt:{maximum:12,minimum:.25,type:"number"}},required:["style","color","widthPt","spacePt"],type:"object"},offsetFrom:{enum:["page","text"],type:"string"},right:{additionalProperties:!1,properties:{color:{pattern:"^#[0-9a-fA-F]{6}$",type:"string"},spacePt:{maximum:31,minimum:0,type:"number"},style:{enum:["single","double","dotted","dashed"],type:"string"},widthPt:{maximum:12,minimum:.25,type:"number"}},required:["style","color","widthPt","spacePt"],type:"object"},top:{additionalProperties:!1,properties:{color:{pattern:"^#[0-9a-fA-F]{6}$",type:"string"},spacePt:{maximum:31,minimum:0,type:"number"},style:{enum:["single","double","dotted","dashed"],type:"string"},widthPt:{maximum:12,minimum:.25,type:"number"}},required:["style","color","widthPt","spacePt"],type:"object"},zOrder:{enum:["front","back"],type:"string"}},required:["offsetFrom","display","zOrder"],type:"object"},pageHeight:{description:'Explicit page height. Include an explicit unit: in, cm, or px (examples: "1in", "3cm", "72px"). Prefer in/cm for page layout values shown in the UI. Do not send bare numbers.',type:"string"},pageNumberFormat:{description:"Page number style: decimal (1, 2, 3), lowerRoman (i, ii, iii), or upperRoman (I, II, III). Applies to page-number fields, the table of contents, and exports. Use sectionIndex for front matter.",enum:["decimal","lowerRoman","upperRoman"],type:"string"},pageNumberPosition:{description:"Page number position.",enum:["top-left","top-right","bottom-left","bottom-right"],type:"string"},pageNumberRestart:{description:"Section numbering mode (use with sectionIndex, including the final section): true restarts at pageNumberStart (default 1); false continues from the previous section. Typical thesis: Roman front matter, then the final body section restarts at 1.",type:"boolean"},pageNumberStart:{description:"First page number. With sectionIndex it restarts numbering at that section (e.g. body starts again at 1 after Roman front matter).",minimum:1,type:"integer"},pageSize:{description:"Named page-size preset.",enum:["letter","tabloid","legal","statement","executive","folio","a3","a4","a5","b4","b5"],type:"string"},pageWidth:{description:'Explicit page width. Include an explicit unit: in, cm, or px (examples: "1in", "3cm", "72px"). Prefer in/cm for page layout values shown in the UI. Do not send bare numbers.',type:"string"},pageless:{description:"Enable pageless mode.",type:"boolean"},preset:{description:"Preset applied before overrides.",enum:["apa7"],type:"string"},sectionIndex:{description:"One-based section number to patch (invalid indexes fail the call). Omit to apply the passed fields to the document defaults and every section.",minimum:1,type:"integer"},showPageNumbers:{description:"Show or hide page numbers. Page numbers are header/footer content: this manages an automatic page-number field slot (combine with pageNumberPosition). Hand-authored header/footer content is never overwritten.",type:"boolean"}},required:[],type:"object"}},{name:"set_header_footer",description:'Edit page header/footer content. Each side has three zones (left, center, right); provide only the zones to change - untouched zones keep their content and formatting. Use the literal token {PAGE} for a live page number and {PAGES} for the total page count, anywhere in any zone (e.g. right: "Page {PAGE} of {PAGES}"). An empty string clears a zone; clear=true removes the whole header or footer. For a plain bottom-right page number, set_page_layout with showPageNumbers also works.',inputSchema:{properties:{center:{description:"Center zone text ({PAGE}/{PAGES} tokens allowed). Omit to keep unchanged; empty string clears.",type:"string"},clear:{description:"Remove this side's header/footer entirely.",type:"boolean"},left:{description:"Left zone text ({PAGE}/{PAGES} tokens allowed). Omit to keep unchanged; empty string clears.",type:"string"},right:{description:"Right zone text ({PAGE}/{PAGES} tokens allowed). Omit to keep unchanged; empty string clears.",type:"string"},side:{description:"Which band to edit.",enum:["header","footer"],type:"string"},slot:{description:"Which pages this applies to (Word slot model). Default: all pages.",enum:["default","first","even"],type:"string"}},required:["side"],type:"object"}},{name:"replace",description:"Preferred/default tool for editing text inside an existing block, including wording, sentences, typos, punctuation, formatting-preserving rewrites, and even replacing all visible text in one paragraph when its block type/structure should stay the same. It preserves block identity and untouched formatting; use replace_block only for whole-block structural or block-type changes. Supports one or more in-place edits inside one block, uniquely identifiable edits across loaded blocks when id is omitted, or the same edits independently in every block from a full search_document result via search_result_id. An empty find safely fills a direct-id target only when that target is truly empty. Each operation may include its own comment, which is attached to every suggestion produced by that operation. For each edit, occurrence defaults to unique: its find HTML/text must be specific enough to match exactly one location in each target block or the entire call fails without changing the document. Use occurrence=all only when every exact occurrence should change. Omit no-op replacements where find and replace are identical.",inputSchema:{additionalProperties:!1,properties:{id:{description:"Target block ID. May be omitted only when every non-empty find uniquely identifies one loaded block, or when search_result_id is used.",type:"string"},replacements:{description:"Ordered replacement operations. Use one item for one edit and multiple items to batch edits in the same block.",items:{additionalProperties:!1,properties:{comment:{description:"Optional comment explaining this operation. It is attached separately to every resulting suggestion from this operation, including every match when occurrence=all. Prefer this over a separate leave_comment when the feedback explains the suggested edit.",type:"string"},find:{description:"Exact text to find; HTML allowed for formatted targets. With occurrence=unique or when occurrence is omitted, include enough surrounding context to match exactly one location.",type:"string"},occurrence:{description:"unique (default when omitted) requires exactly one match; all replaces every exact match.",enum:["unique","all"],type:"string"},replace:{description:"Replacement text; HTML allowed for formatting changes. Must differ from find unless the replacement HTML creates a real formatting change.",type:"string"}},required:["find","replace"],type:"object"},maxItems:50,minItems:1,type:"array"},search_result_id:{description:"Request-scoped ID returned by search_document for the current document. Applies this operation to every block in the full unpaginated result set. Use instead of id or ids. Rerun search_document if the reference is unavailable or stale.",type:"string"}},required:["replacements"],type:"object"}},{name:"leave_comment",description:"Leave granular review feedback on the current document without changing its text. Prefer this for substantive passage-specific critique, feedback, annotations, issues, or improvements instead of putting that feedback in a long chat response. Two modes. To START a thread: target one block with id and exactly one anchor form — unique exact text for a short range, start/end boundary text for a longer range without reproducing it, or the whole block for structural/empty content. To REPLY to a thread that already exists: pass reply_to_comment_id (a <comment-thread> id from loaded document content) and comment, with no id and no anchor. Existing threads are visible as <comment-thread> elements in loaded document content; when text already carries one, reply to it rather than starting a second thread that repeats the same point.",inputSchema:{additionalProperties:!1,properties:{acknowledge_existing_thread_ids:{description:"Only for a NEW thread that deliberately overlaps existing unresolved threads: list their ids to confirm you read them and are raising a genuinely different point. Without this, a new thread overlapping an existing one is rejected. Do not use it to restate a point an existing thread already makes — reply to that thread instead.",items:{type:"string"},type:"array"},anchor:{description:"Exactly one single-block anchor. Required for a new thread; omit when replying.",oneOf:[{additionalProperties:!1,properties:{text:{description:"Exact text or HTML fragment that identifies exactly one occurrence in the block. When words repeat with different formatting, include the formatting, for example <b>claim</b> for the bold occurrence or <i>claim</i> for the italic occurrence. Include only the text to be commented on.",type:"string"}},required:["text"],type:"object"},{additionalProperties:!1,properties:{end_text:{description:"Exact text or HTML fragment at the end of the range. This boundary is included in the comment; do not use surrounding separators unless they should also be commented on.",type:"string"},start_text:{description:"Exact text or HTML fragment at the beginning of the range. This boundary is included in the comment; do not use surrounding separators unless they should also be commented on.",type:"string"}},required:["start_text","end_text"],type:"object"},{additionalProperties:!1,properties:{whole_block:{const:!0,description:"Anchor the comment to the entire block.",type:"boolean"}},required:["whole_block"],type:"object"}]},comment:{description:"Comment body.",type:"string"},id:{description:"Target block ID for a NEW thread. The block must be present in loaded document context. Omit when replying.",type:"string"},reply_to_comment_id:{description:"Reply to an existing thread instead of starting a new one: any comment id in that thread (the reply attaches to the thread root). A reply inherits the thread's anchor, so omit id and anchor when replying.",type:"string"}},required:["comment"],type:"object"}},{name:"insert_table_row",description:"Insert a new row into an existing table. Prefer referenceRowId from the visible <tr id> for a named row; this remains stable when earlier rows are inserted. Use position=before for above/before that row and after for below/after. Only call this when the target <table> block is visible in the loaded document content; read the table's blocks first if it is not loaded.",inputSchema:{additionalProperties:!1,properties:{content:{description:"HTML indexed by grid column (0-based); use an empty string as a placeholder for a position covered by a merged cell, or an empty array to insert empty cells. Nonempty content at covered positions and entries beyond the table dimensions are rejected without changing the table.",items:{type:"string"},type:"array"},position:{description:"Whether to insert before or after the reference row",enum:["before","after"],type:"string"},referenceIndex:{description:"Optional 0-based row index, counting header and empty rows. Required only without referenceRowId. If both are supplied, they must identify the same current row.",type:"integer"},referenceRowId:{description:"Preferred stable row ID from <tr id> in the loaded table. Supply this or referenceIndex.",type:"string"},tableId:{description:"The table block ID",type:"string"}},required:["tableId","position","content"],type:"object"}},{name:"remove_table_row",description:"Remove a row from an existing table. Only call this when the target <table> block is visible in the loaded document content; read the table's blocks first if it is not loaded.",inputSchema:{additionalProperties:!1,properties:{rowIndex:{description:"The index of the row to remove (0-based)",type:"integer"},tableId:{description:"The table block ID",type:"string"}},required:["tableId","rowIndex"],type:"object"}},{name:"insert_table_column",description:"Insert a new column into an existing table. Only call this when the target <table> block is visible in the loaded document content; read the table's blocks first if it is not loaded.",inputSchema:{additionalProperties:!1,properties:{content:{description:"HTML indexed by grid row (0-based); use an empty string as a placeholder for a position covered by a merged cell, or an empty array to insert empty cells. Nonempty content at covered positions and entries beyond the table dimensions are rejected without changing the table.",items:{type:"string"},type:"array"},position:{description:"Whether to insert before or after the reference column",enum:["before","after"],type:"string"},referenceIndex:{description:"The column index to insert relative to (0-based)",type:"integer"},tableId:{description:"The table block ID",type:"string"}},required:["tableId","referenceIndex","position","content"],type:"object"}},{name:"remove_table_column",description:"Remove a column from an existing table. Only call this when the target <table> block is visible in the loaded document content; read the table's blocks first if it is not loaded.",inputSchema:{additionalProperties:!1,properties:{columnIndex:{description:"The index of the column to remove (0-based)",type:"integer"},tableId:{description:"The table block ID",type:"string"}},required:["tableId","columnIndex"],type:"object"}},{name:"edit_table_cells",description:"Set the plain text of up to 50 table cells in one call, addressed by table_id, stable row_id and 0-based logical column. Every target cell must be editable now: fully delivered by read_table or, in agent conversations, listed in editable_now of the table's newest <table_descriptor> for the current request (complete table seeds and full cell snapshots qualify). Edit listed cells directly without a redundant read_table call; summaries and partial cell_text windows do not count. text is literal exact text, never HTML: values such as 007, 1e5, <b> and tabs/newlines are kept verbatim. Supports cells holding one plain-text paragraph; table and cell formatting is preserved. Cells with rich or multi-block content (images, lists, nested tables) are refused with a route to the existing rich editing tools. mode=fill_if_empty writes only cells that are still empty and reports every skipped non-empty cell; mode=replace overwrites. An unknown, duplicate, covered (merged non-anchor), cross-table or geometry-shifted target, or a stale replace target, rejects the whole batch with every invalid item listed and no changes. Each cell is an individually reviewable suggestion and one successful call is one undo step. Collect targets from delivered table contents and batch up to 50 edits per call; never send one call per cell when a batch is possible. Serialized arguments are limited to 32 KiB.",inputSchema:{additionalProperties:!1,properties:{cells:{description:"Cell edits. Each (row_id, column) may appear once.",items:{additionalProperties:!1,properties:{column:{description:"0-based logical column of the cell's anchor.",minimum:0,type:"integer"},row_id:{description:"Stable row ID (<tr id>).",type:"string"},text:{description:"Exact literal cell text. Not HTML.",type:"string"}},required:["row_id","column","text"],type:"object"},maxItems:50,minItems:1,type:"array"},mode:{description:"fill_if_empty skips and reports cells that are no longer empty; replace overwrites the delivered cell text.",enum:["fill_if_empty","replace"],type:"string"},table_id:{description:"Table block ID in the current document.",type:"string"}},required:["table_id","mode","cells"],type:"object"}}],Is=new Map(Qn.map(t=>[t.name,t.inputSchema]));function Lt(t){return t!==null&&typeof t=="object"&&!Array.isArray(t)}function eo(t,e){return Object.prototype.hasOwnProperty.call(t,e)}function Ss(t,e){switch(e){case"null":return t===null;case"object":return Lt(t);case"array":return Array.isArray(t);case"string":return typeof t=="string";case"number":return typeof t=="number"&&Number.isFinite(t);case"integer":return typeof t=="number"&&Number.isInteger(t);case"boolean":return typeof t=="boolean";default:return!0}}function Be(t,e){return!(t.const!==void 0&&!Object.is(t.const,e)||t.enum&&!t.enum.some(n=>Object.is(n,e))||t.type&&!(Array.isArray(t.type)?t.type:[t.type]).some(n=>Ss(e,n))||t.allOf?.some(n=>!Be(n,e))||t.anyOf&&!t.anyOf.some(n=>Be(n,e))||t.oneOf&&t.oneOf.filter(n=>Be(n,e)).length!==1||t.not&&Be(t.not,e)||Lt(e)&&t.required&&!t.required.every(n=>eo(e,n)))}function Xe(t,e){let n=t;if(Array.isArray(n)&&e.items)n=n.map(o=>Xe(o,e.items));else if(Lt(n)&&e.properties){const o=new Set(e.required??[]),r={...n};for(const[s,i]of Object.entries(e.properties))if(eo(r,s)){if(r[s]===null&&!o.has(s)&&!Be(i,null)){delete r[s];continue}r[s]=Xe(r[s],i)}n=r}for(const o of e.allOf??[])n=Xe(n,o);for(const o of[e.anyOf,e.oneOf]){const r=o?.filter(s=>Be(s,n));r?.length===1&&(n=Xe(n,r[0]))}return n}function xs(t,e){const n=Is.get(t);return n?Xe(e,n):e}const Cs="This request is non-interactive. Continue the supported work using the supplied context and reasonable assumptions. Explain material gaps in the final response or permitted comments; do not invent facts or ask for clarification or approval.",$s=new Set(["read_table","create_plan","update_plan","read_blocks","read_blocks_from_index","read_specific_blocks","search_document","find_highlights","measure_document","measure_blocks","list_documents","search_documents","get_attachment","view_image","render_document_pages","set_status","request_user_input","end_agent_run","finish_response","ready_for_verification"]),Ms=new Set(["missed_requirements","verification_passed"]);function to(t){const e=t.trim();return e==="remove_blocks"?"remove_block":e}function Ds(t){return Array.from(new Set(t.map(to).filter(Boolean)))}function Ts(t,e){const n=to(e);return Ms.has(n)?{code:"agent_tool_not_allowed",message:"This legacy verification tool is unavailable. Continue supported work or finish with end_agent_run."}:n==="request_user_input"&&t.interaction==="best_effort"?{code:"agent_interaction_not_allowed",message:Cs}:t.allowedTools!=null&&!Ds(t.allowedTools).includes(n)?{code:"agent_tool_not_allowed",message:"This tool is outside the host's execution allowlist. Continue using permitted tools or finish with the best supported response."}:Tt.has(n)?t.documentAccess==="edit"||t.documentAccess==="comment"&&n==="leave_comment"?null:{code:"agent_document_access_denied",message:"This request does not permit this document mutation. Continue within the granted document access and explain any work that could not be completed."}:$s.has(n)?null:{code:"agent_tool_not_allowed",message:"This tool has no execution-policy classification and cannot run. Continue using permitted tools."}}const pt="no_new_read_context",Ne={scanDocumentFontFamily:!1};function Le(t){return t.getAgentAuthorName?.()?.trim()||Vo}const no=2,As=48,qs=.4,qe=10,Rs=100,Ps=100,Oe=48e3,Ue="out_of_context_edit",xe="document_state_changed",oo="table_batch_rejected",Bs="duplicate_comment_anchor",Ns="one_read_search_per_turn",ro="terminal_tool_requires_turn_two_continuation",so="terminal_response_status_only",Ls="end_agent_run",Os="finish_response",Us="ready_for_verification",js=new Set(["read_blocks","read_blocks_from_index","read_specific_blocks","search_document","search_documents","find_highlights","render_document_pages"]);function Fs(t){return t===Ls||t===Os}function io(t){return t.replace(/<status\b[^>]*>[\s\S]*?<\/status>/gi,"").trim().length===0}const Ot="https://app-api.revise-sdk.invalid";function Es(t){if(t&&typeof t=="object"&&!Array.isArray(t))return t;if(typeof t!="string")return null;const e=t.trim();if(!e)return null;if(!e.startsWith("{")||!e.endsWith("}"))return{text:e};try{const n=JSON.parse(e);return n&&typeof n=="object"&&!Array.isArray(n)?n:null}catch{return null}}function zs(t){const e=He(t.doc,t.requestedBlockId);if(!e||!Array.isArray(e.children))return null;const n=[],o=r=>{if(!(!r||typeof r!="object")&&(r.id!==t.requestedBlockId&&typeof r.id=="string"&&Jo(r)&&n.push({blockId:r.id,text:St(r),html:mn(t.anchorText)?hn(r):void 0}),Array.isArray(r.children)))for(const s of r.children)o(s)};return o(e),un(n,t.anchorText)}function Hs(t){return!t.loadedBlockIds||t.loadedBlockIds.size===0?null:un(zo(t.doc).filter(e=>e.blockId!==t.requestedBlockId&&Ho(e,t.loadedBlockIds)).map(e=>({...e,html:mn(t.anchorText)?hn(He(t.doc,e.blockId)):void 0})),t.anchorText)}function Ws(t,e,n,o,r,s,i){if(i.hasBlockId||i.hasAnchor)return k(t,"A reply inherits its thread's anchor: pass reply_to_comment_id and comment alone, without id or anchor.");const a=Fo(o,r);if(!a)return k(t,`Comment '${r}' was not found. Reply only to a <comment-thread> id you can see in loaded document content.`,xe);if(a.resolved===!0)return k(t,`Comment thread '${a.id}' is resolved. Leave a new anchored comment instead of replying to a settled thread.`);const c=n.getDocumentMutator(),u=Eo(o,c,a.id,s,{author:Le(e),authorType:"ai",agentName:Le(e),...e.getAgentModel?{agentModel:e.getAgentModel()}:{}}).commentId;if(!u)return k(t,`Could not reply to comment thread '${a.id}'.`);const f=Js(o,a);return f&&e.toolState.editedBlockIds.add(f),e.turnState.hasMutatedSinceLastRead=!0,e.metrics?.count("agent.comment.reply",1),W(t,`Replied ${u} in comment thread ${a.id}.`,void 0,void 0,JSON.stringify({commentId:u,threadId:a.id,mode:"reply",...f?{blockId:f}:{}}))}function Js(t,e){if(e.anchorBlockId){const n=Ie(t,e.anchorBlockId);return n>=0?t.children[n]?.id??e.anchorBlockId:e.anchorBlockId}for(const n of t.children)if(n.id&&Wo(n).has(e.id))return n.id;return null}function Gs(t,e,n,o){const r=t.arguments??{};let s=typeof r.id=="string"?r.id.trim():"";const i=typeof r.comment=="string"?r.comment.trim():"",a=Es(r.anchor),c=typeof r.reply_to_comment_id=="string"?r.reply_to_comment_id.trim():"",u=new Set((Array.isArray(r.acknowledge_existing_thread_ids)?r.acknowledge_existing_thread_ids:[]).filter(w=>typeof w=="string").map(w=>w.trim()).filter(Boolean));if(!i)return k(t,"leave_comment requires a non-empty comment.");if(c)return Ws(t,e,n,o,c,i,{hasBlockId:!!s,hasAnchor:!!a});if(!s)return k(t,"leave_comment requires id.");if(!a)return k(t,"leave_comment requires an anchor.");let f=He(o,s),$=null;const T=Ut(e.turnState),R=typeof a.text=="string"&&a.text.length>0?a.text:null;if(R&&f){const w=zs({doc:o,requestedBlockId:s,anchorText:R});w&&(s=w,f=He(o,s))}if(R&&(!f||Uo(f,R).length===0)){const w=Hs({doc:o,requestedBlockId:s,anchorText:R,loadedBlockIds:T});w&&w!==s&&($=s,s=w,f=He(o,s))}if(!f)return k(t,`Block '${s}' was not found.`,xe);const P=Ie(o,s),U=P>=0?o.children[P]?.id:void 0;if(!T||!T.has(s)&&(!U||!T.has(U)))return k(t,`leave_comment targets block '${s}', which is outside the loaded <document_content> context. Read that block first, then retry.`,Ue);const D=n.getDocumentMutator(),_={author:Le(e),authorType:"ai",agentName:Le(e),...e.getAgentModel?{agentModel:e.getAgentModel()}:{}},g=jo(n.getWorkingDocument(),o,D,s,i,a,_,Array.from(u));if(!g.success)return g.overlappingThreadIds?.length&&e.metrics?.count("agent.comment.overlap_blocked",1),k(t,g.error??"Could not attach comment.",g.overlappingThreadIds?.length?Bs:g.errorCode);const y=g.commentId,q=a.whole_block===!0,A=g.range;return u.size&&e.metrics?.count("agent.comment.overlap_acknowledged",1),e.toolState.editedBlockIds.add(U??s),e.turnState.hasMutatedSinceLastRead=!0,W(t,$?`Left comment ${y} on block ${s}: the anchor text was not in block ${$}, and ${s} is the only loaded block that contains it.`:`Left comment ${y} on block ${s}.`,void 0,void 0,JSON.stringify({commentId:y,blockId:s,...$?{requestedBlockId:$}:{},anchor:q?{wholeBlock:!0}:A}))}function k(t,e,n){return{toolCall:t,success:!1,error:e,...n?{errorCode:n}:{}}}function Vs(t){return t&&vs(new Error(t)).kind==="document_state"?xe:void 0}function W(t,e,n,o,r){return{toolCall:t,success:!0,agentFeedback:e,...n?{imageAttachment:n}:{},...o?{nonMeaningful:!0}:{},...r?{toolOutput:r}:{}}}function Ks(t){return t.tool||t.name}function Xs(t){if(!t||typeof t!="object")return null;const e=typeof t.status=="string"?t.status:typeof t.message=="string"?t.message:null;if(!e)return null;const n=e.replace(/[\s\n]+/g," ").trim();return n.length>0?n:null}function Ys(t){if(!t||typeof t!="object")return null;const e=typeof t.context_notes=="string"?t.context_notes:null;if(!e)return null;const n=e.trim();return n.length>0?n:null}function ao(t,e){for(const n of t){if(n.type==="image"&&n.id===e)return{src:n.src,sourceUrl:n.sourceUrl,alt:n.alt,width:n.width,height:n.height};if(Array.isArray(n.children)&&n.children.length>0){const o=ao(n.children,e);if(o)return o}}return null}function Ye(t){if(!t||typeof t!="object")return[];const e=t,n=[],o=new Set,r=i=>{if(typeof i!="string")return;const a=i.trim();!a||o.has(a)||(o.add(a),n.push(a))};if(r(e.id),r(e.referenceId),r(e.firstId),r(e.secondId),r(e.from_id),r(e.block_id),r(e.tableId),r(e.referenceRowId),r(e.after_block_id),Array.isArray(e.id))for(const i of e.id)r(i);if(Array.isArray(e.block_ids))for(const i of e.block_ids)r(i);Array.isArray(e.ids)&&e.ids.forEach(r);const s=Array.isArray(e.selectors)?e.selectors:[e.selectors];for(const i of s)if(typeof i=="string")for(const a of i.split(",")){const c=a.trim().match(/^#([A-Za-z0-9_-]+)(?=$|[\s:>~+])/);c&&r(c[1])}if(e.selector&&typeof e.selector=="object"&&Ye(e.selector).forEach(r),Array.isArray(e.replacements))for(const i of e.replacements)Ye(i).forEach(r);return n}function co(t){const e=Ye(t.arguments),n=e.length===0?"the target block":e.length===1?`block ${e[0]}`:`${e.length} blocks`;if(t.name==="set_block_attribute"||t.name==="style_blocks"){const o=t.arguments&&typeof t.arguments=="object"?t.arguments:{},r=typeof o.attribute=="string"&&o.attribute.trim().length>0?o.attribute.trim():"attribute";return(typeof o.operation=="string"&&o.operation.trim().length>0?o.operation.trim():"set")==="remove"?`No document mutation occurred; ${r} was already removed on ${n}.`:`No document mutation occurred; ${r} was already set on ${n}.`}return t.name==="clear_formatting"?`No document mutation occurred; formatting was already clear on ${n}.`:t.name==="replace_block"?`No document mutation occurred; replacing ${n} produced no document change. This result does not prove that the requested content is present; verify the current block before deciding no change is needed.`:t.name==="replace"||t.name==="replace_all"||t.name==="replace_many"?`No document mutation occurred; the replacement on ${n} produced no document change. This result does not prove that the requested content is present; verify the current block before deciding no change is needed.`:"No document mutation occurred; the document already matched the requested update."}function Zs(t){const e=Ks(t);return{id:t.id,name:e,arguments:xs(e,t.arguments)}}function Qs(t){return t.replace(/<[^>]*>/g," ").replace(/&nbsp;/gi," ").replace(/&amp;/gi,"&").replace(/&lt;/gi,"<").replace(/&gt;/gi,">").replace(/&quot;/gi,'"').replace(/&#39;|&apos;/gi,"'").replace(/\s+/g," ").trim()}function lo(t){return t.replace(/\s+/g," ").trim()}function Ut(t){const e=new Set;for(const n of[t.lastReadBlockIds,t.requestedBlockIds])if(n)for(const o of n)e.add(o);for(const n of t.docContextLedger?.delivered.keys()??[])e.add(n);return e.size>0?e:null}function ei(t){const e=[],n=new Set;for(const o of t)for(const r of Ye(o.arguments))n.has(r)||(n.add(r),e.push(r));return e}function uo(t,e){const n=new Set(e),o=new Set(e),r=s=>{const i="id"in s?s.id:void 0;let a=!!(i&&n.has(i));if("children"in s)for(const c of s.children)r(c)&&(a=!0);return a&&i&&o.add(i),a};for(const s of[...t.children,...t.chrome??[],...t.notes??[]])r(s);return o}function ti(t,e){if(t.length===1)return`block ${t[0]}`;if(t.length>1){const n=t.slice(0,4).join(", "),o=t.length>4?` (+${t.length-4} more)`:"";return`blocks ${n}${o}`}return e?`block ${e}`:"the target block"}function ni(t){if(t.length===0)return"";const e=Array.from(new Set(t.map(r=>`${r.fromBlockId}->${r.toBlockId}`))).map(r=>{const[s,i]=r.split("->");return`${s} -> ${i}`}),n=e.slice(0,4).join(", "),o=e.length>4?` (+${e.length-4} more)`:"";return`Retargeted ${t.length} replacement ${t.length===1?"operation":"operations"} to the unique loaded-context block match${t.length===1?"":"es"}: ${n}${o}.`}function oi(t,e,n){if(typeof t!="number"||!Number.isFinite(t))return e;const o=Math.floor(t);return o<=0?e:Math.min(o,n)}function Ze(t,e){if(typeof t!="number"||!Number.isFinite(t))return e;const n=Math.floor(t);return Math.max(0,n)}function ho(t,e,n,o,r,s){let i=[...s?.targetBlockIds??o];if(i.length===0&&t.arguments&&typeof t.arguments=="object"&&typeof t.arguments.id=="string"&&(i=[t.arguments.id.trim()].filter(Boolean)),i.length===1&&t.name==="remove_block"&&t.arguments&&typeof t.arguments=="object"){const A=i[0],w=oi(t.arguments.count,1,50),O=Ie(e,A);O!==-1&&w>1&&(i=e.children.slice(O,O+w).map(z=>z.id).filter(z=>typeof z=="string"&&z.length>0))}const a=t.arguments&&typeof t.arguments=="object"&&typeof t.arguments.search_result_id=="string"?t.arguments.search_result_id:null,c=a!==null||i.length>qe,u=!c&&t.name!=="replace"&&t.name!=="replace_many"&&t.name!=="replace_all"&&i.length>0?i.flatMap(A=>{const w=se(e,A);if(!w)return[];const O=t.arguments??{};if(w.type==="table"&&/^(insert|remove)_table_(row|column)$/.test(t.name)){if(t.name.endsWith("_row")){const d=typeof O.referenceRowId=="string"?w.children.find(C=>C.id===O.referenceRowId):w.children[Number(O.rowIndex??O.referenceIndex)];return d?[{id:d.id,html:ne.renderTableRow(w,d,e)}]:[]}const z=Te(w),K=Number(O.columnIndex??O.referenceIndex);return z.cells.filter(d=>d.col<=K&&d.col+d.colSpan>K).map(({cell:d})=>({id:d.id,html:ne.renderSubtree(d,e)}))}if(w.type==="table"&&w.id!==A){const z=w.children.find(K=>K.id===A);if(z)return[{id:A,html:ne.renderTableRow(w,z,e)}]}return[{id:A,html:ne.renderSubtree(w,e)}]}):[],f=[],$=[];let T=0;for(const A of u)T+A.html.length+1>8e3?$.push(A.id):(f.push(A.html),T+=A.html.length+1);const R=f.join(`
5
- `),P=i.filter(A=>se(e,A)&&!se(n,A)),U=s?.changedBlockIds??i.filter(A=>{const w=se(e,A),O=se(n,A);return JSON.stringify(w??null)!==JSON.stringify(O??null)}),D=new Set,_=A=>{for(const w of A)"id"in w&&w.id&&D.add(w.id),"children"in w&&_(w.children)};_(ge(e));const g=[],y=A=>{for(const w of A)"id"in w&&w.id&&!D.has(w.id)?g.push(w.id):"children"in w&&y(w.children)};y(ge(n));const q=(A,w,O=!1)=>c||O&&w.length>qe?{[`${A}_sample`]:w.slice(0,qe),[`${A}_omitted_count`]:Math.max(0,w.length-qe)}:{[A]:w};return JSON.stringify({tool:t.name,...a?{target_reference:a}:{},...r?{summary:r}:{},...s?{style_outcome:s.outcome,attribute_effects:s.attributes.map(A=>({name:A.name,applied_target_count:A.appliedBlockIds.length,skipped_target_count:new Set(A.skipped.map(w=>w.blockId)).size,...q("applied_block_ids",A.appliedBlockIds,!0),skipped:A.skipped.slice(0,qe),skipped_omitted_count:Math.max(0,A.skipped.length-qe)}))}:{},effect:{...s?q("affected_block_ids",s.affectedBlockIds,!0):{},requested_target_count:i.length,changed_target_count:U.length,removed_target_count:P.length,inserted_block_count:g.length,...q("target_block_ids",i),...q("changed_block_ids",U),...q("removed_block_ids",P),...q("inserted_block_ids",g),top_level_blocks_before:ge(e).length,top_level_blocks_after:ge(n).length},...!c&&(R.trim()||$.length)?{before_block:R,...$.length?{before_block_truncated:!0,before_block_omitted_ids:$.slice(0,20),before_block_omitted_count:$.length,before_block_recovery:"This is a partial lookback, not a complete replacement source. For pending edits use rollback_agent_suggestions with the appropriate request/turn, then reread. Accepted content requires historical edit evidence; never reconstruct it from this partial snapshot."}:{}}:{}})}function ge(t){return[...t.children,...t.notes??[]]}function jt(t,e){return ne.extractSpecificBlocks(t,[e],void 0,Ne).foundBlocks[0]?.blockIndex??-1}function ri(t){return`(${t} ${t===1?"block":"blocks"} omitted...)`}function Ft(t,e){const n=ge(t)[e];return n?.id?ne.extractSpecificBlocks(t,[n.id],void 0,Ne).foundBlocks[0]??null:null}function ft(t){if(t.length===0)return 0;let e=`Showing ${t.length} block(s):
6
-
7
- `.length+t[0].html.length;for(let n=1;n<t.length;n+=1){const o=t[n-1],r=t[n],s=r.blockIndex-o.blockIndex-1;s>0&&(e+=1+ri(s).length),e+=1+r.html.length}return e}function mo(t){const{doc:e,startIndex:n,maxTokens:o}=t,r=[];let s=0,i=n-1,a=!1;for(let c=n;c<ge(e).length;c+=1){const u=Ft(e,c);if(!u)continue;const f=ft([...r,u]),$=f>o;if($&&r.length>0){a=!0;break}if(r.push(u),s=f,i=u.blockIndex,$){a=!0;break}}return{blockIds:r.map(c=>c.id),endIndex:i,estimatedTokens:s,reachedTokenBudget:a}}function si(t){const{doc:e,requestedBlockIds:n,maxTokens:o}=t,r=[],s=new Set,i=new Map,a=(T,R)=>(i.has(T)||i.set(T,Ft(e,R)),i.get(T)??null),c=[];let u=0,f=!1,$=0;for(const T of n){const R=pi(e,T);if(!R){$+=1;continue}if(s.has(R.topLevelBlockId))continue;const P=a(R.topLevelBlockId,R.topLevelIndex);if(!P){$+=1;continue}const U=ft([...c,P]),D=U>o;if(D&&r.length>0){f=!0;break}if(r.push(R.topLevelBlockId),s.add(R.topLevelBlockId),c.push(P),u=U,D){f=!0;break}}return{blockIds:r,estimatedTokens:u,reachedTokenBudget:f,missingRequestedBlocks:$}}function go(t){const{doc:e,results:n,pageSize:o,maxTokens:r}=t;if(n.length===0)return[];const s=new Map,i=T=>(s.has(T.blockId)||s.set(T.blockId,Ft(e,T.blockIndex)),s.get(T.blockId)??null),a=[];let c=[],u=[],f=0;const $=T=>{c.length!==0&&(a.push({results:c,startResultIndex:f,endResultIndexExclusive:T,estimatedTokens:ft(u)}),c=[],u=[])};for(let T=0;T<n.length;T+=1){const R=n[T],P=i(R);if(!P)continue;c.length===0&&(f=T);const U=ft([...u,P]),D=c.length>=o,_=U>r;c.length>0&&(D||_)&&($(T),f=T),c=[...c,R],u=[...u,P]}return $(n.length),a}function po(t){if(t.length===0)return[];const e=[...t].sort((s,i)=>s-i),n=[];let o=e[0],r=e[0];for(let s=1;s<e.length;s+=1){const i=e[s];if(i<=r+1){r=i;continue}n.push({start:o,end:r}),o=i,r=i}return n.push({start:o,end:r}),n}function Et(t,e){const n=new Set;for(const o of e){const r=jt(t,o);r!==-1&&n.add(r)}return Array.from(n).sort((o,r)=>o-r)}function Qe(t,e){const n=We(e,t.toolState.tableContext,t.turnState.requestedBlockIds??new Set),o=Et(e,n),r=po(o),s=o.length,i=!t.toolState.tableContext?.scopedTableIds?.some(a=>!n.has(a))&&(t.toolState.everReadFullDocument||ge(e).length>0&&s>=ge(e).length);return{requestedBlockCount:s,readBlocksThisTurn:t.turnState.readBudgetBlockIds?.size??0,readTokenBudgetMax:Oe,requestedRanges:r,fullDocumentLoaded:i}}function et(t){return JSON.stringify({kind:"read_context",tool:t.tool,loaded:t.loaded,next:t.next??null,endOfDocument:t.endOfDocument,coverage:t.coverage})}function fo(t){return JSON.stringify({kind:"search_context",tool:t.tool,...t.queries?{queries:t.queries}:{},...t.color?{color:t.color}:{},totalMatches:t.totalMatches,...t.searchResultId?{search_result_id:t.searchResultId}:{},page:{current:t.currentPage,total:t.totalPages,startResult:t.pageStart+1,endResult:t.pageEnd},nextPage:t.nextPage,matches:t.pageResults.map(e=>({blockId:e.blockId,blockIndex:e.blockIndex,...e.matchedQueries?{matchedQueries:e.matchedQueries}:{},...e.matchedColors?{matchedColors:e.matchedColors}:{}})),coverage:t.coverage})}function ii(t){return t==="account"||t==="folder"?t:"current_folder"}function je(t){return t.getAuthToken?.().trim()??""}function bo(t){return typeof t.document_id=="string"?t.document_id.trim():""}function yo(t){return t.replaceAll("-","").toLowerCase()}function _e(t,e){const n=bo(t);if(!n)return"";const o=e.getCurrentDocumentId?.().trim()??"";return o&&yo(n)===yo(o)?"":n}async function ai(t){const e=t.scope==="folder"?t.folderId:t.currentFolderId,n=qn({query:t.query,page:t.page+1,limit:10,currentFolderId:t.scope==="account"?void 0:e}),o=await fetch(`${Ot}/documents/search?${n.toString()}`,{headers:{Authorization:`Bearer ${t.token}`}});if(!o.ok)throw new Error(`Document search failed with ${o.status}`);return Rn(await o.json(),10)}async function ci(t){const e=qn({includeFolders:!0,page:t.page+1,limit:t.limit,parentFolderId:t.parentFolderId}),n=await fetch(`${Ot}/documents?${e.toString()}`,{headers:{Authorization:`Bearer ${t.token}`}});if(!n.ok)throw new Error(`Document listing failed with ${n.status}`);return Rn(await n.json(),t.limit)}async function bt(t){const e=await fetch(`${Ot}/documents/${encodeURIComponent(t.documentId)}?includeTailUpdates=1&trackAccess=0`,{headers:{Authorization:`Bearer ${t.token}`}});if(!e.ok)throw new Error(`Document open failed with ${e.status}`);const n=await e.json(),o=Fr({content:n.content,yjsState:n.yjsState,yjsUpdates:n.yjsUpdates,source:`agent read document ${t.documentId}`})??{type:"doc",children:[]};return o.title=n.title||o.title||"Untitled",{id:n.id||t.documentId,title:n.title||"Untitled",canonicalPath:n.canonicalPath,parentFolderId:n.parentFolderId??null,content:o}}function li(t){return JSON.stringify({kind:"account_document_search",query:t.query,scope:t.scope,searchedCurrentFolder:t.searchedCurrentFolder,folderId:t.folderId??null,page:{current:t.page,total:t.totalPages},totalMatches:t.totalCount,results:t.results.map(e=>({itemType:e.itemType==="folder"?"folder":"document",...e.itemType==="folder"?{folderId:e.id}:{documentId:e.id},title:e.title,canonicalPath:e.canonicalPath||`/${e.title||e.id}`,snippet:e.snippet||"",href:e.itemType==="folder"?`/docs/folders/${e.id}`:`/docs/${e.id}`,parentFolderId:e.parentFolderId??null}))})}function di(t){return JSON.stringify({kind:"document_tree_listing",parentFolderId:t.parentFolderId,page:{current:t.page,total:t.totalPages},totalItems:t.totalCount,hasMore:t.hasMore,items:t.items.map(e=>({type:e.itemType==="folder"?"folder":"document",id:e.id,title:e.title||e.name||"Untitled",name:e.name||e.title||"Untitled",canonicalPath:e.canonicalPath||`/${e.title||e.name||e.id}`,href:e.itemType==="folder"?`/docs?folder=${e.id}`:`/docs/${e.id}`,parentFolderId:e.parentFolderId??null,childCount:typeof e.childCount=="number"?e.childCount:void 0,updatedAt:e.updatedAt}))})}function zt(t){return{editable:!1,editInstructions:`Read-only source. Mutation tools only edit the active document. To edit this source, give the user a clickable link to /docs/${t} and ask them to open it and continue there. Never use these block IDs to edit the active document.`}}function Ht(t){return JSON.stringify({kind:"document_read",document:{documentId:t.documentId,title:t.title,canonicalPath:t.canonicalPath||`/${t.title}`,href:`/docs/${t.documentId}`,...zt(t.documentId)},loaded:{startIndex:t.startIndex,endIndex:t.endIndex,estimatedTokens:t.estimatedTokens},next:t.nextIndex===null?null:{index:t.nextIndex},endOfDocument:t.endOfDocument,documentContent:t.content})}function _o(t,e){if(t==="search_document"){const o=Array.isArray(e.queries)?e.queries.filter(s=>typeof s=="string"):[],r=typeof e.document_id=="string"&&e.document_id.trim().length>0?e.document_id.trim():null;return JSON.stringify({documentId:r,queries:o})}const n=typeof e.color=="string"&&e.color.trim().length>0?e.color.trim().toLowerCase():null;return JSON.stringify({color:n})}function ui(t){const e=new Map;for(const n of t)for(const o of n.matchedColors??[])e.set(o,(e.get(o)??0)+1);return e.size===0?"":Array.from(e.entries()).sort((n,o)=>o[1]-n[1]||n[0].localeCompare(o[0])).map(([n,o])=>`${o} ${n}`).join(", ")}function hi(t,e){let n=0;for(;n<t.length&&n<e.length&&t[n]===e[n];)n+=1;let o=t.length-1,r=e.length-1;for(;o>=n&&r>=n&&t[o]===e[r];)o-=1,r-=1;const s=Math.max(0,o-n+1),i=Math.max(0,r-n+1);return Math.max(s,i)}function mi(t,e){if(t.name!=="replace_block"||!t.arguments||typeof t.arguments!="object")return null;const n=t.arguments.id,o=t.arguments.content,r=t.arguments.count;if(typeof n!="string"||typeof r=="number"&&Number.isFinite(r)&&Math.floor(r)>1||!Array.isArray(o)||o.length!==1||typeof o[0]!="string")return null;const s=e.children.find($=>$.id===n);if(!s)return null;const i=lo(St(s)),a=lo(Qs(o[0]));if(!i||!a||i===a)return null;const c=hi(i,a),u=Math.max(i.length,a.length);if(u<=0)return null;const f=c/u;return c>As||f>qs?null:`WARNING: replace_block only changed a small span (~${c} chars, ${(f*100).toFixed(0)}% of block). Prefer replace for typo, punctuation, and wording edits; reserve replace_block for full rewrites.`}function ko(t,e,n){if(!n||n.size===0)return!1;if(n.has(e))return!0;const o=ot(t,e);if(o&&n.has(o))return!0;const r=Ie(t,e),s=r>=0?t.children[r]?.id:void 0;return typeof s=="string"&&n.has(s)}function gi(t,e,n){if(t.name!=="replace_block"&&t.name!=="remove_block")return{toolCall:t};if(!t.arguments||typeof t.arguments!="object")return{toolCall:t};const o=t.arguments.id;if(typeof o!="string"||o.trim().length===0)return{toolCall:t};const r=t.arguments.count;if(r!==void 0&&(typeof r!="number"||!Number.isFinite(r)||Math.floor(r)<1))return{toolCall:t};const s=r===void 0?1:Math.floor(r);if(s<=1)return{toolCall:t};const i=Zo(e,o),a=i&&"children"in i?Qo(i,o):-1;if(!i||a===-1)return{toolCall:t};if(!n||n.size===0)return{toolCall:t,error:`${t.name} requested ${s} consecutive blocks, but no request-level multi-block document context is available. Read the complete range first, then retry without narrowing the count.`};const c=new Set(Array.from(n).map(f=>Ie(e,f)).filter(f=>f!==-1));let u=0;for(let f=a;f<i.children.length;f++){const $=i.children[f]?.id;if(typeof $!="string"||$.length===0)break;const T=Ie(e,$);if(T===-1||!c.has(T))break;u+=1}return u<=0?{toolCall:t,error:`${t.name} targets block '${o}', which is outside the loaded <document_content> context. Read that block first, then retry.`}:u>=s?{toolCall:t}:{toolCall:t,error:`${t.name} requested ${s} consecutive blocks, but only ${u} were seen in request-level document context. Read the remaining range and retry; no partial mutation was applied.`}}function pi(t,e){const n=jt(t,e);if(n===-1)return null;const o=ge(t)[n];return o?.id?{block:o,topLevelBlockId:o.id,topLevelIndex:n}:null}function fi(t){const e=t.toolState.editedBlockIds.size;if(e===0)return{loadedBlockCount:0,editedBlockCount:0};const n=t.getLatestDocument(),o=n.children.length,r=new Set;for(const c of t.toolState.editedBlockIds){const u=Ie(n,c);u!==-1&&r.add(u)}const s=new Set;for(const c of r)for(let u=Math.max(0,c-no);u<=Math.min(o-1,c+no);u++)s.add(u);const i=[],a=Array.from(s).sort((c,u)=>c-u);for(const c of a){const u=n.children[c];u?.id&&i.push(u.id)}t.turnState.requestedBlockIds||(t.turnState.requestedBlockIds=new Set);for(const c of i)t.turnState.requestedBlockIds.add(c);return t.turnState.documentRequested=!0,{loadedBlockCount:i.length,editedBlockCount:e}}async function bi(t){const e=await Hr(t);if(e)return{id:e.id,type:e.type,content:e.content,preview:e.preview,charCount:e.charCount,...e.fileName?{fileName:e.fileName}:{},...e.mimeType?{mimeType:e.mimeType}:{},...e.fileSize?{fileSize:e.fileSize}:{},...e.urls?{urls:e.urls}:{},...e.dimensions?{dimensions:e.dimensions}:{}}}function yi(t){const e=t.loadAttachment??bi,n=t.metrics??or;if(!t.toolState.foreignBlockSources){t.toolState.foreignBlockSources=new Map;for(const _ of t.getConversationHistory?.()??[])if(!(!_.toolResult?.success||!_.toolResult.output))try{const g=JSON.parse(_.toolResult.output),y=g.document?.documentId;if(typeof y!="string"||!["document_read","document_search_context"].includes(g.kind)||typeof g.documentContent!="string"||!_e({document_id:y},t))continue;const q=new DOMParser().parseFromString(g.documentContent,"text/html");for(const A of q.querySelectorAll("[id]"))t.toolState.foreignBlockSources.set(A.id,y)}catch{}}const o=t.toolState.foreignBlockSources,r=(_,g,y)=>{const q=A=>{if(A.id&&y(A.id),"children"in A&&Array.isArray(A.children))for(const w of A.children)"id"in w&&q(w)};for(const A of g){const w=se(_,A);w&&q(w)}},s=(_,g,y)=>r(_,g,q=>o.set(q,y)),i=_=>{const g=t.tryAddRequestedBlocks(_);return(!g||g.code===pt)&&r(t.getLatestDocument(),_,y=>o.delete(y)),g};let a=t.turnState.currentTurn??0,c=0,u=0;const f=new Map;let $=1;const T=async()=>{t.getDocumentSession()||await t.waitForDocumentSession?.();const _=t.getDocumentSession(),g=_?.getDocumentId?.(),y=t.getCurrentDocumentId?.();return _&&(!g||!y||_e({document_id:g},t)==="")?_:null},R=_=>k(_,Zn,us),P=new Set(["read_table","read_blocks","read_blocks_from_index","read_specific_blocks","search_document","find_highlights","measure_document","measure_blocks","view_image","render_document_pages"]),U=new Set(["read_blocks","read_blocks_from_index","read_specific_blocks","search_document"]),D=()=>{const _=t.turnState.currentTurn??0;_!==a&&(a=_,c=0,u=0)};return async _=>{var g,y,q,A,w,O,z;const K=Zs(_),d=K.name==="remove_blocks"?{...K,name:"remove_block"}:K,C=d.name,ce=t.getExecutionPolicy?.(),me=ce?Ts(ce,C):null;if(me)return k(d,me.message,me.code);if(t.allowCrossDocumentReads===!1&&(bo(d.arguments??{}).length>0||C==="list_documents"||C==="search_documents"))return k(d,"This host only permits the supplied document. document_id routing is unavailable.","agent_tool_not_allowed");if(D(),C==="create_plan"||C==="update_plan"){if(!t.getPlanState||!t.setPlanState)return k(d,"This host does not support task plans.","plan_unavailable");try{const l=yn(t.getPlanState(),C,d.arguments??{});return t.setPlanState(l),t.markConversationDirty(),W(d,JSON.stringify(l.plan),void 0,!0,JSON.stringify({kind:"task_plan",plan:l.plan}))}catch(l){return k(d,l instanceof Error?l.message:String(l),"invalid_plan_update")}}if(t.mutationTools.includes(C)||C==="remove_block"){const l=_e(d.arguments??{},t),h=Ye(d.arguments).filter(v=>o.has(v)&&_e({document_id:o.get(v)},t)!==""),m=l||(h.length?o.get(h[0]):void 0);if(m){if(!l&&h.every(I=>se(t.getLatestDocument(),I)))return{...k(d,`These IDs occur in both the source and active documents. If this edit is intended for the source, do not edit here: give the user a clickable link to /docs/${m} and ask them to open it. Only if the edit belongs in the active document, re-read the target IDs without document_id before editing.`,"foreign_document_id_collision"),sourceDocumentId:m};const v=t.turnState.currentRequestId??0;t.toolState.foreignTargetFailureState?.requestId!==v&&(t.toolState.foreignTargetFailureState={requestId:v,count:0});const p=++t.toolState.foreignTargetFailureState.count;return{...k(d,`These edits target a read-only source document. Open /docs/${m} and continue there to edit it. The active document has not been changed by this call. Do not retry these IDs with another mutation tool. To edit the active document instead, read its target blocks without document_id first.`,p>=2?"foreign_document_target_repeated":"foreign_document_target"),sourceDocumentId:m}}}const _t=U.has(C)&&_e(d.arguments??{},t)!=="";if(t.requireDocumentSessionForReads&&P.has(C)&&!_t&&!await T())return R(d);if(C==="import_attachment_into_document"){const l=typeof d.arguments?.attachment_id=="string"?d.arguments.attachment_id.trim():"";if(!l)return k(d,"attachment_id is required.");const h=d.arguments?.after_block_id;if(h!=null&&typeof h!="string")return k(d,"after_block_id must be a block ID string.");const m=typeof h=="string"&&h.trim()||void 0,v=t.getAllAttachments().get(l)??await e(l);if(!v)return k(d,`Attachment "${l}" was not found.`);if(v.type!=="docx"&&v.type!=="pdf")return k(d,"Only DOCX and PDF attachments can be imported into the document.");if(!t.importAttachmentIntoDocument)return k(d,"Attachment import is unavailable in this document.");try{t.toolState.statusMessage=`Importing ${v.fileName||"attachment"}…`,t.notifyListeners();const p=await t.importAttachmentIntoDocument(v,m);return t.toolState.editedBlockIds.clear(),t.toolState.hasImportedAttachment=!0,t.turnState.documentRequested=!1,t.turnState.requestedBlockIds=null,t.turnState.lastReadBlockIds=null,t.toolState.everReadFullDocument=!1,t.toolState.sequentialReadBlockIds=new Set,t.toolState.statusMessage=null,t.markConversationDirty(),t.notifyListeners(),W(d,`Imported "${p.fileName}" into the current document (${p.blockCount} blocks)${m?` after block "${m}"`:""}. The URL stayed the same. Continue the user's request by reading the imported content, then edit it.`)}catch(p){return t.toolState.statusMessage=null,t.notifyListeners(),k(d,p instanceof Error?p.message:"Attachment import failed.")}}if(js.has(C)){if(!Ys(d.arguments))return k(d,'context_notes is required on every read/search call. Use "N/A" if nothing from the previous context needs to carry forward.');if(c>=1)return k(d,'Use at most one read/search tool call per turn. Continue with edits in this turn, then read/search again in the next turn with context_notes or "N/A".',Ns);c+=1}if(C==="measure_document"){const l=d.arguments||{},h=l.include_sections===!0,m=Number(l.section_offset),v=Number.isFinite(m)&&m>0?Math.floor(m):0,p=Number(l.section_limit),I=Number.isFinite(p)&&p>0?Math.min(Math.floor(p),Ps):Rs,S=(Array.isArray(l.heading_levels)?l.heading_levels:[]).map(he=>typeof he=="number"?he:typeof he=="string"?Number.parseInt(he,10):Number.NaN).filter(he=>he===1||he===2||he===3),x=t.getLatestDocument(),b=Xn(x,{includeSections:h,...S.length>0?{headingLevels:S}:{}}),M=t.getDocumentSession()?.getDocumentWithoutPendingSuggestions(),B=M&&M!==x?Xn(M,{includeSections:!1}):null,j=B&&(B.wordCount!==b.wordCount||B.characterCount!==b.characterCount)?{wordCount:B.wordCount,characterCount:B.characterCount,paragraphCount:B.paragraphCount,pageCount:B.pageCount}:void 0,ae=b.sections??[],F=ae.length,L=Math.min(v,F),G=h?ae.slice(L,L+I):void 0,E=G?.length??0,Q=h&&L+E<F,V=JSON.stringify({kind:"document_measurement",tool:"measure_document",measurementBasis:"pending_suggestions_applied",...b,...j?{originalReviewProjection:j}:{},...h?{sections:G,sectionCount:F,sectionOffset:L,sectionLimit:I,returnedSectionCount:E,hasMoreSections:Q,...Q?{nextSectionOffset:L+E}:{}}:{}});n.count("agent.measure.call",1,{tool_name:C}),n.distribution("agent.measure.sections",F,void 0,{tool_name:C});const ee=h?`Measured document totals and ${F} heading section(s).`:"Measured document totals.",oe=h&&F>0?` Returned sections ${L+1}-${L+E} of ${F}.${Q?` Use section_offset=${L+E} to continue.`:""}`:"",H=h?"heading titles, counts, and page ranges only; it does not include body document text":"counts and page ranges only; it does not include document text",be=j?` The primary totals treat pending suggestions as accepted. The original review projection has ${j.wordCount} words and ${j.characterCount} characters because it excludes pending suggestions; use the projection matching the user's editor view when reconciling a reported count.`:"";return{toolCall:d,success:!0,toolOutput:V,agentFeedback:`${ee}${oe}${be} The result includes ${H}.`,control:{shouldContinue:!0}}}if(C==="measure_blocks"){const l=d.arguments||{},h=typeof l.mode=="string"?l.mode.trim():"inclusive";if(h!==""&&h!=="inclusive")return k(d,'measure_blocks only supports mode="inclusive".');const m=Array.isArray(l.ranges)?l.ranges:[];if(m.length===0)return k(d,"measure_blocks requires at least one range.");const v=m.map(M=>{const B=M&&typeof M=="object"?M:{};return{startBlockId:typeof B.start_block_id=="string"?B.start_block_id:"",endBlockId:typeof B.end_block_id=="string"?B.end_block_id:void 0}}),p=ls(t.getLatestDocument(),v),I=p.ranges.length,S=p.errors.length,x=JSON.stringify({kind:"document_measurement",tool:"measure_blocks",...p});if(n.count("agent.measure.call",1,{tool_name:C}),n.distribution("agent.measure.ranges",I,void 0,{tool_name:C}),I===0){const M=p.errors.map(B=>B.error).join(" ")||"No valid inclusive ranges were measured.";return k(d,M,xe)}const b=S>0?`Measured ${I} inclusive block range(s); ${S} range(s) had errors.`:`Measured ${I} inclusive block range(s).`;return W(d,b,void 0,void 0,x)}if(C==="read_table"){const l=t.getLatestDocument(),h=d.arguments??{};if(typeof h.context_notes!="string")return k(d,"context_notes is required (use N/A when there is no prior context to preserve).");const m=at(l,h,b=>ne.renderSubtree(b,l));if(m.error)return k(d,m.error);const v=Br(t.getTableTaskState?.()??t.toolState.tableTasks??Dn(),l,h,{requestId:t.turnState.currentRequestId??0,chatHistory:t.getConversationHistory?.()??[],attachmentExists:b=>t.getAllAttachments().has(b)});let p;if("error"in v){const b=(t.getTableTaskState?.()??t.toolState.tableTasks)?.task;p={accepted:!1,reason:v.error,retained_scope:b&&b.tableId===m.table_id?{task_kind:b.kind,scope_row_start:b.declaredRowStart,scope_row_count:b.rowIds.length,scope_columns:b.columns}:null,note:b?"The existing task scope still applies; finish all of it unless the user narrows it.":"No task scope is recorded for this table; no table task status will be reported until a valid declaration."}}else t.toolState.tableTasks=v.state,v.declared&&t.setTableTaskState?.(v.state);const I=(g=t.toolState).tableContext??(g.tableContext=wn());h.mode!=="cell_text"&&(I.geometries??(I.geometries={}),I.geometries[m.table_id]=m.revision),I.scopedTableIds=[...new Set([...I.scopedTableIds??[],m.table_id])],I.requestedCells??(I.requestedCells={}),I.requestedCells[m.table_id]=[...new Set([...I.requestedCells[m.table_id]??[],...m.rows.flatMap(b=>b.cells.map(M=>M.id).filter(Boolean))])];const S=!!t.turnState.docContextLedger;S?(I.pendingReadCells??(I.pendingReadCells={}),I.pendingReadCells[m.table_id]=[...new Set([...I.pendingReadCells[m.table_id]??[],...m.rows.flatMap(b=>b.cells.map(M=>M.id).filter(Boolean))])],(y=t.turnState).requestedBlockIds??(y.requestedBlockIds=new Set),t.turnState.requestedBlockIds.add(m.table_id),(q=t.turnState).lastReadBlockIds??(q.lastReadBlockIds=new Set),t.turnState.lastReadBlockIds.add(m.table_id),t.turnState.documentRequested=!0):ct(l,I,m.table_id,m.complete_cell_ids),t.markConversationDirty();const x=S&&h.mode!=="cell_text"?{...m,rows:void 0,complete_cell_ids:void 0,delivered_rows:m.rows.map(b=>({row_id:b.row_id,columns:b.cells.filter(M=>m.complete_cell_ids.includes(M.id)).map(M=>M.column)})),delivered_cell_count:m.complete_cell_ids.length,delivery:"Requested cells arrive in the next document snapshot. Summary/preview alone is not edit authorization.",...p?{task_scope_update:p}:{}}:{...m,...p?{task_scope_update:p}:{}};return W(d,p?"Table context read. The task scope declaration was rejected (see task_scope_update); the existing scope is unchanged.":"Table context read. Use fill counts to include gaps in earlier rows.",void 0,void 0,JSON.stringify(x))}if(C==="read_blocks"){const l=d.arguments||{},h=_e(l,t),m=l.from_id,v=h?je(t):"";if(h&&!v&&!t.loadRemoteDocument)return k(d,"Cross-document access is only available for signed-in documents.");let p=null;try{p=h?await(t.loadRemoteDocument?.(h)??bt({token:v,documentId:h})):null}catch(L){return k(d,L instanceof Error?L.message:"Document read failed.")}const I=p?.content??t.getLatestDocument(),S=ge(I),x=S.length,b=typeof m=="string"?jt(I,m):-1;if(b===-1)return k(d,`Block ID "${m}" not found`,xe);if(b>=x)return k(d,`Start index ${b} is out of range for ${x} blocks.`);const M=mo({doc:I,startIndex:b,maxTokens:Oe});if(M.blockIds.length===0||M.endIndex<b)return k(d,`No readable blocks found from index ${b}.`);if(p){s(I,M.blockIds,p.id);const L=ne.extractSpecificBlocks(I,M.blockIds,void 0,Ne),G=ne.formatSpecificBlocks(L),E=M.endIndex+1<x?M.endIndex+1:null,Q=Ht({documentId:p.id,title:p.title,canonicalPath:p.canonicalPath,startIndex:b,endIndex:M.endIndex,estimatedTokens:M.estimatedTokens,content:G,nextIndex:E,endOfDocument:E===null}),V=M.reachedTokenBudget?" Reached per-call token budget.":"";return W(d,`Read ${M.blockIds.length} blocks from "${p.title}" (index ${b}-${M.endIndex}). Serialized characters: ~${M.estimatedTokens}.${V}${E!==null?` Next: read_blocks_from_index(document_id="${p.id}", index=${E}).`:" End of document."}`,void 0,void 0,Q)}const B=(A=t.toolState).sequentialReadBlockIds??(A.sequentialReadBlockIds=new Set);if(B.size>0&&M.blockIds.every(L=>B.has(L)))return k(d,`This sequential read window (index ${b}-${M.endIndex}) contains only blocks already returned by earlier sequential read calls in this request. Do not cycle among previously read indices. Follow the last successful nextIndex, use read_specific_blocks for an intentional exact revisit, make the pending edits, or finish.`,pt);const j=i(M.blockIds);if(j)return k(d,j.message,j.code);for(const L of M.blockIds)B.add(L);t.turnState.documentRequested=!0,n.count("agent.read.call",1,{tool_name:C}),n.distribution("agent.read.blocks_loaded",M.blockIds.length,void 0,{tool_name:C}),n.distribution("agent.read.tokens_loaded_estimate",M.estimatedTokens,void 0,{tool_name:C}),M.reachedTokenBudget&&n.count("agent.read.token_budget_reached",1,{tool_name:C});const ae=Qe(t,I);if(M.endIndex+1<x){const L=M.endIndex+1,G=S[L]?.id,E=et({tool:C,loaded:{count:M.blockIds.length,startIndex:b,endIndex:M.endIndex,estimatedTokens:M.estimatedTokens},next:{index:L,...G?{blockId:G}:{}},endOfDocument:!1,coverage:ae}),Q=M.reachedTokenBudget?" Reached per-call token budget.":"",V=G?` Next block ID: ${G}.`:"";return W(d,`Read ${M.blockIds.length} blocks (index ${b}-${M.endIndex}). Serialized characters: ~${M.estimatedTokens}.${Q} Next: read_blocks_from_index(index=${L}).${V}`,void 0,void 0,E)}const F=et({tool:C,loaded:{count:M.blockIds.length,startIndex:b,endIndex:M.endIndex,estimatedTokens:M.estimatedTokens},endOfDocument:!0,coverage:ae});return W(d,`Read ${M.blockIds.length} blocks (index ${b}-${M.endIndex}). Serialized characters: ~${M.estimatedTokens}. End of document.`,void 0,void 0,F)}if(C==="read_blocks_from_index"){const l=d.arguments||{},h=_e(l,t),m=Ze(l.index,0),v=h?je(t):"";if(h&&!v&&!t.loadRemoteDocument)return k(d,"Cross-document access is only available for signed-in documents.");let p=null;try{p=h?await(t.loadRemoteDocument?.(h)??bt({token:v,documentId:h})):null}catch(F){return k(d,F instanceof Error?F.message:"Document read failed.")}const I=p?.content??t.getLatestDocument(),S=ge(I),x=S.length;if(!p&&t.toolState.everReadFullDocument)return k(d,"You have already read the entire current document in this request. Continue by making edits if needed. If you need to revisit exact known blocks, use read_specific_blocks instead of restarting a sequential read.",pt);if(p&&x===0&&m===0)return W(d,`Read 0 blocks from "${p.title}". End of document.`,void 0,void 0,Ht({documentId:p.id,title:p.title,canonicalPath:p.canonicalPath,startIndex:0,endIndex:-1,estimatedTokens:0,content:"",nextIndex:null,endOfDocument:!0}));if(m>=x)return k(d,`Start index ${m} is out of range for ${x} blocks${p?` in "${p.title}"`:""}.`);const b=mo({doc:I,startIndex:m,maxTokens:Oe});if(b.blockIds.length===0||b.endIndex<m)return k(d,`No readable blocks found from index ${m}.`);if(p){s(I,b.blockIds,p.id);const F=ne.extractSpecificBlocks(I,b.blockIds,void 0,Ne),L=ne.formatSpecificBlocks(F),G=b.endIndex+1<x?b.endIndex+1:null,E=Ht({documentId:p.id,title:p.title,canonicalPath:p.canonicalPath,startIndex:m,endIndex:b.endIndex,estimatedTokens:b.estimatedTokens,content:L,nextIndex:G,endOfDocument:G===null}),Q=b.reachedTokenBudget?" Reached per-call token budget.":"";return n.count("agent.read.call",1,{tool_name:C}),n.distribution("agent.read.blocks_loaded",b.blockIds.length,void 0,{tool_name:C}),W(d,`Read ${b.blockIds.length} blocks from "${p.title}" (index ${m}-${b.endIndex}). Serialized characters: ~${b.estimatedTokens}.${Q}${G!==null?` Next: read_blocks_from_index(document_id="${p.id}", index=${G}).`:" End of document."}`,void 0,void 0,E)}const M=(w=t.toolState).sequentialReadBlockIds??(w.sequentialReadBlockIds=new Set);if(M.size>0&&b.blockIds.every(F=>M.has(F)))return k(d,`This sequential read window (index ${m}-${b.endIndex}) contains only blocks already returned by earlier sequential read calls in this request. Do not cycle among previously read indices. Follow the last successful nextIndex, use read_specific_blocks for an intentional exact revisit, make the pending edits, or finish.`,pt);const B=i(b.blockIds);if(B)return k(d,B.message,B.code);for(const F of b.blockIds)M.add(F);t.turnState.documentRequested=!0,n.count("agent.read.call",1,{tool_name:C}),n.distribution("agent.read.blocks_loaded",b.blockIds.length,void 0,{tool_name:C}),n.distribution("agent.read.tokens_loaded_estimate",b.estimatedTokens,void 0,{tool_name:C}),b.reachedTokenBudget&&n.count("agent.read.token_budget_reached",1,{tool_name:C});const j=Qe(t,I);if(b.endIndex+1<x){const F=b.endIndex+1,L=S[F]?.id,G=et({tool:C,loaded:{count:b.blockIds.length,startIndex:m,endIndex:b.endIndex,estimatedTokens:b.estimatedTokens},next:{index:F,...L?{blockId:L}:{}},endOfDocument:!1,coverage:j}),E=b.reachedTokenBudget?" Reached per-call token budget.":"",Q=L?` Next block ID: ${L}.`:"";return W(d,`Read ${b.blockIds.length} blocks (index ${m}-${b.endIndex}). Serialized characters: ~${b.estimatedTokens}.${E} Next: read_blocks_from_index(index=${F}).${Q}`,void 0,void 0,G)}const ae=et({tool:C,loaded:{count:b.blockIds.length,startIndex:m,endIndex:b.endIndex,estimatedTokens:b.estimatedTokens},endOfDocument:!0,coverage:j});return W(d,`Read ${b.blockIds.length} blocks (index ${m}-${b.endIndex}). Serialized characters: ~${b.estimatedTokens}. End of document.`,void 0,void 0,ae)}if(C==="search_document"){const l=d.arguments||{},h=_e(l,t),m=l.queries,v=Array.isArray(m)?m.filter(re=>typeof re=="string"&&re.length>0):typeof m=="string"&&m.length>0?[m]:[];if(v.length===0)return k(d,'search_document requires "queries": a non-empty array of search strings.');const p=typeof l.page=="number"?l.page:0,I=h?je(t):"";if(h&&!I&&!t.loadRemoteDocument)return k(d,"Cross-document access is only available for signed-in documents.");let S=null;try{S=h?await(t.loadRemoteDocument?.(h)??bt({token:I,documentId:h})):null}catch(re){return k(d,re instanceof Error?re.message:"Document search failed.")}const x=S?.content??t.getLatestDocument(),b=t.searchPageSize,M=_o("search_document",l);let B;p>0&&t.toolState.lastSearchState&&t.toolState.lastSearchState.toolName==="search_document"&&t.toolState.lastSearchState.requestKey===M?B=t.toolState.lastSearchState.allResults:B=ne.searchDocument(x,v);let j;if(!S&&B.length>0){const re=p>0&&t.toolState.lastSearchState?.requestKey===M?t.toolState.lastSearchState.resultSetId:void 0;if(re&&f.has(re))j=re;else{j=`search_result_${$++}`;const Me=Array.from(new Set(B.map(Pe=>Pe.blockId)));f.set(j,{id:j,blockIds:Me,blockHashes:xt(x,Me)})}}const ae=go({doc:x,results:B,pageSize:b,maxTokens:Oe}),F=Math.max(1,ae.length),L=Math.min(p,Math.max(0,F-1)),G=ae[L]??{results:[],startResultIndex:0,endResultIndexExclusive:0},E=G.startResultIndex,Q=G.endResultIndexExclusive,V=G.results,ee=V.map(re=>re.blockId),oe=S||ee.length===0?null:i(ee);t.toolState.lastSearchState={toolName:"search_document",requestKey:M,allResults:B,currentPage:L,totalPages:F,...j?{resultSetId:j}:{}};let H;B.length===0?H=`No matches found${S?` in "${S.title}"`:""} for: ${v.join(", ")}`:(H=`Found ${B.length} matching blocks${S?` in "${S.title}"`:""}. Showing page ${L+1}/${F} (results ${E+1}-${Q} of ${B.length}).`,!S&&j&&(H+=` The full unpaginated result set is saved as ${j}; pass search_result_id="${j}" to replace, replace_block, style_blocks, or remove_blocks to target all ${B.length} matches in one call.`),L<F-1&&S&&(H+=S?` Call search_document with document_id="${S.id}" and page=${L+1} to see next page.`:` Call search_document with page=${L+1} to see next page.`));const be=oe?.code==="no_new_read_context";if(oe&&!be){if(B.length>0){let re=`Found ${B.length} matching blocks. Showing page ${L+1}/${F} (blocks ${E+1}-${Q} of ${B.length}). Matching blocks could not be loaded this turn.`;return L<F-1&&(re+=` Call search_document with page=${L+1} to see next page.`),k(d,`${oe.message} ${re}`,oe.code)}return k(d,`${oe.message} ${H}`,oe.code)}if(be&&B.length>0&&(H+=" Matching block content is already available in this request's cached context."),S){s(x,ee,S.id);const re=ne.extractSpecificBlocks(x,ee,void 0,Ne),Me=ne.formatSpecificBlocks(re),Pe=JSON.stringify({kind:"document_search_context",tool:"search_document",document:{documentId:S.id,title:S.title,canonicalPath:S.canonicalPath||`/${S.title}`,href:`/docs/${S.id}`,...zt(S.id)},queries:v,totalMatches:B.length,page:{current:L,total:F,startResult:E+1,endResult:Q},nextPage:L<F-1?L+1:null,matches:V.map(ze=>({blockId:ze.blockId,blockIndex:ze.blockIndex,matchedQueries:ze.matchedQueries??[]})),documentContent:Me});return n.count("agent.read.search_call",1,{tool_name:C}),n.distribution("agent.read.blocks_loaded",ee.length,void 0,{tool_name:C}),W(d,H,void 0,void 0,Pe)}t.turnState.documentRequested=!0,n.count("agent.read.search_call",1,{tool_name:C}),n.distribution("agent.read.blocks_loaded",ee.length,void 0,{tool_name:C});const he=fo({tool:"search_document",queries:v,totalMatches:B.length,currentPage:L,totalPages:F,pageStart:E,pageEnd:Q,pageResults:V,nextPage:L<F-1?L+1:null,...j?{searchResultId:j}:{},coverage:Qe(t,t.getLatestDocument())});return W(d,H,void 0,void 0,he)}if(C==="list_documents"){const l=d.arguments||{},h=typeof l.parent_folder_id=="string"&&l.parent_folder_id.trim().length>0?l.parent_folder_id.trim():null,m=Ze(l.page,0),v=je(t);if(!v)return k(d,"Document tree listing is only available for signed-in documents.");try{const p=await ci({token:v,parentFolderId:h,page:m,limit:50}),I=p.hasMore?` Call list_documents with page=${m+1} for more.`:"",S=p.items.filter(B=>B.itemType==="folder").length,x=p.items.length-S,b=p.totalCount===0?`No items found in ${h?"that folder":"the account root"}.`:`Listed ${p.items.length} of ${p.totalCount} items in ${h?"the folder":"the account root"} (${S} folders, ${x} documents).${I}`,M=di({parentFolderId:h,page:m,totalCount:p.totalCount,totalPages:Math.max(1,p.totalPages),hasMore:p.hasMore,items:p.items});return n.count("agent.read.document_tree_list",1,{tool_name:C}),W(d,b,void 0,void 0,M)}catch(p){return k(d,p instanceof Error?p.message:"Document listing failed.")}}if(C==="search_documents"){const l=d.arguments||{},h=typeof l.query=="string"?l.query.trim():"";if(!h)return k(d,"search_documents requires a query.");const m=je(t);if(!m)return k(d,"Cross-document search is only available for signed-in documents.");const v=ii(l.scope),p=t.getCurrentFolderId?.()??null,I=typeof l.folder_id=="string"&&l.folder_id.trim().length>0?l.folder_id.trim():null,S=v==="current_folder"&&!p||v==="folder"&&!I?"account":v,x=Ze(l.page,0);try{const b=await ai({token:m,query:h,scope:S,page:x,currentFolderId:p,folderId:I}),M=S==="current_folder"&&!!p,B=S==="folder"&&I?"the selected folder tree":M?"the current folder tree":"the account",j=x+1<b.totalPages?` Call search_documents with page=${x+1} for more.`:"",ae=b.totalCount===0?`No documents found for "${h}" in ${B}.`:`Found ${b.totalCount} documents for "${h}" in ${B}. Showing page ${x+1}/${Math.max(1,b.totalPages)}.${j}`,F=li({query:h,scope:S,searchedCurrentFolder:M,folderId:S==="folder"?I:null,page:x,totalCount:b.totalCount,totalPages:Math.max(1,b.totalPages),results:b.items});return n.count("agent.read.account_search_call",1,{tool_name:C}),W(d,ae,void 0,void 0,F)}catch(b){return k(d,b instanceof Error?b.message:"Document search failed.")}}if(C==="find_highlights"){const l=d.arguments||{},h=typeof l.color=="string"&&l.color.trim().length>0?l.color.trim().toLowerCase():void 0,m=typeof l.page=="number"?l.page:0,v=t.getLatestDocument(),p=t.searchPageSize,I=_o("find_highlights",l);let S;m>0&&t.toolState.lastSearchState&&t.toolState.lastSearchState.toolName==="find_highlights"&&t.toolState.lastSearchState.requestKey===I?S=t.toolState.lastSearchState.allResults:S=ne.findHighlights(v,h);const x=go({doc:v,results:S,pageSize:p,maxTokens:Oe}),b=Math.max(1,x.length),M=Math.min(m,Math.max(0,b-1)),B=x[M]??{results:[],startResultIndex:0,endResultIndexExclusive:0},j=B.startResultIndex,ae=B.endResultIndexExclusive,F=B.results,L=F.map(H=>H.blockId),G=L.length===0?null:i(L);t.toolState.lastSearchState={toolName:"find_highlights",requestKey:I,allResults:S,currentPage:M,totalPages:b};const E=h?`${h} highlight`:"highlighted content",Q=h||S.length===0?"":` Colors: ${ui(S)}.`;let V;S.length===0?V=`No blocks found with ${E}.`:(V=`Found ${S.length} blocks with ${E}. Showing page ${M+1}/${b} (results ${j+1}-${ae} of ${S.length}).${Q}`,M<b-1&&(V+=` Call find_highlights with page=${M+1} to see next page.`));const ee=G?.code==="no_new_read_context";if(G&&!ee){if(S.length>0){let H=`Found ${S.length} blocks with ${E}. Showing page ${M+1}/${b} (blocks ${j+1}-${ae} of ${S.length}). Matching blocks could not be loaded this turn.`;return M<b-1&&(H+=` Call find_highlights with page=${M+1} to see next page.`),k(d,`${G.message} ${H}`,G.code)}return k(d,`${G.message} ${V}`,G.code)}ee&&S.length>0&&(V+=" Matching block content is already available in this request's cached context."),t.turnState.documentRequested=!0,n.count("agent.read.search_call",1,{tool_name:C}),n.distribution("agent.read.blocks_loaded",L.length,void 0,{tool_name:C});const oe=fo({tool:"find_highlights",color:h??null,totalMatches:S.length,currentPage:M,totalPages:b,pageStart:j,pageEnd:ae,pageResults:F,nextPage:M<b-1?M+1:null,coverage:Qe(t,t.getLatestDocument())});return W(d,V,void 0,void 0,oe)}if(C==="read_specific_blocks"){const l=d.arguments||{},h=_e(l,t),m=l.block_ids,v=Array.isArray(m)?m.filter(E=>typeof E=="string"&&E.length>0):typeof m=="string"&&m.length>0?[m]:[];if(v.length===0)return k(d,"No block IDs provided");const p=h?je(t):"";if(h&&!p&&!t.loadRemoteDocument)return k(d,"Cross-document access is only available for signed-in documents.");let I=null;try{I=h?await(t.loadRemoteDocument?.(h)??bt({token:p,documentId:h})):null}catch(E){return k(d,E instanceof Error?E.message:"Document read failed.")}const S=I?.content??t.getLatestDocument();if(!I&&t.toolState.tableContext?.scopedTableIds?.length){const E=[];Je(S,V=>E.push(V));const Q=V=>[...E].reverse().find(ee=>(ee.children.length>=Oo||t.toolState.tableContext.scopedTableIds.includes(ee.id))&&de(ee).includes(V));if(v.some(V=>Q(V))){const V=[];let ee=0;for(const H of v){const be=se(S,H),he=Q(H);if(!be||be.id!==H)return k(d,`Unknown or structural block '${H}'. Use read_table with table_id and row_ids for table rows.`);let re=!1;if(Je(be,()=>{re=!0}),re)return k(d,`Block '${H}' contains a table. Use read_table(table_id="${he?.id??E.find(ze=>de(be).includes(ze.id))?.id}") for bounded row windows.`);const Me=ne.renderSubtree(be,S),Pe=JSON.stringify({id:H,html:Me}).length;if(ee+Pe>24e3)return k(d,"Requested nested content exceeds 24000 serialized characters. Read fewer blocks; for a huge cell use read_table mode=cell_text. No new edit rights were granted.");ee+=Pe,V.push({id:H,html:Me,table_id:he?.id})}const oe=t.toolState.tableContext;for(const H of V)H.table_id&&(oe.scopedTableIds=[...new Set([...oe.scopedTableIds??[],H.table_id])],kn(S,oe,H.table_id,H.id),t.turnState.docContextLedger&&(oe.pendingReadBlocks??(oe.pendingReadBlocks={}),oe.pendingReadBlocks[H.id]=oe.blocks[H.id]),se(S,H.id)?.type==="table-cell"&&ct(S,oe,H.table_id,[H.id])),(O=t.turnState).requestedBlockIds??(O.requestedBlockIds=new Set),t.turnState.requestedBlockIds.add(H.id);return t.turnState.documentRequested=!0,t.markConversationDirty(),W(d,`Read ${V.length} exact nested blocks. Ancestors and sibling cells remain unread. During context recovery, only blocks repeated in the next <table_recovery_window> stay editable; any it omits are listed there and are not editable.`,void 0,void 0,JSON.stringify({blocks:V,serialized_characters:ee}))}}const{blockIds:x,estimatedTokens:b,reachedTokenBudget:M,missingRequestedBlocks:B}=si({doc:S,requestedBlockIds:v,maxTokens:Oe});if(x.length===0)return B>0?k(d,"None of the requested block IDs were found in the document.",xe):k(d,"No readable blocks could be loaded.");if(I){s(S,x,I.id);const E=ne.extractSpecificBlocks(S,x,void 0,Ne),Q=ne.formatSpecificBlocks(E),V=Et(S,new Set(x)),ee=JSON.stringify({kind:"document_read",tool:C,document:{documentId:I.id,title:I.title,canonicalPath:I.canonicalPath||`/${I.title}`,href:`/docs/${I.id}`,...zt(I.id)},loaded:{count:x.length,blockIds:x,blockIndices:V,estimatedTokens:b},reachedTokenBudget:M,documentContent:Q});return n.count("agent.read.call",1,{tool_name:C}),n.distribution("agent.read.blocks_loaded",x.length,void 0,{tool_name:C}),W(d,`Read ${x.length} specific blocks from "${I.title}". Serialized characters: ~${b}.${M?" Reached per-call token budget.":""}`,void 0,void 0,ee)}const j=i(x);if(j)return k(d,j.message,j.code);t.turnState.documentRequested=!0,n.count("agent.read.call",1,{tool_name:C}),n.distribution("agent.read.blocks_loaded",x.length,void 0,{tool_name:C}),n.distribution("agent.read.tokens_loaded_estimate",b,void 0,{tool_name:C}),M&&n.count("agent.read.token_budget_reached",1,{tool_name:C});const ae=Et(S,new Set(x)),F=et({tool:C,loaded:{count:x.length,requestedCount:v.length,estimatedTokens:b,ranges:po(ae)},endOfDocument:!1,coverage:Qe(t,S)}),L=M?` Reached per-call token budget; loaded ${x.length}/${v.length} requested blocks.`:"",G=B>0?` ${B} requested block IDs were not found.`:"";return W(d,`Loaded ${x.length} specific blocks.${L}${G} Serialized characters: ~${b}.`,void 0,void 0,F)}if(C==="get_attachment"){const l=(d.arguments||{}).attachment_id;if(!l)return k(d,"No attachment_id provided");let h=t.getAllAttachments().get(l);return h||(h=await e(l),h&&t.getAllAttachments().set(l,h)),h?h.content?.trim()??""?W(d,`Loaded attachment "${h.id}" (${h.charCount} chars).`,void 0,void 0,`<attachment id="${h.id}" type="${h.type}"${h.fileName?` filename="${h.fileName}"`:""} chars="${h.charCount}">
8
- ${h.content}
9
- </attachment>`):W(d,`Attachment "${h.id}" has no text content to retrieve; it is a hosted file already visible in the conversation history.`):k(d,`Attachment "${l}" not found. Available attachments: ${Array.from(t.getAllAttachments().keys()).join(", ")||"none"}`)}if(C==="view_image"){const l=(d.arguments||{}).block_id;if(!l)return k(d,"No block_id provided");const h=t.getLatestDocument(),m=ao(h.children,l);if(!m)return k(d,`Image block "${l}" not found in document`,xe);const v={id:`view_image_${l}`,type:"image",content:"",preview:"",charCount:0,fileName:m.alt||`image_${l}`,urls:[m.src],dimensions:[{width:m.width,height:m.height}]};return W(d,`Image retrieved: ${m.alt?`"${m.alt}" `:""}(${m.width}x${m.height}px)${m.sourceUrl?` Source: ${m.sourceUrl}`:""}`,v)}if(C==="render_document_pages"){if(!t.renderDocumentPages)return k(d,"Rendered page inspection is unavailable until the document canvas is ready.");const l=d.arguments||{},h=Ze(l.start_page,1),m=Ze(l.page_count,1),v=l.mode==="layout"?"layout":"appearance";let p=l.quality==="compact"?"compact":"detailed";if(h<1)return k(d,"start_page must be 1 or greater.");const I=p==="detailed"&&m>2;I&&m<=4&&(p="compact");const S=p==="compact"?4:2;if(m<1||m>S)return k(d,`page_count must be between 1 and ${S} for ${p} quality.`);try{const x=await t.renderDocumentPages({startPage:h,pageCount:m,mode:v,quality:p});if(x.placeholderImageCount||x.failedImageCount||x.mathPlaceholderCount)return{...k(d,`Visual inspection is incomplete: ${x.placeholderImageCount} image placeholders, ${x.failedImageCount} failed images, and ${x.mathPlaceholderCount} formula placeholders. Resolve the unavailable resources before a retry: allow pending resources to finish loading, re-upload broken images, or correct unsupported formulas. Repeating this call without fixing them will not verify the document.`,"visual_resource_unavailable"),failure:{code:"visual_resource_unavailable",phase:"verification",retryable:!1,mutationOutcome:"unchanged"}};const b=x.pages.length===1?`page ${x.pages[0]}`:`pages ${x.pages[0]}-${x.pages[x.pages.length-1]}`,M={id:`render_document_pages_${d.id}`,type:"image",content:"",preview:"",charCount:0,fileName:`Rendered document ${b} (${v}, ${p})`,mimeType:x.dataUrl.startsWith("data:image/png")?"image/png":"image/jpeg",urls:[x.dataUrl],dimensions:[{width:x.width,height:x.height}],visionDetail:p==="compact"?"low":"high"};return W(d,`Rendered ${b} of ${x.totalPages} in ${v} mode at ${p} quality.${I?" The request was downgraded from detailed to compact quality so all requested pages fit in one bounded render.":""}`,M,void 0,JSON.stringify({pages:x.pages,totalPages:x.totalPages,mode:v,quality:p,placeholderImageCount:x.placeholderImageCount,failedImageCount:x.failedImageCount,mathPlaceholderCount:x.mathPlaceholderCount}))}catch(x){return k(d,x instanceof Error?x.message:"Document page rendering failed.",x instanceof Error&&"code"in x?String(x.code):void 0)}}if(C==="set_status"){const l=Xs(d.arguments);return t.toolState.statusMessage=l,t.markConversationDirty(),t.notifyListeners(),W(d,l?`Status set to "${l}".`:"Status updated.")}if(C==="request_user_input"){const l=d.arguments??{},h=typeof l.chat_response=="string"?l.chat_response.trim():"";return!h||io(h)?k(d,"request_user_input requires a concrete user-facing question, not only a status update.",so):!Array.isArray(l.suggested_next_prompts)&&!Array.isArray(l.followups)?k(d,"request_user_input requires suggested_next_prompts as an array."):W(d,"User input requested.")}if(C===Us)return!t.skipSameTurnCompletionGuard&&u>0?k(d,`${C} cannot be used in the same tool batch as document edits. Inspect the successful mutation results on the next turn, then call end_agent_run if the request is complete.`,ro):W(d,"Legacy completion handoff acknowledged. Call end_agent_run on the next turn.");if(Fs(C)){if(!t.skipSameTurnCompletionGuard&&u>0)return k(d,`${C} cannot be used in the same tool batch as document edits. Inspect the successful mutation results on the next turn, then continue concrete work or call end_agent_run if the request is complete.`,ro);const l=d.arguments??{},h=typeof l.chat_response=="string"?l.chat_response.trim():"";if(!h)return k(d,`${C} requires a non-empty chat_response.`);if(io(h))return k(d,`${C} requires a final user-facing response, not only a status update.`,so);if(!Array.isArray(l.suggested_next_prompts)&&!Array.isArray(l.followups))return k(d,`${C} requires suggested_next_prompts as an array.`);let m;if(l.completed_plan_item_ids!=null||l.completed_plan_steps!=null){if(!t.getPlanState||!t.setPlanState)return k(d,"This host does not support task plans.","plan_unavailable");const v=l.completed_plan_item_ids??[];if(!Array.isArray(v)||v.some(I=>typeof I!="string"))return k(d,"completed_plan_item_ids must be an array of current-plan item IDs.","invalid_plan_update");const p=l.completed_plan_steps??[];if(!Array.isArray(p)||p.some(I=>typeof I!="string"||!I.trim()))return k(d,"completed_plan_steps must be an array of new non-empty requirements.","invalid_plan_update");if(v.length>0||p.length>0)try{const I=t.getPlanState(),S=yn(I,"update_plan",{plan_id:I.plan?.id,updates:v.map(x=>({item_id:x,status:"completed"})),add_steps:p});for(const x of S.plan.items.slice(I.plan.items.length))x.status="completed";m=()=>{t.getPlanState()===I&&(t.setPlanState(S),t.markConversationDirty())}}catch(I){return k(d,I instanceof Error?I.message:String(I),"invalid_plan_update")}}return{...W(d,"Final response recorded."),...m?{commitPlanCompletion:m}:{}}}const te=await T();if(!te)return R(d);const Z=t.getLatestDocument();if(C==="rollback_agent_suggestions"){const l=d.arguments??{},h=l.request_id==null?void 0:l.request_id,m=l.turn==null?void 0:l.turn;if(h!==void 0&&(!Number.isInteger(h)||Number(h)<1))return k(d,"request_id must be a positive integer.");if(m!==void 0&&(!Number.isInteger(m)||Number(m)<1))return k(d,"turn must be a positive integer.");if(m!==void 0&&h===void 0)return k(d,"turn requires request_id.");const v=t.turnState.currentRequestId??0,p=t.turnState.currentTurn??0;if(h!==void 0&&Number(h)>v)return k(d,`request_id ${h} is in the future; the current request is ${v}.`);const I=t.getConversationId?.().trim()??"";if(!I)return k(d,"This conversation has no stable ID, so its suggestions cannot be rolled back safely.");const S=te.getDocumentWithPendingSuggestionsApplied(),x=te.rollbackAgentSuggestions({agentConversationId:I,requestId:h===void 0?void 0:Number(h),turn:m===void 0?void 0:Number(m),currentRequestId:v,currentTurn:p});if(x.resolvedCount===0){const j=x.requestId===void 0?"any prior request":`request ${x.requestId}${x.turn===void 0?"":` turn ${x.turn}`}`;return W(d,`No still-pending suggestions from this conversation matched ${j}. Accepted edits and other authors' work were left untouched. Recover omitted text from historical_edit_evidence or earlier before_block snapshots, then propose a targeted correction against the current document while preserving later edits. Searching the current document cannot recover text that was deleted.`,void 0,!0)}const b=te.getDocumentWithPendingSuggestionsApplied(),M=new Map(S.children.map(j=>[j.id,j])),B=new Map(b.children.map(j=>[j.id,j]));for(const j of new Set([...M.keys(),...B.keys()]))JSON.stringify(M.get(j))!==JSON.stringify(B.get(j))&&t.toolState.editedBlockIds.add(j);return t.turnState.hasMutatedSinceLastRead=!0,u+=1,t.markConversationDirty(),t.notifyListeners(),W(d,`Rolled back ${x.resolvedCount} pending suggestion${x.resolvedCount===1?"":"s"} ${x.turn===void 0?`to before request ${x.requestId}`:`from request ${x.requestId} turn ${x.turn}`}. The rollback is one user-undoable history item. Now make the corrected edits; do not ask the user to reject the old suggestions.`)}if(C==="leave_comment"){const l=Gs(d,t,te,Z);return l.success&&(u+=1),l}if((C==="insert_block"||C==="insert_table_row"||C==="insert_table_column")&&d.arguments?.position!=="before"&&d.arguments?.position!=="after")return k(d,`${C} has invalid "position" ${JSON.stringify(d.arguments?.position??null)}; use "before" or "after".`);if(C==="set_header_footer"&&d.arguments?.side!=="header"&&d.arguments?.side!=="footer")return k(d,`set_header_footer has invalid "side" ${JSON.stringify(d.arguments?.side??null)}; use "header" or "footer".`);const kt=We(Z,t.toolState.tableContext,Ut(t.turnState)??new Set),ke=Or({toolCall:d,docBefore:Z,isTargetAllowed:l=>ko(Z,l,kt)});if(ke?.error)return k(d,ke.error,ke.errorCode);const Jt=ke?.toolCall??d,Gt=new Set(kt??[]);for(const l of ke?.targetBlockIds??[])Gt.add(l);const le=Bo({toolCall:Jt,docBefore:Z,resultSets:f});if(le?.error)return k(d,le.error,le.errorCode);const Re=gi(Jt,Z,Gt);if(Re.error)return k(d,Re.error,Ue);const N=Re.toolCall;if(N.name==="replace"&&N.arguments&&Array.isArray(N.arguments.replacements)&&Object.prototype.hasOwnProperty.call(N.arguments,"comment"))return k(N,'replace comment belongs on each operation inside "replacements", alongside find, replace, and occurrence.');const xo=new Set(Z.children.map(l=>l.id)),Fe=new Set(kt??[]);for(const l of ke?.targetBlockIds??[])Fe.add(l);for(const l of le?.targetBlockIds??[])Fe.add(l);const tt=Ur(N,Z,l=>ko(Z,l,Fe));if(tt.error)return k(N,tt.error,tt.error.includes("request-level document context")?Ue:void 0);const ie=(z=t.toolState).tableContext??(z.tableContext=wn()),Vt={responseTurn:t.turnState.currentTurn,hasForeignSuggestion:l=>{const h=te.getDocumentMutator(),m=se(te.getWorkingDocument(),l.id);return m?h.getLiveSuggestionIdsForBlock(m).some(v=>{const p=h.getLiveSuggestion(v),I=t.getConversationId?.();return!ie.ownedSuggestionIds?.includes(v)&&!(I&&p?.agentConversationId===I)}):!1}},X=N.name==="edit_table_cells"?Sn(Z,ie,N.arguments,Vt):null,Kt=l=>{const h=l.filter(p=>p.reason.includes("not delivered"));if(!h.length)return{};const m=h[0].column,v=[...new Set(h.filter(p=>p.column===m).map(p=>p.row_id))].slice(0,50);return{recovery_read:{name:"read_table",arguments:{table_id:N.arguments?.table_id,mode:"rows",row_ids:v,column_start:m,column_count:1,context_notes:"Refresh this failed cell batch; preserve the original task and exact requested values."}},recovery_instruction:"Read this window, then edit only its fully delivered target cells before reading another window. Compaction can retire older read windows. Preserve the original task and continue until its full scope is complete.",remaining_unread_target_count:h.length-v.length}};if(X?.errors.length)return{...k(N,"No cells changed. Resolve every listed target error and retry the batch.",oo),toolOutput:JSON.stringify({errors:X.errors,...Kt(X.errors),skipped:X.skipped,changed_count:0})};const we=X?{actions:X.actions.map((l,h)=>({...l,id:`${N.id}-${h}`})),blockId:void 0,error:void 0}:le?{actions:le.actions,blockId:void 0,error:void 0}:N.name==="remove_block"&&Array.isArray(N.arguments?.ids)?{actions:tt.actions,blockId:void 0,error:void 0}:No(N,{doc:Z,loadedBlockIds:Fe});if(we.error){const l="failure"in we?we.failure:void 0;return{...k(N,we.error,l?.code),failure:l}}if(we.actions.length===0)return X?W(N,"No cells changed; inspect skipped and unchanged targets before continuing.",void 0,!0,JSON.stringify({changed_count:0,skipped:X.skipped,unchanged:X.unchanged})):W(N,`${co(N)} Continue with the remaining work; do not repeat this unchanged operation.`,void 0,!0);const wt=X?{actions:we.actions,retargets:[]}:Lo({actions:we.actions,doc:Z,loadedBlockIds:Fe}),Ce=wt.actions,ue=Array.from(new Set([...le?.targetBlockIds??[],...ke?.targetBlockIds??[],...ei(Ce)])),Xt=l=>{if(!t.toolState.tableContext?.scopedTableIds?.length||N.name==="edit_table_cells"||["style_blocks","clear_formatting"].includes(N.name))return;const h=t.toolState.tableContext.scopedTableIds;if(["insert_table_row","insert_table_column","remove_table_row","remove_table_column"].includes(N.name))return Sr(l,t.toolState.tableContext,N.name,N.arguments)?void 0:k(N,"Table geometry changed or cells affected by this deletion were not fully read. Reread the table summary for insertions, or every affected row/column cell for deletions.",Ue);const m=We(l,t.toolState.tableContext,Ut(t.turnState)??new Set);for(const v of ue){if(ke?.targetBlockIds.includes(v))continue;const p=se(l,v);if(h.some(I=>{const S=se(l,I);return S&&de(S).includes(v)||p&&de(p).includes(I)})&&!m.has(v))return k(N,`Target '${v}' was not fully read. Use read_table for its cells; a table preview does not authorize edits.`,Ue)}if(!ue.length&&!["set_title","set_notes","set_page_layout","set_header_footer","insert_block"].includes(N.name))return k(N,"This broad operation includes partially read tables. Read their cells or target fully delivered block IDs explicitly.",Ue)},Yt=Xt(Z);if(Yt)return Yt;const Zt=["insert_table_row","remove_table_row","insert_table_column","remove_table_column"].includes(N.name),Qt=new Map;if((N.name==="replace_block"||N.name==="remove_block"||Zt&&!t.toolState.tableContext?.scopedTableIds?.includes(String(N.arguments.tableId)))&&t.turnState.promptBlockContentHashes)for(const l of uo(Z,ue)){const h=se(Z,l),m=h?new Set(de(h)):new Set,v=ue.filter(I=>m.has(I));if(v.length&&v.every(I=>(ie.scopedTableIds??[]).some(S=>{const x=se(Z,S);return x&&de(x).includes(I)})))continue;const p=t.turnState.promptBlockContentHashes.get(l);p&&Qt.set(l,p)}const en=l=>{for(const[h,m]of Qt){const v=Ct(l,h);if(v!==null&&v!==m)return k(N,`Block '${h}' was edited (likely by the user) after you last read it. Re-read the block and re-apply your change against its current content.`,xe)}},tn=en(Z);if(tn)return tn;const nn=N.id||`tool-${Date.now()}`,$e=await(t.rehostImages??ts)(Ce);if($e.failedUrls.length>0){const l=$e.failedUrls.length===1?"1 external image":`${$e.failedUrls.length} external images`,h=$e.failures.some(p=>p.status===429),m=$e.failures.length===1?$e.failures[0]:void 0,v=m?` Reason: ${m.message}${m.status?` (HTTP ${m.status})`:""}.`:"";return k(N,`${l} could not be copied into Revise storage, so no document changes were applied.${v} ${h?"Do not attempt more external image insertions in this request. Keep any earlier successful changes and tell the user which image remains incomplete.":"Do not retry this URL. Use a different verified direct raster image URL or upload the image before trying again."}`,$e.unavailable?"agent_tool_not_allowed":void 0)}const pe=t.getLatestDocument(),on=Xt(pe);if(on)return on;if(X){const l=Sn(pe,ie,N.arguments,Vt);if(l.errors.length||JSON.stringify(l.targets)!==JSON.stringify(X.targets))return{...k(N,"Table targets changed while preparing this batch; no cells changed. Reread and retry.",oo),toolOutput:JSON.stringify({errors:l.errors,...Kt(l.errors),skipped:l.skipped,changed_count:0})}}const rn=en(pe);if(rn)return rn;let J;const Ee=N.name==="remove_block"?[...new Set(Ce.map(l=>typeof l.arguments?.id=="string"?ot(Z,l.arguments.id):null).filter(l=>l!==null))]:[];if(Ee.length>0&&Ce.some(l=>l.arguments?.count!=null&&l.arguments.count!==1||typeof l.arguments?.id!="string"||!ot(Z,l.arguments.id)))return k(N,"To remove footnotes/endnotes, pass their exact note IDs in ids, or one note ID with count 1. Remove main-document blocks separately.");for(const l of Ce){if(l.name!=="replace_block")continue;const h=pe.notes?.find(m=>m.id===l.arguments?.id);if(h&&dn(pe,h.id)===h.id)return k(N,`Note '${h.id}' contains multiple body blocks or no single editable text block. Use replace_block with an exact body block ID (${h.children.map(m=>m.id).join(", ")}) instead of replacing the note wrapper.`)}if(Ee.length>0){const l=te.getDocumentMutator(),h=new Set(l.getLiveSuggestionIds()),m=l.suggestingMode;l.suggestingMode=!0;let v=!1;try{const{result:I}=l.withSuggestionMetadata({source:"agent",authorType:"ai",agentName:Le(t),...t.getAgentModel?{agentModel:t.getAgentModel()}:{},agentConversationId:t.getConversationId?.(),agentRequestId:t.turnState.currentRequestId,agentTurn:t.turnState.currentTurn,commentThreadId:t.commentThreadId,historyOrigin:`live-suggestions:${nn}`},()=>Ee.every(S=>l.removeFootnote(S)));v=I}finally{l.suggestingMode=m}const p=l.getLiveSuggestionIds().filter(I=>!h.has(I));J=v?{success:!0,suggestionIds:p,agentFeedback:`Removed footnote/endnote blocks ${Ee.join(", ")} and their inline references.`}:{success:!1,error:`Footnote/endnote blocks '${Ee.join(", ")}' could not be removed.`}}else J=te.applyAgentActions({message:"AI Assistant",actions:Ce.map(l=>{if((l.name==="replace"||l.name==="replace_all"||l.name==="replace_block")&&typeof l.arguments?.id=="string"){const h=dn(pe,l.arguments.id);if(h&&h!==l.arguments.id)return{...l,arguments:{...l.arguments,id:h}}}return l}),agentName:Le(t),agentModel:t.getAgentModel?.(),agentConversationId:t.getConversationId?.(),agentRequestId:t.turnState.currentRequestId,agentTurn:t.turnState.currentTurn,commentThreadId:t.commentThreadId},nn,{optimizeStyleFormatting:t.getOptimizeStyleFormatting?.()??!1});if(J.resultCode==="already_satisfied")return W(N,J.styleEffects&&J.agentFeedback?J.agentFeedback:"Verified that the requested state is already satisfied; no document mutation occurred. "+co(N),void 0,!0,JSON.stringify({code:"already_satisfied",mutationOutcome:"unchanged",...J.styleEffects?JSON.parse(ho(N,Z,Z,J.styleEffects.targetBlockIds,J.agentFeedback,J.styleEffects)):{}}));if(J.success!==!1&&J.styleEffects){const l=new Set([...J.styleEffects.changedBlockIds,...J.styleEffects.affectedBlockIds]);l.size<=qe&&ue.splice(0,ue.length,...l)}const fe=J.success!==!1;let Y=J.agentFeedback,nt;if(fe&&le?.resultSet){const l=le.resultSet,h=`Applied ${N.name} to all ${l.blockIds.length} blocks in ${l.id}.`;Y=Y?.includes(h)?Y:Y?`${h}
10
- ${Y}`:h}if(fe&&(N.name==="replace_many"||N.name==="replace"&&Array.isArray(N.arguments?.replacements))){const l=Ce.length,h=ti(ue,we.blockId),m=`Applied ${l} replacement ${l===1?"operation":"operations"} in ${h}.`;Y=Y?.includes(m)?Y:Y?`${m}
11
- ${Y}`:m}if(fe&&Re.feedback&&(Y=Y?`${Y}
12
- ${Re.feedback}`:Re.feedback),fe&&wt.retargets.length>0){const l=ni(wt.retargets);l&&(Y=Y?`${Y}
13
- ${l}`:l)}if(fe&&((J.commentedSuggestionIds?.length??0)>0||(J.commentAttachmentFailureCount??0)>0)){const l=J.attachedCommentIds??[],h=J.commentAttachmentFailureCount??0,m=l.length>0?`Attached ${l.length===1?"comment":`${l.length} separate comments`} to the resulting ${l.length===1?"suggestion":"suggestions"} (${l.join(", ")}).${h>0?` ${h} requested ${h===1?"comment":"comments"} could not be anchored; do not repeat the edits.`:""}`:"The edits were suggested, but their requested comments could not be anchored. Do not repeat the edits; use leave_comment on the affected text instead.";Y=Y?`${Y}
14
- ${m}`:m}if(fe){const l=mi(N,Z);l&&(Y=Y?`${Y}
15
- ${l}`:l)}if(t.toolState.directMode&&fe){const l=new Set(J.commentedSuggestionIds??[]),h=(J.suggestionIds??[]).filter(m=>!l.has(m));if(h.length>0&&te.acceptLiveSuggestions(h),h.length>0&&l.size===0){const m=te.getDocumentMutator();m?.resetToolCallHistory&&m.resetToolCallHistory()}}if(fe){t.mutationTools.includes(C)&&(u+=1);const l=te.getDocumentWithPendingSuggestionsApplied();if(Zt&&typeof N.arguments.tableId=="string"){const h=at(l,{table_id:N.arguments.tableId,mode:"summary"});h.error||(ie.geometries??(ie.geometries={}),ie.geometries[h.table_id]=h.revision)}if(!X){const h=We(pe,ie,new Set);for(const m of Object.values(ie.cells))h.has(m.cellId)&&m.blockIds.some(v=>ue.includes(v))&&ct(l,ie,m.tableId,[m.cellId]);for(const[m,v]of Object.entries(ie.blocks??{}))h.has(m)&&v.blockIds.some(p=>ue.includes(p))&&kn(l,ie,v.tableId,m)}if(le?.resultSet&&(le.resultSet.blockHashes=xt(l,le.resultSet.blockIds)),nt=X?void 0:ho(N,Z,l,ue,Y,J.styleEffects),X){const h=String(N.arguments.table_id);ct(l,ie,h,X.targets.map(S=>S.cellId));const m=t.turnState.currentTurn??0;ie.responseClaims={turn:m,cellIds:[...ie.responseClaims?.turn===m?ie.responseClaims.cellIds:[],...X.targets.map(S=>S.cellId)]},ie.ownedSuggestionIds=[...ie.ownedSuggestionIds??[],...J.suggestionIds??[]];const v=Nr(t.getTableTaskState?.()??t.toolState.tableTasks??Dn(),{requestId:t.turnState.currentRequestId??0,tableId:h,cellIds:X.targets.map(S=>S.cellId)});t.toolState.tableTasks=v,t.setTableTaskState?.(v);const p=[];let I=0;if(N.arguments.mode==="replace")for(const S of X.targets){const x=se(pe,S.paragraphId),b=x?.type==="paragraph"?x.children.map(B=>B.type==="text"?B.text:"").join(""):null,M={row_id:S.row_id,column:S.column,previous_text:b??""};b===null||JSON.stringify([...p,M]).length>8e3?I++:p.push(M)}nt=JSON.stringify({tool:"edit_table_cells",...N.arguments.mode==="replace"?{previous_cells:p,omitted_previous_cells:I,...I?{previous_values_recovery:"Some prior values were omitted from this bounded lookback. For pending edits use rollback_agent_suggestions for the relevant request/turn, then reread. Accepted edits require earlier historical edit evidence; do not reconstruct missing prior text from the current document."}:{}}:{},table_id:h,proposed_cell_count:X.targets.length,changed_count:X.targets.length,rows:[...new Set(X.targets.map(S=>S.row_id))],skipped:X.skipped,unchanged:X.unchanged,remaining_empty_in_working_document:at(l,{table_id:h,mode:"summary"}).columns.filter(S=>X.targets.some(x=>x.column===S.column)),status:t.toolState.directMode?"applied":"proposed_pending_review"})}if(t.turnState.hasMutatedSinceLastRead=!0,t.mutationTools.includes(C)&&C!=="set_title"&&C!=="set_notes"&&C!=="set_page_layout"){if(!le)for(const h of ue)t.toolState.editedBlockIds.add(h);if(!le)for(const h of l.children)h.id&&!xo.has(h.id)&&t.toolState.editedBlockIds.add(h.id);if(t.turnState.promptBlockContentHashes){const h=uo(pe,ue);for(const m of h){const v=t.turnState.promptBlockContentHashes.get(m);if(v&&Ct(pe,m)!==v||!v&&!ue.includes(m))continue;const p=Ct(l,m);p!==null?t.turnState.promptBlockContentHashes.set(m,p):t.turnState.promptBlockContentHashes.delete(m)}}le||fi(t)}}const sn=Vs(J.error);return{toolCall:N,success:fe,error:J.error,failure:J.failure,...J.failure?{errorCode:J.failure.code}:{},...!fe&&sn?{errorCode:sn}:{},documentStateAfter:te.getDocumentWithPendingSuggestionsApplied(),agentFeedback:Y,...nt?{toolOutput:nt}:{}}}}const wo={read_table:["task_kind","scope_row_start","scope_row_count","scope_columns","source_attachment_id","deliberate_blanks"]};function _i(t){const e=wo[t.name];if(!e)return t;const n=t.inputSchema;return{...t,description:t.description.split(/(?<=\.)\s+/).filter(o=>!e.some(r=>o.includes(r))&&!/task scope/i.test(o)).join(" "),inputSchema:{...t.inputSchema,properties:Object.fromEntries(Object.entries(n.properties??{}).filter(([o])=>!e.includes(o))),...n.required?{required:n.required.filter(o=>!e.includes(o))}:{}}}}const ki=Qn.map(t=>_i(t));function wi(t){const e=wo[t.name],n=t.arguments;if(!e||!n||typeof n!="object"||Array.isArray(n))return{toolCall:t};const o=e.filter(r=>ht(n[r]));return o.length?{error:`${t.name} does not accept ${o.join(", ")} in the embedded SDK: task declarations are tracked only by the native Revise agent. Omit them; reading and editing table cells works without them. Nothing was read.`}:{toolCall:{...t,arguments:Object.fromEntries(Object.entries(n).filter(([r])=>!e.includes(r)))}}}function vo(t){return t.replace(/^Failed operation: [\w-]+: (?:\w*Error: )?/,"").replaceAll("Please only reference IDs you see inside <document_content>.","Use a block ID from a read or search result.").replaceAll("outside the loaded <document_content> context","outside what has been read").replaceAll("<document_content>","the read results")}function vi(t,e){return t.success?{ok:!0,value:{callId:t.toolCallId,tool:t.name,message:t.agentFeedback===void 0||t.agentFeedback===null?null:vo(t.agentFeedback),data:t.output??null,context:t.documentContent?{format:"revise-html",html:t.documentContent}:null,suggestionIds:e}}:{ok:!1,error:{callId:t.toolCallId,tool:t.name,code:t.errorCode??"tool_failed",message:vo(t.error??t.agentFeedback??`${t.name} failed.`)}}}function Ii(t){if(t)try{return JSON.parse(t)}catch{return t}}class Si{constructor(e){this.options=e,this.toolState={editedBlockIds:new Set,hasImportedAttachment:!1,everReadFullDocument:!1,lastSearchState:null,statusMessage:null,directMode:!1,directModeForced:!1},this.turnState={currentTurn:0,requestedBlockIds:null,readBudgetBlockIds:null,lastReadBlockIds:null,promptBlockContentHashes:new Map,documentRequested:!1,hasMutatedSinceLastRead:!1},this.deliveredBlockIds=[],this.handler=null}async run(e,n={}){this.turnState.currentTurn+=1,this.deliveredBlockIds=[],this.toolState.sequentialReadBlockIds=new Set;const o=wi(e);if("error"in o)return{toolCall:e,success:!1,error:o.error,errorCode:"unsupported_argument"};e=o.toolCall;const r=this.handler??(this.handler=this.createHandler()),s=this.toolState.directMode,i=this.toolState.directModeForced;n.directMode!==void 0&&(this.toolState.directMode=n.directMode,this.toolState.directModeForced=!0);try{return await r(e)}finally{this.toolState.directMode=s,this.toolState.directModeForced=i}}buildResult(e,n,o){const r=o.success&&this.deliveredBlockIds.length>0?ne.formatSpecificBlocks(ne.extractSpecificBlocks(this.options.getDocumentSession().getDocumentWithPendingSuggestionsApplied(),this.deliveredBlockIds)):void 0;return{toolCallId:e,name:n,success:o.success,...o.error?{error:o.error}:{},...o.errorCode?{errorCode:o.errorCode}:{},...o.agentFeedback?{agentFeedback:o.agentFeedback}:{},...o.toolOutput?{output:Ii(o.toolOutput)}:{},...r?{documentContent:r}:{}}}createHandler(){return yi({toolState:this.toolState,turnState:this.turnState,getAllAttachments:()=>new Map,getFlaggedAttachmentIds:()=>new Set,getLatestDocument:()=>this.options.getDocumentSession().getDocumentWithPendingSuggestionsApplied(),getDocumentSession:()=>this.options.getDocumentSession(),markConversationDirty:()=>{},notifyListeners:()=>{},tryAddRequestedBlocks:e=>{const n=this.turnState.requestedBlockIds??new Set,o=this.turnState.readBudgetBlockIds??new Set;for(const s of e)n.add(s),o.add(s);this.turnState.requestedBlockIds=n,this.turnState.readBudgetBlockIds=o,this.turnState.lastReadBlockIds=new Set(e);const r=this.options.getDocumentSession().getDocumentWithPendingSuggestionsApplied();for(const[s,i]of xt(r,e))this.turnState.promptBlockContentHashes.set(s,i);return this.deliveredBlockIds=[...e],null},mutationTools:[...this.options.mutationTools],searchPageSize:this.options.searchPageSize??25,getAgentAuthorName:()=>this.options.getAgentName?.()})}}const xi="N/A";function Io(t,e,n){if(e.context_notes!==void 0)return e;const o=n.find(r=>r.name===t)?.inputSchema?.required;return!Array.isArray(o)||!o.includes("context_notes")?e:{...e,context_notes:xi}}const So=new Set(["get_selection","view_image"]),Ci=new Set(["remove_block"]),$i=["document_id","search_documents",...So];function Mi(t){const e=structuredClone(t),n=e.properties;return delete n?.document_id,Array.isArray(e.required)&&(e.required=e.required.filter(o=>o!=="document_id")),e}function Di(t){return t.split(/(?<=\.)\s+/).filter(e=>!$i.some(n=>e.includes(n))).join(" ")}const yt=ki.filter(t=>!So.has(t.name)).map(t=>({name:t.name,description:Di(t.description),inputSchema:Mi(t.inputSchema)}));function Ti(t,e){if(!e.documentId.trim())throw new Error("Revise: documentId is required for a server session.");const n=new Wt(e.documentId,t,void 0,{disableHistory:!0,disableProposalPersistence:!0}),o=new Set(Tt);let r=e.mode??"suggesting";n.setSuggestingMode(r==="suggesting");const s=new Si({getDocumentSession:()=>n,mutationTools:Array.from(Tt),searchPageSize:e.searchPageSize});let i=1,a=!1,c=Promise.resolve();const u=()=>{if(a)throw new Error("Revise: server document session is disposed.")},f=(D,_,g,y)=>({ok:!1,error:{callId:D,tool:_,code:g,message:y}}),$=async(D,_,g,y)=>{u();const q=`server-tool-${i++}`;if(!yt.some(w=>w.name===D)&&!Ci.has(D))return f(q,D,"unknown_tool",`Unknown or unavailable server document tool: ${D}`);if("document_id"in _)return f(q,D,"document_id_not_supported","document_id is not accepted: a server document session is bound to one document. Omit it and retry.");await qo(),u(),n.setSuggestingMode(y==="suggesting");const A=o.has(D)?new Set(n.getDocumentMutator().getLiveSuggestionIds()):null;try{const w=await s.run({id:q,name:D,arguments:_},{directMode:g.directMode??y==="editing"}),O=s.buildResult(q,D,w);return vi(O,A?n.getDocumentMutator().getLiveSuggestionIds().filter(z=>!A.has(z)):null)}catch(w){return f(q,D,"internal_error",w instanceof Error?w.message:String(w))}finally{n.setSuggestingMode(r==="suggesting")}},T=(D,_,g)=>{const y=r,q=c.then(()=>$(D,_,g,y));return c=q.then(()=>{},()=>{}),q},R={getDefinitions:()=>(u(),yt.map(D=>({...D,inputSchema:structuredClone(D.inputSchema)}))),execute:(D,..._)=>{const[g={},y={}]=_;return T(D,Io(D,g,yt),y)},executeDynamic:(D,_={},g={})=>T(D,_,g),call:async(D,..._)=>{const[g={},y={}]=_,q=await T(D,Io(D,g,yt),y);if(!q.ok)throw new Ao(q.error);return q.value}},P=()=>{u();const D=n.getDocumentMutator();return D.getLiveSuggestionIds().map(_=>{const g=D.getLiveSuggestion(_),y=D.getInlineSuggestionMetadataFromDocument(_),q=g&&"blockId"in g?g.blockId:g?.type==="paragraph-merge"?g.firstBlockId:void 0,A={id:_,...g?.type?{type:g.type}:{},...q?{blockId:q}:{},...g?.type==="table-change"?{tableId:g.tableId}:{}};for(const w of["authorType","agentName","agentModel","source","label","createdAt"]){const O=y?.[w]??g?.[w];O!==void 0&&Object.assign(A,{[w]:O})}return A})},U=(D,_)=>{u();const g=Array.from(new Set(_.filter(z=>typeof z=="string"&&z.trim().length>0))),y=n.getDocumentMutator(),q=new Set(y.getLiveSuggestionIds()),A=g.filter(z=>!q.has(z)),w=g.filter(z=>q.has(z));w.length>0&&(D==="accept"?n.acceptLiveSuggestions(w):n.rejectLiveSuggestions(w));const O=new Set(y.getLiveSuggestionIds());return{resolved:w.filter(z=>!O.has(z)),missing:A,unresolved:w.filter(z=>O.has(z))}};return{getMode:()=>(u(),r),setSuggestingMode:()=>{u(),r="suggesting"},setEditingMode:()=>{u(),r="editing"},tools:R,getPendingSuggestionIds:()=>(u(),n.getDocumentMutator().getLiveSuggestionIds()),listSuggestions:P,acceptSuggestions:D=>U("accept",D),rejectSuggestions:D=>U("reject",D),acceptAllSuggestions:()=>(u(),U("accept",n.getDocumentMutator().getLiveSuggestionIds())),rejectAllSuggestions:()=>(u(),U("reject",n.getDocumentMutator().getLiveSuggestionIds())),dispose:()=>{a||(a=!0,n.dispose())}}}export{Ti as createServerDocumentSession};
@@ -1,17 +0,0 @@
1
- import{ag as g,r as h,ab as j,b6 as A,b7 as k}from"./backend-BIhAX-Gi.js";const c=2;function s(e){return e===null||typeof e!="object"?JSON.stringify(e)??"null":Array.isArray(e)?`[${e.map(s).join(",")}\
2
- ]`:`{${Object.entries(e).filter(([,t])=>t!==void 0).sort(([t],[r])=>t<r?-1:t>r?1:0).map(([t,r])=>`${JSON.stringify(t)}:${s(r)}`).join(",")}}`}function i(e,t=c){if(e===null||typeof e!="object")return e;
3
- if(Array.isArray(e))return e.map(o=>i(o,t));const r=e;if(r.type==="text")return{...r,marks:(t===1?A:k)(r.marks)};const n={};for(const[o,a]of Object.entries(r))o==="indentLevel"&&r.type==="list-item"&&
4
- !a||o==="hasHeader"&&r.type==="table"&&!a||o==="footnoteNumber"&&r.type==="footnote"||(n[o]=i(a,t));if(Array.isArray(n.children)){const o=[];for(const a of n.children){const f=o[o.length-1];if(f&&f.type===
5
- "text"&&a.type==="text"&&s(f.marks)===s(a.marks)){f.text=`${f.text}${a.text}`;continue}o.push(a)}n.children=o}return n}function u(e){return`${d(e,0).toString(36)}-${d(e,2654435769).toString(36)}`}function d(e,t){
6
- let r=3735928559^t,n=1103547991^t;for(let o=0;o<e.length;o++){const a=e.charCodeAt(o);r=Math.imul(r^a,2654435761),n=Math.imul(n^a,1597334677)}return r=Math.imul(r^r>>>16,2246822507),r^=Math.imul(n^n>>>
7
- 13,3266489909),n=Math.imul(n^n>>>16,2246822507),n^=Math.imul(r^r>>>13,3266489909),4294967296*(2097151&n)+(r>>>0)}function b(e,t=c){return s(i(e,t))}function x(e,t=c){return u(b(e,t))}function O(e){return u(
8
- s(h(e.pageLayout)))}function l(e){if(e===null||typeof e!="object")return e;if(Array.isArray(e))return e.map(l);const t=e;if(t.type==="text"&&t.marks&&typeof t.marks=="object"&&"fontFamily"in t.marks){
9
- const n={...t.marks};return delete n.fontFamily,{...t,marks:n}}const r={};for(const[n,o]of Object.entries(t))r[n]=l(o);return r}function $(e,t=c){const r=[...e.children.filter(n=>n.type==="footnote"),
10
- ...e.notes??[]];return u(s(r.map(n=>i(l(n),t))))}function m(e){if(e===null||typeof e!="object")return e;if(Array.isArray(e))return e.map(m);const t={};for(const[r,n]of Object.entries(e))r!=="id"&&(t[r]=
11
- m(n));return t}function v(e,t=c){let r=[...e.children.filter(n=>n.type==="header-footer"),...e.chrome??[]];return r.length===0&&(e.headers||e.footers)&&(r=j(e.headers,e.footers)),u(s(i({blocks:r.map(n=>m(
12
- n)),watermark:e.watermark??null,chromeImages:e.chromeImages??[]},t)))}function M(e,t=c){const r=n=>[...n].sort((o,a)=>{const f=s(i(o,t)),p=s(i(a,t));return f<p?-1:f>p?1:0});return u(s(i({sdtWrappers:r(
13
- e.sdtWrappers??[]),oxmlRanges:r(e.oxmlRanges??[])},t)))}function S(e,t=c){return u(s(i({stylesXml:e.stylesXml??null,stylesheet:e.stylesheet??null},t)))}function y(e){if(e===null||typeof e!="object")return!1;
14
- if(Array.isArray(e))return e.some(y);const t=e;if(t.type==="toc")return!0;const r=t.marks;return r&&typeof r=="object"&&typeof r.fieldInstr=="string"?!0:Object.values(t).some(y)}function F(e){const t=[
15
- ...e.children.filter(n=>n.type==="header-footer"),...e.chrome??[]],r=!!(e.headers?.even||e.footers?.even)||t.some(n=>n.slot==="even"&&g(n));return u(s({autoHyphenation:h(e.pageLayout).hyphenationEnabled,
16
- evenAndOddHeaders:r,updateFields:y(e.children)}))}function N(e,t=c){return u(s([...e.comments??[]].sort((r,n)=>r.id<n.id?-1:r.id>n.id?1:0).map(r=>i(r,t))))}function C(e){return u(s(e.coreProperties??{}))}
17
- export{c as C,b as a,x as b,M as c,F as d,S as e,v as f,N as g,C as h,i,s as j,$ as n,O as p,u as s};