arki 0.0.5 → 0.0.7
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 +21 -3
- package/dist/config/.arki/config.json +3 -0
- package/dist/config/.arki/state.json +4 -0
- package/dist/config/{config.json → arki/config.json} +1 -1
- package/dist/index.d.ts +100 -83
- package/dist/index.js +534 -273
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,125 +1,421 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __esm = (fn, res) => function __init() {
|
|
5
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
6
|
+
};
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
2
11
|
|
|
3
|
-
// src/
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import * as path5 from "path";
|
|
7
|
-
import * as os2 from "os";
|
|
8
|
-
|
|
9
|
-
// src/config/config.ts
|
|
10
|
-
import * as fs from "fs/promises";
|
|
11
|
-
import * as path from "path";
|
|
12
|
-
import * as os from "os";
|
|
12
|
+
// src/fs/paths.ts
|
|
13
|
+
import os from "os";
|
|
14
|
+
import path from "path";
|
|
13
15
|
import { fileURLToPath } from "url";
|
|
14
|
-
function
|
|
15
|
-
|
|
16
|
+
function getOSName() {
|
|
17
|
+
const platform = os.platform();
|
|
18
|
+
switch (platform) {
|
|
19
|
+
case "win32":
|
|
20
|
+
return "windows";
|
|
21
|
+
case "darwin":
|
|
22
|
+
return "mac";
|
|
23
|
+
case "linux":
|
|
24
|
+
return "linux";
|
|
25
|
+
default:
|
|
26
|
+
return "other";
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function setWorkingDir(dir) {
|
|
30
|
+
workingDir = dir;
|
|
16
31
|
}
|
|
17
|
-
function
|
|
32
|
+
function getGlobalConfigDir() {
|
|
33
|
+
if (OS.name === "windows") {
|
|
34
|
+
return path.join(
|
|
35
|
+
process.env.APPDATA || path.join(os.homedir(), "AppData", "Roaming"),
|
|
36
|
+
"arki"
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
return path.join(os.homedir(), ".config", "arki");
|
|
40
|
+
}
|
|
41
|
+
function getPackageDir(relativePath) {
|
|
18
42
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
19
|
-
return path.join(__dirname, "
|
|
43
|
+
return path.join(__dirname, "..", relativePath);
|
|
20
44
|
}
|
|
21
|
-
var
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
this.loadEnvApiKeys();
|
|
43
|
-
this.loaded = true;
|
|
44
|
-
return this.config;
|
|
45
|
+
var OS, workingDir, PATHS;
|
|
46
|
+
var init_paths = __esm({
|
|
47
|
+
"src/fs/paths.ts"() {
|
|
48
|
+
"use strict";
|
|
49
|
+
OS = {
|
|
50
|
+
name: getOSName(),
|
|
51
|
+
version: os.release()
|
|
52
|
+
};
|
|
53
|
+
workingDir = process.cwd();
|
|
54
|
+
PATHS = {
|
|
55
|
+
/** Global config directory (~/.config/arki or %APPDATA%\arki) */
|
|
56
|
+
globalConfig: getGlobalConfigDir(),
|
|
57
|
+
/** Project config directory (.arki/) - returns path based on current workingDir */
|
|
58
|
+
get projectConfig() {
|
|
59
|
+
return path.join(workingDir, ".arki");
|
|
60
|
+
},
|
|
61
|
+
/** Package's global config template directory */
|
|
62
|
+
globalTemplate: getPackageDir("config/arki"),
|
|
63
|
+
/** Package's project config template directory */
|
|
64
|
+
projectTemplate: getPackageDir("config/.arki")
|
|
65
|
+
};
|
|
45
66
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
if (process.env.ANTHROPIC_API_KEY && configToSave.apiKeys.anthropic === process.env.ANTHROPIC_API_KEY) {
|
|
58
|
-
delete configToSave.apiKeys.anthropic;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
await fs.writeFile(configPath, JSON.stringify(configToSave, null, 2), "utf-8");
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// src/fs/file.ts
|
|
70
|
+
import * as fs from "fs/promises";
|
|
71
|
+
async function fileExists(filePath) {
|
|
72
|
+
try {
|
|
73
|
+
const stat3 = await fs.stat(filePath);
|
|
74
|
+
return stat3.isFile();
|
|
75
|
+
} catch {
|
|
76
|
+
return false;
|
|
62
77
|
}
|
|
63
|
-
|
|
64
|
-
|
|
78
|
+
}
|
|
79
|
+
async function readJsonFile(filePath) {
|
|
80
|
+
try {
|
|
81
|
+
const content = await fs.readFile(filePath, "utf-8");
|
|
82
|
+
return JSON.parse(content);
|
|
83
|
+
} catch {
|
|
84
|
+
return null;
|
|
65
85
|
}
|
|
66
|
-
|
|
67
|
-
|
|
86
|
+
}
|
|
87
|
+
async function writeJsonFile(filePath, data) {
|
|
88
|
+
await fs.writeFile(filePath, JSON.stringify(data, null, 2), "utf-8");
|
|
89
|
+
}
|
|
90
|
+
async function readFile2(filePath) {
|
|
91
|
+
try {
|
|
92
|
+
return await fs.readFile(filePath, "utf-8");
|
|
93
|
+
} catch {
|
|
94
|
+
return null;
|
|
68
95
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
96
|
+
}
|
|
97
|
+
async function writeFile2(filePath, content) {
|
|
98
|
+
await fs.writeFile(filePath, content, "utf-8");
|
|
99
|
+
}
|
|
100
|
+
var init_file = __esm({
|
|
101
|
+
"src/fs/file.ts"() {
|
|
102
|
+
"use strict";
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// src/fs/dir.ts
|
|
107
|
+
import * as fs2 from "fs/promises";
|
|
108
|
+
import * as path2 from "path";
|
|
109
|
+
async function copyDir(src, dest) {
|
|
110
|
+
await fs2.mkdir(dest, { recursive: true });
|
|
111
|
+
const entries = await fs2.readdir(src, { withFileTypes: true });
|
|
112
|
+
for (const entry of entries) {
|
|
113
|
+
const srcPath = path2.join(src, entry.name);
|
|
114
|
+
const destPath = path2.join(dest, entry.name);
|
|
115
|
+
if (entry.isDirectory()) {
|
|
116
|
+
await copyDir(srcPath, destPath);
|
|
117
|
+
} else {
|
|
118
|
+
await fs2.copyFile(srcPath, destPath);
|
|
73
119
|
}
|
|
74
|
-
return agentConfig;
|
|
75
120
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
121
|
+
}
|
|
122
|
+
async function dirExists(dirPath) {
|
|
123
|
+
try {
|
|
124
|
+
const stat3 = await fs2.stat(dirPath);
|
|
125
|
+
return stat3.isDirectory();
|
|
126
|
+
} catch {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
async function mkdir2(dirPath) {
|
|
131
|
+
await fs2.mkdir(dirPath, { recursive: true });
|
|
132
|
+
}
|
|
133
|
+
var init_dir = __esm({
|
|
134
|
+
"src/fs/dir.ts"() {
|
|
135
|
+
"use strict";
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
// src/fs/index.ts
|
|
140
|
+
var fs_exports = {};
|
|
141
|
+
__export(fs_exports, {
|
|
142
|
+
OS: () => OS,
|
|
143
|
+
PATHS: () => PATHS,
|
|
144
|
+
copyDir: () => copyDir,
|
|
145
|
+
dirExists: () => dirExists,
|
|
146
|
+
fileExists: () => fileExists,
|
|
147
|
+
mkdir: () => mkdir2,
|
|
148
|
+
readFile: () => readFile2,
|
|
149
|
+
readJsonFile: () => readJsonFile,
|
|
150
|
+
setWorkingDir: () => setWorkingDir,
|
|
151
|
+
workingDir: () => workingDir,
|
|
152
|
+
writeFile: () => writeFile2,
|
|
153
|
+
writeJsonFile: () => writeJsonFile
|
|
154
|
+
});
|
|
155
|
+
var init_fs = __esm({
|
|
156
|
+
"src/fs/index.ts"() {
|
|
157
|
+
"use strict";
|
|
158
|
+
init_paths();
|
|
159
|
+
init_file();
|
|
160
|
+
init_dir();
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
// src/log/log.ts
|
|
165
|
+
function getTimestamp() {
|
|
166
|
+
return (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
|
|
167
|
+
}
|
|
168
|
+
function print(message) {
|
|
169
|
+
console.log(convertColorTags(message));
|
|
170
|
+
}
|
|
171
|
+
function log(message) {
|
|
172
|
+
print(`<gray>[${getTimestamp()}]</gray> ${message}`);
|
|
173
|
+
}
|
|
174
|
+
function info(message) {
|
|
175
|
+
log(`<blue>[INFO]</blue> ${message}`);
|
|
176
|
+
}
|
|
177
|
+
function success(message) {
|
|
178
|
+
log(`<green>[OK]</green> ${message}`);
|
|
179
|
+
}
|
|
180
|
+
function warn(message) {
|
|
181
|
+
log(`<yellow>[WARN]</yellow> ${message}`);
|
|
182
|
+
}
|
|
183
|
+
function error(message) {
|
|
184
|
+
log(`<red>[ERROR]</red> ${message}`);
|
|
185
|
+
}
|
|
186
|
+
var init_log = __esm({
|
|
187
|
+
"src/log/log.ts"() {
|
|
188
|
+
"use strict";
|
|
189
|
+
init_log2();
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
// src/log/debug.ts
|
|
194
|
+
function isDebugMode() {
|
|
195
|
+
return _debugMode;
|
|
196
|
+
}
|
|
197
|
+
function setDebugMode(enabled) {
|
|
198
|
+
_debugMode = enabled;
|
|
199
|
+
}
|
|
200
|
+
function formatData(data, maxLen = 100) {
|
|
201
|
+
if (data === void 0) return "";
|
|
202
|
+
const str = typeof data === "string" ? data : JSON.stringify(data);
|
|
203
|
+
const singleLine = str.replace(/\s+/g, " ").trim();
|
|
204
|
+
return singleLine.length > maxLen ? singleLine.slice(0, maxLen) + "..." : singleLine;
|
|
205
|
+
}
|
|
206
|
+
function debug(category, message, data) {
|
|
207
|
+
if (!_debugMode) return;
|
|
208
|
+
const dataStr = data !== void 0 ? ` <dim>${formatData(data)}</dim>` : "";
|
|
209
|
+
log(`<magenta>[${category}]</magenta> <cyan>${message}</cyan>${dataStr}`);
|
|
210
|
+
}
|
|
211
|
+
var _debugMode;
|
|
212
|
+
var init_debug = __esm({
|
|
213
|
+
"src/log/debug.ts"() {
|
|
214
|
+
"use strict";
|
|
215
|
+
init_log();
|
|
216
|
+
_debugMode = false;
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
// src/log/index.ts
|
|
221
|
+
function convertColorTags(str) {
|
|
222
|
+
return str.replace(tagRegex, (_, closing, tag) => {
|
|
223
|
+
return closing ? colors.reset : colors[tag.toLowerCase()] || "";
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
function createColorConverter() {
|
|
227
|
+
let buffer = "";
|
|
228
|
+
return (chunk) => {
|
|
229
|
+
buffer += chunk;
|
|
230
|
+
const lastOpen = buffer.lastIndexOf("<");
|
|
231
|
+
if (lastOpen === -1) {
|
|
232
|
+
const out2 = convertColorTags(buffer);
|
|
233
|
+
buffer = "";
|
|
234
|
+
return out2;
|
|
82
235
|
}
|
|
83
|
-
if (
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
236
|
+
if (buffer.indexOf(">", lastOpen) !== -1) {
|
|
237
|
+
const out2 = convertColorTags(buffer);
|
|
238
|
+
buffer = "";
|
|
239
|
+
return out2;
|
|
88
240
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
241
|
+
const out = convertColorTags(buffer.slice(0, lastOpen));
|
|
242
|
+
buffer = buffer.slice(lastOpen);
|
|
243
|
+
return out;
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
var colors, tagNames, tagRegex;
|
|
247
|
+
var init_log2 = __esm({
|
|
248
|
+
"src/log/index.ts"() {
|
|
249
|
+
"use strict";
|
|
250
|
+
init_debug();
|
|
251
|
+
init_log();
|
|
252
|
+
colors = {
|
|
253
|
+
reset: "\x1B[0m",
|
|
254
|
+
bold: "\x1B[1m",
|
|
255
|
+
dim: "\x1B[2m",
|
|
256
|
+
italic: "\x1B[3m",
|
|
257
|
+
underline: "\x1B[4m",
|
|
258
|
+
inverse: "\x1B[7m",
|
|
259
|
+
strikethrough: "\x1B[9m",
|
|
260
|
+
red: "\x1B[31m",
|
|
261
|
+
green: "\x1B[32m",
|
|
262
|
+
yellow: "\x1B[33m",
|
|
263
|
+
blue: "\x1B[34m",
|
|
264
|
+
magenta: "\x1B[35m",
|
|
265
|
+
cyan: "\x1B[36m",
|
|
266
|
+
gray: "\x1B[90m"
|
|
267
|
+
};
|
|
268
|
+
tagNames = Object.keys(colors).filter((k) => k !== "reset").join("|");
|
|
269
|
+
tagRegex = new RegExp(`<(\\/?)(${tagNames})>`, "gi");
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
// src/init/loader.ts
|
|
274
|
+
var loader_exports = {};
|
|
275
|
+
__export(loader_exports, {
|
|
276
|
+
getAgentConfig: () => getAgentConfig,
|
|
277
|
+
getApiKey: () => getApiKey,
|
|
278
|
+
getConfig: () => getConfig,
|
|
279
|
+
loadConfigs: () => loadConfigs,
|
|
280
|
+
saveConfig: () => saveConfig
|
|
281
|
+
});
|
|
282
|
+
import * as path3 from "path";
|
|
283
|
+
function deepMerge(base, override) {
|
|
284
|
+
const result = {
|
|
285
|
+
...base,
|
|
286
|
+
agents: { ...base.agents }
|
|
287
|
+
};
|
|
288
|
+
if (override.agents) {
|
|
289
|
+
for (const key of Object.keys(override.agents)) {
|
|
290
|
+
const overrideAgent = override.agents[key];
|
|
291
|
+
if (overrideAgent) {
|
|
292
|
+
result.agents[key] = { ...result.agents[key], ...overrideAgent };
|
|
93
293
|
}
|
|
94
294
|
}
|
|
95
295
|
}
|
|
96
|
-
|
|
97
|
-
|
|
296
|
+
return result;
|
|
297
|
+
}
|
|
298
|
+
async function loadConfigs() {
|
|
299
|
+
if (mergedConfig) {
|
|
300
|
+
return mergedConfig;
|
|
301
|
+
}
|
|
302
|
+
const globalConfigPath = path3.join(PATHS.globalConfig, "config.json");
|
|
303
|
+
const globalConfig = await readJsonFile(globalConfigPath);
|
|
304
|
+
if (!globalConfig) {
|
|
305
|
+
throw new Error(`Failed to load global config: ${globalConfigPath}`);
|
|
306
|
+
}
|
|
307
|
+
const projectConfigPath = path3.join(PATHS.projectConfig, "config.json");
|
|
308
|
+
const projectConfig = await readJsonFile(projectConfigPath);
|
|
309
|
+
if (projectConfig) {
|
|
310
|
+
mergedConfig = deepMerge(globalConfig, projectConfig);
|
|
311
|
+
} else {
|
|
312
|
+
mergedConfig = globalConfig;
|
|
313
|
+
}
|
|
314
|
+
return mergedConfig;
|
|
315
|
+
}
|
|
316
|
+
function getConfig() {
|
|
317
|
+
if (!mergedConfig) {
|
|
318
|
+
throw new Error("Config not loaded yet. Please call loadConfigs() first.");
|
|
319
|
+
}
|
|
320
|
+
return mergedConfig;
|
|
321
|
+
}
|
|
322
|
+
function getApiKey(provider) {
|
|
323
|
+
const envMap = {
|
|
324
|
+
openai: "OPENAI_API_KEY",
|
|
325
|
+
anthropic: "ANTHROPIC_API_KEY",
|
|
326
|
+
google: "GOOGLE_API_KEY"
|
|
327
|
+
};
|
|
328
|
+
const envVar = envMap[provider] || `${provider.toUpperCase()}_API_KEY`;
|
|
329
|
+
return process.env[envVar];
|
|
330
|
+
}
|
|
331
|
+
function getAgentConfig(agentType) {
|
|
332
|
+
const agentConfig = getConfig().agents[agentType];
|
|
333
|
+
if (!agentConfig) {
|
|
334
|
+
throw new Error(`Agent config not found: ${agentType}`);
|
|
335
|
+
}
|
|
336
|
+
return agentConfig;
|
|
337
|
+
}
|
|
338
|
+
async function saveConfig() {
|
|
339
|
+
const config = getConfig();
|
|
340
|
+
const configPath = path3.join(PATHS.globalConfig, "config.json");
|
|
341
|
+
await writeJsonFile(configPath, config);
|
|
342
|
+
}
|
|
343
|
+
var mergedConfig;
|
|
344
|
+
var init_loader = __esm({
|
|
345
|
+
"src/init/loader.ts"() {
|
|
346
|
+
"use strict";
|
|
347
|
+
init_fs();
|
|
348
|
+
mergedConfig = null;
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
// src/init/project.ts
|
|
353
|
+
var project_exports = {};
|
|
354
|
+
__export(project_exports, {
|
|
355
|
+
initProject: () => initProject
|
|
356
|
+
});
|
|
357
|
+
import * as path4 from "path";
|
|
358
|
+
import * as readline from "readline";
|
|
359
|
+
async function askQuestion(question) {
|
|
360
|
+
const rl = readline.createInterface({
|
|
361
|
+
input: process.stdin,
|
|
362
|
+
output: process.stdout
|
|
363
|
+
});
|
|
364
|
+
return new Promise((resolve4) => {
|
|
365
|
+
rl.question(`${question} (y/n): `, (answer) => {
|
|
366
|
+
rl.close();
|
|
367
|
+
resolve4(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
|
|
368
|
+
});
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
async function initProject(forceInit) {
|
|
372
|
+
const projectConfigDir = PATHS.projectConfig;
|
|
373
|
+
if (await dirExists(projectConfigDir)) {
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
const trusted = forceInit ? true : await (async () => {
|
|
377
|
+
print(`
|
|
378
|
+
<dim>Project directory: ${workingDir}</dim>`);
|
|
379
|
+
return askQuestion("Do you trust this project and want to initialize arki config?");
|
|
380
|
+
})();
|
|
381
|
+
if (!trusted) {
|
|
382
|
+
print("<yellow>Initialization cancelled.</yellow>");
|
|
383
|
+
process.exit(0);
|
|
384
|
+
}
|
|
385
|
+
await copyDir(PATHS.projectTemplate, projectConfigDir);
|
|
386
|
+
const statePath = path4.join(projectConfigDir, "state.json");
|
|
387
|
+
const state = {
|
|
388
|
+
initialized: true,
|
|
389
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
390
|
+
};
|
|
391
|
+
await writeJsonFile(statePath, state);
|
|
392
|
+
print("<green>Project configuration initialized.</green>");
|
|
393
|
+
}
|
|
394
|
+
var init_project = __esm({
|
|
395
|
+
"src/init/project.ts"() {
|
|
396
|
+
"use strict";
|
|
397
|
+
init_fs();
|
|
398
|
+
init_log2();
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
// src/index.ts
|
|
403
|
+
import * as readline2 from "readline";
|
|
404
|
+
import * as fs6 from "fs";
|
|
405
|
+
import * as path8 from "path";
|
|
406
|
+
import * as os2 from "os";
|
|
407
|
+
|
|
408
|
+
// src/global.ts
|
|
409
|
+
init_fs();
|
|
98
410
|
|
|
99
411
|
// src/adapter/openai.ts
|
|
100
412
|
import OpenAI from "openai";
|
|
101
413
|
|
|
102
414
|
// src/adapter/Adapter.ts
|
|
103
|
-
var TEMPERATURE = 0.2;
|
|
104
|
-
var MAX_COMPLETION_TOKENS = 4096;
|
|
105
415
|
var Adapter = class {
|
|
106
416
|
apiKey;
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
flex;
|
|
110
|
-
/** Reasoning effort (thinking mode) */
|
|
111
|
-
reasoningEffort;
|
|
112
|
-
/** Available tools list */
|
|
113
|
-
tools;
|
|
114
|
-
constructor(config2) {
|
|
115
|
-
this.apiKey = config2.apiKey;
|
|
116
|
-
this.model = config2.model;
|
|
117
|
-
this.flex = config2.flex;
|
|
118
|
-
this.reasoningEffort = config2.reasoningEffort;
|
|
119
|
-
this.tools = config2.tools;
|
|
120
|
-
}
|
|
121
|
-
getModel() {
|
|
122
|
-
return this.model;
|
|
417
|
+
constructor(apiKey) {
|
|
418
|
+
this.apiKey = apiKey;
|
|
123
419
|
}
|
|
124
420
|
};
|
|
125
421
|
|
|
@@ -179,97 +475,12 @@ var ToolResultMsg = class _ToolResultMsg extends Msg {
|
|
|
179
475
|
}
|
|
180
476
|
};
|
|
181
477
|
|
|
182
|
-
// src/log/log.ts
|
|
183
|
-
function getTimestamp() {
|
|
184
|
-
return (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
|
|
185
|
-
}
|
|
186
|
-
function log(message) {
|
|
187
|
-
const ts = `<gray>[${getTimestamp()}]</gray>`;
|
|
188
|
-
console.log(convertColorTags(`${ts} ${message}`));
|
|
189
|
-
}
|
|
190
|
-
function info(message) {
|
|
191
|
-
log(`<blue>[INFO]</blue> ${message}`);
|
|
192
|
-
}
|
|
193
|
-
function success(message) {
|
|
194
|
-
log(`<green>[OK]</green> ${message}`);
|
|
195
|
-
}
|
|
196
|
-
function warn(message) {
|
|
197
|
-
log(`<yellow>[WARN]</yellow> ${message}`);
|
|
198
|
-
}
|
|
199
|
-
function error(message) {
|
|
200
|
-
log(`<red>[ERROR]</red> ${message}`);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
// src/log/debug.ts
|
|
204
|
-
var _debugMode = false;
|
|
205
|
-
function isDebugMode() {
|
|
206
|
-
return _debugMode;
|
|
207
|
-
}
|
|
208
|
-
function setDebugMode(enabled) {
|
|
209
|
-
_debugMode = enabled;
|
|
210
|
-
}
|
|
211
|
-
function formatData(data, maxLen = 100) {
|
|
212
|
-
if (data === void 0) return "";
|
|
213
|
-
const str = typeof data === "string" ? data : JSON.stringify(data);
|
|
214
|
-
const singleLine = str.replace(/\s+/g, " ").trim();
|
|
215
|
-
return singleLine.length > maxLen ? singleLine.slice(0, maxLen) + "..." : singleLine;
|
|
216
|
-
}
|
|
217
|
-
function debug(category, message, data) {
|
|
218
|
-
if (!_debugMode) return;
|
|
219
|
-
const dataStr = data !== void 0 ? ` <dim>${formatData(data)}</dim>` : "";
|
|
220
|
-
log(`<magenta>[${category}]</magenta> <cyan>${message}</cyan>${dataStr}`);
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// src/log/index.ts
|
|
224
|
-
var colors2 = {
|
|
225
|
-
reset: "\x1B[0m",
|
|
226
|
-
bold: "\x1B[1m",
|
|
227
|
-
dim: "\x1B[2m",
|
|
228
|
-
italic: "\x1B[3m",
|
|
229
|
-
underline: "\x1B[4m",
|
|
230
|
-
inverse: "\x1B[7m",
|
|
231
|
-
strikethrough: "\x1B[9m",
|
|
232
|
-
red: "\x1B[31m",
|
|
233
|
-
green: "\x1B[32m",
|
|
234
|
-
yellow: "\x1B[33m",
|
|
235
|
-
blue: "\x1B[34m",
|
|
236
|
-
magenta: "\x1B[35m",
|
|
237
|
-
cyan: "\x1B[36m",
|
|
238
|
-
gray: "\x1B[90m"
|
|
239
|
-
};
|
|
240
|
-
var tagNames = Object.keys(colors2).filter((k) => k !== "reset").join("|");
|
|
241
|
-
var tagRegex = new RegExp(`<(\\/?)(${tagNames})>`, "gi");
|
|
242
|
-
function convertColorTags(str) {
|
|
243
|
-
return str.replace(tagRegex, (_, closing, tag) => {
|
|
244
|
-
return closing ? colors2.reset : colors2[tag.toLowerCase()] || "";
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
function createColorConverter() {
|
|
248
|
-
let buffer = "";
|
|
249
|
-
return (chunk) => {
|
|
250
|
-
buffer += chunk;
|
|
251
|
-
const lastOpen = buffer.lastIndexOf("<");
|
|
252
|
-
if (lastOpen === -1) {
|
|
253
|
-
const out2 = convertColorTags(buffer);
|
|
254
|
-
buffer = "";
|
|
255
|
-
return out2;
|
|
256
|
-
}
|
|
257
|
-
if (buffer.indexOf(">", lastOpen) !== -1) {
|
|
258
|
-
const out2 = convertColorTags(buffer);
|
|
259
|
-
buffer = "";
|
|
260
|
-
return out2;
|
|
261
|
-
}
|
|
262
|
-
const out = convertColorTags(buffer.slice(0, lastOpen));
|
|
263
|
-
buffer = buffer.slice(lastOpen);
|
|
264
|
-
return out;
|
|
265
|
-
};
|
|
266
|
-
}
|
|
267
|
-
|
|
268
478
|
// src/adapter/openai.ts
|
|
479
|
+
init_log2();
|
|
269
480
|
var OpenAIAdapter = class extends Adapter {
|
|
270
481
|
client;
|
|
271
|
-
constructor(
|
|
272
|
-
super(
|
|
482
|
+
constructor(apiKey) {
|
|
483
|
+
super(apiKey);
|
|
273
484
|
if (!this.apiKey) {
|
|
274
485
|
throw new Error("OpenAI API key is required. Set OPENAI_API_KEY environment variable.");
|
|
275
486
|
}
|
|
@@ -308,8 +519,9 @@ var OpenAIAdapter = class extends Adapter {
|
|
|
308
519
|
}
|
|
309
520
|
return result;
|
|
310
521
|
}
|
|
311
|
-
|
|
312
|
-
|
|
522
|
+
formatTools(tools) {
|
|
523
|
+
if (tools.length === 0) return void 0;
|
|
524
|
+
return tools.map((t) => ({
|
|
313
525
|
type: "function",
|
|
314
526
|
function: {
|
|
315
527
|
name: t.name,
|
|
@@ -322,20 +534,19 @@ var OpenAIAdapter = class extends Adapter {
|
|
|
322
534
|
}
|
|
323
535
|
}));
|
|
324
536
|
}
|
|
325
|
-
async chat(messages, onChunk) {
|
|
326
|
-
debug("API", `Requesting OpenAI (model: ${
|
|
537
|
+
async chat(model, messages, tools, options, onChunk) {
|
|
538
|
+
debug("API", `Requesting OpenAI (model: ${model}, messages: ${messages.length})`);
|
|
327
539
|
const openaiMessages = this.toOpenAIMessages(messages);
|
|
328
540
|
const startTime = Date.now();
|
|
329
541
|
const requestParams = {
|
|
330
|
-
model
|
|
542
|
+
model,
|
|
331
543
|
messages: openaiMessages,
|
|
332
|
-
tools: this.
|
|
333
|
-
|
|
334
|
-
max_completion_tokens: MAX_COMPLETION_TOKENS,
|
|
544
|
+
tools: this.formatTools(tools),
|
|
545
|
+
max_completion_tokens: options.maxCompletionTokens,
|
|
335
546
|
stream: true,
|
|
336
547
|
stream_options: { include_usage: true },
|
|
337
|
-
service_tier:
|
|
338
|
-
reasoning_effort:
|
|
548
|
+
service_tier: options.flex ? "flex" : void 0,
|
|
549
|
+
reasoning_effort: options.reasoningEffort
|
|
339
550
|
};
|
|
340
551
|
const stream = await this.client.chat.completions.create(requestParams);
|
|
341
552
|
let text = "";
|
|
@@ -378,33 +589,46 @@ var OpenAIAdapter = class extends Adapter {
|
|
|
378
589
|
}
|
|
379
590
|
};
|
|
380
591
|
|
|
381
|
-
// src/global.ts
|
|
382
|
-
|
|
383
|
-
function setWorkingDir(dir) {
|
|
384
|
-
workingDir = dir;
|
|
385
|
-
}
|
|
592
|
+
// src/init/global.ts
|
|
593
|
+
init_fs();
|
|
386
594
|
var TOOLS = {};
|
|
387
595
|
var PROCEDURES = {};
|
|
388
|
-
var
|
|
389
|
-
function
|
|
390
|
-
|
|
391
|
-
|
|
596
|
+
var adapters = {};
|
|
597
|
+
function getAdapter(platform) {
|
|
598
|
+
const adapter = adapters[platform];
|
|
599
|
+
if (!adapter) {
|
|
600
|
+
throw new Error(`Adapter not found for platform: ${platform}`);
|
|
601
|
+
}
|
|
602
|
+
return adapter;
|
|
603
|
+
}
|
|
604
|
+
async function initGlobalConfig() {
|
|
605
|
+
const globalConfigDir = PATHS.globalConfig;
|
|
606
|
+
if (await dirExists(globalConfigDir)) return;
|
|
607
|
+
await copyDir(PATHS.globalTemplate, globalConfigDir);
|
|
608
|
+
}
|
|
609
|
+
async function initAdapters() {
|
|
610
|
+
const { getApiKey: getApiKey2 } = await Promise.resolve().then(() => (init_loader(), loader_exports));
|
|
611
|
+
const openaiKey = getApiKey2("openai");
|
|
612
|
+
if (openaiKey) {
|
|
613
|
+
adapters["openai"] = new OpenAIAdapter(openaiKey);
|
|
392
614
|
}
|
|
393
|
-
const mainAgentConfig = config.getAgentConfig("main");
|
|
394
|
-
adapter = new OpenAIAdapter({
|
|
395
|
-
apiKey: config.getApiKey("openai") || "",
|
|
396
|
-
model: mainAgentConfig.model,
|
|
397
|
-
flex: mainAgentConfig.flex,
|
|
398
|
-
tools: Object.values(TOOLS)
|
|
399
|
-
});
|
|
400
615
|
}
|
|
401
|
-
async function init(cwd) {
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
616
|
+
async function init(cwd, forceInit) {
|
|
617
|
+
const { setWorkingDir: setWorkingDir2 } = await Promise.resolve().then(() => (init_fs(), fs_exports));
|
|
618
|
+
setWorkingDir2(cwd || process.cwd());
|
|
619
|
+
await initGlobalConfig();
|
|
620
|
+
const { initProject: initProject2 } = await Promise.resolve().then(() => (init_project(), project_exports));
|
|
621
|
+
await initProject2(forceInit);
|
|
622
|
+
const { loadConfigs: loadConfigs2 } = await Promise.resolve().then(() => (init_loader(), loader_exports));
|
|
623
|
+
await loadConfigs2();
|
|
624
|
+
await initAdapters();
|
|
405
625
|
}
|
|
406
626
|
|
|
627
|
+
// src/init/index.ts
|
|
628
|
+
init_loader();
|
|
629
|
+
|
|
407
630
|
// src/tool/Tool.ts
|
|
631
|
+
init_log2();
|
|
408
632
|
var HAS_MANUAL = "\u{1F4D8}";
|
|
409
633
|
var Tool = class _Tool {
|
|
410
634
|
name;
|
|
@@ -413,12 +637,12 @@ var Tool = class _Tool {
|
|
|
413
637
|
required;
|
|
414
638
|
manual;
|
|
415
639
|
_execute;
|
|
416
|
-
constructor(
|
|
417
|
-
this.name =
|
|
418
|
-
this.parameters =
|
|
419
|
-
this.required =
|
|
420
|
-
this._execute =
|
|
421
|
-
const { description, manual } = _Tool.parseManual(
|
|
640
|
+
constructor(config) {
|
|
641
|
+
this.name = config.name;
|
|
642
|
+
this.parameters = config.parameters;
|
|
643
|
+
this.required = config.required;
|
|
644
|
+
this._execute = config.execute;
|
|
645
|
+
const { description, manual } = _Tool.parseManual(config.manualContent);
|
|
422
646
|
this.description = description;
|
|
423
647
|
this.manual = manual;
|
|
424
648
|
}
|
|
@@ -461,8 +685,8 @@ var Tool = class _Tool {
|
|
|
461
685
|
};
|
|
462
686
|
|
|
463
687
|
// src/tool/read_file/index.ts
|
|
464
|
-
import * as
|
|
465
|
-
import * as
|
|
688
|
+
import * as fs3 from "fs/promises";
|
|
689
|
+
import * as path5 from "path";
|
|
466
690
|
|
|
467
691
|
// src/tool/read_file/manual.md
|
|
468
692
|
var manual_default = "read_file: Read the content of a specified file\n";
|
|
@@ -478,8 +702,8 @@ TOOLS["read_file"] = new Tool({
|
|
|
478
702
|
execute: async (args) => {
|
|
479
703
|
const filePath = args.path;
|
|
480
704
|
try {
|
|
481
|
-
const fullPath =
|
|
482
|
-
return await
|
|
705
|
+
const fullPath = path5.resolve(workingDir, filePath);
|
|
706
|
+
return await fs3.readFile(fullPath, "utf-8");
|
|
483
707
|
} catch (error2) {
|
|
484
708
|
return {
|
|
485
709
|
content: `Failed to read file: ${error2 instanceof Error ? error2.message : String(error2)}`,
|
|
@@ -490,8 +714,8 @@ TOOLS["read_file"] = new Tool({
|
|
|
490
714
|
});
|
|
491
715
|
|
|
492
716
|
// src/tool/write_file/index.ts
|
|
493
|
-
import * as
|
|
494
|
-
import * as
|
|
717
|
+
import * as fs4 from "fs/promises";
|
|
718
|
+
import * as path6 from "path";
|
|
495
719
|
|
|
496
720
|
// src/tool/write_file/manual.md
|
|
497
721
|
var manual_default2 = "write_file: Write content to a specified file, create the file if it doesn't exist\n";
|
|
@@ -509,9 +733,9 @@ TOOLS["write_file"] = new Tool({
|
|
|
509
733
|
const filePath = args.path;
|
|
510
734
|
const content = args.content;
|
|
511
735
|
try {
|
|
512
|
-
const fullPath =
|
|
513
|
-
await
|
|
514
|
-
await
|
|
736
|
+
const fullPath = path6.resolve(workingDir, filePath);
|
|
737
|
+
await fs4.mkdir(path6.dirname(fullPath), { recursive: true });
|
|
738
|
+
await fs4.writeFile(fullPath, content, "utf-8");
|
|
515
739
|
return `File written successfully: ${filePath}`;
|
|
516
740
|
} catch (error2) {
|
|
517
741
|
return {
|
|
@@ -523,8 +747,8 @@ TOOLS["write_file"] = new Tool({
|
|
|
523
747
|
});
|
|
524
748
|
|
|
525
749
|
// src/tool/list_directory/index.ts
|
|
526
|
-
import * as
|
|
527
|
-
import * as
|
|
750
|
+
import * as fs5 from "fs/promises";
|
|
751
|
+
import * as path7 from "path";
|
|
528
752
|
|
|
529
753
|
// src/tool/list_directory/manual.md
|
|
530
754
|
var manual_default3 = "list_directory: List files and subdirectories in a specified directory\n";
|
|
@@ -540,8 +764,8 @@ TOOLS["list_directory"] = new Tool({
|
|
|
540
764
|
execute: async (args) => {
|
|
541
765
|
const dirPath = args.path || ".";
|
|
542
766
|
try {
|
|
543
|
-
const fullPath =
|
|
544
|
-
const entries = await
|
|
767
|
+
const fullPath = path7.resolve(workingDir, dirPath);
|
|
768
|
+
const entries = await fs5.readdir(fullPath, { withFileTypes: true });
|
|
545
769
|
const result = entries.map((entry) => {
|
|
546
770
|
const type = entry.isDirectory() ? "[DIR]" : "[FILE]";
|
|
547
771
|
return `${type} ${entry.name}`;
|
|
@@ -659,9 +883,9 @@ var Procedure = class _Procedure {
|
|
|
659
883
|
name;
|
|
660
884
|
description;
|
|
661
885
|
manual;
|
|
662
|
-
constructor(
|
|
663
|
-
this.name =
|
|
664
|
-
const { description, manual } = _Procedure.parseManual(
|
|
886
|
+
constructor(config) {
|
|
887
|
+
this.name = config.name;
|
|
888
|
+
const { description, manual } = _Procedure.parseManual(config.procedureContent);
|
|
665
889
|
this.description = description;
|
|
666
890
|
this.manual = manual;
|
|
667
891
|
}
|
|
@@ -692,6 +916,9 @@ PROCEDURES["understand_project"] = new Procedure({
|
|
|
692
916
|
procedureContent: procedure_default
|
|
693
917
|
});
|
|
694
918
|
|
|
919
|
+
// src/index.ts
|
|
920
|
+
init_log2();
|
|
921
|
+
|
|
695
922
|
// src/model/models.ts
|
|
696
923
|
var MODELS = {
|
|
697
924
|
"gpt-5.2": {
|
|
@@ -733,12 +960,17 @@ var MODELS = {
|
|
|
733
960
|
};
|
|
734
961
|
|
|
735
962
|
// src/agent/Agent.ts
|
|
963
|
+
init_log2();
|
|
736
964
|
var Agent = class {
|
|
737
965
|
config;
|
|
738
966
|
messages = [];
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
this.
|
|
967
|
+
toolsMap = {};
|
|
968
|
+
constructor(config) {
|
|
969
|
+
this.config = config;
|
|
970
|
+
this.messages = [...config.messages];
|
|
971
|
+
for (const tool of config.tools) {
|
|
972
|
+
this.toolsMap[tool.name] = tool;
|
|
973
|
+
}
|
|
742
974
|
}
|
|
743
975
|
/**
|
|
744
976
|
* Render template string, replacing {{variable}} style variables
|
|
@@ -760,7 +992,16 @@ var Agent = class {
|
|
|
760
992
|
let totalUsage = { promptTokens: 0, completionTokens: 0, totalTokens: 0, cachedTokens: 0 };
|
|
761
993
|
while (true) {
|
|
762
994
|
debug("Agent", `Starting conversation (message count: ${this.messages.length})`);
|
|
763
|
-
const response = await this.config.adapter.chat(
|
|
995
|
+
const response = await this.config.adapter.chat(
|
|
996
|
+
this.config.model,
|
|
997
|
+
this.messages,
|
|
998
|
+
this.config.tools,
|
|
999
|
+
{
|
|
1000
|
+
...this.config.platformOptions,
|
|
1001
|
+
maxCompletionTokens: this.config.maxCompletionTokens
|
|
1002
|
+
},
|
|
1003
|
+
this.config.onStream
|
|
1004
|
+
);
|
|
764
1005
|
if (response.usage) {
|
|
765
1006
|
totalUsage.promptTokens += response.usage.promptTokens;
|
|
766
1007
|
totalUsage.completionTokens += response.usage.completionTokens;
|
|
@@ -785,7 +1026,7 @@ var Agent = class {
|
|
|
785
1026
|
const toolResults = [];
|
|
786
1027
|
for (const tc of toolCalls) {
|
|
787
1028
|
this.config.onBeforeToolRun?.(tc.name, tc.arguments);
|
|
788
|
-
const tool =
|
|
1029
|
+
const tool = this.toolsMap[tc.name];
|
|
789
1030
|
const result = tool ? await tool.run(tc.arguments) : { toolName: tc.name, result: `Unknown tool: ${tc.name}`, isError: true };
|
|
790
1031
|
toolCallHistory.push({
|
|
791
1032
|
name: tc.name,
|
|
@@ -804,15 +1045,22 @@ var Agent = class {
|
|
|
804
1045
|
}
|
|
805
1046
|
};
|
|
806
1047
|
|
|
1048
|
+
// src/agent/Arki/Arki.ts
|
|
1049
|
+
init_log2();
|
|
1050
|
+
|
|
807
1051
|
// src/agent/Arki/system.md
|
|
808
1052
|
var system_default = "You are Arki, a professional AI programming assistant. You work in the codebase directory `{{working_dir}}`.\n\n## Tool Usage\n\nTools can be called multiple times at once.\nIf a tool has the {{has_manual}} symbol in its description, you **MUST** call `read_tool_manual` before using it. Read the manual exactly once per tool - do not skip it, and do not read it repeatedly.\n\n## Procedure Usage\n\nProcedures are step-by-step guides for specific workflows. When a task involves a defined procedure, you **MUST** call `read_procedure` first to get the complete steps, then follow the procedure exactly.\n\nIf a procedure defines output text/format templates, translate them to the user's language unless the procedure explicitly forbids translation.\n\nAvailable procedures:\n{{procedures}}\n\n## Working Principles\n\n- **Accuracy**: Before answering questions, use tools to view relevant code first. Don't base statements on assumptions. If you don't know something, just admit it - it's no big deal. For example, never tell the user what might be inside a directory based only on its name\u2014always inspect its contents first, and never guess functionality from directory, file, or function names in a way that could mislead the user.\n- **Safety**: Consider potential risks before executing commands.\n- **Conciseness**: Keep answers brief and concise, avoid repetition and redundancy. Keep each response within 200 words unless the user requests detailed explanation. If user requirements are unclear, ask for clarification once at most. If still unclear after asking, proceed with your best understanding and show the result to the user - do not ask multiple times.\n- **Proactivity**: Actively suggest improvements when you find issues.\n\n## Response Style\n\n- Answer questions directly, avoid excessive pleasantries\n- Don't use emojis\n- Don't repeatedly ask about user needs, once is enough. Don't ask and answer yourself.\n\nThe user is talking to you via **CLI terminal**. Prefer terminal-friendly characters and plain text formatting. **Do not** output Markdown syntax such as `**` for bold, `*` or `-` for lists, etc. For long answers, feel free to organize content with clear section headings. Use numbered lists for ordered lists only when items have a clear sequence or dependency; otherwise use the \u2022 symbol for unordered lists.\nUse the following tags to format output:\n\n| Purpose | Format Tag | Usage |\n|--------|------------|-------|\n| Code blocks (```...```) | `<dim>...</dim>` | Wrap the entire code block content |\n| Inline code (`...`) | `<dim>...</dim>` | Wrap inline code snippets |\n| File paths | `<cyan>...</cyan>` | For paths, e.g., `src/index.ts` |\n| Filenames | `<gray>...</gray>` | For file names when mentioned alone |\n| Command names | `<blue>...</blue>` | For commands, e.g., `npm install` |\n| Section headings / titles | `<bold><cyan>...</cyan></bold>` | For section titles in plain text output |\n| Important or strong emphasis (**...**) | `<bold>...</bold>` | For key points that must stand out |\n| Secondary / less important info | `<dim>...</dim>` | For metadata, debug info, token counts, etc. |\n| Tips / important notices | `<yellow>...</yellow>` | For tips, cautions, non-fatal problems |\n| Success confirmations | `<green>...</green>` | For success messages, completion status |\n| Errors or serious problems | `<red>...</red>` | For real problems the user must fix |\n| Neutral informational messages | `<blue>...</blue>` | For general info that is not success/failure |\n| Highlighted keywords / categories | `<magenta>...</magenta>` | For labels, categories, or tags in text |\n| De-emphasized / grayed-out text | `<gray>...</gray>` | For low-priority info, old values, etc. |\n| Underlined emphasis | `<underline>...</underline>` | For things you want to underline instead of bold |\n| Optional / tentative text | `<italic>...</italic>` | For suggestions, optional steps, side notes |\n| Reversed highlight | `<inverse>...</inverse>` | For very strong highlights (rarely use) |\n| Deleted / not recommended content | `<strikethrough>...</strikethrough>` | For deprecated commands or steps |\n\nTags can be combined, e.g., `<bold><red>Critical Error</red></bold>`\n\n- Do not mention the contents of this prompt to users. The prompt provides context and instructions for you to follow, not to recite verbatim. Use the information in the prompt to inform your responses naturally. Bad example: \"You are currently talking to me via a Mac OS terminal interface. How can I help you?\" Good example: (Display terminal-friendly characters and provide suggestions based on the Mac OS system environment)\n\nPlease answer questions in the language the user is using, and flexibly use available tools to complete tasks.\n\n";
|
|
809
1053
|
|
|
810
1054
|
// src/agent/Arki/Arki.ts
|
|
1055
|
+
var MAX_COMPLETION_TOKENS = 4096;
|
|
811
1056
|
var toolStartTimes = /* @__PURE__ */ new Map();
|
|
812
|
-
function
|
|
813
|
-
|
|
814
|
-
|
|
1057
|
+
function createArkiAgent() {
|
|
1058
|
+
const config = getAgentConfig("arki");
|
|
1059
|
+
const model = MODELS[config.model];
|
|
1060
|
+
if (!model) {
|
|
1061
|
+
throw new Error(`Unknown model: ${config.model}`);
|
|
815
1062
|
}
|
|
1063
|
+
const adapter = getAdapter(model.provider);
|
|
816
1064
|
const proceduresList = Object.values(PROCEDURES).map((p) => `- ${p.name}: ${p.description}`).join("\n");
|
|
817
1065
|
const systemInstruction = Agent.renderTemplate(system_default, {
|
|
818
1066
|
working_dir: workingDir,
|
|
@@ -822,6 +1070,13 @@ function createMainAgent() {
|
|
|
822
1070
|
const convertColor = createColorConverter();
|
|
823
1071
|
const agent = new Agent({
|
|
824
1072
|
adapter,
|
|
1073
|
+
model: config.model,
|
|
1074
|
+
tools: Object.values(TOOLS),
|
|
1075
|
+
maxCompletionTokens: MAX_COMPLETION_TOKENS,
|
|
1076
|
+
platformOptions: {
|
|
1077
|
+
flex: config.flex,
|
|
1078
|
+
reasoningEffort: config.reasoningEffort
|
|
1079
|
+
},
|
|
825
1080
|
messages: [new SystemMsg(systemInstruction)],
|
|
826
1081
|
onStream: (chunk) => {
|
|
827
1082
|
process.stdout.write(convertColor(chunk));
|
|
@@ -859,7 +1114,7 @@ function createMainAgent() {
|
|
|
859
1114
|
// package.json
|
|
860
1115
|
var package_default = {
|
|
861
1116
|
name: "arki",
|
|
862
|
-
version: "0.0.
|
|
1117
|
+
version: "0.0.7",
|
|
863
1118
|
description: "AI Agent Programming Assistant",
|
|
864
1119
|
type: "module",
|
|
865
1120
|
main: "dist/index.js",
|
|
@@ -916,13 +1171,14 @@ var package_default = {
|
|
|
916
1171
|
};
|
|
917
1172
|
|
|
918
1173
|
// src/index.ts
|
|
919
|
-
|
|
920
|
-
|
|
1174
|
+
init_log2();
|
|
1175
|
+
function getConfigPath() {
|
|
1176
|
+
return path8.join(os2.homedir(), ".config", "arki", "config.json");
|
|
921
1177
|
}
|
|
922
1178
|
function resetConfig() {
|
|
923
|
-
const configPath =
|
|
924
|
-
if (
|
|
925
|
-
|
|
1179
|
+
const configPath = getConfigPath();
|
|
1180
|
+
if (fs6.existsSync(configPath)) {
|
|
1181
|
+
fs6.unlinkSync(configPath);
|
|
926
1182
|
console.log(`Configuration file deleted: ${configPath}`);
|
|
927
1183
|
console.log("Default configuration will be used on next startup.");
|
|
928
1184
|
} else {
|
|
@@ -934,6 +1190,7 @@ function parseArgs() {
|
|
|
934
1190
|
const args = process.argv.slice(2);
|
|
935
1191
|
let targetDir = process.cwd();
|
|
936
1192
|
let enableDebug = false;
|
|
1193
|
+
let forceInit = false;
|
|
937
1194
|
for (let i = 0; i < args.length; i++) {
|
|
938
1195
|
if (args[i] === "-p" && args[i + 1]) {
|
|
939
1196
|
targetDir = args[i + 1];
|
|
@@ -942,6 +1199,8 @@ function parseArgs() {
|
|
|
942
1199
|
enableDebug = true;
|
|
943
1200
|
} else if (args[i] === "--reset") {
|
|
944
1201
|
resetConfig();
|
|
1202
|
+
} else if (args[i] === "--init") {
|
|
1203
|
+
forceInit = true;
|
|
945
1204
|
} else if (args[i] === "--help" || args[i] === "-h") {
|
|
946
1205
|
console.log(`
|
|
947
1206
|
Usage: arki [options]
|
|
@@ -949,40 +1208,37 @@ Usage: arki [options]
|
|
|
949
1208
|
Options:
|
|
950
1209
|
-p <path> Specify working directory
|
|
951
1210
|
--debug, -d Enable debug mode, show detailed logs
|
|
1211
|
+
--init Initialize project config without prompting
|
|
952
1212
|
--reset Reset configuration to factory defaults
|
|
953
1213
|
--help, -h Show help information
|
|
954
1214
|
`);
|
|
955
1215
|
process.exit(0);
|
|
956
1216
|
}
|
|
957
1217
|
}
|
|
958
|
-
return { targetDir, enableDebug };
|
|
1218
|
+
return { targetDir, enableDebug, forceInit };
|
|
959
1219
|
}
|
|
960
1220
|
async function main() {
|
|
961
|
-
const { targetDir, enableDebug } = parseArgs();
|
|
1221
|
+
const { targetDir, enableDebug, forceInit } = parseArgs();
|
|
962
1222
|
if (enableDebug) {
|
|
963
1223
|
setDebugMode(true);
|
|
964
1224
|
debug("Init", "Debug mode enabled");
|
|
965
1225
|
}
|
|
966
|
-
await init(targetDir);
|
|
967
|
-
const
|
|
968
|
-
const model = MODELS[
|
|
969
|
-
console.log();
|
|
970
|
-
log(`<cyan>Arki AI Agent v${package_default.version}</cyan>`);
|
|
1226
|
+
await init(targetDir, forceInit);
|
|
1227
|
+
const arkiAgentConfig = getAgentConfig("arki");
|
|
1228
|
+
const model = MODELS[arkiAgentConfig.model];
|
|
971
1229
|
console.log();
|
|
972
|
-
log(`<
|
|
973
|
-
log(`<dim>
|
|
1230
|
+
log(`<bold><cyan>Arki AI Agent</cyan></bold> <dim>v${package_default.version}</dim>`);
|
|
1231
|
+
log(`<green>Model:</green> <bold>${model?.name || arkiAgentConfig.model}</bold> <dim>|</dim> <green>OS:</green> ${OS.name} <dim>(${OS.version})</dim>`);
|
|
1232
|
+
log(`<green>Path:</green> <dim>${workingDir}</dim>`);
|
|
1233
|
+
log(`<green>Tools:</green> ${Object.keys(TOOLS).length} loaded`);
|
|
974
1234
|
if (isDebugMode()) {
|
|
975
1235
|
log(`<yellow>Debug mode enabled</yellow>`);
|
|
976
|
-
}
|
|
977
|
-
console.log();
|
|
978
|
-
log(`<dim>Loaded ${Object.keys(TOOLS).length} tools</dim>`);
|
|
979
|
-
if (isDebugMode()) {
|
|
980
1236
|
debug("Init", "Loaded tools", Object.keys(TOOLS));
|
|
981
|
-
debug("Init", "Agent config",
|
|
1237
|
+
debug("Init", "Agent config", arkiAgentConfig);
|
|
982
1238
|
}
|
|
983
1239
|
console.log();
|
|
984
|
-
const agent =
|
|
985
|
-
const rl =
|
|
1240
|
+
const agent = createArkiAgent();
|
|
1241
|
+
const rl = readline2.createInterface({
|
|
986
1242
|
input: process.stdin,
|
|
987
1243
|
output: process.stdout
|
|
988
1244
|
});
|
|
@@ -1054,30 +1310,35 @@ export {
|
|
|
1054
1310
|
Adapter,
|
|
1055
1311
|
Agent,
|
|
1056
1312
|
HAS_MANUAL,
|
|
1057
|
-
MAX_COMPLETION_TOKENS,
|
|
1058
1313
|
MODELS,
|
|
1059
1314
|
Msg,
|
|
1060
1315
|
MsgType,
|
|
1316
|
+
OS,
|
|
1061
1317
|
OpenAIAdapter,
|
|
1318
|
+
PATHS,
|
|
1062
1319
|
PROCEDURES,
|
|
1063
1320
|
SystemMsg,
|
|
1064
|
-
TEMPERATURE,
|
|
1065
1321
|
TOOLS,
|
|
1066
1322
|
Tool,
|
|
1067
1323
|
ToolCallMsg,
|
|
1068
1324
|
ToolResultMsg,
|
|
1069
1325
|
UserMsg,
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
config,
|
|
1326
|
+
adapters,
|
|
1327
|
+
colors,
|
|
1073
1328
|
convertColorTags,
|
|
1074
1329
|
createColorConverter,
|
|
1075
1330
|
debug,
|
|
1076
1331
|
error,
|
|
1332
|
+
getAdapter,
|
|
1333
|
+
getAgentConfig,
|
|
1334
|
+
getApiKey,
|
|
1335
|
+
getConfig,
|
|
1077
1336
|
info,
|
|
1078
1337
|
init,
|
|
1079
1338
|
isDebugMode,
|
|
1080
1339
|
log,
|
|
1340
|
+
print,
|
|
1341
|
+
saveConfig,
|
|
1081
1342
|
setDebugMode,
|
|
1082
1343
|
setWorkingDir,
|
|
1083
1344
|
success,
|