@migor/agentia 0.10.2 → 0.10.4

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.
Files changed (144) hide show
  1. package/CHANGELOG.md +969 -64
  2. package/LICENSE +1 -1
  3. package/README.en.md +93 -38
  4. package/README.md +105 -218
  5. package/dist/AGENTS.md +234 -41
  6. package/dist/core/limits.d.ts +33 -1
  7. package/dist/core/limits.js +37 -1
  8. package/dist/core/limits.js.map +1 -1
  9. package/dist/core/run.d.ts +2 -2
  10. package/dist/core/timeout.d.ts +5 -5
  11. package/dist/core/timeout.js +5 -5
  12. package/dist/core/tool.d.ts +2 -2
  13. package/dist/core/trace-sink.d.ts +8 -0
  14. package/dist/core/trace-sink.js +24 -0
  15. package/dist/core/trace-sink.js.map +1 -0
  16. package/dist/core/trace.d.ts +12 -2
  17. package/dist/core/trace.js +10 -1
  18. package/dist/core/trace.js.map +1 -1
  19. package/dist/engine/concurrency.d.ts +1 -1
  20. package/dist/engine/concurrency.js +1 -1
  21. package/dist/engine/errors.d.ts +2 -2
  22. package/dist/engine/errors.js +2 -2
  23. package/dist/engine/loop-result.d.ts +3 -3
  24. package/dist/engine/loop.js +99 -56
  25. package/dist/engine/loop.js.map +1 -1
  26. package/dist/engine/mcp-server-http.js +1 -1
  27. package/dist/engine/mcp-server-http.js.map +1 -1
  28. package/dist/engine/mcp-server-stdio.js +7 -3
  29. package/dist/engine/mcp-server-stdio.js.map +1 -1
  30. package/dist/engine/mcp-server.d.ts +17 -2
  31. package/dist/engine/mcp-server.js +42 -17
  32. package/dist/engine/mcp-server.js.map +1 -1
  33. package/dist/engine/resume-input.d.ts +1 -1
  34. package/dist/engine/resume-input.js +1 -1
  35. package/dist/engine/retry.d.ts +15 -0
  36. package/dist/engine/retry.js +51 -2
  37. package/dist/engine/retry.js.map +1 -1
  38. package/dist/engine/span-scope.d.ts +15 -0
  39. package/dist/engine/span-scope.js +8 -1
  40. package/dist/engine/span-scope.js.map +1 -1
  41. package/dist/engine/spec.d.ts +5 -1
  42. package/dist/engine/spec.js.map +1 -1
  43. package/dist/engine/tracer.d.ts +8 -4
  44. package/dist/engine/tracer.js +24 -17
  45. package/dist/engine/tracer.js.map +1 -1
  46. package/dist/engine/turn.d.ts +2 -2
  47. package/dist/engine/turn.js +19 -4
  48. package/dist/engine/turn.js.map +1 -1
  49. package/dist/engine/types.d.ts +13 -5
  50. package/dist/engine/types.js +1 -0
  51. package/dist/engine/types.js.map +1 -1
  52. package/dist/eval/export.js +2 -2
  53. package/dist/eval/export.js.map +1 -1
  54. package/dist/eval/harvest.d.ts +4 -1
  55. package/dist/eval/harvest.js +32 -6
  56. package/dist/eval/harvest.js.map +1 -1
  57. package/dist/index.d.ts +3 -1
  58. package/dist/index.js +5 -2
  59. package/dist/index.js.map +1 -1
  60. package/dist/integrations/anthropic.d.ts +1 -1
  61. package/dist/integrations/anthropic.js +1 -1
  62. package/dist/integrations/anthropic.js.map +1 -1
  63. package/dist/integrations/file-sink.d.ts +0 -16
  64. package/dist/integrations/file-sink.js +24 -6
  65. package/dist/integrations/file-sink.js.map +1 -1
  66. package/dist/integrations/mcp-http.js +4 -3
  67. package/dist/integrations/mcp-http.js.map +1 -1
  68. package/dist/integrations/mcp-protocol.d.ts +35 -10
  69. package/dist/integrations/mcp-protocol.js +19 -1
  70. package/dist/integrations/mcp-protocol.js.map +1 -1
  71. package/dist/integrations/mcp-stdio.js +91 -50
  72. package/dist/integrations/mcp-stdio.js.map +1 -1
  73. package/dist/integrations/mcp.d.ts +1 -1
  74. package/dist/integrations/mcp.js +19 -3
  75. package/dist/integrations/mcp.js.map +1 -1
  76. package/dist/integrations/metrics-otlp.d.ts +1 -1
  77. package/dist/integrations/metrics-otlp.js +8 -2
  78. package/dist/integrations/metrics-otlp.js.map +1 -1
  79. package/dist/integrations/metrics-render.js +17 -6
  80. package/dist/integrations/metrics-render.js.map +1 -1
  81. package/dist/integrations/metrics-state.d.ts +2 -2
  82. package/dist/integrations/metrics-state.js +4 -4
  83. package/dist/integrations/metrics-state.js.map +1 -1
  84. package/dist/integrations/metrics.d.ts +2 -2
  85. package/dist/integrations/otlp.d.ts +29 -6
  86. package/dist/integrations/otlp.js +128 -7
  87. package/dist/integrations/otlp.js.map +1 -1
  88. package/dist/integrations/report.d.ts +14 -2
  89. package/dist/integrations/report.js +39 -6
  90. package/dist/integrations/report.js.map +1 -1
  91. package/dist/runtime/run.d.ts +1 -1
  92. package/dist/runtime/run.js +19 -17
  93. package/dist/runtime/run.js.map +1 -1
  94. package/dist/store/fsStore.js +9 -5
  95. package/dist/store/fsStore.js.map +1 -1
  96. package/dist/store/record.d.ts +2 -2
  97. package/dist/store/record.js +1 -1
  98. package/dist/store/sqliteStore.d.ts +2 -2
  99. package/dist/store/sqliteStore.js +3 -3
  100. package/dist/store/sqliteStore.js.map +1 -1
  101. package/dist/store/store.d.ts +27 -7
  102. package/dist/store/store.js +43 -5
  103. package/dist/store/store.js.map +1 -1
  104. package/dist/toolkit/collect.d.ts +11 -5
  105. package/dist/toolkit/collect.js +10 -4
  106. package/dist/toolkit/collect.js.map +1 -1
  107. package/dist/toolkit/discover.js +27 -1
  108. package/dist/toolkit/discover.js.map +1 -1
  109. package/dist/toolkit/module.js +183 -50
  110. package/dist/toolkit/module.js.map +1 -1
  111. package/dist/toolkit/prompt.d.ts +1 -1
  112. package/dist/toolkit/prompt.js +2 -2
  113. package/dist/toolkit/prompt.js.map +1 -1
  114. package/dist/toolkit/subagent.d.ts +1 -1
  115. package/dist/toolkit/subagent.js +17 -3
  116. package/dist/toolkit/subagent.js.map +1 -1
  117. package/dist/transport/approval-policy.js +1 -1
  118. package/dist/transport/approval-policy.js.map +1 -1
  119. package/dist/transport/approval-supervisor.d.ts +8 -0
  120. package/dist/transport/approval-supervisor.js +23 -3
  121. package/dist/transport/approval-supervisor.js.map +1 -1
  122. package/dist/transport/async.d.ts +3 -0
  123. package/dist/transport/async.js +128 -25
  124. package/dist/transport/async.js.map +1 -1
  125. package/dist/transport/http-endpoints.js +1 -1
  126. package/dist/transport/http-route.js +2 -2
  127. package/dist/transport/http-route.js.map +1 -1
  128. package/dist/transport/http-shapes.d.ts +1 -1
  129. package/dist/transport/http-shapes.js +1 -1
  130. package/dist/transport/resume-scanner.d.ts +7 -0
  131. package/dist/transport/resume-scanner.js +40 -9
  132. package/dist/transport/resume-scanner.js.map +1 -1
  133. package/dist/transport/run-call-options.js +7 -3
  134. package/dist/transport/run-call-options.js.map +1 -1
  135. package/dist/transport/scheduler.js +5 -0
  136. package/dist/transport/scheduler.js.map +1 -1
  137. package/dist/transport/serve.d.ts +92 -0
  138. package/dist/transport/serve.js +155 -0
  139. package/dist/transport/serve.js.map +1 -0
  140. package/dist/transport/signal-supervisor.d.ts +10 -2
  141. package/dist/transport/signal-supervisor.js +15 -2
  142. package/dist/transport/signal-supervisor.js.map +1 -1
  143. package/dist/transport/wake-policy.d.ts +1 -1
  144. package/package.json +23 -10
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 retrychx
3
+ Copyright (c) 2026 migor
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
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) [![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)
3
+ [![CI](https://github.com/migoric/agentia/actions/workflows/ci.yml/badge.svg)](https://github.com/migoric/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
 
@@ -8,25 +8,23 @@
8
8
  with decorators + DI and a main agent orchestrates them; every run yields structured output and an
9
9
  observable call tree (trace, cost, metrics).
10
10
 
11
- **1 package · ≈2 MB · 0 runtime dependencies · 90+ guards** — the answer to the first question when
12
- choosing a library (how big is the install?): `npm i @migor/agentia` puts exactly **one** package into
13
- `node_modules` and pulls in no vendor SDK. These numbers are recomputed by
14
- `tests/docs/scoreboard.test.ts` on every run; hand-written figures rot.
11
+ **1 package · ≈2 MB · 0 runtime dependencies · 90+ guards** — recomputed by
12
+ `tests/docs/scoreboard.test.ts` on every run.
15
13
 
16
- > This is a **summary**. The [website](https://agentia-web.pages.dev/en) is **bilingual** — the English
17
- > pages mirror the Chinese ones section by section — but the authoritative and always-current
18
- > **long-form** documentation is Chinese:
19
- > [`docs/usage-guide.md`](./docs/usage-guide.md) (API reference, type wiring, known limits; the same
20
- > text is served verbatim at `/llms-full.txt`). We keep this file short on purpose — a hand-maintained
21
- > full translation drifts.
14
+ > This is a **summary**, kept short on purpose (a hand-maintained full translation drifts). The
15
+ > [website](https://agentia-web.pages.dev/en) is bilingual, but the authoritative long-form
16
+ > documentation is Chinese: [`docs/usage-guide.md`](./docs/usage-guide.md) (also served verbatim at
17
+ > `/llms-full.txt`).
22
18
 
23
19
  ## Requirements
24
20
 
25
- Node.js **≥ 18** (the only `engines` requirement). CI covers **18 / 20 / 24** — the `import-floor`
26
- matrix pins the floor declared in `engines`, every other job follows the current LTS. Deno and edge
27
- runtimes are **not** validated. The only store touching a Node builtin is `SqliteTaskStore` (needs
28
- Node ≥ 22.5 for `node:sqlite`) — it fails with a readable error at construction time, and never breaks
29
- importing the package.
21
+ Node.js **≥ 18** (the only `engines` requirement); CI covers **18 / 20 / 24**. Designed and tested on
22
+ Node; **Bun and Deno are verified runnable** (four-step check — import → assemble → HTTP → side
23
+ effects — plus minimal mounting code per host and the measured versions, in
24
+ [`docs/frameworks.md`](./docs/frameworks.md); the front page deliberately carries no version numbers —
25
+ they rot); **edge runtimes remain unverified**.
26
+ `SqliteTaskStore` needs Node ≥ 22.5 (`node:sqlite`) and fails with a
27
+ readable error at construction — importing the package still works.
30
28
 
31
29
  ## Install
32
30
 
@@ -34,26 +32,34 @@ importing the package.
34
32
  npm i @migor/agentia # the framework
35
33
  npm i -g @migor/cli # CLI: scaffold / generate / dev inspector
36
34
 
37
- agentia create my-app # scaffold ships .env / .env.example
38
- $EDITOR my-app/.env # put ANTHROPIC_API_KEY here (export works too — real env wins)
35
+ agentia create my-app --minimal # single entry file + a bare tool; ships .env / .env.example
36
+ cd my-app && npm install
37
+ $EDITOR .env # put ANTHROPIC_API_KEY here (export works too — real env wins)
38
+ npm run dev -- "your question" # tsx src/main.ts: one run, then exit
39
39
  # optional: ANTHROPIC_BASE_URL (compatible gateways), AGENTIA_MODEL (default claude-opus-5)
40
40
  ```
41
41
 
42
- > The framework does **not** read `.env` on its own: the scaffolded `src/main.ts` calls
43
- > `loadEnvFile()` on its first line. Real environment variables always win over the file
44
- > (CI / docker / command line), unless you pass `loadEnvFile({ override: true })`.
42
+ > The framework does **not** read `.env` on its own: the template entry calls `loadEnvFile()`.
43
+ > Real environment variables win over the file unless you pass `{ override: true }`.
45
44
 
46
45
  ## Quick start
47
46
 
48
47
  ### A. CLI
49
48
 
49
+ Start with `--minimal` to exercise the model and a bare tool without learning decorators, DI or the HTTP
50
+ host first. For the inspector, four capability directories and a production service, use the **default
51
+ full template without `--minimal`** (unchanged):
52
+
50
53
  ```bash
51
- agentia create my-app
52
- cd my-app && npm install
54
+ agentia create my-service
55
+ cd my-service && npm install
53
56
  agentia g tool weather # create src/tools/weather/index.ts and register it
54
57
  agentia dev # local inspector panel (drive a run, pick capabilities/workdir)
55
58
  ```
56
59
 
60
+ In the full template, `src/main.ts` starts the HTTP service and `src/batch.ts` is the one-shot
61
+ `npm run start:batch` entry.
62
+
57
63
  Four self-describing directories hold capabilities — the directory name **is** the kind:
58
64
  `src/tools/` · `src/skills/` · `src/prompts/` · `src/subagents/`; the registry is `src/registry.ts`.
59
65
 
@@ -91,6 +97,21 @@ console.log(result.trace); // call tree + per-step tokens/cost (traceId ===
91
97
  Or point `createApp` at the directories instead of passing providers:
92
98
  `createApp({ discover: ['src/tools', 'src/skills', 'src/prompts', 'src/subagents'], system })`.
93
99
 
100
+ ### C. Existing service? Add one endpoint
101
+
102
+ Don't scaffold a new project, and don't rewrite the one you have. Wrap an existing function as a
103
+ `@Tool`, then add **one branch** in your existing `createServer`: business routes first (your code
104
+ stays untouched), everything else goes to `createHttpHandler` (`/run`, `/tasks`, `/healthz`).
105
+ Auth is **the same function** for both, and `drain()` hooks into the SIGTERM flow you already have.
106
+
107
+ Six steps, roughly 30 lines of glue. Runnable example:
108
+ [`examples/agent-endpoint/`](./examples/agent-endpoint/) — an order service that already ships
109
+ `GET /api/orders/:id`, with the agent endpoint added alongside; `src/orders.ts` is unchanged.
110
+
111
+ > Three deliberate calls: **one auth path** (the framework gives you the seam, not the policy);
112
+ > **RAG is your tool** (wrap your own `pg.query` / vector client in a `@Tool` — the framework won't
113
+ > ship one); **no budget knobs = no fuse** (the example sets all three).
114
+
94
115
  ## The four capability kinds
95
116
 
96
117
  The model picks from one shared "menu" by `description`; the decorator decides **who controls the flow**:
@@ -133,6 +154,19 @@ One run == one trace (`traceId === runId`), **built in from turn 0** — not a b
133
154
  - **Models** — `createAnthropicClient()` (default) and `createOpenAIClient()` for any OpenAI-compatible
134
155
  endpoint (DeepSeek, **Ollama**, gateways). You never need to touch a vendor SDK: pass
135
156
  `createAnthropicClient({ baseURL })` / `createOpenAIClient({ baseURL })`.
157
+ - **Web framework hosts** — `createHttpHandler` returns a plain `(req, res) => void`, so anything that
158
+ can mount a raw node handler can mount it, with no adapter layer:
159
+
160
+ | Host | Minimal mounting | Required config |
161
+ |---|---|---|
162
+ | `node:http` | `createServer(createHttpHandler(app, { runner }))` | none |
163
+ | NestJS 12 (CJS / ESM) | `nestApp.use('/agent', handler)` — 3 lines | CJS mode needs Node ≥ 22.12 (or `await import()`) |
164
+ | Egg 4 | middleware + `ctx.respond = false` | two `ignore` entries (CSRF / bodyParser) — the string form crashes the worker at startup |
165
+ | Bun / Deno | identical to `node:http`, zero changes | Deno's `--allow-net/read/write/run` |
166
+
167
+ Under cluster / multi-instance the task store **must** be shared — one in-memory store per worker
168
+ makes polling the same taskId alternate `404 200`. Conclusion table, minimal code and Egg's three
169
+ pitfalls: [`docs/frameworks.md`](./docs/frameworks.md).
136
170
  - **MCP** — `createStdioMcpConnector()` / `createStreamableHttpMcpConnector()` ship with the framework
137
171
  (stdlib only: `node:child_process` + global `fetch`); `mcpTools()` bridges the server's tools into the
138
172
  menu. The framework never imports the MCP SDK, and the `McpClientLike` seam stays open
@@ -142,12 +176,36 @@ One run == one trace (`traceId === runId`), **built in from turn 0** — not a b
142
176
  - **Platforms** — send traces to Langfuse / Phoenix / etc. via OTLP or a tiny custom `TraceSink`
143
177
  (see [`docs/observability.md`](./docs/observability.md) §2.6)
144
178
 
179
+ ## API at a glance
180
+
181
+ | Export | Purpose |
182
+ |---|---|
183
+ | `createApp` / `discoverProviders` | assemble an app / scan capability directories |
184
+ | `defineModule` | capability package (providers + middleware, distributable) |
185
+ | `Tool` / `Skill` / `SubAgent` / `Prompt` | the four capability decorators |
186
+ | `CapabilityMiddleware` (the `middleware` option) | interceptor chain around capability calls |
187
+ | `asset` | read a text asset inside a capability folder |
188
+ | `SystemPrompt` | compose the system prompt (adds the cache breakpoint) |
189
+ | `RunContext.current()` | blackboard / runId for the current run |
190
+ | `AsyncRunner` / `Scheduler` / `runSync` / `createHttpHandler` | async / scheduled / sync / HTTP triggering |
191
+ | `FileTaskStore` / `SqliteTaskStore` / `RedisTaskStore` / `InMemoryTaskStore` | task record stores |
192
+ | `createBudgetPolicy` | long-context budget guard |
193
+ | `createAnthropicClient` | default ModelClient (Anthropic) |
194
+ | `createOpenAIClient` | any OpenAI-compatible endpoint |
195
+ | `InMemoryMemoryStore` (the `memory` option) | cross-run memory hydration / write-back |
196
+ | `createOtlpExporter` | export traces over OTLP |
197
+ | `traceToMessages` | replay a finished trace as model messages |
198
+ | `fromZod` | zod schema adapter (optional peer) |
199
+ | `runAgent` / `executeRun` | bare engine entry (no assembly) |
200
+
145
201
  ## Documentation
146
202
 
147
203
  | | |
148
204
  |---|---|
149
205
  | Usage guide (authoritative, zh) | [`docs/usage-guide.md`](./docs/usage-guide.md) |
150
206
  | Production observability recipes | [`docs/observability.md`](./docs/observability.md) |
207
+ | Database integration (inject your pool / implement `TaskStore` for MySQL) | [`docs/database.md`](./docs/database.md) |
208
+ | Framework compatibility (measured: NestJS / Egg / Bun / Deno) | [`docs/frameworks.md`](./docs/frameworks.md) |
151
209
  | Examples (complete app / minimal deploy / observability) | [`examples/`](./examples/) |
152
210
  | Design spec & roadmap | [`docs/spec.md`](./docs/spec.md) · [`docs/roadmap.md`](./docs/roadmap.md) |
153
211
  | Website · Playground | [agentia-web.pages.dev/en](https://agentia-web.pages.dev/en) · [playground](https://agentia-web.pages.dev/en/playground) |
@@ -163,19 +221,17 @@ stating what **you** have to change.
163
221
  grep -nE '^#{3,4} .*(迁移|破坏性)' CHANGELOG.md # every "you must act" section
164
222
  ```
165
223
 
166
- > Honest caveat: this discipline was **tightened over time** — early versions (`0.7.1`, a type-level
167
- > change) put the action in the entry's leading blockquote instead of its own section. The command
168
- > above is a **lower bound**, not the whole set. And this README deliberately prints **no**
169
- > "N releases / M migrations" count: hand-written counts rot, so we ship the command instead.
224
+ > The command above is a **lower bound**, not the whole set — early versions didn't follow this format.
225
+ > Counts ("N releases / M migrations") are deliberately not printed: they rot.
170
226
 
171
- **What is covered by the compatibility promise:** the **named exports** of `@migor/agentia`
172
- (`src/index.ts` is the source of truth) and the `@migor/cli` command surface, plus the Node range in
173
- `engines.node` — CI runs the full chain on every version in that range. **Not covered:** deep imports
174
- (`dist/**`) — **sealed by the `exports` field** in `package.json` (guarded by
175
- `tests/architecture/package-exports.test.ts`; before `exports` existed they really did resolve) —
176
- internal module paths, `packages/*`, `examples/*`, Deno / Bun / edge runtimes (unvalidated),
177
- and anything a release does not spell out in its migration note. Runtime third-party dependencies are
178
- **zero** — enforced by `tests/architecture/no-runtime-deps.test.ts`, not by promise.
227
+ **Covered by the compatibility promise:** the **named exports** of `@migor/agentia` (`src/index.ts` is
228
+ the source of truth) and the `@migor/cli` command surface, plus the Node range in `engines.node` (CI
229
+ runs the full chain on every version in it). **Not covered:** deep imports (`dist/**`) — sealed by the
230
+ `exports` field in `package.json`, guarded by `package-exports.test.ts` — internal module paths,
231
+ `packages/*`, `examples/*`, edge runtimes, and anything a release doesn't spell out in its
232
+ migration note. Bun / Deno are **verified runnable but outside the `engines` promise**
233
+ ([`docs/frameworks.md`](./docs/frameworks.md)). Runtime third-party dependencies are **zero**, enforced by
234
+ `no-runtime-deps.test.ts`, not by promise.
179
235
 
180
236
  **What 1.0 waits for** (all three are checkable): every open item in `docs/spec.md` §11 is either
181
237
  shipped or explicitly struck out; `docs/guards.md` §2 ("awaiting a guard") is empty; and the public
@@ -199,9 +255,8 @@ cost you pay under which condition, and what a different implementation could re
199
255
  > load; copying them as an SLA will be wrong. What is actually constant is the **shape** (how many
200
256
  > times larger, how many round trips, what scales with what).
201
257
  >
202
- > The five benchmarks are **deliberately not in CI** (timing benchmarks only add noise on CI machines;
203
- > `docs/plans/2026-09-22-dev-debug-loop.md` settled on "run them when you want to look") ⇒ nothing
204
- > guards the numbers below — re-run the command in the last column.
258
+ > The five benchmarks are **deliberately not in CI** (timing benchmarks only add noise) ⇒ nothing
259
+ > guards these numbers; re-run the command in the last column.
205
260
 
206
261
  ## Contributing
207
262