arki 0.0.3 → 0.0.5
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 +8 -31
- package/dist/index.d.ts +73 -22
- package/dist/index.js +217 -138
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
> **⚠️ Warning: This project is under active development. Please do not use it in production environments.**
|
|
2
|
+
|
|
1
3
|
# Arki - AI Agent Programming Assistant
|
|
2
4
|
|
|
3
5
|
Arki is an AI agent programming tool.
|
|
@@ -43,6 +45,7 @@ arki [options]
|
|
|
43
45
|
Options:
|
|
44
46
|
-p <path> Specify working directory
|
|
45
47
|
--debug, -d Enable debug mode, show detailed logs
|
|
48
|
+
--reset Reset configuration to factory defaults
|
|
46
49
|
--help, -h Show help information
|
|
47
50
|
```
|
|
48
51
|
|
|
@@ -81,39 +84,13 @@ Ways to enable:
|
|
|
81
84
|
|
|
82
85
|
Configuration file is located at `~/.config/arki/config.json`:
|
|
83
86
|
|
|
84
|
-
|
|
85
|
-
{
|
|
86
|
-
"agents": {
|
|
87
|
-
"main": {
|
|
88
|
-
"model": "gpt-5.1",
|
|
89
|
-
"flex": false,
|
|
90
|
-
"reasoningEffort": "medium"
|
|
91
|
-
},
|
|
92
|
-
"coder": {
|
|
93
|
-
"model": "gpt-5.2",
|
|
94
|
-
"flex": false,
|
|
95
|
-
"reasoningEffort": "high"
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
Each Agent configuration:
|
|
102
|
-
- `model` - Model ID to use
|
|
103
|
-
- `flex` - Use Flex API (low priority, low cost)
|
|
104
|
-
- `reasoningEffort` - Reasoning effort, optional values: `low`, `medium`, `high` (for models that support thinking mode)
|
|
105
|
-
|
|
106
|
-
Default configuration is automatically copied from the package on first run.
|
|
87
|
+
### Reset to Factory Defaults
|
|
107
88
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
89
|
+
```bash
|
|
90
|
+
arki --reset
|
|
91
|
+
```
|
|
111
92
|
|
|
112
|
-
|
|
113
|
-
- `write_file` - Write to file
|
|
114
|
-
- `list_directory` - List directory contents
|
|
115
|
-
- `run_command` - Execute shell commands
|
|
116
|
-
- `get_tool_info` - View detailed usage instructions for tools
|
|
93
|
+
This will delete the current configuration file. The default configuration will be used on next startup.
|
|
117
94
|
|
|
118
95
|
## Development
|
|
119
96
|
|
package/dist/index.d.ts
CHANGED
|
@@ -39,31 +39,44 @@ declare class AIMsg extends Msg {
|
|
|
39
39
|
readonly type = MsgType.AI;
|
|
40
40
|
constructor(content: string);
|
|
41
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Single tool call
|
|
44
|
+
*/
|
|
45
|
+
interface ToolCall {
|
|
46
|
+
name: string;
|
|
47
|
+
arguments: Record<string, unknown>;
|
|
48
|
+
}
|
|
42
49
|
/**
|
|
43
50
|
* Tool call message constructor
|
|
44
51
|
*/
|
|
45
52
|
declare class ToolCallMsg extends Msg {
|
|
46
53
|
readonly type = MsgType.ToolCall;
|
|
47
|
-
readonly toolCalls:
|
|
48
|
-
|
|
49
|
-
arguments: Record<string, unknown>;
|
|
50
|
-
}>;
|
|
51
|
-
constructor(content: string, toolCalls: Array<{
|
|
52
|
-
name: string;
|
|
53
|
-
arguments: Record<string, unknown>;
|
|
54
|
-
}>);
|
|
54
|
+
readonly toolCalls: ToolCall[];
|
|
55
|
+
constructor(content: string, toolCalls: ToolCall[]);
|
|
55
56
|
}
|
|
56
57
|
/**
|
|
57
|
-
*
|
|
58
|
+
* Single tool result
|
|
59
|
+
*/
|
|
60
|
+
interface ToolResult {
|
|
61
|
+
toolName: string;
|
|
62
|
+
result: string;
|
|
63
|
+
isError?: boolean;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Tool result message constructor (contains multiple results)
|
|
58
67
|
*/
|
|
59
68
|
declare class ToolResultMsg extends Msg {
|
|
60
69
|
readonly type = MsgType.ToolResult;
|
|
61
|
-
readonly
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
70
|
+
readonly toolResults: ToolResult[];
|
|
71
|
+
constructor(toolResults: ToolResult[]);
|
|
72
|
+
/** Helper: create from single result */
|
|
73
|
+
static single(toolName: string, result: string, isError?: boolean): ToolResultMsg;
|
|
65
74
|
}
|
|
66
75
|
|
|
76
|
+
/**
|
|
77
|
+
* Symbol indicating tool has detailed manual (needs to call read_tool_manual before use)
|
|
78
|
+
*/
|
|
79
|
+
declare const HAS_MANUAL = "\uD83D\uDCD8";
|
|
67
80
|
/**
|
|
68
81
|
* Tool class
|
|
69
82
|
*/
|
|
@@ -88,6 +101,7 @@ declare class Tool {
|
|
|
88
101
|
* Parse manual.md content
|
|
89
102
|
* First line format: "tool_name: description", extract description
|
|
90
103
|
* Remaining content is the manual
|
|
104
|
+
* If manual has content, prepend HAS_MANUAL symbol to description
|
|
91
105
|
*/
|
|
92
106
|
static parseManual(content: string): {
|
|
93
107
|
description: string;
|
|
@@ -96,7 +110,29 @@ declare class Tool {
|
|
|
96
110
|
/**
|
|
97
111
|
* Execute tool (with error handling and logging)
|
|
98
112
|
*/
|
|
99
|
-
run(args: Record<string, unknown>): Promise<
|
|
113
|
+
run(args: Record<string, unknown>): Promise<ToolResult>;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Procedure class - step-by-step guide for specific workflows
|
|
118
|
+
*/
|
|
119
|
+
declare class Procedure {
|
|
120
|
+
readonly name: string;
|
|
121
|
+
readonly description: string;
|
|
122
|
+
readonly manual: string;
|
|
123
|
+
constructor(config: {
|
|
124
|
+
name: string;
|
|
125
|
+
procedureContent: string;
|
|
126
|
+
});
|
|
127
|
+
/**
|
|
128
|
+
* Parse procedure.md content
|
|
129
|
+
* First line format: "procedure_name: description", extract description
|
|
130
|
+
* Remaining content is the procedure steps
|
|
131
|
+
*/
|
|
132
|
+
static parseManual(content: string): {
|
|
133
|
+
description: string;
|
|
134
|
+
manual: string;
|
|
135
|
+
};
|
|
100
136
|
}
|
|
101
137
|
|
|
102
138
|
/**
|
|
@@ -207,6 +243,8 @@ declare let workingDir: string;
|
|
|
207
243
|
declare function setWorkingDir(dir: string): void;
|
|
208
244
|
/** Global tool registry */
|
|
209
245
|
declare const TOOLS: Record<string, Tool>;
|
|
246
|
+
/** Global procedure registry */
|
|
247
|
+
declare const PROCEDURES: Record<string, Procedure>;
|
|
210
248
|
/** Global Adapter instance */
|
|
211
249
|
declare let adapter: Adapter | null;
|
|
212
250
|
/** Initialize global state */
|
|
@@ -214,29 +252,31 @@ declare function init(cwd?: string): Promise<void>;
|
|
|
214
252
|
|
|
215
253
|
/**
|
|
216
254
|
* Debug logging module
|
|
255
|
+
* All debug output is single-line for log-friendly format
|
|
217
256
|
*/
|
|
218
257
|
/** Get debug mode status */
|
|
219
258
|
declare function isDebugMode(): boolean;
|
|
220
259
|
/** Set debug mode */
|
|
221
260
|
declare function setDebugMode(enabled: boolean): void;
|
|
222
261
|
/**
|
|
223
|
-
* Debug log function
|
|
262
|
+
* Debug log function - single line output with timestamp
|
|
224
263
|
* @param category Log category (e.g., 'API', 'Agent', 'Tool')
|
|
225
264
|
* @param message Log message
|
|
226
|
-
* @param data Optional additional data
|
|
265
|
+
* @param data Optional additional data (will be formatted to single line)
|
|
227
266
|
*/
|
|
228
267
|
declare function debug(category: string, message: string, data?: unknown): void;
|
|
229
268
|
|
|
230
269
|
/**
|
|
231
270
|
* General logging module
|
|
271
|
+
* All log output is single-line with timestamp prefix
|
|
272
|
+
* Supports XML-style color tags: <red>text</red>, <bold>text</bold>, etc.
|
|
232
273
|
*/
|
|
233
|
-
|
|
234
274
|
/**
|
|
235
|
-
*
|
|
236
|
-
* @param color
|
|
237
|
-
* @
|
|
275
|
+
* Log output with timestamp and XML color tag support
|
|
276
|
+
* @param message Message string with optional XML color tags
|
|
277
|
+
* @example log('<yellow>[TOOL]</yellow> read_file <dim>{"path":"test.txt"}</dim>')
|
|
238
278
|
*/
|
|
239
|
-
declare function log(
|
|
279
|
+
declare function log(message: string): void;
|
|
240
280
|
/**
|
|
241
281
|
* Info log
|
|
242
282
|
*/
|
|
@@ -257,6 +297,7 @@ declare function error(message: string): void;
|
|
|
257
297
|
/**
|
|
258
298
|
* Logging module
|
|
259
299
|
* Provides debug mode and logging functionality
|
|
300
|
+
* Supports XML-style color tags: <red>text</red>, <bold>text</bold>, etc.
|
|
260
301
|
*/
|
|
261
302
|
/**
|
|
262
303
|
* Terminal colors and style definitions
|
|
@@ -279,6 +320,16 @@ declare const colors: {
|
|
|
279
320
|
};
|
|
280
321
|
/** Color name type */
|
|
281
322
|
type ColorName = keyof typeof colors;
|
|
323
|
+
/**
|
|
324
|
+
* Convert XML-style color tags to ANSI escape sequences
|
|
325
|
+
* Example: "<red>error</red>" -> "\x1b[31merror\x1b[0m"
|
|
326
|
+
*/
|
|
327
|
+
declare function convertColorTags(str: string): string;
|
|
328
|
+
/**
|
|
329
|
+
* Create a buffered streaming color converter
|
|
330
|
+
* Used for streaming output where tags may span multiple chunks
|
|
331
|
+
*/
|
|
332
|
+
declare function createColorConverter(): (chunk: string) => string;
|
|
282
333
|
|
|
283
334
|
declare class OpenAIAdapter extends Adapter {
|
|
284
335
|
private client;
|
|
@@ -353,4 +404,4 @@ interface Model {
|
|
|
353
404
|
readonly capabilities: ModelCapabilities;
|
|
354
405
|
}
|
|
355
406
|
|
|
356
|
-
export { AIMsg, Adapter, type AdapterResponse, Agent, type AgentResponse, type ColorName, MAX_COMPLETION_TOKENS, MODELS, type Model, type ModelCapabilities, type ModelProvider, Msg, MsgType, OpenAIAdapter, type ReasoningEffort$1 as ReasoningEffort, SystemMsg, TEMPERATURE, TOOLS, Tool, ToolCallMsg, ToolResultMsg, UserMsg, adapter, colors, config, debug, error, info, init, isDebugMode, log, setDebugMode, setWorkingDir, success, warn, workingDir };
|
|
407
|
+
export { AIMsg, Adapter, type AdapterResponse, Agent, type AgentResponse, type ColorName, HAS_MANUAL, MAX_COMPLETION_TOKENS, MODELS, type Model, type ModelCapabilities, type ModelProvider, Msg, MsgType, OpenAIAdapter, PROCEDURES, type ReasoningEffort$1 as ReasoningEffort, SystemMsg, TEMPERATURE, TOOLS, Tool, type ToolCall, ToolCallMsg, type ToolResult, ToolResultMsg, UserMsg, adapter, colors, config, convertColorTags, createColorConverter, debug, error, info, init, isDebugMode, log, setDebugMode, setWorkingDir, success, warn, workingDir };
|
package/dist/index.js
CHANGED
|
@@ -166,19 +166,40 @@ var ToolCallMsg = class extends Msg {
|
|
|
166
166
|
this.toolCalls = toolCalls;
|
|
167
167
|
}
|
|
168
168
|
};
|
|
169
|
-
var ToolResultMsg = class extends Msg {
|
|
169
|
+
var ToolResultMsg = class _ToolResultMsg extends Msg {
|
|
170
170
|
type = "tool_result" /* ToolResult */;
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
isError;
|
|
174
|
-
constructor(toolName, result, isError) {
|
|
171
|
+
toolResults;
|
|
172
|
+
constructor(toolResults) {
|
|
175
173
|
super("");
|
|
176
|
-
this.
|
|
177
|
-
|
|
178
|
-
|
|
174
|
+
this.toolResults = toolResults;
|
|
175
|
+
}
|
|
176
|
+
/** Helper: create from single result */
|
|
177
|
+
static single(toolName, result, isError) {
|
|
178
|
+
return new _ToolResultMsg([{ toolName, result, isError }]);
|
|
179
179
|
}
|
|
180
180
|
};
|
|
181
181
|
|
|
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
|
+
|
|
182
203
|
// src/log/debug.ts
|
|
183
204
|
var _debugMode = false;
|
|
184
205
|
function isDebugMode() {
|
|
@@ -187,43 +208,20 @@ function isDebugMode() {
|
|
|
187
208
|
function setDebugMode(enabled) {
|
|
188
209
|
_debugMode = enabled;
|
|
189
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
|
+
}
|
|
190
217
|
function debug(category, message, data) {
|
|
191
218
|
if (!_debugMode) return;
|
|
192
|
-
const
|
|
193
|
-
|
|
194
|
-
console.log(`${prefix} ${colors.cyan}${message}${colors.reset}`);
|
|
195
|
-
if (data !== void 0) {
|
|
196
|
-
const dataStr = typeof data === "string" ? data : JSON.stringify(data, null, 2);
|
|
197
|
-
const lines = dataStr.split("\n");
|
|
198
|
-
const maxLines = 20;
|
|
199
|
-
const truncated = lines.length > maxLines;
|
|
200
|
-
const displayLines = truncated ? lines.slice(-maxLines) : lines;
|
|
201
|
-
if (truncated) {
|
|
202
|
-
console.log(colors.dim + ` ... (${lines.length - maxLines} earlier lines)` + colors.reset);
|
|
203
|
-
}
|
|
204
|
-
console.log(colors.dim + displayLines.map((l) => ` ${l}`).join("\n") + colors.reset);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// src/log/log.ts
|
|
209
|
-
function log(color, ...args) {
|
|
210
|
-
console.log(colors[color], ...args, colors.reset);
|
|
211
|
-
}
|
|
212
|
-
function info(message) {
|
|
213
|
-
console.log(`${colors.blue}\u2139${colors.reset} ${message}`);
|
|
214
|
-
}
|
|
215
|
-
function success(message) {
|
|
216
|
-
console.log(`${colors.green}\u2714${colors.reset} ${message}`);
|
|
217
|
-
}
|
|
218
|
-
function warn(message) {
|
|
219
|
-
console.log(`${colors.yellow}\u26A0${colors.reset} ${message}`);
|
|
220
|
-
}
|
|
221
|
-
function error(message) {
|
|
222
|
-
console.log(`${colors.red}\u2716${colors.reset} ${message}`);
|
|
219
|
+
const dataStr = data !== void 0 ? ` <dim>${formatData(data)}</dim>` : "";
|
|
220
|
+
log(`<magenta>[${category}]</magenta> <cyan>${message}</cyan>${dataStr}`);
|
|
223
221
|
}
|
|
224
222
|
|
|
225
223
|
// src/log/index.ts
|
|
226
|
-
var
|
|
224
|
+
var colors2 = {
|
|
227
225
|
reset: "\x1B[0m",
|
|
228
226
|
bold: "\x1B[1m",
|
|
229
227
|
dim: "\x1B[2m",
|
|
@@ -239,6 +237,33 @@ var colors = {
|
|
|
239
237
|
cyan: "\x1B[36m",
|
|
240
238
|
gray: "\x1B[90m"
|
|
241
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
|
+
}
|
|
242
267
|
|
|
243
268
|
// src/adapter/openai.ts
|
|
244
269
|
var OpenAIAdapter = class extends Adapter {
|
|
@@ -272,11 +297,13 @@ var OpenAIAdapter = class extends Adapter {
|
|
|
272
297
|
});
|
|
273
298
|
} else if (msg.type === "tool_result" /* ToolResult */) {
|
|
274
299
|
const toolResultMsg = msg;
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
300
|
+
for (const tr of toolResultMsg.toolResults) {
|
|
301
|
+
result.push({
|
|
302
|
+
role: "tool",
|
|
303
|
+
tool_call_id: pendingIds.shift() || `call_${msg.timestamp}`,
|
|
304
|
+
content: tr.isError ? `Error: ${tr.result}` : tr.result
|
|
305
|
+
});
|
|
306
|
+
}
|
|
280
307
|
}
|
|
281
308
|
}
|
|
282
309
|
return result;
|
|
@@ -298,7 +325,6 @@ var OpenAIAdapter = class extends Adapter {
|
|
|
298
325
|
async chat(messages, onChunk) {
|
|
299
326
|
debug("API", `Requesting OpenAI (model: ${this.model}, messages: ${messages.length})`);
|
|
300
327
|
const openaiMessages = this.toOpenAIMessages(messages);
|
|
301
|
-
debug("API", "Sent prompt:", openaiMessages);
|
|
302
328
|
const startTime = Date.now();
|
|
303
329
|
const requestParams = {
|
|
304
330
|
model: this.model,
|
|
@@ -358,6 +384,7 @@ function setWorkingDir(dir) {
|
|
|
358
384
|
workingDir = dir;
|
|
359
385
|
}
|
|
360
386
|
var TOOLS = {};
|
|
387
|
+
var PROCEDURES = {};
|
|
361
388
|
var adapter = null;
|
|
362
389
|
function initAdapter() {
|
|
363
390
|
if (adapter) {
|
|
@@ -378,6 +405,7 @@ async function init(cwd) {
|
|
|
378
405
|
}
|
|
379
406
|
|
|
380
407
|
// src/tool/Tool.ts
|
|
408
|
+
var HAS_MANUAL = "\u{1F4D8}";
|
|
381
409
|
var Tool = class _Tool {
|
|
382
410
|
name;
|
|
383
411
|
description;
|
|
@@ -398,6 +426,7 @@ var Tool = class _Tool {
|
|
|
398
426
|
* Parse manual.md content
|
|
399
427
|
* First line format: "tool_name: description", extract description
|
|
400
428
|
* Remaining content is the manual
|
|
429
|
+
* If manual has content, prepend HAS_MANUAL symbol to description
|
|
401
430
|
*/
|
|
402
431
|
static parseManual(content) {
|
|
403
432
|
const lines = content.split("\n");
|
|
@@ -408,28 +437,25 @@ var Tool = class _Tool {
|
|
|
408
437
|
description = firstLine.slice(colonIndex + 1).trim();
|
|
409
438
|
}
|
|
410
439
|
const manual = lines.slice(1).join("\n").trim();
|
|
440
|
+
if (manual) {
|
|
441
|
+
description = `${HAS_MANUAL}${description}`;
|
|
442
|
+
}
|
|
411
443
|
return { description, manual };
|
|
412
444
|
}
|
|
413
445
|
/**
|
|
414
446
|
* Execute tool (with error handling and logging)
|
|
415
447
|
*/
|
|
416
448
|
async run(args) {
|
|
417
|
-
debug("Tool", `Starting tool execution: ${this.name}`, args);
|
|
418
|
-
const startTime = Date.now();
|
|
419
449
|
try {
|
|
420
450
|
const result = await this._execute(args);
|
|
421
|
-
const elapsed = Date.now() - startTime;
|
|
422
451
|
if (typeof result === "string") {
|
|
423
|
-
|
|
424
|
-
return new ToolResultMsg(this.name, result);
|
|
452
|
+
return { toolName: this.name, result };
|
|
425
453
|
}
|
|
426
|
-
|
|
427
|
-
return new ToolResultMsg(this.name, result.content, result.isError);
|
|
454
|
+
return { toolName: this.name, result: result.content, isError: result.isError };
|
|
428
455
|
} catch (error2) {
|
|
429
|
-
const elapsed = Date.now() - startTime;
|
|
430
456
|
const errorMsg = error2 instanceof Error ? error2.message : String(error2);
|
|
431
|
-
debug("Tool",
|
|
432
|
-
return
|
|
457
|
+
debug("Tool", `${this.name} error`, errorMsg);
|
|
458
|
+
return { toolName: this.name, result: `Error: ${errorMsg}`, isError: true };
|
|
433
459
|
}
|
|
434
460
|
}
|
|
435
461
|
};
|
|
@@ -439,7 +465,7 @@ import * as fs2 from "fs/promises";
|
|
|
439
465
|
import * as path2 from "path";
|
|
440
466
|
|
|
441
467
|
// src/tool/read_file/manual.md
|
|
442
|
-
var manual_default = "read_file: Read the content of a specified file\n
|
|
468
|
+
var manual_default = "read_file: Read the content of a specified file\n";
|
|
443
469
|
|
|
444
470
|
// src/tool/read_file/index.ts
|
|
445
471
|
TOOLS["read_file"] = new Tool({
|
|
@@ -468,7 +494,7 @@ import * as fs3 from "fs/promises";
|
|
|
468
494
|
import * as path3 from "path";
|
|
469
495
|
|
|
470
496
|
// src/tool/write_file/manual.md
|
|
471
|
-
var manual_default2 = "write_file: Write content to a specified file, create the file if it doesn't exist\n
|
|
497
|
+
var manual_default2 = "write_file: Write content to a specified file, create the file if it doesn't exist\n";
|
|
472
498
|
|
|
473
499
|
// src/tool/write_file/index.ts
|
|
474
500
|
TOOLS["write_file"] = new Tool({
|
|
@@ -501,7 +527,7 @@ import * as fs4 from "fs/promises";
|
|
|
501
527
|
import * as path4 from "path";
|
|
502
528
|
|
|
503
529
|
// src/tool/list_directory/manual.md
|
|
504
|
-
var manual_default3 = "list_directory: List files and subdirectories in a specified directory\n
|
|
530
|
+
var manual_default3 = "list_directory: List files and subdirectories in a specified directory\n";
|
|
505
531
|
|
|
506
532
|
// src/tool/list_directory/index.ts
|
|
507
533
|
TOOLS["list_directory"] = new Tool({
|
|
@@ -566,12 +592,12 @@ ${stderr}`;
|
|
|
566
592
|
}
|
|
567
593
|
});
|
|
568
594
|
|
|
569
|
-
// src/tool/
|
|
570
|
-
var manual_default5 = "
|
|
595
|
+
// src/tool/read_tool_manual/manual.md
|
|
596
|
+
var manual_default5 = "read_tool_manual: View detailed usage instructions for a specified tool\n";
|
|
571
597
|
|
|
572
|
-
// src/tool/
|
|
573
|
-
TOOLS["
|
|
574
|
-
name: "
|
|
598
|
+
// src/tool/read_tool_manual/index.ts
|
|
599
|
+
TOOLS["read_tool_manual"] = new Tool({
|
|
600
|
+
name: "read_tool_manual",
|
|
575
601
|
parameters: {
|
|
576
602
|
tool_name: { type: "string", description: "Tool name to view" }
|
|
577
603
|
},
|
|
@@ -596,6 +622,76 @@ ${foundTool.manual}`;
|
|
|
596
622
|
}
|
|
597
623
|
});
|
|
598
624
|
|
|
625
|
+
// src/tool/read_procedure/manual.md
|
|
626
|
+
var manual_default6 = "read_procedure: View detailed steps for a specified procedure\n";
|
|
627
|
+
|
|
628
|
+
// src/tool/read_procedure/index.ts
|
|
629
|
+
TOOLS["read_procedure"] = new Tool({
|
|
630
|
+
name: "read_procedure",
|
|
631
|
+
parameters: {
|
|
632
|
+
procedure_name: { type: "string", description: "Procedure name to view" }
|
|
633
|
+
},
|
|
634
|
+
required: ["procedure_name"],
|
|
635
|
+
manualContent: manual_default6,
|
|
636
|
+
execute: async (args) => {
|
|
637
|
+
const procedureName = args.procedure_name;
|
|
638
|
+
const procedure = PROCEDURES[procedureName];
|
|
639
|
+
if (!procedure) {
|
|
640
|
+
const available = Object.keys(PROCEDURES).join(", ");
|
|
641
|
+
return {
|
|
642
|
+
content: `Procedure not found: ${procedureName}
|
|
643
|
+
Available: ${available}`,
|
|
644
|
+
isError: true
|
|
645
|
+
};
|
|
646
|
+
}
|
|
647
|
+
return `# ${procedure.name}
|
|
648
|
+
|
|
649
|
+
${procedure.description}
|
|
650
|
+
|
|
651
|
+
## Steps
|
|
652
|
+
|
|
653
|
+
${procedure.manual}`;
|
|
654
|
+
}
|
|
655
|
+
});
|
|
656
|
+
|
|
657
|
+
// src/procedure/Procedure.ts
|
|
658
|
+
var Procedure = class _Procedure {
|
|
659
|
+
name;
|
|
660
|
+
description;
|
|
661
|
+
manual;
|
|
662
|
+
constructor(config2) {
|
|
663
|
+
this.name = config2.name;
|
|
664
|
+
const { description, manual } = _Procedure.parseManual(config2.procedureContent);
|
|
665
|
+
this.description = description;
|
|
666
|
+
this.manual = manual;
|
|
667
|
+
}
|
|
668
|
+
/**
|
|
669
|
+
* Parse procedure.md content
|
|
670
|
+
* First line format: "procedure_name: description", extract description
|
|
671
|
+
* Remaining content is the procedure steps
|
|
672
|
+
*/
|
|
673
|
+
static parseManual(content) {
|
|
674
|
+
const lines = content.split("\n");
|
|
675
|
+
const firstLine = lines[0] || "";
|
|
676
|
+
let description = "";
|
|
677
|
+
const colonIndex = firstLine.indexOf(":");
|
|
678
|
+
if (colonIndex > 0) {
|
|
679
|
+
description = firstLine.slice(colonIndex + 1).trim();
|
|
680
|
+
}
|
|
681
|
+
const manual = lines.slice(1).join("\n").trim();
|
|
682
|
+
return { description, manual };
|
|
683
|
+
}
|
|
684
|
+
};
|
|
685
|
+
|
|
686
|
+
// src/procedure/understand_project/procedure.md
|
|
687
|
+
var procedure_default = "understand_project: Systematically explore and understand the current project structure\n\n1. Use `list_directory` on the root directory to get an overview\n - Identify key directories (src, lib, tests, docs, etc.)\n - Note configuration files (package.json, tsconfig.json, Cargo.toml, etc.)\n\n2. Use `read_file` on the main configuration file (package.json, Cargo.toml, pyproject.toml, etc.)\n - Project name and description\n - Dependencies and their purposes\n - Scripts/commands available\n - Entry points\n\n3. Use `read_file` on README.md if it exists\n - Project purpose and goals\n - Setup instructions\n - Usage examples\n\n4. Use `list_directory` on the main source directory (src/, lib/, app/, etc.)\n - Identify the entry point file (index.ts, main.ts, app.ts, etc.)\n - List subdirectories to understand module organization\n - Note any patterns (MVC, feature-based, etc.)\n\n5. Use `read_file` on 2-3 key source files to understand\n - Coding style and conventions\n - Main abstractions and patterns used\n - How modules interact with each other\n\n6. Output the final report in this format **in user's language**:\n\n---\n<bold><cyan>Project Overview</cyan></bold>\n\nName: [project name]\nType: [CLI tool / Web app / Library / API server / etc.]\nLanguage: [TypeScript / JavaScript / Python / etc.]\nPackage Manager: [npm / pnpm / yarn / pip / cargo / etc.]\n\n<bold><cyan>Project Structure</cyan></bold>\n\n[Brief description of directory structure and organization pattern]\n\n<bold><cyan>Key Components</cyan></bold>\n\n\u2022 [Component 1]: [brief description]\n\u2022 [Component 2]: [brief description]\n\u2022 [Component 3]: [brief description]\n...\n\n<bold><cyan>Entry Points</cyan></bold>\n\n\u2022 Main: [path to main entry]\n\u2022 CLI: [path to CLI entry if applicable]\n\u2022 Tests: [path to test entry if applicable]\n\n<bold><cyan>Dependencies</cyan></bold>\n\nCore:\n\u2022 [dep1]: [purpose]\n\u2022 [dep2]: [purpose]\n\nDev:\n\u2022 [dev-dep1]: [purpose]\n\u2022 [dev-dep2]: [purpose]\n\n<bold><cyan>Available Commands</cyan></bold>\n\n\u2022 [command1]: [description]\n\u2022 [command2]: [description]\n...\n\n<bold><cyan>Code Patterns</cyan></bold>\n\n\u2022 [Pattern 1 observed in the codebase]\n\u2022 [Pattern 2 observed in the codebase]\n...\n---\n";
|
|
688
|
+
|
|
689
|
+
// src/procedure/understand_project/index.ts
|
|
690
|
+
PROCEDURES["understand_project"] = new Procedure({
|
|
691
|
+
name: "understand_project",
|
|
692
|
+
procedureContent: procedure_default
|
|
693
|
+
});
|
|
694
|
+
|
|
599
695
|
// src/model/models.ts
|
|
600
696
|
var MODELS = {
|
|
601
697
|
"gpt-5.2": {
|
|
@@ -686,23 +782,20 @@ var Agent = class {
|
|
|
686
782
|
const toolCalls = toolCallMsg.toolCalls;
|
|
687
783
|
debug("Agent", `Received tool call request`, toolCalls.map((tc) => tc.name));
|
|
688
784
|
this.config.onToolCallMsg?.(toolCallMsg);
|
|
785
|
+
const toolResults = [];
|
|
689
786
|
for (const tc of toolCalls) {
|
|
690
787
|
this.config.onBeforeToolRun?.(tc.name, tc.arguments);
|
|
691
|
-
debug("Agent", `Executing tool: ${tc.name}`, tc.arguments);
|
|
692
788
|
const tool = TOOLS[tc.name];
|
|
693
|
-
const result = tool ? await tool.run(tc.arguments) :
|
|
694
|
-
debug("Agent", `Tool execution completed: ${tc.name}`, {
|
|
695
|
-
isError: result.isError,
|
|
696
|
-
contentLength: result.result.length
|
|
697
|
-
});
|
|
789
|
+
const result = tool ? await tool.run(tc.arguments) : { toolName: tc.name, result: `Unknown tool: ${tc.name}`, isError: true };
|
|
698
790
|
toolCallHistory.push({
|
|
699
791
|
name: tc.name,
|
|
700
792
|
arguments: tc.arguments,
|
|
701
793
|
result: result.result
|
|
702
794
|
});
|
|
703
795
|
this.config.onToolResult?.(tc.name, tc.arguments, result.result);
|
|
704
|
-
|
|
796
|
+
toolResults.push(result);
|
|
705
797
|
}
|
|
798
|
+
this.messages.push(new ToolResultMsg(toolResults));
|
|
706
799
|
}
|
|
707
800
|
}
|
|
708
801
|
reset() {
|
|
@@ -711,48 +804,20 @@ var Agent = class {
|
|
|
711
804
|
}
|
|
712
805
|
};
|
|
713
806
|
|
|
714
|
-
// src/agent/
|
|
715
|
-
var
|
|
716
|
-
var tagRegex = new RegExp(`<(\\/?)(${tagNames})>`, "gi");
|
|
717
|
-
function convertColorTags(str) {
|
|
718
|
-
return str.replace(tagRegex, (_, closing, tag) => {
|
|
719
|
-
return closing ? colors.reset : colors[tag.toLowerCase()] || "";
|
|
720
|
-
});
|
|
721
|
-
}
|
|
722
|
-
function createColorConverter() {
|
|
723
|
-
let buffer = "";
|
|
724
|
-
return (chunk) => {
|
|
725
|
-
buffer += chunk;
|
|
726
|
-
const lastOpen = buffer.lastIndexOf("<");
|
|
727
|
-
if (lastOpen === -1) {
|
|
728
|
-
const out2 = convertColorTags(buffer);
|
|
729
|
-
buffer = "";
|
|
730
|
-
return out2;
|
|
731
|
-
}
|
|
732
|
-
if (buffer.indexOf(">", lastOpen) !== -1) {
|
|
733
|
-
const out2 = convertColorTags(buffer);
|
|
734
|
-
buffer = "";
|
|
735
|
-
return out2;
|
|
736
|
-
}
|
|
737
|
-
const out = convertColorTags(buffer.slice(0, lastOpen));
|
|
738
|
-
buffer = buffer.slice(lastOpen);
|
|
739
|
-
return out;
|
|
740
|
-
};
|
|
741
|
-
}
|
|
742
|
-
|
|
743
|
-
// src/agent/main/system.md
|
|
744
|
-
var system_default = "You are Arki, a professional AI programming assistant. You work in the codebase directory `{{working_dir}}`.\n\n## Available Tools\n\n{{tools}}\n\nTools can be called multiple times at once. Make good use of this to improve efficiency.\nIf you need to understand the detailed usage of a tool, use the `get_tool_info` tool to view it.\n\n## Working Principles\n\n1. **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.\n2. **Safety**: Consider potential risks before executing commands.\n3. **Conciseness**: Keep answers brief and concise, avoid repetition and redundancy. Keep each response within 200 words unless the user requests detailed explanation.\n4. **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**. **Do not** output Markdown. Use numbered lists for ordered lists, and \u2022 symbol for unordered lists.\nUse the following tags to format output:\n\n| Scenario | Format |\n|----------|--------|\n| Error/Danger | `<red>...</red>` |\n| Warning/Notice | `<yellow>...</yellow>` |\n| Success/Complete | `<green>...</green>` |\n| File path | `<cyan>...</cyan>` |\n| Code/Command | `<dim>...</dim>` |\n| Emphasis | `<bold>...</bold>` |\n\nTags can be combined, e.g., `<bold><red>Critical Error</red></bold>`\n\nPlease answer questions in the language the user is using, and flexibly use available tools to complete tasks.\n";
|
|
807
|
+
// src/agent/Arki/system.md
|
|
808
|
+
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";
|
|
745
809
|
|
|
746
|
-
// src/agent/
|
|
810
|
+
// src/agent/Arki/Arki.ts
|
|
811
|
+
var toolStartTimes = /* @__PURE__ */ new Map();
|
|
747
812
|
function createMainAgent() {
|
|
748
813
|
if (!adapter) {
|
|
749
814
|
throw new Error("Adapter not initialized, please call init() first");
|
|
750
815
|
}
|
|
751
|
-
const
|
|
816
|
+
const proceduresList = Object.values(PROCEDURES).map((p) => `- ${p.name}: ${p.description}`).join("\n");
|
|
752
817
|
const systemInstruction = Agent.renderTemplate(system_default, {
|
|
753
818
|
working_dir: workingDir,
|
|
754
|
-
|
|
755
|
-
|
|
819
|
+
has_manual: HAS_MANUAL,
|
|
820
|
+
procedures: proceduresList || "(none)"
|
|
756
821
|
});
|
|
757
822
|
const convertColor = createColorConverter();
|
|
758
823
|
const agent = new Agent({
|
|
@@ -761,19 +826,31 @@ function createMainAgent() {
|
|
|
761
826
|
onStream: (chunk) => {
|
|
762
827
|
process.stdout.write(convertColor(chunk));
|
|
763
828
|
},
|
|
764
|
-
onBeforeToolRun: (name
|
|
765
|
-
|
|
766
|
-
const argsPreview = argsStr.length > 60 ? argsStr.substring(0, 60) + "..." : argsStr;
|
|
767
|
-
process.stdout.write(`\x1B[33m\u{1F527} ${name}\x1B[0m \x1B[2m${argsPreview}\x1B[0m`);
|
|
829
|
+
onBeforeToolRun: (name) => {
|
|
830
|
+
toolStartTimes.set(name, Date.now());
|
|
768
831
|
},
|
|
769
832
|
onToolResult: (name, args, result) => {
|
|
833
|
+
const startTime = toolStartTimes.get(name) || Date.now();
|
|
834
|
+
const elapsed = Date.now() - startTime;
|
|
835
|
+
toolStartTimes.delete(name);
|
|
770
836
|
const argsStr = JSON.stringify(args);
|
|
771
837
|
const argsPreview = argsStr.length > 60 ? argsStr.substring(0, 60) + "..." : argsStr;
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
838
|
+
let output = `<green>[TOOL]</green> ${name} <dim>${argsPreview} (${elapsed}ms)`;
|
|
839
|
+
if (isDebugMode()) {
|
|
840
|
+
const lines = result.split("\n").filter((l) => l.trim());
|
|
841
|
+
let summary;
|
|
842
|
+
if (lines.length <= 3) {
|
|
843
|
+
summary = lines.join(", ");
|
|
844
|
+
if (summary.length > 60) summary = summary.substring(0, 60) + "...";
|
|
845
|
+
} else {
|
|
846
|
+
const preview = lines.slice(0, 3).join(", ");
|
|
847
|
+
summary = preview.length > 50 ? preview.substring(0, 50) + "..." : preview;
|
|
848
|
+
summary += ` (+${lines.length - 3} more)`;
|
|
849
|
+
}
|
|
850
|
+
output += ` -> ${summary}`;
|
|
851
|
+
}
|
|
852
|
+
output += "</dim>";
|
|
853
|
+
log(output);
|
|
777
854
|
}
|
|
778
855
|
});
|
|
779
856
|
return agent;
|
|
@@ -782,7 +859,7 @@ function createMainAgent() {
|
|
|
782
859
|
// package.json
|
|
783
860
|
var package_default = {
|
|
784
861
|
name: "arki",
|
|
785
|
-
version: "0.0.
|
|
862
|
+
version: "0.0.5",
|
|
786
863
|
description: "AI Agent Programming Assistant",
|
|
787
864
|
type: "module",
|
|
788
865
|
main: "dist/index.js",
|
|
@@ -890,15 +967,15 @@ async function main() {
|
|
|
890
967
|
const mainAgentConfig = config.getAgentConfig("main");
|
|
891
968
|
const model = MODELS[mainAgentConfig.model];
|
|
892
969
|
console.log();
|
|
893
|
-
log(
|
|
970
|
+
log(`<cyan>Arki AI Agent v${package_default.version}</cyan>`);
|
|
894
971
|
console.log();
|
|
895
|
-
log(
|
|
896
|
-
log(
|
|
972
|
+
log(`<dim>Model: ${mainAgentConfig.model}${model ? ` (${model.name})` : ""}</dim>`);
|
|
973
|
+
log(`<dim>Working directory: ${workingDir}</dim>`);
|
|
897
974
|
if (isDebugMode()) {
|
|
898
|
-
log(
|
|
975
|
+
log(`<yellow>Debug mode enabled</yellow>`);
|
|
899
976
|
}
|
|
900
977
|
console.log();
|
|
901
|
-
log(
|
|
978
|
+
log(`<dim>Loaded ${Object.keys(TOOLS).length} tools</dim>`);
|
|
902
979
|
if (isDebugMode()) {
|
|
903
980
|
debug("Init", "Loaded tools", Object.keys(TOOLS));
|
|
904
981
|
debug("Init", "Agent config", mainAgentConfig);
|
|
@@ -909,38 +986,39 @@ async function main() {
|
|
|
909
986
|
input: process.stdin,
|
|
910
987
|
output: process.stdout
|
|
911
988
|
});
|
|
912
|
-
log(
|
|
913
|
-
log(
|
|
989
|
+
log(`<blue>Enter your question and press Enter to send. Type /exit or /quit to exit.</blue>`);
|
|
990
|
+
log(`<blue>Type /clear to clear conversation history.</blue>`);
|
|
914
991
|
console.log();
|
|
992
|
+
const promptStr = convertColorTags("<green>> </green>");
|
|
915
993
|
const prompt = () => {
|
|
916
|
-
rl.question(
|
|
994
|
+
rl.question(promptStr, async (input) => {
|
|
917
995
|
const trimmed = input.trim();
|
|
918
996
|
if (trimmed === "/exit" || trimmed === "/quit") {
|
|
919
|
-
log(
|
|
997
|
+
log(`<cyan>Goodbye!</cyan>`);
|
|
920
998
|
rl.close();
|
|
921
999
|
process.exit(0);
|
|
922
1000
|
}
|
|
923
1001
|
if (trimmed === "/clear") {
|
|
924
1002
|
agent.reset();
|
|
925
|
-
log(
|
|
1003
|
+
log(`<yellow>Conversation history cleared</yellow>`);
|
|
926
1004
|
console.log();
|
|
927
1005
|
prompt();
|
|
928
1006
|
return;
|
|
929
1007
|
}
|
|
930
1008
|
if (trimmed === "/help") {
|
|
931
1009
|
console.log();
|
|
932
|
-
log(
|
|
933
|
-
log(
|
|
934
|
-
log(
|
|
935
|
-
log(
|
|
936
|
-
log(
|
|
1010
|
+
log(`<cyan>Available commands:</cyan>`);
|
|
1011
|
+
log(`<dim> /exit, /quit - Exit program</dim>`);
|
|
1012
|
+
log(`<dim> /clear - Clear conversation history</dim>`);
|
|
1013
|
+
log(`<dim> /debug - Toggle debug mode</dim>`);
|
|
1014
|
+
log(`<dim> /help - Show help</dim>`);
|
|
937
1015
|
console.log();
|
|
938
1016
|
prompt();
|
|
939
1017
|
return;
|
|
940
1018
|
}
|
|
941
1019
|
if (trimmed === "/debug") {
|
|
942
1020
|
setDebugMode(!isDebugMode());
|
|
943
|
-
log(
|
|
1021
|
+
log(`<yellow>Debug mode ${isDebugMode() ? "enabled" : "disabled"}</yellow>`);
|
|
944
1022
|
console.log();
|
|
945
1023
|
prompt();
|
|
946
1024
|
return;
|
|
@@ -955,14 +1033,11 @@ async function main() {
|
|
|
955
1033
|
console.log();
|
|
956
1034
|
if (result.usage) {
|
|
957
1035
|
const contextLimit = model?.capabilities.contextWindow || "N/A";
|
|
958
|
-
log(
|
|
959
|
-
"dim",
|
|
960
|
-
`[Tokens: ${result.usage.totalTokens} (prompt: ${result.usage.promptTokens}, cached: ${result.usage.cachedTokens || 0}, limit: ${contextLimit})]`
|
|
961
|
-
);
|
|
1036
|
+
log(`<dim>[Tokens: ${result.usage.totalTokens} (prompt: ${result.usage.promptTokens}, cached: ${result.usage.cachedTokens || 0}, limit: ${contextLimit})]</dim>`);
|
|
962
1037
|
}
|
|
963
1038
|
console.log();
|
|
964
1039
|
} catch (error2) {
|
|
965
|
-
log(
|
|
1040
|
+
log(`<red>Error: ${error2 instanceof Error ? error2.message : String(error2)}</red>`);
|
|
966
1041
|
console.log();
|
|
967
1042
|
}
|
|
968
1043
|
prompt();
|
|
@@ -978,11 +1053,13 @@ export {
|
|
|
978
1053
|
AIMsg,
|
|
979
1054
|
Adapter,
|
|
980
1055
|
Agent,
|
|
1056
|
+
HAS_MANUAL,
|
|
981
1057
|
MAX_COMPLETION_TOKENS,
|
|
982
1058
|
MODELS,
|
|
983
1059
|
Msg,
|
|
984
1060
|
MsgType,
|
|
985
1061
|
OpenAIAdapter,
|
|
1062
|
+
PROCEDURES,
|
|
986
1063
|
SystemMsg,
|
|
987
1064
|
TEMPERATURE,
|
|
988
1065
|
TOOLS,
|
|
@@ -991,8 +1068,10 @@ export {
|
|
|
991
1068
|
ToolResultMsg,
|
|
992
1069
|
UserMsg,
|
|
993
1070
|
adapter,
|
|
994
|
-
colors,
|
|
1071
|
+
colors2 as colors,
|
|
995
1072
|
config,
|
|
1073
|
+
convertColorTags,
|
|
1074
|
+
createColorConverter,
|
|
996
1075
|
debug,
|
|
997
1076
|
error,
|
|
998
1077
|
info,
|