@zds-ai/cli 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/grok-agent.d.ts +8 -0
- package/dist/agent/grok-agent.js +131 -34
- package/dist/agent/grok-agent.js.map +1 -1
- package/dist/agent/prompt-variables.d.ts +99 -0
- package/dist/agent/prompt-variables.js +191 -0
- package/dist/agent/prompt-variables.js.map +1 -0
- package/dist/bin/fastcaption.sh +55 -0
- package/dist/bin/generate_image_sd.sh +1 -1
- package/dist/grok/client.d.ts +1 -0
- package/dist/grok/client.js +23 -6
- package/dist/grok/client.js.map +1 -1
- package/dist/grok/tools.js +4 -3
- package/dist/grok/tools.js.map +1 -1
- package/dist/hooks/use-input-handler.js +34 -0
- package/dist/hooks/use-input-handler.js.map +1 -1
- package/dist/tools/image-tool.d.ts +2 -2
- package/dist/tools/image-tool.js +6 -16
- package/dist/tools/image-tool.js.map +1 -1
- package/dist/utils/chat-history-manager.d.ts +1 -0
- package/dist/utils/chat-history-manager.js.map +1 -1
- package/dist/utils/image-encoder.js +4 -3
- package/dist/utils/image-encoder.js.map +1 -1
- package/dist/utils/slash-commands.d.ts +1 -1
- package/dist/utils/slash-commands.js +31 -0
- package/dist/utils/slash-commands.js.map +1 -1
- package/dist/utils/startup-hook.js +21 -12
- package/dist/utils/startup-hook.js.map +1 -1
- package/package.json +2 -1
|
@@ -229,6 +229,7 @@ export declare class GrokAgent extends EventEmitter {
|
|
|
229
229
|
baseUrl: string;
|
|
230
230
|
apiKeyEnvVar: string;
|
|
231
231
|
model: string;
|
|
232
|
+
supportsVision: boolean;
|
|
232
233
|
};
|
|
233
234
|
/**
|
|
234
235
|
* Restore session state from persistence
|
|
@@ -249,7 +250,14 @@ export declare class GrokAgent extends EventEmitter {
|
|
|
249
250
|
baseUrl?: string;
|
|
250
251
|
apiKeyEnvVar?: string;
|
|
251
252
|
model?: string;
|
|
253
|
+
supportsVision?: boolean;
|
|
252
254
|
}): Promise<void>;
|
|
255
|
+
/**
|
|
256
|
+
* Compact conversation context by keeping system prompt and last N messages
|
|
257
|
+
* Reduces context size when it grows too large for backend to handle
|
|
258
|
+
* @returns Number of messages removed
|
|
259
|
+
*/
|
|
260
|
+
compactContext(keepLastMessages?: number): number;
|
|
253
261
|
/**
|
|
254
262
|
* Get all tool instances and their class names for display purposes
|
|
255
263
|
*/
|
package/dist/agent/grok-agent.js
CHANGED
|
@@ -5,6 +5,7 @@ import { ChatHistoryManager } from "../utils/chat-history-manager.js";
|
|
|
5
5
|
import { logApiError } from "../utils/error-logger.js";
|
|
6
6
|
import { parseImagesFromMessage, hasImageReferences } from "../utils/image-encoder.js";
|
|
7
7
|
import { getTextContent } from "../utils/content-utils.js";
|
|
8
|
+
import { Variable } from "./prompt-variables.js";
|
|
8
9
|
import fs from "fs";
|
|
9
10
|
import { TextEditorTool, MorphEditorTool, ZshTool, ConfirmationTool, SearchTool, EnvTool, IntrospectTool, ClearCacheTool, CharacterTool, TaskTool, InternetTool, ImageTool, FileConversionTool, RestartTool } from "../tools/index.js";
|
|
10
11
|
import { EventEmitter } from "events";
|
|
@@ -413,25 +414,26 @@ Current working directory: ${process.cwd()}`;
|
|
|
413
414
|
}
|
|
414
415
|
}
|
|
415
416
|
}
|
|
417
|
+
// Clear one-shot variables
|
|
418
|
+
Variable.clearOneShot();
|
|
419
|
+
// Parse images once if present (for both text extraction and later assembly)
|
|
420
|
+
const parsed = hasImageReferences(messageToSend)
|
|
421
|
+
? parseImagesFromMessage(messageToSend)
|
|
422
|
+
: { text: messageToSend, images: [] };
|
|
423
|
+
// Set USER:PROMPT variable (text only, images stripped)
|
|
424
|
+
Variable.set("USER:PROMPT", parsed.text);
|
|
425
|
+
// Assemble final message from variables
|
|
426
|
+
const assembledMessage = Variable.renderFull("USER");
|
|
416
427
|
// Add user/system message to conversation
|
|
417
|
-
// Check for image references and parse if present
|
|
418
428
|
// Note: System messages can only have string content, so images are only supported for user messages
|
|
419
429
|
const supportsVision = this.grokClient.getSupportsVision();
|
|
420
|
-
let messageContent =
|
|
421
|
-
if (messageType === "user" &&
|
|
422
|
-
//
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
{ type: "text", text: parsed.text },
|
|
428
|
-
...parsed.images
|
|
429
|
-
];
|
|
430
|
-
}
|
|
431
|
-
else {
|
|
432
|
-
// No valid images found (errors will be in parsed.text)
|
|
433
|
-
messageContent = parsed.text;
|
|
434
|
-
}
|
|
430
|
+
let messageContent = assembledMessage;
|
|
431
|
+
if (messageType === "user" && parsed.images.length > 0 && supportsVision) {
|
|
432
|
+
// Construct content array with assembled text and images
|
|
433
|
+
messageContent = [
|
|
434
|
+
{ type: "text", text: assembledMessage },
|
|
435
|
+
...parsed.images
|
|
436
|
+
];
|
|
435
437
|
}
|
|
436
438
|
const userEntry = {
|
|
437
439
|
type: messageType,
|
|
@@ -691,6 +693,22 @@ Current working directory: ${process.cwd()}`;
|
|
|
691
693
|
return newEntries;
|
|
692
694
|
}
|
|
693
695
|
catch (error) {
|
|
696
|
+
// Check if context is too large (413 error when vision already disabled)
|
|
697
|
+
if (error.message && error.message.startsWith('CONTEXT_TOO_LARGE:')) {
|
|
698
|
+
const beforeCount = this.chatHistory.length;
|
|
699
|
+
this.compactContext(20);
|
|
700
|
+
const afterCount = this.chatHistory.length;
|
|
701
|
+
const removedCount = beforeCount - afterCount;
|
|
702
|
+
const compactEntry = {
|
|
703
|
+
type: "system",
|
|
704
|
+
content: `Context was too large for backend. Automatically compacted: removed ${removedCount} older messages, keeping last 20 messages. Please retry your request.`,
|
|
705
|
+
timestamp: new Date(),
|
|
706
|
+
};
|
|
707
|
+
this.chatHistory.push(compactEntry);
|
|
708
|
+
// Mark first message as processed
|
|
709
|
+
this.firstMessageProcessed = true;
|
|
710
|
+
return [userEntry, compactEntry];
|
|
711
|
+
}
|
|
694
712
|
const errorEntry = {
|
|
695
713
|
type: "assistant",
|
|
696
714
|
content: `Sorry, I encountered an error: ${error.message}`,
|
|
@@ -862,25 +880,26 @@ Current working directory: ${process.cwd()}`;
|
|
|
862
880
|
}
|
|
863
881
|
}
|
|
864
882
|
}
|
|
883
|
+
// Clear one-shot variables
|
|
884
|
+
Variable.clearOneShot();
|
|
885
|
+
// Parse images once if present (for both text extraction and later assembly)
|
|
886
|
+
const parsed = hasImageReferences(messageToSend)
|
|
887
|
+
? parseImagesFromMessage(messageToSend)
|
|
888
|
+
: { text: messageToSend, images: [] };
|
|
889
|
+
// Set USER:PROMPT variable (text only, images stripped)
|
|
890
|
+
Variable.set("USER:PROMPT", parsed.text);
|
|
891
|
+
// Assemble final message from variables
|
|
892
|
+
const assembledMessage = Variable.renderFull("USER");
|
|
865
893
|
// Add user/system message to both API conversation and chat history
|
|
866
|
-
// Check for image references and parse if present
|
|
867
894
|
// Note: System messages can only have string content, so images are only supported for user messages
|
|
868
895
|
const supportsVision = this.grokClient.getSupportsVision();
|
|
869
|
-
let messageContent =
|
|
870
|
-
if (messageType === "user" &&
|
|
871
|
-
//
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
{ type: "text", text: parsed.text },
|
|
877
|
-
...parsed.images
|
|
878
|
-
];
|
|
879
|
-
}
|
|
880
|
-
else {
|
|
881
|
-
// No valid images found (errors will be in parsed.text)
|
|
882
|
-
messageContent = parsed.text;
|
|
883
|
-
}
|
|
896
|
+
let messageContent = assembledMessage;
|
|
897
|
+
if (messageType === "user" && parsed.images.length > 0 && supportsVision) {
|
|
898
|
+
// Construct content array with assembled text and images
|
|
899
|
+
messageContent = [
|
|
900
|
+
{ type: "text", text: assembledMessage },
|
|
901
|
+
...parsed.images
|
|
902
|
+
];
|
|
884
903
|
}
|
|
885
904
|
const userEntry = {
|
|
886
905
|
type: messageType,
|
|
@@ -894,7 +913,7 @@ Current working directory: ${process.cwd()}`;
|
|
|
894
913
|
}
|
|
895
914
|
else {
|
|
896
915
|
// System messages must have string content only
|
|
897
|
-
this.messages.push({ role: "system", content: typeof messageContent === "string" ? messageContent :
|
|
916
|
+
this.messages.push({ role: "system", content: typeof messageContent === "string" ? messageContent : assembledMessage });
|
|
898
917
|
}
|
|
899
918
|
await this.emitContextChange();
|
|
900
919
|
// Yield user message so UI can display it immediately
|
|
@@ -1237,6 +1256,25 @@ Current working directory: ${process.cwd()}`;
|
|
|
1237
1256
|
yield { type: "done" };
|
|
1238
1257
|
return;
|
|
1239
1258
|
}
|
|
1259
|
+
// Check if context is too large (413 error when vision already disabled)
|
|
1260
|
+
if (error.message && error.message.startsWith('CONTEXT_TOO_LARGE:')) {
|
|
1261
|
+
const beforeCount = this.chatHistory.length;
|
|
1262
|
+
this.compactContext(20);
|
|
1263
|
+
const afterCount = this.chatHistory.length;
|
|
1264
|
+
const removedCount = beforeCount - afterCount;
|
|
1265
|
+
const compactEntry = {
|
|
1266
|
+
type: "system",
|
|
1267
|
+
content: `Context was too large for backend. Automatically compacted: removed ${removedCount} older messages, keeping last 20 messages. Please retry your request.`,
|
|
1268
|
+
timestamp: new Date(),
|
|
1269
|
+
};
|
|
1270
|
+
this.chatHistory.push(compactEntry);
|
|
1271
|
+
yield {
|
|
1272
|
+
type: "content",
|
|
1273
|
+
content: getTextContent(compactEntry.content),
|
|
1274
|
+
};
|
|
1275
|
+
yield { type: "done" };
|
|
1276
|
+
return;
|
|
1277
|
+
}
|
|
1240
1278
|
const errorEntry = {
|
|
1241
1279
|
type: "assistant",
|
|
1242
1280
|
content: `Sorry, I encountered an error: ${error.message}`,
|
|
@@ -1496,7 +1534,7 @@ Current working directory: ${process.cwd()}`;
|
|
|
1496
1534
|
case "generateImage":
|
|
1497
1535
|
return await this.imageTool.generateImage(args.prompt, args.negativePrompt, args.width, args.height, args.model, args.sampler, args.configScale, args.numSteps, args.nsfw, args.name, args.move, args.seed);
|
|
1498
1536
|
case "captionImage":
|
|
1499
|
-
return await this.imageTool.captionImage(args.filename, args.
|
|
1537
|
+
return await this.imageTool.captionImage(args.filename, args.backend);
|
|
1500
1538
|
case "pngInfo":
|
|
1501
1539
|
return await this.imageTool.pngInfo(args.filename);
|
|
1502
1540
|
case "listImageModels":
|
|
@@ -2038,6 +2076,8 @@ Current working directory: ${process.cwd()}`;
|
|
|
2038
2076
|
}
|
|
2039
2077
|
setModel(model) {
|
|
2040
2078
|
this.grokClient.setModel(model);
|
|
2079
|
+
// Reset supportsVision flag for new model
|
|
2080
|
+
this.grokClient.setSupportsVision(true);
|
|
2041
2081
|
// Update token counter for new model
|
|
2042
2082
|
this.tokenCounter.dispose();
|
|
2043
2083
|
this.tokenCounter = createTokenCounter(model);
|
|
@@ -2412,6 +2452,7 @@ Current working directory: ${process.cwd()}`;
|
|
|
2412
2452
|
baseUrl: this.grokClient.getBaseURL(),
|
|
2413
2453
|
apiKeyEnvVar: this.apiKeyEnvVar,
|
|
2414
2454
|
model: this.getCurrentModel(),
|
|
2455
|
+
supportsVision: this.grokClient.getSupportsVision(),
|
|
2415
2456
|
};
|
|
2416
2457
|
}
|
|
2417
2458
|
/**
|
|
@@ -2441,6 +2482,10 @@ Current working directory: ${process.cwd()}`;
|
|
|
2441
2482
|
const model = state.model || this.getCurrentModel();
|
|
2442
2483
|
this.grokClient = new GrokClient(apiKey, model, state.baseUrl, state.backend);
|
|
2443
2484
|
this.apiKeyEnvVar = state.apiKeyEnvVar;
|
|
2485
|
+
// Restore supportsVision flag if present
|
|
2486
|
+
if (state.supportsVision !== undefined) {
|
|
2487
|
+
this.grokClient.setSupportsVision(state.supportsVision);
|
|
2488
|
+
}
|
|
2444
2489
|
// Reinitialize MCP servers when restoring session
|
|
2445
2490
|
try {
|
|
2446
2491
|
const config = loadMCPConfig();
|
|
@@ -2494,6 +2539,58 @@ Current working directory: ${process.cwd()}`;
|
|
|
2494
2539
|
}
|
|
2495
2540
|
}
|
|
2496
2541
|
}
|
|
2542
|
+
/**
|
|
2543
|
+
* Compact conversation context by keeping system prompt and last N messages
|
|
2544
|
+
* Reduces context size when it grows too large for backend to handle
|
|
2545
|
+
* @returns Number of messages removed
|
|
2546
|
+
*/
|
|
2547
|
+
compactContext(keepLastMessages = 20) {
|
|
2548
|
+
if (this.chatHistory.length <= keepLastMessages) {
|
|
2549
|
+
// Nothing to compact
|
|
2550
|
+
return 0;
|
|
2551
|
+
}
|
|
2552
|
+
const removedCount = this.chatHistory.length - keepLastMessages;
|
|
2553
|
+
const keptMessages = this.chatHistory.slice(-keepLastMessages);
|
|
2554
|
+
// Clear both arrays
|
|
2555
|
+
this.chatHistory = keptMessages;
|
|
2556
|
+
this.messages = [];
|
|
2557
|
+
// Add system message noting the compaction
|
|
2558
|
+
const compactionNote = {
|
|
2559
|
+
type: 'system',
|
|
2560
|
+
content: `Context compacted: removed ${removedCount} older messages, keeping last ${keepLastMessages} messages.`,
|
|
2561
|
+
timestamp: new Date()
|
|
2562
|
+
};
|
|
2563
|
+
this.chatHistory.push(compactionNote);
|
|
2564
|
+
// Rebuild this.messages from compacted chatHistory
|
|
2565
|
+
for (const entry of this.chatHistory) {
|
|
2566
|
+
if (entry.type === 'system') {
|
|
2567
|
+
this.messages.push({
|
|
2568
|
+
role: 'system',
|
|
2569
|
+
content: entry.content
|
|
2570
|
+
});
|
|
2571
|
+
}
|
|
2572
|
+
else if (entry.type === 'user') {
|
|
2573
|
+
this.messages.push({
|
|
2574
|
+
role: 'user',
|
|
2575
|
+
content: entry.content
|
|
2576
|
+
});
|
|
2577
|
+
}
|
|
2578
|
+
else if (entry.type === 'assistant') {
|
|
2579
|
+
this.messages.push({
|
|
2580
|
+
role: 'assistant',
|
|
2581
|
+
content: entry.content
|
|
2582
|
+
});
|
|
2583
|
+
}
|
|
2584
|
+
else if (entry.type === 'tool_result') {
|
|
2585
|
+
this.messages.push({
|
|
2586
|
+
role: 'tool',
|
|
2587
|
+
tool_call_id: entry.toolResult.output || '',
|
|
2588
|
+
content: JSON.stringify(entry.toolResult)
|
|
2589
|
+
});
|
|
2590
|
+
}
|
|
2591
|
+
}
|
|
2592
|
+
return removedCount;
|
|
2593
|
+
}
|
|
2497
2594
|
/**
|
|
2498
2595
|
* Get all tool instances and their class names for display purposes
|
|
2499
2596
|
*/
|