page-agent-sdk 3.44.0 → 3.44.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/README.md +2 -2
- package/README.zh-CN.md +2 -2
- package/dist/page-agent-sdk.headless.js +39 -32
- package/dist/page-agent-sdk.iife.js +6 -6
- package/dist/page-agent-sdk.js +39 -32
- package/dist/page-agent-sdk.legacy.js +39 -32
- package/dist/page-agent-sdk.umd.cjs +6 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
[](https://www.npmjs.com/package/page-agent-sdk)
|
|
10
10
|
[](https://github.com/whyymj/page-agent-sdk/blob/master/LICENSE)
|
|
11
|
-
[](#self-tests)
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
@@ -495,7 +495,7 @@ function switchTo(i: number) {
|
|
|
495
495
|
## Self-tests
|
|
496
496
|
|
|
497
497
|
```bash
|
|
498
|
-
npm test #
|
|
498
|
+
npm test # 2882 assertions (tsx, source-level; no LLM dependency)
|
|
499
499
|
npm run test:e2e # 940 integration assertions (node, built dist; covers APIs/options/modules/simple&complex scenes: default systemPrompt(capability overview) / dynamic register + inspect sync / inspect(tools/middleware/subagent/verify/mcp/todos/lastCompression/checkpoints reflect config) / custom tools/middleware/skills/memory injection / runtime dynamic reconfiguration(setTools/addTool/removeTool/setLlm/setMemory/setSubagents reflect) / switchSession(on/off) / shareContext on/off sharing/independent / storage backends + object config / presets(3) / checkpoint / exports complete(39+ fns/components) / util fns usable(isQuotaError/estimateTokens/jpEval/searchJson) / source=builtin / mount boundary / hook multi-listener / llm config / hide/show / error scenes)
|
|
500
500
|
```
|
|
501
501
|
|
package/README.zh-CN.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
[](https://www.npmjs.com/package/page-agent-sdk)
|
|
10
10
|
[](https://github.com/whyymj/page-agent-sdk/blob/master/LICENSE)
|
|
11
|
-
[](#自测)
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
@@ -498,7 +498,7 @@ function switchTo(i: number) {
|
|
|
498
498
|
## 自测
|
|
499
499
|
|
|
500
500
|
```bash
|
|
501
|
-
npm test #
|
|
501
|
+
npm test # 2882 项断言(tsx 源码级,不依赖 LLM)
|
|
502
502
|
npm run test:e2e # 940 项集成断言(node 跑构建产物 dist;覆盖各 API/配置项/功能模块/简单与复杂场景:默认 systemPrompt(含能力概述) / 动态注册与 inspect 同步 / inspect(tools/middleware/subagent/verify/mcp/todos/lastCompression/checkpoints 反映配置) / 自定义 tools/middleware/skills/memory 注入 / 运行时动态重配置(setTools/addTool/removeTool/setLlm/setMemory/setSubagents 反映) / switchSession(开/未开) / shareContext 开/关共享独立 / storage 后端+对象配置 / presets 三预设 / checkpoint / 导出项完整(39+ 函数/组件) / 工具函数可用(isQuotaError/estimateTokens/jpEval/searchJson) / source=builtin / mount 边界 / hook 多监听器 / llm 配置 / 错误场景)
|
|
503
503
|
```
|
|
504
504
|
|
|
@@ -2957,7 +2957,7 @@ var aa = "", oa = "根(整体)", sa = /* @__PURE__ */ new Set([
|
|
|
2957
2957
|
]), ca = /* @__PURE__ */ new Set(["resource_update", "resource_delete"]), la = /* @__PURE__ */ new Set(["remove", "move"]);
|
|
2958
2958
|
function ua(e) {
|
|
2959
2959
|
let t = String(e).trim();
|
|
2960
|
-
return t === "(root)" || t === "$" ? aa : (t.startsWith("$.") ? t = t.slice(2) : t.startsWith("$") && (t = t.slice(1)), t);
|
|
2960
|
+
return t === "(root)" || t === "$" ? aa : (t.startsWith("$.") ? t = t.slice(2) : t.startsWith("$") && (t = t.slice(1)), t = t.replace(/\[(\d+)\]/g, ".$1"), t);
|
|
2961
2961
|
}
|
|
2962
2962
|
function da(e) {
|
|
2963
2963
|
let t = ua(e);
|
|
@@ -3220,9 +3220,9 @@ function Ga(e) {
|
|
|
3220
3220
|
function Ka(e, t) {
|
|
3221
3221
|
return !(!e.length || !e.some((e) => e.status !== "completed") || /[??]\s*$/.test(t));
|
|
3222
3222
|
}
|
|
3223
|
-
function qa(e) {
|
|
3224
|
-
let
|
|
3225
|
-
return `⚠️ 任务未完成:待办清单还有 ${
|
|
3223
|
+
function qa(e, t) {
|
|
3224
|
+
let n = e.filter((e) => e.status !== "completed"), r = n.map((e) => `#${e.id} [${e.status}] ${e.content.length > 60 ? `${e.content.slice(0, 60)}…` : e.content}`).join("\n"), i = e.filter((e) => e.status === "completed" && !e.evidence && (!t || t.get(e.id) !== "completed")), a = i.length ? `\n另有 ${i.length} 项已标记完成但 evidence 为空(${i.map((e) => `#${e.id}`).join("、")}):标记完成时请用 update_todo 附 evidence(本次实际写入的 jsonPath,如 components.2);经委派完成等无主写路径时如实写明完成方式。` : "";
|
|
3225
|
+
return `⚠️ 任务未完成:待办清单还有 ${n.length} 项未完成:\n${r}\n若这些工作实际已完成,请先用 update_todo 把它们全部标记 completed(或一次 write_todos 整表替换)再给出最终总结;若尚未完成,请继续执行剩余任务。不要中途停止。${a}`;
|
|
3226
3226
|
}
|
|
3227
3227
|
function Ja(e = [], n = {}) {
|
|
3228
3228
|
let i = Wa(e), a = 0, o = 0, s = !1, c = 0, l = n.maxPlanRevisions ?? 5;
|
|
@@ -3325,7 +3325,7 @@ function eo(e) {
|
|
|
3325
3325
|
gate: {
|
|
3326
3326
|
stage: "completion_gate",
|
|
3327
3327
|
attempt: t.completionRetries,
|
|
3328
|
-
feedback: qa(e.todos),
|
|
3328
|
+
feedback: qa(e.todos, e.todosStatusAtStart),
|
|
3329
3329
|
logData: { pending: e.todos.filter((e) => e.status !== "completed").map((e) => e.id) }
|
|
3330
3330
|
}
|
|
3331
3331
|
};
|
|
@@ -4085,14 +4085,14 @@ function Eo(e) {
|
|
|
4085
4085
|
for (let e = 0; e < o.length; e++) {
|
|
4086
4086
|
let t = h[e];
|
|
4087
4087
|
if (!t) continue;
|
|
4088
|
-
let n = `${o[e].call.name}|${JSON.stringify(o[e].call.args ?? {})}`,
|
|
4089
|
-
if (
|
|
4090
|
-
let e = (g.get(
|
|
4091
|
-
g.set(
|
|
4092
|
-
} else g.delete(
|
|
4088
|
+
let n = (e) => e && typeof e == "object" && !Array.isArray(e) ? Object.fromEntries(Object.keys(e).sort().map((t) => [t, n(e[t])])) : e, r = `${o[e].call.name}|${JSON.stringify(n(o[e].call.args ?? {}))}`, i = t.status === "error" || typeof t.content == "string" && t.content.startsWith("ERROR:"), a = t.content;
|
|
4089
|
+
if (i) {
|
|
4090
|
+
let e = (g.get(r) ?? 0) + 1;
|
|
4091
|
+
g.set(r, e), e >= 2 && (a = `${t.content}\n(提示:同参数已连续失败 ${e} 次,原样重试大概率仍失败;请检查参数/换路径/换方法,或向用户如实说明困难)`);
|
|
4092
|
+
} else g.delete(r);
|
|
4093
4093
|
c.push(new s({
|
|
4094
4094
|
tool_call_id: o[e].id,
|
|
4095
|
-
content:
|
|
4095
|
+
content: a
|
|
4096
4096
|
}));
|
|
4097
4097
|
}
|
|
4098
4098
|
for (let e = 0; e < o.length; e++) {
|
|
@@ -9013,42 +9013,49 @@ function Hu(e, n = {}) {
|
|
|
9013
9013
|
message: `jsonPath "${m}" 含非法段(__proto__/constructor/prototype)`,
|
|
9014
9014
|
hint: "使用正常属性路径,如 components.0.text(数组索引数字)"
|
|
9015
9015
|
});
|
|
9016
|
+
let h = (e, t) => {
|
|
9017
|
+
let n = (e ? Ao(o, e) : o)?.shape;
|
|
9018
|
+
return n && typeof n == "object" ? Object.keys(n) : t && typeof t == "object" && !Array.isArray(t) ? Object.keys(t) : [];
|
|
9019
|
+
};
|
|
9016
9020
|
if (!Oo(m, o, l)) {
|
|
9017
|
-
let e = /[.[]/.test(m) ? m.replace(/[.[][^.[]*$/, "") : "", t = e ? Q(s, e) : s, n = t
|
|
9021
|
+
let e = /[.[]/.test(m) ? m.replace(/[.[][^.[]*$/, "") : "", t = h(e, e ? Q(s, e) : s), n = t.length ? `;父级 "${e || "(root)"}" 的可用字段:${t.slice(0, 12).join(", ")}${t.length > 12 ? " …" : ""}` : "";
|
|
9018
9022
|
return X({
|
|
9019
9023
|
code: "PATH_DENIED",
|
|
9020
9024
|
message: `read @ "${m}" 不在 schema 声明字段内`,
|
|
9021
9025
|
hint: `主数据仅暴露 schema 声明的字段;若需操作该字段,集成方需在 schema 中声明它${n}`
|
|
9022
9026
|
});
|
|
9023
9027
|
}
|
|
9024
|
-
let
|
|
9025
|
-
if (m &&
|
|
9026
|
-
let e =
|
|
9027
|
-
|
|
9028
|
-
|
|
9029
|
-
|
|
9030
|
-
|
|
9031
|
-
|
|
9032
|
-
|
|
9028
|
+
let g = m ? Q(s, m) : s;
|
|
9029
|
+
if (m && g === void 0) {
|
|
9030
|
+
let e = Ao(o, m);
|
|
9031
|
+
if (!(e && typeof e.isOptional == "function" && e.isOptional())) {
|
|
9032
|
+
let e = /[.[]/.test(m) ? m.replace(/[.[][^.[]*$/, "") : "", t = e ? Q(s, e) : s, n = h(e, t), r = Array.isArray(t) ? `父级 "${e || "(root)"}" 是 ${t.length} 元数组,有效索引 0-${Math.max(t.length - 1, 0)};先 read({jsonPath:"${e}"}) 确认现状,追加元素走 write 的 append` : n.length ? `父级 "${e || "(root)"}" 的可用字段:${n.slice(0, 12).join(", ")}${n.length > 12 ? " …" : ""};先 read({jsonPath:"${e}"}) 确认` : `父级 "${e || "(root)"}" 不存在或不是容器;先 read() 不传 jsonPath 查看顶层字段`;
|
|
9033
|
+
return X({
|
|
9034
|
+
code: "PATH_NOT_FOUND",
|
|
9035
|
+
path: m,
|
|
9036
|
+
message: `路径 "${m}" 不存在`,
|
|
9037
|
+
hint: r
|
|
9038
|
+
});
|
|
9039
|
+
}
|
|
9033
9040
|
}
|
|
9034
|
-
if (!m && l)
|
|
9041
|
+
if (!m && l) g = Uo(g, o);
|
|
9035
9042
|
else if (l) {
|
|
9036
9043
|
let e = Ao(o, m);
|
|
9037
|
-
e && (
|
|
9044
|
+
e && (g = Uo(g, e));
|
|
9038
9045
|
}
|
|
9039
|
-
let
|
|
9040
|
-
p && (
|
|
9046
|
+
let _ = g;
|
|
9047
|
+
p && (_ = Tu({
|
|
9041
9048
|
jp: m,
|
|
9042
|
-
resolved:
|
|
9049
|
+
resolved: _,
|
|
9043
9050
|
resourcesByPath: p.resourcesByPath,
|
|
9044
9051
|
resourceStore: p.resourceStore
|
|
9045
|
-
})), b(f, d), n && n.length && (
|
|
9046
|
-
let
|
|
9047
|
-
if ((i !== void 0 || a !== void 0) && Array.isArray(
|
|
9048
|
-
let e =
|
|
9049
|
-
return `${
|
|
9052
|
+
})), b(f, d), n && n.length && (_ = As(_, n)), r != null && (_ = js(_, r)), _ = Lu(_, d === "", D, E);
|
|
9053
|
+
let y = e ? "" : `主数据说明: ${c}\n格式: 写入值需为 JSON,且通过声明的 schema 校验(校验失败时 write 会返回结构化错误)。字段约束(类型/min/max/enum/必填/默认)见 systemPrompt「可操作数据」段,或用 schema_data({ jsonPath }) 按需查。\n\n`, x = n && n.length ? `(字段裁剪:${n.join(",")})` : "", S = r == null ? "" : `(深度≤${r})`, C = x || S ? ` ${x}${S}` : "";
|
|
9054
|
+
if ((i !== void 0 || a !== void 0) && Array.isArray(_)) {
|
|
9055
|
+
let e = _.length, t = Math.max(0, i ?? 0), n = Math.min(200, Math.max(1, a ?? 50)), r = _.slice(t, t + n), o = t + n < e;
|
|
9056
|
+
return `${y}主数据${m ? ` @ ${m}` : ""} 数组分页[offset=${t},limit=${n}]${C} = ${$(r)} (total=${e}, hasMore=${o}) (hash=${f})`;
|
|
9050
9057
|
}
|
|
9051
|
-
return
|
|
9058
|
+
return _ === void 0 ? `${y}主数据${m ? ` @ ${m}` : ""}${C} = (undefined) (hash=${f})` : `${y}主数据${m ? ` @ ${m}` : ""}${C} = ${$(_)} (hash=${f})`;
|
|
9052
9059
|
}, {
|
|
9053
9060
|
name: "read",
|
|
9054
9061
|
description: "读取主数据(高层入口,合并 describe/get)。不传 jsonPath → 返回主数据说明 + 格式提示(含字段约束);传 jsonPath → 返回该子路径当前值 + hash;传 jsonPaths → 一次读多个不相关子路径(省多轮往返)。hash 用于乐观锁(声明 conflictWatchFields 后 write 自动比对;未声明不自动校验)。fields(字段裁剪)/depth(深度截断)减体积;offset+limit 对数组目标分页(返回切片 + total/hasMore)。",
|
|
@@ -160,21 +160,21 @@ self.onmessage = async (e) => {
|
|
|
160
160
|
self.postMessage({ ok: false, error: String((err && err.message) || err) });
|
|
161
161
|
}
|
|
162
162
|
};`,c=``,l;try{let e=new Blob([s],{type:`application/javascript`});c=URL.createObjectURL(e),l=new Worker(c)}catch(e){c&&URL.revokeObjectURL(c),r({ok:!1,error:`无法创建 Worker 沙箱: ${e.message}`,elapsedMs:0});return}let u=setTimeout(()=>o({ok:!1,error:`脚本执行超时(${t}ms),已终止`}),t);l.onmessage=e=>o(e.data),l.onerror=e=>o({ok:!1,error:e.message||`Worker 运行错误`});try{l.postMessage({data:n,script:e})}catch(e){o({ok:!1,error:`数据无法传递给 Worker(可能含不可克隆值): ${e.message}`})}})}}var DW=/[\w$-]/;function OW(e){let t=[],n=e.trim(),r=+(n[0]===`$`);for(;r<n.length;){let e=n[r];if(e===`.`){if(n[r+1]===`.`){if(r+=2,n[r]===`*`){t.push({type:`descendAll`}),r++;continue}let e=``;for(;r<n.length&&DW.test(n[r]);)e+=n[r++];if(!e)throw Error(`JSONPath: .. 后缺属性名`);t.push({type:`descendKey`,key:e});continue}if(r++,n[r]===`*`){t.push({type:`wildcard`}),r++;continue}let e=``;for(;r<n.length&&DW.test(n[r]);)e+=n[r++];if(!e)throw Error(`JSONPath: . 后缺属性名`);t.push({type:`key`,key:e});continue}if(e===`[`){r++;let e=n[r];if(e===`*`){t.push({type:`wildcard`}),r+=2;continue}if(e===`?`&&n[r+1]===`(`){r+=2;let e=1,i=``;for(;r<n.length&&e>0;){if(n[r]===`(`)e++;else if(n[r]===`)`&&(e--,e===0))break;i+=n[r++]}if(e!==0)throw Error(`JSONPath: 过滤表达式括号不匹配`);if(r++,n[r]!==`]`)throw Error(`JSONPath: 过滤表达式后缺 ]`);r++,t.push({type:`filter`,filter:i});continue}if(e===`'`||e===`"`){let i=e;r++;let a=``;for(;r<n.length&&n[r]!==i;)a+=n[r++];if(r++,n[r]!==`]`)throw Error(`JSONPath: 字符串索引后缺 ]`);r++,t.push({type:`key`,key:a});continue}let i=``;for(;r<n.length&&/[\d-]/.test(n[r]);)i+=n[r++];if(n[r]!==`]`)throw Error(`JSONPath: 索引后缺 ]`);r++,t.push({type:`index`,index:parseInt(i,10)});continue}throw Error(`JSONPath: 语法错误,意外字符 '${e}' @${r}`)}return t}function kW(e){let t=[],n=0,r=e.trim();for(;n<r.length;){let e=r[n];if(e===` `||e===` `||e===`
|
|
163
|
-
`){n++;continue}if(e===`@`||e===`.`){let e=``;for(;n<r.length&&/[@.\w$-]/.test(r[n]);)e+=r[n++];t.push(e);continue}if(e===`'`||e===`"`){let i=e,a=e;for(n++;n<r.length&&r[n]!==i;)a+=r[n++];a+=r[n]||``,n++,t.push(a);continue}if(/[\d-]/.test(e)){let e=``;for(;n<r.length&&/[\d.eE+-]/.test(r[n]);)e+=r[n++];t.push(e);continue}let i=r.slice(n,n+2);if(i===`==`||i===`!=`||i===`<=`||i===`>=`||i===`&&`||i===`||`){t.push(i),n+=2;continue}if(e===`<`||e===`>`||e===`(`||e===`)`){t.push(e),n++;continue}if(/[a-zA-Z_$]/.test(e)){let e=``;for(;n<r.length&&/[\w$]/.test(r[n]);)e+=r[n++];t.push(e);continue}throw Error(`过滤表达式:意外字符 '${e}'`)}return t}var AW=class{toks;item;pos=0;constructor(e,t){this.toks=e,this.item=t}parse(){let e=this.or();if(this.pos<this.toks.length)throw Error(`过滤表达式:尾部多余 token`);return e}peek(){return this.toks[this.pos]}next(){return this.toks[this.pos++]}or(){let e=this.and();for(;this.peek()===`||`;)this.next(),e=this.and()||e;return e}and(){let e=this.cmp();for(;this.peek()===`&&`;)this.next(),e=this.cmp()&&e;return e}cmp(){if(this.peek()===`(`){this.next();let e=this.or();if(this.peek()!==`)`)throw Error(`过滤表达式:缺 )`);return this.next(),e}let e=this.operand(),t=this.peek();return t===`==`||t===`!=`||t===`<`||t===`<=`||t===`>`||t===`>=`?(this.next(),NW(t,e,this.operand())):jW(e)}operand(){let e=this.next();if(e===void 0)throw Error(`过滤表达式:缺操作数`);if(e.startsWith(`@`))return MW(e,this.item);if(e[0]===`'`||e[0]===`"`)return e.slice(1,-1);if(e===`true`)return!0;if(e===`false`)return!1;if(e===`null`)return null;let t=Number(e);if(!Number.isNaN(t))return t;throw Error(`过滤表达式:未知操作数 '${e}'`)}};function jW(e){return!!e&&e!==0&&e!==``&&e!==null}function MW(e,t){let n=e.split(`.`).filter(e=>e&&e!==`@`),r=t;for(let e of n){if(typeof r!=`object`||!r)return;r=r[e]}return r}function NW(e,t,n){switch(e){case`==`:return t===n;case`!=`:return t!==n;case`<`:return t<n;case`<=`:return t<=n;case`>`:return t>n;case`>=`:return t>=n;default:return!1}}function PW(e,t){return new AW(kW(e),t).parse()}function FW(e,t){return e?`${e}.${t}`:String(t)}function IW(e,t){let n=[{path:``,value:e}];for(let e of OW(t)){let t=[];if(e.type===`key`)for(let r of n)r.value!=null&&typeof r.value==`object`&&e.key in r.value&&t.push({path:FW(r.path,e.key),value:r.value[e.key]});else if(e.type===`index`){for(let r of n)if(Array.isArray(r.value)){let n=r.value[e.index];e.index>=0&&e.index<r.value.length&&t.push({path:FW(r.path,e.index),value:n,index:e.index})}}else if(e.type===`wildcard`){for(let e of n)if(Array.isArray(e.value))e.value.forEach((n,r)=>t.push({path:FW(e.path,r),value:n,index:r}));else if(e.value!=null&&typeof e.value==`object`)for(let n of Object.keys(e.value))t.push({path:FW(e.path,n),value:e.value[n]})}else if(e.type===`descendKey`){let r=e.key,i=e=>{if(!(e.value==null||typeof e.value!=`object`))for(let n of Object.keys(e.value)){let a={path:FW(e.path,n),value:e.value[n]};n===r&&t.push(a),i(a)}};for(let e of n)i(e)}else if(e.type===`descendAll`){let e=n=>{if(!(n.value==null||typeof n.value!=`object`))for(let r of Object.keys(n.value)){let i={path:FW(n.path,r),value:n.value[r]};t.push(i),e(i)}};for(let t of n)e(t)}else if(e.type===`filter`){for(let r of n)if(Array.isArray(r.value))r.value.forEach((n,i)=>{PW(e.filter,n)&&t.push({path:FW(r.path,i),value:n,index:i})});else if(r.value!=null&&typeof r.value==`object`)for(let n of Object.keys(r.value)){let i=r.value[n];PW(e.filter,i)&&t.push({path:FW(r.path,n),value:i})}}n=t}return n}function LW(e,t){let n=e.length,r=t.length;if(!n)return r;if(!r)return n;let i=Array(r+1);for(let e=0;e<=r;e++)i[e]=e;for(let a=1;a<=n;a++){let n=i[0];i[0]=a;for(let o=1;o<=r;o++){let r=i[o];i[o]=Math.min(i[o]+1,i[o-1]+1,n+(e[a-1]===t[o-1]?0:1)),n=r}}return i[r]}function RW(e,t,n={}){let r=n.mode||`substring`,i=n.limit??50,a=n.matchKey!==!1,o=[],s=null;if(r===`regex`)try{s=new RegExp(t,`i`)}catch(e){throw Error(`正则表达式无效: ${e.message}`)}let c=(e,l,u)=>{if(o.length>=i||e==null)return;if(typeof e==`object`){if(Array.isArray(e))e.forEach((e,t)=>c(e,FW(l,t),String(t)));else for(let t of Object.keys(e))c(e[t],FW(l,t),t);return}let d=String(e),f=zW(d,t,r,n.fuzzyThreshold??2,s);if(f){o.push({path:l,key:u,value:d.length>200?d.slice(0,200)+`…`:d,score:f});return}if(a&&u){let e=zW(u,t,r,n.fuzzyThreshold??2,s);e&&o.push({path:l,key:u,value:d.length>200?d.slice(0,200)+`…`:d,score:e})}};return c(e,``),o}function zW(e,t,n,r,i){let a=e.toLowerCase(),o=t.toLowerCase();if(n===`substring`)return a.includes(o)?1:null;if(n===`regex`)return i&&i.test(e)?1:null;if(n===`fuzzy`){if(a.includes(o))return 2;let e=LW(a,o);return e<=r?r-e+1:null}return null}function BW(e,t,n=3e3){return EW(t,n)(e)}var VW=``,HW=`根(整体)`,UW=new Set([`read`,`get_data`,`query_data`,`search_data`]),WW=new Set([`resource_update`,`resource_delete`]),GW=new Set([`remove`,`move`]);function KW(e){let t=String(e).trim();return t===`(root)`||t===`$`?VW:(t.startsWith(`$.`)?t=t.slice(2):t.startsWith(`$`)&&(t=t.slice(1)),t)}function qW(e){let t=KW(e);return t===VW?HW:t}function JW(e){let t=Math.max(e.lastIndexOf(`.`),e.lastIndexOf(`[`));return t<=0?VW:e.slice(0,t)}function YW(e,t){let n=KW(e),r=KW(t);return n===VW||r===VW||n===r||n.startsWith(r+`.`)||n.startsWith(r+`[`)||r.startsWith(n+`.`)||r.startsWith(n+`[`)}function XW(e){if(!e)return VW;try{let t=[];for(let n of OW(e))if(n.type===`key`&&n.key)t.push(n.key);else if(n.type===`index`&&n.index!==void 0)t.push(String(n.index));else break;return t.length?t.join(`.`):VW}catch{return VW}}function ZW(e,t){let n=t||{};if(e===`query_data`)return[XW(String(n.expr||``))];if(e===`search_data`)return[VW];let r=[];if(typeof n.jsonPath==`string`&&n.jsonPath&&r.push(n.jsonPath),Array.isArray(n.jsonPaths))for(let e of n.jsonPaths)typeof e==`string`&&e&&r.push(e);return r.length?r.map(KW):[VW]}function QW(e){if(WW.has(e.name))return null;let t=e.args||{},n=t.del===!0||e.name===`delete_data`,r=[];if(n)r.push({path:String(t.patch?.jsonPath??t.jsonPath??``),op:`remove`});else if(Array.isArray(t.patches))for(let e of t.patches)e&&typeof e==`object`&&r.push({path:String(e.jsonPath||``),op:String(e.op||`set`),value:e.value});else t.patch&&typeof t.patch==`object`?r.push({path:String(t.patch.jsonPath||``),op:String(t.patch.op||`set`),value:t.patch.value}):typeof t.jsonPath==`string`&&t.jsonPath?r.push({path:t.jsonPath,op:e.name===`edit_data`?String(t.op||`set`):`set`}):typeof t.path==`string`&&t.path?r.push({path:t.path,op:`set`}):r.push({path:VW,op:`set`});let i=new Set;for(let{path:e,op:t,value:n}of r){let r=KW(e);if(i.add(r),GW.has(t)&&i.add(JW(r)),t===`move`&&typeof n==`string`&&n){let e=KW(n);i.add(e),i.add(JW(e))}}return{paths:[...i],hasPostValue:!n,callIndex:e.callIndex}}function $W(e,t,n,r){let i=e.map(qW).join(`、`),a=[...new Set(n.flatMap(e=>e.paths))].map(qW).join(`、`),o=[`⏱[过期快照] 此前读取 ${i} 的结果已失效(${r===void 0?`已写入 ${a}`:`第 ${r} 轮写入了 ${a}`})。`];return n.some(e=>e.hasPostValue)?o.push(`该轮写入结果已含 ${a} 最新值与新 hash;${i} 的兄弟子树(未触及部分)仍为读取时原值可参考。`):o.push(`${i} 的兄弟子树(未触及部分)仍为读取时原值可参考。`),t===`query_data`||t===`search_data`?o.push(`需当前结果时重跑 ${t}(表达式/条件不变即可)。`):o.push(`需当前精确值时再 read(建议窄读:${i})。`),o.join(`
|
|
163
|
+
`){n++;continue}if(e===`@`||e===`.`){let e=``;for(;n<r.length&&/[@.\w$-]/.test(r[n]);)e+=r[n++];t.push(e);continue}if(e===`'`||e===`"`){let i=e,a=e;for(n++;n<r.length&&r[n]!==i;)a+=r[n++];a+=r[n]||``,n++,t.push(a);continue}if(/[\d-]/.test(e)){let e=``;for(;n<r.length&&/[\d.eE+-]/.test(r[n]);)e+=r[n++];t.push(e);continue}let i=r.slice(n,n+2);if(i===`==`||i===`!=`||i===`<=`||i===`>=`||i===`&&`||i===`||`){t.push(i),n+=2;continue}if(e===`<`||e===`>`||e===`(`||e===`)`){t.push(e),n++;continue}if(/[a-zA-Z_$]/.test(e)){let e=``;for(;n<r.length&&/[\w$]/.test(r[n]);)e+=r[n++];t.push(e);continue}throw Error(`过滤表达式:意外字符 '${e}'`)}return t}var AW=class{toks;item;pos=0;constructor(e,t){this.toks=e,this.item=t}parse(){let e=this.or();if(this.pos<this.toks.length)throw Error(`过滤表达式:尾部多余 token`);return e}peek(){return this.toks[this.pos]}next(){return this.toks[this.pos++]}or(){let e=this.and();for(;this.peek()===`||`;)this.next(),e=this.and()||e;return e}and(){let e=this.cmp();for(;this.peek()===`&&`;)this.next(),e=this.cmp()&&e;return e}cmp(){if(this.peek()===`(`){this.next();let e=this.or();if(this.peek()!==`)`)throw Error(`过滤表达式:缺 )`);return this.next(),e}let e=this.operand(),t=this.peek();return t===`==`||t===`!=`||t===`<`||t===`<=`||t===`>`||t===`>=`?(this.next(),NW(t,e,this.operand())):jW(e)}operand(){let e=this.next();if(e===void 0)throw Error(`过滤表达式:缺操作数`);if(e.startsWith(`@`))return MW(e,this.item);if(e[0]===`'`||e[0]===`"`)return e.slice(1,-1);if(e===`true`)return!0;if(e===`false`)return!1;if(e===`null`)return null;let t=Number(e);if(!Number.isNaN(t))return t;throw Error(`过滤表达式:未知操作数 '${e}'`)}};function jW(e){return!!e&&e!==0&&e!==``&&e!==null}function MW(e,t){let n=e.split(`.`).filter(e=>e&&e!==`@`),r=t;for(let e of n){if(typeof r!=`object`||!r)return;r=r[e]}return r}function NW(e,t,n){switch(e){case`==`:return t===n;case`!=`:return t!==n;case`<`:return t<n;case`<=`:return t<=n;case`>`:return t>n;case`>=`:return t>=n;default:return!1}}function PW(e,t){return new AW(kW(e),t).parse()}function FW(e,t){return e?`${e}.${t}`:String(t)}function IW(e,t){let n=[{path:``,value:e}];for(let e of OW(t)){let t=[];if(e.type===`key`)for(let r of n)r.value!=null&&typeof r.value==`object`&&e.key in r.value&&t.push({path:FW(r.path,e.key),value:r.value[e.key]});else if(e.type===`index`){for(let r of n)if(Array.isArray(r.value)){let n=r.value[e.index];e.index>=0&&e.index<r.value.length&&t.push({path:FW(r.path,e.index),value:n,index:e.index})}}else if(e.type===`wildcard`){for(let e of n)if(Array.isArray(e.value))e.value.forEach((n,r)=>t.push({path:FW(e.path,r),value:n,index:r}));else if(e.value!=null&&typeof e.value==`object`)for(let n of Object.keys(e.value))t.push({path:FW(e.path,n),value:e.value[n]})}else if(e.type===`descendKey`){let r=e.key,i=e=>{if(!(e.value==null||typeof e.value!=`object`))for(let n of Object.keys(e.value)){let a={path:FW(e.path,n),value:e.value[n]};n===r&&t.push(a),i(a)}};for(let e of n)i(e)}else if(e.type===`descendAll`){let e=n=>{if(!(n.value==null||typeof n.value!=`object`))for(let r of Object.keys(n.value)){let i={path:FW(n.path,r),value:n.value[r]};t.push(i),e(i)}};for(let t of n)e(t)}else if(e.type===`filter`){for(let r of n)if(Array.isArray(r.value))r.value.forEach((n,i)=>{PW(e.filter,n)&&t.push({path:FW(r.path,i),value:n,index:i})});else if(r.value!=null&&typeof r.value==`object`)for(let n of Object.keys(r.value)){let i=r.value[n];PW(e.filter,i)&&t.push({path:FW(r.path,n),value:i})}}n=t}return n}function LW(e,t){let n=e.length,r=t.length;if(!n)return r;if(!r)return n;let i=Array(r+1);for(let e=0;e<=r;e++)i[e]=e;for(let a=1;a<=n;a++){let n=i[0];i[0]=a;for(let o=1;o<=r;o++){let r=i[o];i[o]=Math.min(i[o]+1,i[o-1]+1,n+(e[a-1]===t[o-1]?0:1)),n=r}}return i[r]}function RW(e,t,n={}){let r=n.mode||`substring`,i=n.limit??50,a=n.matchKey!==!1,o=[],s=null;if(r===`regex`)try{s=new RegExp(t,`i`)}catch(e){throw Error(`正则表达式无效: ${e.message}`)}let c=(e,l,u)=>{if(o.length>=i||e==null)return;if(typeof e==`object`){if(Array.isArray(e))e.forEach((e,t)=>c(e,FW(l,t),String(t)));else for(let t of Object.keys(e))c(e[t],FW(l,t),t);return}let d=String(e),f=zW(d,t,r,n.fuzzyThreshold??2,s);if(f){o.push({path:l,key:u,value:d.length>200?d.slice(0,200)+`…`:d,score:f});return}if(a&&u){let e=zW(u,t,r,n.fuzzyThreshold??2,s);e&&o.push({path:l,key:u,value:d.length>200?d.slice(0,200)+`…`:d,score:e})}};return c(e,``),o}function zW(e,t,n,r,i){let a=e.toLowerCase(),o=t.toLowerCase();if(n===`substring`)return a.includes(o)?1:null;if(n===`regex`)return i&&i.test(e)?1:null;if(n===`fuzzy`){if(a.includes(o))return 2;let e=LW(a,o);return e<=r?r-e+1:null}return null}function BW(e,t,n=3e3){return EW(t,n)(e)}var VW=``,HW=`根(整体)`,UW=new Set([`read`,`get_data`,`query_data`,`search_data`]),WW=new Set([`resource_update`,`resource_delete`]),GW=new Set([`remove`,`move`]);function KW(e){let t=String(e).trim();return t===`(root)`||t===`$`?VW:(t.startsWith(`$.`)?t=t.slice(2):t.startsWith(`$`)&&(t=t.slice(1)),t=t.replace(/\[(\d+)\]/g,`.$1`),t)}function qW(e){let t=KW(e);return t===VW?HW:t}function JW(e){let t=Math.max(e.lastIndexOf(`.`),e.lastIndexOf(`[`));return t<=0?VW:e.slice(0,t)}function YW(e,t){let n=KW(e),r=KW(t);return n===VW||r===VW||n===r||n.startsWith(r+`.`)||n.startsWith(r+`[`)||r.startsWith(n+`.`)||r.startsWith(n+`[`)}function XW(e){if(!e)return VW;try{let t=[];for(let n of OW(e))if(n.type===`key`&&n.key)t.push(n.key);else if(n.type===`index`&&n.index!==void 0)t.push(String(n.index));else break;return t.length?t.join(`.`):VW}catch{return VW}}function ZW(e,t){let n=t||{};if(e===`query_data`)return[XW(String(n.expr||``))];if(e===`search_data`)return[VW];let r=[];if(typeof n.jsonPath==`string`&&n.jsonPath&&r.push(n.jsonPath),Array.isArray(n.jsonPaths))for(let e of n.jsonPaths)typeof e==`string`&&e&&r.push(e);return r.length?r.map(KW):[VW]}function QW(e){if(WW.has(e.name))return null;let t=e.args||{},n=t.del===!0||e.name===`delete_data`,r=[];if(n)r.push({path:String(t.patch?.jsonPath??t.jsonPath??``),op:`remove`});else if(Array.isArray(t.patches))for(let e of t.patches)e&&typeof e==`object`&&r.push({path:String(e.jsonPath||``),op:String(e.op||`set`),value:e.value});else t.patch&&typeof t.patch==`object`?r.push({path:String(t.patch.jsonPath||``),op:String(t.patch.op||`set`),value:t.patch.value}):typeof t.jsonPath==`string`&&t.jsonPath?r.push({path:t.jsonPath,op:e.name===`edit_data`?String(t.op||`set`):`set`}):typeof t.path==`string`&&t.path?r.push({path:t.path,op:`set`}):r.push({path:VW,op:`set`});let i=new Set;for(let{path:e,op:t,value:n}of r){let r=KW(e);if(i.add(r),GW.has(t)&&i.add(JW(r)),t===`move`&&typeof n==`string`&&n){let e=KW(n);i.add(e),i.add(JW(e))}}return{paths:[...i],hasPostValue:!n,callIndex:e.callIndex}}function $W(e,t,n,r){let i=e.map(qW).join(`、`),a=[...new Set(n.flatMap(e=>e.paths))].map(qW).join(`、`),o=[`⏱[过期快照] 此前读取 ${i} 的结果已失效(${r===void 0?`已写入 ${a}`:`第 ${r} 轮写入了 ${a}`})。`];return n.some(e=>e.hasPostValue)?o.push(`该轮写入结果已含 ${a} 最新值与新 hash;${i} 的兄弟子树(未触及部分)仍为读取时原值可参考。`):o.push(`${i} 的兄弟子树(未触及部分)仍为读取时原值可参考。`),t===`query_data`||t===`search_data`?o.push(`需当前结果时重跑 ${t}(表达式/条件不变即可)。`):o.push(`需当前精确值时再 read(建议窄读:${i})。`),o.join(`
|
|
164
164
|
`)}function eG(e,t,n={}){let r=n.maxParallelTools??1,i=t.map(e=>QW(e)).filter(e=>e!==null);if(!i.length||!e.length)return{messages:e,invalidatedCount:0,invalidated:[]};let a=e=>e._getType?.()??`unknown`,o=-1;for(let t=e.length-1;t>=0;t--){let n=e[t];if(a(n)===`ai`){let e=n.tool_calls;if(Array.isArray(e)&&e.length){o=t;break}}}let s=[],c=[],l=-1;for(let t=0;t<e.length;t++){let n=e[t];if(a(n)===`ai`){let e=n.tool_calls;c=(Array.isArray(e)?e:[]).map((e,t)=>({callIndex:t,id:e.id,name:e.name,args:e.args||{},used:!1})),l=t}else if(n instanceof bx){let e=n.tool_call_id,r=e===void 0?void 0:c.find(t=>!t.used&&t.id!==void 0&&t.id===e);if(!r){let e=n.name;r=e?c.find(t=>!t.used&&t.name===e):c.find(e=>!e.used)}r&&(r.used=!0,UW.has(r.name)&&s.push({aiIndex:l,callIndex:r.callIndex,name:r.name,paths:ZW(r.name,r.args),msgIndex:t}))}}let u=null,d=[];for(let t of s){let a=e[t.msgIndex];if(String(a.content??``).startsWith(`⏱[过期快照]`))continue;let s=i.filter(e=>e.paths.some(e=>t.paths.some(t=>YW(t,e))));if(!s.length)continue;let c;if(c=t.aiIndex!==o||r>1||s.some(e=>e.callIndex===void 0||t.callIndex<e.callIndex),!c)continue;let l=$W(t.paths,t.name,s,n.round);u||=e.slice(),u[t.msgIndex]=new bx({tool_call_id:a.tool_call_id??``,name:a.name,content:l}),d.push({paths:t.paths,writtenPaths:s.flatMap(e=>e.paths)})}return{messages:u??e,invalidatedCount:d.length,invalidated:d}}var tG=/(改|改掉|改成|修改|更新|加|添加|新增|加上|删|删掉|删除|移除|移|移动|换|替换|调|调整|调换|生成|创建|做|做个|做一个|建|搭建|重建|重新|清空|设置|配置|美化|优化|排版|布置|填充|写入|保存|发布|上线|部署)/,nG=/(看看|看一下|查|查一下|查询|了解|了解下|说说|讲讲|解释|解释下|总结|总结一下|对比|对比一下|确认|确认一下|核对|检查|检查一下|看看有没有|帮我看看|review|Review)/,rG=/(不用改|不用动|只是问|只是想问|先别动|先不要|不用写入|不要保存|只是确认|告诉我即可|不用执行)/,iG=/^(use_|spawn_agent|spawn_agents)/;function aG(e){let t=(e||``).trim();if(!t||rG.test(t)||/(吗|呢)[??]?\s*$/.test(t)||/[??]\s*$/.test(t))return!1;let n=(t.split(/[。!?;?!,\n,]/)[0]??t).slice(0,16);return!nG.test(n)&&tG.test(n)}function oG(e,t){for(let[n,r]of Object.entries(e.counts))if(!(r<=0)&&(t(n)||iG.test(n)))return!1;return!0}function sG(e,t,n=()=>!1){let r=Object.entries(e.counts).filter(([e,t])=>t>0||n(e)).map(([e,t])=>`${e}×${t}`);e.counts.write===void 0&&n(`write`)&&r.push(`write×0`);let i=r.length?r.join(`, `):`无`,a=e.writePaths.length?e.writePaths.slice(0,5).join(`, `)+(e.writePaths.length>5?` 等 ${e.writePaths.length} 处`:``):`无`,o=t?.length??0,s=t?.filter(e=>e.status===`completed`).length??0,c=o?`${s}/${o} 完成`:`无 todos`;return`本轮事实:工具调用 ${i};成功写入路径:${a};失败/回灌 ${e.failures};todos:${c}。`}var cG=/(components?\.\d+|child(ren)?\.\d+|[a-zA-Z][a-zA-Z0-9_-]{3,}\.\d+|jsonPath|@ ?"[^"]+"|路径)/;function lG(e){return[`⚠️ 这条指令看起来需要改动数据,但本轮没有任何写入或委派操作。`,`${e}`,`如果确实已完成:请在回复中逐项说明改动位置(jsonPath / 组件 id),与上述事实对账;`,`如果尚未完成:请继续执行(用 write 增量改 / 委派对应子 agent);`,`如果做不到或需要用户决定:请如实说明原因,不要回复「已完成」。`].join(`
|
|
165
165
|
`)}function uG(e){return cG.test(e||``)}var dG=/(写到了哪|写到哪|在哪写|什么位置|完成了吗|完成没|做完了吗|做好了|好了吗|搞定了吗|生成了吗|改好了吗|改完了吗|保存了吗|写入了吗|写入了没有|有没有写入|有没有保存|现在的?(页面|数据|状态|内容)|当前(页面|数据|状态)|进度如何|进度怎么样|什么状态)/,fG=/(已写入|已保存|已添加|已删除|已修改|已更新|已设置|已生成|已创建|已搭建|已删除|已经写入|已经完成|全部完成|全部搞定)/;function pG(e){return dG.test((e||``).trim())}function mG(e){return fG.test(e||``)}function hG(e){return Object.values(e.counts).every(e=>e<=0)}function gG(e){return[`⚠️ 这是关于数据现状的询问,但本轮你没有调用任何工具(含 read)就断言了「已写入/已完成」状态。`,`${e}`,`数据可能已被刷新回退或外部修改,凭对话记忆断言状态不可靠。`,`请先用 read / list 类工具核实实际数据再据实回答;若实际未写入,如实说明并继续完成,不要凭印象回复「已完成」。`].join(`
|
|
166
166
|
`)}var _G=/(我先|让我先|我先看|先看看|先了解|先加载|先查阅|稍后|接下来我|我将先|等我|查完.{0,12}再|看完.{0,12}再|了解.{0,8}再)/,vG=/(已完成|已生成|已修改|已创建|已添加|已删除|已更新|已调整|已处理|已委派|已配置|已切换|成功|完成[。!?]|搞定了|做好了)/;function yG(e){if(!e)return!1;let t=e.trim();return t.length>160||vG.test(t)?!1:_G.test(t)}var bG=/(add_component|delete_component|move_component|list_components|select_component|load_skill|use_[a-z]+|rag_[a-z]+|request_human_confirmation|\bwrite\b|\bread\b)/,xG=/(我来|让我|我先|现在|开始|先加载|先添加|先写|先删|先看看|执行|添加|写入|加载|删除)/;function SG(e){if(!e)return!1;let t=e.trim();return bG.test(t)&&xG.test(t)}function CG(e){if(!e)return[];let t=String(e).replace(/\$\.?/g,` `).replace(/\[(\d+)\]/g,`.$1`),n=[];for(let e of t.matchAll(/[A-Za-z_][\w-]*(?:\.[A-Za-z_][\w-]*|\.\d+)+/g))n.push(e[0]);return[...new Set(n)]}function wG(e,t){let n=Array.from(t);return n.length?e.some(e=>n.some(t=>YW(e,t))):!1}Yp();var TG=new Set([`write`,`set_data`,`edit_data`,`delete_data`]);function EG(e){return e.map((e,t)=>({id:e.id||`t-${t+1}`,content:e.content,status:e.status,...e.parentId===void 0?{}:{parentId:e.parentId},...e.deps===void 0?{}:{deps:e.deps},...e.criteria===void 0?{}:{criteria:e.criteria},...e.evidence===void 0?{}:{evidence:e.evidence}}))}function DG(e){if(!e.length)return;let t=e.some(e=>e.parentId||e.deps&&e.deps.length),n=[];if(t){let t=t=>e.filter(e=>e.parentId===t),r=t=>e.find(e=>e.id===t)?.status===`completed`?`✓`:`⏳`,i=(e,a,o)=>{if(o.has(e.id))return;o.add(e.id);let s=` `.repeat(a),c=e.deps?.length?` (依赖:${e.deps.map(e=>r(e)).join(``)})`:``,l=e.evidence?` [证据:${e.evidence}]`:``,u=e.criteria?` [标准:${e.criteria}]`:``;n.push(`${s}- #${e.id} [${e.status}] ${e.content}${u}${c}${l}`),t(e.id).forEach(e=>i(e,a+1,o))};e.filter(e=>!e.parentId).forEach(e=>i(e,0,new Set))}else e.forEach((e,t)=>{let r=e.evidence?` [证据:${e.evidence}]`:``;n.push(`${t+1}. #${e.id} [${e.status}] ${e.content}${r}`)});let r=t?`规则:write_todos 拆解(可带 parentId 表达层级、deps 表达依赖);有依赖的任务,deps 全 completed 后再标 in_progress;完成一个立即 update_todo({id, status:"completed"})。注意:write_todos(整表替换)与 update_todo(增量)不可同轮混用;批量标多个完成建议一次 write_todos 传完整数组(全 completed),不必逐个 update_todo。`:`规则:开始前用 write_todos 拆解;首个任务标 in_progress;完成一个立即 update_todo({id, status:"completed"}) 标完成(不必重传整个清单);保持至少一个 in_progress 直到全部完成。注意:write_todos(整表替换)与 update_todo(增量)不可同轮混用;批量标多个完成建议一次 write_todos 传完整数组(全 completed),不必逐个 update_todo。`;return[`## 当前任务清单(write_todos 整表替换 / update_todo 按 id 增量改单项)`,n.join(`
|
|
167
167
|
`),r].join(`
|
|
168
|
-
`)}function OG(e,t){return!(!e.length||!e.some(e=>e.status!==`completed`)||/[??]\s*$/.test(t))}function kG(e){let
|
|
169
|
-
`),
|
|
168
|
+
`)}function OG(e,t){return!(!e.length||!e.some(e=>e.status!==`completed`)||/[??]\s*$/.test(t))}function kG(e,t){let n=e.filter(e=>e.status!==`completed`),r=n.map(e=>`#${e.id} [${e.status}] ${e.content.length>60?`${e.content.slice(0,60)}…`:e.content}`).join(`
|
|
169
|
+
`),i=e.filter(e=>e.status===`completed`&&!e.evidence&&(!t||t.get(e.id)!==`completed`)),a=i.length?`\n另有 ${i.length} 项已标记完成但 evidence 为空(${i.map(e=>`#${e.id}`).join(`、`)}):标记完成时请用 update_todo 附 evidence(本次实际写入的 jsonPath,如 components.2);经委派完成等无主写路径时如实写明完成方式。`:``;return`⚠️ 任务未完成:待办清单还有 ${n.length} 项未完成:\n${r}\n若这些工作实际已完成,请先用 update_todo 把它们全部标记 completed(或一次 write_todos 整表替换)再给出最终总结;若尚未完成,请继续执行剩余任务。不要中途停止。${a}`}function AG(e=[],t={}){let n=EG(e),r=0,i=0,a=!1,o=0,s=t.maxPlanRevisions??5;return{name:`todos`,tools:[QI(async({todos:e})=>{if(!a)a=!0,o=1;else if(o++,o>s)return`规划阶段已达上限(${s} 次修订,现在已是第 ${o} 版计划)。停止修订,基于当前清单开始执行(用 write 落地;advanced 模式亦可用 set_data/edit_data)。当前清单:\n${n.map((e,t)=>`${t+1}. #${e.id} [${e.status}] ${e.content}`).join(`
|
|
170
170
|
`)||`(空)`}`;return n=EG(e),`已更新任务清单:${n.length} 项\n${n.map((e,t)=>`${t+1}. #${e.id} [${e.status}] ${e.content}`).join(`
|
|
171
|
-
`)}`},{name:`write_todos`,description:`更新(整表替换)任务清单。用于多步任务的拆解与进度跟踪。每次传入完整的 todos 数组(状态 pending/in_progress/completed),不要增量 patch——增量改单项用 update_todo。`,schema:B({todos:z(B({id:R().optional().describe(`任务 id(可选;不传框架自动生成 t-1/t-2...)`),content:R().describe(`任务描述`),status:Wd([`pending`,`in_progress`,`completed`]),parentId:R().optional().describe(`父任务 id(表达层级;structured-todos-tier)`),deps:z(R()).optional().describe(`依赖的任务 id 数组(必须先完成)`),criteria:R().optional().describe(`完成标准(可选)`),evidence:R().optional().describe(`完成证据(标 completed 建议附实际写入的 jsonPath,如 components.2)`)})).describe(`完整的任务清单(整表替换)`)})}),QI(async({id:e,content:t,status:r,parentId:i,deps:c,criteria:l,evidence:u})=>{if(a&&o>s&&(t!==void 0||i!==void 0||c!==void 0||l!==void 0))return`规划阶段已达上限(${s} 次修订,现在已是第 ${o} 版计划)。停止修订计划内容(改任务文本/层级/依赖);status/evidence 进度跟踪可继续,或基于当前清单开始执行。当前任务 id:${n.map(e=>e.id).join(`, `)||`(空)`}`;let d=n.findIndex(t=>t.id===e);return d<0?`错误:找不到 id="${e}" 的任务(TODO_NOT_FOUND)。当前任务 id:${n.map(e=>e.id).join(`, `)||`(空)`}`:(t!==void 0&&(n[d].content=t),r!==void 0&&(n[d].status=r),i!==void 0&&(n[d].parentId=i),c!==void 0&&(n[d].deps=c),l!==void 0&&(n[d].criteria=l),u!==void 0&&(n[d].evidence=u),`已更新任务 #${e}:[${n[d].status}] ${n[d].content}`)},{name:`update_todo`,description:`按 id 增量更新单个任务(改 content/status,不必重传整个清单)。id 见当前任务清单渲染(如 t-1)。执行中动态修订步骤用此工具;与 write_todos 不可同轮调用。`,schema:B({id:R().describe(`目标任务 id(见当前任务清单)`),content:R().optional().describe(`新任务描述(不传则不改)`),status:Wd([`pending`,`in_progress`,`completed`]).optional().describe(`新状态(不传则不改)`),parentId:R().optional().describe(`父任务 id(改层级;不传则不改)`),deps:z(R()).optional().describe(`依赖任务 id 数组(不传则不改)`),criteria:R().optional().describe(`完成标准(不传则不改)`),evidence:R().optional().describe(`完成证据(标 completed 建议附实际写入的 jsonPath,如 components.2;不传则不改)`)})})],beforeAgent:()=>({todos:n}),beforeModel:()=>(r=0,i=0,{todos:n}),augmentPrompt:()=>DG(n),wrapToolCall:async(e,t)=>{if(e.name===`write_todos`||e.name===`update_todo`){if(e.name===`write_todos`?r++:i++,r>1)return{content:`错误:write_todos(整表替换)不应在一轮中调用多次(末次覆盖前者,无意义)。一次传完整数组即可。`,status:`error`};if(r>0&&i>0)return{content:`错误:write_todos(整表替换)与 update_todo(增量改单项)不应在一轮中混用,语义冲突。请只选一种:write_todos 传完整数组,或 update_todo 逐个改。`,status:`error`}}let n=await t(e);return TG.has(e.name)&&n?.status!==`error`&&(a=!1,o=0),n},reset:e=>{n=EG(e.map(e=>({...e}))),a=!1,o=0},getPlanPhase:()=>({inPlanning:a,rounds:o,limit:s})}}function jG(){return{transitionalRetries:0,completionRetries:0,zeroToolRetries:0,auditRetries:0}}var MG=2,NG=2,PG=2,FG=2;function IG(e){let{state:t,garbled:n,rounds:r}=e,i=e.finalContent;if(n)return null;let a=r>0?yG(i):SG(i);if(t.transitionalRetries<MG&&a)return t.transitionalRetries+=1,{kind:`feedback`,gate:{stage:`transitional_retry`,attempt:t.transitionalRetries,feedback:`⚠️ 你刚才只输出了计划/行动叙述(如「我先看看」「开始添加」),没有发起任何工具调用,因此什么都未执行。请立即用标准 function calling 调用所需工具把任务做完,全部完成后再给出总结回复。`,logData:{rounds:r}}};if(r>0&&!e.isSubagent&&t.completionRetries<NG&&OG(e.todos,i))return t.completionRetries+=1,{kind:`feedback`,gate:{stage:`completion_gate`,attempt:t.completionRetries,feedback:kG(e.todos),logData:{pending:e.todos.filter(e=>e.status!==`completed`).map(e=>e.id)}}};let o=e.isSubagent?[]:LG(e.todos,e.todosStatusAtStart??new Map,e.sessionWritePaths??[]);if(o.length)return t.auditRetries<FG?(t.auditRetries+=1,{kind:`feedback`,gate:{stage:`evidence_audit_gate`,attempt:t.auditRetries,feedback:RG(o),logData:{offenders:o.map(e=>({id:e.id,evidence:e.evidence}))}}}):{kind:`observable`,obs:{code:`AUDIT_GATE_EXHAUSTED`,message:`evidence 审计经 2 次回灌后仍有 ${o.length} 项任务的证据路径与写入记录不符,已放行;最终回复中的完成声明可能不实`,context:{offenders:o.map(e=>({id:e.id,evidence:e.evidence}))}}};if(e.isSubagent)return null;let s=``;for(let t=e.messages.length-1;t>=0;t--){let n=e.messages[t];if(n._getType?.()===`human`){s=String(n.content??``);break}}if(t.zeroToolRetries<PG&&oG(e.turnUsage,e.isWriteToolByName)&&aG(s)&&!uG(i)&&!/[??]\s*$/.test(i.trim())){t.zeroToolRetries+=1;let n=sG(e.turnUsage,e.todos,e.isWriteToolByName);return{kind:`feedback`,gate:{stage:`zero_tool_gate`,attempt:t.zeroToolRetries,feedback:lG(n),logData:{factSheet:n}}}}if(t.zeroToolRetries<PG&&hG(e.turnUsage)&&pG(s)&&mG(i)){t.zeroToolRetries+=1;let n=sG(e.turnUsage,e.todos,e.isWriteToolByName);return{kind:`feedback`,gate:{stage:`status_query_gate`,attempt:t.zeroToolRetries,feedback:gG(n),logData:{factSheet:n}}}}return t.zeroToolRetries>=PG&&oG(e.turnUsage,e.isWriteToolByName)&&aG(s)?{kind:`observable`,obs:{code:`ZERO_TOOL_GATE_EXHAUSTED`,message:`操作指令经 2 次回灌后仍以零工具纯文本收尾(疑似谎报完成),已放行;最终回复可能不实`,context:{factSheet:sG(e.turnUsage,e.todos,e.isWriteToolByName)}}}:null}function LG(e,t,n){let r=Array.from(n??[]);return e.filter(e=>{if(e.status!==`completed`||t?.get(e.id)===`completed`)return!1;let n=CG(e.evidence??``);return n.length?!wG(n,r):!1})}function RG(e){return[`⚠️ 以下已完成任务的 evidence 路径与本次会话的写入记录对不上(该路径从未被写入):`,e.map(e=>`#${e.id}(${e.content.length>40?`${e.content.slice(0,40)}…`:e.content}) evidence:「${(e.evidence??``).slice(0,80)}」`).join(`
|
|
171
|
+
`)}`},{name:`write_todos`,description:`更新(整表替换)任务清单。用于多步任务的拆解与进度跟踪。每次传入完整的 todos 数组(状态 pending/in_progress/completed),不要增量 patch——增量改单项用 update_todo。`,schema:B({todos:z(B({id:R().optional().describe(`任务 id(可选;不传框架自动生成 t-1/t-2...)`),content:R().describe(`任务描述`),status:Wd([`pending`,`in_progress`,`completed`]),parentId:R().optional().describe(`父任务 id(表达层级;structured-todos-tier)`),deps:z(R()).optional().describe(`依赖的任务 id 数组(必须先完成)`),criteria:R().optional().describe(`完成标准(可选)`),evidence:R().optional().describe(`完成证据(标 completed 建议附实际写入的 jsonPath,如 components.2)`)})).describe(`完整的任务清单(整表替换)`)})}),QI(async({id:e,content:t,status:r,parentId:i,deps:c,criteria:l,evidence:u})=>{if(a&&o>s&&(t!==void 0||i!==void 0||c!==void 0||l!==void 0))return`规划阶段已达上限(${s} 次修订,现在已是第 ${o} 版计划)。停止修订计划内容(改任务文本/层级/依赖);status/evidence 进度跟踪可继续,或基于当前清单开始执行。当前任务 id:${n.map(e=>e.id).join(`, `)||`(空)`}`;let d=n.findIndex(t=>t.id===e);return d<0?`错误:找不到 id="${e}" 的任务(TODO_NOT_FOUND)。当前任务 id:${n.map(e=>e.id).join(`, `)||`(空)`}`:(t!==void 0&&(n[d].content=t),r!==void 0&&(n[d].status=r),i!==void 0&&(n[d].parentId=i),c!==void 0&&(n[d].deps=c),l!==void 0&&(n[d].criteria=l),u!==void 0&&(n[d].evidence=u),`已更新任务 #${e}:[${n[d].status}] ${n[d].content}`)},{name:`update_todo`,description:`按 id 增量更新单个任务(改 content/status,不必重传整个清单)。id 见当前任务清单渲染(如 t-1)。执行中动态修订步骤用此工具;与 write_todos 不可同轮调用。`,schema:B({id:R().describe(`目标任务 id(见当前任务清单)`),content:R().optional().describe(`新任务描述(不传则不改)`),status:Wd([`pending`,`in_progress`,`completed`]).optional().describe(`新状态(不传则不改)`),parentId:R().optional().describe(`父任务 id(改层级;不传则不改)`),deps:z(R()).optional().describe(`依赖任务 id 数组(不传则不改)`),criteria:R().optional().describe(`完成标准(不传则不改)`),evidence:R().optional().describe(`完成证据(标 completed 建议附实际写入的 jsonPath,如 components.2;不传则不改)`)})})],beforeAgent:()=>({todos:n}),beforeModel:()=>(r=0,i=0,{todos:n}),augmentPrompt:()=>DG(n),wrapToolCall:async(e,t)=>{if(e.name===`write_todos`||e.name===`update_todo`){if(e.name===`write_todos`?r++:i++,r>1)return{content:`错误:write_todos(整表替换)不应在一轮中调用多次(末次覆盖前者,无意义)。一次传完整数组即可。`,status:`error`};if(r>0&&i>0)return{content:`错误:write_todos(整表替换)与 update_todo(增量改单项)不应在一轮中混用,语义冲突。请只选一种:write_todos 传完整数组,或 update_todo 逐个改。`,status:`error`}}let n=await t(e);return TG.has(e.name)&&n?.status!==`error`&&(a=!1,o=0),n},reset:e=>{n=EG(e.map(e=>({...e}))),a=!1,o=0},getPlanPhase:()=>({inPlanning:a,rounds:o,limit:s})}}function jG(){return{transitionalRetries:0,completionRetries:0,zeroToolRetries:0,auditRetries:0}}var MG=2,NG=2,PG=2,FG=2;function IG(e){let{state:t,garbled:n,rounds:r}=e,i=e.finalContent;if(n)return null;let a=r>0?yG(i):SG(i);if(t.transitionalRetries<MG&&a)return t.transitionalRetries+=1,{kind:`feedback`,gate:{stage:`transitional_retry`,attempt:t.transitionalRetries,feedback:`⚠️ 你刚才只输出了计划/行动叙述(如「我先看看」「开始添加」),没有发起任何工具调用,因此什么都未执行。请立即用标准 function calling 调用所需工具把任务做完,全部完成后再给出总结回复。`,logData:{rounds:r}}};if(r>0&&!e.isSubagent&&t.completionRetries<NG&&OG(e.todos,i))return t.completionRetries+=1,{kind:`feedback`,gate:{stage:`completion_gate`,attempt:t.completionRetries,feedback:kG(e.todos,e.todosStatusAtStart),logData:{pending:e.todos.filter(e=>e.status!==`completed`).map(e=>e.id)}}};let o=e.isSubagent?[]:LG(e.todos,e.todosStatusAtStart??new Map,e.sessionWritePaths??[]);if(o.length)return t.auditRetries<FG?(t.auditRetries+=1,{kind:`feedback`,gate:{stage:`evidence_audit_gate`,attempt:t.auditRetries,feedback:RG(o),logData:{offenders:o.map(e=>({id:e.id,evidence:e.evidence}))}}}):{kind:`observable`,obs:{code:`AUDIT_GATE_EXHAUSTED`,message:`evidence 审计经 2 次回灌后仍有 ${o.length} 项任务的证据路径与写入记录不符,已放行;最终回复中的完成声明可能不实`,context:{offenders:o.map(e=>({id:e.id,evidence:e.evidence}))}}};if(e.isSubagent)return null;let s=``;for(let t=e.messages.length-1;t>=0;t--){let n=e.messages[t];if(n._getType?.()===`human`){s=String(n.content??``);break}}if(t.zeroToolRetries<PG&&oG(e.turnUsage,e.isWriteToolByName)&&aG(s)&&!uG(i)&&!/[??]\s*$/.test(i.trim())){t.zeroToolRetries+=1;let n=sG(e.turnUsage,e.todos,e.isWriteToolByName);return{kind:`feedback`,gate:{stage:`zero_tool_gate`,attempt:t.zeroToolRetries,feedback:lG(n),logData:{factSheet:n}}}}if(t.zeroToolRetries<PG&&hG(e.turnUsage)&&pG(s)&&mG(i)){t.zeroToolRetries+=1;let n=sG(e.turnUsage,e.todos,e.isWriteToolByName);return{kind:`feedback`,gate:{stage:`status_query_gate`,attempt:t.zeroToolRetries,feedback:gG(n),logData:{factSheet:n}}}}return t.zeroToolRetries>=PG&&oG(e.turnUsage,e.isWriteToolByName)&&aG(s)?{kind:`observable`,obs:{code:`ZERO_TOOL_GATE_EXHAUSTED`,message:`操作指令经 2 次回灌后仍以零工具纯文本收尾(疑似谎报完成),已放行;最终回复可能不实`,context:{factSheet:sG(e.turnUsage,e.todos,e.isWriteToolByName)}}}:null}function LG(e,t,n){let r=Array.from(n??[]);return e.filter(e=>{if(e.status!==`completed`||t?.get(e.id)===`completed`)return!1;let n=CG(e.evidence??``);return n.length?!wG(n,r):!1})}function RG(e){return[`⚠️ 以下已完成任务的 evidence 路径与本次会话的写入记录对不上(该路径从未被写入):`,e.map(e=>`#${e.id}(${e.content.length>40?`${e.content.slice(0,40)}…`:e.content}) evidence:「${(e.evidence??``).slice(0,80)}」`).join(`
|
|
172
172
|
`),`请核实并处理:① 路径写错 → 用 update_todo 修正 evidence 为本次实际写入的 jsonPath;② 实际未完成 → 改回 pending 继续执行,不要谎报完成;③ 工作经委派子 agent 等未走主写路径完成 → 修正 evidence 为如实说明(不含路径样式文字)。`].join(`
|
|
173
173
|
`)}function zG(e,t){return t?{...e,...t}:e}async function BG(e,t){let n=t;for(let t of e)t.beforeAgent&&(n=zG(n,await t.beforeAgent(n)));return n}function VG(e,t){let n=t.state;for(let r of e)r.beforeModel&&(n=zG(n,r.beforeModel({messages:t.messages,state:n})));return n}function HG(e,t,n){let r=n;for(let n=e.length-1;n>=0;n--){let i=e[n];i.afterModel&&(r=zG(r,i.afterModel(t,r)))}return r}async function UG(e,t){let n=t;for(let t=e.length-1;t>=0;t--){let r=e[t];r.afterAgent&&(n=zG(n,await r.afterAgent(n)))}return n}async function WG(e,t){let n=[];for(let r of e){if(!r.beforeReturn)continue;let e=await r.beforeReturn(t);e&&n.push(e)}return n.length?n.join(`
|
|
174
174
|
|
|
175
175
|
`):null}function GG(e,t){return e.reduceRight((e,t)=>n=>t.wrapModelCall?t.wrapModelCall(n,e):e(n),t)}function KG(e,t){return e.reduceRight((e,t)=>n=>t.wrapToolCall?t.wrapToolCall(n,e):e(n),t)}function qG(e){return e?/<|tool_calls|>|<||[^>]*tool_call|<||?DSML|<||?tool[_a-z]*|?>|<invoke\s+name=|<\/?tool_call>|<function_call>/i.test(e):!1}function JG(e){if(!e)return``;let t=e.search(/<|tool_calls|>|<||[^>]*tool_call|<||?DSML|<||?tool[_a-z]*|?>|<function_call>|<invoke\s+name=/i);return(t>=0?e.slice(0,t):e).trim()}var YG=/<|tool_calls|>|<||[^>]*tool_call|<||?DSML|<||?tool[_a-z]*|?>/i;function XG(e){return e.replace(/```[\w-]*\n?[\s\S]*?```/g,``)}function ZG(e){if(!e||!qG(e))return null;let t=XG(e);if(!YG.test(t))return null;t=t.replace(/<|(?!|)[^|<>]*?|>/g,``);let n=/<(?:||?DSML||?)?\s*invoke\s+name=["']([^"']+)["'][^>]*>/gi,r=[],i;for(;(i=n.exec(t))!==null;)r.push({name:i[1],tagStart:i.index,after:n.lastIndex});if(!r.length)return null;let a=/<\/?\s*(?:||?DSML||?)?\/?\s*invoke\s*>/i,o=/<(?:||?DSML||?)?\s*parameter\s+name=["']([^"']+)["'][^>]*>([\s\S]*?)<\/?\s*(?:||?DSML||?)?\/?\s*parameter\s*>/gi,s=/<(?:||?DSML||?)?\s*parameter\s+name=["'][^"']+["'][^>]*>/gi,c=/<\/?\s*(?:||?DSML||?)?\/?\s*parameter\s*>/gi,l=[];for(let e=0;e<r.length;e++){let n=e+1<r.length?r[e+1].tagStart:t.length,i=t.slice(r[e].after,n),u=i.match(a);if(u&&u.index!==void 0&&(i=i.slice(0,u.index)),(i.match(s)||[]).length>(i.match(c)||[]).length)continue;let d={};o.lastIndex=0;let f;for(;(f=o.exec(i))!==null;)d[f[1]]=QG(f[2].trim());l.push({id:`dsml_${e}_${Date.now().toString(36)}`,name:r[e].name,args:d})}return l.length?l:null}function QG(e){if(e===`true`)return!0;if(e===`false`)return!1;if(e===`null`)return null;try{return JSON.parse(e)}catch{return e}}var $G=30,eK=300,tK=6e3;function nK(e,t){let n=e=>aW(typeof e.content==`string`?e.content:JSON.stringify(e.content)),r=e.reduce((e,t)=>e+n(t),0);if(r<=t)return e;let i=0,a=r-t,o=Math.max(100,Math.min(400,Math.round(t/500))),s=e.map(e=>{if(i>=a||!(e instanceof bx))return e;let t=typeof e.content==`string`?e.content:JSON.stringify(e.content);if(t.length<=400)return e;let n=`…[已自动压缩 ${t.length} 字符,保留首 ${o}]\n`+t.slice(0,o);return i+=aW(t)-aW(n),new bx({tool_call_id:e.tool_call_id,content:n})}),c=s.reduce((e,t)=>e+n(t),0);return c>t&&console.warn(`[page-agent-sdk] trim 后仍超窗口:${c} > ${t} tokens(系统段/历史超预算,见 Phase 5/P3)`),s}function rK(e,t){return t??Math.max(e*3,30)}function iK(e,t){if(t<=0||e<0)return``;let n=t-e;return n<=0?``:n<=2?`⚠️ 轮次预算告急:本轮任务已用 ${e}/${t} 轮工具调用,仅剩 ${n} 轮。立即停止扩展性操作(查询/重读/优化),完成手头最关键的一步写入或委派,然后用纯文本给出诚实结论:哪些已完成、哪些未做(用 update_todo 如实标记),用户可回复「继续」续跑。`:e>=Math.ceil(t*.7)?`⚠️ 轮次预算提醒:本轮任务已用 ${e}/${t} 轮工具调用,剩余 ${n} 轮。优先完成核心写入/委派与收口,砍掉非必要的查询与重复读;若预估剩余步骤超出预算,先做最重要的部分并如实标记未完成项,不要等被打断。`:``}var aK=new Set([`write`,`set_data`,`edit_data`,`delete_data`,`draft_commit`]);function oK(e){if(!e||typeof e!=`object`)return``;let t=e;if(typeof t.jsonPath==`string`)return t.jsonPath;let n=t.patch;if(n&&typeof n.jsonPath==`string`)return n.jsonPath;let r=t.patches;return Array.isArray(r)&&r.length&&r[0]&&typeof r[0].jsonPath==`string`?r[0].jsonPath:``}function sK(e){let{apiKey:t,baseUrl:n,model:r=`gpt-3.5-turbo`,temperature:i=.7,maxTokens:a,extraBody:o,extraConfig:s,systemPrompt:c,tools:l=[],middleware:u=[],maxToolRounds:d,maxIterations:f,maxRetries:p=2,retryDelayMs:m=500,stallMs:h=_W,streamMaxMs:g=yW,maxParallelTools:_=1,maxVerifyAttempts:v=0,roundTokenBudget:y=0,onLog:b,onSpan:x,onTrace:S,onLlmChange:C,imageContentFormat:w=`openai`,staleReadInvalidation:T=!0,debug:E=!1}=e,D=d??$G;(!Number.isFinite(D)||D<1)&&(console.warn(`[page-agent-sdk] maxToolRounds=${D} 非法(须 ≥1 正整数),已 clamp 到 1(0/负数致主循环 while 不进 → agent 不调 LLM 静默返回兜底文案)`),D=1),_>1&&console.warn(`[page-agent-sdk] maxParallelTools=${_}:并发工具下 dataOps 写工具不互锁(同轮并发两写都在 await handleConflict 让出前取旧基线 → 均通过乐观锁 → 后写覆盖前写,无 VERSION_CONFLICT 回灌);并发写不互锁,如需冲突保护保持 maxParallelTools=1 并声明 conflictWatchFields`);let O=iW({model:r,contextWindow:e.contextWindow,maxOutputTokens:e.maxOutputTokens,vision:e.vision}),k=a??O.maxOutputTokens,A=oW(O.contextWindow),ee=sW(O.contextWindow);function j(e){O=e,A=oW(O.contextWindow),ee=sW(O.contextWindow)}let te=yz([]),ne=0,re=new Set;function M(e,t){let n={timestamp:Date.now(),type:e,data:t};te.value.push(n),te.value.length>eK&&te.value.splice(0,te.value.length-eK),xz(te),b?.(n),E&&console.log(`%c[Agent] ${e}`,`color:#667eea;font-weight:bold`,t)}let ie=e=>{te.value.push(e),te.value.length>eK&&te.value.splice(0,te.value.length-eK),xz(te)},ae=yz([]),oe=0,se=!!x||!!S;function ce(e,t,n,r={}){if(!se)return null;let i={id:`span-${++oe}`,parentId:e,name:n,type:t,startTs:Date.now(),status:`ok`,attributes:r};return ae.value.push(i),ae.value.length>eK&&ae.value.splice(0,ae.value.length-eK),xz(ae),i}function le(e,t=`ok`,n){!e||!se||(e.endTs=Date.now(),e.durationMs=e.endTs-e.startTs,e.status=t,n&&Object.assign(e.attributes,n),xz(ae),x?.(e))}let ue=[...u.flatMap(e=>e.tools||[]),...l],de=e.llm??new qI({apiKey:t,model:r,temperature:i,maxTokens:k,configuration:{...n?{baseURL:oL(n)}:{},fetch:aL,...s},...o?{modelKwargs:o}:{}}),fe=ue.length>0?de.bindTools?.(ue)??de:de,N=()=>{let e=de;return(typeof e.model==`string`&&e.model?e.model:typeof e.modelName==`string`&&e.modelName?e.modelName:``)||r};function pe(){fe=ue.length>0?de.bindTools?.(ue)??de:de}let me=lW();e.__pgIsSubagent&&(me.__pgIsSubagent=!0);let he=.25,ge=new Set([`mission`,`workingMemory`,`intentGuard`,`resumeNotice`]);function _e(){let e=c||`你是一个智能助手。`,t=[];for(let e of u)if(e.augmentPrompt){let n=e.augmentPrompt(me);n&&t.push({name:e.name,text:n,tokens:aW(n),pin:ge.has(e.name)})}let n=Math.max(2e3,Math.round(O.contextWindow*he)),r=aW(e)+t.reduce((e,t)=>e+t.tokens,0);if(r>n){let e=r,i=[];for(let e of t.filter(e=>!e.pin).sort((e,t)=>t.tokens-e.tokens)){if(r<=n)break;i.push(`${e.name}(${e.tokens})`),r-=e.tokens,e.text=``}i.length&&console.warn(`[page-agent-sdk] 系统段超预算(${e} > ${n} tokens,窗口 ${O.contextWindow} 的 ${he*100}%),drop 非核心段:${i.join(`, `)}(保 base/mission/workingMemory)`)}return[e,...t.filter(e=>e.text).map(e=>e.text)].join(`
|
|
176
176
|
|
|
177
|
-
`)}function P(e){let t=[new rS(_e())];for(let n of e)if(n.role===`user`){let e=O.vision&&n.images?.length?VU(n.content,n.images,w):null;e?t.push(new eS({content:e})):n.images?.some(e=>e.description)?t.push(new eS(HU(n.content,n.images))):t.push(new eS(n.content))}else n.role===`assistant`?t.push(new gS(n.content)):n.role===`system`&&t.push(new rS(n.content));return t}function ve(e,t){let n=e[0]&&I(e[0])===`system`?e.slice(1):e.slice(),r=_e();return[new rS(t?`${r}\n\n${t}`:r),...n]}async function F(e,t,n,r){let i=r??fe,a={signal:n,maxRetries:p,baseDelayMs:m,onRetry:({attempt:e,error:t,waitMs:n})=>{let r=t?.message??String(t);M(`error`,{stage:`model_retry`,attempt:e,waitMs:n,error:r}),console.warn(`[Agent] 模型调用失败,第 ${e}/${p} 次重试(等 ${n}ms):${r}`)}},o=new AbortController;n&&(n.aborted?o.abort():n.addEventListener(`abort`,()=>o.abort(),{once:!0}));let s;try{let t;try{s=await mW(()=>{clearTimeout(t);let n=h>0?h:_W,r=i.stream(e.messages,{signal:o.signal});return h>0?Promise.race([r,new Promise((e,r)=>{t=setTimeout(()=>r(new hW(n)),n)})]):r},a)}finally{clearTimeout(t)}}catch(i){if(uW(i,n))return{message:new gS(``),toolCalls:[],content:``,aborted:!0};if(xW(i)&&!e._ctxRetry){e._ctxRetry=!0;let i=e=>aW(typeof e.content==`string`?e.content:JSON.stringify(e.content)),a=e.messages.reduce((e,t)=>e+i(t),0),o=be(e.messages,Math.round(O.contextWindow*.3)),s=o.reduce((e,t)=>e+i(t),0);return M(`error`,{stage:`context_overflow_retry`,at:`launch`,beforeTokens:a,afterTokens:s,window:O.contextWindow}),console.warn(`[page-agent-sdk] 上下文超限(启动)→ 激进 trim 重试:${a} → ${s} tokens`),F({...e,messages:o},t,n,r)}throw i}if(!s)return{message:new gS(``),toolCalls:[],content:``,aborted:!0};let c=null,l=``;try{for await(let e of bW(s,h,g)){c=c?c.concat(e):e;let n=lL(e);n&&t&&(l+=n,t({type:`text`,delta:n}));let r=uL(e);r&&t&&t({type:`reasoning`,delta:r})}}catch(i){if(i instanceof hW)throw o.abort(),M(`error`,{stage:i instanceof gW?`stream_max_duration`:`stream_stalled`,waitedMs:i.waitedMs,stallMs:h,streamMaxMs:g}),i;if(uW(i,n))return{message:c??new gS(l),toolCalls:[],content:l,aborted:!0};if(xW(i)&&c===null&&l===``&&!e._ctxRetry){e._ctxRetry=!0;let i=e=>aW(typeof e.content==`string`?e.content:JSON.stringify(e.content)),a=e.messages.reduce((e,t)=>e+i(t),0),o=be(e.messages,Math.round(O.contextWindow*.3)),s=o.reduce((e,t)=>e+i(t),0);return M(`error`,{stage:`context_overflow_retry`,beforeTokens:a,afterTokens:s,window:O.contextWindow}),console.warn(`[page-agent-sdk] 上下文超限 → 激进 trim 重试:${a} → ${s} tokens(窗口 ${O.contextWindow})`),F({...e,messages:o},t,n,r)}throw i}if(c===null){if(!e._emptyRetry)return e._emptyRetry=!0,M(`error`,{stage:`empty_llm_response_retry`,hint:`流正常结束但零 chunk(网关 200+错误体形态),自动重试 1 次`}),F(e,t,n,r);throw M(`error`,{stage:`empty_llm_response`,retried:!0,hint:`重试后仍零 chunk,抛 EmptyLLMResponseError 显式报错`}),new vW}let u=c;return{message:u,toolCalls:u.tool_calls||[],content:l}}async function ye(e){let t=ue.find(t=>t.name===e.name);if(!t)return{content:`工具 "${e.name}" 不存在`,status:`error`};try{let n={__pgDataScope:``,...e.callConfig??{}},r=await t.invoke(e.args,{configurable:n}),i=typeof r==`string`?r:JSON.stringify(r),a=ue.some(e=>e.name===`vfs_read`);return i=$U(i,{files:e.state.files,vfsAvailable:!!e.state.files&&a,toolName:e.name,threshold:A,passThroughChars:ee}).content,{content:i,status:`done`}}catch(e){return{content:`工具执行出错:${MU(e,`recoverable`).message}`,status:`error`}}}function I(e){return e instanceof eS?`human`:e instanceof gS?`ai`:e instanceof rS?`system`:e instanceof bx?`tool`:`unknown`}function be(e,t){return nK(e,t)}function xe(e){return!E&&!b?[]:e.map(e=>{let t=I(e),n={role:t===`human`?`user`:t===`ai`?`assistant`:t},r=typeof e.content==`string`?e.content:JSON.stringify(e.content);r&&(n.content=r.length>tK?r.slice(0,tK)+`…(截断 ${r.length-tK} 字符)`:r);let i=e.tool_calls;Array.isArray(i)&&i.length&&(n.tool_calls=i.map(e=>({id:e.id,type:`function`,function:{name:e.name,arguments:typeof e.args==`string`?e.args:JSON.stringify(e.args)}})));let a=e.tool_call_id;return a&&(n.tool_call_id=a),n})}async function Se(t,n,r){ae.value=[],oe=0,me=lW(),e.__pgIsSubagent&&(me.__pgIsSubagent=!0),me.messages=t,me=await BG(u,me);let i=t;for(let e of u)if(e.compressInput){let t=ce(void 0,`compression`,`compress:${e.name}`,{}),n=await e.compressInput(i);i=Array.isArray(n)?n:n.messages,n&&!Array.isArray(n)&&n.stats?(me={...me,lastCompression:n.stats},le(t,`ok`,{stats:n.stats})):le(t)}{let e=aW(c||`你是一个智能助手。`),t=Math.max(2e3,Math.round(O.contextWindow*he));if(e>t){let r=`[page-agent-sdk] systemPrompt 本身(${e} tokens)超过系统段预算(${t} tokens,窗口 ${O.contextWindow} 的 ${he*100}%);请缩减 systemPrompt 或换更大窗口模型`;return console.error(r),n({type:`error`,message:r,severity:`fatal`,code:`SYSTEM_PROMPT_OVER_BUDGET`}),n({type:`done`,content:``}),``}}let a=P(i);M(`context`,{model:N(),tools:ue.map(e=>e.name),middleware:u.map(e=>e.name)});let o=GG(u,e=>F(e,n,r)),s=KG(u,ye),l={rounds:0,maxToolRounds:D,invokeUsage:{prompt_tokens:0,completion_tokens:0,total_tokens:0},writeFailures:{},budgetHinted:!1};me.loopProgress=l;let d={counts:{},writePaths:[],failures:0},p=jG(),m=new Map((me.todos??[]).map(e=>[e.id,e.status])),h=new Map,g=e=>{let t=ue.find(t=>t.name===e);return t&&`writeCapable`in t?typeof t.writeCapable==`function`||t.writeCapable===!0:aK.has(e)},b=0,x=0,C=rK(D,f),w=null,E=0,k=!1;try{for(;(b<D||k)&&x<C&&(x++,!r?.aborted);){if(y>0&&l.invokeUsage.total_tokens>y){let e=`本轮 token 预算(约 ${y})已用尽:任务在 ${b} 轮工具调用后中断,已完成的部分均保留。可继续对话,指定下一步(如「继续完成」/「只改 X」/「提高预算重试」)。`;return M(`error`,{stage:`round_token_budget_exceeded`,used:l.invokeUsage.total_tokens,budget:y,rounds:b}),n({type:`error`,message:e,severity:`observable`,code:`ROUND_TOKEN_BUDGET_EXCEEDED`,context:{used:l.invokeUsage.total_tokens,budget:y}}),n({type:`done`,content:e}),e}let e=ce(void 0,`round`,`round ${x}`,{round:x})?.id;n({type:`round_start`,round:x}),me=VG(u,{messages:a,state:me}),a=ve(a,iK(b,D)),a=be(a,Math.round(O.contextWindow*.6));let t=ce(e,`model`,N(),{round:b+1,tools:ue.map(e=>e.name)});M(`llm_request`,{round:b+1,model:N(),tools:ue.map(e=>e.name),messages:xe(a)});let i=await o({messages:a,state:me});a.push(i.message),M(`llm_response`,{round:b+1,content:i.content,toolCalls:i.toolCalls}),le(t,i.aborted?`timeout`:`ok`,{usage:dL(i.message)});{let e=pL(i.message);e&&(l.invokeUsage.prompt_tokens+=e.prompt_tokens??0,l.invokeUsage.completion_tokens+=e.completion_tokens??0,l.invokeUsage.total_tokens+=e.total_tokens??0)}if(me=HG(u,i,me),i.aborted)return n({type:`done`,content:i.content}),i.content;if(!i.toolCalls.length){let e=qG(i.content),t=e?ZG(i.content):null;if(t&&t.length){i.toolCalls=t;let e=i.message;e&&(e.tool_calls=t.map(e=>({id:e.id,name:e.name,args:e.args,type:`tool_call`}))),M(`middleware`,{stage:`dsml_parsed`,count:t.length,names:t.map(e=>e.name)})}else{if(e&&E<2){E+=1,k=!0,M(`middleware`,{stage:`format_retry`,attempt:E,content:i.content.slice(0,200)}),a.push(new eS(`⚠️ 你刚才把工具调用写成了文本(伪 XML/标签/DSML 标记,如 <|tool_calls|>、<||DSML||>、<invoke name=...>),未被系统识别为工具调用,因此未执行,页面无变化。请直接用标准 function calling(工具调用)格式重新发起工具调用,不要在回复正文里输出这些标签或 JSON 文本。`));continue}e&&(M(`error`,{stage:`garbled_exhausted`,retries:E,content:i.content.slice(0,200)}),n({type:`error`,message:`模型连续 2 次输出无法解析的工具调用格式(DSML/伪标签),任务可能未完成。请重试或换模型。`,severity:`observable`,code:`GARBLED_TOOL_CALL_EXHAUSTED`,context:{content:i.content.slice(0,200)}}));let t=IG({state:p,garbled:e,rounds:b,finalContent:i.content,todos:me.todos,isSubagent:!!me.__pgIsSubagent,turnUsage:d,isWriteToolByName:g,messages:a,sessionWritePaths:re,todosStatusAtStart:m});if(t?.kind===`feedback`){k=!0,M(`middleware`,{stage:t.gate.stage,attempt:t.gate.attempt,...t.gate.logData??{},content:i.content.slice(0,160)}),a.push(new eS(t.gate.feedback));continue}if(t?.kind===`observable`&&n({type:`error`,message:t.obs.message,severity:`observable`,code:t.obs.code,context:t.obs.context}),!e&&v>0&&me.verifyAttempts<v){let e=await WG(u,{messages:a,state:me,response:i,log:(e,t)=>M(e,t)});if(e){w=i.content,me.verifyAttempts+=1,a.push(new eS(`⚠️ 验证未通过,请修正:${e}`)),M(`middleware`,{stage:`verify_retry`,attempt:me.verifyAttempts,feedback:e});continue}}k=!1;let r=i.content;if(e){let e=JG(r);r=e?`${e}\n\n(注:此后模型输出了无法解析的工具调用文本,该调用未执行,任务可能未完成。)`:`模型多次输出无法解析的工具调用格式,本次任务可能未完成。请重试或继续指示。`}return n({type:`done`,content:r}),r}}k=!1;let c=i.toolCalls.map(e=>{let t=e.id||`call_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return{id:t,call:e,ctx:{id:t,name:e.name,args:e.args,state:me,signal:r,emit:n,logSink:ie}}}),f=await eW(c,_,async t=>{if(r?.aborted)return;let i=ce(e,`tool`,t.call.name,{name:t.call.name}),a=Date.now();n({type:`tool_call`,name:t.call.name,args:t.call.args,id:t.id}),M(`tool_call`,{round:b+1,name:t.call.name,args:t.call.args,id:t.id});let o;try{o=await s(t.ctx)}catch(e){if(uW(e,r))throw e;o={content:`工具执行出错:${MU(e,`recoverable`).message}`,status:`error`}}let c=Date.now()-a;return n({type:`tool_result`,name:t.call.name,result:o.content,status:o.status,durationMs:c,id:t.id}),M(`tool_result`,{round:b+1,name:t.call.name,result:o.content,status:o.status,durationMs:c}),le(i,o.status===`error`?`error`:`ok`,{resultSnippet:String(o.content).slice(0,100)}),o},r);for(let e=0;e<c.length;e++){let t=f[e];if(!t)continue;let n=`${c[e].call.name}|${JSON.stringify(c[e].call.args??{})}`,r=t.status===`error`||typeof t.content==`string`&&t.content.startsWith(`ERROR:`),i=t.content;if(r){let e=(h.get(n)??0)+1;h.set(n,e),e>=2&&(i=`${t.content}\n(提示:同参数已连续失败 ${e} 次,原样重试大概率仍失败;请检查参数/换路径/换方法,或向用户如实说明困难)`)}else h.delete(n);a.push(new bx({tool_call_id:c[e].id,content:i}))}for(let e=0;e<c.length;e++){let t=f[e];if(!t||!aK.has(c[e].call.name))continue;let n=oK(c[e].call.args);t.status===`error`?l.writeFailures[n]=(l.writeFailures[n]??0)+1:delete l.writeFailures[n]}let S=[];for(let e=0;e<c.length;e++){let t=f[e];if(!t)continue;let n=c[e].call.name;if(d.counts[n]=(d.counts[n]??0)+1,t.status===`error`&&(d.failures+=1),SW(ue.find(e=>e.name===n),c[e].call.args,t)){let t=oK(c[e].call.args);d.writePaths.push(t||`(整体)`),S.push({name:n,args:c[e].call.args,callIndex:e});let r=QW({name:n,args:c[e].call.args,callIndex:e});if(r)for(let e of r.paths)re.add(e)}}if(T&&S.length){let e=eG(a,S,{round:b+1,maxParallelTools:_});e.invalidatedCount>0&&(a=e.messages,ne+=e.invalidatedCount,M(`middleware`,{stage:`stale_read_invalidated`,round:b+1,writtenPaths:S.map(e=>oK(e.args)||`(整体)`),invalidatedCount:e.invalidatedCount}))}if(r?.aborted)break;b++,l.rounds=b}if(r?.aborted)return n({type:`done`,content:``}),``;let e=`\n\n(提示:工具调用次数已达上限(${D} 轮 / ${C} 次迭代),以上为基于已完成操作的阶段性结果,任务可能未完成。回复「继续」或告诉我下一步重点,即可接着做。)`;M(`error`,{stage:`react_call_limit_exceeded`,rounds:b,maxToolRounds:D,iterations:x,maxIterations:C}),n({type:`error`,message:`ReAct 循环达到调用上限(rounds=${b}/${D},iterations=${x}/${C}),已强制收口,可回复「继续」。`,severity:`observable`,code:`REACT_CALL_LIMIT_EXCEEDED`,context:{rounds:b,maxToolRounds:D,iterations:x,maxIterations:C}});let t=LG(me.todos??[],m,re);if(t.length){let e=t.map(e=>({id:e.id,evidence:e.evidence}));M(`middleware`,{stage:`evidence_audit_flagged`,offenders:e}),n({type:`error`,message:`轮次耗尽收口:${t.length} 项已完成任务的 evidence 路径与写入记录不符,最终回复中的完成声明可能不实`,severity:`observable`,code:`AUDIT_EVIDENCE_SUSPECT`,context:{offenders:e}})}if(w!=null){let t=w+e;return n({type:`done`,content:t}),t}let i=a[a.length-1];if(i&&I(i)===`tool`){let t=a[0]&&I(a[0])===`system`?a.slice(1):a.slice(),i=[new rS(_e()+`
|
|
177
|
+
`)}function P(e){let t=[new rS(_e())];for(let n of e)if(n.role===`user`){let e=O.vision&&n.images?.length?VU(n.content,n.images,w):null;e?t.push(new eS({content:e})):n.images?.some(e=>e.description)?t.push(new eS(HU(n.content,n.images))):t.push(new eS(n.content))}else n.role===`assistant`?t.push(new gS(n.content)):n.role===`system`&&t.push(new rS(n.content));return t}function ve(e,t){let n=e[0]&&I(e[0])===`system`?e.slice(1):e.slice(),r=_e();return[new rS(t?`${r}\n\n${t}`:r),...n]}async function F(e,t,n,r){let i=r??fe,a={signal:n,maxRetries:p,baseDelayMs:m,onRetry:({attempt:e,error:t,waitMs:n})=>{let r=t?.message??String(t);M(`error`,{stage:`model_retry`,attempt:e,waitMs:n,error:r}),console.warn(`[Agent] 模型调用失败,第 ${e}/${p} 次重试(等 ${n}ms):${r}`)}},o=new AbortController;n&&(n.aborted?o.abort():n.addEventListener(`abort`,()=>o.abort(),{once:!0}));let s;try{let t;try{s=await mW(()=>{clearTimeout(t);let n=h>0?h:_W,r=i.stream(e.messages,{signal:o.signal});return h>0?Promise.race([r,new Promise((e,r)=>{t=setTimeout(()=>r(new hW(n)),n)})]):r},a)}finally{clearTimeout(t)}}catch(i){if(uW(i,n))return{message:new gS(``),toolCalls:[],content:``,aborted:!0};if(xW(i)&&!e._ctxRetry){e._ctxRetry=!0;let i=e=>aW(typeof e.content==`string`?e.content:JSON.stringify(e.content)),a=e.messages.reduce((e,t)=>e+i(t),0),o=be(e.messages,Math.round(O.contextWindow*.3)),s=o.reduce((e,t)=>e+i(t),0);return M(`error`,{stage:`context_overflow_retry`,at:`launch`,beforeTokens:a,afterTokens:s,window:O.contextWindow}),console.warn(`[page-agent-sdk] 上下文超限(启动)→ 激进 trim 重试:${a} → ${s} tokens`),F({...e,messages:o},t,n,r)}throw i}if(!s)return{message:new gS(``),toolCalls:[],content:``,aborted:!0};let c=null,l=``;try{for await(let e of bW(s,h,g)){c=c?c.concat(e):e;let n=lL(e);n&&t&&(l+=n,t({type:`text`,delta:n}));let r=uL(e);r&&t&&t({type:`reasoning`,delta:r})}}catch(i){if(i instanceof hW)throw o.abort(),M(`error`,{stage:i instanceof gW?`stream_max_duration`:`stream_stalled`,waitedMs:i.waitedMs,stallMs:h,streamMaxMs:g}),i;if(uW(i,n))return{message:c??new gS(l),toolCalls:[],content:l,aborted:!0};if(xW(i)&&c===null&&l===``&&!e._ctxRetry){e._ctxRetry=!0;let i=e=>aW(typeof e.content==`string`?e.content:JSON.stringify(e.content)),a=e.messages.reduce((e,t)=>e+i(t),0),o=be(e.messages,Math.round(O.contextWindow*.3)),s=o.reduce((e,t)=>e+i(t),0);return M(`error`,{stage:`context_overflow_retry`,beforeTokens:a,afterTokens:s,window:O.contextWindow}),console.warn(`[page-agent-sdk] 上下文超限 → 激进 trim 重试:${a} → ${s} tokens(窗口 ${O.contextWindow})`),F({...e,messages:o},t,n,r)}throw i}if(c===null){if(!e._emptyRetry)return e._emptyRetry=!0,M(`error`,{stage:`empty_llm_response_retry`,hint:`流正常结束但零 chunk(网关 200+错误体形态),自动重试 1 次`}),F(e,t,n,r);throw M(`error`,{stage:`empty_llm_response`,retried:!0,hint:`重试后仍零 chunk,抛 EmptyLLMResponseError 显式报错`}),new vW}let u=c;return{message:u,toolCalls:u.tool_calls||[],content:l}}async function ye(e){let t=ue.find(t=>t.name===e.name);if(!t)return{content:`工具 "${e.name}" 不存在`,status:`error`};try{let n={__pgDataScope:``,...e.callConfig??{}},r=await t.invoke(e.args,{configurable:n}),i=typeof r==`string`?r:JSON.stringify(r),a=ue.some(e=>e.name===`vfs_read`);return i=$U(i,{files:e.state.files,vfsAvailable:!!e.state.files&&a,toolName:e.name,threshold:A,passThroughChars:ee}).content,{content:i,status:`done`}}catch(e){return{content:`工具执行出错:${MU(e,`recoverable`).message}`,status:`error`}}}function I(e){return e instanceof eS?`human`:e instanceof gS?`ai`:e instanceof rS?`system`:e instanceof bx?`tool`:`unknown`}function be(e,t){return nK(e,t)}function xe(e){return!E&&!b?[]:e.map(e=>{let t=I(e),n={role:t===`human`?`user`:t===`ai`?`assistant`:t},r=typeof e.content==`string`?e.content:JSON.stringify(e.content);r&&(n.content=r.length>tK?r.slice(0,tK)+`…(截断 ${r.length-tK} 字符)`:r);let i=e.tool_calls;Array.isArray(i)&&i.length&&(n.tool_calls=i.map(e=>({id:e.id,type:`function`,function:{name:e.name,arguments:typeof e.args==`string`?e.args:JSON.stringify(e.args)}})));let a=e.tool_call_id;return a&&(n.tool_call_id=a),n})}async function Se(t,n,r){ae.value=[],oe=0,me=lW(),e.__pgIsSubagent&&(me.__pgIsSubagent=!0),me.messages=t,me=await BG(u,me);let i=t;for(let e of u)if(e.compressInput){let t=ce(void 0,`compression`,`compress:${e.name}`,{}),n=await e.compressInput(i);i=Array.isArray(n)?n:n.messages,n&&!Array.isArray(n)&&n.stats?(me={...me,lastCompression:n.stats},le(t,`ok`,{stats:n.stats})):le(t)}{let e=aW(c||`你是一个智能助手。`),t=Math.max(2e3,Math.round(O.contextWindow*he));if(e>t){let r=`[page-agent-sdk] systemPrompt 本身(${e} tokens)超过系统段预算(${t} tokens,窗口 ${O.contextWindow} 的 ${he*100}%);请缩减 systemPrompt 或换更大窗口模型`;return console.error(r),n({type:`error`,message:r,severity:`fatal`,code:`SYSTEM_PROMPT_OVER_BUDGET`}),n({type:`done`,content:``}),``}}let a=P(i);M(`context`,{model:N(),tools:ue.map(e=>e.name),middleware:u.map(e=>e.name)});let o=GG(u,e=>F(e,n,r)),s=KG(u,ye),l={rounds:0,maxToolRounds:D,invokeUsage:{prompt_tokens:0,completion_tokens:0,total_tokens:0},writeFailures:{},budgetHinted:!1};me.loopProgress=l;let d={counts:{},writePaths:[],failures:0},p=jG(),m=new Map((me.todos??[]).map(e=>[e.id,e.status])),h=new Map,g=e=>{let t=ue.find(t=>t.name===e);return t&&`writeCapable`in t?typeof t.writeCapable==`function`||t.writeCapable===!0:aK.has(e)},b=0,x=0,C=rK(D,f),w=null,E=0,k=!1;try{for(;(b<D||k)&&x<C&&(x++,!r?.aborted);){if(y>0&&l.invokeUsage.total_tokens>y){let e=`本轮 token 预算(约 ${y})已用尽:任务在 ${b} 轮工具调用后中断,已完成的部分均保留。可继续对话,指定下一步(如「继续完成」/「只改 X」/「提高预算重试」)。`;return M(`error`,{stage:`round_token_budget_exceeded`,used:l.invokeUsage.total_tokens,budget:y,rounds:b}),n({type:`error`,message:e,severity:`observable`,code:`ROUND_TOKEN_BUDGET_EXCEEDED`,context:{used:l.invokeUsage.total_tokens,budget:y}}),n({type:`done`,content:e}),e}let e=ce(void 0,`round`,`round ${x}`,{round:x})?.id;n({type:`round_start`,round:x}),me=VG(u,{messages:a,state:me}),a=ve(a,iK(b,D)),a=be(a,Math.round(O.contextWindow*.6));let t=ce(e,`model`,N(),{round:b+1,tools:ue.map(e=>e.name)});M(`llm_request`,{round:b+1,model:N(),tools:ue.map(e=>e.name),messages:xe(a)});let i=await o({messages:a,state:me});a.push(i.message),M(`llm_response`,{round:b+1,content:i.content,toolCalls:i.toolCalls}),le(t,i.aborted?`timeout`:`ok`,{usage:dL(i.message)});{let e=pL(i.message);e&&(l.invokeUsage.prompt_tokens+=e.prompt_tokens??0,l.invokeUsage.completion_tokens+=e.completion_tokens??0,l.invokeUsage.total_tokens+=e.total_tokens??0)}if(me=HG(u,i,me),i.aborted)return n({type:`done`,content:i.content}),i.content;if(!i.toolCalls.length){let e=qG(i.content),t=e?ZG(i.content):null;if(t&&t.length){i.toolCalls=t;let e=i.message;e&&(e.tool_calls=t.map(e=>({id:e.id,name:e.name,args:e.args,type:`tool_call`}))),M(`middleware`,{stage:`dsml_parsed`,count:t.length,names:t.map(e=>e.name)})}else{if(e&&E<2){E+=1,k=!0,M(`middleware`,{stage:`format_retry`,attempt:E,content:i.content.slice(0,200)}),a.push(new eS(`⚠️ 你刚才把工具调用写成了文本(伪 XML/标签/DSML 标记,如 <|tool_calls|>、<||DSML||>、<invoke name=...>),未被系统识别为工具调用,因此未执行,页面无变化。请直接用标准 function calling(工具调用)格式重新发起工具调用,不要在回复正文里输出这些标签或 JSON 文本。`));continue}e&&(M(`error`,{stage:`garbled_exhausted`,retries:E,content:i.content.slice(0,200)}),n({type:`error`,message:`模型连续 2 次输出无法解析的工具调用格式(DSML/伪标签),任务可能未完成。请重试或换模型。`,severity:`observable`,code:`GARBLED_TOOL_CALL_EXHAUSTED`,context:{content:i.content.slice(0,200)}}));let t=IG({state:p,garbled:e,rounds:b,finalContent:i.content,todos:me.todos,isSubagent:!!me.__pgIsSubagent,turnUsage:d,isWriteToolByName:g,messages:a,sessionWritePaths:re,todosStatusAtStart:m});if(t?.kind===`feedback`){k=!0,M(`middleware`,{stage:t.gate.stage,attempt:t.gate.attempt,...t.gate.logData??{},content:i.content.slice(0,160)}),a.push(new eS(t.gate.feedback));continue}if(t?.kind===`observable`&&n({type:`error`,message:t.obs.message,severity:`observable`,code:t.obs.code,context:t.obs.context}),!e&&v>0&&me.verifyAttempts<v){let e=await WG(u,{messages:a,state:me,response:i,log:(e,t)=>M(e,t)});if(e){w=i.content,me.verifyAttempts+=1,a.push(new eS(`⚠️ 验证未通过,请修正:${e}`)),M(`middleware`,{stage:`verify_retry`,attempt:me.verifyAttempts,feedback:e});continue}}k=!1;let r=i.content;if(e){let e=JG(r);r=e?`${e}\n\n(注:此后模型输出了无法解析的工具调用文本,该调用未执行,任务可能未完成。)`:`模型多次输出无法解析的工具调用格式,本次任务可能未完成。请重试或继续指示。`}return n({type:`done`,content:r}),r}}k=!1;let c=i.toolCalls.map(e=>{let t=e.id||`call_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return{id:t,call:e,ctx:{id:t,name:e.name,args:e.args,state:me,signal:r,emit:n,logSink:ie}}}),f=await eW(c,_,async t=>{if(r?.aborted)return;let i=ce(e,`tool`,t.call.name,{name:t.call.name}),a=Date.now();n({type:`tool_call`,name:t.call.name,args:t.call.args,id:t.id}),M(`tool_call`,{round:b+1,name:t.call.name,args:t.call.args,id:t.id});let o;try{o=await s(t.ctx)}catch(e){if(uW(e,r))throw e;o={content:`工具执行出错:${MU(e,`recoverable`).message}`,status:`error`}}let c=Date.now()-a;return n({type:`tool_result`,name:t.call.name,result:o.content,status:o.status,durationMs:c,id:t.id}),M(`tool_result`,{round:b+1,name:t.call.name,result:o.content,status:o.status,durationMs:c}),le(i,o.status===`error`?`error`:`ok`,{resultSnippet:String(o.content).slice(0,100)}),o},r);for(let e=0;e<c.length;e++){let t=f[e];if(!t)continue;let n=e=>e&&typeof e==`object`&&!Array.isArray(e)?Object.fromEntries(Object.keys(e).sort().map(t=>[t,n(e[t])])):e,r=`${c[e].call.name}|${JSON.stringify(n(c[e].call.args??{}))}`,i=t.status===`error`||typeof t.content==`string`&&t.content.startsWith(`ERROR:`),o=t.content;if(i){let e=(h.get(r)??0)+1;h.set(r,e),e>=2&&(o=`${t.content}\n(提示:同参数已连续失败 ${e} 次,原样重试大概率仍失败;请检查参数/换路径/换方法,或向用户如实说明困难)`)}else h.delete(r);a.push(new bx({tool_call_id:c[e].id,content:o}))}for(let e=0;e<c.length;e++){let t=f[e];if(!t||!aK.has(c[e].call.name))continue;let n=oK(c[e].call.args);t.status===`error`?l.writeFailures[n]=(l.writeFailures[n]??0)+1:delete l.writeFailures[n]}let S=[];for(let e=0;e<c.length;e++){let t=f[e];if(!t)continue;let n=c[e].call.name;if(d.counts[n]=(d.counts[n]??0)+1,t.status===`error`&&(d.failures+=1),SW(ue.find(e=>e.name===n),c[e].call.args,t)){let t=oK(c[e].call.args);d.writePaths.push(t||`(整体)`),S.push({name:n,args:c[e].call.args,callIndex:e});let r=QW({name:n,args:c[e].call.args,callIndex:e});if(r)for(let e of r.paths)re.add(e)}}if(T&&S.length){let e=eG(a,S,{round:b+1,maxParallelTools:_});e.invalidatedCount>0&&(a=e.messages,ne+=e.invalidatedCount,M(`middleware`,{stage:`stale_read_invalidated`,round:b+1,writtenPaths:S.map(e=>oK(e.args)||`(整体)`),invalidatedCount:e.invalidatedCount}))}if(r?.aborted)break;b++,l.rounds=b}if(r?.aborted)return n({type:`done`,content:``}),``;let e=`\n\n(提示:工具调用次数已达上限(${D} 轮 / ${C} 次迭代),以上为基于已完成操作的阶段性结果,任务可能未完成。回复「继续」或告诉我下一步重点,即可接着做。)`;M(`error`,{stage:`react_call_limit_exceeded`,rounds:b,maxToolRounds:D,iterations:x,maxIterations:C}),n({type:`error`,message:`ReAct 循环达到调用上限(rounds=${b}/${D},iterations=${x}/${C}),已强制收口,可回复「继续」。`,severity:`observable`,code:`REACT_CALL_LIMIT_EXCEEDED`,context:{rounds:b,maxToolRounds:D,iterations:x,maxIterations:C}});let t=LG(me.todos??[],m,re);if(t.length){let e=t.map(e=>({id:e.id,evidence:e.evidence}));M(`middleware`,{stage:`evidence_audit_flagged`,offenders:e}),n({type:`error`,message:`轮次耗尽收口:${t.length} 项已完成任务的 evidence 路径与写入记录不符,最终回复中的完成声明可能不实`,severity:`observable`,code:`AUDIT_EVIDENCE_SUSPECT`,context:{offenders:e}})}if(w!=null){let t=w+e;return n({type:`done`,content:t}),t}let i=a[a.length-1];if(i&&I(i)===`tool`){let t=a[0]&&I(a[0])===`system`?a.slice(1):a.slice(),i=[new rS(_e()+`
|
|
178
178
|
|
|
179
179
|
工具调用次数已达上限,请基于已有工具结果直接给出最终回答,不要再调用工具。`),...t];M(`llm_request`,{round:`wrap_up`,model:N(),tools:[],messages:xe(i)});let o=await GG(u,e=>F(e,n,r,de))({messages:i,state:me});if(me=HG(u,o,me),M(`llm_response`,{round:`wrap_up`,content:o.content}),o.aborted)return n({type:`done`,content:o.content}),o.content;if(o.content){let t=o.content;if(qG(t)){let e=JG(t);M(`error`,{stage:`garbled_wrapup`,content:t.slice(0,200)}),n({type:`error`,message:`模型在收口(工具轮耗尽)时输出无法解析的工具调用格式,任务可能未完成。请重试或换模型。`,severity:`observable`,code:`GARBLED_TOOL_CALL_EXHAUSTED`,context:{content:t.slice(0,200)}}),t=e?`${e}\n\n(注:工具调用次数已达上限,模型最后试图发起的调用未执行,任务可能未完成。)`:`我已完成本轮能做的部分操作,但最后的计划未能执行(工具调用次数已达上限)。请重试或继续指示。`}return n({type:`done`,content:t+e}),t+e}}let c=`我已完成本轮能做的操作,但未能综合出最终结论。请基于上方已完成的工具操作结果继续,或告诉我下一步重点。`;return n({type:`done`,content:c+e}),c+e}finally{try{await UG(u,me)}catch(e){let t=MU(e,`observable`);console.warn(`[Agent] afterAgent 清理出错(observable,已忽略):`,t.message)}if(se&&S)try{S(ae.value,cW(ae.value))}catch{}}}async function Ce(e,t,n){let r=``;return await Se(e,e=>{e.type===`done`&&(r=e.content),n?.(e)},t),r}function we(e){ue=[...u.flatMap(e=>e.tools||[]),...e],pe()}function Te(e){de=e,pe(),C?.(e)}return{invoke:Ce,stream:Se,getState:()=>me,get allTools(){return ue},getStaleReadsInvalidated:()=>ne,resetStaleReadsInvalidated:()=>{ne=0},setTools:we,setLlm:Te,setModelCaps:j,debugLogs:te,spans:ae,getEffectiveSystemPrompt:()=>_e()}}Yp();function cK(e){let t=e;for(let e=0;e<5&&t&&t._def;e++){if(t._def.innerType){t=t._def.innerType;continue}break}if(!t||!t.shape||typeof t.shape!=`object`)return null;try{let e=typeof t.shape==`function`?t.shape():t.shape;return Object.keys(e)}catch{return null}}function lK(e,t,n){if(!n||!e)return!0;let r=uK(t);for(let t of e.split(`.`)){if(t.startsWith(`__pg`)||!r)return!1;if(r=uK(r),r&&r.shape&&typeof r.shape==`object`){let e=typeof r.shape==`function`?r.shape():r.shape;if(!(t in e))return!1;r=e[t]}else if(r&&(r._def?.type===`array`||r.constructor?.name===`ZodArray`)){if(!/^\d+$/.test(t))return!1;r=r.element}else if(r&&(r._def?.type===`union`||r._def?.type===`discriminatedUnion`||Array.isArray(r.options)))return!0;else if(r&&r._def?.type===`record`)r=r._def.valueType;else if(r&&(r._def?.type===`any`||r._def?.type===`unknown`))r=r;else return!1}return!0}function uK(e){let t=e;for(let e=0;e<8&&t&&t._def;e++){if(t._def.innerType){t=t._def.innerType;continue}if(t._def.schema){t=t._def.schema;continue}if(t._def.getter){t=t._def.getter();continue}break}return t}function dK(e,t){if(!t)return e;let n=uK(e),r=t.split(`.`);for(let e=0;e<r.length;e++){let t=r[e];if(!n)return null;if(n=uK(n),n&&n.shape&&typeof n.shape==`object`)n=(typeof n.shape==`function`?n.shape():n.shape)[t];else if(n&&(n._def?.type===`array`||n.constructor?.name===`ZodArray`)){if(!/^\d+$/.test(t))return null;n=n.element}else if(n&&(n._def?.type===`union`||n._def?.type===`discriminatedUnion`||Array.isArray(n.options))){let t=r.slice(e).join(`.`),i=(n.options??[]).map(e=>dK(e,t)).filter(e=>e!=null);return i.length?i[0]:null}else if(n&&n._def?.type===`record`)n=n._def.valueType;else if(!(n&&(n._def?.type===`any`||n._def?.type===`unknown`)))return null}return n??null}function fK(e){return e._def?.type===`union`||e._def?.type===`discriminatedUnion`||Array.isArray(e.options)&&e.options.length>0&&typeof e.options[0]==`object`&&e.options[0]?._def!=null}function pK(e){if(!e||!e.shape)return!1;let t=e._def?.catchall??e._def?.catchAll;return!t||!t._def?!1:t._def.type!==`never`}function mK(e,t){let n=e=>{let t=[],n=[...e];for(;n.length;){let e=uK(n.shift());if(e){if(fK(e)){n.push(...e.options??[]);continue}t.push(e)}}return t};if(!t)return{kind:`schemas`,schemas:[e]};let r=[e];for(let e of t.split(`.`)){let t=[],i=!1;for(let a of n(r)){if(a._def?.type===`any`||a._def?.type===`unknown`){i=!0;continue}if(a.shape&&typeof a.shape==`object`){let n=typeof a.shape==`function`?a.shape():a.shape;e in n?t.push(n[e]):pK(a)&&(i=!0)}else a._def?.type===`array`||a.constructor?.name===`ZodArray`?/^\d+$/.test(e)&&t.push(a.element):a._def?.type===`record`&&t.push(a._def.valueType)}if(i)return{kind:`open`};if(!t.length)return{kind:`missing`};r=t}return{kind:`schemas`,schemas:r.filter(Boolean)}}function hK(e,t,n){let r=mK(e,t);if(r.kind===`open`)return{ok:!0,data:n,resolution:`open`};if(r.kind===`missing`)return{ok:!1,resolution:`missing`,issues:[]};let i=[];for(let e of r.schemas){let t=e.safeParse(n);if(t.success)return{ok:!0,data:t.data,resolution:`schemas`};i.push(...t.error?.issues??[])}return{ok:!1,issues:i,resolution:`schemas`}}function gK(e){let t=uK(e)?._def?.checks;return Array.isArray(t)?t.some(e=>e?._zod?.def?.check===`custom`):!1}function _K(e){let t=uK(e)?._def?.checks;if(!Array.isArray(t))return null;let n=null;for(let e of t){let t=e?._zod?.def;t?.check===`min_length`&&typeof t.minimum==`number`&&(n=Math.max(n??0,t.minimum))}return n}function vK(e){let t=[];for(let n of e){let e=uK(n);(e?._def?.type===`array`||e?.constructor?.name===`ZodArray`)&&e.element&&t.push(e.element)}return t}function yK(e){let t=uK(e);return t?._def?.type===`string`||t?.constructor?.name===`ZodString`}function bK(e){let t=uK(e);return t?._def?.type===`array`||t?.constructor?.name===`ZodArray`?t.element??null:null}function xK(e,t=`code`){let n=uK(e);if(!n)return!1;if(n.shape&&typeof n.shape==`object`){let e=typeof n.shape==`function`?n.shape():n.shape;return t in e&&yK(e[t])}return n._def?.type===`union`||Array.isArray(n.options)?(n.options??[]).some(e=>xK(e,t)):!1}function SK(e){let t=uK(e);if(!t||!t.shape||typeof t.shape!=`object`)return!1;let n=typeof t.shape==`function`?t.shape():t.shape;for(let e of Object.keys(n)){if(e===`code`&&yK(n[e]))return!0;let t=bK(n[e]);if(t&&xK(t))return!0}return!1}function CK(e,t=`code`){let n=uK(e);if(!n||!n.shape||typeof n.shape!=`object`)return[];let r=typeof n.shape==`function`?n.shape():n.shape,i=[];for(let e of Object.keys(r)){if(e.startsWith(`__pg`))continue;let n=bK(r[e]);n&&xK(n,t)&&i.push(e)}return i}function wK(e,t){if(typeof e!=`object`||!e||!t)return e;let n=uK(t);if(!n||!n.shape){if(Array.isArray(e)&&(n?._def?.type||n?.element)){let t=n.element??n._def?.type;return e.map(e=>wK(e,t))}if(!Array.isArray(e)){let t=e,n=Object.keys(t);if(!n.some(e=>e.startsWith(`__pg`)))return e;let r={};for(let e of n)e.startsWith(`__pg`)||(r[e]=t[e]);return r}return e}let r=typeof n.shape==`function`?n.shape():n.shape,i={};for(let t of Object.keys(e))if(t in r&&!t.startsWith(`__pg`)){let n=e[t];i[t]=wK(n,r[t])}return i}function TK(e,t){if(!t||typeof e!=`object`||!e||Array.isArray(e))return e;let n=new Set(t),r={};for(let t of Object.keys(e))n.has(t)&&(r[t]=e[t]);return r}var EK=!1;function DK(){EK||=!0}function OK(e){let t=e?._def?.checks;if(!Array.isArray(t))return[];let n=[];for(let e of t)e?._zod?.def&&n.push(e._zod.def);return n}function kK(e){return e===-(2**53-1)||e===-1/0}function AK(e){return e===2**53-1||e===1/0}function jK(e,t=new WeakSet,n=0){let r=!1,i=!1,a=!1,o,s=e;for(let e=0;e<8&&s&&s._def;e++){let e=s._def.type;if(e===`optional`||e==="default"||e===`nullable`||e===`catch`||e===`readonly`||e===`prefault`){e===`optional`?r=!0:e===`nullable`?i=!0:(e==="default"||e===`prefault`)&&(a=!0,o=s._def.defaultValue),s=s._def.innerType;continue}if(e===`lazy`){s=s._def.getter?s._def.getter():s._def.schema;continue}if(e===`pipe`){s=s._def.in??s._def.innerType;continue}break}let c=s?._def?.type||`unknown`;if(s?._def||DK(),n>15)return{type:c,description:`↩ 深度截断(>15,防栈溢出;查深层用 schema_data({jsonPath}))`};if(s&&typeof s==`object`&&t.has(s))return{type:c,description:`↩ 递归引用(容器 children 自引用,已截断防栈溢出)`};s&&typeof s==`object`&&t.add(s);let l={type:c};r&&(l.optional=!0),i&&(l.nullable=!0),a&&(l.default=o),s?.description&&(l.description=s.description);let u={};switch(c){case`string`:{s.minLength!=null&&(u.minLength=s.minLength),s.maxLength!=null&&(u.maxLength=s.maxLength);let e=OK(s).filter(e=>e.check===`string_format`).map(e=>e.format).filter(Boolean);e.length&&(u.format=e.length===1?e[0]:e);break}case`number`:s.minValue!=null&&!kK(s.minValue)&&(u.min=s.minValue),s.maxValue!=null&&!AK(s.maxValue)&&(u.max=s.maxValue),s.isInt&&(u.int=!0),s.format&&s.format!==`number`&&(u.format=s.format);break;case`enum`:u.values=s.options;break;case`literal`:{let e=s._def?.values??(s._def?.value===void 0?[]:[s._def.value]);u.value=e.length===1?e[0]:e;break}case`array`:u.item=jK(s.element,t,n+1);for(let e of OK(s))e.check===`min_length`?u.minLength=e.minimum:e.check===`max_length`?u.maxLength=e.maximum:e.check===`length_equals`&&(u.length=e.length);break;case`object`:{let e=typeof s.shape==`function`?s.shape():s.shape;u.shape=Object.fromEntries(Object.entries(e||{}).map(([e,r])=>[e,jK(r,t,n+1)]));break}case`union`:{let e=(s._def?.options||[]).map(e=>jK(e,t,n+1));e.length&&(u.anyOf=e);break}case`record`:s._def?.valueType&&(u.valueType=jK(s._def.valueType,t,n+1));break;default:break}return Object.keys(u).length&&(l.constraints=u),l}function MK(e){let t=[];return e.minLength!==void 0&&t.push(`minLen=${e.minLength}`),e.maxLength!==void 0&&t.push(`maxLen=${e.maxLength}`),e.length!==void 0&&t.push(`len=${e.length}`),e.min!==void 0&&t.push(`min=${e.min}`),e.max!==void 0&&t.push(`max=${e.max}`),e.int&&t.push(`int`),e.format&&t.push(`format=${Array.isArray(e.format)?e.format.join(`|`):e.format}`),e.values&&t.push(`enum=[${e.values.map(e=>String(e)).join(`|`)}]`),e.value!==void 0&&t.push(`=${JSON.stringify(e.value)}`),t.join(`, `)}function NK(e,t){let n=[t.constraints?MK(t.constraints):``,t.type===`record`?`键集开放,任意键可写`:``].filter(Boolean),r=n.length?`[${n.join(`, `)}]`:``,i=t.optional?`?`:``,a=t.description?`: ${t.description}`:``;return`- ${e} (${t.type}${i})${r}${a}`}function PK(e){if(!e)return``;try{let t=e;for(let e=0;e<8&&t&&t._def;e++){if(t._def.innerType){t=t._def.innerType;continue}if(t._def.getter){t=t._def.getter();continue}if(t._def.schema){t=t._def.schema;continue}break}let n=t?.shape?typeof t.shape==`function`?t.shape():t.shape:null;if(n&&typeof n==`object`&&Object.keys(n).length)return Object.entries(n).map(([e,t])=>NK(e,jK(t))).join(`
|
|
180
180
|
`)}catch{}try{return NK(`(root)`,jK(e))}catch{}return``}function FK(e,t){let n=jK(t),r=n.description?`: ${n.description}`:``,i=n.type===`record`?`[键集开放,任意键可写]`:``,a=n.optional?`?`:``;return`- ${e} (${n.type}${a})${i}${r}`}function IK(e,t){let n=[],r=uK(e);if(!r?.shape)return{schema:e,fallback:[...t]};let i={...typeof r.shape==`function`?r.shape():r.shape};for(let e of t){if(e.includes(`.`)){n.push(e);continue}let t=i[e];if(!t){n.push(e);continue}let r=uK(t),a=r?.element?uK(r.element):null;if(a?.shape)i[e]=z(a.extend({__pgId:R().optional()}));else if(Array.isArray(a?.options)){let t=a.options.map(e=>{let t=uK(e);return t?.shape?t.extend({__pgId:R().optional()}):e});i[e]=z(a._def?.discriminator===void 0?Pd(t):Id(a._def.discriminator,t))}else n.push(e)}return{schema:B(i),fallback:n}}function LK(e){if(!e)return``;try{let t=e;for(let e=0;e<8&&t&&t._def;e++){if(t._def.innerType){t=t._def.innerType;continue}if(t._def.getter){t=t._def.getter();continue}if(t._def.schema){t=t._def.schema;continue}break}let n=t?.shape?typeof t.shape==`function`?t.shape():t.shape:null;if(n&&typeof n==`object`&&Object.keys(n).length)return Object.entries(n).map(([e,t])=>FK(e,t)).join(`
|
|
@@ -249,7 +249,7 @@ ${t}`,d++;break;case`id`:l=t.includes(`\0`)?void 0:t;break;case`retry`:/^\d+$/.t
|
|
|
249
249
|
`)}`:`未找到匹配 /${t}/ 的内容。`},{name:`vfs_grep`,description:`在虚拟工作区文件内容中正则搜索。`,schema:B({pattern:R().describe(`正则表达式`),path:R().optional().describe(`限定单个文件,不传则搜索全部`)})}),QI(async({path:t,jsonPath:n})=>{let r=d2(t),i=e.files[r];if(!i)return DU({code:`NOT_FOUND`,path:t,message:`未找到文件 "${t}"`,hint:`用 vfs_ls 查看虚拟工作区文件列表`});let a;try{a=JSON.parse(i.content)}catch(e){return DU({code:`VFS_JSON_INVALID`,path:t,message:`文件内容非合法 JSON: ${e.message}`,hint:`vfs_json_read 要求文件内容是合法 JSON;先 vfs_read 查看实际内容,或 vfs_write({jsonString:true}) 重写为合法 JSON`})}if(n){let e=sq(a,n);return e===void 0?DU({code:`VFS_PATH_NOT_FOUND`,path:t,message:`jsonPath "${n}" 不存在`,hint:`不传 jsonPath 整体读查看结构,或核对路径段`}):`${t}#${n} (JSON):\n${JSON.stringify(e)}`}return`${t} (JSON):\n${JSON.stringify(a)}`},{name:`vfs_json_read`,description:`把虚拟工作区文件当 JSON 读取:先 parse 整文件,再按 jsonPath 取子树(省略返整体)。文件非合法 JSON 报 VFS_JSON_INVALID。适合结构化读取 vfs 内大 JSON。`,schema:B({path:R().describe(`文件路径(内容须为合法 JSON)`),jsonPath:R().optional().describe(`点分隔子路径(如 components.0.title);省略读整体`)})}),QI(async({path:t,patches:n})=>{let r=d2(t),i=e.files[r];if(!i)return DU({code:`NOT_FOUND`,path:t,message:`未找到文件 "${t}"`,hint:`用 vfs_ls 查看虚拟工作区文件列表`});let a;try{a=JSON.parse(i.content)}catch(e){return DU({code:`VFS_JSON_INVALID`,path:t,message:`文件内容非合法 JSON: ${e.message}`,hint:`vfs_json_patch 要求文件内容是合法 JSON`})}let o=uq(a),s=[];for(let e of n){let n=vq(o,e.op,e.jsonPath,e.value);if(n)return DU({code:`PATCH_FAILED`,path:t,message:n,hint:`修正 patches 后重试(原文件未改动)`,details:{failedPatch:e}});s.push(e.jsonPath||`(根)`)}let c=JSON.stringify(o);return e.files[r]={content:c,updatedAt:f2()},`已对 ${t} 应用 ${n.length} 个 patch(影响 ${s.length} 处:${s.join(`, `)}),文件现 ${c.length} 字符`},{name:`vfs_json_patch`,description:`在虚拟工作区 JSON 文件内做原子 jsonPath patch(set/remove/merge/append)。先 parse → clone 上应用全部 patches → 任一失败或 JSON 非法则整体不写回(原文件不变)。`,schema:B({path:R().describe(`文件路径(内容须为合法 JSON)`),patches:z(B({op:Wd([`set`,`remove`,`merge`,`append`]).describe(`操作`),jsonPath:R().describe(`点分隔路径(如 components.0.title);merge/append 目标可为根(空串)`),value:Ed().optional().describe(`set/merge/append 的值(remove 不需要)`)})).describe(`按顺序应用的 patch 列表(原子:任一失败整体不写回)`)})}),QI(async({path:t})=>{let n=d2(t);return e.files[n]?(delete e.files[n],`已删除 ${t}`):DU({code:`NOT_FOUND`,path:t,message:`未找到文件 "${t}",无需删除`,hint:`用 vfs_ls 查看虚拟工作区文件列表`})},{name:`vfs_rm`,description:`删除虚拟工作区文件(清理中间产物 / drafts 下草稿,补「只进不出」的闭环)。不存在返回 NOT_FOUND。`,schema:B({path:R().describe(`要删除的文件路径`)})})]}function cde(e){return{name:`vfs`,tools:sde(e),beforeAgent:()=>({files:e.files})}}var p2=`⟦frozen:`,m2=`⟦res:`,h2=`⟧`;function g2(e){return`${p2}${e}${h2}`}function _2(e){return`${m2}${e}${h2}`}function lde(e){return typeof e==`string`?e.startsWith(p2)&&e.endsWith(h2)?{type:`frozen`,path:e.slice(8,e.length-1)}:e.startsWith(m2)&&e.endsWith(h2)?{type:`res`,handle:e.slice(5,e.length-1)}:null:null}function v2(e){return String(e??``).trim().replace(/^\.+/,``)}function y2(e){let t=5381;for(let n=0;n<e.length;n++)t=(t*33^e.charCodeAt(n))>>>0;return(t>>>0).toString(16).padStart(8,`0`).slice(0,8)}function b2(e,t){return e===t?!0:e&&t&&typeof e==`object`&&typeof t==`object`?JSON.stringify(e)===JSON.stringify(t):!1}function x2(e,t){let n=v2(e);if(!n)return;let r=t.get(n);if(r)return{spec:r,relation:`exact`,protectedPath:n};let i;for(let[e,r]of t)n!==e&&(n.startsWith(e+`.`)?(!i||e.length>i.protectedPath.length)&&(i={spec:r,protectedPath:e,relation:`descendant`}):e.startsWith(n+`.`)&&(!i||e.length<i.protectedPath.length)&&(i={spec:r,protectedPath:e,relation:`ancestor`}));return i}var ude=class{vfs;constructor(e){this.vfs=e}key(e){return`resources/${e}.json`}ensure(e,t,n){let r=y2(e),i={path:e,mode:n,value:t,handle:r};return this.vfs.files[this.key(r)]={content:JSON.stringify(i),updatedAt:Date.now()},r}get(e){return this.readEntry(this.key(e))||this.readEntry(this.key(y2(e)))}readEntry(e){let t=this.vfs.files[e];if(t)try{let e=JSON.parse(t.content);return e&&typeof e.path==`string`?e:void 0}catch{return}}update(e,t){let n=this.get(e);this.ensure(e,t,n?.mode??`verbatim`)}delete(e){let t=this.get(e)?.handle??y2(e),n=this.key(t),r=!!this.vfs.files[n];return r&&delete this.vfs.files[n],r}list(){let e=[];for(let[t,n]of Object.entries(this.vfs.files))if(t.startsWith(`resources/`))try{let t=JSON.parse(n.content);t&&typeof t.path==`string`&&e.push({path:t.path,mode:t.mode,handle:t.handle,bytes:n.content.length})}catch{}return e}clear(){for(let e of Object.keys(this.vfs.files))e.startsWith(`resources/`)&&delete this.vfs.files[e]}};function S2(e){let{jp:t,resolved:n,resourcesByPath:r,resourceStore:i}=e;if(!r.size)return n;let a=!1;for(let e of r.keys())if(t===``||e===t||e.startsWith(t+`.`)){a=!0;break}if(!a)return n;let o=uq(n);for(let[e,n]of r){if(t!==``&&e!==t&&!e.startsWith(t+`.`))continue;if(e===t){if(o===void 0)continue;return n.mode===`freeze`?g2(e):i?_2(i.ensure(e,o,`verbatim`)):o}let r=t===``?e:e.slice(t.length+1),a=sq(o,r);a!==void 0&&(n.mode===`freeze`?cq(o,r,g2(e)):i&&cq(o,r,_2(i.ensure(e,a,`verbatim`))))}return o}function dde(e,t,n,r){if(!r)return{code:`RESOURCE_NOT_FOUND`,message:`句柄 "${e}" 无法展开(资源池未启用)`,hint:`verbatim 保护需启用 vfs(capabilities.vfs 默认开);集成方经 createChatSdk 配 data.resources 时自动提供 vfsStore`};let i=r.get(e);return i?n===void 0?{code:`RESOURCE_NOT_FOUND`,message:`字段 "${t}" 在 bind 中已不存在,无法展开句柄 "${e}"`,hint:`该字段可能已被删除或 restore 到不含此字段的快照;重新 read 确认当前结构`}:b2(i.value,n)?{value:i.value}:(r.update(t,n),{value:n}):n===void 0?{code:`RESOURCE_NOT_FOUND`,message:`句柄 "${e}" 不存在(字段 "${t}" 可能未注册或已被删除)`,hint:`重新 read 该字段触发懒注册`}:{code:`RESOURCE_EVICTED`,message:`字段 "${t}" 的 verbatim 资源已被淘汰(资源池 LRU)`,hint:`重新 read 该字段触发懒注册重建句柄,再写回新句柄 ⟦res:<handle>⟧`}}function C2(e,t){let n=t.getBind();for(let[r,i]of t.resourcesByPath){let a=sq(n,r),o=sq(e,r);if(o===void 0){a!==void 0&&cq(e,r,a);continue}if(i.mode===`freeze`){if(o===g2(r)){cq(e,r,a);continue}if(!b2(o,a))return{ok:!1,code:`FROZEN_FIELD`,path:r,message:`字段 "${r}" 已冻结(freeze 保护),不可修改`,hint:`该字段由系统/集成方维护,LLM 不得改动。如需展示其值用 resource_get({path}) 取真值`}}else{let n=lde(o);if(n&&n.type===`res`){let i=dde(n.handle,r,a,t.resourceStore);if(`value`in i){cq(e,r,i.value);continue}return{ok:!1,code:i.code,path:r,message:i.message,hint:i.hint}}if(!b2(o,a))return{ok:!1,code:`VERBATIM_MISMATCH`,path:r,message:`字段 "${r}" 为 verbatim 保护(精确原样保留),写入值与原值不符`,hint:`要改该值请先 resource_update({path, value}) 更新资源池,再写回句柄 ⟦res:<handle>⟧;或写回原值(经 resource_get 取到的值)保持不变`}}}return{ok:!0}}function w2(e,t,n){let r=t===void 0?e.message:`patches[${t}]${n?` @ "${n}"`:``}: ${e.message}`;return DU({code:e.code,path:e.path,message:r,hint:e.hint,...t===void 0?{}:{details:{patchIndex:t,patchJsonPath:n??null}}})}function T2(e){let{value:t,ctx:n}=e;if(!n||!n.resourcesByPath.size)return{ok:!0,value:t};let r=uq(t),i=C2(r,n);return i.ok?{ok:!0,value:r}:{ok:!1,error:w2(i)}}function fde(e){let{patches:t,clone:n,ctx:r}=e;if(!r||!r.resourcesByPath.size)return{ok:!0};for(let e=0;e<t.length;e++){let n=t[e];if(n.op===`remove`){let t=x2(n.jsonPath||``,r.resourcesByPath);if(t){let r=t.spec.mode===`freeze`?`FROZEN_FIELD`:`VERBATIM_PROTECTED`,i=t.spec.mode===`freeze`?`冻结字段不可删。如需移除请联系集成方调整 data.resources 配置`:`verbatim 字段不可直接删;先 resource_delete({path}) 释放资源保护后再删`;return{ok:!1,error:DU({code:r,path:t.protectedPath,message:`patches[${e}] @ "${n.jsonPath}" 命中受保护字段 "${t.protectedPath}"(${t.spec.mode}),不可删除`,hint:i,details:{patchIndex:e,patchJsonPath:n.jsonPath??``}})}}}}let i=C2(n,r);if(!i.ok){let e=pde(i.path,t);return{ok:!1,error:w2(i,e>=0?e:void 0,e>=0?t[e].jsonPath:void 0)}}return{ok:!0}}function pde(e,t){let n=v2(e);for(let e=0;e<t.length;e++){let r=v2(t[e].jsonPath||``);if(r&&(r===n||n.startsWith(r+`.`)||r.startsWith(n+`.`)))return e}return-1}Yp();function E2(e){let{schema:t,allowKeys:n,value:r,bindRef:i}=e,a=[];if(n){if(typeof r!=`object`||!r||Array.isArray(r))return{ok:!1,error:kU(``,[{path:[],code:`invalid_type`,message:`整体 set 需为 JSON 对象(当前为 ${Array.isArray(r)?`array`:r===null?`null`:typeof r})`,expected:`object`}]),notices:a};let e=i&&typeof i==`object`&&!Array.isArray(i)?i:{},n=r,o={};for(let r of Object.keys(n)){if(r.startsWith(`__pg`))continue;let i=n[r],s=hK(t,r,i);if(!s.ok){if(s.resolution===`missing`){if(r in e)continue;return{ok:!1,error:DU({code:`SCHEMA_STRIP`,message:`字段 ${r} 不在 schema 声明内,写入被拒绝(防静默丢失)`,hint:`该数据结构不支持这些字段;请只用 schema 声明的字段,或在 data.schema 中声明后重试`,path:r,details:{stripped:[r]}}),notices:a}}return{ok:!1,error:kU(r,s.issues??[]),notices:a}}s.resolution===`open`&&a.push(`${r}=开放节点放行`);let c=wq(e[r],i,s.data,r);if(c.length)return{ok:!1,error:DU({code:`SCHEMA_STRIP`,message:`字段 ${c.join(`, `)} 不在 schema 声明内,写入被拒绝(防静默丢失)`,hint:`该数据结构不支持这些字段;请只用 schema 声明的字段,或在 data.schema 中声明后重试`,path:c[0],details:{stripped:c}}),notices:a};o[r]=s.data}return gK(t)&&a.push(`根级 refine/superRefine 不再在 write 时执行(走 capabilities.verify)`),{ok:!0,assembly:o,wholeParsed:null,notices:a}}let o=t.safeParse(r);if(!o.success)return{ok:!1,error:kU(``,o.error.issues),notices:a};let s=wq(i,r,o.data);return s.length?{ok:!1,error:DU({code:`SCHEMA_STRIP`,message:`字段 ${s.join(`, `)} 不在 schema 声明内,写入被拒绝(防静默丢失)`,hint:`该数据结构不支持这些字段;请只用 schema 声明的字段,或在 data.schema 中声明后重试`,path:s[0],details:{stripped:s}}),notices:a}:{ok:!0,assembly:o.data,wholeParsed:o.data,notices:a}}function D2(e){let{schema:t,bindRef:n,clone:r,patches:i,schemaErrorMode:a=`zod`,appendCaptures:o,moveCaptures:s}=e,c=[],l=t=>{let n=sq(r,t);return n===void 0?e.valueAt?.(t):n},u=(e,t)=>a===`schema_invalid`?DU({code:`SCHEMA_INVALID`,message:`patches 应用后局部校验失败 @ "${e}",未写入`,hint:`确认该路径的值符合 schema;兄弟节点的既有数据不影响本次写入`,details:OU(t)}):kU(e,t),d=e=>DU({code:`SCHEMA_STRIP`,message:`字段 ${e.join(`, `)} 不在 schema 声明内,写入被拒绝(防静默丢失)`,hint:`该数据结构不支持这些字段;请只用 schema 声明的字段,或在 data.schema 中声明后重试`,path:e[0],details:{stripped:e}}),f=[];gK(t)&&c.push(`根级 refine/superRefine 不再在 write 时执行(走 capabilities.verify)`);let p=0,m=0;for(let e of i){let i=e.op??`set`,a=e.jsonPath||``;if(i===`remove`){let e=a.lastIndexOf(`.`);if(e>0&&/^\d+$/.test(a.slice(e+1))){let n=a.slice(0,e),i=mK(t,n);if(i.kind===`schemas`){let e=sq(r,n);if(Array.isArray(e))for(let t of i.schemas){let r=_K(t);if(r!==null&&e.length<r)return{ok:!1,error:u(n,[{path:[n],code:`too_small`,message:`删除后数组长度 ${e.length} 低于 schema 最小约束 ${r}`,expected:`>=${r}`}]),writeBacks:[],notices:c}}}}f.push({op:`remove`,jp:a});continue}if(i===`move`){let n=s[m++];if(n&&n.elem!==void 0){let e=n.toPath.lastIndexOf(`.`),r=e>0&&/^\d+$/.test(n.toPath.slice(e+1))?n.toPath.slice(0,e):n.toPath,i=mK(t,r);if(i.kind===`schemas`){let e=vK(i.schemas);if(e.length){let t=[],r=!1;for(let i of e){let e=i.safeParse(n.elem);if(e.success){r=!0;break}t.push(...e.error?.issues??[])}if(!r)return{ok:!1,error:u(n.toPath,t),writeBacks:[],notices:c}}}else i.kind===`open`&&c.push(`${r}=开放节点放行`)}f.push({op:`move`,jp:a,toPath:String(e.value)});continue}if(i===`append`){let e=o[p++]?.elems??[];if(!e.length){f.push({op:`appendElems`,jp:a,elems:[]});continue}let n=mK(t,a);if(n.kind===`missing`)return{ok:!1,error:d([a||`(根)`]),writeBacks:[],notices:c};if(n.kind===`open`){c.push(`${a||`(根)`}=开放节点放行`),f.push({op:`appendElems`,jp:a,elems:e});continue}let r=vK(n.schemas);if(!r.length){c.push(`${a||`(根)`}:目标非 schema 声明数组,元素未校验放行`),f.push({op:`appendElems`,jp:a,elems:e});continue}let i=[];for(let t=0;t<e.length;t++){let n=[],o,s=!1;for(let i of r){let r=i.safeParse(e[t]);if(r.success){s=!0,o=r.data;break}n.push(...r.error?.issues??[])}if(!s)return{ok:!1,error:u(`${a||`(根)`}[新增元素${t}]`,n),writeBacks:[],notices:c};let l=wq(void 0,e[t],o,a?`${a}.${t}`:String(t));if(l.length)return{ok:!1,error:d(l),writeBacks:[],notices:c};i.push(o)}f.push({op:`appendElems`,jp:a,elems:i});continue}if(i===`merge`){let r=e.value;if(typeof r==`string`){let e=dq(r);if(e.parseError)return{ok:!1,error:AU(`patches merge`,r,e.parseError),writeBacks:[],notices:c};r=e.parsed}if(typeof r!=`object`||!r||Array.isArray(r))return{ok:!1,error:DU({code:`PATCH_FAILED`,message:`merge 的 value 需为对象`,hint:`merge 合并对象键;整体替换用 set`}),writeBacks:[],notices:c};let i=[];for(let e of Object.keys(r)){if(e.startsWith(`__pg`)||iq.has(e))continue;let r=a?`${a}.${e}`:e,o=l(r),s=hK(t,r,o);if(!s.ok){if(s.resolution===`missing`){if(sq(n,r)===void 0)return{ok:!1,error:d([r]),writeBacks:[],notices:c};i.push([e,o]);continue}return{ok:!1,error:u(r,s.issues??[]),writeBacks:[],notices:c}}s.resolution===`open`&&c.push(`${r}=开放节点放行`);let f=wq(sq(n,r),o,s.data,r);if(f.length)return{ok:!1,error:d(f),writeBacks:[],notices:c};i.push([e,s.data])}f.push({op:`mergeKeys`,jp:a,entries:i});continue}let h=l(a),g=a.lastIndexOf(`.`);if(g>0&&/^\d+$/.test(a.slice(g+1))){let e=sq(r,a.slice(0,g));if(Array.isArray(e)){for(let t=0;t<e.length;t++)if(!(t in e))return{ok:!1,error:DU({code:`PATCH_FAILED`,message:`set @ "${a}" 越界数组索引产生稀疏空洞(父数组长度 ${e.length})`,hint:`数组索引须连续(≤ 当前长度);追加请用 op:"append"`}),writeBacks:[],notices:c}}}let _=hK(t,a,h);if(!_.ok){if(_.resolution===`missing`){if(sq(n,a)===void 0)return{ok:!1,error:d([a]),writeBacks:[],notices:c};f.push({op:`set`,jp:a,value:h});continue}return{ok:!1,error:u(a,_.issues??[]),writeBacks:[],notices:c}}_.resolution===`open`&&c.push(`${a||`(根)`}=开放节点放行`);let v=wq(sq(n,a),h,_.data,a);if(v.length)return{ok:!1,error:d(v),writeBacks:[],notices:c};f.push({op:`set`,jp:a,value:_.data})}return{ok:!0,writeBacks:f,notices:c}}function O2(e){let{bindRef:t,schema:n,allowKeys:r,snapshots:i,maxSnapshots:a,audit:o,dryRun:s,op:c=`set`,protectedCtx:l,snapshotLabel:u}=e,d=e.value,f=e.internalAfterWrite?uq(t):null;if(l){let e=T2({value:d,ctx:l});if(!e.ok)return{ok:!1,error:e.error};d=e.value}let p=E2({schema:n,allowKeys:r,value:d,bindRef:t});if(!p.ok)return{ok:!1,error:p.error};let m=p.assembly;if(s)return{ok:!0,hash:``,data:m,notices:p.notices};if(typeof t!=`object`||!t)return{ok:!1,error:DU({code:`LEAF_BIND`,message:`主数据 bind 为原始类型(${t===null?`null`:typeof t}),无法就地替换外部持有的值引用`,hint:`主数据 bind 必须为对象/数组;叶子值请用对象包裹(如 {value:"x"})或集成方通过 sdk.setData 替换 bind`})};let h=uq(t),g=i.length?i[i.length-1].id+1:1;for(i.push({id:g,ts:Date.now(),op:c,value:h,...u?{label:u}:{}});i.length>a;)i.shift();return typeof m==`object`&&m&&(p.wholeParsed?Cq(t,m):oq(t,m)),o({op:c,value:m,timestamp:Date.now()}),e.onWrite?.(),e.internalAfterWrite?.(t,f),{ok:!0,hash:e.hashFn?e.hashFn():gq(t),data:m,notices:p.notices}}function k2(e){let{bindRef:t,patches:n,schema:r,allowKeys:i,snapshots:a,maxSnapshots:o,markDataDirty:s,schemaErrorMode:c=`zod`,snapshotLabel:l,dryRun:u,protectedCtx:d}=e,f=e.internalAfterWrite?uq(t):null,p=uq(t),m=[],h=[],g=[],_=[],v=(e,t)=>{(e===`set`||e===`merge`)&&_.push({jp:t,val:sq(p,t)})};for(let e=0;e<n.length;e++){let t=n[e],a=t.jsonPath||``;if(aq(a))return{ok:!1,error:DU({code:`PATH_UNSAFE`,message:`patches[${e}] jsonPath "${a}" 含非法段`,hint:`使用正常属性路径,如 components.0.text`})};if(!lK(a,r,i))return{ok:!1,error:DU({code:`PATH_DENIED`,message:`patches[${e}] @ "${a}" 不在 schema 声明字段内`,hint:`仅 schema 声明的 key 可写`})};let o=t.op??`set`,s;if(o!==`remove`){if(t.value===void 0||t.value===``&&o===`move`)return{ok:!1,error:DU({code:`MISSING_VALUE`,message:`patches[${e}] ${o} 操作需要 value`,hint:`op 为 ${o} 时 value 必填;删除请用 op:'remove'`})};let n=dq(t.value);if(n.parseError)return{ok:!1,error:AU(`patches[${e}]`,t.value,n.parseError)};if(s=n.parsed,o===`move`&&typeof s==`string`&&!lK(s,r,i))return{ok:!1,error:DU({code:`PATH_DENIED`,message:`patches[${e}] move 目标 "${s}" 不在 schema 声明字段内`,hint:`move 的 value(目标路径)也须在 schema 声明字段内`})}}o===`append`&&h.push({jp:a,elems:Array.isArray(s)?[...s]:[s]}),o===`move`&&g.push({jp:a,toPath:String(s),elem:sq(p,a)});let c=vq(p,o,a,s);if(c)return{ok:!1,error:DU({code:`PATCH_FAILED`,message:`patches[${e}]: ${c}`,hint:`检查 op 与目标类型:merge 需对象,append 需数组`})};v(o,a),m.push({op:o,jp:a,value:s})}if(d){let e=fde({patches:n,clone:p,ctx:d});if(!e.ok)return{ok:!1,error:e.error}}let y=D2({schema:r,bindRef:t,clone:p,patches:n,schemaErrorMode:c,appendCaptures:h,moveCaptures:g,valueAt:e=>_.find(t=>t.jp===e)?.val});if(!y.ok)return{ok:!1,error:y.error};if(u)return{ok:!0,applied:m,clone:p,notices:y.notices};let b=a.length?a[a.length-1].id+1:1;for(a.push({id:b,ts:Date.now(),op:`edit`,value:f??uq(t),...l?{label:l}:{}});a.length>o;)a.shift();for(let e of y.writeBacks)if(e.op===`remove`)lq(t,e.jp);else if(e.op===`set`)cq(t,e.jp,e.value);else if(e.op===`move`)bq(t,e.jp,e.toPath);else if(e.op===`mergeKeys`){let n=e.jp?sq(t,e.jp):t;if(n&&typeof n==`object`&&!Array.isArray(n))for(let[t,r]of e.entries??[])n[t]=r}else if(e.op===`appendElems`){let n=e.jp?sq(t,e.jp):t;Array.isArray(n)&&e.elems?.length&&n.push(...e.elems)}return e.internalAfterWrite?.(t,f),s?.(),{ok:!0,applied:m,clone:p,notices:y.notices}}function mde(e){return e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}KB`:`${(e/(1024*1024)).toFixed(1)}MB`}function A2(e,t,n,r){if(!t||!n.length||typeof e!=`object`||!e)return e;let i=new Set(n.map(e=>e.field)),a=uq(e);return(function e(t){if(Array.isArray(t))for(let n of t)e(n);else if(t&&typeof t==`object`)for(let n of Object.keys(t)){let a=t[n];typeof a==`string`&&i.has(n)&&a.length>=r?t[n]=`<${n} ${mde(a.length)}>`:e(a)}})(a),a}var j2=0;function hde(){return j2++,`c_`+Math.random().toString(36).slice(2,8)+j2.toString(36)}function M2(e,t){if(!(!e||typeof e!=`object`))for(let n of t){let t=sq(e,n);if(Array.isArray(t))for(let e of t)e&&typeof e==`object`&&!(`__pgId`in e)&&(e.__pgId=hde())}}function N2(e){(function e(t){if(Array.isArray(t))t.forEach(e);else if(t&&typeof t==`object`)for(let n of Object.keys(t))n.startsWith(`__pg`)?delete t[n]:e(t[n])})(e)}function P2(e,t={}){let n=t.pgIdPaths??[],r=n.length?(e,t)=>{if(t&&typeof t==`object`)for(let r of n){let n=sq(t,r),i=sq(e,r);if(!Array.isArray(n)||!Array.isArray(i))continue;let a=e=>{if(!e||typeof e!=`object`)return e;let t={...e};return delete t.__pgId,t},o=new Set;for(let e=0;e<i.length;e++){let t=i[e];if(!(!t||typeof t!=`object`||`__pgId`in t))for(let e=0;e<n.length;e++){if(o.has(e))continue;let r=n[e];if(!(!r||typeof r!=`object`||!r.__pgId)&&b2(a(r),a(t))){t.__pgId=r.__pgId,o.add(e);break}}}for(let e=0;e<n.length&&e<i.length;e++){if(o.has(e))continue;let t=n[e]?.__pgId,r=i[e];t&&r&&typeof r==`object`&&!(`__pgId`in r)&&(r.__pgId=t,o.add(e))}}M2(e,n)}:void 0,i=n.length?IK(e.schema,n).schema:e.schema,a=e.bind,o=e.description??`主数据对象`,s=cK(i),c=new Map,l=t.vfsStore?new ude(t.vfsStore):void 0;function u(e){if(c.clear(),e)for(let t of e){let e=v2(t.path);c.set(e,{path:e,mode:t.mode})}}u(e.resources);let d=c.size?{resourcesByPath:c,resourceStore:l,getBind:()=>a}:void 0,f=[],p=t.maxSnapshots??20,m=new Map,h=``,g=e=>e?.configurable?.__pgDataScope??h,_=e=>m.get(e??h),v=(e,t)=>{let n=t??h;e===void 0?m.delete(n):m.set(n,e)},y=t.conflictWatchFields??[],b=!y.includes(`*`)&&y.length?new Set(y):void 0,x=y.length>0,S=()=>b?_q(a,b):gq(a),C=e=>{let t=S();return v(t,e),t},w=t.largeTextThreshold??200,T=(t.largeTextPaths??[]).map(e=>{let t=e.lastIndexOf(`.`);return t>0?{arrayPath:e.slice(0,t),field:e.slice(t+1)}:null}).filter(e=>e!==null),E=!0;function D(){E=!0}let O={get:()=>({schema:i,bind:a,description:o}),set:e=>{i=n.length?IK(e.schema,n).schema:e.schema,a=e.bind,o=e.description??`主数据对象`,s=cK(i),f.length=0,m.clear(),u(e.resources),l?.clear(),D()},update:e=>{a=e,f.length=0,m.clear(),D()},markDataDirty:D,consumeDataDirty:()=>{let e=E;return E=!1,e},enterScope:e=>{let t=h;return h=e,()=>{h=t}},exitScope:e=>{m.delete(e)},recomputeBaseline:e=>{m.set(e??``,S())},recomputeAllBaselines:()=>{let e=S();for(let t of m.keys())m.set(t,e)},hasBaselines:()=>m.size>0,getResourcesSnapshot:()=>{let e=[];for(let[t,n]of c)if(n.mode===`verbatim`){let r=l?.get(t);e.push(r?.handle?{path:t,mode:n.mode,handle:r.handle}:{path:t,mode:n.mode})}else e.push({path:t,mode:n.mode});return e},createResource:l?(e,t)=>{let n=v2(e),r=c.get(n),i=t===void 0?sq(a,n):t;return l.ensure(n,i,r?.mode??`verbatim`)}:void 0,getResource:l?e=>{let t=l.get(e);return t?{path:t.path,mode:t.mode,value:t.value,handle:t.handle}:void 0}:void 0,updateResource:l?(e,t)=>{let n=v2(e);l.update(n,t),cq(a,n,t),D()}:void 0,deleteResource:l?e=>l.delete(e):void 0,listResources:l?()=>l.list():void 0},k=e=>{t.onAudit?.(e)};function A(e,t){let n=uq(a),r=f.length?f[f.length-1].id+1:1;for(f.push({id:r,ts:Date.now(),op:e,label:t,value:n});f.length>p;)f.shift();return r}async function ee(e,n,r){if(!n||n===``)return null;let i=S();if(i===n)return null;if(!t.onConflict)return DU({code:`VERSION_CONFLICT`,message:`乐观锁冲突:expectedHash=${n} 但当前 hash=${i}。主数据在你 read 之后已被修改(外部代码/其他 agent/用户手动改)。`,hint:`重新 read 拿最新值与 hash,基于最新值修改后再写入。当前值:${mq(a,400)}`});let o=await t.onConflict({op:e,agentValue:r,currentValue:a,currentHash:i,expectedHash:n,snapshotId:0});if(o.action===`keep_external`)return`已保留外部修改(未写入)。当前值:${mq(a,400)} (hash=${i})。请重新 read 拿最新值与 hash 再改。`;if(o.action===`restore`){if(!f.length)return`无历史快照可回退(本次为首次操作)。当前值:${mq(a,400)} (hash=${i})。请重新 read 再改或选「强制覆盖」。`;let e=f[f.length-1];return Sq(a,uq(e.value)),D(),`已回退主数据到历史快照 #${e.id}[${e.op}]。当前值:${mq(a,400)} (hash=${S()})。请基于回退后的值重写或停止。`}return null}let j=(e,t=!0)=>{e.writeCapable=t},te=QI(async()=>[`说明: ${o}`,`格式: 写入值需为 JSON,且通过声明的 schema 校验(校验失败时 set_data/edit_data 会返回结构化错误,含具体字段与期望类型)。`].join(`
|
|
250
250
|
`),{name:`describe_data`,description:`获取主数据的说明与格式要求。`,schema:B({})}),ne=QI(async({jsonPath:e},t)=>{let n=g(t),r=e||``;if(aq(r))return DU({code:`PATH_UNSAFE`,message:`jsonPath "${r}" 含非法段(__proto__/constructor/prototype)`,hint:`使用正常属性路径,如 components.0.text(数组索引用数字)`});if(!lK(r,i,s))return DU({code:`PATH_DENIED`,message:`get_data @ "${r}" 不在 schema 声明字段内(仅 schema 声明的 key 可读)`,hint:`主数据仅暴露 schema 声明的字段;若需操作该字段,集成方需在 schema 中声明它`});let o=r?sq(a,r):a;!r&&s&&(o=wK(o,i)),d&&(o=S2({jp:r,resolved:o,resourcesByPath:d.resourcesByPath,resourceStore:d.resourceStore}));let c=S();return v(c,n),o===void 0?`主数据${r?` @ ${r}`:``} = (undefined) (hash=${c})`:(o=A2(o,n===``,T,w),`主数据${r?` @ ${r}`:``} = ${mq(o)} (hash=${c})`)},{name:`get_data`,description:`@deprecated(改用 read,等价且支持 fields/depth/分页)。读取主数据当前值(返回含 hash 供乐观锁);jsonPath 可选读子路径。大结果自动外存 vfs。`,schema:B({jsonPath:R().optional().describe(`相对主数据根的点号路径(如 components.0.text);不传则读整个主数据`)})}),re=QI(async({value:e},t)=>{let n=g(t),o=await ee(`set`,x?_(n):void 0);if(o!==null)return o;let c=dq(e);if(c.parseError)return AU(``,e,c.parseError);let l=O2({bindRef:a,value:c.parsed,schema:i,allowKeys:s,snapshots:f,maxSnapshots:p,audit:k,onWrite:D,internalAfterWrite:r,protectedCtx:d,hashFn:S});return l.ok?(v(l.hash,n),`已设置主数据 = ${mq(l.data,600)} (新 hash=${l.hash})${s?`(白名单模式:仅更新 schema 声明字段,未声明字段保留)`:``}`):l.error},{name:`set_data`,description:`@deprecated(改用 write,等价)。整体设置主数据(value 需过 schema 校验)。白名单模式:set 为根级浅合并,深层整体替换(未传字段丢失);保留深层字段用 edit_data({op:"merge"})。`,schema:B({value:Dd().describe(`JSON 对象(推荐直传,如 {title:"x"}),或 JSON 字符串;需符合 schema`)})});j(re);let M=QI(async(e,t)=>{let n=g(t),o=e.op??e.patch?.op,c=e.jsonPath??e.patch?.jsonPath,l=e.value??e.patch?.value;if(!o)return DU({code:`MISSING_VALUE`,message:`edit_data 需要 op(set/remove/merge/append)`,hint:`顶层 op 或 patch.op 至少传一个`});let u=c||``;if(aq(u))return DU({code:`PATH_UNSAFE`,message:`jsonPath "${u}" 含非法段(__proto__/constructor/prototype)`,hint:`使用正常的属性路径,如 components.0.text(数组索引用数字)`});if(!lK(u,i,s))return DU({code:`PATH_DENIED`,message:`edit_data @ "${u}" 不在 schema 声明字段内`,hint:`仅 schema 声明的 key 可写;若需操作该字段,集成方需在 schema 中声明它`});let m=await ee(`edit`,x?_(n):void 0);if(m!==null)return m;if(typeof a!=`object`||!a)return DU({code:`NOT_OBJECT`,message:`edit 仅适用于对象/数组主数据,当前是 ${a===void 0?`undefined`:typeof a}`,hint:`叶子(原始类型)请用 set_data 整体设置`});let h=k2({bindRef:a,patches:[{op:o,jsonPath:u,value:l}],schema:i,allowKeys:s,snapshots:f,maxSnapshots:p,markDataDirty:D,schemaErrorMode:`zod`,internalAfterWrite:r,protectedCtx:d});if(!h.ok)return h.error;let v=h.applied[0];k({op:`edit`,detail:`${v.op}${u?`@`+u:``}`,value:v.value,timestamp:Date.now()});let y=C(n);return`已 edit 主数据(${v.op}${u?` @ `+u:``})。当前值:${mq(a,600)} (新 hash=${y})`},{name:`edit_data`,description:`增量编辑主数据(advanced;simple 用 write 等价)。op:set/remove/merge/append/move;jsonPath 相对根(数组索引用数字);value 对象或 JSON 字符串。schema 校验失败不写。大对象优先增量改。`,schema:B({op:Wd([`set`,`remove`,`merge`,`append`,`move`]).optional().describe(`增量操作(顶层或 patch.op 至少一个):set 设值/remove 删/merge 合并/append 追加/move 移动数组元素(value=目标路径字符串,数组本身=追加/数组内下标=插入;同数组即重排,目标下标按移除源后解释)`),jsonPath:R().optional().describe(`相对主数据根的点号路径(如 components.0.text);顶层或 patch.jsonPath。set/remove 必填,merge/append 不填则作用于根`),value:Dd().optional().describe(`JSON 对象(推荐直传,如 {text:"x"})或 JSON 字符串;顶层或 patch.value(set/merge/append 必填)`),patch:B({op:Wd([`set`,`remove`,`merge`,`append`]).optional(),jsonPath:R().optional(),value:Dd().optional()}).optional().describe(`容错:误传 write 的 {patch:{op,jsonPath,value}} 形式时从此取值(顶层优先)。正常用顶层 op/jsonPath/value 即可`)})});j(M);let ie=QI(async({jsonPath:e},t)=>{let n=g(t);if(!e)return DU({code:`MISSING_VALUE`,message:`delete_data 需要 jsonPath 指定要删的子路径(主数据整体不可删,用 set_data 整体替换)`,hint:`如 jsonPath:"components.0" 删数组首项`});if(aq(e))return DU({code:`PATH_UNSAFE`,message:`jsonPath "${e}" 含非法段`,hint:`使用正常属性路径`});if(!lK(e,i,s))return DU({code:`PATH_DENIED`,message:`delete_data @ "${e}" 不在 schema 声明字段内`,hint:`仅 schema 声明的 key 可删`});if(d){let t=x2(e,d.resourcesByPath);if(t)return DU({code:t.spec.mode===`freeze`?`FROZEN_FIELD`:`VERBATIM_PROTECTED`,message:`delete_data @ "${e}" 命中受保护字段 "${t.protectedPath}"(${t.spec.mode}),不可删除`,hint:t.spec.mode===`freeze`?`冻结字段不可删;如需移除请联系集成方调整 data.resources`:`verbatim 字段不可直接删;先 resource_delete({path}) 释放资源保护后再删`})}let r=await ee(`delete`,x?_(n):void 0);if(r!==null)return r;A(`delete`);let o=lq(a,e);return D(),k({op:`delete`,detail:e,timestamp:Date.now()}),v(S(),n),o?`已删除主数据 @ ${e}`:`主数据 @ ${e} 不存在(无需删除)`},{name:`delete_data`,description:`删除主数据的某个子路径(jsonPath)。主数据整体不可删(用 set_data 整体替换)。`,schema:B({jsonPath:R().describe(`要删除的子路径(相对主数据根,如 components.0)`)})});j(ie);let ae=QI(async({id:e},t)=>{let n=g(t);if(!f.length)return DU({code:`NO_SNAPSHOT`,message:`无快照可回退`,hint:`set/edit/delete 会自动存快照;或 history_data({list:true}) 查看可用快照`});let r=e===void 0?f[f.length-1]:f.find(t=>t.id===e);if(!r)return DU({code:`SNAPSHOT_NOT_FOUND`,message:`未找到快照 #${e}`,hint:`用 history_data({list:true}) 查看可用快照序号`});let o=i.safeParse(r.value);return o.success?(Sq(a,uq(r.value)),D(),k({op:`restore`,detail:`#${r.id}`,timestamp:Date.now()}),v(S(),n),`已回退主数据到快照 #${r.id}[${r.op}]${r.label?`(${r.label})`:``}。`):DU({code:`SNAPSHOT_SCHEMA_INVALID`,message:`快照 #${r.id} 的值不符合当前 schema,无法回退`,hint:`schema 可能已变更;该快照已过期,选其他快照或重新设置`,details:OU(o.error.issues)})},{name:`restore_data`,description:`把主数据回退到某个快照(就地还原,保留响应式)。不传 id 则回退最近一次(快速回退)。可用 history_data({list:true}) 查看快照列表。`,schema:B({id:pd().int().optional().describe(`指定快照序号;不传则回退最近一次`)})});j(ae);let oe=QI(async({id:e,jsonPath:t,list:n})=>{if(n){if(!f.length)return`无快照。set/edit/delete 会自动存快照。`;let e=f.map(e=>{let t=JSON.stringify(e.value??``).length,n=new Date(e.ts).toLocaleTimeString(`zh-CN`,{hour12:!1});return` #${e.id} [${e.op}]${e.label?` "${e.label}"`:``} ${n} 修改前≈${t}字符`});return`主数据快照时间线(共 ${f.length} 条,默认最近一次):\n${e.join(`
|
|
251
251
|
`)}\n用 history_data({id}) 查看某条快照内容;restore_data({id}) 回退;diff_data({snapshotId}) 对比差异。`}if(!f.length)return DU({code:`NO_SNAPSHOT`,message:`无历史快照可查看`,hint:`set/edit/delete 会自动存快照;或 history_data({list:true}) 查看可用序号`});let r=e===void 0?f[f.length-1]:f.find(t=>t.id===e);if(!r)return DU({code:`SNAPSHOT_NOT_FOUND`,message:`未找到快照 #${e}`,hint:`不传 id 查看最近一次;或 history_data({list:true}) 查看可用序号`});let a=uq(r.value),o=t||``;if(o){if(aq(o))return DU({code:`PATH_UNSAFE`,message:`jsonPath "${o}" 含非法段`,hint:`使用正常属性路径`});if(!lK(o,i,s))return DU({code:`PATH_DENIED`,message:`history_data @ "${o}" 不在 schema 声明字段内`,hint:`仅 schema 声明的 key 可读`});a=sq(a,o);let e=dK(i,o);e&&(a=wK(a,e))}else s&&(a=wK(a,i));return`快照 #${r.id}[${r.op}]${r.label?`(${r.label})`:``}${o?` @ ${o}`:``} = ${mq(a)}`},{name:`history_data`,description:`查看主数据快照(只读不回退当前)。list:true 列时间线;传 id 看某次快照内容(默认最近),jsonPath 可只看子路径。冲突诊断/看上一版用;对比差异用 diff_data;回退用 restore_data。`,schema:B({id:pd().int().optional().describe(`快照序号;不传则最近一次(list:true 时忽略)`),jsonPath:R().optional().describe(`只看快照的某子路径(相对主数据根);不传则整个快照`),list:yd().optional().describe(`true 则列出快照时间线元信息(序号/操作/标签/时间/大小);不传则查看单条快照内容`)})}),se=QI(async({expr:e,limit:t},n)=>{let r=g(n);if(typeof a!=`object`||!a)return DU({code:`NOT_OBJECT`,message:`主数据不是对象/数组,无法查询(当前为 ${a===void 0?`undefined`:typeof a})`,hint:`query 仅适用于对象/数组;叶子用 get_data 读`});let o=s?wK(a,i):a,c;try{c=IW(o,e)}catch(t){return DU({code:`JSONPATH_SYNTAX`,message:`JSONPath 解析错误: ${t.message}`,hint:`语法子集:$ .key [n] ["key"] [*] [?(filter)] ..key ..*;filter:@.field op literal,&&/||/();对象根需先点出数组字段再过滤,如 $.components[?(@.x>1)]`,details:{expr:e}})}let l=t??50,u=c.slice(0,l),d=u.map(e=>`{"path":${JSON.stringify(e.path)},"index":${e.index===void 0?`null`:e.index},"value":${mq(A2(e.value,r===``,T,w))}}`);return`{"matched":${c.length},"returned":${u.length},"truncated":${c.length>l},"results":[${d.join(`,`)}]}`},{name:`query_data`,description:`用 JSONPath 查询主数据(只读):$ 根/.key/[n]/[*]/[?(==/!=/</<=/>/>=,&&/||)]/..key 递归。返回匹配元素 path/index/value(path 可作 write patch 的 jsonPath);大数组筛选定位用它。`,schema:B({expr:R().describe(`JSONPath 表达式,如 $.components[?(@.type=="card" && @.price<100)] 或 $..title(递归找所有 title)`),limit:pd().int().min(1).max(200).optional().describe(`返回结果上限,默认 50`)})}),ce=QI(async({query:e,mode:t,fuzzyThreshold:n,matchKey:r,limit:o})=>{if(a==null)return DU({code:`EMPTY`,message:`主数据为空,无可搜索内容`});try{let c=RW(s?wK(a,i):a,e,{mode:t,fuzzyThreshold:n,matchKey:r,limit:o??50});return mq({matched:c.length,results:c})}catch(t){return DU({code:`REGEX_INVALID`,message:`搜索错误: ${t.message}`,hint:`regex 模式下 query 须为合法正则;改 mode 为 substring/fuzzy 可避免正则语法问题`,details:{query:e}})}},{name:`search_data`,description:`主数据内文本搜索(只读)。mode:substring(默认,不区分大小写)/regex(i 标志)/fuzzy(Levenshtein ≤ fuzzyThreshold)。递归遍历叶子值返回命中 path+value(超 200 字符截断);找名字记不清的元素用它。`,schema:B({query:R().describe(`搜索词(substring/regex/fuzzy 共用)`),mode:Wd([`substring`,`regex`,`fuzzy`]).optional().describe(`匹配模式,默认 substring`),fuzzyThreshold:pd().int().min(0).max(5).optional().describe(`fuzzy 模式最大编辑距离,默认 2`),matchKey:yd().optional().describe(`是否同时匹配 key 名,默认 true`),limit:pd().int().min(1).max(200).optional().describe(`返回上限,默认 50`)})}),le=QI(async({script:e,mode:t,jsonPath:n},o)=>{let c=g(o);if(e.length>8e3)return DU({code:`SCRIPT_TOO_LARGE`,message:`脚本过长(${e.length} 字符,上限 8000)`,hint:`精简脚本;复杂逻辑可分步(先 query 探查再 transform 改),或拆成多次 eval`});let l=n||``,u;if(l){if(!lK(l,i,s))return DU({code:`PATH_DENIED`,message:`eval_script @ "${l}" 不在 schema 声明字段内`,hint:`仅 schema 声明的 key 可作为子树`});if(u=sq(a,l),s){let e=dK(i,l);e&&(u=wK(u,e))}}else u=s?wK(a,i):a;let m=uq(u),h=await BW(m,e,l&&JSON.stringify(m).length>1e5?8e3:3e3);if(!h.ok){let t=/超时/.test(h.error||``);return DU({code:t?`SCRIPT_TIMEOUT`:`SCRIPT_ERROR`,message:`脚本执行失败: ${h.error}`,hint:t?`脚本可能有死循环或过重计算;加边界检查/分批;transform 返回完整新值勿返回巨大中间结果`:`检查脚本语法与运行时错误;入参为 data(主数据深拷贝),沙箱内禁用 fetch/XHR/WebSocket`,details:{elapsedMs:h.elapsedMs,scriptLen:e.length}})}if(t===`transform`){let e=h.result;if(l){let t=k2({bindRef:a,patches:[{op:`set`,jsonPath:l,value:e}],schema:i,allowKeys:s,snapshots:f,maxSnapshots:p,markDataDirty:D,schemaErrorMode:`schema_invalid`,snapshotLabel:`eval_transform_subtree`,internalAfterWrite:r,protectedCtx:d});return t.ok?(k({op:`edit`,detail:`eval_transform_subtree @ ${l}`,timestamp:Date.now()}),v(S(),c),`已通过脚本 transform 子树 @ ${l} 更新(耗时 ${h.elapsedMs}ms)。当前值: ${mq(a,600)}`):t.error}if(e&&typeof e==`object`&&!Array.isArray(e)&&`patches`in e&&Array.isArray(e.patches)){if(typeof a!=`object`||!a)return DU({code:`LEAF_BIND`,message:`主数据 bind 为原始类型(${a===null?`null`:typeof a}),eval transform(patches) 无法就地替换`,hint:`主数据 bind 必须为对象/数组;叶子值请用对象包裹或集成方通过 sdk.setData 替换 bind`});let t=k2({bindRef:a,patches:e.patches,schema:i,allowKeys:s,snapshots:f,maxSnapshots:p,markDataDirty:D,schemaErrorMode:`schema_invalid`,snapshotLabel:`eval_transform`,internalAfterWrite:r,protectedCtx:d});return t.ok?(k({op:`edit`,detail:`eval_transform(${t.applied.length} patches)`,timestamp:Date.now()}),v(S(),c),`已通过脚本 transform(patches) 更新主数据(${t.applied.length} 个 patch,耗时 ${h.elapsedMs}ms)。当前值: ${mq(a,600)}`):t.error}let t=e;if(d){let e=T2({value:t,ctx:d});if(!e.ok)return e.error;t=e.value}if(typeof a!=`object`||!a)return DU({code:`LEAF_BIND`,message:`主数据 bind 为原始类型(${a===null?`null`:typeof a}),eval transform 无法就地替换外部持有的值引用`,hint:`主数据 bind 必须为对象/数组;叶子值请用对象包裹或集成方通过 sdk.setData 替换 bind`});let n=E2({schema:i,allowKeys:s,value:t,bindRef:a});return n.ok?(A(`edit`,`eval_transform`),n.wholeParsed?Cq(a,n.assembly):n.assembly!==null&&typeof n.assembly==`object`&&oq(a,n.assembly),D(),k({op:`edit`,detail:`eval_transform`,timestamp:Date.now()}),v(S(),c),`已通过脚本 transform 更新主数据(耗时 ${h.elapsedMs}ms)。当前值: ${mq(a,600)}`):DU({code:`SCHEMA_INVALID`,message:`脚本返回值校验失败,未写入(transform 模式要求返回主数据的完整新值或顶层 key 子集)`,hint:`确认脚本 return 了完整新值(非部分);或返回 {patches:[...]} 走增量模式;按 describe_data() 查看格式`,details:(n.error.match(/"details":\s*(\[[^\]]*\])/)?.[1]??``)||n.error})}return mq({ok:!0,result:h.result,elapsedMs:h.elapsedMs})},{name:`eval_script`,description:`在 Worker 沙箱对主数据跑自定义 JS(无 window/fetch,超时 3s)。入参 data(深拷贝),返回值即结果。mode:query 只读回给 LLM(过滤/映射/聚合)/transform 落地(返回完整新值或 {patches:[...]} 增量)。jsonPath 可只对子树执行。`,schema:B({script:R().describe(`JS 脚本体,如 data.filter(c=>c.stock>0).map(c=>c.id);入参名 data;末尾表达式或 return 即返回值`),mode:Wd([`query`,`transform`]).optional().describe(`query=只读返回结果(默认),transform=校验后落地为新值`),jsonPath:R().optional().describe(`子树模式:仅对 jsonPath 指向的子树执行(降低大 JSON 成本);transform 时返回值作为该子树新值`)})});j(le,e=>e?.mode===`transform`);let ue=QI(async({jsonPath:e,jsonPaths:t,fields:n,depth:r,offset:c,limit:l},u)=>{let f=g(u),p=S();if(t&&t.length){let e=!1,o=t.map(t=>{let o=t||``;if(!lK(o,i,s))return`- ${o||`(根)`}: [PATH_DENIED: 不在 schema 声明字段内]`;e=!0;let c=o?sq(a,o):a;if(!o&&s)c=wK(c,i);else if(s){let e=dK(i,o);e&&(c=wK(c,e))}let l=c;return d&&(l=S2({jp:o,resolved:l,resourcesByPath:d.resourcesByPath,resourceStore:d.resourceStore})),n&&n.length&&(l=fq(l,n)),r!=null&&(l=pq(l,r)),l=A2(l,f===``,T,w),l===void 0?`- ${o} = (undefined)`:`- ${o} = ${mq(l)}`});return e&&v(p,f),`多路径读取(共 ${t.length} 项,hash=${p}):\n${o.join(`
|
|
252
|
-
`)}`}let m=e||``;if(aq(m))return DU({code:`PATH_UNSAFE`,message:`jsonPath "${m}" 含非法段(__proto__/constructor/prototype)`,hint:`使用正常属性路径,如 components.0.text(数组索引数字)`});if(!lK(m,i,s)){let e=/[.[]/.test(m)?m.replace(/[.[][^.[]*$/,``):``,t=e?sq(a,e):a,n=t
|
|
252
|
+
`)}`}let m=e||``;if(aq(m))return DU({code:`PATH_UNSAFE`,message:`jsonPath "${m}" 含非法段(__proto__/constructor/prototype)`,hint:`使用正常属性路径,如 components.0.text(数组索引数字)`});let h=(e,t)=>{let n=(e?dK(i,e):i)?.shape;return n&&typeof n==`object`?Object.keys(n):t&&typeof t==`object`&&!Array.isArray(t)?Object.keys(t):[]};if(!lK(m,i,s)){let e=/[.[]/.test(m)?m.replace(/[.[][^.[]*$/,``):``,t=h(e,e?sq(a,e):a),n=t.length?`;父级 "${e||`(root)`}" 的可用字段:${t.slice(0,12).join(`, `)}${t.length>12?` …`:``}`:``;return DU({code:`PATH_DENIED`,message:`read @ "${m}" 不在 schema 声明字段内`,hint:`主数据仅暴露 schema 声明的字段;若需操作该字段,集成方需在 schema 中声明它${n}`})}let _=m?sq(a,m):a;if(m&&_===void 0){let e=dK(i,m);if(!(e&&typeof e.isOptional==`function`&&e.isOptional())){let e=/[.[]/.test(m)?m.replace(/[.[][^.[]*$/,``):``,t=e?sq(a,e):a,n=h(e,t),r=Array.isArray(t)?`父级 "${e||`(root)`}" 是 ${t.length} 元数组,有效索引 0-${Math.max(t.length-1,0)};先 read({jsonPath:"${e}"}) 确认现状,追加元素走 write 的 append`:n.length?`父级 "${e||`(root)`}" 的可用字段:${n.slice(0,12).join(`, `)}${n.length>12?` …`:``};先 read({jsonPath:"${e}"}) 确认`:`父级 "${e||`(root)`}" 不存在或不是容器;先 read() 不传 jsonPath 查看顶层字段`;return DU({code:`PATH_NOT_FOUND`,path:m,message:`路径 "${m}" 不存在`,hint:r})}}if(!m&&s)_=wK(_,i);else if(s){let e=dK(i,m);e&&(_=wK(_,e))}let y=_;d&&(y=S2({jp:m,resolved:y,resourcesByPath:d.resourcesByPath,resourceStore:d.resourceStore})),v(p,f),n&&n.length&&(y=fq(y,n)),r!=null&&(y=pq(y,r)),y=A2(y,f===``,T,w);let b=e?``:`主数据说明: ${o}\n格式: 写入值需为 JSON,且通过声明的 schema 校验(校验失败时 write 会返回结构化错误)。字段约束(类型/min/max/enum/必填/默认)见 systemPrompt「可操作数据」段,或用 schema_data({ jsonPath }) 按需查。\n\n`,x=n&&n.length?`(字段裁剪:${n.join(`,`)})`:``,C=r==null?``:`(深度≤${r})`,E=x||C?` ${x}${C}`:``;if((c!==void 0||l!==void 0)&&Array.isArray(y)){let e=y.length,t=Math.max(0,c??0),n=Math.min(200,Math.max(1,l??50)),r=y.slice(t,t+n),i=t+n<e;return`${b}主数据${m?` @ ${m}`:``} 数组分页[offset=${t},limit=${n}]${E} = ${mq(r)} (total=${e}, hasMore=${i}) (hash=${p})`}return y===void 0?`${b}主数据${m?` @ ${m}`:``}${E} = (undefined) (hash=${p})`:`${b}主数据${m?` @ ${m}`:``}${E} = ${mq(y)} (hash=${p})`},{name:`read`,description:`读取主数据(高层入口,合并 describe/get)。不传 jsonPath → 返回主数据说明 + 格式提示(含字段约束);传 jsonPath → 返回该子路径当前值 + hash;传 jsonPaths → 一次读多个不相关子路径(省多轮往返)。hash 用于乐观锁(声明 conflictWatchFields 后 write 自动比对;未声明不自动校验)。fields(字段裁剪)/depth(深度截断)减体积;offset+limit 对数组目标分页(返回切片 + total/hasMore)。`,schema:B({jsonPath:R().optional().describe(`要读的子路径(相对主数据根,如 components.0.text);不传则读整个主数据并返回说明`),jsonPaths:z(R()).optional().describe(`多路径读取:一次读多个不相关子路径(与 jsonPath 互斥,优先于 jsonPath);返回各路径值,非法路径单项标错不整批失败`),fields:z(R()).optional().describe(`字段裁剪:只返回指定字段(对对象/数组元素投影),减少返回体积,如 ["id","title"]`),depth:pd().int().min(0).optional().describe(`嵌套深度限制:0=只根占位,1=根+子,递归到 depth 层后用 {...}/[...] 占位截断,减少深层返回体积`),offset:pd().int().min(0).optional().describe(`数组分页起始偏移(仅当读取目标是数组时生效,默认 0),配合 limit 分页读大数组`),limit:pd().int().min(1).max(200).optional().describe(`数组分页每页条数(默认 50,上限 200;仅数组时生效),返回切片 + total/hasMore`)})}),de=QI(async({value:e,patch:t,patches:n,del:o,dryRun:c},l)=>{let u=g(l),m=`set`;o?m=`delete`:(n&&n.length||t)&&(m=`edit`);let h=t?.value===void 0?e:t.value,y=x?_(u):void 0;if(c&&y!==void 0){let e=S();if(e!==y)return DU({code:`VERSION_CONFLICT`,message:`dryRun 预检发现乐观锁冲突: expectedHash=${y} 当前 hash=${e}(主数据在你 read 后被改)`,hint:`重新 read 拿最新 hash 再预检/写`})}if(m===`delete`){if(!t?.jsonPath)return DU({code:`MISSING_VALUE`,message:`delete 需要 patch.jsonPath 指定要删的子路径(主数据整体不可删,用 write(value) 整体替换)`,hint:`如 patch:{jsonPath:"components.0"}, del:true`});if(aq(t.jsonPath))return DU({code:`PATH_UNSAFE`,message:`jsonPath "${t.jsonPath}" 含非法段`,hint:`使用正常属性路径`});if(!lK(t.jsonPath,i,s))return DU({code:`PATH_DENIED`,message:`write delete @ "${t.jsonPath}" 不在 schema 声明字段内`,hint:`仅 schema 声明的 key 可删`});if(d){let e=x2(t.jsonPath,d.resourcesByPath);if(e)return DU({code:e.spec.mode===`freeze`?`FROZEN_FIELD`:`VERBATIM_PROTECTED`,message:`write delete @ "${t.jsonPath}" 命中受保护字段 "${e.protectedPath}"(${e.spec.mode}),不可删除`,hint:e.spec.mode===`freeze`?`冻结字段不可删`:`verbatim 字段不可直接删;先 resource_delete 释放`})}let e=await ee(`delete`,y);if(e!==null)return e;if(c){let e=uq(a);return lq(e,t.jsonPath)?`dryRun(delete): 将删除 @ ${t.jsonPath}。预览剩余:${mq(e,600)}。未实际写入、未入快照。`:`dryRun(delete): @ ${t.jsonPath} 不存在(无需删除)。未实际写入。`}A(`delete`);let n=lq(a,t.jsonPath);return D(),k({op:`delete`,detail:t.jsonPath,timestamp:Date.now()}),r&&(r(a,null),D()),v(S(),u),n?`已删除主数据 @ ${t.jsonPath}`:`主数据 @ ${t.jsonPath} 不存在(无需删除)`}if(m===`edit`){if(typeof a!=`object`||!a)return DU({code:`NOT_OBJECT`,message:`edit 仅适用于对象/数组主数据,当前是 ${a===void 0?`undefined`:typeof a}`,hint:`叶子用 write(value) 整体设置`});let e=await ee(`edit`,y);if(e!==null)return e;let o=n&&n.length?n:[{op:t.op??`set`,jsonPath:t.jsonPath||``,value:h}],l=k2({bindRef:a,patches:o,schema:i,allowKeys:s,snapshots:f,maxSnapshots:p,markDataDirty:D,schemaErrorMode:`zod`,dryRun:c,internalAfterWrite:r,protectedCtx:d});if(!l.ok)return l.error;if(c)return`dryRun(edit): ${l.applied.length} 个 patch 预检通过(schema 校验 OK)。预览结果:${mq(l.clone,600)}。未实际写入、未入快照。`;k({op:`edit`,detail:`${l.applied.length} 个 patch${l.applied.length>1?`(批量)`:``}`,value:l.applied.map(e=>`${e.op}@${e.jp}`),timestamp:Date.now()});let m=C(u);return N2(l.clone),`已 write(edit) 主数据(${l.applied.length} 个 patch)。当前值:${mq(l.clone,600)} (新 hash=${m})`}let b=dq(h);if(b.parseError)return AU(``,h,b.parseError);let w=await ee(`set`,y);if(w!==null)return w;let T=O2({bindRef:a,value:b.parsed,schema:i,allowKeys:s,snapshots:f,maxSnapshots:p,audit:k,dryRun:c,onWrite:D,internalAfterWrite:r,protectedCtx:d,hashFn:S});if(!T.ok)return T.error;if(c)return`dryRun(set): schema 校验通过。预览新值:${mq(T.data,600)}。未实际写入、未入快照。`;let E=S();return v(E,u),N2(T.data),`已 write(set) 主数据 = ${mq(T.data,600)} (新 hash=${E})${s?`(白名单模式:仅更新 schema 声明字段,未声明字段保留)`:``}`},{name:`write`,description:`写入主数据(高层入口,合并 set/edit/delete + 自动乐观锁 + 自动快照)。四意图:① 整体替换 write({value:整个对象});② 增量 write({patch:{op,jsonPath,value}}) op=set/remove/merge/append/move(move 的 value=目标路径字符串);③ 批量原子 write({patches:[...]})(任一失败整批回滚);④ 删子路径 write({patch:{jsonPath},del:true})。dryRun:true 预检不落盘。写入自动 schema 校验(失败不写,按错误修正重试)+ 自动快照。详细用法见系统提示「能力使用提示」。`,schema:B({value:Dd().optional().describe(`JSON 对象(推荐,如 {title:"x"})或 JSON 字符串;set 整体或单个 patch 的 set/merge/append 必填`),patch:B({op:Wd([`set`,`remove`,`merge`,`append`,`move`]).optional().describe(`增量操作:set 设值/remove 删/merge 合并对象/append 追加数组/move 移动数组元素(value=目标路径字符串)。单 patch edit 缺省按 set;del 模式(write({patch:{jsonPath},del:true}))不读 op 可省略`),jsonPath:R().optional().describe(`相对主数据根的点号路径(如 components.0.text);set/remove 必填,merge/append 不填则作用于根`),value:Dd().optional().describe(`该 patch 的值(JSON 直传或 JSON 字符串);set/merge/append 必填,remove 不需。与顶层 value 二选一:优先 patch.value,未填则回退顶层 value(向后兼容)。推荐用 patch.value(自带,与 patches 元素一致,无歧义)`)}).optional().describe(`单个增量编辑(自带 value,与 patches 元素一致);传 patch(无 patches)走单 patch edit 语义`),patches:z(B({op:Wd([`set`,`remove`,`merge`,`append`,`move`]),jsonPath:R().optional().describe(`相对主数据根的点号路径;set/remove 必填,merge/append 不填则作用于根`),value:Dd().optional().describe(`JSON 值(推荐直传)或 JSON 字符串;set/merge/append 必填,remove 不需`)})).optional().describe(`批量增量编辑:一次原子应用多个 patch(任一失败则整体不写入,clone 试跑全部 + schema 校验通过才落 live)。适合一次改多处,减少多轮往返`),del:yd().optional().describe(`true 则删除 patch.jsonPath 指定的子路径(等价 delete_data)`),dryRun:yd().optional().describe(`预检模式:走完整校验链(schema + 白名单 + patch 应用到 clone)但不落盘、不入快照,返回预览。四意图(value/patch/patches/del)均支持;乐观锁冲突照常检测(返回 VERSION_CONFLICT 不挂起)`)})});j(de);let fe=QI(async({jsonPath:e})=>{let t=e||``,n=t?dK(i,t):i;return n?`schema${t?` @ ${t}`:``} = ${mq(jK(n))}`:DU({code:`PATH_DENIED`,message:`schema @ "${t}" 不存在`,hint:`jsonPath 需在 schema 声明字段内(用 read() 不传 jsonPath 查看顶层字段)`})},{name:`schema_data`,description:`查看主数据(或子路径)的字段约束:类型/min/max/enum/必填/默认值/嵌套 shape。写前查约束,避免写错重试。不传 jsonPath 查根;传子路径(如 components.0)查该位置约束。`,schema:B({jsonPath:R().optional().describe(`要查约束的子路径;不传查根 schema`)})}),N=QI(async({snapshotId:e,against:t})=>{let n=t!=null,r,o;if(n){let e=t;if(typeof e==`string`){let t=dq(e);t.parseError||(e=t.parsed)}r=e,o=`against`}else{if(!f.length)return DU({code:`NO_SNAPSHOT`,message:`无快照可对比`,hint:`set/edit/delete 自动存快照;或传 against 一段 JSON 值直接对比`});let t=e===void 0?f[f.length-1]:f.find(t=>t.id===e);if(!t)return DU({code:`SNAPSHOT_NOT_FOUND`,message:`未找到快照 #${e}`,hint:`不传 snapshotId 用最近一次;或传 against`});r=t.value,o=`快照 #${t.id}`}let c=s?wK(a,i):a,l=Tq(r,uq(c));return l.length?`差异(当前 vs ${o},共 ${l.length} 处):\n${l.map(e=>` ${e.path}: ${mq(e.from)} → ${mq(e.to)}`).join(`
|
|
253
253
|
`)}`:`无差异:当前主数据与 ${o} 完全相同。`},{name:`diff_data`,description:`对比当前主数据与某快照(默认最近)或一段 JSON(against)的差异,返回结构化 {path, from→to} 列表。供 verify 自纠/冲突诊断/操作审计("刚才改了啥")。snapshotId 指定快照;against 传一段 JSON 值(与 snapshotId 互斥,传则忽略快照)。`,schema:B({snapshotId:pd().int().optional().describe(`对比的快照序号;不传则最近一次`),against:Dd().optional().describe(`对比的一段 JSON 值(与 snapshotId 互斥;传则忽略快照)`)})}),pe=[];if(t.vfsStore){let e=t.vfsStore,n=e=>`drafts/${e}.json`,o=QI(({draftId:t,chunk:r,mode:i})=>{let a=n(t),o=e.files[a],s=i===`append`&&o,c=s?o.content+r:r;return e.files[a]={content:c,updatedAt:Date.now()},JSON.stringify({draftId:t,bytes:c.length,mode:s?`append`:`start`})},{name:`draft_write`,description:`分块写 JSON 草稿到 drafts 池(单次 write 受 max_tokens 限制装不下时用)。mode:"start" 新建/"append" 追加拼接;返回 {draftId,bytes} 看累计进度。累积完 draft_commit 提交;拼接不合法返回 JSON_INVALID 草稿保留。`,schema:B({draftId:R().describe(`草稿标识(自起,如 "page-gen-1")`),chunk:R().describe(`JSON 片段字符串(分块输出,append 拼接成完整 JSON;如 '{"components":[' / '{"type":"heading",...},' / ']}')`),mode:Wd([`start`,`append`]).optional().describe(`start=新建/覆盖(默认);append=追加 chunk 到已有草稿`)})}),c=QI(async({draftId:t},o)=>{let c=g(o),l=n(t),u=e.files[l];if(!u)return DU({code:`DRAFT_NOT_FOUND`,message:`草稿 "${t}" 不存在`,hint:`先 draft_write({draftId, chunk, mode:"start"}) 新建,再 append 累积分块`});let m;try{m=JSON.parse(u.content)}catch(e){return DU({code:`JSON_INVALID`,message:`草稿 "${t}" 拼接后非合法 JSON: ${e.message}`,hint:`检查 chunk 拼接(逗号/括号/引号是否匹配,首尾是否闭合);草稿保留未删,可继续 draft_write 修正后重 commit`,details:{bytes:u.content.length,preview:u.content.slice(0,200)+(u.content.length>200?`…`:``)}})}let h=await ee(`set`,x?_(c):void 0);if(h!==null)return h;let y=O2({bindRef:a,value:m,schema:i,allowKeys:s,snapshots:f,maxSnapshots:p,audit:k,op:`draft_commit`,onWrite:D,internalAfterWrite:r,protectedCtx:d,hashFn:S});return y.ok?(v(y.hash,c),delete e.files[l],`已 draft_commit 草稿 "${t}" → 主数据 = ${mq(y.data,600)} (新 hash=${y.hash})${s?`(白名单模式:仅更新 schema 声明字段)`:``}。草稿已清理。`):y.error},{name:`draft_commit`,description:`把 draft_write 累积的草稿合并 + JSON.parse + 乐观锁 + schema 校验,原子提交主数据(任一步失败不写,草稿保留可修后重试;成功清草稿 + 自动快照可回退)。仅大 JSON 从零生成用;小改用 write。`,schema:B({draftId:R().describe(`要提交的草稿标识(对应 draft_write 的 draftId)`)})});j(c),pe.push(o,c)}let me=[];if(e.resources?.length&&l){let e=QI(async({path:e,handle:t})=>{let n=e;if(!n&&t&&(n=l.get(t)?.path),!n)return DU({code:`RESOURCE_NOT_FOUND`,message:`未提供 path 或有效 handle`,hint:`传 path(受保护字段)或 handle(占位符 ⟦res:handle⟧ 里的句柄)`});let r=v2(n);if(!c.has(r))return DU({code:`RESOURCE_NOT_FOUND`,message:`"${n}" 不是受保护字段`,hint:`resource_get 仅查集成方在 data.resources 声明的路径`});let i=l.get(r);if(i)return mq({path:i.path,mode:i.mode,value:i.value,handle:i.handle});let o=sq(a,r);if(o===void 0)return DU({code:`RESOURCE_NOT_FOUND`,message:`字段 "${n}" 当前无值,无法注册`,hint:`该字段可能在 bind 中不存在;先 read 触发懒注册`});let s=c.get(r),u=l.ensure(r,o,s.mode);return mq({path:r,mode:s.mode,value:o,handle:u})},{name:`resource_get`,description:`取受保护字段(freeze/verbatim)的真实值(占位符背后的精确值)。仅受保护路径(集成方在 data.resources 声明)。read 返回 ⟦frozen:path⟧/⟦res:handle⟧ 占位符,确需真值时用此工具。传 path 或 handle。`,schema:B({path:R().optional().describe(`受保护字段路径(data.resources 声明的)`),handle:R().optional().describe(`占位符 ⟦res:handle⟧ 里的句柄(与 path 二选一)`)})}),t=QI(async({path:e,value:t},n)=>{let r=g(n);if(!e)return DU({code:`MISSING_VALUE`,message:`resource_update 需要 path`,hint:`传要更新的 verbatim 受保护字段路径`});let o=v2(e),s=c.get(o);if(!s)return DU({code:`RESOURCE_NOT_FOUND`,message:`"${e}" 不是受保护字段`,hint:`resource_update 仅改 data.resources 声明的字段`});if(s.mode===`freeze`)return DU({code:`FROZEN_FIELD`,message:`字段 "${e}" 已冻结,resource_update 也不可改`,hint:`冻结字段完全只读`});let u=dK(i,o);if(u){let n=u.safeParse(t);if(!n.success)return DU({code:`SCHEMA_INVALID`,message:`resource_update 值不符合 "${e}" 的类型`,hint:`按字段类型传值`,details:OU(n.error.issues)})}l.update(o,t),cq(a,o,t),v(S(),r),D();let d=l.get(o)?.handle;return`已更新 verbatim 资源 "${e}" = ${mq(t,200)}(handle ${d??`(未知)`} 不变)。后续 write 该字段写回句柄 ⟦res:${d}⟧ 或新值`},{name:`resource_update`,description:`更新 verbatim 受保护字段的真实值(改精确原值,如刷新 token/hash)。仅 verbatim 可改;freeze 拒。更新后同步 bind + 标脏,后续 write 写回句柄即用新值。`,schema:B({path:R().describe(`要更新的 verbatim 受保护字段路径`),value:Dd().describe(`新值(需符合字段 schema 类型)`)})});j(t);let n=QI(async()=>{let e=l.list();return e.length?mq({resources:e}):`当前无已注册的受保护资源(read 受保护路径会懒注册)`},{name:`resource_list`,description:`列出所有已注册的受保护资源(path/mode/handle/bytes)。`,schema:B({})}),r=QI(async({path:e,handle:t})=>{let n=e;return!n&&t&&(n=l.get(t)?.path),n?l.delete(n)?`已释放资源 "${n}"(后续 read 该字段会重新懒注册)`:`资源 "${n}" 不存在(无需释放)`:DU({code:`RESOURCE_NOT_FOUND`,message:`未提供 path 或有效 handle`,hint:`传要释放的受保护字段 path 或 handle`})},{name:`resource_delete`,description:`释放受保护资源(从资源池删除,后续 read 重新懒注册)。用于不再需要保护的字段或释放空间。`,schema:B({path:R().optional().describe(`要释放的受保护字段路径`),handle:R().optional().describe(`占位符句柄(与 path 二选一)`)})});j(r),me.push(e,t,n,r)}let he=[te,ne,re,M,ie,ae,oe,se,ce,le,ue,de,fe,N,...pe,...me];Object.defineProperty(he,"controller",{value:O,enumerable:!1,configurable:!1,writable:!1});for(let e of he)Object.defineProperty(e,"__dataOpsScoped",{value:!0,enumerable:!1,configurable:!1});return he}var F2=new Set([`area`,`base`,`br`,`col`,`embed`,`hr`,`img`,`input`,`link`,`meta`,`param`,`source`,`track`,`wbr`]),gde=new Set([`script`,`style`]);function I2(e){let t=[],n=e.length;if(!e.trim())return t;let r=[0];for(let t=0;t<n;t++)e[t]===`
|
|
254
254
|
`&&r.push(t+1);let i=e=>{let t=0,n=r.length-1;for(;t<n;){let i=t+n+1>>1;r[i]<=e?t=i:n=i-1}return t+1},a=[],o=0;for(;o<n;){let r=e.indexOf(`<`,o);if(r<0)break;if(e.startsWith(`<!--`,r)){let n=e.indexOf(`-->`,r+4);if(n<0){t.push({line:i(r),code:`UNCLOSED_COMMENT`,message:`注释 <!-- 未闭合(缺 -->)`});break}o=n+3;continue}if(e[r+1]===`!`){let t=e.indexOf(`>`,r);o=t<0?n:t+1;continue}let s=e[r+1]===`/`,c=s?r+2:r+1,l=e[c]??``;if(!/[a-zA-Z]/.test(l)){o=r+1;continue}let u=c,d=``;for(;u<n;){let t=e[u];if(d)t===d&&(d=``);else if(t===`"`||t===`'`)d=t;else if(t===`>`)break;u++}if(u>=n){t.push({line:i(r),code:`UNCLOSED_TAG`,message:`标签 ${e.slice(r,Math.min(r+20,n))} 未写完(缺 >)`});break}let f=e.slice(c,u),p=(f.match(/^[a-zA-Z][a-zA-Z0-9-]*/)??[``])[0].toLowerCase(),m=!s&&/\/\s*$/.test(f);if(o=u+1,p){if(s){let e=a.length-1;if(e>=0&&a[e].name===p)a.pop();else{let e=a.findIndex(e=>e.name===p);if(e>=0){let n=a.splice(e);for(let e of n.slice(1))t.push({line:i(e.idx),code:`UNCLOSED_TAG`,message:`<${e.name}> 未闭合(先遇到 </${p}>)`})}else t.push({line:i(r),code:`STRAY_CLOSE_TAG`,message:`</${p}> 无匹配的开标签`})}continue}if(!(F2.has(p)||m)){if(gde.has(p)){let n=RegExp(`</${p}\\s*>`,`i`).exec(e.slice(o));if(!n){t.push({line:i(r),code:`UNCLOSED_TAG`,message:`<${p}> 未闭合(缺 </${p}>)`});break}o+=n.index+n[0].length;continue}a.push({name:p,idx:r})}}}for(let e of a)t.push({line:i(e.idx),code:`UNCLOSED_TAG`,message:`<${e.name}> 未闭合`});return t}var L2=`__pgTouched`,R2=`__pgFinalText`,z2=`__pgCodeHashes`,B2=`__pgKeepExternal`,V2=`__pgNotes`,H2=200;function _de(e){let t=[];for(let n of e.split(`
|
|
255
255
|
`)){let e=n.match(/^\s*[-*]?\s*\[note\]\s*(.*)$/i);e&&e[1].trim()&&t.push(`[note] `+e[1].trim())}return[...new Set(t)]}function vde(e,t){let n=Array.isArray(e[V2])?e[V2].filter(e=>typeof e==`string`):[];e[V2]=[...new Set([...n,...t])].map(e=>e.length>H2?e.slice(0,H2)+`…`:e).slice(-5)}function U2(e){let t=5381;for(let n=0;n<e.length;n++)t=(t<<5)+t+e.charCodeAt(n)|0;return(t>>>0).toString(16)}function yde(e,t){let n=[];return G2(e,t,e=>{typeof e.name==`string`&&e.name&&n.push(e.name)}),n}function W2(e,t){if(!e.startsWith(t))return null;let n=e.slice(t.length),r=n.lastIndexOf(`.`);return(r>0?n.slice(0,r):r===0?``:n)||null}function G2(e,t,n){if(!(!e||typeof e!=`object`))for(let r of t){let t=sq(e,r);if(Array.isArray(t))for(let e=0;e<t.length;e++){let i=t[e];i&&typeof i==`object`&&typeof i.__pgId==`string`&&n(i,r,e)}}}function bde(e,t,n){let r=new Set;if(!e||typeof e!=`object`)return r;for(let i of t){let t=sq(e,i);if(Array.isArray(t))for(let e=0;e<t.length;e++){let a=t[e];if(!a||typeof a!=`object`)continue;let o=a.__pgId;if(typeof o!=`string`)continue;let s=`${i}.${e}`;for(let e of n)if(e.path===s||e.path.startsWith(s+`.`)){r.add(o);break}}}return r}function xde(e){let{writablePaths:t,codeVfsPrefix:n,ext:r,codeField:i=`code`,onWarning:a,getController:o,vfsStore:s,craftNotes:c=!0}=e,l=s,u=l.__pgLastCheckout??=new Map,d=l.__pgPendingRetry??=new Set;return{name:`code-asset-checkout-commit`,beforeAgent:e=>{let c=o()?.get?.().bind;c&&M2(c,t);let l=0,f=0,p=new Map;if(G2(c,t,e=>{l++;let t=sq(e,i);if(typeof t==`string`){f++;let i=e.__pgId,a=U2(t);p.set(i,a);let o=`${n}${i}.${r}`,c=s.files[o],l=u.get(i);c&&typeof c.content==`string`&&c.content!==t&&l===a?d.add(o):(s.files[o]={content:t,updatedAt:Date.now()},d.delete(o)),u.set(i,a)}}),l>0&&f===0&&a){let e=``;for(let n of t){let t=sq(c,n);if(Array.isArray(t)&&t.length){e=Object.keys(t[0]??{}).join(`,`);break}}a(`codeField '${i}' 在当前 ${l} 个组件中均未命中 string 值。组件实际字段:[${e}]。若预期有代码组件请核对 codeField 路径;若当前确无代码组件可忽略。`)}return{files:s.files,[L2]:new Set,[R2]:{text:``},[z2]:p,[B2]:[]}},wrapModelCall:async(e,t)=>{let n=await t(e),r=e.state[R2];return r&&!(n.toolCalls&&n.toolCalls.length)&&typeof n.content==`string`&&n.content&&(r.text=n.content),n},augmentPrompt:()=>{let e=o()?.get?.().bind,i=[],a=0;if(G2(e,t,(e,t,o)=>{a++;let l=typeof e.name==`string`&&e.name?e.name:``,u=l?`${l} [${o}]`:`(未命名 [${o}])`,d=`${n}${e.__pgId}.${r}`,f=!!s.files[d];if(i.push(`- ${u} → ${d}${f?``:`(尚未检出,先 vfs_write 创建)`}`),c){let t=Array.isArray(e[V2])?e[V2].filter(e=>typeof e==`string`):[];if(t.length){let e=t[t.length-1];i.push(` 📝 笔记×${t.length}(最近):${e.length>120?e.slice(0,120)+`…`:e}`)}}}),!i.length)return;let l=``;for(let n of t){let t=sq(e,n);if(Array.isArray(t)){l=`\n新建组件追加索引:write({patch:{op:'set',jsonPath:'${n}.${t.length}',value:{...}}})(当前共 ${t.length} 个,勿覆盖已有索引)`;break}}return`## 组件代码文件地图(改组件时按 name 直接改对应 vfs 文件;框架自动 checkout/commit)${c?`
|