@reviseio/engine 3.0.1 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/assets/{historyMaterializeWorker-Kl0syEbc.js → historyMaterializeWorker-BMHTnStL.js} +131 -130
- package/chunks/{AgentHtmlConverter-CnnB8-WI.js → AgentHtmlConverter-B5qstcmM.js} +129 -128
- package/chunks/{AgentPageRenderer-DLgUGrGy.js → AgentPageRenderer-JMhCw-hi.js} +4 -4
- package/chunks/BlockDiff-C8eiZ-sf.js +45 -0
- package/chunks/{CanvasRenderer-C1Vegx9Y.js → CanvasRenderer-C2vAzLWM.js} +12 -12
- package/chunks/DocumentCompare-DX4RWeSV.js +10 -0
- package/chunks/{DocumentLayoutEngine-C62pyGVf.js → DocumentLayoutEngine-BhcWXkeu.js} +45 -45
- package/chunks/{DocumentMutator-Bat_oLBQ.js → DocumentMutator-FEFU1YM0.js} +6 -6
- package/chunks/DocumentOutline-BOZoTohH.js +4 -0
- package/chunks/{DocumentScrubber-BZQn_z92.js → DocumentScrubber-C4N3Qagm.js} +1 -1
- package/chunks/{DocumentSession-BDcazSEv.js → DocumentSession-gZHWP7By.js} +1 -1
- package/chunks/{DocxConverter-BC31uYIL.js → DocxConverter-BOyLn5eZ.js} +709 -703
- package/chunks/{DocxGraft-L10HXM3U.js → DocxGraft-BbE-AaM5.js} +2 -2
- package/chunks/{HtmlConverter-C5ihhZ6G.js → HtmlConverter-BlzwsPEn.js} +3 -3
- package/chunks/MarkdownConverter-BHVskVXI.js +59 -0
- package/chunks/{OdtConverter-c1fTWoAt.js → OdtConverter-BdmBFOD1.js} +1 -1
- package/chunks/{OfficeImportShared-CrOpHpJ-.js → OfficeImportShared-B2XJgnDO.js} +4 -4
- package/chunks/{PdfConverter-DX7fsRH5.js → PdfConverter-DZMCHDAo.js} +6 -6
- package/chunks/{RtfConverter-hbJ2529G.js → RtfConverter-RqE-xZcW.js} +2 -2
- package/chunks/{TableBorders-DVhdvo6f.js → TableBorders-ARyTi49V.js} +1 -1
- package/chunks/{TxtConverter-YHv5FXWb.js → TxtConverter-EPQtb6A6.js} +1 -1
- package/chunks/{Typography-B4gndEdB.js → Typography-XR6scRNV.js} +9 -9
- package/chunks/{XmlConverter-BRRluy9k.js → XmlConverter-9sFRFaza.js} +1 -1
- package/chunks/{capture-i_dPkQIS.js → capture-DhGn0CWA.js} +1 -1
- package/chunks/{carrier-pYM9xf6x.js → carrier-D58g-gw4.js} +1 -1
- package/chunks/{chromeImageLayout-BiQ3Iz1-.js → chromeImageLayout-DeYYS8YP.js} +1 -1
- package/chunks/{engine-LMUnxdm2.js → engine-C5fxuZJo.js} +139 -139
- package/chunks/{footnoteFlatten-EE85Hjre.js → footnoteFlatten-coCVFd3c.js} +1 -1
- package/chunks/{graftExport-G-dG7Vcc.js → graftExport-FBGE2qvt.js} +1 -1
- package/chunks/{index-BLb10wQt.js → index-Cezk1s_y.js} +4 -4
- package/chunks/{serverDocumentSession-DGDU5Lh3.js → serverDocumentSession-LMu3kocH.js} +559 -560
- package/chunks/{signatures-DTNDS2PH.js → signatures-DsJnnIqV.js} +1 -1
- package/chunks/textExtraction-Bqaqt1Kg.js +2 -0
- package/engine.js +2 -2
- package/package.json +2 -2
- package/chunks/BlockDiff-B6-aJxHo.js +0 -42
- package/chunks/DocumentCompare-C8295s35.js +0 -6
- package/chunks/MarkdownConverter-DofaSeC4.js +0 -57
|
@@ -1,166 +1,167 @@
|
|
|
1
|
-
import{DocumentSession as Ko}from"./DocumentSession-
|
|
2
|
-
i as
|
|
3
|
-
|
|
4
|
-
e as dr,t as ur,i as mr,j as hr}from"./engine-
|
|
5
|
-
import{
|
|
6
|
-
super(t.message),this.failure=t,this.name="ReviseToolError",
|
|
7
|
-
|
|
8
|
-
["images.revise.io"]);for(const n of e.flatMap(o=>(o??"").split(",")))if(n.
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
length<8||n[1]!=="wikipedia"||n[2]!=="commons"||n[3]!=="thumb"?e:(t.
|
|
12
|
-
amp;").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">
|
|
13
|
-
i=t.get(r);if(!i)return n;let a=n.replace(Mt,(c,d,u)=>`${d}${u}${i.url}${u}`);
|
|
14
|
-
test(a)
|
|
15
|
-
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
failure:{url:e,status:t.status,message:
|
|
20
|
-
{}}}}catch{return{ok:!1,failure:{url:e,message:"
|
|
21
|
-
"
|
|
22
|
-
n);if(o&&An(o.url)&&t.add(o.url),!n?.name||!Dn.has(
|
|
23
|
-
const n
|
|
24
|
-
const c=await t(l);c.ok?r.set(l,c.image):i.push(c.failure)}));
|
|
25
|
-
l),d=c&&r.get(c.url);if(c&&d&&(c.url=d.url,d.naturalWidth&&d.
|
|
26
|
-
|
|
27
|
-
1024*1024,
|
|
28
|
-
|
|
29
|
-
"WEBP"){const o=n(12,4);if(o==="VP8X"){const r=i=>e[i]|e[i+1]<<8|
|
|
30
|
-
height:
|
|
31
|
-
216){let o=2;for(;o+9<e.length&&e[o]===255;){const r=e[o+1],i=t.getUint16(
|
|
32
|
-
2+i}return{mime:"image/jpeg"}}return null}function
|
|
33
|
-
const[u,f,b,y]=n.slice(1).map(Number);t=`${t.slice(0,n.index)}${(u<<8|f).toString(
|
|
34
|
-
includes("::")?i(r):[],c=8-a.length-l.length;if(c<0||!t.includes("::")&&c!==0)return null;
|
|
35
|
-
return e===0||e===10||e===127||e===100&&t>=64&&t<=127||e===169&&t===254||e===172&&
|
|
36
|
-
exec(e);if(t)return
|
|
37
|
-
n[1]===65435&&r(2,6)?o(n[6]):n[0]===8194?o(n[1]):(n[0]&65024)===64512||(n[0]&65472)===65152||
|
|
38
|
-
if(e.protocol!=="http:"&&e.protocol!=="https:")throw new Te(`Only http(s) image URLs can
|
|
39
|
-
protocol==="https:"?import("node:https"):import("node:http")]),a=e.hostname.replace(/^\[|\]$/g,
|
|
40
|
-
|
|
41
|
-
u.all?f(null,
|
|
42
|
-
const o=AbortSignal.timeout(
|
|
43
|
-
e,{signal:o});if(!u.ok)throw new Te(`The image URL answered HTTP ${u.status}.`,u.status);if(Number(
|
|
44
|
-
try{for(;;){const{done:b,value:y}=await f.read();if(b)break;l(y)}}catch(b){throw await f.cancel().
|
|
45
|
-
const b=await
|
|
46
|
-
`The image URL answered HTTP ${y}.`,y);if(Number(b.headers["content-length"]??0)>n)throw b.destroy(),
|
|
47
|
-
for(const u of i)c.set(u,d),d+=u.length;return c}function gt(e,t,n){const o={url:e,message:t};
|
|
48
|
-
let o;try{o=await
|
|
49
|
-
"The image's pixel size could not be read."):r.width*r.height>
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
"
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
create_plan"){if(typeof n.objective!="string"||!n.objective.trim())throw new Error(
|
|
57
|
-
plan&&n.supersedes_plan_id!==e.plan.id)throw new Error(`To start a new task,
|
|
58
|
-
null)throw new Error("There is no plan to supersede.");const c=`plan_${e.
|
|
59
|
-
_item_${u+1}`,step:d,status:"pending"}))}}}const o=e.plan;if(!o||n.plan_id!==
|
|
60
|
-
[]:On(n.add_steps),i=n.updates===void 0?[]:n.updates;if(!Array.isArray(i))throw new Error(
|
|
61
|
-
l.item_id)||!
|
|
62
|
-
|
|
63
|
-
add_steps.");return{nextPlanNumber:e.nextPlanNumber,plan:{...o,items:[...o.items.map(l=>({...l,status:i.
|
|
64
|
-
c+1}`,step:l,status:"pending"}))]}}}const En=50,
|
|
65
|
-
children.map(c=>c.id),text:`Contains nested tables. Read them with read_table: ${n.slice(0,20).join(", ")}
|
|
66
|
-
e.cell),r=et(e.cell);let i={id:e.cell.id,column:e.col,kind:r?"empty":o?"text":"rich",row_span:e.rowSpan,
|
|
67
|
-
marks,l=a?ft(a):void 0;return i.formatting={cell:ft(e.cell),...o?{paragraph:ft(o),text_marks:l&&Object.keys(
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
"children"].includes(t)&&!
|
|
71
|
-
|
|
72
|
-
const t=e;return[...t.id?[t.id]:[],...Ot(e).flatMap(ue)]}function Ot(e){const t=e;return[t.children,t.notes,t.
|
|
73
|
-
map(u=>e.children[u].id),a=i.reduce((u,f)=>f.length>u.length?f:u,""),l=u=>({table_id:e.id,...u,column_start:t.
|
|
74
|
-
row_count:o}),d=u=>JSON.stringify(u).length-1;return Math.max(d({next_row:t.rows,next_read:c}),d({next_row:t.
|
|
75
|
-
function jt(e){return ke([e.columnWidths,e.children.map(t=>[t.id,t.children.map(n=>[n.id,n.rowSpan,n.colSpan])])])}
|
|
76
|
-
""),row_count:0,column_count:0,revision:"",columns:[],unplaced_cell_ids:[],rows:[],complete_cell_ids:[]};if(!o)return{
|
|
77
|
-
cols,r.revision=jt(o),r.columns=Array.from({length:i.cols},(D,A)=>({column:A,empty:0,filled:0,covered:0}));for(let D=0;D<
|
|
78
|
-
col!==A?r.columns[A].covered++:et(M.cell)?r.columns[A].empty++:r.columns[A].filled++)}const a=o.children.flatMap(D=>D.children.
|
|
79
|
-
let l=2;for(const D of a){if(r.unplaced_cell_ids.length>=100)break;const A=JSON.stringify(D).length+(r.unplaced_cell_ids.length?
|
|
80
|
-
t.column_start)&&Number(t.column_start)>=0?Number(t.column_start):0;r.columns=r.columns.slice(c,c+100),c+100<i.cols&&(r.next_summary=
|
|
81
|
-
"rows";if(d==="summary")return r;if(d==="cell_text"){const D=i.byId.get(String(t.cell_id??""));if(!D)return{...r,error:"Unknown
|
|
82
|
-
A)return{...r,error:"Cell changed since the previous window; restart at text_offset=0."};const M=t.text_offset??0,I=
|
|
83
|
-
filter((we,pe)=>{const lt=I.segments[pe+1]?.start??C.length+1;return we.start<$&<>h}).map(we=>({id:we.id,text_offset:we.
|
|
84
|
-
error:"Invalid text_offset."};if(Number(M)>0&&/[\uDC00-\uDFFF]/u.test(C.charAt(Number(M))))return{...r,error:"text_offset
|
|
85
|
-
cell.id,text:"",text_offset:Number(M),next_text_offset:C.length,blocks:q(Number(M),Math.min(C.length,Number(M)+8e3))}).
|
|
86
|
-
test(C.charAt(j))&&/[\uDC00-\uDFFF]/.test(C.charAt(j+1))?2:1;if(j+h>z)break;const $=JSON.stringify(C.
|
|
87
|
-
|
|
88
|
-
Number(M),Math.max(j,Number(M)+1))}}if(d!=="rows")return{...r,error:"mode must be summary, rows,
|
|
89
|
-
Table geometry changed since the previous window; reread the summary and resume using stable
|
|
90
|
-
y].every(D=>Number.isInteger(D))||Number(u)<0||Number(f)<1||Number(f)>50||Number(b)<0||Number(
|
|
91
|
-
isArray(t.row_ids)||!t.row_ids.length||t.row_ids.length>50||new Set(t.row_ids).size!==t.row_ids.
|
|
92
|
-
A=>A.id===D)),
|
|
93
|
-
...r,error:`column_start is beyond the table's ${i.cols} columns.`};let L=JSON.stringify(
|
|
94
|
-
id,row_index:D,cells:[]},M=JSON.stringify({...A,cells:[]}).length+(r.rows.length?1:
|
|
95
|
-
I?q={id:"",column:I,kind:"covered",anchor_id:C.cell.id}:q=
|
|
96
|
-
1:M)+JSON.stringify(oe).length+(h?JSON.stringify(oe.id).length+(r.complete_cell_ids.
|
|
97
|
-
text:"Content omitted: this cell does not fit in a row window. Page its text
|
|
98
|
-
does not authorize replacement."},j=z(q,!1),L+j+O>Ze)return{...r,error:"This
|
|
99
|
-
|
|
100
|
-
filter($=>!h.has($)),r.next_row=D,r.next_read={table_id:o.id,...t.row_ids==
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
revision}),r.remaining_row_ids=oe,r}A.cells.push(q),L+=j,J&&r.complete_cell_ids.
|
|
105
|
-
{table_id:o.id,row_start:T+1,row_count:Number(f),column_start:Number(b),column_count:Number(
|
|
106
|
-
n);for(const r of t.scopedTableIds){const i=
|
|
107
|
-
const l=Ce(i);let c=!0;for(const d of l.cells){const u=t.cells[bt(r,i.children[d.row].id,
|
|
108
|
-
reduce((d,u)=>d+u.children.length,0)){o.add(i.id);for(const d of i.children)o.add(d.id)}}
|
|
109
|
-
r)&&ke(a)===i.content)for(const c of i.blockIds)o.add(c)}return o}function Ln(e,t,n,o){
|
|
110
|
-
const r=
|
|
111
|
-
r,o);if("error"in b)return!1;l=b.rowIndices,c=b.byId}if(!c&&!a)return!1;const d=o.
|
|
112
|
-
row+b.rowSpan>y):b.col<=Number(d)&&b.col+b.colSpan>Number(d)),f=Ye(e,t,new Set);return u.
|
|
113
|
-
return{cells:{}}}function
|
|
114
|
-
t)}const bt=(e,t,n)=>JSON.stringify([e,t,n]),Lt=(e,t)=>ke([t,e.columnWidths]),
|
|
115
|
-
|
|
116
|
-
e,n);if(!r)return;const i=Ce(r),a=o?new Set(o):null,l=Lt(r,i.cols),c=jt(
|
|
117
|
-
column:d.col,cellId:d.cell.id,rowSpan:d.rowSpan,colSpan:d.colSpan,geometry:l,
|
|
118
|
-
const t=e.children[0];if(t.type!=="paragraph"||!t.children.every(o=>o.type===
|
|
119
|
-
if(!o.text)continue;const i=
|
|
120
|
-
error:`Cell contains nested tables (${t.slice(0,20).join(", ")}). Read them
|
|
121
|
-
tables.`};const n=[],o=[],r=(d,u)=>{n.push(d),o.push(u??"")},i=d=>d.map(u=>u.
|
|
122
|
-
for(const b of d.children){const y=Math.max(0,b.indentLevel??0);f.length=
|
|
123
|
-
checked?"[x] ":"[ ] ":"• ";r(`${" ".repeat(y)}${L}${i(b.children)}`,b.
|
|
124
|
-
for(const f of u.children)a(f);return}r(`[${u.type}${u.id?` ${u.id}`:
|
|
125
|
-
push({id:f,start:c});const y=b?`${
|
|
1
|
+
import{DocumentSession as Ko}from"./DocumentSession-gZHWP7By.js";import{n as fn,A as ae,a as Vo,c as bn}from"./AgentHtmlConverter-B5qstcmM.js";import{c as ke,a as _n,b as qt,d as ht,e as Dt,g as Xo,h as Qo,
|
|
2
|
+
i as Zo,j as yn,k as Pt,l as Ve,m as Yo,n as er,o as tr,p as wn,q as nr,s as or,t as kn,u as rr,v as ir}from"./DocumentMutator-FEFU1YM0.js";import{b as Ce}from"./TableGrid-DbroRucl.js";import{D as Nt,
|
|
3
|
+
i as sr,A as ar}from"./AgentPageRenderViews-BTLjPZJQ.js";import{f as re,h as Ae,i as vn,j as lr}from"./CanvasRenderer-C2vAzLWM.js";import{e as Xe}from"./textExtraction-Bqaqt1Kg.js";import*as Qe from"yjs";
|
|
4
|
+
import{d as cr,y as In,r as xn,c as Sn,e as dr,t as ur,i as mr,j as hr}from"./engine-C5fxuZJo.js";import{b as Rt}from"./base64-Di1bxoXD.js";import{documentHeadingSections as pr}from"./DocumentOutline-BOZoTohH.js";
|
|
5
|
+
import{createStandardLayout as gr}from"./DocumentLayout-CsU5MR-3.js";import{c as fr,h as br}from"./DocumentLayoutEngine-BhcWXkeu.js";import{c as _r}from"./index-Cezk1s_y.js";import"./ParagraphDiffAnalysis-DrmStvmz.js";
|
|
6
|
+
import{c as yr}from"./UnicodeUtils-CXtusU4g.js";import{R as wr}from"./suggestionAuthorship-B-IuLQlE.js";class kr extends Error{constructor(t){super(t.message),this.failure=t,this.name="ReviseToolError",
|
|
7
|
+
this.callId=t.callId,this.tool=t.tool,this.code=t.code}}const vr={count:()=>{},gauge:()=>{},distribution:()=>{}},Mt=/(<img\b[^>]*?\bsrc\s*=\s*)(["'])([\s\S]*?)\2/gi,$n=/(!\[[^\]]*\]\(\s*)(<[^>]+>|[^)\s]+)((?:\s+(?:"[^"]*"|'[^']*'|\([^)]*\)))?\s*\))/g;
|
|
8
|
+
function pt(e){const t=e.trim();return t.startsWith("<")&&t.endsWith(">")?t.slice(1,-1).trim():t}function Ir(e){const t=new Set(["images.revise.io"]);for(const n of e.flatMap(o=>(o??"").split(",")))if(n.
|
|
9
|
+
trim())try{t.add(new URL(n.includes("://")?n.trim():"https://"+n.trim()).host)}catch{}return t}function xr(e,t,n){try{const o=new URL(pt(e),n);return!["http:","https:"].includes(o.protocol)||t.has(o.host)?
|
|
10
|
+
!1:!n||o.origin!==new URL(n).origin}catch{return!1}}function Sr(e,t,n,o=!1){for(const r of e.matchAll(Mt)){const i=pt(r[3]);n(i)&&t.add(i)}if(o)for(const r of e.matchAll($n)){const i=pt(r[2]);n(i)&&t.
|
|
11
|
+
add(i)}}function $r(e){try{const t=new URL(e);if(t.hostname!=="upload.wikimedia.org")return e;const n=t.pathname.split("/");return n.length<8||n[1]!=="wikipedia"||n[2]!=="commons"||n[3]!=="thumb"?e:(t.
|
|
12
|
+
pathname=["","wikipedia","commons",...n.slice(4,-1)].join("/"),t.toString())}catch{return e}}function Cr(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">\
|
|
13
|
+
;")}function Ar(e,t){return e.replace(/<img\b[^>]*>/gi,n=>{const o=Array.from(n.matchAll(Mt))[0];if(!o)return n;const r=o[3].trim(),i=t.get(r);if(!i)return n;let a=n.replace(Mt,(c,d,u)=>`${d}${u}${i.url}${u}`);
|
|
14
|
+
const l=[];return/\bdata-source-url\s*=/i.test(a)||l.push(`data-source-url="${Cr(r)}"`),i.naturalWidth&&i.naturalHeight&&!/\bdata-revise-natural-(?:width|height)\s*=/i.test(a)&&l.push(`data-revise-nat\
|
|
15
|
+
ural-width="${i.naturalWidth}"`,`data-revise-natural-height="${i.naturalHeight}"`),l.length>0&&(a=a.replace(/\s*\/?>$/,c=>` ${l.join(" ")}${c}`)),a})}function Cn(e,t,n=!1){const o=n?e.replace($n,(r,i,a,l)=>{
|
|
16
|
+
const c=t.get(pt(a));return c?i+"<"+c.url+">"+l:r}):e;return Ar(o,t)}const Tr="https://app-api.revise-sdk.invalid";function An(e){return xr(e,Ir([""]),typeof window<"u"?window.location.href:void 0)}function Tn(e){
|
|
17
|
+
return typeof e=="number"&&Number.isInteger(e)&&e>0?e:void 0}async function qr(e){try{const t=await fetch(`${Tr}/uploads/images/rehost`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.
|
|
18
|
+
stringify({url:$r(e)}),signal:AbortSignal.timeout(3e4)});if(!t.ok){let i=`Image copy request failed (HTTP ${t.status}).`;try{const a=await t.json();typeof a.error=="string"&&a.error.trim().length>0&&(i=
|
|
19
|
+
a.error.trim())}catch{}return{ok:!1,failure:{url:e,status:t.status,message:i}}}const n=await t.json();if(typeof n.fileUrl!="string"||!n.fileUrl)return{ok:!1,failure:{url:e,status:t.status,message:"Ima\
|
|
20
|
+
ge copy response did not include a file URL."}};const o=Tn(n.width),r=Tn(n.height);return{ok:!0,image:{url:n.fileUrl,...o&&r?{naturalWidth:o,naturalHeight:r}:{}}}}catch{return{ok:!1,failure:{url:e,message:"\
|
|
21
|
+
Image copy request could not reach Revise storage."}}}}function qn(e){if(e?.name!=="set_header_footer")return null;const t=e.arguments?.image;if(!t||typeof t!="object")return null;const n=t.url;return typeof n==
|
|
22
|
+
"string"&&n.trim().length>0?t:null}const Dn=new Set(["insert_block","replace_block"]);function Dr(e){const t=new Set;for(const n of e??[]){const o=qn(n);if(o&&An(o.url)&&t.add(o.url),!n?.name||!Dn.has(
|
|
23
|
+
n.name))continue;const r=n.arguments?.content;for(const i of Array.isArray(r)?r:[r])typeof i=="string"&&Sr(i,t,An)}return t}async function Pn(e,t=qr){const n={attempted:0,rehosted:0,failedUrls:[],failures:[]};
|
|
24
|
+
if(!Array.isArray(e)||e.length===0)return n;const o=Dr(e);if(o.size===0)return n;const r=new Map,i=[];await Promise.all([...o].map(async l=>{const c=await t(l);c.ok?r.set(l,c.image):i.push(c.failure)}));
|
|
25
|
+
const a=[...o].filter(l=>!r.has(l));if(r.size===0)return{attempted:o.size,rehosted:0,failedUrls:a,failures:i};for(const l of e){const c=qn(l),d=c&&r.get(c.url);if(c&&d&&(c.url=d.url,d.naturalWidth&&d.
|
|
26
|
+
naturalHeight&&(c.naturalWidth=d.naturalWidth,c.naturalHeight=d.naturalHeight)),!l?.name||!Dn.has(l.name))continue;const u=l.arguments;u&&(typeof u.content=="string"?u.content=Cn(u.content,r):Array.isArray(
|
|
27
|
+
u.content)&&(u.content=u.content.map(f=>typeof f=="string"?Cn(f,r):f)))}return{attempted:o.size,rehosted:r.size,failedUrls:a,failures:i}}const Pr=20*1024*1024,Nr=2e4,Rr=5,Mr=1e8;function Br(e){const t=new DataView(
|
|
28
|
+
e.buffer,e.byteOffset,e.byteLength),n=(o,r)=>String.fromCharCode(...e.subarray(o,o+r));if(e.length>=24&&n(1,3)==="PNG")return{mime:"image/png",width:t.getUint32(16),height:t.getUint32(20)};if(e.length>=
|
|
29
|
+
10&&n(0,3)==="GIF")return{mime:"image/gif",width:t.getUint16(6,!0),height:t.getUint16(8,!0)};if(e.length>=30&&n(0,4)==="RIFF"&&n(8,4)==="WEBP"){const o=n(12,4);if(o==="VP8X"){const r=i=>e[i]|e[i+1]<<8|
|
|
30
|
+
e[i+2]<<16;return{mime:"image/webp",width:r(24)+1,height:r(27)+1}}if(o==="VP8 ")return{mime:"image/webp",width:t.getUint16(26,!0)&16383,height:t.getUint16(28,!0)&16383};if(o==="VP8L"&&e[20]===47){const r=t.
|
|
31
|
+
getUint32(21,!0);return{mime:"image/webp",width:(r&16383)+1,height:(r>>14&16383)+1}}return null}if(e.length>=4&&e[0]===255&&e[1]===216){let o=2;for(;o+9<e.length&&e[o]===255;){const r=e[o+1],i=t.getUint16(
|
|
32
|
+
o+2);if(r>=192&&r<=207&&r!==196&&r!==200&&r!==204)return{mime:"image/jpeg",height:t.getUint16(o+5),width:t.getUint16(o+7)};o+=2+i}return{mime:"image/jpeg"}}return null}function Or(e){let t=e.toLowerCase().
|
|
33
|
+
replace(/^\[|\]$/g,"").replace(/%.*$/,"");if(!t.includes(":"))return null;const n=/(\d+)\.(\d+)\.(\d+)\.(\d+)$/.exec(t);if(n){const[u,f,b,y]=n.slice(1).map(Number);t=`${t.slice(0,n.index)}${(u<<8|f).toString(
|
|
34
|
+
16)}:${(b<<8|y).toString(16)}`}const[o,r]=t.split("::"),i=u=>u?u.split(":").map(f=>Number.parseInt(f,16)):[],a=i(o),l=t.includes("::")?i(r):[],c=8-a.length-l.length;if(c<0||!t.includes("::")&&c!==0)return null;
|
|
35
|
+
const d=[...a,...Array(c).fill(0),...l];return d.every(u=>Number.isInteger(u)&&u>=0&&u<=65535)?d:null}function Nn(e,t){return e===0||e===10||e===127||e===100&&t>=64&&t<=127||e===169&&t===254||e===172&&
|
|
36
|
+
t>=16&&t<=31||e===192&&t===168||e===198&&(t===18||t===19)||e>=224}function Rn(e){const t=/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/.exec(e);if(t)return Nn(Number(t[1]),Number(t[2]));const n=Or(e);if(!n)return!0;const o=i=>Nn(
|
|
37
|
+
i>>8,i&255),r=(i,a)=>n.slice(i,a).every(l=>l===0);return r(0,5)&&n[5]===65535?o(n[6]):r(0,6)?!0:n[0]===100&&n[1]===65435&&r(2,6)?o(n[6]):n[0]===8194?o(n[1]):(n[0]&65024)===64512||(n[0]&65472)===65152||
|
|
38
|
+
(n[0]&65280)===65280}class Te extends Error{constructor(t,n){super(t),this.status=n}}async function jr(e,t,n){if(e.protocol!=="http:"&&e.protocol!=="https:")throw new Te(`Only http(s) image URLs can b\
|
|
39
|
+
e fetched, not ${e.protocol}`);const[{isIP:o},r,i]=await Promise.all([import("node:net"),import("node:dns"),e.protocol==="https:"?import("node:https"):import("node:http")]),a=e.hostname.replace(/^\[|\]$/g,
|
|
40
|
+
""),l=()=>new Te(`${a} is a private or local address; images are fetched only from public hosts.`);if(o(a)&&!t.allowPrivateNetwork&&Rn(a))throw l();const c=(d,u,f)=>{r.lookup(d,{...u,all:!0},(b,y)=>{if(b)
|
|
41
|
+
return f(b,"");const R=y;return!t.allowPrivateNetwork&&(R.length===0||R.some(L=>Rn(L.address)))?f(l(),""):u.all?f(null,R):f(null,R[0].address,R[0].family)})};return new Promise((d,u)=>{const f=i.request(
|
|
42
|
+
e,{lookup:c,signal:n,headers:{"user-agent":"revise"}},d);f.on("error",u),f.end()})}async function Er(e,t,n){const o=AbortSignal.timeout(Nr),r=()=>new Te(`The image is larger than ${Math.round(n/1048576)}\
|
|
43
|
+
MB.`),i=[];let a=0;const l=u=>{if(a+=u.length,a>n)throw r();i.push(u)};if(t.fetch){const u=await t.fetch(e,{signal:o});if(!u.ok)throw new Te(`The image URL answered HTTP ${u.status}.`,u.status);if(Number(
|
|
44
|
+
u.headers.get("content-length")??0)>n)throw await u.body?.cancel(),r();if(u.body){const f=u.body.getReader();try{for(;;){const{done:b,value:y}=await f.read();if(b)break;l(y)}}catch(b){throw await f.cancel().
|
|
45
|
+
catch(()=>{}),b}}else l(new Uint8Array(await u.arrayBuffer()))}else{let u=new URL(e);for(let f=0;;f+=1){const b=await jr(u,t,o),y=b.statusCode??0,R=b.headers.location;if(y>=300&&y<400&&R){if(b.resume(),
|
|
46
|
+
f>=Rr)throw new Te("Too many redirects.");u=new URL(R,u);continue}if(y<200||y>=300)throw b.resume(),new Te(`The image URL answered HTTP ${y}.`,y);if(Number(b.headers["content-length"]??0)>n)throw b.destroy(),
|
|
47
|
+
r();try{for await(const L of b)l(L)}catch(L){throw b.destroy(),L}break}}const c=new Uint8Array(a);let d=0;for(const u of i)c.set(u,d),d+=u.length;return c}function gt(e,t,n){const o={url:e,message:t};
|
|
48
|
+
return n!==void 0&&(o.status=n),{ok:!1,failure:o}}function Lr(e={}){const t=e.maxBytes??Pr;return async function(n){let o;try{o=await Er(n,e,t)}catch(i){return gt(n,i instanceof Te?i.message:`Could no\
|
|
49
|
+
t download the image: ${i.message}`,i instanceof Te?i.status:void 0)}const r=Br(o);return r?!r.width||!r.height?gt(n,"The image's pixel size could not be read."):r.width*r.height>Mr?gt(n,"The image's \
|
|
50
|
+
pixel dimensions are implausibly large."):{ok:!0,image:{url:`data:${r.mime};base64,${Buffer.from(o).toString("base64")}`,...r.width?{naturalWidth:r.width}:{},...r.height?{naturalHeight:r.height}:{}}}:
|
|
51
|
+
gt(n,"The URL did not return a PNG, JPEG, GIF, or WebP image (an HTML page or SVG, perhaps). Use a direct link to a raster image.")}}const Bt=new Set(["move_blocks","edit_table_cells","import_attachme\
|
|
52
|
+
nt_into_document","insert_block","insert_footnote","replace_block","set_block_attribute","style_blocks","clear_formatting","append_to_paragraph","break_paragraph","join_paragraphs","replace","replace_\
|
|
53
|
+
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_rows","re\
|
|
54
|
+
move_table_row","insert_table_column","remove_table_column"]),Ur=new Set(["pending","in_progress","completed","blocked","cancelled"]);function Mn(e){return Array.isArray(e.work)&&e.work.length>0}const Bn="\
|
|
55
|
+
create_plan/update_plan have no work field; the calls listed in work were NOT executed. Emit them as ordinary tool calls.";function On(e){if(!Array.isArray(e)||e.some(t=>typeof t!="string"||!t.trim()))
|
|
56
|
+
throw new Error("steps must be an array of non-empty strings.");return e.map(t=>t.trim())}function jn(e,t,n){if(t==="create_plan"){if(typeof n.objective!="string"||!n.objective.trim())throw new Error(
|
|
57
|
+
"objective is required.");const l=On(n.steps);if(!l.length)throw new Error("A plan requires at least one step.");if(e.plan&&n.supersedes_plan_id!==e.plan.id)throw new Error(`To start a new task, expli\
|
|
58
|
+
citly set supersedes_plan_id to ${e.plan.id}. Use update_plan for steering the existing task.`);if(!e.plan&&n.supersedes_plan_id!=null)throw new Error("There is no plan to supersede.");const c=`plan_${e.
|
|
59
|
+
nextPlanNumber}`;return{nextPlanNumber:e.nextPlanNumber+1,plan:{id:c,objective:n.objective.trim(),items:l.map((d,u)=>({id:`${c}_item_${u+1}`,step:d,status:"pending"}))}}}const o=e.plan;if(!o||n.plan_id!==
|
|
60
|
+
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?[]:On(n.add_steps),i=n.updates===void 0?[]:n.updates;if(!Array.isArray(i))throw new Error(
|
|
61
|
+
"updates must be an array.");const a=new Set;for(const l of i){if(!l||typeof l!="object"||!o.items.some(c=>c.id===l.item_id)||!Ur.has(l.status)||Object.keys(l).some(c=>!["item_id","status"].includes(c))||
|
|
62
|
+
a.has(l.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.");a.add(l.item_id)}
|
|
63
|
+
if(!i.length&&!r.length)throw new Error(Mn(n)?`Provide updates or add_steps. ${Bn}`:"Provide updates or add_steps.");return{nextPlanNumber:e.nextPlanNumber,plan:{...o,items:[...o.items.map(l=>({...l,status:i.
|
|
64
|
+
find(c=>c.item_id===l.id)?.status??l.status})),...r.map((l,c)=>({id:`${o.id}_item_${o.items.length+c+1}`,step:l,status:"pending"}))]}}}const En=50,Fr=32*1024;function zr(e,t){const n=[];if(Le(e.cell,c=>n.
|
|
65
|
+
push(c.id)),n.length)return{id:e.cell.id,column:e.col,kind:"rich",truncated:!0,block_ids:e.cell.children.map(c=>c.id),text:`Contains nested tables. Read them with read_table: ${n.slice(0,20).join(", ")}\
|
|
66
|
+
. Read other nested blocks separately. This preview does not authorize replacement.`};const o=Ft(e.cell),r=et(e.cell);let i={id:e.cell.id,column:e.col,kind:r?"empty":o?"text":"rich",row_span:e.rowSpan,
|
|
67
|
+
col_span:e.colSpan,block_ids:ue(e.cell)};const a=(o?.children.find(c=>c.text)??o?.children[0])?.marks,l=a?ft(a):void 0;return i.formatting={cell:ft(e.cell),...o?{paragraph:ft(o),text_marks:l&&Object.keys(
|
|
68
|
+
l).length?l:void 0}:{}},o||r?i.text=zt(e.cell):i.html=t?.(e.cell)??"Rich content; read nested blocks before editing.",JSON.stringify(i).length>2e4&&(i={id:e.cell.id,column:e.col,kind:i.kind,truncated:!0,
|
|
69
|
+
text:"Content omitted: use cell_text with this cell_id, or read a nested block with read_specific_blocks and edit that block ID. This preview does not authorize replacement."}),i}const Jr=/^(oxml|docx)/;
|
|
70
|
+
function ft(e){return Object.fromEntries(Object.entries(e).filter(([t])=>!["type","id","children"].includes(t)&&!Jr.test(t)))}const Wr=new Set(["bold","italic","underline","strikethrough","doubleStrik\
|
|
71
|
+
ethrough","smallCaps","allCaps","hidden","letterSpacing","lang","code","superscript","subscript","fontSize","color","backgroundColor","fontFamily"]),Hr=e=>JSON.stringify(Object.fromEntries(Object.entries(
|
|
72
|
+
e).sort(([t],[n])=>t.localeCompare(n))));function ue(e){if(!e||typeof e!="object")return[];const t=e;return[...t.id?[t.id]:[],...Ot(e).flatMap(ue)]}function Ot(e){const t=e;return[t.children,t.notes,t.
|
|
73
|
+
chrome].flatMap(n=>Array.isArray(n)?n:[])}const Ze=24e3,Gr=2e3;function Kr(e,t,n,o,r){const i=n.map(u=>e.children[u].id),a=i.reduce((u,f)=>f.length>u.length?f:u,""),l=u=>({table_id:e.id,...u,column_start:t.
|
|
74
|
+
cols,column_count:t.cols,continuation_revision:r}),c=l(o===null?{row_ids:i}:{row_start:t.rows,row_count:o}),d=u=>JSON.stringify(u).length-1;return Math.max(d({next_row:t.rows,next_read:c}),d({next_row:t.
|
|
75
|
+
rows,next_column:t.cols,next_read:l({row_ids:[a]}),following_read:c,remaining_row_ids:i}))}function jt(e){return ke([e.columnWidths,e.children.map(t=>[t.id,t.children.map(n=>[n.id,n.rowSpan,n.colSpan])])])}
|
|
76
|
+
function Et(e,t,n){const o=Re(e,String(t.table_id??"")),r={table_id:String(t.table_id??""),row_count:0,column_count:0,revision:"",columns:[],unplaced_cell_ids:[],rows:[],complete_cell_ids:[]};if(!o)return{
|
|
77
|
+
...r,error:"Unknown table_id."};const i=Ce(o);r.row_count=i.rows,r.column_count=i.cols,r.revision=jt(o),r.columns=Array.from({length:i.cols},(D,A)=>({column:A,empty:0,filled:0,covered:0}));for(let D=0;D<
|
|
78
|
+
i.rows;D++)for(let A=0;A<i.cols;A++){const M=i.occupancy[D][A];M&&(M.row!==D||M.col!==A?r.columns[A].covered++:et(M.cell)?r.columns[A].empty++:r.columns[A].filled++)}const a=o.children.flatMap(D=>D.children.
|
|
79
|
+
filter(A=>!i.byId.has(A.id)).map(A=>A.id));r.unplaced_cell_count=a.length;let l=2;for(const D of a){if(r.unplaced_cell_ids.length>=100)break;const A=JSON.stringify(D).length+(r.unplaced_cell_ids.length?
|
|
80
|
+
1:0);l+A>Gr||(r.unplaced_cell_ids.push(D),l+=A)}const c=Number.isInteger(t.column_start)&&Number(t.column_start)>=0?Number(t.column_start):0;r.columns=r.columns.slice(c,c+100),c+100<i.cols&&(r.next_summary=
|
|
81
|
+
{table_id:o.id,mode:"summary",column_start:c+100});const d=t.mode??"rows";if(d==="summary")return r;if(d==="cell_text"){const D=i.byId.get(String(t.cell_id??""));if(!D)return{...r,error:"Unknown cell_\
|
|
82
|
+
id."};const A=ke(D.cell);if(t.continuation_revision!=null&&t.continuation_revision!==A)return{...r,error:"Cell changed since the previous window; restart at text_offset=0."};const M=t.text_offset??0,I=Yr(
|
|
83
|
+
D.cell);if("error"in I)return{...r,error:I.error};const C=I.text,q=(h,$)=>I.segments.filter((we,pe)=>{const lt=I.segments[pe+1]?.start??C.length+1;return we.start<$&<>h}).map(we=>({id:we.id,text_offset:we.
|
|
84
|
+
start}));if(!Number.isInteger(M)||Number(M)<0||Number(M)>C.length)return{...r,error:"Invalid text_offset."};if(Number(M)>0&&/[\uDC00-\uDFFF]/u.test(C.charAt(Number(M))))return{...r,error:"text_offset \
|
|
85
|
+
splits a Unicode character."};const J=Ze-JSON.stringify({...r,revision:A,cell_id:D.cell.id,text:"",text_offset:Number(M),next_text_offset:C.length,blocks:q(Number(M),Math.min(C.length,Number(M)+8e3))}).
|
|
86
|
+
length,z=Math.min(C.length,Number(M)+8e3);let j=Number(M),oe=0;for(;j<z;){const h=/[\uD800-\uDBFF]/.test(C.charAt(j))&&/[\uDC00-\uDFFF]/.test(C.charAt(j+1))?2:1;if(j+h>z)break;const $=JSON.stringify(C.
|
|
87
|
+
slice(j,j+h)).length-2;if(oe+$>J)break;oe+=$,j+=h}return j===Number(M)&&j<C.length?{...r,error:"This cell's text cannot fit beside the table summary within 24,000 characters."}:{...r,revision:A,cell_id:D.
|
|
88
|
+
cell.id,text:C.slice(Number(M),j),text_offset:Number(M),...j<C.length?{next_text_offset:j}:{},blocks:q(Number(M),Math.max(j,Number(M)+1))}}if(d!=="rows")return{...r,error:"mode must be summary, rows, \
|
|
89
|
+
or cell_text."};if(t.continuation_revision!=null&&t.continuation_revision!==r.revision)return{...r,error:"Table geometry changed since the previous window; reread the summary and resume using stable r\
|
|
90
|
+
ow_ids."};const u=t.row_start??0,f=t.row_count??25,b=t.column_start??0,y=t.column_count??i.cols;if(![u,f,b,y].every(D=>Number.isInteger(D))||Number(u)<0||Number(f)<1||Number(f)>50||Number(b)<0||Number(
|
|
91
|
+
y)<1)return{...r,error:"Invalid row or column window (maximum 50 rows)."};let R;if(t.row_ids!=null){if(!Array.isArray(t.row_ids)||!t.row_ids.length||t.row_ids.length>50||new Set(t.row_ids).size!==t.row_ids.
|
|
92
|
+
length)return{...r,error:"row_ids requires 1-50 unique row IDs."};if(R=t.row_ids.map(D=>o.children.findIndex(A=>A.id===D)),R.some(D=>D<0))return{...r,error:"Unknown row_id; nothing read."}}else R=Array.
|
|
93
|
+
from({length:Math.max(0,Math.min(Number(f),i.rows-Number(u)))},(D,A)=>Number(u)+A);if(Number(b)>=i.cols)return{...r,error:`column_start is beyond the table's ${i.cols} columns.`};let L=JSON.stringify(
|
|
94
|
+
r).length;const O=Kr(o,i,R,t.row_ids==null?Number(f):null,r.revision);for(const D of R){const A={row_id:o.children[D].id,row_index:D,cells:[]},M=JSON.stringify({...A,cells:[]}).length+(r.rows.length?1:
|
|
95
|
+
0);for(let I=Number(b);I<Math.min(i.cols,Number(b)+Number(y));I++){const C=i.occupancy[D][I];let q;C?C.row!==D||C.col!==I?q={id:"",column:I,kind:"covered",anchor_id:C.cell.id}:q=zr(C,n):q={id:"",column:I,
|
|
96
|
+
kind:"unplaced"};const J=!!C&&C.row===D&&C.col===I&&!q.truncated&&!!(Ft(C.cell)||et(C.cell)||n),z=(oe,h)=>(A.cells.length?1:M)+JSON.stringify(oe).length+(h?JSON.stringify(oe.id).length+(r.complete_cell_ids.
|
|
97
|
+
length?1:0):0);let j=z(q,J);if(L+j+O>Ze&&!r.rows.length&&!A.cells.length){if(q={id:q.id,column:I,kind:q.kind,truncated:!0,text:"Content omitted: this cell does not fit in a row window. Page its text w\
|
|
98
|
+
ith mode=cell_text and this cell_id, or read a nested block with read_specific_blocks and edit that block ID. This preview does not authorize replacement."},j=z(q,!1),L+j+O>Ze)return{...r,error:"This \
|
|
99
|
+
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."};A.cells.push(
|
|
100
|
+
q),L+=j;continue}if(L+j+O>Ze){if(r.rows.length){const h=new Set(A.cells.map($=>$.id));return r.complete_cell_ids=r.complete_cell_ids.filter($=>!h.has($)),r.next_row=D,r.next_read={table_id:o.id,...t.row_ids==
|
|
101
|
+
null?{row_start:D,row_count:Number(f)}:{row_ids:R.slice(R.indexOf(D)).map($=>o.children[$].id)},column_start:Number(b),column_count:Number(y),continuation_revision:r.revision},r}A.cells.length&&r.rows.
|
|
102
|
+
push(A),r.next_row=D,r.next_column=I,r.next_read={table_id:o.id,row_ids:[o.children[D].id],column_start:I,column_count:Math.min(i.cols,Number(b)+Number(y))-I,continuation_revision:r.revision};const oe=R.
|
|
103
|
+
slice(R.indexOf(D)+1).map(h=>o.children[h].id);return t.row_ids==null&&D+1<i.rows?r.following_read={table_id:o.id,row_start:D+1,row_count:Number(f),column_start:Number(b),column_count:Number(y),continuation_revision:r.
|
|
104
|
+
revision}:oe.length&&(r.following_read={table_id:o.id,row_ids:oe,column_start:Number(b),column_count:Number(y),continuation_revision:r.revision}),r.remaining_row_ids=oe,r}A.cells.push(q),L+=j,J&&r.complete_cell_ids.
|
|
105
|
+
push(C.cell.id)}r.rows.push(A)}const T=R.at(-1);return t.row_ids==null&&T!==void 0&&T+1<i.rows&&(r.next_row=T+1,r.next_read={table_id:o.id,row_start:T+1,row_count:Number(f),column_start:Number(b),column_count:Number(
|
|
106
|
+
y),continuation_revision:r.revision}),r}function Ye(e,t,n){if(!t?.scopedTableIds?.length)return n;const o=new Set(n);for(const r of t.scopedTableIds){const i=Re(e,r);if(!i)continue;for(const d of ue(i))
|
|
107
|
+
o.delete(d);const a=d=>{const u=d,f=u.id===r||Ot(d).map(a).some(Boolean);return f&&u.id&&o.delete(u.id),f};a(e);const l=Ce(i);let c=!0;for(const d of l.cells){const u=t.cells[bt(r,i.children[d.row].id,
|
|
108
|
+
d.col)];if(!u||!Xr(i,l,d,u)){c=!1;continue}for(const f of u.blockIds)o.add(f)}if(c&&l.cells.length===i.children.reduce((d,u)=>d+u.children.length,0)){o.add(i.id);for(const d of i.children)o.add(d.id)}}
|
|
109
|
+
for(const[r,i]of Object.entries(t.blocks??{})){const a=re(e,r),l=Re(e,i.tableId);if(a?.id===r&&l&&ue(l).includes(r)&&ke(a)===i.content)for(const c of i.blockIds)o.add(c)}return o}function Ln(e,t,n,o){
|
|
110
|
+
const r=re(e,o);!r||r.id!==o||(t.blocks??(t.blocks={}),t.blocks[o]={tableId:n,content:ke(r),blockIds:ue(r)})}function Vr(e,t,n,o){const r=Re(e,String(o.tableId??""));if(!r)return!1;const i=jt(r),a=t.geometries?.[r.
|
|
111
|
+
id]===i;if(n==="insert_table_row"||n==="insert_table_column")return a;let l,c=!1;if(n==="remove_table_row"){const b=_n(r,o);if("error"in b)return!1;l=b.rowIndices,c=b.byId}if(!c&&!a)return!1;const d=o.
|
|
112
|
+
columnIndex;if(!l&&(!Number.isInteger(d)||Number(d)<0))return!1;const u=Ce(r).cells.filter(b=>l?l.some(y=>b.row<=y&&b.row+b.rowSpan>y):b.col<=Number(d)&&b.col+b.colSpan>Number(d)),f=Ye(e,t,new Set);return u.
|
|
113
|
+
length>0&&u.every(b=>f.has(b.cell.id)&&(c||!l||t.cells[bt(r.id,r.children[b.row].id,b.col)]?.revision===i))}function Un(){return{cells:{}}}function Re(e,t){const n=re(e,t);return n?.type==="table"&&n.
|
|
114
|
+
id===t?n:null}function Le(e,t){if(!e||typeof e!="object")return;const n=e;n.type==="table"&&t(n);for(const o of Ot(e))Le(o,t)}const bt=(e,t,n)=>JSON.stringify([e,t,n]),Lt=(e,t)=>ke([t,e.columnWidths]),
|
|
115
|
+
Ut=(e,t)=>JSON.stringify(e.children.slice(t.row,t.row+t.rowSpan).map(n=>n.id));function Xr(e,t,n,o){return o.cellId===n.cell.id&&o.rowId===e.children[n.row].id&&o.column===n.col&&o.content===ke(n.cell)&&
|
|
116
|
+
o.coveredRows===Ut(e,n)&&o.geometry===Lt(e,t.cols)&&o.rowSpan===n.rowSpan&&o.colSpan===n.colSpan}function _t(e,t,n,o){const r=Re(e,n);if(!r)return;const i=Ce(r),a=o?new Set(o):null,l=Lt(r,i.cols),c=jt(
|
|
117
|
+
r);for(const d of i.cells){if(a&&!a.has(d.cell.id))continue;const u=r.children[d.row].id;t.cells[bt(n,u,d.col)]={tableId:n,rowId:u,column:d.col,cellId:d.cell.id,rowSpan:d.rowSpan,colSpan:d.colSpan,geometry:l,
|
|
118
|
+
coveredRows:Ut(r,d),content:ke(d.cell),blockIds:ue(d.cell),revision:c}}}function Ft(e){if(e.children.length!==1)return null;const t=e.children[0];if(t.type!=="paragraph"||!t.children.every(o=>o.type===
|
|
119
|
+
"text"))return null;let n;for(const o of t.children){const r=ft(o.marks??{});if(Object.keys(r).some(a=>!Wr.has(a)))return null;if(!o.text)continue;const i=Hr(r);if(n!==void 0&&i!==n)return null;n=i}return t}
|
|
120
|
+
const Qr=Ze,Zr=e=>`[[${e}]] `;function Yr(e){const t=[];for(const d of e.children)Le(d,u=>t.push(u.id));if(t.length)return{error:`Cell contains nested tables (${t.slice(0,20).join(", ")}). Read them w\
|
|
121
|
+
ith 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=[],r=(d,u)=>{n.push(d),o.push(u??"")},i=d=>d.map(u=>u.
|
|
122
|
+
type==="text"?u.text??"":"").join(""),a=d=>{if(d.type==="paragraph"){r(i(d.children),d.id);return}if(d.type==="list"){const f=[];for(const b of d.children){const y=Math.max(0,b.indentLevel??0);f.length=
|
|
123
|
+
y+1;const R=y===0?d.startNumber??1:1;f[y]=f[y]===void 0?R:f[y]+1;const L=d.variant==="ordered"?`${f[y]}. `:d.variant==="todo"?b.checked?"[x] ":"[ ] ":"• ";r(`${" ".repeat(y)}${L}${i(b.children)}`,b.
|
|
124
|
+
id??d.id)}return}const u=d;if(typeof u.content=="string"){r(u.content,u.id);return}if(Array.isArray(u.children)&&u.children.length){for(const f of u.children)a(f);return}r(`[${u.type}${u.id?` ${u.id}`:
|
|
125
|
+
""}]`,u.id)};for(const d of e.children)a(d);const l=[];let c=0;return{text:n.map((d,u)=>{const f=o[u],b=!!f&&l.at(-1)?.id!==f;b&&l.push({id:f,start:c});const y=b?`${Zr(f)}${d}`:d;return c+=y.length+1,
|
|
126
|
+
y}).join(`
|
|
126
127
|
`),segments:l}}function zt(e){return e.children.map(t=>t.type==="paragraph"?t.children.map(n=>n.type==="text"?n.text:"").join(""):"").join(`
|
|
127
128
|
`)}function et(e){return e.children.every(t=>t.type==="paragraph"&&t.children.every(n=>n.type==="text"&&!n.text.replace(/[\s\u200b\u200c\u200d\ufeff]/gu,"")))}const Fn=e=>`<span>${e.replaceAll("&","&a\
|
|
128
129
|
mp;").replaceAll("<","<").replaceAll(">",">").replaceAll(`
|
|
129
130
|
`,"<br>").replaceAll(" ","	")}</span>`;function zn(e,t,n,o={}){const r={actions:[],targets:[],errors:[],skipped:[],unchanged:[]},i=n,a=b=>(r.errors.push({row_id:"",column:-1,reason:b}),r);if(!i||typeof i.
|
|
130
131
|
table_id!="string")return a("table_id is required.");if(i.mode!=="fill_if_empty"&&i.mode!=="replace")return a("mode must be fill_if_empty or replace.");if(!Array.isArray(i.cells)||!i.cells.length||i.cells.
|
|
131
|
-
length>En)return a(`Provide 1-${En} cells.`);if(new TextEncoder().encode(JSON.stringify(i)).length>
|
|
132
|
-
"Unknown table_id; read the current table first.");const c=Ce(l),d=Lt(l,c.cols),u=new Set,f=new Map;for(const b of ue(e))f.set(b,(f.get(b)??0)+1);for(const b of i.cells){const y=b,
|
|
133
|
-
"string"?y.row_id:"",L=typeof y?.column=="number"?y.column:-1,O=q=>({row_id:
|
|
134
|
-
, a zero-based integer column, and exact text."));continue}const T=bt(l.id,
|
|
135
|
-
A=c.occupancy[D]?.[L];if(!A||A.row!==D||A.col!==L){r.errors.push(O("Unknown row/column or covered merge position; target the anchor cell."));continue}const M=t.cells[T];if(!M&&zt(A.cell).length>
|
|
132
|
+
length>En)return a(`Provide 1-${En} cells.`);if(new TextEncoder().encode(JSON.stringify(i)).length>Fr)return a("Cell-edit arguments exceed 32KiB; split the batch.");const l=Re(e,i.table_id);if(!l)return a(
|
|
133
|
+
"Unknown table_id; read the current table first.");const c=Ce(l),d=Lt(l,c.cols),u=new Set,f=new Map;for(const b of ue(e))f.set(b,(f.get(b)??0)+1);for(const b of i.cells){const y=b,R=typeof y?.row_id==
|
|
134
|
+
"string"?y.row_id:"",L=typeof y?.column=="number"?y.column:-1,O=q=>({row_id:R,column:L,reason:q});if(!R||!Number.isInteger(L)||L<0||typeof y?.text!="string"){r.errors.push(O("Each item requires row_id\
|
|
135
|
+
, a zero-based integer column, and exact text."));continue}const T=bt(l.id,R,L);if(u.has(T)){r.errors.push(O("Duplicate target in batch."));continue}u.add(T);const D=l.children.findIndex(q=>q.id===R),
|
|
136
|
+
A=c.occupancy[D]?.[L];if(!A||A.row!==D||A.col!==L){r.errors.push(O("Unknown row/column or covered merge position; target the anchor cell."));continue}const M=t.cells[T];if(!M&&zt(A.cell).length>Qr){r.
|
|
136
137
|
errors.push(O(`Cell ${A.cell.id} is too large for any table read to deliver, so edit_table_cells cannot target it. To change a passage inside it, find the nested block with read_table mode=cell_text, \
|
|
137
138
|
read that block with read_specific_blocks, then edit the block ID with replace.`));continue}if(!M){r.errors.push(O("Cell was not delivered in this request. Read it before editing."));continue}if(ue(A.
|
|
138
|
-
cell).some(q=>f.get(q)!==1)||f.get(
|
|
139
|
+
cell).some(q=>f.get(q)!==1)||f.get(R)!==1){r.errors.push(O("Duplicate document identity makes this target ambiguous; repair the malformed table before editing."));continue}if(M.cellId!==A.cell.id||M.rowSpan!==
|
|
139
140
|
A.rowSpan||M.colSpan!==A.colSpan||M.coveredRows!==Ut(l,A)||M.geometry!==d){r.errors.push(O("Table geometry or anchor identity changed since delivery; reread."));continue}if(o.responseTurn!==void 0&&t.
|
|
140
141
|
responseClaims?.turn===o.responseTurn&&t.responseClaims.cellIds.includes(A.cell.id)){r.errors.push(O("Another call in this response already edited this cell; inspect the result before editing again."));
|
|
141
142
|
continue}if(o.hasForeignSuggestion?.(A.cell)){(i.mode==="fill_if_empty"?r.skipped:r.errors).push(O("Cell has a conflicting pending suggestion from another author; preserved."));continue}if(i.mode==="f\
|
|
142
143
|
ill_if_empty"&&!et(A.cell)){r.skipped.push(O("Cell is non-empty; preserved."));continue}if(M.content!==ke(A.cell)){r.errors.push(O("Cell changed after delivery; reread before replacing."));continue}const I=Ft(
|
|
143
144
|
A.cell);if(!I){r.errors.push(O("Cell contains rich or multi-block content. Use its nested block IDs with the existing rich editing tools."));continue}const C=zt(A.cell);if(C===y.text){r.unchanged.push(
|
|
144
|
-
O("Already equal."));continue}r.actions.push({name:"replace",arguments:{id:I.id,find:C?Fn(C):"",replace:Fn(y.text)}}),r.targets.push({row_id:
|
|
145
|
-
length&&(r.actions=[],r.targets=[]),r}function
|
|
146
|
-
for(const o of t)for(const r of e.matchAll(o)){const i=r[1].trim();i&&n.add(i)}return[...n]}function
|
|
147
|
-
return null;const a=
|
|
148
|
-
const[f]=u;f.start<=r.start&&f.end>=r.end&&c.add(a.slice(f.start,f.end))}return c.size===1?[...c][0]:null}const
|
|
145
|
+
O("Already equal."));continue}r.actions.push({name:"replace",arguments:{id:I.id,find:C?Fn(C):"",replace:Fn(y.text)}}),r.targets.push({row_id:R,column:L,cellId:A.cell.id,paragraphId:I.id})}return r.errors.
|
|
146
|
+
length&&(r.actions=[],r.targets=[]),r}function ei(e){const t=[/"([^"\n]{2,300})"/g,/“([^”\n]{2,300})”/g,/‘([^’\n]{2,300})’/g,/(?<![\p{L}\p{N}])'([^'\n]{2,300})'(?![\p{L}\p{N}])/gu],n=new Set;
|
|
147
|
+
for(const o of t)for(const r of e.matchAll(o)){const i=r[1].trim();i&&n.add(i)}return[...n]}function ti(e,t,n){const o=qt(e,t);if(o.length!==1)return null;const[r]=o,i=fn(t).text.trim();if(i.length<3)
|
|
148
|
+
return null;const a=Xe(e),l=ei(n).filter(d=>{const u=fn(d).text.trim();return u.length>i.length&&(u.startsWith(i)||u.endsWith(i))}),c=new Set;for(const d of l){const u=qt(e,d);if(u.length!==1)continue;
|
|
149
|
+
const[f]=u;f.start<=r.start&&f.end>=r.end&&c.add(a.slice(f.start,f.end))}return c.size===1?[...c][0]:null}const ni="outside_user_selection",oi=new Set(["replace","replace_all","replace_block","remove_\
|
|
149
150
|
block","style_blocks","clear_formatting","edit_table_cells"]);function Jn(e){const t=[],n=(o,r)=>{const i=o,a=typeof i.id=="string"?i.id:null;if(a&&t.push({id:a,ancestors:r}),Array.isArray(i.children))
|
|
150
|
-
for(const l of i.children)n(l,a?[...r,a]:r)};for(const o of e.children)n(o,[]);return t}function
|
|
151
|
+
for(const l of i.children)n(l,a?[...r,a]:r)};for(const o of e.children)n(o,[]);return t}function ri(e,t){const n=Jn(e),o=new Map(n.map((a,l)=>[a.id,l])),r=new Set,i=new Set;for(const a of t){const l=o.
|
|
151
152
|
get(a.startBlock),c=o.get(a.endBlock);if(l===void 0||c===void 0)return null;const[d,u]=l<=c?[l,c]:[c,l];for(let b=d;b<=u;b++)r.add(n[b].id);const f=n[u].id;for(let b=u+1;b<n.length&&n[b].ancestors.includes(
|
|
152
|
-
f);b++)r.add(n[b].id);for(const b of[n[d].id,f])for(const y of n[o.get(b)].ancestors)i.add(y)}return{selected:r,containers:i}}function
|
|
153
|
-
"table"&&i.id===t){n=r;return}i.children?.forEach(o)};return e.children.forEach(o),n}function
|
|
154
|
-
if(t==="edit_table_cells"){const i=typeof n.table_id=="string"?
|
|
153
|
+
f);b++)r.add(n[b].id);for(const b of[n[d].id,f])for(const y of n[o.get(b)].ancestors)i.add(y)}return{selected:r,containers:i}}function ii(e,t){let n=null;const o=r=>{if(n)return;const i=r;if(i.type===
|
|
154
|
+
"table"&&i.id===t){n=r;return}i.children?.forEach(o)};return e.children.forEach(o),n}function si(e,t,n){if(!oi.has(t)||!n)return[];const o=new Set,r=i=>{typeof i=="string"&&i.trim()&&o.add(i.trim())};
|
|
155
|
+
if(t==="edit_table_cells"){const i=typeof n.table_id=="string"?ii(e,n.table_id):null;if(!i||!Array.isArray(n.cells))return[];const a=Ce(i);for(const l of n.cells){const c=l,d=i.children.findIndex(f=>f.
|
|
155
156
|
id===c?.row_id),u=typeof c?.column=="number"?c.column:-1;r(a.occupancy[d]?.[u]?.cell.id)}return[...o]}r(n.id);for(const i of["id","ids","block_ids"])Array.isArray(n[i])&&n[i].forEach(r);if(Array.isArray(
|
|
156
157
|
n.replacements))for(const i of n.replacements)r(i?.id);if(Array.isArray(n.selectors)){for(const i of n.selectors)if(typeof i=="string"){const a=/^#([A-Za-z0-9_-]+)$/.exec(i.trim());a&&r(a[1])}}return[
|
|
157
|
-
...o]}function
|
|
158
|
+
...o]}function ai(e,t,n){if(!n.length||!t.length)return[];const o=ri(e,t);if(!o)return[];const r=Jn(e),i=new Map(r.map(c=>[c.id,c])),a=new Map,l=c=>{const d=c;typeof d.id=="string"&&a.set(d.id,c),d.children?.
|
|
158
159
|
forEach(l)};return e.children.forEach(l),n.filter(c=>{if(!i.get(c)||o.selected.has(c)||o.containers.has(c)||r.some(u=>u.ancestors.includes(c)&&o.selected.has(u.id)))return!1;const d=a.get(c);return(d?.
|
|
159
|
-
structuralSuggestionKind??d?.diffState)!=="insert"})}function
|
|
160
|
+
structuralSuggestionKind??d?.diffState)!=="insert"})}function li(e){const t=e.map(n=>n.selectedText.replace(/\s+/g," ").trim()).join(" … ");return t.length>160?`${t.slice(0,157)}...`:t}const ci="emp\
|
|
160
161
|
ty_mutation_arguments",yt="To change colors, borders, shading, fonts, alignment or other formatting, use style_blocks",Wn="to delete blocks, use remove_blocks",Jt="to add a table column use insert_tab\
|
|
161
|
-
le_column, and to add rows insert_table_row",Hn="to swap or reorder blocks or images, use move_blocks";function
|
|
162
|
-
!0:typeof e=="string"?e.trim().length===0:Array.isArray(e)?e.length===0||e.every(
|
|
163
|
-
pty ${t}, so nothing was changed. ${n}`}function
|
|
162
|
+
le_column, and to add rows insert_table_row",Hn="to swap or reorder blocks or images, use move_blocks";function di(e){return typeof e=="string"?e.trim().length===0:e==null}function Wt(e){return e==null?
|
|
163
|
+
!0:typeof e=="string"?e.trim().length===0:Array.isArray(e)?e.length===0||e.every(di):!1}function Gn(e){return typeof e=="string"&&e.trim().length>0}function ve(e,t,n){return`${e} was called with an em\
|
|
164
|
+
pty ${t}, so nothing was changed. ${n}`}function ui(e,t){const n=t&&typeof t=="object"?t:{};switch(e){case"replace_block":return Wt(n.content)?ve("replace_block","content array",`It never removes or r\
|
|
164
165
|
estyles a block. ${yt}; ${Wn}; ${Jt}; ${Hn}. Otherwise call replace_block again with the complete replacement HTML.`):null;case"insert_block":return Wt(n.content)?ve("insert_block","content array",`Pa\
|
|
165
166
|
ss the HTML of each block to insert. ${yt}; ${Jt}.`):null;case"replace":case"replace_many":{const o=n.replacements;return Array.isArray(o)&&o.length===0?ve(e,"replacements array",`Each replacement nee\
|
|
166
167
|
ds find and replace text. ${yt}; ${Hn}; ${Wn}.`):null}case"edit_table_cells":return Array.isArray(n.cells)&&n.cells.length===0?ve("edit_table_cells","cells array",`List each cell to write as {row_id, \
|
|
@@ -170,330 +171,328 @@ _table_row":case"remove_table_rows":{const o=n.rowIds,r=n.rowIndices,i=o==null||
|
|
|
170
171
|
wIds list","List the row IDs (<tr id> / row_id) of the rows to remove. To clear cell text instead, use edit_table_cells."):null}case"move_blocks":return Array.isArray(n.block_ids)&&n.block_ids.length===
|
|
171
172
|
0?ve("move_blocks","block_ids array","List the source block IDs in current document order, plus reference_id and position."):null;case"style_blocks":return Array.isArray(n.attrs)&&n.attrs.length===0?ve(
|
|
172
173
|
"style_blocks","attrs array",'List each formatting change as {name, value}, e.g. {name: "color", value: "#c00000"}.'):Array.isArray(n.selectors)&&n.selectors.length===0?ve("style_blocks","selectors li\
|
|
173
|
-
st","Name what to style, e.g. #blockId, #tableId td p, or p."):null;default:return null}}const Kn=50,Vn=200,Xn=5e3,
|
|
174
|
-
const
|
|
175
|
-
r+=l,i+=a}return i+n}function
|
|
176
|
-
e>0,kt=e=>typeof e=="string";function
|
|
174
|
+
st","Name what to style, e.g. #blockId, #tableId td p, or p."):null;default:return null}}const Kn=50,Vn=200,Xn=5e3,mi=5e3,hi=8,pi=200,Qn=32*1024;function Zn(){return{version:1,nextTaskNumber:1,task:null}}
|
|
175
|
+
const gi=new TextEncoder;function tt(e){return gi.encode(e).length}function Yn(e,t,n="…"){if(tt(e)<=t)return e;const o=Math.max(0,t-tt(n));let r=0,i="";for(const a of e){const l=tt(a);if(r+l>o)break;
|
|
176
|
+
r+=l,i+=a}return i+n}function fi(e,t){const n=e.replace(/[\u0000-\u001f\u007f]+/gu," ").replace(/\s+/gu," ").trim();return Yn(n,t)}const wt=e=>typeof e=="number"&&Number.isInteger(e)&&e>=0,bi=e=>wt(e)&&
|
|
177
|
+
e>0,kt=e=>typeof e=="string";function _i(e,t,n){const o=tt(t),r=o>Qn;return{requestId:e,text:r?Yn(t,Qn,""):t,originalBytes:o,truncated:r,...typeof n=="number"&&Number.isFinite(n)?{timestamp:n}:{}}}function yi(e){
|
|
177
178
|
for(let t=e.length-1;t>=0;t--){const n=e[t];if(n.role!=="user")continue;const o=It(n);if(o.trim())return`${n.requestId??"?"}|${n.timestamp??""}|${ke(o)}`}}function eo(e,t,n){const o=e??{};if(!(t in o)&&
|
|
178
|
-
Object.keys(o).length>=
|
|
179
|
-
...o,[t]:a?[...r].slice(-a):[]}}const
|
|
180
|
-
Array.isArray(e)?e.length>0:!0}function It(e){return typeof e.content=="string"?e.content:""}function
|
|
181
|
-
length-1;o>=0;o--){const r=e[o];if(r.role==="user"&&It(r).trim())return r}}function
|
|
182
|
-
a)return l;const c=(e.guardedCellIds??e.cellIds)?.[t.id]??[],d=new Set,u=new Set;let f=0;for(const b of c){const y=n.byId.get(b);if(!y||et(y.cell))continue;let
|
|
183
|
-
!
|
|
184
|
-
y)}}function
|
|
179
|
+
Object.keys(o).length>=hi)return o;const r=new Set(o[t]??[]);for(const l of n)r.delete(l),r.add(l);const i=Object.entries(o).filter(([l])=>l!==t).reduce((l,[,c])=>l+c.length,0),a=Math.max(0,mi-i);return{
|
|
180
|
+
...o,[t]:a?[...r].slice(-a):[]}}const wi=["task_kind","scope_row_start","scope_row_count","scope_columns","source_attachment_id"];function vt(e){return e==null?!1:typeof e=="string"?e.trim().length>0:
|
|
181
|
+
Array.isArray(e)?e.length>0:!0}function It(e){return typeof e.content=="string"?e.content:""}function ki(e,t){const n=e.find(o=>o.role==="user"&&o.requestId===t&&It(o).trim());if(n)return n;for(let o=e.
|
|
182
|
+
length-1;o>=0;o--){const r=e[o];if(r.role==="user"&&It(r).trim())return r}}function vi(e,t,n,o,r,i,a){const l={cells:0,rows:[],columns:[]};if(!e||e.requestId!==i||e.userMarker!==void 0&&e.userMarker!==
|
|
183
|
+
a)return l;const c=(e.guardedCellIds??e.cellIds)?.[t.id]??[],d=new Set,u=new Set;let f=0;for(const b of c){const y=n.byId.get(b);if(!y||et(y.cell))continue;let R=!1;for(let L=y.row;L<y.row+y.rowSpan&&
|
|
184
|
+
!R;L++)if(o.has(t.children[L]?.id??""))for(let O=y.col;O<y.col+y.colSpan;O++)r.has(O)&&(R=!0);R||(f++,d.add(y.row),u.add(y.col))}return{cells:f,rows:[...d].sort((b,y)=>b-y),columns:[...u].sort((b,y)=>b-
|
|
185
|
+
y)}}function Ii(e,t,n,o){const r=wi.some(f=>vt(n[f])),i=n.deliberate_blanks,a=vt(i);if(!r&&!a)return{state:e,declared:!1};const l=kt(n.table_id)?n.table_id:"",c=Re(t,l);if(!c)return{error:"Unknown tab\
|
|
185
186
|
le_id; no task scope was recorded."};const d=Ce(c);let u;if(r){const f=n.task_kind;if(f!=="fill"&&f!=="transform")return{error:"Declaring a table task requires task_kind (fill or transform) together w\
|
|
186
|
-
ith scope_row_start, scope_row_count and scope_columns; no scope was recorded."};const b=n.scope_row_start,y=n.scope_row_count,
|
|
187
|
+
ith scope_row_start, scope_row_count and scope_columns; no scope was recorded."};const b=n.scope_row_start,y=n.scope_row_count,R=n.scope_columns;if(!wt(b)||!bi(y)||!Array.isArray(R)||!R.length)return{
|
|
187
188
|
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(b+y>d.rows)return{error:`Task scope rows ${b}-${b+y-1}\
|
|
188
|
-
exceed the table's ${d.rows} rows; no scope was recorded.`};if(y>Xn)return{error:`A table task scope may cover at most ${Xn} rows; declare the scope in parts.`};if(!
|
|
189
|
-
|
|
189
|
+
exceed the table's ${d.rows} rows; no scope was recorded.`};if(y>Xn)return{error:`A table task scope may cover at most ${Xn} rows; declare the scope in parts.`};if(!R.every(wt)||new Set(R).size!==R.length||
|
|
190
|
+
R.some(j=>j>=d.cols))return{error:`scope_columns must be unique 0-based columns below ${d.cols}; no scope was recorded.`};let L;if(vt(n.source_attachment_id)){if(!kt(n.source_attachment_id)||!n.source_attachment_id.
|
|
190
191
|
trim()||tt(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))
|
|
191
192
|
return{error:`Attachment '${n.source_attachment_id}' is not available in this conversation; no scope was recorded.`};L=n.source_attachment_id}const O=c.children.slice(b,b+y).map(j=>j.id),T=e.task,D=T&&
|
|
192
|
-
T.tableId===c.id&&T.kind===f,A=
|
|
193
|
-
let J=q;if(D){const j=new Set(c.children.map(pe=>pe.id)),oe=T.rowIds.filter(pe=>j.has(pe)&&!I.has(pe)),h=T.columns.filter(pe=>!C.has(pe)),$=oe.length>0||h.length>0,we=!$&&O.length===T.rowIds.length&&
|
|
193
|
+
T.tableId===c.id&&T.kind===f,A=ki(o.chatHistory,o.requestId),M=D?T.originRequest:_i(typeof A?.requestId=="number"?A.requestId:o.requestId,A?It(A):"",A?.timestamp),I=new Set(O),C=new Set(R),q=yi(o.chatHistory);
|
|
194
|
+
let J=q;if(D){const j=new Set(c.children.map(pe=>pe.id)),oe=T.rowIds.filter(pe=>j.has(pe)&&!I.has(pe)),h=T.columns.filter(pe=>!C.has(pe)),$=oe.length>0||h.length>0,we=!$&&O.length===T.rowIds.length&&R.
|
|
194
195
|
length===T.columns.length;if($&&T.scopeUserMarker!==void 0&&T.scopeUserMarker===q)return{error:`This declaration would drop ${[oe.length?`${oe.length} rows`:"",h.length?`columns ${h.join(",")}`:""].filter(
|
|
195
196
|
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_\
|
|
196
|
-
start/row_count or row_ids for a smaller read window. The declared scope is unchanged.`};we&&(J=T.scopeUserMarker??q)}else{const j=
|
|
197
|
-
first task declaration omits ${j.cells} cell${j.cells===1?"":"s"} this request already edited in this table (row_index ${
|
|
197
|
+
start/row_count or row_ids for a smaller read window. The declared scope is unchanged.`};we&&(J=T.scopeUserMarker??q)}else{const j=vi(e.localEdits,c,d,I,C,o.requestId,q);if(j.cells)return{error:`This \
|
|
198
|
+
first task declaration omits ${j.cells} cell${j.cells===1?"":"s"} this request already edited in this table (row_index ${Si(j.rows,12)}; columns ${j.columns.join(",")}). The task scope must cover the \
|
|
198
199
|
user's whole request, including work already done: declare the full scope and use row_start/row_count or row_ids for a smaller read window. No scope was recorded.`}}const z=L??(D?T.sourceAttachmentId:
|
|
199
|
-
void 0);u={id:D?T.id:`table_task_${e.nextTaskNumber}`,tableId:c.id,kind:f,rowIds:O,declaredRowStart:b,columns:[...
|
|
200
|
+
void 0);u={id:D?T.id:`table_task_${e.nextTaskNumber}`,tableId:c.id,kind:f,rowIds:O,declaredRowStart:b,columns:[...R].sort((j,oe)=>j-oe),...z?{sourceAttachmentId:z}:{},deliberateBlanks:D?T.deliberateBlanks.
|
|
200
201
|
filter(j=>I.has(j.rowId)&&C.has(j.column)):[],touchedCellIds:D?T.touchedCellIds:[],originRequest:M,...D&&T.latestSteering?{latestSteering:T.latestSteering}:{},declaredRequestId:o.requestId,lastActivityRequestId:o.
|
|
201
202
|
requestId,...J?{scopeUserMarker:J}:{}}}else{const f=e.task;if(!f||f.tableId!==c.id)return{error:"deliberate_blanks require a declared task for this table; include task_kind and scope_* first."};u={...f,
|
|
202
203
|
deliberateBlanks:[...f.deliberateBlanks],lastActivityRequestId:o.requestId}}if(a){if(!Array.isArray(i)||i.length>Kn)return{error:`deliberate_blanks must be an array of at most ${Kn} cells; no scope wa\
|
|
203
|
-
s recorded.`};const f=new Set(u.rowIds),b=new Set(u.columns),y=new Set,
|
|
204
|
+
s recorded.`};const f=new Set(u.rowIds),b=new Set(u.columns),y=new Set,R=[];for(const O of i){const T=O,D=`${String(T?.row_id)}:${String(T?.column)}`;if(!T||!kt(T.row_id)||!wt(T.column)||!kt(T.reason)||
|
|
204
205
|
!T.reason.trim())return{error:`Each deliberate blank needs row_id, column and a non-empty reason (${D}); no scope was recorded.`};if(!f.has(T.row_id)||!b.has(T.column))return{error:`Deliberate blank ${D}\
|
|
205
206
|
is outside the declared task scope; no scope was recorded.`};const A=c.children.findIndex(I=>I.id===T.row_id),M=d.occupancy[A]?.[T.column];if(!M||M.row!==A||M.col!==T.column)return{error:`Deliberate \
|
|
206
|
-
blank ${D} is a covered merge position or unplaced cell; name the anchor cell.`};if(y.has(D))return{error:`Duplicate deliberate blank ${D}; no scope was recorded.`};y.add(D),
|
|
207
|
-
column,reason:
|
|
207
|
+
blank ${D} is a covered merge position or unplaced cell; name the anchor cell.`};if(y.has(D))return{error:`Duplicate deliberate blank ${D}; no scope was recorded.`};y.add(D),R.push({rowId:T.row_id,column:T.
|
|
208
|
+
column,reason:fi(T.reason,pi)})}const L=new Map(u.deliberateBlanks.map(O=>[`${O.rowId}:${O.column}`,O]));for(const O of R)L.set(`${O.rowId}:${O.column}`,O);if(L.size>Vn)return{error:`A task may record\
|
|
208
209
|
at most ${Vn} deliberate blanks; no scope was recorded.`};u.deliberateBlanks=[...L.values()]}return{state:{version:1,nextTaskNumber:u.id!==e.task?.id?e.nextTaskNumber+1:e.nextTaskNumber,task:u,...e.localEdits?
|
|
209
|
-
{localEdits:e.localEdits}:{}},declared:!0}}function
|
|
210
|
+
{localEdits:e.localEdits}:{}},declared:!0}}function xi(e,t){if(!t.cellIds.length)return e;const n=e.localEdits?.requestId===t.requestId?e.localEdits:{requestId:t.requestId,tables:{}},o={...n,tables:{...n.
|
|
210
211
|
tables,[t.tableId]:(n.tables[t.tableId]??0)+t.cellIds.length},cellIds:eo(n.cellIds,t.tableId,t.cellIds),...n.guardedCellIds?{guardedCellIds:eo(n.guardedCellIds,t.tableId,t.cellIds)}:{}},r=e.task;if(!r||
|
|
211
212
|
r.tableId!==t.tableId)return{...e,localEdits:o};const i=[...new Set([...r.touchedCellIds,...t.cellIds])].slice(-5e3);return{...e,localEdits:o,task:{...r,touchedCellIds:i,lastActivityRequestId:t.requestId}}}
|
|
212
|
-
function
|
|
213
|
-
n.length<=t?n.join(","):`${n.slice(0,t).join(",")} +${n.length-t} more ranges`}const to=50
|
|
213
|
+
function Si(e,t){if(!e.length)return"none";const n=[];let o=e[0],r=e[0];for(const i of e.slice(1)){if(i===r+1){r=i;continue}n.push(o===r?`${o}`:`${o}-${r}`),o=r=i}return n.push(o===r?`${o}`:`${o}-${r}`),
|
|
214
|
+
n.length<=t?n.join(","):`${n.slice(0,t).join(",")} +${n.length-t} more ranges`}const to=50,$i="out_of_context_edit";function Ci(e){const{toolCall:t,docBefore:n,isTargetAllowed:o}=e;if(t.name!=="remove\
|
|
214
215
|
_block")return null;const r=t.arguments;if(!r||typeof r!="object")return null;const i=r.through_end;if(i==null||i===!1)return null;if(i!==!0)return{toolCall:t,targetBlockIds:[],error:"remove_blocks th\
|
|
215
216
|
rough_end must be true when provided."};const a=r.id,l=r.count,c=r.ids,d=r.search_result_id;if(typeof a!="string"||a.trim().length===0)return{toolCall:t,targetBlockIds:[],error:"remove_blocks through_\
|
|
216
217
|
end requires a non-empty top-level id."};if(l!=null||c!=null||d!=null)return{toolCall:t,targetBlockIds:[],error:"remove_blocks through_end is mutually exclusive with count, ids, and search_result_id."};
|
|
217
218
|
const u=a.trim(),f=Ae(n,u);if(f<0||n.children[f]?.id!==u)return{toolCall:t,targetBlockIds:[],error:`remove_blocks through_end target '${u}' must be a current top-level block.`};if(!o(u))return{toolCall:t,
|
|
218
|
-
targetBlockIds:[],error:`remove_blocks through_end start '${u}' is outside the request-level document context. Read or search for that boundary block first, then retry.`,errorCode
|
|
219
|
-
slice(f).map(y=>y.id).filter(y=>typeof y=="string"&&y.length>0);return{toolCall:{...t,arguments:{id:u,count:b.length}},targetBlockIds:b}}function
|
|
219
|
+
targetBlockIds:[],error:`remove_blocks through_end start '${u}' is outside the request-level document context. Read or search for that boundary block first, then retry.`,errorCode:$i};const b=n.children.
|
|
220
|
+
slice(f).map(y=>y.id).filter(y=>typeof y=="string"&&y.length>0);return{toolCall:{...t,arguments:{id:u,count:b.length}},targetBlockIds:b}}function Ai(e,t,n){if(e.name!=="remove_block")return{actions:[e]};
|
|
220
221
|
const o=e.arguments;if(!o||typeof o!="object")return{actions:[],error:"remove_blocks requires object arguments"};const r=o.ids;if(r==null)return{actions:[e]};if(typeof o.id=="string")return{actions:[],
|
|
221
222
|
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>to)return{actions:[],
|
|
222
223
|
error:`remove_blocks supports at most ${to} exact IDs per call`};const i=[],a=new Set;for(const c of r){if(typeof c!="string"||c.trim().length===0)return{actions:[],error:"remove_blocks ids must all b\
|
|
223
224
|
e non-empty strings"};const d=c.trim();if(!a.has(d)){if(!re(t,d))return{actions:[],error:`remove_blocks target '${d}' was not found`};if(!n(d))return{actions:[],error:`remove_blocks target '${d}' is o\
|
|
224
225
|
utside the request-level document context. Read or search for that block first, then retry the exact ID batch.`};a.add(d),i.push(d)}}const l=i.filter(c=>ht(t,c)).length;return l>0&&l<i.length?{actions:[],
|
|
225
226
|
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:i.map((c,d)=>({id:`${e.id||"rem\
|
|
226
|
-
ove_block"}-${d+1}`,name:"remove_block",arguments:{id:c,count:1}}))}}const
|
|
227
|
-
e.chrome??[],e.notes??[]])if(o.some(r=>r.id===t))return o;return null}return"children"in n?n.children:null}function
|
|
228
|
-
if(!o||typeof o!="object"||o.end_id==null)return null;const r=t.name==="remove_block"?"remove_blocks":t.name,i=
|
|
229
|
-
end_id must be a block ID.`);if(typeof a!="string"||!a.trim())return i(`${r} end_id requires id, the first block of the range.`);for(const
|
|
230
|
-
o[
|
|
231
|
-
cument.`);const u=c.findIndex(
|
|
227
|
+
ove_block"}-${d+1}`,name:"remove_block",arguments:{id:c,count:1}}))}}const Ti=new Set(["replace_block","remove_block"]);function qi(e,t){const n=vn(e,t);if(!n)return null;if(n===e){for(const o of[e.children,
|
|
228
|
+
e.chrome??[],e.notes??[]])if(o.some(r=>r.id===t))return o;return null}return"children"in n?n.children:null}function Di(e){const{toolCall:t,docBefore:n}=e;if(!Ti.has(t.name))return null;const o=t.arguments;
|
|
229
|
+
if(!o||typeof o!="object"||o.end_id==null)return null;const r=t.name==="remove_block"?"remove_blocks":t.name,i=R=>({toolCall:t,error:R}),{id:a,end_id:l}=o;if(typeof l!="string"||!l.trim())return i(`${r}\
|
|
230
|
+
end_id must be a block ID.`);if(typeof a!="string"||!a.trim())return i(`${r} end_id requires id, the first block of the range.`);for(const R of["ids","search_result_id","through_end"])if(o[R]!=null&&
|
|
231
|
+
o[R]!==!1)return i(`${r} end_id names a range from id; it cannot be combined with ${R}.`);const c=qi(n,a),d=c?.findIndex(R=>R.id===a)??-1;if(!c||d===-1)return i(`${r} id '${a}' was not found in the do\
|
|
232
|
+
cument.`);const u=c.findIndex(R=>R.id===l);if(u===-1)return i(re(n,l)?`${r} end_id '${l}' is not in the same container as id '${a}'. A range covers consecutive sibling blocks: use end_id from the same\
|
|
232
233
|
level (for content inside a table cell or list, target blocks in that cell or list).`:`${r} end_id '${l}' was not found in the document.`);if(u<d)return i(`${r} end_id '${l}' comes before id '${a}'. \
|
|
233
234
|
Use the first block of the range as id and the last as end_id.`);const f=u-d+1;if(o.count!=null&&o.count!==f)return i(`${r} got count ${String(o.count)} but id '${a}' through end_id '${l}' is ${f} blo\
|
|
234
235
|
cks. Pass only id and end_id.`);const{end_id:b,...y}=o;return{toolCall:{...t,arguments:{...y,count:f}}}}function no(e){const t=new URLSearchParams;e.query!==void 0&&t.set("q",e.query),t.set("includeCo\
|
|
235
236
|
ntent","false");for(const n of["page","limit","currentFolderId","parentFolderId","sortBy","order"]){const o=e[n];o!=null&&o!==""&&t.set(n,String(o))}return e.includeFolders&&t.set("includeFolders","1"),
|
|
236
237
|
t}function oo(e,t=10){const n=e,o=Array.isArray(n?.items)?n.items:[],r=i=>typeof i=="number"&&Number.isFinite(i)&&i>=0;return{items:o,totalCount:r(n?.pagination?.totalCount)?n.pagination.totalCount:o.
|
|
237
238
|
length,totalPages:r(n?.pagination?.totalPages)?n.pagination.totalPages:Math.max(1,Math.ceil(o.length/Math.max(1,t))),hasMore:n?.pagination?.hasMore===!0}}function ro(e){return typeof e=="object"&&e!==
|
|
238
|
-
null&&e.type==="doc"&&Array.isArray(e.children)}function
|
|
239
|
-
yjsUpdates:n,source:o}){const r=Array.isArray(n)?n.filter(i=>i.length>0):[];if(typeof t=="string"&&t.length>0||r.length>0)try{if(typeof t=="string"&&t.length>0)return
|
|
240
|
-
Doc;if(r.length>0){for(const a of r)Qe.applyUpdate(i,
|
|
241
|
-
null}const Ri="revise_conversations",
|
|
242
|
-
"IndexedDB not available"));return}const o=indexedDB.open(Ri,e??
|
|
239
|
+
null&&e.type==="doc"&&Array.isArray(e.children)}function Pi(e,t=[]){const n=new Qe.Doc;Qe.applyUpdate(n,Rt(e));for(const o of t)o&&Qe.applyUpdate(n,Rt(o));return In(n)}function Ni({content:e,yjsState:t,
|
|
240
|
+
yjsUpdates:n,source:o}){const r=Array.isArray(n)?n.filter(i=>i.length>0):[];if(typeof t=="string"&&t.length>0||r.length>0)try{if(typeof t=="string"&&t.length>0)return Pi(t,r);const i=ro(e)?cr(e):new Qe.
|
|
241
|
+
Doc;if(r.length>0){for(const a of r)Qe.applyUpdate(i,Rt(a));return In(i)}}catch(i){console.error(`[resolveDocRootFromSerializedState] Failed to decode yjs updates${o?` for ${o}`:""}`,i)}return ro(e)?e:
|
|
242
|
+
null}const Ri="revise_conversations",Mi=2,io="conversations",nt="attachments";let qe=null;function so(){return typeof indexedDB<"u"}function ao(e){return qe||(qe=new Promise((t,n)=>{if(!so()){n(new Error(
|
|
243
|
+
"IndexedDB not available"));return}const o=indexedDB.open(Ri,e??Mi);o.onerror=()=>{qe=null,n(o.error)},o.onblocked=()=>{console.warn("[LocalConversationStorage] Database upgrade blocked - close other \
|
|
243
244
|
tabs")},o.onsuccess=()=>{const r=o.result;if(!r.objectStoreNames.contains(nt)){if(e!==void 0){r.close(),qe=null,n(new Error("Attachments store still missing after version bump"));return}console.warn("\
|
|
244
245
|
[LocalConversationStorage] Attachments store missing, bumping version to create it");const i=r.version+1;r.close(),qe=null,ao(i).then(t).catch(n);return}r.onclose=()=>{qe=null},r.onerror=()=>{qe=null},
|
|
245
246
|
t(r)},o.onupgradeneeded=r=>{const i=r.target.result;if(!i.objectStoreNames.contains(io)){const a=i.createObjectStore(io,{keyPath:"id"});a.createIndex("documentId","documentId",{unique:!1}),a.createIndex(
|
|
246
|
-
"updatedAt","updatedAt",{unique:!1})}i.objectStoreNames.contains(nt)||i.createObjectStore(nt,{keyPath:"id"}).createIndex("conversationId","conversationId",{unique:!1})}}),qe)}async function
|
|
247
|
+
"updatedAt","updatedAt",{unique:!1})}i.objectStoreNames.contains(nt)||i.createObjectStore(nt,{keyPath:"id"}).createIndex("conversationId","conversationId",{unique:!1})}}),qe)}async function Bi(e){if(!so())
|
|
247
248
|
return null;try{const t=await ao();return new Promise((n,o)=>{const r=t.transaction(nt,"readonly").objectStore(nt).get(e);r.onsuccess=()=>{n(r.result??null)},r.onerror=()=>o(r.error)})}catch(t){return console.
|
|
248
|
-
warn("[LocalConversationStorage] Failed to get attachment:",t),null}}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
"
|
|
278
|
-
"
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
const t=e.
|
|
288
|
-
|
|
289
|
-
toLowerCase()
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
{name:"
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
ent.
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
:
|
|
335
|
-
|
|
336
|
-
type:"
|
|
337
|
-
Optional declared task scope: 0-based
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
.
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
description:"
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
type
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
or px (examples: "1in", "3cm", "72px"). Prefer in/cm for page layout values shown in the UI. Do not send bare numbers.',type:"
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
"
|
|
445
|
-
|
|
446
|
-
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,
|
|
447
|
-
required:["style","color","widthPt","spacePt"],type:"object"},
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
"
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
,
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
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\
|
|
496
|
-
<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,
|
|
249
|
+
warn("[LocalConversationStorage] Failed to get attachment:",t),null}}const Oi=new Set([8203,8204,8205,8288,65279]);function ji(){return{wordCount:0,paragraphCount:0,characterCount:0,hasVisibleText:!1,
|
|
250
|
+
inWord:!1}}function lo(e,t){for(let n=0;n<e.length;n+=1){const o=e.codePointAt(n);if(o===void 0||(o>65535&&(n+=1),Oi.has(o)))continue;const r=String.fromCodePoint(o);if(t.characterCount+=r.length,/\s/.
|
|
251
|
+
test(r)){t.inWord=!1;continue}t.hasVisibleText=!0,t.inWord||(t.wordCount+=1,t.inWord=!0)}}function co(e,t){if(!e||typeof e!="object")return;const n=e;if(n.type==="text"&&typeof n.text=="string"){lo(n.
|
|
252
|
+
text,t);return}if(n.type==="paragraph"&&(t.paragraphCount+=1),(n.type==="code"||n.type==="math")&&typeof n.content=="string"){lo(n.content,t),t.inWord=!1;return}if(n.type==="placeholder"||n.type==="im\
|
|
253
|
+
age"||n.type==="page-break"||n.type==="section-break"){t.inWord=!1;return}if(Array.isArray(n.children))for(const o of n.children)co(o,t),o&&typeof o=="object"&&"type"in o&&o.type!=="text"&&(t.inWord=!1)}
|
|
254
|
+
function Ei(e){const t=ji();for(const o of e)co(o,t),t.inWord=!1;const n={parts:[],paragraphCount:0,containsSentinel:!1};for(const o of e)uo(o,n),n.parts.push(" ");return t.wordCount=yr(n.parts.join("")),
|
|
255
|
+
t}const ot="\0";function uo(e,t){if(!e||typeof e!="object")return;const n=e;if(n.type==="text"&&typeof n.text=="string"){n.text.includes(ot)&&(t.containsSentinel=!0),t.parts.push(n.text);return}if(n.type===
|
|
256
|
+
"paragraph"&&(t.paragraphCount+=1),(n.type==="code"||n.type==="math")&&typeof n.content=="string"){n.content.includes(ot)&&(t.containsSentinel=!0),t.parts.push(n.content,ot);return}if(n.type==="placeh\
|
|
257
|
+
older"||n.type==="image"||n.type==="page-break"||n.type==="section-break"){t.parts.push(ot);return}if(Array.isArray(n.children))for(const o of n.children)uo(o,t),o&&typeof o=="object"&&"type"in o&&o.type!==
|
|
258
|
+
"text"&&t.parts.push(ot)}function mo(e){return Ei(e)}function ho(e){const t=xn(e.pageLayout),n=dr(t);return{layout:gr({pageWidth:n.pageWidth,pageHeight:n.pageHeight,pageMargin:t.marginLeftPx,pageMarginTop:t.
|
|
259
|
+
marginTopPx,pageMarginRight:t.marginRightPx,pageMarginBottom:t.marginBottomPx,pageMarginLeft:t.marginLeftPx,availableWidth:Math.max(1,n.pageWidth-t.marginLeftPx-t.marginRightPx),textStartY:t.marginTopPx,
|
|
260
|
+
indentStepPx:t.indentStepPx,blockSpacingPx:t.blockSpacingPx,hyphenationEnabled:t.hyphenationEnabled,lineNumbering:t.lineNumbering,columnCount:t.columnCount,columnGapPx:ur(t.columnGapTwips),pageless:e.
|
|
261
|
+
pageless===!0}),resolved:t}}function po(e){if(typeof document>"u")return null;const t=document.createElement("canvas").getContext("2d");if(!t)return null;const n=_r(t),{layout:o}=ho(e);return fr(e,n,o)}
|
|
262
|
+
function go(e,t){const n=new Map;if(!t||e.pageless===!0)return new Map;const o=(a,l)=>{if(!a||typeof l!="number"||!Number.isFinite(l))return;const c=Math.max(1,Math.floor(l)),d=n.get(a);if(!d){n.set(a,
|
|
263
|
+
{min:c,max:c});return}d.min=Math.min(d.min,c),d.max=Math.max(d.max,c)};for(const a of t.fragments)o(a.blockId,a.pageNumber);for(const a of t.blocks)o(a.blockId,a.pageNumber);const r=xn(e.pageLayout),i=new Map;
|
|
264
|
+
for(const[a,l]of n)i.set(a,{pageStart:Sn(r,l.min-1),pageEnd:Sn(r,l.max-1)});return i}function Li(e,t){let n,o;for(const r of e){const i=t.get(r);i&&(n=n===void 0?i.pageStart:Math.min(n,i.pageStart),o=
|
|
265
|
+
o===void 0?i.pageEnd:Math.max(o,i.pageEnd))}return n!==void 0&&o!==void 0?{pageStart:n,pageEnd:o}:void 0}function fo(e,t,n,o){const r=Math.max(0,Math.min(t,e.children.length-1)),i=Math.max(0,Math.min(
|
|
266
|
+
n,e.children.length-1));if(r>i||e.children.length===0)return null;const a=e.children.slice(r,i+1),l=e.children[r],c=e.children[i];if(!l?.id||!c?.id)return null;const d=mo(a),u=a.map(b=>b.id).filter(Boolean),
|
|
267
|
+
f=Li(u,o);return{startIndex:r,endIndex:i,startBlockId:l.id,endBlockId:c.id,inclusive:!0,blockCount:a.length,wordCount:d.wordCount,paragraphCount:d.paragraphCount,characterCount:d.characterCount,...f?{
|
|
268
|
+
pageStart:f.pageStart,pageEnd:f.pageEnd}:{}}}function Ui(e,t,n){const o=[],r=n?new Set(n):null;for(const i of pr(e,{maxDepth:3})){const a=i.index,l=i.endIndex,c=i.level;if(r&&!r.has(c))continue;const d=fo(
|
|
269
|
+
e,a,l,t);d&&o.push({startIndex:d.startIndex,endIndex:d.endIndex,startBlockId:d.startBlockId,endBlockId:d.endBlockId,headingLevel:c,title:i.title,wordCount:d.wordCount,paragraphCount:d.paragraphCount,characterCount:d.
|
|
270
|
+
characterCount,...d.pageStart!==void 0?{pageStart:d.pageStart,pageEnd:d.pageEnd}:{}})}return o}function bo(e,t){const n=t&&"layout"in t?t.layout??null:e.pageless===!0?null:po(e),o=mo(e.children),r=e.pageless===
|
|
271
|
+
!0?null:n,i=t?.includeSections===!0?go(e,n):new Map;return{inclusive:!0,totalBlocks:e.children.length,wordCount:o.wordCount,paragraphCount:o.paragraphCount,characterCount:o.characterCount,...r?{pageCount:r.
|
|
272
|
+
pageCount}:{},...t?.includeFractionalPageCount===!0&&r?{fractionalPageCount:Fi(e,r)}:{},...t?.includeSections===!0?{sections:Ui(e,i,t.headingLevels).map(a=>({...a,inclusive:!0,blockCount:a.endIndex-a.
|
|
273
|
+
startIndex+1}))}:{}}}function Fi(e,t){const{layout:n}=ho(e);return br(n,t)}function _o(e){return typeof e!="string"?"":e.trim().replace(/^#+/,"")}function zi(e,t,n){const o=po(e),r=go(e,o),i=new Map;for(let c=0;c<
|
|
274
|
+
e.children.length;c+=1){const d=e.children[c]?.id;d&&i.set(d,c)}const a=[],l=[];for(const c of t){const d=_o(c.startBlockId),u=_o(c.endBlockId??d),f=i.get(d),b=i.get(u);if(!d){l.push({error:"start_blo\
|
|
275
|
+
ck_id is required."});continue}if(f===void 0){l.push({startBlockId:d,endBlockId:u,error:`start_block_id "${d}" was not found.`});continue}if(b===void 0){l.push({startBlockId:d,endBlockId:u,error:`end_\
|
|
276
|
+
block_id "${u}" was not found.`});continue}if(b<f){l.push({startBlockId:d,endBlockId:u,error:`end_block_id "${u}" comes before start_block_id "${d}". Ranges must be forward and inclusive.`});continue}
|
|
277
|
+
const y=fo(e,f,b,r);if(!y){l.push({startBlockId:d,endBlockId:u,error:`Could not measure inclusive range "${d}"-"${u}".`});continue}a.push(y)}return{inclusive:!0,totalBlocks:e.children.length,ranges:a,
|
|
278
|
+
errors:l}}const Ji="The agent had trouble completing this request. Please try again.",yo="Document session unavailable after waiting for document load",Wi="document_session_unavailable";class Hi extends Error{constructor(t){
|
|
279
|
+
super("Open the source document linked in the conversation to continue these edits."),this.sourceDocumentId=t,this.name="ForeignDocumentTargetError"}}const Gi="InvalidAssistantResponseError",Ki="Could\
|
|
280
|
+
n't reach the server. Please check your connection and try again.",Vi=["aborted without reason","bodystreambuffer was aborted","client.timeout","connection reset by peer","context canceled","context c\
|
|
281
|
+
ancellation","context cancelled","context deadline exceeded","econnreset","etimedout","failed to fetch","failed to execute 'fetch'","fetch is aborted","gateway timeout","http error! status:","illegal \
|
|
282
|
+
access","illegal invocation","load failed","network request failed","socket hang up","upstream request timeout","while reading body"],Xi=["function call is missing a thought_signature","does not suppo\
|
|
283
|
+
rt the effort parameter","response with id=","gemini api error: 400","xai api error: 404","anthropic api error: 400"],Qi=["server_error","service_unavailable","server_is_overloaded","503 service unava\
|
|
284
|
+
ilable","error in input stream"],Zi=["context_length_exceeded","input token count exceeds","exceeds the context window","maximum number of tokens","maximum context length","prompt is too long","too ma\
|
|
285
|
+
ny input tokens"],Yi=['attachment "',"attachment not found","unable to download the file","failed to fetch attachment","expected a valid url","invalid 'input","image_url"],es=['block id "',"document c\
|
|
286
|
+
hanged while","reference block","not found in document","not found in the document","insert_block"];function ts(e){const t=e.toLowerCase();return t.includes("network")||Vi.some(n=>t.includes(n))}function ns(e){
|
|
287
|
+
if(e?.name==="AbortError"||e instanceof DOMException&&e.code===20)return{isAbort:!0,isRateLimited:!1,isNetworkError:!1,kind:"abort",rawMessage:"",message:"",shouldRetryWithStableModel:!1,shouldTrackConversationError:!1};
|
|
288
|
+
const t=e instanceof Error?e.message:typeof e?.toString=="function"?e.toString():String(e??""),n=t.toLowerCase(),o=t==="RATE_LIMITED"||e?.message==="RATE_LIMITED",r=e instanceof TypeError||ts(t),i=e instanceof
|
|
289
|
+
Error&&e.name===Gi,a=d=>d.some(u=>n.includes(u)),l=e instanceof Hi?"document_target":o?"rate_limited":i?"invalid_assistant_response":t.trim().length===0?"unknown_empty":a(Zi)?"context_limit":a(Yi)?"at\
|
|
290
|
+
tachment":n.includes(yo.toLowerCase())?"document_loading":a(es)?"document_state":a(Xi)?"provider_protocol":a(Qi)?"provider_transient":r?"connection":"unknown";let c;return o?c="Rate limit reached":i?c=
|
|
291
|
+
"The agent sent an invalid response. Please try again.":l==="connection"?c=Ki:l==="provider_protocol"||l==="provider_transient"?c="The model service had trouble completing this request. Please try aga\
|
|
292
|
+
in.":l==="context_limit"?c="This request is too large for the model. Try a smaller request or attach fewer files.":l==="attachment"?c="The agent could not read one of the attached files.":l==="documen\
|
|
293
|
+
t_loading"?c="The document is still loading. Please wait a moment and try again.":l==="document_target"?c=t:l==="document_state"?c="Document state changed during the request.":l==="unknown_empty"?c="T\
|
|
294
|
+
he agent stopped unexpectedly. Your prompt is saved.":c=Ji,{isAbort:!1,isRateLimited:o,isNetworkError:r,kind:l,rawMessage:t,message:c,shouldRetryWithStableModel:l==="provider_protocol"||l==="provider_\
|
|
295
|
+
transient",shouldTrackConversationError:l!=="rate_limited"&&l!=="connection"&&l!=="document_loading"}}const wo=[{name:"get_selection",description:"Read the host user's current semantic editor selectio\
|
|
296
|
+
n. 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 alre\
|
|
297
|
+
ady 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\
|
|
298
|
+
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_doc\
|
|
299
|
+
uments. 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 \
|
|
300
|
+
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 \
|
|
301
|
+
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:"intege\
|
|
302
|
+
r"}},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 eve\
|
|
303
|
+
ry 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 docum\
|
|
304
|
+
ent. 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 with\
|
|
305
|
+
out 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 kno\
|
|
306
|
+
w 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:"\
|
|
307
|
+
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 \
|
|
308
|
+
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 resu\
|
|
309
|
+
lt 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",
|
|
310
|
+
"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 highlig\
|
|
311
|
+
hted 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 blo\
|
|
312
|
+
cks 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:[
|
|
313
|
+
"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.",
|
|
314
|
+
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 do\
|
|
315
|
+
cument_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 \
|
|
316
|
+
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:"\
|
|
317
|
+
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 \
|
|
318
|
+
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\
|
|
319
|
+
_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 cal\
|
|
320
|
+
lers 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\
|
|
321
|
+
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 \
|
|
322
|
+
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_re\
|
|
323
|
+
vision; cell_text includes list markers and explicit non-text placeholders, opens each nested block's text with an inline [[block_id]] marker (metadata, not document text; never include it in find tex\
|
|
324
|
+
t), 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 \
|
|
325
|
+
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 alread\
|
|
326
|
+
y 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 \
|
|
327
|
+
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\
|
|
328
|
+
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 author\
|
|
329
|
+
izes 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\
|
|
330
|
+
/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 windo\
|
|
331
|
+
ws 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,
|
|
332
|
+
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"}},
|
|
333
|
+
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: bound\
|
|
334
|
+
ed 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:"\
|
|
335
|
+
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 \
|
|
336
|
+
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:{
|
|
337
|
+
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:"\
|
|
338
|
+
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 val\
|
|
339
|
+
ues 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: rewri\
|
|
340
|
+
te 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 continu\
|
|
341
|
+
ation.",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 tota\
|
|
342
|
+
l 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 c\
|
|
343
|
+
ounts, 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 inclus\
|
|
344
|
+
ive 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:[
|
|
345
|
+
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:{
|
|
346
|
+
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 wh\
|
|
347
|
+
en 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 bl\
|
|
348
|
+
ock 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 \
|
|
349
|
+
#.",inputSchema:{additionalProperties:!1,properties:{mode:{description:"Range mode. Only inclusive is supported.",enum:["inclusive"],type:"string"},ranges:{description:"Inclusive block ranges to measu\
|
|
350
|
+
re. 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.",
|
|
351
|
+
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:"\
|
|
352
|
+
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\
|
|
353
|
+
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:["\
|
|
354
|
+
block_id"],type:"object"}},{name:"insert_block",description:'Insert native block(s) before/after a reference block using HTML. To add items inside an existing list, reference a list-item ID and pass s\
|
|
355
|
+
eparate <li>...</li> entries in the desired order; this preserves the existing list numbering and style. Referencing the list container inserts a separate sibling block, not items within that list. A \
|
|
356
|
+
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-source\
|
|
357
|
+
d 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\
|
|
358
|
+
, 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\
|
|
359
|
+
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 c\
|
|
360
|
+
opied 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 \
|
|
361
|
+
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\
|
|
362
|
+
: <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 blo\
|
|
363
|
+
ck elements to insert, e.g. <p>, <h1>, <li> (within an existing list), <ul> (a new list), <img>, <toc levels="3"></toc> (live table of contents), <page-break />, <hr /> (horizontal rule), <pre>. An im\
|
|
364
|
+
age 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 filenam\
|
|
365
|
+
e. 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 i\
|
|
366
|
+
ts exact document id (dimensions and alt may be restated); the source is resolved automatically, so never ask the user for it.',items:{type:"string"},minItems:1,type:"array"},position:{description:"In\
|
|
367
|
+
sert 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 \
|
|
368
|
+
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","refer\
|
|
369
|
+
enceId"],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\
|
|
370
|
+
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 bloc\
|
|
371
|
+
k (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 strin\
|
|
372
|
+
g 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, numb\
|
|
373
|
+
ered 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"}},
|
|
374
|
+
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 alone; this removes the entire n\
|
|
375
|
+
ote 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 an end_id \
|
|
376
|
+
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 alone for one block, or id + end_id for a consecutive range, bo\
|
|
377
|
+
th inclusive), 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 start\
|
|
378
|
+
ing 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, \
|
|
379
|
+
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 discov\
|
|
380
|
+
ers candidates but never deletes them implicitly.",inputSchema:{additionalProperties:!1,properties:{end_id:{description:"Last block ID of a consecutive range to remove, inclusive, at the same level as\
|
|
381
|
+
id (same document level, table cell, or list). Omit to remove only id. Every block from id through end_id must have appeared in current request context.",type:"string"},id:{description:"First block I\
|
|
382
|
+
D 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:"\
|
|
383
|
+
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 u\
|
|
384
|
+
npaginated 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 blo\
|
|
385
|
+
ck and the entire document tail after it. Mutually exclusive with end_id, ids, and search_result_id. Omit unless the whole tail is intentionally in scope.",type:"boolean"}},type:"object"}},{name:"appe\
|
|
386
|
+
nd_to_paragraph",description:"Append HTML content to a paragraph.",inputSchema:{additionalProperties:!1,properties:{content:{description:"HTML content to append.",type:"string"},id:{description:"Parag\
|
|
387
|
+
raph 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:{
|
|
388
|
+
additionalProperties:!1,properties:{id:{description:"Paragraph ID.",type:"string"},substring:{description:"Substring where split begins.",type:"string"}},required:["id","substring"],type:"object"}},{name:"\
|
|
389
|
+
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.\
|
|
390
|
+
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 format\
|
|
391
|
+
ting 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:{
|
|
392
|
+
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 \
|
|
393
|
+
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)\
|
|
394
|
+
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, it\
|
|
395
|
+
s 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-preser\
|
|
396
|
+
ving 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 chang\
|
|
397
|
+
e 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 ras\
|
|
398
|
+
ter 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,
|
|
399
|
+
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 \
|
|
400
|
+
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\
|
|
401
|
+
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 \
|
|
402
|
+
restated); the source is resolved automatically, so never ask the user for it.',items:{type:"string"},minItems:1,type:"array"},end_id:{description:"Last block ID of a consecutive range to replace, inc\
|
|
403
|
+
lusive, at the same level as id (same document level, table cell, or list). Omit to replace only id. Every block from id through end_id must have appeared in current request context.",type:"string"},id:{
|
|
404
|
+
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 \
|
|
405
|
+
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:'\
|
|
406
|
+
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 se\
|
|
407
|
+
arch_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 \
|
|
408
|
+
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\
|
|
409
|
+
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\
|
|
410
|
+
, blue, purple, pink, or gray; other names and CSS colors normalize to this palette by hue (a pale lavender such as #E4DFEC becomes purple) and may be the same color. A backgroundColor on a table-cell\
|
|
411
|
+
selector sets the cell fill; on text blocks or inline selectors it highlights text, which is also how to express paragraph shading. Setting a value back to the original reverts your pending formattin\
|
|
412
|
+
g suggestion. 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":"backgrou\
|
|
413
|
+
ndColor","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="*" \
|
|
414
|
+
and fontFamily/fontSize/lineSpacing attrs; bold headings with selectors=["h1","h2","h3"] and fontWeight="bold".',inputSchema:{additionalProperties:!1,properties:{attrs:{description:"Use CSS/Revise nam\
|
|
415
|
+
es. 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, imag\
|
|
416
|
+
e 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,
|
|
417
|
+
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"},
|
|
418
|
+
{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\
|
|
419
|
+
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:{
|
|
420
|
+
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 inli\
|
|
421
|
+
ne 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 \
|
|
422
|
+
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. Ar\
|
|
423
|
+
rays and comma grouping are allowed.',oneOf:[{type:"string"},{items:{type:"string"},minItems:1,type:"array"}]}},required:["selectors","attrs"],type:"object"}},{name:"clear_formatting",description:"Cle\
|
|
424
|
+
ar 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 col\
|
|
425
|
+
or, 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:"\
|
|
426
|
+
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,
|
|
427
|
+
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\
|
|
428
|
+
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; o\
|
|
429
|
+
mit 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,
|
|
430
|
+
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 u\
|
|
431
|
+
se 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\
|
|
432
|
+
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:{
|
|
433
|
+
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\
|
|
434
|
+
", "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 p\
|
|
435
|
+
x (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. Includ\
|
|
436
|
+
e 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 pag\
|
|
437
|
+
e 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:'\
|
|
438
|
+
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:{
|
|
439
|
+
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"},
|
|
440
|
+
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:"\
|
|
441
|
+
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 s\
|
|
442
|
+
uperscript 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"},
|
|
443
|
+
orientation:{description:"Page orientation.",enum:["portrait","landscape"],type:"string"},pageBorders:{additionalProperties:!1,description:"Native page border for the target section(s), rendered in th\
|
|
444
|
+
e 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:{
|
|
445
|
+
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:"strin\
|
|
446
|
+
g"},widthPt:{maximum:12,minimum:.25,type:"number"}},required:["style","color","widthPt","spacePt"],type:"object"},display:{enum:["allPages","firstPage","notFirstPage"],type:"string"},left:{additionalProperties:!1,
|
|
447
|
+
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,
|
|
448
|
+
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\
|
|
449
|
+
}$",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","colo\
|
|
450
|
+
r","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","do\
|
|
451
|
+
uble","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:[
|
|
452
|
+
"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 va\
|
|
453
|
+
lues 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 pag\
|
|
454
|
+
e-number fields, the table of contents, and exports. Use sectionIndex for front matter.",enum:["decimal","lowerRoman","upperRoman"],type:"string"},pageNumberPosition:{description:"Page number position\
|
|
455
|
+
.",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 \
|
|
456
|
+
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:"\
|
|
457
|
+
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 pre\
|
|
458
|
+
set.",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 (ex\
|
|
459
|
+
amples: "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:"\
|
|
460
|
+
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 docu\
|
|
461
|
+
ment 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\
|
|
462
|
+
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\
|
|
463
|
+
/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 num\
|
|
464
|
+
ber 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 header or footer from every page (all slots\
|
|
465
|
+
and every section's override, unless slot or sectionIndex narrows it). Without sectionIndex, zone edits change the document-wide header/footer; a section with its own override keeps it (the result sa\
|
|
466
|
+
ys so). The result lists the headers/footers that exist afterwards, and a call that changes nothing fails with that list. For a plain bottom-right page number, set_page_layout with showPageNumbers als\
|
|
467
|
+
o 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 s\
|
|
468
|
+
ide's header/footer: from every page and section unless slot or sectionIndex narrows it.",type:"boolean"},image:{additionalProperties:!1,description:"Put an image (e.g. a logo) in this header/footer o\
|
|
469
|
+
n every page, replacing any image already in that band. Pass image_id to reuse an image already in the document, or url for a direct image URL. It is drawn in the page margin band, scaled down to fit \
|
|
470
|
+
(never into the body text), next to any zone text. Do not insert copies of the image into the body to fake a header. Applies to every section; do not combine with sectionIndex or clear.",properties:{alt:{
|
|
471
|
+
description:"Short description of the image.",type:"string"},height:{description:"Optional display height in px.",type:"number"},image_id:{description:"ID of an existing image block to reuse.",type:"s\
|
|
472
|
+
tring"},url:{description:"Direct http(s) URL of a raster image (PNG/JPEG/GIF/WebP).",type:"string"},width:{description:"Optional display width in px (height follows the aspect ratio). Omit to use the \
|
|
473
|
+
image's own size.",type:"number"},zone:{description:"Horizontal position in the band. Default left.",enum:["left","center","right"],type:"string"}},type:"object"},left:{description:"Left zone text ({P\
|
|
474
|
+
AGE}/{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 cle\
|
|
475
|
+
ars.",type:"string"},sectionIndex:{description:"One-based section whose own header/footer override to edit or clear. Omit for the document-wide header/footer (and, with clear, every section's override\
|
|
476
|
+
too).",minimum:1,type:"integer"},side:{description:"Which band to edit.",enum:["header","footer"],type:"string"},slot:{description:"Which pages this applies to (Word slot model). Zone edits default t\
|
|
477
|
+
o 'default' (all pages); clear without slot removes every slot.",enum:["default","first","even"],type:"string"}},required:["side"],type:"object"}},{name:"replace",description:"Preferred/default tool f\
|
|
478
|
+
or 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/str\
|
|
479
|
+
ucture 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 o\
|
|
480
|
+
ne 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 saf\
|
|
481
|
+
ely 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, occurren\
|
|
482
|
+
ce 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 whe\
|
|
483
|
+
n 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\
|
|
484
|
+
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 \
|
|
485
|
+
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 eve\
|
|
486
|
+
ry 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:"\
|
|
487
|
+
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:{
|
|
488
|
+
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 fo\
|
|
489
|
+
rmatting 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:{
|
|
490
|
+
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_do\
|
|
491
|
+
cument 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 wi\
|
|
492
|
+
thout 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 S\
|
|
493
|
+
TART 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 str\
|
|
494
|
+
uctural/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 a\
|
|
495
|
+
re 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,
|
|
497
496
|
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 genuin\
|
|
498
497
|
ely 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:"\
|
|
499
498
|
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 o\
|
|
@@ -537,11 +536,11 @@ string"},text:{description:"Exact literal cell text. Not HTML.",type:"string"}},
|
|
|
537
536
|
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 doc\
|
|
538
537
|
ument.",type:"string"}},required:["table_id","mode","cells"],type:"object"}}],os=new Map(wo.map(e=>[e.name,e.inputSchema]));function Ht(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function ko(e,t){
|
|
539
538
|
return Object.prototype.hasOwnProperty.call(e,t)}function rs(e,t){switch(t){case"null":return e===null;case"object":return Ht(e);case"array":return Array.isArray(e);case"string":return typeof e=="stri\
|
|
540
|
-
ng";case"number":return typeof e=="number"&&Number.isFinite(e);case"integer":return typeof e=="number"&&Number.isInteger(e);case"boolean":return typeof e=="boolean";default:return!0}}function
|
|
541
|
-
return!(e.const!==void 0&&!Object.is(e.const,t)||e.enum&&!e.enum.some(n=>Object.is(n,t))||e.type&&!(Array.isArray(e.type)?e.type:[e.type]).some(n=>rs(t,n))||e.allOf?.some(n=>!
|
|
542
|
-
some(n=>
|
|
543
|
-
o,t.items));else if(Ht(n)&&t.properties){const o=new Set(t.required??[]),r={...n};for(const[i,a]of Object.entries(t.properties))if(ko(r,i)){if(r[i]===null&&!o.has(i)&&!
|
|
544
|
-
r[i]=rt(r[i],a)}n=r}for(const o of t.allOf??[])n=rt(n,o);for(const o of[t.anyOf,t.oneOf]){const r=o?.filter(i=>
|
|
539
|
+
ng";case"number":return typeof e=="number"&&Number.isFinite(e);case"integer":return typeof e=="number"&&Number.isInteger(e);case"boolean":return typeof e=="boolean";default:return!0}}function Ue(e,t){
|
|
540
|
+
return!(e.const!==void 0&&!Object.is(e.const,t)||e.enum&&!e.enum.some(n=>Object.is(n,t))||e.type&&!(Array.isArray(e.type)?e.type:[e.type]).some(n=>rs(t,n))||e.allOf?.some(n=>!Ue(n,t))||e.anyOf&&!e.anyOf.
|
|
541
|
+
some(n=>Ue(n,t))||e.oneOf&&e.oneOf.filter(n=>Ue(n,t)).length!==1||e.not&&Ue(e.not,t)||Ht(t)&&e.required&&!e.required.every(n=>ko(t,n)))}function rt(e,t){let n=e;if(Array.isArray(n)&&t.items)n=n.map(o=>rt(
|
|
542
|
+
o,t.items));else if(Ht(n)&&t.properties){const o=new Set(t.required??[]),r={...n};for(const[i,a]of Object.entries(t.properties))if(ko(r,i)){if(r[i]===null&&!o.has(i)&&!Ue(a,null)){delete r[i];continue}
|
|
543
|
+
r[i]=rt(r[i],a)}n=r}for(const o of t.allOf??[])n=rt(n,o);for(const o of[t.anyOf,t.oneOf]){const r=o?.filter(i=>Ue(i,n));r?.length===1&&(n=rt(n,r[0]))}return n}function is(e,t){const n=os.get(e);return n?
|
|
545
544
|
rt(t,n):t}const ss="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 comment\
|
|
546
545
|
s; do not invent facts or ask for clarification or approval.",as=new Set(["read_table","create_plan","update_plan","read_blocks","read_blocks_from_index","read_specific_blocks","search_document","find\
|
|
547
546
|
_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_res\
|
|
@@ -551,28 +550,28 @@ ble_row":t}function cs(e){return Array.from(new Set(e.map(vo).filter(Boolean)))}
|
|
|
551
550
|
e.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."}:Bt.
|
|
552
551
|
has(n)?e.documentAccess==="edit"||e.documentAccess==="comment"&&n==="leave_comment"?null:{code:"agent_document_access_denied",message:"This request does not permit this document mutation. Continue wit\
|
|
553
552
|
hin the granted document access and explain any work that could not be completed."}:as.has(n)?null:{code:"agent_tool_not_allowed",message:"This tool has no execution-policy classification and cannot r\
|
|
554
|
-
un. Continue using permitted tools."}}const Io="no_new_read_context",
|
|
555
|
-
|
|
553
|
+
un. Continue using permitted tools."}}const Io="no_new_read_context",Fe={scanDocumentFontFamily:!1};function ze(e){return e.getAgentAuthorName?.()?.trim()||wr}const xo=2,us=48,ms=.4,Me=10,hs=100,ps=100,
|
|
554
|
+
Je=48e3,Be="out_of_context_edit",De="document_state_changed",So="table_batch_rejected",gs="duplicate_comment_anchor",fs="one_read_search_per_turn",Gt="terminal_tool_requires_turn_two_continuation",$o="\
|
|
556
555
|
terminal_response_status_only",bs="end_agent_run",_s="finish_response",ys="ready_for_verification",ws=new Set(["read_blocks","read_blocks_from_index","read_specific_blocks","search_document","search_d\
|
|
557
556
|
ocuments","find_highlights","render_document_pages"]);function ks(e){return e===bs||e===_s}function Co(e){return e.replace(/<status\b[^>]*>[\s\S]*?<\/status>/gi,"").trim().length===0}const Kt="https:/\
|
|
558
557
|
/app-api.revise-sdk.invalid";function vs(e){if(e&&typeof e=="object"&&!Array.isArray(e))return e;if(typeof e!="string")return null;const t=e.trim();if(!t)return null;if(!t.startsWith("{")||!t.endsWith(
|
|
559
|
-
"}"))return{text:t};try{const n=JSON.parse(t);return n&&typeof n=="object"&&!Array.isArray(n)?n:null}catch{return null}}function Is(e){const t=
|
|
560
|
-
return null;const n=[],o=r=>{if(!(!r||typeof r!="object")&&(r.id!==e.requestedBlockId&&typeof r.id=="string"&&ir(r)&&n.push({blockId:r.id,text:
|
|
558
|
+
"}"))return{text:t};try{const n=JSON.parse(t);return n&&typeof n=="object"&&!Array.isArray(n)?n:null}catch{return null}}function Is(e){const t=Ve(e.doc,e.requestedBlockId);if(!t||!Array.isArray(t.children))
|
|
559
|
+
return null;const n=[],o=r=>{if(!(!r||typeof r!="object")&&(r.id!==e.requestedBlockId&&typeof r.id=="string"&&ir(r)&&n.push({blockId:r.id,text:Xe(r),html:bn(e.anchorText)?kn(r):void 0}),Array.isArray(
|
|
561
560
|
r.children)))for(const i of r.children)o(i)};return o(t),wn(n,e.anchorText)}function xs(e){return!e.loadedBlockIds||e.loadedBlockIds.size===0?null:wn(nr(e.doc).filter(t=>t.blockId!==e.requestedBlockId&&
|
|
562
|
-
or(t,e.loadedBlockIds)).map(t=>({...t,html:bn(e.anchorText)?kn(
|
|
561
|
+
or(t,e.loadedBlockIds)).map(t=>({...t,html:bn(e.anchorText)?kn(Ve(e.doc,t.blockId)):void 0})),e.anchorText)}function Ss(e,t,n,o,r,i,a){if(a.hasBlockId||a.hasAnchor)return v(e,"A reply inherits its thr\
|
|
563
562
|
ead's anchor: pass reply_to_comment_id and comment alone, without id or anchor.");const l=er(o,r);if(!l)return v(e,`Comment '${r}' was not found. Reply only to a <comment-thread> id you can see in loa\
|
|
564
563
|
ded document content.`,De);if(l.resolved===!0)return v(e,`Comment thread '${l.id}' is resolved. Leave a new anchored comment instead of replying to a settled thread.`);const c=n.getDocumentMutator(),d=tr(
|
|
565
|
-
o,c,l.id,i,{author:
|
|
564
|
+
o,c,l.id,i,{author:ze(t),authorType:"ai",agentName:ze(t),...t.getAgentModel?{agentModel:t.getAgentModel()}:{}}).commentId;if(!d)return v(e,`Could not reply to comment thread '${l.id}'.`);const u=$s(o,
|
|
566
565
|
l);return u&&t.toolState.editedBlockIds.add(u),t.turnState.hasMutatedSinceLastRead=!0,t.metrics?.count("agent.comment.reply",1),H(e,`Replied ${d} in comment thread ${l.id}.`,void 0,void 0,JSON.stringify(
|
|
567
566
|
{commentId:d,threadId:l.id,mode:"reply",...u?{blockId:u}:{}}))}function $s(e,t){if(t.anchorBlockId){const n=Ae(e,t.anchorBlockId);return n>=0?e.children[n]?.id??t.anchorBlockId:t.anchorBlockId}for(const n of e.
|
|
568
567
|
children)if(n.id&&rr(n).has(t.id))return n.id;return null}function Cs(e,t,n,o){const r=e.arguments??{};let i=typeof r.id=="string"?r.id.trim():"";const a=typeof r.comment=="string"?r.comment.trim():"";
|
|
569
568
|
let l=vs(r.anchor);const c=typeof r.reply_to_comment_id=="string"?r.reply_to_comment_id.trim():"",d=new Set((Array.isArray(r.acknowledge_existing_thread_ids)?r.acknowledge_existing_thread_ids:[]).filter(
|
|
570
569
|
q=>typeof q=="string").map(q=>q.trim()).filter(Boolean));if(!a)return v(e,"leave_comment requires a non-empty comment.");if(c)return Ss(e,t,n,o,c,a,{hasBlockId:!!i,hasAnchor:!!l});if(!i)return v(e,"le\
|
|
571
|
-
ave_comment requires id.");if(!l)return v(e,"leave_comment requires an anchor.");let u=
|
|
572
|
-
{doc:o,requestedBlockId:i,anchorText:y});q&&(i=q,u=
|
|
573
|
-
e,`Block '${i}' was not found.`,De);const
|
|
574
|
-
. Read that block first, then retry.`,Be);let O=null;if(y){const q=[...t.getConversationHistory?.()??[]].reverse().find(z=>z.role==="user")?.content,J=typeof q=="string"?
|
|
575
|
-
text:J})}const T=n.getDocumentMutator(),D={author:
|
|
570
|
+
ave_comment requires id.");if(!l)return v(e,"leave_comment requires an anchor.");let u=Ve(o,i),f=null;const b=Vt(t.turnState),y=typeof l.text=="string"&&l.text.length>0?l.text:null;if(y&&u){const q=Is(
|
|
571
|
+
{doc:o,requestedBlockId:i,anchorText:y});q&&(i=q,u=Ve(o,i))}if(y&&(!u||qt(u,y).length===0)){const q=xs({doc:o,requestedBlockId:i,anchorText:y,loadedBlockIds:b});q&&q!==i&&(f=i,i=q,u=Ve(o,i))}if(!u)return v(
|
|
572
|
+
e,`Block '${i}' was not found.`,De);const R=Ae(o,i),L=R>=0?o.children[R]?.id:void 0;if(!$t(o,i,b))return v(e,`leave_comment targets block '${i}', which is outside the loaded <document_content> context\
|
|
573
|
+
. Read that block first, then retry.`,Be);let O=null;if(y){const q=[...t.getConversationHistory?.()??[]].reverse().find(z=>z.role==="user")?.content,J=typeof q=="string"?ti(u,y,q):null;J&&(O=y,l={...l,
|
|
574
|
+
text:J})}const T=n.getDocumentMutator(),D={author:ze(t),authorType:"ai",agentName:ze(t),...t.getAgentModel?{agentModel:t.getAgentModel()}:{}},A=Yo(n.getWorkingDocument(),o,T,i,a,l,D,Array.from(d));if(!A.
|
|
576
575
|
success)return A.overlappingThreadIds?.length&&t.metrics?.count("agent.comment.overlap_blocked",1),v(e,A.error??"Could not attach comment.",A.overlappingThreadIds?.length?gs:A.errorCode);const M=A.commentId,
|
|
577
576
|
I=l.whole_block===!0,C=A.range;return d.size&&t.metrics?.count("agent.comment.overlap_acknowledged",1),t.toolState.editedBlockIds.add(L??i),t.turnState.hasMutatedSinceLastRead=!0,H(e,(f?`Left comment ${M}\
|
|
578
577
|
on block ${i}: the anchor text was not in block ${f}, and ${i} is the only loaded block that contains it.`:`Left comment ${M} on block ${i}.`)+(O?` The anchor ${JSON.stringify(O)} covered only part o\
|
|
@@ -585,20 +584,20 @@ ument_state"?De:void 0}function H(e,t,n,o,r){return{toolCall:e,success:!0,agentF
|
|
|
585
584
|
name}function Ds(e){if(!e||typeof e!="object")return null;const t=typeof e.status=="string"?e.status:typeof e.message=="string"?e.message:null;if(!t)return null;const n=t.replace(/[\s\n]+/g," ").trim();
|
|
586
585
|
return n.length>0?n:null}function Ps(e){if(!e||typeof e!="object")return null;const t=typeof e.context_notes=="string"?e.context_notes:null;if(!t)return null;const n=t.trim();return n.length>0?n:null}
|
|
587
586
|
function Ao(e,t){for(const n of e){if(n.type==="image"&&n.id===t)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(
|
|
588
|
-
n.children,t);if(o)return o}}return null}function
|
|
587
|
+
n.children,t);if(o)return o}}return null}function We(e){if(!e||typeof e!="object")return[];const t=e,n=[],o=new Set,r=a=>{if(typeof a!="string")return;const l=a.trim();!l||o.has(l)||(o.add(l),n.push(l))};
|
|
589
588
|
if(r(t.id),r(t.referenceId),r(t.reference_id),r(t.firstId),r(t.secondId),r(t.from_id),r(t.block_id),r(t.tableId),r(t.referenceRowId),r(t.after_block_id),Array.isArray(t.id))for(const a of t.id)r(a);if(Array.
|
|
590
589
|
isArray(t.block_ids))for(const a of t.block_ids)r(a);Array.isArray(t.ids)&&t.ids.forEach(r);const i=Array.isArray(t.selectors)?t.selectors:[t.selectors];for(const a of i)if(typeof a=="string")for(const l of a.
|
|
591
|
-
split(",")){const c=l.trim().match(/^#([A-Za-z0-9_-]+)(?=$|[\s:>~+])/);c&&r(c[1])}if(t.selector&&typeof t.selector=="object"&&
|
|
592
|
-
|
|
590
|
+
split(",")){const c=l.trim().match(/^#([A-Za-z0-9_-]+)(?=$|[\s:>~+])/);c&&r(c[1])}if(t.selector&&typeof t.selector=="object"&&We(t.selector).forEach(r),Array.isArray(t.replacements))for(const a of t.replacements)
|
|
591
|
+
We(a).forEach(r);return n}function To(e){const t=We(e.arguments),n=t.length===0?"the target block":t.length===1?`block ${t[0]}`:`${t.length} blocks`;if(e.name==="set_block_attribute"||e.name==="style_\
|
|
593
592
|
blocks"){const o=e.arguments&&typeof e.arguments=="object"?e.arguments:{},r=typeof o.attribute=="string"&&o.attribute.trim().length>0?o.attribute.trim():"attribute";return(typeof o.operation=="string"&&
|
|
594
593
|
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 e.
|
|
595
594
|
name==="clear_formatting"?`No document mutation occurred; formatting was already clear on ${n}.`:e.name==="replace_block"?`No document mutation occurred; replacing ${n} produced no document change. Th\
|
|
596
595
|
is result does not prove that the requested content is present; verify the current block before deciding no change is needed.`:e.name==="replace"||e.name==="replace_all"||e.name==="replace_many"?`No d\
|
|
597
596
|
ocument 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 \
|
|
598
|
-
needed.`:"No document mutation occurred; the document already matched the requested update."}function
|
|
597
|
+
needed.`:"No document mutation occurred; the document already matched the requested update."}function Ns(e){const t=qs(e);return{id:e.id,name:t,arguments:is(t,e.arguments)}}function Rs(e){return e.replace(
|
|
599
598
|
/<[^>]*>/g," ").replace(/ /gi," ").replace(/&/gi,"&").replace(/</gi,"<").replace(/>/gi,">").replace(/"/gi,'"').replace(/'|'/gi,"'").replace(/\s+/g," ").trim()}function qo(e){
|
|
600
599
|
return e.replace(/\s+/g," ").trim()}function Vt(e){const t=new Set;for(const n of[e.lastReadBlockIds,e.requestedBlockIds])if(n)for(const o of n)t.add(o);for(const n of e.docContextLedger?.delivered.keys()??
|
|
601
|
-
[])t.add(n);return t.size>0?t:null}function Ms(e){const t=[],n=new Set;for(const o of e)for(const r of
|
|
600
|
+
[])t.add(n);return t.size>0?t:null}function Ms(e){const t=[],n=new Set;for(const o of e)for(const r of We(o.arguments))n.has(r)||(n.add(r),t.push(r));return t}function Do(e,t){const n=new Set(t),o=new Set(
|
|
602
601
|
t),r=i=>{const a="id"in i?i.id:void 0;let l=!!(a&&n.has(a));if("children"in i)for(const c of i.children)r(c)&&(l=!0);return l&&a&&o.add(a),l};for(const i of[...e.children,...e.chrome??[],...e.notes??[]])
|
|
603
602
|
r(i);return o}function Bs(e,t){if(e.length===1)return`block ${e[0]}`;if(e.length>1){const n=e.slice(0,4).join(", "),o=e.length>4?` (+${e.length-4} more)`:"";return`blocks ${n}${o}`}return t?`block ${t}`:
|
|
604
603
|
"the target block"}function Os(e){if(e.length===0)return"";const t=Array.from(new Set(e.map(r=>`${r.fromBlockId}->${r.toBlockId}`))).map(r=>{const[i,a]=r.split("->");return`${i} -> ${a}`}),n=t.slice(0,
|
|
@@ -612,40 +611,40 @@ test(e.name)){if(e.name.endsWith("_row")){const j=typeof q.referenceRowId=="stri
|
|
|
612
611
|
renderTableRow(C,j,t)}]:[]}const J=Ce(C),z=Number(q.columnIndex??q.referenceIndex);return J.cells.filter(j=>j.col<=z&&j.col+j.colSpan>z).map(({cell:j})=>({id:j.id,html:ae.renderSubtree(j,t)}))}if(C.type===
|
|
613
612
|
"table"&&C.id!==I){const J=C.children.find(z=>z.id===I);if(J)return[{id:I,html:ae.renderTableRow(C,J,t)}]}return[{id:I,html:ae.renderSubtree(C,t)}]}):[],u=[],f=[];let b=0;for(const I of d)b+I.html.length+
|
|
614
613
|
1>8e3?f.push(I.id):(u.push(I.html),b+=I.html.length+1);const y=u.join(`
|
|
615
|
-
`),
|
|
614
|
+
`),R=a.filter(I=>re(t,I)&&!re(n,I)),L=i?.changedBlockIds??a.filter(I=>{const C=re(t,I),q=re(n,I);return JSON.stringify(C??null)!==JSON.stringify(q??null)}),O=new Set,T=I=>{for(const C of I)"id"in C&&C.
|
|
616
615
|
id&&O.add(C.id),"children"in C&&T(C.children)};T(_e(t));const D=[],A=I=>{for(const C of I)"id"in C&&C.id&&!O.has(C.id)?D.push(C.id):"children"in C&&A(C.children)};A(_e(n));const M=(I,C,q=!1)=>c||q&&C.
|
|
617
616
|
length>Me?{[`${I}_sample`]:C.slice(0,Me),[`${I}_omitted_count`]:Math.max(0,C.length-Me)}:{[I]:C};return JSON.stringify({tool:e.name,...l?{target_reference:l}:{},...r?{summary:r}:{},...i?{style_outcome:i.
|
|
618
617
|
outcome,attribute_effects:i.attributes.map(I=>({name:I.name,applied_target_count:I.appliedBlockIds.length,skipped_target_count:new Set(I.skipped.map(C=>C.blockId)).size,...M("applied_block_ids",I.appliedBlockIds,
|
|
619
618
|
!0),skipped:I.skipped.slice(0,Me),skipped_omitted_count:Math.max(0,I.skipped.length-Me)}))}:{},effect:{...i?M("affected_block_ids",i.affectedBlockIds,!0):{},requested_target_count:a.length,changed_target_count:L.
|
|
620
|
-
length,removed_target_count:
|
|
619
|
+
length,removed_target_count:R.length,inserted_block_count:D.length,...M("target_block_ids",a),...M("changed_block_ids",L),...M("removed_block_ids",R),...M("inserted_block_ids",D),top_level_blocks_before:_e(
|
|
621
620
|
t).length,top_level_blocks_after:_e(n).length},...!c&&(y.trim()||f.length)?{before_block:y,...f.length?{before_block_truncated:!0,before_block_omitted_ids:f.slice(0,20),before_block_omitted_count:f.length,
|
|
622
621
|
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 \
|
|
623
622
|
requires historical edit evidence; never reconstruct it from this partial snapshot."}:{}}:{}})}function _e(e){return[...e.children,...e.notes??[]]}function Xt(e,t){return ae.extractSpecificBlocks(e,[t],
|
|
624
|
-
void 0,
|
|
623
|
+
void 0,Fe).foundBlocks[0]?.blockIndex??-1}function Es(e){return`(${e} ${e===1?"block":"blocks"} omitted...)`}function Qt(e,t){const n=_e(e)[t];return n?.id?ae.extractSpecificBlocks(e,[n.id],void 0,Fe).
|
|
625
624
|
foundBlocks[0]??null:null}function xt(e){if(e.length===0)return 0;let t=`Showing ${e.length} block(s):
|
|
626
625
|
|
|
627
|
-
`.length+e[0].html.length;for(let n=1;n<e.length;n+=1){const o=e[n-1],r=e[n],i=r.blockIndex-o.blockIndex-1;i>0&&(t+=1+Es(i).length),t+=1+r.html.length}return t}function
|
|
626
|
+
`.length+e[0].html.length;for(let n=1;n<e.length;n+=1){const o=e[n-1],r=e[n],i=r.blockIndex-o.blockIndex-1;i>0&&(t+=1+Es(i).length),t+=1+r.html.length}return t}function No(e){const{doc:t,startIndex:n,
|
|
628
627
|
maxTokens:o}=e,r=[];let i=0,a=n-1,l=!1;for(let c=n;c<_e(t).length;c+=1){const d=Qt(t,c);if(!d)continue;const u=xt([...r,d]),f=u>o;if(f&&r.length>0){l=!0;break}if(r.push(d),i=u,a=d.blockIndex,f){l=!0;break}}
|
|
629
628
|
return{blockIds:r.map(c=>c.id),endIndex:a,estimatedTokens:i,reachedTokenBudget:l}}function Ls(e){const{doc:t,requestedBlockIds:n,maxTokens:o}=e,r=[],i=new Set,a=new Map,l=(b,y)=>(a.has(b)||a.set(b,Qt(
|
|
630
|
-
t,y)),a.get(b)??null),c=[];let d=0,u=!1,f=0;for(const b of n){const y=Xs(t,b);if(!y){f+=1;continue}if(i.has(y.topLevelBlockId))continue;const
|
|
631
|
-
const L=xt([...c,
|
|
632
|
-
function
|
|
633
|
-
d=[],u=0;const f=b=>{c.length!==0&&(l.push({results:c,startResultIndex:u,endResultIndexExclusive:b,estimatedTokens:xt(d)}),c=[],d=[])};for(let b=0;b<n.length;b+=1){const y=n[b],
|
|
634
|
-
length===0&&(u=b);const L=xt([...d,
|
|
629
|
+
t,y)),a.get(b)??null),c=[];let d=0,u=!1,f=0;for(const b of n){const y=Xs(t,b);if(!y){f+=1;continue}if(i.has(y.topLevelBlockId))continue;const R=l(y.topLevelBlockId,y.topLevelIndex);if(!R){f+=1;continue}
|
|
630
|
+
const L=xt([...c,R]),O=L>o;if(O&&r.length>0){u=!0;break}if(r.push(y.topLevelBlockId),i.add(y.topLevelBlockId),c.push(R),d=L,O){u=!0;break}}return{blockIds:r,estimatedTokens:d,reachedTokenBudget:u,missingRequestedBlocks:f}}
|
|
631
|
+
function Ro(e){const{doc:t,results:n,pageSize:o,maxTokens:r}=e;if(n.length===0)return[];const i=new Map,a=b=>(i.has(b.blockId)||i.set(b.blockId,Qt(t,b.blockIndex)),i.get(b.blockId)??null),l=[];let c=[],
|
|
632
|
+
d=[],u=0;const f=b=>{c.length!==0&&(l.push({results:c,startResultIndex:u,endResultIndexExclusive:b,estimatedTokens:xt(d)}),c=[],d=[])};for(let b=0;b<n.length;b+=1){const y=n[b],R=a(y);if(!R)continue;c.
|
|
633
|
+
length===0&&(u=b);const L=xt([...d,R]),O=c.length>=o,T=L>r;c.length>0&&(O||T)&&(f(b),u=b),c=[...c,y],d=[...d,R]}return f(n.length),l}function Mo(e){if(e.length===0)return[];const t=[...e].sort((i,a)=>i-
|
|
635
634
|
a),n=[];let o=t[0],r=t[0];for(let i=1;i<t.length;i+=1){const a=t[i];if(a<=r+1){r=a;continue}n.push({start:o,end:r}),o=a,r=a}return n.push({start:o,end:r}),n}function Zt(e,t){const n=new Set;for(const o of t){
|
|
636
635
|
const r=Xt(e,o);r!==-1&&n.add(r)}return Array.from(n).sort((o,r)=>o-r)}function st(e,t){const n=Ye(t,e.toolState.tableContext,e.turnState.requestedBlockIds??new Set),o=Zt(t,n),r=Mo(o),i=o.length,a=!e.
|
|
637
636
|
toolState.tableContext?.scopedTableIds?.some(l=>!n.has(l))&&(e.toolState.everReadFullDocument||_e(t).length>0&&i>=_e(t).length);return{requestedBlockCount:i,readBlocksThisTurn:e.turnState.readBudgetBlockIds?.
|
|
638
|
-
size??0,readTokenBudgetMax:
|
|
637
|
+
size??0,readTokenBudgetMax:Je,requestedRanges:r,fullDocumentLoaded:a}}function at(e){return JSON.stringify({kind:"read_context",tool:e.tool,loaded:e.loaded,next:e.next??null,endOfDocument:e.endOfDocument,
|
|
639
638
|
coverage:e.coverage})}function Bo(e){return JSON.stringify({kind:"search_context",tool:e.tool,...e.queries?{queries:e.queries}:{},...e.color?{color:e.color}:{},totalMatches:e.totalMatches,...e.searchResultId?
|
|
640
639
|
{search_result_id:e.searchResultId}:{},page:{current:e.currentPage,total:e.totalPages,startResult:e.pageStart+1,endResult:e.pageEnd},nextPage:e.nextPage,matches:e.pageResults.map(t=>({blockId:t.blockId,
|
|
641
640
|
blockIndex:t.blockIndex,...t.matchedQueries?{matchedQueries:t.matchedQueries}:{},...t.matchedColors?{matchedColors:t.matchedColors}:{}})),coverage:e.coverage})}function Us(e){return e==="account"||e===
|
|
642
|
-
"folder"?e:"current_folder"}function
|
|
641
|
+
"folder"?e:"current_folder"}function He(e){return e.getAuthToken?.().trim()??""}function Oo(e){return typeof e.document_id=="string"?e.document_id.trim():""}function jo(e){return e.replaceAll("-","").
|
|
643
642
|
toLowerCase()}function Ie(e,t){const n=Oo(e);if(!n)return"";const o=t.getCurrentDocumentId?.().trim()??"";return o&&jo(n)===jo(o)?"":n}async function Fs(e){const t=e.scope==="folder"?e.folderId:e.currentFolderId,
|
|
644
643
|
n=no({query:e.query,page:e.page+1,limit:10,currentFolderId:e.scope==="account"?void 0:t}),o=await fetch(`${Kt}/documents/search?${n.toString()}`,{headers:{Authorization:`Bearer ${e.token}`}});if(!o.ok)
|
|
645
644
|
throw new Error(`Document search failed with ${o.status}`);return oo(await o.json(),10)}async function zs(e){const t=no({includeFolders:!0,page:e.page+1,limit:e.limit,parentFolderId:e.parentFolderId}),
|
|
646
645
|
n=await fetch(`${Kt}/documents?${t.toString()}`,{headers:{Authorization:`Bearer ${e.token}`}});if(!n.ok)throw new Error(`Document listing failed with ${n.status}`);return oo(await n.json(),e.limit)}async function St(e){
|
|
647
646
|
const t=await fetch(`${Kt}/documents/${encodeURIComponent(e.documentId)}?includeTailUpdates=1&trackAccess=0`,{headers:{Authorization:`Bearer ${e.token}`}});if(!t.ok)throw new Error(`Document open fail\
|
|
648
|
-
ed with ${t.status}`);const n=await t.json(),o=
|
|
647
|
+
ed with ${t.status}`);const n=await t.json(),o=Ni({content:n.content,yjsState:n.yjsState,yjsUpdates:n.yjsUpdates,source:`agent read document ${e.documentId}`})??{type:"doc",children:[]};return o.title=
|
|
649
648
|
n.title||o.title||"Untitled",{id:n.id||e.documentId,title:n.title||"Untitled",canonicalPath:n.canonicalPath,parentFolderId:n.parentFolderId??null,content:o}}function Js(e){return JSON.stringify({kind:"\
|
|
650
649
|
account_document_search",query:e.query,scope:e.scope,searchedCurrentFolder:e.searchedCurrentFolder,folderId:e.folderId??null,page:{current:e.page,total:e.totalPages},totalMatches:e.totalCount,results:e.
|
|
651
650
|
results.map(t=>({itemType:t.itemType==="folder"?"folder":"document",...t.itemType==="folder"?{folderId:t.id}:{documentId:t.id},title:t.title,canonicalPath:t.canonicalPath||`/${t.title||t.id}`,snippet:t.
|
|
@@ -661,32 +660,32 @@ queries:o})}const n=typeof t.color=="string"&&t.color.trim().length>0?t.color.tr
|
|
|
661
660
|
matchedColors??[])t.set(o,(t.get(o)??0)+1);return t.size===0?"":Array.from(t.entries()).sort((n,o)=>o[1]-n[1]||n[0].localeCompare(o[0])).map(([n,o])=>`${o} ${n}`).join(", ")}function Gs(e,t){let n=0;for(;n<
|
|
662
661
|
e.length&&n<t.length&&e[n]===t[n];)n+=1;let o=e.length-1,r=t.length-1;for(;o>=n&&r>=n&&e[o]===t[r];)o-=1,r-=1;const i=Math.max(0,o-n+1),a=Math.max(0,r-n+1);return Math.max(i,a)}function Ks(e,t){if(e.name!==
|
|
663
662
|
"replace_block"||!e.arguments||typeof e.arguments!="object")return null;const n=e.arguments.id,o=e.arguments.content,r=e.arguments.count;if(typeof n!="string"||typeof r=="number"&&Number.isFinite(r)&&
|
|
664
|
-
Math.floor(r)>1||!Array.isArray(o)||o.length!==1||typeof o[0]!="string")return null;const i=t.children.find(f=>f.id===n);if(!i)return null;const a=qo(
|
|
663
|
+
Math.floor(r)>1||!Array.isArray(o)||o.length!==1||typeof o[0]!="string")return null;const i=t.children.find(f=>f.id===n);if(!i)return null;const a=qo(Xe(i)),l=qo(Rs(o[0]));if(!a||!l||a===l)return null;
|
|
665
664
|
const c=Gs(a,l),d=Math.max(a.length,l.length);if(d<=0)return null;const u=c/d;return c>us||u>ms?null:`WARNING: replace_block only changed a small span (~${c} chars, ${(u*100).toFixed(0)}% of block). P\
|
|
666
665
|
refer replace for typo, punctuation, and wording edits; reserve replace_block for full rewrites.`}function $t(e,t,n){if(!n||n.size===0)return!1;if(n.has(t))return!0;const o=ht(e,t);if(o&&n.has(o))return!0;
|
|
667
666
|
const r=Ae(e,t),i=r>=0?e.children[r]?.id:void 0;return typeof i=="string"&&n.has(i)}function Vs(e,t,n){if(e.name!=="replace_block"&&e.name!=="remove_block")return{toolCall:e};if(!e.arguments||typeof e.
|
|
668
667
|
arguments!="object")return{toolCall:e};const o=e.arguments.id;if(typeof o!="string"||o.trim().length===0)return{toolCall:e};const r=e.arguments.count;if(r!==void 0&&(typeof r!="number"||!Number.isFinite(
|
|
669
668
|
r)||Math.floor(r)<1))return{toolCall:e};const i=r===void 0?1:Math.floor(r);if(i<=1)return{toolCall:e};const a=vn(t,o),l=a&&"children"in a?lr(a,o):-1;if(!a||l===-1)return{toolCall:e};const c=e.name==="\
|
|
670
669
|
remove_block"?"remove_blocks":e.name,d=a.children[Math.min(l+i,a.children.length)-1]?.id??o;if(!n||n.size===0)return{toolCall:e,error:`${c} range '${o}' through '${d}' needs those blocks in request-le\
|
|
671
|
-
vel document context. Read the complete range first, then retry with the same range.`};const u=new Set(Array.from(n).map(y=>Ae(t,y)).filter(y=>y!==-1));let f=0;for(let y=l;y<a.children.length;y++){const
|
|
672
|
-
children[y]?.id;if(typeof
|
|
670
|
+
vel document context. Read the complete range first, then retry with the same range.`};const u=new Set(Array.from(n).map(y=>Ae(t,y)).filter(y=>y!==-1));let f=0;for(let y=l;y<a.children.length;y++){const R=a.
|
|
671
|
+
children[y]?.id;if(typeof R!="string"||R.length===0)break;const L=Ae(t,R);if(L===-1||!u.has(L))break;f+=1}if(f<=0)return{toolCall:e,error:`${e.name} targets block '${o}', which is outside the loaded <\
|
|
673
672
|
document_content> context. Read that block first, then retry.`};if(f>=i)return{toolCall:e};const b=a.children[l+f]?.id??d;return{toolCall:e,error:`${c} range '${o}' through '${d}' includes block '${b}\
|
|
674
673
|
', which was not read in this request. Read ${b===d?`'${d}'`:`'${b}' through '${d}'`}, then retry with the same range; no partial mutation was applied.`}}function Xs(e,t){const n=Xt(e,t);if(n===-1)return null;
|
|
675
674
|
const o=_e(e)[n];return o?.id?{block:o,topLevelBlockId:o.id,topLevelIndex:n}:null}function Qs(e){const t=e.toolState.editedBlockIds.size;if(t===0)return{loadedBlockCount:0,editedBlockCount:0};const n=e.
|
|
676
675
|
getLatestDocument(),o=n.children.length,r=new Set;for(const c of e.toolState.editedBlockIds){const d=Ae(n,c);d!==-1&&r.add(d)}const i=new Set;for(const c of r)for(let d=Math.max(0,c-xo);d<=Math.min(o-
|
|
677
676
|
1,c+xo);d++)i.add(d);const a=[],l=Array.from(i).sort((c,d)=>c-d);for(const c of l){const d=n.children[c];d?.id&&a.push(d.id)}e.turnState.requestedBlockIds||(e.turnState.requestedBlockIds=new Set);for(const c of a)
|
|
678
|
-
e.turnState.requestedBlockIds.add(c);return e.turnState.documentRequested=!0,{loadedBlockCount:a.length,editedBlockCount:t}}async function Zs(e){const t=await
|
|
677
|
+
e.turnState.requestedBlockIds.add(c);return e.turnState.documentRequested=!0,{loadedBlockCount:a.length,editedBlockCount:t}}async function Zs(e){const t=await Bi(e);if(t)return{id:t.id,type:t.type,content:t.
|
|
679
678
|
content,preview:t.preview,charCount:t.charCount,...t.fileName?{fileName:t.fileName}:{},...t.mimeType?{mimeType:t.mimeType}:{},...t.fileSize?{fileSize:t.fileSize}:{},...t.urls?{urls:t.urls}:{},...t.dimensions?
|
|
680
|
-
{dimensions:t.dimensions}:{}}}function Ys(e){const t=e.loadAttachment??Zs,n=e.metrics??
|
|
679
|
+
{dimensions:t.dimensions}:{}}}function Ys(e){const t=e.loadAttachment??Zs,n=e.metrics??vr;if(!e.toolState.foreignBlockSources){e.toolState.foreignBlockSources=new Map;for(const I of e.getConversationHistory?.()??
|
|
681
680
|
[])if(!(!I.toolResult?.success||!I.toolResult.output))try{const C=JSON.parse(I.toolResult.output),q=C.document?.documentId;if(typeof q!="string"||!["document_read","document_search_context"].includes(
|
|
682
681
|
C.kind)||typeof C.documentContent!="string"||!Ie({document_id:q},e))continue;const J=new DOMParser().parseFromString(C.documentContent,"text/html");for(const z of J.querySelectorAll("[id]"))e.toolState.
|
|
683
682
|
foreignBlockSources.set(z.id,q)}catch{}}const o=e.toolState.foreignBlockSources,r=(I,C,q)=>{const J=z=>{if(z.id&&q(z.id),"children"in z&&Array.isArray(z.children))for(const j of z.children)"id"in j&&J(
|
|
684
683
|
j)};for(const z of C){const j=re(I,z);j&&J(j)}},i=(I,C,q)=>r(I,C,J=>o.set(J,q)),a=I=>{const C=e.tryAddRequestedBlocks(I);return(!C||C.code===Io)&&r(e.getLatestDocument(),I,q=>o.delete(q)),C},l=I=>{const C=a(
|
|
685
684
|
I);return C&&C.code!==Io?{error:C,reread:!1}:(e.redeliverReadBlocks?.(I),{error:null,reread:!!C})},c=" These blocks were already in context; their latest content is re-sent in the next document snapsh\
|
|
686
|
-
ot.";let d=e.turnState.currentTurn??0,u=0,f=0,b=0;const y=new Map;let
|
|
685
|
+
ot.";let d=e.turnState.currentTurn??0,u=0,f=0,b=0;const y=new Map;let R=1;const L=async()=>{e.getDocumentSession()||await e.waitForDocumentSession?.();const I=e.getDocumentSession(),C=I?.getDocumentId?.(),
|
|
687
686
|
q=e.getCurrentDocumentId?.();return I&&(!C||!q||Ie({document_id:C},e)==="")?I:null},O=I=>v(I,yo,Wi),T=new Set(["read_table","read_blocks","read_blocks_from_index","read_specific_blocks","search_docume\
|
|
688
687
|
nt","find_highlights","measure_document","measure_blocks","view_image","render_document_pages"]),D=new Set(["read_blocks","read_blocks_from_index","read_specific_blocks","search_document"]),A=()=>{const I=e.
|
|
689
|
-
turnState.currentTurn??0;I!==d&&(d=I,u=0,f=0,b=0)},M={requestId:-1,ids:new Set};return async I=>{var C,q,J,z,j;const oe=
|
|
688
|
+
turnState.currentTurn??0;I!==d&&(d=I,u=0,f=0,b=0)},M={requestId:-1,ids:new Set};return async I=>{var C,q,J,z,j;const oe=Ns(I);let h=oe.name==="remove_blocks"?{...oe,name:"remove_block"}:oe.name==="rem\
|
|
690
689
|
ove_table_rows"?{...oe,name:"remove_table_row"}:oe;const $=h.name,we=e.getExecutionPolicy?.(),pe=we?ds(we,$):null;if(pe)return v(h,pe.message,pe.code);if(e.allowCrossDocumentReads===!1&&(Oo(h.arguments??
|
|
691
690
|
{}).length>0||$==="list_documents"||$==="search_documents"))return v(h,"This host only permits the supplied document. document_id routing is unavailable.","agent_tool_not_allowed");if(A(),(T.has($)||D.
|
|
692
691
|
has($))&&(b+=1),$==="move_blocks"){const s=h.arguments??{};let m=s.reference_id;if(typeof m=="string"){const p=m.trim();if(m=p,p.startsWith("[")||p.startsWith('"'))try{m=JSON.parse(p)}catch{m=null}}if(Array.
|
|
@@ -696,16 +695,16 @@ tring (for example "d5BLVe", not a stringified array), and position "before" or
|
|
|
696
695
|
block_ids.map(p=>p.trim()),reference_id:m.trim()}}}if($==="create_plan"||$==="update_plan"){if(!e.getPlanState||!e.setPlanState)return v(h,"This host does not support task plans.","plan_unavailable");
|
|
697
696
|
try{const s=jn(e.getPlanState(),$,h.arguments??{});return e.setPlanState(s),e.markConversationDirty(),H(h,Mn(h.arguments??{})?`${JSON.stringify(s.plan)}
|
|
698
697
|
${Bn}`:JSON.stringify(s.plan),void 0,!0,JSON.stringify({kind:"task_plan",plan:s.plan}))}catch(s){return v(h,s instanceof Error?s.message:String(s),"invalid_plan_update")}}if(e.mutationTools.includes($)||
|
|
699
|
-
$==="remove_block"){const s=Ie(h.arguments??{},e),m=
|
|
698
|
+
$==="remove_block"){const s=Ie(h.arguments??{},e),m=We(h.arguments).filter(w=>o.has(w)&&Ie({document_id:o.get(w)},e)!==""),p=s||(m.length?o.get(m[0]):void 0);if(p){if(!s&&m.every(k=>re(e.getLatestDocument(),
|
|
700
699
|
k)))return{...v(h,`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/${p} and ask them to open\
|
|
701
700
|
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:p};const w=e.turnState.currentRequestId??
|
|
702
701
|
0;e.toolState.foreignTargetFailureState?.requestId!==w&&(e.toolState.foreignTargetFailureState={requestId:w,count:0});const g=++e.toolState.foreignTargetFailureState.count;return{...v(h,`These edits t\
|
|
703
702
|
arget a read-only source document. Open /docs/${p} 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 \
|
|
704
|
-
active document instead, read its target blocks without document_id first.`,g>=2?"foreign_document_target_repeated":"foreign_document_target"),sourceDocumentId:p}}}const lt=
|
|
705
|
-
h,lt,
|
|
706
|
-
const w=m.filter(g=>!M.ids.has(g));if(w.length)return w.forEach(g=>M.ids.add(g)),v(h,`${w.map(g=>`'${g}'`).join(", ")} ${w.length===1?"is":"are"} outside the user's selection (${JSON.stringify(
|
|
703
|
+
active document instead, read its target blocks without document_id first.`,g>=2?"foreign_document_target_repeated":"foreign_document_target"),sourceDocumentId:p}}}const lt=ui($,h.arguments);if(lt)return v(
|
|
704
|
+
h,lt,ci);const At=e.getLockedSelection?.()??null;if(At?.length){const s=e.getLatestDocument(),m=ai(s,At,si(s,$,h.arguments)),p=e.turnState.currentRequestId??0;M.requestId!==p&&(M.requestId=p,M.ids.clear());
|
|
705
|
+
const w=m.filter(g=>!M.ids.has(g));if(w.length)return w.forEach(g=>M.ids.add(g)),v(h,`${w.map(g=>`'${g}'`).join(", ")} ${w.length===1?"is":"are"} outside the user's selection (${JSON.stringify(li(At))}\
|
|
707
706
|
). This request refers to the selected content, so leave other content unchanged and mention it in chat instead; nothing was changed by this call. Only if the user explicitly asked to change content b\
|
|
708
|
-
eyond the selection, send the same call again.`,
|
|
707
|
+
eyond the selection, send the same call again.`,ni)}const Wo=D.has($)&&Ie(h.arguments??{},e)!=="";if(e.requireDocumentSessionForReads&&T.has($)&&!Wo&&!await L())return O(h);if($==="import_attachment_i\
|
|
709
708
|
nto_document"){const s=typeof h.arguments?.attachment_id=="string"?h.arguments.attachment_id.trim():"";if(!s)return v(h,"attachment_id is required.");const m=h.arguments?.after_block_id;if(m!=null&&typeof m!=
|
|
710
709
|
"string")return v(h,"after_block_id must be a block ID string.");const p=typeof m=="string"&&m.trim()||void 0,w=e.getAllAttachments().get(s)??await t(s);if(!w)return v(h,`Attachment "${s}" was not fou\
|
|
711
710
|
nd.`);if(w.type!=="docx"&&w.type!=="pdf")return v(h,"Only DOCX and PDF attachments can be imported into the document.");if(!e.importAttachmentIntoDocument)return v(h,"Attachment import is unavailable \
|
|
@@ -716,8 +715,8 @@ user's request by reading the imported content, then edit it.`)}catch(g){return
|
|
|
716
715
|
has($)){if(!Ps(h.arguments))return v(h,'context_notes is required on every read/search call. Use "N/A" if nothing from the previous context needs to carry forward.');if(u>=1)return v(h,'Use at most on\
|
|
717
716
|
e 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".',fs);u+=1}if($==="measure_document"){const s=h.arguments||{},m=s.
|
|
718
717
|
include_sections===!0,p=Number(s.section_offset),w=Number.isFinite(p)&&p>0?Math.floor(p):0,g=Number(s.section_limit),k=Number.isFinite(g)&&g>0?Math.min(Math.floor(g),ps):hs,S=(Array.isArray(s.heading_levels)?
|
|
719
|
-
s.heading_levels:[]).map(se=>typeof se=="number"?se:typeof se=="string"?Number.parseInt(se,10):Number.NaN).filter(se=>se===1||se===2||se===3),
|
|
720
|
-
0?{headingLevels:S}:{}}),x=e.getDocumentSession()?.getDocumentWithoutPendingSuggestions(),P=x&&x!==
|
|
718
|
+
s.heading_levels:[]).map(se=>typeof se=="number"?se:typeof se=="string"?Number.parseInt(se,10):Number.NaN).filter(se=>se===1||se===2||se===3),N=e.getLatestDocument(),_=bo(N,{includeSections:m,...S.length>
|
|
719
|
+
0?{headingLevels:S}:{}}),x=e.getDocumentSession()?.getDocumentWithoutPendingSuggestions(),P=x&&x!==N?bo(x,{includeSections:!1}):null,E=P&&(P.wordCount!==_.wordCount||P.characterCount!==_.characterCount)?
|
|
721
720
|
{wordCount:P.wordCount,characterCount:P.characterCount,paragraphCount:P.paragraphCount,pageCount:P.pageCount}:void 0,K=_.sections??[],F=K.length,U=Math.min(w,F),Z=m?K.slice(U,U+k):void 0,W=Z?.length??
|
|
722
721
|
0,le=m&&U+W<F,ee=JSON.stringify({kind:"document_measurement",tool:"measure_document",measurementBasis:"pending_suggestions_applied",..._,...E?{originalReviewProjection:E}:{},...m?{sections:Z,sectionCount:F,
|
|
723
722
|
sectionOffset:U,sectionLimit:k,returnedSectionCount:W,hasMoreSections:le,...le?{nextSectionOffset:U+W}:{}}:{}});n.count("agent.measure.call",1,{tool_name:$}),n.distribution("agent.measure.sections",F,
|
|
@@ -727,11 +726,11 @@ tals treat pending suggestions as accepted. The original review projection has $
|
|
|
727
726
|
ing the user's editor view when reconciling a reported count.`:"";return{toolCall:h,success:!0,toolOutput:ee,agentFeedback:`${ie}${ge}${Q} The result includes ${te}.`,control:{shouldContinue:!0}}}if($===
|
|
728
727
|
"measure_blocks"){const s=h.arguments||{},m=typeof s.mode=="string"?s.mode.trim():"inclusive";if(m!==""&&m!=="inclusive")return v(h,'measure_blocks only supports mode="inclusive".');const p=Array.isArray(
|
|
729
728
|
s.ranges)?s.ranges:[];if(p.length===0)return v(h,"measure_blocks requires at least one range.");const w=p.map(x=>{const P=x&&typeof x=="object"?x:{};return{startBlockId:typeof P.start_block_id=="strin\
|
|
730
|
-
g"?P.start_block_id:"",endBlockId:typeof P.end_block_id=="string"?P.end_block_id:void 0}}),g=zi(e.getLatestDocument(),w),k=g.ranges.length,S=g.errors.length,
|
|
729
|
+
g"?P.start_block_id:"",endBlockId:typeof P.end_block_id=="string"?P.end_block_id:void 0}}),g=zi(e.getLatestDocument(),w),k=g.ranges.length,S=g.errors.length,N=JSON.stringify({kind:"document_measuremen\
|
|
731
730
|
t",tool:"measure_blocks",...g});if(n.count("agent.measure.call",1,{tool_name:$}),n.distribution("agent.measure.ranges",k,void 0,{tool_name:$}),k===0){const x=g.errors.map(P=>P.error).join(" ")||"No va\
|
|
732
731
|
lid inclusive ranges were measured.";return v(h,x,De)}const _=S>0?`Measured ${k} inclusive block range(s); ${S} range(s) had errors.`:`Measured ${k} inclusive block range(s).`;return H(h,_,void 0,void 0,
|
|
733
|
-
|
|
734
|
-
const p=Et(s,m,x=>ae.renderSubtree(x,s));if(p.error)return v(h,p.error);const w=
|
|
732
|
+
N)}if($==="read_table"){const s=e.getLatestDocument(),m=h.arguments??{};if(typeof m.context_notes!="string")return v(h,"context_notes is required (use N/A when there is no prior context to preserve).");
|
|
733
|
+
const p=Et(s,m,x=>ae.renderSubtree(x,s));if(p.error)return v(h,p.error);const w=Ii(e.getTableTaskState?.()??e.toolState.tableTasks??Zn(),s,m,{requestId:e.turnState.currentRequestId??0,chatHistory:e.getConversationHistory?.()??
|
|
735
734
|
[],attachmentExists:x=>e.getAllAttachments().has(x)});let g;if("error"in w){const x=(e.getTableTaskState?.()??e.toolState.tableTasks)?.task;g={accepted:!1,reason:w.error,retained_scope:x&&x.tableId===
|
|
736
735
|
p.table_id?{task_kind:x.kind,scope_row_start:x.declaredRowStart,scope_row_count:x.rowIds.length,scope_columns:x.columns}:null,note:x?"The existing task scope still applies; finish all of it unless the\
|
|
737
736
|
user narrows it.":"No task scope is recorded for this table; no table task status will be reported until a valid declaration."}}else e.toolState.tableTasks=w.state,w.declared&&e.setTableTaskState?.(w.
|
|
@@ -739,77 +738,77 @@ state);const k=(C=e.toolState).tableContext??(C.tableContext=Un());m.mode!=="cel
|
|
|
739
738
|
[],p.table_id])],k.requestedCells??(k.requestedCells={}),k.requestedCells[p.table_id]=[...new Set([...k.requestedCells[p.table_id]??[],...p.rows.flatMap(x=>x.cells.map(P=>P.id).filter(Boolean))])];const S=!!e.
|
|
740
739
|
turnState.docContextLedger;S?(k.pendingReadCells??(k.pendingReadCells={}),k.pendingReadCells[p.table_id]=[...new Set([...k.pendingReadCells[p.table_id]??[],...p.rows.flatMap(x=>x.cells.map(P=>P.id).filter(
|
|
741
740
|
Boolean))])],(q=e.turnState).requestedBlockIds??(q.requestedBlockIds=new Set),e.turnState.requestedBlockIds.add(p.table_id),(J=e.turnState).lastReadBlockIds??(J.lastReadBlockIds=new Set),e.turnState.lastReadBlockIds.
|
|
742
|
-
add(p.table_id),e.turnState.documentRequested=!0):_t(s,k,p.table_id,p.complete_cell_ids),e.markConversationDirty();const
|
|
741
|
+
add(p.table_id),e.turnState.documentRequested=!0):_t(s,k,p.table_id,p.complete_cell_ids),e.markConversationDirty();const N=p.rows.flatMap(x=>x.cells.filter(P=>P.id&&P.kind!=="covered"&&!p.complete_cell_ids.
|
|
743
742
|
includes(P.id)).map(P=>{const E=re(s,P.id),K=E?.type==="table-cell"?E.children.map(F=>F.id):[];return{row_id:x.row_id,column:P.column,cell_id:P.id,...P.truncated&&P.text?{note:P.text}:{},...K.length?{
|
|
744
743
|
nested_block_ids:K.length>40?[...K.slice(0,40),`+${K.length-40} more`]:K}:{}}})),_=S&&m.mode!=="cell_text"?{...p,rows:void 0,complete_cell_ids:void 0,delivered_rows:p.rows.map(x=>({row_id:x.row_id,columns:x.
|
|
745
|
-
cells.filter(P=>p.complete_cell_ids.includes(P.id)).map(P=>P.column)})),delivered_cell_count:p.complete_cell_ids.length,...
|
|
744
|
+
cells.filter(P=>p.complete_cell_ids.includes(P.id)).map(P=>P.column)})),delivered_cell_count:p.complete_cell_ids.length,...N.length?{undelivered_cells:N}:{},delivery:N.length?"Delivered cells arrive i\
|
|
746
745
|
n the next document snapshot; undelivered_cells will not, so follow each one's note. Summary/preview alone is not edit authorization.":"Requested cells arrive in the next document snapshot. Summary/pr\
|
|
747
746
|
eview alone is not edit authorization.",...g?{task_scope_update:g}:{}}:{...p,...g?{task_scope_update:g}:{}};return H(h,g?"Table context read. The task scope declaration was rejected (see task_scope_up\
|
|
748
747
|
date); the existing scope is unchanged.":m.mode==="cell_text"?"Cell text page read. cell_text is read-only: each block's text starts with its [[block_id]] marker (not document text). To edit a passage\
|
|
749
748
|
, read that block with read_specific_blocks, then target its block ID.":"Table context read. Use fill counts to include gaps in earlier rows.",void 0,void 0,JSON.stringify(_))}if($==="read_blocks"){const s=h.
|
|
750
|
-
arguments||{},m=Ie(s,e),p=s.from_id,w=m?
|
|
751
|
-
m)??St({token:w,documentId:m})):null}catch(F){return v(h,F instanceof Error?F.message:"Document read failed.")}const k=g?.content??e.getLatestDocument(),S=_e(k),
|
|
752
|
-
-1;if(_===-1)return v(h,`Block ID "${p}" not found`,De);if(_>=
|
|
753
|
-
x.endIndex<_)return v(h,`No readable blocks found from index ${_}.`);if(g){i(k,x.blockIds,g.id);const F=ae.extractSpecificBlocks(k,x.blockIds,void 0,
|
|
749
|
+
arguments||{},m=Ie(s,e),p=s.from_id,w=m?He(e):"";if(m&&!w&&!e.loadRemoteDocument)return v(h,"Cross-document access is only available for signed-in documents.");let g=null;try{g=m?await(e.loadRemoteDocument?.(
|
|
750
|
+
m)??St({token:w,documentId:m})):null}catch(F){return v(h,F instanceof Error?F.message:"Document read failed.")}const k=g?.content??e.getLatestDocument(),S=_e(k),N=S.length,_=typeof p=="string"?Xt(k,p):
|
|
751
|
+
-1;if(_===-1)return v(h,`Block ID "${p}" not found`,De);if(_>=N)return v(h,`Start index ${_} is out of range for ${N} blocks.`);const x=No({doc:k,startIndex:_,maxTokens:Je});if(x.blockIds.length===0||
|
|
752
|
+
x.endIndex<_)return v(h,`No readable blocks found from index ${_}.`);if(g){i(k,x.blockIds,g.id);const F=ae.extractSpecificBlocks(k,x.blockIds,void 0,Fe),U=ae.formatSpecificBlocks(F),Z=x.endIndex+1<N?x.
|
|
754
753
|
endIndex+1:null,W=en({documentId:g.id,title:g.title,canonicalPath:g.canonicalPath,startIndex:_,endIndex:x.endIndex,estimatedTokens:x.estimatedTokens,content:U,nextIndex:Z,endOfDocument:Z===null}),le=x.
|
|
755
754
|
reachedTokenBudget?" Reached per-call token budget.":"";return H(h,`Read ${x.blockIds.length} blocks from "${g.title}" (index ${_}-${x.endIndex}). Serialized characters: ~${x.estimatedTokens}.${le}${Z!==
|
|
756
755
|
null?` Next: read_blocks_from_index(document_id="${g.id}", index=${Z}).`:" End of document."}`,void 0,void 0,W)}const P=l(x.blockIds);if(P.error)return v(h,P.error.message,P.error.code);e.turnState.documentRequested=
|
|
757
756
|
!0,n.count("agent.read.call",1,{tool_name:$}),n.distribution("agent.read.blocks_loaded",x.blockIds.length,void 0,{tool_name:$}),n.distribution("agent.read.tokens_loaded_estimate",x.estimatedTokens,void 0,
|
|
758
|
-
{tool_name:$}),x.reachedTokenBudget&&n.count("agent.read.token_budget_reached",1,{tool_name:$});const E=st(e,k);if(x.endIndex+1<
|
|
757
|
+
{tool_name:$}),x.reachedTokenBudget&&n.count("agent.read.token_budget_reached",1,{tool_name:$});const E=st(e,k);if(x.endIndex+1<N){const F=x.endIndex+1,U=S[F]?.id,Z=at({tool:$,loaded:{count:x.blockIds.
|
|
759
758
|
length,startIndex:_,endIndex:x.endIndex,estimatedTokens:x.estimatedTokens},next:{index:F,...U?{blockId:U}:{}},endOfDocument:!1,coverage:E}),W=x.reachedTokenBudget?" Reached per-call token budget.":"",
|
|
760
759
|
le=U?` Next block ID: ${U}.`:"";return H(h,`Read ${x.blockIds.length} blocks (index ${_}-${x.endIndex}). Serialized characters: ~${x.estimatedTokens}.${W} Next: read_blocks_from_index(index=${F}).${le}${P.
|
|
761
760
|
reread?c:""}`,void 0,P.reread,Z)}const K=at({tool:$,loaded:{count:x.blockIds.length,startIndex:_,endIndex:x.endIndex,estimatedTokens:x.estimatedTokens},endOfDocument:!0,coverage:E});return H(h,`Read ${x.
|
|
762
761
|
blockIds.length} blocks (index ${_}-${x.endIndex}). Serialized characters: ~${x.estimatedTokens}. End of document.${P.reread?c:""}`,void 0,P.reread,K)}if($==="read_blocks_from_index"){const s=h.arguments||
|
|
763
|
-
{},m=Ie(s,e),p=it(s.index,0),w=m?
|
|
764
|
-
m)??St({token:w,documentId:m})):null}catch(K){return v(h,K instanceof Error?K.message:"Document read failed.")}const k=g?.content??e.getLatestDocument(),S=_e(k),
|
|
762
|
+
{},m=Ie(s,e),p=it(s.index,0),w=m?He(e):"";if(m&&!w&&!e.loadRemoteDocument)return v(h,"Cross-document access is only available for signed-in documents.");let g=null;try{g=m?await(e.loadRemoteDocument?.(
|
|
763
|
+
m)??St({token:w,documentId:m})):null}catch(K){return v(h,K instanceof Error?K.message:"Document read failed.")}const k=g?.content??e.getLatestDocument(),S=_e(k),N=S.length;if(g&&N===0&&p===0)return H(
|
|
765
764
|
h,`Read 0 blocks from "${g.title}". End of document.`,void 0,void 0,en({documentId:g.id,title:g.title,canonicalPath:g.canonicalPath,startIndex:0,endIndex:-1,estimatedTokens:0,content:"",nextIndex:null,
|
|
766
|
-
endOfDocument:!0}));if(p>=
|
|
767
|
-
p)return v(h,`No readable blocks found from index ${p}.`);if(g){i(k,_.blockIds,g.id);const K=ae.extractSpecificBlocks(k,_.blockIds,void 0,
|
|
765
|
+
endOfDocument:!0}));if(p>=N)return v(h,`Start index ${p} is out of range for ${N} blocks${g?` in "${g.title}"`:""}.`);const _=No({doc:k,startIndex:p,maxTokens:Je});if(_.blockIds.length===0||_.endIndex<
|
|
766
|
+
p)return v(h,`No readable blocks found from index ${p}.`);if(g){i(k,_.blockIds,g.id);const K=ae.extractSpecificBlocks(k,_.blockIds,void 0,Fe),F=ae.formatSpecificBlocks(K),U=_.endIndex+1<N?_.endIndex+1:
|
|
768
767
|
null,Z=en({documentId:g.id,title:g.title,canonicalPath:g.canonicalPath,startIndex:p,endIndex:_.endIndex,estimatedTokens:_.estimatedTokens,content:F,nextIndex:U,endOfDocument:U===null}),W=_.reachedTokenBudget?
|
|
769
768
|
" Reached per-call token budget.":"";return n.count("agent.read.call",1,{tool_name:$}),n.distribution("agent.read.blocks_loaded",_.blockIds.length,void 0,{tool_name:$}),H(h,`Read ${_.blockIds.length} \
|
|
770
769
|
blocks from "${g.title}" (index ${p}-${_.endIndex}). Serialized characters: ~${_.estimatedTokens}.${W}${U!==null?` Next: read_blocks_from_index(document_id="${g.id}", index=${U}).`:" End of document."}`,
|
|
771
770
|
void 0,void 0,Z)}const x=l(_.blockIds);if(x.error)return v(h,x.error.message,x.error.code);e.turnState.documentRequested=!0,n.count("agent.read.call",1,{tool_name:$}),n.distribution("agent.read.blocks\
|
|
772
771
|
_loaded",_.blockIds.length,void 0,{tool_name:$}),n.distribution("agent.read.tokens_loaded_estimate",_.estimatedTokens,void 0,{tool_name:$}),_.reachedTokenBudget&&n.count("agent.read.token_budget_reach\
|
|
773
|
-
ed",1,{tool_name:$});const P=st(e,k);if(_.endIndex+1<
|
|
772
|
+
ed",1,{tool_name:$});const P=st(e,k);if(_.endIndex+1<N){const K=_.endIndex+1,F=S[K]?.id,U=at({tool:$,loaded:{count:_.blockIds.length,startIndex:p,endIndex:_.endIndex,estimatedTokens:_.estimatedTokens},
|
|
774
773
|
next:{index:K,...F?{blockId:F}:{}},endOfDocument:!1,coverage:P}),Z=_.reachedTokenBudget?" Reached per-call token budget.":"",W=F?` Next block ID: ${F}.`:"";return H(h,`Read ${_.blockIds.length} blocks\
|
|
775
774
|
(index ${p}-${_.endIndex}). Serialized characters: ~${_.estimatedTokens}.${Z} Next: read_blocks_from_index(index=${K}).${W}${x.reread?c:""}`,void 0,x.reread,U)}const E=at({tool:$,loaded:{count:_.blockIds.
|
|
776
775
|
length,startIndex:p,endIndex:_.endIndex,estimatedTokens:_.estimatedTokens},endOfDocument:!0,coverage:P});return H(h,`Read ${_.blockIds.length} blocks (index ${p}-${_.endIndex}). Serialized characters:\
|
|
777
776
|
~${_.estimatedTokens}. End of document.${x.reread?c:""}`,void 0,x.reread,E)}if($==="search_document"){const s=h.arguments||{},m=Ie(s,e),p=s.queries,w=Array.isArray(p)?p.filter(ne=>typeof ne=="string"&&
|
|
778
|
-
ne.length>0):typeof p=="string"&&p.length>0?[p]:[];if(w.length===0)return v(h,'search_document requires "queries": a non-empty array of search strings.');const g=typeof s.page=="number"?s.page:0,k=m?
|
|
777
|
+
ne.length>0):typeof p=="string"&&p.length>0?[p]:[];if(w.length===0)return v(h,'search_document requires "queries": a non-empty array of search strings.');const g=typeof s.page=="number"?s.page:0,k=m?He(
|
|
779
778
|
e):"";if(m&&!k&&!e.loadRemoteDocument)return v(h,"Cross-document access is only available for signed-in documents.");let S=null;try{S=m?await(e.loadRemoteDocument?.(m)??St({token:k,documentId:m})):null}catch(ne){
|
|
780
|
-
return v(h,ne instanceof Error?ne.message:"Document search failed.")}const
|
|
781
|
-
lastSearchState.toolName==="search_document"&&e.toolState.lastSearchState.requestKey===x?P=e.toolState.lastSearchState.allResults:P=ae.searchDocument(
|
|
782
|
-
lastSearchState?.requestKey===x?e.toolState.lastSearchState.resultSetId:void 0;if(ne&&y.has(ne))E=ne;else{E=`search_result_${
|
|
783
|
-
blockHashes:Dt(
|
|
779
|
+
return v(h,ne instanceof Error?ne.message:"Document search failed.")}const N=S?.content??e.getLatestDocument(),_=e.searchPageSize,x=Eo("search_document",s);let P;g>0&&e.toolState.lastSearchState&&e.toolState.
|
|
780
|
+
lastSearchState.toolName==="search_document"&&e.toolState.lastSearchState.requestKey===x?P=e.toolState.lastSearchState.allResults:P=ae.searchDocument(N,w);let E;if(!S&&P.length>0){const ne=g>0&&e.toolState.
|
|
781
|
+
lastSearchState?.requestKey===x?e.toolState.lastSearchState.resultSetId:void 0;if(ne&&y.has(ne))E=ne;else{E=`search_result_${R++}`;const be=Array.from(new Set(P.map($e=>$e.blockId)));y.set(E,{id:E,blockIds:be,
|
|
782
|
+
blockHashes:Dt(N,be)})}}const K=Ro({doc:N,results:P,pageSize:_,maxTokens:Je}),F=Math.max(1,K.length),U=Math.min(g,Math.max(0,F-1)),Z=K[U]??{results:[],startResultIndex:0,endResultIndexExclusive:0},W=Z.
|
|
784
783
|
startResultIndex,le=Z.endResultIndexExclusive,ee=Z.results,ie=ee.map(ne=>ne.blockId),ge=S||ie.length===0?null:a(ie);e.toolState.lastSearchState={toolName:"search_document",requestKey:x,allResults:P,currentPage:U,
|
|
785
784
|
totalPages:F,...E?{resultSetId:E}:{}};let te;P.length===0?te=`No matches found${S?` in "${S.title}"`:""} for: ${w.join(", ")}`:(te=`Found ${P.length} matching blocks${S?` in "${S.title}"`:""}. Showing\
|
|
786
785
|
page ${U+1}/${F} (results ${W+1}-${le} of ${P.length}).`,!S&&E&&(te+=` The full unpaginated result set is saved as ${E}; pass search_result_id="${E}" to replace, replace_block, style_blocks, or remov\
|
|
787
786
|
e_blocks to target all ${P.length} matches in one call.`),U<F-1&&S&&(te+=S?` Call search_document with document_id="${S.id}" and page=${U+1} to see next page.`:` Call search_document with page=${U+1} \
|
|
788
787
|
to see next page.`));const Q=ge?.code==="no_new_read_context";if(ge&&!Q){if(P.length>0){let ne=`Found ${P.length} matching blocks. Showing page ${U+1}/${F} (blocks ${W+1}-${le} of ${P.length}). Matchi\
|
|
789
788
|
ng blocks could not be loaded this turn.`;return U<F-1&&(ne+=` Call search_document with page=${U+1} to see next page.`),v(h,`${ge.message} ${ne}`,ge.code)}return v(h,`${ge.message} ${te}`,ge.code)}if(Q&&
|
|
790
|
-
P.length>0&&(te+=" Matching block content is already available in this request's cached context."),!S){const ne=mr(
|
|
789
|
+
P.length>0&&(te+=" Matching block content is already available in this request's cached context."),!S){const ne=mr(N.chrome??[]).filter(be=>w.some($e=>be.toLowerCase().includes($e.toLowerCase())));ne.
|
|
791
790
|
length>0&&(te+=` Also found in page headers/footers (not body blocks; change them with set_header_footer):
|
|
792
791
|
${ne.map(be=>`- ${be}`).join(`
|
|
793
|
-
`)}`)}if(S){i(
|
|
792
|
+
`)}`)}if(S){i(N,ie,S.id);const ne=ae.extractSpecificBlocks(N,ie,void 0,Fe),be=ae.formatSpecificBlocks(ne),$e=JSON.stringify({kind:"document_search_context",tool:"search_document",document:{documentId:S.
|
|
794
793
|
id,title:S.title,canonicalPath:S.canonicalPath||`/${S.title}`,href:`/docs/${S.id}`,...Yt(S.id)},queries:w,totalMatches:P.length,page:{current:U,total:F,startResult:W+1,endResult:le},nextPage:U<F-1?U+1:
|
|
795
794
|
null,matches:ee.map(Ee=>({blockId:Ee.blockId,blockIndex:Ee.blockIndex,matchedQueries:Ee.matchedQueries??[]})),documentContent:be});return n.count("agent.read.search_call",1,{tool_name:$}),n.distribution(
|
|
796
795
|
"agent.read.blocks_loaded",ie.length,void 0,{tool_name:$}),H(h,te,void 0,void 0,$e)}e.turnState.documentRequested=!0,n.count("agent.read.search_call",1,{tool_name:$}),n.distribution("agent.read.blocks\
|
|
797
796
|
_loaded",ie.length,void 0,{tool_name:$});const se=Bo({tool:"search_document",queries:w,totalMatches:P.length,currentPage:U,totalPages:F,pageStart:W,pageEnd:le,pageResults:ee,nextPage:U<F-1?U+1:null,...E?
|
|
798
797
|
{searchResultId:E}:{},coverage:st(e,e.getLatestDocument())});return H(h,te,void 0,void 0,se)}if($==="list_documents"){const s=h.arguments||{},m=typeof s.parent_folder_id=="string"&&s.parent_folder_id.
|
|
799
|
-
trim().length>0?s.parent_folder_id.trim():null,p=it(s.page,0),w=
|
|
800
|
-
page:p,limit:50}),k=g.hasMore?` Call list_documents with page=${p+1} for more.`:"",S=g.items.filter(P=>P.itemType==="folder").length,
|
|
801
|
-
folder":"the account root"}.`:`Listed ${g.items.length} of ${g.totalCount} items in ${m?"the folder":"the account root"} (${S} folders, ${
|
|
798
|
+
trim().length>0?s.parent_folder_id.trim():null,p=it(s.page,0),w=He(e);if(!w)return v(h,"Document tree listing is only available for signed-in documents.");try{const g=await zs({token:w,parentFolderId:m,
|
|
799
|
+
page:p,limit:50}),k=g.hasMore?` Call list_documents with page=${p+1} for more.`:"",S=g.items.filter(P=>P.itemType==="folder").length,N=g.items.length-S,_=g.totalCount===0?`No items found in ${m?"that \
|
|
800
|
+
folder":"the account root"}.`:`Listed ${g.items.length} of ${g.totalCount} items in ${m?"the folder":"the account root"} (${S} folders, ${N} documents).${k}`,x=Ws({parentFolderId:m,page:p,totalCount:g.
|
|
802
801
|
totalCount,totalPages:Math.max(1,g.totalPages),hasMore:g.hasMore,items:g.items});return n.count("agent.read.document_tree_list",1,{tool_name:$}),H(h,_,void 0,void 0,x)}catch(g){return v(h,g instanceof
|
|
803
|
-
Error?g.message:"Document listing failed.")}}if($==="search_documents"){const s=h.arguments||{},m=typeof s.query=="string"?s.query.trim():"";if(!m)return v(h,"search_documents requires a query.");const p=
|
|
802
|
+
Error?g.message:"Document listing failed.")}}if($==="search_documents"){const s=h.arguments||{},m=typeof s.query=="string"?s.query.trim():"";if(!m)return v(h,"search_documents requires a query.");const p=He(
|
|
804
803
|
e);if(!p)return v(h,"Cross-document search is only available for signed-in documents.");const w=Us(s.scope),g=e.getCurrentFolderId?.()??null,k=typeof s.folder_id=="string"&&s.folder_id.trim().length>0?
|
|
805
|
-
s.folder_id.trim():null,S=w==="current_folder"&&!g||w==="folder"&&!k?"account":w,
|
|
806
|
-
r"&&!!g,P=S==="folder"&&k?"the selected folder tree":x?"the current folder tree":"the account",E=
|
|
807
|
-
s found for "${m}" in ${P}.`:`Found ${_.totalCount} documents for "${m}" in ${P}. Showing page ${
|
|
808
|
-
er"?k:null,page:
|
|
804
|
+
s.folder_id.trim():null,S=w==="current_folder"&&!g||w==="folder"&&!k?"account":w,N=it(s.page,0);try{const _=await Fs({token:p,query:m,scope:S,page:N,currentFolderId:g,folderId:k}),x=S==="current_folde\
|
|
805
|
+
r"&&!!g,P=S==="folder"&&k?"the selected folder tree":x?"the current folder tree":"the account",E=N+1<_.totalPages?` Call search_documents with page=${N+1} for more.`:"",K=_.totalCount===0?`No document\
|
|
806
|
+
s found for "${m}" in ${P}.`:`Found ${_.totalCount} documents for "${m}" in ${P}. Showing page ${N+1}/${Math.max(1,_.totalPages)}.${E}`,F=Js({query:m,scope:S,searchedCurrentFolder:x,folderId:S==="fold\
|
|
807
|
+
er"?k:null,page:N,totalCount:_.totalCount,totalPages:Math.max(1,_.totalPages),results:_.items});return n.count("agent.read.account_search_call",1,{tool_name:$}),H(h,K,void 0,void 0,F)}catch(_){return v(
|
|
809
808
|
h,_ instanceof Error?_.message:"Document search failed.")}}if($==="find_highlights"){const s=h.arguments||{},m=typeof s.color=="string"&&s.color.trim().length>0?s.color.trim().toLowerCase():void 0,p=typeof s.
|
|
810
809
|
page=="number"?s.page:0,w=e.getLatestDocument(),g=e.searchPageSize,k=Eo("find_highlights",s);let S;p>0&&e.toolState.lastSearchState&&e.toolState.lastSearchState.toolName==="find_highlights"&&e.toolState.
|
|
811
|
-
lastSearchState.requestKey===k?S=e.toolState.lastSearchState.allResults:S=ae.findHighlights(w,m);const
|
|
812
|
-
1)),P=
|
|
810
|
+
lastSearchState.requestKey===k?S=e.toolState.lastSearchState.allResults:S=ae.findHighlights(w,m);const N=Ro({doc:w,results:S,pageSize:g,maxTokens:Je}),_=Math.max(1,N.length),x=Math.min(p,Math.max(0,_-
|
|
811
|
+
1)),P=N[x]??{results:[],startResultIndex:0,endResultIndexExclusive:0},E=P.startResultIndex,K=P.endResultIndexExclusive,F=P.results,U=F.map(te=>te.blockId),Z=U.length===0?null:a(U);e.toolState.lastSearchState=
|
|
813
812
|
{toolName:"find_highlights",requestKey:k,allResults:S,currentPage:x,totalPages:_};const W=m?`${m} highlight`:"highlighted content",le=m||S.length===0?"":` Colors: ${Hs(S)}.`;let ee;S.length===0?ee=`No\
|
|
814
813
|
blocks found with ${W}.`:(ee=`Found ${S.length} blocks with ${W}. Showing page ${x+1}/${_} (results ${E+1}-${K} of ${S.length}).${le}`,x<_-1&&(ee+=` Call find_highlights with page=${x+1} to see next \
|
|
815
814
|
page.`));const ie=Z?.code==="no_new_read_context";if(Z&&!ie){if(S.length>0){let te=`Found ${S.length} blocks with ${W}. Showing page ${x+1}/${_} (blocks ${E+1}-${K} of ${S.length}). Matching blocks co\
|
|
@@ -817,26 +816,26 @@ uld not be loaded this turn.`;return x<_-1&&(te+=` Call find_highlights with pag
|
|
|
817
816
|
" Matching block content is already available in this request's cached context."),e.turnState.documentRequested=!0,n.count("agent.read.search_call",1,{tool_name:$}),n.distribution("agent.read.blocks_l\
|
|
818
817
|
oaded",U.length,void 0,{tool_name:$});const ge=Bo({tool:"find_highlights",color:m??null,totalMatches:S.length,currentPage:x,totalPages:_,pageStart:E,pageEnd:K,pageResults:F,nextPage:x<_-1?x+1:null,coverage:st(
|
|
819
818
|
e,e.getLatestDocument())});return H(h,ee,void 0,void 0,ge)}if($==="read_specific_blocks"){const s=h.arguments||{},m=Ie(s,e),p=s.block_ids,w=Array.isArray(p)?p.filter(W=>typeof W=="string"&&W.length>0):
|
|
820
|
-
typeof p=="string"&&p.length>0?[p]:[];if(w.length===0)return v(h,"No block IDs provided");const g=m?
|
|
819
|
+
typeof p=="string"&&p.length>0?[p]:[];if(w.length===0)return v(h,"No block IDs provided");const g=m?He(e):"";if(m&&!g&&!e.loadRemoteDocument)return v(h,"Cross-document access is only available for sig\
|
|
821
820
|
ned-in documents.");let k=null;try{k=m?await(e.loadRemoteDocument?.(m)??St({token:g,documentId:m})):null}catch(W){return v(h,W instanceof Error?W.message:"Document read failed.")}const S=k?.content??e.
|
|
822
|
-
getLatestDocument();if(!k&&e.toolState.tableContext?.scopedTableIds?.length){const W=[];
|
|
821
|
+
getLatestDocument();if(!k&&e.toolState.tableContext?.scopedTableIds?.length){const W=[];Le(S,ee=>W.push(ee));const le=ee=>[...W].reverse().find(ie=>(ie.children.length>=Vo||e.toolState.tableContext.scopedTableIds.
|
|
823
822
|
includes(ie.id))&&ue(ie).includes(ee));if(w.some(ee=>le(ee))){const ee=[];let ie=0;const ge=[...new Set(w.map(Q=>{const se=re(S,Q);return se?.type==="list"&&se.children.some(ne=>ne.id===Q)?se.id:Q}))];
|
|
824
|
-
for(const Q of ge){const se=re(S,Q),ne=le(Q);if(!se||se.id!==Q)return v(h,`Unknown or structural block '${Q}'. Use read_table with table_id and row_ids for table rows.`);let be=!1;if(
|
|
823
|
+
for(const Q of ge){const se=re(S,Q),ne=le(Q);if(!se||se.id!==Q)return v(h,`Unknown or structural block '${Q}'. Use read_table with table_id and row_ids for table rows.`);let be=!1;if(Le(se,()=>{be=!0}),
|
|
825
824
|
be)return v(h,`Block '${Q}' contains a table. Use read_table(table_id="${ne?.id??W.find(Go=>ue(se).includes(Go.id))?.id}") for bounded row windows.`);const $e=ae.renderSubtree(se,S),Ee=JSON.stringify(
|
|
826
825
|
{id:Q,html:$e}).length;if(ie+Ee>24e3)return v(h,"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\
|
|
827
826
|
granted.");ie+=Ee,ee.push({id:Q,html:$e,table_id:ne?.id})}const te=e.toolState.tableContext;for(const Q of ee)Q.table_id&&(te.scopedTableIds=[...new Set([...te.scopedTableIds??[],Q.table_id])],Ln(S,te,
|
|
828
827
|
Q.table_id,Q.id),e.turnState.docContextLedger&&(te.pendingReadBlocks??(te.pendingReadBlocks={}),te.pendingReadBlocks[Q.id]=te.blocks[Q.id]),re(S,Q.id)?.type==="table-cell"&&_t(S,te,Q.table_id,[Q.id])),
|
|
829
828
|
(z=e.turnState).requestedBlockIds??(z.requestedBlockIds=new Set),e.turnState.requestedBlockIds.add(Q.id);return e.turnState.documentRequested=!0,e.markConversationDirty(),H(h,`Read ${ee.length} exact \
|
|
830
829
|
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 edi\
|
|
831
|
-
table.`,void 0,void 0,JSON.stringify({blocks:ee,serialized_characters:ie}))}}const{blockIds:
|
|
832
|
-
if(
|
|
833
|
-
|
|
834
|
-
id}`,...Yt(k.id)},loaded:{count:
|
|
835
|
-
.read.blocks_loaded",
|
|
836
|
-
|
|
837
|
-
n.distribution("agent.read.tokens_loaded_estimate",_,void 0,{tool_name:$}),x&&n.count("agent.read.token_budget_reached",1,{tool_name:$});const K=Zt(S,new Set(
|
|
838
|
-
length,estimatedTokens:_,ranges:Mo(K)},endOfDocument:!1,coverage:st(e,S)}),U=x?` Reached per-call token budget; loaded ${
|
|
839
|
-
re not found.`:"";return H(h,`Loaded ${
|
|
830
|
+
table.`,void 0,void 0,JSON.stringify({blocks:ee,serialized_characters:ie}))}}const{blockIds:N,estimatedTokens:_,reachedTokenBudget:x,missingRequestedBlocks:P}=Ls({doc:S,requestedBlockIds:w,maxTokens:Je});
|
|
831
|
+
if(N.length===0)return P>0?v(h,"None of the requested block IDs were found in the document.",De):v(h,"No readable blocks could be loaded.");if(k){i(S,N,k.id);const W=ae.extractSpecificBlocks(S,N,void 0,
|
|
832
|
+
Fe),le=ae.formatSpecificBlocks(W),ee=Zt(S,new Set(N)),ie=JSON.stringify({kind:"document_read",tool:$,document:{documentId:k.id,title:k.title,canonicalPath:k.canonicalPath||`/${k.title}`,href:`/docs/${k.
|
|
833
|
+
id}`,...Yt(k.id)},loaded:{count:N.length,blockIds:N,blockIndices:ee,estimatedTokens:_},reachedTokenBudget:x,documentContent:le});return n.count("agent.read.call",1,{tool_name:$}),n.distribution("agent\
|
|
834
|
+
.read.blocks_loaded",N.length,void 0,{tool_name:$}),H(h,`Read ${N.length} specific blocks from "${k.title}". Serialized characters: ~${_}.${x?" Reached per-call token budget.":""}`,void 0,void 0,ie)}const E=l(
|
|
835
|
+
N);if(E.error)return v(h,E.error.message,E.error.code);e.turnState.documentRequested=!0,n.count("agent.read.call",1,{tool_name:$}),n.distribution("agent.read.blocks_loaded",N.length,void 0,{tool_name:$}),
|
|
836
|
+
n.distribution("agent.read.tokens_loaded_estimate",_,void 0,{tool_name:$}),x&&n.count("agent.read.token_budget_reached",1,{tool_name:$});const K=Zt(S,new Set(N)),F=at({tool:$,loaded:{count:N.length,requestedCount:w.
|
|
837
|
+
length,estimatedTokens:_,ranges:Mo(K)},endOfDocument:!1,coverage:st(e,S)}),U=x?` Reached per-call token budget; loaded ${N.length}/${w.length} requested blocks.`:"",Z=P>0?` ${P} requested block IDs we\
|
|
838
|
+
re not found.`:"";return H(h,`Loaded ${N.length} specific blocks.${U}${Z} Serialized characters: ~${_}.${E.reread?c:""}`,void 0,E.reread,F)}if($==="get_attachment"){const s=(h.arguments||{}).attachment_id;
|
|
840
839
|
if(!s)return v(h,"No attachment_id provided");let m=e.getAllAttachments().get(s);return m||(m=await t(s),m&&e.getAllAttachments().set(s,m)),m?m.content?.trim()??""?H(h,`Loaded attachment "${m.id}" (${m.
|
|
841
840
|
charCount} chars).`,void 0,void 0,`<attachment id="${m.id}" type="${m.type}"${m.fileName?` filename="${m.fileName}"`:""} chars="${m.charCount}">
|
|
842
841
|
${m.content}
|
|
@@ -845,16 +844,16 @@ from(e.getAllAttachments().keys()).join(", ")||"none"}`)}if($==="view_image"){co
|
|
|
845
844
|
s);if(!p)return v(h,`Image block "${s}" not found in document`,De);const w={id:`view_image_${s}`,type:"image",content:"",preview:"",charCount:0,fileName:p.alt||`image_${s}`,urls:[p.src],dimensions:[{width:p.
|
|
846
845
|
width,height:p.height}]};return H(h,`Image retrieved: ${p.alt?`"${p.alt}" `:""}(${p.width}x${p.height}px)${p.sourceUrl?` Source: ${p.sourceUrl}`:""}`,w)}if($==="render_document_pages"){if(!e.renderDocumentPages)
|
|
847
846
|
return v(h,"Rendered page inspection is unavailable until the document canvas is ready.");const s=h.arguments||{},m=it(s.start_page,1),p=it(s.page_count,1),w=s.mode==="layout"?"layout":"appearance";let g=s.
|
|
848
|
-
quality==="compact"?"compact":"detailed";const k=s.view===void 0||s.view===null?
|
|
849
|
-
eed the accepted or before preview.`,"invalid_view");if(m<1)return v(h,"start_page must be 1 or greater.");const S=g==="detailed"&&p>2;S&&p<=4&&(g="compact");const
|
|
850
|
-
h,`page_count must be between 1 and ${
|
|
847
|
+
quality==="compact"?"compact":"detailed";const k=s.view===void 0||s.view===null?Nt:s.view;if(!sr(k))return v(h,`view must be one of ${ar.join(", ")}. Use show-tracked-changes unless you specifically n\
|
|
848
|
+
eed the accepted or before preview.`,"invalid_view");if(m<1)return v(h,"start_page must be 1 or greater.");const S=g==="detailed"&&p>2;S&&p<=4&&(g="compact");const N=g==="compact"?4:2;if(p<1||p>N)return v(
|
|
849
|
+
h,`page_count must be between 1 and ${N} for ${g} quality.`);try{const _=await e.renderDocumentPages({startPage:m,pageCount:p,mode:w,quality:g,view:k}),x=_.view??Nt;if(x!==k)return v(h,`This document \
|
|
851
850
|
surface cannot render the ${k} view (it rendered ${x}). Use show-tracked-changes, or inspect the accepted text with a read tool.`,"render_view_unsupported");if(_.placeholderImageCount||_.failedImageCount||
|
|
852
851
|
_.mathPlaceholderCount)return{...v(h,`Visual inspection is incomplete: ${_.placeholderImageCount} image placeholders, ${_.failedImageCount} failed images, and ${_.mathPlaceholderCount} formula placeho\
|
|
853
852
|
lders. 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 wi\
|
|
854
853
|
ll not verify the document.`,"visual_resource_unavailable"),failure:{code:"visual_resource_unavailable",phase:"verification",retryable:!1,mutationOutcome:"unchanged"}};const P=_.pages.length===1?`page\
|
|
855
854
|
${_.pages[0]}`:`pages ${_.pages[0]}-${_.pages[_.pages.length-1]}`,E={id:`render_document_pages_${h.id}`,type:"image",content:"",preview:"",charCount:0,fileName:`Rendered document ${P} (${w}, ${g}, ${k}\
|
|
856
855
|
)`,mimeType:_.dataUrl.startsWith("data:image/png")?"image/png":"image/jpeg",urls:[_.dataUrl],dimensions:[{width:_.width,height:_.height}],visionDetail:g==="compact"?"low":"high"};return H(h,`Rendered ${P}\
|
|
857
|
-
of ${_.totalPages} in ${w} mode at ${g} quality, ${k} view.${k===
|
|
856
|
+
of ${_.totalPages} in ${w} mode at ${g} quality, ${k} view.${k===Nt?"":` This is an isolated preview with ${_.snapshot?`all ${_.snapshot.pendingSuggestionCount}`:"all"} pending suggestions ${k==="sho\
|
|
858
857
|
w-with-tracked-changes-accepted"?"accepted":"rejected"}; no suggestion was accepted or rejected in the document, and the page count is for this view.`}${_.snapshot?.description?` ${_.snapshot.description}`:
|
|
859
858
|
""}${S?" The request was downgraded from detailed to compact quality so all requested pages fit in one bounded render.":""}`,E,void 0,JSON.stringify({pages:_.pages,totalPages:_.totalPages,mode:w,quality:g,
|
|
860
859
|
view:k,..._.snapshot?{snapshot:_.snapshot}:{},placeholderImageCount:_.placeholderImageCount,failedImageCount:_.failedImageCount,mathPlaceholderCount:_.mathPlaceholderCount}))}catch(_){return v(h,_ instanceof
|
|
@@ -870,31 +869,31 @@ h,`${$} requires a final user-facing response, not only a status update.`,$o);if
|
|
|
870
869
|
as an array.`);let p;if(s.completed_plan_item_ids!=null||s.completed_plan_steps!=null){if(!e.getPlanState||!e.setPlanState)return v(h,"This host does not support task plans.","plan_unavailable");const w=s.
|
|
871
870
|
completed_plan_item_ids??[];if(!Array.isArray(w)||w.some(k=>typeof k!="string"))return v(h,"completed_plan_item_ids must be an array of current-plan item IDs.","invalid_plan_update");const g=s.completed_plan_steps??
|
|
872
871
|
[];if(!Array.isArray(g)||g.some(k=>typeof k!="string"||!k.trim()))return v(h,"completed_plan_steps must be an array of new non-empty requirements.","invalid_plan_update");if(w.length>0||g.length>0)try{
|
|
873
|
-
const k=e.getPlanState(),S=jn(k,"update_plan",{plan_id:k.plan?.id,updates:w.map(
|
|
872
|
+
const k=e.getPlanState(),S=jn(k,"update_plan",{plan_id:k.plan?.id,updates:w.map(N=>({item_id:N,status:"completed"})),add_steps:g});for(const N of S.plan.items.slice(k.plan.items.length))N.status="comp\
|
|
874
873
|
leted";p=()=>{e.getPlanState()===k&&(e.setPlanState(S),e.markConversationDirty())}}catch(k){return v(h,k instanceof Error?k.message:String(k),"invalid_plan_update")}}return{...H(h,"Final response reco\
|
|
875
874
|
rded."),...p?{commitPlanCompletion:p}:{}}}const me=await L();if(!me)return O(h);const V=e.getLatestDocument();if($==="rollback_agent_suggestions"){const s=h.arguments??{},m=s.request_id==null?void 0:s.
|
|
876
875
|
request_id,p=s.turn==null?void 0:s.turn;if(m!==void 0&&(!Number.isInteger(m)||Number(m)<1))return v(h,"request_id must be a positive integer.");if(p!==void 0&&(!Number.isInteger(p)||Number(p)<1))return v(
|
|
877
876
|
h,"turn must be a positive integer.");if(p!==void 0&&m===void 0)return v(h,"turn requires request_id.");const w=e.turnState.currentRequestId??0,g=e.turnState.currentTurn??0;if(m!==void 0&&Number(m)>w)
|
|
878
877
|
return v(h,`request_id ${m} is in the future; the current request is ${w}.`);const k=e.getConversationId?.().trim()??"";if(!k)return v(h,"This conversation has no stable ID, so its suggestions cannot \
|
|
879
|
-
be rolled back safely.");const S=me.getDocumentWithPendingSuggestionsApplied(),
|
|
880
|
-
p),currentRequestId:w,currentTurn:g});if(
|
|
878
|
+
be rolled back safely.");const S=me.getDocumentWithPendingSuggestionsApplied(),N=me.rollbackAgentSuggestions({agentConversationId:k,requestId:m===void 0?void 0:Number(m),turn:p===void 0?void 0:Number(
|
|
879
|
+
p),currentRequestId:w,currentTurn:g});if(N.resolvedCount===0){const E=N.requestId===void 0?"any prior request":`request ${N.requestId}${N.turn===void 0?"":` turn ${N.turn}`}`;return H(h,`No still-pend\
|
|
881
880
|
ing suggestions from this conversation matched ${E}. Accepted edits and other authors' work were left untouched. Recover omitted text from historical_edit_evidence or earlier before_block snapshots, t\
|
|
882
881
|
hen 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 _=me.getDocumentWithPendingSuggestionsApplied(),
|
|
883
882
|
x=new Map(S.children.map(E=>[E.id,E])),P=new Map(_.children.map(E=>[E.id,E]));for(const E of new Set([...x.keys(),...P.keys()]))JSON.stringify(x.get(E))!==JSON.stringify(P.get(E))&&e.toolState.editedBlockIds.
|
|
884
|
-
add(E);return e.turnState.hasMutatedSinceLastRead=!0,f+=1,e.markConversationDirty(),e.notifyListeners(),H(h,`Rolled back ${
|
|
885
|
-
`to before request ${
|
|
883
|
+
add(E);return e.turnState.hasMutatedSinceLastRead=!0,f+=1,e.markConversationDirty(),e.notifyListeners(),H(h,`Rolled back ${N.resolvedCount} pending suggestion${N.resolvedCount===1?"":"s"} ${N.turn===void 0?
|
|
884
|
+
`to before request ${N.requestId}`:`from request ${N.requestId} turn ${N.turn}`}. The rollback is one user-undoable history item. Now make the corrected edits; do not ask the user to reject the old su\
|
|
886
885
|
ggestions.`)}if($==="leave_comment"){const s=Cs(h,e,me,V);return s.success&&(f+=1),s}if(($==="insert_block"||$==="insert_table_row"||$==="insert_table_column")&&h.arguments?.position!=="before"&&h.arguments?.
|
|
887
886
|
position!=="after")return v(h,`${$} has invalid "position" ${JSON.stringify(h.arguments?.position??null)}; use "before" or "after".`);if($==="set_header_footer"&&h.arguments?.side!=="header"&&h.arguments?.
|
|
888
887
|
side!=="footer")return v(h,`set_header_footer has invalid "side" ${JSON.stringify(h.arguments?.side??null)}; use "header" or "footer".`);const Oe=Ye(V,e.toolState.tableContext,Vt(e.turnState)??new Set);
|
|
889
|
-
if($==="move_blocks"){const s=
|
|
890
|
-
children.length<=30?V.children.filter(k=>Oe.has(k.id)).map(k=>({id:k.id,text:
|
|
888
|
+
if($==="move_blocks"){const s=We(h.arguments),m=new Set([...V.children.map(g=>g.id),...e.getDocumentSession()?.getWorkingDocument().children.map(g=>g.id)??[]]),p=s.filter(g=>!m.has(g));if(p.length){const g=V.
|
|
889
|
+
children.length<=30?V.children.filter(k=>Oe.has(k.id)).map(k=>({id:k.id,text:Xe(k).slice(0,80)})):[];return v(h,`Move targets are not current top-level block IDs: ${p.map(k=>JSON.stringify(k)).join(",\
|
|
891
890
|
")}. Use current IDs from the document; read the relevant range if IDs are stale. This is an invalid target, not an unread-block error.${g.length?` Current already-read blocks in document order: ${JSON.
|
|
892
891
|
stringify(g)}.`:""}`,"invalid_move_target")}const w=s.filter(g=>!$t(V,g,Oe));if(w.length)return v(h,`Move targets were not read in this request: ${w.slice(0,10).join(", ")}. Read the source range and \
|
|
893
|
-
destination before moving.`,Be)}const ct=
|
|
892
|
+
destination before moving.`,Be)}const ct=Di({toolCall:h,docBefore:V});if(ct?.error)return v(h,ct.error,"invalid_block_range");const xe=Ci({toolCall:ct?.toolCall??h,docBefore:V,isTargetAllowed:s=>$t(V,
|
|
894
893
|
s,Oe)});if(xe?.error)return v(h,xe.error,xe.errorCode);const tn=xe?.toolCall??ct?.toolCall??h,nn=new Set(Oe??[]);for(const s of xe?.targetBlockIds??[])nn.add(s);const de=Xo({toolCall:tn,docBefore:V,resultSets:y});
|
|
895
894
|
if(de?.error)return v(h,de.error,de.errorCode);const je=Vs(tn,V,nn);if(je.error)return v(h,je.error,Be);const B=je.toolCall;if(B.name==="replace"&&B.arguments&&Array.isArray(B.arguments.replacements)&&
|
|
896
895
|
Object.prototype.hasOwnProperty.call(B.arguments,"comment"))return v(B,'replace comment belongs on each operation inside "replacements", alongside find, replace, and occurrence.');const Ho=new Set(V.children.
|
|
897
|
-
map(s=>s.id)),
|
|
896
|
+
map(s=>s.id)),Ge=new Set(Oe??[]);for(const s of xe?.targetBlockIds??[])Ge.add(s);for(const s of de?.targetBlockIds??[])Ge.add(s);const dt=Ai(B,V,s=>$t(V,s,Ge));if(dt.error)return v(B,dt.error,dt.error.
|
|
898
897
|
includes("request-level document context")?Be:void 0);const ce=(j=e.toolState).tableContext??(j.tableContext=Un()),on={responseTurn:e.turnState.currentTurn,hasForeignSuggestion:s=>{const m=me.getDocumentMutator(),
|
|
899
898
|
p=re(me.getWorkingDocument(),s.id);return p?m.getLiveSuggestionIdsForBlock(p).some(w=>{const g=m.getLiveSuggestion(w),k=e.getConversationId?.();return!ce.ownedSuggestionIds?.includes(w)&&!(k&&g?.agentConversationId===
|
|
900
899
|
k)}):!1}},Y=B.name==="edit_table_cells"?zn(V,ce,B.arguments,on):null,rn=s=>{const m=s.filter(g=>g.reason.includes("not delivered"));if(!m.length)return{};const p=m[0].column,w=[...new Set(m.filter(g=>g.
|
|
@@ -903,36 +902,36 @@ this failed cell batch; preserve the original task and exact requested values."}
|
|
|
903
902
|
Compaction can retire older read windows. Preserve the original task and continue until its full scope is complete.",remaining_unread_target_count:m.length-w.length}};if(Y?.errors.length)return{...v(
|
|
904
903
|
B,"No cells changed. Resolve every listed target error and retry the batch.",So),toolOutput:JSON.stringify({errors:Y.errors,...rn(Y.errors),skipped:Y.skipped,changed_count:0})};const Se=Y?{actions:Y.actions.
|
|
905
904
|
map((s,m)=>({...s,id:`${B.id}-${m}`})),blockId:void 0,error:void 0}:de?{actions:de.actions,blockId:void 0,error:void 0}:B.name==="remove_block"&&Array.isArray(B.arguments?.ids)?{actions:dt.actions,blockId:void 0,
|
|
906
|
-
error:void 0}:Qo(B,{doc:V,loadedBlockIds:
|
|
905
|
+
error:void 0}:Qo(B,{doc:V,loadedBlockIds:Ge});if(Se.error){const s="failure"in Se?Se.failure:void 0;return{...v(B,Se.error,s?.code),failure:s}}if(Se.actions.length===0)return Y?H(B,"No cells changed; \
|
|
907
906
|
inspect skipped and unchanged targets before continuing.",void 0,!0,JSON.stringify({changed_count:0,skipped:Y.skipped,unchanged:Y.unchanged})):H(B,`${To(B)} Continue with the remaining work; do not re\
|
|
908
|
-
peat this unchanged operation.`,void 0,!0);const Tt=Y?{actions:Se.actions,retargets:[]}:Zo({actions:Se.actions,doc:V,loadedBlockIds:
|
|
907
|
+
peat this unchanged operation.`,void 0,!0);const Tt=Y?{actions:Se.actions,retargets:[]}:Zo({actions:Se.actions,doc:V,loadedBlockIds:Ge}),Pe=Tt.actions,he=Array.from(new Set([...de?.targetBlockIds??[],
|
|
909
908
|
...xe?.targetBlockIds??[],...Ms(Pe)])),sn=s=>{if(!e.toolState.tableContext?.scopedTableIds?.length||B.name==="edit_table_cells"||["style_blocks","clear_formatting"].includes(B.name))return;const m=e.toolState.
|
|
910
|
-
tableContext.scopedTableIds;if(["insert_table_row","insert_table_column","remove_table_row","remove_table_column"].includes(B.name))return
|
|
909
|
+
tableContext.scopedTableIds;if(["insert_table_row","insert_table_column","remove_table_row","remove_table_column"].includes(B.name))return Vr(s,e.toolState.tableContext,B.name,B.arguments)?void 0:v(B,
|
|
911
910
|
B.name==="remove_table_row"?As(s,B.arguments):"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\
|
|
912
911
|
for deletions.",Be);const p=Ye(s,e.toolState.tableContext,Vt(e.turnState)??new Set);for(const w of he){if(xe?.targetBlockIds.includes(w))continue;const g=re(s,w);if(m.some(k=>{const S=re(s,k);return S&&
|
|
913
|
-
ue(S).includes(w)||g&&ue(g).includes(k)})&&!p.has(w)){let k=!1;g&&
|
|
912
|
+
ue(S).includes(w)||g&&ue(g).includes(k)})&&!p.has(w)){let k=!1;g&&Le(g,()=>k=!0);const S=g&&!k&&!["table-row","table-cell"].includes(g.type)?`Read it with read_specific_blocks(block_ids=["${w}"]), the\
|
|
914
913
|
n retry`:"Use read_table for its cells";return v(B,`Target '${w}' was not fully read. ${S}; a table preview or cell_text page does not authorize edits.`,Be)}}if(!he.length&&!["set_title","set_notes","\
|
|
915
914
|
set_page_layout","set_header_footer","insert_block"].includes(B.name))return v(B,"This broad operation includes partially read tables. Read their cells or target fully delivered block IDs explicitly.",
|
|
916
915
|
Be)},an=sn(V);if(an)return an;const ln=["insert_table_row","remove_table_row","insert_table_column","remove_table_column"].includes(B.name),cn=new Map;if((B.name==="replace_block"||B.name==="move_bloc\
|
|
917
916
|
ks"||B.name==="remove_block"||ln&&!e.toolState.tableContext?.scopedTableIds?.includes(String(B.arguments.tableId)))&&e.turnState.promptBlockContentHashes)for(const s of Do(V,he)){const m=re(V,s),p=m?new Set(
|
|
918
|
-
ue(m)):new Set,w=he.filter(k=>p.has(k));if(w.length&&w.every(k=>(ce.scopedTableIds??[]).some(S=>{const
|
|
917
|
+
ue(m)):new Set,w=he.filter(k=>p.has(k));if(w.length&&w.every(k=>(ce.scopedTableIds??[]).some(S=>{const N=re(V,S);return N&&ue(N).includes(k)})))continue;const g=e.turnState.promptBlockContentHashes.get(
|
|
919
918
|
s);g&&cn.set(s,g)}const dn=s=>{for(const[m,p]of cn){const w=Pt(s,m);if(w!==null&&w!==p)return v(B,`Block '${m}' was edited (likely by the user) after you last read it. Re-read the block and re-apply y\
|
|
920
|
-
our change against its current content.`,De)}},un=dn(V);if(un)return un;const mn=B.id||`tool-${Date.now()}`,
|
|
921
|
-
"1 external image":`${
|
|
919
|
+
our change against its current content.`,De)}},un=dn(V);if(un)return un;const mn=B.id||`tool-${Date.now()}`,Ne=await(e.rehostImages??Pn)(Pe);if(Ne.failedUrls.length>0){const s=Ne.failedUrls.length===1?
|
|
920
|
+
"1 external image":`${Ne.failedUrls.length} external images`,m=Ne.failures.some(g=>g.status===429),p=Ne.failures.length===1?Ne.failures[0]:void 0,w=p?` Reason: ${p.message}${p.status?` (HTTP ${p.status}\
|
|
922
921
|
)`:""}.`:"";return v(B,`${s} could not be copied into Revise storage, so no document changes were applied.${w} ${m?"Do not attempt more external image insertions in this request. Keep any earlier succ\
|
|
923
|
-
essful 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."}`,
|
|
922
|
+
essful 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."}`,Ne.unavailable?"a\
|
|
924
923
|
gent_tool_not_allowed":void 0)}const ye=e.getLatestDocument(),hn=sn(ye);if(hn)return hn;if(Y){const s=zn(ye,ce,B.arguments,on);if(s.errors.length||JSON.stringify(s.targets)!==JSON.stringify(Y.targets))
|
|
925
924
|
return{...v(B,"Table targets changed while preparing this batch; no cells changed. Reread and retry.",So),toolOutput:JSON.stringify({errors:s.errors,...rn(s.errors),skipped:s.skipped,changed_count:0})}}
|
|
926
|
-
const pn=dn(ye);if(pn)return pn;let G;const
|
|
925
|
+
const pn=dn(ye);if(pn)return pn;let G;const Ke=B.name==="remove_block"?[...new Set(Pe.map(s=>typeof s.arguments?.id=="string"?ht(V,s.arguments.id):null).filter(s=>s!==null))]:[];if(Ke.length>0&&Pe.some(
|
|
927
926
|
s=>s.arguments?.count!=null&&s.arguments.count!==1||typeof s.arguments?.id!="string"||!ht(V,s.arguments.id)))return v(B,"To remove footnotes/endnotes, pass their exact note IDs in ids, or one note ID \
|
|
928
927
|
as id. Remove main-document blocks separately.");for(const s of Pe){if(s.name!=="replace_block")continue;const m=ye.notes?.find(p=>p.id===s.arguments?.id);if(m&&yn(ye,m.id)===m.id)return v(B,`Note '${m.
|
|
929
|
-
id}' contains multiple body blocks or no single editable text block. Use replace_block with an exact body block ID (${m.children.map(p=>p.id).join(", ")}) instead of replacing the note wrapper.`)}if(
|
|
928
|
+
id}' contains multiple body blocks or no single editable text block. Use replace_block with an exact body block ID (${m.children.map(p=>p.id).join(", ")}) instead of replacing the note wrapper.`)}if(Ke.
|
|
930
929
|
length>0){const s=me.getDocumentMutator(),m=new Set(s.getLiveSuggestionIds()),p=s.suggestingMode;s.suggestingMode=!0;let w=!1;try{const{result:k}=s.withSuggestionMetadata({source:"agent",authorType:"a\
|
|
931
|
-
i",agentName:
|
|
932
|
-
commentThreadId,historyOrigin:`live-suggestions:${mn}`},()=>
|
|
933
|
-
agentFeedback:`Removed footnote/endnote blocks ${
|
|
930
|
+
i",agentName:ze(e),...e.getAgentModel?{agentModel:e.getAgentModel()}:{},agentConversationId:e.getConversationId?.(),agentRequestId:e.turnState.currentRequestId,agentTurn:e.turnState.currentTurn,commentThreadId:e.
|
|
931
|
+
commentThreadId,historyOrigin:`live-suggestions:${mn}`},()=>Ke.every(S=>s.removeFootnote(S)));w=k}finally{s.suggestingMode=p}const g=s.getLiveSuggestionIds().filter(k=>!m.has(k));G=w?{success:!0,suggestionIds:g,
|
|
932
|
+
agentFeedback:`Removed footnote/endnote blocks ${Ke.join(", ")} and their inline references.`}:{success:!1,error:`Footnote/endnote blocks '${Ke.join(", ")}' could not be removed.`}}else G=me.applyAgentActions(
|
|
934
933
|
{message:"AI Assistant",actions:Pe.map(s=>{if((s.name==="replace"||s.name==="replace_all"||s.name==="replace_block")&&typeof s.arguments?.id=="string"){const m=yn(ye,s.arguments.id);if(m&&m!==s.arguments.
|
|
935
|
-
id)return{...s,arguments:{...s.arguments,id:m}}}return s}),agentName:
|
|
934
|
+
id)return{...s,arguments:{...s.arguments,id:m}}}return s}),agentName:ze(e),agentModel:e.getAgentModel?.(),agentConversationId:e.getConversationId?.(),agentRequestId:e.turnState.currentRequestId,agentTurn:e.
|
|
936
935
|
turnState.currentTurn,commentThreadId:e.commentThreadId},mn,{optimizeStyleFormatting:e.getOptimizeStyleFormatting?.()??!1,applyBlockMovesDirectly:e.toolState.directMode,directMode:e.toolState.directMode});
|
|
937
936
|
if(G.resultCode==="already_satisfied")return H(B,(G.styleEffects||$==="move_blocks")&&G.agentFeedback?G.agentFeedback:"Verified that the requested state is already satisfied; no document mutation occu\
|
|
938
937
|
rred. "+To(B),void 0,!0,JSON.stringify({code:"already_satisfied",mutationOutcome:"unchanged",...$==="move_blocks"&&G.agentFeedback?{summary:G.agentFeedback}:{},...G.styleEffects?JSON.parse(Po(B,V,V,G.
|
|
@@ -952,18 +951,18 @@ mment was":"their comments were"} not added: no change remains there to explain.
|
|
|
952
951
|
${s}`:s}if(fe){const s=Ks(B,V);s&&(X=X?`${X}
|
|
953
952
|
${s}`:s)}if(e.toolState.directMode&&fe){const s=new Set(G.commentedSuggestionIds??[]),m=(G.suggestionIds??[]).filter(p=>!s.has(p));if(m.length>0&&me.acceptLiveSuggestions(m),m.length>0&&s.size===0){const p=me.
|
|
954
953
|
getDocumentMutator();p?.resetToolCallHistory&&p.resetToolCallHistory()}}if(fe){e.mutationTools.includes($)&&(f+=1);const s=me.getDocumentWithPendingSuggestionsApplied();if($==="move_blocks"&&s.children.
|
|
955
|
-
length<=30){const m=new Set(V.children.map(w=>w.id)),p=s.children.filter(w=>Oe.has(w.id)||!m.has(w.id)).map(w=>({id:w.id,text:
|
|
954
|
+
length<=30){const m=new Set(V.children.map(w=>w.id)),p=s.children.filter(w=>Oe.has(w.id)||!m.has(w.id)).map(w=>({id:w.id,text:Xe(w).slice(0,80)}));X=`${X??"Move completed."} Current already-read block\
|
|
956
955
|
s in document order: ${JSON.stringify(p)}.`}if(ln&&typeof B.arguments.tableId=="string"){const m=Et(s,{table_id:B.arguments.tableId,mode:"summary"});m.error||(ce.geometries??(ce.geometries={}),ce.geometries[m.
|
|
957
956
|
table_id]=m.revision)}if(!Y){const m=Ye(ye,ce,new Set);for(const p of Object.values(ce.cells))m.has(p.cellId)&&p.blockIds.some(w=>he.includes(w))&&_t(s,ce,p.tableId,[p.cellId]);for(const[p,w]of Object.
|
|
958
957
|
entries(ce.blocks??{}))m.has(p)&&w.blockIds.some(g=>he.includes(g))&&Ln(s,ce,w.tableId,p)}if(de?.resultSet&&(de.resultSet.blockHashes=Dt(s,de.resultSet.blockIds)),ut=Y?void 0:Po(B,V,s,he,X,G.styleEffects),
|
|
959
958
|
Y){const m=String(B.arguments.table_id);_t(s,ce,m,Y.targets.map(S=>S.cellId));const p=e.turnState.currentTurn??0;ce.responseClaims={turn:p,cellIds:[...ce.responseClaims?.turn===p?ce.responseClaims.cellIds:
|
|
960
|
-
[],...Y.targets.map(S=>S.cellId)]},ce.ownedSuggestionIds=[...ce.ownedSuggestionIds??[],...G.suggestionIds??[]];const w=
|
|
961
|
-
0,tableId:m,cellIds:Y.targets.map(S=>S.cellId)});e.toolState.tableTasks=w,e.setTableTaskState?.(w);const g=[];let k=0;if(B.arguments.mode==="replace")for(const S of Y.targets){const
|
|
962
|
-
_=
|
|
959
|
+
[],...Y.targets.map(S=>S.cellId)]},ce.ownedSuggestionIds=[...ce.ownedSuggestionIds??[],...G.suggestionIds??[]];const w=xi(e.getTableTaskState?.()??e.toolState.tableTasks??Zn(),{requestId:e.turnState.currentRequestId??
|
|
960
|
+
0,tableId:m,cellIds:Y.targets.map(S=>S.cellId)});e.toolState.tableTasks=w,e.setTableTaskState?.(w);const g=[];let k=0;if(B.arguments.mode==="replace")for(const S of Y.targets){const N=re(ye,S.paragraphId),
|
|
961
|
+
_=N?.type==="paragraph"?N.children.map(P=>P.type==="text"?P.text:"").join(""):null,x={row_id:S.row_id,column:S.column,previous_text:_??""};_===null||JSON.stringify([...g,x]).length>8e3?k++:g.push(x)}ut=
|
|
963
962
|
JSON.stringify({tool:"edit_table_cells",...B.arguments.mode==="replace"?{previous_cells:g,omitted_previous_cells:k,...k?{previous_values_recovery:"Some prior values were omitted from this bounded look\
|
|
964
963
|
back. 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 t\
|
|
965
964
|
he current document."}:{}}:{},table_id:m,proposed_cell_count:Y.targets.length,changed_count:Y.targets.length,rows:[...new Set(Y.targets.map(S=>S.row_id))],skipped:Y.skipped,unchanged:Y.unchanged,remaining_empty_in_working_document:Et(
|
|
966
|
-
s,{table_id:m,mode:"summary"}).columns.filter(S=>Y.targets.some(
|
|
965
|
+
s,{table_id:m,mode:"summary"}).columns.filter(S=>Y.targets.some(N=>N.column===S.column)),status:e.toolState.directMode?"applied":"proposed_pending_review"})}if(e.turnState.hasMutatedSinceLastRead=!0,e.
|
|
967
966
|
mutationTools.includes($)&&$!=="set_title"&&$!=="set_notes"&&$!=="set_page_layout"){if(!de)for(const m of he)e.toolState.editedBlockIds.add(m);if(!de)for(const m of s.children)m.id&&!Ho.has(m.id)&&e.toolState.
|
|
968
967
|
editedBlockIds.add(m.id);if(e.turnState.promptBlockContentHashes){const m=Do(ye,he);for(const p of m){const w=e.turnState.promptBlockContentHashes.get(p);if(w&&Pt(ye,p)!==w||!w&&!he.includes(p))continue;
|
|
969
968
|
const g=Pt(s,p);g!==null?e.turnState.promptBlockContentHashes.set(p,g):e.turnState.promptBlockContentHashes.delete(p)}}de||Qs(e)}}const gn=Ts(G.error);return{toolCall:B,success:fe,error:G.error,failure:G.
|
|
@@ -994,18 +993,18 @@ tes")?t:{...t,context_notes:sa}}const zo=new Set(["get_selection","view_image"])
|
|
|
994
993
|
e),n=t.properties;return delete n?.document_id,Array.isArray(t.required)&&(t.required=t.required.filter(o=>o!=="document_id")),t}function da(e){return e.split(/(?<=\.)\s+/).filter(t=>!la.some(n=>t.includes(
|
|
995
994
|
n))).join(" ")}const Ct=ta.filter(e=>!zo.has(e.name)).map(e=>({name:e.name,description:da(e.description),inputSchema:ca(e.inputSchema)})),Jo=new WeakSet;function ua(e){Jo.add(e)}function ma(e,t){if(!t.
|
|
996
995
|
documentId.trim())throw new Error("Revise: documentId is required for a server session.");const n=new Ko(t.documentId,e,void 0,{disableHistory:!0,disableProposalPersistence:!0}),o=new Set(Bt);let r=t.
|
|
997
|
-
mode??"suggesting";n.setSuggestingMode(r==="suggesting"),n.setDocxRoundTripRequired(Jo.has(e));const i=
|
|
996
|
+
mode??"suggesting";n.setSuggestingMode(r==="suggesting"),n.setDocxRoundTripRequired(Jo.has(e));const i=Lr(t.images),a=new ia({getDocumentSession:()=>n,mutationTools:Array.from(Bt),searchPageSize:t.searchPageSize,
|
|
998
997
|
getAgentName:()=>t.agentName,rehostImages:T=>Pn(T,i)});let l=1,c=!1,d=Promise.resolve();const u=()=>{if(c)throw new Error("Revise: server document session is disposed.")},f=(T,D,A,M)=>({ok:!1,error:{callId:T,
|
|
999
998
|
tool:D,code:A,message:M}}),b=async(T,D,A,M)=>{u();const I=`server-tool-${l++}`;if(!Ct.some(q=>q.name===T)&&!aa.has(T))return f(I,T,"unknown_tool",`Unknown or unavailable server document tool: ${T}`);if("\
|
|
1000
999
|
document_id"in D)return f(I,T,"document_id_not_supported","document_id is not accepted: a server document session is bound to one document. Omit it and retry.");await hr(),u(),n.setSuggestingMode(M===
|
|
1001
1000
|
"suggesting");const C=o.has(T)?new Set(n.getDocumentMutator().getLiveSuggestionIds()):null;try{const q=await a.run({id:I,name:T,arguments:D},{directMode:A.directMode??M==="editing"}),J=a.buildResult(I,
|
|
1002
1001
|
T,q);return oa(J,C?n.getDocumentMutator().getLiveSuggestionIds().filter(z=>!C.has(z)):null)}catch(q){return f(I,T,"internal_error",q instanceof Error?q.message:String(q))}finally{n.setSuggestingMode(r===
|
|
1003
|
-
"suggesting")}},y=(T,D,A)=>{const M=r,I=d.then(()=>b(T,D,A,M));return d=I.then(()=>{},()=>{}),I},
|
|
1004
|
-
const[A={},M={}]=D;return y(T,Fo(T,A,Ct),M)},executeDynamic:(T,D={},A={})=>y(T,D,A),call:async(T,...D)=>{const[A={},M={}]=D,I=await y(T,Fo(T,A,Ct),M);if(!I.ok)throw new
|
|
1002
|
+
"suggesting")}},y=(T,D,A)=>{const M=r,I=d.then(()=>b(T,D,A,M));return d=I.then(()=>{},()=>{}),I},R={getDefinitions:()=>(u(),Ct.map(T=>({...T,inputSchema:structuredClone(T.inputSchema)}))),execute:(T,...D)=>{
|
|
1003
|
+
const[A={},M={}]=D;return y(T,Fo(T,A,Ct),M)},executeDynamic:(T,D={},A={})=>y(T,D,A),call:async(T,...D)=>{const[A={},M={}]=D,I=await y(T,Fo(T,A,Ct),M);if(!I.ok)throw new kr(I.error);return I.value}},L=()=>{
|
|
1005
1004
|
u();const T=n.getDocumentMutator();return T.getLiveSuggestionIds().map(D=>{const A=T.getLiveSuggestion(D),M=T.getInlineSuggestionMetadataFromDocument(D),I=A&&"blockId"in A?A.blockId:A?.type==="paragra\
|
|
1006
1005
|
ph-merge"?A.firstBlockId:void 0,C={id:D,...A?.type?{type:A.type}:{},...I?{blockId:I}:{},...A?.type==="table-change"?{tableId:A.tableId}:{}};for(const q of["authorType","agentName","agentModel","source",
|
|
1007
1006
|
"label","createdAt"]){const J=M?.[q]??A?.[q];J!==void 0&&Object.assign(C,{[q]:J})}return C})},O=(T,D)=>{u();const A=Array.from(new Set(D.filter(z=>typeof z=="string"&&z.trim().length>0))),M=n.getDocumentMutator(),
|
|
1008
1007
|
I=new Set(M.getLiveSuggestionIds()),C=A.filter(z=>!I.has(z)),q=A.filter(z=>I.has(z));q.length>0&&(T==="accept"?n.acceptLiveSuggestions(q):n.rejectLiveSuggestions(q));const J=new Set(M.getLiveSuggestionIds());
|
|
1009
|
-
return{resolved:q.filter(z=>!J.has(z)),missing:C,unresolved:q.filter(z=>J.has(z))}};return{getMode:()=>(u(),r),setSuggestingMode:()=>{u(),r="suggesting"},setEditingMode:()=>{u(),r="editing"},tools:
|
|
1008
|
+
return{resolved:q.filter(z=>!J.has(z)),missing:C,unresolved:q.filter(z=>J.has(z))}};return{getMode:()=>(u(),r),setSuggestingMode:()=>{u(),r="suggesting"},setEditingMode:()=>{u(),r="editing"},tools:R,getPendingSuggestionIds:()=>(u(),
|
|
1010
1009
|
n.getDocumentMutator().getLiveSuggestionIds()),listSuggestions:L,acceptSuggestions:T=>O("accept",T),rejectSuggestions:T=>O("reject",T),acceptAllSuggestions:()=>(u(),O("accept",n.getDocumentMutator().getLiveSuggestionIds())),
|
|
1011
1010
|
rejectAllSuggestions:()=>(u(),O("reject",n.getDocumentMutator().getLiveSuggestionIds())),dispose:()=>{c||(c=!0,n.dispose())}}}export{ma as createServerDocumentSession,ua as requireDocxRoundTrip};
|