@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/dist/startup.js
CHANGED
|
@@ -1,119 +1,229 @@
|
|
|
1
|
-
import { readFile } from "node:fs/promises";
|
|
1
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { homedir } from "node:os";
|
|
2
3
|
import { join } from "node:path";
|
|
3
|
-
import { createAnthropicProvider, createDeepSeekProvider, createFauxProvider, createOpenAIProvider, createZhipuProvider, } from "@di-code/ai";
|
|
4
|
+
import { createAnthropicProvider, createDeepSeekProvider, createFauxProvider, createOpenAIChatCompletionsProvider, createOpenAIProvider, createZhipuProvider, } from "@di-code/ai";
|
|
4
5
|
const FAUX_RESPONSES = [
|
|
5
|
-
{
|
|
6
|
+
{
|
|
7
|
+
type: "success",
|
|
8
|
+
content: [
|
|
9
|
+
{
|
|
10
|
+
type: "text",
|
|
11
|
+
text: "你好,我是di-code,一个面向终端的 TypeScript AI Coding Agent,支持多 Provider 流式对话、工具调用、JSONL 会话持久化、交互式 TUI、插件扩展与 JSONL RPC 集成。",
|
|
12
|
+
},
|
|
13
|
+
],
|
|
14
|
+
},
|
|
15
|
+
{ type: "success", content: [{ type: "text", text: "当前回复为faux数据" }] },
|
|
6
16
|
];
|
|
7
|
-
const
|
|
17
|
+
const SETTINGS_FILE_NAME = "settings.json";
|
|
18
|
+
const SETTINGS_PATH = join(".di-code", SETTINGS_FILE_NAME);
|
|
8
19
|
export function resolveStartupArgs(args) {
|
|
9
20
|
return args.length === 0 ? ["--interactive"] : args;
|
|
10
21
|
}
|
|
11
|
-
function optionalString(value, path) {
|
|
22
|
+
function optionalString(value, path, settingsPath) {
|
|
12
23
|
if (value === undefined)
|
|
13
24
|
return undefined;
|
|
14
25
|
if (typeof value !== "string")
|
|
15
|
-
throw new Error(`${
|
|
26
|
+
throw new Error(`${settingsPath}: ${path} must be a string`);
|
|
16
27
|
return value;
|
|
17
28
|
}
|
|
18
|
-
function requiredString(value, path) {
|
|
19
|
-
const result = optionalString(value, path);
|
|
29
|
+
function requiredString(value, path, settingsPath = SETTINGS_PATH) {
|
|
30
|
+
const result = optionalString(value, path, settingsPath);
|
|
20
31
|
if (!result?.trim())
|
|
21
|
-
throw new Error(`${
|
|
32
|
+
throw new Error(`${settingsPath}: ${path} must be a non-empty string`);
|
|
22
33
|
return result.trim();
|
|
23
34
|
}
|
|
24
|
-
function positiveInteger(value, path, fallback) {
|
|
35
|
+
function positiveInteger(value, path, fallback, settingsPath) {
|
|
25
36
|
const result = value ?? fallback;
|
|
26
37
|
if (!Number.isInteger(result) || result <= 0) {
|
|
27
|
-
throw new Error(`${
|
|
38
|
+
throw new Error(`${settingsPath}: ${path} must be a positive integer`);
|
|
28
39
|
}
|
|
29
40
|
return result;
|
|
30
41
|
}
|
|
31
|
-
function nonNegativeNumber(value, path, fallback) {
|
|
42
|
+
function nonNegativeNumber(value, path, fallback, settingsPath) {
|
|
32
43
|
const result = value ?? fallback;
|
|
33
44
|
if (typeof result !== "number" || !Number.isFinite(result) || result < 0) {
|
|
34
|
-
throw new Error(`${
|
|
45
|
+
throw new Error(`${settingsPath}: ${path} must be a non-negative finite number`);
|
|
35
46
|
}
|
|
36
47
|
return result;
|
|
37
48
|
}
|
|
38
|
-
function parseModels(value, path, providerId, providerApi, providerBaseUrl) {
|
|
49
|
+
function parseModels(value, path, providerId, providerApi, providerBaseUrl, settingsPath) {
|
|
39
50
|
if (value === undefined)
|
|
40
51
|
return undefined;
|
|
41
52
|
if (!Array.isArray(value))
|
|
42
|
-
throw new Error(`${
|
|
53
|
+
throw new Error(`${settingsPath}: ${path} must be an array`);
|
|
43
54
|
return value.map((entry, index) => {
|
|
44
55
|
const modelPath = `${path}[${index}]`;
|
|
45
56
|
if (typeof entry !== "object" || entry === null || Array.isArray(entry)) {
|
|
46
|
-
throw new Error(`${
|
|
57
|
+
throw new Error(`${settingsPath}: ${modelPath} must be an object`);
|
|
47
58
|
}
|
|
48
59
|
const model = entry;
|
|
49
60
|
const input = model.input ?? ["text"];
|
|
50
61
|
if (!Array.isArray(input) || input.length === 0 || input.some((item) => item !== "text" && item !== "image")) {
|
|
51
|
-
throw new Error(`${
|
|
62
|
+
throw new Error(`${settingsPath}: ${modelPath}.input must contain text and/or image`);
|
|
52
63
|
}
|
|
53
64
|
const cost = model.cost ?? {};
|
|
54
65
|
if (typeof cost !== "object" || cost === null || Array.isArray(cost)) {
|
|
55
|
-
throw new Error(`${
|
|
66
|
+
throw new Error(`${settingsPath}: ${modelPath}.cost must be an object`);
|
|
56
67
|
}
|
|
57
68
|
const prices = cost;
|
|
58
69
|
if (model.reasoning !== undefined && typeof model.reasoning !== "boolean") {
|
|
59
|
-
throw new Error(`${
|
|
70
|
+
throw new Error(`${settingsPath}: ${modelPath}.reasoning must be a boolean`);
|
|
71
|
+
}
|
|
72
|
+
const configuredReasoningEfforts = model.reasoningEfforts;
|
|
73
|
+
if (configuredReasoningEfforts !== undefined) {
|
|
74
|
+
if (!Array.isArray(configuredReasoningEfforts) || configuredReasoningEfforts.length === 0) {
|
|
75
|
+
throw new Error(`${settingsPath}: ${modelPath}.reasoningEfforts must be a non-empty array`);
|
|
76
|
+
}
|
|
77
|
+
if (model.reasoning !== true ||
|
|
78
|
+
configuredReasoningEfforts.some((effort) => effort !== "low" && effort !== "medium" && effort !== "high") ||
|
|
79
|
+
new Set(configuredReasoningEfforts).size !== configuredReasoningEfforts.length) {
|
|
80
|
+
throw new Error(`${settingsPath}: ${modelPath}.reasoningEfforts requires reasoning=true and unique low, medium, or high values`);
|
|
81
|
+
}
|
|
60
82
|
}
|
|
61
83
|
if (model.cacheRetention !== undefined && model.cacheRetention !== "long") {
|
|
62
|
-
throw new Error(`${
|
|
84
|
+
throw new Error(`${settingsPath}: ${modelPath}.cacheRetention must be "long" when provided`);
|
|
63
85
|
}
|
|
64
86
|
if (model.sessionAffinity !== undefined && model.sessionAffinity !== "codex") {
|
|
65
|
-
throw new Error(`${
|
|
87
|
+
throw new Error(`${settingsPath}: ${modelPath}.sessionAffinity must be "codex" when provided`);
|
|
66
88
|
}
|
|
67
|
-
const api = optionalString(model.api, `${modelPath}.api
|
|
89
|
+
const api = optionalString(model.api, `${modelPath}.api`, settingsPath) ?? providerApi;
|
|
68
90
|
if (!api)
|
|
69
|
-
throw new Error(`${
|
|
70
|
-
|
|
71
|
-
|
|
91
|
+
throw new Error(`${settingsPath}: ${modelPath}.api is required`);
|
|
92
|
+
if (!["faux", "openai-responses", "openai-chat-completions", "anthropic-messages"].includes(api)) {
|
|
93
|
+
throw new Error(`${settingsPath}: ${modelPath}.api is unsupported`);
|
|
94
|
+
}
|
|
95
|
+
const typedApi = api;
|
|
96
|
+
const reasoningEfforts = configuredReasoningEfforts === undefined && model.reasoning === true && api === "openai-responses"
|
|
97
|
+
? ["low", "medium", "high"]
|
|
98
|
+
: configuredReasoningEfforts === undefined
|
|
99
|
+
? undefined
|
|
100
|
+
: [...configuredReasoningEfforts];
|
|
101
|
+
const baseUrl = optionalString(model.baseUrl, `${modelPath}.baseUrl`, settingsPath) ?? providerBaseUrl;
|
|
102
|
+
const id = requiredString(model.id, `${modelPath}.id`, settingsPath);
|
|
72
103
|
return {
|
|
73
104
|
id,
|
|
74
|
-
name: requiredString(model.name ?? id, `${modelPath}.name
|
|
105
|
+
name: requiredString(model.name ?? id, `${modelPath}.name`, settingsPath),
|
|
75
106
|
provider: providerId,
|
|
76
|
-
api,
|
|
107
|
+
api: typedApi,
|
|
77
108
|
...(baseUrl === undefined ? {} : { baseUrl }),
|
|
78
109
|
input: [...input],
|
|
79
110
|
reasoning: model.reasoning ?? false,
|
|
111
|
+
...(reasoningEfforts ? { reasoningEfforts } : {}),
|
|
80
112
|
...(model.cacheRetention === "long" ? { cacheRetention: "long" } : {}),
|
|
81
113
|
...(model.sessionAffinity === "codex" ? { sessionAffinity: "codex" } : {}),
|
|
82
|
-
contextWindow: positiveInteger(model.contextWindow, `${modelPath}.contextWindow`, 128_000),
|
|
83
|
-
maxOutputTokens: positiveInteger(model.maxTokens ?? model.maxOutputTokens, `${modelPath}.maxTokens`, 16_384),
|
|
114
|
+
contextWindow: positiveInteger(model.contextWindow, `${modelPath}.contextWindow`, 128_000, settingsPath),
|
|
115
|
+
maxOutputTokens: positiveInteger(model.maxTokens ?? model.maxOutputTokens, `${modelPath}.maxTokens`, 16_384, settingsPath),
|
|
84
116
|
cost: {
|
|
85
|
-
input: nonNegativeNumber(prices.input, `${modelPath}.cost.input`, 0) / 1_000_000,
|
|
86
|
-
output: nonNegativeNumber(prices.output, `${modelPath}.cost.output`, 0) / 1_000_000,
|
|
87
|
-
cacheRead: nonNegativeNumber(prices.cacheRead, `${modelPath}.cost.cacheRead`, 0) / 1_000_000,
|
|
88
|
-
cacheWrite: nonNegativeNumber(prices.cacheWrite, `${modelPath}.cost.cacheWrite`, 0) / 1_000_000,
|
|
117
|
+
input: nonNegativeNumber(prices.input, `${modelPath}.cost.input`, 0, settingsPath) / 1_000_000,
|
|
118
|
+
output: nonNegativeNumber(prices.output, `${modelPath}.cost.output`, 0, settingsPath) / 1_000_000,
|
|
119
|
+
cacheRead: nonNegativeNumber(prices.cacheRead, `${modelPath}.cost.cacheRead`, 0, settingsPath) / 1_000_000,
|
|
120
|
+
cacheWrite: nonNegativeNumber(prices.cacheWrite, `${modelPath}.cost.cacheWrite`, 0, settingsPath) / 1_000_000,
|
|
89
121
|
},
|
|
90
122
|
};
|
|
91
123
|
});
|
|
92
124
|
}
|
|
93
|
-
function parseSettings(value) {
|
|
125
|
+
function parseSettings(value, settingsPath) {
|
|
94
126
|
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
95
|
-
throw new Error(`${
|
|
127
|
+
throw new Error(`${settingsPath}: root value must be an object`);
|
|
96
128
|
}
|
|
97
129
|
const record = value;
|
|
98
130
|
const providersValue = record.providers;
|
|
99
131
|
if (typeof providersValue !== "object" || providersValue === null || Array.isArray(providersValue)) {
|
|
100
|
-
throw new Error(`${
|
|
132
|
+
throw new Error(`${settingsPath}: providers must be an object`);
|
|
101
133
|
}
|
|
102
134
|
const providers = {};
|
|
103
135
|
for (const [id, entry] of Object.entries(providersValue)) {
|
|
104
136
|
if (typeof entry !== "object" || entry === null || Array.isArray(entry)) {
|
|
105
|
-
throw new Error(`${
|
|
137
|
+
throw new Error(`${settingsPath}: providers.${id} must be an object`);
|
|
106
138
|
}
|
|
107
139
|
const provider = entry;
|
|
108
140
|
providers[id] = {
|
|
109
|
-
name: optionalString(provider.name, `providers.${id}.name
|
|
110
|
-
baseUrl: optionalString(provider.baseUrl, `providers.${id}.baseUrl
|
|
111
|
-
apiKey: optionalString(provider.apiKey, `providers.${id}.apiKey
|
|
112
|
-
api: optionalString(provider.api, `providers.${id}.api
|
|
141
|
+
name: optionalString(provider.name, `providers.${id}.name`, settingsPath),
|
|
142
|
+
baseUrl: optionalString(provider.baseUrl, `providers.${id}.baseUrl`, settingsPath),
|
|
143
|
+
apiKey: optionalString(provider.apiKey, `providers.${id}.apiKey`, settingsPath),
|
|
144
|
+
api: optionalString(provider.api, `providers.${id}.api`, settingsPath),
|
|
113
145
|
models: provider.models,
|
|
114
146
|
};
|
|
115
147
|
}
|
|
116
|
-
|
|
148
|
+
const defaultProvider = record.defaultProvider === undefined
|
|
149
|
+
? undefined
|
|
150
|
+
: requiredString(record.defaultProvider, "defaultProvider", settingsPath);
|
|
151
|
+
const defaultModel = record.defaultModel === undefined ? undefined : requiredString(record.defaultModel, "defaultModel", settingsPath);
|
|
152
|
+
return {
|
|
153
|
+
providers,
|
|
154
|
+
...(defaultProvider === undefined ? {} : { defaultProvider }),
|
|
155
|
+
...(defaultModel === undefined ? {} : { defaultModel }),
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
async function readSettingsFile(path, displayPath) {
|
|
159
|
+
try {
|
|
160
|
+
const source = await readFile(path, "utf8");
|
|
161
|
+
if (source.trim().length === 0)
|
|
162
|
+
return undefined;
|
|
163
|
+
return parseSettings(JSON.parse(source), displayPath);
|
|
164
|
+
}
|
|
165
|
+
catch (cause) {
|
|
166
|
+
if (cause instanceof Error && "code" in cause && cause.code === "ENOENT")
|
|
167
|
+
return undefined;
|
|
168
|
+
if (cause instanceof SyntaxError)
|
|
169
|
+
throw new Error(`${displayPath}: invalid JSON`, { cause });
|
|
170
|
+
throw cause;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
function mergeSettings(globalSettings, projectSettings) {
|
|
174
|
+
const globalProviders = globalSettings?.providers ?? {};
|
|
175
|
+
const projectProviders = projectSettings?.providers ?? {};
|
|
176
|
+
const providers = { ...globalProviders };
|
|
177
|
+
for (const [id, projectProvider] of Object.entries(projectProviders)) {
|
|
178
|
+
providers[id] = {
|
|
179
|
+
...globalProviders[id],
|
|
180
|
+
...(projectProvider.name === undefined ? {} : { name: projectProvider.name }),
|
|
181
|
+
...(projectProvider.baseUrl === undefined ? {} : { baseUrl: projectProvider.baseUrl }),
|
|
182
|
+
...(projectProvider.apiKey === undefined ? {} : { apiKey: projectProvider.apiKey }),
|
|
183
|
+
...(projectProvider.api === undefined ? {} : { api: projectProvider.api }),
|
|
184
|
+
...(projectProvider.models === undefined ? {} : { models: projectProvider.models }),
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
const defaultProvider = projectSettings?.defaultProvider ?? globalSettings?.defaultProvider;
|
|
188
|
+
const defaultModel = projectSettings?.defaultModel ??
|
|
189
|
+
(projectSettings?.defaultProvider === undefined ? globalSettings?.defaultModel : undefined);
|
|
190
|
+
return {
|
|
191
|
+
providers,
|
|
192
|
+
...(defaultProvider === undefined ? {} : { defaultProvider }),
|
|
193
|
+
...(defaultModel === undefined ? {} : { defaultModel }),
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
export async function saveGlobalProviderApiKey(agentDir, providerId, api, apiKey, modelId) {
|
|
197
|
+
const settingsFilePath = join(agentDir, SETTINGS_FILE_NAME);
|
|
198
|
+
const trimmedApiKey = apiKey.trim();
|
|
199
|
+
if (!trimmedApiKey)
|
|
200
|
+
throw new Error(`${settingsFilePath}: apiKey must be a non-empty string`);
|
|
201
|
+
const existingSettings = await readSettingsFile(settingsFilePath, settingsFilePath);
|
|
202
|
+
const settings = mergeSettings(existingSettings, {
|
|
203
|
+
providers: { [providerId]: { api, apiKey: trimmedApiKey } },
|
|
204
|
+
defaultProvider: providerId,
|
|
205
|
+
...(modelId === undefined ? {} : { defaultModel: modelId }),
|
|
206
|
+
});
|
|
207
|
+
await mkdir(agentDir, { recursive: true, mode: 0o700 });
|
|
208
|
+
await writeFile(settingsFilePath, `${JSON.stringify(settings, null, "\t")}\n`, { encoding: "utf8", mode: 0o600 });
|
|
209
|
+
}
|
|
210
|
+
/** Removes only the persisted credential for one provider; environment variables remain untouched. */
|
|
211
|
+
export async function removeGlobalProviderApiKey(agentDir, providerId) {
|
|
212
|
+
const settingsFilePath = join(agentDir, SETTINGS_FILE_NAME);
|
|
213
|
+
const existingSettings = await readSettingsFile(settingsFilePath, settingsFilePath);
|
|
214
|
+
const provider = existingSettings?.providers[providerId];
|
|
215
|
+
if (!provider || provider.apiKey === undefined)
|
|
216
|
+
return false;
|
|
217
|
+
const { apiKey: _apiKey, ...providerWithoutApiKey } = provider;
|
|
218
|
+
const settings = {
|
|
219
|
+
...existingSettings,
|
|
220
|
+
providers: {
|
|
221
|
+
...existingSettings.providers,
|
|
222
|
+
[providerId]: providerWithoutApiKey,
|
|
223
|
+
},
|
|
224
|
+
};
|
|
225
|
+
await writeFile(settingsFilePath, `${JSON.stringify(settings, null, "\t")}\n`, { encoding: "utf8", mode: 0o600 });
|
|
226
|
+
return true;
|
|
117
227
|
}
|
|
118
228
|
function resolveConfigValue(value, env) {
|
|
119
229
|
if (value === undefined)
|
|
@@ -176,10 +286,9 @@ function createBuiltInRuntime(env, providerId) {
|
|
|
176
286
|
}
|
|
177
287
|
function createConfiguredRuntime(env, configuration) {
|
|
178
288
|
if (configuration.api !== "openai-responses" &&
|
|
179
|
-
configuration.api !== "
|
|
180
|
-
configuration.api !== "zhipu-chat-completions" &&
|
|
289
|
+
configuration.api !== "openai-chat-completions" &&
|
|
181
290
|
configuration.api !== "anthropic-messages") {
|
|
182
|
-
throw new Error(`Unsupported API "${configuration.api ?? "missing"}" for provider "${configuration.id}". Expected openai-responses,
|
|
291
|
+
throw new Error(`Unsupported API "${configuration.api ?? "missing"}" for provider "${configuration.id}". Expected openai-responses, openai-chat-completions, or anthropic-messages.`);
|
|
183
292
|
}
|
|
184
293
|
if (configuration.id !== "openai" &&
|
|
185
294
|
configuration.id !== "deepseek" &&
|
|
@@ -188,46 +297,70 @@ function createConfiguredRuntime(env, configuration) {
|
|
|
188
297
|
!configuration.models) {
|
|
189
298
|
throw new Error(`${SETTINGS_PATH}: providers.${configuration.id}.models is required for a custom provider`);
|
|
190
299
|
}
|
|
191
|
-
const provider = configuration.api === "
|
|
192
|
-
?
|
|
193
|
-
env: configuration.id === "
|
|
300
|
+
const provider = configuration.api === "openai-chat-completions"
|
|
301
|
+
? createOpenAIChatCompletionsProvider({
|
|
302
|
+
env: configuration.id === "zhipu" || configuration.id === "deepseek"
|
|
194
303
|
? env
|
|
195
|
-
: Object.fromEntries(Object.entries(env).filter(([name]) => name !== "
|
|
304
|
+
: Object.fromEntries(Object.entries(env).filter(([name]) => name !== "OPENAI_API_KEY" && name !== "OPENAI_BASE_URL")),
|
|
196
305
|
models: configuration.models,
|
|
197
306
|
apiKey: resolveConfigValue(configuration.apiKey, env),
|
|
198
307
|
baseUrl: configuration.models ? undefined : configuration.baseUrl,
|
|
199
308
|
providerId: configuration.id,
|
|
200
|
-
name: configuration.name,
|
|
309
|
+
name: configuration.name ?? configuration.id,
|
|
310
|
+
...(configuration.id === "zhipu"
|
|
311
|
+
? {
|
|
312
|
+
apiKeyEnvironmentVariable: "ZAI_API_KEY",
|
|
313
|
+
baseUrlEnvironmentVariable: "ZHIPU_BASE_URL",
|
|
314
|
+
defaultBaseUrl: "https://open.bigmodel.cn/api/coding/paas/v4",
|
|
315
|
+
}
|
|
316
|
+
: configuration.id === "deepseek"
|
|
317
|
+
? {
|
|
318
|
+
apiKeyEnvironmentVariable: "DEEPSEEK_API_KEY",
|
|
319
|
+
baseUrlEnvironmentVariable: "DEEPSEEK_BASE_URL",
|
|
320
|
+
defaultBaseUrl: "https://api.deepseek.com",
|
|
321
|
+
}
|
|
322
|
+
: {}),
|
|
201
323
|
})
|
|
202
|
-
: configuration.
|
|
203
|
-
?
|
|
204
|
-
env
|
|
324
|
+
: configuration.api === "anthropic-messages"
|
|
325
|
+
? createAnthropicProvider({
|
|
326
|
+
env: configuration.id === "anthropic"
|
|
327
|
+
? env
|
|
328
|
+
: Object.fromEntries(Object.entries(env).filter(([name]) => name !== "ANTHROPIC_API_KEY" && name !== "ANTHROPIC_BASE_URL")),
|
|
205
329
|
models: configuration.models,
|
|
206
330
|
apiKey: resolveConfigValue(configuration.apiKey, env),
|
|
207
331
|
baseUrl: configuration.models ? undefined : configuration.baseUrl,
|
|
332
|
+
providerId: configuration.id,
|
|
333
|
+
name: configuration.name,
|
|
208
334
|
})
|
|
209
|
-
: configuration.id === "
|
|
210
|
-
?
|
|
335
|
+
: configuration.id === "deepseek"
|
|
336
|
+
? createDeepSeekProvider({
|
|
211
337
|
env,
|
|
212
338
|
models: configuration.models,
|
|
213
339
|
apiKey: resolveConfigValue(configuration.apiKey, env),
|
|
214
340
|
baseUrl: configuration.models ? undefined : configuration.baseUrl,
|
|
215
341
|
})
|
|
216
|
-
:
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
:
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
342
|
+
: configuration.id === "zhipu"
|
|
343
|
+
? createZhipuProvider({
|
|
344
|
+
env,
|
|
345
|
+
models: configuration.models,
|
|
346
|
+
apiKey: resolveConfigValue(configuration.apiKey, env),
|
|
347
|
+
baseUrl: configuration.models ? undefined : configuration.baseUrl,
|
|
348
|
+
})
|
|
349
|
+
: createOpenAIProvider({
|
|
350
|
+
env: configuration.id === "openai"
|
|
351
|
+
? env
|
|
352
|
+
: Object.fromEntries(Object.entries(env).filter(([name]) => name !== "OPENAI_API_KEY" && name !== "OPENAI_BASE_URL")),
|
|
353
|
+
models: configuration.models,
|
|
354
|
+
apiKey: resolveConfigValue(configuration.apiKey, env),
|
|
355
|
+
baseUrl: configuration.models ? undefined : configuration.baseUrl,
|
|
356
|
+
providerId: configuration.id,
|
|
357
|
+
name: configuration.name,
|
|
358
|
+
});
|
|
226
359
|
const model = selectProviderModel(provider, configuration.id, env);
|
|
227
360
|
return { provider, model };
|
|
228
361
|
}
|
|
229
|
-
export function resolveStartupRuntime(env, providers) {
|
|
230
|
-
const selectedProviderId = env.DI_CODE_PROVIDER?.trim() || (providers.length === 1 ? providers[0]?.id : undefined);
|
|
362
|
+
export function resolveStartupRuntime(env, providers, defaults = {}) {
|
|
363
|
+
const selectedProviderId = env.DI_CODE_PROVIDER?.trim() || defaults.providerId || (providers.length === 1 ? providers[0]?.id : undefined);
|
|
231
364
|
if (selectedProviderId === "faux")
|
|
232
365
|
return createFauxRuntime();
|
|
233
366
|
if (!selectedProviderId) {
|
|
@@ -236,39 +369,35 @@ export function resolveStartupRuntime(env, providers) {
|
|
|
236
369
|
}
|
|
237
370
|
throw new Error("DI_CODE_PROVIDER is required when more than one provider is configured.");
|
|
238
371
|
}
|
|
372
|
+
const runtimeEnvironment = env.DI_CODE_MODEL?.trim() || defaults.providerId !== selectedProviderId || !defaults.modelId
|
|
373
|
+
? env
|
|
374
|
+
: { ...env, DI_CODE_MODEL: defaults.modelId };
|
|
239
375
|
const selectedProvider = providers.find((provider) => provider.id === selectedProviderId);
|
|
240
376
|
if (selectedProvider)
|
|
241
|
-
return createConfiguredRuntime(
|
|
242
|
-
const builtInRuntime = createBuiltInRuntime(
|
|
377
|
+
return createConfiguredRuntime(runtimeEnvironment, selectedProvider);
|
|
378
|
+
const builtInRuntime = createBuiltInRuntime(runtimeEnvironment, selectedProviderId);
|
|
243
379
|
if (builtInRuntime)
|
|
244
380
|
return builtInRuntime;
|
|
245
381
|
throw new Error(`Unknown configured provider "${selectedProviderId}". Available providers: ${providers.map((provider) => provider.id).join(", ")}.`);
|
|
246
382
|
}
|
|
247
|
-
export async function loadStartupConfiguration(cwd, environment = process.env) {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
settings = parseSettings(JSON.parse(source));
|
|
254
|
-
}
|
|
255
|
-
catch (cause) {
|
|
256
|
-
if (cause instanceof Error && "code" in cause && cause.code === "ENOENT") {
|
|
257
|
-
return { environment, providers: [] };
|
|
258
|
-
}
|
|
259
|
-
if (cause instanceof SyntaxError)
|
|
260
|
-
throw new Error(`${SETTINGS_PATH}: invalid JSON`, { cause });
|
|
261
|
-
throw cause;
|
|
262
|
-
}
|
|
383
|
+
export async function loadStartupConfiguration(cwd, environment = process.env, agentDir = join(homedir(), ".di-code")) {
|
|
384
|
+
const [globalSettings, projectSettings] = await Promise.all([
|
|
385
|
+
readSettingsFile(join(agentDir, SETTINGS_FILE_NAME), join(agentDir, SETTINGS_FILE_NAME)),
|
|
386
|
+
readSettingsFile(join(cwd, SETTINGS_PATH), SETTINGS_PATH),
|
|
387
|
+
]);
|
|
388
|
+
const settings = mergeSettings(globalSettings, projectSettings);
|
|
263
389
|
const providers = Object.entries(settings.providers).map(([id, provider]) => ({
|
|
264
390
|
id: requiredString(id, `providers.${id}`),
|
|
265
391
|
name: provider.name,
|
|
266
392
|
api: provider.api,
|
|
267
393
|
apiKey: provider.apiKey,
|
|
268
394
|
baseUrl: provider.baseUrl,
|
|
269
|
-
models: parseModels(provider.models, `providers.${id}.models`, id, provider.api, provider.baseUrl),
|
|
395
|
+
models: parseModels(provider.models, `providers.${id}.models`, id, provider.api, provider.baseUrl, SETTINGS_PATH),
|
|
270
396
|
}));
|
|
271
|
-
|
|
397
|
+
const defaults = settings.defaultProvider === undefined && settings.defaultModel === undefined
|
|
398
|
+
? undefined
|
|
399
|
+
: { providerId: settings.defaultProvider, modelId: settings.defaultModel };
|
|
400
|
+
return { environment, providers, ...(defaults === undefined ? {} : { defaults }) };
|
|
272
401
|
}
|
|
273
402
|
export async function loadStartupEnvironment(cwd, environment = process.env) {
|
|
274
403
|
return (await loadStartupConfiguration(cwd, environment)).environment;
|
package/dist/startup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startup.js","sourceRoot":"","sources":["../src/startup.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport {\n\tcreateAnthropicProvider,\n\tcreateDeepSeekProvider,\n\tcreateFauxProvider,\n\tcreateOpenAIProvider,\n\tcreateZhipuProvider,\n\ttype FauxResponse,\n\ttype Model,\n\ttype Provider,\n} from \"@di-code/ai\";\n\nexport interface StartupRuntime {\n\treadonly provider: Provider;\n\treadonly model: Model;\n}\n\nexport interface StartupProviderConfiguration {\n\treadonly id: string;\n\treadonly name?: string;\n\treadonly api?: string;\n\treadonly apiKey?: string;\n\treadonly baseUrl?: string;\n\treadonly models?: readonly Model[];\n}\n\nexport interface StartupConfiguration {\n\treadonly environment: Environment;\n\treadonly providers: readonly StartupProviderConfiguration[];\n}\n\nconst FAUX_RESPONSES: readonly FauxResponse[] = [\n\t{ type: \"success\", content: [{ type: \"text\", text: \"Faux response.\" }] },\n];\n\nconst SETTINGS_PATH = join(\".di-code\", \"settings.json\");\n\ntype Environment = Readonly<Record<string, string | undefined>>;\n\ninterface SettingsFile {\n\treadonly providers: Record<\n\t\tstring,\n\t\t{\n\t\t\treadonly name?: string;\n\t\t\treadonly baseUrl?: string;\n\t\t\treadonly apiKey?: string;\n\t\t\treadonly api?: string;\n\t\t\treadonly models?: unknown;\n\t\t}\n\t>;\n}\n\nexport function resolveStartupArgs(args: readonly string[]): readonly string[] {\n\treturn args.length === 0 ? [\"--interactive\"] : args;\n}\n\nfunction optionalString(value: unknown, path: string): string | undefined {\n\tif (value === undefined) return undefined;\n\tif (typeof value !== \"string\") throw new Error(`${SETTINGS_PATH}: ${path} must be a string`);\n\treturn value;\n}\n\nfunction requiredString(value: unknown, path: string): string {\n\tconst result = optionalString(value, path);\n\tif (!result?.trim()) throw new Error(`${SETTINGS_PATH}: ${path} must be a non-empty string`);\n\treturn result.trim();\n}\n\nfunction positiveInteger(value: unknown, path: string, fallback: number): number {\n\tconst result = value ?? fallback;\n\tif (!Number.isInteger(result) || (result as number) <= 0) {\n\t\tthrow new Error(`${SETTINGS_PATH}: ${path} must be a positive integer`);\n\t}\n\treturn result as number;\n}\n\nfunction nonNegativeNumber(value: unknown, path: string, fallback: number): number {\n\tconst result = value ?? fallback;\n\tif (typeof result !== \"number\" || !Number.isFinite(result) || result < 0) {\n\t\tthrow new Error(`${SETTINGS_PATH}: ${path} must be a non-negative finite number`);\n\t}\n\treturn result;\n}\n\nfunction parseModels(\n\tvalue: unknown,\n\tpath: string,\n\tproviderId: string,\n\tproviderApi: string | undefined,\n\tproviderBaseUrl: string | undefined,\n): readonly Model[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) throw new Error(`${SETTINGS_PATH}: ${path} must be an array`);\n\n\treturn value.map((entry, index) => {\n\t\tconst modelPath = `${path}[${index}]`;\n\t\tif (typeof entry !== \"object\" || entry === null || Array.isArray(entry)) {\n\t\t\tthrow new Error(`${SETTINGS_PATH}: ${modelPath} must be an object`);\n\t\t}\n\t\tconst model = entry as Record<string, unknown>;\n\t\tconst input = model.input ?? [\"text\"];\n\t\tif (!Array.isArray(input) || input.length === 0 || input.some((item) => item !== \"text\" && item !== \"image\")) {\n\t\t\tthrow new Error(`${SETTINGS_PATH}: ${modelPath}.input must contain text and/or image`);\n\t\t}\n\t\tconst cost = model.cost ?? {};\n\t\tif (typeof cost !== \"object\" || cost === null || Array.isArray(cost)) {\n\t\t\tthrow new Error(`${SETTINGS_PATH}: ${modelPath}.cost must be an object`);\n\t\t}\n\t\tconst prices = cost as Record<string, unknown>;\n\t\tif (model.reasoning !== undefined && typeof model.reasoning !== \"boolean\") {\n\t\t\tthrow new Error(`${SETTINGS_PATH}: ${modelPath}.reasoning must be a boolean`);\n\t\t}\n\t\tif (model.cacheRetention !== undefined && model.cacheRetention !== \"long\") {\n\t\t\tthrow new Error(`${SETTINGS_PATH}: ${modelPath}.cacheRetention must be \"long\" when provided`);\n\t\t}\n\t\tif (model.sessionAffinity !== undefined && model.sessionAffinity !== \"codex\") {\n\t\t\tthrow new Error(`${SETTINGS_PATH}: ${modelPath}.sessionAffinity must be \"codex\" when provided`);\n\t\t}\n\t\tconst api = optionalString(model.api, `${modelPath}.api`) ?? providerApi;\n\t\tif (!api) throw new Error(`${SETTINGS_PATH}: ${modelPath}.api is required`);\n\t\tconst baseUrl = optionalString(model.baseUrl, `${modelPath}.baseUrl`) ?? providerBaseUrl;\n\t\tconst id = requiredString(model.id, `${modelPath}.id`);\n\t\treturn {\n\t\t\tid,\n\t\t\tname: requiredString(model.name ?? id, `${modelPath}.name`),\n\t\t\tprovider: providerId,\n\t\t\tapi,\n\t\t\t...(baseUrl === undefined ? {} : { baseUrl }),\n\t\t\tinput: [...input],\n\t\t\treasoning: model.reasoning ?? false,\n\t\t\t...(model.cacheRetention === \"long\" ? { cacheRetention: \"long\" as const } : {}),\n\t\t\t...(model.sessionAffinity === \"codex\" ? { sessionAffinity: \"codex\" as const } : {}),\n\t\t\tcontextWindow: positiveInteger(model.contextWindow, `${modelPath}.contextWindow`, 128_000),\n\t\t\tmaxOutputTokens: positiveInteger(model.maxTokens ?? model.maxOutputTokens, `${modelPath}.maxTokens`, 16_384),\n\t\t\tcost: {\n\t\t\t\tinput: nonNegativeNumber(prices.input, `${modelPath}.cost.input`, 0) / 1_000_000,\n\t\t\t\toutput: nonNegativeNumber(prices.output, `${modelPath}.cost.output`, 0) / 1_000_000,\n\t\t\t\tcacheRead: nonNegativeNumber(prices.cacheRead, `${modelPath}.cost.cacheRead`, 0) / 1_000_000,\n\t\t\t\tcacheWrite: nonNegativeNumber(prices.cacheWrite, `${modelPath}.cost.cacheWrite`, 0) / 1_000_000,\n\t\t\t},\n\t\t};\n\t});\n}\n\nfunction parseSettings(value: unknown): SettingsFile {\n\tif (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n\t\tthrow new Error(`${SETTINGS_PATH}: root value must be an object`);\n\t}\n\tconst record = value as Record<string, unknown>;\n\tconst providersValue = record.providers;\n\tif (typeof providersValue !== \"object\" || providersValue === null || Array.isArray(providersValue)) {\n\t\tthrow new Error(`${SETTINGS_PATH}: providers must be an object`);\n\t}\n\tconst providers: Record<string, SettingsFile[\"providers\"][string]> = {};\n\tfor (const [id, entry] of Object.entries(providersValue as Record<string, unknown>)) {\n\t\tif (typeof entry !== \"object\" || entry === null || Array.isArray(entry)) {\n\t\t\tthrow new Error(`${SETTINGS_PATH}: providers.${id} must be an object`);\n\t\t}\n\t\tconst provider = entry as Record<string, unknown>;\n\t\tproviders[id] = {\n\t\t\tname: optionalString(provider.name, `providers.${id}.name`),\n\t\t\tbaseUrl: optionalString(provider.baseUrl, `providers.${id}.baseUrl`),\n\t\t\tapiKey: optionalString(provider.apiKey, `providers.${id}.apiKey`),\n\t\t\tapi: optionalString(provider.api, `providers.${id}.api`),\n\t\t\tmodels: provider.models,\n\t\t};\n\t}\n\treturn { providers };\n}\n\nfunction resolveConfigValue(value: string | undefined, env: Environment): string | undefined {\n\tif (value === undefined) return undefined;\n\tconst trimmed = value.trim();\n\tconst match = /^\\$\\{([A-Za-z_][A-Za-z0-9_]*)\\}$|^\\$([A-Za-z_][A-Za-z0-9_]*)$/.exec(trimmed);\n\tif (match) {\n\t\tconst name = match[1] ?? match[2];\n\t\tconst resolved = env[name];\n\t\tif (!resolved?.trim()) throw new Error(`Configured apiKey environment variable \"${name}\" is not set.`);\n\t\treturn resolved;\n\t}\n\tif (trimmed.startsWith(\"!\")) {\n\t\tthrow new Error(\"Command-based apiKey values are not supported by di-code; use $ENV_VAR instead.\");\n\t}\n\treturn value;\n}\n\nfunction createFauxRuntime(): StartupRuntime {\n\tconst faux = createFauxProvider({ responses: FAUX_RESPONSES });\n\treturn { provider: faux.provider, model: faux.model };\n}\n\nfunction selectProviderModel(provider: Provider, providerId: string, env: Environment): Model {\n\tconst modelId =\n\t\tenv.DI_CODE_MODEL?.trim() ||\n\t\t(providerId === \"anthropic\"\n\t\t\t? provider.models.find((candidate) => candidate.id === \"claude-sonnet-4-5\")?.id\n\t\t\t: providerId === \"openai\"\n\t\t\t\t? provider.models.find((candidate) => candidate.id === \"gpt-4o\")?.id\n\t\t\t\t: providerId === \"zhipu\"\n\t\t\t\t\t? provider.models.find((candidate) => candidate.id === \"glm-5.3\")?.id\n\t\t\t\t\t: undefined) ||\n\t\tprovider.models[0]?.id;\n\tif (!modelId) throw new Error(\"DI_CODE_MODEL is required when the selected provider has no models\");\n\tconst model = provider.models.find((candidate) => candidate.id === modelId);\n\tif (!model) {\n\t\tconst availableModels = provider.models.map((candidate) => candidate.id).join(\", \");\n\t\tthrow new Error(`Unknown model \"${modelId}\" for provider \"${providerId}\". Available models: ${availableModels}.`);\n\t}\n\treturn model;\n}\n\nfunction createBuiltInRuntime(env: Environment, providerId: string): StartupRuntime | undefined {\n\tif (providerId === \"anthropic\") {\n\t\tconst provider = createAnthropicProvider({ env });\n\t\treturn { provider, model: selectProviderModel(provider, providerId, env) };\n\t}\n\tif (providerId === \"openai\") {\n\t\tconst provider = createOpenAIProvider({ env });\n\t\treturn { provider, model: selectProviderModel(provider, providerId, env) };\n\t}\n\tif (providerId === \"deepseek\") {\n\t\tconst provider = createDeepSeekProvider({ env });\n\t\treturn { provider, model: selectProviderModel(provider, providerId, env) };\n\t}\n\tif (providerId === \"zhipu\") {\n\t\tconst provider = createZhipuProvider({ env });\n\t\treturn { provider, model: selectProviderModel(provider, providerId, env) };\n\t}\n\treturn undefined;\n}\n\nfunction createConfiguredRuntime(env: Environment, configuration: StartupProviderConfiguration): StartupRuntime {\n\tif (\n\t\tconfiguration.api !== \"openai-responses\" &&\n\t\tconfiguration.api !== \"deepseek-responses\" &&\n\t\tconfiguration.api !== \"zhipu-chat-completions\" &&\n\t\tconfiguration.api !== \"anthropic-messages\"\n\t) {\n\t\tthrow new Error(\n\t\t\t`Unsupported API \"${configuration.api ?? \"missing\"}\" for provider \"${configuration.id}\". Expected openai-responses, deepseek-responses, zhipu-chat-completions, or anthropic-messages.`,\n\t\t);\n\t}\n\tif (\n\t\tconfiguration.id !== \"openai\" &&\n\t\tconfiguration.id !== \"deepseek\" &&\n\t\tconfiguration.id !== \"zhipu\" &&\n\t\tconfiguration.id !== \"anthropic\" &&\n\t\t!configuration.models\n\t) {\n\t\tthrow new Error(`${SETTINGS_PATH}: providers.${configuration.id}.models is required for a custom provider`);\n\t}\n\tconst provider =\n\t\tconfiguration.api === \"anthropic-messages\"\n\t\t\t? createAnthropicProvider({\n\t\t\t\t\tenv:\n\t\t\t\t\t\tconfiguration.id === \"anthropic\"\n\t\t\t\t\t\t\t? env\n\t\t\t\t\t\t\t: Object.fromEntries(\n\t\t\t\t\t\t\t\t\tObject.entries(env).filter(([name]) => name !== \"ANTHROPIC_API_KEY\" && name !== \"ANTHROPIC_BASE_URL\"),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\tmodels: configuration.models,\n\t\t\t\t\tapiKey: resolveConfigValue(configuration.apiKey, env),\n\t\t\t\t\tbaseUrl: configuration.models ? undefined : configuration.baseUrl,\n\t\t\t\t\tproviderId: configuration.id,\n\t\t\t\t\tname: configuration.name,\n\t\t\t\t})\n\t\t\t: configuration.id === \"deepseek\"\n\t\t\t\t? createDeepSeekProvider({\n\t\t\t\t\t\tenv,\n\t\t\t\t\t\tmodels: configuration.models,\n\t\t\t\t\t\tapiKey: resolveConfigValue(configuration.apiKey, env),\n\t\t\t\t\t\tbaseUrl: configuration.models ? undefined : configuration.baseUrl,\n\t\t\t\t\t})\n\t\t\t\t: configuration.id === \"zhipu\"\n\t\t\t\t\t? createZhipuProvider({\n\t\t\t\t\t\t\tenv,\n\t\t\t\t\t\t\tmodels: configuration.models,\n\t\t\t\t\t\t\tapiKey: resolveConfigValue(configuration.apiKey, env),\n\t\t\t\t\t\t\tbaseUrl: configuration.models ? undefined : configuration.baseUrl,\n\t\t\t\t\t\t})\n\t\t\t\t\t: createOpenAIProvider({\n\t\t\t\t\t\t\tenv:\n\t\t\t\t\t\t\t\tconfiguration.id === \"openai\"\n\t\t\t\t\t\t\t\t\t? env\n\t\t\t\t\t\t\t\t\t: Object.fromEntries(\n\t\t\t\t\t\t\t\t\t\t\tObject.entries(env).filter(([name]) => name !== \"OPENAI_API_KEY\" && name !== \"OPENAI_BASE_URL\"),\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tmodels: configuration.models,\n\t\t\t\t\t\t\tapiKey: resolveConfigValue(configuration.apiKey, env),\n\t\t\t\t\t\t\tbaseUrl: configuration.models ? undefined : configuration.baseUrl,\n\t\t\t\t\t\t\tproviderId: configuration.id,\n\t\t\t\t\t\t\tname: configuration.name,\n\t\t\t\t\t\t});\n\tconst model = selectProviderModel(provider, configuration.id, env);\n\treturn { provider, model };\n}\n\nexport function resolveStartupRuntime(\n\tenv: Environment,\n\tproviders: readonly StartupProviderConfiguration[],\n): StartupRuntime {\n\tconst selectedProviderId = env.DI_CODE_PROVIDER?.trim() || (providers.length === 1 ? providers[0]?.id : undefined);\n\tif (selectedProviderId === \"faux\") return createFauxRuntime();\n\tif (!selectedProviderId) {\n\t\tif (providers.length === 0) {\n\t\t\tthrow new Error(\"Provider is not configured. Set DI_CODE_PROVIDER or start interactive mode in a TTY.\");\n\t\t}\n\t\tthrow new Error(\"DI_CODE_PROVIDER is required when more than one provider is configured.\");\n\t}\n\tconst selectedProvider = providers.find((provider) => provider.id === selectedProviderId);\n\tif (selectedProvider) return createConfiguredRuntime(env, selectedProvider);\n\tconst builtInRuntime = createBuiltInRuntime(env, selectedProviderId);\n\tif (builtInRuntime) return builtInRuntime;\n\tthrow new Error(\n\t\t`Unknown configured provider \"${selectedProviderId}\". Available providers: ${providers.map((provider) => provider.id).join(\", \")}.`,\n\t);\n}\n\nexport async function loadStartupConfiguration(\n\tcwd: string,\n\tenvironment: Environment = process.env,\n): Promise<StartupConfiguration> {\n\tlet settings: SettingsFile;\n\ttry {\n\t\tconst source = await readFile(join(cwd, SETTINGS_PATH), \"utf8\");\n\t\tif (source.trim().length === 0) return { environment, providers: [] };\n\t\tsettings = parseSettings(JSON.parse(source));\n\t} catch (cause) {\n\t\tif (cause instanceof Error && \"code\" in cause && cause.code === \"ENOENT\") {\n\t\t\treturn { environment, providers: [] };\n\t\t}\n\t\tif (cause instanceof SyntaxError) throw new Error(`${SETTINGS_PATH}: invalid JSON`, { cause });\n\t\tthrow cause;\n\t}\n\n\tconst providers = Object.entries(settings.providers).map(([id, provider]) => ({\n\t\tid: requiredString(id, `providers.${id}`),\n\t\tname: provider.name,\n\t\tapi: provider.api,\n\t\tapiKey: provider.apiKey,\n\t\tbaseUrl: provider.baseUrl,\n\t\tmodels: parseModels(provider.models, `providers.${id}.models`, id, provider.api, provider.baseUrl),\n\t}));\n\treturn { environment, providers };\n}\n\nexport async function loadStartupEnvironment(\n\tcwd: string,\n\tenvironment: Environment = process.env,\n): Promise<Environment> {\n\treturn (await loadStartupConfiguration(cwd, environment)).environment;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"startup.js","sourceRoot":"","sources":["../src/startup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EACN,uBAAuB,EACvB,sBAAsB,EACtB,kBAAkB,EAClB,mCAAmC,EACnC,oBAAoB,EACpB,mBAAmB,GAKnB,MAAM,aAAa,CAAC;AA2BrB,MAAM,cAAc,GAA4B;IAC/C;QACC,IAAI,EAAE,SAAS;QACf,OAAO,EAAE;YACR;gBACC,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,gHAAgH;aACtH;SACD;KACD;IACD,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,EAAE;CACrE,CAAC;AAEF,MAAM,kBAAkB,GAAG,eAAe,CAAC;AAC3C,MAAM,aAAa,GAAG,IAAI,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC;AAmB3D,MAAM,UAAU,kBAAkB,CAAC,IAAuB;IACzD,OAAO,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACrD,CAAC;AAED,SAAS,cAAc,CAAC,KAAc,EAAE,IAAY,EAAE,YAAoB;IACzE,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,YAAY,KAAK,IAAI,mBAAmB,CAAC,CAAC;IAC5F,OAAO,KAAK,CAAC;AACd,CAAC;AAED,SAAS,cAAc,CAAC,KAAc,EAAE,IAAY,EAAE,YAAY,GAAG,aAAa;IACjF,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;IACzD,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,YAAY,KAAK,IAAI,6BAA6B,CAAC,CAAC;IAC5F,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;AACtB,CAAC;AAED,SAAS,eAAe,CAAC,KAAc,EAAE,IAAY,EAAE,QAAgB,EAAE,YAAoB;IAC5F,MAAM,MAAM,GAAG,KAAK,IAAI,QAAQ,CAAC;IACjC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAK,MAAiB,IAAI,CAAC,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CAAC,GAAG,YAAY,KAAK,IAAI,6BAA6B,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,MAAgB,CAAC;AACzB,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAc,EAAE,IAAY,EAAE,QAAgB,EAAE,YAAoB;IAC9F,MAAM,MAAM,GAAG,KAAK,IAAI,QAAQ,CAAC;IACjC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1E,MAAM,IAAI,KAAK,CAAC,GAAG,YAAY,KAAK,IAAI,uCAAuC,CAAC,CAAC;IAClF,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC;AAED,SAAS,WAAW,CACnB,KAAc,EACd,IAAY,EACZ,UAAkB,EAClB,WAA+B,EAC/B,eAAmC,EACnC,YAAoB;IAEpB,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,YAAY,KAAK,IAAI,mBAAmB,CAAC,CAAC;IAExF,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QACjC,MAAM,SAAS,GAAG,GAAG,IAAI,IAAI,KAAK,GAAG,CAAC;QACtC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzE,MAAM,IAAI,KAAK,CAAC,GAAG,YAAY,KAAK,SAAS,oBAAoB,CAAC,CAAC;QACpE,CAAC;QACD,MAAM,KAAK,GAAG,KAAgC,CAAC;QAC/C,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,OAAO,CAAC,EAAE,CAAC;YAC9G,MAAM,IAAI,KAAK,CAAC,GAAG,YAAY,KAAK,SAAS,uCAAuC,CAAC,CAAC;QACvF,CAAC;QACD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;QAC9B,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACtE,MAAM,IAAI,KAAK,CAAC,GAAG,YAAY,KAAK,SAAS,yBAAyB,CAAC,CAAC;QACzE,CAAC;QACD,MAAM,MAAM,GAAG,IAA+B,CAAC;QAC/C,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YAC3E,MAAM,IAAI,KAAK,CAAC,GAAG,YAAY,KAAK,SAAS,8BAA8B,CAAC,CAAC;QAC9E,CAAC;QACD,MAAM,0BAA0B,GAAG,KAAK,CAAC,gBAAgB,CAAC;QAC1D,IAAI,0BAA0B,KAAK,SAAS,EAAE,CAAC;YAC9C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,0BAA0B,CAAC,IAAI,0BAA0B,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC3F,MAAM,IAAI,KAAK,CAAC,GAAG,YAAY,KAAK,SAAS,6CAA6C,CAAC,CAAC;YAC7F,CAAC;YACD,IACC,KAAK,CAAC,SAAS,KAAK,IAAI;gBACxB,0BAA0B,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,MAAM,CAAC;gBACzG,IAAI,GAAG,CAAC,0BAA0B,CAAC,CAAC,IAAI,KAAK,0BAA0B,CAAC,MAAM,EAC7E,CAAC;gBACF,MAAM,IAAI,KAAK,CACd,GAAG,YAAY,KAAK,SAAS,kFAAkF,CAC/G,CAAC;YACH,CAAC;QACF,CAAC;QACD,IAAI,KAAK,CAAC,cAAc,KAAK,SAAS,IAAI,KAAK,CAAC,cAAc,KAAK,MAAM,EAAE,CAAC;YAC3E,MAAM,IAAI,KAAK,CAAC,GAAG,YAAY,KAAK,SAAS,8CAA8C,CAAC,CAAC;QAC9F,CAAC;QACD,IAAI,KAAK,CAAC,eAAe,KAAK,SAAS,IAAI,KAAK,CAAC,eAAe,KAAK,OAAO,EAAE,CAAC;YAC9E,MAAM,IAAI,KAAK,CAAC,GAAG,YAAY,KAAK,SAAS,gDAAgD,CAAC,CAAC;QAChG,CAAC;QACD,MAAM,GAAG,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,SAAS,MAAM,EAAE,YAAY,CAAC,IAAI,WAAW,CAAC;QACvF,IAAI,CAAC,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,YAAY,KAAK,SAAS,kBAAkB,CAAC,CAAC;QAC3E,IAAI,CAAC,CAAC,MAAM,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,oBAAoB,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAClG,MAAM,IAAI,KAAK,CAAC,GAAG,YAAY,KAAK,SAAS,qBAAqB,CAAC,CAAC;QACrE,CAAC;QACD,MAAM,QAAQ,GAAG,GAAe,CAAC;QACjC,MAAM,gBAAgB,GACrB,0BAA0B,KAAK,SAAS,IAAI,KAAK,CAAC,SAAS,KAAK,IAAI,IAAI,GAAG,KAAK,kBAAkB;YACjG,CAAC,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC;YAC3B,CAAC,CAAC,0BAA0B,KAAK,SAAS;gBACzC,CAAC,CAAC,SAAS;gBACX,CAAC,CAAE,CAAC,GAAG,0BAA0B,CAA+B,CAAC;QACpE,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,SAAS,UAAU,EAAE,YAAY,CAAC,IAAI,eAAe,CAAC;QACvG,MAAM,EAAE,GAAG,cAAc,CAAC,KAAK,CAAC,EAAE,EAAE,GAAG,SAAS,KAAK,EAAE,YAAY,CAAC,CAAC;QACrE,OAAO;YACN,EAAE;YACF,IAAI,EAAE,cAAc,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,EAAE,GAAG,SAAS,OAAO,EAAE,YAAY,CAAC;YACzE,QAAQ,EAAE,UAAU;YACpB,GAAG,EAAE,QAAQ;YACb,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;YAC7C,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC;YACjB,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,KAAK;YACnC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACjD,GAAG,CAAC,KAAK,CAAC,cAAc,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,MAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/E,GAAG,CAAC,KAAK,CAAC,eAAe,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,OAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACnF,aAAa,EAAE,eAAe,CAAC,KAAK,CAAC,aAAa,EAAE,GAAG,SAAS,gBAAgB,EAAE,OAAO,EAAE,YAAY,CAAC;YACxG,eAAe,EAAE,eAAe,CAC/B,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,eAAe,EACxC,GAAG,SAAS,YAAY,EACxB,MAAM,EACN,YAAY,CACZ;YACD,IAAI,EAAE;gBACL,KAAK,EAAE,iBAAiB,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,SAAS,aAAa,EAAE,CAAC,EAAE,YAAY,CAAC,GAAG,SAAS;gBAC9F,MAAM,EAAE,iBAAiB,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,SAAS,cAAc,EAAE,CAAC,EAAE,YAAY,CAAC,GAAG,SAAS;gBACjG,SAAS,EAAE,iBAAiB,CAAC,MAAM,CAAC,SAAS,EAAE,GAAG,SAAS,iBAAiB,EAAE,CAAC,EAAE,YAAY,CAAC,GAAG,SAAS;gBAC1G,UAAU,EAAE,iBAAiB,CAAC,MAAM,CAAC,UAAU,EAAE,GAAG,SAAS,kBAAkB,EAAE,CAAC,EAAE,YAAY,CAAC,GAAG,SAAS;aAC7G;SACD,CAAC;IACH,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,KAAc,EAAE,YAAoB;IAC1D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzE,MAAM,IAAI,KAAK,CAAC,GAAG,YAAY,gCAAgC,CAAC,CAAC;IAClE,CAAC;IACD,MAAM,MAAM,GAAG,KAAgC,CAAC;IAChD,MAAM,cAAc,GAAG,MAAM,CAAC,SAAS,CAAC;IACxC,IAAI,OAAO,cAAc,KAAK,QAAQ,IAAI,cAAc,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;QACpG,MAAM,IAAI,KAAK,CAAC,GAAG,YAAY,+BAA+B,CAAC,CAAC;IACjE,CAAC;IACD,MAAM,SAAS,GAAsD,EAAE,CAAC;IACxE,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,cAAyC,CAAC,EAAE,CAAC;QACrF,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzE,MAAM,IAAI,KAAK,CAAC,GAAG,YAAY,eAAe,EAAE,oBAAoB,CAAC,CAAC;QACvE,CAAC;QACD,MAAM,QAAQ,GAAG,KAAgC,CAAC;QAClD,SAAS,CAAC,EAAE,CAAC,GAAG;YACf,IAAI,EAAE,cAAc,CAAC,QAAQ,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY,CAAC;YACzE,OAAO,EAAE,cAAc,CAAC,QAAQ,CAAC,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,CAAC;YAClF,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,CAAC;YAC/E,GAAG,EAAE,cAAc,CAAC,QAAQ,CAAC,GAAG,EAAE,aAAa,EAAE,MAAM,EAAE,YAAY,CAAC;YACtE,MAAM,EAAE,QAAQ,CAAC,MAAM;SACvB,CAAC;IACH,CAAC;IACD,MAAM,eAAe,GACpB,MAAM,CAAC,eAAe,KAAK,SAAS;QACnC,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,eAAe,EAAE,iBAAiB,EAAE,YAAY,CAAC,CAAC;IAC5E,MAAM,YAAY,GACjB,MAAM,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,YAAY,EAAE,cAAc,EAAE,YAAY,CAAC,CAAC;IACnH,OAAO;QACN,SAAS;QACT,GAAG,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC;QAC7D,GAAG,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC;KACvD,CAAC;AACH,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,IAAY,EAAE,WAAmB;IAChE,IAAI,CAAC;QACJ,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC5C,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QACjD,OAAO,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,CAAC;IACvD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,IAAI,KAAK,YAAY,KAAK,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,SAAS,CAAC;QAC3F,IAAI,KAAK,YAAY,WAAW;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,WAAW,gBAAgB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAC7F,MAAM,KAAK,CAAC;IACb,CAAC;AACF,CAAC;AAED,SAAS,aAAa,CACrB,cAAwC,EACxC,eAAyC;IAEzC,MAAM,eAAe,GAAG,cAAc,EAAE,SAAS,IAAI,EAAE,CAAC;IACxD,MAAM,gBAAgB,GAAG,eAAe,EAAE,SAAS,IAAI,EAAE,CAAC;IAC1D,MAAM,SAAS,GAAG,EAAE,GAAG,eAAe,EAAE,CAAC;IACzC,KAAK,MAAM,CAAC,EAAE,EAAE,eAAe,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACtE,SAAS,CAAC,EAAE,CAAC,GAAG;YACf,GAAG,eAAe,CAAC,EAAE,CAAC;YACtB,GAAG,CAAC,eAAe,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,eAAe,CAAC,IAAI,EAAE,CAAC;YAC7E,GAAG,CAAC,eAAe,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,eAAe,CAAC,OAAO,EAAE,CAAC;YACtF,GAAG,CAAC,eAAe,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,eAAe,CAAC,MAAM,EAAE,CAAC;YACnF,GAAG,CAAC,eAAe,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,eAAe,CAAC,GAAG,EAAE,CAAC;YAC1E,GAAG,CAAC,eAAe,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,eAAe,CAAC,MAAM,EAAE,CAAC;SACnF,CAAC;IACH,CAAC;IACD,MAAM,eAAe,GAAG,eAAe,EAAE,eAAe,IAAI,cAAc,EAAE,eAAe,CAAC;IAC5F,MAAM,YAAY,GACjB,eAAe,EAAE,YAAY;QAC7B,CAAC,eAAe,EAAE,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAC7F,OAAO;QACN,SAAS;QACT,GAAG,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC;QAC7D,GAAG,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC;KACvD,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC7C,QAAgB,EAChB,UAAkB,EAClB,GAA8B,EAC9B,MAAc,EACd,OAAgB;IAEhB,MAAM,gBAAgB,GAAG,IAAI,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC;IAC5D,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IACpC,IAAI,CAAC,aAAa;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,gBAAgB,qCAAqC,CAAC,CAAC;IAC9F,MAAM,gBAAgB,GAAG,MAAM,gBAAgB,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,CAAC;IACpF,MAAM,QAAQ,GAAG,aAAa,CAAC,gBAAgB,EAAE;QAChD,SAAS,EAAE,EAAE,CAAC,UAAU,CAAC,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,aAAa,EAAE,EAAE;QAC3D,eAAe,EAAE,UAAU;QAC3B,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC;KAC3D,CAAC,CAAC;IACH,MAAM,KAAK,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACxD,MAAM,SAAS,CAAC,gBAAgB,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AACnH,CAAC;AAED,sGAAsG;AACtG,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,QAAgB,EAAE,UAAkB;IACpF,MAAM,gBAAgB,GAAG,IAAI,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC;IAC5D,MAAM,gBAAgB,GAAG,MAAM,gBAAgB,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,CAAC;IACpF,MAAM,QAAQ,GAAG,gBAAgB,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;IACzD,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAE7D,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,qBAAqB,EAAE,GAAG,QAAQ,CAAC;IAC/D,MAAM,QAAQ,GAAiB;QAC9B,GAAG,gBAAgB;QACnB,SAAS,EAAE;YACV,GAAG,gBAAgB,CAAC,SAAS;YAC7B,CAAC,UAAU,CAAC,EAAE,qBAAqB;SACnC;KACD,CAAC;IACF,MAAM,SAAS,CAAC,gBAAgB,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAClH,OAAO,IAAI,CAAC;AACb,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAyB,EAAE,GAAgB;IACtE,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAG,+DAA+D,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC5F,IAAI,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,QAAQ,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,2CAA2C,IAAI,eAAe,CAAC,CAAC;QACvG,OAAO,QAAQ,CAAC;IACjB,CAAC;IACD,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,iFAAiF,CAAC,CAAC;IACpG,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,SAAS,iBAAiB;IACzB,MAAM,IAAI,GAAG,kBAAkB,CAAC,EAAE,SAAS,EAAE,cAAc,EAAE,CAAC,CAAC;IAC/D,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;AACvD,CAAC;AAED,SAAS,mBAAmB,CAAC,QAAkB,EAAE,UAAkB,EAAE,GAAgB;IACpF,MAAM,OAAO,GACZ,GAAG,CAAC,aAAa,EAAE,IAAI,EAAE;QACzB,CAAC,UAAU,KAAK,WAAW;YAC1B,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,mBAAmB,CAAC,EAAE,EAAE;YAC/E,CAAC,CAAC,UAAU,KAAK,QAAQ;gBACxB,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,QAAQ,CAAC,EAAE,EAAE;gBACpE,CAAC,CAAC,UAAU,KAAK,OAAO;oBACvB,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,SAAS,CAAC,EAAE,EAAE;oBACrE,CAAC,CAAC,SAAS,CAAC;QACf,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACxB,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;IACpG,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;IAC5E,IAAI,CAAC,KAAK,EAAE,CAAC;QACZ,MAAM,eAAe,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpF,MAAM,IAAI,KAAK,CAAC,kBAAkB,OAAO,mBAAmB,UAAU,wBAAwB,eAAe,GAAG,CAAC,CAAC;IACnH,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,SAAS,oBAAoB,CAAC,GAAgB,EAAE,UAAkB;IACjE,IAAI,UAAU,KAAK,WAAW,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,uBAAuB,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QAClD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,mBAAmB,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,CAAC,EAAE,CAAC;IAC5E,CAAC;IACD,IAAI,UAAU,KAAK,QAAQ,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,oBAAoB,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QAC/C,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,mBAAmB,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,CAAC,EAAE,CAAC;IAC5E,CAAC;IACD,IAAI,UAAU,KAAK,UAAU,EAAE,CAAC;QAC/B,MAAM,QAAQ,GAAG,sBAAsB,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QACjD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,mBAAmB,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,CAAC,EAAE,CAAC;IAC5E,CAAC;IACD,IAAI,UAAU,KAAK,OAAO,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,mBAAmB,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QAC9C,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,mBAAmB,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,CAAC,EAAE,CAAC;IAC5E,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,SAAS,uBAAuB,CAAC,GAAgB,EAAE,aAA2C;IAC7F,IACC,aAAa,CAAC,GAAG,KAAK,kBAAkB;QACxC,aAAa,CAAC,GAAG,KAAK,yBAAyB;QAC/C,aAAa,CAAC,GAAG,KAAK,oBAAoB,EACzC,CAAC;QACF,MAAM,IAAI,KAAK,CACd,oBAAoB,aAAa,CAAC,GAAG,IAAI,SAAS,mBAAmB,aAAa,CAAC,EAAE,+EAA+E,CACpK,CAAC;IACH,CAAC;IACD,IACC,aAAa,CAAC,EAAE,KAAK,QAAQ;QAC7B,aAAa,CAAC,EAAE,KAAK,UAAU;QAC/B,aAAa,CAAC,EAAE,KAAK,OAAO;QAC5B,aAAa,CAAC,EAAE,KAAK,WAAW;QAChC,CAAC,aAAa,CAAC,MAAM,EACpB,CAAC;QACF,MAAM,IAAI,KAAK,CAAC,GAAG,aAAa,eAAe,aAAa,CAAC,EAAE,2CAA2C,CAAC,CAAC;IAC7G,CAAC;IACD,MAAM,QAAQ,GACb,aAAa,CAAC,GAAG,KAAK,yBAAyB;QAC9C,CAAC,CAAC,mCAAmC,CAAC;YACpC,GAAG,EACF,aAAa,CAAC,EAAE,KAAK,OAAO,IAAI,aAAa,CAAC,EAAE,KAAK,UAAU;gBAC9D,CAAC,CAAC,GAAG;gBACL,CAAC,CAAC,MAAM,CAAC,WAAW,CAClB,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,gBAAgB,IAAI,IAAI,KAAK,iBAAiB,CAAC,CAC/F;YACJ,MAAM,EAAE,aAAa,CAAC,MAAM;YAC5B,MAAM,EAAE,kBAAkB,CAAC,aAAa,CAAC,MAAM,EAAE,GAAG,CAAC;YACrD,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO;YACjE,UAAU,EAAE,aAAa,CAAC,EAAE;YAC5B,IAAI,EAAE,aAAa,CAAC,IAAI,IAAI,aAAa,CAAC,EAAE;YAC5C,GAAG,CAAC,aAAa,CAAC,EAAE,KAAK,OAAO;gBAC/B,CAAC,CAAC;oBACA,yBAAyB,EAAE,aAAa;oBACxC,0BAA0B,EAAE,gBAAgB;oBAC5C,cAAc,EAAE,6CAA6C;iBAC7D;gBACF,CAAC,CAAC,aAAa,CAAC,EAAE,KAAK,UAAU;oBAChC,CAAC,CAAC;wBACA,yBAAyB,EAAE,kBAAkB;wBAC7C,0BAA0B,EAAE,mBAAmB;wBAC/C,cAAc,EAAE,0BAA0B;qBAC1C;oBACF,CAAC,CAAC,EAAE,CAAC;SACP,CAAC;QACH,CAAC,CAAC,aAAa,CAAC,GAAG,KAAK,oBAAoB;YAC3C,CAAC,CAAC,uBAAuB,CAAC;gBACxB,GAAG,EACF,aAAa,CAAC,EAAE,KAAK,WAAW;oBAC/B,CAAC,CAAC,GAAG;oBACL,CAAC,CAAC,MAAM,CAAC,WAAW,CAClB,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CACzB,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,mBAAmB,IAAI,IAAI,KAAK,oBAAoB,CACzE,CACD;gBACJ,MAAM,EAAE,aAAa,CAAC,MAAM;gBAC5B,MAAM,EAAE,kBAAkB,CAAC,aAAa,CAAC,MAAM,EAAE,GAAG,CAAC;gBACrD,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO;gBACjE,UAAU,EAAE,aAAa,CAAC,EAAE;gBAC5B,IAAI,EAAE,aAAa,CAAC,IAAI;aACxB,CAAC;YACH,CAAC,CAAC,aAAa,CAAC,EAAE,KAAK,UAAU;gBAChC,CAAC,CAAC,sBAAsB,CAAC;oBACvB,GAAG;oBACH,MAAM,EAAE,aAAa,CAAC,MAAM;oBAC5B,MAAM,EAAE,kBAAkB,CAAC,aAAa,CAAC,MAAM,EAAE,GAAG,CAAC;oBACrD,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO;iBACjE,CAAC;gBACH,CAAC,CAAC,aAAa,CAAC,EAAE,KAAK,OAAO;oBAC7B,CAAC,CAAC,mBAAmB,CAAC;wBACpB,GAAG;wBACH,MAAM,EAAE,aAAa,CAAC,MAAM;wBAC5B,MAAM,EAAE,kBAAkB,CAAC,aAAa,CAAC,MAAM,EAAE,GAAG,CAAC;wBACrD,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO;qBACjE,CAAC;oBACH,CAAC,CAAC,oBAAoB,CAAC;wBACrB,GAAG,EACF,aAAa,CAAC,EAAE,KAAK,QAAQ;4BAC5B,CAAC,CAAC,GAAG;4BACL,CAAC,CAAC,MAAM,CAAC,WAAW,CAClB,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,gBAAgB,IAAI,IAAI,KAAK,iBAAiB,CAAC,CAC/F;wBACJ,MAAM,EAAE,aAAa,CAAC,MAAM;wBAC5B,MAAM,EAAE,kBAAkB,CAAC,aAAa,CAAC,MAAM,EAAE,GAAG,CAAC;wBACrD,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO;wBACjE,UAAU,EAAE,aAAa,CAAC,EAAE;wBAC5B,IAAI,EAAE,aAAa,CAAC,IAAI;qBACxB,CAAC,CAAC;IACT,MAAM,KAAK,GAAG,mBAAmB,CAAC,QAAQ,EAAE,aAAa,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IACnE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,qBAAqB,CACpC,GAAgB,EAChB,SAAkD,EAClD,WAA4B,EAAE;IAE9B,MAAM,kBAAkB,GACvB,GAAG,CAAC,gBAAgB,EAAE,IAAI,EAAE,IAAI,QAAQ,CAAC,UAAU,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAChH,IAAI,kBAAkB,KAAK,MAAM;QAAE,OAAO,iBAAiB,EAAE,CAAC;IAC9D,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACzB,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,sFAAsF,CAAC,CAAC;QACzG,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,yEAAyE,CAAC,CAAC;IAC5F,CAAC;IACD,MAAM,kBAAkB,GACvB,GAAG,CAAC,aAAa,EAAE,IAAI,EAAE,IAAI,QAAQ,CAAC,UAAU,KAAK,kBAAkB,IAAI,CAAC,QAAQ,CAAC,OAAO;QAC3F,CAAC,CAAC,GAAG;QACL,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,aAAa,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC;IAChD,MAAM,gBAAgB,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,KAAK,kBAAkB,CAAC,CAAC;IAC1F,IAAI,gBAAgB;QAAE,OAAO,uBAAuB,CAAC,kBAAkB,EAAE,gBAAgB,CAAC,CAAC;IAC3F,MAAM,cAAc,GAAG,oBAAoB,CAAC,kBAAkB,EAAE,kBAAkB,CAAC,CAAC;IACpF,IAAI,cAAc;QAAE,OAAO,cAAc,CAAC;IAC1C,MAAM,IAAI,KAAK,CACd,gCAAgC,kBAAkB,2BAA2B,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CACnI,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC7C,GAAW,EACX,cAA2B,OAAO,CAAC,GAAG,EACtC,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC;IAEtC,MAAM,CAAC,cAAc,EAAE,eAAe,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC3D,gBAAgB,CAAC,IAAI,CAAC,QAAQ,EAAE,kBAAkB,CAAC,EAAE,IAAI,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC;QACxF,gBAAgB,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,EAAE,aAAa,CAAC;KACzD,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,aAAa,CAAC,cAAc,EAAE,eAAe,CAAC,CAAC;IAEhE,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC;QAC7E,EAAE,EAAE,cAAc,CAAC,EAAE,EAAE,aAAa,EAAE,EAAE,CAAC;QACzC,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,GAAG,EAAE,QAAQ,CAAC,GAAG;QACjB,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,OAAO,EAAE,QAAQ,CAAC,OAAO;QACzB,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,EAAE,EAAE,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;KACjH,CAAC,CAAC,CAAC;IACJ,MAAM,QAAQ,GACb,QAAQ,CAAC,eAAe,KAAK,SAAS,IAAI,QAAQ,CAAC,YAAY,KAAK,SAAS;QAC5E,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,EAAE,UAAU,EAAE,QAAQ,CAAC,eAAe,EAAE,OAAO,EAAE,QAAQ,CAAC,YAAY,EAAE,CAAC;IAC7E,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;AACpF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC3C,GAAW,EACX,cAA2B,OAAO,CAAC,GAAG;IAEtC,OAAO,CAAC,MAAM,wBAAwB,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC;AACvE,CAAC","sourcesContent":["import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport {\n\tcreateAnthropicProvider,\n\tcreateDeepSeekProvider,\n\tcreateFauxProvider,\n\tcreateOpenAIChatCompletionsProvider,\n\tcreateOpenAIProvider,\n\tcreateZhipuProvider,\n\ttype FauxResponse,\n\ttype Model,\n\ttype ModelApi,\n\ttype Provider,\n} from \"@di-code/ai\";\n\nexport interface StartupRuntime {\n\treadonly provider: Provider;\n\treadonly model: Model;\n}\n\nexport interface StartupProviderConfiguration {\n\treadonly id: string;\n\treadonly name?: string;\n\treadonly api?: string;\n\treadonly apiKey?: string;\n\treadonly baseUrl?: string;\n\treadonly models?: readonly Model[];\n}\n\nexport interface StartupConfiguration {\n\treadonly environment: Environment;\n\treadonly providers: readonly StartupProviderConfiguration[];\n\treadonly defaults?: StartupDefaults;\n}\n\nexport interface StartupDefaults {\n\treadonly providerId?: string;\n\treadonly modelId?: string;\n}\n\nconst FAUX_RESPONSES: readonly FauxResponse[] = [\n\t{\n\t\ttype: \"success\",\n\t\tcontent: [\n\t\t\t{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: \"你好,我是di-code,一个面向终端的 TypeScript AI Coding Agent,支持多 Provider 流式对话、工具调用、JSONL 会话持久化、交互式 TUI、插件扩展与 JSONL RPC 集成。\",\n\t\t\t},\n\t\t],\n\t},\n\t{ type: \"success\", content: [{ type: \"text\", text: \"当前回复为faux数据\" }] },\n];\n\nconst SETTINGS_FILE_NAME = \"settings.json\";\nconst SETTINGS_PATH = join(\".di-code\", SETTINGS_FILE_NAME);\n\ntype Environment = Readonly<Record<string, string | undefined>>;\n\ninterface SettingsFile {\n\treadonly defaultProvider?: string;\n\treadonly defaultModel?: string;\n\treadonly providers: Record<\n\t\tstring,\n\t\t{\n\t\t\treadonly name?: string;\n\t\t\treadonly baseUrl?: string;\n\t\t\treadonly apiKey?: string;\n\t\t\treadonly api?: string;\n\t\t\treadonly models?: unknown;\n\t\t}\n\t>;\n}\n\nexport function resolveStartupArgs(args: readonly string[]): readonly string[] {\n\treturn args.length === 0 ? [\"--interactive\"] : args;\n}\n\nfunction optionalString(value: unknown, path: string, settingsPath: string): string | undefined {\n\tif (value === undefined) return undefined;\n\tif (typeof value !== \"string\") throw new Error(`${settingsPath}: ${path} must be a string`);\n\treturn value;\n}\n\nfunction requiredString(value: unknown, path: string, settingsPath = SETTINGS_PATH): string {\n\tconst result = optionalString(value, path, settingsPath);\n\tif (!result?.trim()) throw new Error(`${settingsPath}: ${path} must be a non-empty string`);\n\treturn result.trim();\n}\n\nfunction positiveInteger(value: unknown, path: string, fallback: number, settingsPath: string): number {\n\tconst result = value ?? fallback;\n\tif (!Number.isInteger(result) || (result as number) <= 0) {\n\t\tthrow new Error(`${settingsPath}: ${path} must be a positive integer`);\n\t}\n\treturn result as number;\n}\n\nfunction nonNegativeNumber(value: unknown, path: string, fallback: number, settingsPath: string): number {\n\tconst result = value ?? fallback;\n\tif (typeof result !== \"number\" || !Number.isFinite(result) || result < 0) {\n\t\tthrow new Error(`${settingsPath}: ${path} must be a non-negative finite number`);\n\t}\n\treturn result;\n}\n\nfunction parseModels(\n\tvalue: unknown,\n\tpath: string,\n\tproviderId: string,\n\tproviderApi: string | undefined,\n\tproviderBaseUrl: string | undefined,\n\tsettingsPath: string,\n): readonly Model[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value)) throw new Error(`${settingsPath}: ${path} must be an array`);\n\n\treturn value.map((entry, index) => {\n\t\tconst modelPath = `${path}[${index}]`;\n\t\tif (typeof entry !== \"object\" || entry === null || Array.isArray(entry)) {\n\t\t\tthrow new Error(`${settingsPath}: ${modelPath} must be an object`);\n\t\t}\n\t\tconst model = entry as Record<string, unknown>;\n\t\tconst input = model.input ?? [\"text\"];\n\t\tif (!Array.isArray(input) || input.length === 0 || input.some((item) => item !== \"text\" && item !== \"image\")) {\n\t\t\tthrow new Error(`${settingsPath}: ${modelPath}.input must contain text and/or image`);\n\t\t}\n\t\tconst cost = model.cost ?? {};\n\t\tif (typeof cost !== \"object\" || cost === null || Array.isArray(cost)) {\n\t\t\tthrow new Error(`${settingsPath}: ${modelPath}.cost must be an object`);\n\t\t}\n\t\tconst prices = cost as Record<string, unknown>;\n\t\tif (model.reasoning !== undefined && typeof model.reasoning !== \"boolean\") {\n\t\t\tthrow new Error(`${settingsPath}: ${modelPath}.reasoning must be a boolean`);\n\t\t}\n\t\tconst configuredReasoningEfforts = model.reasoningEfforts;\n\t\tif (configuredReasoningEfforts !== undefined) {\n\t\t\tif (!Array.isArray(configuredReasoningEfforts) || configuredReasoningEfforts.length === 0) {\n\t\t\t\tthrow new Error(`${settingsPath}: ${modelPath}.reasoningEfforts must be a non-empty array`);\n\t\t\t}\n\t\t\tif (\n\t\t\t\tmodel.reasoning !== true ||\n\t\t\t\tconfiguredReasoningEfforts.some((effort) => effort !== \"low\" && effort !== \"medium\" && effort !== \"high\") ||\n\t\t\t\tnew Set(configuredReasoningEfforts).size !== configuredReasoningEfforts.length\n\t\t\t) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`${settingsPath}: ${modelPath}.reasoningEfforts requires reasoning=true and unique low, medium, or high values`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tif (model.cacheRetention !== undefined && model.cacheRetention !== \"long\") {\n\t\t\tthrow new Error(`${settingsPath}: ${modelPath}.cacheRetention must be \"long\" when provided`);\n\t\t}\n\t\tif (model.sessionAffinity !== undefined && model.sessionAffinity !== \"codex\") {\n\t\t\tthrow new Error(`${settingsPath}: ${modelPath}.sessionAffinity must be \"codex\" when provided`);\n\t\t}\n\t\tconst api = optionalString(model.api, `${modelPath}.api`, settingsPath) ?? providerApi;\n\t\tif (!api) throw new Error(`${settingsPath}: ${modelPath}.api is required`);\n\t\tif (![\"faux\", \"openai-responses\", \"openai-chat-completions\", \"anthropic-messages\"].includes(api)) {\n\t\t\tthrow new Error(`${settingsPath}: ${modelPath}.api is unsupported`);\n\t\t}\n\t\tconst typedApi = api as ModelApi;\n\t\tconst reasoningEfforts: Model[\"reasoningEfforts\"] =\n\t\t\tconfiguredReasoningEfforts === undefined && model.reasoning === true && api === \"openai-responses\"\n\t\t\t\t? [\"low\", \"medium\", \"high\"]\n\t\t\t\t: configuredReasoningEfforts === undefined\n\t\t\t\t\t? undefined\n\t\t\t\t\t: ([...configuredReasoningEfforts] as Model[\"reasoningEfforts\"]);\n\t\tconst baseUrl = optionalString(model.baseUrl, `${modelPath}.baseUrl`, settingsPath) ?? providerBaseUrl;\n\t\tconst id = requiredString(model.id, `${modelPath}.id`, settingsPath);\n\t\treturn {\n\t\t\tid,\n\t\t\tname: requiredString(model.name ?? id, `${modelPath}.name`, settingsPath),\n\t\t\tprovider: providerId,\n\t\t\tapi: typedApi,\n\t\t\t...(baseUrl === undefined ? {} : { baseUrl }),\n\t\t\tinput: [...input],\n\t\t\treasoning: model.reasoning ?? false,\n\t\t\t...(reasoningEfforts ? { reasoningEfforts } : {}),\n\t\t\t...(model.cacheRetention === \"long\" ? { cacheRetention: \"long\" as const } : {}),\n\t\t\t...(model.sessionAffinity === \"codex\" ? { sessionAffinity: \"codex\" as const } : {}),\n\t\t\tcontextWindow: positiveInteger(model.contextWindow, `${modelPath}.contextWindow`, 128_000, settingsPath),\n\t\t\tmaxOutputTokens: positiveInteger(\n\t\t\t\tmodel.maxTokens ?? model.maxOutputTokens,\n\t\t\t\t`${modelPath}.maxTokens`,\n\t\t\t\t16_384,\n\t\t\t\tsettingsPath,\n\t\t\t),\n\t\t\tcost: {\n\t\t\t\tinput: nonNegativeNumber(prices.input, `${modelPath}.cost.input`, 0, settingsPath) / 1_000_000,\n\t\t\t\toutput: nonNegativeNumber(prices.output, `${modelPath}.cost.output`, 0, settingsPath) / 1_000_000,\n\t\t\t\tcacheRead: nonNegativeNumber(prices.cacheRead, `${modelPath}.cost.cacheRead`, 0, settingsPath) / 1_000_000,\n\t\t\t\tcacheWrite: nonNegativeNumber(prices.cacheWrite, `${modelPath}.cost.cacheWrite`, 0, settingsPath) / 1_000_000,\n\t\t\t},\n\t\t};\n\t});\n}\n\nfunction parseSettings(value: unknown, settingsPath: string): SettingsFile {\n\tif (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n\t\tthrow new Error(`${settingsPath}: root value must be an object`);\n\t}\n\tconst record = value as Record<string, unknown>;\n\tconst providersValue = record.providers;\n\tif (typeof providersValue !== \"object\" || providersValue === null || Array.isArray(providersValue)) {\n\t\tthrow new Error(`${settingsPath}: providers must be an object`);\n\t}\n\tconst providers: Record<string, SettingsFile[\"providers\"][string]> = {};\n\tfor (const [id, entry] of Object.entries(providersValue as Record<string, unknown>)) {\n\t\tif (typeof entry !== \"object\" || entry === null || Array.isArray(entry)) {\n\t\t\tthrow new Error(`${settingsPath}: providers.${id} must be an object`);\n\t\t}\n\t\tconst provider = entry as Record<string, unknown>;\n\t\tproviders[id] = {\n\t\t\tname: optionalString(provider.name, `providers.${id}.name`, settingsPath),\n\t\t\tbaseUrl: optionalString(provider.baseUrl, `providers.${id}.baseUrl`, settingsPath),\n\t\t\tapiKey: optionalString(provider.apiKey, `providers.${id}.apiKey`, settingsPath),\n\t\t\tapi: optionalString(provider.api, `providers.${id}.api`, settingsPath),\n\t\t\tmodels: provider.models,\n\t\t};\n\t}\n\tconst defaultProvider =\n\t\trecord.defaultProvider === undefined\n\t\t\t? undefined\n\t\t\t: requiredString(record.defaultProvider, \"defaultProvider\", settingsPath);\n\tconst defaultModel =\n\t\trecord.defaultModel === undefined ? undefined : requiredString(record.defaultModel, \"defaultModel\", settingsPath);\n\treturn {\n\t\tproviders,\n\t\t...(defaultProvider === undefined ? {} : { defaultProvider }),\n\t\t...(defaultModel === undefined ? {} : { defaultModel }),\n\t};\n}\n\nasync function readSettingsFile(path: string, displayPath: string): Promise<SettingsFile | undefined> {\n\ttry {\n\t\tconst source = await readFile(path, \"utf8\");\n\t\tif (source.trim().length === 0) return undefined;\n\t\treturn parseSettings(JSON.parse(source), displayPath);\n\t} catch (cause) {\n\t\tif (cause instanceof Error && \"code\" in cause && cause.code === \"ENOENT\") return undefined;\n\t\tif (cause instanceof SyntaxError) throw new Error(`${displayPath}: invalid JSON`, { cause });\n\t\tthrow cause;\n\t}\n}\n\nfunction mergeSettings(\n\tglobalSettings: SettingsFile | undefined,\n\tprojectSettings: SettingsFile | undefined,\n): SettingsFile {\n\tconst globalProviders = globalSettings?.providers ?? {};\n\tconst projectProviders = projectSettings?.providers ?? {};\n\tconst providers = { ...globalProviders };\n\tfor (const [id, projectProvider] of Object.entries(projectProviders)) {\n\t\tproviders[id] = {\n\t\t\t...globalProviders[id],\n\t\t\t...(projectProvider.name === undefined ? {} : { name: projectProvider.name }),\n\t\t\t...(projectProvider.baseUrl === undefined ? {} : { baseUrl: projectProvider.baseUrl }),\n\t\t\t...(projectProvider.apiKey === undefined ? {} : { apiKey: projectProvider.apiKey }),\n\t\t\t...(projectProvider.api === undefined ? {} : { api: projectProvider.api }),\n\t\t\t...(projectProvider.models === undefined ? {} : { models: projectProvider.models }),\n\t\t};\n\t}\n\tconst defaultProvider = projectSettings?.defaultProvider ?? globalSettings?.defaultProvider;\n\tconst defaultModel =\n\t\tprojectSettings?.defaultModel ??\n\t\t(projectSettings?.defaultProvider === undefined ? globalSettings?.defaultModel : undefined);\n\treturn {\n\t\tproviders,\n\t\t...(defaultProvider === undefined ? {} : { defaultProvider }),\n\t\t...(defaultModel === undefined ? {} : { defaultModel }),\n\t};\n}\n\nexport async function saveGlobalProviderApiKey(\n\tagentDir: string,\n\tproviderId: string,\n\tapi: Exclude<ModelApi, \"faux\">,\n\tapiKey: string,\n\tmodelId?: string,\n): Promise<void> {\n\tconst settingsFilePath = join(agentDir, SETTINGS_FILE_NAME);\n\tconst trimmedApiKey = apiKey.trim();\n\tif (!trimmedApiKey) throw new Error(`${settingsFilePath}: apiKey must be a non-empty string`);\n\tconst existingSettings = await readSettingsFile(settingsFilePath, settingsFilePath);\n\tconst settings = mergeSettings(existingSettings, {\n\t\tproviders: { [providerId]: { api, apiKey: trimmedApiKey } },\n\t\tdefaultProvider: providerId,\n\t\t...(modelId === undefined ? {} : { defaultModel: modelId }),\n\t});\n\tawait mkdir(agentDir, { recursive: true, mode: 0o700 });\n\tawait writeFile(settingsFilePath, `${JSON.stringify(settings, null, \"\\t\")}\\n`, { encoding: \"utf8\", mode: 0o600 });\n}\n\n/** Removes only the persisted credential for one provider; environment variables remain untouched. */\nexport async function removeGlobalProviderApiKey(agentDir: string, providerId: string): Promise<boolean> {\n\tconst settingsFilePath = join(agentDir, SETTINGS_FILE_NAME);\n\tconst existingSettings = await readSettingsFile(settingsFilePath, settingsFilePath);\n\tconst provider = existingSettings?.providers[providerId];\n\tif (!provider || provider.apiKey === undefined) return false;\n\n\tconst { apiKey: _apiKey, ...providerWithoutApiKey } = provider;\n\tconst settings: SettingsFile = {\n\t\t...existingSettings,\n\t\tproviders: {\n\t\t\t...existingSettings.providers,\n\t\t\t[providerId]: providerWithoutApiKey,\n\t\t},\n\t};\n\tawait writeFile(settingsFilePath, `${JSON.stringify(settings, null, \"\\t\")}\\n`, { encoding: \"utf8\", mode: 0o600 });\n\treturn true;\n}\n\nfunction resolveConfigValue(value: string | undefined, env: Environment): string | undefined {\n\tif (value === undefined) return undefined;\n\tconst trimmed = value.trim();\n\tconst match = /^\\$\\{([A-Za-z_][A-Za-z0-9_]*)\\}$|^\\$([A-Za-z_][A-Za-z0-9_]*)$/.exec(trimmed);\n\tif (match) {\n\t\tconst name = match[1] ?? match[2];\n\t\tconst resolved = env[name];\n\t\tif (!resolved?.trim()) throw new Error(`Configured apiKey environment variable \"${name}\" is not set.`);\n\t\treturn resolved;\n\t}\n\tif (trimmed.startsWith(\"!\")) {\n\t\tthrow new Error(\"Command-based apiKey values are not supported by di-code; use $ENV_VAR instead.\");\n\t}\n\treturn value;\n}\n\nfunction createFauxRuntime(): StartupRuntime {\n\tconst faux = createFauxProvider({ responses: FAUX_RESPONSES });\n\treturn { provider: faux.provider, model: faux.model };\n}\n\nfunction selectProviderModel(provider: Provider, providerId: string, env: Environment): Model {\n\tconst modelId =\n\t\tenv.DI_CODE_MODEL?.trim() ||\n\t\t(providerId === \"anthropic\"\n\t\t\t? provider.models.find((candidate) => candidate.id === \"claude-sonnet-4-5\")?.id\n\t\t\t: providerId === \"openai\"\n\t\t\t\t? provider.models.find((candidate) => candidate.id === \"gpt-4o\")?.id\n\t\t\t\t: providerId === \"zhipu\"\n\t\t\t\t\t? provider.models.find((candidate) => candidate.id === \"glm-5.3\")?.id\n\t\t\t\t\t: undefined) ||\n\t\tprovider.models[0]?.id;\n\tif (!modelId) throw new Error(\"DI_CODE_MODEL is required when the selected provider has no models\");\n\tconst model = provider.models.find((candidate) => candidate.id === modelId);\n\tif (!model) {\n\t\tconst availableModels = provider.models.map((candidate) => candidate.id).join(\", \");\n\t\tthrow new Error(`Unknown model \"${modelId}\" for provider \"${providerId}\". Available models: ${availableModels}.`);\n\t}\n\treturn model;\n}\n\nfunction createBuiltInRuntime(env: Environment, providerId: string): StartupRuntime | undefined {\n\tif (providerId === \"anthropic\") {\n\t\tconst provider = createAnthropicProvider({ env });\n\t\treturn { provider, model: selectProviderModel(provider, providerId, env) };\n\t}\n\tif (providerId === \"openai\") {\n\t\tconst provider = createOpenAIProvider({ env });\n\t\treturn { provider, model: selectProviderModel(provider, providerId, env) };\n\t}\n\tif (providerId === \"deepseek\") {\n\t\tconst provider = createDeepSeekProvider({ env });\n\t\treturn { provider, model: selectProviderModel(provider, providerId, env) };\n\t}\n\tif (providerId === \"zhipu\") {\n\t\tconst provider = createZhipuProvider({ env });\n\t\treturn { provider, model: selectProviderModel(provider, providerId, env) };\n\t}\n\treturn undefined;\n}\n\nfunction createConfiguredRuntime(env: Environment, configuration: StartupProviderConfiguration): StartupRuntime {\n\tif (\n\t\tconfiguration.api !== \"openai-responses\" &&\n\t\tconfiguration.api !== \"openai-chat-completions\" &&\n\t\tconfiguration.api !== \"anthropic-messages\"\n\t) {\n\t\tthrow new Error(\n\t\t\t`Unsupported API \"${configuration.api ?? \"missing\"}\" for provider \"${configuration.id}\". Expected openai-responses, openai-chat-completions, or anthropic-messages.`,\n\t\t);\n\t}\n\tif (\n\t\tconfiguration.id !== \"openai\" &&\n\t\tconfiguration.id !== \"deepseek\" &&\n\t\tconfiguration.id !== \"zhipu\" &&\n\t\tconfiguration.id !== \"anthropic\" &&\n\t\t!configuration.models\n\t) {\n\t\tthrow new Error(`${SETTINGS_PATH}: providers.${configuration.id}.models is required for a custom provider`);\n\t}\n\tconst provider =\n\t\tconfiguration.api === \"openai-chat-completions\"\n\t\t\t? createOpenAIChatCompletionsProvider({\n\t\t\t\t\tenv:\n\t\t\t\t\t\tconfiguration.id === \"zhipu\" || configuration.id === \"deepseek\"\n\t\t\t\t\t\t\t? env\n\t\t\t\t\t\t\t: Object.fromEntries(\n\t\t\t\t\t\t\t\t\tObject.entries(env).filter(([name]) => name !== \"OPENAI_API_KEY\" && name !== \"OPENAI_BASE_URL\"),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\tmodels: configuration.models,\n\t\t\t\t\tapiKey: resolveConfigValue(configuration.apiKey, env),\n\t\t\t\t\tbaseUrl: configuration.models ? undefined : configuration.baseUrl,\n\t\t\t\t\tproviderId: configuration.id,\n\t\t\t\t\tname: configuration.name ?? configuration.id,\n\t\t\t\t\t...(configuration.id === \"zhipu\"\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tapiKeyEnvironmentVariable: \"ZAI_API_KEY\",\n\t\t\t\t\t\t\t\tbaseUrlEnvironmentVariable: \"ZHIPU_BASE_URL\",\n\t\t\t\t\t\t\t\tdefaultBaseUrl: \"https://open.bigmodel.cn/api/coding/paas/v4\",\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: configuration.id === \"deepseek\"\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\tapiKeyEnvironmentVariable: \"DEEPSEEK_API_KEY\",\n\t\t\t\t\t\t\t\t\tbaseUrlEnvironmentVariable: \"DEEPSEEK_BASE_URL\",\n\t\t\t\t\t\t\t\t\tdefaultBaseUrl: \"https://api.deepseek.com\",\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t: {}),\n\t\t\t\t})\n\t\t\t: configuration.api === \"anthropic-messages\"\n\t\t\t\t? createAnthropicProvider({\n\t\t\t\t\t\tenv:\n\t\t\t\t\t\t\tconfiguration.id === \"anthropic\"\n\t\t\t\t\t\t\t\t? env\n\t\t\t\t\t\t\t\t: Object.fromEntries(\n\t\t\t\t\t\t\t\t\t\tObject.entries(env).filter(\n\t\t\t\t\t\t\t\t\t\t\t([name]) => name !== \"ANTHROPIC_API_KEY\" && name !== \"ANTHROPIC_BASE_URL\",\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\tmodels: configuration.models,\n\t\t\t\t\t\tapiKey: resolveConfigValue(configuration.apiKey, env),\n\t\t\t\t\t\tbaseUrl: configuration.models ? undefined : configuration.baseUrl,\n\t\t\t\t\t\tproviderId: configuration.id,\n\t\t\t\t\t\tname: configuration.name,\n\t\t\t\t\t})\n\t\t\t\t: configuration.id === \"deepseek\"\n\t\t\t\t\t? createDeepSeekProvider({\n\t\t\t\t\t\t\tenv,\n\t\t\t\t\t\t\tmodels: configuration.models,\n\t\t\t\t\t\t\tapiKey: resolveConfigValue(configuration.apiKey, env),\n\t\t\t\t\t\t\tbaseUrl: configuration.models ? undefined : configuration.baseUrl,\n\t\t\t\t\t\t})\n\t\t\t\t\t: configuration.id === \"zhipu\"\n\t\t\t\t\t\t? createZhipuProvider({\n\t\t\t\t\t\t\t\tenv,\n\t\t\t\t\t\t\t\tmodels: configuration.models,\n\t\t\t\t\t\t\t\tapiKey: resolveConfigValue(configuration.apiKey, env),\n\t\t\t\t\t\t\t\tbaseUrl: configuration.models ? undefined : configuration.baseUrl,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t: createOpenAIProvider({\n\t\t\t\t\t\t\t\tenv:\n\t\t\t\t\t\t\t\t\tconfiguration.id === \"openai\"\n\t\t\t\t\t\t\t\t\t\t? env\n\t\t\t\t\t\t\t\t\t\t: Object.fromEntries(\n\t\t\t\t\t\t\t\t\t\t\t\tObject.entries(env).filter(([name]) => name !== \"OPENAI_API_KEY\" && name !== \"OPENAI_BASE_URL\"),\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\tmodels: configuration.models,\n\t\t\t\t\t\t\t\tapiKey: resolveConfigValue(configuration.apiKey, env),\n\t\t\t\t\t\t\t\tbaseUrl: configuration.models ? undefined : configuration.baseUrl,\n\t\t\t\t\t\t\t\tproviderId: configuration.id,\n\t\t\t\t\t\t\t\tname: configuration.name,\n\t\t\t\t\t\t\t});\n\tconst model = selectProviderModel(provider, configuration.id, env);\n\treturn { provider, model };\n}\n\nexport function resolveStartupRuntime(\n\tenv: Environment,\n\tproviders: readonly StartupProviderConfiguration[],\n\tdefaults: StartupDefaults = {},\n): StartupRuntime {\n\tconst selectedProviderId =\n\t\tenv.DI_CODE_PROVIDER?.trim() || defaults.providerId || (providers.length === 1 ? providers[0]?.id : undefined);\n\tif (selectedProviderId === \"faux\") return createFauxRuntime();\n\tif (!selectedProviderId) {\n\t\tif (providers.length === 0) {\n\t\t\tthrow new Error(\"Provider is not configured. Set DI_CODE_PROVIDER or start interactive mode in a TTY.\");\n\t\t}\n\t\tthrow new Error(\"DI_CODE_PROVIDER is required when more than one provider is configured.\");\n\t}\n\tconst runtimeEnvironment =\n\t\tenv.DI_CODE_MODEL?.trim() || defaults.providerId !== selectedProviderId || !defaults.modelId\n\t\t\t? env\n\t\t\t: { ...env, DI_CODE_MODEL: defaults.modelId };\n\tconst selectedProvider = providers.find((provider) => provider.id === selectedProviderId);\n\tif (selectedProvider) return createConfiguredRuntime(runtimeEnvironment, selectedProvider);\n\tconst builtInRuntime = createBuiltInRuntime(runtimeEnvironment, selectedProviderId);\n\tif (builtInRuntime) return builtInRuntime;\n\tthrow new Error(\n\t\t`Unknown configured provider \"${selectedProviderId}\". Available providers: ${providers.map((provider) => provider.id).join(\", \")}.`,\n\t);\n}\n\nexport async function loadStartupConfiguration(\n\tcwd: string,\n\tenvironment: Environment = process.env,\n\tagentDir = join(homedir(), \".di-code\"),\n): Promise<StartupConfiguration> {\n\tconst [globalSettings, projectSettings] = await Promise.all([\n\t\treadSettingsFile(join(agentDir, SETTINGS_FILE_NAME), join(agentDir, SETTINGS_FILE_NAME)),\n\t\treadSettingsFile(join(cwd, SETTINGS_PATH), SETTINGS_PATH),\n\t]);\n\tconst settings = mergeSettings(globalSettings, projectSettings);\n\n\tconst providers = Object.entries(settings.providers).map(([id, provider]) => ({\n\t\tid: requiredString(id, `providers.${id}`),\n\t\tname: provider.name,\n\t\tapi: provider.api,\n\t\tapiKey: provider.apiKey,\n\t\tbaseUrl: provider.baseUrl,\n\t\tmodels: parseModels(provider.models, `providers.${id}.models`, id, provider.api, provider.baseUrl, SETTINGS_PATH),\n\t}));\n\tconst defaults =\n\t\tsettings.defaultProvider === undefined && settings.defaultModel === undefined\n\t\t\t? undefined\n\t\t\t: { providerId: settings.defaultProvider, modelId: settings.defaultModel };\n\treturn { environment, providers, ...(defaults === undefined ? {} : { defaults }) };\n}\n\nexport async function loadStartupEnvironment(\n\tcwd: string,\n\tenvironment: Environment = process.env,\n): Promise<Environment> {\n\treturn (await loadStartupConfiguration(cwd, environment)).environment;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@di-code/coding-agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Coding agent product layer for di-code",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai-coding-agent",
|
|
@@ -52,9 +52,10 @@
|
|
|
52
52
|
"test": "vitest run --passWithNoTests"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@di-code/agent": "0.1.
|
|
56
|
-
"@di-code/ai": "0.1.
|
|
57
|
-
"@di-code/tui": "0.1.
|
|
55
|
+
"@di-code/agent": "0.1.4",
|
|
56
|
+
"@di-code/ai": "0.1.4",
|
|
57
|
+
"@di-code/tui": "0.1.4",
|
|
58
|
+
"diff": "8.0.4",
|
|
58
59
|
"highlight.js": "^10.7.3",
|
|
59
60
|
"jiti": "^2.5.1"
|
|
60
61
|
},
|