@migor/agentia 0.7.2 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +106 -1
- package/README.md +10 -6
- package/dist/AGENTS.md +55 -9
- package/dist/core/trace.d.ts +25 -0
- package/dist/core/trace.js +31 -0
- package/dist/core/trace.js.map +1 -1
- package/dist/engine/loop-result.d.ts +72 -0
- package/dist/engine/loop-result.js +80 -0
- package/dist/engine/loop-result.js.map +1 -0
- package/dist/engine/loop.d.ts +3 -40
- package/dist/engine/loop.js +37 -127
- package/dist/engine/loop.js.map +1 -1
- package/dist/engine/resume-input.d.ts +26 -0
- package/dist/engine/resume-input.js +39 -0
- package/dist/engine/resume-input.js.map +1 -0
- package/dist/engine/retry.d.ts +8 -0
- package/dist/engine/retry.js +10 -0
- package/dist/engine/retry.js.map +1 -1
- package/dist/engine/run-config.d.ts +28 -0
- package/dist/engine/run-config.js +75 -0
- package/dist/engine/run-config.js.map +1 -0
- package/dist/engine/span-scope.d.ts +48 -0
- package/dist/engine/span-scope.js +31 -0
- package/dist/engine/span-scope.js.map +1 -0
- package/dist/engine/stop-reason.d.ts +27 -0
- package/dist/engine/stop-reason.js +76 -0
- package/dist/engine/stop-reason.js.map +1 -0
- package/dist/engine/text.d.ts +10 -0
- package/dist/engine/text.js +6 -0
- package/dist/engine/text.js.map +1 -0
- package/dist/engine/tool-context.d.ts +32 -0
- package/dist/engine/tool-context.js +18 -0
- package/dist/engine/tool-context.js.map +1 -0
- package/dist/engine/tool-events.d.ts +42 -0
- package/dist/engine/tool-events.js +64 -0
- package/dist/engine/tool-events.js.map +1 -0
- package/dist/engine/turn-request.d.ts +24 -0
- package/dist/engine/turn-request.js +12 -0
- package/dist/engine/turn-request.js.map +1 -0
- package/dist/engine/turn.d.ts +4 -27
- package/dist/engine/turn.js +48 -158
- package/dist/engine/turn.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/integrations/otlp.d.ts +1 -1
- package/dist/integrations/otlp.js +13 -15
- package/dist/integrations/otlp.js.map +1 -1
- package/dist/toolkit/skill.js +4 -1
- package/dist/toolkit/skill.js.map +1 -1
- package/dist/toolkit/subagent.js +6 -3
- package/dist/toolkit/subagent.js.map +1 -1
- package/dist/toolkit/tool.js +1 -0
- package/dist/toolkit/tool.js.map +1 -1
- package/dist/transport/approval-policy.d.ts +30 -0
- package/dist/transport/approval-policy.js +37 -0
- package/dist/transport/approval-policy.js.map +1 -0
- package/dist/transport/async.d.ts +0 -4
- package/dist/transport/async.js +40 -144
- package/dist/transport/async.js.map +1 -1
- package/dist/transport/drain-gate.d.ts +28 -0
- package/dist/transport/drain-gate.js +62 -0
- package/dist/transport/drain-gate.js.map +1 -0
- package/dist/transport/http-route.d.ts +55 -0
- package/dist/transport/http-route.js +72 -0
- package/dist/transport/http-route.js.map +1 -0
- package/dist/transport/http-shapes.d.ts +57 -0
- package/dist/transport/http-shapes.js +56 -0
- package/dist/transport/http-shapes.js.map +1 -0
- package/dist/transport/http.d.ts +5 -21
- package/dist/transport/http.js +176 -232
- package/dist/transport/http.js.map +1 -1
- package/dist/transport/resume-policy.d.ts +40 -0
- package/dist/transport/resume-policy.js +25 -0
- package/dist/transport/resume-policy.js.map +1 -0
- package/dist/transport/slot-pool.d.ts +24 -0
- package/dist/transport/slot-pool.js +43 -0
- package/dist/transport/slot-pool.js.map +1 -0
- package/dist/transport/task-waiters.d.ts +25 -0
- package/dist/transport/task-waiters.js +63 -0
- package/dist/transport/task-waiters.js.map +1 -0
- package/package.json +4 -3
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 并发槽位池 —— 从 AsyncRunner 里抽出的第一个协作件(纯原语、零依赖)。
|
|
3
|
+
*
|
|
4
|
+
* 为什么单独成件:AsyncRunner 一个类同时扛状态机/并发/幂等/恢复/审批/session/超时/持久化,
|
|
5
|
+
* 并发槽位是其中**唯一不碰 store、不碰引擎**的一块 —— 先把它抽出来并配单测,后续抽块才有基线。
|
|
6
|
+
*
|
|
7
|
+
* 语义与原 `#acquireSlot` / `#releaseSlot` **逐字一致**:
|
|
8
|
+
* - 超限时 `acquire()` 的 promise 进 FIFO 队列等(此时任务记录仍由调用方留在 store 里为 queued);
|
|
9
|
+
* - `release()` **把槽位直接移交**给队首等待者(不是先减再让等待者自增)—— 移交期间计数不变,
|
|
10
|
+
* 所以「同时最多 limit 个」这条不变量在中间态也成立;
|
|
11
|
+
* - 没有等待者时才真正归还计数。
|
|
12
|
+
*/
|
|
13
|
+
export declare class SlotPool {
|
|
14
|
+
private readonly limit;
|
|
15
|
+
private running;
|
|
16
|
+
private readonly waitQueue;
|
|
17
|
+
constructor(limit: number);
|
|
18
|
+
/** 取槽位:未到上限立刻兑现,否则排队 */
|
|
19
|
+
acquire(): Promise<void>;
|
|
20
|
+
/** 还槽位:有等待者则移交(计数不变),否则归还 */
|
|
21
|
+
release(): void;
|
|
22
|
+
/** 当前占用数(测试用;AsyncRunner 对外暴露的是 active,不是它) */
|
|
23
|
+
get inUse(): number;
|
|
24
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 并发槽位池 —— 从 AsyncRunner 里抽出的第一个协作件(纯原语、零依赖)。
|
|
3
|
+
*
|
|
4
|
+
* 为什么单独成件:AsyncRunner 一个类同时扛状态机/并发/幂等/恢复/审批/session/超时/持久化,
|
|
5
|
+
* 并发槽位是其中**唯一不碰 store、不碰引擎**的一块 —— 先把它抽出来并配单测,后续抽块才有基线。
|
|
6
|
+
*
|
|
7
|
+
* 语义与原 `#acquireSlot` / `#releaseSlot` **逐字一致**:
|
|
8
|
+
* - 超限时 `acquire()` 的 promise 进 FIFO 队列等(此时任务记录仍由调用方留在 store 里为 queued);
|
|
9
|
+
* - `release()` **把槽位直接移交**给队首等待者(不是先减再让等待者自增)—— 移交期间计数不变,
|
|
10
|
+
* 所以「同时最多 limit 个」这条不变量在中间态也成立;
|
|
11
|
+
* - 没有等待者时才真正归还计数。
|
|
12
|
+
*/
|
|
13
|
+
export class SlotPool {
|
|
14
|
+
limit;
|
|
15
|
+
running = 0;
|
|
16
|
+
waitQueue = [];
|
|
17
|
+
constructor(limit) {
|
|
18
|
+
this.limit = limit;
|
|
19
|
+
}
|
|
20
|
+
/** 取槽位:未到上限立刻兑现,否则排队 */
|
|
21
|
+
acquire() {
|
|
22
|
+
if (this.running < this.limit) {
|
|
23
|
+
this.running++;
|
|
24
|
+
return Promise.resolve();
|
|
25
|
+
}
|
|
26
|
+
return new Promise((resolve) => this.waitQueue.push(resolve));
|
|
27
|
+
}
|
|
28
|
+
/** 还槽位:有等待者则移交(计数不变),否则归还 */
|
|
29
|
+
release() {
|
|
30
|
+
const next = this.waitQueue.shift();
|
|
31
|
+
if (next) {
|
|
32
|
+
next();
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
this.running--;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/** 当前占用数(测试用;AsyncRunner 对外暴露的是 active,不是它) */
|
|
39
|
+
get inUse() {
|
|
40
|
+
return this.running;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=slot-pool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slot-pool.js","sourceRoot":"","sources":["../../src/transport/slot-pool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,QAAQ;IAIU,KAAK;IAH1B,OAAO,GAAG,CAAC,CAAC;IACH,SAAS,GAAsB,EAAE,CAAC;IAEnD,YAA6B,KAAa;qBAAb,KAAK;IAAW,CAAC;IAE9C,wBAAwB;IACxB,OAAO;QACL,IAAI,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9B,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;QAC3B,CAAC;QACD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAChE,CAAC;IAED,6BAA6B;IAC7B,OAAO;QACL,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;QACpC,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,EAAE,CAAC;QACT,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,CAAC;IACH,CAAC;IAED,+CAA+C;IAC/C,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;CACF"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 任务终态等待表 —— 从 AsyncRunner 里抽出的第五个(也是最后一个)协作件
|
|
3
|
+
* (slot-pool → approval-policy → drain-gate → resume-policy → 这里)。
|
|
4
|
+
*
|
|
5
|
+
* 为什么单独成件:`awaitTask` 是**双通道**的 —— 主路径是事件唤醒(本进程把任务写到终态时
|
|
6
|
+
* 主动叫醒),兜底是轮询(他进程写终态时唤不醒,只能靠间隔唤醒后自己重读 store)。
|
|
7
|
+
* 两条通道各自的语义、以及"超时到底算 resolve 还是 reject"这类边界,混在 900 行的类里
|
|
8
|
+
* 只能透过 `awaitTask` 的整体行为间接观察;抽出来后可以直接打在表本身。
|
|
9
|
+
*
|
|
10
|
+
* ⚠️ 覆盖范围(这是本模块最重要的一条约束):**只覆盖本进程写终态**。他进程写的终态唤不醒
|
|
11
|
+
* 这里的等待者 —— 那是 `awaitTask` 用 `intervalMs` 兜底轮询的原因,不是缺陷。
|
|
12
|
+
*
|
|
13
|
+
* `wait()` 到期是 **resolve 而不是 reject**:它只是"该醒来看一眼了",超时的判定权在
|
|
14
|
+
* `awaitTask` 的循环里(它重读 store、算 deadline、再决定继续等还是抛错)。
|
|
15
|
+
*/
|
|
16
|
+
export declare class TaskWaiters {
|
|
17
|
+
/** taskId → 等待者;仅覆盖本进程写终态(他进程写靠兜底轮询) */
|
|
18
|
+
private readonly waiters;
|
|
19
|
+
/** 任务终态唤醒:本进程写终态的统一出口调用(成功 / 失败 / 采纳既有结果各路径) */
|
|
20
|
+
notify(taskId: string): void;
|
|
21
|
+
/** 等「本进程把该任务写到终态」或被 timeoutMs 兜底唤醒(二者先到先返回) */
|
|
22
|
+
wait(taskId: string, timeoutMs: number): Promise<void>;
|
|
23
|
+
/** 当前登记的等待者总数(单测与诊断用) */
|
|
24
|
+
get count(): number;
|
|
25
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 任务终态等待表 —— 从 AsyncRunner 里抽出的第五个(也是最后一个)协作件
|
|
3
|
+
* (slot-pool → approval-policy → drain-gate → resume-policy → 这里)。
|
|
4
|
+
*
|
|
5
|
+
* 为什么单独成件:`awaitTask` 是**双通道**的 —— 主路径是事件唤醒(本进程把任务写到终态时
|
|
6
|
+
* 主动叫醒),兜底是轮询(他进程写终态时唤不醒,只能靠间隔唤醒后自己重读 store)。
|
|
7
|
+
* 两条通道各自的语义、以及"超时到底算 resolve 还是 reject"这类边界,混在 900 行的类里
|
|
8
|
+
* 只能透过 `awaitTask` 的整体行为间接观察;抽出来后可以直接打在表本身。
|
|
9
|
+
*
|
|
10
|
+
* ⚠️ 覆盖范围(这是本模块最重要的一条约束):**只覆盖本进程写终态**。他进程写的终态唤不醒
|
|
11
|
+
* 这里的等待者 —— 那是 `awaitTask` 用 `intervalMs` 兜底轮询的原因,不是缺陷。
|
|
12
|
+
*
|
|
13
|
+
* `wait()` 到期是 **resolve 而不是 reject**:它只是"该醒来看一眼了",超时的判定权在
|
|
14
|
+
* `awaitTask` 的循环里(它重读 store、算 deadline、再决定继续等还是抛错)。
|
|
15
|
+
*/
|
|
16
|
+
export class TaskWaiters {
|
|
17
|
+
/** taskId → 等待者;仅覆盖本进程写终态(他进程写靠兜底轮询) */
|
|
18
|
+
waiters = new Map();
|
|
19
|
+
/** 任务终态唤醒:本进程写终态的统一出口调用(成功 / 失败 / 采纳既有结果各路径) */
|
|
20
|
+
notify(taskId) {
|
|
21
|
+
const waiters = this.waiters.get(taskId);
|
|
22
|
+
if (!waiters || waiters.length === 0)
|
|
23
|
+
return;
|
|
24
|
+
this.waiters.delete(taskId);
|
|
25
|
+
for (const w of waiters)
|
|
26
|
+
w();
|
|
27
|
+
}
|
|
28
|
+
/** 等「本进程把该任务写到终态」或被 timeoutMs 兜底唤醒(二者先到先返回) */
|
|
29
|
+
wait(taskId, timeoutMs) {
|
|
30
|
+
return new Promise((resolve) => {
|
|
31
|
+
let settled = false;
|
|
32
|
+
const finish = () => {
|
|
33
|
+
if (settled)
|
|
34
|
+
return;
|
|
35
|
+
settled = true;
|
|
36
|
+
clearTimeout(timer);
|
|
37
|
+
const waiters = this.waiters.get(taskId);
|
|
38
|
+
if (waiters) {
|
|
39
|
+
const i = waiters.indexOf(finish);
|
|
40
|
+
if (i >= 0)
|
|
41
|
+
waiters.splice(i, 1);
|
|
42
|
+
if (waiters.length === 0)
|
|
43
|
+
this.waiters.delete(taskId);
|
|
44
|
+
}
|
|
45
|
+
resolve();
|
|
46
|
+
};
|
|
47
|
+
const timer = setTimeout(finish, timeoutMs);
|
|
48
|
+
const waiters = this.waiters.get(taskId);
|
|
49
|
+
if (waiters)
|
|
50
|
+
waiters.push(finish);
|
|
51
|
+
else
|
|
52
|
+
this.waiters.set(taskId, [finish]);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
/** 当前登记的等待者总数(单测与诊断用) */
|
|
56
|
+
get count() {
|
|
57
|
+
let n = 0;
|
|
58
|
+
for (const list of this.waiters.values())
|
|
59
|
+
n += list.length;
|
|
60
|
+
return n;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=task-waiters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-waiters.js","sourceRoot":"","sources":["../../src/transport/task-waiters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,WAAW;IACtB,wCAAwC;IACvB,OAAO,GAAG,IAAI,GAAG,EAA6B,CAAC;IAEhE,gDAAgD;IAChD,MAAM,CAAC,MAAc;QACnB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACzC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAC7C,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC5B,KAAK,MAAM,CAAC,IAAI,OAAO;YAAE,CAAC,EAAE,CAAC;IAC/B,CAAC;IAED,+CAA+C;IAC/C,IAAI,CAAC,MAAc,EAAE,SAAiB;QACpC,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YACnC,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,MAAM,MAAM,GAAG,GAAS,EAAE;gBACxB,IAAI,OAAO;oBAAE,OAAO;gBACpB,OAAO,GAAG,IAAI,CAAC;gBACf,YAAY,CAAC,KAAK,CAAC,CAAC;gBACpB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBACzC,IAAI,OAAO,EAAE,CAAC;oBACZ,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;oBAClC,IAAI,CAAC,IAAI,CAAC;wBAAE,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;oBACjC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;wBAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBACxD,CAAC;gBACD,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC;YACF,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;YAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACzC,IAAI,OAAO;gBAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;;gBAC7B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;IACL,CAAC;IAED,yBAAyB;IACzB,IAAI,KAAK;QACP,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE;YAAE,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC;QAC3D,OAAO,CAAC,CAAC;IACX,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@migor/agentia",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "面向应用开发的声明式 agent 服务开发框架:装饰器 + DI 声明四类能力,主 agent 编排执行;每次 run 产出结构化结果与可观测调用树(trace、成本、指标),交付可直接上线的服务。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
],
|
|
36
36
|
"scripts": {
|
|
37
37
|
"build": "tsc -p tsconfig.json && node scripts/copy-assets.mjs",
|
|
38
|
-
"build:cli": "npm run build -w @migor/trace-view && tsc -p packages/cli/tsconfig.json && node packages/cli/scripts/copy-assets.mjs",
|
|
38
|
+
"build:cli": "npm run build -w @migor/trace-view && tsc -p packages/cli/tsconfig.json && tsc --noEmit -p packages/cli/tsconfig.templates.json && node packages/cli/scripts/copy-assets.mjs",
|
|
39
39
|
"build:website": "npm run build -w @migor/trace-view && npm run build -w @migor/website",
|
|
40
40
|
"deploy:website": "npm run build:website && npx --yes wrangler@4.131.0 pages deploy packages/website/dist --project-name=agentia-web",
|
|
41
41
|
"prepublishOnly": "node scripts/check-release.mjs && npm run build",
|
|
@@ -57,10 +57,11 @@
|
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
59
|
"@anthropic-ai/sdk": "^0.126.0",
|
|
60
|
-
"@biomejs/biome": "^2.5.
|
|
60
|
+
"@biomejs/biome": "^2.5.14",
|
|
61
61
|
"@grpc/grpc-js": "^1.14.5",
|
|
62
62
|
"@grpc/proto-loader": "^0.8.1",
|
|
63
63
|
"@types/node": "^26.5.1",
|
|
64
|
+
"c8": "^10.1.3",
|
|
64
65
|
"tsx": "^4.19.0",
|
|
65
66
|
"typescript": "^7.0.2",
|
|
66
67
|
"zod": "^4.6.1"
|