@migor/agentia 0.10.3 → 0.10.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +572 -30
- package/LICENSE +1 -1
- package/README.en.md +93 -38
- package/README.md +105 -218
- package/dist/AGENTS.md +227 -30
- package/dist/core/limits.d.ts +8 -0
- package/dist/core/limits.js +9 -0
- package/dist/core/limits.js.map +1 -1
- package/dist/core/tool.d.ts +18 -0
- package/dist/core/trace-sink.d.ts +8 -0
- package/dist/core/trace-sink.js +24 -0
- package/dist/core/trace-sink.js.map +1 -0
- package/dist/core/trace.d.ts +4 -1
- package/dist/core/trace.js +14 -0
- package/dist/core/trace.js.map +1 -1
- package/dist/engine/forwarded.d.ts +3 -1
- package/dist/engine/forwarded.js +5 -0
- package/dist/engine/forwarded.js.map +1 -1
- package/dist/engine/loop-result.d.ts +1 -1
- package/dist/engine/loop.d.ts +5 -1
- package/dist/engine/loop.js +16 -1
- package/dist/engine/loop.js.map +1 -1
- package/dist/engine/mcp-server.d.ts +2 -2
- package/dist/engine/mcp-server.js +3 -9
- package/dist/engine/mcp-server.js.map +1 -1
- package/dist/engine/run-config.js +3 -0
- package/dist/engine/run-config.js.map +1 -1
- package/dist/engine/spec.d.ts +5 -1
- package/dist/engine/spec.js.map +1 -1
- package/dist/engine/tool-context.d.ts +3 -1
- package/dist/engine/tool-context.js +3 -1
- package/dist/engine/tool-context.js.map +1 -1
- package/dist/engine/tool-events.d.ts +6 -2
- package/dist/engine/tool-events.js +17 -3
- package/dist/engine/tool-events.js.map +1 -1
- package/dist/engine/turn.d.ts +5 -1
- package/dist/engine/turn.js +9 -4
- package/dist/engine/turn.js.map +1 -1
- package/dist/engine/types.d.ts +14 -3
- package/dist/engine/types.js +1 -0
- package/dist/engine/types.js.map +1 -1
- package/dist/eval/harvest.d.ts +4 -1
- package/dist/eval/harvest.js +32 -6
- package/dist/eval/harvest.js.map +1 -1
- package/dist/index.d.ts +13 -3
- package/dist/index.js +10 -1
- package/dist/index.js.map +1 -1
- package/dist/integrations/file-sink.d.ts +0 -16
- package/dist/integrations/file-sink.js +22 -4
- package/dist/integrations/file-sink.js.map +1 -1
- package/dist/integrations/mcp-stdio.js +63 -42
- package/dist/integrations/mcp-stdio.js.map +1 -1
- package/dist/integrations/metrics-render.js +16 -5
- package/dist/integrations/metrics-render.js.map +1 -1
- package/dist/runtime/run.d.ts +1 -1
- package/dist/runtime/run.js +19 -17
- package/dist/runtime/run.js.map +1 -1
- package/dist/store/store.d.ts +6 -1
- package/dist/store/store.js +9 -2
- package/dist/store/store.js.map +1 -1
- package/dist/toolkit/capability-loop.d.ts +92 -0
- package/dist/toolkit/capability-loop.js +81 -0
- package/dist/toolkit/capability-loop.js.map +1 -0
- package/dist/toolkit/discover.js +27 -1
- package/dist/toolkit/discover.js.map +1 -1
- package/dist/toolkit/manifest.d.ts +21 -0
- package/dist/toolkit/manifest.js +38 -0
- package/dist/toolkit/manifest.js.map +1 -0
- package/dist/toolkit/module.d.ts +5 -0
- package/dist/toolkit/module.js +113 -49
- package/dist/toolkit/module.js.map +1 -1
- package/dist/toolkit/prompt.d.ts +3 -1
- package/dist/toolkit/prompt.js +10 -0
- package/dist/toolkit/prompt.js.map +1 -1
- package/dist/toolkit/skill.d.ts +3 -1
- package/dist/toolkit/skill.js +2 -0
- package/dist/toolkit/skill.js.map +1 -1
- package/dist/toolkit/subagent.d.ts +4 -2
- package/dist/toolkit/subagent.js +2 -0
- package/dist/toolkit/subagent.js.map +1 -1
- package/dist/toolkit/tool.d.ts +3 -1
- package/dist/toolkit/tool.js +2 -0
- package/dist/toolkit/tool.js.map +1 -1
- package/dist/transport/async.d.ts +2 -4
- package/dist/transport/async.js +14 -7
- package/dist/transport/async.js.map +1 -1
- package/dist/transport/http-endpoints.d.ts +13 -0
- package/dist/transport/http-endpoints.js +101 -28
- package/dist/transport/http-endpoints.js.map +1 -1
- package/dist/transport/http-shapes.d.ts +26 -3
- package/dist/transport/http-shapes.js +12 -2
- package/dist/transport/http-shapes.js.map +1 -1
- package/dist/transport/http.d.ts +46 -2
- package/dist/transport/http.js +43 -18
- package/dist/transport/http.js.map +1 -1
- package/dist/transport/run-call-options.js +3 -0
- package/dist/transport/run-call-options.js.map +1 -1
- package/dist/transport/run-options.d.ts +98 -0
- package/dist/transport/run-options.js +121 -0
- package/dist/transport/run-options.js.map +1 -0
- package/dist/transport/run-outcome.js +3 -0
- package/dist/transport/run-outcome.js.map +1 -1
- package/dist/transport/serve.d.ts +92 -0
- package/dist/transport/serve.js +155 -0
- package/dist/transport/serve.js.map +1 -0
- package/package.json +23 -10
package/dist/AGENTS.md
CHANGED
|
@@ -41,10 +41,41 @@
|
|
|
41
41
|
|
|
42
42
|
## 1. 最小可运行示例
|
|
43
43
|
|
|
44
|
+
### 1.1 先跑一个裸工具(不需要装饰器 / DI)
|
|
45
|
+
|
|
44
46
|
```ts
|
|
45
|
-
import {
|
|
47
|
+
import { createApp } from '@migor/agentia';
|
|
48
|
+
|
|
49
|
+
const app = createApp({
|
|
50
|
+
system: '你是友好的助手。',
|
|
51
|
+
tools: [
|
|
52
|
+
{
|
|
53
|
+
name: 'say_hello',
|
|
54
|
+
description: '向某人打招呼',
|
|
55
|
+
inputSchema: {
|
|
56
|
+
type: 'object',
|
|
57
|
+
properties: { name: { type: 'string' } },
|
|
58
|
+
required: ['name'],
|
|
59
|
+
},
|
|
60
|
+
run: (input) => `你好,${(input as { name: string }).name}`,
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
});
|
|
46
64
|
|
|
47
|
-
const
|
|
65
|
+
const { result } = await app.run([{ role: 'user', content: '跟小明打个招呼' }]);
|
|
66
|
+
if (result.error) throw new Error(`${result.stopReason}: ${result.error.message}`);
|
|
67
|
+
console.log(result.finalText, result.trace.totalUsage);
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
这是最短路径:`tools + createApp + app.run`。`inputSchema` 约束模型入参,`run` 是实际函数;
|
|
71
|
+
`result.error` 必须检查,不能只打印 `finalText`。`trace` 从第一次 run 就在,不需要先配观测后端。
|
|
72
|
+
|
|
73
|
+
也可以直接 `npx @migor/cli create my-app --minimal` 生成同形态的单文件工程(见下一节)。
|
|
74
|
+
|
|
75
|
+
### 1.2 能力变多后再用装饰器组织
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
import { Tool, createApp, SystemPrompt } from '@migor/agentia';
|
|
48
79
|
|
|
49
80
|
class Greeter {
|
|
50
81
|
@Tool({
|
|
@@ -80,21 +111,31 @@ console.log(result.finalText, result.stopReason, result.trace.totalUsage);
|
|
|
80
111
|
## 2. 项目结构(CLI 约定)
|
|
81
112
|
|
|
82
113
|
```bash
|
|
83
|
-
|
|
114
|
+
# 只想先跑一个 agent:单文件 + 裸工具,无装饰器 / registry / HTTP 宿主
|
|
115
|
+
npx @migor/cli create my-app --minimal
|
|
84
116
|
cd my-app && npm install # 框架与 CLI 都装进工程
|
|
85
117
|
$EDITOR .env # 填 ANTHROPIC_API_KEY(脚手架已生成,且已被 .gitignore 挡住)
|
|
118
|
+
npm run dev -- "你的问题" # = tsx src/main.ts,跑一次并退出
|
|
119
|
+
|
|
120
|
+
# 需要 inspector、能力目录与生产服务时:不带 --minimal 的默认完整模板
|
|
121
|
+
npx @migor/cli create my-service
|
|
122
|
+
cd my-service && npm install
|
|
86
123
|
npm run dev # = agentia dev:本地 inspector 面板(输入 prompt / 选能力 / 选工作目录)
|
|
87
|
-
npx agentia g tool fetch-weather
|
|
124
|
+
npx agentia g tool fetch-weather # 生成到 src/tools/fetch-weather/(skill/prompt/subagent 同理)
|
|
88
125
|
npx agentia doctor # 静态体检(未登记/悬空/命名/重复)
|
|
126
|
+
npx agentia manifest # 真实装配 → 能力契约 JSON(不调用模型)
|
|
89
127
|
npx agentia --version # CLI 版本(= -v)
|
|
90
128
|
```
|
|
91
129
|
|
|
130
|
+
**两种模板只是起点不同**:minimal 用于先跑通模型与工具,完整模板用于继续组织能力和交付服务;
|
|
131
|
+
默认仍是不带 `--minimal` 的完整服务模板,既有项目与脚本不变。
|
|
132
|
+
|
|
92
133
|
> **命令从哪来**:脚手架把 `@migor/cli` 装进工程的 `devDependencies`,所以**工程内**用短名
|
|
93
134
|
> `npx agentia …` 即可(走本地 bin:离线可用、版本与工程一同 pin)。**首次创建**必须用带 scope 的
|
|
94
135
|
> `npx @migor/cli create` —— npm 上另有一个别人的 `agentia` 包,短名会装错东西。
|
|
95
136
|
> 想全局装上(到处都能敲 `agentia`):`npm i -g @migor/cli`。
|
|
96
137
|
|
|
97
|
-
四分类目录,一能力一文件夹:`src/tools/` · `src/skills/` · `src/prompts/` · `src/subagents/` —— **目录名就是类型**,不用记别名。每个文件夹的 `index.ts` 是入口,`default export` 支持三种形态:**类**(token = 文件夹名)、**Provider 对象**、**Provider
|
|
138
|
+
四分类目录,一能力一文件夹:`src/tools/` · `src/skills/` · `src/prompts/` · `src/subagents/` —— **目录名就是类型**,不用记别名。每个文件夹的 `index.ts` 是入口,`default export` 支持三种形态:**类**(token = 文件夹名)、**Provider 对象**、**Provider 数组**。类形态要注入依赖时,在类上写 `static readonly deps = ['WORKDIR']` —— `discover` 会把它带上(**不必**把该能力挪到显式 `providers` 再注册一遍,那样同一 token 会有两份、靠「后注册覆盖先注册」碰巧成立);`deps` 写成非字符串数组会**响亮报错**,不当成「没有依赖」。显式注册表在 `src/registry.ts`(`agentia g` 自动维护,也可手改)。
|
|
98
139
|
|
|
99
140
|
### 2.1 脚手架生成的文件(**装配与启动是分开的**)
|
|
100
141
|
|
|
@@ -206,15 +247,40 @@ token 的作用是挡住**本机其它进程**,别把它当网络边界:这
|
|
|
206
247
|
|
|
207
248
|
```bash
|
|
208
249
|
agentia report .agentia/traces.jsonl # 哪个能力慢 / 贵 / 爱失败
|
|
250
|
+
agentia view .agentia/traces.jsonl --open # 把落盘的 trace 画成一棵树(单文件 HTML,见下)
|
|
209
251
|
agentia diff .agentia/traces.jsonl ... # 改 prompt 前后逐 span 比对(有差异时退出码 1)
|
|
210
252
|
agentia harvest .agentia/traces.jsonl --failed # 失败的 run → eval 用例骨架
|
|
211
253
|
agentia export .agentia/traces.jsonl # → 训练数据集 JSONL
|
|
212
254
|
```
|
|
213
255
|
|
|
256
|
+
**`agentia view` —— 事后看一棵树**(面板只管「在飞」的,这个管「盘上」的):
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
agentia view .agentia/traces.jsonl --open # 渲完直接用默认浏览器打开
|
|
260
|
+
agentia view .agentia/traces.jsonl -o r.html # 指定产物名(缺省 = 输入名去扩展名 .html)
|
|
261
|
+
agentia view .agentia/traces.jsonl --trace-id <id> # 只看一条
|
|
262
|
+
agentia view .agentia/traces.jsonl --limit 20 # 默认最近 50 条(超了会明说,不静默截断)
|
|
263
|
+
agentia view .agentia/traces.jsonl --limit 20 --head # 从头看(排查「第一次出现的问题」时用)
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
⚠️ **`--limit` 缺省取「最近」N 条,不是前 N 条**:`.agentia/traces.jsonl` 只增不减,最新的一次
|
|
267
|
+
run 在**文件末尾** —— 取最早那种写法在长跑 dev 环里等于「想复盘刚才那次,给你今早第一批」。
|
|
268
|
+
同一节奏:产物缺省写在输入旁边,但输入在**点目录**里(`.agentia/`)时**上跳到最近的可见目录**,
|
|
269
|
+
不把 HTML 藏进隐藏目录;产物路径等于输入文件本身会直接报错(否则把 trace 数据覆盖成 HTML);
|
|
270
|
+
覆盖同名文件会在 stdout 明说(HTML 是派生物,重跑是常态,所以不像 `harvest` 那样要 `--force`)。
|
|
271
|
+
|
|
272
|
+
产物是**单文件自包含 HTML**:CSS 与渲染器**全部内联**,零外链、离线可开、可以直接贴进 PR 或
|
|
273
|
+
发给同事(业界同类工具在 2026 已收敛到这个形态)。⚠️ 三件事要知道:
|
|
274
|
+
① **默认脱敏**(`--raw` 关闭,且此时 stderr 会警告)—— 产物的默认命运是「被转发」,而 trace
|
|
275
|
+
含完整 prompt 与工具出入参;② 脱敏是 **best-effort**,覆盖 6 类值内凭证形态
|
|
276
|
+
(bearer / jwt / aws-access-key / llm-api-key / email / phone-cn),**`password=` 这类不在内**,
|
|
277
|
+
业务自有字段用 `--redact-key <字段名>`(按字段名整字段抹平,与前者是两种机制);
|
|
278
|
+
③ 多条 trace 时顶部下拉切换,`#N` 锚点可直达。
|
|
279
|
+
|
|
214
280
|
落盘**不替代**右栏的实时树:那是两条缝(落盘管「事后能查」,`onTraceEvent` 管「此刻看到」)。
|
|
215
281
|
三条如实标注:① 文件**只增不减**(要清是你自己 `rm`);② 落盘是**同步写**,单条 trace 以百 KB
|
|
216
282
|
计、且 `traceLimits.maxEvents` 本来兜上限;③ 面板的 run 列表是**内存** ring(50 条),
|
|
217
|
-
重启就空了 ——
|
|
283
|
+
重启就空了 —— 落盘让数据**没丢**,但面板不会替你回看历史,**回看历史走 `agentia view`**。
|
|
218
284
|
|
|
219
285
|
**并排 A/B(比两条 run差在哪)**:run 列表里 **⌘/Ctrl + 单击**选两条(再点一次取消、
|
|
220
286
|
选第三条挤掉最早那条),右栏切**双栏**并排两棵调用树,顶部一条差异摘要
|
|
@@ -261,6 +327,7 @@ agentia export .agentia/traces.jsonl # → 训练数据集 JSONL
|
|
|
261
327
|
| `name` | 模型可见的工具名,缺省取方法名(建议 snake_case) |
|
|
262
328
|
| `strict` | 透传给 Anthropic 的 strict 模式(**框架不校验 schema 合规性**) |
|
|
263
329
|
| `approval` | `'required'` = 每次调用先挂起等人工审批(HITL,见 §6.6「人工审批」) |
|
|
330
|
+
| `metadata` | 可选 `{ owner?, version?, risk?: 'read'\|'write'\|'external', sideEffect?: 'none'\|'idempotent'\|'non-idempotent' }`;进能力 manifest,供 owner 分工与变更审查 |
|
|
264
331
|
|
|
265
332
|
### `@Skill(spec: SkillSpec)`
|
|
266
333
|
|
|
@@ -273,6 +340,7 @@ agentia export .agentia/traces.jsonl # → 训练数据集 JSONL
|
|
|
273
340
|
| `maxTokens` | 同上 |
|
|
274
341
|
| `maxIterations` | 同上 |
|
|
275
342
|
| `tools` | `ctx.llm()` 可调工具:**provider token 列表**(复用该 provider 的能力菜单),或 `'<token>/<能力名>'` 能力级路径(只引菜单里的单个能力) |
|
|
343
|
+
| `metadata` | 同 `@Tool`:owner / 版本 / 风险 / 副作用幂等性,进能力 manifest |
|
|
276
344
|
|
|
277
345
|
技能方法体拿到的第二参是 `SkillContext`:`ctx.llm({ prompt })` 才会真正调模型(脚本式,调几次由你写死)。
|
|
278
346
|
|
|
@@ -289,6 +357,7 @@ agentia export .agentia/traces.jsonl # → 训练数据集 JSONL
|
|
|
289
357
|
| `maxTokens` | 同上 |
|
|
290
358
|
| `maxIterations` | 同上 |
|
|
291
359
|
| `resultSchema` | 给出后子 agent 用隐藏 `submit_result` 提交结构化结果 |
|
|
360
|
+
| `metadata` | 同 `@Tool`:owner / 版本 / 风险 / 副作用幂等性,进能力 manifest |
|
|
292
361
|
|
|
293
362
|
子 agent 是**独立循环 + 裁剪上下文**:主 agent 的历史它看不到,只有最终文本(或 `{ report, result }`)以 tool_result 回流。
|
|
294
363
|
|
|
@@ -300,6 +369,7 @@ agentia export .agentia/traces.jsonl # → 训练数据集 JSONL
|
|
|
300
369
|
| `name` | 缺省取方法名 |
|
|
301
370
|
| `schema` | 模板化入参 schema;缺省空对象(无参资产) |
|
|
302
371
|
| `version` | 资产版本号(git hash / `'v3'` 等);装配期随能力名收集,每次 run 落 run 根 span 的 `prompts.versions` attribute —— 见 §6「提示词版本化」。缺省(无版本)则该能力不进表 |
|
|
372
|
+
| `metadata` | 同 `@Tool`;`metadata.version` 缺省回落 `version`,两项都给时以 metadata 为准 |
|
|
303
373
|
|
|
304
374
|
`@Prompt` **只支持方法形态**(标准装饰器下字段拿不到值/类引用)。实例方法与静态方法都**沿继承链**收集(父类的 `@Prompt` 资产子类自动带上)。方法体内用 `asset(import.meta.url, './x.md')` 读同目录长文本。
|
|
305
375
|
|
|
@@ -336,6 +406,7 @@ agentia export .agentia/traces.jsonl # → 训练数据集 JSONL
|
|
|
336
406
|
| `toolTimeoutMs` | 缺省单工具超时(毫秒);超时该条 tool_result 记 is_error,不杀 run |
|
|
337
407
|
| `maxToolConcurrency` | 缺省同回合并行工具上限;不设 = 不限(全并行) |
|
|
338
408
|
| `maxEventChars` | 缺省 trace 事件正文截断上限(可被单次 run 覆盖):数字 = 入参/出参统一用该上限,`false` = **不截断**(完整正文进 trace,面板里能展开看全文);不设 = 框架缺省 |
|
|
409
|
+
| `maxToolResultChars` | 缺省单条工具结果**回模型**的字符上限:非负安全整数;`false` / 不设 = 不截断,0 = 截到零长度并留 `…(+N)`。与 maxEventChars 正交,会透传子循环 |
|
|
339
410
|
| `traceLimits` | **记账的数量上限** `{ maxEvents? }`(可被单次 run 覆盖):整条 trace 的事件总数闸。超限即停止记账,并在 run 根留**两笔** `trace.truncated` —— **起点标记** `{limit}`(断点在这里)+ **收尾摘要** `{droppedEvents, limit}`(丢了多少),两笔**同时**进交付的 trace 与 `onTraceEvent` 增量流。缺口位置可预测(尾巴)且**有计数**。与管**长度**的 `maxEventChars` 正交(一个管「多长」、一个管「多少」);不设 = 不限(全量记账是本框架的承诺)。坏值(NaN / 负数 / 小数)在 run 入口抛 `TypeError` |
|
|
340
411
|
|
|
341
412
|
### `app.run(messages, opts?: RunAppOptions)`
|
|
@@ -368,7 +439,9 @@ agentia export .agentia/traces.jsonl # → 训练数据集 JSONL
|
|
|
368
439
|
| `onUnpricedModel` | 单次覆盖未定价回调(**是函数,因此不在 transport 的 `RunInvocationOptions` 里** —— 异步宿主不会替你传) |
|
|
369
440
|
| `toolTimeoutMs` | 单个工具执行超时(毫秒);超时该条 tool_result 记 is_error,run 继续 |
|
|
370
441
|
| `maxToolConcurrency` | 同回合并行工具上限;缺省不限 |
|
|
371
|
-
| `maxEventChars` | trace 事件正文截断上限(字符):数字 = 入参/出参统一用该上限,`false` = **不截断**;缺省按类型收敛(入参/成功出参 2000、失败出参 1000)。**透传给子 agent/skill 的子循环** ——
|
|
442
|
+
| `maxEventChars` | trace 事件正文截断上限(字符):数字 = 入参/出参统一用该上限,`false` = **不截断**;缺省按类型收敛(入参/成功出参 2000、失败出参 1000)。**透传给子 agent/skill 的子循环** —— 同一棵调用树上口径一致。只影响**记账**;回模型上限另看 `maxToolResultChars` |
|
|
443
|
+
| `maxToolResultChars` | 单次覆盖工具结果回模型的字符上限;缺省 / false = 不截断,0 = 截到零长度 |
|
|
444
|
+
| `usageOffset` | 本段之前已落账的 `Usage`;通常只由 AsyncRunner 在挂起恢复时注入,让预算按整任务累计。HTTP 客户端不能自填 |
|
|
372
445
|
| `session` | 会话持久化 `{ store, id }`:run 前拼历史、成功收尾追加本轮(见 `SessionStore`) |
|
|
373
446
|
| `sessionId` | 会话**引用**(可序列化):**只被异步宿主消费** —— 「`sessionId` + runner 的 `sessionStore`」那条路(任务里只落 id,store 实例不可序列化;runner 没配 `sessionStore` 而任务带了它 ⇒ submit 当场报错)。⚠️ 直接 `app.run` 传它**不生效**(不建 `session.id`、不接历史),入口会 `console.warn` 一次指出改用上一行的 `session: { store, id }`;只要 run 根的 `session.id` 标记而不要历史,直连 `executeRun` / `runAgent` 的引擎级 `sessionId`(见 §6.4「提示词版本化与会话标记」) |
|
|
374
447
|
| `memory` | 跨 run 记忆 `{ store, keys }`:run 前水合进 blackboard(用户种子优先)、收尾写回;与 `session` 正交(见 `MemoryStore`) |
|
|
@@ -445,7 +518,7 @@ const { result } = await app.run(messages, {
|
|
|
445
518
|
result.typed; // { answer: string } | undefined
|
|
446
519
|
```
|
|
447
520
|
|
|
448
|
-
|
|
521
|
+
模型没提交时 `typed` 为 `undefined`,且 run 以 `stopReason='result_missing'` **失败**(trace 同样记 `error`,`error.type='result_missing'`);不再把「声明了结构化结果却没收尾」当成功。子 agent 声明 `resultSchema` 后未提交也会以 `is_error` 回主 agent。
|
|
449
522
|
|
|
450
523
|
### 5.4 消息类型族(自有公共类型,与厂商 SDK 结构兼容)
|
|
451
524
|
|
|
@@ -492,12 +565,56 @@ run 内取上下文(黑板 / `@Skill` 第二参)、把装饰器装配成 app
|
|
|
492
565
|
| `model` | 本次技能的缺省模型 |
|
|
493
566
|
| `llm` | 受限子运行:`await ctx.llm({ prompt })` / `{ messages, system, model, maxTokens, maxIterations }` |
|
|
494
567
|
|
|
568
|
+
#### `runCapabilityLoop(ctx, opts)` —— 代码控制顺序的子循环(2026-11-04)
|
|
569
|
+
|
|
570
|
+
四类能力之外还有一格:**顺序由你的代码定、但活不过这次请求**。`@SubAgent` / `@Skill` 的流程由
|
|
571
|
+
模型或方法体驱动、子循环里的审批挂不起整条 run;`AsyncRunner` 的 task 能挂起能续跑,但要为它
|
|
572
|
+
造一条任务记录。中间这一格就是本原语(它把 `runAgentScoped` 包成「旋钮不可漏」的形状 ——
|
|
573
|
+
`ToolRunContext` 上那七个必须原样下交的键一次取自单源,使用方接触不到)。
|
|
574
|
+
|
|
575
|
+
| 选哪个 | 判据 |
|
|
576
|
+
|---|---|
|
|
577
|
+
| `@SubAgent` | 流程交给**模型**决定,子 agent 自己挑工具 |
|
|
578
|
+
| `@Skill` + `ctx.llm()` | 流程由方法体定,但**不要**结构化结果 / 裁剪 / 人批 |
|
|
579
|
+
| **`runCapabilityLoop`** | 流程由方法体定,且需要 `contextPolicy`(长跑不撞上限)/ `resultSchema` / 同一棵树 |
|
|
580
|
+
| `AsyncRunner.submit` | 这件事会**活过这次请求**(耐久、崩溃续跑、审批原生) |
|
|
581
|
+
|
|
582
|
+
```ts
|
|
583
|
+
@Tool({
|
|
584
|
+
name: 'approve_invoice',
|
|
585
|
+
description: '核对并批准一张发票(会改账,需人工批准)',
|
|
586
|
+
inputSchema: INVOICE_SCHEMA,
|
|
587
|
+
approval: 'required', // 审批落在**这个工具调用**上 ⇒ 整条 run 可挂起等人批
|
|
588
|
+
})
|
|
589
|
+
class InvoiceTool {
|
|
590
|
+
constructor(private readonly client: ModelClient) {}
|
|
591
|
+
|
|
592
|
+
async run(input: { id: string }, ctx: ToolRunContext) {
|
|
593
|
+
const ledger = await runCapabilityLoop(ctx, {
|
|
594
|
+
name: 'invoice-review', // trace 里那个 capability span 的名字
|
|
595
|
+
input: `核对发票 ${input.id}:先查合同,再比对金额`,
|
|
596
|
+
tools: [contractTool, ledgerTool], // 子循环自己的菜单(不继承主菜单)
|
|
597
|
+
contextPolicy: createBudgetPolicy({ maxTokens: 40_000 }), // 长跑子循环不撞上限
|
|
598
|
+
resultSchema: VERDICT_SCHEMA,
|
|
599
|
+
});
|
|
600
|
+
// 成败自己判(框架不替它抛):非正常收尾时 stopReason 会告诉你为什么
|
|
601
|
+
if (!isSuccessStopReason(ledger.stopReason)) throw new Error(`核对失败:${ledger.stopReason}`);
|
|
602
|
+
return ledger.typed;
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
三条边界(都是刻意):**不自开 run 根**(`llm.turn` 挂在本条 run 的树里,`runId` 不会多一个);
|
|
608
|
+
**不继承主 run 的 `fallbacks` 链**(同 `runAgentScoped` 的有意边界);**挂起不穿透** ——
|
|
609
|
+
子循环里触发 `deferUntil` / 审批挂起时,语义同其它嵌套能力(以 `is_error` 交回,整条 run 不挂起)。
|
|
610
|
+
|
|
495
611
|
#### 装配与执行
|
|
496
612
|
|
|
497
613
|
| API | 说明 |
|
|
498
614
|
|---|---|
|
|
499
615
|
| `createApp` | 装配应用(同步;带 `discover` 时为 `Promise<AgentApp>`) |
|
|
500
|
-
| `AgentApp` | `run` / `tools` / `container` / `name` |
|
|
616
|
+
| `AgentApp` | `run` / `tools` / `container` / `name` / `getCapabilityManifest()` |
|
|
617
|
+
| `buildCapabilityManifest` | 从最终菜单生成 `{ app, hash, capabilities }`;hash 覆盖描述/schema/审批/元数据且与顺序无关,适合 PR 留档比较 |
|
|
501
618
|
| `defineModule` | 定义能力包 |
|
|
502
619
|
| `executeRun` | 低层 run 入口(自己管 `Run`/trace sink/记忆) |
|
|
503
620
|
| `runAgent` | 更底层:只要一个循环 + trace,不管 run 生命周期 |
|
|
@@ -556,6 +673,7 @@ const app = await createApp({ ... });
|
|
|
556
673
|
| `FileTaskStore` | JSONL 耐久存储(`compact()` 可压实日志) |
|
|
557
674
|
| `SqliteTaskStore` | `node:sqlite` 耐久存储(WAL + busy_timeout) |
|
|
558
675
|
| `RedisTaskStore` | duck-typed Redis 存储(可设 `ttlSeconds`);客户端结构面 `get` / `set` / `del` / `keys`(或 `scanIterator`),外加设 TTL 时必需的 `expire`。`set` **只传两参** —— 尾参的选项形状两家相反:ioredis 认位置参数 `('EX', n)`、node-redis 认对象 `{ EX: n }`,取任何一种都会在另一家上失效(ioredis 会把对象字符串化成 `"[object Object]"` 报语法错;**node-redis 的 `SET` 只声明三个形参,位置参数被静默丢弃**)。所以 TTL 一律走 `expire(key, seconds)`(两家同名同形);设了 `ttlSeconds > 0` 却没给 `expire` 时**构造期抛错**,不静默丢掉 TTL |
|
|
676
|
+
| `parseTaskRecord` | 自定义 store 的公共读回入口:JSON 解析 + 形状守卫 + 旧版本归一;坏 JSON 抛错,非记录返回 undefined |
|
|
559
677
|
|
|
560
678
|
**`compact()` / `close()` 是接口上的可选能力,但由宿主按需调**:`FileTaskStore.compact()`
|
|
561
679
|
(压实 JSONL:一 task 一行、丢掉历史覆写行)与 `SqliteTaskStore.close()` 此前只活在具体类上 ——
|
|
@@ -648,7 +766,7 @@ npm run client # 另一个终端:把四个 RPC 跑一遍
|
|
|
648
766
|
| 端点 | 请求 | 响应 |
|
|
649
767
|
|---|---|---|
|
|
650
768
|
| `POST /run` | body 是 `RunInput`(string / messages / `{prompt\|text\|messages}`);带 `Accept: text/event-stream` 则走 SSE | 200 `{ runId, status, stopReason, finalText, typed?, trace, error? }` —— **`status=failed` 也照返 200**(`rethrow:false` 语义:硬失败以 `error` 字段表达,不用 HTTP 错误码) |
|
|
651
|
-
| `POST /tasks` | `{ input, idempotencyKey?, options? }` —— `input` 同 `RunInput`;`options`
|
|
769
|
+
| `POST /tasks` | `{ input, idempotencyKey?, options? }` —— `input` 同 `RunInput`;`options` 只接受**白名单**:`traceContext` / `maxCostUsd` / `maxTotalTokens`(多一个键 → 400,含 `blackboard` / `tools` / `model`)。**身份与租户不走 body** —— 由宿主的 `resolveRunOptions` 按请求注入 | 202 `TaskRecord`(`status: 'queued'`);同 `idempotencyKey` 未失败则去重、直接返回既有记录(**同步 store** 当场判定;**异步 store** 下只保证**同进程内并发提交**不重复执行,跨进程与终态后重提仍是 at-least-once —— 见 §7「同键去重的能力边界」) |
|
|
652
770
|
| `GET /tasks/:id` | — | 200 `TaskRecord`;不存在 → 404。**停机中仍可轮询**(否则拿不到在飞任务的结果) |
|
|
653
771
|
| `GET /tasks/:id/stream` | — | **任务进度流(SSE)**:先在 `id:` 里给流序号,逐帧下发 `trace.event`(body 即 `TraceRecordEvent`),终态发 `task.end` 并关闭。断线重连带 `Last-Event-ID`(或 `?from=<序号>`)即可续订 —— 只补该序号之后的事件。缓冲超限先发一帧 `stream.truncated{droppedBefore}`;别的进程在跑的任务发 `stream.unavailable` 后收口(**不假装实时**)。任务不存在 → 404;方法不对 → 405。⚠️ 它的读者是**旁观者**:背压/断开只收口这条流,**不中止任务** |
|
|
654
772
|
| `POST /tasks/:id/approve` | `{ decisions: { <tool_use_id>: { approved, reason? } }, decidedBy? }` | 200 `TaskRecord`(HITL 审批:批准/拒绝挂起任务,见 §6.6「人工审批」);任务不存在 → 404;**挂起原因不是 `approval`**(含未挂起)→ 409;`decisions` 里有不在该任务 `pendingApprovals` 里的 id → **400(整批拒,记录一字不动)**;body 非法 → 400。**停机中仍可审批**(与 GET 轮询同理由) |
|
|
@@ -660,6 +778,42 @@ npm run client # 另一个终端:把四个 RPC 跑一遍
|
|
|
660
778
|
方法不符 → 405(带 `Allow` 头);路径不符 → 404;body 非法 JSON → 400;body 超 `maxBodyBytes` → 413;
|
|
661
779
|
`POST /run` 超 `maxConcurrentRuns` → 503 + `Retry-After`;停机中 `POST /run`、`POST /tasks` → 503。
|
|
662
780
|
|
|
781
|
+
上表是缺省 `responseMode:'full'` 的兼容形状。对外多租户服务建议 `responseMode:'public'`:
|
|
782
|
+
run/task 响应不再携带 trace、spec.messages、suspendedMessages 与 ownerId,SSE 的 trace 帧也默认关;
|
|
783
|
+
它不改变任务库和 sinks 的完整记录。对象级授权由 `authorizeTask` 另行决定,两者不能互相替代。
|
|
784
|
+
|
|
785
|
+
#### 本地怎么调(可直接复制的命令)
|
|
786
|
+
|
|
787
|
+
⚠️ 先认下这条,否则会照着别的框架的经验找错东西:**没有「一个业务一个 URL」的接口层**。
|
|
788
|
+
HTTP 面就上面那几条**固定**端点 —— 加一个 `@Tool` 不会多出一条路,**调哪个能力由模型决定,
|
|
789
|
+
不在 URL 里**(这是「换宿主不换语义」的另一半:换 HTTP / gRPC / MCP,能力代码一行不动)。
|
|
790
|
+
⇒ 要「一个能力一个接口」的形态,走下面的 ④;要常规联调,走 ①②③。
|
|
791
|
+
|
|
792
|
+
| # | 想干什么 | 怎么做 |
|
|
793
|
+
|---|---|---|
|
|
794
|
+
| ① | **不起服务**,最快跑一次 | `npm run start:batch -- "你的问题"`(脚手架的 `batch.ts`:只跑一轮、打印 `finalText`、失败置非零退出码) |
|
|
795
|
+
| ② | 起了服务后用 curl 调 | 见下面的命令块 |
|
|
796
|
+
| ③ | 带调用树可视化地调 | `agentia dev` —— 终端打出 `Inspector: http://127.0.0.1:<随机端口>/?t=<token>`;面板里选能力 / 工作目录、输 prompt,右栏实时调用树,改代码自动重启 |
|
|
797
|
+
| ④ | **单挑某一个工具**(不让模型决定) | `createMcpServer(app, { transport: 'stdio' })` ⇒ 每个 `@Tool` 变成一个标准 MCP tool,用 MCP inspector 或 `tools/call` 直接调(见 §6.5「MCP 反向桥」) |
|
|
798
|
+
|
|
799
|
+
```bash
|
|
800
|
+
curl -s localhost:3000/healthz # 先确认活着(不鉴权)
|
|
801
|
+
curl -s localhost:3000/run \
|
|
802
|
+
-H 'content-type: application/json' \
|
|
803
|
+
-d '{"prompt":"介绍一下你自己"}' # body 也收裸字符串 "..." 与 messages 数组
|
|
804
|
+
curl -sN localhost:3000/run \
|
|
805
|
+
-H 'content-type: application/json' \
|
|
806
|
+
-H 'Accept: text/event-stream' -d '"你的问题"' # -N 关掉 curl 缓冲 ⇒ 逐帧滚动
|
|
807
|
+
curl -s localhost:3000/tasks \
|
|
808
|
+
-H 'content-type: application/json' \
|
|
809
|
+
-d '{"input":"你的问题"}' # → 202 TaskRecord(拿 id 去 GET /tasks/:id 轮询)
|
|
810
|
+
```
|
|
811
|
+
|
|
812
|
+
⚠️ **两个别只看 curl 退出码的判据**:
|
|
813
|
+
① `POST /run` **失败也回 200** —— 硬失败写在响应体的 `status: "failed"` + `error` 字段里
|
|
814
|
+
(`rethrow:false` 语义:不用 HTTP 错误码表达失败)⇒ 脚本里要判 `status`,不是判 `$?`;
|
|
815
|
+
② SSE 那条要加 `-N`,否则 curl 自己缓冲着,看起来像「服务没吐东西」。
|
|
816
|
+
|
|
663
817
|
**换 model client 的缝**:HTTP 宿主**不持有 client** —— 同步 `/run` 走的是 `app.run(messages, opts)`,
|
|
664
818
|
而 `AppCallable` 就是 `{ name, run }`。所以要换 provider(OpenAI 兼容端点 / 自建 client),
|
|
665
819
|
**包一层**把 `client` 补进 `opts` 即可:
|
|
@@ -671,13 +825,18 @@ const handler = createHttpHandler(callable, { runner });
|
|
|
671
825
|
|
|
672
826
|
异步侧更直接:`AsyncRunner` 的构造选项就有 `client`。完整可跑写法见仓库 `examples/complete/`
|
|
673
827
|
(**不随 npm 包发布** —— 包里只有 `dist/`、README、LICENSE 与本说明):
|
|
674
|
-
<https://github.com/
|
|
828
|
+
<https://github.com/migoric/agentia/tree/main/examples/complete>
|
|
675
829
|
|
|
676
830
|
#### `createHttpHandler(app, opts?: HttpHandlerOptions)`
|
|
677
831
|
|
|
678
832
|
| 选项 | 说明 |
|
|
679
833
|
|---|---|
|
|
680
|
-
| `authenticate` | 入口鉴权钩子:**除 `/healthz` 与 `/metrics` 外所有路径**都过它,且在**读 body 之前**(未通过就不收 body
|
|
834
|
+
| `authenticate` | 入口鉴权钩子:**除 `/healthz` 与 `/metrics` 外所有路径**都过它,且在**读 body 之前**(未通过就不收 body)。正常返回即通过,**返回值作为 `principal` 交给 `resolveRunOptions`**;抛 `HttpException` 按其 `status`/`body` 回;抛别的错误回 401,原文只进服务端日志。框架**不实现策略**(不读 env、不碰凭据) |
|
|
835
|
+
| `resolveRunOptions` | `(req, { route, principal }) => { blackboard?, labels?, maxCostUsd?, maxTotalTokens? }` —— **身份 / 租户 / 配额封顶的唯一可信通道**(`/run` 与 `/tasks` 都生效)。`blackboard` **整体替换**、`labels` 按键盘合并(服务端胜)、预算与客户端值取**更严者**(上限不能由叫价方抬高)。抛 `HttpException` 按其状态码回。为什么必须有它:`POST /tasks` 的 `body.options` 走白名单之后,客户端已经**设不了** `blackboard` —— 身份不从这里进就没有地方进了(见 §6.6「多租户配额」) |
|
|
836
|
+
| `authorizeTask` | `(req, { action, taskId, task, principal })`:任务控制面的**对象级授权**,action 为 `poll/approve/cancel/event/stream`;返回 false → 403,抛 HttpException 按状态码回。审批/事件在读 body 之前判;缺省不拦(旧行为) |
|
|
837
|
+
| `resolveApprovalActor` | `(req, principal) => string\|undefined`:从认证结果生成可信审批人;配置后**覆盖**审批 body 的自报 `decidedBy`。空字符串按宿主配置错误 500 |
|
|
838
|
+
| `responseMode` | `'full'`(缺省,旧形状)/ `'public'`:公共模式去掉 run/task 响应的 trace、任务 spec、挂起历史与 ownerId;TaskStore/sinks 仍保留完整记录 |
|
|
839
|
+
| `exposeTraceEvents` | 是否开放 `/run` 与 `/tasks/:id/stream` 的 trace 事件;缺省 = `responseMode==='full'`。公共模式下显式 true 可单独开放,但不会把完整 trace 加回 run.end |
|
|
681
840
|
| `metrics` | 指标出口:给 `metricsSink()`(或任意 `{ render() }` / 返回字符串的闭包)后,`GET /metrics` 回它的 Prometheus 文本。**不鉴权**(拉取端在集群内网);要保护请放反代后面。不给则该路径 404。⚠️ 这只管**渲染** —— 数字要真的累计,必须把**同一个** sink 注册进 `createApp({ sinks: [metrics] })`(它靠 run 收尾投递,不自己埋点),否则 `/metrics` 恒为 0 **且不报错** |
|
|
682
841
|
| `maxBodyBytes` | 请求 body 上限(字节),超限回 413;缺省 1 MiB。构造期校验:必须 > 0 或 `Infinity` —— 0 会让**每个带 body 的请求**都 413(`POST /run` / `POST /tasks` / 审批全废),故直接抛错。⚠️ 还挡 `Number('') === 0`:从**空的环境变量**读出来的配置会静默变成「拒绝一切」 |
|
|
683
842
|
| `maxConcurrentRuns` | 同时在跑的 `POST /run` 上限,超限回 503 + `Retry-After`;缺省 32(传 `Infinity` 恢复无上限)。构造期校验:必须 > 0 或 Infinity —— NaN 会让闸门静默失效、0/负数会全部 503,故直接抛错 |
|
|
@@ -695,21 +854,50 @@ const handler = createHttpHandler(callable, { runner });
|
|
|
695
854
|
`abort` 收尾的,不是排空的;只关掉**旁观者长连**(`GET /tasks/:id/stream`)⇒ 不损失任何工作,
|
|
696
855
|
不影响这个布尔。宿主的 SIGTERM 决策(退出 / 再等)就依赖它。
|
|
697
856
|
**框架不订阅信号** —— `process.on('SIGTERM', () => handler.drain())` 是宿主的事(同「框架不读 env」)。
|
|
857
|
+
不想自己写那 ~20 行停机样板就用 `serve()` + `gracefulShutdown()`(2026-10-22 ref-serve-graceful-shutdown):它们把
|
|
858
|
+
「起监听 / 收连接 / 二次信号 / 停完回调」收进实现,但仍要**宿主显式调用、显式传 `signals`**
|
|
859
|
+
—— 不传就一个信号都不订阅。
|
|
698
860
|
- **`handler.runner`** —— 内部 `AsyncRunner`,需要时手动控制(`resumePending` / `awaitTask` / `list`)。
|
|
699
861
|
|
|
700
862
|
```ts
|
|
863
|
+
import {
|
|
864
|
+
createHttpHandler,
|
|
865
|
+
gracefulShutdown,
|
|
866
|
+
serve,
|
|
867
|
+
HttpException,
|
|
868
|
+
} from '@migor/agentia';
|
|
869
|
+
|
|
701
870
|
const handler = createHttpHandler(app, {
|
|
702
871
|
// 只给缝:token/JWT/签名策略由你的宿主或反代实现
|
|
703
872
|
authenticate: (req) => {
|
|
704
873
|
if (req.headers['x-api-key'] !== expected) throw new HttpException(401, { error: '无效凭据' });
|
|
874
|
+
// 返回值不是白抛的:它就是 principal,下一步交给 resolveRunOptions
|
|
875
|
+
return { userId: String(req.headers['x-user-id'] ?? '') };
|
|
876
|
+
},
|
|
877
|
+
// 身份 / 租户进 run 的唯一可信通道(客户端在 body 里填不了黑板)
|
|
878
|
+
resolveRunOptions: (_req, { principal }) => {
|
|
879
|
+
const { userId } = principal as { userId: string };
|
|
880
|
+
return { blackboard: { tenant: tenantOf(userId) }, labels: { user: userId } };
|
|
705
881
|
},
|
|
706
882
|
});
|
|
707
|
-
http.createServer(handler).listen(3000);
|
|
708
883
|
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
884
|
+
// `serve` = createServer + listen + 等真的在听;`port` 是**实际**端口(传 0 时由 OS 分配)。
|
|
885
|
+
// 端口冲突 / 权限不足直接 reject —— boot 阶段静默起不来比崩更难查。
|
|
886
|
+
serve(handler, { port: 3000 }).then(({ server }) => {
|
|
887
|
+
gracefulShutdown({
|
|
888
|
+
server,
|
|
889
|
+
drain: () => handler.drain({ timeoutMs: 15_000 }),
|
|
890
|
+
// 不传 = 一个信号都不订阅(框架不做进程级决策);传了即宿主显式认领
|
|
891
|
+
signals: ['SIGTERM', 'SIGINT'],
|
|
892
|
+
timeoutMs: 15_000,
|
|
893
|
+
// 第二次信号:本原语**不吞** —— 给了这个钩子就交给你,没给就摘掉监听让 Node 默认行为接管
|
|
894
|
+
onSecondSignal: () => process.exit(1),
|
|
895
|
+
// 停机完成(`clean` = 排空且连接关干净)。本原语自己不 exit —— 退出码是宿主的编排
|
|
896
|
+
onShutdown: (clean) => {
|
|
897
|
+
console.log(clean ? '已排空' : '超时收口,剩余任务下次启动续跑');
|
|
898
|
+
process.exit(clean ? 0 : 1);
|
|
899
|
+
},
|
|
900
|
+
});
|
|
713
901
|
});
|
|
714
902
|
```
|
|
715
903
|
|
|
@@ -825,12 +1013,12 @@ trace 出去之后能干什么:指标、调用树面板、调优报告、生
|
|
|
825
1013
|
|
|
826
1014
|
| API | 说明 |
|
|
827
1015
|
|---|---|
|
|
828
|
-
| `TraceSink` | `{ export(trace) }`,run
|
|
1016
|
+
| `TraceSink` | `{ export(trace) }`,run 收尾(成功/失败)都投递。抛错只告警、不影响 run;单个 sink 默认最多等待 10 秒,超时同样告警并放弃等待(**不取消底层导出**),后续 sink 仍照常接收。run 宿主与 MCP 反向桥共用这套口径 |
|
|
829
1017
|
| `registerDefaultTraceSink` | 注册全局默认 sink(构造期快照合并) |
|
|
830
1018
|
| `TraceRecorder` | 内存 recorder(一次 run 一个);`addLink(spanId, { traceId, spanId? })` 记一条跨 trace 链路(见 §6「跨进程关联」) |
|
|
831
1019
|
| `parseTraceparent` | 解析 W3C `traceparent` 头 → `{ traceId, spanId? }`;**非法 / 缺头一律返回 `undefined`**(不抛、不打 400)—— 结果直接交给 `traceContext` 选项,见 §6「跨进程关联」 |
|
|
832
1020
|
| `createOtlpExporter` | OTLP/JSON 导出,零依赖;选项见下面「`OtlpExporterOptions`」表 |
|
|
833
|
-
| `jsonlTraceSink` | JSONL 文件 sink:`jsonlTraceSink({ path })` → `TraceSink`,一行一条裸 Trace 追加落盘(父目录自动创建、追加不覆盖)—— **`agentia report` / `diff` / `harvest` / `export` 的输入格式**,见 §6
|
|
1021
|
+
| `jsonlTraceSink` | JSONL 文件 sink:`jsonlTraceSink({ path })` → `TraceSink`,一行一条裸 Trace 追加落盘(父目录自动创建、追加不覆盖)—— **`agentia report` / `diff` / `harvest` / `export` / `view` 的输入格式**,见 §6「调优报告」。⚠️ **同一路径进程内幂等**(两次调用返回同一个 sink):两条 sink 对口一个文件会让一次 run 落两行同 traceId,而下面的命令按「一行 = 一次 run」计数 ⇒ 一次 run 被数两次(不报错,比不落盘更难发现)。所以「应用级 `sinks` 与 `registerDefaultTraceSink` 都往 `.agentia/traces.jsonl` 写」是安全的 |
|
|
834
1022
|
| `TraceRecordEvent` | **增量记账事件**(`onTraceEvent` 的回调参数):`span.begin` / `span.end` / `span.event` / `span.attribute` / `span.link`,每条带单调 `seq`。载荷是**增量 + 此刻的拷贝**(`span.begin` 只给初始形状,属性/事件/链路各走自己的类型);按 `seq` 升序折回必须**逐字等于**收尾时的 trace |
|
|
835
1023
|
| `metricsSink` | 指标累加器(Prometheus 文本 / OTLP metrics),满足 `TraceSink` 即接入 —— 见 §6「指标」 |
|
|
836
1024
|
| `buildRunReport` | 从一条 trace 生成**调优报告**(能力/模型的耗时、token、成本、错误率排行)—— 见 §6「调优报告」 |
|
|
@@ -1108,14 +1296,15 @@ calls / err / 耗时照记(那是它自己这次调用的真账)。
|
|
|
1108
1296
|
> CLI 报告的聚合口径与 `agentia dev` 面板的能力排行同源(同一份 `@migor/trace-view` 实现)。
|
|
1109
1297
|
|
|
1110
1298
|
那个 jsonl 从哪来 —— 框架内置了文件 sink,一行接入(零依赖)。它产出的格式就是
|
|
1111
|
-
**CLI
|
|
1112
|
-
都吃这个文件(一行一个 JSON,裸 Trace):
|
|
1299
|
+
**CLI 五件套的输入**:`agentia report` / `agentia diff` / `agentia harvest` / `agentia export` /
|
|
1300
|
+
`agentia view` 都吃这个文件(一行一个 JSON,裸 Trace):
|
|
1113
1301
|
|
|
1114
1302
|
```ts
|
|
1115
1303
|
import { createApp, jsonlTraceSink } from '@migor/agentia';
|
|
1116
1304
|
|
|
1117
1305
|
const app = await createApp({ /* … */ sinks: [jsonlTraceSink({ path: 'trace.jsonl' })] });
|
|
1118
|
-
// 之后:agentia report trace.jsonl / agentia diff a.jsonl b.jsonl / agentia harvest trace.jsonl /
|
|
1306
|
+
// 之后:agentia report trace.jsonl / agentia diff a.jsonl b.jsonl / agentia harvest trace.jsonl /
|
|
1307
|
+
// agentia export trace.jsonl / agentia view trace.jsonl --open
|
|
1119
1308
|
```
|
|
1120
1309
|
|
|
1121
1310
|
父目录不存在会自动递归创建;**追加不覆盖**(多跑几次就累积多行);写失败抛给 `flushSinks`
|
|
@@ -1415,7 +1604,10 @@ agentia harvest trace.jsonl --out evals/harvested.ts --force # 覆盖已存在
|
|
|
1415
1604
|
- 产物是**可粘贴进 eval 文件的用例字面量**:`client: scriptedClient([...])` 按 trace 的主循环 llm.turn 逐回合重建,`expect` 预填「主循环工具序列」的轨迹断言(文件顶部附跑法注释)。
|
|
1416
1605
|
- `--out` 指向已存在的文件时**默认拒绝覆盖**(产物是要人工核对的脚手架,重跑一次就抹掉你改过的断言与 input);要覆盖显式加 `--force`。
|
|
1417
1606
|
- ⚠️ **脚手架不是成品,人工核对后再进 CI**:
|
|
1418
|
-
- **
|
|
1607
|
+
- **assistant 文本要看 run 开没开 `traceContent: 'full'`**(§4 的 opt-in 开关):开了就取
|
|
1608
|
+
llm.turn 的 `output.text` 真值;没开则脚本**只含工具调用**,终端回合的 text 是占位
|
|
1609
|
+
`'[harvest] assistant 文本未入 trace'`(纯 tool_use 回合**不补占位** —— 那会变成「模型
|
|
1610
|
+
说过这句话」的假事实)。骨架头注会写明这一次是哪一种,不会让你自己去猜;
|
|
1419
1611
|
- 只重建**直属 run 根**的主循环回合 —— 子 agent 的嵌套回合不走主循环脚本(要覆盖子 agent 请单独写 eval);
|
|
1420
1612
|
- 预填的 `expect` 是从原 trace **抄录的实际轨迹** —— 发生过 ≠ 应该发生;
|
|
1421
1613
|
- `EvalCase` 没有 `expect` 字段,粘贴时把断言搬进 `defineEval({ expect })`(脚手架注释会教)。
|
|
@@ -1556,6 +1748,9 @@ createApp({ system, providers: [...], middleware: [quota], sinks: [billing] });
|
|
|
1556
1748
|
|
|
1557
1749
|
- 拦下来的那次 run **仍然要记账**(模型的钱已经花了)—— 记账在 sink 里、拦截在 middleware 里,两者独立。
|
|
1558
1750
|
- 被拦下的能力**不会执行**(副作用不发生),但 run 继续跑(模型可以换路)。
|
|
1751
|
+
- ⚠️ **`tenant` 从哪来**(2026-11-04 起):只能由宿主注入 —— `createHttpHandler({ authenticate, resolveRunOptions })` 里
|
|
1752
|
+
`resolveRunOptions` 返回 `{ blackboard: { tenant } }`。客户端在 `POST /tasks` 的 `options` 里**填不了黑板**
|
|
1753
|
+
(白名单外即 400):这条配方此前照着抄会被绕过 —— 谁能调 `/tasks` 谁就能自填 `tenant`,额度记到别人头上。
|
|
1559
1754
|
|
|
1560
1755
|
#### 人工审批
|
|
1561
1756
|
|
|
@@ -1610,7 +1805,9 @@ class DeployTools {
|
|
|
1610
1805
|
`{ decisions: { '<tool_use_id>': { approved: true } }, decidedBy: 'alice' }`
|
|
1611
1806
|
(或直接 `runner.approve(taskId, decisions, { decidedBy })`)。**逐 tool_use_id 幂等**
|
|
1612
1807
|
(第一次决定赢,重复提交不推翻)。决定**随任务落库**(`TaskRecord.approvals`,
|
|
1613
|
-
|
|
1808
|
+
进程重启不丢);待决集合齐了任务自动恢复执行。生产 HTTP 端建议同时配置
|
|
1809
|
+
`authorizeTask`(谁能批这个任务)与 `resolveApprovalActor`(从 principal 生成 decidedBy,
|
|
1810
|
+
覆盖请求体自报身份);否则 `decidedBy` 只是调用方填写的审计字段,不是可信身份。
|
|
1614
1811
|
4. 恢复时:**批准**的工具正常执行(工具体内经 `ToolRunContext.approval` 读到自己的决定 —
|
|
1615
1812
|
谁批的、什么时候、什么理由);**拒绝**的工具得到 `tool_result(is_error: true,
|
|
1616
1813
|
content: '审批被拒绝:…')` —— 理由回给模型,可自行换路。恢复后再遇未决审批 ⇒
|
|
@@ -1778,7 +1975,7 @@ const callable = {
|
|
|
1778
1975
|
| 任务进度流的边界(内存 / 跨进程) | `GET /tasks/:id/stream` 的事件缓冲在**跑任务的进程内存**里:每任务最近 500 条(可用 `AsyncRunner` 的 `streamBufferEvents` 调,须为正整数,坏值构造期抛错),超限丢**最旧**并先发一帧 `stream.truncated`;终态流只留最近 16 条。**没跑完**的流另有一道**缓冲配额**(`streamNonTerminalBuffers`,缺省 32 条流;`0` = 不留):超出即从最旧、**没有订阅者**的流开始回收**回放历史** —— 表项与序号都留着,连上来的读者先收一帧 `stream.truncated` 再转实时(**不会**变成 `stream.unavailable`,那是对别的进程说的话);正在被订阅的流不受配额约束(不抽走正在读的数据)。**跨进程**(队列消费者在别的进程)时没有实时流:发一帧 `stream.unavailable` 后**立即收口** —— 任务已终态则补 `task.end`(随后关连接);**非终态**则补一帧 `stream.closed`(流级收尾,不是伪造终态)并关连接,客户端此后应转去轮询 `GET /tasks/:id`。要跨进程实时请用 `onTraceEvent` 把事件转发到宿主自己的总线(Redis Streams / Kafka) |
|
|
1779
1976
|
| 异步任务的**排队段**边界(内存) | `concurrency` 管「同时在跑几个」,**不管**「跑不上、排在后面」那一段 —— 缺省**排队段无上限**:`submit` 总是收单、`POST /tasks` 总是 202,灌多少就在内存里排多少(每条 = 一条记录 + 一棵悬挂的 `#execute` promise + 一个槽位等待者)。要背压就配 `AsyncRunner({ maxQueued })`:超限 `submit` 抛 `TaskQueueFullError`、HTTP 回 **503 + `Retry-After`**(**只在 `submit` 判** —— 恢复路径推进的是已受理任务,拦下来等于把它搁死在 store 里;幂等键命中的重复提交也不吃 503)。`runner.queued` 是实时读数(与闸同一判据)。⚠️ 进程内拒单**不等于**集群级背压:多副本各算各的,要全局就得上队列 |
|
|
1780
1977
|
| `traceLimits` 与 `maxEventChars` 各管一头 | `maxEventChars` 管**单个事件正文多长**(既有),`traceLimits.maxEvents` 管**整条 trace 记多少条记录事件**(本版)。两者正交、都「不设 = 不限」;超限即**停止记账**,并在 run 根留**两笔** `trace.truncated`:**起点标记** `{limit}`(断点在这里)+ **收尾摘要** `{droppedEvents, limit}`(丢了多少)—— 两笔**同时**进交付的 trace 与 `onTraceEvent` 增量流(⇒ 按 `seq` 折回仍逐字等于收尾那份;两笔簿记**不占** `maxEvents` 配额)。⚠️ 实测 `maxEventChars: false` + 大出参会让 trace 放大 **13.7×**(`npm run bench:trace` 可复现)—— 先收长度再谈采样,收益顺序比反过来大 |
|
|
1781
|
-
|
|
|
1978
|
+
| 工具结果缺省不截断;上限要显式开 | `maxEventChars` / `traceContent` 管**记账侧**;`maxToolResultChars` 管回模型的单条结果,缺省/false = 不截断,给非负整数即截并附 `…(+N)`。它按字符而非 token/业务行数计费;要语义化摘要仍在工具内做 |
|
|
1782
1979
|
| **采样是导出决策,不是记账决策** | 采样在 `sink` 外做(配方见 `docs/observability.md` 2.3):被采样掉的 trace 在框架内**仍然完整记账**,只是没发给下游。所以别拿「有采样」当「可以少记账」;也正因如此,出站 `traceparent` 的 flags 恒 `00`(记录/导出决策发生在收尾之后,运行期不可知——不替下游声明) |
|
|
1783
1980
|
| 菜单漂移只**标记**、不判失败 | 续跑时未决 tool_use 的工具不在当前菜单 ⇒ 三处信号(`menu.drift` 事件 / 父 span attribute / `console.warn`),run **照常收尾**(那些 tool_use 以 `unknown tool` 回给模型)。**射程如实标注**:判据只看**名字** —— 「工具还在、schema 变了」能被 `tools.menuHash` 比出来,但**不会**在续跑时报 `menu.drift`;**只改 `description`** 连签名都不变(有意:润色文案不算漂移)。严格模式(带具名 error 的收尾)与「结果级字段」记在 spec §11 开放项 |
|
|
1784
1981
|
| `approve` 只收**待决的** id(多一个 → 400 整批拒) | `decisions` 的键必须都在该任务的 `pendingApprovals` 里(调用方从记录的 `pendingApprovals` 读)。多出任何一个 ⇒ **400 + 整批拒 + 记录一字不动**。不校验的代价(已修,2026-09-28 外部深评):多出来的键会写进 `TaskRecord.approvals`,随每次 `save` 全文重写、且终态也不清 ⇒ 一个**认证调用方**单次请求就能把记录撑大(实证:一次 5000 个无关键 = +419 KB),反复调用可无限叠加 |
|
|
@@ -1796,7 +1993,7 @@ const callable = {
|
|
|
1796
1993
|
| 观测失败被吞 | sink 抛错不影响 run(观测是辅助动作);但吞之前落一条 `console.warn`(含「trace sink」字样)—— sink 天天挂不再零信号。同理记忆水合/回写失败也不击穿 run |
|
|
1797
1994
|
| 框架不自动读 .env | 除 `AGENTIA_MODEL`(缺省模型覆盖)与 `OPENAI_API_KEY`(OpenAI 适配器)外,框架自己不去翻环境变量,也不读 `.env`;要读就在启动代码里调 `loadEnvFile()`(脚手架已内置那行),**真实环境变量优先**于文件 |
|
|
1798
1995
|
| 鉴权只是缝 | 框架**不实现** token / JWT / 签名策略,也不碰凭据 env —— `authenticate` 只承诺「拦在入口、读 body 之前」;策略是宿主或反代的事 |
|
|
1799
|
-
|
|
|
1996
|
+
| 运行时:Node 承诺,Bun / Deno 实测 | 按 Node ≥ 18 设计与测试(`engines` 写明;CI 覆盖 18 / 20 / 24 —— `import-floor` 矩阵跑下限、其余 job 跟当前 LTS);Bun 1.4 / Deno 2.9 已实测可跑(四步判定 + 各宿主最小代码见 `docs/frameworks.md`),但**不在 `engines` 承诺内**;**edge 未验证**。`SqliteTaskStore` 需 Node ≥ 22.5(`node:sqlite`),未提供时构造期抛可读报错 |
|
|
1800
1997
|
| 停机不由框架触发 | 框架给 `drain()` 但**不订阅** `SIGTERM`/`SIGINT`(不做进程级决策);信号处理是宿主的 |
|
|
1801
1998
|
| 停机可能切断 SSE | `drain()` 收口时会强制关闭仍开着的 SSE 流,`/run` 的流被收口时其 run 以 `stopReason='aborted'` 收尾(客户端应把断流当作可重试)。**没有 `timeoutMs` 时也收口**(否则等待没有终点,见上);只关旁观者长连(`/tasks/:id/stream`)**不损失工作**,那种收口不影响 `drain()` 的返回值 |
|
|
1802
1999
|
| 多进程共库:续跑认领靠**租约**,不靠时间(2026-09-28) | `resumePending({ staleAfterMs })` 的 `staleAfterMs` **不是**租约而是**兜底启发式**。`> 0` 时按两档判他进程的记录:① `ownerId` 里的主机名是本机 ⇒ **问那个 pid 还在不在**(`process.kill(pid, 0)`)——**在的绝不抢**(不管记录多老)、**不在的立刻可抢**(崩溃孤儿不等保鲜期);② **判不了**(异主机 / 升级前写下的旧格式 `ownerId` / 自定义串)⇒ 才用 `staleAfterMs`(「记录看起来还新」)。缺省 `0` = 不问他进程,与升级前逐字一致 |
|
|
@@ -1846,15 +2043,15 @@ const callable = {
|
|
|
1846
2043
|
| 审批超时是**惰性**判定 | `approvalTimeoutMs` 不起定时器:`approve` / `poll` / `resumePending` 读到过期挂起任务时才自动全拒并重派 —— 没人读的任务不会自己超时(要定期扫就调 `resumePending()`) |
|
|
1847
2044
|
| 挂起段与恢复段是两棵 trace | 每段执行一棵独立的树(`traceId == runId`),恢复段经根 span 的 `links` 挂到上一段;指标按段计(挂起段算一次 ok 的 run —— 「等人」不算失败,区分看 `stop_reason` attribute) |
|
|
1848
2045
|
| 审批是 at-least-once | 崩溃发生在「批准后、恢复执行中」时,副作用工具会重执行(与 `resumePending` 续跑同口径)—— 副作用工具自己保证幂等 |
|
|
1849
|
-
|
|
|
1850
|
-
|
|
|
1851
|
-
| 嵌套能力内的审批不支持挂起 | @SubAgent / @Skill 子循环里的 `approval: 'required'` 工具无法把整个 run 挂起 —— 子循环挂起会以 `is_error` 交回主 agent
|
|
2046
|
+
| 恢复预算按任务累计,但崩溃未落账段不可追回 | 每个已收尾段折进 `TaskRecord.usageTotal`;恢复段经 `usageOffset` 参与 maxTotalTokens/maxCostUsd,trace 仍每段一棵。进程崩在「模型已花、结果未落库」窗口时那笔无从恢复,不能把它当全局精确账单 |
|
|
2047
|
+
| 恢复段的会话输入随任务落库 | 首个挂起段把本轮输入写进 `TaskRecord.sessionInput`,恢复成功后由 AsyncRunner 补写并终态清除;挂起期间重启不再丢这一轮。旧版本留下的挂起记录没有该字段,仍只能跳过补写 |
|
|
2048
|
+
| 嵌套能力内的审批不支持挂起 | @SubAgent / @Skill 子循环里的 `approval: 'required'` 工具无法把整个 run 挂起 —— 子循环挂起会以 `is_error` 交回主 agent(要审批的能力请放主菜单)。要「代码定顺序 + 人批」两样都要:把 `runCapabilityLoop` 放进一个 `@Tool({ approval: 'required' })` —— 审批落在**外层工具调用**上,于是照样能挂起等人批 |
|
|
1852
2049
|
| 同步 `/run` 撞上审批没人可批 | 同步 RPC 会带着 `stopReason: 'suspended'` 收尾返回 —— 但响应体(`toHttpBody`)**不含** `suspendedMessages`,也没有任务记录可审批(待决清单只能去 trace 的 `approval.requested` 事件里看)。**要审批请走 `POST /tasks` 异步宿主** |
|
|
1853
2050
|
| Scheduler 调度表不落库 | `every` / `at` 的调度本身只在内存:已 submit 的任务记录能经 `resumePending` 续跑,但「未来某刻再触发」的调度在重启后不存在(远期单发由宿主自己的 cron 驱动)。另:`drain()` 不停 Scheduler —— 停机窗口内到点的 tick 会打一条触发失败日志(无害但吵),介意就 `scheduler.stop()` 先行 |
|
|
1854
2051
|
| file store 的撕裂写只在启动时自愈 | 写入中途失败(磁盘满等)留下的残行由 `healTail` 在**构造期**修复;同进程内继续 append 会把新记录粘在残行尾部、下次启动时一起丢弃 —— 磁盘满告警后先恢复写入能力再继续依赖它 |
|
|
1855
2052
|
| 终态落库失败 ⇒ 重启会重跑 | AsyncRunner 终态 `save` 失败**不遮罩主流程**(「不击穿业务」的代价):store 抖动时任务可能永远停在 `running`,重启后 `resumePending` 会重跑一个**实际已成功**(副作用已发生)的任务 —— 所以副作用工具必须自身幂等。**但失败本身不再静默**:`new AsyncRunner(app, { onPersistError })` 会收到 `{ record, error, phase }`(`phase: 'initial' \| 'outcome'`,后者就是这条)。⚠️ 框架**修不了**它(写不进去就是写不进去)—— 出口的职责是让你能对账、让「记录无声丢失」不再是默认行为(与 `createOtlpExporter({ onExportError })` 同因同形) |
|
|
1856
2053
|
| 缺省**不裁剪**上下文(长跑每回合重发全量历史 ⇒ 成本随回合数平方增长) | `contextPolicy` 不注入就一个回合都不裁:每回合把**整段历史**重发给模型,于是回合数翻倍、总输入约翻两番。框架给了缝与一份参考实现(`createBudgetPolicy`),但**不替你决定** —— 裁剪有损(截在哪、留什么会影响答案),是宿主的策略。长任务(几十回合以上)请在 `createApp` 里显式注入 `contextPolicy` |
|
|
1857
|
-
| `contextPolicy` 不进子循环 | 应用级 `contextPolicy` / `onText` 只对主循环生效:@SubAgent / @Skill 的子运行不做上下文裁剪(长跑子 agent 撞上下文上限会以 api 错误收尾)。预算护栏(`maxTotalTokens` / `maxCostUsd
|
|
2054
|
+
| `contextPolicy` 不进子循环 | 应用级 `contextPolicy` / `onText` 只对主循环生效:@SubAgent / @Skill 的子运行不做上下文裁剪(长跑子 agent 撞上下文上限会以 api 错误收尾)。预算护栏(`maxTotalTokens` / `maxCostUsd`)正常透传。要裁剪就显式给:`runCapabilityLoop(ctx, { contextPolicy })`(不继承应用级 —— 子循环的策略是调用点的决策) |
|
|
1858
2055
|
| 记忆没有删除语义 | `MemoryStore` 只有 load/save:run 内 `ctx.delete` 掉的键回写时不会从 store 移除(下一轮水合会复活)。要真删请直接操作 store 实现 |
|
|
1859
2056
|
| 同 keys 的并发回写不合并 | CAS(`loadWithRev` + `saveIfRev`)只做到「冲突时**不写 + 出声**」:框架**不合并、不重试**(合并语义是 store 与宿主的决定,配方见 §6.5)。只有 `load` / `save` 的 store 连冲突都**看不见** —— 版本号是唯一依据,没有它就检测不了覆盖;`InMemoryMemoryStore` 的版本粒度是**整店一个计数**(宁可多报冲突,不漏报真实覆盖) |
|
|
1860
2057
|
| 内容护栏不给实现 | 同「配额」:只给缝(入参包 `app.run` / 工具前 `middleware` / 出参包返回值或 `sinks`),策略(正则 / 分类器 / 外部 API)是你的 |
|
package/dist/core/limits.d.ts
CHANGED
|
@@ -166,6 +166,14 @@ export declare const LIMIT_SEMANTICS: readonly [{
|
|
|
166
166
|
readonly zeroClause: '0 = 截到零长度;false = 不截断';
|
|
167
167
|
readonly badValue: 'none';
|
|
168
168
|
readonly note: '两个「关掉」的写法语义不同:`false` 才是「不截断」(调试期看全文),`0` 是把正文截成空串。⚠️ 靠 `!= null` 判定透传(真值判定会吃掉 `false`)。';
|
|
169
|
+
}, {
|
|
170
|
+
readonly knob: 'maxToolResultChars';
|
|
171
|
+
readonly where: 'engine/tool-events.ts(toolResultBlock / validateMaxToolResultChars)';
|
|
172
|
+
readonly unit: 'chars';
|
|
173
|
+
readonly zero: 'disabled';
|
|
174
|
+
readonly zeroClause: '0 = 截到零长度;false = 不截断';
|
|
175
|
+
readonly badValue: 'throws';
|
|
176
|
+
readonly note: '与 maxEventChars 同读法但不同保护面:这个裁回模型的 tool_result,那个裁 trace。NaN/负数/小数在第一次模型调用前拒,否则上限可能静默失效或行为不定。';
|
|
169
177
|
}, {
|
|
170
178
|
readonly knob: 'runAgent.maxIterations';
|
|
171
179
|
readonly where: 'engine/loop.ts';
|
package/dist/core/limits.js
CHANGED
|
@@ -132,6 +132,15 @@ export const LIMIT_SEMANTICS = [
|
|
|
132
132
|
badValue: 'none',
|
|
133
133
|
note: '两个「关掉」的写法语义不同:`false` 才是「不截断」(调试期看全文),`0` 是把正文截成空串。⚠️ 靠 `!= null` 判定透传(真值判定会吃掉 `false`)。',
|
|
134
134
|
},
|
|
135
|
+
{
|
|
136
|
+
knob: 'maxToolResultChars',
|
|
137
|
+
where: 'engine/tool-events.ts(toolResultBlock / validateMaxToolResultChars)',
|
|
138
|
+
unit: 'chars',
|
|
139
|
+
zero: 'disabled',
|
|
140
|
+
zeroClause: '0 = 截到零长度;false = 不截断',
|
|
141
|
+
badValue: 'throws',
|
|
142
|
+
note: '与 maxEventChars 同读法但不同保护面:这个裁回模型的 tool_result,那个裁 trace。NaN/负数/小数在第一次模型调用前拒,否则上限可能静默失效或行为不定。',
|
|
143
|
+
},
|
|
135
144
|
{
|
|
136
145
|
knob: 'runAgent.maxIterations',
|
|
137
146
|
where: 'engine/loop.ts',
|
package/dist/core/limits.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"limits.js","sourceRoot":"","sources":["../../src/core/limits.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"limits.js","sourceRoot":"","sources":["../../src/core/limits.ts"],"names":[],"mappings":"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"}
|