@hasna-internal/kai-tool-call-timeout-policy 0.1.1-rc.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 DeepSeek
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,6 @@
1
+ # Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
2
+ # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
+ # after editing either side, bring the other along and re-record with:
4
+ # pnpm run verify-translation-pairing --write packages/guard/timeout-policy/README.md
5
+ README.md: 4b0ea4e541f0740289623f5e81d79e168240a402
6
+ README.zh.md: 36bf8150e5b095c713cb71b76bd8dcc43857afc8
package/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # dsh-tool-call-timeout-policy
2
+
3
+ English | [中文](README.zh.md)
4
+
5
+ Tool-call timeout enforcer: a single `tools/execute` around-dispatch listener that arms a per-call cooperative deadline on `exec.signal` for a tool declaring `timeoutMs` on its `ToolDefinition` and returns a structured `TOOL_TIMEOUT` result when that deadline wins. The budget is read from the tool's own declaration (`ToolDefinition.timeoutMs`, set by the owning tool plugin), so this plugin is **zero-config**. It is the reference `tools/execute` wrapper and the enforcement home for model-facing tool-call budgets ([timeout-library Agent Note](../../../.agents/notes/implemented/architecture/2026-07-06-timeout-deadline-library.md)).
6
+
7
+ ## Plugin (namespace: `timeout-policy`)
8
+
9
+ A function/namespace plugin (`name` / `inject` / `apply`), not a service. It registers no tool and takes no config — it consumes `ctx.tools`'s `tools/execute` waterfall (which the `dsh-tools` registry always provides) and reads each dispatched tool's declared `timeoutMs` from the registry (`ctx.tools.get(exec.name)`).
10
+
11
+ ```yaml
12
+ - id: timeout-policy
13
+ name: '@hasna-internal/kai-tool-call-timeout-policy'
14
+ ```
15
+
16
+ The per-tool budget is declared by the tool plugin (e.g. `dsh-tool-web`'s `fetchTimeoutMs`/`searchTimeoutMs` config, attached as `ToolDefinition.timeoutMs`); this plugin only enforces it, so a mistyped tool name is not possible.
17
+
18
+ ### Behavior
19
+
20
+ For a tool that **declares a `timeoutMs`** the listener:
21
+
22
+ 1. Reads the budget from the tool's own declaration in the registry (`ctx.tools.get(exec.name)?.timeoutMs`) and arms `deadline(exec.signal, timeoutMs, 'TOOL_TIMEOUT')` — one signal fusing the caller's abort with this plugin's timer (`@hasna-internal/kai-timeout`).
23
+ 2. Swaps that derived signal onto `exec` for the downstream dispatch, then restores the caller's own signal afterward (cordis `next()` ignores passed arguments, so the wrapper mutates the shared `exec` in place; restoring keeps `tools/post-execute` seeing the caller's signal).
24
+ 3. After dispatch, if `timeoutOf(d.signal, 'TOOL_TIMEOUT')` matches — this plugin's own timer fired — replaces the result with a structured `TOOL_TIMEOUT` tool result: `{ isError: true, error: { message, info: { name: 'ToolTimeoutError', code: 'TOOL_TIMEOUT' } }, content: 'Error: tool call timed out after <ms>ms' }`.
25
+
26
+ A tool that **declares no budget** delegates untouched (no deadline).
27
+
28
+ The base `next()` of `tools/execute` is the registry's dispatch-with-normalization thunk, so when the timeout signal reaches a provider that throws its own upstream-abort error, dispatch first turns it into a normal error result, and this wrapper then replaces that with `TOOL_TIMEOUT`. That ordering is why the replacement is keyed off the signal (`timeoutOf`), not off the dispatched result's shape.
29
+
30
+ ### Cooperative, not a hard kill
31
+
32
+ The derived signal only **notifies**; termination stays with the tool and the capability it forwards `exec.signal` to (the `dsh-timeout` library owns no kill). **Declaring `timeoutMs` therefore means "cooperative with `exec.signal`"**: a tool that ignores the signal will not stop on timeout. Only signal-forwarding tools should declare it — the shipped `web_fetch`/`web_search` (which forward through `ctx.web` to providers) are the reference. `TOOL_TIMEOUT` needs no session event for reconstructability: it is the final model-facing `tool/result`, already logged by the loop.
33
+
34
+ ### Composing with other `tools/execute` wrappers
35
+
36
+ Multiple `tools/execute` listeners compose by cordis registration order. Combined with a future retry/sandbox/metrics wrapper, registration order chooses the semantics — "timeout covers the whole retry operation" (timeout registered outer) versus "timeout covers each attempt" (timeout registered inner).
37
+
38
+ ## Model Experience
39
+
40
+ ### Conditional tool result
41
+
42
+ #### What the model sees
43
+
44
+ This plugin adds no prompt or schema. If a declared deadline wins, it replaces the provider's outcome with `Error: tool call timed out after <ms>ms` plus structured `TOOL_TIMEOUT`; otherwise the original result passes through unchanged.
45
+
46
+ #### Token effect
47
+
48
+ Zero tokens on non-timeout calls. A timeout adds one small retained error result and can prevent a larger late provider result from entering context.
49
+
50
+ #### KV Cache effect
51
+
52
+ Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
53
+
54
+ ## Known Limitations and Deferred Work
55
+
56
+ - **Cooperative, never a hard kill** — the deadline only notifies via `exec.signal`; a tool that ignores the signal does not stop on timeout (see § Cooperative, not a hard kill).
57
+ - **No blanket budget** — only tools that declare `timeoutMs` on their `ToolDefinition` get a deadline; there is no registry-wide default for undeclared tools (the shipped `bash`/`read`/`write`/`edit` deliberately declare none).
package/README.zh.md ADDED
@@ -0,0 +1,57 @@
1
+ # dsh-tool-call-timeout-policy
2
+
3
+ [English](README.md) | 中文
4
+
5
+ 工具调用超时强制执行器:单个 `tools/execute` 环绕分发监听器,会在 `exec.signal` 上设置单次调用的协作式截止时间;适用于声明了 `timeoutMs` 且声明位于其 `ToolDefinition` 上的工具。该截止时间先到时,它返回结构化 `TOOL_TIMEOUT` 结果。预算从工具自身的声明中读取(`ToolDefinition.timeoutMs`,由拥有该工具的插件设置),因此此插件是**零配置**的。它是 `tools/execute` 包装层的参考实现,也是面向模型工具调用预算的强制执行归属地([超时库 Agent Note](../../../.agents/notes/implemented/architecture/2026-07-06-timeout-deadline-library.zh.md))。
6
+
7
+ ## 插件(命名空间:`timeout-policy`)
8
+
9
+ 它是函数/命名空间插件(`name`/`inject`/`apply`),而非服务。它不注册工具,也不接受配置;它消费 `ctx.tools` 的 `tools/execute` waterfall(瀑布式事件)(由 `dsh-tools` 注册表始终提供),并读取每个已分发工具声明的 `timeoutMs`;该声明来自注册表(`ctx.tools.get(exec.name)`)。
10
+
11
+ ```yaml
12
+ - id: timeout-policy
13
+ name: '@hasna-internal/kai-tool-call-timeout-policy'
14
+ ```
15
+
16
+ 每工具预算由工具插件声明(例如 `dsh-tool-web` 的 `fetchTimeoutMs`/`searchTimeoutMs` 配置,会附加为 `ToolDefinition.timeoutMs`);此插件只负责强制执行,因此不可能拼错工具名。
17
+
18
+ ### 行为
19
+
20
+ 对 **声明了 `timeoutMs` 的工具**,监听器会:
21
+
22
+ 1. 从注册表中的工具自身声明(`ctx.tools.get(exec.name)?.timeoutMs`)读取预算,并设置 `deadline(exec.signal, timeoutMs, 'TOOL_TIMEOUT')`:一个将调用方中止与此插件计时器融合的信号(`@hasna-internal/kai-timeout`)。
23
+ 2. 将该派生信号替换到 `exec` 上用于下游分发,然后恢复调用方自身的信号(Cordis `next()` 忽略传入的参数,因此包装层会原地修改共享 `exec`;恢复可使 `tools/post-execute` 看到调用方的信号)。
24
+ 3. 分发后,如果 `timeoutOf(d.signal, 'TOOL_TIMEOUT')` 检测到此插件自身的计时器已触发,则将结果替换为结构化 `TOOL_TIMEOUT` 工具结果:`{ isError: true, error: { message, info: { name: 'ToolTimeoutError', code: 'TOOL_TIMEOUT' } }, content: 'Error: tool call timed out after <ms>ms' }`。
25
+
26
+ **未声明预算的工具** 会原样委托(不启动截止时间)。
27
+
28
+ 基础 `next()` 是注册表为 `tools/execute` 提供的、带规范化处理的分发 thunk,因此当超时信号到达抛出自身上游中止错误的提供方时,分发会先将其转换为普通错误结果,再由此包装层替换为 `TOOL_TIMEOUT`。这一顺序就是替换依据信号(`timeoutOf`)而非已分发结果形状的原因。
29
+
30
+ ### 协作式,而非硬终止
31
+
32
+ 派生信号只会**通知**;是否终止仍取决于工具及其将 `exec.signal` 转发到的能力(`dsh-timeout` 库本身不负责硬终止)。**因此,声明 `timeoutMs` 意味着「与 `exec.signal` 协作」**:忽略该信号的工具不会在超时时停止。只有转发信号的工具才应声明该字段;已交付的 `web_fetch`/`web_search`(通过 `ctx.web` 转发给提供方)是参考实现。`TOOL_TIMEOUT` 无需会话事件以满足可重建性:它是最终面向模型的 `tool/result`,已由循环记录。
33
+
34
+ ### 与其他 `tools/execute` 包装层组合
35
+
36
+ 多个 `tools/execute` 监听器按 Cordis 注册顺序组合。与未来的重试/沙箱/指标包装层一起使用时,注册顺序决定语义:「超时覆盖整个重试操作」(超时注册在外层),或「超时覆盖每次尝试」(超时注册在内层)。
37
+
38
+ ## 模型体验
39
+
40
+ ### 条件工具结果
41
+
42
+ #### 模型看到的内容
43
+
44
+ 此插件不添加提示词或 schema。如果已声明的截止时间先到,它会将提供方结果替换为 `Error: tool call timed out after <ms>ms` 与结构化 `TOOL_TIMEOUT`;否则原结果保持不变。
45
+
46
+ #### Token 影响
47
+
48
+ 未超时的调用不会增加 token。超时会添加一条会被保留的简短错误结果,并可防止体积更大、较晚返回的提供方结果进入上下文。
49
+
50
+ #### KV Cache 影响
51
+
52
+ 仅追加;新可见内容位于可复用请求前缀之后,不会使现有 KV Cache 条目失效。
53
+
54
+ ## 已知限制与暂缓事项
55
+
56
+ - **协作式,绝不是硬终止**:截止时间只通过 `exec.signal` 通知;忽略该信号的工具不会在超时时停止(参见「协作式,而非硬终止」一节)。
57
+ - **没有统一预算**:只有声明 `timeoutMs` 并将其放在 `ToolDefinition` 上的工具才会获得截止时间;未声明工具没有注册表级默认值(已交付的 `bash`/`read`/`write`/`edit` 有意不声明)。
package/lib/index.js ADDED
@@ -0,0 +1,144 @@
1
+ import { deadline, timeoutOf } from "@hasna-internal/kai-timeout";
2
+ //#region lib/types/index.js
3
+ /**
4
+ * Cooperative tool-call timeout enforcer. A tool declares `timeoutMs` and
5
+ * promises to honor `exec.signal`; this wrapper arms that deadline and maps its
6
+ * own expiry to `TOOL_TIMEOUT` without racing or abandoning the tool promise.
7
+ *
8
+ * FIXME: settle the intended `@hasna-internal/kai-timeout-guard` rename before the
9
+ * first tagged release — suggestion only, aligning the name with its `guard/`
10
+ * home; decide at resolution time
11
+ * ([regrouping Agent Note](../../../../.agents/notes/implemented/architecture/2026-07-29-package-regrouping.md)).
12
+ *
13
+ * @module @hasna-internal/kai-tool-call-timeout-policy
14
+ */
15
+ var __addDisposableResource = function(env, value, async) {
16
+ if (value !== null && value !== void 0) {
17
+ if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
18
+ var dispose, inner;
19
+ if (async) {
20
+ if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
21
+ dispose = value[Symbol.asyncDispose];
22
+ }
23
+ if (dispose === void 0) {
24
+ if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
25
+ dispose = value[Symbol.dispose];
26
+ if (async) inner = dispose;
27
+ }
28
+ if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
29
+ if (inner) dispose = function() {
30
+ try {
31
+ inner.call(this);
32
+ } catch (e) {
33
+ return Promise.reject(e);
34
+ }
35
+ };
36
+ env.stack.push({
37
+ value,
38
+ dispose,
39
+ async
40
+ });
41
+ } else if (async) env.stack.push({ async: true });
42
+ return value;
43
+ };
44
+ var __disposeResources = (function(SuppressedError) {
45
+ return function(env) {
46
+ function fail(e) {
47
+ env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
48
+ env.hasError = true;
49
+ }
50
+ var r, s = 0;
51
+ function next() {
52
+ while (r = env.stack.pop()) try {
53
+ if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
54
+ if (r.dispose) {
55
+ var result = r.dispose.call(r.value);
56
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) {
57
+ fail(e);
58
+ return next();
59
+ });
60
+ } else s |= 1;
61
+ } catch (e) {
62
+ fail(e);
63
+ }
64
+ if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
65
+ if (env.hasError) throw env.error;
66
+ }
67
+ return next();
68
+ };
69
+ })(typeof SuppressedError === "function" ? SuppressedError : function(error, suppressed, message) {
70
+ var e = new Error(message);
71
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
72
+ });
73
+ /**
74
+ * The code owned by this plugin, used BOTH as the internal {@link deadline}
75
+ * classification code AND as the structured error `code` on the replacement
76
+ * tool result. Scoping {@link timeoutOf} to it keeps a nested outer deadline
77
+ * (another `tools/execute` wrapper's timer that fired first) from being misread
78
+ * as this plugin's own timeout — it reads as an ordinary upstream cancel.
79
+ */
80
+ const TOOL_TIMEOUT = "TOOL_TIMEOUT";
81
+ /** Cordis plugin name used by loader diagnostics. */
82
+ const name = "timeout-policy";
83
+ /** The tool registry service this plugin wraps (`tools/execute`) and reads (`get`). */
84
+ const inject = ["tools"];
85
+ /**
86
+ * The structured result substituted when this plugin's deadline wins. `content`
87
+ * is the model-facing message; `error.code` is the same {@link TOOL_TIMEOUT}
88
+ * this plugin owns, so a retry/sandbox plugin (and replay) can route on it.
89
+ *
90
+ * @param timeoutMs - the elapsed budget, rendered into the model-facing message.
91
+ * @returns the `isError` {@link ToolExecutionResult} with a `TOOL_TIMEOUT` error.
92
+ */
93
+ function toolTimeoutResult(timeoutMs) {
94
+ const message = `tool call timed out after ${timeoutMs}ms`;
95
+ return {
96
+ content: [{
97
+ type: "text",
98
+ text: `Error: ${message}`
99
+ }],
100
+ isError: true,
101
+ error: {
102
+ message,
103
+ info: {
104
+ name: "ToolTimeoutError",
105
+ code: TOOL_TIMEOUT
106
+ }
107
+ }
108
+ };
109
+ }
110
+ /**
111
+ * Register the timeout wrapper. It resolves the caller-visible tool definition,
112
+ * temporarily replaces `exec.signal`, delegates, restores the upstream signal,
113
+ * and replaces the result only when this wrapper's own timer fired.
114
+ */
115
+ function apply(ctx) {
116
+ ctx.on("tools/execute", async (exec, next) => {
117
+ const env_1 = {
118
+ stack: [],
119
+ error: void 0,
120
+ hasError: false
121
+ };
122
+ try {
123
+ const timeoutMs = ctx.tools.get(exec.name, exec.agent)?.timeoutMs;
124
+ if (timeoutMs === void 0) return next();
125
+ const d = __addDisposableResource(env_1, deadline(exec.signal, timeoutMs, TOOL_TIMEOUT), false);
126
+ const upstream = exec.signal;
127
+ exec.signal = d.signal;
128
+ try {
129
+ const result = await next();
130
+ if (timeoutOf(d.signal, "TOOL_TIMEOUT") !== void 0) return toolTimeoutResult(timeoutMs);
131
+ return result;
132
+ } finally {
133
+ exec.signal = upstream;
134
+ }
135
+ } catch (e_1) {
136
+ env_1.error = e_1;
137
+ env_1.hasError = true;
138
+ } finally {
139
+ __disposeResources(env_1);
140
+ }
141
+ });
142
+ }
143
+ //#endregion
144
+ export { TOOL_TIMEOUT, apply, inject, name };
@@ -0,0 +1,23 @@
1
+ //#region lib/types/invariant.js
2
+ /**
3
+ * Package-owned invariant companion for `@hasna-internal/kai-tool-call-timeout-policy`.
4
+ * @module @hasna-internal/kai-tool-call-timeout-policy/invariant
5
+ */
6
+ const PACKAGE_NAME = "@hasna-internal/kai-tool-call-timeout-policy";
7
+ /** Cordis companion plugin name. */
8
+ const name = "timeout-policy-invariant";
9
+ /** Service required before the companion can reserve package ownership. */
10
+ const inject = ["invariants"];
11
+ /**
12
+ * No runtime invariant: this stateless policy plugin owns no package-local event history or mutable
13
+ * data relation beyond the seam it intercepts.
14
+ */
15
+ const install = () => {};
16
+ /**
17
+ * Register this package's invariant companion.
18
+ * @param ctx - Cordis context carrying the invariant service.
19
+ * @returns the installed registration's disposer after setup succeeds.
20
+ */
21
+ const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
22
+ //#endregion
23
+ export { apply, inject, name };
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Cooperative tool-call timeout enforcer. A tool declares `timeoutMs` and
3
+ * promises to honor `exec.signal`; this wrapper arms that deadline and maps its
4
+ * own expiry to `TOOL_TIMEOUT` without racing or abandoning the tool promise.
5
+ *
6
+ * FIXME: settle the intended `@hasna-internal/kai-timeout-guard` rename before the
7
+ * first tagged release — suggestion only, aligning the name with its `guard/`
8
+ * home; decide at resolution time
9
+ * ([regrouping Agent Note](../../../../.agents/notes/implemented/architecture/2026-07-29-package-regrouping.md)).
10
+ *
11
+ * @module @hasna-internal/kai-tool-call-timeout-policy
12
+ */
13
+ import type { Context } from '@deepseek-ai/cordis';
14
+ /**
15
+ * The code owned by this plugin, used BOTH as the internal {@link deadline}
16
+ * classification code AND as the structured error `code` on the replacement
17
+ * tool result. Scoping {@link timeoutOf} to it keeps a nested outer deadline
18
+ * (another `tools/execute` wrapper's timer that fired first) from being misread
19
+ * as this plugin's own timeout — it reads as an ordinary upstream cancel.
20
+ */
21
+ export declare const TOOL_TIMEOUT = "TOOL_TIMEOUT";
22
+ /** Cordis plugin name used by loader diagnostics. */
23
+ export declare const name = "timeout-policy";
24
+ /** The tool registry service this plugin wraps (`tools/execute`) and reads (`get`). */
25
+ export declare const inject: string[];
26
+ /**
27
+ * Register the timeout wrapper. It resolves the caller-visible tool definition,
28
+ * temporarily replaces `exec.signal`, delegates, restores the upstream signal,
29
+ * and replaces the result only when this wrapper's own timer fired.
30
+ */
31
+ export declare function apply(ctx: Context): void;
32
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Package-owned invariant companion for `@hasna-internal/kai-tool-call-timeout-policy`.
3
+ * @module @hasna-internal/kai-tool-call-timeout-policy/invariant
4
+ */
5
+ import type { Context } from '@deepseek-ai/cordis';
6
+ /** Cordis companion plugin name. */
7
+ export declare const name = "timeout-policy-invariant";
8
+ /** Service required before the companion can reserve package ownership. */
9
+ export declare const inject: string[];
10
+ /**
11
+ * Register this package's invariant companion.
12
+ * @param ctx - Cordis context carrying the invariant service.
13
+ * @returns the installed registration's disposer after setup succeeds.
14
+ */
15
+ export declare const apply: (ctx: Context) => Promise<() => void>;
16
+ //# sourceMappingURL=invariant.d.ts.map
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@hasna-internal/kai-tool-call-timeout-policy",
3
+ "description": "Tool-call timeout policy: a tools/execute wrapper that arms a per-tool deadline on exec.signal and returns TOOL_TIMEOUT when it wins",
4
+ "version": "0.1.1-rc.2",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/deepseek-ai/deepseek-harness.git",
11
+ "directory": "packages/guard/timeout-policy"
12
+ },
13
+ "type": "module",
14
+ "main": "lib/index.js",
15
+ "types": "lib/types/index.d.ts",
16
+ "exports": {
17
+ ".": {
18
+ "types": "./lib/types/index.d.ts",
19
+ "default": "./lib/index.js"
20
+ },
21
+ "./invariant": {
22
+ "types": "./lib/types/invariant.d.ts",
23
+ "default": "./lib/invariant.js"
24
+ },
25
+ "./src/*": "./src/*",
26
+ "./package.json": "./package.json"
27
+ },
28
+ "files": [
29
+ "lib/index.js",
30
+ "lib/invariant.js",
31
+ "lib/types/**/*.d.ts"
32
+ ],
33
+ "license": "MIT",
34
+ "peerDependencies": {
35
+ "@hasna-internal/kai-invariants": "^0.1.1-rc.2",
36
+ "@hasna-internal/kai-tools": "^0.1.1-rc.2",
37
+ "@hasna-internal/kai-llm": "^0.1.1-rc.2",
38
+ "@hasna-internal/kai-timeout": "^0.1.1-rc.2",
39
+ "@deepseek-ai/cordis": "^4.0.1"
40
+ },
41
+ "devDependencies": {
42
+ "@hasna-internal/kai-invariants": "^0.1.1-rc.2",
43
+ "@deepseek-ai/cordis": "^4.0.1",
44
+ "@hasna-internal/kai-tools": "^0.1.1-rc.2",
45
+ "@hasna-internal/kai-llm": "^0.1.1-rc.2",
46
+ "@hasna-internal/kai-timeout": "^0.1.1-rc.2"
47
+ }
48
+ }