@reinsjs/agent 0.1.0 → 0.2.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/CHANGELOG.md +35 -2
- package/README.md +4 -3
- package/dist/index.d.ts +5 -2
- package/dist/index.js +9 -3
- package/dist/index.js.map +1 -1
- package/package.json +8 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
# @reinsjs/agent
|
|
2
2
|
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 49d5dea: `createAgent({ store })` installs `leasedRunRegistry(store.runLease)` on the handler when the store provides a `RunLease` (as `pgStores()` now does), so multi-instance deployments get the cross-process "one run per session" guard without extra wiring. A `handler.runs` you pass yourself still wins.
|
|
8
|
+
- 14345eb: Every user-facing runtime string is now English. This covers thrown error messages (construction-time validation, store and registry errors, HTTP 4xx bodies), `warn()` output from the brain modules and the server, the text the model sees in error tool results (`Unknown tool: …`, `Tool call blocked: …`, `Invalid arguments: …`, `Approval denied…`, `Approval expired…`), the `note` / `when` fields of every lowering loss matrix and landing, the placeholder text for content a wire protocol cannot carry, the conformance suites exported from `@reinsjs/core/testing`, and the `@reinsjs/eval` report and gate output. Previously these were Chinese while the READMEs and model-facing prompts were English, which left a non-Chinese-speaking host with unreadable diagnostics.
|
|
9
|
+
|
|
10
|
+
Nothing changes structurally: same errors, same codes, same warning points, same landing kinds. Hosts that match on the text of a message or a landing note (rather than on its error code or `landing` value) need to update those matches.
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- c16e3ea: README only: point to `@reinsjs/lowering-fetch` as the second lowering layer (the umbrella README's install line and import now show it; `@reinsjs/lowering-pi`'s README links to the side-by-side comparison; `@reinsjs/core`'s module table lists both implementations). No code changes.
|
|
15
|
+
- Updated dependencies [5955d45]
|
|
16
|
+
- Updated dependencies [49d5dea]
|
|
17
|
+
- Updated dependencies [49d5dea]
|
|
18
|
+
- Updated dependencies [c16e3ea]
|
|
19
|
+
- Updated dependencies [14345eb]
|
|
20
|
+
- Updated dependencies [a082a0c]
|
|
21
|
+
- Updated dependencies [a082a0c]
|
|
22
|
+
- @reinsjs/server@0.2.0
|
|
23
|
+
- @reinsjs/core@0.2.0
|
|
24
|
+
- @reinsjs/ui-agui@0.2.0
|
|
25
|
+
|
|
26
|
+
## 0.1.1
|
|
27
|
+
|
|
28
|
+
### Patch Changes
|
|
29
|
+
|
|
30
|
+
- Docs only: the umbrella package is `@reinsjs/agent` (npm refused the bare name `reins` as too similar to `redis`). READMEs and the 0.1.0 changelog text now say so; no code changes.
|
|
31
|
+
- Updated dependencies
|
|
32
|
+
- @reinsjs/core@0.1.1
|
|
33
|
+
- @reinsjs/server@0.1.1
|
|
34
|
+
- @reinsjs/ui-agui@0.1.1
|
|
35
|
+
|
|
3
36
|
## 0.1.0
|
|
4
37
|
|
|
5
38
|
### Minor Changes
|
|
@@ -8,11 +41,11 @@
|
|
|
8
41
|
|
|
9
42
|
- **Timeline first.** Append-only event log with `schemaVersion` on every event and fail-closed upcast on read; projection decides what the model sees each turn; replay and fork from the log alone.
|
|
10
43
|
- **A loop you can copy.** `runLoop` as an exported async generator: pause/resume is a return value with a small signed state, bounded retry on transient failures only while nothing has been written, tool pipeline `beforeTool → validate → approval → execute → afterTool`, sub-agent pause bubbling (`Interruption { kind: "subagent" }`).
|
|
11
|
-
- **Brain modules** (`@reinsjs/brain`): perception, compact (with folded-result manifest and `recall`; recommended on after measuring 100% recall at lower token cost on two model families), pins, spill, handoff, memory (`memory_20250818` shape, namespace isolation), approval (deny → ask → allow, fail-closed), budget (five limits, sub-agent usage included).
|
|
44
|
+
- **Brain modules** (`@reinsjs/brain`): perception, compact (with folded-result manifest and `recall`; recommended on after measuring 100% recall at lower token cost on two model families), pins, spill, handoff, memory (`memory_20250818` shape, namespace isolation), approval (deny → ask → allow, fail-closed), budget (five limits, sub-agent usage included), skills (Agent Skills with progressive disclosure: menu in the system prompt, `skill_read` to open one).
|
|
12
45
|
- **Lowering** (`@reinsjs/lowering-pi`): Anthropic Messages and OpenAI Responses via pi-ai with a declared loss matrix, trust markers on untrusted content, cache-breakpoint handling.
|
|
13
46
|
- **Serving** (`@reinsjs/server`, `@reinsjs/ui-agui`): Web-standard handler with SSE replay from `lastSeq`, per-session run lock, `authorizeSession` (only `true` allows), AG-UI as the first-class UI protocol.
|
|
14
47
|
- **Stores**: SQLite (`node:sqlite` / `bun:sqlite`) and Postgres (`pg` / PGlite), conformance-tested; configurable memory table for per-role isolation.
|
|
15
|
-
- **Tools**: MCP servers as one socket (`@reinsjs/tools-mcp`, tools bound per run, annotations as defaults not permissions); `asTool(agent)` in
|
|
48
|
+
- **Tools**: MCP servers as one socket (`@reinsjs/tools-mcp`, tools bound per run, annotations as defaults not permissions); `asTool(agent)` in `@reinsjs/agent`.
|
|
16
49
|
- **TanStack AI** middleware (`@reinsjs/adapter-tanstack-ai`): the brain on TanStack's loop with the log as the single source of truth; idempotent client-message import; runtime check for the approval interrupt.
|
|
17
50
|
- **Eval harness** (`@reinsjs/eval`): fixtures from real recordings, recorded tools, arm-vs-arm runner, metrics, the four-rule gate.
|
|
18
51
|
|
package/README.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# @reinsjs/agent
|
|
2
2
|
|
|
3
|
-
**Hand the reins to the model.** `
|
|
3
|
+
**Hand the reins to the model.** `@reinsjs/agent` is the umbrella package: `createAgent()` plus everything from `@reinsjs/core`, `@reinsjs/server` and `@reinsjs/ui-agui` re-exported, so one install gives you an agent with a Web-standard handler and an AG-UI stream. Bring a lowering layer (`@reinsjs/lowering-pi`) and, optionally, the brain (`@reinsjs/brain`) and a store (`@reinsjs/store-sqlite`, `@reinsjs/store-pg`).
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
|
-
pnpm add @reinsjs/agent @reinsjs/lowering-
|
|
6
|
+
pnpm add @reinsjs/agent @reinsjs/lowering-fetch @reinsjs/brain
|
|
7
7
|
```
|
|
8
8
|
|
|
9
9
|
```ts
|
|
10
|
-
import { anthropic } from "@reinsjs/lowering-pi"
|
|
10
|
+
import { anthropic } from "@reinsjs/lowering-fetch" // or "@reinsjs/lowering-pi" — same call, see its README
|
|
11
11
|
import { approval, compact, perception } from "@reinsjs/brain"
|
|
12
12
|
import { createAgent, defineTool, memoryStore } from "@reinsjs/agent"
|
|
13
13
|
|
|
@@ -62,6 +62,7 @@ Whether to call an expert, what to ask, and whether to trust the answer are the
|
|
|
62
62
|
- A loop of a few hundred lines you can read and copy, with pause/resume as a return value.
|
|
63
63
|
- Brain modules that let the model tidy its own context, keep constraints, spill big results, remember, ask before dangerous actions, and stop at a budget — each optional, each measured before it became a default.
|
|
64
64
|
- Fail-closed defaults: unknown events are rejected, forged approval decisions cannot enter through the input, sessions are `404` to anyone not explicitly authorized.
|
|
65
|
+
- One run per session across processes when the store provides a `RunLease` (`pgStores()` does): `createAgent` installs `leasedRunRegistry` with its defaults (30 s lease, random owner). To tune `ttlMs` / `owner`, build it yourself and pass `handler: { runs }` — see "Multiple instances" in `@reinsjs/server`.
|
|
65
66
|
|
|
66
67
|
## Documentation
|
|
67
68
|
|
package/dist/index.d.ts
CHANGED
|
@@ -9,13 +9,16 @@ export * from '@reinsjs/ui-agui';
|
|
|
9
9
|
* `handler`(Web 标准 (Request) => Response,缺省 AG-UI 编码)和 `run()`(不经 HTTP 直接跑,脚本 / 队列 / 测试用)。
|
|
10
10
|
*
|
|
11
11
|
* 它不引入新概念:AgentDefinition 就是 runLoop 的跨请求配置,handler 就是 createAgentHandler。
|
|
12
|
-
* 这里只负责把 BoundModel 拆成 model + lowering、把 Stores 拆成 log / blobs / memory
|
|
12
|
+
* 这里只负责把 BoundModel 拆成 model + lowering、把 Stores 拆成 log / blobs / memory(runLease 则换成 handler 的登记表)。
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
interface CreateAgentOptions extends Omit<AgentDefinition, "model" | "lowering" | "log" | "blobs" | "memory"> {
|
|
16
16
|
/** `anthropic("claude-opus-5", { apiKey })` 之类工厂的返回值,或自己组的 { model, lowering } */
|
|
17
17
|
model: BoundModel;
|
|
18
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* `memoryStore()`、`sqliteStores(db)`、`await pgStores(client)`(B9)或自己实现的一套接口;只有 log 必需。
|
|
20
|
+
* 带 `runLease` 时 handler 自动用跨进程的租约登记表(D4)——多实例部署同一条会话同时只跑一个 run
|
|
21
|
+
*/
|
|
19
22
|
store: Stores;
|
|
20
23
|
/** 传输层选项;缺省 AG-UI 编码(`encode: aguiEncoding()`),想推原始事件就传 `encode: () => rawEncoder` */
|
|
21
24
|
handler?: HandlerOptions;
|
package/dist/index.js
CHANGED
|
@@ -35,7 +35,7 @@ function asTool(agent, opts) {
|
|
|
35
35
|
risk: opts.risk ?? "low",
|
|
36
36
|
validate(input) {
|
|
37
37
|
const task = input?.task;
|
|
38
|
-
if (typeof task !== "string" || task.trim() === "") throw new Error("task
|
|
38
|
+
if (typeof task !== "string" || task.trim() === "") throw new Error("task must be a non-empty string");
|
|
39
39
|
return { task };
|
|
40
40
|
},
|
|
41
41
|
async execute(input, ctx) {
|
|
@@ -141,7 +141,8 @@ import {
|
|
|
141
141
|
uuidv7
|
|
142
142
|
} from "@reinsjs/core";
|
|
143
143
|
import {
|
|
144
|
-
createAgentHandler
|
|
144
|
+
createAgentHandler,
|
|
145
|
+
leasedRunRegistry
|
|
145
146
|
} from "@reinsjs/server";
|
|
146
147
|
import { aguiEncoding } from "@reinsjs/ui-agui";
|
|
147
148
|
function createAgent(options) {
|
|
@@ -154,7 +155,12 @@ function createAgent(options) {
|
|
|
154
155
|
...store.blobs ? { blobs: store.blobs } : {},
|
|
155
156
|
...store.memory ? { memory: store.memory } : {}
|
|
156
157
|
};
|
|
157
|
-
const
|
|
158
|
+
const runs = store.runLease !== void 0 ? {
|
|
159
|
+
runs: leasedRunRegistry(store.runLease, {
|
|
160
|
+
...handlerOptions?.warn !== void 0 ? { warn: handlerOptions.warn } : {}
|
|
161
|
+
})
|
|
162
|
+
} : {};
|
|
163
|
+
const handler = createAgentHandler(definition, { encode: aguiEncoding(), ...runs, ...handlerOptions });
|
|
158
164
|
return {
|
|
159
165
|
definition,
|
|
160
166
|
handler,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/as-tool.ts","../src/create-agent.ts"],"sourcesContent":["/**\n * reins —— 总包。装上、配自己的模型,就得到一辆有驾驭经验的车(PRD §5.1):\n *\n * import { createAgent, memoryStore } from \"@reinsjs/agent\"\n * import { anthropic } from \"@reinsjs/lowering-pi\"\n * const agent = createAgent({ model: anthropic(\"claude-opus-5\", { apiKey }), tools, store: memoryStore() })\n * export const POST = agent.handler\n *\n * 本包只做一件事:createAgent。其余全部原样再导出 @reinsjs/core、@reinsjs/server、@reinsjs/ui-agui,\n * 用户装一个包就够;降级层(@reinsjs/lowering-pi,带 pi-ai 依赖)单独装,换别的降级层实现不必带着它。\n */\nexport * from \"@reinsjs/core\"\nexport * from \"@reinsjs/server\"\nexport * from \"@reinsjs/ui-agui\"\nexport {\n type AsToolOptions,\n asTool,\n defaultChildSessionId,\n SUBAGENT_TASK_SCHEMA,\n type SubagentOutcome,\n type SubagentTask,\n type SubagentUsage,\n subagentOutcomesOf,\n usageOf,\n} from \"./as-tool.js\"\nexport { type Agent, type CreateAgentOptions, createAgent, type RunOptions } from \"./create-agent.js\"\n","/**\n * asTool:把一个 Agent 包成另一个 Agent 工具表上的 Tool —— 子代理即工具(技术方案 §10.1)。\n *\n * 要不要叫这个专家、叫它做什么、结果信不信,都是父模型在判断(宪法一);库不做编排器,只把\"手写容易做错的两件事\"做对:\n * - **审批冒泡**:子 run 暂停(审批 / 预算 / 中止)时不把状态当 isError 交给父模型,而是返回 `subagentPause`——父 run 不落这条\n * tool_result、整体 paused,宿主拿到 `Interruption(kind=subagent)`,处理子的审批后续跑父 run;父续跑补齐这条 pending 调用时,\n * 本工具凭 childSessionId 续跑子 run。状态全部可序列化,换进程成立。\n * - **预算合算**:子 run 的每条 budget_usage 经 `ctx.spend` 计入父 run 的 tokensSpent,父的 budget 模块按总账拦。\n * 其余三件与手写范式(examples/team/subagent-tool.handwritten.ts)一致:中止传递由使用者自决(abort)、principal 原样下传、\n * childSessionId 写进结果 JSON(模型可见,回放顺着它找子会话)。\n *\n * 子会话 id 缺省 `${父 sessionId}:${toolCallId}`:确定性派生,续跑时不靠内存、不靠宿主传回就能找回子会话。\n * 子日志末条是 run_paused 即续跑(不带 input,宿主给子会话的结论从 `ctx.decisions` 原样下传,多层嵌套逐层传);\n * 否则当这个专家的新一轮(带 input)——传自己的 `childSessionId` 就能跟同一个专家多轮对话。\n * 深度守卫仍靠工具表:专家 agent 的工具表里不放 asTool 类工具。\n */\nimport {\n type BudgetUsagePayload,\n createCoreRegistry,\n defineTool,\n type Event,\n type RunResult,\n readTimeline,\n subagentPause,\n type Tool,\n type ToolContext,\n type ToolResult,\n} from \"@reinsjs/core\"\nimport type { Agent } from \"./create-agent.js\"\n\nexport interface SubagentTask {\n task: string\n}\n\nexport interface AsToolOptions {\n /** 模型看到的工具名,如 ask_analyst */\n name: string\n description: string\n /** 角色名,写进结果 JSON 方便模型与回放辨认 */\n role?: string\n /**\n * 中止传递:linked(缺省)把父的 signal 传给子 run,父停子停;detached 不传,父中止时子做完为止(接力语义)。\n * 循环层保证正在执行的工具跑完、结果落进父日志,父才 paused(host)\n */\n abort?: \"linked\" | \"detached\"\n /** 缺省 low(专家只有只读工具)。专家能改东西就提高,让父侧 approval 模块问人 */\n risk?: \"low\" | \"medium\" | \"high\"\n /** 子会话 id;缺省 `${父 sessionId}:${toolCallId}`。返回已有会话即跟同一个专家继续多轮 */\n childSessionId?: (ctx: ToolContext, input: SubagentTask) => string\n}\n\n/** 子 run 的用量汇总(从子会话时间线算,含续跑之前的部分) */\nexport interface SubagentUsage {\n requests: number\n input: number\n output: number\n cacheRead: number\n cacheWrite: number\n toolCalls: number\n}\n\n/** 写进父 tool_result 的 JSON(模型可见) */\nexport interface SubagentOutcome {\n role?: string\n childSessionId: string\n /** 只会是 done / handoff / error:paused 不落结果而是冒泡 */\n status: RunResult[\"status\"]\n /** 子 run 最后一轮的文本(最后一次工具调用之后的 model_text 拼接) */\n answer?: string\n /** handoff 时的目标会话,error 时的错误 */\n detail?: string\n usage: SubagentUsage\n}\n\nexport const SUBAGENT_TASK_SCHEMA: Record<string, unknown> = {\n type: \"object\",\n properties: {\n task: {\n type: \"string\",\n description:\n \"What you want this expert to do, self-contained: the expert sees none of your conversation.\",\n },\n },\n required: [\"task\"],\n additionalProperties: false,\n}\n\n/** 缺省子会话 id:父会话 + 这次调用,确定性派生 */\nexport function defaultChildSessionId(ctx: ToolContext): string {\n return `${ctx.sessionId}:${ctx.toolCallId}`\n}\n\nexport function asTool(agent: Agent, opts: AsToolOptions): Tool {\n const abort = opts.abort ?? \"linked\"\n const registry = agent.definition.registry ?? createCoreRegistry()\n const log = agent.definition.log\n\n return defineTool<SubagentTask>({\n name: opts.name,\n description: opts.description,\n inputSchema: SUBAGENT_TASK_SCHEMA,\n risk: opts.risk ?? \"low\",\n validate(input) {\n const task = (input as { task?: unknown } | null)?.task\n if (typeof task !== \"string\" || task.trim() === \"\") throw new Error(\"task 必须是非空字符串\")\n return { task }\n },\n async execute(input, ctx) {\n const childSessionId = (opts.childSessionId ?? defaultChildSessionId)(ctx, input)\n // 子日志末条是 run_paused → 这是父续跑补齐 pending:续跑子 run,不再追加 input\n const last = (await log.tail(childSessionId, 1))[0]\n const resuming = last?.type === \"core.run_paused\"\n\n const run = agent.run({\n sessionId: childSessionId,\n ...(resuming ? {} : { input: input.task }),\n // 宿主给别的会话的结论原样下传:子循环把 sessionId 等于自己的拿去校验并记事件,其余再转发给它的工具(多层嵌套)\n ...(ctx.decisions && ctx.decisions.length > 0 ? { decisions: ctx.decisions } : {}),\n ...(ctx.principal ? { principal: ctx.principal } : {}),\n ...(abort === \"linked\" && ctx.signal ? { signal: ctx.signal } : {}),\n })\n\n let answer: string[] = []\n let result: RunResult\n while (true) {\n const step = await run.next()\n if (step.done) {\n result = step.value\n break\n }\n const e = step.value\n switch (e.type) {\n case \"core.budget_usage\":\n // 预算合算:子的每次模型请求都记到父 run 的账上\n ctx.spend?.((e.payload as BudgetUsagePayload).tokens)\n break\n case \"core.tool_call\":\n answer = [] // 答案 = 最后一次工具调用之后的文本\n break\n case \"core.model_text\":\n answer.push((e.payload as { text: string }).text)\n break\n }\n }\n\n if (result.status === \"paused\") {\n // 审批冒泡:不落结果,父 run 整体暂停;宿主处理子的中断后续跑父,父补齐这条 pending 时本工具再进来续跑子\n return subagentPause({\n childSessionId,\n reason: result.reason,\n interruptions: result.interruptions,\n state: result.state,\n })\n }\n\n const outcome: SubagentOutcome = {\n ...(opts.role !== undefined ? { role: opts.role } : {}),\n childSessionId,\n status: result.status,\n usage: usageOf(await readTimeline(log, childSessionId, { registry })),\n }\n let isError = false\n switch (result.status) {\n case \"done\":\n outcome.answer = answer.join(\"\\n\")\n break\n case \"handoff\":\n outcome.answer = answer.join(\"\\n\")\n outcome.detail = `expert handed off to session ${result.toSessionId}; its work continues there`\n break\n case \"error\":\n isError = true\n outcome.detail = `expert failed: ${(result.error.payload as { message?: string }).message ?? \"unknown error\"}`\n break\n }\n const res: ToolResult = { content: [{ type: \"text\", text: JSON.stringify(outcome, null, 2) }], isError }\n return res\n },\n })\n}\n\n/** 子会话时间线里的用量合计:每条 budget_usage 一次请求,tool_call 计工具次数 */\nexport function usageOf(timeline: readonly Event[]): SubagentUsage {\n const usage: SubagentUsage = { requests: 0, input: 0, output: 0, cacheRead: 0, cacheWrite: 0, toolCalls: 0 }\n for (const e of timeline) {\n if (e.type === \"core.budget_usage\") {\n const t = (e.payload as BudgetUsagePayload).tokens\n usage.requests += 1\n usage.input += t.input\n usage.output += t.output\n usage.cacheRead += t.cacheRead ?? 0\n usage.cacheWrite += t.cacheWrite ?? 0\n } else if (e.type === \"core.tool_call\") usage.toolCalls += 1\n }\n return usage\n}\n\n/** 父时间线里,凡 name 在 toolNames 里的 tool_result,其 JSON 里的 childSessionId —— 回放 / 导出用 */\nexport function subagentOutcomesOf(\n events: Iterable<{ type: string; payload: unknown }>,\n toolNames: ReadonlySet<string>,\n): SubagentOutcome[] {\n const found: SubagentOutcome[] = []\n for (const e of events) {\n if (e.type !== \"core.tool_result\") continue\n const p = e.payload as { name: string; content: { type: string; text?: string }[] }\n if (!toolNames.has(p.name)) continue\n const text = p.content.find((c) => c.type === \"text\")?.text\n if (!text) continue\n try {\n const parsed = JSON.parse(text) as Partial<SubagentOutcome>\n if (typeof parsed.childSessionId === \"string\") found.push(parsed as SubagentOutcome)\n } catch {\n // 不是 asTool 写的结果(如入参校验失败的 isError 文本),跳过\n }\n }\n return found\n}\n","/**\n * createAgent:把\"模型 + 工具 + 存储 + 脑子\"装成一个 agent 对象,给出两种用法 ——\n * `handler`(Web 标准 (Request) => Response,缺省 AG-UI 编码)和 `run()`(不经 HTTP 直接跑,脚本 / 队列 / 测试用)。\n *\n * 它不引入新概念:AgentDefinition 就是 runLoop 的跨请求配置,handler 就是 createAgentHandler。\n * 这里只负责把 BoundModel 拆成 model + lowering、把 Stores 拆成 log / blobs / memory。\n */\nimport {\n type ApprovalDecisionInput,\n type BoundModel,\n type ContentPart,\n type Event,\n type EventDraft,\n type LoweringDelta,\n type Principal,\n type RunResult,\n runLoop,\n type SerializedRunState,\n type Stores,\n uuidv7,\n} from \"@reinsjs/core\"\nimport {\n type AgentDefinition,\n type AgentHandler,\n createAgentHandler,\n type HandlerOptions,\n} from \"@reinsjs/server\"\nimport { aguiEncoding } from \"@reinsjs/ui-agui\"\n\nexport interface CreateAgentOptions\n extends Omit<AgentDefinition, \"model\" | \"lowering\" | \"log\" | \"blobs\" | \"memory\"> {\n /** `anthropic(\"claude-opus-5\", { apiKey })` 之类工厂的返回值,或自己组的 { model, lowering } */\n model: BoundModel\n /** `memoryStore()`、`sqliteStores(db)`、`await pgStores(client)`(B9)或自己实现的一套接口;只有 log 必需 */\n store: Stores\n /** 传输层选项;缺省 AG-UI 编码(`encode: aguiEncoding()`),想推原始事件就传 `encode: () => rawEncoder` */\n handler?: HandlerOptions\n}\n\n/** `agent.run()` 的每次参数:与 HTTP 请求体是同一组字段,多了 signal / onDelta / principal 这些进程内才有的 */\nexport interface RunOptions {\n /** 缺省新建会话;结果的 sessionId 告诉你它是什么 */\n sessionId?: string\n input?: string | ContentPart[] | EventDraft\n resume?: SerializedRunState\n decisions?: readonly ApprovalDecisionInput[]\n principal?: Principal\n signal?: AbortSignal\n onDelta?: (delta: LoweringDelta) => void\n}\n\nexport interface Agent {\n /** 跨请求不变的循环配置;要自己起 runLoop 或接别的传输层时用它 */\n readonly definition: AgentDefinition\n /** Web 标准 handler:POST 起 run、GET 补发,见 @reinsjs/server */\n readonly handler: AgentHandler\n /** 不经 HTTP 直接跑一次:yield 每条刚 append 的事件,返回 RunResult 四态 */\n run(options?: RunOptions): AsyncGenerator<Event, RunResult>\n}\n\nexport function createAgent(options: CreateAgentOptions): Agent {\n const { model, store, handler: handlerOptions, ...rest } = options\n const definition: AgentDefinition = {\n ...rest,\n model: model.model,\n lowering: model.lowering,\n log: store.log,\n ...(store.blobs ? { blobs: store.blobs } : {}),\n ...(store.memory ? { memory: store.memory } : {}),\n }\n const handler = createAgentHandler(definition, { encode: aguiEncoding(), ...handlerOptions })\n return {\n definition,\n handler,\n run(runOptions = {}) {\n const { sessionId, ...perRun } = runOptions\n return runLoop({ ...definition, ...stripUndefined(perRun), sessionId: sessionId ?? uuidv7() })\n },\n }\n}\n\n/** exactOptionalPropertyTypes 下不能把 undefined 传给可选字段,这里把没给的键去掉 */\nfunction stripUndefined<T extends object>(obj: T): T {\n return Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== undefined)) as T\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/as-tool.ts","../src/create-agent.ts"],"sourcesContent":["/**\n * reins —— 总包。装上、配自己的模型,就得到一辆有驾驭经验的车(PRD §5.1):\n *\n * import { createAgent, memoryStore } from \"@reinsjs/agent\"\n * import { anthropic } from \"@reinsjs/lowering-pi\"\n * const agent = createAgent({ model: anthropic(\"claude-opus-5\", { apiKey }), tools, store: memoryStore() })\n * export const POST = agent.handler\n *\n * 本包只做一件事:createAgent。其余全部原样再导出 @reinsjs/core、@reinsjs/server、@reinsjs/ui-agui,\n * 用户装一个包就够;降级层(@reinsjs/lowering-pi,带 pi-ai 依赖)单独装,换别的降级层实现不必带着它。\n */\nexport * from \"@reinsjs/core\"\nexport * from \"@reinsjs/server\"\nexport * from \"@reinsjs/ui-agui\"\nexport {\n type AsToolOptions,\n asTool,\n defaultChildSessionId,\n SUBAGENT_TASK_SCHEMA,\n type SubagentOutcome,\n type SubagentTask,\n type SubagentUsage,\n subagentOutcomesOf,\n usageOf,\n} from \"./as-tool.js\"\nexport { type Agent, type CreateAgentOptions, createAgent, type RunOptions } from \"./create-agent.js\"\n","/**\n * asTool:把一个 Agent 包成另一个 Agent 工具表上的 Tool —— 子代理即工具(技术方案 §10.1)。\n *\n * 要不要叫这个专家、叫它做什么、结果信不信,都是父模型在判断(宪法一);库不做编排器,只把\"手写容易做错的两件事\"做对:\n * - **审批冒泡**:子 run 暂停(审批 / 预算 / 中止)时不把状态当 isError 交给父模型,而是返回 `subagentPause`——父 run 不落这条\n * tool_result、整体 paused,宿主拿到 `Interruption(kind=subagent)`,处理子的审批后续跑父 run;父续跑补齐这条 pending 调用时,\n * 本工具凭 childSessionId 续跑子 run。状态全部可序列化,换进程成立。\n * - **预算合算**:子 run 的每条 budget_usage 经 `ctx.spend` 计入父 run 的 tokensSpent,父的 budget 模块按总账拦。\n * 其余三件与手写范式(examples/team/subagent-tool.handwritten.ts)一致:中止传递由使用者自决(abort)、principal 原样下传、\n * childSessionId 写进结果 JSON(模型可见,回放顺着它找子会话)。\n *\n * 子会话 id 缺省 `${父 sessionId}:${toolCallId}`:确定性派生,续跑时不靠内存、不靠宿主传回就能找回子会话。\n * 子日志末条是 run_paused 即续跑(不带 input,宿主给子会话的结论从 `ctx.decisions` 原样下传,多层嵌套逐层传);\n * 否则当这个专家的新一轮(带 input)——传自己的 `childSessionId` 就能跟同一个专家多轮对话。\n * 深度守卫仍靠工具表:专家 agent 的工具表里不放 asTool 类工具。\n */\nimport {\n type BudgetUsagePayload,\n createCoreRegistry,\n defineTool,\n type Event,\n type RunResult,\n readTimeline,\n subagentPause,\n type Tool,\n type ToolContext,\n type ToolResult,\n} from \"@reinsjs/core\"\nimport type { Agent } from \"./create-agent.js\"\n\nexport interface SubagentTask {\n task: string\n}\n\nexport interface AsToolOptions {\n /** 模型看到的工具名,如 ask_analyst */\n name: string\n description: string\n /** 角色名,写进结果 JSON 方便模型与回放辨认 */\n role?: string\n /**\n * 中止传递:linked(缺省)把父的 signal 传给子 run,父停子停;detached 不传,父中止时子做完为止(接力语义)。\n * 循环层保证正在执行的工具跑完、结果落进父日志,父才 paused(host)\n */\n abort?: \"linked\" | \"detached\"\n /** 缺省 low(专家只有只读工具)。专家能改东西就提高,让父侧 approval 模块问人 */\n risk?: \"low\" | \"medium\" | \"high\"\n /** 子会话 id;缺省 `${父 sessionId}:${toolCallId}`。返回已有会话即跟同一个专家继续多轮 */\n childSessionId?: (ctx: ToolContext, input: SubagentTask) => string\n}\n\n/** 子 run 的用量汇总(从子会话时间线算,含续跑之前的部分) */\nexport interface SubagentUsage {\n requests: number\n input: number\n output: number\n cacheRead: number\n cacheWrite: number\n toolCalls: number\n}\n\n/** 写进父 tool_result 的 JSON(模型可见) */\nexport interface SubagentOutcome {\n role?: string\n childSessionId: string\n /** 只会是 done / handoff / error:paused 不落结果而是冒泡 */\n status: RunResult[\"status\"]\n /** 子 run 最后一轮的文本(最后一次工具调用之后的 model_text 拼接) */\n answer?: string\n /** handoff 时的目标会话,error 时的错误 */\n detail?: string\n usage: SubagentUsage\n}\n\nexport const SUBAGENT_TASK_SCHEMA: Record<string, unknown> = {\n type: \"object\",\n properties: {\n task: {\n type: \"string\",\n description:\n \"What you want this expert to do, self-contained: the expert sees none of your conversation.\",\n },\n },\n required: [\"task\"],\n additionalProperties: false,\n}\n\n/** 缺省子会话 id:父会话 + 这次调用,确定性派生 */\nexport function defaultChildSessionId(ctx: ToolContext): string {\n return `${ctx.sessionId}:${ctx.toolCallId}`\n}\n\nexport function asTool(agent: Agent, opts: AsToolOptions): Tool {\n const abort = opts.abort ?? \"linked\"\n const registry = agent.definition.registry ?? createCoreRegistry()\n const log = agent.definition.log\n\n return defineTool<SubagentTask>({\n name: opts.name,\n description: opts.description,\n inputSchema: SUBAGENT_TASK_SCHEMA,\n risk: opts.risk ?? \"low\",\n validate(input) {\n const task = (input as { task?: unknown } | null)?.task\n if (typeof task !== \"string\" || task.trim() === \"\") throw new Error(\"task must be a non-empty string\")\n return { task }\n },\n async execute(input, ctx) {\n const childSessionId = (opts.childSessionId ?? defaultChildSessionId)(ctx, input)\n // 子日志末条是 run_paused → 这是父续跑补齐 pending:续跑子 run,不再追加 input\n const last = (await log.tail(childSessionId, 1))[0]\n const resuming = last?.type === \"core.run_paused\"\n\n const run = agent.run({\n sessionId: childSessionId,\n ...(resuming ? {} : { input: input.task }),\n // 宿主给别的会话的结论原样下传:子循环把 sessionId 等于自己的拿去校验并记事件,其余再转发给它的工具(多层嵌套)\n ...(ctx.decisions && ctx.decisions.length > 0 ? { decisions: ctx.decisions } : {}),\n ...(ctx.principal ? { principal: ctx.principal } : {}),\n ...(abort === \"linked\" && ctx.signal ? { signal: ctx.signal } : {}),\n })\n\n let answer: string[] = []\n let result: RunResult\n while (true) {\n const step = await run.next()\n if (step.done) {\n result = step.value\n break\n }\n const e = step.value\n switch (e.type) {\n case \"core.budget_usage\":\n // 预算合算:子的每次模型请求都记到父 run 的账上\n ctx.spend?.((e.payload as BudgetUsagePayload).tokens)\n break\n case \"core.tool_call\":\n answer = [] // 答案 = 最后一次工具调用之后的文本\n break\n case \"core.model_text\":\n answer.push((e.payload as { text: string }).text)\n break\n }\n }\n\n if (result.status === \"paused\") {\n // 审批冒泡:不落结果,父 run 整体暂停;宿主处理子的中断后续跑父,父补齐这条 pending 时本工具再进来续跑子\n return subagentPause({\n childSessionId,\n reason: result.reason,\n interruptions: result.interruptions,\n state: result.state,\n })\n }\n\n const outcome: SubagentOutcome = {\n ...(opts.role !== undefined ? { role: opts.role } : {}),\n childSessionId,\n status: result.status,\n usage: usageOf(await readTimeline(log, childSessionId, { registry })),\n }\n let isError = false\n switch (result.status) {\n case \"done\":\n outcome.answer = answer.join(\"\\n\")\n break\n case \"handoff\":\n outcome.answer = answer.join(\"\\n\")\n outcome.detail = `expert handed off to session ${result.toSessionId}; its work continues there`\n break\n case \"error\":\n isError = true\n outcome.detail = `expert failed: ${(result.error.payload as { message?: string }).message ?? \"unknown error\"}`\n break\n }\n const res: ToolResult = { content: [{ type: \"text\", text: JSON.stringify(outcome, null, 2) }], isError }\n return res\n },\n })\n}\n\n/** 子会话时间线里的用量合计:每条 budget_usage 一次请求,tool_call 计工具次数 */\nexport function usageOf(timeline: readonly Event[]): SubagentUsage {\n const usage: SubagentUsage = { requests: 0, input: 0, output: 0, cacheRead: 0, cacheWrite: 0, toolCalls: 0 }\n for (const e of timeline) {\n if (e.type === \"core.budget_usage\") {\n const t = (e.payload as BudgetUsagePayload).tokens\n usage.requests += 1\n usage.input += t.input\n usage.output += t.output\n usage.cacheRead += t.cacheRead ?? 0\n usage.cacheWrite += t.cacheWrite ?? 0\n } else if (e.type === \"core.tool_call\") usage.toolCalls += 1\n }\n return usage\n}\n\n/** 父时间线里,凡 name 在 toolNames 里的 tool_result,其 JSON 里的 childSessionId —— 回放 / 导出用 */\nexport function subagentOutcomesOf(\n events: Iterable<{ type: string; payload: unknown }>,\n toolNames: ReadonlySet<string>,\n): SubagentOutcome[] {\n const found: SubagentOutcome[] = []\n for (const e of events) {\n if (e.type !== \"core.tool_result\") continue\n const p = e.payload as { name: string; content: { type: string; text?: string }[] }\n if (!toolNames.has(p.name)) continue\n const text = p.content.find((c) => c.type === \"text\")?.text\n if (!text) continue\n try {\n const parsed = JSON.parse(text) as Partial<SubagentOutcome>\n if (typeof parsed.childSessionId === \"string\") found.push(parsed as SubagentOutcome)\n } catch {\n // 不是 asTool 写的结果(如入参校验失败的 isError 文本),跳过\n }\n }\n return found\n}\n","/**\n * createAgent:把\"模型 + 工具 + 存储 + 脑子\"装成一个 agent 对象,给出两种用法 ——\n * `handler`(Web 标准 (Request) => Response,缺省 AG-UI 编码)和 `run()`(不经 HTTP 直接跑,脚本 / 队列 / 测试用)。\n *\n * 它不引入新概念:AgentDefinition 就是 runLoop 的跨请求配置,handler 就是 createAgentHandler。\n * 这里只负责把 BoundModel 拆成 model + lowering、把 Stores 拆成 log / blobs / memory(runLease 则换成 handler 的登记表)。\n */\nimport {\n type ApprovalDecisionInput,\n type BoundModel,\n type ContentPart,\n type Event,\n type EventDraft,\n type LoweringDelta,\n type Principal,\n type RunResult,\n runLoop,\n type SerializedRunState,\n type Stores,\n uuidv7,\n} from \"@reinsjs/core\"\nimport {\n type AgentDefinition,\n type AgentHandler,\n createAgentHandler,\n type HandlerOptions,\n leasedRunRegistry,\n} from \"@reinsjs/server\"\nimport { aguiEncoding } from \"@reinsjs/ui-agui\"\n\nexport interface CreateAgentOptions\n extends Omit<AgentDefinition, \"model\" | \"lowering\" | \"log\" | \"blobs\" | \"memory\"> {\n /** `anthropic(\"claude-opus-5\", { apiKey })` 之类工厂的返回值,或自己组的 { model, lowering } */\n model: BoundModel\n /**\n * `memoryStore()`、`sqliteStores(db)`、`await pgStores(client)`(B9)或自己实现的一套接口;只有 log 必需。\n * 带 `runLease` 时 handler 自动用跨进程的租约登记表(D4)——多实例部署同一条会话同时只跑一个 run\n */\n store: Stores\n /** 传输层选项;缺省 AG-UI 编码(`encode: aguiEncoding()`),想推原始事件就传 `encode: () => rawEncoder` */\n handler?: HandlerOptions\n}\n\n/** `agent.run()` 的每次参数:与 HTTP 请求体是同一组字段,多了 signal / onDelta / principal 这些进程内才有的 */\nexport interface RunOptions {\n /** 缺省新建会话;结果的 sessionId 告诉你它是什么 */\n sessionId?: string\n input?: string | ContentPart[] | EventDraft\n resume?: SerializedRunState\n decisions?: readonly ApprovalDecisionInput[]\n principal?: Principal\n signal?: AbortSignal\n onDelta?: (delta: LoweringDelta) => void\n}\n\nexport interface Agent {\n /** 跨请求不变的循环配置;要自己起 runLoop 或接别的传输层时用它 */\n readonly definition: AgentDefinition\n /** Web 标准 handler:POST 起 run、GET 补发,见 @reinsjs/server */\n readonly handler: AgentHandler\n /** 不经 HTTP 直接跑一次:yield 每条刚 append 的事件,返回 RunResult 四态 */\n run(options?: RunOptions): AsyncGenerator<Event, RunResult>\n}\n\nexport function createAgent(options: CreateAgentOptions): Agent {\n const { model, store, handler: handlerOptions, ...rest } = options\n const definition: AgentDefinition = {\n ...rest,\n model: model.model,\n lowering: model.lowering,\n log: store.log,\n ...(store.blobs ? { blobs: store.blobs } : {}),\n ...(store.memory ? { memory: store.memory } : {}),\n }\n // store 带 runLease(如 pgStores)就自动装跨进程的租约登记表(D4),宿主不用记这一步;自己传 handler.runs 则以宿主为准\n const runs =\n store.runLease !== undefined\n ? {\n runs: leasedRunRegistry(store.runLease, {\n ...(handlerOptions?.warn !== undefined ? { warn: handlerOptions.warn } : {}),\n }),\n }\n : {}\n const handler = createAgentHandler(definition, { encode: aguiEncoding(), ...runs, ...handlerOptions })\n return {\n definition,\n handler,\n run(runOptions = {}) {\n const { sessionId, ...perRun } = runOptions\n return runLoop({ ...definition, ...stripUndefined(perRun), sessionId: sessionId ?? uuidv7() })\n },\n }\n}\n\n/** exactOptionalPropertyTypes 下不能把 undefined 传给可选字段,这里把没给的键去掉 */\nfunction stripUndefined<T extends object>(obj: T): T {\n return Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== undefined)) as T\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reinsjs/agent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "reins — hand the reins to the model. createAgent() + re-exports of @reinsjs/core, @reinsjs/server and @reinsjs/ui-agui",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|
|
@@ -34,15 +34,15 @@
|
|
|
34
34
|
"dist",
|
|
35
35
|
"CHANGELOG.md"
|
|
36
36
|
],
|
|
37
|
+
"scripts": {
|
|
38
|
+
"build": "tsup"
|
|
39
|
+
},
|
|
37
40
|
"dependencies": {
|
|
38
|
-
"@reinsjs/core": "
|
|
39
|
-
"@reinsjs/server": "
|
|
40
|
-
"@reinsjs/ui-agui": "
|
|
41
|
+
"@reinsjs/core": "workspace:*",
|
|
42
|
+
"@reinsjs/server": "workspace:*",
|
|
43
|
+
"@reinsjs/ui-agui": "workspace:*"
|
|
41
44
|
},
|
|
42
45
|
"engines": {
|
|
43
46
|
"node": ">=22"
|
|
44
|
-
},
|
|
45
|
-
"scripts": {
|
|
46
|
-
"build": "tsup"
|
|
47
47
|
}
|
|
48
|
-
}
|
|
48
|
+
}
|