@deepseek-ai/dsh-agent-loop-testkit 0.1.3-alpha.2 → 0.1.5-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.i18n.yaml +2 -2
- package/README.md +47 -22
- package/README.zh.md +47 -22
- package/lib/index.js +97 -4
- package/lib/types/inbox.d.ts +14 -0
- package/lib/types/index.d.ts +34 -3
- package/package.json +18 -14
package/README.i18n.yaml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
3
|
# after editing either side, bring the other along and re-record with:
|
|
4
4
|
# pnpm run verify-translation-pairing --write packages/test-support/agent-loop-testkit/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: abcd5966399998fbbeea5ac7573a9ee4085e05ca
|
|
6
|
+
README.zh.md: 76a6a43b07acd65aa135536d41a5c9c1ec122e16
|
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: "
|
|
2
|
+
description: "Prerequisite mounting, production AgentLoop drivers, and explicit Inbox stubs for agent-loop tests."
|
|
3
3
|
kind: "package-library"
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -9,7 +9,7 @@ English | [中文](README.zh.md)
|
|
|
9
9
|
|
|
10
10
|
## Summary
|
|
11
11
|
|
|
12
|
-
`dsh-agent-loop-testkit`
|
|
12
|
+
Use `dsh-agent-loop-testkit` to give AgentLoop tests the standard prerequisites and a production loop driver without repeating setup. The harness creates real Agents and exposes Inbox input claiming for tests of durable events, recovery, notifications, and claim behavior. For consumer tests that need only queue editing, choose the process-local Inbox stub; choose the fail-fast Inbox when pending input must never be touched. Tests still own adapters, optional plugins, load order, and context disposal, and the package adds no model-visible behavior.
|
|
13
13
|
|
|
14
14
|
## Table of Contents
|
|
15
15
|
|
|
@@ -25,31 +25,54 @@ English | [中文](README.zh.md)
|
|
|
25
25
|
<a id="use-this-package"></a>
|
|
26
26
|
## Use this package
|
|
27
27
|
|
|
28
|
-
This package gives an AgentLoop test a working service topology
|
|
28
|
+
This package gives an AgentLoop test a working service topology and keeps the choice between production Inbox behavior and a structural stub explicit.
|
|
29
29
|
|
|
30
|
-
###
|
|
30
|
+
### Drive a production Agent
|
|
31
|
+
|
|
32
|
+
Use `mountAgentLoopTestHarness()` when the test covers durable Inbox events, projection recovery or validation, live Inbox notifications, or loop-driver claims. Mount any load-order-sensitive consumers after the prerequisites and before creating the Agent. The context owns the loop and every Agent returned by the harness.
|
|
31
33
|
|
|
32
34
|
```ts
|
|
33
35
|
import { Context } from '@deepseek-ai/cordis'
|
|
34
|
-
import
|
|
35
|
-
import {
|
|
36
|
+
import { SessionId, type UserMessage } from '@deepseek-ai/dsh-session'
|
|
37
|
+
import {
|
|
38
|
+
mountAgentLoopTestDependencies,
|
|
39
|
+
mountAgentLoopTestHarness,
|
|
40
|
+
} from '@deepseek-ai/dsh-agent-loop-testkit'
|
|
36
41
|
|
|
37
42
|
const ctx = new Context()
|
|
38
43
|
|
|
39
44
|
await mountAgentLoopTestDependencies(ctx)
|
|
40
|
-
// Register the test adapter and any
|
|
41
|
-
|
|
45
|
+
// Register the test adapter and any load-order-sensitive plugins here.
|
|
46
|
+
const harness = await mountAgentLoopTestHarness(ctx)
|
|
47
|
+
const agent = await harness.create(SessionId('test-agent'))
|
|
48
|
+
declare const message: UserMessage
|
|
49
|
+
|
|
50
|
+
agent.inbox.append('next-turn', message)
|
|
51
|
+
const admitted = harness.claim(agent, 'next-turn', 1)
|
|
42
52
|
```
|
|
43
53
|
|
|
44
|
-
The helper
|
|
54
|
+
The dependency helper forwards system-prompt and tool-registry configuration through `options` and provides no test defaults beyond those services' own defaults. A plugin-load failure rejects the helper call; services activated earlier in the sequence remain context-owned and unwind when the context is disposed.
|
|
55
|
+
|
|
56
|
+
### Build a structural Agent stub
|
|
57
|
+
|
|
58
|
+
Use `createInboxStub()` when the test subject needs mutable pending lists but does not exercise durability, projection validation, live Inbox notifications, or the driver's claim policy. The stub implements the public queue operations with two process-local arrays and never writes to a Session. Use `unsupportedInbox()` when the test subject must not touch pending input; every mutation throws at the first unexpected dependency.
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
import { createInboxStub } from '@deepseek-ai/dsh-agent-loop-testkit'
|
|
62
|
+
|
|
63
|
+
const agent = {
|
|
64
|
+
// ...
|
|
65
|
+
inbox: createInboxStub(),
|
|
66
|
+
}
|
|
67
|
+
```
|
|
45
68
|
|
|
46
69
|
### When to use it
|
|
47
70
|
|
|
48
|
-
Use the
|
|
71
|
+
Use the dependency and loop helpers for tests whose subject is production loop or durable Inbox behavior. Use the structural stub for consumer-domain tests that only need queue editing. Mount dependencies directly when a test probes service injection failures or partial topologies, because the helper hides exactly the wiring those tests must control.
|
|
49
72
|
|
|
50
73
|
### What can go wrong
|
|
51
74
|
|
|
52
|
-
|
|
75
|
+
The harness mounts no LLM adapter. Register an adapter before sending work that would start a model request. Dispose the owning context after every test so Agents reach quiescence and their scoped registrations unwind.
|
|
53
76
|
|
|
54
77
|
-----
|
|
55
78
|
|
|
@@ -59,11 +82,11 @@ A plugin-load failure rejects the helper call; services activated earlier in the
|
|
|
59
82
|
<details>
|
|
60
83
|
<summary>Implementation internals — click to expand</summary>
|
|
61
84
|
|
|
62
|
-
This section explains the design of the
|
|
85
|
+
This section explains the design of the test utilities; the observable behavior is fully covered in [Use this package](#use-this-package).
|
|
63
86
|
|
|
64
87
|
### Design
|
|
65
88
|
|
|
66
|
-
|
|
89
|
+
`mountAgentLoopTestDependencies` mounts six service plugins in a fixed dependency order — LLM, session, session-projection registry, system-prompt registry, tool registry, then agent registry — and stops before `AgentLoop`, so the caller controls loop load order. `mountAgentLoopTestHarness` mounts the public production plugin, creates Agents through its service, and exposes the production driver's claim operation without exporting the loop's concrete Inbox class or projection definition. [`src/inbox.ts`](src/inbox.ts) contains only the process-local mutable stub and the fail-fast unsupported placeholder; it owns no projection or durable event implementation. The mounting and driver implementation lives in [`src/index.ts`](src/index.ts). No invariant companion is published because the package owns only test helpers and has no independent production observations that can diverge.
|
|
67
90
|
|
|
68
91
|
</details>
|
|
69
92
|
|
|
@@ -72,11 +95,11 @@ This section explains the design of the helper; the observable behavior is fully
|
|
|
72
95
|
<a id="further-exploration"></a>
|
|
73
96
|
## Further Exploration
|
|
74
97
|
|
|
75
|
-
Read these pages when the package-level
|
|
98
|
+
Read these pages when the package-level behavior is not enough. They move from the loop to the services the helper mounts and the tests that use it.
|
|
76
99
|
|
|
77
|
-
- [Agent loop package](../../core/agent-loop/README.md) — the concrete loop this helper
|
|
78
|
-
- [Session package](../../core/session/README.md) — the
|
|
79
|
-
- [LLM package](../../llm/llm/README.md) — the LLM runtime and adapter
|
|
100
|
+
- [Agent loop package](../../core/agent-loop/README.md) — the concrete loop this helper mounts for production behavior.
|
|
101
|
+
- [Session package](../../core/session/README.md) — the durable event log used by production Inbox behavior.
|
|
102
|
+
- [LLM package](../../llm/llm/README.md) — the LLM runtime and adapter interface the helper prepares.
|
|
80
103
|
- [Testing policy](../../../docs/testing.md) — the coverage tiers these tests serve.
|
|
81
104
|
- [Test-support group map](../README.md) — sibling harnesses and support packages.
|
|
82
105
|
|
|
@@ -85,20 +108,22 @@ Read these pages when the package-level contract is not enough. They move from t
|
|
|
85
108
|
<a id="model-experience"></a>
|
|
86
109
|
## Model Experience
|
|
87
110
|
|
|
88
|
-
None, as
|
|
111
|
+
None, as these test-only utilities neither assemble nor modify model requests.
|
|
89
112
|
|
|
90
113
|
#### KV Cache effect
|
|
91
114
|
|
|
92
|
-
None;
|
|
115
|
+
None; the package itself sends no provider request.
|
|
93
116
|
|
|
94
117
|
## Known Limitations and Deferred Work
|
|
95
118
|
|
|
96
119
|
<a id="known-limitations-and-deferred-work"></a>
|
|
97
120
|
|
|
121
|
+
These limits define what the utilities do not share. They are current package constraints, not a task backlog.
|
|
98
122
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
- **
|
|
123
|
+
- **Only the mandatory prerequisite spine is shared** — adapters, optional plugins, scenario-specific load order, and context teardown remain caller-owned.
|
|
124
|
+
- **The production harness has no adapter default** — tests that start the loop must register the route they exercise.
|
|
125
|
+
- **The mutable Inbox stub is process-local only** — use a harness-created Agent whenever durable events, projection recovery or validation, live notifications, or claim policy matter.
|
|
126
|
+
- **The unsupported Inbox accepts no mutations** — use the mutable stub or a harness-created Agent whenever pending input is part of the test subject.
|
|
102
127
|
|
|
103
128
|
<a id="dev-note"></a>
|
|
104
129
|
### Dev Note
|
package/README.zh.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: "
|
|
2
|
+
description: "为 agent-loop 测试提供先决依赖挂载、生产 AgentLoop 驱动与职责明确的 Inbox 桩。"
|
|
3
3
|
kind: "package-library"
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -9,7 +9,7 @@ kind: "package-library"
|
|
|
9
9
|
|
|
10
10
|
## 概述
|
|
11
11
|
|
|
12
|
-
`dsh-agent-loop-testkit`
|
|
12
|
+
使用 `dsh-agent-loop-testkit` 可以为 AgentLoop 测试准备标准先决条件和生产 loop 驱动,避免重复设置。Harness 可以创建真实 Agent,并公开 Inbox 输入认领能力,以测试持久事件、恢复、通知和认领行为。只需编辑队列的消费方测试应选择进程内 Inbox 桩;待处理输入绝不应被访问时,应选择快速失败的 Inbox。测试仍然负责适配器、可选插件、加载顺序和上下文释放,本包不会添加模型可见行为。
|
|
13
13
|
|
|
14
14
|
## 目录
|
|
15
15
|
|
|
@@ -25,31 +25,54 @@ kind: "package-library"
|
|
|
25
25
|
<a id="use-this-package"></a>
|
|
26
26
|
## 使用本包
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
本包为 AgentLoop 测试提供可用的服务拓扑,并要求测试明确选择生产 Inbox 行为或结构化桩。
|
|
29
29
|
|
|
30
|
-
###
|
|
30
|
+
### 驱动生产 Agent
|
|
31
|
+
|
|
32
|
+
当测试覆盖持久 Inbox 事件、投影恢复或校验、实时 Inbox 通知,或 loop 驱动的认领策略时,使用 `mountAgentLoopTestHarness()`。应在挂载先决依赖后、创建 Agent 前挂载所有对加载顺序敏感的消费方。上下文拥有 loop 以及该 harness 返回的每个 Agent。
|
|
31
33
|
|
|
32
34
|
```ts
|
|
33
35
|
import { Context } from '@deepseek-ai/cordis'
|
|
34
|
-
import
|
|
35
|
-
import {
|
|
36
|
+
import { SessionId, type UserMessage } from '@deepseek-ai/dsh-session'
|
|
37
|
+
import {
|
|
38
|
+
mountAgentLoopTestDependencies,
|
|
39
|
+
mountAgentLoopTestHarness,
|
|
40
|
+
} from '@deepseek-ai/dsh-agent-loop-testkit'
|
|
36
41
|
|
|
37
42
|
const ctx = new Context()
|
|
38
43
|
|
|
39
44
|
await mountAgentLoopTestDependencies(ctx)
|
|
40
|
-
// Register the test adapter and any
|
|
41
|
-
|
|
45
|
+
// Register the test adapter and any load-order-sensitive plugins here.
|
|
46
|
+
const harness = await mountAgentLoopTestHarness(ctx)
|
|
47
|
+
const agent = await harness.create(SessionId('test-agent'))
|
|
48
|
+
declare const message: UserMessage
|
|
49
|
+
|
|
50
|
+
agent.inbox.append('next-turn', message)
|
|
51
|
+
const admitted = harness.claim(agent, 'next-turn', 1)
|
|
42
52
|
```
|
|
43
53
|
|
|
44
|
-
|
|
54
|
+
依赖辅助函数通过 `options` 转发系统提示词与工具注册表配置,除这些服务自有的默认值外不提供测试默认值。插件加载失败会使辅助函数调用被拒绝;顺序中较早激活的服务仍归上下文所有,并在上下文释放时一并解除。
|
|
55
|
+
|
|
56
|
+
### 构造结构化 Agent 桩
|
|
57
|
+
|
|
58
|
+
当测试对象需要可变的待处理列表,但不测试持久性、投影校验、实时 Inbox 通知或驱动的认领策略时,使用 `createInboxStub()`。该桩通过两个进程内数组实现公开队列操作,且绝不会写入 Session。当测试对象不应访问待处理输入时,使用 `unsupportedInbox()`;每次变更都会在首个意外依赖处抛错。
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
import { createInboxStub } from '@deepseek-ai/dsh-agent-loop-testkit'
|
|
62
|
+
|
|
63
|
+
const agent = {
|
|
64
|
+
// ...
|
|
65
|
+
inbox: createInboxStub(),
|
|
66
|
+
}
|
|
67
|
+
```
|
|
45
68
|
|
|
46
69
|
### 何时使用
|
|
47
70
|
|
|
48
|
-
|
|
71
|
+
当测试对象是生产 loop 或持久 Inbox 行为时,使用依赖与 loop 辅助函数。只需要编辑队列的消费方领域测试使用结构化桩。当测试探测服务注入失败或部分拓扑时,请直接挂载依赖,因为辅助函数隐藏的正是这类测试必须控制的接线。
|
|
49
72
|
|
|
50
73
|
### 可能出什么问题
|
|
51
74
|
|
|
52
|
-
|
|
75
|
+
harness 不会挂载任何 LLM 适配器。若测试发送的任务会启动模型请求,请先注册被测路由的适配器。每个测试结束后都应释放所属上下文,使 Agent 达到静止状态并解除其作用域注册。
|
|
53
76
|
|
|
54
77
|
-----
|
|
55
78
|
|
|
@@ -59,11 +82,11 @@ await ctx.plugin(AgentLoop, { agents: [] })
|
|
|
59
82
|
<details>
|
|
60
83
|
<summary>实现细节——点击展开</summary>
|
|
61
84
|
|
|
62
|
-
|
|
85
|
+
本节解释测试辅助工具的设计;可观察行为已在[使用本包](#use-this-package)中完整说明。
|
|
63
86
|
|
|
64
87
|
### 设计
|
|
65
88
|
|
|
66
|
-
|
|
89
|
+
`mountAgentLoopTestDependencies` 按固定依赖顺序——LLM、会话、会话投影注册表、系统提示词注册表、工具注册表、agent 注册表——挂载六个服务插件,并在 `AgentLoop` 之前停下,使调用方控制 loop 加载顺序。`mountAgentLoopTestHarness` 挂载公开的生产插件,通过其服务创建 Agent,并公开生产驱动的认领操作,而不导出 loop 的具体 Inbox 类或投影定义。[`src/inbox.ts`](src/inbox.ts) 仅包含进程内可变桩和快速失败且不支持操作的占位值;它不持有投影或持久事件实现。挂载与驱动实现位于 [`src/index.ts`](src/index.ts)。本包不发布 invariant companion,因为它只持有测试辅助工具,不存在可能相互偏离的独立生产观测。
|
|
67
90
|
|
|
68
91
|
</details>
|
|
69
92
|
|
|
@@ -72,11 +95,11 @@ await ctx.plugin(AgentLoop, { agents: [] })
|
|
|
72
95
|
<a id="further-exploration"></a>
|
|
73
96
|
## 进一步探索
|
|
74
97
|
|
|
75
|
-
|
|
98
|
+
当包级行为不够用时阅读以下页面。它们从 loop 逐步进入辅助函数挂载的服务以及使用它的测试。
|
|
76
99
|
|
|
77
|
-
- [Agent loop 包](../../core/agent-loop/README.zh.md)
|
|
78
|
-
- [会话包](../../core/session/README.zh.md)
|
|
79
|
-
- [LLM 包](../../llm/llm/README.zh.md)
|
|
100
|
+
- [Agent loop 包](../../core/agent-loop/README.zh.md)——本辅助函数为生产行为挂载的具体 loop。
|
|
101
|
+
- [会话包](../../core/session/README.zh.md)——生产 Inbox 行为使用的持久事件日志。
|
|
102
|
+
- [LLM 包](../../llm/llm/README.zh.md)——本辅助函数准备的 LLM 运行时与适配器接口。
|
|
80
103
|
- [测试策略](../../../docs/testing.zh.md)——这些测试所服务的覆盖层级。
|
|
81
104
|
- [test-support 组地图](../README.zh.md)——兄弟 harness 与支持包。
|
|
82
105
|
|
|
@@ -85,20 +108,22 @@ await ctx.plugin(AgentLoop, { agents: [] })
|
|
|
85
108
|
<a id="model-experience"></a>
|
|
86
109
|
## 模型体验
|
|
87
110
|
|
|
88
|
-
|
|
111
|
+
无。这些测试专用辅助工具既不组装也不修改模型请求。
|
|
89
112
|
|
|
90
113
|
#### KV Cache 影响
|
|
91
114
|
|
|
92
|
-
|
|
115
|
+
无;本包自身不发送提供方请求。
|
|
93
116
|
|
|
94
117
|
## 已知限制与延期工作
|
|
95
118
|
|
|
96
119
|
<a id="known-limitations-and-deferred-work"></a>
|
|
97
120
|
|
|
121
|
+
这些限制说明辅助工具不共享什么。它们是当前包约束,不是任务积压。
|
|
98
122
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
-
|
|
123
|
+
- **只共享必需的先决主干**——适配器、可选插件、场景特定的加载顺序与上下文清理仍由调用方负责。
|
|
124
|
+
- **生产 harness 没有适配器默认值**——启动 loop 的测试必须注册其实际使用的路由。
|
|
125
|
+
- **可变 Inbox 桩仅存在于进程内**——只要持久事件、投影恢复或校验、实时通知或认领策略属于测试对象,就应使用 harness 创建的 Agent。
|
|
126
|
+
- **不支持操作的 Inbox 不接受变更**——只要待处理输入属于测试对象,就应使用可变桩或 harness 创建的 Agent。
|
|
102
127
|
|
|
103
128
|
<a id="dev-note"></a>
|
|
104
129
|
### 开发备注
|
package/lib/index.js
CHANGED
|
@@ -1,13 +1,90 @@
|
|
|
1
1
|
import AgentRegistry from "@deepseek-ai/dsh-agent";
|
|
2
|
+
import AgentLoop from "@deepseek-ai/dsh-agent-loop";
|
|
2
3
|
import LlmRuntime from "@deepseek-ai/dsh-llm";
|
|
3
4
|
import SessionStore from "@deepseek-ai/dsh-session";
|
|
5
|
+
import SessionProjectionRegistry from "@deepseek-ai/dsh-session-projection";
|
|
4
6
|
import SystemPrompt from "@deepseek-ai/dsh-system-prompt";
|
|
5
7
|
import ToolRuntime from "@deepseek-ai/dsh-tools";
|
|
8
|
+
//#region lib/types/inbox.js
|
|
9
|
+
/**
|
|
10
|
+
* Create a mutable in-memory Inbox stub for tests that exercise only the public
|
|
11
|
+
* queue operations. Durable events, projection validation, and live Inbox
|
|
12
|
+
* notifications require a real Agent created by the AgentLoop test harness.
|
|
13
|
+
* @returns an Inbox backed by two process-local arrays.
|
|
14
|
+
*/
|
|
15
|
+
function createInboxStub() {
|
|
16
|
+
const pending = {
|
|
17
|
+
"next-turn": [],
|
|
18
|
+
"next-step": []
|
|
19
|
+
};
|
|
20
|
+
const locate = (messageId) => {
|
|
21
|
+
for (const target of ["next-turn", "next-step"]) {
|
|
22
|
+
const index = pending[target].findIndex((message) => message.id === messageId);
|
|
23
|
+
if (index >= 0) return {
|
|
24
|
+
target,
|
|
25
|
+
index
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
return {
|
|
30
|
+
get nextTurn() {
|
|
31
|
+
return pending["next-turn"];
|
|
32
|
+
},
|
|
33
|
+
get nextStep() {
|
|
34
|
+
return pending["next-step"];
|
|
35
|
+
},
|
|
36
|
+
clear() {
|
|
37
|
+
pending["next-step"].splice(0);
|
|
38
|
+
pending["next-turn"].splice(0);
|
|
39
|
+
},
|
|
40
|
+
append(target, message) {
|
|
41
|
+
pending[target].push(message);
|
|
42
|
+
},
|
|
43
|
+
prepend(target, message) {
|
|
44
|
+
pending[target].unshift(message);
|
|
45
|
+
},
|
|
46
|
+
replace(messageId, message) {
|
|
47
|
+
const location = locate(messageId);
|
|
48
|
+
if (location === void 0) return false;
|
|
49
|
+
pending[location.target].splice(location.index, 1, message);
|
|
50
|
+
return true;
|
|
51
|
+
},
|
|
52
|
+
remove(messageId) {
|
|
53
|
+
const location = locate(messageId);
|
|
54
|
+
if (location === void 0) return false;
|
|
55
|
+
pending[location.target].splice(location.index, 1);
|
|
56
|
+
return true;
|
|
57
|
+
},
|
|
58
|
+
splice(target, start, deleteCount, inserted) {
|
|
59
|
+
return pending[target].splice(start, deleteCount, ...inserted);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Create an unsupported Inbox placeholder for Agent stubs whose tests do not exercise Inbox behavior.
|
|
65
|
+
* @returns an Inbox whose pending lists are empty and whose mutation methods throw.
|
|
66
|
+
*/
|
|
67
|
+
function unsupportedInbox() {
|
|
68
|
+
const rejectMutation = () => {
|
|
69
|
+
throw new Error("this test Agent does not support Inbox mutations");
|
|
70
|
+
};
|
|
71
|
+
return {
|
|
72
|
+
nextTurn: [],
|
|
73
|
+
nextStep: [],
|
|
74
|
+
clear: rejectMutation,
|
|
75
|
+
append: rejectMutation,
|
|
76
|
+
prepend: rejectMutation,
|
|
77
|
+
replace: rejectMutation,
|
|
78
|
+
remove: rejectMutation,
|
|
79
|
+
splice: rejectMutation
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
//#endregion
|
|
6
83
|
//#region lib/types/index.js
|
|
7
84
|
/**
|
|
8
|
-
* Shared mounting
|
|
9
|
-
* agent
|
|
10
|
-
* optional plugins, and teardown.
|
|
85
|
+
* Shared service mounting, real AgentLoop drivers, and structural Inbox stubs
|
|
86
|
+
* for agent-loop tests. Callers retain ownership of their contexts, adapters,
|
|
87
|
+
* optional plugins, agents, and teardown.
|
|
11
88
|
* @module @deepseek-ai/dsh-agent-loop-testkit
|
|
12
89
|
*/
|
|
13
90
|
/**
|
|
@@ -25,9 +102,25 @@ import ToolRuntime from "@deepseek-ai/dsh-tools";
|
|
|
25
102
|
async function mountAgentLoopTestDependencies(ctx, options = {}) {
|
|
26
103
|
await ctx.plugin(LlmRuntime);
|
|
27
104
|
await ctx.plugin(SessionStore);
|
|
105
|
+
await ctx.plugin(SessionProjectionRegistry);
|
|
28
106
|
await ctx.plugin(SystemPrompt, options.systemPrompt ?? {});
|
|
29
107
|
await ctx.plugin(ToolRuntime, options.tools ?? {});
|
|
30
108
|
await ctx.plugin(AgentRegistry);
|
|
31
109
|
}
|
|
110
|
+
/**
|
|
111
|
+
* Mount the production AgentLoop and expose its narrow test-driver operations.
|
|
112
|
+
* Mount {@link mountAgentLoopTestDependencies} and any load-order-sensitive
|
|
113
|
+
* consumers before calling this helper. The context owns the loop and every
|
|
114
|
+
* Agent returned by the harness.
|
|
115
|
+
* @param ctx - test context with the AgentLoop prerequisite services active.
|
|
116
|
+
* @returns a driver that creates production Agents and claims their real Inbox.
|
|
117
|
+
*/
|
|
118
|
+
async function mountAgentLoopTestHarness(ctx) {
|
|
119
|
+
await ctx.plugin(AgentLoop, { agents: [] });
|
|
120
|
+
return {
|
|
121
|
+
create: async (id, options = {}, meta = {}) => ctx.agentLoop.create(id, options, meta),
|
|
122
|
+
claim: (agent, target, turn) => agent.inbox.claim(target, turn)
|
|
123
|
+
};
|
|
124
|
+
}
|
|
32
125
|
//#endregion
|
|
33
|
-
export { mountAgentLoopTestDependencies };
|
|
126
|
+
export { createInboxStub, mountAgentLoopTestDependencies, mountAgentLoopTestHarness, unsupportedInbox };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Inbox } from '@deepseek-ai/dsh-agent';
|
|
2
|
+
/**
|
|
3
|
+
* Create a mutable in-memory Inbox stub for tests that exercise only the public
|
|
4
|
+
* queue operations. Durable events, projection validation, and live Inbox
|
|
5
|
+
* notifications require a real Agent created by the AgentLoop test harness.
|
|
6
|
+
* @returns an Inbox backed by two process-local arrays.
|
|
7
|
+
*/
|
|
8
|
+
export declare function createInboxStub(): Inbox;
|
|
9
|
+
/**
|
|
10
|
+
* Create an unsupported Inbox placeholder for Agent stubs whose tests do not exercise Inbox behavior.
|
|
11
|
+
* @returns an Inbox whose pending lists are empty and whose mutation methods throw.
|
|
12
|
+
*/
|
|
13
|
+
export declare function unsupportedInbox(): Inbox;
|
|
14
|
+
//# sourceMappingURL=inbox.d.ts.map
|
package/lib/types/index.d.ts
CHANGED
|
@@ -1,12 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Shared mounting
|
|
3
|
-
* agent
|
|
4
|
-
* optional plugins, and teardown.
|
|
2
|
+
* Shared service mounting, real AgentLoop drivers, and structural Inbox stubs
|
|
3
|
+
* for agent-loop tests. Callers retain ownership of their contexts, adapters,
|
|
4
|
+
* optional plugins, agents, and teardown.
|
|
5
5
|
* @module @deepseek-ai/dsh-agent-loop-testkit
|
|
6
6
|
*/
|
|
7
7
|
import type { Context } from '@deepseek-ai/cordis';
|
|
8
|
+
import type { Agent, AgentOptions, InboxTarget } from '@deepseek-ai/dsh-agent';
|
|
9
|
+
import type { SessionHeader, SessionId, UserMessage } from '@deepseek-ai/dsh-session';
|
|
8
10
|
import type { Config as SystemPromptConfig } from '@deepseek-ai/dsh-system-prompt';
|
|
9
11
|
import type { Config as ToolRuntimeConfig } from '@deepseek-ai/dsh-tools';
|
|
12
|
+
export { createInboxStub, unsupportedInbox } from './inbox.ts';
|
|
13
|
+
/** Test driver for production Agents created by a mounted AgentLoop. */
|
|
14
|
+
export interface AgentLoopTestHarness {
|
|
15
|
+
/**
|
|
16
|
+
* Create a production Agent and fresh Session owned by the harness context.
|
|
17
|
+
* @param id - shared Agent and Session identity.
|
|
18
|
+
* @param options - concrete loop options.
|
|
19
|
+
* @param meta - optional fresh-session workspace metadata.
|
|
20
|
+
* @returns the published production Agent after creation completes.
|
|
21
|
+
*/
|
|
22
|
+
create(id: SessionId, options?: AgentOptions, meta?: Pick<SessionHeader, 'cwd'>): Promise<Agent>;
|
|
23
|
+
/**
|
|
24
|
+
* Admit pending messages through the production loop driver's claim operation.
|
|
25
|
+
* @param agent - Agent returned by this harness's `create` method.
|
|
26
|
+
* @param target - boundary whose pending input is admitted.
|
|
27
|
+
* @param turn - turn that owns the admitted messages.
|
|
28
|
+
* @returns next-step messages followed by one next-turn message when requested.
|
|
29
|
+
*/
|
|
30
|
+
claim(agent: Agent, target: InboxTarget, turn: number): UserMessage[];
|
|
31
|
+
}
|
|
10
32
|
/** Configuration forwarded to the prerequisite service plugins. */
|
|
11
33
|
export interface AgentLoopTestDependenciesOptions {
|
|
12
34
|
/** Configuration for the system-prompt registry. */
|
|
@@ -27,4 +49,13 @@ export interface AgentLoopTestDependenciesOptions {
|
|
|
27
49
|
* @returns after every prerequisite service has activated.
|
|
28
50
|
*/
|
|
29
51
|
export declare function mountAgentLoopTestDependencies(ctx: Context, options?: AgentLoopTestDependenciesOptions): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Mount the production AgentLoop and expose its narrow test-driver operations.
|
|
54
|
+
* Mount {@link mountAgentLoopTestDependencies} and any load-order-sensitive
|
|
55
|
+
* consumers before calling this helper. The context owns the loop and every
|
|
56
|
+
* Agent returned by the harness.
|
|
57
|
+
* @param ctx - test context with the AgentLoop prerequisite services active.
|
|
58
|
+
* @returns a driver that creates production Agents and claims their real Inbox.
|
|
59
|
+
*/
|
|
60
|
+
export declare function mountAgentLoopTestHarness(ctx: Context): Promise<AgentLoopTestHarness>;
|
|
30
61
|
//# sourceMappingURL=index.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-agent-loop-testkit",
|
|
3
|
-
"description": "
|
|
4
|
-
"version": "0.1.
|
|
3
|
+
"description": "Prerequisite mounting, production AgentLoop drivers, and Inbox stubs for tests",
|
|
4
|
+
"version": "0.1.5-alpha.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -27,20 +27,24 @@
|
|
|
27
27
|
],
|
|
28
28
|
"license": "MIT",
|
|
29
29
|
"peerDependencies": {
|
|
30
|
-
"@deepseek-ai/dsh-agent": "^0.1.
|
|
31
|
-
"@deepseek-ai/dsh-
|
|
32
|
-
"@deepseek-ai/dsh-session": "^0.1.
|
|
33
|
-
"@deepseek-ai/dsh-
|
|
34
|
-
"@deepseek-ai/dsh-
|
|
30
|
+
"@deepseek-ai/dsh-agent": "^0.1.5-alpha.2",
|
|
31
|
+
"@deepseek-ai/dsh-agent-loop": "^0.1.5-alpha.2",
|
|
32
|
+
"@deepseek-ai/dsh-session": "^0.1.5-alpha.2",
|
|
33
|
+
"@deepseek-ai/dsh-llm": "^0.1.5-alpha.2",
|
|
34
|
+
"@deepseek-ai/dsh-session-projection": "^0.1.5-alpha.2",
|
|
35
|
+
"@deepseek-ai/dsh-system-prompt": "^0.1.5-alpha.2",
|
|
36
|
+
"@deepseek-ai/dsh-tools": "^0.1.5-alpha.2",
|
|
35
37
|
"@deepseek-ai/cordis": "^4.0.2"
|
|
36
38
|
},
|
|
39
|
+
"dependencies": {},
|
|
37
40
|
"devDependencies": {
|
|
38
|
-
"@deepseek-ai/dsh-agent": "^0.1.
|
|
39
|
-
"@deepseek-ai/dsh-
|
|
40
|
-
"@deepseek-ai/dsh-
|
|
41
|
-
"@deepseek-ai/dsh-
|
|
42
|
-
"@deepseek-ai/dsh-
|
|
43
|
-
"@deepseek-ai/dsh-tools": "^0.1.
|
|
44
|
-
"@deepseek-ai/cordis": "^4.0.2"
|
|
41
|
+
"@deepseek-ai/dsh-agent": "^0.1.5-alpha.2",
|
|
42
|
+
"@deepseek-ai/dsh-agent-loop": "^0.1.5-alpha.2",
|
|
43
|
+
"@deepseek-ai/dsh-llm": "^0.1.5-alpha.2",
|
|
44
|
+
"@deepseek-ai/dsh-session": "^0.1.5-alpha.2",
|
|
45
|
+
"@deepseek-ai/dsh-session-projection": "^0.1.5-alpha.2",
|
|
46
|
+
"@deepseek-ai/dsh-tools": "^0.1.5-alpha.2",
|
|
47
|
+
"@deepseek-ai/cordis": "^4.0.2",
|
|
48
|
+
"@deepseek-ai/dsh-system-prompt": "^0.1.5-alpha.2"
|
|
45
49
|
}
|
|
46
50
|
}
|