@zmzai/agent-framework 0.1.0 → 0.2.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 +37 -0
- package/dist/adapters/openai-provider.d.ts +31 -2
- package/dist/adapters/openai-provider.d.ts.map +1 -1
- package/dist/adapters/openai-provider.js +118 -74
- package/dist/adapters/openai-provider.js.map +1 -1
- package/dist/adapters/subprocess-sandbox.d.ts +4 -5
- package/dist/adapters/subprocess-sandbox.d.ts.map +1 -1
- package/dist/adapters/subprocess-sandbox.js +106 -18
- package/dist/adapters/subprocess-sandbox.js.map +1 -1
- package/dist/adapters/terminal-backend.d.ts +5 -0
- package/dist/adapters/terminal-backend.d.ts.map +1 -0
- package/dist/adapters/terminal-backend.js +153 -0
- package/dist/adapters/terminal-backend.js.map +1 -0
- package/dist/cli.js +0 -0
- package/dist/core/agent/registry.d.ts +3 -0
- package/dist/core/agent/registry.d.ts.map +1 -1
- package/dist/core/agent/registry.js +9 -2
- package/dist/core/agent/registry.js.map +1 -1
- package/dist/core/events/manifest.d.ts +29 -4
- package/dist/core/events/manifest.d.ts.map +1 -1
- package/dist/core/events/manifest.js +21 -0
- package/dist/core/events/manifest.js.map +1 -1
- package/dist/core/mcp/client.d.ts +46 -0
- package/dist/core/mcp/client.d.ts.map +1 -0
- package/dist/core/mcp/client.js +286 -0
- package/dist/core/mcp/client.js.map +1 -0
- package/dist/core/mcp/http-client.d.ts +54 -0
- package/dist/core/mcp/http-client.d.ts.map +1 -0
- package/dist/core/mcp/http-client.js +385 -0
- package/dist/core/mcp/http-client.js.map +1 -0
- package/dist/core/mcp/servers.d.ts +30 -0
- package/dist/core/mcp/servers.d.ts.map +1 -0
- package/dist/core/mcp/servers.js +104 -0
- package/dist/core/mcp/servers.js.map +1 -0
- package/dist/core/permission/ruleset.d.ts +1 -1
- package/dist/core/permission/ruleset.d.ts.map +1 -1
- package/dist/core/permission/ruleset.js +4 -0
- package/dist/core/permission/ruleset.js.map +1 -1
- package/dist/core/permission/write-path.d.ts +27 -0
- package/dist/core/permission/write-path.d.ts.map +1 -0
- package/dist/core/permission/write-path.js +52 -0
- package/dist/core/permission/write-path.js.map +1 -0
- package/dist/core/repomap/cache.d.ts +24 -0
- package/dist/core/repomap/cache.d.ts.map +1 -0
- package/dist/core/repomap/cache.js +59 -0
- package/dist/core/repomap/cache.js.map +1 -0
- package/dist/core/repomap/graph.d.ts +14 -0
- package/dist/core/repomap/graph.d.ts.map +1 -0
- package/dist/core/repomap/graph.js +89 -0
- package/dist/core/repomap/graph.js.map +1 -0
- package/dist/core/repomap/render.d.ts +10 -0
- package/dist/core/repomap/render.d.ts.map +1 -0
- package/dist/core/repomap/render.js +33 -0
- package/dist/core/repomap/render.js.map +1 -0
- package/dist/core/repomap/repomap.d.ts +38 -0
- package/dist/core/repomap/repomap.d.ts.map +1 -0
- package/dist/core/repomap/repomap.js +116 -0
- package/dist/core/repomap/repomap.js.map +1 -0
- package/dist/core/repomap/tags.d.ts +26 -0
- package/dist/core/repomap/tags.d.ts.map +1 -0
- package/dist/core/repomap/tags.js +191 -0
- package/dist/core/repomap/tags.js.map +1 -0
- package/dist/core/runtime/compaction.d.ts +26 -14
- package/dist/core/runtime/compaction.d.ts.map +1 -1
- package/dist/core/runtime/compaction.js +46 -34
- package/dist/core/runtime/compaction.js.map +1 -1
- package/dist/core/runtime/lifecycle.d.ts +79 -0
- package/dist/core/runtime/lifecycle.d.ts.map +1 -0
- package/dist/core/runtime/lifecycle.js +71 -0
- package/dist/core/runtime/lifecycle.js.map +1 -0
- package/dist/core/runtime/pi-bridge.d.ts +4 -1
- package/dist/core/runtime/pi-bridge.d.ts.map +1 -1
- package/dist/core/runtime/pi-bridge.js +15 -1
- package/dist/core/runtime/pi-bridge.js.map +1 -1
- package/dist/core/runtime/run-transcript.d.ts +14 -0
- package/dist/core/runtime/run-transcript.d.ts.map +1 -0
- package/dist/core/runtime/run-transcript.js +35 -0
- package/dist/core/runtime/run-transcript.js.map +1 -0
- package/dist/core/runtime/runner.d.ts +38 -9
- package/dist/core/runtime/runner.d.ts.map +1 -1
- package/dist/core/runtime/runner.js +140 -20
- package/dist/core/runtime/runner.js.map +1 -1
- package/dist/core/session/sqlite-store.d.ts +18 -0
- package/dist/core/session/sqlite-store.d.ts.map +1 -0
- package/dist/core/session/sqlite-store.js +159 -0
- package/dist/core/session/sqlite-store.js.map +1 -0
- package/dist/core/session/types.d.ts +12 -0
- package/dist/core/session/types.d.ts.map +1 -1
- package/dist/core/tools/adapter.d.ts +11 -4
- package/dist/core/tools/adapter.d.ts.map +1 -1
- package/dist/core/tools/adapter.js +167 -8
- package/dist/core/tools/adapter.js.map +1 -1
- package/dist/core/tools/builtins.d.ts.map +1 -1
- package/dist/core/tools/builtins.js +5 -2
- package/dist/core/tools/builtins.js.map +1 -1
- package/dist/core/tools/context.d.ts +2 -0
- package/dist/core/tools/context.d.ts.map +1 -1
- package/dist/core/tools/def.d.ts +25 -0
- package/dist/core/tools/def.d.ts.map +1 -1
- package/dist/core/tools/def.js +3 -1
- package/dist/core/tools/def.js.map +1 -1
- package/dist/core/tools/git.d.ts +12 -0
- package/dist/core/tools/git.d.ts.map +1 -0
- package/dist/core/tools/git.js +189 -0
- package/dist/core/tools/git.js.map +1 -0
- package/dist/core/tools/patch.d.ts +45 -0
- package/dist/core/tools/patch.d.ts.map +1 -0
- package/dist/core/tools/patch.js +224 -0
- package/dist/core/tools/patch.js.map +1 -0
- package/dist/core/tools/qa-check.d.ts.map +1 -1
- package/dist/core/tools/qa-check.js +9 -2
- package/dist/core/tools/qa-check.js.map +1 -1
- package/dist/core/tools/repomap.d.ts +8 -0
- package/dist/core/tools/repomap.d.ts.map +1 -0
- package/dist/core/tools/repomap.js +34 -0
- package/dist/core/tools/repomap.js.map +1 -0
- package/dist/core/tools/terminal.d.ts +80 -0
- package/dist/core/tools/terminal.d.ts.map +1 -0
- package/dist/core/tools/terminal.js +265 -0
- package/dist/core/tools/terminal.js.map +1 -0
- package/dist/core/tools/trim.d.ts +31 -0
- package/dist/core/tools/trim.d.ts.map +1 -0
- package/dist/core/tools/trim.js +98 -0
- package/dist/core/tools/trim.js.map +1 -0
- package/dist/core/tools/webfetch.d.ts +10 -0
- package/dist/core/tools/webfetch.d.ts.map +1 -0
- package/dist/core/tools/webfetch.js +104 -0
- package/dist/core/tools/webfetch.js.map +1 -0
- package/dist/core/tools/websearch.d.ts +19 -0
- package/dist/core/tools/websearch.d.ts.map +1 -0
- package/dist/core/tools/websearch.js +132 -0
- package/dist/core/tools/websearch.js.map +1 -0
- package/dist/index.d.ts +30 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -1
- package/dist/index.js.map +1 -1
- package/dist/server/create-agent-runtime.d.ts +68 -0
- package/dist/server/create-agent-runtime.d.ts.map +1 -0
- package/dist/server/create-agent-runtime.js +67 -0
- package/dist/server/create-agent-runtime.js.map +1 -0
- package/dist/server/create-server.d.ts +5 -0
- package/dist/server/create-server.d.ts.map +1 -1
- package/dist/server/create-server.js +2 -0
- package/dist/server/create-server.js.map +1 -1
- package/package.json +23 -9
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { readdir, stat } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { Language, Parser } from "web-tree-sitter";
|
|
4
|
+
/** wasm 资源目录。bundler 环境(Next 等)下包会被打卷、createRequire 被 shim,
|
|
5
|
+
* 相对包路径解析必失败——消费方在那种环境下用 setWasmDirs 注入真实目录
|
|
6
|
+
* (如 require.resolve 包后取 dirname);Node 直跑用默认 resolve 路径。 */
|
|
7
|
+
let wasmDirs = {};
|
|
8
|
+
export function setWasmDirs(dirs) {
|
|
9
|
+
wasmDirs = { ...dirs };
|
|
10
|
+
parserInit = null; // 已初始化的 Parser 绑定旧 locateFile,重置以让新目录生效
|
|
11
|
+
languageCache.clear();
|
|
12
|
+
}
|
|
13
|
+
function nodeRequire() {
|
|
14
|
+
// getBuiltinModule 是运行时真 API,不会被 bundler shim;顶层 createRequire
|
|
15
|
+
// 在 bundle 里可能是空壳,故这里动态取并 fallback
|
|
16
|
+
const mod = process.getBuiltinModule?.("node:module");
|
|
17
|
+
const createRequireFn = mod?.createRequire;
|
|
18
|
+
if (typeof createRequireFn !== "function") {
|
|
19
|
+
throw new Error("无法获取 node:module.createRequire(bundler 环境请用 setWasmDirs 注入 wasm 目录)");
|
|
20
|
+
}
|
|
21
|
+
return createRequireFn(path.join(process.cwd(), "index.js"));
|
|
22
|
+
}
|
|
23
|
+
const SKIP_DIRS = new Set([
|
|
24
|
+
"node_modules", ".git", ".next", "dist", "build", "out", "coverage",
|
|
25
|
+
".zmzai", ".venv", "venv", "__pycache__", "vendor", ".cache", ".turbo",
|
|
26
|
+
]);
|
|
27
|
+
const CODE_EXTS = new Set([".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs", ".py", ".go"]);
|
|
28
|
+
const MAX_FILE_BYTES = 512 * 1024;
|
|
29
|
+
const LANG_BY_EXT = {
|
|
30
|
+
".ts": { wasm: "tree-sitter-typescript.wasm", defs: ["function_declaration", "class_declaration", "method_definition", "interface_declaration", "enum_declaration", "type_alias_declaration", "abstract_class_declaration", "generator_function_declaration"], refs: ["identifier", "property_identifier", "type_identifier"] },
|
|
31
|
+
".mts": { wasm: "tree-sitter-typescript.wasm", defs: ["function_declaration", "class_declaration", "method_definition", "interface_declaration", "enum_declaration", "type_alias_declaration"], refs: ["identifier", "property_identifier", "type_identifier"] },
|
|
32
|
+
".cts": { wasm: "tree-sitter-typescript.wasm", defs: ["function_declaration", "class_declaration", "method_definition", "interface_declaration", "enum_declaration", "type_alias_declaration"], refs: ["identifier", "property_identifier", "type_identifier"] },
|
|
33
|
+
".tsx": { wasm: "tree-sitter-tsx.wasm", defs: ["function_declaration", "class_declaration", "method_definition", "interface_declaration", "enum_declaration", "type_alias_declaration"], refs: ["identifier", "property_identifier", "type_identifier"] },
|
|
34
|
+
".js": { wasm: "tree-sitter-javascript.wasm", defs: ["function_declaration", "class_declaration", "method_definition", "generator_function_declaration"], refs: ["identifier", "property_identifier", "shorthand_property_identifier"] },
|
|
35
|
+
".jsx": { wasm: "tree-sitter-javascript.wasm", defs: ["function_declaration", "class_declaration", "method_definition"], refs: ["identifier", "property_identifier", "shorthand_property_identifier"] },
|
|
36
|
+
".mjs": { wasm: "tree-sitter-javascript.wasm", defs: ["function_declaration", "class_declaration", "method_definition"], refs: ["identifier", "property_identifier", "shorthand_property_identifier"] },
|
|
37
|
+
".cjs": { wasm: "tree-sitter-javascript.wasm", defs: ["function_declaration", "class_declaration", "method_definition"], refs: ["identifier", "property_identifier", "shorthand_property_identifier"] },
|
|
38
|
+
".py": { wasm: "tree-sitter-python.wasm", defs: ["function_definition", "class_definition"], refs: ["identifier"] },
|
|
39
|
+
".go": { wasm: "tree-sitter-go.wasm", defs: ["function_declaration", "method_declaration", "type_spec"], refs: ["identifier", "field_identifier", "type_identifier", "package_identifier"] },
|
|
40
|
+
};
|
|
41
|
+
let parserInit = null;
|
|
42
|
+
const languageCache = new Map();
|
|
43
|
+
const parserByLang = new Map();
|
|
44
|
+
function pkgDir(moduleName) {
|
|
45
|
+
// 包 exports 各有缺口(web-tree-sitter 不暴露 wasm/package.json 子路径,
|
|
46
|
+
// tree-sitter-wasms 的 main 坏了),双策略:先 package.json 锚点,fallback 主入口
|
|
47
|
+
const require_ = nodeRequire();
|
|
48
|
+
try {
|
|
49
|
+
return path.dirname(require_.resolve(`${moduleName}/package.json`));
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return path.dirname(require_.resolve(moduleName));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function runtimeWasmDir() {
|
|
56
|
+
return wasmDirs.runtime ?? pkgDir("web-tree-sitter");
|
|
57
|
+
}
|
|
58
|
+
function grammarWasmDir() {
|
|
59
|
+
return wasmDirs.grammar ?? path.join(pkgDir("tree-sitter-wasms"), "out");
|
|
60
|
+
}
|
|
61
|
+
function ensureParserInit() {
|
|
62
|
+
parserInit ??= Parser.init({
|
|
63
|
+
locateFile(scriptName) {
|
|
64
|
+
// web-tree-sitter 的运行时 wasm(tree-sitter.wasm)随包分发
|
|
65
|
+
return path.join(runtimeWasmDir(), scriptName);
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
return parserInit;
|
|
69
|
+
}
|
|
70
|
+
async function languageFor(wasmFile) {
|
|
71
|
+
const cached = languageCache.get(wasmFile);
|
|
72
|
+
if (cached)
|
|
73
|
+
return cached;
|
|
74
|
+
const pending = (async () => {
|
|
75
|
+
await ensureParserInit();
|
|
76
|
+
return Language.load(path.join(grammarWasmDir(), wasmFile));
|
|
77
|
+
})();
|
|
78
|
+
languageCache.set(wasmFile, pending);
|
|
79
|
+
return pending;
|
|
80
|
+
}
|
|
81
|
+
function collectTags(file, content, spec) {
|
|
82
|
+
const tags = [];
|
|
83
|
+
let parser = parserByLang.get(spec.wasm);
|
|
84
|
+
if (!parser) {
|
|
85
|
+
parser = new Parser();
|
|
86
|
+
parserByLang.set(spec.wasm, parser);
|
|
87
|
+
}
|
|
88
|
+
const tree = parser.parse(content);
|
|
89
|
+
if (!tree)
|
|
90
|
+
return tags;
|
|
91
|
+
const root = tree.rootNode;
|
|
92
|
+
for (const defType of spec.defs) {
|
|
93
|
+
for (const node of root.descendantsOfType(defType)) {
|
|
94
|
+
if (!node)
|
|
95
|
+
continue;
|
|
96
|
+
const nameNode = node.childForFieldName("name");
|
|
97
|
+
if (!nameNode)
|
|
98
|
+
continue;
|
|
99
|
+
tags.push({ file, line: node.startPosition.row + 1, name: nameNode.text, kind: "def" });
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
for (const refType of spec.refs) {
|
|
103
|
+
for (const node of root.descendantsOfType(refType)) {
|
|
104
|
+
if (!node)
|
|
105
|
+
continue;
|
|
106
|
+
const name = node.text;
|
|
107
|
+
if (name && name.length <= 64)
|
|
108
|
+
tags.push({ file, line: node.startPosition.row + 1, name, kind: "ref" });
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
tree.delete();
|
|
112
|
+
return tags;
|
|
113
|
+
}
|
|
114
|
+
/** 解析单文件为标签(缓存未命中路径)。语言不支持或解析失败返回空。 */
|
|
115
|
+
export async function extractTags(relFile, absFile) {
|
|
116
|
+
const ext = path.extname(relFile).toLowerCase();
|
|
117
|
+
const spec = LANG_BY_EXT[ext];
|
|
118
|
+
if (!spec)
|
|
119
|
+
return [];
|
|
120
|
+
const { readFile } = await import("node:fs/promises");
|
|
121
|
+
let content;
|
|
122
|
+
try {
|
|
123
|
+
const info = await stat(absFile);
|
|
124
|
+
if (info.size > MAX_FILE_BYTES)
|
|
125
|
+
return [];
|
|
126
|
+
content = await readFile(absFile, "utf8");
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return [];
|
|
130
|
+
}
|
|
131
|
+
if (content.includes("\u0000"))
|
|
132
|
+
return []; // 二进制嗅探
|
|
133
|
+
try {
|
|
134
|
+
const lang = await languageFor(spec.wasm);
|
|
135
|
+
let parser = parserByLang.get(spec.wasm);
|
|
136
|
+
if (!parser) {
|
|
137
|
+
parser = new Parser();
|
|
138
|
+
parserByLang.set(spec.wasm, parser);
|
|
139
|
+
}
|
|
140
|
+
parser.setLanguage(lang);
|
|
141
|
+
return collectTags(relFile, content, spec);
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
// 抽取失败必须向编排层报错(而非静默空数组):空结果会被 mtime 缓存、
|
|
145
|
+
// 污染后续调用;由编排层决定跳过与重试。Next 等 bundler 环境下 wasm
|
|
146
|
+
// 解析可能失败(import.meta.url 被重写),用 serverExternalPackages 解决。
|
|
147
|
+
if (process.env.ZMZAI_REPOMAP_DEBUG)
|
|
148
|
+
console.error("[repomap] extract failed:", error);
|
|
149
|
+
throw error instanceof Error ? error : new Error(String(error));
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/** 递归列出工作区内的代码文件(跳重目录,cap 防爆)。 */
|
|
153
|
+
export async function listCodeFiles(root, opts = {}) {
|
|
154
|
+
const maxFiles = opts.maxFiles ?? 5000;
|
|
155
|
+
const files = [];
|
|
156
|
+
let skipped = 0;
|
|
157
|
+
const walk = async (dir) => {
|
|
158
|
+
if (files.length >= maxFiles)
|
|
159
|
+
return;
|
|
160
|
+
let entries;
|
|
161
|
+
try {
|
|
162
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
for (const entry of entries) {
|
|
168
|
+
if (files.length >= maxFiles)
|
|
169
|
+
return;
|
|
170
|
+
const abs = path.join(dir, entry.name);
|
|
171
|
+
if (entry.isDirectory()) {
|
|
172
|
+
if (SKIP_DIRS.has(entry.name) || entry.name.startsWith("."))
|
|
173
|
+
continue;
|
|
174
|
+
await walk(abs);
|
|
175
|
+
}
|
|
176
|
+
else if (entry.isFile()) {
|
|
177
|
+
const rel = path.relative(root, abs).split(path.sep).join("/");
|
|
178
|
+
if (!CODE_EXTS.has(path.extname(entry.name).toLowerCase()))
|
|
179
|
+
continue;
|
|
180
|
+
if (opts.filter && !opts.filter(rel))
|
|
181
|
+
continue;
|
|
182
|
+
files.push(rel);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
await walk(root);
|
|
187
|
+
if (files.length >= maxFiles)
|
|
188
|
+
skipped = files.length; // 达到 cap:未知总数,标记触顶
|
|
189
|
+
return { files: files.sort(), skipped };
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=tags.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tags.js","sourceRoot":"","sources":["../../../src/core/repomap/tags.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,25 @@
|
|
|
1
1
|
import type { AgentMessage } from "@earendil-works/pi-agent-core";
|
|
2
2
|
import type { Api, Model } from "@earendil-works/pi-ai";
|
|
3
|
-
/** Framework compaction (spec §8.3)
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
3
|
+
/** Framework compaction (spec §8.3) — projection style (tutorial-advanced 06):
|
|
4
|
+
* canonical history (PI state.messages) is never mutated; the transform keeps
|
|
5
|
+
* closure state {anchor, summary} and projects the model's view as
|
|
6
|
+
* [summaryMessage, ...messages.slice(anchor)]. PI's transformContext result is
|
|
7
|
+
* request-only (never written back to state), so the previous stateless
|
|
8
|
+
* version re-summarized the whole history on every LLM request — the anchor
|
|
9
|
+
* turns compaction into an incremental, idempotent projection.
|
|
10
|
+
* Known limitation: closure state lives per-run (the runner builds a fresh
|
|
11
|
+
* transform for each runLoop), so a new run re-summarizes once when it next
|
|
12
|
+
* crosses the threshold; cross-run persistence belongs in the store later.
|
|
13
|
+
*
|
|
14
|
+
* Harness-course retrofits (tutorial-harness 05/07) preserved:
|
|
15
|
+
* - 膨胀拒绝:新摘要比它替代的内容(新折叠段 + 旧摘要)还长时作废本次压缩。
|
|
16
|
+
* - 失败记忆:摘要调用失败或膨胀后,本轮不再反复烧摘要 token。
|
|
17
|
+
* Projection retrofit adds (tutorial-advanced 06):
|
|
18
|
+
* - 滞回带:已有摘要时,只有投影尾部自上次压缩后长够摘要体量的一半才再压,
|
|
19
|
+
* 防止超窗后每个请求都重摘一遍。
|
|
20
|
+
* - 增量摘要:摘要提示词带【已有摘要】+ 新折叠段,反复压缩是续写不是重启。
|
|
21
|
+
* - 摘要消息固定 timestamp: 0:投影前缀跨请求逐字节稳定,provider 的
|
|
22
|
+
* prompt cache(前缀逐字节匹配)在两次压缩之间持续命中。 */
|
|
9
23
|
export type CompactionOptions = {
|
|
10
24
|
/** Cheap model used to write the summary (the relay's small model). */
|
|
11
25
|
summaryModel: Model<Api>;
|
|
@@ -22,15 +36,12 @@ export type CompactionOptions = {
|
|
|
22
36
|
/** Called when a compaction attempt fails ("summary-empty" | "summary-inflated");
|
|
23
37
|
* after any failure the transform stops retrying for this run (失败记忆). */
|
|
24
38
|
onCompactionFailed?: (reason: "summary-empty" | "summary-inflated") => void | Promise<void>;
|
|
39
|
+
/** 无条件压缩(UI「压缩当前会话」):跳过阈值与滞回早退,其余保护(膨胀拒绝等)不变。 */
|
|
40
|
+
force?: boolean;
|
|
25
41
|
};
|
|
26
|
-
/** Returns a transformContext that
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* - 膨胀拒绝(Gemini chatCompressionService):摘要比被压区还长时作废本次压缩,
|
|
30
|
-
* 宁可用全量上下文也不换一份负收益的摘要。
|
|
31
|
-
* - 失败记忆(Gemini hasFailedCompressionAttempt):摘要调用失败或膨胀后记住这次
|
|
32
|
-
* 失败,后续不再反复烧摘要 token;失败不静默,通过 onCompactionFailed 上报。
|
|
33
|
-
*/
|
|
42
|
+
/** Returns a transformContext that projects the model's view as
|
|
43
|
+
* [summaryMessage?, ...messages.slice(anchor)] and compacts incrementally
|
|
44
|
+
* when the projection crosses the window. */
|
|
34
45
|
export declare function createCompactionTransform(options: CompactionOptions): (messages: AgentMessage[], signal?: AbortSignal) => Promise<AgentMessage[]>;
|
|
35
46
|
/** One-shot completion via an AssistantMessageEventStream (relay streamFn
|
|
36
47
|
* shape): drives the stream to completion and returns its full text. Used for
|
|
@@ -55,5 +66,6 @@ export declare function buildCompactionTransform(input: {
|
|
|
55
66
|
summaryModel: Model<Api> | null;
|
|
56
67
|
streamOne: (model: Model<Api>, messages: AgentMessage[]) => Promise<string>;
|
|
57
68
|
onCompacted?: (summary: string, tokensBefore: number) => void;
|
|
69
|
+
force?: boolean;
|
|
58
70
|
}): ((messages: AgentMessage[], signal?: AbortSignal) => Promise<AgentMessage[]>) | undefined;
|
|
59
71
|
//# sourceMappingURL=compaction.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compaction.d.ts","sourceRoot":"","sources":["../../../src/core/runtime/compaction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAExD
|
|
1
|
+
{"version":3,"file":"compaction.d.ts","sourceRoot":"","sources":["../../../src/core/runtime/compaction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAExD;;;;;;;;;;;;;;;;;;;0CAmB0C;AAE1C,MAAM,MAAM,iBAAiB,GAAG;IAC9B,uEAAuE;IACvE,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACzB,4CAA4C;IAC5C,aAAa,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iDAAiD;IACjD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,qDAAqD;IACrD,aAAa,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7D,wEAAwE;IACxE,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9D;8EAC0E;IAC1E,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,GAAG,kBAAkB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5F,iDAAiD;IACjD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAwCF;;8CAE8C;AAC9C,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,iBAAiB,GAAG,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAoDjJ;AAED;;kEAEkE;AAClE,wBAAsB,aAAa,CACjC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,YAAY,EAAE,CAAA;CAAE,KAAK,OAAO,CAAC;IAAE,MAAM,IAAI,OAAO,CAAC;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,GAAG;IAAE,MAAM,IAAI,OAAO,CAAC;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAA;CAAE,EAClM,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,YAAY,EAAE,GACvB,OAAO,CAAC,MAAM,CAAC,CAYjB;AAED;6EAC6E;AAC7E,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAC9C,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IAChC,SAAS,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5E,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9D,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,GAAG,CAAC,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,GAAG,SAAS,CAS5F"}
|
|
@@ -27,53 +27,64 @@ function estimateTokens(messages) {
|
|
|
27
27
|
return total;
|
|
28
28
|
}
|
|
29
29
|
const SUMMARY_INSTRUCTION = "把以下对话压缩成一份中文工作摘要,保留:任务目标、已完成的关键步骤与工具结果、当前进度、待办事项、重要的文件路径/命令/产物。不要续写对话,只输出结构化摘要。";
|
|
30
|
-
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
30
|
+
/** The summary message is deterministic (fixed shape, timestamp 0) so the
|
|
31
|
+
* projected prefix is byte-stable across requests — this is what lets the
|
|
32
|
+
* provider's prompt cache keep hitting between two compactions. */
|
|
33
|
+
function summaryMessage(text) {
|
|
34
|
+
return { role: "user", content: `【早期对话摘要】\n${text}`, timestamp: 0 };
|
|
35
|
+
}
|
|
36
|
+
/** Returns a transformContext that projects the model's view as
|
|
37
|
+
* [summaryMessage?, ...messages.slice(anchor)] and compacts incrementally
|
|
38
|
+
* when the projection crosses the window. */
|
|
38
39
|
export function createCompactionTransform(options) {
|
|
39
40
|
const reserve = options.reserveTokens ?? 4096;
|
|
40
41
|
const keepRecent = options.keepRecentMessages ?? 8;
|
|
41
|
-
let
|
|
42
|
+
let summary = null; // 投影的唯一状态:当前摘要
|
|
43
|
+
let anchor = 0; // canonical 历史中已折叠的前缀长度
|
|
44
|
+
let tailTokensAtCompaction = 0; // 上次压缩时投影尾部的 token 量(滞回带基准)
|
|
45
|
+
let hasFailed = false; // 失败记忆:本轮不再重试摘要
|
|
42
46
|
return async (messages, signal) => {
|
|
43
47
|
void signal;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
if (
|
|
48
|
-
return
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const
|
|
52
|
-
const
|
|
48
|
+
// 投影:canonical 不可变,模型看到的永远是 [摘要?, slice(anchor)]
|
|
49
|
+
const projected = summary === null ? messages : [summaryMessage(summary), ...messages.slice(anchor)];
|
|
50
|
+
const projectedTokens = estimateTokens(projected);
|
|
51
|
+
if (!options.force && projectedTokens + reserve < options.contextWindow)
|
|
52
|
+
return projected;
|
|
53
|
+
// 滞回带:已有摘要但尾部自上次压缩后没长够摘要的一半——再压不划算
|
|
54
|
+
const tailTokens = estimateTokens(messages.slice(anchor));
|
|
55
|
+
const summaryTokens = summary === null ? 0 : estimateTokens([summaryMessage(summary)]);
|
|
56
|
+
const grownEnough = summary === null || tailTokens >= tailTokensAtCompaction + Math.ceil(summaryTokens / 2);
|
|
57
|
+
if (!options.force && (hasFailed || !grownEnough))
|
|
58
|
+
return projected;
|
|
59
|
+
if (messages.length - anchor <= keepRecent + 1)
|
|
60
|
+
return projected; // nothing new worth folding
|
|
61
|
+
const tailCount = Math.min(keepRecent, messages.length - anchor);
|
|
62
|
+
const fold = messages.slice(anchor, messages.length - tailCount);
|
|
63
|
+
const foldTokens = estimateTokens(fold);
|
|
64
|
+
// 增量摘要:旧摘要作为上下文带入,只对新折叠段续写
|
|
65
|
+
const priorSection = summary === null ? "" : `【已有摘要】\n${summary}\n\n`;
|
|
53
66
|
const summaryInput = [
|
|
54
|
-
...
|
|
55
|
-
{ role: "user", content: SUMMARY_INSTRUCTION
|
|
67
|
+
...fold,
|
|
68
|
+
{ role: "user", content: `${priorSection}${SUMMARY_INSTRUCTION}`, timestamp: Date.now() },
|
|
56
69
|
];
|
|
57
|
-
const
|
|
58
|
-
if (!
|
|
70
|
+
const next = await options.streamSummary(summaryInput).catch(() => "");
|
|
71
|
+
if (!next) {
|
|
59
72
|
hasFailed = true;
|
|
60
73
|
await options.onCompactionFailed?.("summary-empty");
|
|
61
|
-
return
|
|
74
|
+
return projected; // compaction failed — degrade to the current projection
|
|
62
75
|
}
|
|
63
|
-
//
|
|
64
|
-
const
|
|
65
|
-
if (
|
|
76
|
+
// 膨胀拒绝:新摘要比它替代的内容(新折叠段 + 旧摘要)还长,压了不如不压
|
|
77
|
+
const nextTokens = estimateTokens([summaryMessage(next)]);
|
|
78
|
+
if (nextTokens >= foldTokens + summaryTokens) {
|
|
66
79
|
hasFailed = true;
|
|
67
80
|
await options.onCompactionFailed?.("summary-inflated");
|
|
68
|
-
return
|
|
81
|
+
return projected;
|
|
69
82
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
};
|
|
76
|
-
return [compactionMessage, ...tail];
|
|
83
|
+
summary = next;
|
|
84
|
+
anchor = messages.length - tailCount;
|
|
85
|
+
tailTokensAtCompaction = estimateTokens(messages.slice(anchor));
|
|
86
|
+
options.onCompacted?.(summary, projectedTokens);
|
|
87
|
+
return [summaryMessage(summary), ...messages.slice(anchor)];
|
|
77
88
|
};
|
|
78
89
|
}
|
|
79
90
|
/** One-shot completion via an AssistantMessageEventStream (relay streamFn
|
|
@@ -103,6 +114,7 @@ export function buildCompactionTransform(input) {
|
|
|
103
114
|
contextWindow: input.contextWindow,
|
|
104
115
|
streamSummary: (messages) => input.streamOne(input.summaryModel, messages),
|
|
105
116
|
...(input.onCompacted ? { onCompacted: input.onCompacted } : {}),
|
|
117
|
+
...(input.force ? { force: true } : {}),
|
|
106
118
|
});
|
|
107
119
|
}
|
|
108
120
|
//# sourceMappingURL=compaction.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compaction.js","sourceRoot":"","sources":["../../../src/core/runtime/compaction.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"compaction.js","sourceRoot":"","sources":["../../../src/core/runtime/compaction.ts"],"names":[],"mappings":"AA4CA;gDACgD;AAChD,SAAS,cAAc,CAAC,QAAwB;IAC9C,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAI,OAAiC,CAAC,OAAO,CAAC;QAC3D,IAAI,OAAO,OAAO,KAAK,QAAQ;YAAE,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;aACnE,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YAChC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,OAAQ,KAA4B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAC1G,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,CAAE,KAA0B,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBACpE,CAAC;YACH,CAAC;QACH,CAAC;QACD,IAAI,OAAO,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YAClC,MAAM,MAAM,GAAI,OAAiC,CAAC,OAAO,CAAC;YAC1D,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC1B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;oBAC3B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,OAAQ,KAA4B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;wBAC1G,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,CAAE,KAA0B,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;oBACpE,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,mBAAmB,GACvB,iFAAiF,CAAC;AAEpF;;oEAEoE;AACpE,SAAS,cAAc,CAAC,IAAY;IAClC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,EAAkB,CAAC;AACtF,CAAC;AAED;;8CAE8C;AAC9C,MAAM,UAAU,yBAAyB,CAAC,OAA0B;IAClE,MAAM,OAAO,GAAG,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC;IAC9C,MAAM,UAAU,GAAG,OAAO,CAAC,kBAAkB,IAAI,CAAC,CAAC;IACnD,IAAI,OAAO,GAAkB,IAAI,CAAC,CAAC,eAAe;IAClD,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,wBAAwB;IACxC,IAAI,sBAAsB,GAAG,CAAC,CAAC,CAAC,4BAA4B;IAC5D,IAAI,SAAS,GAAG,KAAK,CAAC,CAAC,gBAAgB;IAEvC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE;QAChC,KAAK,MAAM,CAAC;QACZ,iDAAiD;QACjD,MAAM,SAAS,GAAG,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QACrG,MAAM,eAAe,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;QAClD,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,eAAe,GAAG,OAAO,GAAG,OAAO,CAAC,aAAa;YAAE,OAAO,SAAS,CAAC;QAE1F,mCAAmC;QACnC,MAAM,UAAU,GAAG,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QAC1D,MAAM,aAAa,GAAG,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACvF,MAAM,WAAW,GAAG,OAAO,KAAK,IAAI,IAAI,UAAU,IAAI,sBAAsB,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC;QAC5G,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC,SAAS,IAAI,CAAC,WAAW,CAAC;YAAE,OAAO,SAAS,CAAC;QACpE,IAAI,QAAQ,CAAC,MAAM,GAAG,MAAM,IAAI,UAAU,GAAG,CAAC;YAAE,OAAO,SAAS,CAAC,CAAC,4BAA4B;QAE9F,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;QACjE,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;QACjE,MAAM,UAAU,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;QAExC,2BAA2B;QAC3B,MAAM,YAAY,GAAG,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,OAAO,MAAM,CAAC;QACtE,MAAM,YAAY,GAAmB;YACnC,GAAG,IAAI;YACP,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,YAAY,GAAG,mBAAmB,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAkB;SAC1G,CAAC;QACF,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QACvE,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,SAAS,GAAG,IAAI,CAAC;YACjB,MAAM,OAAO,CAAC,kBAAkB,EAAE,CAAC,eAAe,CAAC,CAAC;YACpD,OAAO,SAAS,CAAC,CAAC,wDAAwD;QAC5E,CAAC;QACD,uCAAuC;QACvC,MAAM,UAAU,GAAG,cAAc,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC1D,IAAI,UAAU,IAAI,UAAU,GAAG,aAAa,EAAE,CAAC;YAC7C,SAAS,GAAG,IAAI,CAAC;YACjB,MAAM,OAAO,CAAC,kBAAkB,EAAE,CAAC,kBAAkB,CAAC,CAAC;YACvD,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,OAAO,GAAG,IAAI,CAAC;QACf,MAAM,GAAG,QAAQ,CAAC,MAAM,GAAG,SAAS,CAAC;QACrC,sBAAsB,GAAG,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QAChE,OAAO,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;QAChD,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9D,CAAC,CAAC;AACJ,CAAC;AAED;;kEAEkE;AAClE,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,QAAkM,EAClM,KAAiB,EACjB,YAAoB,EACpB,QAAwB;IAExB,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,CAAC;IACjE,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC;IACpC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAC9B,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC;IAChD,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,OAAO,OAAO;aACX,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAK,KAA4B,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAE,KAA4B,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;aACtK,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;6EAC6E;AAC7E,MAAM,UAAU,wBAAwB,CAAC,KAOxC;IACC,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY;QAAE,OAAO,SAAS,CAAC;IAC5D,OAAO,yBAAyB,CAAC;QAC/B,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,aAAa,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,YAAa,EAAE,QAAQ,CAAC;QAC3E,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACxC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/** 生命周期钩子(P0):宿主/插件在不侵入 runner 的前提下观察并约束运行。
|
|
2
|
+
* 参考 codex hooks/ 与 gemini hooks/ 的最小面——四个挂点:
|
|
3
|
+
*
|
|
4
|
+
* - onRunStart 一次 run 开始(收到 prompt,尚未调模型)
|
|
5
|
+
* - onBeforeToolCall 权限审批通过后、工具执行前;可 {block:true,reason}
|
|
6
|
+
* 拦截(reason 会作为结果反馈给模型)
|
|
7
|
+
* - onAfterToolCall 工具执行结束(含 isError);只读,不可改结果
|
|
8
|
+
* - onRunEnd run 终态(ok/aborted)
|
|
9
|
+
*
|
|
10
|
+
* 约定:钩子抛错只告警不中断运行;block 是唯一有副作用的出口。多个 hook
|
|
11
|
+
* 依次调用,第一个返回 block 的生效。 */
|
|
12
|
+
import type { RunTranscriptMessage } from "./run-transcript.js";
|
|
13
|
+
export type LifecycleHook = {
|
|
14
|
+
/** 诊断名(日志用) */
|
|
15
|
+
name?: string;
|
|
16
|
+
onRunStart?(input: {
|
|
17
|
+
sessionId: string;
|
|
18
|
+
agent: string;
|
|
19
|
+
text: string;
|
|
20
|
+
}): void | Promise<void>;
|
|
21
|
+
onBeforeToolCall?(input: {
|
|
22
|
+
sessionId: string;
|
|
23
|
+
agent: string;
|
|
24
|
+
tool: string;
|
|
25
|
+
args: unknown;
|
|
26
|
+
}): {
|
|
27
|
+
block: true;
|
|
28
|
+
reason: string;
|
|
29
|
+
} | undefined | void | Promise<{
|
|
30
|
+
block: true;
|
|
31
|
+
reason: string;
|
|
32
|
+
} | undefined | void>;
|
|
33
|
+
onAfterToolCall?(input: {
|
|
34
|
+
sessionId: string;
|
|
35
|
+
agent: string;
|
|
36
|
+
tool: string;
|
|
37
|
+
isError: boolean;
|
|
38
|
+
title?: string;
|
|
39
|
+
}): void | Promise<void>;
|
|
40
|
+
onRunEnd?(input: {
|
|
41
|
+
sessionId: string;
|
|
42
|
+
agent: string;
|
|
43
|
+
ok: boolean;
|
|
44
|
+
aborted: boolean;
|
|
45
|
+
workspaceId?: string;
|
|
46
|
+
newMessages?: RunTranscriptMessage[];
|
|
47
|
+
}): void | Promise<void>;
|
|
48
|
+
};
|
|
49
|
+
export declare function fireRunStart(hooks: LifecycleHook[], input: {
|
|
50
|
+
sessionId: string;
|
|
51
|
+
agent: string;
|
|
52
|
+
text: string;
|
|
53
|
+
}): Promise<void>[];
|
|
54
|
+
/** 返回第一个生效的 block;钩子抛错视同放行。 */
|
|
55
|
+
export declare function firstToolBlock(hooks: LifecycleHook[], input: {
|
|
56
|
+
sessionId: string;
|
|
57
|
+
agent: string;
|
|
58
|
+
tool: string;
|
|
59
|
+
args: unknown;
|
|
60
|
+
}): Promise<{
|
|
61
|
+
block: true;
|
|
62
|
+
reason: string;
|
|
63
|
+
} | undefined>;
|
|
64
|
+
export declare function fireAfterToolCall(hooks: LifecycleHook[], input: {
|
|
65
|
+
sessionId: string;
|
|
66
|
+
agent: string;
|
|
67
|
+
tool: string;
|
|
68
|
+
isError: boolean;
|
|
69
|
+
title?: string;
|
|
70
|
+
}): Promise<void>[];
|
|
71
|
+
export declare function fireRunEnd(hooks: LifecycleHook[], input: {
|
|
72
|
+
sessionId: string;
|
|
73
|
+
agent: string;
|
|
74
|
+
ok: boolean;
|
|
75
|
+
aborted: boolean;
|
|
76
|
+
workspaceId?: string;
|
|
77
|
+
newMessages?: RunTranscriptMessage[];
|
|
78
|
+
}): Promise<void>[];
|
|
79
|
+
//# sourceMappingURL=lifecycle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../../src/core/runtime/lifecycle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/** 生命周期钩子(P0):宿主/插件在不侵入 runner 的前提下观察并约束运行。
|
|
2
|
+
* 参考 codex hooks/ 与 gemini hooks/ 的最小面——四个挂点:
|
|
3
|
+
*
|
|
4
|
+
* - onRunStart 一次 run 开始(收到 prompt,尚未调模型)
|
|
5
|
+
* - onBeforeToolCall 权限审批通过后、工具执行前;可 {block:true,reason}
|
|
6
|
+
* 拦截(reason 会作为结果反馈给模型)
|
|
7
|
+
* - onAfterToolCall 工具执行结束(含 isError);只读,不可改结果
|
|
8
|
+
* - onRunEnd run 终态(ok/aborted)
|
|
9
|
+
*
|
|
10
|
+
* 约定:钩子抛错只告警不中断运行;block 是唯一有副作用的出口。多个 hook
|
|
11
|
+
* 依次调用,第一个返回 block 的生效。 */
|
|
12
|
+
function warn(hook, phase, error) {
|
|
13
|
+
console.warn(`[zmzai-agent-framework] lifecycle hook ${hook.name ?? "anonymous"}#${phase} 抛错已忽略:`, error);
|
|
14
|
+
}
|
|
15
|
+
export function fireRunStart(hooks, input) {
|
|
16
|
+
return hooks.map((hook) => {
|
|
17
|
+
if (!hook.onRunStart)
|
|
18
|
+
return Promise.resolve();
|
|
19
|
+
try {
|
|
20
|
+
return Promise.resolve(hook.onRunStart(input)).catch((error) => warn(hook, "onRunStart", error));
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
warn(hook, "onRunStart", error);
|
|
24
|
+
return Promise.resolve();
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
/** 返回第一个生效的 block;钩子抛错视同放行。 */
|
|
29
|
+
export async function firstToolBlock(hooks, input) {
|
|
30
|
+
for (const hook of hooks) {
|
|
31
|
+
if (!hook.onBeforeToolCall)
|
|
32
|
+
continue;
|
|
33
|
+
try {
|
|
34
|
+
const result = await hook.onBeforeToolCall(input);
|
|
35
|
+
if (result && "block" in result && result.block === true) {
|
|
36
|
+
return { block: true, reason: result.reason };
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
warn(hook, "onBeforeToolCall", error);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
export function fireAfterToolCall(hooks, input) {
|
|
46
|
+
return hooks.map((hook) => {
|
|
47
|
+
if (!hook.onAfterToolCall)
|
|
48
|
+
return Promise.resolve();
|
|
49
|
+
try {
|
|
50
|
+
return Promise.resolve(hook.onAfterToolCall(input)).catch((error) => warn(hook, "onAfterToolCall", error));
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
warn(hook, "onAfterToolCall", error);
|
|
54
|
+
return Promise.resolve();
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
export function fireRunEnd(hooks, input) {
|
|
59
|
+
return hooks.map((hook) => {
|
|
60
|
+
if (!hook.onRunEnd)
|
|
61
|
+
return Promise.resolve();
|
|
62
|
+
try {
|
|
63
|
+
return Promise.resolve(hook.onRunEnd(input)).catch((error) => warn(hook, "onRunEnd", error));
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
warn(hook, "onRunEnd", error);
|
|
67
|
+
return Promise.resolve();
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../../src/core/runtime/lifecycle.ts"],"names":[],"mappings":"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"}
|
|
@@ -40,7 +40,10 @@ export declare class PartProjector {
|
|
|
40
40
|
private flushText;
|
|
41
41
|
private flushAllText;
|
|
42
42
|
private assistantPart;
|
|
43
|
-
onUserPrompt(emit: Emit, text: string
|
|
43
|
+
onUserPrompt(emit: Emit, text: string, images?: readonly {
|
|
44
|
+
url: string;
|
|
45
|
+
mediaType: string;
|
|
46
|
+
}[]): MessageInfo;
|
|
44
47
|
onAssistantStart(emit: Emit): void;
|
|
45
48
|
onTextDelta(emit: Emit, contentIndex: number, delta: string): void;
|
|
46
49
|
onThinkingDelta(emit: Emit, contentIndex: number, delta: string): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pi-bridge.d.ts","sourceRoot":"","sources":["../../../src/core/runtime/pi-bridge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAElE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAmB,MAAM,qBAAqB,CAAC;AAElF;;yEAEyE;AAEzE,MAAM,MAAM,cAAc,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAA;CAAE,CAAC;AAEnF,KAAK,IAAI,GAAG,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;AAY5C;;oEAEoE;AACpE,wBAAgB,aAAa,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAQ1H;AAED,qBAAa,aAAa;IAoBZ,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAnBrC,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,kBAAkB,CAAuB;IACjD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA2B;IACjD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgC;IAC9D,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAgC;IACnE,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA6B;IAC9D,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,WAAW,CAAK;IACxB;;8EAE0E;IAC1E,OAAO,CAAC,mBAAmB,CAAuB;IAElD;mCAC+B;IAC/B,IAAI,yBAAyB,IAAI,MAAM,GAAG,IAAI,CAE7C;gBAE4B,QAAQ,EAAE,cAAc;IAErD,OAAO,CAAC,QAAQ;IAKhB,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,SAAS;IAQjB,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,aAAa;IAarB,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW;
|
|
1
|
+
{"version":3,"file":"pi-bridge.d.ts","sourceRoot":"","sources":["../../../src/core/runtime/pi-bridge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAElE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAmB,MAAM,qBAAqB,CAAC;AAElF;;yEAEyE;AAEzE,MAAM,MAAM,cAAc,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAA;CAAE,CAAC;AAEnF,KAAK,IAAI,GAAG,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;AAY5C;;oEAEoE;AACpE,wBAAgB,aAAa,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAQ1H;AAED,qBAAa,aAAa;IAoBZ,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAnBrC,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,kBAAkB,CAAuB;IACjD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA2B;IACjD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgC;IAC9D,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAgC;IACnE,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA6B;IAC9D,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,WAAW,CAAK;IACxB;;8EAE0E;IAC1E,OAAO,CAAC,mBAAmB,CAAuB;IAElD;mCAC+B;IAC/B,IAAI,yBAAyB,IAAI,MAAM,GAAG,IAAI,CAE7C;gBAE4B,QAAQ,EAAE,cAAc;IAErD,OAAO,CAAC,QAAQ;IAKhB,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,SAAS;IAQjB,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,aAAa;IAarB,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,EAAE,GAAG,WAAW;IAwC3G,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAqBlC,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAWlE,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAWtE,oBAAoB,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IAe3G,qBAAqB,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;IAU7E,kBAAkB,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;IAuB3F,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI;CA6BxD"}
|