@migor/agentia 0.2.1 → 0.2.2
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/LICENSE +21 -0
- package/README.en.md +144 -0
- package/README.md +202 -76
- package/dist/AGENTS.md +811 -0
- package/dist/container/container.d.ts +10 -2
- package/dist/container/container.js +27 -3
- package/dist/container/container.js.map +1 -1
- package/dist/core/abort.d.ts +10 -0
- package/dist/core/abort.js +28 -0
- package/dist/core/abort.js.map +1 -0
- package/dist/core/blackboard.d.ts +37 -0
- package/dist/core/blackboard.js +2 -0
- package/dist/core/blackboard.js.map +1 -0
- package/dist/core/json.d.ts +2 -0
- package/dist/core/json.js +4 -0
- package/dist/core/json.js.map +1 -1
- package/dist/core/run.d.ts +18 -0
- package/dist/core/run.js +2 -0
- package/dist/core/run.js.map +1 -0
- package/dist/core/schema.js +2 -2
- package/dist/core/schema.js.map +1 -1
- package/dist/core/tool.d.ts +62 -7
- package/dist/core/trace.d.ts +20 -4
- package/dist/engine/budget.d.ts +49 -0
- package/dist/engine/budget.js +30 -0
- package/dist/engine/budget.js.map +1 -0
- package/dist/engine/concurrency.d.ts +43 -0
- package/dist/engine/concurrency.js +95 -0
- package/dist/engine/concurrency.js.map +1 -0
- package/dist/engine/errors.d.ts +2 -0
- package/dist/engine/errors.js +7 -0
- package/dist/engine/errors.js.map +1 -1
- package/dist/engine/loop.d.ts +35 -10
- package/dist/engine/loop.js +336 -66
- package/dist/engine/loop.js.map +1 -1
- package/dist/engine/policy.d.ts +9 -1
- package/dist/engine/policy.js +8 -5
- package/dist/engine/policy.js.map +1 -1
- package/dist/engine/replay.d.ts +8 -5
- package/dist/engine/replay.js +30 -29
- package/dist/engine/replay.js.map +1 -1
- package/dist/engine/retry.d.ts +47 -0
- package/dist/engine/retry.js +51 -0
- package/dist/engine/retry.js.map +1 -0
- package/dist/engine/spec.d.ts +61 -0
- package/dist/{run → engine}/spec.js +4 -1
- package/dist/engine/spec.js.map +1 -0
- package/dist/engine/tracer.d.ts +9 -0
- package/dist/engine/tracer.js +57 -1
- package/dist/engine/tracer.js.map +1 -1
- package/dist/engine/{context.d.ts → trimming.d.ts} +19 -20
- package/dist/engine/trimming.js +238 -0
- package/dist/engine/trimming.js.map +1 -0
- package/dist/engine/types.d.ts +109 -13
- package/dist/engine/types.js +9 -1
- package/dist/engine/types.js.map +1 -1
- package/dist/engine/usage.d.ts +28 -2
- package/dist/engine/usage.js +39 -6
- package/dist/engine/usage.js.map +1 -1
- package/dist/eval/defineEval.d.ts +73 -0
- package/dist/eval/defineEval.js +44 -0
- package/dist/eval/defineEval.js.map +1 -0
- package/dist/eval/scripted.d.ts +26 -0
- package/dist/eval/scripted.js +43 -0
- package/dist/eval/scripted.js.map +1 -0
- package/dist/index.d.ts +60 -35
- package/dist/index.js +38 -20
- package/dist/index.js.map +1 -1
- package/dist/integrations/anthropic.d.ts +53 -0
- package/dist/integrations/anthropic.js +24 -0
- package/dist/integrations/anthropic.js.map +1 -0
- package/dist/integrations/mcp.d.ts +79 -0
- package/dist/integrations/mcp.js +108 -0
- package/dist/integrations/mcp.js.map +1 -0
- package/dist/integrations/metrics.d.ts +131 -0
- package/dist/integrations/metrics.js +488 -0
- package/dist/integrations/metrics.js.map +1 -0
- package/dist/{run → integrations}/openai.d.ts +12 -5
- package/dist/integrations/openai.js +386 -0
- package/dist/integrations/openai.js.map +1 -0
- package/dist/integrations/otlp.js.map +1 -0
- package/dist/integrations/report.d.ts +78 -0
- package/dist/integrations/report.js +257 -0
- package/dist/integrations/report.js.map +1 -0
- package/dist/runtime/context.d.ts +25 -0
- package/dist/{run → runtime}/context.js +8 -1
- package/dist/runtime/context.js.map +1 -0
- package/dist/{run → runtime}/memory.d.ts +1 -1
- package/dist/{run → runtime}/memory.js +3 -1
- package/dist/runtime/memory.js.map +1 -0
- package/dist/{run → runtime}/run.d.ts +22 -5
- package/dist/runtime/run.js +218 -0
- package/dist/runtime/run.js.map +1 -0
- package/dist/runtime/session.d.ts +27 -0
- package/dist/runtime/session.js +16 -0
- package/dist/runtime/session.js.map +1 -0
- package/dist/{run → runtime}/spec.d.ts +16 -2
- package/dist/runtime/spec.js +28 -0
- package/dist/runtime/spec.js.map +1 -0
- package/dist/{run → runtime}/systemPrompt.d.ts +12 -0
- package/dist/{run → runtime}/systemPrompt.js +16 -3
- package/dist/runtime/systemPrompt.js.map +1 -0
- package/dist/{run → runtime}/types.js.map +1 -1
- package/dist/{run → store}/fsStore.d.ts +15 -0
- package/dist/{run → store}/fsStore.js +43 -1
- package/dist/store/fsStore.js.map +1 -0
- package/dist/{run → store}/redisStore.d.ts +19 -1
- package/dist/{run → store}/redisStore.js +33 -6
- package/dist/store/redisStore.js.map +1 -0
- package/dist/{run → store}/sqliteStore.js +22 -1
- package/dist/store/sqliteStore.js.map +1 -0
- package/dist/{run → store}/store.d.ts +25 -3
- package/dist/store/store.js +63 -0
- package/dist/store/store.js.map +1 -0
- package/dist/toolkit/asset.d.ts +7 -6
- package/dist/toolkit/asset.js +7 -6
- package/dist/toolkit/asset.js.map +1 -1
- package/dist/toolkit/collect.d.ts +20 -7
- package/dist/toolkit/collect.js +21 -7
- package/dist/toolkit/collect.js.map +1 -1
- package/dist/toolkit/discover.d.ts +21 -1
- package/dist/toolkit/discover.js +59 -12
- package/dist/toolkit/discover.js.map +1 -1
- package/dist/toolkit/middleware.d.ts +10 -10
- package/dist/toolkit/middleware.js +17 -4
- package/dist/toolkit/middleware.js.map +1 -1
- package/dist/toolkit/module.d.ts +100 -34
- package/dist/toolkit/module.js +112 -36
- package/dist/toolkit/module.js.map +1 -1
- package/dist/toolkit/prompt.d.ts +4 -6
- package/dist/toolkit/prompt.js +11 -10
- package/dist/toolkit/prompt.js.map +1 -1
- package/dist/toolkit/skill.d.ts +14 -16
- package/dist/toolkit/skill.js +32 -25
- package/dist/toolkit/skill.js.map +1 -1
- package/dist/toolkit/subagent.d.ts +10 -12
- package/dist/toolkit/subagent.js +23 -21
- package/dist/toolkit/subagent.js.map +1 -1
- package/dist/toolkit/tool.d.ts +19 -11
- package/dist/toolkit/tool.js +11 -8
- package/dist/toolkit/tool.js.map +1 -1
- package/dist/toolkit/zod.d.ts +4 -3
- package/dist/toolkit/zod.js +2 -1
- package/dist/toolkit/zod.js.map +1 -1
- package/dist/transport/async.d.ts +133 -0
- package/dist/transport/async.js +415 -0
- package/dist/transport/async.js.map +1 -0
- package/dist/transport/http.d.ts +146 -0
- package/dist/transport/http.js +387 -0
- package/dist/transport/http.js.map +1 -0
- package/dist/{run → transport}/scheduler.d.ts +9 -1
- package/dist/transport/scheduler.js +133 -0
- package/dist/transport/scheduler.js.map +1 -0
- package/dist/transport/sse.d.ts +43 -0
- package/dist/transport/sse.js +51 -0
- package/dist/transport/sse.js.map +1 -0
- package/dist/{run → transport}/transport.d.ts +1 -1
- package/dist/{run → transport}/transport.js +1 -1
- package/dist/transport/transport.js.map +1 -0
- package/package.json +24 -9
- package/dist/engine/context.js +0 -146
- package/dist/engine/context.js.map +0 -1
- package/dist/run/async.d.ts +0 -59
- package/dist/run/async.js +0 -201
- package/dist/run/async.js.map +0 -1
- package/dist/run/context.d.ts +0 -16
- package/dist/run/context.js.map +0 -1
- package/dist/run/fsStore.js.map +0 -1
- package/dist/run/http.d.ts +0 -47
- package/dist/run/http.js +0 -119
- package/dist/run/http.js.map +0 -1
- package/dist/run/memory.js.map +0 -1
- package/dist/run/openai.js +0 -181
- package/dist/run/openai.js.map +0 -1
- package/dist/run/otlp.js.map +0 -1
- package/dist/run/redisStore.js.map +0 -1
- package/dist/run/run.js +0 -129
- package/dist/run/run.js.map +0 -1
- package/dist/run/scheduler.js +0 -85
- package/dist/run/scheduler.js.map +0 -1
- package/dist/run/spec.js.map +0 -1
- package/dist/run/sqliteStore.js.map +0 -1
- package/dist/run/store.js +0 -28
- package/dist/run/store.js.map +0 -1
- package/dist/run/systemPrompt.js.map +0 -1
- package/dist/run/transport.js.map +0 -1
- /package/dist/{run → integrations}/otlp.d.ts +0 -0
- /package/dist/{run → integrations}/otlp.js +0 -0
- /package/dist/{run → runtime}/types.d.ts +0 -0
- /package/dist/{run → runtime}/types.js +0 -0
- /package/dist/{run → store}/sqliteStore.d.ts +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defineEval.js","sourceRoot":"","sources":["../../src/eval/defineEval.ts"],"names":[],"mappings":"AAwEA,SAAS,SAAS,CAAC,CAAU;IAC3B,OAAO,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACpD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CACxB,GAAsB;IAEtB,OAAO;QACL,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,KAAK,CAAC,GAAG;YACP,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,GAAG,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAqB,EAAE,CAAC;YAEnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC1C,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBACvB,MAAM,KAAK,GAAG,CAAC,CAAC,IAAI,IAAI,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACxC,MAAM,QAAQ,GAA6B,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;gBAChF,IAAI,MAAM,GAAmB,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;gBACxD,IAAI,CAAC;oBACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;oBAC5E,MAAM,KAAK,GAAG,MAA2B,CAAC;oBAC1C,+CAA+C;oBAC/C,MAAM,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;oBACvF,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;gBACnD,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,MAAM,GAAG,EAAE,GAAG,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzD,CAAC;gBACD,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACrB,CAAC;YAED,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC;YAChD,OAAO;gBACL,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,KAAK,EAAE,KAAK,CAAC,MAAM;gBACnB,MAAM;gBACN,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM;gBAC7B,EAAE,EAAE,MAAM,KAAK,KAAK,CAAC,MAAM;gBAC3B,KAAK;aACN,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ModelClient } from '../core/tool.js';
|
|
2
|
+
/**
|
|
3
|
+
* Agentia —— 脚本化模型客户端(D2,evals)。
|
|
4
|
+
*
|
|
5
|
+
* 把测试里那个手写的 `mockClient` 提升为一等能力:按脚本依次返回**模型响应**,
|
|
6
|
+
* 于是「改 prompt / 换模型 / 加工具之后有没有回归」可以写成断言,而不是靠人眼看。
|
|
7
|
+
* 这是 agent 服务最缺的一环 —— 单测覆盖的是框架语义,evals 覆盖的是**你的 agent 语义**。
|
|
8
|
+
*
|
|
9
|
+
* 与 `tests/helpers.ts` 的 mockClient 的差别(为什么不是同一个东西):
|
|
10
|
+
* - 这里是**公共 API**,走 `ModelClient` 类型,能在用户项目里用(mockClient 是测试夹具);
|
|
11
|
+
* - 这里会**真的把文本块逐块通过 `on('text')` 吐出去** —— 于是 `onText` / SSE 链路
|
|
12
|
+
* 在 eval 里也真实走一遍(mockClient 直接忽略 `on`);副作用是「已吐字不重试」这类
|
|
13
|
+
* 与流式相关的分支在 eval 里也按真实路径走;
|
|
14
|
+
* - 步骤耗尽会抛错(而不是静默返回 undefined),脚本与 agent 行为不匹配时立刻可见。
|
|
15
|
+
*/
|
|
16
|
+
/** 一步脚本:直接给响应对象,或按本次请求参数现算(`(params) => message`) */
|
|
17
|
+
export type ScriptedStep = Record<string, unknown> | ((params: unknown) => Record<string, unknown> | Promise<Record<string, unknown>>);
|
|
18
|
+
/**
|
|
19
|
+
* 按脚本依次返回模型响应。
|
|
20
|
+
*
|
|
21
|
+
* 消费时机:**在 `finalMessage()` 成功返回之后**才前进到下一步 —— 于是
|
|
22
|
+
* ① 抛错的步骤(用函数步骤 `throw` 模拟 429 / 网络失败)会在重试时**重放同一步**,
|
|
23
|
+
* 想验重试就写 `(params) => { if (++n === 1) throw ...; return msg; }`;
|
|
24
|
+
* ② 脚本耗尽时报错指向「第几次调用」,一眼看出 agent 多调了一轮模型。
|
|
25
|
+
*/
|
|
26
|
+
export declare function scriptedClient(steps: ScriptedStep[]): ModelClient;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 按脚本依次返回模型响应。
|
|
3
|
+
*
|
|
4
|
+
* 消费时机:**在 `finalMessage()` 成功返回之后**才前进到下一步 —— 于是
|
|
5
|
+
* ① 抛错的步骤(用函数步骤 `throw` 模拟 429 / 网络失败)会在重试时**重放同一步**,
|
|
6
|
+
* 想验重试就写 `(params) => { if (++n === 1) throw ...; return msg; }`;
|
|
7
|
+
* ② 脚本耗尽时报错指向「第几次调用」,一眼看出 agent 多调了一轮模型。
|
|
8
|
+
*/
|
|
9
|
+
export function scriptedClient(steps) {
|
|
10
|
+
let cursor = 0;
|
|
11
|
+
return {
|
|
12
|
+
messages: {
|
|
13
|
+
stream(params) {
|
|
14
|
+
const handlers = [];
|
|
15
|
+
return {
|
|
16
|
+
on(event, cb) {
|
|
17
|
+
if (event === 'text')
|
|
18
|
+
handlers.push(cb);
|
|
19
|
+
},
|
|
20
|
+
async finalMessage() {
|
|
21
|
+
const step = steps[cursor];
|
|
22
|
+
if (step === undefined) {
|
|
23
|
+
throw new Error(`scriptedClient 脚本耗尽:第 ${cursor + 1} 次调用模型,但只给了 ${steps.length} 步`);
|
|
24
|
+
}
|
|
25
|
+
const message = (await (typeof step === 'function'
|
|
26
|
+
? step(params)
|
|
27
|
+
: step));
|
|
28
|
+
// 真的逐块吐文本 —— onText / SSE 链路在 eval 里按真实路径走一遍
|
|
29
|
+
for (const block of (message.content ?? [])) {
|
|
30
|
+
if (block.type === 'text' && block.text) {
|
|
31
|
+
for (const h of handlers)
|
|
32
|
+
h(block.text);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
cursor++;
|
|
36
|
+
return message;
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=scripted.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scripted.js","sourceRoot":"","sources":["../../src/eval/scripted.ts"],"names":[],"mappings":"AAuBA;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,KAAqB;IAClD,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,OAAO;QACL,QAAQ,EAAE;YACR,MAAM,CAAC,MAAe;gBACpB,MAAM,QAAQ,GAAmC,EAAE,CAAC;gBACpD,OAAO;oBACL,EAAE,CAAC,KAAa,EAAE,EAA2B;wBAC3C,IAAI,KAAK,KAAK,MAAM;4BAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBAC1C,CAAC;oBACD,KAAK,CAAC,YAAY;wBAChB,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;wBAC3B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;4BACvB,MAAM,IAAI,KAAK,CACb,yBAAyB,MAAM,GAAG,CAAC,eAAe,KAAK,CAAC,MAAM,IAAI,CACnE,CAAC;wBACJ,CAAC;wBACD,MAAM,OAAO,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,KAAK,UAAU;4BAChD,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;4BACd,CAAC,CAAC,IAAI,CAAC,CAAiC,CAAC;wBAC3C,6CAA6C;wBAC7C,KAAK,MAAM,KAAK,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAGxC,EAAE,CAAC;4BACH,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gCACxC,KAAK,MAAM,CAAC,IAAI,QAAQ;oCAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;4BAC1C,CAAC;wBACH,CAAC;wBACD,MAAM,EAAE,CAAC;wBACT,OAAO,OAAO,CAAC;oBACjB,CAAC;iBACF,CAAC;YACJ,CAAC;SACF;KACa,CAAC;AACnB,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,58 +1,83 @@
|
|
|
1
|
-
export declare const AGENTIA_VERSION = "0.2.
|
|
2
|
-
export type { Trace, Span, SpanEvent, SpanError, SpanId, SpanKind, SpanStatus, TraceId,
|
|
3
|
-
export type { AgentTool, JsonSchema, ModelClient, RecorderBackend, ToolRunContext } from './core/tool.js';
|
|
1
|
+
export declare const AGENTIA_VERSION = "0.2.2";
|
|
2
|
+
export type { Trace, Span, SpanEvent, SpanError, SpanId, SpanKind, SpanStatus, TraceId, TraceSink, CapabilityType, Usage, } from './core/trace.js';
|
|
3
|
+
export type { AgentTool, JsonSchema, ModelClient, RecorderBackend, SchemaInput, SchemaType, ToolRunContext, TypedSchema, } from './core/tool.js';
|
|
4
4
|
export { validateJsonSchema } from './core/schema.js';
|
|
5
|
+
export { combineSignals } from './core/abort.js';
|
|
5
6
|
export { runAgent, resolveDefaultModel } from './engine/loop.js';
|
|
6
7
|
export { TraceRecorder } from './engine/tracer.js';
|
|
7
|
-
export { classifyError } from './engine/errors.js';
|
|
8
|
+
export { classifyError, isAbortError } from './engine/errors.js';
|
|
9
|
+
export { isSuccessStopReason } from './engine/types.js';
|
|
8
10
|
export type { AgentRunResult, AgentStopReason, ContextPolicy, RunAgentOptions, SystemParam, SystemTextBlock, } from './engine/types.js';
|
|
9
|
-
export { defaultEstimateTokens, estimateMessages, renderMessages, trimToolPairs, compactMessages, } from './engine/
|
|
10
|
-
export type { CompactOptions, TrimOptions } from './engine/
|
|
11
|
+
export { defaultEstimateTokens, estimateMessages, renderMessages, trimToolPairs, compactMessages, } from './engine/trimming.js';
|
|
12
|
+
export type { CompactOptions, TrimOptions } from './engine/trimming.js';
|
|
11
13
|
export { createBudgetPolicy } from './engine/policy.js';
|
|
12
14
|
export type { BudgetPolicyOptions } from './engine/policy.js';
|
|
13
|
-
export {
|
|
14
|
-
export {
|
|
15
|
-
export {
|
|
16
|
-
export type {
|
|
17
|
-
export
|
|
18
|
-
export
|
|
15
|
+
export { createBudgetGuard } from './engine/budget.js';
|
|
16
|
+
export type { BudgetGuard, BudgetGuardOptions, BudgetSnapshot } from './engine/budget.js';
|
|
17
|
+
export { DEFAULT_PRICING, buildPricing } from './engine/usage.js';
|
|
18
|
+
export type { ModelPricing } from './core/tool.js';
|
|
19
|
+
export { mapWithConcurrency } from './engine/concurrency.js';
|
|
20
|
+
export { DEFAULT_RETRY } from './engine/retry.js';
|
|
21
|
+
export type { RetryOptions } from './engine/retry.js';
|
|
22
|
+
export { Run, executeRun } from './runtime/run.js';
|
|
23
|
+
export { RunContext, withRunContext } from './runtime/context.js';
|
|
24
|
+
export type { Blackboard, BlackboardKey, BlackboardSeed, BlackboardValue, } from './core/blackboard.js';
|
|
25
|
+
export { SystemPrompt } from './runtime/systemPrompt.js';
|
|
26
|
+
export type { SystemPromptOptions, SystemSection } from './runtime/systemPrompt.js';
|
|
27
|
+
export type { ExecuteRunOptions } from './runtime/run.js';
|
|
28
|
+
export type { RunMeta, RunStatus } from './core/run.js';
|
|
19
29
|
export { Container } from './container/container.js';
|
|
20
30
|
export type { Provider, ClassProvider, ValueProvider, FactoryProvider, Token, } from './container/container.js';
|
|
21
31
|
export { asset } from './toolkit/asset.js';
|
|
22
32
|
export { discoverProviders } from './toolkit/discover.js';
|
|
23
33
|
export { applyMiddleware } from './toolkit/middleware.js';
|
|
24
|
-
export type {
|
|
34
|
+
export type { CapabilityCall, CapabilityMiddleware, CapabilityNext } from './toolkit/middleware.js';
|
|
25
35
|
export { Tool, collectTools } from './toolkit/tool.js';
|
|
26
36
|
export type { ToolSpec } from './toolkit/tool.js';
|
|
27
37
|
export { SubAgent, collectSubAgents, subagentToTool } from './toolkit/subagent.js';
|
|
28
|
-
export type { SubAgentSpec,
|
|
38
|
+
export type { SubAgentSpec, SubAgentCapability } from './toolkit/subagent.js';
|
|
29
39
|
export { Skill, collectSkills, skillToTool } from './toolkit/skill.js';
|
|
30
|
-
export type { SkillContext, SkillLlmOptions, SkillLlmResult, SkillSpec,
|
|
40
|
+
export type { SkillContext, SkillLlmOptions, SkillLlmResult, SkillSpec, SkillCapability, } from './toolkit/skill.js';
|
|
31
41
|
export { Prompt, collectPrompts } from './toolkit/prompt.js';
|
|
32
42
|
export type { PromptSpec } from './toolkit/prompt.js';
|
|
33
|
-
export { createApp, AgentApp } from './toolkit/module.js';
|
|
43
|
+
export { createApp, AgentApp, registerDefaultTraceSink } from './toolkit/module.js';
|
|
34
44
|
export type { AppOptions, RunAppOptions, AgentRunOutput } from './toolkit/module.js';
|
|
35
45
|
export { defineModule } from './toolkit/module.js';
|
|
36
46
|
export type { AgentModule } from './toolkit/module.js';
|
|
37
47
|
export { fromZod } from './toolkit/zod.js';
|
|
38
|
-
export { normalizeMessages } from './
|
|
39
|
-
export type { RunInput, RunSpec, RunInvocationOptions } from './
|
|
40
|
-
export { InMemoryTaskStore } from './
|
|
41
|
-
export type { TaskRecord, TaskStore } from './
|
|
42
|
-
export { FileTaskStore } from './
|
|
43
|
-
export { AsyncRunner } from './
|
|
44
|
-
export type { AsyncRunnerOptions,
|
|
45
|
-
export { Scheduler } from './
|
|
46
|
-
export type { ScheduleEveryOptions, ScheduleHandle } from './
|
|
47
|
-
export { runSync, createSyncHandler } from './
|
|
48
|
-
export { createHttpHandler } from './
|
|
49
|
-
export {
|
|
50
|
-
export {
|
|
51
|
-
export {
|
|
52
|
-
export {
|
|
53
|
-
export
|
|
54
|
-
export {
|
|
55
|
-
export
|
|
56
|
-
export type {
|
|
48
|
+
export { normalizeMessages } from './engine/spec.js';
|
|
49
|
+
export type { RunInput, RunSpec, RunInvocationOptions } from './engine/spec.js';
|
|
50
|
+
export { InMemoryTaskStore } from './store/store.js';
|
|
51
|
+
export type { TaskRecord, TaskStore } from './store/store.js';
|
|
52
|
+
export { FileTaskStore } from './store/fsStore.js';
|
|
53
|
+
export { AsyncRunner } from './transport/async.js';
|
|
54
|
+
export type { AppCallable, AsyncRunnerOptions, ResumePendingOptions, TaskSink, } from './transport/async.js';
|
|
55
|
+
export { Scheduler } from './transport/scheduler.js';
|
|
56
|
+
export type { ScheduleEveryOptions, ScheduleHandle } from './transport/scheduler.js';
|
|
57
|
+
export { runSync, createSyncHandler } from './transport/transport.js';
|
|
58
|
+
export { createHttpHandler, HttpException } from './transport/http.js';
|
|
59
|
+
export type { HttpHandlerOptions, HttpHandler, HealthResponse, RunHttpResponse, TaskSubmitBody, } from './transport/http.js';
|
|
60
|
+
export { SqliteTaskStore } from './store/sqliteStore.js';
|
|
61
|
+
export { createOtlpExporter } from './integrations/otlp.js';
|
|
62
|
+
export { createOpenAIClient } from './integrations/openai.js';
|
|
63
|
+
export { createAnthropicClient } from './integrations/anthropic.js';
|
|
64
|
+
export type { AnthropicClientOptions } from './integrations/anthropic.js';
|
|
65
|
+
export { InMemoryMemoryStore } from './runtime/memory.js';
|
|
66
|
+
export type { MemoryStore } from './runtime/memory.js';
|
|
67
|
+
export { InMemorySessionStore } from './runtime/session.js';
|
|
68
|
+
export type { SessionStore } from './runtime/session.js';
|
|
69
|
+
export { RedisTaskStore } from './store/redisStore.js';
|
|
70
|
+
export type { RedisLike, RedisSetOptions, RedisTaskStoreOptions } from './store/redisStore.js';
|
|
71
|
+
export type { MaybePromise } from './store/store.js';
|
|
57
72
|
export { traceToMessages } from './engine/replay.js';
|
|
58
73
|
export type { ReplayOptions } from './engine/replay.js';
|
|
74
|
+
export { mcpTools, MCP_DEFAULT_TIMEOUT_MS } from './integrations/mcp.js';
|
|
75
|
+
export type { McpClientLike, McpToolInfo, McpToolsOptions } from './integrations/mcp.js';
|
|
76
|
+
export { metricsSink, DEFAULT_BUCKETS } from './integrations/metrics.js';
|
|
77
|
+
export type { MetricsSink, MetricsSinkOptions, MetricsSnapshot, ModelMetrics, CapabilityMetrics, } from './integrations/metrics.js';
|
|
78
|
+
export { buildRunReport, mergeRunReports, renderRunReport } from './integrations/report.js';
|
|
79
|
+
export type { DurationReport, ModelReport, RunReport, CapabilityReport, } from './integrations/report.js';
|
|
80
|
+
export { scriptedClient } from './eval/scripted.js';
|
|
81
|
+
export type { ScriptedStep } from './eval/scripted.js';
|
|
82
|
+
export { defineEval } from './eval/defineEval.js';
|
|
83
|
+
export type { EvalCase, EvalCaseReport, EvalContext, EvalDefinition, EvalReport, } from './eval/defineEval.js';
|
package/dist/index.js
CHANGED
|
@@ -1,19 +1,26 @@
|
|
|
1
|
-
export const AGENTIA_VERSION = '0.2.
|
|
1
|
+
export const AGENTIA_VERSION = '0.2.2';
|
|
2
2
|
export { validateJsonSchema } from './core/schema.js';
|
|
3
|
+
export { combineSignals } from './core/abort.js';
|
|
3
4
|
// engine:运行时内核
|
|
4
5
|
export { runAgent, resolveDefaultModel } from './engine/loop.js';
|
|
5
6
|
export { TraceRecorder } from './engine/tracer.js';
|
|
6
|
-
export { classifyError } from './engine/errors.js';
|
|
7
|
+
export { classifyError, isAbortError } from './engine/errors.js';
|
|
8
|
+
export { isSuccessStopReason } from './engine/types.js';
|
|
7
9
|
// engine:长上下文策略
|
|
8
|
-
export { defaultEstimateTokens, estimateMessages, renderMessages, trimToolPairs, compactMessages, } from './engine/
|
|
10
|
+
export { defaultEstimateTokens, estimateMessages, renderMessages, trimToolPairs, compactMessages, } from './engine/trimming.js';
|
|
9
11
|
export { createBudgetPolicy } from './engine/policy.js';
|
|
12
|
+
export { createBudgetGuard } from './engine/budget.js';
|
|
13
|
+
// engine:用量与成本(F1 价格表可注入 / F2 未定价显式)
|
|
14
|
+
export { DEFAULT_PRICING, buildPricing } from './engine/usage.js';
|
|
15
|
+
export { mapWithConcurrency } from './engine/concurrency.js';
|
|
16
|
+
export { DEFAULT_RETRY } from './engine/retry.js';
|
|
10
17
|
// run:run 生命周期
|
|
11
|
-
export { Run, executeRun } from './
|
|
12
|
-
export { RunContext, withRunContext } from './
|
|
13
|
-
export { SystemPrompt } from './
|
|
18
|
+
export { Run, executeRun } from './runtime/run.js';
|
|
19
|
+
export { RunContext, withRunContext } from './runtime/context.js';
|
|
20
|
+
export { SystemPrompt } from './runtime/systemPrompt.js';
|
|
14
21
|
// container:显式 DI
|
|
15
22
|
export { Container } from './container/container.js';
|
|
16
|
-
// toolkit
|
|
23
|
+
// toolkit:声明式能力 + 应用装配
|
|
17
24
|
export { asset } from './toolkit/asset.js';
|
|
18
25
|
export { discoverProviders } from './toolkit/discover.js';
|
|
19
26
|
export { applyMiddleware } from './toolkit/middleware.js';
|
|
@@ -21,22 +28,33 @@ export { Tool, collectTools } from './toolkit/tool.js';
|
|
|
21
28
|
export { SubAgent, collectSubAgents, subagentToTool } from './toolkit/subagent.js';
|
|
22
29
|
export { Skill, collectSkills, skillToTool } from './toolkit/skill.js';
|
|
23
30
|
export { Prompt, collectPrompts } from './toolkit/prompt.js';
|
|
24
|
-
export { createApp, AgentApp } from './toolkit/module.js';
|
|
31
|
+
export { createApp, AgentApp, registerDefaultTraceSink } from './toolkit/module.js';
|
|
25
32
|
export { defineModule } from './toolkit/module.js';
|
|
26
33
|
export { fromZod } from './toolkit/zod.js';
|
|
27
34
|
// run:触发传输 + run 存储
|
|
28
|
-
export { normalizeMessages } from './
|
|
29
|
-
export { InMemoryTaskStore } from './
|
|
30
|
-
export { FileTaskStore } from './
|
|
31
|
-
export { AsyncRunner } from './
|
|
32
|
-
export { Scheduler } from './
|
|
33
|
-
export { runSync, createSyncHandler } from './
|
|
35
|
+
export { normalizeMessages } from './engine/spec.js';
|
|
36
|
+
export { InMemoryTaskStore } from './store/store.js';
|
|
37
|
+
export { FileTaskStore } from './store/fsStore.js';
|
|
38
|
+
export { AsyncRunner } from './transport/async.js';
|
|
39
|
+
export { Scheduler } from './transport/scheduler.js';
|
|
40
|
+
export { runSync, createSyncHandler } from './transport/transport.js';
|
|
34
41
|
// run:宿主与导出(R3/R4)
|
|
35
|
-
export { createHttpHandler } from './
|
|
36
|
-
export { SqliteTaskStore } from './
|
|
37
|
-
export { createOtlpExporter } from './
|
|
38
|
-
export { createOpenAIClient } from './
|
|
39
|
-
export {
|
|
40
|
-
export {
|
|
42
|
+
export { createHttpHandler, HttpException } from './transport/http.js';
|
|
43
|
+
export { SqliteTaskStore } from './store/sqliteStore.js';
|
|
44
|
+
export { createOtlpExporter } from './integrations/otlp.js';
|
|
45
|
+
export { createOpenAIClient } from './integrations/openai.js';
|
|
46
|
+
export { createAnthropicClient } from './integrations/anthropic.js';
|
|
47
|
+
export { InMemoryMemoryStore } from './runtime/memory.js';
|
|
48
|
+
export { InMemorySessionStore } from './runtime/session.js';
|
|
49
|
+
export { RedisTaskStore } from './store/redisStore.js';
|
|
41
50
|
export { traceToMessages } from './engine/replay.js';
|
|
51
|
+
// integrations:MCP 桥(D1)—— duck-typed,框架零依赖;连接器在独立包 @migor/mcp
|
|
52
|
+
export { mcpTools, MCP_DEFAULT_TIMEOUT_MS } from './integrations/mcp.js';
|
|
53
|
+
// integrations:指标(D3 → E2/E3/E4/E5)—— 满足 TraceSink 即可接入,能力零新出口
|
|
54
|
+
export { metricsSink, DEFAULT_BUCKETS } from './integrations/metrics.js';
|
|
55
|
+
// integrations:调优报告(G1)—— 纯函数,从 trace 派生「哪个能力慢/贵/爱失败」
|
|
56
|
+
export { buildRunReport, mergeRunReports, renderRunReport } from './integrations/report.js';
|
|
57
|
+
// eval:把 mockClient 提升为一等能力(D2)—— 叶子消费模块,只依赖公共面
|
|
58
|
+
export { scriptedClient } from './eval/scripted.js';
|
|
59
|
+
export { defineEval } from './eval/defineEval.js';
|
|
42
60
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { ModelClient } from '../core/tool.js';
|
|
2
|
+
/**
|
|
3
|
+
* Agentia —— 默认 ModelClient:Anthropic Messages API。
|
|
4
|
+
*
|
|
5
|
+
* **为什么要有这个工厂**:这是 `@anthropic-ai/sdk` 在框架内的**唯一实例化点**。
|
|
6
|
+
* 引擎(`engine/loop.ts`)只经由此处取默认 client,不再散落 `new Anthropic()`。两个好处:
|
|
7
|
+
*
|
|
8
|
+
* ① **使用者不必接触厂商 SDK 的类** —— 想自定义只传 `apiKey` / `baseURL`
|
|
9
|
+
* (或直接用环境变量 `ANTHROPIC_API_KEY` / `ANTHROPIC_BASE_URL`);
|
|
10
|
+
* ② 厂商 SDK 成为一个**可替换的实现细节** —— 将来若换自研 fetch 实现(去掉依赖),
|
|
11
|
+
* 只动这一个文件,引擎与公共契约都不变。
|
|
12
|
+
*
|
|
13
|
+
* 契约:返回值必须满足 `core` 的 `ModelClient` 结构面。
|
|
14
|
+
*
|
|
15
|
+
* ⚠️ **不能直接 `return new Anthropic(...)`**(2026-09-14 修):`ModelClient` 契约把 `signal`
|
|
16
|
+
* 放在 **params 内部**,而 SDK 的签名是 `stream(body, options?)`,`signal` **只在 `RequestOptions`
|
|
17
|
+
* 里认**。把 signal 放 body 里会被 SDK **静默丢弃** ⇒ 调用方无法中止在飞请求。
|
|
18
|
+
* 真端点实测(`scripts/e2e-live.ts` 步骤 ⑤):
|
|
19
|
+
*
|
|
20
|
+
* | signal 位置 | abort 后的实测结果 |
|
|
21
|
+
* |---|---|
|
|
22
|
+
* | body 内(旧实现) | 收到 **599 个分片后仍跑完**,1.4s 才结束 —— 中止被吞 |
|
|
23
|
+
* | RequestOptions(现实现) | 2 个分片即断,**1ms** 内以 `Request was aborted.` 收场 |
|
|
24
|
+
*
|
|
25
|
+
* 这不只是「少个功能」:`transport/async.ts` 的 `runTimeoutMs` 对外承诺「到点真中止、
|
|
26
|
+
* token 不再继续烧」,靠的就是这个 signal。旧实现下超时的 run 会在后台**继续烧 token**
|
|
27
|
+
* 直到模型自己说完。`integrations/openai.ts` 是手写 fetch,本来就转发 signal(无此问题)。
|
|
28
|
+
*/
|
|
29
|
+
export interface AnthropicClientOptions {
|
|
30
|
+
/** 缺省读环境变量 `ANTHROPIC_API_KEY` */
|
|
31
|
+
apiKey?: string;
|
|
32
|
+
/** 缺省读环境变量 `ANTHROPIC_BASE_URL`(兼容端点 / 网关) */
|
|
33
|
+
baseURL?: string;
|
|
34
|
+
/** 其余构造参数原样透传给 SDK(高级用法) */
|
|
35
|
+
[key: string]: unknown;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* 把 `ModelClient` 契约里的 `signal`(在 params 内部)拆到 SDK 的 `RequestOptions` 上。
|
|
39
|
+
*
|
|
40
|
+
* 单独导出只为**可测**:这是「默认 client 到底能不能中止在飞请求」的唯一分界点,
|
|
41
|
+
* 白盒探查 SDK 内部不现实,但这一步的输入/输出可以钉死(见 `tests/integrations/anthropic.test.ts`)。
|
|
42
|
+
*/
|
|
43
|
+
export declare function splitSignal(params: {
|
|
44
|
+
signal?: AbortSignal | null;
|
|
45
|
+
[key: string]: unknown;
|
|
46
|
+
}): {
|
|
47
|
+
body: Record<string, unknown>;
|
|
48
|
+
options: {
|
|
49
|
+
signal?: AbortSignal;
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
/** 创建默认 ModelClient(Anthropic)。不传则完全走 SDK 的默认凭据解析。 */
|
|
53
|
+
export declare function createAnthropicClient(options?: AnthropicClientOptions): ModelClient;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import Anthropic from '@anthropic-ai/sdk';
|
|
2
|
+
/**
|
|
3
|
+
* 把 `ModelClient` 契约里的 `signal`(在 params 内部)拆到 SDK 的 `RequestOptions` 上。
|
|
4
|
+
*
|
|
5
|
+
* 单独导出只为**可测**:这是「默认 client 到底能不能中止在飞请求」的唯一分界点,
|
|
6
|
+
* 白盒探查 SDK 内部不现实,但这一步的输入/输出可以钉死(见 `tests/integrations/anthropic.test.ts`)。
|
|
7
|
+
*/
|
|
8
|
+
export function splitSignal(params) {
|
|
9
|
+
const { signal, ...body } = params;
|
|
10
|
+
return { body, options: signal ? { signal } : {} };
|
|
11
|
+
}
|
|
12
|
+
/** 创建默认 ModelClient(Anthropic)。不传则完全走 SDK 的默认凭据解析。 */
|
|
13
|
+
export function createAnthropicClient(options = {}) {
|
|
14
|
+
const client = new Anthropic(options);
|
|
15
|
+
const messages = client.messages;
|
|
16
|
+
const nativeStream = messages.stream.bind(messages);
|
|
17
|
+
// 包一层:把契约里的 signal 搬到 RequestOptions(详见文件头注释里的实测对照表)。
|
|
18
|
+
messages.stream = ((body, requestOptions) => {
|
|
19
|
+
const { body: cleanBody, options: signalOptions } = splitSignal(body);
|
|
20
|
+
return nativeStream(cleanBody, { ...requestOptions, ...signalOptions });
|
|
21
|
+
});
|
|
22
|
+
return client;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=anthropic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/integrations/anthropic.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAuC1C;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,MAA+D;IAIzF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,MAAM,CAAC;IACnC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AACrD,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,qBAAqB,CAAC,OAAO,GAA2B,EAAE;IACxE,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,OAAqD,CAAC,CAAC;IACpF,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;IACjC,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACpD,sDAAsD;IACtD,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,IAA6B,EAAE,cAAwC,EAAE,EAAE;QAC7F,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QACtE,OAAO,YAAY,CAAC,SAAkB,EAAE,EAAE,GAAG,cAAc,EAAE,GAAG,aAAa,EAAE,CAAC,CAAC;IACnF,CAAC,CAA2B,CAAC;IAC7B,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { AgentTool } from '../core/tool.js';
|
|
2
|
+
/**
|
|
3
|
+
* Agentia —— MCP 桥(D1,spec §10 决策记录)。
|
|
4
|
+
*
|
|
5
|
+
* 设计原则同 `RedisLike`:框架只定义**结构面**,不 import `@modelcontextprotocol/sdk`,
|
|
6
|
+
* 也**不含任何传输实现**(stdio spawn / StreamableHTTP 都在独立可选包 `@migor/mcp`,
|
|
7
|
+
* 或用户自己接 SDK 后实现 `McpClientLike`)。本文件只依赖 core,符合分层约定
|
|
8
|
+
* (`integrations` → `core`)。
|
|
9
|
+
*
|
|
10
|
+
* 用法:在 `createApp({ providers })` 里放一个 provider 即可 ——
|
|
11
|
+
* ```ts
|
|
12
|
+
* createApp({
|
|
13
|
+
* system: '…',
|
|
14
|
+
* providers: [{ provide: 'mcp', useFactory: () => mcpTools(client, { server: 'time' }) }],
|
|
15
|
+
* });
|
|
16
|
+
* ```
|
|
17
|
+
* 复用既有装配 / 查重 / 中间件,**零新机制**(MCP 工具与本地 @Tool 同处一个命名空间,
|
|
18
|
+
* 重名由 AgentApp 的装配期查重拦下)。
|
|
19
|
+
*
|
|
20
|
+
* 不做(YAGNI,见 spec §10):`sampling`(server 反向请求模型)、`resources` / `prompts`
|
|
21
|
+
* 原语(只做 tools)、连接池。
|
|
22
|
+
*/
|
|
23
|
+
/** MCP server 的 `tools/list` 条目(结构面子集:多出来的字段一律忽略) */
|
|
24
|
+
export interface McpToolInfo {
|
|
25
|
+
name: string;
|
|
26
|
+
description?: string;
|
|
27
|
+
/** MCP 协议里已是 JSON Schema → 直接当框架的 `inputSchema` 用 */
|
|
28
|
+
inputSchema?: unknown;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* MCP client 的最小结构面:任何实现了 `tools/list` + `tools/call` 的客户端都能接,
|
|
32
|
+
* 无需继承、无需 import 任何 SDK(duck-typed,与 `RedisLike` 同款)。
|
|
33
|
+
*
|
|
34
|
+
* 约定:`callTool` 失败请**抛错**(框架会包成 `is_error` 的 tool_result 回给模型,
|
|
35
|
+
* 不中断 run —— 与本地工具抛错同语义)。MCP 协议层的 `isError: true` 请由连接器
|
|
36
|
+
* 转成抛错,否则模型看不到失败。
|
|
37
|
+
*/
|
|
38
|
+
export interface McpClientLike {
|
|
39
|
+
listTools(): Promise<McpToolInfo[]>;
|
|
40
|
+
callTool(name: string, args: Record<string, unknown>): Promise<unknown>;
|
|
41
|
+
}
|
|
42
|
+
export interface McpToolsOptions {
|
|
43
|
+
/**
|
|
44
|
+
* 工具名前缀,避免与本地能力撞名。缺省 `mcp_<server>_`;没给 `server` 时缺省 `mcp_`。
|
|
45
|
+
* 传 `''` 表示不加前缀(此时 MCP 原名直接进菜单,撞名风险自负)。
|
|
46
|
+
*/
|
|
47
|
+
prefix?: string;
|
|
48
|
+
/** server 标识,只用于拼缺省前缀(不会发给 server) */
|
|
49
|
+
server?: string;
|
|
50
|
+
/**
|
|
51
|
+
* 单次 `callTool` 超时(毫秒),缺省 60000;非正数 = 不限。
|
|
52
|
+
* 超时**不杀 run**:该条 tool_result 记 `is_error` 回模型(与 engine 的
|
|
53
|
+
* `toolTimeoutMs` 同语义,只是这里由桥自己兜 —— 双保险,谁短谁生效)。
|
|
54
|
+
*/
|
|
55
|
+
timeoutMs?: number;
|
|
56
|
+
}
|
|
57
|
+
/** 缺省超时:MCP server 可能去连外部系统,60s 是「明显卡死」与「慢但正常」的分界 */
|
|
58
|
+
export declare const MCP_DEFAULT_TIMEOUT_MS = 60000;
|
|
59
|
+
/**
|
|
60
|
+
* 给一次 MCP 调用套超时。⚠️ 与 engine 的 `withTimeout` 同样是**放弃等待**而非取消 ——
|
|
61
|
+
* MCP 的 `notifications/cancelled` 属于连接器职责,桥这一层拿不到取消句柄。
|
|
62
|
+
*
|
|
63
|
+
* 转导导出(module 级,**不进公共面**)只为可测:`tests/timeoutLiveness.test.ts` 拿它验
|
|
64
|
+
* 「截止计时器不得 unref」—— 那是「被 await 的超时到底会不会触发」的唯一分界点。
|
|
65
|
+
*/
|
|
66
|
+
export declare function withDeadline<T>(p: Promise<T>, timeoutMs: number, label: string): Promise<T>;
|
|
67
|
+
/**
|
|
68
|
+
* 把一个 MCP server 的工具映射成框架的 `AgentTool[]`(可直接进 `tools` / providers)。
|
|
69
|
+
*
|
|
70
|
+
* - **名字**:`prefix + 归一化原名`;归一化后同名的两条直接抛错(否则装配期查重只会报
|
|
71
|
+
* 「菜单能力重名」,看不出根因是 MCP 名撞了);
|
|
72
|
+
* - **原名**:每次调用时写进发起 turn 的 `mcp.tool` attribute(审计 / 回放要还原出
|
|
73
|
+
* 回调 server 用的原名);
|
|
74
|
+
* - **入参 schema**:MCP 的 `inputSchema` 已是 JSON Schema → 原样透传,由 engine 的
|
|
75
|
+
* 子集校验器在 `callTool` 之前先校验(非法入参根本不会发出,模型自己会改);
|
|
76
|
+
* - **返回结构**:MCP 的结果对象(`content` 数组等)原样交给 engine 序列化,
|
|
77
|
+
* 不做「把 content 拼成字符串」这类有损加工 —— 需要塑形请自行包一层工具。
|
|
78
|
+
*/
|
|
79
|
+
export declare function mcpTools(client: McpClientLike, opts?: McpToolsOptions): Promise<AgentTool[]>;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/** 缺省超时:MCP server 可能去连外部系统,60s 是「明显卡死」与「慢但正常」的分界 */
|
|
2
|
+
export const MCP_DEFAULT_TIMEOUT_MS = 60_000;
|
|
3
|
+
/**
|
|
4
|
+
* 工具名归一化:MCP 名可含 `-` / `.` / `/` / 空格等(对 LLM API 不友好或非法)
|
|
5
|
+
* → 一律转 `_`,并把连续分隔符收成一个(`foo..bar` → `foo_bar`)。
|
|
6
|
+
* 归一化后仍非法(空名 / 超长)直接抛错,**不静默改名** —— 静默截断会得到一个
|
|
7
|
+
* 调用不回去的名字,比启动期报错难查得多。
|
|
8
|
+
*/
|
|
9
|
+
function normalizeToolName(raw) {
|
|
10
|
+
const cleaned = raw
|
|
11
|
+
.trim()
|
|
12
|
+
.replace(/[^A-Za-z0-9_]+/g, '_')
|
|
13
|
+
.replace(/^_+|_+$/g, '');
|
|
14
|
+
return cleaned;
|
|
15
|
+
}
|
|
16
|
+
/** 超时哨兵:区分「超时」与「工具恰好返回了 undefined」(同 engine 的 TIMED_OUT) */
|
|
17
|
+
const TIMED_OUT = Symbol('agentia.mcp.timed-out');
|
|
18
|
+
/**
|
|
19
|
+
* 给一次 MCP 调用套超时。⚠️ 与 engine 的 `withTimeout` 同样是**放弃等待**而非取消 ——
|
|
20
|
+
* MCP 的 `notifications/cancelled` 属于连接器职责,桥这一层拿不到取消句柄。
|
|
21
|
+
*
|
|
22
|
+
* 转导导出(module 级,**不进公共面**)只为可测:`tests/timeoutLiveness.test.ts` 拿它验
|
|
23
|
+
* 「截止计时器不得 unref」—— 那是「被 await 的超时到底会不会触发」的唯一分界点。
|
|
24
|
+
*/
|
|
25
|
+
export async function withDeadline(p, timeoutMs, label) {
|
|
26
|
+
if (!(timeoutMs > 0))
|
|
27
|
+
return p;
|
|
28
|
+
let timer;
|
|
29
|
+
try {
|
|
30
|
+
const raced = await Promise.race([
|
|
31
|
+
p,
|
|
32
|
+
new Promise((resolve) => {
|
|
33
|
+
timer = setTimeout(() => resolve(TIMED_OUT), timeoutMs);
|
|
34
|
+
// ⚠️ 不 unref:同 engine 的 `withTimeout` —— 它的触发是「这个 await 得以结束」的条件。
|
|
35
|
+
// unref 过它 ⇒ 空事件循环下进程先退出,挂起的 MCP 调用让整段代码静默消失。
|
|
36
|
+
}),
|
|
37
|
+
]);
|
|
38
|
+
if (raced === TIMED_OUT) {
|
|
39
|
+
throw new Error(`MCP 工具 "${label}" 调用超时(超过 ${timeoutMs}ms)`);
|
|
40
|
+
}
|
|
41
|
+
return raced;
|
|
42
|
+
}
|
|
43
|
+
finally {
|
|
44
|
+
if (timer)
|
|
45
|
+
clearTimeout(timer);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* 把一个 MCP server 的工具映射成框架的 `AgentTool[]`(可直接进 `tools` / providers)。
|
|
50
|
+
*
|
|
51
|
+
* - **名字**:`prefix + 归一化原名`;归一化后同名的两条直接抛错(否则装配期查重只会报
|
|
52
|
+
* 「菜单能力重名」,看不出根因是 MCP 名撞了);
|
|
53
|
+
* - **原名**:每次调用时写进发起 turn 的 `mcp.tool` attribute(审计 / 回放要还原出
|
|
54
|
+
* 回调 server 用的原名);
|
|
55
|
+
* - **入参 schema**:MCP 的 `inputSchema` 已是 JSON Schema → 原样透传,由 engine 的
|
|
56
|
+
* 子集校验器在 `callTool` 之前先校验(非法入参根本不会发出,模型自己会改);
|
|
57
|
+
* - **返回结构**:MCP 的结果对象(`content` 数组等)原样交给 engine 序列化,
|
|
58
|
+
* 不做「把 content 拼成字符串」这类有损加工 —— 需要塑形请自行包一层工具。
|
|
59
|
+
*/
|
|
60
|
+
export async function mcpTools(client, opts = {}) {
|
|
61
|
+
const timeoutMs = opts.timeoutMs ?? MCP_DEFAULT_TIMEOUT_MS;
|
|
62
|
+
const prefix = opts.prefix ?? (opts.server === undefined ? 'mcp_' : `mcp_${normalizeToolName(opts.server)}_`);
|
|
63
|
+
const listed = await client.listTools();
|
|
64
|
+
const seen = new Map(); // 归一化名 → 首个占位的 MCP 原名
|
|
65
|
+
const tools = [];
|
|
66
|
+
for (const info of listed) {
|
|
67
|
+
const original = info.name;
|
|
68
|
+
if (typeof original !== 'string' || original.trim() === '') {
|
|
69
|
+
throw new Error(`MCP server 返回了空工具名:${JSON.stringify(info.name)}`);
|
|
70
|
+
}
|
|
71
|
+
const name = `${prefix}${normalizeToolName(original)}`;
|
|
72
|
+
if (!/^[A-Za-z0-9_-]{1,64}$/.test(name)) {
|
|
73
|
+
throw new Error(`MCP 工具名 "${original}" 归一化后为 "${name}",不满足 ^[A-Za-z0-9_-]{1,64}$` +
|
|
74
|
+
`(前缀 "${prefix}" 过长或原名含过多非法字符)—— 请换个更短的 prefix`);
|
|
75
|
+
}
|
|
76
|
+
const dup = seen.get(name);
|
|
77
|
+
if (dup !== undefined) {
|
|
78
|
+
throw new Error(`MCP 工具名归一化后撞名:${JSON.stringify(dup)} 与 ${JSON.stringify(original)} ` +
|
|
79
|
+
`都变成 "${name}" —— 请给其中一个在 server 侧改名,或用 prefix 区分`);
|
|
80
|
+
}
|
|
81
|
+
seen.set(name, original);
|
|
82
|
+
const schema = info.inputSchema && typeof info.inputSchema === 'object' && !Array.isArray(info.inputSchema)
|
|
83
|
+
? info.inputSchema
|
|
84
|
+
: { type: 'object' };
|
|
85
|
+
tools.push({
|
|
86
|
+
name,
|
|
87
|
+
description: info.description?.trim() || `MCP 工具 ${original}`,
|
|
88
|
+
inputSchema: schema,
|
|
89
|
+
run: async (input, ctx) => {
|
|
90
|
+
// 原名先落账再调用:连接器抛错/超时时,trace 里仍留得下「本想调谁」
|
|
91
|
+
if (ctx) {
|
|
92
|
+
try {
|
|
93
|
+
ctx.recorder.setAttribute(ctx.parentSpanId, 'mcp.tool', original);
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
/* 观测是辅助动作:记账失败不得把一次正常调用变成失败 */
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
const args = input && typeof input === 'object' && !Array.isArray(input)
|
|
100
|
+
? input
|
|
101
|
+
: {};
|
|
102
|
+
return withDeadline(client.callTool(original, args), timeoutMs, original);
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
return tools;
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=mcp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/integrations/mcp.ts"],"names":[],"mappings":"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"}
|