@migor/agentia 0.2.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.en.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Agentia
2
2
 
3
- [![CI](https://github.com/retrychx/agentia/actions/workflows/ci.yml/badge.svg)](https://github.com/retrychx/agentia/actions/workflows/ci.yml) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
3
+ [![CI](https://github.com/retrychx/agentia/actions/workflows/ci.yml/badge.svg)](https://github.com/retrychx/agentia/actions/workflows/ci.yml) [![npm](https://img.shields.io/npm/v/@migor/agentia)](https://www.npmjs.com/package/@migor/agentia) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
4
4
 
5
5
  [中文 README](./README.md) · **English**
6
6
 
@@ -24,9 +24,16 @@ Node.js **≥ 18** (the only `engines` requirement; CI runs 18 / 20 / 22). Deno
24
24
  ```bash
25
25
  npm i @migor/agentia # the framework
26
26
  npm i -g @migor/cli # CLI: scaffold / generate / dev inspector
27
- export ANTHROPIC_API_KEY=sk-... # or ANTHROPIC_AUTH_TOKEN; ANTHROPIC_BASE_URL for compatible gateways
27
+
28
+ agentia create my-app # scaffold ships .env / .env.example
29
+ $EDITOR my-app/.env # put ANTHROPIC_API_KEY here (export works too — real env wins)
30
+ # optional: ANTHROPIC_BASE_URL (compatible gateways), AGENTIA_MODEL (default claude-opus-5)
28
31
  ```
29
32
 
33
+ > The framework does **not** read `.env` on its own: the scaffolded `src/main.ts` calls
34
+ > `loadEnvFile()` on its first line. Real environment variables always win over the file
35
+ > (CI / docker / command line), unless you pass `loadEnvFile({ override: true })`.
36
+
30
37
  ## Quick start
31
38
 
32
39
  ### A. CLI
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [中文](./README.md) · [English](./README.en.md)
4
4
 
5
- [![CI](https://github.com/retrychx/agentia/actions/workflows/ci.yml/badge.svg)](https://github.com/retrychx/agentia/actions/workflows/ci.yml) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
5
+ [![CI](https://github.com/retrychx/agentia/actions/workflows/ci.yml/badge.svg)](https://github.com/retrychx/agentia/actions/workflows/ci.yml) [![npm](https://img.shields.io/npm/v/@migor/agentia)](https://www.npmjs.com/package/@migor/agentia) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
6
6
 
7
7
  面向应用开发的声明式 agent 服务开发框架:装饰器 + DI 声明四类能力,主 agent 编排执行;每次 run 产出结构化结果与可观测调用树(trace、成本、指标),交付可直接上线的服务。
8
8
 
@@ -22,11 +22,15 @@
22
22
  npm i @migor/agentia # 框架(项目依赖)
23
23
  npm i -g @migor/cli # 命令行工具(脚手架 / 生成 / 调试)
24
24
 
25
- export ANTHROPIC_API_KEY=sk-... # 或 ANTHROPIC_AUTH_TOKEN
25
+ agentia create my-app # 脚手架(含 .env / .env.example)
26
+ $EDITOR my-app/.env # 填 ANTHROPIC_API_KEY(也可直接 export,真实环境变量优先)
26
27
  # 可选:ANTHROPIC_BASE_URL(兼容端点)、AGENTIA_MODEL(缺省 claude-opus-5)
27
28
  ```
28
29
 
29
- > **版本**:`0.2.2`(`@migor/agentia` 与 `@migor/cli` 均已发布到 npm)。`examples/` **刻意**用
30
+ > 框架**不自动**读 `.env`:脚手架 `src/main.ts` 首行的 `loadEnvFile()` 负责把它读进 `process.env`。
31
+ > 真实环境变量优先(CI / docker / 命令行永远赢过文件),`loadEnvFile({ override: true })` 才反过来。
32
+
33
+ > **版本**:`0.3.0`(`@migor/agentia` 与 `@migor/cli` 均已发布到 npm)。`examples/` **刻意**用
30
34
  > `file:../..` 指向本仓库而不是 npm 版本 —— 跑的是**工作区代码**,理由见
31
35
  > [`examples/README.md`](examples/README.md) 的「依赖说明」。
32
36
 
package/dist/AGENTS.md CHANGED
@@ -70,9 +70,9 @@ console.log(result.finalText, result.stopReason, result.trace.totalUsage);
70
70
  ## 2. 项目结构(CLI 约定)
71
71
 
72
72
  ```bash
73
- npx @migor/cli create my-app # 脚手架
73
+ npx @migor/cli create my-app # 脚手架(含 .env / .env.example)
74
74
  cd my-app && npm install
75
- export ANTHROPIC_API_KEY=sk-ant-...
75
+ $EDITOR .env # 填 ANTHROPIC_API_KEY(脚手架已生成,且已被 .gitignore 挡住)
76
76
  npx @migor/cli dev # tsx watch + 本地 inspector 面板
77
77
  npx @migor/cli g tool fetch-weather # 生成到 src/tools/fetch-weather/(skill/prompt/subagent 同理)
78
78
  npx @migor/cli doctor # 静态体检(未登记/悬空/命名/重复)
@@ -283,6 +283,31 @@ result.typed; // { answer: string } | undefined
283
283
  | `isSuccessStopReason` | `end_turn` / `stop_sequence` 都算正常收尾 |
284
284
  | `resolveDefaultModel` | 显式 > `AGENTIA_MODEL` > `claude-opus-5` |
285
285
 
286
+ ### 环境变量与 `.env`(`loadEnvFile`)
287
+
288
+ | API | 说明 |
289
+ |---|---|
290
+ | `loadEnvFile` | 读一份 `.env` 进 `process.env`,返回**本次真正生效**的键;选项 `LoadEnvOptions`:`{ path?, override? }` |
291
+
292
+ ```ts
293
+ import { createApp, loadEnvFile } from '@migor/agentia';
294
+
295
+ loadEnvFile(); // 缺省 cwd/.env;文件不存在 = 静默返回 {}(首次 clone、CI 的正常路径)
296
+ const app = await createApp({ ... });
297
+ ```
298
+
299
+ 三条语义(都刻意,别当成实现细节):
300
+
301
+ - **框架不自动读 `.env`** —— 读哪个文件、什么时候读是宿主的启动决策。塞进 `createApp` 里自动做,会让「同一份代码换个目录跑结果不同」变成要花时间排查的悬案;而放 CLI 里只有 `agentia dev` 生效。写在**你的** `main.ts` 里,`node dist/main.js`、docker、别的宿主都一样读得到。
302
+ - **真实环境变量优先**(缺省不覆盖):`process.env` 里已定义(哪怕空串)的键保持不动 —— CI / docker / `FOO=bar npm start` 永远赢过文件。要让文件里的值压过环境变量就 `loadEnvFile({ override: true })`。
303
+ - **想知道「生效没」看返回值**,别去看文件:被挡下的键不在返回对象里。
304
+
305
+ `agentia create` 生成的脚手架把 `.env`、`.env.example` 与 `main.ts` 首行的 `loadEnvFile();` 都备好了,并在 `.gitignore` 里挡住 `.env` —— 生成 `.env` 却不 ignore,等于把 key 送进用户的第一个 commit。
306
+
307
+ > ⚠️ **本机 export 过 `ANTHROPIC_API_KEY` 的人**(比如同时用 Claude Code):按上面的优先级,脚手架 `.env` 里的 key 会被**静默压住**。改了 `.env` 却「没生效」时,先 `echo $ANTHROPIC_API_KEY` 看看环境里是不是已经有一份。
308
+
309
+ 解析规则(刻意窄,够用就好):`KEY=VALUE`,允许 `export ` 前缀与 `=` 两侧空白;`#` 整行注释;单引号内原样、双引号内认 `\n \r \t \" \\`;未加引号的值里 ` #` 起为行内注释。**不做变量展开、不合并续行**(需要就上专门的库);既不像 `KEY=VALUE` 又不是注释的行**直接报错并指出行号** —— 静默跳过等于让你以为「配上了其实没配上」。
310
+
286
311
  ### 宿主(换宿主不换语义)
287
312
 
288
313
  | API | 说明 |
@@ -320,14 +345,16 @@ const callable = { name: app.name, run: (msgs, opts) => app.run(msgs, { ...opts,
320
345
  const handler = createHttpHandler(callable, { runner });
321
346
  ```
322
347
 
323
- 异步侧更直接:`AsyncRunner` 的构造选项就有 `client`。完整可跑写法见仓库 `examples/complete/`。
348
+ 异步侧更直接:`AsyncRunner` 的构造选项就有 `client`。完整可跑写法见仓库 `examples/complete/`
349
+ (**不随 npm 包发布** —— 包里只有 `dist/`、README、LICENSE 与本说明):
350
+ <https://github.com/retrychx/agentia/tree/main/examples/complete>
324
351
 
325
352
  ### `createHttpHandler(app, opts?: HttpHandlerOptions)`
326
353
 
327
354
  | 选项 | 说明 |
328
355
  |---|---|
329
356
  | `authenticate` | 入口鉴权钩子:**除 `/healthz` 与 `/metrics` 外所有路径**都过它,且在**读 body 之前**(未通过就不收 body)。正常返回即通过;抛 `HttpException` 按其 `status`/`body` 回;抛别的错误回 401,原文只进服务端日志。框架**不实现策略**(不读 env、不碰凭据) |
330
- | `metrics` | 指标出口:给 `metricsSink()`(或任意 `{ render() }` / 返回字符串的闭包)后,`GET /metrics` 回它的 Prometheus 文本。**不鉴权**(拉取端在集群内网);要保护请放反代后面。不给则该路径 404 |
357
+ | `metrics` | 指标出口:给 `metricsSink()`(或任意 `{ render() }` / 返回字符串的闭包)后,`GET /metrics` 回它的 Prometheus 文本。**不鉴权**(拉取端在集群内网);要保护请放反代后面。不给则该路径 404。⚠️ 这只管**渲染** —— 数字要真的累计,必须把**同一个** sink 注册进 `createApp({ sinks: [metrics] })`(它靠 run 收尾投递,不自己埋点),否则 `/metrics` 恒为 0 **且不报错** |
331
358
  | `maxBodyBytes` | 请求 body 上限(字节),超限回 413;缺省 1 MiB |
332
359
  | `maxConcurrentRuns` | 同时在跑的 `POST /run` 上限,超限回 503 + `Retry-After`;缺省 32(传 `Infinity` 恢复无上限) |
333
360
  | `exposeErrors` | 是否把内部异常原文回给调用方;缺省 `false`(细节只进服务端日志) |
@@ -613,6 +640,22 @@ CLI 侧有薄壳:`agentia report <trace.jsonl>` —— 每行一个 JSON(裸
613
640
  > 要看分位请用 `mergeRunReports` 汇总多条,或用 `metricsSink` 的直方图。
614
641
  > CLI 报告的聚合口径与 `agentia dev` 面板的能力排行同源(同一份 `@migor/trace-view` 实现)。
615
642
 
643
+ 那个 jsonl 从哪来 —— 框架不替你落盘(观测出口是缝),自己接一个 sink 就行,零依赖:
644
+
645
+ ```ts
646
+ import { appendFileSync } from 'node:fs';
647
+ import { createApp, type TraceSink } from '@migor/agentia';
648
+
649
+ const jsonl: TraceSink = {
650
+ export: (trace) => appendFileSync('trace.jsonl', `${JSON.stringify(trace)}\n`, 'utf8'),
651
+ };
652
+ const app = await createApp({ /* … */ sinks: [jsonl] });
653
+ // 之后:agentia report trace.jsonl
654
+ ```
655
+
656
+ 异步宿主更省事:把 `FileTaskStore` 的落盘文件直接喂给它 —— `TaskRecord` 里带 `result.trace`,
657
+ `report` 认这种形态,不用另写 sink。
658
+
616
659
  ### 生效配置快照(「这条 run 用了哪套旋钮」)
617
660
 
618
661
  每个 run 的**根 span** 都带一组 `config.*` attributes(`config.maxTokens` / `config.maxCostUsd` /
@@ -739,10 +782,10 @@ const callable = {
739
782
  | 能力引用是 provider 粒度 | 子 agent / skill 的 `tools` 写的是 **provider token**,不是单个工具名 |
740
783
  | 取消要传进客户端才有效 | 传 `signal` 后框架会 abort 在飞请求(内置 Anthropic / OpenAI 适配器都转发);不转发 `signal` 的自定义 `ModelClient` 只能「放弃等待」(请求在后台跑完、产物丢弃) |
741
784
  | 观测失败被吞 | sink 抛错不影响 run(观测是辅助动作);同理记忆水合/回写失败也不击穿 run |
742
- | 框架不读 env | 除 `AGENTIA_MODEL`(缺省模型覆盖)与 `OPENAI_API_KEY`(OpenAI 适配器)外不读环境变量;不含 dev 逻辑 |
785
+ | 框架不自动读 .env | 除 `AGENTIA_MODEL`(缺省模型覆盖)与 `OPENAI_API_KEY`(OpenAI 适配器)外,框架自己不去翻环境变量,也不读 `.env`;要读就在启动代码里调 `loadEnvFile()`(脚手架已内置那行),**真实环境变量优先**于文件 |
743
786
  | 鉴权只是缝 | 框架**不实现** token / JWT / 签名策略,也不碰凭据 env —— `authenticate` 只承诺「拦在入口、读 body 之前」;策略是宿主或反代的事 |
744
787
  | 运行时是 Node | 按 Node ≥ 18 设计与测试(`engines` 写明,CI 在 18/20/22 上守);**未对 Deno / edge 做验证**。`SqliteTaskStore` 需 Node ≥ 22.5(`node:sqlite`),未提供时构造期抛可读报错 |
745
- | 停机不由框架触发 | 框架给 `drain()` 但**不订阅** `SIGTERM`/`SIGINT`(不读 env、不做进程级决策);信号处理是宿主的 |
788
+ | 停机不由框架触发 | 框架给 `drain()` 但**不订阅** `SIGTERM`/`SIGINT`(不做进程级决策);信号处理是宿主的 |
746
789
  | 停机可能切断 SSE | `drain()` 超时后会强制关闭仍开着的 SSE 流,其 run 以 `stopReason='aborted'` 收尾 —— 客户端应把断流当作可重试 |
747
790
  | 鉴权失败即断连 | 未通过鉴权时在读到 body 之前就回响应,连接**不可复用**(显式 `connection: close`);这是「不收body省资源」的代价 |
748
791
  | 预算护栏不是硬实时 | 一回合记账完才判,实际用量可能超上限一个回合的量;模型自然收尾的那回合超限**不算失败**(只留 `budget.exceeded` 事件) |
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export declare const AGENTIA_VERSION = "0.2.2";
1
+ export declare const AGENTIA_VERSION = "0.3.0";
2
2
  export type { Trace, Span, SpanEvent, SpanError, SpanId, SpanKind, SpanStatus, TraceId, TraceSink, CapabilityType, Usage, } from './core/trace.js';
3
3
  export type { AgentTool, JsonSchema, ModelClient, RecorderBackend, SchemaInput, SchemaType, ToolRunContext, TypedSchema, } from './core/tool.js';
4
4
  export { validateJsonSchema } from './core/schema.js';
@@ -29,6 +29,8 @@ export type { RunMeta, RunStatus } from './core/run.js';
29
29
  export { Container } from './container/container.js';
30
30
  export type { Provider, ClassProvider, ValueProvider, FactoryProvider, Token, } from './container/container.js';
31
31
  export { asset } from './toolkit/asset.js';
32
+ export { loadEnvFile } from './toolkit/env.js';
33
+ export type { LoadEnvOptions } from './toolkit/env.js';
32
34
  export { discoverProviders } from './toolkit/discover.js';
33
35
  export { applyMiddleware } from './toolkit/middleware.js';
34
36
  export type { CapabilityCall, CapabilityMiddleware, CapabilityNext } from './toolkit/middleware.js';
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export const AGENTIA_VERSION = '0.2.2';
1
+ export const AGENTIA_VERSION = '0.3.0';
2
2
  export { validateJsonSchema } from './core/schema.js';
3
3
  export { combineSignals } from './core/abort.js';
4
4
  // engine:运行时内核
@@ -22,6 +22,7 @@ export { SystemPrompt } from './runtime/systemPrompt.js';
22
22
  export { Container } from './container/container.js';
23
23
  // toolkit:声明式能力 + 应用装配
24
24
  export { asset } from './toolkit/asset.js';
25
+ export { loadEnvFile } from './toolkit/env.js';
25
26
  export { discoverProviders } from './toolkit/discover.js';
26
27
  export { applyMiddleware } from './toolkit/middleware.js';
27
28
  export { Tool, collectTools } from './toolkit/tool.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Agentia —— 可选的 `.env` 引导工具(零依赖手写解析,Node ≥18 即可用)。
3
+ *
4
+ * 定位:**框架自身不会自动读 `.env`** —— 读哪个文件、什么时候读,是宿主的启动决策。
5
+ * 本函数把它收成一行显式调用(`agentia create` 生成的 `src/main.ts` 首行就是它):
6
+ *
7
+ * ```ts
8
+ * import { createApp, loadEnvFile } from '@migor/agentia';
9
+ *
10
+ * loadEnvFile(); // 缺省读 cwd/.env;已存在的真实环境变量优先,不会被文件覆盖
11
+ * const app = await createApp({ ... });
12
+ * ```
13
+ *
14
+ * **为什么不塞进 `createApp` 自动做**:读 `.env` 会改 `process.env`,而 `.env` 是按 cwd 找的。
15
+ * 隐式生效后,「同一份代码换个目录跑结果不同」和「本地多放了个 `.env`,测试行为悄悄变了」
16
+ * 都会变成要花时间排查的悬案。显式一行,时机与路径都摆在文件里(`loadEnvFile({ path })`)。
17
+ *
18
+ * **为什么不放 CLI**:`agentia dev` 只是宿主之一。放 CLI 会让 `node dist/main.js`、docker、
19
+ * 别的宿主都读不到 —— 那才是真的「只有 dev 生效」(与 spec §10 的决策一致)。
20
+ *
21
+ * 解析规则(刻意窄,够用就好):
22
+ * - 逐行 `KEY=VALUE`:允许 `export ` 前缀、`=` 两侧空白;空行与 `#` 开头整行忽略;
23
+ * - 单引号内**原样**;双引号内认 `\n` `\r` `\t` `\"` `\\`;未加引号的值里 ` #` 起为行内注释;
24
+ * - **不做变量展开**(`${VAR}` 原样保留)、不合并多行续行(行尾 `\`)—— 需要这些请上专门的库;
25
+ * - 键名只认 `[A-Za-z_][A-Za-z0-9_]*`;既不像 `KEY=VALUE` 又不是注释的行**直接抛错**(附行号)——
26
+ * 静默跳过等于让你以为「配上了其实没配上」。
27
+ */
28
+ /** `loadEnvFile` 的选项 */
29
+ export interface LoadEnvOptions {
30
+ /** 文件路径,缺省 `.env`(相对 `process.cwd()` 解析) */
31
+ path?: string;
32
+ /** `true` = 文件里的值**覆盖**已存在的进程环境变量(缺省 `false`:真实环境变量优先) */
33
+ override?: boolean;
34
+ }
35
+ /** 解析 `.env` 文本 → 键值表(不碰 `process.env`,纯函数;抛错信息带行号) */
36
+ export declare function parseEnvText(text: string): Record<string, string>;
37
+ /**
38
+ * 读 `.env` 并写进 `process.env`,返回**本次真正生效**的键值。
39
+ *
40
+ * 三条语义(都刻意,别当成实现细节):
41
+ * - **文件不存在 = 正常情况**(首次 clone、CI、生产靠真实环境变量)→ 静默返回 `{}`,
42
+ * 不制造「没建 .env 就跑不起来」的假依赖;
43
+ * - **已有环境变量优先**:`process.env` 里已定义(哪怕空串)的键不覆盖 —— 这样 CI / docker /
44
+ * 命令行的显式变量永远赢过文件,`override: true` 才反过来;
45
+ * - 想知道「到底生效没」看返回值,别去看文件。
46
+ */
47
+ export declare function loadEnvFile(options?: LoadEnvOptions): Record<string, string>;
@@ -0,0 +1,62 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ const KEY_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
4
+ /** 解析 `.env` 文本 → 键值表(不碰 `process.env`,纯函数;抛错信息带行号) */
5
+ export function parseEnvText(text) {
6
+ const out = {};
7
+ // 先剥 BOM:Windows 记事本存过的 .env 会带上 \uFEFF,不剥会让第一个键名匹配失败
8
+ const lines = text.replace(/^\uFEFF/, '').split(/\r?\n/);
9
+ for (let i = 0; i < lines.length; i++) {
10
+ const raw = lines[i] ?? '';
11
+ const line = raw.trim();
12
+ if (line === '' || line.startsWith('#'))
13
+ continue;
14
+ const body = line.startsWith('export ') ? line.slice('export '.length).trim() : line;
15
+ const eq = body.indexOf('=');
16
+ if (eq === -1)
17
+ throw new Error(`.env 第 ${i + 1} 行不是 KEY=VALUE:${raw}`);
18
+ const key = body.slice(0, eq).trim();
19
+ if (!KEY_RE.test(key))
20
+ throw new Error(`.env 第 ${i + 1} 行键名非法:${key || '(空)'}`);
21
+ out[key] = parseValue(body.slice(eq + 1));
22
+ }
23
+ return out;
24
+ }
25
+ function parseValue(raw) {
26
+ const v = raw.trim();
27
+ if (v.length >= 2 && v.startsWith('"') && v.endsWith('"')) {
28
+ return v
29
+ .slice(1, -1)
30
+ .replace(/\\([nrt"\\])/g, (_m, c) => c === 'n' ? '\n' : c === 'r' ? '\r' : c === 't' ? '\t' : c);
31
+ }
32
+ if (v.length >= 2 && v.startsWith("'") && v.endsWith("'"))
33
+ return v.slice(1, -1);
34
+ // 未加引号:` #` 起为行内注释(`#` 紧贴值不当作注释,避免吃掉含 # 的 token)
35
+ const hash = v.search(/\s#/);
36
+ return (hash === -1 ? v : v.slice(0, hash)).trim();
37
+ }
38
+ /**
39
+ * 读 `.env` 并写进 `process.env`,返回**本次真正生效**的键值。
40
+ *
41
+ * 三条语义(都刻意,别当成实现细节):
42
+ * - **文件不存在 = 正常情况**(首次 clone、CI、生产靠真实环境变量)→ 静默返回 `{}`,
43
+ * 不制造「没建 .env 就跑不起来」的假依赖;
44
+ * - **已有环境变量优先**:`process.env` 里已定义(哪怕空串)的键不覆盖 —— 这样 CI / docker /
45
+ * 命令行的显式变量永远赢过文件,`override: true` 才反过来;
46
+ * - 想知道「到底生效没」看返回值,别去看文件。
47
+ */
48
+ export function loadEnvFile(options = {}) {
49
+ const path = resolve(options.path ?? '.env');
50
+ if (!existsSync(path))
51
+ return {};
52
+ const parsed = parseEnvText(readFileSync(path, 'utf8'));
53
+ const applied = {};
54
+ for (const [key, value] of Object.entries(parsed)) {
55
+ if (!options.override && process.env[key] !== undefined)
56
+ continue;
57
+ process.env[key] = value;
58
+ applied[key] = value;
59
+ }
60
+ return applied;
61
+ }
62
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/toolkit/env.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@migor/agentia",
3
- "version": "0.2.2",
3
+ "version": "0.3.0",
4
4
  "description": "面向应用开发的声明式 agent 服务开发框架:装饰器 + DI 声明四类能力,主 agent 编排执行;每次 run 产出结构化结果与可观测调用树(trace、成本、指标),交付可直接上线的服务。",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,55 +0,0 @@
1
- import type Anthropic from '@anthropic-ai/sdk';
2
- import type { ModelClient } from '../core/tool.js';
3
- import type { AgentTool } from '../core/tool.js';
4
- import type { ContextPolicy } from '../engine/types.js';
5
- import type { RetryOptions } from '../engine/retry.js';
6
- import type { BlackboardSeed } from './context.js';
7
- /**
8
- * Agentia —— run 调用契约(spec §6.3 三类触发共用同一份入参形态)。
9
- * transport 层(同步 RPC / 异步任务 / 定时)只谈 RunInput / RunSpec,
10
- * 与具体 agent 装配解耦 —— 换宿主(HTTP/队列/DB)不换语义(spec §6.6)。
11
- */
12
- /** 单次 run 透传给引擎/应用的可选调用参数(与 toolkit/module 的 RunAppOptions 子集对齐) */
13
- export interface RunInvocationOptions {
14
- model?: string;
15
- maxTokens?: number;
16
- maxIterations?: number;
17
- client?: ModelClient;
18
- onText?: (delta: string) => void;
19
- /** 中断信号:中止则在飞请求被取消,run 以 stopReason='aborted' 收尾 */
20
- signal?: AbortSignal;
21
- /** 预置进本次 RunContext.blackboard(扩展过 Blackboard 时键有补全) */
22
- blackboard?: BlackboardSeed;
23
- /** 上下文预算策略(compaction / context editing) */
24
- contextPolicy?: ContextPolicy;
25
- /** 模型请求重试策略(覆盖应用级缺省);见 RunAgentOptions.retry */
26
- retry?: RetryOptions | false;
27
- /** 幂等键:异步宿主的 at-least-once 去重依据 */
28
- idempotencyKey?: string;
29
- /** 硬失败是否抛出;缺省 true(异步宿主置 false 落 failed 记录) */
30
- rethrow?: boolean;
31
- tools?: AgentTool[];
32
- /** 成本硬管控:整条 run 累计 token 上限;超限以 stopReason='budget_exceeded' 收尾(算失败) */
33
- maxTotalTokens?: number;
34
- /** 成本硬管控:累计成本(美元)上限;依赖模型在价格表内,见 createBudgetGuard */
35
- maxCostUsd?: number;
36
- /** 单个工具执行超时(毫秒);超时该条 tool_result 记 is_error,不杀 run */
37
- toolTimeoutMs?: number;
38
- /** 同回合并行工具上限;缺省不限 */
39
- maxToolConcurrency?: number;
40
- }
41
- /** 一次任务的规范化入参:messages(已由 normalizeMessages 规整) */
42
- export interface RunSpec {
43
- messages: Anthropic.MessageParam[];
44
- options?: RunInvocationOptions;
45
- /** 触发来源标记(sync / async / schedule:<id>),供 run 记录审计 */
46
- source?: string;
47
- }
48
- /** transport 层接受的原始入参形态 */
49
- export type RunInput = string | Anthropic.MessageParam[] | {
50
- prompt?: string;
51
- text?: string;
52
- messages?: Anthropic.MessageParam[];
53
- };
54
- /** 把任意任务入参规范成 messages(首条缺省包成 user)。 */
55
- export declare function normalizeMessages(input: RunInput | unknown): Anthropic.MessageParam[];
@@ -1,28 +0,0 @@
1
- /** 把任意任务入参规范成 messages(首条缺省包成 user)。 */
2
- export function normalizeMessages(input) {
3
- if (typeof input === 'string') {
4
- // 空串与 []、{prompt:''} 一致报错:返回 [] 会带着空 messages 去调模型
5
- if (!input)
6
- throw new Error('任务 messages 不能为空');
7
- return [{ role: 'user', content: input }];
8
- }
9
- if (Array.isArray(input)) {
10
- if (input.length === 0)
11
- throw new Error('任务 messages 不能为空');
12
- return input;
13
- }
14
- if (input && typeof input === 'object') {
15
- const o = input;
16
- if (Array.isArray(o.messages)) {
17
- if (o.messages.length === 0)
18
- throw new Error('任务 messages 不能为空');
19
- return o.messages;
20
- }
21
- if (typeof o.prompt === 'string' && o.prompt)
22
- return [{ role: 'user', content: o.prompt }];
23
- if (typeof o.text === 'string' && o.text)
24
- return [{ role: 'user', content: o.text }];
25
- }
26
- throw new Error(`无法识别为任务输入: ${JSON.stringify(input)?.slice(0, 200)}`);
27
- }
28
- //# sourceMappingURL=spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"spec.js","sourceRoot":"","sources":["../../src/runtime/spec.ts"],"names":[],"mappings":"AAyDA,wCAAwC;AACxC,MAAM,UAAU,iBAAiB,CAAC,KAAyB;IACzD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,mDAAmD;QACnD,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;QAChD,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IAC5C,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;QAC5D,OAAO,KAAiC,CAAC;IAC3C,CAAC;IACD,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,MAAM,CAAC,GAAG,KAAiE,CAAC;QAC5E,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC9B,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;YACjE,OAAO,CAAC,CAAC,QAAoC,CAAC;QAChD,CAAC;QACD,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM;YAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QAC3F,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI;YAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACvF,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,cAAc,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;AACxE,CAAC"}
@@ -1,12 +0,0 @@
1
- import type { SpanError } from '../core/trace.js';
2
- /** run 生命周期状态机(spec §6.1) */
3
- export type RunStatus = 'queued' | 'running' | 'succeeded' | 'failed';
4
- export interface RunMeta {
5
- runId: string;
6
- status: RunStatus;
7
- idempotencyKey?: string;
8
- createdAt: number;
9
- startedAt?: number;
10
- finishedAt?: number;
11
- error?: SpanError;
12
- }
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=types.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/runtime/types.ts"],"names":[],"mappings":""}