@qjp88995/agent-runtime-redis 0.0.0-stage → 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.
@@ -0,0 +1,80 @@
1
+ import type { Redis } from 'ioredis';
2
+ import { type AgentEvent, InProcessStreamBus, type InProcessStreamBusOptions, type SessionStreamEntry } from '@qjp88995/agent-runtime';
3
+ import { type RedisKeyOptions } from './keys.js';
4
+ export interface RedisStreamBusOptions extends RedisKeyOptions, InProcessStreamBusOptions {
5
+ /** 写侧合并窗口;`null` 关掉合并(一条事件一条条目)。缺省 50ms。 */
6
+ batchMs?: number | null;
7
+ /** 落库后的退役宽限期。缺省 30s。 */
8
+ retireGraceMs?: number;
9
+ /** 会话流的 MAXLEN 兜底。缺省 10000。 */
10
+ maxLen?: number;
11
+ /** 会话流的 TTL(每写一条刷新)。缺省 1 小时;轮次登记表在进程里也活这么久。 */
12
+ streamTtlSeconds?: number;
13
+ /** 一次 XREAD 阻塞多久后回来检查 abort。缺省 5s。 */
14
+ xreadBlockMs?: number;
15
+ }
16
+ /**
17
+ * 多实例事件总线:**per-stream 面留在进程内**(继承 `InProcessStreamBus`:seq、buffer、取消信号——
18
+ * 消费它们的 pump 与 `streamText` 都在跑这一轮的那个进程里),**会话面换成 Redis Streams**
19
+ * (键 `agent-session:<root>`),跨实例、断线可按游标续订。搬自 agent-base `RedisStreamBus`。
20
+ *
21
+ * ## 会话面只保留尚未落库的尾巴
22
+ *
23
+ * - **落库即退役**:宿主落库成功后调 `retireUpTo(runId, seq)`,宽限期后 XDEL 这一轮 seq ≤ 边界的条目;
24
+ * `run-finish` / `error` 宽限期后整轮清掉。条目 id 从 XADD 回值登记在进程内存里(写这轮事件的
25
+ * 就是跑这轮的进程);别的实例补发的 `run-finish` 在本进程查不到表,删除是 no-op,孤儿条目由
26
+ * TTL / MAXLEN 兜底。
27
+ * - **写侧合并**:连续的同段 delta 攒一个窗口再写;任何不可合并的事件先把攒着的吐掉,顺序不变。
28
+ *
29
+ * 会话面的写是 fire-and-forget:观测不承重,序列化失败或 Redis 出错只丢这一条,绝不让一轮对话失败。
30
+ *
31
+ * ## 与 agent-base 的差别
32
+ *
33
+ * - `publish` 只在流活着时写会话面(agent-base 不看流状态;这里与进程内实现、端口约定对齐:
34
+ * 「流未 open / 已 close 时丢弃」)。
35
+ * - 测试用的 `configureForTest` 改成构造参数 `batchMs` / `retireGraceMs`;加 `dispose()`。
36
+ * - 键可加前缀(`keyPrefix`)。
37
+ *
38
+ * **停止按钮仍是进程内的**:`abort(streamId)` 只对本进程跑着的流生效,与 agent-base 一样——
39
+ * 停止请求落到别的实例上时,宿主要自己把它路由到跑这轮的实例(或者走会话锁所在实例)。
40
+ */
41
+ export declare class RedisStreamBus extends InProcessStreamBus {
42
+ private readonly redis;
43
+ private readonly keys;
44
+ private readonly batchMs;
45
+ private readonly graceMs;
46
+ private readonly maxLen;
47
+ private readonly streamTtlSeconds;
48
+ private readonly xreadBlockMs;
49
+ private readonly pendingByRoot;
50
+ private readonly entriesByRun;
51
+ private readonly timers;
52
+ private readonly runTableTimer;
53
+ constructor(redis: Redis, options?: RedisStreamBusOptions);
54
+ publish(event: AgentEvent): void;
55
+ publishSessionEvent(event: AgentEvent): void;
56
+ retireUpTo(runId: string, uptoSeq: number): void;
57
+ /** 宽限期后执行;`dispose()` 会清掉还没到点的。 */
58
+ private later;
59
+ /**
60
+ * 会话面入口。序列化在进入 fire-and-forget 链之前同步做完(见 `xaddSession`),非 JSON-safe
61
+ * 载荷不会经 `publish` 冒进 `runTurn`。
62
+ */
63
+ private enqueueSession;
64
+ private flushPending;
65
+ /** 写一条并登记;返回的 promise 在登记完(或失败被吞)后落定,从不 reject。 */
66
+ private xaddSession;
67
+ private deleteEntries;
68
+ /** 轮次登记表兜底清理:正常路径由 run-finish / error 清;崩溃或别的实例收尾的轮次靠这里。 */
69
+ private sweepRunTables;
70
+ /**
71
+ * 每个订阅一条独立连接(XREAD BLOCK 会占住连接);`signal` abort 时断开它,在途的 XREAD 随之结束。
72
+ */
73
+ subscribeSession(rootSessionId: string, fromId: string | undefined, signal: AbortSignal): AsyncIterable<SessionStreamEntry>;
74
+ /**
75
+ * 停掉定时器:攒着的 delta 立刻写出去(不丢),还没到点的退役放弃(条目由 TTL / MAXLEN 兜底)。
76
+ * 不关宿主给的连接。
77
+ */
78
+ dispose(): void;
79
+ }
80
+ //# sourceMappingURL=stream-bus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-bus.d.ts","sourceRoot":"","sources":["../src/stream-bus.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAErC,OAAO,EACL,KAAK,UAAU,EACf,kBAAkB,EAClB,KAAK,yBAAyB,EAC9B,KAAK,kBAAkB,EACxB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,KAAK,eAAe,EAA6B,MAAM,WAAW,CAAC;AA+E5E,MAAM,WAAW,qBACf,SAAQ,eAAe,EAAE,yBAAyB;IAClD,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,wBAAwB;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,+BAA+B;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,sCAAsC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,cAAe,SAAQ,kBAAkB;IAalD,OAAO,CAAC,QAAQ,CAAC,KAAK;IAZxB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAY;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAmC;IACjE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAiC;IAC9D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6B;IACpD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAiB;gBAG5B,KAAK,EAAE,KAAK,EAC7B,OAAO,GAAE,qBAA0B;IAiB5B,OAAO,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAKhC,mBAAmB,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAI5C,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAIzD,mCAAmC;IACnC,OAAO,CAAC,KAAK;IASb;;;OAGG;IACH,OAAO,CAAC,cAAc;IAiCtB,OAAO,CAAC,YAAY;IAQpB,mDAAmD;IACnD,OAAO,CAAC,WAAW;IA4BnB,OAAO,CAAC,aAAa;IAiBrB,4DAA4D;IAC5D,OAAO,CAAC,cAAc;IAQtB;;OAEG;IACa,gBAAgB,CAC9B,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,MAAM,EAAE,WAAW,GAClB,aAAa,CAAC,kBAAkB,CAAC;IA2CpC;;;OAGG;IACM,OAAO,IAAI,IAAI;CAOzB"}
@@ -0,0 +1,285 @@
1
+ import { InProcessStreamBus, } from '@qjp88995/agent-runtime';
2
+ import { redisKeys } from './keys.js';
3
+ /**
4
+ * 兜底上限,不是常态:落库的段落会从流里退役(`retireUpTo`),流里常态只剩尚未落库的那一段。
5
+ * 它只挡进程崩溃留下的孤儿轮次、以及一段长到落库之前就写出上万条的极端情况。
6
+ */
7
+ const MAXLEN = 10_000;
8
+ const STREAM_TTL_SECONDS = 3600;
9
+ const XREAD_BLOCK_MS = 5_000;
10
+ /**
11
+ * 一次 XREAD 最多取多少条。首连的重放段吃这个数(游标缺省 `'0'`,100 一批就是上百次往返);
12
+ * 活跃期一批本来也就一两条,调大不影响。
13
+ */
14
+ const XREAD_COUNT = 500;
15
+ /**
16
+ * 非 abort 的 XREAD 失败后的退避。畸形游标会让 XREAD **立即**拒绝,没有退避就是 CPU 热循环兼
17
+ * 疯狂重连 Redis。
18
+ */
19
+ const XREAD_RETRY_DELAY_MS = 250;
20
+ /**
21
+ * 写侧合并窗口:同一段里连续的 `text-delta` / `reasoning-delta` 攒这么久再 XADD 成一条。流条目
22
+ * 不可变,合并只能在写入前做;前端本来就按渲染帧合帧,多攒两帧看不出来,条目数少一个数量级。
23
+ */
24
+ const XADD_BATCH_MS = 50;
25
+ /**
26
+ * 落库后条目在流里的宽限期。前端打开会话是「先拉历史、后订阅」两步,一段恰好在两步之间落库时,
27
+ * 它在库快照里没有、流里又删了——留一段让重放还能送到(前端按 `flushedSeq` 去重)。
28
+ */
29
+ const RETIRE_GRACE_MS = 30_000;
30
+ const XDEL_CHUNK = 500;
31
+ const SWEEP_INTERVAL_MS = 60_000;
32
+ function parseEntry(fields) {
33
+ const i = fields.indexOf('data');
34
+ if (i < 0 || i + 1 >= fields.length)
35
+ return null;
36
+ try {
37
+ return JSON.parse(fields[i + 1]);
38
+ }
39
+ catch {
40
+ return null;
41
+ }
42
+ }
43
+ function isMergeableDelta(e) {
44
+ return e.type === 'text-delta' || e.type === 'reasoning-delta';
45
+ }
46
+ function textOf(e) {
47
+ const p = e.payload;
48
+ return typeof p?.text === 'string' ? p.text : '';
49
+ }
50
+ /**
51
+ * 「紧邻的同一段」:同 root、同 run、同 messageId、同 type、同深度。退役边界永远落在类型切换处,
52
+ * 所以一条合并条目不会横跨边界,`seq ≤ 边界` 对合并条目(seq 取最后一条)仍然精确。
53
+ */
54
+ function sameSegment(a, b) {
55
+ return (a.rootSessionId === b.rootSessionId &&
56
+ a.runId === b.runId &&
57
+ a.messageId === b.messageId &&
58
+ a.type === b.type &&
59
+ a.depth === b.depth);
60
+ }
61
+ /**
62
+ * 多实例事件总线:**per-stream 面留在进程内**(继承 `InProcessStreamBus`:seq、buffer、取消信号——
63
+ * 消费它们的 pump 与 `streamText` 都在跑这一轮的那个进程里),**会话面换成 Redis Streams**
64
+ * (键 `agent-session:<root>`),跨实例、断线可按游标续订。搬自 agent-base `RedisStreamBus`。
65
+ *
66
+ * ## 会话面只保留尚未落库的尾巴
67
+ *
68
+ * - **落库即退役**:宿主落库成功后调 `retireUpTo(runId, seq)`,宽限期后 XDEL 这一轮 seq ≤ 边界的条目;
69
+ * `run-finish` / `error` 宽限期后整轮清掉。条目 id 从 XADD 回值登记在进程内存里(写这轮事件的
70
+ * 就是跑这轮的进程);别的实例补发的 `run-finish` 在本进程查不到表,删除是 no-op,孤儿条目由
71
+ * TTL / MAXLEN 兜底。
72
+ * - **写侧合并**:连续的同段 delta 攒一个窗口再写;任何不可合并的事件先把攒着的吐掉,顺序不变。
73
+ *
74
+ * 会话面的写是 fire-and-forget:观测不承重,序列化失败或 Redis 出错只丢这一条,绝不让一轮对话失败。
75
+ *
76
+ * ## 与 agent-base 的差别
77
+ *
78
+ * - `publish` 只在流活着时写会话面(agent-base 不看流状态;这里与进程内实现、端口约定对齐:
79
+ * 「流未 open / 已 close 时丢弃」)。
80
+ * - 测试用的 `configureForTest` 改成构造参数 `batchMs` / `retireGraceMs`;加 `dispose()`。
81
+ * - 键可加前缀(`keyPrefix`)。
82
+ *
83
+ * **停止按钮仍是进程内的**:`abort(streamId)` 只对本进程跑着的流生效,与 agent-base 一样——
84
+ * 停止请求落到别的实例上时,宿主要自己把它路由到跑这轮的实例(或者走会话锁所在实例)。
85
+ */
86
+ export class RedisStreamBus extends InProcessStreamBus {
87
+ redis;
88
+ keys;
89
+ batchMs;
90
+ graceMs;
91
+ maxLen;
92
+ streamTtlSeconds;
93
+ xreadBlockMs;
94
+ pendingByRoot = new Map();
95
+ entriesByRun = new Map();
96
+ timers = new Set();
97
+ runTableTimer;
98
+ constructor(redis, options = {}) {
99
+ super(options);
100
+ this.redis = redis;
101
+ this.keys = redisKeys(options);
102
+ this.batchMs =
103
+ options.batchMs === undefined ? XADD_BATCH_MS : options.batchMs;
104
+ this.graceMs = options.retireGraceMs ?? RETIRE_GRACE_MS;
105
+ this.maxLen = options.maxLen ?? MAXLEN;
106
+ this.streamTtlSeconds = options.streamTtlSeconds ?? STREAM_TTL_SECONDS;
107
+ this.xreadBlockMs = options.xreadBlockMs ?? XREAD_BLOCK_MS;
108
+ this.runTableTimer = setInterval(() => this.sweepRunTables(), SWEEP_INTERVAL_MS);
109
+ this.runTableTimer.unref();
110
+ }
111
+ publish(event) {
112
+ // 只喂进程内的 per-stream 面,绝不走基类的进程内会话面(那块在这里永远是空的)。
113
+ if (this.publishToStream(event))
114
+ this.enqueueSession(event);
115
+ }
116
+ publishSessionEvent(event) {
117
+ this.enqueueSession(event);
118
+ }
119
+ retireUpTo(runId, uptoSeq) {
120
+ this.later(() => this.deleteEntries(runId, e => e.seq <= uptoSeq));
121
+ }
122
+ /** 宽限期后执行;`dispose()` 会清掉还没到点的。 */
123
+ later(fn) {
124
+ const timer = setTimeout(() => {
125
+ this.timers.delete(timer);
126
+ fn();
127
+ }, this.graceMs);
128
+ timer.unref();
129
+ this.timers.add(timer);
130
+ }
131
+ /**
132
+ * 会话面入口。序列化在进入 fire-and-forget 链之前同步做完(见 `xaddSession`),非 JSON-safe
133
+ * 载荷不会经 `publish` 冒进 `runTurn`。
134
+ */
135
+ enqueueSession(event) {
136
+ const root = event.rootSessionId;
137
+ const pending = this.pendingByRoot.get(root);
138
+ if (this.batchMs !== null && isMergeableDelta(event)) {
139
+ if (pending && sameSegment(pending.event, event)) {
140
+ pending.event = {
141
+ ...pending.event,
142
+ seq: event.seq,
143
+ ts: event.ts,
144
+ payload: { text: textOf(pending.event) + textOf(event) },
145
+ };
146
+ return;
147
+ }
148
+ if (pending)
149
+ this.flushPending(root);
150
+ const timer = setTimeout(() => this.flushPending(root), this.batchMs);
151
+ timer.unref();
152
+ this.pendingByRoot.set(root, { event, timer });
153
+ return;
154
+ }
155
+ if (pending)
156
+ this.flushPending(root);
157
+ const written = this.xaddSession(event);
158
+ // 宽限期从这条自己登记完才开始算:XADD 回包后才把 id 记进登记表,同步起表的话回包慢过
159
+ // 宽限期时删除先跑——边界事件本身漏删,回包再登记出一张没人清的表。
160
+ if (event.type === 'run-finish' || event.type === 'error') {
161
+ void written.then(() => this.later(() => {
162
+ this.deleteEntries(event.runId, () => true);
163
+ this.entriesByRun.delete(event.runId);
164
+ }));
165
+ }
166
+ }
167
+ flushPending(root) {
168
+ const pending = this.pendingByRoot.get(root);
169
+ if (!pending)
170
+ return;
171
+ clearTimeout(pending.timer);
172
+ this.pendingByRoot.delete(root);
173
+ void this.xaddSession(pending.event);
174
+ }
175
+ /** 写一条并登记;返回的 promise 在登记完(或失败被吞)后落定,从不 reject。 */
176
+ xaddSession(event) {
177
+ let data;
178
+ try {
179
+ data = JSON.stringify(event);
180
+ }
181
+ catch {
182
+ return Promise.resolve();
183
+ }
184
+ const key = this.keys.sessionStream(event.rootSessionId);
185
+ // XADD + 刷新 TTL 一次往返。会话级事件(seq 0)不登记——它们不属于任何会落库的段落。
186
+ return this.redis
187
+ .multi()
188
+ .xadd(key, 'MAXLEN', '~', String(this.maxLen), '*', 'data', data)
189
+ .expire(key, this.streamTtlSeconds)
190
+ .exec()
191
+ .then(res => {
192
+ const id = res?.[0]?.[1];
193
+ if (typeof id !== 'string' || event.seq <= 0)
194
+ return;
195
+ let run = this.entriesByRun.get(event.runId);
196
+ if (!run) {
197
+ run = { key, ids: [], lastActivity: Date.now() };
198
+ this.entriesByRun.set(event.runId, run);
199
+ }
200
+ run.ids.push({ seq: event.seq, id });
201
+ run.lastActivity = Date.now();
202
+ })
203
+ .catch(() => undefined);
204
+ }
205
+ deleteEntries(runId, pick) {
206
+ const run = this.entriesByRun.get(runId);
207
+ if (!run)
208
+ return;
209
+ const doomed = run.ids.filter(pick).map(e => e.id);
210
+ if (doomed.length === 0)
211
+ return;
212
+ run.ids = run.ids.filter(e => !pick(e));
213
+ run.lastActivity = Date.now();
214
+ for (let i = 0; i < doomed.length; i += XDEL_CHUNK) {
215
+ void this.redis
216
+ .xdel(run.key, ...doomed.slice(i, i + XDEL_CHUNK))
217
+ .catch(() => undefined);
218
+ }
219
+ }
220
+ /** 轮次登记表兜底清理:正常路径由 run-finish / error 清;崩溃或别的实例收尾的轮次靠这里。 */
221
+ sweepRunTables() {
222
+ const now = Date.now();
223
+ const ttlMs = this.streamTtlSeconds * 1000;
224
+ for (const [runId, run] of this.entriesByRun) {
225
+ if (now - run.lastActivity > ttlMs)
226
+ this.entriesByRun.delete(runId);
227
+ }
228
+ }
229
+ /**
230
+ * 每个订阅一条独立连接(XREAD BLOCK 会占住连接);`signal` abort 时断开它,在途的 XREAD 随之结束。
231
+ */
232
+ async *subscribeSession(rootSessionId, fromId, signal) {
233
+ if (signal.aborted)
234
+ return;
235
+ const sub = this.redis.duplicate();
236
+ const onAbort = () => void sub.disconnect();
237
+ signal.addEventListener('abort', onAbort);
238
+ const key = this.keys.sessionStream(rootSessionId);
239
+ let cursor = fromId && fromId.length > 0 ? fromId : '0';
240
+ try {
241
+ for (;;) {
242
+ if (signal.aborted)
243
+ return;
244
+ let res;
245
+ try {
246
+ res = (await sub.xread('COUNT', XREAD_COUNT, 'BLOCK', this.xreadBlockMs, 'STREAMS', key, cursor));
247
+ }
248
+ catch {
249
+ if (signal.aborted)
250
+ return;
251
+ await new Promise(resolve => setTimeout(resolve, XREAD_RETRY_DELAY_MS));
252
+ continue;
253
+ }
254
+ if (!res)
255
+ continue;
256
+ for (const [, entries] of res) {
257
+ for (const [id, fields] of entries) {
258
+ cursor = id;
259
+ const event = parseEntry(fields);
260
+ if (event)
261
+ yield { id, event };
262
+ }
263
+ }
264
+ }
265
+ }
266
+ finally {
267
+ signal.removeEventListener('abort', onAbort);
268
+ await sub.quit().catch(() => undefined);
269
+ }
270
+ }
271
+ /**
272
+ * 停掉定时器:攒着的 delta 立刻写出去(不丢),还没到点的退役放弃(条目由 TTL / MAXLEN 兜底)。
273
+ * 不关宿主给的连接。
274
+ */
275
+ dispose() {
276
+ super.dispose();
277
+ clearInterval(this.runTableTimer);
278
+ for (const root of [...this.pendingByRoot.keys()])
279
+ this.flushPending(root);
280
+ for (const timer of this.timers)
281
+ clearTimeout(timer);
282
+ this.timers.clear();
283
+ }
284
+ }
285
+ //# sourceMappingURL=stream-bus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-bus.js","sourceRoot":"","sources":["../src/stream-bus.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,49 @@
1
1
  {
2
2
  "name": "@qjp88995/agent-runtime-redis",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.2.0",
4
+ "description": "Redis adapters for @qjp88995/agent-runtime: event bus, session lock, wake/idle channel, subagent await lease, tree budget, task lease and task background signal, for running on more than one instance.",
5
+ "license": "UNLICENSED",
6
+ "type": "module",
7
+ "publishConfig": {
8
+ "access": "public",
9
+ "registry": "https://registry.npmjs.org/"
10
+ },
11
+ "files": [
12
+ "dist",
13
+ "src",
14
+ "!src/**/*.spec.ts",
15
+ "!src/test-redis.ts"
16
+ ],
17
+ "engines": {
18
+ "node": ">=22.12"
19
+ },
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/qjp88995/agent-kit.git",
23
+ "directory": "packages/runtime-redis"
24
+ },
25
+ "exports": {
26
+ ".": {
27
+ "types": "./dist/index.d.ts",
28
+ "default": "./dist/index.js"
29
+ }
30
+ },
31
+ "peerDependencies": {
32
+ "ioredis": "^5.4.0",
33
+ "@qjp88995/agent-runtime": "^0.2.0"
34
+ },
35
+ "devDependencies": {
36
+ "@types/node": "^25.9.5",
37
+ "ioredis": "^5.11.1",
38
+ "typescript": "^5.9.3",
39
+ "vitest": "^4.1.10",
40
+ "@qjp88995/agent-runtime": "0.2.0"
41
+ },
42
+ "scripts": {
43
+ "build": "rm -rf dist *.tsbuildinfo && tsc -p tsconfig.build.json",
44
+ "lint": "eslint .",
45
+ "typecheck": "tsc --noEmit",
46
+ "test": "pnpm build && vitest run",
47
+ "clean": "rm -rf dist .turbo *.tsbuildinfo"
48
+ }
6
49
  }