@botbotgo/agent-harness 0.0.210 → 0.0.212
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.md +31 -42
- package/README.zh.md +59 -72
- package/dist/package-version.d.ts +1 -1
- package/dist/package-version.js +1 -1
- package/dist/persistence/sqlite-store.js +75 -20
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -14,11 +14,11 @@
|
|
|
14
14
|
# @botbotgo/agent-harness
|
|
15
15
|
|
|
16
16
|
<p align="center">
|
|
17
|
-
<strong>
|
|
17
|
+
<strong>Build a stable, enterprise-grade, operable runtime for multi-agent products—with approvals, recovery, and operator control built in.</strong>
|
|
18
18
|
</p>
|
|
19
19
|
|
|
20
20
|
<p align="center">
|
|
21
|
-
<strong>
|
|
21
|
+
<strong>Ship quickly: one workspace assembles into one production-ready product runtime.</strong>
|
|
22
22
|
</p>
|
|
23
23
|
|
|
24
24
|
<p align="center">
|
|
@@ -39,14 +39,14 @@
|
|
|
39
39
|
|
|
40
40
|
<p align="center">
|
|
41
41
|
<em
|
|
42
|
-
>
|
|
42
|
+
>For AI solutions and help shipping a product idea, contact
|
|
43
43
|
<a href="mailto:info@easynet.world">info@easynet.world</a>.</em
|
|
44
44
|
>
|
|
45
45
|
</p>
|
|
46
46
|
|
|
47
|
-
## Start
|
|
47
|
+
## Start in a few lines
|
|
48
48
|
|
|
49
|
-
You can
|
|
49
|
+
You can boot an agent runtime in a few lines of code:
|
|
50
50
|
|
|
51
51
|
```ts
|
|
52
52
|
import { createAgentHarness, request, stop } from "@botbotgo/agent-harness";
|
|
@@ -65,16 +65,17 @@ try {
|
|
|
65
65
|
}
|
|
66
66
|
```
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
The goal is an **operable** runtime: approvals, recovery, inspection, and governance—ready for production operations.
|
|
69
|
+
Where you already use LangChain v1 or DeepAgents for execution, agent-harness adds the product runtime layer around
|
|
70
|
+
them without forcing a rewrite.
|
|
70
71
|
|
|
71
72
|
## Documentation Paths
|
|
72
73
|
|
|
73
|
-
|
|
74
|
+
Choose an entry point that matches what you need:
|
|
74
75
|
|
|
75
|
-
- **Technology:**
|
|
76
|
+
- **Technology:** capability comparison, runtime model, protocol surfaces, API, recovery, approvals, and operator control
|
|
76
77
|
- **Product:** what the stable runtime surface already is, which product scenarios it fits, and why it is not another agent framework
|
|
77
|
-
- **Commercial:**
|
|
78
|
+
- **Commercial:** pricing, engagement process, and scoped services for deployment help, launch hardening, and team handoff
|
|
78
79
|
|
|
79
80
|
Recommended entry points:
|
|
80
81
|
|
|
@@ -86,18 +87,18 @@ Recommended entry points:
|
|
|
86
87
|
|
|
87
88
|
## License & Commercial Support
|
|
88
89
|
|
|
89
|
-
This
|
|
90
|
+
This project is licensed under **Apache License 2.0**.
|
|
90
91
|
[LICENSE](./LICENSE)
|
|
91
92
|
|
|
92
|
-
Core runtime is open source
|
|
93
|
-
Commercial support
|
|
93
|
+
Core runtime is open source: inspect and run it freely.
|
|
94
|
+
Commercial support focuses on helping teams reach a production-ready handoff, including:
|
|
94
95
|
|
|
95
96
|
- Deployment and integration guidance for your environment
|
|
96
97
|
- Initial deployment setup and launch assistance
|
|
97
98
|
- Priority issue triage and troubleshooting
|
|
98
99
|
- Runtime governance, approval flow, and recovery hardening support
|
|
99
100
|
- Custom tools, connectors, and protocol integrations
|
|
100
|
-
- Operator runbooks and handoff guidance for
|
|
101
|
+
- Operator runbooks and handoff guidance for your team
|
|
101
102
|
|
|
102
103
|
Production operations, managed hosting, on-call coverage, and long-term run-the-system support are not included by default.
|
|
103
104
|
If a team wants us to take on that responsibility, we scope it separately based on environment complexity and SLA expectations.
|
|
@@ -108,29 +109,29 @@ If your team needs a scalable enterprise setup, please contact:
|
|
|
108
109
|
Additional docs:
|
|
109
110
|
|
|
110
111
|
- [Commercial service offerings](./docs/commercial-pricing.md)
|
|
111
|
-
- [
|
|
112
|
+
- [Commercial engagement process](./docs/enterprise-process.md)
|
|
112
113
|
|
|
113
114
|
## Easy to start · Full runtime · Configure and extend
|
|
114
115
|
|
|
115
|
-
**At a glance:**
|
|
116
|
+
**At a glance:** onboarding stays thin, the runtime ships as a full layer, and day-to-day work lives in **YAML** plus **extensions** (local tools, SKILL packages, MCP)—not bespoke runtime plumbing.
|
|
116
117
|
|
|
117
118
|
- **Easy to start:** `createAgentHarness` → `request` → `stop`, plus inspection helpers such as `subscribe`, `listSessions`, `listApprovals`, and `resolveApproval`.
|
|
118
119
|
- **Configure:** routing, models, tools, stores, backends, MCP, recovery, and maintenance in declarative workspace YAML (see [Quick Start](#quick-start) and [How To Configure](#how-to-configure)).
|
|
119
120
|
- **Extend:** drop `tool({...})` modules and SKILL trees under `resources/`, wire shared tools and MCP in catalogs, and let agents whitelist what they use.
|
|
120
121
|
- **Built into the runtime:** persisted `requests`, `sessions`, `approvals`, and `events`; recovery and queueing; streaming listeners; MCP in/out; LangChain v1 and DeepAgents adapters—so you do not rebuild that layer per app.
|
|
121
122
|
|
|
122
|
-
##
|
|
123
|
+
## Runtime capabilities at a glance
|
|
123
124
|
|
|
124
|
-
The
|
|
125
|
+
The public API spans a full product runtime—persistent records, memory and evidence, protocol surfaces, and governance—not only a thin bootstrap around YAML and tools.
|
|
125
126
|
|
|
126
127
|
- **Core runtime API:** `createAgentHarness`, `request`, `subscribe`, `resolveApproval`, inspection helpers, and stable persisted runtime records for `requests`, `sessions`, `approvals`, `events`, and artifacts.
|
|
127
128
|
- **Runtime memory and evidence:** `memorize`, `recall`, `listMemories`, memory policy hooks, `listArtifacts`, `getArtifact`, `exportEvaluationBundle`, `replayEvaluationBundle`, and request/session evidence export helpers.
|
|
128
129
|
- **Protocol and transport surfaces:** `createAcpServer`, `serveAcpStdio`, `serveAcpHttp`, `serveA2aHttp`, `serveAgUiHttp`, and `createRuntimeMcpServer` / `serveRuntimeMcpOverStdio`.
|
|
129
130
|
- **Governed workspace runtime:** YAML-owned routing, concurrency, maintenance, MCP policy, runtime governance bundles, and approval defaults for sensitive memory or write-like MCP side effects.
|
|
130
131
|
|
|
131
|
-
|
|
132
|
+
If you integrate external clients, treat `deepagents-acp` as the primary protocol direction: clients connect through that surface while `agent-harness` keeps persistence, recovery, approvals, and operator control on the runtime side.
|
|
132
133
|
|
|
133
|
-
##
|
|
134
|
+
## The problem this solves
|
|
134
135
|
|
|
135
136
|
In one line: `agent-harness` productizes the runtime work that usually appears after the demo.
|
|
136
137
|
|
|
@@ -164,7 +165,7 @@ Teams still need clear answers to the runtime questions that appear after that s
|
|
|
164
165
|
|
|
165
166
|
`agent-harness` solves that layer. It keeps agent execution upstream while turning the application runtime into something teams can operate, recover, and govern.
|
|
166
167
|
|
|
167
|
-
|
|
168
|
+
In short:
|
|
168
169
|
|
|
169
170
|
- you bring the workspace, agents, tools, and prompts
|
|
170
171
|
- `agent-harness` brings persisted `requests`, `sessions`, `approvals`, `events`, recovery, and operator visibility
|
|
@@ -221,7 +222,7 @@ In practice, the harness exists for the parts that are expensive and repetitive
|
|
|
221
222
|
- queueing, concurrency, maintenance, and operational policy
|
|
222
223
|
- stable runtime records that stay usable even if the backend changes
|
|
223
224
|
|
|
224
|
-
The
|
|
225
|
+
The default workspace configuration shipped with the package is deliberately full-shaped. The bundled YAML keeps explicit defaults for important runtime and agent knobs so teams can start from concrete configuration instead of reverse-engineering adapter behavior from source.
|
|
225
226
|
|
|
226
227
|
The default rule is:
|
|
227
228
|
|
|
@@ -241,7 +242,7 @@ Start with these user-facing docs:
|
|
|
241
242
|
- `docs/long-term-memory.md`
|
|
242
243
|
- `docs/memory-policy-reference.md`
|
|
243
244
|
|
|
244
|
-
|
|
245
|
+
Deeper design notes and boundary discussions ship alongside the package for advanced readers; everyday integration and operations rely on the README, developer docs, and topical references above.
|
|
245
246
|
|
|
246
247
|
`deepagents-acp` is the required external protocol direction when external tools need a standard runtime boundary. The harness should conform to `deepagents-acp` semantics at that boundary while keeping runtime lifecycle, persistence, recovery, and governance harness-owned.
|
|
247
248
|
|
|
@@ -251,20 +252,6 @@ Recommended orchestration shape for long-running flows:
|
|
|
251
252
|
- use `backend: deepagent` when you want high-level execution semantics with minimal application wiring
|
|
252
253
|
- keep `backend: langchain-v1` for lighter direct-response or explicitly chosen V1 agent shapes
|
|
253
254
|
|
|
254
|
-
## Why This Exists
|
|
255
|
-
|
|
256
|
-
Most agent tooling stops at execution. Production software does not.
|
|
257
|
-
|
|
258
|
-
Real products need a runtime that can answer harder questions:
|
|
259
|
-
|
|
260
|
-
- Where do requests live?
|
|
261
|
-
- How are approvals resolved?
|
|
262
|
-
- What survives process restart?
|
|
263
|
-
- How do you inspect sessions and events without exposing raw backend state?
|
|
264
|
-
- How do you swap backend implementations without rewriting the product model?
|
|
265
|
-
|
|
266
|
-
`agent-harness` is the layer that answers those questions without turning your application API into a mirror of LangChain v1 or DeepAgents.
|
|
267
|
-
|
|
268
255
|
## What Makes It Different
|
|
269
256
|
|
|
270
257
|
- It treats `requests`, `sessions`, `approvals`, `events`, and recovery as first-class product records
|
|
@@ -274,9 +261,9 @@ Real products need a runtime that can answer harder questions:
|
|
|
274
261
|
- It lets YAML own assembly and operating policy while code keeps a small, stable surface
|
|
275
262
|
- It goes deep on runtime concerns that upstream libraries do not fully productize
|
|
276
263
|
|
|
277
|
-
##
|
|
264
|
+
## Primary use cases
|
|
278
265
|
|
|
279
|
-
|
|
266
|
+
These scenarios map most directly to what the runtime is built for:
|
|
280
267
|
|
|
281
268
|
- Enterprise internal agent runtime: approvals, restart-safe recovery, operator evidence, and policy-owned MCP access.
|
|
282
269
|
- Code modernization runtime: long-running coding flows, approval checkpoints, resumable runs, and exported evidence packages.
|
|
@@ -367,7 +354,7 @@ Three-minute mental model:
|
|
|
367
354
|
2. Call `request(runtime, { ... })` to execute one request.
|
|
368
355
|
3. Inspect persisted runtime records instead of treating the final answer as the only product artifact.
|
|
369
356
|
|
|
370
|
-
|
|
357
|
+
In brief:
|
|
371
358
|
|
|
372
359
|
- your team builds the agent app
|
|
373
360
|
- `agent-harness` makes that app operable
|
|
@@ -718,7 +705,7 @@ Current temporary limits on the `backend: langchain-v1` path are:
|
|
|
718
705
|
|
|
719
706
|
- approval-gated side-effect tools are less reliable than the DeepAgents path under real remote models
|
|
720
707
|
- long multi-agent or orchestration-heavy flows are not the recommended default path
|
|
721
|
-
- the
|
|
708
|
+
- the package now treats DeepAgents as the default execution path for complex runtime coverage, and LangChain v1 should be selected explicitly when a workspace truly wants that behavior
|
|
722
709
|
|
|
723
710
|
Practical guidance:
|
|
724
711
|
|
|
@@ -748,6 +735,8 @@ Important fields:
|
|
|
748
735
|
- `maintenance.checkpoints` trims backend checkpoint state used for resume/recovery
|
|
749
736
|
- `maintenance.records` trims harness-owned terminal session/request records stored in `runtime.sqlite`
|
|
750
737
|
|
|
738
|
+
When libSQL reports an error against harness runtime persistence, the message is prefixed with the absolute path to `runtime.sqlite`. For constraint-class failures (or whenever you set `AGENT_HARNESS_RUNTIME_SQLITE_DEBUG=1`), the message also includes a truncated copy of the failing SQL so you can tell harness persistence apart from other SQLite databases in the same process.
|
|
739
|
+
|
|
751
740
|
Example:
|
|
752
741
|
|
|
753
742
|
```yaml
|
|
@@ -963,7 +952,7 @@ spec:
|
|
|
963
952
|
middleware: []
|
|
964
953
|
```
|
|
965
954
|
|
|
966
|
-
For backend-specific options, prefer the upstream concept directly inside `spec.config`. Keep the public runtime contract in the main developer docs and API reference rather than relying on
|
|
955
|
+
For backend-specific options, prefer the upstream concept directly inside `spec.config`. Keep the public runtime contract in the main developer docs and API reference rather than relying only on informal comparison notes.
|
|
967
956
|
|
|
968
957
|
## Design Notes
|
|
969
958
|
|
package/README.zh.md
CHANGED
|
@@ -14,11 +14,11 @@
|
|
|
14
14
|
# @botbotgo/agent-harness
|
|
15
15
|
|
|
16
16
|
<p align="center">
|
|
17
|
-
<strong
|
|
17
|
+
<strong>快速搭建稳定、可运维的企业级多智能体运行时:内置审批、恢复与运维能力,不止于「能跑通执行」。</strong>
|
|
18
18
|
</p>
|
|
19
19
|
|
|
20
20
|
<p align="center">
|
|
21
|
-
<strong
|
|
21
|
+
<strong>一个工作区即可装配成面向生产的运行时(产品级能力)。</strong>
|
|
22
22
|
</p>
|
|
23
23
|
|
|
24
24
|
<p align="center">
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
</p>
|
|
28
28
|
|
|
29
29
|
<p align="center">
|
|
30
|
-
<a href="https://botbotgo.github.io/agent-harness/development/">开发文档</a>
|
|
30
|
+
<a href="https://botbotgo.github.io/agent-harness/development/zh/">开发文档</a>
|
|
31
31
|
(多页面静态文档位于 <code>docs/development/</code>,支持 English / 中文)
|
|
32
32
|
</p>
|
|
33
33
|
|
|
@@ -39,14 +39,14 @@
|
|
|
39
39
|
|
|
40
40
|
<p align="center">
|
|
41
41
|
<em
|
|
42
|
-
|
|
42
|
+
>如需 AI 解决方案或产品落地支持,欢迎来信
|
|
43
43
|
<a href="mailto:info@easynet.world">info@easynet.world</a>。</em
|
|
44
44
|
>
|
|
45
45
|
</p>
|
|
46
46
|
|
|
47
47
|
## 几行代码启动
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
几行代码即可把工作区跑成智能体运行时:
|
|
50
50
|
|
|
51
51
|
```ts
|
|
52
52
|
import { createAgentHarness, request, stop } from "@botbotgo/agent-harness";
|
|
@@ -65,74 +65,73 @@ try {
|
|
|
65
65
|
}
|
|
66
66
|
```
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
recovery、inspection 和 operator control。
|
|
68
|
+
目标是交付<strong>可运维</strong>的运行时:审批、恢复、可观测与治理默认就绪。若执行层已采用 LangChain v1 或 DeepAgents,可在其之上衔接产品级运行时,无需推倒重来。
|
|
70
69
|
|
|
71
70
|
## 阅读路径
|
|
72
71
|
|
|
73
|
-
|
|
72
|
+
按你的目标选入口即可:
|
|
74
73
|
|
|
75
|
-
-
|
|
76
|
-
-
|
|
77
|
-
-
|
|
74
|
+
- **想尽快接入:** 从[开发文档](./docs/development/zh/index.html)起步,再按需打开 API、协议与 Cookbook。
|
|
75
|
+
- **想弄清边界:** 读[并列对比](./docs/development/zh/comparison.html),区分运行时产品与上游执行框架。
|
|
76
|
+
- **需要部署、加固或交接支持:** 查看[商业服务](./docs/commercial-pricing.md)与[合作流程](./docs/enterprise-process.md)。
|
|
78
77
|
|
|
79
78
|
推荐入口:
|
|
80
79
|
|
|
81
|
-
- [开发文档入口](./docs/development/index.html)
|
|
82
|
-
- [并列对比页](./docs/development/comparison.html)
|
|
83
|
-
- [API 参考](./docs/development/api-reference.html)
|
|
84
|
-
- [
|
|
80
|
+
- [开发文档入口](./docs/development/zh/index.html)
|
|
81
|
+
- [并列对比页](./docs/development/zh/comparison.html)
|
|
82
|
+
- [API 参考](./docs/development/zh/api-reference.html)
|
|
83
|
+
- [协议接入说明](./docs/development/zh/protocol-surfaces.html)
|
|
85
84
|
- [商业服务价格说明](./docs/commercial-pricing.md)
|
|
86
85
|
|
|
87
86
|
## 许可证与商业支持
|
|
88
87
|
|
|
89
|
-
|
|
88
|
+
本项目采用 **Apache License 2.0** 开源许可。[查看 LICENSE](./LICENSE)
|
|
90
89
|
|
|
91
|
-
|
|
92
|
-
|
|
90
|
+
核心运行时开源,可自由查看与试用。
|
|
91
|
+
商业支持侧重帮助团队完成生产落地与交接,例如:
|
|
93
92
|
|
|
94
|
-
-
|
|
95
|
-
-
|
|
93
|
+
- 部署与接入咨询(面向你的环境)
|
|
94
|
+
- 初期环境搭建与上线协助
|
|
96
95
|
- 优先故障响应与问题排查
|
|
97
96
|
- 运行时治理、审批流和恢复能力加固支持
|
|
98
97
|
- 定制工具、连接器与协议接入开发
|
|
99
|
-
-
|
|
98
|
+
- 操作手册与交接说明(面向接手团队)
|
|
100
99
|
|
|
101
|
-
|
|
102
|
-
|
|
100
|
+
正式生产运维、托管、值班与长期代运营不在默认范围内。
|
|
101
|
+
若需要我方承担上述职责,将按环境与 SLA 单独评估与报价。
|
|
103
102
|
|
|
104
|
-
|
|
103
|
+
企业级合作请联络:**[info@easynet.world](mailto:info@easynet.world)**。
|
|
105
104
|
|
|
106
105
|
相关资料:
|
|
107
106
|
|
|
108
107
|
- [商业服务价格说明](./docs/commercial-pricing.md)
|
|
109
|
-
- [
|
|
108
|
+
- [商业合作流程](./docs/enterprise-process.md)
|
|
110
109
|
|
|
111
110
|
## 容易上手 · 能力齐全 · 配置与扩展
|
|
112
111
|
|
|
113
|
-
**一句话:**
|
|
112
|
+
**一句话:** 对外接口保持精简、运行时能力一次备齐,日常工作落在 **YAML 配置** 与 **扩展**(本地工具、SKILL、MCP)上,而不是反复搭建运行时底座。
|
|
114
113
|
|
|
115
114
|
- **容易上手:** `createAgentHarness` → `request` → `stop`,以及 `subscribe`、`listSessions`、`listApprovals`、`resolveApproval` 等查询与控制能力。
|
|
116
115
|
- **配置:** 路由、模型、工具、存储、后端、MCP、恢复与维护写在声明式工作区 YAML 里(见[快速开始](#快速开始)与[如何配置](#如何配置))。
|
|
117
116
|
- **扩展:** 在 `resources/` 下放置 `tool({...})` 模块与 SKILL 目录,在目录里声明共享工具与 MCP,再由各 agent 按名字白名单启用。
|
|
118
117
|
- **内建运行时:** 持久化 `requests`、`sessions`、`approvals` 与 `events`;恢复与排队;流式监听;MCP 接入与对外暴露;LangChain v1 与 DeepAgents 适配——避免每个应用重复造这一层。
|
|
119
118
|
|
|
120
|
-
##
|
|
119
|
+
## 运行时能力速览
|
|
121
120
|
|
|
122
|
-
|
|
121
|
+
若你想先看「今天能直接用到什么」,可从本节读起。`agent-harness` 提供完整的产品级运行时能力,而不只是「能启动」的脚手架。
|
|
123
122
|
|
|
124
|
-
- **核心 runtime API:** `createAgentHarness`、`request`、`subscribe`、`resolveApproval
|
|
125
|
-
- **运行时 memory 与证据能力:** `memorize`、`recall`、`listMemories`、memory policy hooks、`listArtifacts`、`getArtifact`、`exportEvaluationBundle`、`replayEvaluationBundle`,以及 request / session
|
|
126
|
-
-
|
|
123
|
+
- **核心 runtime API:** `createAgentHarness`、`request`、`subscribe`、`resolveApproval`、各类查询与检查辅助 API,以及稳定持久化的 `requests`、`sessions`、`approvals`、`events` 与 artifacts 记录。
|
|
124
|
+
- **运行时 memory 与证据能力:** `memorize`、`recall`、`listMemories`、memory policy hooks、`listArtifacts`、`getArtifact`、`exportEvaluationBundle`、`replayEvaluationBundle`,以及 request / session 级证据导出辅助函数。
|
|
125
|
+
- **协议与传输层:** `createAcpServer`、`serveAcpStdio`、`serveAcpHttp`、`serveA2aHttp`、`serveAgUiHttp`,以及 `createRuntimeMcpServer` / `serveRuntimeMcpOverStdio`。
|
|
127
126
|
- **受治理的工作区运行时:** 由 YAML 持有的路由、并发、维护、MCP 策略、runtime governance bundles,以及针对敏感 memory 或写类 MCP 副作用的默认审批门槛。
|
|
128
127
|
|
|
129
|
-
|
|
128
|
+
若你的产品需要对接外部客户端,可从本节理解边界:`deepagents-acp` 是主要的外部协议接入方向;持久化、恢复、审批与运行控制仍由 `agent-harness` 在运行时侧承担。
|
|
130
129
|
|
|
131
|
-
##
|
|
130
|
+
## 这能解决什么问题
|
|
132
131
|
|
|
133
|
-
一句话概括:`agent-harness` 把通常在 demo
|
|
132
|
+
一句话概括:`agent-harness` 把通常在 demo 之后才不得不补上的运行时工作,提前做成产品运行时的一部分。
|
|
134
133
|
|
|
135
|
-
如果团队已经有 agents、prompts、tools 和 workflows
|
|
134
|
+
如果团队已经有 agents、prompts、tools 和 workflows,真正缺的通常不是再多一层执行,而是把这些能力沉淀成**可长期运维的软件**所需的运行时层。
|
|
136
135
|
|
|
137
136
|
第一天就能直接拿到的东西:
|
|
138
137
|
|
|
@@ -219,27 +218,27 @@ AI 让 agent 逻辑、工具调用和工作流代码更容易生成,真正更
|
|
|
219
218
|
- 队列、并发、维护与运维策略
|
|
220
219
|
- 即使后端变更也保持稳定的运行时记录模型
|
|
221
220
|
|
|
222
|
-
|
|
221
|
+
本包附带的默认工作区配置刻意做成「形状完整」。随发行版提供的 YAML 对关键运行时与 agent 开关给出显式默认值,便于从具体配置起步,而不必从源码反推适配器行为。
|
|
223
222
|
|
|
224
223
|
默认原则是:
|
|
225
224
|
|
|
226
225
|
- 若 LangChain v1 或 DeepAgents 已有能力,则在 YAML 中映射并在内部适配
|
|
227
226
|
- 除非问题确实属于运行时职责,否则不增加新的公共运行时 API
|
|
228
227
|
|
|
229
|
-
|
|
228
|
+
建议从这些面向用户的文档开始(中文多页面在 `docs/development/zh/`):
|
|
230
229
|
|
|
231
|
-
- `docs/development/index.html`
|
|
232
|
-
- `docs/development/getting-started.html`
|
|
233
|
-
- `docs/development/comparison.html`
|
|
234
|
-
- `docs/development/api-reference.html`
|
|
235
|
-
- `docs/development/protocol-surfaces.html`
|
|
236
|
-
- `docs/development/cookbook.html`
|
|
230
|
+
- `docs/development/zh/index.html`
|
|
231
|
+
- `docs/development/zh/getting-started.html`
|
|
232
|
+
- `docs/development/zh/comparison.html`
|
|
233
|
+
- `docs/development/zh/api-reference.html`
|
|
234
|
+
- `docs/development/zh/protocol-surfaces.html`
|
|
235
|
+
- `docs/development/zh/cookbook.html`
|
|
237
236
|
- `docs/runtime-inspection-contract.md`
|
|
238
237
|
- `docs/tool-execution-policy.md`
|
|
239
238
|
- `docs/long-term-memory.md`
|
|
240
239
|
- `docs/memory-policy-reference.md`
|
|
241
240
|
|
|
242
|
-
|
|
241
|
+
项目内还包含面向进阶读者与贡献者的设计说明与边界讨论;日常接入与运维以 README、开发文档与上文专题为准即可。
|
|
243
242
|
|
|
244
243
|
当外部工具需要标准运行时边界时,`deepagents-acp` 是必须遵循的外部协议方向。`agent-harness` 应在该边界上严格契合 `deepagents-acp` 语义,同时继续把运行时生命周期、持久化、恢复与治理保留在 harness 内部。
|
|
245
244
|
|
|
@@ -249,36 +248,22 @@ AI 让 agent 逻辑、工具调用和工作流代码更容易生成,真正更
|
|
|
249
248
|
- 想用高层执行语义、少写应用编排时,优先选择 `backend: deepagent`
|
|
250
249
|
- 轻量 direct-response 或明确需要 V1 agent 语义时,使用 `backend: langchain-v1`
|
|
251
250
|
|
|
252
|
-
## 为何需要它
|
|
253
|
-
|
|
254
|
-
多数 agent 工具停在「能跑」,但生产软件不能只停在这里。
|
|
255
|
-
|
|
256
|
-
真实产品需要能回答更难问题的运行时:
|
|
257
|
-
|
|
258
|
-
- 请求(requests)存在哪里?
|
|
259
|
-
- 审批如何闭环?
|
|
260
|
-
- 进程重启后什么还在?
|
|
261
|
-
- 如何在不暴露原始后端状态的前提下检查会话与事件?
|
|
262
|
-
- 如何在不大改产品模型的前提下替换后端实现?
|
|
263
|
-
|
|
264
|
-
`agent-harness` 在不把应用 API 做成 LangChain v1 / DeepAgents 翻版的前提下,回答这些问题。
|
|
265
|
-
|
|
266
251
|
## 有何不同
|
|
267
252
|
|
|
268
|
-
- 将 `requests`、`sessions`、`approvals`、`events`
|
|
269
|
-
-
|
|
253
|
+
- 将 `requests`、`sessions`、`approvals`、`events` 与恢复视为核心产品数据(长期可查、可治理)
|
|
254
|
+
- 给运维侧提供运行时控制面,而不是把原始后端内部结构直接暴露出去
|
|
270
255
|
- 将可观测性与治理留在运行时:包括 trace correlation、continuity metadata,以及高风险副作用的默认审批
|
|
271
256
|
- 将 checkpoint 恢复作为系统管理的行为,而不是把 checkpoint 细节抬成主 API
|
|
272
257
|
- 复杂装配与运行策略交给 YAML,代码面保持小而稳
|
|
273
258
|
- 在上游库未充分产品化的运行时问题上做深做透
|
|
274
259
|
|
|
275
|
-
##
|
|
260
|
+
## 典型应用场景
|
|
276
261
|
|
|
277
|
-
|
|
262
|
+
下面三类用法与 runtime 的设计目标最直接对应:
|
|
278
263
|
|
|
279
|
-
-
|
|
264
|
+
- 企业内部智能体运行时:审批、重启恢复、运维侧证据链,以及由策略约束的 MCP 访问控制。
|
|
280
265
|
- 代码现代化运行时:长链路 coding flow、审批检查点、可恢复 runs,以及可导出的运行证据包。
|
|
281
|
-
- 协议桥接运行时:ACP、A2A、AG-UI 与 runtime MCP
|
|
266
|
+
- 协议桥接运行时:ACP、A2A、AG-UI 与 runtime MCP 共用一套稳定控制面,而不是为每个对外入口各写一层集成胶水。
|
|
282
267
|
|
|
283
268
|
一套常见的 runtime 治理默认值大致如下:
|
|
284
269
|
|
|
@@ -365,7 +350,7 @@ try {
|
|
|
365
350
|
2. 用 `request(runtime, { ... })` 执行一次请求。
|
|
366
351
|
3. 把持久化的运行时记录当成产品资产,而不是只盯着最终回答。
|
|
367
352
|
|
|
368
|
-
|
|
353
|
+
一句话概括:
|
|
369
354
|
|
|
370
355
|
- 你的团队负责构建 agent app
|
|
371
356
|
- `agent-harness` 负责让这个 app 可运维
|
|
@@ -505,7 +490,7 @@ const recalled = await recall(runtime, {
|
|
|
505
490
|
|
|
506
491
|
- `memorize(...)` 返回稳定的 `MemoryRecord` 与 `MemoryDecision` 结果,而 merge、review、archive 与存储布局仍由 runtime 内部托管
|
|
507
492
|
- `recall(...)` 返回按相关性排序、并按 scope / kind 过滤后的 `MemoryRecord`
|
|
508
|
-
- `listMemories(...)` 返回稳定的 `MemoryRecord
|
|
493
|
+
- `listMemories(...)` 返回稳定的 `MemoryRecord`,用于排查与管理场景;如果不传 status 过滤器,默认只返回 `active`
|
|
509
494
|
- `updateMemory(...)` 通过 `memoryId` 更新单条 durable memory,而不暴露内部 store namespace
|
|
510
495
|
- `removeMemory(...)` 通过 `memoryId` 删除单条 durable memory,并重建运行时托管的 projection
|
|
511
496
|
- 业务知识分类、review UI 与管理后台仍应留在应用层
|
|
@@ -661,12 +646,12 @@ await stop(runtime);
|
|
|
661
646
|
本地 function tool 如果在模块里声明了 schema,runtime governance 会直接把该模块 schema 视为事实来源;不需要为了 schema-bound 元数据再额外复制一份 YAML `inputSchema.ref`。
|
|
662
647
|
若本地工具使用 Zod schema,请让工作区或隔离的 `resources` 包统一使用 `zod@^4`,避免 raw shape validator 与 runtime 解析落在不同 major 版本上。
|
|
663
648
|
|
|
664
|
-
|
|
649
|
+
配置大致分这几层(由下至上叠加):
|
|
665
650
|
|
|
666
|
-
-
|
|
667
|
-
- agent
|
|
668
|
-
- `config/runtime/workspace.yaml`
|
|
669
|
-
- `config/catalogs/*.yaml`
|
|
651
|
+
- workspace 启动时扫描本地与附加的 `resources` 包,建立统一 registry
|
|
652
|
+
- 各 agent 再按名称白名单选用 tools 与 skills
|
|
653
|
+
- `config/runtime/workspace.yaml` 承载运行时策略
|
|
654
|
+
- `config/catalogs/*.yaml` 承载可复用对象目录
|
|
670
655
|
- `config/**/*.yaml` 中的 agent 装配
|
|
671
656
|
|
|
672
657
|
### Backend 选择建议
|
|
@@ -677,7 +662,7 @@ await stop(runtime);
|
|
|
677
662
|
|
|
678
663
|
- 在真实远端模型下,带 approval 的副作用工具调用稳定性弱于 DeepAgents 路径
|
|
679
664
|
- 不建议把它作为长链路、多 agent、重 orchestration 流程的默认执行路径
|
|
680
|
-
-
|
|
665
|
+
- 本包当前已把 DeepAgents 作为复杂运行时覆盖的默认主路径;只有在工作区明确需要 V1 行为时,才应显式选择 LangChain v1
|
|
681
666
|
|
|
682
667
|
实际建议:
|
|
683
668
|
|
|
@@ -709,6 +694,8 @@ await stop(runtime);
|
|
|
709
694
|
- `maintenance.checkpoints` 清理后端用于 resume/recovery 的 checkpoint 状态
|
|
710
695
|
- `maintenance.records` 清理 harness 自己保存在 `runtime.sqlite` 中、已结束的 session/request 记录
|
|
711
696
|
|
|
697
|
+
当 libSQL 对 harness 运行时持久化报错时,错误信息会带上 `runtime.sqlite` 的绝对路径。对约束类错误(或设置环境变量 `AGENT_HARNESS_RUNTIME_SQLITE_DEBUG=1` 时),信息中还会包含被截断的失败 SQL,便于在同一进程里区分 harness 与其它 SQLite 数据库。
|
|
698
|
+
|
|
712
699
|
示例:
|
|
713
700
|
|
|
714
701
|
```yaml
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export declare const AGENT_HARNESS_VERSION = "0.0.211";
|
package/dist/package-version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export const AGENT_HARNESS_VERSION = "0.0.211";
|
|
@@ -27,6 +27,27 @@ function toSqliteUrl(filePath) {
|
|
|
27
27
|
function nowIso() {
|
|
28
28
|
return new Date(Date.now()).toISOString();
|
|
29
29
|
}
|
|
30
|
+
function runtimeSqliteErrorShouldIncludeSql(baseMessage) {
|
|
31
|
+
if (process.env.AGENT_HARNESS_RUNTIME_SQLITE_DEBUG === "1") {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
return /SQLITE_CONSTRAINT|FOREIGN KEY|UNIQUE constraint|NOT NULL/i.test(baseMessage);
|
|
35
|
+
}
|
|
36
|
+
function formatRuntimeSqliteErrorMessage(dbPath, sql, baseMessage) {
|
|
37
|
+
let detail = `agent-harness runtime SQLite (${dbPath}): ${baseMessage}`;
|
|
38
|
+
if (sql && runtimeSqliteErrorShouldIncludeSql(baseMessage)) {
|
|
39
|
+
const sqlPreview = sql.replace(/\s+/g, " ").trim();
|
|
40
|
+
const truncated = sqlPreview.length > 220 ? `${sqlPreview.slice(0, 220)}…` : sqlPreview;
|
|
41
|
+
detail += ` [sql=${truncated}]`;
|
|
42
|
+
}
|
|
43
|
+
return detail;
|
|
44
|
+
}
|
|
45
|
+
function throwWrappedRuntimeSqliteError(dbPath, sql, error) {
|
|
46
|
+
const base = error instanceof Error ? error.message : String(error);
|
|
47
|
+
const wrapped = new Error(formatRuntimeSqliteErrorMessage(dbPath, sql, base));
|
|
48
|
+
wrapped.cause = error;
|
|
49
|
+
throw wrapped;
|
|
50
|
+
}
|
|
30
51
|
function buildWhereClause(filters) {
|
|
31
52
|
const active = filters.filter(([, value]) => value !== undefined);
|
|
32
53
|
if (active.length === 0) {
|
|
@@ -42,12 +63,18 @@ async function selectProtectedThreadIds(dbPath) {
|
|
|
42
63
|
return [];
|
|
43
64
|
}
|
|
44
65
|
const client = createClient({ url: toSqliteUrl(dbPath) });
|
|
45
|
-
const
|
|
66
|
+
const sql = `SELECT DISTINCT thread_id
|
|
46
67
|
FROM runs
|
|
47
68
|
WHERE checkpoint_ref IS NOT NULL
|
|
48
69
|
AND checkpoint_ref != ''
|
|
49
|
-
AND (resumable = 1 OR state NOT IN ('completed', 'failed'))
|
|
50
|
-
|
|
70
|
+
AND (resumable = 1 OR state NOT IN ('completed', 'failed'))`;
|
|
71
|
+
try {
|
|
72
|
+
const result = await client.execute(sql);
|
|
73
|
+
return result.rows.map((row) => asString(asRow(row).thread_id)).filter((value) => value.length > 0);
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
throwWrappedRuntimeSqliteError(dbPath, sql, error);
|
|
77
|
+
}
|
|
51
78
|
}
|
|
52
79
|
export async function listProtectedCheckpointThreadIds(dbPath) {
|
|
53
80
|
return new Set(await selectProtectedThreadIds(dbPath));
|
|
@@ -83,16 +110,26 @@ export class SqlitePersistence {
|
|
|
83
110
|
}
|
|
84
111
|
async rawExecute(sql, args) {
|
|
85
112
|
const client = await this.getClient();
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
113
|
+
try {
|
|
114
|
+
if (args) {
|
|
115
|
+
await client.execute(sql, args);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
await client.execute(sql);
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
throwWrappedRuntimeSqliteError(this.dbPath, sql, error);
|
|
89
122
|
}
|
|
90
|
-
await client.execute(sql);
|
|
91
123
|
}
|
|
92
124
|
async rawSelectAll(sql, args) {
|
|
93
125
|
const client = await this.getClient();
|
|
94
|
-
|
|
95
|
-
|
|
126
|
+
try {
|
|
127
|
+
const result = args ? await client.execute(sql, args) : await client.execute(sql);
|
|
128
|
+
return result.rows.map((row) => asRow(row));
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
throwWrappedRuntimeSqliteError(this.dbPath, sql, error);
|
|
132
|
+
}
|
|
96
133
|
}
|
|
97
134
|
async ensureInitialized() {
|
|
98
135
|
if (this.initialized) {
|
|
@@ -286,18 +323,25 @@ export class SqlitePersistence {
|
|
|
286
323
|
async execute(sql, args) {
|
|
287
324
|
await this.ensureInitialized();
|
|
288
325
|
const client = await this.getClient();
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
326
|
+
try {
|
|
327
|
+
if (args) {
|
|
328
|
+
await client.execute(sql, args);
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
await client.execute(sql);
|
|
332
|
+
}
|
|
333
|
+
catch (error) {
|
|
334
|
+
throwWrappedRuntimeSqliteError(this.dbPath, sql, error);
|
|
292
335
|
}
|
|
293
|
-
await client.execute(sql);
|
|
294
336
|
}
|
|
295
337
|
async executeTransaction(steps) {
|
|
296
338
|
await this.ensureInitialized();
|
|
297
339
|
const client = await this.getClient();
|
|
298
|
-
|
|
340
|
+
let lastSql = "BEGIN IMMEDIATE";
|
|
299
341
|
try {
|
|
342
|
+
await client.execute("BEGIN IMMEDIATE");
|
|
300
343
|
for (const step of steps) {
|
|
344
|
+
lastSql = step.sql;
|
|
301
345
|
if (step.args) {
|
|
302
346
|
await client.execute(step.sql, step.args);
|
|
303
347
|
}
|
|
@@ -305,6 +349,7 @@ export class SqlitePersistence {
|
|
|
305
349
|
await client.execute(step.sql);
|
|
306
350
|
}
|
|
307
351
|
}
|
|
352
|
+
lastSql = "COMMIT";
|
|
308
353
|
await client.execute("COMMIT");
|
|
309
354
|
}
|
|
310
355
|
catch (error) {
|
|
@@ -314,21 +359,31 @@ export class SqlitePersistence {
|
|
|
314
359
|
catch {
|
|
315
360
|
// Ignore rollback failures and preserve the original error.
|
|
316
361
|
}
|
|
317
|
-
|
|
362
|
+
throwWrappedRuntimeSqliteError(this.dbPath, lastSql, error);
|
|
318
363
|
}
|
|
319
364
|
}
|
|
320
365
|
async selectOne(sql, args) {
|
|
321
366
|
await this.ensureInitialized();
|
|
322
367
|
const client = await this.getClient();
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
368
|
+
try {
|
|
369
|
+
const result = args ? await client.execute(sql, args) : await client.execute(sql);
|
|
370
|
+
const first = result.rows[0];
|
|
371
|
+
return first ? asRow(first) : null;
|
|
372
|
+
}
|
|
373
|
+
catch (error) {
|
|
374
|
+
throwWrappedRuntimeSqliteError(this.dbPath, sql, error);
|
|
375
|
+
}
|
|
326
376
|
}
|
|
327
377
|
async selectAll(sql, args) {
|
|
328
378
|
await this.ensureInitialized();
|
|
329
379
|
const client = await this.getClient();
|
|
330
|
-
|
|
331
|
-
|
|
380
|
+
try {
|
|
381
|
+
const result = args ? await client.execute(sql, args) : await client.execute(sql);
|
|
382
|
+
return result.rows.map((row) => asRow(row));
|
|
383
|
+
}
|
|
384
|
+
catch (error) {
|
|
385
|
+
throwWrappedRuntimeSqliteError(this.dbPath, sql, error);
|
|
386
|
+
}
|
|
332
387
|
}
|
|
333
388
|
mapThreadSummary(row) {
|
|
334
389
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@botbotgo/agent-harness",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.212",
|
|
4
4
|
"description": "Workspace runtime for multi-agent applications",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -70,6 +70,7 @@
|
|
|
70
70
|
"test:real-providers": "vitest run test/providers/real-provider-harness.test.ts",
|
|
71
71
|
"security:ci": "npm audit --omit=dev --audit-level=high",
|
|
72
72
|
"security:report": "npm audit --omit=dev --json > security-audit-report.json || true",
|
|
73
|
+
"docs:sync-dev-nav": "node ./scripts/sync-developer-docs-nav.mjs",
|
|
73
74
|
"release:prepare": "npm version patch --no-git-tag-version && node ./scripts/sync-example-version.mjs",
|
|
74
75
|
"release:pack": "npm pack --dry-run",
|
|
75
76
|
"release:publish": "npm publish --access public --registry https://registry.npmjs.org/"
|