arki 0.0.1
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/LICENSE +21 -0
- package/README.md +125 -0
- package/bin/arki.js +4 -0
- package/dist/config/config.json +14 -0
- package/dist/index.d.ts +355 -0
- package/dist/index.js +1003 -0
- package/package.json +56 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 arki.moe
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Arki - AI Agent Programming Assistant
|
|
2
|
+
|
|
3
|
+
Arki is an AI agent programming tool.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
### Via npm
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g arki
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Via pnpm
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pnpm install -g arki
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### From source
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
git clone https://github.com/your-username/arki.git
|
|
23
|
+
cd arki
|
|
24
|
+
pnpm install
|
|
25
|
+
pnpm build
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
export OPENAI_API_KEY="your-api-key"
|
|
32
|
+
arki
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Command Line Arguments
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
arki [options]
|
|
39
|
+
|
|
40
|
+
Options:
|
|
41
|
+
-p <path> Specify working directory
|
|
42
|
+
--debug, -d Enable debug mode, show detailed logs
|
|
43
|
+
--help, -h Show help information
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Example:
|
|
47
|
+
```bash
|
|
48
|
+
# Start in specified directory with debug mode enabled
|
|
49
|
+
arki -p /path/to/project --debug
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Supported Models
|
|
53
|
+
|
|
54
|
+
- `gpt-5.2` - GPT-5.2
|
|
55
|
+
- `gpt-5.1` - GPT-5.1
|
|
56
|
+
- `gpt-5` - GPT-5
|
|
57
|
+
- `gpt-5-nano` - GPT-5 Nano
|
|
58
|
+
|
|
59
|
+
### Interactive Commands
|
|
60
|
+
|
|
61
|
+
- `/exit` or `/quit` - Exit program
|
|
62
|
+
- `/clear` - Clear conversation history
|
|
63
|
+
- `/debug` - Toggle debug mode
|
|
64
|
+
- `/help` - Show help
|
|
65
|
+
|
|
66
|
+
### Debug Mode
|
|
67
|
+
|
|
68
|
+
Debug mode outputs detailed runtime logs, including:
|
|
69
|
+
- API request/response information (model, message count, elapsed time, tokens)
|
|
70
|
+
- Agent run loop (rounds, message count)
|
|
71
|
+
- Tool execution details (parameters, elapsed time, results)
|
|
72
|
+
|
|
73
|
+
Ways to enable:
|
|
74
|
+
1. Add `--debug` or `-d` parameter at startup
|
|
75
|
+
2. Type `/debug` during runtime to toggle
|
|
76
|
+
|
|
77
|
+
## Configuration File
|
|
78
|
+
|
|
79
|
+
Configuration file is located at `~/.config/arki/config.json`:
|
|
80
|
+
|
|
81
|
+
```json
|
|
82
|
+
{
|
|
83
|
+
"agents": {
|
|
84
|
+
"main": {
|
|
85
|
+
"model": "gpt-5.1",
|
|
86
|
+
"flex": false,
|
|
87
|
+
"reasoningEffort": "medium"
|
|
88
|
+
},
|
|
89
|
+
"coder": {
|
|
90
|
+
"model": "gpt-5.2",
|
|
91
|
+
"flex": false,
|
|
92
|
+
"reasoningEffort": "high"
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Each Agent configuration:
|
|
99
|
+
- `model` - Model ID to use
|
|
100
|
+
- `flex` - Use Flex API (low priority, low cost)
|
|
101
|
+
- `reasoningEffort` - Reasoning effort, optional values: `low`, `medium`, `high` (for models that support thinking mode)
|
|
102
|
+
|
|
103
|
+
Default configuration is automatically copied from the package on first run.
|
|
104
|
+
|
|
105
|
+
## Built-in Tools
|
|
106
|
+
|
|
107
|
+
Arki includes the following built-in tools that the AI assistant can automatically call:
|
|
108
|
+
|
|
109
|
+
- `read_file` - Read file content
|
|
110
|
+
- `write_file` - Write to file
|
|
111
|
+
- `list_directory` - List directory contents
|
|
112
|
+
- `run_command` - Execute shell commands
|
|
113
|
+
- `get_tool_info` - View detailed usage instructions for tools
|
|
114
|
+
|
|
115
|
+
## Development
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
pnpm dev # Development mode
|
|
119
|
+
pnpm build # Build
|
|
120
|
+
pnpm typecheck # Type checking
|
|
121
|
+
pnpm test # Run tests
|
|
122
|
+
pnpm test:watch # Watch mode testing
|
|
123
|
+
pnpm test:coverage # Test coverage
|
|
124
|
+
pnpm test:e2e # E2E tests
|
|
125
|
+
```
|
package/bin/arki.js
ADDED
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Message type enum (for type narrowing)
|
|
4
|
+
*/
|
|
5
|
+
declare enum MsgType {
|
|
6
|
+
System = "system",
|
|
7
|
+
User = "user",
|
|
8
|
+
AI = "ai",
|
|
9
|
+
ToolCall = "tool_call",
|
|
10
|
+
ToolResult = "tool_result"
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Base message class
|
|
14
|
+
*/
|
|
15
|
+
declare abstract class Msg {
|
|
16
|
+
abstract readonly type: MsgType;
|
|
17
|
+
readonly timestamp: number;
|
|
18
|
+
readonly content: string;
|
|
19
|
+
constructor(content: string);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* System message constructor
|
|
23
|
+
*/
|
|
24
|
+
declare class SystemMsg extends Msg {
|
|
25
|
+
readonly type = MsgType.System;
|
|
26
|
+
constructor(content: string);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* User message constructor
|
|
30
|
+
*/
|
|
31
|
+
declare class UserMsg extends Msg {
|
|
32
|
+
readonly type = MsgType.User;
|
|
33
|
+
constructor(content: string);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* AI message constructor
|
|
37
|
+
*/
|
|
38
|
+
declare class AIMsg extends Msg {
|
|
39
|
+
readonly type = MsgType.AI;
|
|
40
|
+
constructor(content: string);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Tool call message constructor
|
|
44
|
+
*/
|
|
45
|
+
declare class ToolCallMsg extends Msg {
|
|
46
|
+
readonly type = MsgType.ToolCall;
|
|
47
|
+
readonly toolCalls: Array<{
|
|
48
|
+
name: string;
|
|
49
|
+
arguments: Record<string, unknown>;
|
|
50
|
+
}>;
|
|
51
|
+
constructor(content: string, toolCalls: Array<{
|
|
52
|
+
name: string;
|
|
53
|
+
arguments: Record<string, unknown>;
|
|
54
|
+
}>);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Tool result message constructor
|
|
58
|
+
*/
|
|
59
|
+
declare class ToolResultMsg extends Msg {
|
|
60
|
+
readonly type = MsgType.ToolResult;
|
|
61
|
+
readonly toolName: string;
|
|
62
|
+
readonly result: string;
|
|
63
|
+
readonly isError?: boolean;
|
|
64
|
+
constructor(toolName: string, result: string, isError?: boolean);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Tool class
|
|
69
|
+
*/
|
|
70
|
+
declare class Tool {
|
|
71
|
+
readonly name: string;
|
|
72
|
+
readonly description: string;
|
|
73
|
+
readonly parameters: Record<string, unknown>;
|
|
74
|
+
readonly required: string[];
|
|
75
|
+
readonly manual: string;
|
|
76
|
+
private readonly _execute;
|
|
77
|
+
constructor(config: {
|
|
78
|
+
name: string;
|
|
79
|
+
parameters: Record<string, unknown>;
|
|
80
|
+
required: string[];
|
|
81
|
+
manualContent: string;
|
|
82
|
+
execute: (args: Record<string, unknown>) => Promise<string | {
|
|
83
|
+
content: string;
|
|
84
|
+
isError?: boolean;
|
|
85
|
+
}>;
|
|
86
|
+
});
|
|
87
|
+
/**
|
|
88
|
+
* Parse manual.md content
|
|
89
|
+
* First line format: "tool_name: description", extract description
|
|
90
|
+
* Remaining content is the manual
|
|
91
|
+
*/
|
|
92
|
+
static parseManual(content: string): {
|
|
93
|
+
description: string;
|
|
94
|
+
manual: string;
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* Execute tool (with error handling and logging)
|
|
98
|
+
*/
|
|
99
|
+
run(args: Record<string, unknown>): Promise<ToolResultMsg>;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Fixed parameters
|
|
104
|
+
*/
|
|
105
|
+
declare const TEMPERATURE = 0.2;
|
|
106
|
+
declare const MAX_COMPLETION_TOKENS = 4096;
|
|
107
|
+
/**
|
|
108
|
+
* Reasoning effort
|
|
109
|
+
*/
|
|
110
|
+
type ReasoningEffort$1 = 'low' | 'medium' | 'high';
|
|
111
|
+
/**
|
|
112
|
+
* LLM response result
|
|
113
|
+
*/
|
|
114
|
+
interface AdapterResponse {
|
|
115
|
+
message: Msg;
|
|
116
|
+
hasToolCalls: boolean;
|
|
117
|
+
usage?: {
|
|
118
|
+
promptTokens: number;
|
|
119
|
+
completionTokens: number;
|
|
120
|
+
totalTokens: number;
|
|
121
|
+
cachedTokens?: number;
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* LLM adapter base class
|
|
126
|
+
*/
|
|
127
|
+
declare abstract class Adapter {
|
|
128
|
+
protected apiKey: string;
|
|
129
|
+
protected model: string;
|
|
130
|
+
/** Use Flex API (OpenAI) - low priority, low cost */
|
|
131
|
+
protected flex?: boolean;
|
|
132
|
+
/** Reasoning effort (thinking mode) */
|
|
133
|
+
protected reasoningEffort?: ReasoningEffort$1;
|
|
134
|
+
/** Available tools list */
|
|
135
|
+
protected tools?: Tool[];
|
|
136
|
+
constructor(config: {
|
|
137
|
+
apiKey: string;
|
|
138
|
+
model: string;
|
|
139
|
+
/** Use Flex API (OpenAI) - low priority, low cost */
|
|
140
|
+
flex?: boolean;
|
|
141
|
+
/** Reasoning effort (thinking mode) */
|
|
142
|
+
reasoningEffort?: ReasoningEffort$1;
|
|
143
|
+
/** Available tools list */
|
|
144
|
+
tools?: Tool[];
|
|
145
|
+
});
|
|
146
|
+
abstract chat(messages: Msg[], onChunk?: (chunk: string) => void): Promise<AdapterResponse>;
|
|
147
|
+
getModel(): string;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Agent type
|
|
152
|
+
*/
|
|
153
|
+
type AgentType = 'main' | 'coder';
|
|
154
|
+
/**
|
|
155
|
+
* Reasoning effort
|
|
156
|
+
*/
|
|
157
|
+
type ReasoningEffort = 'low' | 'medium' | 'high';
|
|
158
|
+
/**
|
|
159
|
+
* Agent model configuration
|
|
160
|
+
*/
|
|
161
|
+
interface AgentModelConfig {
|
|
162
|
+
/** Model ID */
|
|
163
|
+
model: string;
|
|
164
|
+
/** Use Flex API (low priority, low cost) */
|
|
165
|
+
flex?: boolean;
|
|
166
|
+
/** Reasoning effort (thinking mode) */
|
|
167
|
+
reasoningEffort?: ReasoningEffort;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Global configuration
|
|
171
|
+
*/
|
|
172
|
+
interface GlobalConfig {
|
|
173
|
+
apiKeys?: {
|
|
174
|
+
openai?: string;
|
|
175
|
+
anthropic?: string;
|
|
176
|
+
google?: string;
|
|
177
|
+
[key: string]: string | undefined;
|
|
178
|
+
};
|
|
179
|
+
agents: {
|
|
180
|
+
[K in AgentType]?: AgentModelConfig;
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Global configuration manager
|
|
185
|
+
*/
|
|
186
|
+
declare class ConfigManager {
|
|
187
|
+
private config;
|
|
188
|
+
private loaded;
|
|
189
|
+
/**
|
|
190
|
+
* Load configuration (called at program startup)
|
|
191
|
+
*/
|
|
192
|
+
load(): Promise<GlobalConfig>;
|
|
193
|
+
/**
|
|
194
|
+
* Save configuration
|
|
195
|
+
*/
|
|
196
|
+
save(): Promise<void>;
|
|
197
|
+
get(): GlobalConfig;
|
|
198
|
+
getApiKey(provider: string): string | undefined;
|
|
199
|
+
getAgentConfig(agentType: AgentType): AgentModelConfig;
|
|
200
|
+
private loadEnvApiKeys;
|
|
201
|
+
}
|
|
202
|
+
declare const config: ConfigManager;
|
|
203
|
+
|
|
204
|
+
/** Working directory */
|
|
205
|
+
declare let workingDir: string;
|
|
206
|
+
/** Set working directory (for testing) */
|
|
207
|
+
declare function setWorkingDir(dir: string): void;
|
|
208
|
+
/** Global tool registry */
|
|
209
|
+
declare const TOOLS: Record<string, Tool>;
|
|
210
|
+
/** Global Adapter instance */
|
|
211
|
+
declare let adapter: Adapter | null;
|
|
212
|
+
/** Initialize global state */
|
|
213
|
+
declare function init(cwd?: string): Promise<void>;
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Debug logging module
|
|
217
|
+
*/
|
|
218
|
+
/** Get debug mode status */
|
|
219
|
+
declare function isDebugMode(): boolean;
|
|
220
|
+
/** Set debug mode */
|
|
221
|
+
declare function setDebugMode(enabled: boolean): void;
|
|
222
|
+
/**
|
|
223
|
+
* Debug log function
|
|
224
|
+
* @param category Log category (e.g., 'API', 'Agent', 'Tool')
|
|
225
|
+
* @param message Log message
|
|
226
|
+
* @param data Optional additional data
|
|
227
|
+
*/
|
|
228
|
+
declare function debug(category: string, message: string, data?: unknown): void;
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* General logging module
|
|
232
|
+
*/
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Colored log output
|
|
236
|
+
* @param color Color name
|
|
237
|
+
* @param args Content to output
|
|
238
|
+
*/
|
|
239
|
+
declare function log(color: ColorName, ...args: unknown[]): void;
|
|
240
|
+
/**
|
|
241
|
+
* Info log
|
|
242
|
+
*/
|
|
243
|
+
declare function info(message: string): void;
|
|
244
|
+
/**
|
|
245
|
+
* Success log
|
|
246
|
+
*/
|
|
247
|
+
declare function success(message: string): void;
|
|
248
|
+
/**
|
|
249
|
+
* Warning log
|
|
250
|
+
*/
|
|
251
|
+
declare function warn(message: string): void;
|
|
252
|
+
/**
|
|
253
|
+
* Error log
|
|
254
|
+
*/
|
|
255
|
+
declare function error(message: string): void;
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Logging module
|
|
259
|
+
* Provides debug mode and logging functionality
|
|
260
|
+
*/
|
|
261
|
+
/**
|
|
262
|
+
* Terminal colors and style definitions
|
|
263
|
+
*/
|
|
264
|
+
declare const colors: {
|
|
265
|
+
reset: string;
|
|
266
|
+
bold: string;
|
|
267
|
+
dim: string;
|
|
268
|
+
italic: string;
|
|
269
|
+
underline: string;
|
|
270
|
+
inverse: string;
|
|
271
|
+
strikethrough: string;
|
|
272
|
+
red: string;
|
|
273
|
+
green: string;
|
|
274
|
+
yellow: string;
|
|
275
|
+
blue: string;
|
|
276
|
+
magenta: string;
|
|
277
|
+
cyan: string;
|
|
278
|
+
gray: string;
|
|
279
|
+
};
|
|
280
|
+
/** Color name type */
|
|
281
|
+
type ColorName = keyof typeof colors;
|
|
282
|
+
|
|
283
|
+
declare class OpenAIAdapter extends Adapter {
|
|
284
|
+
private client;
|
|
285
|
+
constructor(config: {
|
|
286
|
+
apiKey: string;
|
|
287
|
+
model: string;
|
|
288
|
+
flex?: boolean;
|
|
289
|
+
reasoningEffort?: 'low' | 'medium' | 'high';
|
|
290
|
+
tools?: Tool[];
|
|
291
|
+
});
|
|
292
|
+
private toOpenAIMessages;
|
|
293
|
+
private getTools;
|
|
294
|
+
chat(messages: Msg[], onChunk?: (chunk: string) => void): Promise<AdapterResponse>;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
interface AgentResponse {
|
|
298
|
+
response: string;
|
|
299
|
+
toolCalls: Array<{
|
|
300
|
+
name: string;
|
|
301
|
+
arguments: Record<string, unknown>;
|
|
302
|
+
result: string;
|
|
303
|
+
}>;
|
|
304
|
+
usage?: {
|
|
305
|
+
promptTokens: number;
|
|
306
|
+
completionTokens: number;
|
|
307
|
+
totalTokens: number;
|
|
308
|
+
cachedTokens?: number;
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
declare class Agent {
|
|
312
|
+
private config;
|
|
313
|
+
private messages;
|
|
314
|
+
constructor(config: {
|
|
315
|
+
adapter: Adapter;
|
|
316
|
+
messages: Msg[];
|
|
317
|
+
onStream?: (chunk: string) => void;
|
|
318
|
+
onToolCallMsg?: (msg: ToolCallMsg) => void;
|
|
319
|
+
onToolResult?: (name: string, result: string) => void;
|
|
320
|
+
});
|
|
321
|
+
/**
|
|
322
|
+
* Render template string, replacing {{variable}} style variables
|
|
323
|
+
*/
|
|
324
|
+
static renderTemplate(template: string, variables: Record<string, string | number | boolean>): string;
|
|
325
|
+
run(userInput: string): Promise<AgentResponse>;
|
|
326
|
+
reset(): this;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* All available model configurations (keyed by ID)
|
|
331
|
+
*/
|
|
332
|
+
declare const MODELS: Record<string, Model>;
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Model provider type
|
|
336
|
+
*/
|
|
337
|
+
type ModelProvider = 'openai' | 'anthropic' | 'google' | 'deepseek' | 'custom';
|
|
338
|
+
/**
|
|
339
|
+
* Model capabilities
|
|
340
|
+
*/
|
|
341
|
+
interface ModelCapabilities {
|
|
342
|
+
streaming: boolean;
|
|
343
|
+
vision: boolean;
|
|
344
|
+
contextWindow: number;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Model interface
|
|
348
|
+
*/
|
|
349
|
+
interface Model {
|
|
350
|
+
readonly name: string;
|
|
351
|
+
readonly provider: ModelProvider;
|
|
352
|
+
readonly capabilities: ModelCapabilities;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
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 };
|