locdotech-ai 1.0.0
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 +104 -0
- package/bin/ai.js +16 -0
- package/dist/api/client.d.ts +75 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +86 -0
- package/dist/api/client.js.map +1 -0
- package/dist/api/index.d.ts +4 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +4 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/streaming.d.ts +15 -0
- package/dist/api/streaming.d.ts.map +1 -0
- package/dist/api/streaming.js +87 -0
- package/dist/api/streaming.js.map +1 -0
- package/dist/api/websocket.d.ts +20 -0
- package/dist/api/websocket.d.ts.map +1 -0
- package/dist/api/websocket.js +80 -0
- package/dist/api/websocket.js.map +1 -0
- package/dist/cli.d.ts +15 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +72 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/clear.d.ts +3 -0
- package/dist/commands/clear.d.ts.map +1 -0
- package/dist/commands/clear.js +13 -0
- package/dist/commands/clear.js.map +1 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +116 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/help.d.ts +3 -0
- package/dist/commands/help.d.ts.map +1 -0
- package/dist/commands/help.js +42 -0
- package/dist/commands/help.js.map +1 -0
- package/dist/commands/history.d.ts +3 -0
- package/dist/commands/history.d.ts.map +1 -0
- package/dist/commands/history.js +62 -0
- package/dist/commands/history.js.map +1 -0
- package/dist/commands/index.d.ts +30 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +54 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/model.d.ts +3 -0
- package/dist/commands/model.d.ts.map +1 -0
- package/dist/commands/model.js +57 -0
- package/dist/commands/model.js.map +1 -0
- package/dist/commands/quit.d.ts +3 -0
- package/dist/commands/quit.d.ts.map +1 -0
- package/dist/commands/quit.js +16 -0
- package/dist/commands/quit.js.map +1 -0
- package/dist/commands/status.d.ts +3 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +39 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +2 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/settings.d.ts +18 -0
- package/dist/config/settings.d.ts.map +1 -0
- package/dist/config/settings.js +56 -0
- package/dist/config/settings.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +100 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/bash.d.ts +41 -0
- package/dist/tools/bash.d.ts.map +1 -0
- package/dist/tools/bash.js +100 -0
- package/dist/tools/bash.js.map +1 -0
- package/dist/tools/file.d.ts +107 -0
- package/dist/tools/file.d.ts.map +1 -0
- package/dist/tools/file.js +189 -0
- package/dist/tools/file.js.map +1 -0
- package/dist/tools/glob.d.ts +38 -0
- package/dist/tools/glob.d.ts.map +1 -0
- package/dist/tools/glob.js +84 -0
- package/dist/tools/glob.js.map +1 -0
- package/dist/tools/grep.d.ts +76 -0
- package/dist/tools/grep.d.ts.map +1 -0
- package/dist/tools/grep.js +166 -0
- package/dist/tools/grep.js.map +1 -0
- package/dist/tools/index.d.ts +29 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +130 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/mcp.d.ts +59 -0
- package/dist/tools/mcp.d.ts.map +1 -0
- package/dist/tools/mcp.js +155 -0
- package/dist/tools/mcp.js.map +1 -0
- package/dist/ui/App.d.ts +6 -0
- package/dist/ui/App.d.ts.map +1 -0
- package/dist/ui/App.js +161 -0
- package/dist/ui/App.js.map +1 -0
- package/dist/ui/components/CodeBlock.d.ts +9 -0
- package/dist/ui/components/CodeBlock.d.ts.map +1 -0
- package/dist/ui/components/CodeBlock.js +83 -0
- package/dist/ui/components/CodeBlock.js.map +1 -0
- package/dist/ui/components/Input.d.ts +11 -0
- package/dist/ui/components/Input.d.ts.map +1 -0
- package/dist/ui/components/Input.js +93 -0
- package/dist/ui/components/Input.js.map +1 -0
- package/dist/ui/components/Message.d.ts +7 -0
- package/dist/ui/components/Message.d.ts.map +1 -0
- package/dist/ui/components/Message.js +86 -0
- package/dist/ui/components/Message.js.map +1 -0
- package/dist/ui/components/ModelSelector.d.ts +7 -0
- package/dist/ui/components/ModelSelector.d.ts.map +1 -0
- package/dist/ui/components/ModelSelector.js +23 -0
- package/dist/ui/components/ModelSelector.js.map +1 -0
- package/dist/ui/components/Permission.d.ts +9 -0
- package/dist/ui/components/Permission.d.ts.map +1 -0
- package/dist/ui/components/Permission.js +41 -0
- package/dist/ui/components/Permission.js.map +1 -0
- package/dist/ui/components/StatusBar.d.ts +11 -0
- package/dist/ui/components/StatusBar.d.ts.map +1 -0
- package/dist/ui/components/StatusBar.js +9 -0
- package/dist/ui/components/StatusBar.js.map +1 -0
- package/dist/ui/components/TaskList.d.ts +12 -0
- package/dist/ui/components/TaskList.d.ts.map +1 -0
- package/dist/ui/components/TaskList.js +21 -0
- package/dist/ui/components/TaskList.js.map +1 -0
- package/dist/ui/components/ToolCall.d.ts +16 -0
- package/dist/ui/components/ToolCall.d.ts.map +1 -0
- package/dist/ui/components/ToolCall.js +50 -0
- package/dist/ui/components/ToolCall.js.map +1 -0
- package/dist/ui/components/index.d.ts +8 -0
- package/dist/ui/components/index.d.ts.map +1 -0
- package/dist/ui/components/index.js +8 -0
- package/dist/ui/components/index.js.map +1 -0
- package/dist/ui/hooks/index.d.ts +4 -0
- package/dist/ui/hooks/index.d.ts.map +1 -0
- package/dist/ui/hooks/index.js +4 -0
- package/dist/ui/hooks/index.js.map +1 -0
- package/dist/ui/hooks/useChat.d.ts +42 -0
- package/dist/ui/hooks/useChat.d.ts.map +1 -0
- package/dist/ui/hooks/useChat.js +305 -0
- package/dist/ui/hooks/useChat.js.map +1 -0
- package/dist/ui/hooks/useHistory.d.ts +14 -0
- package/dist/ui/hooks/useHistory.d.ts.map +1 -0
- package/dist/ui/hooks/useHistory.js +123 -0
- package/dist/ui/hooks/useHistory.js.map +1 -0
- package/dist/ui/hooks/useTools.d.ts +19 -0
- package/dist/ui/hooks/useTools.d.ts.map +1 -0
- package/dist/ui/hooks/useTools.js +54 -0
- package/dist/ui/hooks/useTools.js.map +1 -0
- package/dist/ui/themes/index.d.ts +21 -0
- package/dist/ui/themes/index.d.ts.map +1 -0
- package/dist/ui/themes/index.js +40 -0
- package/dist/ui/themes/index.js.map +1 -0
- package/dist/utils/auth.d.ts +5 -0
- package/dist/utils/auth.d.ts.map +1 -0
- package/dist/utils/auth.js +42 -0
- package/dist/utils/auth.js.map +1 -0
- package/dist/utils/format.d.ts +11 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +71 -0
- package/dist/utils/format.js.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +4 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +18 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +61 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +64 -0
package/README.md
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# AI Router CLI
|
|
2
|
+
|
|
3
|
+
CLI tool giống Claude Code, kết nối đến AIRouter Backend.
|
|
4
|
+
|
|
5
|
+
**Created by [LocdoTech](https://locdo.tech)**
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
### Từ NPM
|
|
10
|
+
```bash
|
|
11
|
+
npm install -g @locdotech/ai-router
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
### Từ GitHub
|
|
15
|
+
```bash
|
|
16
|
+
npm install -g github:locdotech/ai-router-cli
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Từ source
|
|
20
|
+
```bash
|
|
21
|
+
git clone https://github.com/locdotech/ai-router-cli.git
|
|
22
|
+
cd ai-router-cli
|
|
23
|
+
npm install
|
|
24
|
+
npm run build
|
|
25
|
+
npm link
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
### Non-interactive mode
|
|
31
|
+
```bash
|
|
32
|
+
ai "Hello, who are you?"
|
|
33
|
+
ai "List files in current directory"
|
|
34
|
+
ai -m gpt-4 "Explain this code"
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Interactive mode
|
|
38
|
+
```bash
|
|
39
|
+
ai
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Options
|
|
43
|
+
```
|
|
44
|
+
-m, --model <model> Model to use (default: songluan)
|
|
45
|
+
-k, --api-key <key> API key for AIRouter
|
|
46
|
+
-y, --yes Auto-accept all tool executions
|
|
47
|
+
-V, --version Show version
|
|
48
|
+
-h, --help Show help
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Configuration
|
|
52
|
+
|
|
53
|
+
Config file: `~/.ai-router/config.json`
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"apiKey": "your-api-key",
|
|
58
|
+
"apiUrl": "http://103.1.236.240:4001",
|
|
59
|
+
"model": "songluan",
|
|
60
|
+
"autoAccept": false
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Set API Key
|
|
65
|
+
```bash
|
|
66
|
+
ai --api-key sk-your-key-here
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Or in interactive mode:
|
|
70
|
+
```
|
|
71
|
+
/config apiKey sk-your-key-here
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Slash Commands
|
|
75
|
+
|
|
76
|
+
| Command | Description |
|
|
77
|
+
|---------|-------------|
|
|
78
|
+
| `/help` | Show help |
|
|
79
|
+
| `/clear` | Clear conversation |
|
|
80
|
+
| `/model` | Show/change model |
|
|
81
|
+
| `/config` | Show/edit config |
|
|
82
|
+
| `/config reset` | Reset all settings |
|
|
83
|
+
| `/config reset apiKey` | Reset only API key |
|
|
84
|
+
| `/config path` | Show config file path |
|
|
85
|
+
| `/status` | Show connection status |
|
|
86
|
+
| `/history` | Show command history |
|
|
87
|
+
| `/quit` | Exit |
|
|
88
|
+
|
|
89
|
+
## Keyboard Shortcuts
|
|
90
|
+
|
|
91
|
+
| Shortcut | Action |
|
|
92
|
+
|----------|--------|
|
|
93
|
+
| `Ctrl+C` | Abort/Exit |
|
|
94
|
+
| `Ctrl+L` | Clear screen |
|
|
95
|
+
| `Shift+Tab` | Toggle auto-accept |
|
|
96
|
+
| `↑/↓` | Navigate history |
|
|
97
|
+
|
|
98
|
+
## License
|
|
99
|
+
|
|
100
|
+
MIT
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
**Created by [LocdoTech](https://locdo.tech)** 🚀
|
package/bin/ai.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// ESM entry point for AI Router CLI
|
|
4
|
+
async function main() {
|
|
5
|
+
try {
|
|
6
|
+
await import('../dist/index.js');
|
|
7
|
+
} catch (err) {
|
|
8
|
+
console.error('Failed to start AI Router CLI:', err.message);
|
|
9
|
+
if (err.stack) {
|
|
10
|
+
console.error(err.stack);
|
|
11
|
+
}
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
main();
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
export interface Message {
|
|
2
|
+
role: 'system' | 'user' | 'assistant' | 'tool';
|
|
3
|
+
content: string;
|
|
4
|
+
tool_calls?: ToolCall[];
|
|
5
|
+
tool_call_id?: string;
|
|
6
|
+
name?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ToolCall {
|
|
9
|
+
id: string;
|
|
10
|
+
type: 'function';
|
|
11
|
+
function: {
|
|
12
|
+
name: string;
|
|
13
|
+
arguments: string;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export interface Tool {
|
|
17
|
+
type: 'function';
|
|
18
|
+
function: {
|
|
19
|
+
name: string;
|
|
20
|
+
description: string;
|
|
21
|
+
parameters: Record<string, unknown>;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export interface ChatRequest {
|
|
25
|
+
model: string;
|
|
26
|
+
messages: Message[];
|
|
27
|
+
stream?: boolean;
|
|
28
|
+
tools?: Tool[];
|
|
29
|
+
tool_choice?: 'auto' | 'none' | {
|
|
30
|
+
type: 'function';
|
|
31
|
+
function: {
|
|
32
|
+
name: string;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
max_tokens?: number;
|
|
36
|
+
temperature?: number;
|
|
37
|
+
}
|
|
38
|
+
export interface ChatResponse {
|
|
39
|
+
id: string;
|
|
40
|
+
object: string;
|
|
41
|
+
created: number;
|
|
42
|
+
model: string;
|
|
43
|
+
choices: {
|
|
44
|
+
index: number;
|
|
45
|
+
message: Message;
|
|
46
|
+
finish_reason: string;
|
|
47
|
+
}[];
|
|
48
|
+
usage?: {
|
|
49
|
+
prompt_tokens: number;
|
|
50
|
+
completion_tokens: number;
|
|
51
|
+
total_tokens: number;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
export interface StreamChunk {
|
|
55
|
+
id: string;
|
|
56
|
+
object: string;
|
|
57
|
+
created: number;
|
|
58
|
+
model: string;
|
|
59
|
+
choices: {
|
|
60
|
+
index: number;
|
|
61
|
+
delta: Partial<Message>;
|
|
62
|
+
finish_reason: string | null;
|
|
63
|
+
}[];
|
|
64
|
+
}
|
|
65
|
+
export declare class AIRouterClient {
|
|
66
|
+
private baseUrl;
|
|
67
|
+
private apiKey;
|
|
68
|
+
constructor();
|
|
69
|
+
setApiKey(key: string): void;
|
|
70
|
+
chat(request: ChatRequest): Promise<ChatResponse>;
|
|
71
|
+
chatStream(request: ChatRequest): AsyncGenerator<StreamChunk>;
|
|
72
|
+
testConnection(): Promise<boolean>;
|
|
73
|
+
}
|
|
74
|
+
export declare const client: AIRouterClient;
|
|
75
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,QAAQ,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACrC,CAAC;CACH;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG;QAAE,IAAI,EAAE,UAAU,CAAC;QAAC,QAAQ,EAAE;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;IACjF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,OAAO,CAAC;QACjB,aAAa,EAAE,MAAM,CAAC;KACvB,EAAE,CAAC;IACJ,KAAK,CAAC,EAAE;QACN,aAAa,EAAE,MAAM,CAAC;QACtB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;KAC9B,EAAE,CAAC;CACL;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;;IAQvB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAItB,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAkBhD,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,cAAc,CAAC,WAAW,CAAC;IAiD9D,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;CAazC;AAED,eAAO,MAAM,MAAM,gBAAuB,CAAC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { loadSettings, getApiKey } from '../config/index.js';
|
|
2
|
+
export class AIRouterClient {
|
|
3
|
+
baseUrl;
|
|
4
|
+
apiKey;
|
|
5
|
+
constructor() {
|
|
6
|
+
const settings = loadSettings();
|
|
7
|
+
this.baseUrl = settings.apiUrl;
|
|
8
|
+
this.apiKey = getApiKey();
|
|
9
|
+
}
|
|
10
|
+
setApiKey(key) {
|
|
11
|
+
this.apiKey = key;
|
|
12
|
+
}
|
|
13
|
+
async chat(request) {
|
|
14
|
+
const response = await fetch(`${this.baseUrl}/v2/chat/completions`, {
|
|
15
|
+
method: 'POST',
|
|
16
|
+
headers: {
|
|
17
|
+
'Content-Type': 'application/json',
|
|
18
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
19
|
+
},
|
|
20
|
+
body: JSON.stringify(request),
|
|
21
|
+
});
|
|
22
|
+
if (!response.ok) {
|
|
23
|
+
const error = await response.text();
|
|
24
|
+
throw new Error(`API Error: ${response.status} - ${error}`);
|
|
25
|
+
}
|
|
26
|
+
return response.json();
|
|
27
|
+
}
|
|
28
|
+
async *chatStream(request) {
|
|
29
|
+
const response = await fetch(`${this.baseUrl}/v2/chat/completions`, {
|
|
30
|
+
method: 'POST',
|
|
31
|
+
headers: {
|
|
32
|
+
'Content-Type': 'application/json',
|
|
33
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
34
|
+
},
|
|
35
|
+
body: JSON.stringify({ ...request, stream: true }),
|
|
36
|
+
});
|
|
37
|
+
if (!response.ok) {
|
|
38
|
+
const error = await response.text();
|
|
39
|
+
throw new Error(`API Error: ${response.status} - ${error}`);
|
|
40
|
+
}
|
|
41
|
+
if (!response.body) {
|
|
42
|
+
throw new Error('No response body');
|
|
43
|
+
}
|
|
44
|
+
const reader = response.body.getReader();
|
|
45
|
+
const decoder = new TextDecoder();
|
|
46
|
+
let buffer = '';
|
|
47
|
+
while (true) {
|
|
48
|
+
const { done, value } = await reader.read();
|
|
49
|
+
if (done)
|
|
50
|
+
break;
|
|
51
|
+
buffer += decoder.decode(value, { stream: true });
|
|
52
|
+
const lines = buffer.split('\n');
|
|
53
|
+
buffer = lines.pop() || '';
|
|
54
|
+
for (const line of lines) {
|
|
55
|
+
const trimmed = line.trim();
|
|
56
|
+
if (!trimmed || trimmed === 'data: [DONE]')
|
|
57
|
+
continue;
|
|
58
|
+
if (trimmed.startsWith('data: ')) {
|
|
59
|
+
try {
|
|
60
|
+
const json = JSON.parse(trimmed.slice(6));
|
|
61
|
+
yield json;
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
// Skip invalid JSON
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
async testConnection() {
|
|
71
|
+
try {
|
|
72
|
+
const response = await fetch(`${this.baseUrl}/health`, {
|
|
73
|
+
method: 'GET',
|
|
74
|
+
headers: {
|
|
75
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
return response.ok;
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
export const client = new AIRouterClient();
|
|
86
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import { ChatRequest, Message, ToolCall } from './client.js';
|
|
3
|
+
export interface StreamEvent {
|
|
4
|
+
type: 'content' | 'tool_call' | 'done' | 'error';
|
|
5
|
+
content?: string;
|
|
6
|
+
toolCall?: ToolCall;
|
|
7
|
+
error?: Error;
|
|
8
|
+
}
|
|
9
|
+
export declare class StreamingHandler extends EventEmitter {
|
|
10
|
+
private abortController;
|
|
11
|
+
stream(request: ChatRequest): Promise<Message>;
|
|
12
|
+
abort(): void;
|
|
13
|
+
}
|
|
14
|
+
export declare const streamingHandler: StreamingHandler;
|
|
15
|
+
//# sourceMappingURL=streaming.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streaming.d.ts","sourceRoot":"","sources":["../../src/api/streaming.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAU,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAErE,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,SAAS,GAAG,WAAW,GAAG,MAAM,GAAG,OAAO,CAAC;IACjD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,qBAAa,gBAAiB,SAAQ,YAAY;IAChD,OAAO,CAAC,eAAe,CAAgC;IAEjD,MAAM,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IAqFpD,KAAK,IAAI,IAAI;CAKd;AAED,eAAO,MAAM,gBAAgB,kBAAyB,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import { client } from './client.js';
|
|
3
|
+
export class StreamingHandler extends EventEmitter {
|
|
4
|
+
abortController = null;
|
|
5
|
+
async stream(request) {
|
|
6
|
+
this.abortController = new AbortController();
|
|
7
|
+
let fullContent = '';
|
|
8
|
+
const toolCalls = [];
|
|
9
|
+
let currentToolCall = null;
|
|
10
|
+
try {
|
|
11
|
+
for await (const chunk of client.chatStream(request)) {
|
|
12
|
+
if (this.abortController.signal.aborted) {
|
|
13
|
+
break;
|
|
14
|
+
}
|
|
15
|
+
const choice = chunk.choices[0];
|
|
16
|
+
if (!choice)
|
|
17
|
+
continue;
|
|
18
|
+
const delta = choice.delta;
|
|
19
|
+
// Handle content
|
|
20
|
+
if (delta.content) {
|
|
21
|
+
fullContent += delta.content;
|
|
22
|
+
this.emit('content', delta.content);
|
|
23
|
+
}
|
|
24
|
+
// Handle tool calls
|
|
25
|
+
if (delta.tool_calls) {
|
|
26
|
+
for (const tc of delta.tool_calls) {
|
|
27
|
+
if (tc.id) {
|
|
28
|
+
// New tool call
|
|
29
|
+
if (currentToolCall && currentToolCall.id) {
|
|
30
|
+
toolCalls.push(currentToolCall);
|
|
31
|
+
}
|
|
32
|
+
currentToolCall = {
|
|
33
|
+
id: tc.id,
|
|
34
|
+
type: 'function',
|
|
35
|
+
function: {
|
|
36
|
+
name: tc.function?.name || '',
|
|
37
|
+
arguments: tc.function?.arguments || '',
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
else if (currentToolCall && tc.function) {
|
|
42
|
+
// Continue building current tool call
|
|
43
|
+
if (tc.function.name) {
|
|
44
|
+
currentToolCall.function.name += tc.function.name;
|
|
45
|
+
}
|
|
46
|
+
if (tc.function.arguments) {
|
|
47
|
+
currentToolCall.function.arguments += tc.function.arguments;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// Check for finish
|
|
53
|
+
if (choice.finish_reason === 'tool_calls') {
|
|
54
|
+
if (currentToolCall && currentToolCall.id) {
|
|
55
|
+
toolCalls.push(currentToolCall);
|
|
56
|
+
}
|
|
57
|
+
for (const tc of toolCalls) {
|
|
58
|
+
this.emit('tool_call', tc);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (choice.finish_reason) {
|
|
62
|
+
this.emit('finish', choice.finish_reason);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
this.emit('done');
|
|
66
|
+
const message = {
|
|
67
|
+
role: 'assistant',
|
|
68
|
+
content: fullContent,
|
|
69
|
+
};
|
|
70
|
+
if (toolCalls.length > 0) {
|
|
71
|
+
message.tool_calls = toolCalls;
|
|
72
|
+
}
|
|
73
|
+
return message;
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
this.emit('error', error);
|
|
77
|
+
throw error;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
abort() {
|
|
81
|
+
if (this.abortController) {
|
|
82
|
+
this.abortController.abort();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
export const streamingHandler = new StreamingHandler();
|
|
87
|
+
//# sourceMappingURL=streaming.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streaming.js","sourceRoot":"","sources":["../../src/api/streaming.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
export interface WSMessage {
|
|
3
|
+
type: string;
|
|
4
|
+
payload: unknown;
|
|
5
|
+
}
|
|
6
|
+
export declare class WebSocketClient extends EventEmitter {
|
|
7
|
+
private ws;
|
|
8
|
+
private reconnectAttempts;
|
|
9
|
+
private maxReconnectAttempts;
|
|
10
|
+
private reconnectDelay;
|
|
11
|
+
private isConnected;
|
|
12
|
+
constructor();
|
|
13
|
+
connect(): Promise<void>;
|
|
14
|
+
private attemptReconnect;
|
|
15
|
+
send(type: string, payload: unknown): void;
|
|
16
|
+
disconnect(): void;
|
|
17
|
+
getConnectionStatus(): boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare const wsClient: WebSocketClient;
|
|
20
|
+
//# sourceMappingURL=websocket.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../../src/api/websocket.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAGtC,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,qBAAa,eAAgB,SAAQ,YAAY;IAC/C,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,oBAAoB,CAAK;IACjC,OAAO,CAAC,cAAc,CAAQ;IAC9B,OAAO,CAAC,WAAW,CAAS;;IAM5B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAyCxB,OAAO,CAAC,gBAAgB;IAiBxB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;IAQ1C,UAAU,IAAI,IAAI;IAQlB,mBAAmB,IAAI,OAAO;CAG/B;AAED,eAAO,MAAM,QAAQ,iBAAwB,CAAC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import WebSocket from 'ws';
|
|
2
|
+
import { EventEmitter } from 'events';
|
|
3
|
+
import { loadSettings, getApiKey } from '../config/index.js';
|
|
4
|
+
export class WebSocketClient extends EventEmitter {
|
|
5
|
+
ws = null;
|
|
6
|
+
reconnectAttempts = 0;
|
|
7
|
+
maxReconnectAttempts = 5;
|
|
8
|
+
reconnectDelay = 1000;
|
|
9
|
+
isConnected = false;
|
|
10
|
+
constructor() {
|
|
11
|
+
super();
|
|
12
|
+
}
|
|
13
|
+
connect() {
|
|
14
|
+
return new Promise((resolve, reject) => {
|
|
15
|
+
const settings = loadSettings();
|
|
16
|
+
const apiKey = getApiKey();
|
|
17
|
+
const url = `${settings.wsUrl}?token=${apiKey}`;
|
|
18
|
+
this.ws = new WebSocket(url);
|
|
19
|
+
this.ws.on('open', () => {
|
|
20
|
+
this.isConnected = true;
|
|
21
|
+
this.reconnectAttempts = 0;
|
|
22
|
+
this.emit('connected');
|
|
23
|
+
resolve();
|
|
24
|
+
});
|
|
25
|
+
this.ws.on('message', (data) => {
|
|
26
|
+
try {
|
|
27
|
+
const message = JSON.parse(data.toString());
|
|
28
|
+
this.emit('message', message);
|
|
29
|
+
this.emit(message.type, message.payload);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
this.emit('raw', data.toString());
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
this.ws.on('close', () => {
|
|
36
|
+
this.isConnected = false;
|
|
37
|
+
this.emit('disconnected');
|
|
38
|
+
this.attemptReconnect();
|
|
39
|
+
});
|
|
40
|
+
this.ws.on('error', (error) => {
|
|
41
|
+
this.emit('error', error);
|
|
42
|
+
if (!this.isConnected) {
|
|
43
|
+
reject(error);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
attemptReconnect() {
|
|
49
|
+
if (this.reconnectAttempts >= this.maxReconnectAttempts) {
|
|
50
|
+
this.emit('reconnect_failed');
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
this.reconnectAttempts++;
|
|
54
|
+
const delay = this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1);
|
|
55
|
+
setTimeout(() => {
|
|
56
|
+
this.emit('reconnecting', this.reconnectAttempts);
|
|
57
|
+
this.connect().catch(() => {
|
|
58
|
+
// Reconnect failed, will try again
|
|
59
|
+
});
|
|
60
|
+
}, delay);
|
|
61
|
+
}
|
|
62
|
+
send(type, payload) {
|
|
63
|
+
if (!this.ws || !this.isConnected) {
|
|
64
|
+
throw new Error('WebSocket not connected');
|
|
65
|
+
}
|
|
66
|
+
this.ws.send(JSON.stringify({ type, payload }));
|
|
67
|
+
}
|
|
68
|
+
disconnect() {
|
|
69
|
+
if (this.ws) {
|
|
70
|
+
this.ws.close();
|
|
71
|
+
this.ws = null;
|
|
72
|
+
}
|
|
73
|
+
this.isConnected = false;
|
|
74
|
+
}
|
|
75
|
+
getConnectionStatus() {
|
|
76
|
+
return this.isConnected;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
export const wsClient = new WebSocketClient();
|
|
80
|
+
//# sourceMappingURL=websocket.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket.js","sourceRoot":"","sources":["../../src/api/websocket.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface CLIOptions {
|
|
2
|
+
model?: string;
|
|
3
|
+
apiKey?: string;
|
|
4
|
+
autoAccept?: boolean;
|
|
5
|
+
version?: boolean;
|
|
6
|
+
help?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface CLIResult {
|
|
9
|
+
prompt?: string;
|
|
10
|
+
options: CLIOptions;
|
|
11
|
+
command?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function parseArgs(args?: string[]): CLIResult;
|
|
14
|
+
export declare function printHelp(): void;
|
|
15
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,UAAU,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,SAAS,CAAC,IAAI,GAAE,MAAM,EAAiB,GAAG,SAAS,CA8ClE;AAED,wBAAgB,SAAS,IAAI,IAAI,CA8BhC"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { saveSettings } from './config/index.js';
|
|
3
|
+
export function parseArgs(args = process.argv) {
|
|
4
|
+
const program = new Command();
|
|
5
|
+
program
|
|
6
|
+
.name('ai')
|
|
7
|
+
.description('AI Router CLI - Claude Code style AI assistant')
|
|
8
|
+
.version('1.0.0')
|
|
9
|
+
.option('-m, --model <model>', 'Model to use (e.g., songluan, gpt-4)')
|
|
10
|
+
.option('-k, --api-key <key>', 'API key for AIRouter')
|
|
11
|
+
.option('-y, --yes', 'Auto-accept all tool executions')
|
|
12
|
+
.option('--no-stream', 'Disable streaming output')
|
|
13
|
+
.argument('[prompt...]', 'Initial prompt to send')
|
|
14
|
+
.allowUnknownOption(false);
|
|
15
|
+
program.parse(args);
|
|
16
|
+
const opts = program.opts();
|
|
17
|
+
const positionalArgs = program.args;
|
|
18
|
+
// Build options
|
|
19
|
+
const options = {
|
|
20
|
+
model: opts.model,
|
|
21
|
+
apiKey: opts.apiKey,
|
|
22
|
+
autoAccept: opts.yes,
|
|
23
|
+
};
|
|
24
|
+
// Apply options to settings
|
|
25
|
+
if (options.model) {
|
|
26
|
+
saveSettings({ model: options.model });
|
|
27
|
+
}
|
|
28
|
+
if (options.apiKey) {
|
|
29
|
+
saveSettings({ apiKey: options.apiKey });
|
|
30
|
+
}
|
|
31
|
+
if (options.autoAccept !== undefined) {
|
|
32
|
+
saveSettings({ autoAccept: options.autoAccept });
|
|
33
|
+
}
|
|
34
|
+
// Build result
|
|
35
|
+
const result = {
|
|
36
|
+
options,
|
|
37
|
+
prompt: positionalArgs.length > 0 ? positionalArgs.join(' ') : undefined,
|
|
38
|
+
};
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
export function printHelp() {
|
|
42
|
+
console.log(`
|
|
43
|
+
AI Router CLI - Claude Code style AI assistant
|
|
44
|
+
|
|
45
|
+
Usage:
|
|
46
|
+
ai [options] [prompt]
|
|
47
|
+
ai-router [options] [prompt]
|
|
48
|
+
|
|
49
|
+
Options:
|
|
50
|
+
-m, --model <model> Model to use (default: songluan)
|
|
51
|
+
-k, --api-key <key> API key for AIRouter
|
|
52
|
+
-y, --yes Auto-accept all tool executions
|
|
53
|
+
-V, --version Output version number
|
|
54
|
+
-h, --help Display help
|
|
55
|
+
|
|
56
|
+
Examples:
|
|
57
|
+
ai "Hello, who are you?"
|
|
58
|
+
ai -m gpt-4 "Explain this code"
|
|
59
|
+
ai -y "List files in current directory"
|
|
60
|
+
ai # Start interactive mode
|
|
61
|
+
|
|
62
|
+
Interactive Commands:
|
|
63
|
+
/help Show available commands
|
|
64
|
+
/model Show or change model
|
|
65
|
+
/config Show or edit configuration
|
|
66
|
+
/clear Clear conversation
|
|
67
|
+
/quit Exit the CLI
|
|
68
|
+
|
|
69
|
+
For more information, visit: https://github.com/locdotech/ai-router-cli
|
|
70
|
+
`);
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAgB,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAgB/D,MAAM,UAAU,SAAS,CAAC,OAAiB,OAAO,CAAC,IAAI;IACrD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,IAAI,CAAC;SACV,WAAW,CAAC,gDAAgD,CAAC;SAC7D,OAAO,CAAC,OAAO,CAAC;SAChB,MAAM,CAAC,qBAAqB,EAAE,sCAAsC,CAAC;SACrE,MAAM,CAAC,qBAAqB,EAAE,sBAAsB,CAAC;SACrD,MAAM,CAAC,WAAW,EAAE,iCAAiC,CAAC;SACtD,MAAM,CAAC,aAAa,EAAE,0BAA0B,CAAC;SACjD,QAAQ,CAAC,aAAa,EAAE,wBAAwB,CAAC;SACjD,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAE7B,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAEpB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAC5B,MAAM,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAEpC,gBAAgB;IAChB,MAAM,OAAO,GAAe;QAC1B,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,UAAU,EAAE,IAAI,CAAC,GAAG;KACrB,CAAC;IAEF,4BAA4B;IAC5B,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,YAAY,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,YAAY,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACrC,YAAY,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,eAAe;IACf,MAAM,MAAM,GAAc;QACxB,OAAO;QACP,MAAM,EAAE,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS;KACzE,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,SAAS;IACvB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4Bb,CAAC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clear.d.ts","sourceRoot":"","sources":["../../src/commands/clear.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAkB,MAAM,YAAY,CAAC;AAErD,eAAO,MAAM,YAAY,EAAE,OAY1B,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const clearCommand = {
|
|
2
|
+
name: 'clear',
|
|
3
|
+
description: 'Clear conversation history',
|
|
4
|
+
aliases: ['c'],
|
|
5
|
+
async execute(context) {
|
|
6
|
+
if (context.clearMessages) {
|
|
7
|
+
context.clearMessages();
|
|
8
|
+
}
|
|
9
|
+
console.clear();
|
|
10
|
+
return 'Conversation cleared.';
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=clear.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clear.js","sourceRoot":"","sources":["../../src/commands/clear.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,YAAY,GAAY;IACnC,IAAI,EAAE,OAAO;IACb,WAAW,EAAE,4BAA4B;IACzC,OAAO,EAAE,CAAC,GAAG,CAAC;IAEd,KAAK,CAAC,OAAO,CAAC,OAAuB;QACnC,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;YAC1B,OAAO,CAAC,aAAa,EAAE,CAAC;QAC1B,CAAC;QACD,OAAO,CAAC,KAAK,EAAE,CAAC;QAChB,OAAO,uBAAuB,CAAC;IACjC,CAAC;CACF,CAAC"}
|