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.
Files changed (167) hide show
  1. package/README.md +104 -0
  2. package/bin/ai.js +16 -0
  3. package/dist/api/client.d.ts +75 -0
  4. package/dist/api/client.d.ts.map +1 -0
  5. package/dist/api/client.js +86 -0
  6. package/dist/api/client.js.map +1 -0
  7. package/dist/api/index.d.ts +4 -0
  8. package/dist/api/index.d.ts.map +1 -0
  9. package/dist/api/index.js +4 -0
  10. package/dist/api/index.js.map +1 -0
  11. package/dist/api/streaming.d.ts +15 -0
  12. package/dist/api/streaming.d.ts.map +1 -0
  13. package/dist/api/streaming.js +87 -0
  14. package/dist/api/streaming.js.map +1 -0
  15. package/dist/api/websocket.d.ts +20 -0
  16. package/dist/api/websocket.d.ts.map +1 -0
  17. package/dist/api/websocket.js +80 -0
  18. package/dist/api/websocket.js.map +1 -0
  19. package/dist/cli.d.ts +15 -0
  20. package/dist/cli.d.ts.map +1 -0
  21. package/dist/cli.js +72 -0
  22. package/dist/cli.js.map +1 -0
  23. package/dist/commands/clear.d.ts +3 -0
  24. package/dist/commands/clear.d.ts.map +1 -0
  25. package/dist/commands/clear.js +13 -0
  26. package/dist/commands/clear.js.map +1 -0
  27. package/dist/commands/config.d.ts +3 -0
  28. package/dist/commands/config.d.ts.map +1 -0
  29. package/dist/commands/config.js +116 -0
  30. package/dist/commands/config.js.map +1 -0
  31. package/dist/commands/help.d.ts +3 -0
  32. package/dist/commands/help.d.ts.map +1 -0
  33. package/dist/commands/help.js +42 -0
  34. package/dist/commands/help.js.map +1 -0
  35. package/dist/commands/history.d.ts +3 -0
  36. package/dist/commands/history.d.ts.map +1 -0
  37. package/dist/commands/history.js +62 -0
  38. package/dist/commands/history.js.map +1 -0
  39. package/dist/commands/index.d.ts +30 -0
  40. package/dist/commands/index.d.ts.map +1 -0
  41. package/dist/commands/index.js +54 -0
  42. package/dist/commands/index.js.map +1 -0
  43. package/dist/commands/model.d.ts +3 -0
  44. package/dist/commands/model.d.ts.map +1 -0
  45. package/dist/commands/model.js +57 -0
  46. package/dist/commands/model.js.map +1 -0
  47. package/dist/commands/quit.d.ts +3 -0
  48. package/dist/commands/quit.d.ts.map +1 -0
  49. package/dist/commands/quit.js +16 -0
  50. package/dist/commands/quit.js.map +1 -0
  51. package/dist/commands/status.d.ts +3 -0
  52. package/dist/commands/status.d.ts.map +1 -0
  53. package/dist/commands/status.js +39 -0
  54. package/dist/commands/status.js.map +1 -0
  55. package/dist/config/index.d.ts +2 -0
  56. package/dist/config/index.d.ts.map +1 -0
  57. package/dist/config/index.js +2 -0
  58. package/dist/config/index.js.map +1 -0
  59. package/dist/config/settings.d.ts +18 -0
  60. package/dist/config/settings.d.ts.map +1 -0
  61. package/dist/config/settings.js +56 -0
  62. package/dist/config/settings.js.map +1 -0
  63. package/dist/index.d.ts +3 -0
  64. package/dist/index.d.ts.map +1 -0
  65. package/dist/index.js +100 -0
  66. package/dist/index.js.map +1 -0
  67. package/dist/tools/bash.d.ts +41 -0
  68. package/dist/tools/bash.d.ts.map +1 -0
  69. package/dist/tools/bash.js +100 -0
  70. package/dist/tools/bash.js.map +1 -0
  71. package/dist/tools/file.d.ts +107 -0
  72. package/dist/tools/file.d.ts.map +1 -0
  73. package/dist/tools/file.js +189 -0
  74. package/dist/tools/file.js.map +1 -0
  75. package/dist/tools/glob.d.ts +38 -0
  76. package/dist/tools/glob.d.ts.map +1 -0
  77. package/dist/tools/glob.js +84 -0
  78. package/dist/tools/glob.js.map +1 -0
  79. package/dist/tools/grep.d.ts +76 -0
  80. package/dist/tools/grep.d.ts.map +1 -0
  81. package/dist/tools/grep.js +166 -0
  82. package/dist/tools/grep.js.map +1 -0
  83. package/dist/tools/index.d.ts +29 -0
  84. package/dist/tools/index.d.ts.map +1 -0
  85. package/dist/tools/index.js +130 -0
  86. package/dist/tools/index.js.map +1 -0
  87. package/dist/tools/mcp.d.ts +59 -0
  88. package/dist/tools/mcp.d.ts.map +1 -0
  89. package/dist/tools/mcp.js +155 -0
  90. package/dist/tools/mcp.js.map +1 -0
  91. package/dist/ui/App.d.ts +6 -0
  92. package/dist/ui/App.d.ts.map +1 -0
  93. package/dist/ui/App.js +161 -0
  94. package/dist/ui/App.js.map +1 -0
  95. package/dist/ui/components/CodeBlock.d.ts +9 -0
  96. package/dist/ui/components/CodeBlock.d.ts.map +1 -0
  97. package/dist/ui/components/CodeBlock.js +83 -0
  98. package/dist/ui/components/CodeBlock.js.map +1 -0
  99. package/dist/ui/components/Input.d.ts +11 -0
  100. package/dist/ui/components/Input.d.ts.map +1 -0
  101. package/dist/ui/components/Input.js +93 -0
  102. package/dist/ui/components/Input.js.map +1 -0
  103. package/dist/ui/components/Message.d.ts +7 -0
  104. package/dist/ui/components/Message.d.ts.map +1 -0
  105. package/dist/ui/components/Message.js +86 -0
  106. package/dist/ui/components/Message.js.map +1 -0
  107. package/dist/ui/components/ModelSelector.d.ts +7 -0
  108. package/dist/ui/components/ModelSelector.d.ts.map +1 -0
  109. package/dist/ui/components/ModelSelector.js +23 -0
  110. package/dist/ui/components/ModelSelector.js.map +1 -0
  111. package/dist/ui/components/Permission.d.ts +9 -0
  112. package/dist/ui/components/Permission.d.ts.map +1 -0
  113. package/dist/ui/components/Permission.js +41 -0
  114. package/dist/ui/components/Permission.js.map +1 -0
  115. package/dist/ui/components/StatusBar.d.ts +11 -0
  116. package/dist/ui/components/StatusBar.d.ts.map +1 -0
  117. package/dist/ui/components/StatusBar.js +9 -0
  118. package/dist/ui/components/StatusBar.js.map +1 -0
  119. package/dist/ui/components/TaskList.d.ts +12 -0
  120. package/dist/ui/components/TaskList.d.ts.map +1 -0
  121. package/dist/ui/components/TaskList.js +21 -0
  122. package/dist/ui/components/TaskList.js.map +1 -0
  123. package/dist/ui/components/ToolCall.d.ts +16 -0
  124. package/dist/ui/components/ToolCall.d.ts.map +1 -0
  125. package/dist/ui/components/ToolCall.js +50 -0
  126. package/dist/ui/components/ToolCall.js.map +1 -0
  127. package/dist/ui/components/index.d.ts +8 -0
  128. package/dist/ui/components/index.d.ts.map +1 -0
  129. package/dist/ui/components/index.js +8 -0
  130. package/dist/ui/components/index.js.map +1 -0
  131. package/dist/ui/hooks/index.d.ts +4 -0
  132. package/dist/ui/hooks/index.d.ts.map +1 -0
  133. package/dist/ui/hooks/index.js +4 -0
  134. package/dist/ui/hooks/index.js.map +1 -0
  135. package/dist/ui/hooks/useChat.d.ts +42 -0
  136. package/dist/ui/hooks/useChat.d.ts.map +1 -0
  137. package/dist/ui/hooks/useChat.js +305 -0
  138. package/dist/ui/hooks/useChat.js.map +1 -0
  139. package/dist/ui/hooks/useHistory.d.ts +14 -0
  140. package/dist/ui/hooks/useHistory.d.ts.map +1 -0
  141. package/dist/ui/hooks/useHistory.js +123 -0
  142. package/dist/ui/hooks/useHistory.js.map +1 -0
  143. package/dist/ui/hooks/useTools.d.ts +19 -0
  144. package/dist/ui/hooks/useTools.d.ts.map +1 -0
  145. package/dist/ui/hooks/useTools.js +54 -0
  146. package/dist/ui/hooks/useTools.js.map +1 -0
  147. package/dist/ui/themes/index.d.ts +21 -0
  148. package/dist/ui/themes/index.d.ts.map +1 -0
  149. package/dist/ui/themes/index.js +40 -0
  150. package/dist/ui/themes/index.js.map +1 -0
  151. package/dist/utils/auth.d.ts +5 -0
  152. package/dist/utils/auth.d.ts.map +1 -0
  153. package/dist/utils/auth.js +42 -0
  154. package/dist/utils/auth.js.map +1 -0
  155. package/dist/utils/format.d.ts +11 -0
  156. package/dist/utils/format.d.ts.map +1 -0
  157. package/dist/utils/format.js +71 -0
  158. package/dist/utils/format.js.map +1 -0
  159. package/dist/utils/index.d.ts +4 -0
  160. package/dist/utils/index.d.ts.map +1 -0
  161. package/dist/utils/index.js +4 -0
  162. package/dist/utils/index.js.map +1 -0
  163. package/dist/utils/logger.d.ts +18 -0
  164. package/dist/utils/logger.d.ts.map +1 -0
  165. package/dist/utils/logger.js +61 -0
  166. package/dist/utils/logger.js.map +1 -0
  167. 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,4 @@
1
+ export * from './client.js';
2
+ export * from './websocket.js';
3
+ export * from './streaming.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -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,4 @@
1
+ export * from './client.js';
2
+ export * from './websocket.js';
3
+ export * from './streaming.js';
4
+ //# sourceMappingURL=index.js.map
@@ -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
@@ -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,3 @@
1
+ import { Command } from './index.js';
2
+ export declare const clearCommand: Command;
3
+ //# sourceMappingURL=clear.d.ts.map
@@ -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"}