@ddlqhd/agent-sdk 0.1.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 +53 -0
- package/dist/chunk-5QMA2YBY.cjs +2880 -0
- package/dist/chunk-5QMA2YBY.cjs.map +1 -0
- package/dist/chunk-5Y56A64C.cjs +5 -0
- package/dist/chunk-5Y56A64C.cjs.map +1 -0
- package/dist/chunk-A3S3AGE3.js +3 -0
- package/dist/chunk-A3S3AGE3.js.map +1 -0
- package/dist/chunk-CNSGZVRN.cjs +152 -0
- package/dist/chunk-CNSGZVRN.cjs.map +1 -0
- package/dist/chunk-JF5AJQMU.cjs +2788 -0
- package/dist/chunk-JF5AJQMU.cjs.map +1 -0
- package/dist/chunk-NDSL7NPN.js +807 -0
- package/dist/chunk-NDSL7NPN.js.map +1 -0
- package/dist/chunk-OHXW2YM6.js +2708 -0
- package/dist/chunk-OHXW2YM6.js.map +1 -0
- package/dist/chunk-Q3SOMX26.js +2854 -0
- package/dist/chunk-Q3SOMX26.js.map +1 -0
- package/dist/chunk-WH3APNQ5.js +147 -0
- package/dist/chunk-WH3APNQ5.js.map +1 -0
- package/dist/chunk-X35MHWXE.cjs +817 -0
- package/dist/chunk-X35MHWXE.cjs.map +1 -0
- package/dist/cli/index.cjs +926 -0
- package/dist/cli/index.cjs.map +1 -0
- package/dist/cli/index.d.cts +24 -0
- package/dist/cli/index.d.ts +24 -0
- package/dist/cli/index.js +916 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/index-DPsZ1zat.d.ts +447 -0
- package/dist/index-RTPmFjMp.d.cts +447 -0
- package/dist/index.cjs +508 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +664 -0
- package/dist/index.d.ts +664 -0
- package/dist/index.js +204 -0
- package/dist/index.js.map +1 -0
- package/dist/models/index.cjs +62 -0
- package/dist/models/index.cjs.map +1 -0
- package/dist/models/index.d.cts +165 -0
- package/dist/models/index.d.ts +165 -0
- package/dist/models/index.js +5 -0
- package/dist/models/index.js.map +1 -0
- package/dist/tools/index.cjs +207 -0
- package/dist/tools/index.cjs.map +1 -0
- package/dist/tools/index.d.cts +108 -0
- package/dist/tools/index.d.ts +108 -0
- package/dist/tools/index.js +6 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/types-C0aX_Qdp.d.cts +917 -0
- package/dist/types-C0aX_Qdp.d.ts +917 -0
- package/package.json +80 -0
|
@@ -0,0 +1,926 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var chunk5QMA2YBY_cjs = require('../chunk-5QMA2YBY.cjs');
|
|
5
|
+
var chunkX35MHWXE_cjs = require('../chunk-X35MHWXE.cjs');
|
|
6
|
+
var chunkJF5AJQMU_cjs = require('../chunk-JF5AJQMU.cjs');
|
|
7
|
+
require('../chunk-CNSGZVRN.cjs');
|
|
8
|
+
var commander = require('commander');
|
|
9
|
+
var chalk = require('chalk');
|
|
10
|
+
var promises = require('readline/promises');
|
|
11
|
+
|
|
12
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
13
|
+
|
|
14
|
+
var chalk__default = /*#__PURE__*/_interopDefault(chalk);
|
|
15
|
+
|
|
16
|
+
function tokenUsageEqual(a, b) {
|
|
17
|
+
return a.promptTokens === b.promptTokens && a.completionTokens === b.completionTokens && a.totalTokens === b.totalTokens;
|
|
18
|
+
}
|
|
19
|
+
function toolCallIdTag(id) {
|
|
20
|
+
return `[${id}]`;
|
|
21
|
+
}
|
|
22
|
+
function formatStreamToolCallLine(verbose, toolCallId, name, args) {
|
|
23
|
+
const idPart = chalk__default.default.gray(` ${toolCallIdTag(toolCallId)}`);
|
|
24
|
+
if (verbose) {
|
|
25
|
+
const argsStr2 = args != null ? ` ${JSON.stringify(args, null, 2)}` : "";
|
|
26
|
+
return chalk__default.default.yellow(`
|
|
27
|
+
\u{1F527} ${name}`) + idPart + chalk__default.default.gray(argsStr2);
|
|
28
|
+
}
|
|
29
|
+
const argsStr = args != null ? `(${truncate(JSON.stringify(args), 80)})` : "()";
|
|
30
|
+
return chalk__default.default.yellow(`
|
|
31
|
+
\u{1F527} ${name}`) + idPart + chalk__default.default.gray(argsStr);
|
|
32
|
+
}
|
|
33
|
+
function createStreamFormatter(config = {}) {
|
|
34
|
+
const { verbose = false } = config;
|
|
35
|
+
let lastEventType = null;
|
|
36
|
+
let isFirstThinking = true;
|
|
37
|
+
let lastPrintedUsage = null;
|
|
38
|
+
let needsGapAfterToolBlock = false;
|
|
39
|
+
return {
|
|
40
|
+
format(event) {
|
|
41
|
+
let output = "";
|
|
42
|
+
if (lastEventType === "thinking" && event.type !== "thinking") {
|
|
43
|
+
output += "\n";
|
|
44
|
+
isFirstThinking = true;
|
|
45
|
+
}
|
|
46
|
+
if (needsGapAfterToolBlock && (event.type === "text_delta" || event.type === "thinking")) {
|
|
47
|
+
output += "\n";
|
|
48
|
+
needsGapAfterToolBlock = false;
|
|
49
|
+
}
|
|
50
|
+
switch (event.type) {
|
|
51
|
+
case "text_start":
|
|
52
|
+
case "text_end":
|
|
53
|
+
case "tool_call_start":
|
|
54
|
+
case "tool_call_delta":
|
|
55
|
+
case "tool_call_end":
|
|
56
|
+
break;
|
|
57
|
+
case "context_compressed":
|
|
58
|
+
if (verbose) {
|
|
59
|
+
output += chalk__default.default.gray(
|
|
60
|
+
`
|
|
61
|
+
\u{1F4E6} Context compressed: ${event.stats.originalMessageCount} \u2192 ${event.stats.compressedMessageCount} messages (${event.stats.durationMs}ms)
|
|
62
|
+
`
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
break;
|
|
66
|
+
case "text_delta":
|
|
67
|
+
output += event.content;
|
|
68
|
+
break;
|
|
69
|
+
case "thinking":
|
|
70
|
+
if (isFirstThinking) {
|
|
71
|
+
output += `
|
|
72
|
+
${chalk__default.default.gray(`\u{1F4AD} ${event.content}`)}`;
|
|
73
|
+
isFirstThinking = false;
|
|
74
|
+
} else {
|
|
75
|
+
output += chalk__default.default.gray(event.content);
|
|
76
|
+
}
|
|
77
|
+
break;
|
|
78
|
+
case "tool_call":
|
|
79
|
+
output += formatStreamToolCallLine(verbose, event.id, event.name, event.arguments);
|
|
80
|
+
break;
|
|
81
|
+
case "tool_result": {
|
|
82
|
+
const idTag = toolCallIdTag(event.toolCallId);
|
|
83
|
+
if (verbose) {
|
|
84
|
+
output += chalk__default.default.green("\n\u2713 ") + chalk__default.default.gray(`${idTag} `) + chalk__default.default.green(`Result:
|
|
85
|
+
${event.result}
|
|
86
|
+
`);
|
|
87
|
+
} else {
|
|
88
|
+
const resultStr = truncate(event.result, 120);
|
|
89
|
+
output += chalk__default.default.green("\n\u2713 ") + chalk__default.default.gray(`${idTag} `) + chalk__default.default.green(resultStr);
|
|
90
|
+
}
|
|
91
|
+
needsGapAfterToolBlock = true;
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
case "tool_error": {
|
|
95
|
+
const idTag = toolCallIdTag(event.toolCallId);
|
|
96
|
+
if (verbose) {
|
|
97
|
+
output += chalk__default.default.red("\n\u2717 ") + chalk__default.default.gray(`${idTag} `) + chalk__default.default.red(`Error:
|
|
98
|
+
${event.error.message}
|
|
99
|
+
`);
|
|
100
|
+
} else {
|
|
101
|
+
output += chalk__default.default.red("\n\u2717 ") + chalk__default.default.gray(`${idTag} `) + chalk__default.default.red(event.error.message);
|
|
102
|
+
}
|
|
103
|
+
needsGapAfterToolBlock = true;
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
case "model_usage": {
|
|
107
|
+
const usage = event.usage;
|
|
108
|
+
if (!lastPrintedUsage || !tokenUsageEqual(lastPrintedUsage, usage)) {
|
|
109
|
+
lastPrintedUsage = usage;
|
|
110
|
+
output += `
|
|
111
|
+
${formatUsage(usage)}`;
|
|
112
|
+
}
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
case "session_summary": {
|
|
116
|
+
const usage = event.usage;
|
|
117
|
+
if (!lastPrintedUsage || !tokenUsageEqual(lastPrintedUsage, usage)) {
|
|
118
|
+
lastPrintedUsage = usage;
|
|
119
|
+
output += `
|
|
120
|
+
${formatUsage(usage)}`;
|
|
121
|
+
}
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
case "end":
|
|
125
|
+
if (event.reason === "error" && event.error) {
|
|
126
|
+
output += chalk__default.default.red(`
|
|
127
|
+
\u2717 ${event.error.message}`);
|
|
128
|
+
} else if (event.reason === "aborted") {
|
|
129
|
+
output += chalk__default.default.yellow("\n[interrupted]");
|
|
130
|
+
}
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
lastEventType = event.type;
|
|
134
|
+
return output;
|
|
135
|
+
},
|
|
136
|
+
finalize() {
|
|
137
|
+
return lastEventType === "thinking" ? "\n" : "";
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
function formatUsage(usage, config = {}) {
|
|
142
|
+
const { color = true } = config;
|
|
143
|
+
const text = `\u{1F4CA} Tokens: ${usage.promptTokens} in, ${usage.completionTokens} out (${usage.totalTokens} total)`;
|
|
144
|
+
return color ? chalk__default.default.gray(text) : text;
|
|
145
|
+
}
|
|
146
|
+
function formatSessionUsage(usage, config = {}) {
|
|
147
|
+
const { color = true } = config;
|
|
148
|
+
let text = `\u{1F4CA} Input: ${usage.inputTokens} | Output: ${usage.outputTokens} | Total: ${usage.totalTokens}`;
|
|
149
|
+
if (usage.cacheReadTokens > 0 || usage.cacheWriteTokens > 0) {
|
|
150
|
+
text += ` | Cache: ${usage.cacheReadTokens}r/${usage.cacheWriteTokens}w`;
|
|
151
|
+
}
|
|
152
|
+
return color ? chalk__default.default.gray(text) : text;
|
|
153
|
+
}
|
|
154
|
+
function formatTable(data, columns) {
|
|
155
|
+
if (data.length === 0) {
|
|
156
|
+
return "No data";
|
|
157
|
+
}
|
|
158
|
+
const widths = columns.map((col) => {
|
|
159
|
+
const headerLen = col.header.length;
|
|
160
|
+
const maxDataLen = Math.max(
|
|
161
|
+
...data.map((row) => String(row[col.key] || "").length),
|
|
162
|
+
0
|
|
163
|
+
);
|
|
164
|
+
const minW = col.width ?? 0;
|
|
165
|
+
return Math.max(minW, headerLen, maxDataLen, 10);
|
|
166
|
+
});
|
|
167
|
+
const header = columns.map((col, i) => col.header.padEnd(widths[i])).join(" \u2502 ");
|
|
168
|
+
const separator = widths.map((w) => "\u2500".repeat(w)).join("\u2500\u253C\u2500");
|
|
169
|
+
const rows = data.map(
|
|
170
|
+
(row) => columns.map((col, i) => String(row[col.key] || "").padEnd(widths[i])).join(" \u2502 ")
|
|
171
|
+
);
|
|
172
|
+
return [header, separator, ...rows].join("\n");
|
|
173
|
+
}
|
|
174
|
+
function truncate(str, maxLen) {
|
|
175
|
+
if (str.length <= maxLen) return str;
|
|
176
|
+
return str.slice(0, maxLen - 3) + "...";
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// src/cli/utils/keypress.ts
|
|
180
|
+
var isActive = false;
|
|
181
|
+
var currentHandler = null;
|
|
182
|
+
var paused = false;
|
|
183
|
+
var onKeypress = (chunk) => {
|
|
184
|
+
if (!isActive || !currentHandler) return;
|
|
185
|
+
const key = typeof chunk === "string" ? chunk : chunk.toString("utf8");
|
|
186
|
+
if (key === "\x1B" || key.charCodeAt(0) === 27) {
|
|
187
|
+
currentHandler.onAbort();
|
|
188
|
+
}
|
|
189
|
+
if (key === "") {
|
|
190
|
+
currentHandler.onExit?.() || process.exit(130);
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
function initKeypressListener() {
|
|
194
|
+
if (!process.stdin.isTTY) {
|
|
195
|
+
return () => {
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
if (isActive) {
|
|
199
|
+
return () => {
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
isActive = true;
|
|
203
|
+
process.stdin.setRawMode(true);
|
|
204
|
+
process.stdin.resume();
|
|
205
|
+
process.stdin.on("data", onKeypress);
|
|
206
|
+
return () => {
|
|
207
|
+
if (!isActive) return;
|
|
208
|
+
isActive = false;
|
|
209
|
+
currentHandler = null;
|
|
210
|
+
paused = false;
|
|
211
|
+
process.stdin.off("data", onKeypress);
|
|
212
|
+
try {
|
|
213
|
+
process.stdin.setRawMode(false);
|
|
214
|
+
} catch {
|
|
215
|
+
}
|
|
216
|
+
if (process.stdin.isPaused()) {
|
|
217
|
+
process.stdin.resume();
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
function setKeypressHandler(handler) {
|
|
222
|
+
currentHandler = handler;
|
|
223
|
+
}
|
|
224
|
+
function clearKeypressHandler() {
|
|
225
|
+
currentHandler = null;
|
|
226
|
+
}
|
|
227
|
+
function pauseKeypressListener() {
|
|
228
|
+
if (!process.stdin.isTTY || !isActive || paused) {
|
|
229
|
+
return () => {
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
paused = true;
|
|
233
|
+
process.stdin.off("data", onKeypress);
|
|
234
|
+
try {
|
|
235
|
+
process.stdin.setRawMode(false);
|
|
236
|
+
} catch {
|
|
237
|
+
}
|
|
238
|
+
if (process.stdin.isPaused()) {
|
|
239
|
+
process.stdin.resume();
|
|
240
|
+
}
|
|
241
|
+
return () => {
|
|
242
|
+
if (!paused) return;
|
|
243
|
+
paused = false;
|
|
244
|
+
if (!process.stdin.isTTY || !isActive) return;
|
|
245
|
+
try {
|
|
246
|
+
process.stdin.setRawMode(true);
|
|
247
|
+
} catch {
|
|
248
|
+
}
|
|
249
|
+
process.stdin.on("data", onKeypress);
|
|
250
|
+
if (process.stdin.isPaused()) {
|
|
251
|
+
process.stdin.resume();
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
var MAX_PROMPT_RETRIES = 10;
|
|
256
|
+
function parseSingleLine(line, optionCount) {
|
|
257
|
+
const t = line.trim().toLowerCase();
|
|
258
|
+
if (t === "0" || t === "o") {
|
|
259
|
+
return { kind: "other" };
|
|
260
|
+
}
|
|
261
|
+
const n = parseInt(t, 10);
|
|
262
|
+
if (!Number.isFinite(n) || n < 1 || n > optionCount) {
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
return { kind: "indices", indices: [n - 1] };
|
|
266
|
+
}
|
|
267
|
+
function parseMultiLine(line, optionCount) {
|
|
268
|
+
const t = line.trim().toLowerCase();
|
|
269
|
+
if (t === "0" || t === "o") {
|
|
270
|
+
return { kind: "other" };
|
|
271
|
+
}
|
|
272
|
+
const parts = t.split(/[\s,]+/).filter(Boolean);
|
|
273
|
+
if (parts.length === 0) {
|
|
274
|
+
return null;
|
|
275
|
+
}
|
|
276
|
+
const indices = /* @__PURE__ */ new Set();
|
|
277
|
+
for (const p of parts) {
|
|
278
|
+
const n = parseInt(p, 10);
|
|
279
|
+
if (!Number.isFinite(n) || n < 1 || n > optionCount) {
|
|
280
|
+
return null;
|
|
281
|
+
}
|
|
282
|
+
indices.add(n - 1);
|
|
283
|
+
}
|
|
284
|
+
if (indices.size === 0) {
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
return { kind: "indices", indices: [...indices] };
|
|
288
|
+
}
|
|
289
|
+
async function runInteractiveAskUserQuestion(questions, readLine) {
|
|
290
|
+
const answers = [];
|
|
291
|
+
for (let qi = 0; qi < questions.length; qi++) {
|
|
292
|
+
const q = questions[qi];
|
|
293
|
+
const n = q.options.length;
|
|
294
|
+
let attempt = 0;
|
|
295
|
+
let resolved = null;
|
|
296
|
+
const block = [
|
|
297
|
+
`[${q.header}] ${q.question}`,
|
|
298
|
+
...q.options.map((opt, i) => ` ${i + 1}. ${opt.label} \u2014 ${opt.description}`),
|
|
299
|
+
" 0. Other \u2014 custom answer when chosen",
|
|
300
|
+
"",
|
|
301
|
+
q.multiSelect ? "Enter one or more numbers (1-" + n + ") separated by comma or space, or 0/o for Other:" : "Enter a number 1-" + n + ", or 0/o for Other:"
|
|
302
|
+
].join("\n");
|
|
303
|
+
while (attempt < MAX_PROMPT_RETRIES && !resolved) {
|
|
304
|
+
attempt++;
|
|
305
|
+
process.stdout.write(block + "\n");
|
|
306
|
+
const line = await readLine("> ");
|
|
307
|
+
const parsed = q.multiSelect ? parseMultiLine(line, n) : parseSingleLine(line, n);
|
|
308
|
+
if (!parsed) {
|
|
309
|
+
process.stdout.write(
|
|
310
|
+
`Invalid input. ${q.multiSelect ? "Use numbers 1-" + n + " (comma/space separated)" : "Enter 1-" + n}, or 0/o for Other.
|
|
311
|
+
`
|
|
312
|
+
);
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
if (parsed.kind === "other") {
|
|
316
|
+
const otherText = (await readLine("Other (custom text): ")).trim();
|
|
317
|
+
resolved = {
|
|
318
|
+
questionIndex: qi,
|
|
319
|
+
selectedLabels: [],
|
|
320
|
+
otherText
|
|
321
|
+
};
|
|
322
|
+
break;
|
|
323
|
+
}
|
|
324
|
+
const labels = parsed.indices.map((idx) => q.options[idx].label);
|
|
325
|
+
resolved = {
|
|
326
|
+
questionIndex: qi,
|
|
327
|
+
selectedLabels: labels
|
|
328
|
+
};
|
|
329
|
+
break;
|
|
330
|
+
}
|
|
331
|
+
if (!resolved) {
|
|
332
|
+
resolved = {
|
|
333
|
+
questionIndex: qi,
|
|
334
|
+
selectedLabels: [],
|
|
335
|
+
otherText: "(skipped after invalid input)"
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
answers.push(resolved);
|
|
339
|
+
}
|
|
340
|
+
return answers;
|
|
341
|
+
}
|
|
342
|
+
function createTtyReadLineSession() {
|
|
343
|
+
const stdin = process.stdin;
|
|
344
|
+
const ttyIn = stdin.isTTY ? stdin : null;
|
|
345
|
+
const wasRaw = Boolean(ttyIn?.isRaw);
|
|
346
|
+
if (wasRaw) {
|
|
347
|
+
try {
|
|
348
|
+
stdin.setRawMode(false);
|
|
349
|
+
} catch {
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
if (stdin.isPaused()) {
|
|
353
|
+
stdin.resume();
|
|
354
|
+
}
|
|
355
|
+
const rl = promises.createInterface({ input: stdin, output: process.stdout });
|
|
356
|
+
return {
|
|
357
|
+
readLine: (prompt) => rl.question(prompt),
|
|
358
|
+
close: () => {
|
|
359
|
+
rl.close();
|
|
360
|
+
if (wasRaw && stdin.isTTY) {
|
|
361
|
+
try {
|
|
362
|
+
stdin.setRawMode(true);
|
|
363
|
+
} catch {
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
function createTtyAskUserQuestionResolver() {
|
|
370
|
+
return async (questions) => {
|
|
371
|
+
const session = createTtyReadLineSession();
|
|
372
|
+
try {
|
|
373
|
+
return await runInteractiveAskUserQuestion(questions, session.readLine);
|
|
374
|
+
} finally {
|
|
375
|
+
session.close();
|
|
376
|
+
}
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// src/cli/commands/chat.ts
|
|
381
|
+
function parseOllamaThinkCli(value) {
|
|
382
|
+
if (value === void 0 || value === "") return true;
|
|
383
|
+
const s = value.toLowerCase();
|
|
384
|
+
if (s === "true" || s === "1" || s === "yes") return true;
|
|
385
|
+
if (s === "false" || s === "0" || s === "no") return false;
|
|
386
|
+
if (s === "low" || s === "medium" || s === "high") return s;
|
|
387
|
+
throw new Error(`Invalid --ollama-think: ${value} (use true, false, low, medium, or high)`);
|
|
388
|
+
}
|
|
389
|
+
function addModelOptions(cmd) {
|
|
390
|
+
return cmd.option("-m, --model <model>", "Model to use (openai/anthropic/ollama)", "openai").option("-k, --api-key <key>", "API key").option("-u, --base-url <url>", "Base URL for API").option("-M, --model-name <name>", "Model name").option("-s, --session <id>", "Session ID to resume").option("-S, --system <prompt>", "System prompt").option("-t, --temperature <temp>", "Temperature", parseFloat).option("--max-tokens <tokens>", "Max tokens", (v) => parseInt(v, 10)).option("--no-stream", "Disable streaming").option("-v, --verbose", "Show full tool calls and results").option("--mcp-config <path>", "Path to MCP config file (mcp_config.json)").option("--user-base-path <path>", "User base path (default: ~)").option("--cwd <path>", "Working directory (default: current directory)").option(
|
|
391
|
+
"--resume",
|
|
392
|
+
"Resume the most recently updated session (uses same storage as --user-base-path; ignored if --session is set)"
|
|
393
|
+
).option(
|
|
394
|
+
"--ollama-think [value]",
|
|
395
|
+
"Ollama only: `think` param (true|false|low|medium|high; bare flag => true)",
|
|
396
|
+
(v) => parseOllamaThinkCli(v)
|
|
397
|
+
);
|
|
398
|
+
}
|
|
399
|
+
function createModelFromOptions(options) {
|
|
400
|
+
const provider = options.model || "openai";
|
|
401
|
+
return chunkX35MHWXE_cjs.createModel({
|
|
402
|
+
provider,
|
|
403
|
+
apiKey: options.apiKey,
|
|
404
|
+
baseUrl: options.baseUrl,
|
|
405
|
+
model: options.modelName,
|
|
406
|
+
...provider === "ollama" && options.ollamaThink !== void 0 ? { think: options.ollamaThink } : {}
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
function createChatCommand() {
|
|
410
|
+
return addModelOptions(
|
|
411
|
+
new commander.Command("chat").description("Start an interactive chat session")
|
|
412
|
+
).action(async (options) => {
|
|
413
|
+
try {
|
|
414
|
+
let sessionId = options.session;
|
|
415
|
+
if (options.resume && !sessionId) {
|
|
416
|
+
sessionId = await chunk5QMA2YBY_cjs.getLatestSessionId(options.userBasePath);
|
|
417
|
+
if (!sessionId) {
|
|
418
|
+
console.warn(chalk__default.default.yellow("No saved sessions found; starting a new session."));
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
const model = createModelFromOptions(options);
|
|
422
|
+
const mcpResult = chunk5QMA2YBY_cjs.loadMCPConfig(options.mcpConfig, options.cwd || process.cwd(), options.userBasePath);
|
|
423
|
+
if (mcpResult.configPath) {
|
|
424
|
+
console.log(chalk__default.default.gray(`Loaded MCP config from: ${mcpResult.configPath}`));
|
|
425
|
+
if (mcpResult.servers.length > 0) {
|
|
426
|
+
console.log(chalk__default.default.gray(`MCP servers: ${mcpResult.servers.map((s) => s.name).join(", ")}`));
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
const cwd = options.cwd || process.cwd();
|
|
430
|
+
const agent = new chunk5QMA2YBY_cjs.Agent({
|
|
431
|
+
model,
|
|
432
|
+
cwd,
|
|
433
|
+
hookConfigDir: cwd,
|
|
434
|
+
systemPrompt: options.system,
|
|
435
|
+
temperature: options.temperature,
|
|
436
|
+
maxTokens: options.maxTokens,
|
|
437
|
+
mcpServers: mcpResult.servers,
|
|
438
|
+
userBasePath: options.userBasePath,
|
|
439
|
+
askUserQuestion: process.stdin.isTTY ? createTtyAskUserQuestionResolver() : void 0
|
|
440
|
+
});
|
|
441
|
+
await agent.waitForInit();
|
|
442
|
+
const skillRegistry = agent.getSkillRegistry();
|
|
443
|
+
const skills = skillRegistry.getUserInvocableSkills();
|
|
444
|
+
console.log(chalk__default.default.cyan("\u{1F916} Agent SDK Chat"));
|
|
445
|
+
console.log(chalk__default.default.gray(`Model: ${model.name}`));
|
|
446
|
+
console.log(chalk__default.default.gray(`Sessions: ${chunk5QMA2YBY_cjs.getSessionStoragePath(options.userBasePath)}`));
|
|
447
|
+
if (skills.length > 0) {
|
|
448
|
+
console.log(chalk__default.default.gray(`Skills: ${skills.map((s) => `/${s.name}`).join(", ")}`));
|
|
449
|
+
}
|
|
450
|
+
console.log(chalk__default.default.gray('Type "exit" or "quit" to end the session'));
|
|
451
|
+
console.log(chalk__default.default.gray("Press ESC to interrupt streaming"));
|
|
452
|
+
console.log(chalk__default.default.gray("Use /skill-name to invoke a skill\n"));
|
|
453
|
+
const readline = await import('readline');
|
|
454
|
+
let rl = readline.createInterface({
|
|
455
|
+
input: process.stdin,
|
|
456
|
+
output: process.stdout,
|
|
457
|
+
terminal: false
|
|
458
|
+
});
|
|
459
|
+
const askQuestion = () => {
|
|
460
|
+
return new Promise((resolve) => {
|
|
461
|
+
rl.question(chalk__default.default.green("You: "), resolve);
|
|
462
|
+
});
|
|
463
|
+
};
|
|
464
|
+
try {
|
|
465
|
+
while (true) {
|
|
466
|
+
const input = await askQuestion();
|
|
467
|
+
if (input.toLowerCase() === "exit" || input.toLowerCase() === "quit") {
|
|
468
|
+
console.log(chalk__default.default.gray("\nGoodbye! \u{1F44B}"));
|
|
469
|
+
break;
|
|
470
|
+
}
|
|
471
|
+
if (!input.trim()) continue;
|
|
472
|
+
let releasedOuterReadline = false;
|
|
473
|
+
rl.close();
|
|
474
|
+
releasedOuterReadline = true;
|
|
475
|
+
try {
|
|
476
|
+
const processed = await agent.processInput(input);
|
|
477
|
+
if (processed.invoked) {
|
|
478
|
+
console.log(chalk__default.default.yellow(`
|
|
479
|
+
\u26A1 Invoked skill: ${processed.skillName}`));
|
|
480
|
+
}
|
|
481
|
+
process.stdout.write(chalk__default.default.blue("\nAssistant: "));
|
|
482
|
+
if (options.stream === false) {
|
|
483
|
+
const result = await agent.run(input, { sessionId });
|
|
484
|
+
console.log(result.content);
|
|
485
|
+
if (result.usage) {
|
|
486
|
+
console.log(`
|
|
487
|
+
${formatUsage(result.usage)}`);
|
|
488
|
+
}
|
|
489
|
+
console.log(`
|
|
490
|
+
${formatSessionUsage(agent.getSessionUsage())}`);
|
|
491
|
+
const sid = agent.getSessionManager().sessionId;
|
|
492
|
+
if (sid) {
|
|
493
|
+
console.log(chalk__default.default.gray(`Session id: ${sid} (next time: add --resume or -s ${sid})`));
|
|
494
|
+
}
|
|
495
|
+
} else {
|
|
496
|
+
const abortController = new AbortController();
|
|
497
|
+
let interrupted = false;
|
|
498
|
+
const cleanupKeypress = initKeypressListener();
|
|
499
|
+
setKeypressHandler({
|
|
500
|
+
onAbort: () => {
|
|
501
|
+
interrupted = true;
|
|
502
|
+
abortController.abort();
|
|
503
|
+
process.stdout.write(chalk__default.default.yellow("\n[interrupted]\n"));
|
|
504
|
+
}
|
|
505
|
+
});
|
|
506
|
+
let resumeAskStdin = null;
|
|
507
|
+
const pendingAskToolCallIds = /* @__PURE__ */ new Set();
|
|
508
|
+
try {
|
|
509
|
+
const formatter = createStreamFormatter({ verbose: options.verbose });
|
|
510
|
+
for await (const event of agent.stream(input, {
|
|
511
|
+
sessionId,
|
|
512
|
+
signal: abortController.signal
|
|
513
|
+
})) {
|
|
514
|
+
if (interrupted) break;
|
|
515
|
+
if (event.type === "tool_call" && event.name === "AskUserQuestion") {
|
|
516
|
+
pendingAskToolCallIds.add(event.id);
|
|
517
|
+
if (!resumeAskStdin) {
|
|
518
|
+
resumeAskStdin = pauseKeypressListener();
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
if (event.type === "tool_result" && pendingAskToolCallIds.has(event.toolCallId)) {
|
|
522
|
+
pendingAskToolCallIds.delete(event.toolCallId);
|
|
523
|
+
if (pendingAskToolCallIds.size === 0 && resumeAskStdin) {
|
|
524
|
+
resumeAskStdin();
|
|
525
|
+
resumeAskStdin = null;
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
if (event.type === "tool_error" && pendingAskToolCallIds.has(event.toolCallId)) {
|
|
529
|
+
pendingAskToolCallIds.delete(event.toolCallId);
|
|
530
|
+
if (pendingAskToolCallIds.size === 0 && resumeAskStdin) {
|
|
531
|
+
resumeAskStdin();
|
|
532
|
+
resumeAskStdin = null;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
const output = formatter.format(event);
|
|
536
|
+
if (output) process.stdout.write(output);
|
|
537
|
+
}
|
|
538
|
+
if (!interrupted) {
|
|
539
|
+
const tail = formatter.finalize();
|
|
540
|
+
if (tail) process.stdout.write(tail);
|
|
541
|
+
console.log(`
|
|
542
|
+
${formatSessionUsage(agent.getSessionUsage())}`);
|
|
543
|
+
const sid = agent.getSessionManager().sessionId;
|
|
544
|
+
if (sid) {
|
|
545
|
+
console.log(chalk__default.default.gray(`Session id: ${sid} (next time: add --resume or -s ${sid})`));
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
} finally {
|
|
549
|
+
if (resumeAskStdin) {
|
|
550
|
+
resumeAskStdin();
|
|
551
|
+
}
|
|
552
|
+
clearKeypressHandler();
|
|
553
|
+
cleanupKeypress();
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
console.log("\n");
|
|
557
|
+
} finally {
|
|
558
|
+
if (releasedOuterReadline) {
|
|
559
|
+
rl = readline.createInterface({
|
|
560
|
+
input: process.stdin,
|
|
561
|
+
output: process.stdout,
|
|
562
|
+
terminal: false
|
|
563
|
+
});
|
|
564
|
+
if (process.stdin.isPaused()) {
|
|
565
|
+
process.stdin.resume();
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
} finally {
|
|
571
|
+
await agent.destroy();
|
|
572
|
+
rl.close();
|
|
573
|
+
}
|
|
574
|
+
} catch (err) {
|
|
575
|
+
console.error(chalk__default.default.red(`Error: ${err instanceof Error ? err.message : err}`));
|
|
576
|
+
process.exit(1);
|
|
577
|
+
}
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
function createRunCommand() {
|
|
581
|
+
return addModelOptions(
|
|
582
|
+
new commander.Command("run").description("Run a single prompt").argument("<prompt>", "The prompt to run")
|
|
583
|
+
).option("-o, --output <format>", "Output format (text/json)", "text").action(async (prompt, options) => {
|
|
584
|
+
try {
|
|
585
|
+
let sessionId = options.session;
|
|
586
|
+
if (options.resume && !sessionId) {
|
|
587
|
+
sessionId = await chunk5QMA2YBY_cjs.getLatestSessionId(options.userBasePath);
|
|
588
|
+
if (!sessionId) {
|
|
589
|
+
console.warn(chalk__default.default.yellow("No saved sessions found; starting a new session."));
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
const model = createModelFromOptions(options);
|
|
593
|
+
const mcpResult = chunk5QMA2YBY_cjs.loadMCPConfig(options.mcpConfig, options.cwd || process.cwd(), options.userBasePath);
|
|
594
|
+
if (mcpResult.configPath) {
|
|
595
|
+
console.log(chalk__default.default.gray(`Loaded MCP config from: ${mcpResult.configPath}`));
|
|
596
|
+
}
|
|
597
|
+
const cwd = options.cwd || process.cwd();
|
|
598
|
+
const agent = new chunk5QMA2YBY_cjs.Agent({
|
|
599
|
+
model,
|
|
600
|
+
cwd,
|
|
601
|
+
hookConfigDir: cwd,
|
|
602
|
+
systemPrompt: options.system,
|
|
603
|
+
temperature: options.temperature,
|
|
604
|
+
maxTokens: options.maxTokens,
|
|
605
|
+
mcpServers: mcpResult.servers,
|
|
606
|
+
userBasePath: options.userBasePath,
|
|
607
|
+
askUserQuestion: process.stdin.isTTY ? createTtyAskUserQuestionResolver() : void 0
|
|
608
|
+
});
|
|
609
|
+
await agent.waitForInit();
|
|
610
|
+
try {
|
|
611
|
+
if (options.output === "json") {
|
|
612
|
+
const result = await agent.run(prompt, { sessionId });
|
|
613
|
+
console.log(JSON.stringify(result, null, 2));
|
|
614
|
+
} else if (options.stream !== false) {
|
|
615
|
+
const formatter = createStreamFormatter({ verbose: options.verbose });
|
|
616
|
+
for await (const event of agent.stream(prompt, { sessionId })) {
|
|
617
|
+
const output = formatter.format(event);
|
|
618
|
+
if (output) process.stdout.write(output);
|
|
619
|
+
}
|
|
620
|
+
const tail = formatter.finalize();
|
|
621
|
+
if (tail) process.stdout.write(tail);
|
|
622
|
+
} else {
|
|
623
|
+
const result = await agent.run(prompt, { sessionId });
|
|
624
|
+
console.log(result.content);
|
|
625
|
+
if (result.usage) {
|
|
626
|
+
console.log(`
|
|
627
|
+
${formatUsage(result.usage)}`);
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
} finally {
|
|
631
|
+
await agent.destroy();
|
|
632
|
+
}
|
|
633
|
+
} catch (err) {
|
|
634
|
+
console.error(chalk__default.default.red(`Error: ${err instanceof Error ? err.message : err}`));
|
|
635
|
+
process.exit(1);
|
|
636
|
+
}
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
function createToolsCommand() {
|
|
640
|
+
const command = new commander.Command("tools").description("Manage agent tools");
|
|
641
|
+
command.command("list").description("List all available tools").option("-f, --format <format>", "Output format (table/json)", "table").option("-c, --category <category>", "Filter by category").action((options) => {
|
|
642
|
+
const registry = new chunkJF5AJQMU_cjs.ToolRegistry();
|
|
643
|
+
const skillRegistry = chunk5QMA2YBY_cjs.createSkillRegistry();
|
|
644
|
+
registry.registerMany(chunkJF5AJQMU_cjs.getAllBuiltinTools(skillRegistry));
|
|
645
|
+
let tools = registry.getAll();
|
|
646
|
+
if (options.category) {
|
|
647
|
+
tools = tools.filter(
|
|
648
|
+
(t) => t.name.startsWith(options.category) || t.description.toLowerCase().includes(options.category.toLowerCase())
|
|
649
|
+
);
|
|
650
|
+
}
|
|
651
|
+
if (options.format === "json") {
|
|
652
|
+
console.log(JSON.stringify(tools.map((t) => ({
|
|
653
|
+
name: t.name,
|
|
654
|
+
description: t.description,
|
|
655
|
+
dangerous: t.isDangerous || false,
|
|
656
|
+
category: t.category || null
|
|
657
|
+
})), null, 2));
|
|
658
|
+
} else {
|
|
659
|
+
console.log(chalk__default.default.cyan("\n\u{1F4E6} Available Tools\n"));
|
|
660
|
+
console.log(formatTable(
|
|
661
|
+
tools.map((t) => ({
|
|
662
|
+
name: t.name,
|
|
663
|
+
description: t.description.slice(0, 50) + (t.description.length > 50 ? "..." : ""),
|
|
664
|
+
category: t.category || "",
|
|
665
|
+
dangerous: t.isDangerous ? "\u26A0\uFE0F" : ""
|
|
666
|
+
})),
|
|
667
|
+
[
|
|
668
|
+
{ key: "name", header: "Name", width: 20 },
|
|
669
|
+
{ key: "description", header: "Description", width: 50 },
|
|
670
|
+
{ key: "category", header: "Category", width: 12 },
|
|
671
|
+
{ key: "dangerous", header: "", width: 3 }
|
|
672
|
+
]
|
|
673
|
+
));
|
|
674
|
+
console.log(chalk__default.default.gray(`
|
|
675
|
+
Total: ${tools.length} tools`));
|
|
676
|
+
}
|
|
677
|
+
});
|
|
678
|
+
command.command("show <name>").description("Show tool details").action((name) => {
|
|
679
|
+
const registry = new chunkJF5AJQMU_cjs.ToolRegistry();
|
|
680
|
+
const skillRegistry = chunk5QMA2YBY_cjs.createSkillRegistry();
|
|
681
|
+
registry.registerMany(chunkJF5AJQMU_cjs.getAllBuiltinTools(skillRegistry));
|
|
682
|
+
const tool = registry.get(name);
|
|
683
|
+
if (!tool) {
|
|
684
|
+
console.error(chalk__default.default.red(`Tool "${name}" not found`));
|
|
685
|
+
process.exit(1);
|
|
686
|
+
}
|
|
687
|
+
console.log(chalk__default.default.cyan(`
|
|
688
|
+
\u{1F527} ${tool.name}
|
|
689
|
+
`));
|
|
690
|
+
console.log(`Description: ${tool.description}`);
|
|
691
|
+
console.log(`Category: ${tool.category || "none"}`);
|
|
692
|
+
console.log(`Dangerous: ${tool.isDangerous ? "Yes \u26A0\uFE0F" : "No"}`);
|
|
693
|
+
console.log(`
|
|
694
|
+
Parameters Schema:`);
|
|
695
|
+
console.log(JSON.stringify(tool.parameters, null, 2));
|
|
696
|
+
});
|
|
697
|
+
command.command("test <name>").description(
|
|
698
|
+
"Test a tool with arguments. Note: AskUserQuestion returns formatted text only unless the Agent is configured with askUserQuestion (e.g. CLI TTY)."
|
|
699
|
+
).option("-a, --args <json>", "Tool arguments as JSON").action(async (name, options) => {
|
|
700
|
+
const registry = new chunkJF5AJQMU_cjs.ToolRegistry();
|
|
701
|
+
const skillRegistry = chunk5QMA2YBY_cjs.createSkillRegistry();
|
|
702
|
+
registry.registerMany(chunkJF5AJQMU_cjs.getAllBuiltinTools(skillRegistry));
|
|
703
|
+
if (!registry.has(name)) {
|
|
704
|
+
console.error(chalk__default.default.red(`Tool "${name}" not found`));
|
|
705
|
+
process.exit(1);
|
|
706
|
+
}
|
|
707
|
+
let args = {};
|
|
708
|
+
if (options.args) {
|
|
709
|
+
try {
|
|
710
|
+
args = JSON.parse(options.args);
|
|
711
|
+
} catch {
|
|
712
|
+
console.error(chalk__default.default.red("Invalid JSON in --args"));
|
|
713
|
+
process.exit(1);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
console.log(chalk__default.default.cyan(`
|
|
717
|
+
\u{1F9EA} Testing tool: ${name}
|
|
718
|
+
`));
|
|
719
|
+
console.log(chalk__default.default.gray(`Arguments: ${JSON.stringify(args)}
|
|
720
|
+
`));
|
|
721
|
+
const result = await registry.execute(name, args);
|
|
722
|
+
if (result.isError) {
|
|
723
|
+
console.log(chalk__default.default.red("\u274C Error:"));
|
|
724
|
+
console.log(result.content);
|
|
725
|
+
} else {
|
|
726
|
+
console.log(chalk__default.default.green("\u2705 Result:"));
|
|
727
|
+
console.log(result.content);
|
|
728
|
+
}
|
|
729
|
+
});
|
|
730
|
+
return command;
|
|
731
|
+
}
|
|
732
|
+
function addUserBasePathOption(cmd) {
|
|
733
|
+
return cmd.option("--user-base-path <path>", "User base path (default: ~), must match chat/run");
|
|
734
|
+
}
|
|
735
|
+
function createSessionsCommand() {
|
|
736
|
+
const command = new commander.Command("sessions").description("Manage chat sessions");
|
|
737
|
+
addUserBasePathOption(
|
|
738
|
+
command.command("list").description("List all sessions").option("-l, --limit <n>", "Limit number of sessions", parseInt, 20).option("-f, --format <format>", "Output format (table/json)", "table")
|
|
739
|
+
).action(async (options) => {
|
|
740
|
+
const manager = new chunk5QMA2YBY_cjs.SessionManager({
|
|
741
|
+
type: "jsonl",
|
|
742
|
+
basePath: chunk5QMA2YBY_cjs.getSessionStoragePath(options.userBasePath)
|
|
743
|
+
});
|
|
744
|
+
const sessions = await manager.listSessions();
|
|
745
|
+
const limited = sessions.slice(0, options.limit);
|
|
746
|
+
if (options.format === "json") {
|
|
747
|
+
console.log(JSON.stringify(limited, null, 2));
|
|
748
|
+
} else {
|
|
749
|
+
if (limited.length === 0) {
|
|
750
|
+
console.log(chalk__default.default.gray("No sessions found"));
|
|
751
|
+
return;
|
|
752
|
+
}
|
|
753
|
+
console.log(chalk__default.default.cyan("\n\u{1F4AC} Sessions\n"));
|
|
754
|
+
console.log(formatTable(
|
|
755
|
+
limited.map((s) => ({
|
|
756
|
+
id: s.id,
|
|
757
|
+
messages: s.messageCount,
|
|
758
|
+
created: new Date(s.createdAt).toLocaleString(),
|
|
759
|
+
updated: new Date(s.updatedAt).toLocaleString()
|
|
760
|
+
})),
|
|
761
|
+
[
|
|
762
|
+
{ key: "id", header: "ID", width: 36 },
|
|
763
|
+
{ key: "messages", header: "Messages", width: 10 },
|
|
764
|
+
{ key: "created", header: "Created", width: 20 },
|
|
765
|
+
{ key: "updated", header: "Updated", width: 20 }
|
|
766
|
+
]
|
|
767
|
+
));
|
|
768
|
+
console.log(chalk__default.default.gray(`
|
|
769
|
+
Total: ${sessions.length} sessions`));
|
|
770
|
+
}
|
|
771
|
+
});
|
|
772
|
+
addUserBasePathOption(
|
|
773
|
+
command.command("show <id>").description("Show session messages").option("-l, --limit <n>", "Limit number of messages", parseInt, 50)
|
|
774
|
+
).action(async (id, options) => {
|
|
775
|
+
const manager = new chunk5QMA2YBY_cjs.SessionManager({
|
|
776
|
+
type: "jsonl",
|
|
777
|
+
basePath: chunk5QMA2YBY_cjs.getSessionStoragePath(options.userBasePath)
|
|
778
|
+
});
|
|
779
|
+
const exists = await manager.sessionExists(id);
|
|
780
|
+
if (!exists) {
|
|
781
|
+
console.error(chalk__default.default.red(`Session "${id}" not found`));
|
|
782
|
+
process.exit(1);
|
|
783
|
+
}
|
|
784
|
+
const messages = await manager.resumeSession(id);
|
|
785
|
+
const limited = messages.slice(-options.limit);
|
|
786
|
+
console.log(chalk__default.default.cyan(`
|
|
787
|
+
\u{1F4AC} Session: ${id}
|
|
788
|
+
`));
|
|
789
|
+
console.log(chalk__default.default.gray(`Showing ${limited.length} of ${messages.length} messages
|
|
790
|
+
`));
|
|
791
|
+
for (const msg of limited) {
|
|
792
|
+
const role = msg.role === "user" ? chalk__default.default.green("You") : msg.role === "assistant" ? chalk__default.default.blue("Assistant") : chalk__default.default.yellow(msg.role);
|
|
793
|
+
console.log(`${role}: ${msg.content}
|
|
794
|
+
`);
|
|
795
|
+
}
|
|
796
|
+
});
|
|
797
|
+
addUserBasePathOption(
|
|
798
|
+
command.command("delete <id>").description("Delete a session").option("-f, --force", "Skip confirmation")
|
|
799
|
+
).action(async (id, options) => {
|
|
800
|
+
const manager = new chunk5QMA2YBY_cjs.SessionManager({
|
|
801
|
+
type: "jsonl",
|
|
802
|
+
basePath: chunk5QMA2YBY_cjs.getSessionStoragePath(options.userBasePath)
|
|
803
|
+
});
|
|
804
|
+
const exists = await manager.sessionExists(id);
|
|
805
|
+
if (!exists) {
|
|
806
|
+
console.error(chalk__default.default.red(`Session "${id}" not found`));
|
|
807
|
+
process.exit(1);
|
|
808
|
+
}
|
|
809
|
+
if (!options.force) {
|
|
810
|
+
const readline = await import('readline');
|
|
811
|
+
const rl = readline.createInterface({
|
|
812
|
+
input: process.stdin,
|
|
813
|
+
output: process.stdout
|
|
814
|
+
});
|
|
815
|
+
const answer = await new Promise((resolve) => {
|
|
816
|
+
rl.question(chalk__default.default.yellow(`Delete session "${id}"? (y/N) `), resolve);
|
|
817
|
+
});
|
|
818
|
+
rl.close();
|
|
819
|
+
if (answer.toLowerCase() !== "y") {
|
|
820
|
+
console.log(chalk__default.default.gray("Cancelled"));
|
|
821
|
+
return;
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
await manager.deleteSession(id);
|
|
825
|
+
console.log(chalk__default.default.green(`\u2713 Session "${id}" deleted`));
|
|
826
|
+
});
|
|
827
|
+
addUserBasePathOption(
|
|
828
|
+
command.command("clear").description("Delete all sessions").option("-f, --force", "Skip confirmation")
|
|
829
|
+
).action(async (options) => {
|
|
830
|
+
const manager = new chunk5QMA2YBY_cjs.SessionManager({
|
|
831
|
+
type: "jsonl",
|
|
832
|
+
basePath: chunk5QMA2YBY_cjs.getSessionStoragePath(options.userBasePath)
|
|
833
|
+
});
|
|
834
|
+
const sessions = await manager.listSessions();
|
|
835
|
+
if (sessions.length === 0) {
|
|
836
|
+
console.log(chalk__default.default.gray("No sessions to clear"));
|
|
837
|
+
return;
|
|
838
|
+
}
|
|
839
|
+
if (!options.force) {
|
|
840
|
+
const readline = await import('readline');
|
|
841
|
+
const rl = readline.createInterface({
|
|
842
|
+
input: process.stdin,
|
|
843
|
+
output: process.stdout
|
|
844
|
+
});
|
|
845
|
+
const answer = await new Promise((resolve) => {
|
|
846
|
+
rl.question(chalk__default.default.yellow(`Delete all ${sessions.length} sessions? (y/N) `), resolve);
|
|
847
|
+
});
|
|
848
|
+
rl.close();
|
|
849
|
+
if (answer.toLowerCase() !== "y") {
|
|
850
|
+
console.log(chalk__default.default.gray("Cancelled"));
|
|
851
|
+
return;
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
const storage = manager.getStorage();
|
|
855
|
+
for (const session of sessions) {
|
|
856
|
+
await storage.delete(session.id);
|
|
857
|
+
}
|
|
858
|
+
console.log(chalk__default.default.green(`\u2713 Deleted ${sessions.length} sessions`));
|
|
859
|
+
});
|
|
860
|
+
return command;
|
|
861
|
+
}
|
|
862
|
+
function createMCPCommand() {
|
|
863
|
+
const command = new commander.Command("mcp").description("Manage MCP servers");
|
|
864
|
+
command.command("connect <command>").description("Connect to an MCP server and list available tools").option("-n, --name <name>", "Server name", "default").option("-a, --args <args>", "Command arguments (comma-separated)").option("-e, --env <env>", "Environment variables (KEY=VALUE,comma-separated)").action(async (cmd, options) => {
|
|
865
|
+
try {
|
|
866
|
+
const adapter = new chunk5QMA2YBY_cjs.MCPAdapter();
|
|
867
|
+
const args = options.args ? options.args.split(",") : [];
|
|
868
|
+
const env = {};
|
|
869
|
+
if (options.env) {
|
|
870
|
+
for (const pair of options.env.split(",")) {
|
|
871
|
+
const [key, value] = pair.split("=");
|
|
872
|
+
if (key && value) {
|
|
873
|
+
env[key] = value;
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
console.log(chalk__default.default.cyan(`
|
|
878
|
+
\u{1F50C} Connecting to MCP server: ${options.name}
|
|
879
|
+
`));
|
|
880
|
+
const config = {
|
|
881
|
+
name: options.name,
|
|
882
|
+
command: cmd,
|
|
883
|
+
args,
|
|
884
|
+
env: Object.keys(env).length > 0 ? env : void 0
|
|
885
|
+
};
|
|
886
|
+
await adapter.addServer(config);
|
|
887
|
+
console.log(chalk__default.default.green("\u2713 Connected successfully"));
|
|
888
|
+
const tools = await adapter.listAllTools();
|
|
889
|
+
const serverTools = tools.get(options.name) || [];
|
|
890
|
+
if (serverTools.length > 0) {
|
|
891
|
+
console.log(chalk__default.default.cyan("\n\u{1F4E6} Available tools:\n"));
|
|
892
|
+
for (const tool of serverTools) {
|
|
893
|
+
console.log(` \u2022 ${tool.name}: ${tool.description || "No description"}`);
|
|
894
|
+
}
|
|
895
|
+
} else {
|
|
896
|
+
console.log(chalk__default.default.gray("\nNo tools available"));
|
|
897
|
+
}
|
|
898
|
+
await adapter.disconnectAll();
|
|
899
|
+
} catch (err) {
|
|
900
|
+
console.error(chalk__default.default.red(`Connection failed: ${err instanceof Error ? err.message : err}`));
|
|
901
|
+
process.exit(1);
|
|
902
|
+
}
|
|
903
|
+
});
|
|
904
|
+
return command;
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
// src/cli/index.ts
|
|
908
|
+
var isMainModule = process.argv[1]?.endsWith("cli/index.js") || process.argv[1]?.endsWith("cli\\index.js") || process.argv[1]?.includes("agent-sdk");
|
|
909
|
+
if (isMainModule) {
|
|
910
|
+
const program = new commander.Command();
|
|
911
|
+
program.name("agent-sdk").description("A TypeScript Agent SDK with multi-model support, MCP integration, and streaming").version("0.1.0");
|
|
912
|
+
program.addCommand(createChatCommand());
|
|
913
|
+
program.addCommand(createRunCommand());
|
|
914
|
+
program.addCommand(createToolsCommand());
|
|
915
|
+
program.addCommand(createSessionsCommand());
|
|
916
|
+
program.addCommand(createMCPCommand());
|
|
917
|
+
program.parse();
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
exports.createChatCommand = createChatCommand;
|
|
921
|
+
exports.createMCPCommand = createMCPCommand;
|
|
922
|
+
exports.createRunCommand = createRunCommand;
|
|
923
|
+
exports.createSessionsCommand = createSessionsCommand;
|
|
924
|
+
exports.createToolsCommand = createToolsCommand;
|
|
925
|
+
//# sourceMappingURL=index.cjs.map
|
|
926
|
+
//# sourceMappingURL=index.cjs.map
|