@di-code/coding-agent 0.1.6 → 0.1.8
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 +112 -68
- package/compositions/base.yml +54 -0
- package/compositions/interactive.yml +14 -0
- package/compositions/json.yml +6 -0
- package/compositions/print.yml +5 -0
- package/compositions/rpc.yml +12 -0
- package/compositions/webui.yml +9 -0
- package/dist/cli.d.ts +22 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +97 -3
- package/dist/cli.js.map +1 -1
- package/dist/composition-loader-entry.d.ts +11 -0
- package/dist/composition-loader-entry.d.ts.map +1 -0
- package/dist/composition-loader-entry.js +12 -0
- package/dist/composition-loader-entry.js.map +1 -0
- package/dist/compositions.d.ts +32 -0
- package/dist/compositions.d.ts.map +1 -0
- package/dist/compositions.js +173 -0
- package/dist/compositions.js.map +1 -0
- package/dist/core/session/session-manager.d.ts +9 -2
- package/dist/core/session/session-manager.d.ts.map +1 -1
- package/dist/core/session/session-manager.js +28 -0
- package/dist/core/session/session-manager.js.map +1 -1
- package/dist/core/session/session-storage.d.ts.map +1 -1
- package/dist/core/session/session-storage.js +20 -3
- package/dist/core/session/session-storage.js.map +1 -1
- package/dist/core/session/types.d.ts +11 -2
- package/dist/core/session/types.d.ts.map +1 -1
- package/dist/core/session/types.js.map +1 -1
- package/dist/core/session-tools.d.ts +5 -0
- package/dist/core/session-tools.d.ts.map +1 -0
- package/dist/core/session-tools.js +17 -0
- package/dist/core/session-tools.js.map +1 -0
- package/dist/core/session.d.ts +21 -7
- package/dist/core/session.d.ts.map +1 -1
- package/dist/core/session.js +77 -41
- package/dist/core/session.js.map +1 -1
- package/dist/core/tools/bash.d.ts +1 -38
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +1 -207
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts +1 -24
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +1 -135
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts +1 -26
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +1 -140
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/file-mutation-queue.d.ts +1 -1
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/core/tools/file-mutation-queue.js +1 -23
- package/dist/core/tools/file-mutation-queue.js.map +1 -1
- package/dist/core/tools/file-search.d.ts +1 -13
- package/dist/core/tools/file-search.d.ts.map +1 -1
- package/dist/core/tools/file-search.js +1 -98
- package/dist/core/tools/file-search.js.map +1 -1
- package/dist/core/tools/glob.d.ts +1 -10
- package/dist/core/tools/glob.d.ts.map +1 -1
- package/dist/core/tools/glob.js +1 -43
- package/dist/core/tools/glob.js.map +1 -1
- package/dist/core/tools/grep.d.ts +1 -12
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +1 -66
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/load-skill.d.ts +1 -9
- package/dist/core/tools/load-skill.d.ts.map +1 -1
- package/dist/core/tools/load-skill.js +1 -21
- package/dist/core/tools/load-skill.js.map +1 -1
- package/dist/core/tools/path-boundary.d.ts +1 -4
- package/dist/core/tools/path-boundary.d.ts.map +1 -1
- package/dist/core/tools/path-boundary.js +1 -65
- package/dist/core/tools/path-boundary.js.map +1 -1
- package/dist/core/tools/read.d.ts +1 -16
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +1 -131
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/write.d.ts +1 -16
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +1 -44
- package/dist/core/tools/write.js.map +1 -1
- package/dist/entry.js +30 -28
- package/dist/entry.js.map +1 -1
- package/dist/i18n.d.ts.map +1 -1
- package/dist/i18n.js +2 -0
- package/dist/i18n.js.map +1 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -3
- package/dist/index.js.map +1 -1
- package/dist/interactive/builtin.d.ts +17 -0
- package/dist/interactive/builtin.d.ts.map +1 -0
- package/dist/interactive/builtin.js +47 -0
- package/dist/interactive/builtin.js.map +1 -0
- package/dist/interactive/controller.d.ts +85 -0
- package/dist/interactive/controller.d.ts.map +1 -0
- package/dist/interactive/controller.js +211 -0
- package/dist/interactive/controller.js.map +1 -0
- package/dist/interactive/index.d.ts +3 -0
- package/dist/interactive/index.d.ts.map +1 -0
- package/dist/interactive/index.js +3 -0
- package/dist/interactive/index.js.map +1 -0
- package/dist/interactive-host-entry.d.ts +7 -0
- package/dist/interactive-host-entry.d.ts.map +1 -0
- package/dist/interactive-host-entry.js +123 -0
- package/dist/interactive-host-entry.js.map +1 -0
- package/dist/interactive-profile.d.ts +18 -0
- package/dist/interactive-profile.d.ts.map +1 -0
- package/dist/interactive-profile.js +290 -0
- package/dist/interactive-profile.js.map +1 -0
- package/dist/interactive-resources-entry.d.ts +7 -0
- package/dist/interactive-resources-entry.d.ts.map +1 -0
- package/dist/interactive-resources-entry.js +42 -0
- package/dist/interactive-resources-entry.js.map +1 -0
- package/dist/legacy-main.d.ts +39 -0
- package/dist/legacy-main.d.ts.map +1 -0
- package/dist/legacy-main.js +611 -0
- package/dist/legacy-main.js.map +1 -0
- package/dist/main.d.ts +15 -34
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +130 -513
- package/dist/main.js.map +1 -1
- package/dist/mcp/entries.d.ts +42 -0
- package/dist/mcp/entries.d.ts.map +1 -0
- package/dist/mcp/entries.js +98 -0
- package/dist/mcp/entries.js.map +1 -0
- package/dist/mcp-client-entry.d.ts +5 -0
- package/dist/mcp-client-entry.d.ts.map +1 -0
- package/dist/mcp-client-entry.js +6 -0
- package/dist/mcp-client-entry.js.map +1 -0
- package/dist/mcp-config-entry.d.ts +5 -0
- package/dist/mcp-config-entry.d.ts.map +1 -0
- package/dist/mcp-config-entry.js +6 -0
- package/dist/mcp-config-entry.js.map +1 -0
- package/dist/mcp-tools-entry.d.ts +5 -0
- package/dist/mcp-tools-entry.d.ts.map +1 -0
- package/dist/mcp-tools-entry.js +6 -0
- package/dist/mcp-tools-entry.js.map +1 -0
- package/dist/mcp-transport-entry.d.ts +5 -0
- package/dist/mcp-transport-entry.d.ts.map +1 -0
- package/dist/mcp-transport-entry.js +6 -0
- package/dist/mcp-transport-entry.js.map +1 -0
- package/dist/modes/interactive-entry.d.ts +18 -0
- package/dist/modes/interactive-entry.d.ts.map +1 -0
- package/dist/modes/interactive-entry.js +21 -0
- package/dist/modes/interactive-entry.js.map +1 -0
- package/dist/modes/interactive-state.js +1 -1
- package/dist/modes/interactive-state.js.map +1 -1
- package/dist/modes/interactive.d.ts +16 -6
- package/dist/modes/interactive.d.ts.map +1 -1
- package/dist/modes/interactive.js +99 -33
- package/dist/modes/interactive.js.map +1 -1
- package/dist/modes/json-entry.d.ts +13 -0
- package/dist/modes/json-entry.d.ts.map +1 -0
- package/dist/modes/json-entry.js +14 -0
- package/dist/modes/json-entry.js.map +1 -0
- package/dist/modes/json.d.ts +4 -1
- package/dist/modes/json.d.ts.map +1 -1
- package/dist/modes/json.js +3 -3
- package/dist/modes/json.js.map +1 -1
- package/dist/modes/print-entry.d.ts +10 -0
- package/dist/modes/print-entry.d.ts.map +1 -0
- package/dist/modes/print-entry.js +11 -0
- package/dist/modes/print-entry.js.map +1 -0
- package/dist/modes/tree-selector.d.ts.map +1 -1
- package/dist/modes/tree-selector.js +4 -0
- package/dist/modes/tree-selector.js.map +1 -1
- package/dist/plugin-dump-composition.d.ts +6 -0
- package/dist/plugin-dump-composition.d.ts.map +1 -0
- package/dist/plugin-dump-composition.js +7 -0
- package/dist/plugin-dump-composition.js.map +1 -0
- package/dist/plugin-inventory.d.ts +7 -0
- package/dist/plugin-inventory.d.ts.map +1 -0
- package/dist/plugin-inventory.js +8 -0
- package/dist/plugin-inventory.js.map +1 -0
- package/dist/plugin-manager.d.ts +6 -0
- package/dist/plugin-manager.d.ts.map +1 -0
- package/dist/plugin-manager.js +7 -0
- package/dist/plugin-manager.js.map +1 -0
- package/dist/plugin-trace.d.ts +6 -0
- package/dist/plugin-trace.d.ts.map +1 -0
- package/dist/plugin-trace.js +7 -0
- package/dist/plugin-trace.js.map +1 -0
- package/dist/plugins/dynamic-broker.d.ts +76 -0
- package/dist/plugins/dynamic-broker.d.ts.map +1 -0
- package/dist/plugins/dynamic-broker.js +852 -0
- package/dist/plugins/dynamic-broker.js.map +1 -0
- package/dist/plugins/profile.d.ts +15 -0
- package/dist/plugins/profile.d.ts.map +1 -0
- package/dist/plugins/profile.js +34 -0
- package/dist/plugins/profile.js.map +1 -0
- package/dist/plugins/runtime-host.d.ts +37 -0
- package/dist/plugins/runtime-host.d.ts.map +1 -0
- package/dist/plugins/runtime-host.js +95 -0
- package/dist/plugins/runtime-host.js.map +1 -0
- package/dist/plugins/trust.d.ts +8 -0
- package/dist/plugins/trust.d.ts.map +1 -0
- package/dist/plugins/trust.js +59 -0
- package/dist/plugins/trust.js.map +1 -0
- package/dist/project-trust-entry.d.ts +15 -0
- package/dist/project-trust-entry.d.ts.map +1 -0
- package/dist/project-trust-entry.js +15 -0
- package/dist/project-trust-entry.js.map +1 -0
- package/dist/rpc/client.d.ts +78 -6
- package/dist/rpc/client.d.ts.map +1 -1
- package/dist/rpc/client.js +172 -4
- package/dist/rpc/client.js.map +1 -1
- package/dist/rpc/dispatcher.d.ts +121 -0
- package/dist/rpc/dispatcher.d.ts.map +1 -0
- package/dist/rpc/dispatcher.js +994 -0
- package/dist/rpc/dispatcher.js.map +1 -0
- package/dist/rpc/index.d.ts +2 -0
- package/dist/rpc/index.d.ts.map +1 -1
- package/dist/rpc/index.js +2 -0
- package/dist/rpc/index.js.map +1 -1
- package/dist/rpc/lifecycle.d.ts +6 -0
- package/dist/rpc/lifecycle.d.ts.map +1 -0
- package/dist/rpc/lifecycle.js +24 -0
- package/dist/rpc/lifecycle.js.map +1 -0
- package/dist/rpc/protocol.d.ts +112 -31
- package/dist/rpc/protocol.d.ts.map +1 -1
- package/dist/rpc/protocol.js +569 -117
- package/dist/rpc/protocol.js.map +1 -1
- package/dist/rpc/server-service.d.ts +7 -0
- package/dist/rpc/server-service.d.ts.map +1 -0
- package/dist/rpc/server-service.js +3 -0
- package/dist/rpc/server-service.js.map +1 -0
- package/dist/rpc/server.d.ts +16 -19
- package/dist/rpc/server.d.ts.map +1 -1
- package/dist/rpc/server.js +59 -115
- package/dist/rpc/server.js.map +1 -1
- package/dist/rpc-client-sdk-entry.d.ts +12 -0
- package/dist/rpc-client-sdk-entry.d.ts.map +1 -0
- package/dist/rpc-client-sdk-entry.js +11 -0
- package/dist/rpc-client-sdk-entry.js.map +1 -0
- package/dist/rpc-entry.js +50 -18
- package/dist/rpc-entry.js.map +1 -1
- package/dist/rpc-server-entry.d.ts +8 -0
- package/dist/rpc-server-entry.d.ts.map +1 -0
- package/dist/rpc-server-entry.js +67 -0
- package/dist/rpc-server-entry.js.map +1 -0
- package/dist/runtime/attachment-store.d.ts +13 -0
- package/dist/runtime/attachment-store.d.ts.map +1 -0
- package/dist/runtime/attachment-store.js +93 -0
- package/dist/runtime/attachment-store.js.map +1 -0
- package/dist/runtime/bootstrap.d.ts +14 -0
- package/dist/runtime/bootstrap.d.ts.map +1 -0
- package/dist/runtime/bootstrap.js +29 -0
- package/dist/runtime/bootstrap.js.map +1 -0
- package/dist/runtime/interactive-host-service.d.ts +22 -0
- package/dist/runtime/interactive-host-service.d.ts.map +1 -0
- package/dist/runtime/interactive-host-service.js +2 -0
- package/dist/runtime/interactive-host-service.js.map +1 -0
- package/dist/runtime/interactive-resource-service.d.ts +11 -0
- package/dist/runtime/interactive-resource-service.d.ts.map +1 -0
- package/dist/runtime/interactive-resource-service.js +3 -0
- package/dist/runtime/interactive-resource-service.js.map +1 -0
- package/dist/runtime/plugin-inventory-entry.d.ts +5 -0
- package/dist/runtime/plugin-inventory-entry.d.ts.map +1 -0
- package/dist/runtime/plugin-inventory-entry.js +18 -0
- package/dist/runtime/plugin-inventory-entry.js.map +1 -0
- package/dist/runtime/plugin-inventory-service.d.ts +8 -0
- package/dist/runtime/plugin-inventory-service.d.ts.map +1 -0
- package/dist/runtime/plugin-inventory-service.js +3 -0
- package/dist/runtime/plugin-inventory-service.js.map +1 -0
- package/dist/runtime/plugin-manager-entry.d.ts +20 -0
- package/dist/runtime/plugin-manager-entry.d.ts.map +1 -0
- package/dist/runtime/plugin-manager-entry.js +96 -0
- package/dist/runtime/plugin-manager-entry.js.map +1 -0
- package/dist/runtime/plugin-observability-entry.d.ts +12 -0
- package/dist/runtime/plugin-observability-entry.d.ts.map +1 -0
- package/dist/runtime/plugin-observability-entry.js +73 -0
- package/dist/runtime/plugin-observability-entry.js.map +1 -0
- package/dist/runtime/product-host.d.ts +91 -0
- package/dist/runtime/product-host.d.ts.map +1 -0
- package/dist/runtime/product-host.js +529 -0
- package/dist/runtime/product-host.js.map +1 -0
- package/dist/runtime/session-factory.d.ts +17 -0
- package/dist/runtime/session-factory.d.ts.map +1 -0
- package/dist/runtime/session-factory.js +75 -0
- package/dist/runtime/session-factory.js.map +1 -0
- package/dist/runtime/session-host.d.ts +152 -0
- package/dist/runtime/session-host.d.ts.map +1 -0
- package/dist/runtime/session-host.js +895 -0
- package/dist/runtime/session-host.js.map +1 -0
- package/dist/runtime-core-entry.d.ts +11 -0
- package/dist/runtime-core-entry.d.ts.map +1 -0
- package/dist/runtime-core-entry.js +9 -0
- package/dist/runtime-core-entry.js.map +1 -0
- package/dist/session-factory-entry.d.ts +7 -0
- package/dist/session-factory-entry.d.ts.map +1 -0
- package/dist/session-factory-entry.js +9 -0
- package/dist/session-factory-entry.js.map +1 -0
- package/dist/session-store-jsonl-entry.d.ts +7 -0
- package/dist/session-store-jsonl-entry.d.ts.map +1 -0
- package/dist/session-store-jsonl-entry.js +33 -0
- package/dist/session-store-jsonl-entry.js.map +1 -0
- package/dist/startup.d.ts +21 -1
- package/dist/startup.d.ts.map +1 -1
- package/dist/startup.js +179 -10
- package/dist/startup.js.map +1 -1
- package/dist/subagents/index.d.ts +2 -0
- package/dist/subagents/index.d.ts.map +1 -0
- package/dist/subagents/index.js +2 -0
- package/dist/subagents/index.js.map +1 -0
- package/dist/subagents/service.d.ts +50 -0
- package/dist/subagents/service.d.ts.map +1 -0
- package/dist/subagents/service.js +521 -0
- package/dist/subagents/service.js.map +1 -0
- package/dist/ui-host.d.ts +125 -0
- package/dist/ui-host.d.ts.map +1 -0
- package/dist/ui-host.js +275 -0
- package/dist/ui-host.js.map +1 -0
- package/dist/web/assets/index-BwfuGMvv.css +1 -0
- package/dist/web/assets/index-DPUaJqFJ.js +41 -0
- package/dist/web/assets/index-DPUaJqFJ.js.map +1 -0
- package/dist/web/index.html +14 -0
- package/dist/web-command.d.ts +11 -0
- package/dist/web-command.d.ts.map +1 -0
- package/dist/web-command.js +114 -0
- package/dist/web-command.js.map +1 -0
- package/dist/web-frontend.d.ts +73 -0
- package/dist/web-frontend.d.ts.map +1 -0
- package/dist/web-frontend.js +249 -0
- package/dist/web-frontend.js.map +1 -0
- package/dist/web.d.ts +254 -0
- package/dist/web.d.ts.map +1 -0
- package/dist/web.js +740 -0
- package/dist/web.js.map +1 -0
- package/dist/webui-entry.d.ts +3 -0
- package/dist/webui-entry.d.ts.map +1 -0
- package/dist/webui-entry.js +73 -0
- package/dist/webui-entry.js.map +1 -0
- package/dist/webui.d.ts +91 -0
- package/dist/webui.d.ts.map +1 -0
- package/dist/webui.js +882 -0
- package/dist/webui.js.map +1 -0
- package/package.json +89 -8
package/dist/startup.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { mkdir, readFile, rename, unlink, writeFile } from "node:fs/promises";
|
|
2
3
|
import { homedir } from "node:os";
|
|
3
4
|
import { join } from "node:path";
|
|
4
5
|
import { createAnthropicProvider, createDeepSeekProvider, createFauxProvider, createKimiProvider, createOpenAIChatCompletionsProvider, createOpenAIProvider, createZhipuProvider, findBuiltinModel, } from "@di-code/ai";
|
|
@@ -136,12 +137,23 @@ function parseModels(value, path, providerId, providerApi, providerBaseUrl, sett
|
|
|
136
137
|
: configuredReasoningEfforts === undefined
|
|
137
138
|
? undefined
|
|
138
139
|
: [...configuredReasoningEfforts];
|
|
140
|
+
const defaultReasoningEffort = model.defaultReasoningEffort;
|
|
141
|
+
if (defaultReasoningEffort !== undefined &&
|
|
142
|
+
(typeof defaultReasoningEffort !== "string" ||
|
|
143
|
+
!reasoningEfforts?.includes(defaultReasoningEffort))) {
|
|
144
|
+
throw new Error(`${settingsPath}: ${modelPath}.defaultReasoningEffort must be included in reasoningEfforts`);
|
|
145
|
+
}
|
|
139
146
|
const baseUrl = optionalString(model.baseUrl, `${modelPath}.baseUrl`, settingsPath) ?? providerBaseUrl;
|
|
140
147
|
const id = requiredString(model.id, `${modelPath}.id`, settingsPath);
|
|
141
148
|
const chatCompletionsCompat = parseChatCompletionsCompat(model.chatCompletionsCompat, `${modelPath}.chatCompletionsCompat`, settingsPath);
|
|
142
149
|
if (chatCompletionsCompat !== undefined && typedApi !== "openai-chat-completions") {
|
|
143
150
|
throw new Error(`${settingsPath}: ${modelPath}.chatCompletionsCompat requires api "openai-chat-completions"`);
|
|
144
151
|
}
|
|
152
|
+
const contextWindow = positiveInteger(model.contextWindow, `${modelPath}.contextWindow`, 128_000, settingsPath);
|
|
153
|
+
const maxOutputTokens = positiveInteger(model.maxTokens ?? model.maxOutputTokens, `${modelPath}.maxTokens`, 16_384, settingsPath);
|
|
154
|
+
if (maxOutputTokens >= contextWindow) {
|
|
155
|
+
throw new Error(`${settingsPath}: ${modelPath}.maxTokens must be smaller than contextWindow`);
|
|
156
|
+
}
|
|
145
157
|
return {
|
|
146
158
|
id,
|
|
147
159
|
name: requiredString(model.name ?? id, `${modelPath}.name`, settingsPath),
|
|
@@ -151,11 +163,14 @@ function parseModels(value, path, providerId, providerApi, providerBaseUrl, sett
|
|
|
151
163
|
input: [...input],
|
|
152
164
|
reasoning: model.reasoning ?? false,
|
|
153
165
|
...(reasoningEfforts ? { reasoningEfforts } : {}),
|
|
166
|
+
...(defaultReasoningEffort
|
|
167
|
+
? { defaultReasoningEffort: defaultReasoningEffort }
|
|
168
|
+
: {}),
|
|
154
169
|
...(chatCompletionsCompat ? { chatCompletionsCompat } : {}),
|
|
155
170
|
...(model.cacheRetention === "long" ? { cacheRetention: "long" } : {}),
|
|
156
171
|
...(model.sessionAffinity === "codex" ? { sessionAffinity: "codex" } : {}),
|
|
157
|
-
contextWindow
|
|
158
|
-
maxOutputTokens
|
|
172
|
+
contextWindow,
|
|
173
|
+
maxOutputTokens,
|
|
159
174
|
cost: {
|
|
160
175
|
input: nonNegativeNumber(prices.input, `${modelPath}.cost.input`, 0, settingsPath) / 1_000_000,
|
|
161
176
|
output: nonNegativeNumber(prices.output, `${modelPath}.cost.output`, 0, settingsPath) / 1_000_000,
|
|
@@ -227,6 +242,7 @@ function serializeModel(model) {
|
|
|
227
242
|
input: model.input,
|
|
228
243
|
reasoning: model.reasoning,
|
|
229
244
|
...(model.reasoningEfforts ? { reasoningEfforts: model.reasoningEfforts } : {}),
|
|
245
|
+
...(model.defaultReasoningEffort ? { defaultReasoningEffort: model.defaultReasoningEffort } : {}),
|
|
230
246
|
...(model.chatCompletionsCompat ? { chatCompletionsCompat: model.chatCompletionsCompat } : {}),
|
|
231
247
|
...(model.cacheRetention ? { cacheRetention: model.cacheRetention } : {}),
|
|
232
248
|
...(model.sessionAffinity ? { sessionAffinity: model.sessionAffinity } : {}),
|
|
@@ -262,16 +278,49 @@ function parseSettings(value, settingsPath) {
|
|
|
262
278
|
? undefined
|
|
263
279
|
: requiredString(record.defaultProvider, "defaultProvider", settingsPath);
|
|
264
280
|
const defaultModel = record.defaultModel === undefined ? undefined : requiredString(record.defaultModel, "defaultModel", settingsPath);
|
|
281
|
+
const thinkingLevels = parseThinkingLevels(record.thinkingLevels, settingsPath);
|
|
265
282
|
if (record.locale !== undefined && !isLocale(record.locale)) {
|
|
266
283
|
throw new Error(`${settingsPath}: locale must be "en" or "zh-CN"`);
|
|
267
284
|
}
|
|
285
|
+
if (record.permissionMode !== undefined &&
|
|
286
|
+
record.permissionMode !== "ask" &&
|
|
287
|
+
record.permissionMode !== "allow" &&
|
|
288
|
+
record.permissionMode !== "deny") {
|
|
289
|
+
throw new Error(`${settingsPath}: permissionMode must be "ask", "allow", or "deny"`);
|
|
290
|
+
}
|
|
268
291
|
return {
|
|
269
292
|
providers,
|
|
270
293
|
...(defaultProvider === undefined ? {} : { defaultProvider }),
|
|
271
294
|
...(defaultModel === undefined ? {} : { defaultModel }),
|
|
295
|
+
...(thinkingLevels === undefined ? {} : { thinkingLevels }),
|
|
272
296
|
...(record.locale === undefined ? {} : { locale: record.locale }),
|
|
297
|
+
...(record.permissionMode === undefined ? {} : { permissionMode: record.permissionMode }),
|
|
273
298
|
};
|
|
274
299
|
}
|
|
300
|
+
function parseThinkingLevels(value, settingsPath) {
|
|
301
|
+
if (value === undefined)
|
|
302
|
+
return undefined;
|
|
303
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
304
|
+
throw new Error(`${settingsPath}: thinkingLevels must be an object`);
|
|
305
|
+
}
|
|
306
|
+
const preferences = {};
|
|
307
|
+
for (const [providerId, models] of Object.entries(value)) {
|
|
308
|
+
requiredString(providerId, "thinkingLevels provider ID", settingsPath);
|
|
309
|
+
if (typeof models !== "object" || models === null || Array.isArray(models)) {
|
|
310
|
+
throw new Error(`${settingsPath}: thinkingLevels.${providerId} must be an object`);
|
|
311
|
+
}
|
|
312
|
+
const modelPreferences = {};
|
|
313
|
+
for (const [modelId, level] of Object.entries(models)) {
|
|
314
|
+
requiredString(modelId, `thinkingLevels.${providerId} model ID`, settingsPath);
|
|
315
|
+
if (level !== "low" && level !== "medium" && level !== "high" && level !== "max") {
|
|
316
|
+
throw new Error(`${settingsPath}: thinkingLevels.${providerId}.${modelId} must be a valid thinking level`);
|
|
317
|
+
}
|
|
318
|
+
modelPreferences[modelId] = level;
|
|
319
|
+
}
|
|
320
|
+
preferences[providerId] = modelPreferences;
|
|
321
|
+
}
|
|
322
|
+
return preferences;
|
|
323
|
+
}
|
|
275
324
|
async function readSettingsFile(path, displayPath) {
|
|
276
325
|
try {
|
|
277
326
|
const source = await readFile(path, "utf8");
|
|
@@ -304,14 +353,45 @@ function mergeSettings(globalSettings, projectSettings) {
|
|
|
304
353
|
const defaultProvider = projectSettings?.defaultProvider ?? globalSettings?.defaultProvider;
|
|
305
354
|
const defaultModel = projectSettings?.defaultModel ??
|
|
306
355
|
(projectSettings?.defaultProvider === undefined ? globalSettings?.defaultModel : undefined);
|
|
356
|
+
const thinkingLevels = mergeThinkingLevels(globalSettings?.thinkingLevels, projectSettings?.thinkingLevels);
|
|
307
357
|
const locale = globalSettings?.locale;
|
|
308
358
|
return {
|
|
309
359
|
providers,
|
|
310
360
|
...(defaultProvider === undefined ? {} : { defaultProvider }),
|
|
311
361
|
...(defaultModel === undefined ? {} : { defaultModel }),
|
|
362
|
+
...(thinkingLevels === undefined ? {} : { thinkingLevels }),
|
|
312
363
|
...(locale === undefined ? {} : { locale }),
|
|
364
|
+
...(globalSettings?.permissionMode === undefined ? {} : { permissionMode: globalSettings.permissionMode }),
|
|
313
365
|
};
|
|
314
366
|
}
|
|
367
|
+
function mergeThinkingLevels(globalPreferences, workspacePreferences) {
|
|
368
|
+
if (globalPreferences === undefined && workspacePreferences === undefined)
|
|
369
|
+
return undefined;
|
|
370
|
+
const result = {};
|
|
371
|
+
for (const [providerId, models] of Object.entries(globalPreferences ?? {}))
|
|
372
|
+
result[providerId] = { ...models };
|
|
373
|
+
for (const [providerId, models] of Object.entries(workspacePreferences ?? {})) {
|
|
374
|
+
result[providerId] = { ...result[providerId], ...models };
|
|
375
|
+
}
|
|
376
|
+
return result;
|
|
377
|
+
}
|
|
378
|
+
async function writeSettingsFile(agentDir, settings) {
|
|
379
|
+
const settingsFilePath = join(agentDir, SETTINGS_FILE_NAME);
|
|
380
|
+
await mkdir(agentDir, { recursive: true, mode: 0o700 });
|
|
381
|
+
const temporaryPath = `${settingsFilePath}.tmp-${randomUUID()}`;
|
|
382
|
+
try {
|
|
383
|
+
await writeFile(temporaryPath, `${JSON.stringify(settings, null, "\t")}\n`, { encoding: "utf8", mode: 0o600 });
|
|
384
|
+
await rename(temporaryPath, settingsFilePath);
|
|
385
|
+
}
|
|
386
|
+
finally {
|
|
387
|
+
try {
|
|
388
|
+
await unlink(temporaryPath);
|
|
389
|
+
}
|
|
390
|
+
catch {
|
|
391
|
+
// The temporary file was renamed or was never created.
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
315
395
|
/** Persists a user-level terminal language preference without changing project settings. */
|
|
316
396
|
export async function saveGlobalLocale(agentDir, locale) {
|
|
317
397
|
const settingsFilePath = join(agentDir, SETTINGS_FILE_NAME);
|
|
@@ -320,10 +400,19 @@ export async function saveGlobalLocale(agentDir, locale) {
|
|
|
320
400
|
providers: existingSettings?.providers ?? {},
|
|
321
401
|
...(existingSettings?.defaultProvider === undefined ? {} : { defaultProvider: existingSettings.defaultProvider }),
|
|
322
402
|
...(existingSettings?.defaultModel === undefined ? {} : { defaultModel: existingSettings.defaultModel }),
|
|
403
|
+
...(existingSettings?.thinkingLevels === undefined ? {} : { thinkingLevels: existingSettings.thinkingLevels }),
|
|
323
404
|
locale,
|
|
405
|
+
...(existingSettings?.permissionMode === undefined ? {} : { permissionMode: existingSettings.permissionMode }),
|
|
324
406
|
};
|
|
325
|
-
await
|
|
326
|
-
|
|
407
|
+
await writeSettingsFile(agentDir, settings);
|
|
408
|
+
}
|
|
409
|
+
/** Persists the default permission mode; the active Session keeps its own runtime until next turn. */
|
|
410
|
+
export async function saveGlobalPermissionMode(agentDir, permissionMode) {
|
|
411
|
+
const settingsFilePath = join(agentDir, SETTINGS_FILE_NAME);
|
|
412
|
+
const existingSettings = await readSettingsFile(settingsFilePath, settingsFilePath);
|
|
413
|
+
if (permissionMode !== "ask" && permissionMode !== "allow" && permissionMode !== "deny")
|
|
414
|
+
throw new Error(`${settingsFilePath}: permissionMode must be "ask", "allow", or "deny"`);
|
|
415
|
+
await writeSettingsFile(agentDir, { ...mergeSettings(existingSettings, undefined), permissionMode });
|
|
327
416
|
}
|
|
328
417
|
export async function saveGlobalProviderApiKey(agentDir, providerId, api, apiKey, modelId) {
|
|
329
418
|
const settingsFilePath = join(agentDir, SETTINGS_FILE_NAME);
|
|
@@ -336,8 +425,80 @@ export async function saveGlobalProviderApiKey(agentDir, providerId, api, apiKey
|
|
|
336
425
|
defaultProvider: providerId,
|
|
337
426
|
...(modelId === undefined ? {} : { defaultModel: modelId }),
|
|
338
427
|
});
|
|
339
|
-
await
|
|
340
|
-
|
|
428
|
+
await writeSettingsFile(agentDir, settings);
|
|
429
|
+
}
|
|
430
|
+
/** Persists the interactive model selection without changing credentials or Provider configuration. */
|
|
431
|
+
export async function saveGlobalModelSelection(agentDir, providerId, modelId) {
|
|
432
|
+
const settingsFilePath = join(agentDir, SETTINGS_FILE_NAME);
|
|
433
|
+
const normalizedProviderId = requiredString(providerId, "providerId", settingsFilePath);
|
|
434
|
+
const normalizedModelId = requiredString(modelId, "modelId", settingsFilePath);
|
|
435
|
+
const existingSettings = await readSettingsFile(settingsFilePath, settingsFilePath);
|
|
436
|
+
const settings = mergeSettings(existingSettings, {
|
|
437
|
+
providers: {},
|
|
438
|
+
defaultProvider: normalizedProviderId,
|
|
439
|
+
defaultModel: normalizedModelId,
|
|
440
|
+
});
|
|
441
|
+
await writeSettingsFile(agentDir, settings);
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Persists a runtime preference in an existing workspace settings file, falling back to user settings when the
|
|
445
|
+
* workspace has no settings file. This keeps an explicit WebUI selection aligned with startup resolution.
|
|
446
|
+
*/
|
|
447
|
+
export async function saveScopedModelSelection(cwd, agentDir, providerId, modelId) {
|
|
448
|
+
const workspaceDir = join(cwd, ".di-code");
|
|
449
|
+
const workspacePath = join(cwd, SETTINGS_PATH);
|
|
450
|
+
const workspaceSettings = await readSettingsFile(workspacePath, SETTINGS_PATH);
|
|
451
|
+
if (workspaceSettings === undefined) {
|
|
452
|
+
await saveGlobalModelSelection(agentDir, providerId, modelId);
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
const normalizedProviderId = requiredString(providerId, "providerId", SETTINGS_PATH);
|
|
456
|
+
const normalizedModelId = requiredString(modelId, "modelId", SETTINGS_PATH);
|
|
457
|
+
await writeSettingsFile(workspaceDir, {
|
|
458
|
+
...workspaceSettings,
|
|
459
|
+
defaultProvider: normalizedProviderId,
|
|
460
|
+
defaultModel: normalizedModelId,
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
/** Persists a per-provider/model thinking preference in user settings. */
|
|
464
|
+
export async function saveGlobalThinkingLevel(agentDir, providerId, modelId, level) {
|
|
465
|
+
const settingsFilePath = join(agentDir, SETTINGS_FILE_NAME);
|
|
466
|
+
const normalizedProviderId = requiredString(providerId, "providerId", settingsFilePath);
|
|
467
|
+
const normalizedModelId = requiredString(modelId, "modelId", settingsFilePath);
|
|
468
|
+
const existingSettings = await readSettingsFile(settingsFilePath, settingsFilePath);
|
|
469
|
+
const settings = {
|
|
470
|
+
...mergeSettings(existingSettings, undefined),
|
|
471
|
+
thinkingLevels: {
|
|
472
|
+
...(existingSettings?.thinkingLevels ?? {}),
|
|
473
|
+
[normalizedProviderId]: {
|
|
474
|
+
...(existingSettings?.thinkingLevels?.[normalizedProviderId] ?? {}),
|
|
475
|
+
[normalizedModelId]: level,
|
|
476
|
+
},
|
|
477
|
+
},
|
|
478
|
+
};
|
|
479
|
+
await writeSettingsFile(agentDir, settings);
|
|
480
|
+
}
|
|
481
|
+
/** Persists a thinking preference beside an existing workspace model selection, or in user settings as a fallback. */
|
|
482
|
+
export async function saveScopedThinkingLevel(cwd, agentDir, providerId, modelId, level) {
|
|
483
|
+
const workspaceDir = join(cwd, ".di-code");
|
|
484
|
+
const workspacePath = join(cwd, SETTINGS_PATH);
|
|
485
|
+
const workspaceSettings = await readSettingsFile(workspacePath, SETTINGS_PATH);
|
|
486
|
+
if (workspaceSettings === undefined) {
|
|
487
|
+
await saveGlobalThinkingLevel(agentDir, providerId, modelId, level);
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
const normalizedProviderId = requiredString(providerId, "providerId", SETTINGS_PATH);
|
|
491
|
+
const normalizedModelId = requiredString(modelId, "modelId", SETTINGS_PATH);
|
|
492
|
+
await writeSettingsFile(workspaceDir, {
|
|
493
|
+
...workspaceSettings,
|
|
494
|
+
thinkingLevels: {
|
|
495
|
+
...(workspaceSettings.thinkingLevels ?? {}),
|
|
496
|
+
[normalizedProviderId]: {
|
|
497
|
+
...(workspaceSettings.thinkingLevels?.[normalizedProviderId] ?? {}),
|
|
498
|
+
[normalizedModelId]: level,
|
|
499
|
+
},
|
|
500
|
+
},
|
|
501
|
+
});
|
|
341
502
|
}
|
|
342
503
|
/**
|
|
343
504
|
* Replaces the user-managed `custom` provider while retaining other global
|
|
@@ -361,8 +522,7 @@ export async function saveGlobalCustomProvider(agentDir, input) {
|
|
|
361
522
|
defaultProvider: "custom",
|
|
362
523
|
defaultModel: configuration.models?.[0]?.id,
|
|
363
524
|
});
|
|
364
|
-
await
|
|
365
|
-
await writeFile(settingsFilePath, `${JSON.stringify(settings, null, "\t")}\n`, { encoding: "utf8", mode: 0o600 });
|
|
525
|
+
await writeSettingsFile(agentDir, settings);
|
|
366
526
|
return configuration;
|
|
367
527
|
}
|
|
368
528
|
/**
|
|
@@ -388,9 +548,11 @@ export async function removeGlobalProviderApiKey(agentDir, providerId) {
|
|
|
388
548
|
...(clearsDefault || existingSettings.defaultModel === undefined
|
|
389
549
|
? {}
|
|
390
550
|
: { defaultModel: existingSettings.defaultModel }),
|
|
551
|
+
...(existingSettings.thinkingLevels === undefined ? {} : { thinkingLevels: existingSettings.thinkingLevels }),
|
|
391
552
|
...(existingSettings.locale === undefined ? {} : { locale: existingSettings.locale }),
|
|
553
|
+
...(existingSettings.permissionMode === undefined ? {} : { permissionMode: existingSettings.permissionMode }),
|
|
392
554
|
};
|
|
393
|
-
await
|
|
555
|
+
await writeSettingsFile(agentDir, settings);
|
|
394
556
|
return true;
|
|
395
557
|
}
|
|
396
558
|
function resolveConfigValue(value, env) {
|
|
@@ -561,6 +723,11 @@ export function resolveStartupRuntime(env, providers, defaults = {}) {
|
|
|
561
723
|
return builtInRuntime;
|
|
562
724
|
throw new Error(`Unknown configured provider "${selectedProviderId}". Available providers: ${providers.map((provider) => provider.id).join(", ")}.`);
|
|
563
725
|
}
|
|
726
|
+
/** Returns a stored preference only when the selected model still supports it. */
|
|
727
|
+
export function resolveThinkingLevelPreference(configuration, runtime) {
|
|
728
|
+
const preference = configuration?.thinkingLevels?.[runtime.provider.id]?.[runtime.model.id];
|
|
729
|
+
return preference !== undefined && runtime.model.reasoningEfforts?.includes(preference) ? preference : undefined;
|
|
730
|
+
}
|
|
564
731
|
export async function loadStartupConfiguration(cwd, environment = process.env, agentDir = join(homedir(), ".di-code")) {
|
|
565
732
|
const [globalSettings, projectSettings] = await Promise.all([
|
|
566
733
|
readSettingsFile(join(agentDir, SETTINGS_FILE_NAME), join(agentDir, SETTINGS_FILE_NAME)),
|
|
@@ -586,7 +753,9 @@ export async function loadStartupConfiguration(cwd, environment = process.env, a
|
|
|
586
753
|
return {
|
|
587
754
|
environment,
|
|
588
755
|
providers,
|
|
756
|
+
...(settings.thinkingLevels === undefined ? {} : { thinkingLevels: settings.thinkingLevels }),
|
|
589
757
|
...(locale === undefined ? {} : { locale }),
|
|
758
|
+
...(settings.permissionMode === undefined ? {} : { permissionMode: settings.permissionMode }),
|
|
590
759
|
...(defaults === undefined ? {} : { defaults }),
|
|
591
760
|
};
|
|
592
761
|
}
|