@di-code/coding-agent 0.1.3 → 0.1.4
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 +20 -10
- package/dist/core/context-builder.d.ts.map +1 -1
- package/dist/core/context-builder.js +6 -2
- package/dist/core/context-builder.js.map +1 -1
- package/dist/core/image-input.d.ts +1 -1
- package/dist/core/image-input.d.ts.map +1 -1
- package/dist/core/image-input.js +55 -10
- package/dist/core/image-input.js.map +1 -1
- package/dist/core/session/session-storage.d.ts.map +1 -1
- package/dist/core/session/session-storage.js +1 -0
- package/dist/core/session/session-storage.js.map +1 -1
- package/dist/core/session.d.ts +17 -2
- package/dist/core/session.d.ts.map +1 -1
- package/dist/core/session.js +89 -0
- package/dist/core/session.js.map +1 -1
- package/dist/core/tools/bash.d.ts +2 -2
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts +25 -0
- package/dist/core/tools/edit-diff.d.ts.map +1 -0
- package/dist/core/tools/edit-diff.js +136 -0
- package/dist/core/tools/edit-diff.js.map +1 -0
- package/dist/core/tools/edit.d.ts +13 -4
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +64 -30
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/read.d.ts +2 -2
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/write.d.ts +2 -2
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js.map +1 -1
- package/dist/entry.js +9 -2
- package/dist/entry.js.map +1 -1
- package/dist/main.d.ts +3 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +34 -6
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive-components.d.ts +2 -0
- package/dist/modes/interactive-components.d.ts.map +1 -1
- package/dist/modes/interactive-components.js +40 -13
- package/dist/modes/interactive-components.js.map +1 -1
- package/dist/modes/interactive-diff.d.ts +8 -0
- package/dist/modes/interactive-diff.d.ts.map +1 -0
- package/dist/modes/interactive-diff.js +78 -0
- package/dist/modes/interactive-diff.js.map +1 -0
- package/dist/modes/interactive-layout.d.ts +4 -0
- package/dist/modes/interactive-layout.d.ts.map +1 -1
- package/dist/modes/interactive-layout.js +4 -0
- package/dist/modes/interactive-layout.js.map +1 -1
- package/dist/modes/interactive-state.d.ts +5 -0
- package/dist/modes/interactive-state.d.ts.map +1 -1
- package/dist/modes/interactive-state.js +64 -11
- package/dist/modes/interactive-state.js.map +1 -1
- package/dist/modes/interactive.d.ts +10 -0
- package/dist/modes/interactive.d.ts.map +1 -1
- package/dist/modes/interactive.js +190 -20
- package/dist/modes/interactive.js.map +1 -1
- package/dist/provider-onboarding.d.ts +8 -1
- package/dist/provider-onboarding.d.ts.map +1 -1
- package/dist/provider-onboarding.js +46 -23
- package/dist/provider-onboarding.js.map +1 -1
- package/dist/rpc-entry.js +1 -1
- package/dist/rpc-entry.js.map +1 -1
- package/dist/startup.d.ts +11 -3
- package/dist/startup.d.ts.map +1 -1
- package/dist/startup.js +216 -87
- package/dist/startup.js.map +1 -1
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -45,7 +45,11 @@ di-code
|
|
|
45
45
|
3. **填写 API key**:选择真实 Provider 时,在隐藏输入框中粘贴对应的 key;输入内容不会显示在终端中。
|
|
46
46
|
4. **确认并开始对话**:向导完成后进入 interactive 模式,在底部输入框输入问题并按 `Enter`。
|
|
47
47
|
|
|
48
|
-
向导输入的 API key
|
|
48
|
+
向导输入的 API key 会保存到用户全局 `~/.di-code/settings.json`,供之后启动复用;不会写入 `.env`、项目 `.di-code/settings.json`、会话文件或日志。请保护用户目录的访问权限,不要复制或提交该文件。
|
|
49
|
+
|
|
50
|
+
已经进入交互模式后,使用 `/login` 可以重新打开 Provider、模型和 key 向导。它总会要求真实 Provider 输入新的隐藏 key,写入用户全局 `settings.json` 成功后立即切换当前会话的 Provider 和模型。`/logout` 只移除当前 Provider 在该全局文件中的 `apiKey`,保留 `api`、`baseUrl`、`models` 及其他 Provider 配置;它不会也无法删除环境变量中的 key,因此环境变量仍可能继续生效。
|
|
51
|
+
|
|
52
|
+
`/login` 还会更新同一文件的 `defaultProvider` 和 `defaultModel`。当全局配置中有多个 Provider 时,下一次启动会使用这两个默认值;显式设置的 `DI_CODE_PROVIDER` 与 `DI_CODE_MODEL` 始终优先。
|
|
49
53
|
|
|
50
54
|
向导完成后可以直接这样使用:
|
|
51
55
|
|
|
@@ -55,12 +59,14 @@ di-code
|
|
|
55
59
|
|
|
56
60
|
### 方式二:直接用 `settings.json` 配置
|
|
57
61
|
|
|
58
|
-
如果你已经知道 Provider、`baseUrl`、模型和 API key
|
|
62
|
+
如果你已经知道 Provider、`baseUrl`、模型和 API key,可以不使用向导,直接创建 `settings.json`。启动时会先读取用户全局配置 `~/.di-code/settings.json`,再读取当前项目的 `.di-code/settings.json`;项目配置会覆盖同名 Provider 的已设置字段,并保留全局 Provider 中项目未设置的字段。全局配置适合个人常用 Provider,项目配置适合私有网关或项目专用模型。
|
|
63
|
+
|
|
64
|
+
同名 Provider 的 `models` 在项目中出现时会整体替换全局的模型列表;项目未写 `models` 时继续使用全局模型列表。只存在于任一文件中的 Provider 都会保留。
|
|
59
65
|
|
|
60
66
|
下面这个例子使用 OpenAI Responses 兼容接口。将示例中的 `baseUrl`、`apiKey` 和模型字段替换为实际值后即可使用:
|
|
61
67
|
|
|
62
68
|
|
|
63
|
-
`.di-code/settings.json`:
|
|
69
|
+
`~/.di-code/settings.json` 或 `.di-code/settings.json`:
|
|
64
70
|
|
|
65
71
|
```json
|
|
66
72
|
{
|
|
@@ -87,7 +93,7 @@ di-code
|
|
|
87
93
|
默认使用第一个模型。可以添加多个模型然后使用`/model`切换
|
|
88
94
|
|
|
89
95
|
|
|
90
|
-
`settings.json` 中的 `apiKey`
|
|
96
|
+
`settings.json` 中的 `apiKey` 可以直接填写字符串,也可以引用环境变量。全局配置通常不进入项目 Git,因此适合保存个人配置;项目配置若使用明文 key,必须确保 `.di-code/settings.json` 不会提交。环境变量写法如下:
|
|
91
97
|
|
|
92
98
|
```json
|
|
93
99
|
{
|
|
@@ -118,7 +124,9 @@ di-code "检查当前项目的测试状态"
|
|
|
118
124
|
| 字段 | 作用 |
|
|
119
125
|
| --- | --- |
|
|
120
126
|
| `providers` | Provider 配置对象,key 是 Provider ID |
|
|
121
|
-
| `
|
|
127
|
+
| `defaultProvider` | 可选的默认 Provider;`/login` 自动更新,多个 Provider 时用于消除启动歧义 |
|
|
128
|
+
| `defaultModel` | `defaultProvider` 的可选默认模型;`/login` 自动更新 |
|
|
129
|
+
| `api` | 接口类型:`openai-responses`、`openai-chat-completions` 或 `anthropic-messages` |
|
|
122
130
|
| `baseUrl` | Provider 的接口地址,必须是绝对的 `http` 或 `https` URL |
|
|
123
131
|
| `apiKey` | API key,推荐填写 `$ENV_VAR` 或 `${ENV_VAR}` |
|
|
124
132
|
| `models` | 自定义 Provider 必填的模型列表 |
|
|
@@ -146,7 +154,7 @@ di-code "检查当前项目的测试状态"
|
|
|
146
154
|
}
|
|
147
155
|
```
|
|
148
156
|
|
|
149
|
-
|
|
157
|
+
合并后的 `settings.json` 中只有一个 Provider 时,可以省略 `DI_CODE_PROVIDER`;如果有多个 Provider,则必须设置它。`DI_CODE_MODEL` 省略时使用该 Provider 模型列表的第一项。配置完成后,先用 print 模式验证:
|
|
150
158
|
|
|
151
159
|
```powershell
|
|
152
160
|
di-code --print "用一句话介绍当前项目"
|
|
@@ -269,6 +277,8 @@ di-code --continue "继续上一次工作"
|
|
|
269
277
|
| `/session` | 选择或切换会话 |
|
|
270
278
|
| `/theme` | 选择 dark 或 light 主题 |
|
|
271
279
|
| `/settings` | 配置上下文压缩开关 |
|
|
280
|
+
| `/login` | 打开 Provider、模型和隐藏 API key 向导;保存到用户全局配置并切换当前会话 |
|
|
281
|
+
| `/logout` | 移除当前 Provider 的用户全局 `apiKey`,不改环境变量或其他配置字段 |
|
|
272
282
|
| `/compact` | 立即压缩当前持久化会话的旧上下文 |
|
|
273
283
|
| `/usage` | 查看请求数、token、费用和上下文占用 |
|
|
274
284
|
| `/retry` | 重新提交最近失败或取消的 prompt |
|
|
@@ -465,7 +475,7 @@ di-code plugin remove project-status
|
|
|
465
475
|
|
|
466
476
|
## 自定义 Provider
|
|
467
477
|
|
|
468
|
-
自定义 OpenAI Responses
|
|
478
|
+
自定义 OpenAI Responses 兼容网关或私有模型时,可在用户全局 `~/.di-code/settings.json` 或工作根目录 `.di-code/settings.json` 中声明 Provider。两个文件同时存在时,项目配置覆盖全局配置中的同名 Provider 字段。`apiKey` 可以直接填写,或使用环境变量引用:
|
|
469
479
|
|
|
470
480
|
```json
|
|
471
481
|
{
|
|
@@ -499,9 +509,9 @@ $env:DI_CODE_MODEL = "company-coder"
|
|
|
499
509
|
di-code "总结当前项目"
|
|
500
510
|
```
|
|
501
511
|
|
|
502
|
-
`api` 可为 `openai-responses`、`
|
|
512
|
+
`api` 可为 `openai-responses`、`openai-chat-completions` 或 `anthropic-messages`。自定义 Provider 必须提供 `models`;每个模型可设置 `id`、`name`、`input`、`reasoning`、`contextWindow`、`maxTokens`(或 `maxOutputTokens`)及按美元/百万 token 计的 `cost`。Chat Completions 模型还可声明 `chatCompletionsCompat`,用于 DeepSeek/GLM 的 thinking、reasoning_effort、`max_tokens`、流式 usage 和 `tool_stream` 等兼容差异。
|
|
503
513
|
|
|
504
|
-
`apiKey`
|
|
514
|
+
`apiKey` 支持直接字符串,也支持 `$NAME` 或 `${NAME}` 环境变量引用。项目级 `settings.json` 若含明文 key,必须保持未提交;`baseUrl` 必须是绝对 `http`/`https` URL。
|
|
505
515
|
|
|
506
516
|
## 脚本和 RPC 集成
|
|
507
517
|
|
|
@@ -548,7 +558,7 @@ import { RpcClient, RPC_PROTOCOL_VERSION } from "@di-code/coding-agent/rpc";
|
|
|
548
558
|
## 安全边界与故障排查
|
|
549
559
|
|
|
550
560
|
- 在可信项目根目录运行;`bash` 不是沙箱,插件也没有沙箱。
|
|
551
|
-
- API key
|
|
561
|
+
- 向导会将输入的 API key 保存到用户全局 `~/.di-code/settings.json`;不要放入 prompt、Skill、插件源码、会话、图片、项目配置或 Git。
|
|
552
562
|
- 项目 Skill 与插件默认不加载,直到执行 `--trust-project`;该开关是“是否导入项目本地代码/指令”的决定,不会赋予额外系统权限。
|
|
553
563
|
- Provider、模型、图片、配置和工具参数都会校验;外部项目内容和模型输出仍应视作不可信输入。
|
|
554
564
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-builder.d.ts","sourceRoot":"","sources":["../../src/core/context-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAe,MAAM,aAAa,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAA4C,MAAM,oBAAoB,CAAC;AAEjG,MAAM,WAAW,mBAAmB;IACnC,QAAQ,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAC;IACtC,QAAQ,CAAC,cAAc,EAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;CACpD;
|
|
1
|
+
{"version":3,"file":"context-builder.d.ts","sourceRoot":"","sources":["../../src/core/context-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAe,MAAM,aAAa,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAA4C,MAAM,oBAAoB,CAAC;AAEjG,MAAM,WAAW,mBAAmB;IACnC,QAAQ,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAC;IACtC,QAAQ,CAAC,cAAc,EAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;CACpD;AA2BD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,mBAAmB,CAkCzF"}
|
|
@@ -13,6 +13,10 @@ function createSummaryMessage(entry) {
|
|
|
13
13
|
function messageEntries(entries) {
|
|
14
14
|
return entries.filter((entry) => entry.type === "message");
|
|
15
15
|
}
|
|
16
|
+
function contextMessageEntries(entries) {
|
|
17
|
+
return messageEntries(entries).filter((entry) => entry.message.role !== "assistant" ||
|
|
18
|
+
(entry.message.stopReason !== "error" && entry.message.stopReason !== "aborted"));
|
|
19
|
+
}
|
|
16
20
|
export function buildSessionContext(entries) {
|
|
17
21
|
const snapshot = structuredClone([...entries]);
|
|
18
22
|
let summaryIndex = -1;
|
|
@@ -23,7 +27,7 @@ export function buildSessionContext(entries) {
|
|
|
23
27
|
}
|
|
24
28
|
}
|
|
25
29
|
if (summaryIndex < 0) {
|
|
26
|
-
const messages =
|
|
30
|
+
const messages = contextMessageEntries(snapshot);
|
|
27
31
|
return {
|
|
28
32
|
messages: messages.map((entry) => entry.message),
|
|
29
33
|
sourceEntryIds: messages.map((entry) => entry.id),
|
|
@@ -37,7 +41,7 @@ export function buildSessionContext(entries) {
|
|
|
37
41
|
if (firstKeptIndex < 0) {
|
|
38
42
|
throw new Error("Summary firstKeptEntryId must reference an earlier message entry.");
|
|
39
43
|
}
|
|
40
|
-
const keptEntries =
|
|
44
|
+
const keptEntries = contextMessageEntries(snapshot.slice(firstKeptIndex));
|
|
41
45
|
return {
|
|
42
46
|
messages: [createSummaryMessage(summary), ...keptEntries.map((entry) => entry.message)],
|
|
43
47
|
sourceEntryIds: [null, ...keptEntries.map((entry) => entry.id)],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-builder.js","sourceRoot":"","sources":["../../src/core/context-builder.ts"],"names":[],"mappings":"AAQA,SAAS,oBAAoB,CAAC,KAA0B;IACvD,OAAO;QACN,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE;YACR;gBACC,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,2BAA2B,KAAK,CAAC,OAAO,2BAA2B;aACzE;SACD;QACD,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC;KACtC,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,OAAgC;IACvD,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAgC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;AAC1F,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,OAAgC;IACnE,MAAM,QAAQ,GAAG,eAAe,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAC/C,IAAI,YAAY,GAAG,CAAC,CAAC,CAAC;IACtB,KAAK,IAAI,KAAK,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;QAC3D,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE,IAAI,KAAK,SAAS,EAAE,CAAC;YACzC,YAAY,GAAG,KAAK,CAAC;YACrB,MAAM;QACP,CAAC;IACF,CAAC;IAED,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,QAAQ,GAAG,
|
|
1
|
+
{"version":3,"file":"context-builder.js","sourceRoot":"","sources":["../../src/core/context-builder.ts"],"names":[],"mappings":"AAQA,SAAS,oBAAoB,CAAC,KAA0B;IACvD,OAAO;QACN,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE;YACR;gBACC,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,2BAA2B,KAAK,CAAC,OAAO,2BAA2B;aACzE;SACD;QACD,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC;KACtC,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,OAAgC;IACvD,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAgC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;AAC1F,CAAC;AAED,SAAS,qBAAqB,CAAC,OAAgC;IAC9D,OAAO,cAAc,CAAC,OAAO,CAAC,CAAC,MAAM,CACpC,CAAC,KAAK,EAAE,EAAE,CACT,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,WAAW;QAClC,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,KAAK,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,KAAK,SAAS,CAAC,CACjF,CAAC;AACH,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,OAAgC;IACnE,MAAM,QAAQ,GAAG,eAAe,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAC/C,IAAI,YAAY,GAAG,CAAC,CAAC,CAAC;IACtB,KAAK,IAAI,KAAK,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;QAC3D,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE,IAAI,KAAK,SAAS,EAAE,CAAC;YACzC,YAAY,GAAG,KAAK,CAAC;YACrB,MAAM;QACP,CAAC;IACF,CAAC;IAED,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,QAAQ,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC;QACjD,OAAO;YACN,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC;YAChD,cAAc,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;SACjD,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;IACvC,IAAI,OAAO,EAAE,IAAI,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IAChE,CAAC;IACD,MAAM,cAAc,GAAG,QAAQ,CAAC,SAAS,CACxC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,YAAY,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,EAAE,KAAK,OAAO,CAAC,gBAAgB,CAC3G,CAAC;IACF,IAAI,cAAc,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAC;IACtF,CAAC;IAED,MAAM,WAAW,GAAG,qBAAqB,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;IAC1E,OAAO;QACN,QAAQ,EAAE,CAAC,oBAAoB,CAAC,OAAO,CAAC,EAAE,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACvF,cAAc,EAAE,CAAC,IAAI,EAAE,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;KAC/D,CAAC;AACH,CAAC","sourcesContent":["import type { Message, UserMessage } from \"@di-code/ai\";\nimport type { SessionEntry, SessionMessageEntry, SessionSummaryEntry } from \"./session/types.ts\";\n\nexport interface BuiltSessionContext {\n\treadonly messages: readonly Message[];\n\treadonly sourceEntryIds: readonly (string | null)[];\n}\n\nfunction createSummaryMessage(entry: SessionSummaryEntry): UserMessage {\n\treturn {\n\t\trole: \"user\",\n\t\tcontent: [\n\t\t\t{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: `<conversation-summary>\\n${entry.summary}\\n</conversation-summary>`,\n\t\t\t},\n\t\t],\n\t\ttimestamp: Date.parse(entry.timestamp),\n\t};\n}\n\nfunction messageEntries(entries: readonly SessionEntry[]): SessionMessageEntry[] {\n\treturn entries.filter((entry): entry is SessionMessageEntry => entry.type === \"message\");\n}\n\nfunction contextMessageEntries(entries: readonly SessionEntry[]): SessionMessageEntry[] {\n\treturn messageEntries(entries).filter(\n\t\t(entry) =>\n\t\t\tentry.message.role !== \"assistant\" ||\n\t\t\t(entry.message.stopReason !== \"error\" && entry.message.stopReason !== \"aborted\"),\n\t);\n}\n\nexport function buildSessionContext(entries: readonly SessionEntry[]): BuiltSessionContext {\n\tconst snapshot = structuredClone([...entries]);\n\tlet summaryIndex = -1;\n\tfor (let index = snapshot.length - 1; index >= 0; index--) {\n\t\tif (snapshot[index]?.type === \"summary\") {\n\t\t\tsummaryIndex = index;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (summaryIndex < 0) {\n\t\tconst messages = contextMessageEntries(snapshot);\n\t\treturn {\n\t\t\tmessages: messages.map((entry) => entry.message),\n\t\t\tsourceEntryIds: messages.map((entry) => entry.id),\n\t\t};\n\t}\n\n\tconst summary = snapshot[summaryIndex];\n\tif (summary?.type !== \"summary\") {\n\t\tthrow new Error(\"Latest summary entry could not be resolved.\");\n\t}\n\tconst firstKeptIndex = snapshot.findIndex(\n\t\t(entry, index) => index < summaryIndex && entry.type === \"message\" && entry.id === summary.firstKeptEntryId,\n\t);\n\tif (firstKeptIndex < 0) {\n\t\tthrow new Error(\"Summary firstKeptEntryId must reference an earlier message entry.\");\n\t}\n\n\tconst keptEntries = contextMessageEntries(snapshot.slice(firstKeptIndex));\n\treturn {\n\t\tmessages: [createSummaryMessage(summary), ...keptEntries.map((entry) => entry.message)],\n\t\tsourceEntryIds: [null, ...keptEntries.map((entry) => entry.id)],\n\t};\n}\n"]}
|
|
@@ -5,7 +5,7 @@ export declare const MAX_IMAGE_INPUT_BYTES: number;
|
|
|
5
5
|
export declare function imageContentFromBytes(data: Uint8Array, source: string): ImageContent;
|
|
6
6
|
/** Reads explicitly requested local image files into the provider-neutral user-message format. */
|
|
7
7
|
export declare function loadImageInputs(paths: readonly string[], cwd: string): Promise<ImageContent[]>;
|
|
8
|
-
/** Extracts @path
|
|
8
|
+
/** Extracts @path references into image attachments or bounded text blocks for the model prompt. */
|
|
9
9
|
export declare function extractImageAttachments(text: string, cwd: string): Promise<{
|
|
10
10
|
text: string;
|
|
11
11
|
images: ImageContent[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image-input.d.ts","sourceRoot":"","sources":["../../src/core/image-input.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"image-input.d.ts","sourceRoot":"","sources":["../../src/core/image-input.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAIhD,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,eAAO,MAAM,qBAAqB,QAAkB,CAAC;AAwCrD,iFAAiF;AACjF,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,YAAY,CAOpF;AAyDD,kGAAkG;AAClG,wBAAsB,eAAe,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAKpG;AAUD,oGAAoG;AACpG,wBAAsB,uBAAuB,CAC5C,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,GACT,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,YAAY,EAAE,CAAA;CAAE,CAAC,CA8BnD"}
|
package/dist/core/image-input.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { readFile, stat } from "node:fs/promises";
|
|
2
|
-
import { basename, resolve } from "node:path";
|
|
2
|
+
import { basename, isAbsolute, relative, resolve } from "node:path";
|
|
3
|
+
import { resolveAllowedFilePath } from "./tools/path-boundary.js";
|
|
4
|
+
import { DEFAULT_READ_MAX_BYTES, DEFAULT_READ_MAX_LINES } from "./tools/read.js";
|
|
3
5
|
export const MAX_IMAGE_INPUTS = 4;
|
|
4
6
|
export const MAX_IMAGE_INPUT_BYTES = 5 * 1024 * 1024;
|
|
5
7
|
const IMAGE_REFERENCE = /(^|\s)@(?:"([^"\r\n]+)"|'([^'\r\n]+)'|([^\s@]+))/g;
|
|
@@ -58,6 +60,42 @@ async function loadImageInput(path, cwd) {
|
|
|
58
60
|
}
|
|
59
61
|
return imageContentFromBytes(data, path);
|
|
60
62
|
}
|
|
63
|
+
function containsNulByte(data) {
|
|
64
|
+
for (const byte of data)
|
|
65
|
+
if (byte === 0)
|
|
66
|
+
return true;
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
function escapeFileName(path) {
|
|
70
|
+
return path.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """);
|
|
71
|
+
}
|
|
72
|
+
function relativeAttachmentPath(path, cwd) {
|
|
73
|
+
const absolutePath = resolve(cwd, path);
|
|
74
|
+
const relativePath = relative(resolve(cwd), absolutePath).replaceAll("\\", "/");
|
|
75
|
+
return relativePath || basename(absolutePath);
|
|
76
|
+
}
|
|
77
|
+
async function loadTextAttachment(path, cwd) {
|
|
78
|
+
const absolutePath = await resolveAllowedFilePath(path, cwd);
|
|
79
|
+
const metadata = await stat(absolutePath);
|
|
80
|
+
if (!metadata.isFile())
|
|
81
|
+
throw new Error(`File attachment is not a regular file: ${displayPath(path)}`);
|
|
82
|
+
if (metadata.size > DEFAULT_READ_MAX_BYTES) {
|
|
83
|
+
throw new Error(`Text attachment exceeds the 50 KiB limit: ${displayPath(path)}`);
|
|
84
|
+
}
|
|
85
|
+
const data = await readFile(absolutePath);
|
|
86
|
+
if (data.length > DEFAULT_READ_MAX_BYTES) {
|
|
87
|
+
throw new Error(`Text attachment exceeds the 50 KiB limit: ${displayPath(path)}`);
|
|
88
|
+
}
|
|
89
|
+
if (containsNulByte(data))
|
|
90
|
+
throw new Error(`Binary files are not supported by @ attachments: ${displayPath(path)}`);
|
|
91
|
+
const normalized = data.toString("utf8").replace(/\r\n?/g, "\n");
|
|
92
|
+
const lines = normalized.split("\n");
|
|
93
|
+
const content = lines.length > DEFAULT_READ_MAX_LINES
|
|
94
|
+
? `${lines.slice(0, DEFAULT_READ_MAX_LINES).join("\n")}\n\n[File truncated after ${DEFAULT_READ_MAX_LINES} lines.]`
|
|
95
|
+
: normalized;
|
|
96
|
+
const fileName = escapeFileName(relativeAttachmentPath(path, cwd));
|
|
97
|
+
return `<file name="${fileName}">\n${content}\n</file>`;
|
|
98
|
+
}
|
|
61
99
|
/** Reads explicitly requested local image files into the provider-neutral user-message format. */
|
|
62
100
|
export async function loadImageInputs(paths, cwd) {
|
|
63
101
|
if (paths.length > MAX_IMAGE_INPUTS) {
|
|
@@ -68,10 +106,13 @@ export async function loadImageInputs(paths, cwd) {
|
|
|
68
106
|
function isMissingFileError(cause) {
|
|
69
107
|
return cause instanceof Error && "code" in cause && cause.code === "ENOENT";
|
|
70
108
|
}
|
|
71
|
-
|
|
109
|
+
function isUnsupportedImageError(cause) {
|
|
110
|
+
return cause instanceof Error && cause.message.startsWith("Unsupported image format:");
|
|
111
|
+
}
|
|
112
|
+
/** Extracts @path references into image attachments or bounded text blocks for the model prompt. */
|
|
72
113
|
export async function extractImageAttachments(text, cwd) {
|
|
73
114
|
const images = [];
|
|
74
|
-
const
|
|
115
|
+
const attachments = [];
|
|
75
116
|
let result = "";
|
|
76
117
|
let cursor = 0;
|
|
77
118
|
for (const match of text.matchAll(IMAGE_REFERENCE)) {
|
|
@@ -80,23 +121,27 @@ export async function extractImageAttachments(text, cwd) {
|
|
|
80
121
|
const path = match[2] ?? match[3] ?? match[4] ?? "";
|
|
81
122
|
result += `${text.slice(cursor, index)}${leading}`;
|
|
82
123
|
cursor = index + match[0].length;
|
|
83
|
-
if (images.length >= MAX_IMAGE_INPUTS) {
|
|
84
|
-
throw new Error(`At most ${MAX_IMAGE_INPUTS} images can be attached to one prompt.`);
|
|
85
|
-
}
|
|
86
124
|
try {
|
|
125
|
+
if (!isAbsolute(path))
|
|
126
|
+
await resolveAllowedFilePath(path, cwd);
|
|
87
127
|
const [image] = await loadImageInputs([path], cwd);
|
|
88
128
|
if (!image)
|
|
89
129
|
throw new Error("Image attachment was not loaded.");
|
|
130
|
+
if (images.length >= MAX_IMAGE_INPUTS) {
|
|
131
|
+
throw new Error(`At most ${MAX_IMAGE_INPUTS} images can be attached to one prompt.`);
|
|
132
|
+
}
|
|
90
133
|
images.push(image);
|
|
91
|
-
|
|
134
|
+
attachments.push(`[Attached image: ${basename(path)}]`);
|
|
92
135
|
}
|
|
93
136
|
catch (cause) {
|
|
94
137
|
if (isMissingFileError(cause))
|
|
95
|
-
throw new Error(`
|
|
96
|
-
|
|
138
|
+
throw new Error(`File attachment was not found: ${path}`);
|
|
139
|
+
if (!isUnsupportedImageError(cause))
|
|
140
|
+
throw cause;
|
|
141
|
+
attachments.push(await loadTextAttachment(path, cwd));
|
|
97
142
|
}
|
|
98
143
|
}
|
|
99
144
|
const prompt = `${result}${text.slice(cursor)}`.replace(/[ \t]{2,}/g, " ").trim();
|
|
100
|
-
return { text: [...
|
|
145
|
+
return { text: [...attachments, prompt].filter((value) => value.length > 0).join("\n"), images };
|
|
101
146
|
}
|
|
102
147
|
//# sourceMappingURL=image-input.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image-input.js","sourceRoot":"","sources":["../../src/core/image-input.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFile, stat } from \"node:fs/promises\";\nimport { basename, resolve } from \"node:path\";\nimport type { ImageContent } from \"@di-code/ai\";\n\nexport const MAX_IMAGE_INPUTS = 4;\nexport const MAX_IMAGE_INPUT_BYTES = 5 * 1024 * 1024;\n\nconst IMAGE_REFERENCE = /(^|\\s)@(?:\"([^\"\\r\\n]+)\"|'([^'\\r\\n]+)'|([^\\s@]+))/g;\n\nfunction detectImageMimeType(data: Uint8Array): ImageContent[\"mimeType\"] | undefined {\n\tif (\n\t\tdata.length >= 8 &&\n\t\tdata[0] === 137 &&\n\t\tdata[1] === 80 &&\n\t\tdata[2] === 78 &&\n\t\tdata[3] === 71 &&\n\t\tdata[4] === 13 &&\n\t\tdata[5] === 10 &&\n\t\tdata[6] === 26 &&\n\t\tdata[7] === 10\n\t) {\n\t\treturn \"image/png\";\n\t}\n\tif (data.length >= 3 && data[0] === 255 && data[1] === 216 && data[2] === 255) return \"image/jpeg\";\n\tif (\n\t\tdata.length >= 6 &&\n\t\t(Buffer.from(data.subarray(0, 6)).equals(Buffer.from(\"GIF87a\")) ||\n\t\t\tBuffer.from(data.subarray(0, 6)).equals(Buffer.from(\"GIF89a\")))\n\t) {\n\t\treturn \"image/gif\";\n\t}\n\tif (\n\t\tdata.length >= 12 &&\n\t\tBuffer.from(data.subarray(0, 4)).equals(Buffer.from(\"RIFF\")) &&\n\t\tBuffer.from(data.subarray(8, 12)).equals(Buffer.from(\"WEBP\"))\n\t) {\n\t\treturn \"image/webp\";\n\t}\n\treturn undefined;\n}\n\nfunction displayPath(path: string): string {\n\treturn path.trim() || \"<empty path>\";\n}\n\n/** Converts already-read bytes into validated provider-neutral image content. */\nexport function imageContentFromBytes(data: Uint8Array, source: string): ImageContent {\n\tif (data.byteLength > MAX_IMAGE_INPUT_BYTES) {\n\t\tthrow new Error(`Image exceeds the 5 MiB limit: ${displayPath(source)}`);\n\t}\n\tconst mimeType = detectImageMimeType(data);\n\tif (!mimeType) throw new Error(`Unsupported image format: ${displayPath(source)}`);\n\treturn { type: \"image\", data: Buffer.from(data).toString(\"base64\"), mimeType };\n}\n\nasync function loadImageInput(path: string, cwd: string): Promise<ImageContent> {\n\tif (path.trim().length === 0) throw new Error(\"Image path must not be empty.\");\n\tconst absolutePath = resolve(cwd, path);\n\tconst metadata = await stat(absolutePath);\n\tif (!metadata.isFile()) throw new Error(`Image path is not a regular file: ${displayPath(path)}`);\n\tif (metadata.size > MAX_IMAGE_INPUT_BYTES) {\n\t\tthrow new Error(`Image exceeds the 5 MiB limit: ${displayPath(path)}`);\n\t}\n\n\tconst data = await readFile(absolutePath);\n\tif (data.length > MAX_IMAGE_INPUT_BYTES) {\n\t\tthrow new Error(`Image exceeds the 5 MiB limit: ${displayPath(path)}`);\n\t}\n\treturn imageContentFromBytes(data, path);\n}\n\n/** Reads explicitly requested local image files into the provider-neutral user-message format. */\nexport async function loadImageInputs(paths: readonly string[], cwd: string): Promise<ImageContent[]> {\n\tif (paths.length > MAX_IMAGE_INPUTS) {\n\t\tthrow new Error(`At most ${MAX_IMAGE_INPUTS} images can be attached to one prompt.`);\n\t}\n\treturn Promise.all(paths.map((path) => loadImageInput(path, cwd)));\n}\n\nfunction isMissingFileError(cause: unknown): boolean {\n\treturn cause instanceof Error && \"code\" in cause && cause.code === \"ENOENT\";\n}\n\n/** Extracts @path image references while preserving a concise attachment label in the model prompt. */\nexport async function extractImageAttachments(\n\ttext: string,\n\tcwd: string,\n): Promise<{ text: string; images: ImageContent[] }> {\n\tconst images: ImageContent[] = [];\n\tconst labels: string[] = [];\n\tlet result = \"\";\n\tlet cursor = 0;\n\n\tfor (const match of text.matchAll(IMAGE_REFERENCE)) {\n\t\tconst index = match.index ?? 0;\n\t\tconst leading = match[1] ?? \"\";\n\t\tconst path = match[2] ?? match[3] ?? match[4] ?? \"\";\n\t\tresult += `${text.slice(cursor, index)}${leading}`;\n\t\tcursor = index + match[0].length;\n\t\tif (images.length >= MAX_IMAGE_INPUTS) {\n\t\t\tthrow new Error(`At most ${MAX_IMAGE_INPUTS} images can be attached to one prompt.`);\n\t\t}\n\t\ttry {\n\t\t\tconst [image] = await loadImageInputs([path], cwd);\n\t\t\tif (!image) throw new Error(\"Image attachment was not loaded.\");\n\t\t\timages.push(image);\n\t\t\tlabels.push(`[Attached image: ${basename(path)}]`);\n\t\t} catch (cause) {\n\t\t\tif (isMissingFileError(cause)) throw new Error(`Image attachment was not found: ${path}`);\n\t\t\tthrow cause;\n\t\t}\n\t}\n\n\tconst prompt = `${result}${text.slice(cursor)}`.replace(/[ \\t]{2,}/g, \" \").trim();\n\treturn { text: [...labels, prompt].filter((value) => value.length > 0).join(\"\\n\"), images };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"image-input.js","sourceRoot":"","sources":["../../src/core/image-input.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFile, stat } from \"node:fs/promises\";\nimport { basename, isAbsolute, relative, resolve } from \"node:path\";\nimport type { ImageContent } from \"@di-code/ai\";\nimport { resolveAllowedFilePath } from \"./tools/path-boundary.ts\";\nimport { DEFAULT_READ_MAX_BYTES, DEFAULT_READ_MAX_LINES } from \"./tools/read.ts\";\n\nexport const MAX_IMAGE_INPUTS = 4;\nexport const MAX_IMAGE_INPUT_BYTES = 5 * 1024 * 1024;\n\nconst IMAGE_REFERENCE = /(^|\\s)@(?:\"([^\"\\r\\n]+)\"|'([^'\\r\\n]+)'|([^\\s@]+))/g;\n\nfunction detectImageMimeType(data: Uint8Array): ImageContent[\"mimeType\"] | undefined {\n\tif (\n\t\tdata.length >= 8 &&\n\t\tdata[0] === 137 &&\n\t\tdata[1] === 80 &&\n\t\tdata[2] === 78 &&\n\t\tdata[3] === 71 &&\n\t\tdata[4] === 13 &&\n\t\tdata[5] === 10 &&\n\t\tdata[6] === 26 &&\n\t\tdata[7] === 10\n\t) {\n\t\treturn \"image/png\";\n\t}\n\tif (data.length >= 3 && data[0] === 255 && data[1] === 216 && data[2] === 255) return \"image/jpeg\";\n\tif (\n\t\tdata.length >= 6 &&\n\t\t(Buffer.from(data.subarray(0, 6)).equals(Buffer.from(\"GIF87a\")) ||\n\t\t\tBuffer.from(data.subarray(0, 6)).equals(Buffer.from(\"GIF89a\")))\n\t) {\n\t\treturn \"image/gif\";\n\t}\n\tif (\n\t\tdata.length >= 12 &&\n\t\tBuffer.from(data.subarray(0, 4)).equals(Buffer.from(\"RIFF\")) &&\n\t\tBuffer.from(data.subarray(8, 12)).equals(Buffer.from(\"WEBP\"))\n\t) {\n\t\treturn \"image/webp\";\n\t}\n\treturn undefined;\n}\n\nfunction displayPath(path: string): string {\n\treturn path.trim() || \"<empty path>\";\n}\n\n/** Converts already-read bytes into validated provider-neutral image content. */\nexport function imageContentFromBytes(data: Uint8Array, source: string): ImageContent {\n\tif (data.byteLength > MAX_IMAGE_INPUT_BYTES) {\n\t\tthrow new Error(`Image exceeds the 5 MiB limit: ${displayPath(source)}`);\n\t}\n\tconst mimeType = detectImageMimeType(data);\n\tif (!mimeType) throw new Error(`Unsupported image format: ${displayPath(source)}`);\n\treturn { type: \"image\", data: Buffer.from(data).toString(\"base64\"), mimeType };\n}\n\nasync function loadImageInput(path: string, cwd: string): Promise<ImageContent> {\n\tif (path.trim().length === 0) throw new Error(\"Image path must not be empty.\");\n\tconst absolutePath = resolve(cwd, path);\n\tconst metadata = await stat(absolutePath);\n\tif (!metadata.isFile()) throw new Error(`Image path is not a regular file: ${displayPath(path)}`);\n\tif (metadata.size > MAX_IMAGE_INPUT_BYTES) {\n\t\tthrow new Error(`Image exceeds the 5 MiB limit: ${displayPath(path)}`);\n\t}\n\n\tconst data = await readFile(absolutePath);\n\tif (data.length > MAX_IMAGE_INPUT_BYTES) {\n\t\tthrow new Error(`Image exceeds the 5 MiB limit: ${displayPath(path)}`);\n\t}\n\treturn imageContentFromBytes(data, path);\n}\n\nfunction containsNulByte(data: Uint8Array): boolean {\n\tfor (const byte of data) if (byte === 0) return true;\n\treturn false;\n}\n\nfunction escapeFileName(path: string): string {\n\treturn path.replaceAll(\"&\", \"&\").replaceAll(\"<\", \"<\").replaceAll(\">\", \">\").replaceAll('\"', \""\");\n}\n\nfunction relativeAttachmentPath(path: string, cwd: string): string {\n\tconst absolutePath = resolve(cwd, path);\n\tconst relativePath = relative(resolve(cwd), absolutePath).replaceAll(\"\\\\\", \"/\");\n\treturn relativePath || basename(absolutePath);\n}\n\nasync function loadTextAttachment(path: string, cwd: string): Promise<string> {\n\tconst absolutePath = await resolveAllowedFilePath(path, cwd);\n\tconst metadata = await stat(absolutePath);\n\tif (!metadata.isFile()) throw new Error(`File attachment is not a regular file: ${displayPath(path)}`);\n\tif (metadata.size > DEFAULT_READ_MAX_BYTES) {\n\t\tthrow new Error(`Text attachment exceeds the 50 KiB limit: ${displayPath(path)}`);\n\t}\n\n\tconst data = await readFile(absolutePath);\n\tif (data.length > DEFAULT_READ_MAX_BYTES) {\n\t\tthrow new Error(`Text attachment exceeds the 50 KiB limit: ${displayPath(path)}`);\n\t}\n\tif (containsNulByte(data)) throw new Error(`Binary files are not supported by @ attachments: ${displayPath(path)}`);\n\n\tconst normalized = data.toString(\"utf8\").replace(/\\r\\n?/g, \"\\n\");\n\tconst lines = normalized.split(\"\\n\");\n\tconst content =\n\t\tlines.length > DEFAULT_READ_MAX_LINES\n\t\t\t? `${lines.slice(0, DEFAULT_READ_MAX_LINES).join(\"\\n\")}\\n\\n[File truncated after ${DEFAULT_READ_MAX_LINES} lines.]`\n\t\t\t: normalized;\n\tconst fileName = escapeFileName(relativeAttachmentPath(path, cwd));\n\treturn `<file name=\"${fileName}\">\\n${content}\\n</file>`;\n}\n\n/** Reads explicitly requested local image files into the provider-neutral user-message format. */\nexport async function loadImageInputs(paths: readonly string[], cwd: string): Promise<ImageContent[]> {\n\tif (paths.length > MAX_IMAGE_INPUTS) {\n\t\tthrow new Error(`At most ${MAX_IMAGE_INPUTS} images can be attached to one prompt.`);\n\t}\n\treturn Promise.all(paths.map((path) => loadImageInput(path, cwd)));\n}\n\nfunction isMissingFileError(cause: unknown): boolean {\n\treturn cause instanceof Error && \"code\" in cause && cause.code === \"ENOENT\";\n}\n\nfunction isUnsupportedImageError(cause: unknown): boolean {\n\treturn cause instanceof Error && cause.message.startsWith(\"Unsupported image format:\");\n}\n\n/** Extracts @path references into image attachments or bounded text blocks for the model prompt. */\nexport async function extractImageAttachments(\n\ttext: string,\n\tcwd: string,\n): Promise<{ text: string; images: ImageContent[] }> {\n\tconst images: ImageContent[] = [];\n\tconst attachments: string[] = [];\n\tlet result = \"\";\n\tlet cursor = 0;\n\n\tfor (const match of text.matchAll(IMAGE_REFERENCE)) {\n\t\tconst index = match.index ?? 0;\n\t\tconst leading = match[1] ?? \"\";\n\t\tconst path = match[2] ?? match[3] ?? match[4] ?? \"\";\n\t\tresult += `${text.slice(cursor, index)}${leading}`;\n\t\tcursor = index + match[0].length;\n\t\ttry {\n\t\t\tif (!isAbsolute(path)) await resolveAllowedFilePath(path, cwd);\n\t\t\tconst [image] = await loadImageInputs([path], cwd);\n\t\t\tif (!image) throw new Error(\"Image attachment was not loaded.\");\n\t\t\tif (images.length >= MAX_IMAGE_INPUTS) {\n\t\t\t\tthrow new Error(`At most ${MAX_IMAGE_INPUTS} images can be attached to one prompt.`);\n\t\t\t}\n\t\t\timages.push(image);\n\t\t\tattachments.push(`[Attached image: ${basename(path)}]`);\n\t\t} catch (cause) {\n\t\t\tif (isMissingFileError(cause)) throw new Error(`File attachment was not found: ${path}`);\n\t\t\tif (!isUnsupportedImageError(cause)) throw cause;\n\t\t\tattachments.push(await loadTextAttachment(path, cwd));\n\t\t}\n\t}\n\n\tconst prompt = `${result}${text.slice(cursor)}`.replace(/[ \\t]{2,}/g, \" \").trim();\n\treturn { text: [...attachments, prompt].filter((value) => value.length > 0).join(\"\\n\"), images };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-storage.d.ts","sourceRoot":"","sources":["../../../src/core/session/session-storage.ts"],"names":[],"mappings":"AAGA,OAAO,EACN,KAAK,aAAa,EAElB,KAAK,YAAY,EACjB,KAAK,aAAa,EAKlB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"session-storage.d.ts","sourceRoot":"","sources":["../../../src/core/session/session-storage.ts"],"names":[],"mappings":"AAGA,OAAO,EACN,KAAK,aAAa,EAElB,KAAK,YAAY,EACjB,KAAK,aAAa,EAKlB,MAAM,YAAY,CAAC;AA6MpB,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CA+E9E;AAED,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACzD;AAaD,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAiB9F;AA8CD,wBAAsB,kBAAkB,CACvC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,YAAY,EACnB,gBAAgB,EAAE,MAAM,EACxB,OAAO,GAAE,oBAAyB,GAChC,OAAO,CAAC,IAAI,CAAC,CAkFf"}
|
|
@@ -112,6 +112,7 @@ function isMessage(value) {
|
|
|
112
112
|
isNonEmptyString(value.toolName) &&
|
|
113
113
|
Array.isArray(value.content) &&
|
|
114
114
|
value.content.every(isToolResultContent) &&
|
|
115
|
+
(value.details === undefined || isJsonValue(value.details)) &&
|
|
115
116
|
typeof value.isError === "boolean");
|
|
116
117
|
default:
|
|
117
118
|
return false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-storage.js","sourceRoot":"","sources":["../../../src/core/session/session-storage.ts"],"names":[],"mappings":"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","sourcesContent":["import { appendFile, mkdir, open, readFile, unlink } from \"node:fs/promises\";\nimport { dirname, posix, win32 } from \"node:path\";\nimport type { AssistantContent, AssistantMessage, Message, ToolResultContent, Usage, UserContent } from \"@di-code/ai\";\nimport {\n\ttype LoadedSession,\n\tSESSION_FORMAT_VERSION,\n\ttype SessionEntry,\n\ttype SessionHeader,\n\tSessionLoadError,\n\ttype SessionMessageEntry,\n\ttype SessionSummaryEntry,\n\tSessionWriteError,\n} from \"./types.ts\";\n\ntype JsonObject = Record<string, unknown>;\n\nfunction isObject(value: unknown): value is JsonObject {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n\treturn typeof value === \"string\" && value.length > 0;\n}\n\nfunction isNonNegativeNumber(value: unknown): value is number {\n\treturn typeof value === \"number\" && Number.isFinite(value) && value >= 0;\n}\n\nfunction isTimestamp(value: unknown): value is number {\n\treturn Number.isSafeInteger(value) && isNonNegativeNumber(value);\n}\n\nfunction isIsoTimestamp(value: unknown): value is string {\n\tif (typeof value !== \"string\") return false;\n\tconst milliseconds = Date.parse(value);\n\treturn Number.isFinite(milliseconds) && new Date(milliseconds).toISOString() === value;\n}\n\nfunction isRecordId(value: unknown): value is string {\n\treturn typeof value === \"string\" && /^[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?$/.test(value);\n}\n\nfunction isAbsolutePath(value: unknown): value is string {\n\treturn typeof value === \"string\" && (win32.isAbsolute(value) || posix.isAbsolute(value));\n}\n\nfunction isJsonValue(value: unknown): boolean {\n\tif (value === null || typeof value === \"string\" || typeof value === \"boolean\") return true;\n\tif (typeof value === \"number\") return Number.isFinite(value);\n\tif (Array.isArray(value)) return value.every(isJsonValue);\n\treturn isObject(value) && Object.values(value).every(isJsonValue);\n}\n\nfunction isProviderReplay(value: unknown): boolean {\n\treturn isObject(value) && isNonEmptyString(value.api) && isJsonValue(value.data);\n}\n\nfunction isImageContent(value: unknown): value is Extract<UserContent | ToolResultContent, { type: \"image\" }> {\n\treturn (\n\t\tisObject(value) && value.type === \"image\" && typeof value.data === \"string\" && isNonEmptyString(value.mimeType)\n\t);\n}\n\nfunction isTextContent(value: unknown): value is Extract<UserContent, { type: \"text\" }> {\n\treturn isObject(value) && value.type === \"text\" && typeof value.text === \"string\";\n}\n\nfunction isUserContent(value: unknown): value is UserContent {\n\treturn isTextContent(value) || isImageContent(value);\n}\n\nfunction isAssistantContent(value: unknown): value is AssistantContent {\n\tif (!isObject(value)) return false;\n\tswitch (value.type) {\n\t\tcase \"text\":\n\t\t\treturn typeof value.text === \"string\";\n\t\tcase \"thinking\":\n\t\t\treturn typeof value.thinking === \"string\";\n\t\tcase \"tool_call\":\n\t\t\treturn (\n\t\t\t\tisNonEmptyString(value.id) &&\n\t\t\t\tisNonEmptyString(value.name) &&\n\t\t\t\tisObject(value.arguments) &&\n\t\t\t\tisJsonValue(value.arguments)\n\t\t\t);\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\nfunction isToolResultContent(value: unknown): value is ToolResultContent {\n\treturn isTextContent(value) || isImageContent(value);\n}\n\nfunction isUsage(value: unknown): value is Usage {\n\tif (!isObject(value) || !isObject(value.cost)) return false;\n\treturn (\n\t\tisNonNegativeNumber(value.input) &&\n\t\tisNonNegativeNumber(value.output) &&\n\t\tisNonNegativeNumber(value.cacheRead) &&\n\t\tisNonNegativeNumber(value.cacheWrite) &&\n\t\tisNonNegativeNumber(value.totalTokens) &&\n\t\tisNonNegativeNumber(value.cost.input) &&\n\t\tisNonNegativeNumber(value.cost.output) &&\n\t\tisNonNegativeNumber(value.cost.cacheRead) &&\n\t\tisNonNegativeNumber(value.cost.cacheWrite) &&\n\t\tisNonNegativeNumber(value.cost.total)\n\t);\n}\n\nfunction isAssistantMessage(value: JsonObject): value is JsonObject & AssistantMessage {\n\tif (\n\t\tvalue.role !== \"assistant\" ||\n\t\t!Array.isArray(value.content) ||\n\t\t!value.content.every(isAssistantContent) ||\n\t\t!isNonEmptyString(value.provider) ||\n\t\t!isNonEmptyString(value.model) ||\n\t\t(value.providerReplay !== undefined && !isProviderReplay(value.providerReplay)) ||\n\t\t!isUsage(value.usage) ||\n\t\t!isTimestamp(value.timestamp)\n\t) {\n\t\treturn false;\n\t}\n\n\tif (value.stopReason === \"stop\" || value.stopReason === \"length\" || value.stopReason === \"tool_use\") {\n\t\treturn value.errorMessage === undefined;\n\t}\n\tif (value.stopReason === \"error\" || value.stopReason === \"aborted\") {\n\t\treturn typeof value.errorMessage === \"string\";\n\t}\n\treturn false;\n}\n\nfunction isMessage(value: unknown): value is Message {\n\tif (!isObject(value) || !isTimestamp(value.timestamp)) return false;\n\n\tswitch (value.role) {\n\t\tcase \"user\":\n\t\t\treturn Array.isArray(value.content) && value.content.every(isUserContent);\n\t\tcase \"assistant\":\n\t\t\treturn isAssistantMessage(value);\n\t\tcase \"tool_result\":\n\t\t\treturn (\n\t\t\t\tisNonEmptyString(value.toolCallId) &&\n\t\t\t\tisNonEmptyString(value.toolName) &&\n\t\t\t\tArray.isArray(value.content) &&\n\t\t\t\tvalue.content.every(isToolResultContent) &&\n\t\t\t\ttypeof value.isError === \"boolean\"\n\t\t\t);\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\nfunction decodeHeader(value: unknown, filePath: string): SessionHeader {\n\tif (!isObject(value) || value.type !== \"session\") {\n\t\tthrow new SessionLoadError(\"INVALID_HEADER\", filePath, `Invalid session header in \"${filePath}\".`, {\n\t\t\tlineNumber: 1,\n\t\t});\n\t}\n\tif (!(\"version\" in value)) {\n\t\tthrow new SessionLoadError(\"INVALID_HEADER\", filePath, `Session header has no version in \"${filePath}\".`, {\n\t\t\tlineNumber: 1,\n\t\t});\n\t}\n\tif (value.version !== SESSION_FORMAT_VERSION) {\n\t\tthrow new SessionLoadError(\n\t\t\t\"UNSUPPORTED_VERSION\",\n\t\t\tfilePath,\n\t\t\t`Unsupported session version ${JSON.stringify(value.version)} in \"${filePath}\".`,\n\t\t\t{ lineNumber: 1 },\n\t\t);\n\t}\n\tif (\n\t\t!isRecordId(value.id) ||\n\t\tvalue.parentId !== null ||\n\t\t!isIsoTimestamp(value.timestamp) ||\n\t\t!isAbsolutePath(value.cwd)\n\t) {\n\t\tthrow new SessionLoadError(\"INVALID_HEADER\", filePath, `Invalid session header fields in \"${filePath}\".`, {\n\t\t\tlineNumber: 1,\n\t\t});\n\t}\n\treturn value as unknown as SessionHeader;\n}\n\nfunction decodeSessionEntry(value: unknown): { readonly entry?: SessionEntry; readonly reason?: string } {\n\tif (!isObject(value) || (value.type !== \"message\" && value.type !== \"summary\")) {\n\t\treturn { reason: 'record type must be \"message\" or \"summary\"' };\n\t}\n\tif (value.version !== SESSION_FORMAT_VERSION) return { reason: \"record version must be 1\" };\n\tif (!isRecordId(value.id)) return { reason: \"record id is invalid\" };\n\tif (!isRecordId(value.parentId)) return { reason: \"record parentId is invalid\" };\n\tif (!isIsoTimestamp(value.timestamp)) return { reason: \"record timestamp is not canonical ISO 8601 UTC\" };\n\tif (value.type === \"message\") {\n\t\tif (!isMessage(value.message)) return { reason: \"record message does not match the Message contract\" };\n\t\treturn { entry: value as unknown as SessionMessageEntry };\n\t}\n\tif (typeof value.summary !== \"string\" || value.summary.trim().length === 0) {\n\t\treturn { reason: \"record summary must be a non-empty string\" };\n\t}\n\tif (!isRecordId(value.firstKeptEntryId)) return { reason: \"record firstKeptEntryId is invalid\" };\n\tif (!Number.isSafeInteger(value.tokensBefore) || !isNonNegativeNumber(value.tokensBefore)) {\n\t\treturn { reason: \"record tokensBefore must be a non-negative safe integer\" };\n\t}\n\treturn { entry: value as unknown as SessionSummaryEntry };\n}\n\nfunction withoutTrailingCarriageReturn(line: string): string {\n\treturn line.endsWith(\"\\r\") ? line.slice(0, -1) : line;\n}\n\nfunction errorText(cause: unknown): string {\n\treturn cause instanceof Error ? cause.message : String(cause);\n}\n\nexport async function loadSessionFile(filePath: string): Promise<LoadedSession> {\n\tlet content: string;\n\ttry {\n\t\tcontent = await readFile(filePath, \"utf8\");\n\t} catch (cause) {\n\t\tthrow new SessionLoadError(\"READ_FAILED\", filePath, `Failed to read session file \"${filePath}\".`, { cause });\n\t}\n\n\tconst physicalLines = content.split(\"\\n\");\n\tlet partialLineNumber: number | undefined;\n\tif (content.endsWith(\"\\n\")) {\n\t\tphysicalLines.pop();\n\t} else {\n\t\tphysicalLines.pop();\n\t\tpartialLineNumber = physicalLines.length + 1;\n\t}\n\n\tif (physicalLines.length === 0) {\n\t\tthrow new SessionLoadError(\"INVALID_HEADER\", filePath, `Session file has no committed header: \"${filePath}\".`, {\n\t\t\tlineNumber: 1,\n\t\t});\n\t}\n\n\tlet headerValue: unknown;\n\ttry {\n\t\theaderValue = JSON.parse(withoutTrailingCarriageReturn(physicalLines[0] ?? \"\")) as unknown;\n\t} catch (cause) {\n\t\tthrow new SessionLoadError(\"INVALID_HEADER\", filePath, `Session header is not valid JSON in \"${filePath}\".`, {\n\t\t\tlineNumber: 1,\n\t\t\tcause,\n\t\t});\n\t}\n\n\tconst header = decodeHeader(headerValue, filePath);\n\tconst entries: SessionEntry[] = [];\n\tconst diagnostics: LoadedSession[\"diagnostics\"][number][] = [];\n\tconst seenIds = new Set<string>([header.id]);\n\tconst messageEntryIds = new Set<string>();\n\tlet expectedParentId = header.id;\n\n\tfor (let index = 1; index < physicalLines.length; index++) {\n\t\tconst lineNumber = index + 1;\n\t\ttry {\n\t\t\tconst value = JSON.parse(withoutTrailingCarriageReturn(physicalLines[index] ?? \"\")) as unknown;\n\t\t\tconst decoded = decodeSessionEntry(value);\n\t\t\tif (!decoded.entry) throw new Error(decoded.reason ?? \"Invalid session message record.\");\n\t\t\tif (seenIds.has(decoded.entry.id)) throw new Error(\"record id is duplicated\");\n\t\t\tif (decoded.entry.parentId !== expectedParentId) {\n\t\t\t\tthrow new Error(`record parentId must be \"${expectedParentId}\"`);\n\t\t\t}\n\t\t\tif (decoded.entry.type === \"summary\" && !messageEntryIds.has(decoded.entry.firstKeptEntryId)) {\n\t\t\t\tthrow new Error(\"record firstKeptEntryId must reference an earlier message entry\");\n\t\t\t}\n\t\t\tentries.push(decoded.entry);\n\t\t\tseenIds.add(decoded.entry.id);\n\t\t\tif (decoded.entry.type === \"message\") messageEntryIds.add(decoded.entry.id);\n\t\t\texpectedParentId = decoded.entry.id;\n\t\t} catch (cause) {\n\t\t\tdiagnostics.push({ kind: \"corrupt_record\", lineNumber, reason: errorText(cause) });\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (diagnostics.length === 0 && partialLineNumber !== undefined) {\n\t\tdiagnostics.push({\n\t\t\tkind: \"trailing_partial_line\",\n\t\t\tlineNumber: partialLineNumber,\n\t\t\treason: \"final line has no newline commit marker\",\n\t\t});\n\t}\n\n\treturn {\n\t\theader,\n\t\tentries,\n\t\tmessages: entries\n\t\t\t.filter((entry): entry is SessionMessageEntry => entry.type === \"message\")\n\t\t\t.map((entry) => entry.message),\n\t\tdiagnostics,\n\t};\n}\n\nexport interface SessionAppendOptions {\n\treadonly lockTimeoutMs?: number;\n\treadonly lockRetryMs?: number;\n\treadonly now?: () => number;\n\treadonly sleep?: (milliseconds: number) => Promise<void>;\n}\n\nconst DEFAULT_LOCK_TIMEOUT_MS = 5_000;\nconst DEFAULT_LOCK_RETRY_MS = 25;\n\nfunction isNodeError(cause: unknown): cause is NodeJS.ErrnoException {\n\treturn cause instanceof Error && \"code\" in cause;\n}\n\nfunction delay(milliseconds: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, milliseconds));\n}\n\nexport async function createSessionFile(filePath: string, header: SessionHeader): Promise<void> {\n\tconst headerSnapshot = structuredClone(header);\n\ttry {\n\t\tdecodeHeader(headerSnapshot, filePath);\n\t\tawait mkdir(dirname(filePath), { recursive: true });\n\t\tconst handle = await open(filePath, \"wx\");\n\t\ttry {\n\t\t\tawait handle.writeFile(`${JSON.stringify(headerSnapshot)}\\n`, \"utf8\");\n\t\t} finally {\n\t\t\tawait handle.close();\n\t\t}\n\t} catch (cause) {\n\t\tif (cause instanceof SessionWriteError) throw cause;\n\t\tthrow new SessionWriteError(\"CREATE_FAILED\", filePath, `Failed to create session file \"${filePath}\".`, {\n\t\t\tcause,\n\t\t});\n\t}\n}\n\nasync function acquireLock(filePath: string, options: SessionAppendOptions) {\n\tconst lockPath = `${filePath}.lock`;\n\tconst timeout = options.lockTimeoutMs ?? DEFAULT_LOCK_TIMEOUT_MS;\n\tconst retry = options.lockRetryMs ?? DEFAULT_LOCK_RETRY_MS;\n\tconst now = options.now ?? Date.now;\n\tconst sleep = options.sleep ?? delay;\n\tconst startedAt = now();\n\n\twhile (true) {\n\t\ttry {\n\t\t\treturn { handle: await open(lockPath, \"wx\"), lockPath };\n\t\t} catch (cause) {\n\t\t\tif (!isNodeError(cause) || cause.code !== \"EEXIST\") {\n\t\t\t\tthrow new SessionWriteError(\"APPEND_FAILED\", filePath, `Failed to acquire session lock for \"${filePath}\".`, {\n\t\t\t\t\tcause,\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (now() - startedAt >= timeout) {\n\t\t\t\tthrow new SessionWriteError(\"LOCK_TIMEOUT\", filePath, `Timed out waiting for session lock \"${lockPath}\".`, {\n\t\t\t\t\tcause,\n\t\t\t\t});\n\t\t\t}\n\t\t\tawait sleep(retry);\n\t\t}\n\t}\n}\n\nasync function releaseLock(handle: Awaited<ReturnType<typeof open>>, lockPath: string): Promise<void> {\n\tlet closeError: unknown;\n\ttry {\n\t\tawait handle.close();\n\t} catch (cause) {\n\t\tcloseError = cause;\n\t}\n\n\ttry {\n\t\tawait unlink(lockPath);\n\t} catch (cause) {\n\t\tif (!isNodeError(cause) || cause.code !== \"ENOENT\") throw cause;\n\t}\n\n\tif (closeError !== undefined) throw closeError;\n}\n\nexport async function appendSessionEntry(\n\tfilePath: string,\n\tentry: SessionEntry,\n\texpectedParentId: string,\n\toptions: SessionAppendOptions = {},\n): Promise<void> {\n\tconst entrySnapshot = structuredClone(entry);\n\tconst decodedEntry = decodeSessionEntry(entrySnapshot);\n\tif (!decodedEntry.entry) {\n\t\tthrow new SessionWriteError(\n\t\t\t\"APPEND_FAILED\",\n\t\t\tfilePath,\n\t\t\t`Refusing to append an invalid session entry to \"${filePath}\": ${decodedEntry.reason ?? \"invalid record\"}.`,\n\t\t);\n\t}\n\tconst { handle, lockPath } = await acquireLock(filePath, options);\n\tlet operationError: unknown;\n\ttry {\n\t\tconst loaded = await loadSessionFile(filePath);\n\t\tif (loaded.diagnostics.length > 0) {\n\t\t\tthrow new SessionWriteError(\n\t\t\t\t\"CORRUPT_SESSION\",\n\t\t\t\tfilePath,\n\t\t\t\t`Refusing to append to a session with recovery diagnostics: \"${filePath}\".`,\n\t\t\t);\n\t\t}\n\n\t\tconst actualParentId = loaded.entries.at(-1)?.id ?? loaded.header.id;\n\t\tif (\n\t\t\tentrySnapshot.type === \"summary\" &&\n\t\t\t!loaded.entries.some(\n\t\t\t\t(existing): existing is SessionMessageEntry =>\n\t\t\t\t\texisting.type === \"message\" && existing.id === entrySnapshot.firstKeptEntryId,\n\t\t\t)\n\t\t) {\n\t\t\tthrow new SessionWriteError(\n\t\t\t\t\"APPEND_FAILED\",\n\t\t\t\tfilePath,\n\t\t\t\t`Refusing to append a summary with an invalid firstKeptEntryId to \"${filePath}\".`,\n\t\t\t);\n\t\t}\n\t\tif (loaded.header.id === entrySnapshot.id || loaded.entries.some((existing) => existing.id === entrySnapshot.id)) {\n\t\t\tthrow new SessionWriteError(\n\t\t\t\t\"APPEND_FAILED\",\n\t\t\t\tfilePath,\n\t\t\t\t`Refusing to append a duplicate session record id to \"${filePath}\".`,\n\t\t\t);\n\t\t}\n\t\tif (actualParentId !== expectedParentId || entrySnapshot.parentId !== expectedParentId) {\n\t\t\tthrow new SessionWriteError(\n\t\t\t\t\"CONCURRENT_MODIFICATION\",\n\t\t\t\tfilePath,\n\t\t\t\t`Session leaf changed before append in \"${filePath}\".`,\n\t\t\t\t{ expectedParentId, actualParentId },\n\t\t\t);\n\t\t}\n\n\t\tawait appendFile(filePath, `${JSON.stringify(entrySnapshot)}\\n`, \"utf8\");\n\t} catch (cause) {\n\t\toperationError = cause;\n\t} finally {\n\t\ttry {\n\t\t\tawait releaseLock(handle, lockPath);\n\t\t} catch (cause) {\n\t\t\toperationError ??= new SessionWriteError(\n\t\t\t\t\"APPEND_FAILED\",\n\t\t\t\tfilePath,\n\t\t\t\t`Failed to release session lock for \"${filePath}\".`,\n\t\t\t\t{ cause },\n\t\t\t);\n\t\t}\n\t}\n\n\tif (operationError !== undefined) {\n\t\tif (operationError instanceof SessionWriteError) {\n\t\t\tthrow operationError;\n\t\t}\n\t\tif (operationError instanceof SessionLoadError) {\n\t\t\tconst code = operationError.code === \"READ_FAILED\" ? \"APPEND_FAILED\" : \"CORRUPT_SESSION\";\n\t\t\tthrow new SessionWriteError(code, filePath, `Unable to load session before append: \"${filePath}\".`, {\n\t\t\t\tcause: operationError,\n\t\t\t});\n\t\t}\n\t\tthrow new SessionWriteError(\"APPEND_FAILED\", filePath, `Failed to append session entry to \"${filePath}\".`, {\n\t\t\tcause: operationError,\n\t\t});\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"session-storage.js","sourceRoot":"","sources":["../../../src/core/session/session-storage.ts"],"names":[],"mappings":"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","sourcesContent":["import { appendFile, mkdir, open, readFile, unlink } from \"node:fs/promises\";\nimport { dirname, posix, win32 } from \"node:path\";\nimport type { AssistantContent, AssistantMessage, Message, ToolResultContent, Usage, UserContent } from \"@di-code/ai\";\nimport {\n\ttype LoadedSession,\n\tSESSION_FORMAT_VERSION,\n\ttype SessionEntry,\n\ttype SessionHeader,\n\tSessionLoadError,\n\ttype SessionMessageEntry,\n\ttype SessionSummaryEntry,\n\tSessionWriteError,\n} from \"./types.ts\";\n\ntype JsonObject = Record<string, unknown>;\n\nfunction isObject(value: unknown): value is JsonObject {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n\treturn typeof value === \"string\" && value.length > 0;\n}\n\nfunction isNonNegativeNumber(value: unknown): value is number {\n\treturn typeof value === \"number\" && Number.isFinite(value) && value >= 0;\n}\n\nfunction isTimestamp(value: unknown): value is number {\n\treturn Number.isSafeInteger(value) && isNonNegativeNumber(value);\n}\n\nfunction isIsoTimestamp(value: unknown): value is string {\n\tif (typeof value !== \"string\") return false;\n\tconst milliseconds = Date.parse(value);\n\treturn Number.isFinite(milliseconds) && new Date(milliseconds).toISOString() === value;\n}\n\nfunction isRecordId(value: unknown): value is string {\n\treturn typeof value === \"string\" && /^[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?$/.test(value);\n}\n\nfunction isAbsolutePath(value: unknown): value is string {\n\treturn typeof value === \"string\" && (win32.isAbsolute(value) || posix.isAbsolute(value));\n}\n\nfunction isJsonValue(value: unknown): boolean {\n\tif (value === null || typeof value === \"string\" || typeof value === \"boolean\") return true;\n\tif (typeof value === \"number\") return Number.isFinite(value);\n\tif (Array.isArray(value)) return value.every(isJsonValue);\n\treturn isObject(value) && Object.values(value).every(isJsonValue);\n}\n\nfunction isProviderReplay(value: unknown): boolean {\n\treturn isObject(value) && isNonEmptyString(value.api) && isJsonValue(value.data);\n}\n\nfunction isImageContent(value: unknown): value is Extract<UserContent | ToolResultContent, { type: \"image\" }> {\n\treturn (\n\t\tisObject(value) && value.type === \"image\" && typeof value.data === \"string\" && isNonEmptyString(value.mimeType)\n\t);\n}\n\nfunction isTextContent(value: unknown): value is Extract<UserContent, { type: \"text\" }> {\n\treturn isObject(value) && value.type === \"text\" && typeof value.text === \"string\";\n}\n\nfunction isUserContent(value: unknown): value is UserContent {\n\treturn isTextContent(value) || isImageContent(value);\n}\n\nfunction isAssistantContent(value: unknown): value is AssistantContent {\n\tif (!isObject(value)) return false;\n\tswitch (value.type) {\n\t\tcase \"text\":\n\t\t\treturn typeof value.text === \"string\";\n\t\tcase \"thinking\":\n\t\t\treturn typeof value.thinking === \"string\";\n\t\tcase \"tool_call\":\n\t\t\treturn (\n\t\t\t\tisNonEmptyString(value.id) &&\n\t\t\t\tisNonEmptyString(value.name) &&\n\t\t\t\tisObject(value.arguments) &&\n\t\t\t\tisJsonValue(value.arguments)\n\t\t\t);\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\nfunction isToolResultContent(value: unknown): value is ToolResultContent {\n\treturn isTextContent(value) || isImageContent(value);\n}\n\nfunction isUsage(value: unknown): value is Usage {\n\tif (!isObject(value) || !isObject(value.cost)) return false;\n\treturn (\n\t\tisNonNegativeNumber(value.input) &&\n\t\tisNonNegativeNumber(value.output) &&\n\t\tisNonNegativeNumber(value.cacheRead) &&\n\t\tisNonNegativeNumber(value.cacheWrite) &&\n\t\tisNonNegativeNumber(value.totalTokens) &&\n\t\tisNonNegativeNumber(value.cost.input) &&\n\t\tisNonNegativeNumber(value.cost.output) &&\n\t\tisNonNegativeNumber(value.cost.cacheRead) &&\n\t\tisNonNegativeNumber(value.cost.cacheWrite) &&\n\t\tisNonNegativeNumber(value.cost.total)\n\t);\n}\n\nfunction isAssistantMessage(value: JsonObject): value is JsonObject & AssistantMessage {\n\tif (\n\t\tvalue.role !== \"assistant\" ||\n\t\t!Array.isArray(value.content) ||\n\t\t!value.content.every(isAssistantContent) ||\n\t\t!isNonEmptyString(value.provider) ||\n\t\t!isNonEmptyString(value.model) ||\n\t\t(value.providerReplay !== undefined && !isProviderReplay(value.providerReplay)) ||\n\t\t!isUsage(value.usage) ||\n\t\t!isTimestamp(value.timestamp)\n\t) {\n\t\treturn false;\n\t}\n\n\tif (value.stopReason === \"stop\" || value.stopReason === \"length\" || value.stopReason === \"tool_use\") {\n\t\treturn value.errorMessage === undefined;\n\t}\n\tif (value.stopReason === \"error\" || value.stopReason === \"aborted\") {\n\t\treturn typeof value.errorMessage === \"string\";\n\t}\n\treturn false;\n}\n\nfunction isMessage(value: unknown): value is Message {\n\tif (!isObject(value) || !isTimestamp(value.timestamp)) return false;\n\n\tswitch (value.role) {\n\t\tcase \"user\":\n\t\t\treturn Array.isArray(value.content) && value.content.every(isUserContent);\n\t\tcase \"assistant\":\n\t\t\treturn isAssistantMessage(value);\n\t\tcase \"tool_result\":\n\t\t\treturn (\n\t\t\t\tisNonEmptyString(value.toolCallId) &&\n\t\t\t\tisNonEmptyString(value.toolName) &&\n\t\t\t\tArray.isArray(value.content) &&\n\t\t\t\tvalue.content.every(isToolResultContent) &&\n\t\t\t\t(value.details === undefined || isJsonValue(value.details)) &&\n\t\t\t\ttypeof value.isError === \"boolean\"\n\t\t\t);\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\nfunction decodeHeader(value: unknown, filePath: string): SessionHeader {\n\tif (!isObject(value) || value.type !== \"session\") {\n\t\tthrow new SessionLoadError(\"INVALID_HEADER\", filePath, `Invalid session header in \"${filePath}\".`, {\n\t\t\tlineNumber: 1,\n\t\t});\n\t}\n\tif (!(\"version\" in value)) {\n\t\tthrow new SessionLoadError(\"INVALID_HEADER\", filePath, `Session header has no version in \"${filePath}\".`, {\n\t\t\tlineNumber: 1,\n\t\t});\n\t}\n\tif (value.version !== SESSION_FORMAT_VERSION) {\n\t\tthrow new SessionLoadError(\n\t\t\t\"UNSUPPORTED_VERSION\",\n\t\t\tfilePath,\n\t\t\t`Unsupported session version ${JSON.stringify(value.version)} in \"${filePath}\".`,\n\t\t\t{ lineNumber: 1 },\n\t\t);\n\t}\n\tif (\n\t\t!isRecordId(value.id) ||\n\t\tvalue.parentId !== null ||\n\t\t!isIsoTimestamp(value.timestamp) ||\n\t\t!isAbsolutePath(value.cwd)\n\t) {\n\t\tthrow new SessionLoadError(\"INVALID_HEADER\", filePath, `Invalid session header fields in \"${filePath}\".`, {\n\t\t\tlineNumber: 1,\n\t\t});\n\t}\n\treturn value as unknown as SessionHeader;\n}\n\nfunction decodeSessionEntry(value: unknown): { readonly entry?: SessionEntry; readonly reason?: string } {\n\tif (!isObject(value) || (value.type !== \"message\" && value.type !== \"summary\")) {\n\t\treturn { reason: 'record type must be \"message\" or \"summary\"' };\n\t}\n\tif (value.version !== SESSION_FORMAT_VERSION) return { reason: \"record version must be 1\" };\n\tif (!isRecordId(value.id)) return { reason: \"record id is invalid\" };\n\tif (!isRecordId(value.parentId)) return { reason: \"record parentId is invalid\" };\n\tif (!isIsoTimestamp(value.timestamp)) return { reason: \"record timestamp is not canonical ISO 8601 UTC\" };\n\tif (value.type === \"message\") {\n\t\tif (!isMessage(value.message)) return { reason: \"record message does not match the Message contract\" };\n\t\treturn { entry: value as unknown as SessionMessageEntry };\n\t}\n\tif (typeof value.summary !== \"string\" || value.summary.trim().length === 0) {\n\t\treturn { reason: \"record summary must be a non-empty string\" };\n\t}\n\tif (!isRecordId(value.firstKeptEntryId)) return { reason: \"record firstKeptEntryId is invalid\" };\n\tif (!Number.isSafeInteger(value.tokensBefore) || !isNonNegativeNumber(value.tokensBefore)) {\n\t\treturn { reason: \"record tokensBefore must be a non-negative safe integer\" };\n\t}\n\treturn { entry: value as unknown as SessionSummaryEntry };\n}\n\nfunction withoutTrailingCarriageReturn(line: string): string {\n\treturn line.endsWith(\"\\r\") ? line.slice(0, -1) : line;\n}\n\nfunction errorText(cause: unknown): string {\n\treturn cause instanceof Error ? cause.message : String(cause);\n}\n\nexport async function loadSessionFile(filePath: string): Promise<LoadedSession> {\n\tlet content: string;\n\ttry {\n\t\tcontent = await readFile(filePath, \"utf8\");\n\t} catch (cause) {\n\t\tthrow new SessionLoadError(\"READ_FAILED\", filePath, `Failed to read session file \"${filePath}\".`, { cause });\n\t}\n\n\tconst physicalLines = content.split(\"\\n\");\n\tlet partialLineNumber: number | undefined;\n\tif (content.endsWith(\"\\n\")) {\n\t\tphysicalLines.pop();\n\t} else {\n\t\tphysicalLines.pop();\n\t\tpartialLineNumber = physicalLines.length + 1;\n\t}\n\n\tif (physicalLines.length === 0) {\n\t\tthrow new SessionLoadError(\"INVALID_HEADER\", filePath, `Session file has no committed header: \"${filePath}\".`, {\n\t\t\tlineNumber: 1,\n\t\t});\n\t}\n\n\tlet headerValue: unknown;\n\ttry {\n\t\theaderValue = JSON.parse(withoutTrailingCarriageReturn(physicalLines[0] ?? \"\")) as unknown;\n\t} catch (cause) {\n\t\tthrow new SessionLoadError(\"INVALID_HEADER\", filePath, `Session header is not valid JSON in \"${filePath}\".`, {\n\t\t\tlineNumber: 1,\n\t\t\tcause,\n\t\t});\n\t}\n\n\tconst header = decodeHeader(headerValue, filePath);\n\tconst entries: SessionEntry[] = [];\n\tconst diagnostics: LoadedSession[\"diagnostics\"][number][] = [];\n\tconst seenIds = new Set<string>([header.id]);\n\tconst messageEntryIds = new Set<string>();\n\tlet expectedParentId = header.id;\n\n\tfor (let index = 1; index < physicalLines.length; index++) {\n\t\tconst lineNumber = index + 1;\n\t\ttry {\n\t\t\tconst value = JSON.parse(withoutTrailingCarriageReturn(physicalLines[index] ?? \"\")) as unknown;\n\t\t\tconst decoded = decodeSessionEntry(value);\n\t\t\tif (!decoded.entry) throw new Error(decoded.reason ?? \"Invalid session message record.\");\n\t\t\tif (seenIds.has(decoded.entry.id)) throw new Error(\"record id is duplicated\");\n\t\t\tif (decoded.entry.parentId !== expectedParentId) {\n\t\t\t\tthrow new Error(`record parentId must be \"${expectedParentId}\"`);\n\t\t\t}\n\t\t\tif (decoded.entry.type === \"summary\" && !messageEntryIds.has(decoded.entry.firstKeptEntryId)) {\n\t\t\t\tthrow new Error(\"record firstKeptEntryId must reference an earlier message entry\");\n\t\t\t}\n\t\t\tentries.push(decoded.entry);\n\t\t\tseenIds.add(decoded.entry.id);\n\t\t\tif (decoded.entry.type === \"message\") messageEntryIds.add(decoded.entry.id);\n\t\t\texpectedParentId = decoded.entry.id;\n\t\t} catch (cause) {\n\t\t\tdiagnostics.push({ kind: \"corrupt_record\", lineNumber, reason: errorText(cause) });\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (diagnostics.length === 0 && partialLineNumber !== undefined) {\n\t\tdiagnostics.push({\n\t\t\tkind: \"trailing_partial_line\",\n\t\t\tlineNumber: partialLineNumber,\n\t\t\treason: \"final line has no newline commit marker\",\n\t\t});\n\t}\n\n\treturn {\n\t\theader,\n\t\tentries,\n\t\tmessages: entries\n\t\t\t.filter((entry): entry is SessionMessageEntry => entry.type === \"message\")\n\t\t\t.map((entry) => entry.message),\n\t\tdiagnostics,\n\t};\n}\n\nexport interface SessionAppendOptions {\n\treadonly lockTimeoutMs?: number;\n\treadonly lockRetryMs?: number;\n\treadonly now?: () => number;\n\treadonly sleep?: (milliseconds: number) => Promise<void>;\n}\n\nconst DEFAULT_LOCK_TIMEOUT_MS = 5_000;\nconst DEFAULT_LOCK_RETRY_MS = 25;\n\nfunction isNodeError(cause: unknown): cause is NodeJS.ErrnoException {\n\treturn cause instanceof Error && \"code\" in cause;\n}\n\nfunction delay(milliseconds: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, milliseconds));\n}\n\nexport async function createSessionFile(filePath: string, header: SessionHeader): Promise<void> {\n\tconst headerSnapshot = structuredClone(header);\n\ttry {\n\t\tdecodeHeader(headerSnapshot, filePath);\n\t\tawait mkdir(dirname(filePath), { recursive: true });\n\t\tconst handle = await open(filePath, \"wx\");\n\t\ttry {\n\t\t\tawait handle.writeFile(`${JSON.stringify(headerSnapshot)}\\n`, \"utf8\");\n\t\t} finally {\n\t\t\tawait handle.close();\n\t\t}\n\t} catch (cause) {\n\t\tif (cause instanceof SessionWriteError) throw cause;\n\t\tthrow new SessionWriteError(\"CREATE_FAILED\", filePath, `Failed to create session file \"${filePath}\".`, {\n\t\t\tcause,\n\t\t});\n\t}\n}\n\nasync function acquireLock(filePath: string, options: SessionAppendOptions) {\n\tconst lockPath = `${filePath}.lock`;\n\tconst timeout = options.lockTimeoutMs ?? DEFAULT_LOCK_TIMEOUT_MS;\n\tconst retry = options.lockRetryMs ?? DEFAULT_LOCK_RETRY_MS;\n\tconst now = options.now ?? Date.now;\n\tconst sleep = options.sleep ?? delay;\n\tconst startedAt = now();\n\n\twhile (true) {\n\t\ttry {\n\t\t\treturn { handle: await open(lockPath, \"wx\"), lockPath };\n\t\t} catch (cause) {\n\t\t\tif (!isNodeError(cause) || cause.code !== \"EEXIST\") {\n\t\t\t\tthrow new SessionWriteError(\"APPEND_FAILED\", filePath, `Failed to acquire session lock for \"${filePath}\".`, {\n\t\t\t\t\tcause,\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (now() - startedAt >= timeout) {\n\t\t\t\tthrow new SessionWriteError(\"LOCK_TIMEOUT\", filePath, `Timed out waiting for session lock \"${lockPath}\".`, {\n\t\t\t\t\tcause,\n\t\t\t\t});\n\t\t\t}\n\t\t\tawait sleep(retry);\n\t\t}\n\t}\n}\n\nasync function releaseLock(handle: Awaited<ReturnType<typeof open>>, lockPath: string): Promise<void> {\n\tlet closeError: unknown;\n\ttry {\n\t\tawait handle.close();\n\t} catch (cause) {\n\t\tcloseError = cause;\n\t}\n\n\ttry {\n\t\tawait unlink(lockPath);\n\t} catch (cause) {\n\t\tif (!isNodeError(cause) || cause.code !== \"ENOENT\") throw cause;\n\t}\n\n\tif (closeError !== undefined) throw closeError;\n}\n\nexport async function appendSessionEntry(\n\tfilePath: string,\n\tentry: SessionEntry,\n\texpectedParentId: string,\n\toptions: SessionAppendOptions = {},\n): Promise<void> {\n\tconst entrySnapshot = structuredClone(entry);\n\tconst decodedEntry = decodeSessionEntry(entrySnapshot);\n\tif (!decodedEntry.entry) {\n\t\tthrow new SessionWriteError(\n\t\t\t\"APPEND_FAILED\",\n\t\t\tfilePath,\n\t\t\t`Refusing to append an invalid session entry to \"${filePath}\": ${decodedEntry.reason ?? \"invalid record\"}.`,\n\t\t);\n\t}\n\tconst { handle, lockPath } = await acquireLock(filePath, options);\n\tlet operationError: unknown;\n\ttry {\n\t\tconst loaded = await loadSessionFile(filePath);\n\t\tif (loaded.diagnostics.length > 0) {\n\t\t\tthrow new SessionWriteError(\n\t\t\t\t\"CORRUPT_SESSION\",\n\t\t\t\tfilePath,\n\t\t\t\t`Refusing to append to a session with recovery diagnostics: \"${filePath}\".`,\n\t\t\t);\n\t\t}\n\n\t\tconst actualParentId = loaded.entries.at(-1)?.id ?? loaded.header.id;\n\t\tif (\n\t\t\tentrySnapshot.type === \"summary\" &&\n\t\t\t!loaded.entries.some(\n\t\t\t\t(existing): existing is SessionMessageEntry =>\n\t\t\t\t\texisting.type === \"message\" && existing.id === entrySnapshot.firstKeptEntryId,\n\t\t\t)\n\t\t) {\n\t\t\tthrow new SessionWriteError(\n\t\t\t\t\"APPEND_FAILED\",\n\t\t\t\tfilePath,\n\t\t\t\t`Refusing to append a summary with an invalid firstKeptEntryId to \"${filePath}\".`,\n\t\t\t);\n\t\t}\n\t\tif (loaded.header.id === entrySnapshot.id || loaded.entries.some((existing) => existing.id === entrySnapshot.id)) {\n\t\t\tthrow new SessionWriteError(\n\t\t\t\t\"APPEND_FAILED\",\n\t\t\t\tfilePath,\n\t\t\t\t`Refusing to append a duplicate session record id to \"${filePath}\".`,\n\t\t\t);\n\t\t}\n\t\tif (actualParentId !== expectedParentId || entrySnapshot.parentId !== expectedParentId) {\n\t\t\tthrow new SessionWriteError(\n\t\t\t\t\"CONCURRENT_MODIFICATION\",\n\t\t\t\tfilePath,\n\t\t\t\t`Session leaf changed before append in \"${filePath}\".`,\n\t\t\t\t{ expectedParentId, actualParentId },\n\t\t\t);\n\t\t}\n\n\t\tawait appendFile(filePath, `${JSON.stringify(entrySnapshot)}\\n`, \"utf8\");\n\t} catch (cause) {\n\t\toperationError = cause;\n\t} finally {\n\t\ttry {\n\t\t\tawait releaseLock(handle, lockPath);\n\t\t} catch (cause) {\n\t\t\toperationError ??= new SessionWriteError(\n\t\t\t\t\"APPEND_FAILED\",\n\t\t\t\tfilePath,\n\t\t\t\t`Failed to release session lock for \"${filePath}\".`,\n\t\t\t\t{ cause },\n\t\t\t);\n\t\t}\n\t}\n\n\tif (operationError !== undefined) {\n\t\tif (operationError instanceof SessionWriteError) {\n\t\t\tthrow operationError;\n\t\t}\n\t\tif (operationError instanceof SessionLoadError) {\n\t\t\tconst code = operationError.code === \"READ_FAILED\" ? \"APPEND_FAILED\" : \"CORRUPT_SESSION\";\n\t\t\tthrow new SessionWriteError(code, filePath, `Unable to load session before append: \"${filePath}\".`, {\n\t\t\t\tcause: operationError,\n\t\t\t});\n\t\t}\n\t\tthrow new SessionWriteError(\"APPEND_FAILED\", filePath, `Failed to append session entry to \"${filePath}\".`, {\n\t\t\tcause: operationError,\n\t\t});\n\t}\n}\n"]}
|
package/dist/core/session.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type AgentListener } from "@di-code/agent";
|
|
2
|
-
import type { AssistantMessage, ImageContent, Message, Model, Provider, Usage } from "@di-code/ai";
|
|
2
|
+
import type { AssistantMessage, ImageContent, Message, Model, Provider, ThinkingLevel, Usage } from "@di-code/ai";
|
|
3
3
|
import type { ExtensionHost } from "../extensions/runtime.ts";
|
|
4
4
|
import type { SkillResource } from "./resources/types.ts";
|
|
5
5
|
import type { SessionManager } from "./session/session-manager.ts";
|
|
@@ -40,6 +40,9 @@ export type AgentSessionEvent = import("@di-code/agent").AgentEvent | {
|
|
|
40
40
|
reason: "threshold" | "manual";
|
|
41
41
|
success: boolean;
|
|
42
42
|
errorMessage?: string;
|
|
43
|
+
} | {
|
|
44
|
+
type: "queue_update";
|
|
45
|
+
steering: readonly string[];
|
|
43
46
|
} | {
|
|
44
47
|
type: "usage_update";
|
|
45
48
|
usage: SessionUsage;
|
|
@@ -49,10 +52,11 @@ export declare class AgentSession {
|
|
|
49
52
|
private readonly agent;
|
|
50
53
|
private readonly allowedRootValue;
|
|
51
54
|
private readonly sessionManager?;
|
|
52
|
-
private
|
|
55
|
+
private provider;
|
|
53
56
|
private readonly skills;
|
|
54
57
|
private readonly extensionHost?;
|
|
55
58
|
private model;
|
|
59
|
+
private thinkingLevelValue?;
|
|
56
60
|
private readonly sessionIdValue;
|
|
57
61
|
private readonly now;
|
|
58
62
|
private compactionEnabledValue;
|
|
@@ -61,27 +65,38 @@ export declare class AgentSession {
|
|
|
61
65
|
private usageTotals;
|
|
62
66
|
private persistenceError?;
|
|
63
67
|
private promptActive;
|
|
68
|
+
private readonly steeringMessages;
|
|
64
69
|
private readonly sessionListeners;
|
|
65
70
|
constructor(options: AgentSessionOptions);
|
|
66
71
|
get transcript(): readonly Message[];
|
|
67
72
|
get isStreaming(): boolean;
|
|
68
73
|
get sessionId(): string;
|
|
69
74
|
get modelId(): string;
|
|
75
|
+
get providerId(): string;
|
|
76
|
+
get thinkingLevel(): ThinkingLevel | undefined;
|
|
70
77
|
get allowedRoot(): string;
|
|
71
78
|
get availableModels(): readonly Model[];
|
|
79
|
+
get availableSkills(): readonly SkillResource[];
|
|
72
80
|
setModel(modelId: string): Model;
|
|
81
|
+
setRuntime(provider: Provider, model: Model): Model;
|
|
82
|
+
cycleThinkingLevel(): ThinkingLevel | undefined;
|
|
73
83
|
get compactionEnabled(): boolean;
|
|
74
84
|
setCompactionEnabled(enabled: boolean): boolean;
|
|
75
85
|
get sessionFile(): string | undefined;
|
|
76
86
|
get sessionDiagnostics(): readonly SessionDiagnostic[];
|
|
77
87
|
get usage(): SessionUsage;
|
|
78
88
|
prompt(text: string, signal?: AbortSignal): Promise<AssistantMessage>;
|
|
89
|
+
/** Queues an instruction for the next provider request while this Session is running. */
|
|
90
|
+
steer(text: string, signal?: AbortSignal): Promise<void>;
|
|
91
|
+
/** Queues provider-neutral text and image content for the active Agent run. */
|
|
92
|
+
steerWithImages(text: string, images: readonly ImageContent[], signal?: AbortSignal): Promise<void>;
|
|
79
93
|
/** Sends one text prompt with explicitly supplied image attachments. */
|
|
80
94
|
promptWithImages(text: string, images: readonly ImageContent[], signal?: AbortSignal): Promise<AssistantMessage>;
|
|
81
95
|
compact(signal?: AbortSignal): Promise<void>;
|
|
82
96
|
subscribe(listener: AgentListener): () => void;
|
|
83
97
|
subscribeSession(listener: AgentSessionListener): () => void;
|
|
84
98
|
private emitSession;
|
|
99
|
+
private emitQueueUpdate;
|
|
85
100
|
private addUsage;
|
|
86
101
|
private compactIfNeeded;
|
|
87
102
|
private compactNow;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/core/session.ts"],"names":[],"mappings":"AACA,OAAO,EAEN,KAAK,aAAa,EAOlB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/core/session.ts"],"names":[],"mappings":"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"}
|