@majkapp/majk-chat-cli 1.0.15 → 1.0.20
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/cli.js +180 -103
- package/dist/cli.js.map +1 -1
- package/dist/executors/claude-code.executor.d.ts +15 -0
- package/dist/executors/claude-code.executor.d.ts.map +1 -0
- package/dist/executors/claude-code.executor.js +249 -0
- package/dist/executors/claude-code.executor.js.map +1 -0
- package/dist/executors/executor-factory.d.ts +8 -0
- package/dist/executors/executor-factory.d.ts.map +1 -0
- package/dist/executors/executor-factory.js +59 -0
- package/dist/executors/executor-factory.js.map +1 -0
- package/dist/executors/executor.interface.d.ts +46 -0
- package/dist/executors/executor.interface.d.ts.map +1 -0
- package/dist/executors/executor.interface.js +3 -0
- package/dist/executors/executor.interface.js.map +1 -0
- package/dist/executors/index.d.ts +5 -0
- package/dist/executors/index.d.ts.map +1 -0
- package/dist/executors/index.js +21 -0
- package/dist/executors/index.js.map +1 -0
- package/dist/executors/majk.executor.d.ts +12 -0
- package/dist/executors/majk.executor.d.ts.map +1 -0
- package/dist/executors/majk.executor.js +283 -0
- package/dist/executors/majk.executor.js.map +1 -0
- package/dist/majk-chat-standalone.cjs +660 -468
- package/package.json +6 -6
package/dist/cli.js
CHANGED
|
@@ -49,8 +49,6 @@ const interactive_1 = require("./interactive/interactive");
|
|
|
49
49
|
const credentials_1 = require("./utils/credentials");
|
|
50
50
|
const profile_config_1 = require("./utils/profile-config");
|
|
51
51
|
const config_1 = require("./utils/config");
|
|
52
|
-
const bash_tool_1 = require("./tools/bash.tool");
|
|
53
|
-
const filesystem_tool_1 = require("./tools/filesystem.tool");
|
|
54
52
|
const majk_chat_mcp_1 = require("@majkapp/majk-chat-mcp");
|
|
55
53
|
const majk_chat_basic_tools_1 = require("@majkapp/majk-chat-basic-tools");
|
|
56
54
|
const majk_chat_document_tools_1 = require("@majkapp/majk-chat-document-tools");
|
|
@@ -58,13 +56,14 @@ const majk_chat_sessions_1 = require("@majkapp/majk-chat-sessions");
|
|
|
58
56
|
const models_1 = require("./utils/models");
|
|
59
57
|
const tool_filter_1 = require("./utils/tool-filter");
|
|
60
58
|
const output_1 = require("./utils/output");
|
|
59
|
+
const executors_1 = require("./executors");
|
|
61
60
|
// Load environment variables
|
|
62
61
|
dotenv_1.default.config();
|
|
63
62
|
const program = new commander_1.Command();
|
|
64
63
|
program
|
|
65
64
|
.name('majk-chat')
|
|
66
65
|
.description('CLI for multi-provider LLM chat interactions')
|
|
67
|
-
.version('1.0.
|
|
66
|
+
.version('1.0.20');
|
|
68
67
|
// Add credential options helper function
|
|
69
68
|
function addCredentialOptions(command) {
|
|
70
69
|
return command
|
|
@@ -92,13 +91,15 @@ function addCredentialOptions(command) {
|
|
|
92
91
|
}
|
|
93
92
|
// Chat command
|
|
94
93
|
const chatCommand = program
|
|
95
|
-
.command('chat')
|
|
94
|
+
.command('chat [message...]')
|
|
96
95
|
.description('Send a chat message to an LLM provider')
|
|
96
|
+
.option('--agent <type>', 'Executor to use: "majk" (default) or "claude-code". Can also be set via MAJK_AGENT environment variable')
|
|
97
97
|
.option('--provider <provider>', 'Provider to use (openai, anthropic, azure-openai, bedrock)')
|
|
98
98
|
.option('--model <model>', 'Model or alias (e.g., "sonnet", "opus", "claude-3-5-sonnet-20241022")')
|
|
99
99
|
.option('-M, --message <message>', 'Message to send')
|
|
100
100
|
.option('-p <value>', 'JSON messages array or prompt string')
|
|
101
101
|
.option('-f, --file <file>', 'Read message from file')
|
|
102
|
+
.option('--image <paths...>', 'One or more image file paths to include with the message (PNG, JPEG, GIF, WebP)')
|
|
102
103
|
.option('--prompts <file>', 'File with one prompt per line (sequential execution)')
|
|
103
104
|
.option('-s, --system <system>', 'System message')
|
|
104
105
|
.option('-S, --system-file <file>', 'Read system message from file')
|
|
@@ -107,7 +108,7 @@ const chatCommand = program
|
|
|
107
108
|
.option('--max-tokens <tokens>', 'Maximum tokens', parseInt)
|
|
108
109
|
.option('-j, --json', 'Output JSON response')
|
|
109
110
|
.option('--output-format <format>', 'Output format: "text" (default) or "stream-json"', 'text')
|
|
110
|
-
.option('--tools', 'Enable
|
|
111
|
+
.option('--tools', 'Enable core tools (bash, read, write, etc.) - equivalent to --enable-core-tools')
|
|
111
112
|
.option('--enable-core-tools', 'Enable majk-chat-basic-tools (bash, ls, read, etc.)')
|
|
112
113
|
.option('--enable-read-only-tools', 'Enable read-only majk-chat-basic-tools (ls, read, grep, web_fetch, etc.)')
|
|
113
114
|
.option('--disable-tools', 'Disable all tools including read-only tools (overrides defaults)')
|
|
@@ -129,13 +130,23 @@ const chatCommand = program
|
|
|
129
130
|
.option('--list-sessions', 'List all sessions for current directory')
|
|
130
131
|
.option('--delete-session <uuid>', 'Delete a specific session by UUID')
|
|
131
132
|
.option('--dry-run', 'Enable dry run mode - plan operations without executing them')
|
|
132
|
-
.option('--dry-run-review', 'Enable dry run mode with interactive review and execution of planned operations')
|
|
133
|
+
.option('--dry-run-review', 'Enable dry run mode with interactive review and execution of planned operations')
|
|
134
|
+
.option('--save-prompts <file>', 'Save all prompts to JSONL file for analysis and debugging');
|
|
133
135
|
addCredentialOptions(chatCommand)
|
|
134
|
-
.action(async (options) => {
|
|
136
|
+
.action(async (messageArgs, options) => {
|
|
135
137
|
let cleanup = null;
|
|
136
138
|
// Initialize output handler early so we can pass callbacks
|
|
137
139
|
const outputHandler = new output_1.OutputHandler(options.outputFormat);
|
|
140
|
+
// Handle positional message arguments
|
|
141
|
+
if (messageArgs && messageArgs.length > 0 && !options.message && !options.file && !options.p) {
|
|
142
|
+
options.message = messageArgs.join(' ');
|
|
143
|
+
}
|
|
138
144
|
try {
|
|
145
|
+
const agentType = options.agent || process.env.MAJK_AGENT || 'majk';
|
|
146
|
+
if (agentType === 'claude-code' || agentType === 'claude') {
|
|
147
|
+
await handleClaudeCodeExecutor(options, outputHandler);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
139
150
|
const setupOptions = {
|
|
140
151
|
...options,
|
|
141
152
|
outputFormat: options.outputFormat, // Pass output format to suppress logs
|
|
@@ -254,11 +265,11 @@ addCredentialOptions(chatCommand)
|
|
|
254
265
|
messages: allMessages,
|
|
255
266
|
temperature: options.temperature,
|
|
256
267
|
max_tokens: options.maxTokens,
|
|
257
|
-
// Always include tools if any are registered (from MCP or
|
|
268
|
+
// Always include tools if any are registered (from MCP or basic tools)
|
|
258
269
|
tools: tools.length > 0 ? tools : undefined,
|
|
259
270
|
// Enable auto-execution if tools are enabled (default unless --disable-tools) or MCP configured
|
|
260
271
|
max_steps: (options.tools || !options.disableTools || options.mcpConfig || options.mcpServers)
|
|
261
|
-
? (options.maxSteps || 5)
|
|
272
|
+
? (options.maxSteps || (!options.disableTools && !options.tools && !options.mcpConfig && !options.mcpServers ? 500 : 5))
|
|
262
273
|
: 0,
|
|
263
274
|
// Request transcript when saving sessions to capture complete tool execution history
|
|
264
275
|
return_transcript: usesSessions
|
|
@@ -351,7 +362,7 @@ const interactiveCommand = program
|
|
|
351
362
|
.option('-m, --model <model>', 'Model to use')
|
|
352
363
|
.option('-s, --system <system>', 'System message')
|
|
353
364
|
.option('-S, --system-file <file>', 'Read system message from file')
|
|
354
|
-
.option('--tools', 'Enable
|
|
365
|
+
.option('--tools', 'Enable core tools (bash, read, write, etc.) - equivalent to --enable-core-tools')
|
|
355
366
|
.option('--enable-core-tools', 'Enable majk-chat-basic-tools (bash, ls, read, etc.)')
|
|
356
367
|
.option('--enable-read-only-tools', 'Enable read-only majk-chat-basic-tools (ls, read, grep, web_fetch, etc.)')
|
|
357
368
|
.option('--disable-tools', 'Disable all tools including read-only tools (overrides defaults)')
|
|
@@ -374,7 +385,7 @@ addCredentialOptions(interactiveCommand)
|
|
|
374
385
|
const { chat, toolRegistry } = setupResult;
|
|
375
386
|
cleanup = setupResult.cleanup;
|
|
376
387
|
const systemMessage = await getSystemMessage(options);
|
|
377
|
-
// Check if we have tools available from MCP or
|
|
388
|
+
// Check if we have tools available from MCP or basic tools
|
|
378
389
|
const hasTools = toolRegistry.getDefinitions().length > 0;
|
|
379
390
|
const interactive = new interactive_1.InteractiveMode(chat, {
|
|
380
391
|
provider: options.provider,
|
|
@@ -698,6 +709,74 @@ program
|
|
|
698
709
|
}
|
|
699
710
|
});
|
|
700
711
|
// Helper functions
|
|
712
|
+
async function handleClaudeCodeExecutor(options, outputHandler) {
|
|
713
|
+
try {
|
|
714
|
+
await executors_1.ExecutorFactory.validateExecutorChoice('claude-code');
|
|
715
|
+
const messages = await buildMessages(options);
|
|
716
|
+
if (!messages || messages.length === 0) {
|
|
717
|
+
outputHandler.outputError('No message provided');
|
|
718
|
+
process.exit(1);
|
|
719
|
+
}
|
|
720
|
+
const credOptions = extractCredentialOptions(options);
|
|
721
|
+
const executorOptions = {
|
|
722
|
+
provider: options.provider,
|
|
723
|
+
model: options.model,
|
|
724
|
+
messages,
|
|
725
|
+
temperature: options.temperature,
|
|
726
|
+
maxTokens: options.maxTokens,
|
|
727
|
+
maxSteps: options.maxSteps,
|
|
728
|
+
systemPrompt: options.system || options.appendSystemPrompt,
|
|
729
|
+
outputFormat: options.outputFormat || 'text',
|
|
730
|
+
tools: options.tools,
|
|
731
|
+
enableCoreTools: options.enableCoreTools || options.tools,
|
|
732
|
+
enableReadOnlyTools: options.enableReadOnlyTools,
|
|
733
|
+
disableTools: options.disableTools,
|
|
734
|
+
planningMode: options.planningMode,
|
|
735
|
+
mcpConfig: options.mcpConfig,
|
|
736
|
+
mcpServers: options.mcpServers,
|
|
737
|
+
allowedTools: options.allowedTools,
|
|
738
|
+
disallowedTools: options.disallowedTools,
|
|
739
|
+
permissionPromptTool: options.permissionPromptTool,
|
|
740
|
+
bedrockApiKey: credOptions.bedrockApiKey,
|
|
741
|
+
awsAccessKeyId: credOptions.awsAccessKeyId,
|
|
742
|
+
awsSecretAccessKey: credOptions.awsSecretAccessKey,
|
|
743
|
+
awsSessionToken: credOptions.awsSessionToken,
|
|
744
|
+
awsRegion: credOptions.awsRegion,
|
|
745
|
+
anthropicApiKey: credOptions.anthropicApiKey,
|
|
746
|
+
openaiApiKey: credOptions.openaiApiKey,
|
|
747
|
+
cwd: process.cwd(),
|
|
748
|
+
onToolCall: options.outputFormat === 'stream-json'
|
|
749
|
+
? (toolCall) => outputHandler.outputToolCallMessage(toolCall)
|
|
750
|
+
: undefined,
|
|
751
|
+
onToolResult: options.outputFormat === 'stream-json'
|
|
752
|
+
? (toolCall, result) => outputHandler.outputToolResult(toolCall.id, result)
|
|
753
|
+
: undefined
|
|
754
|
+
};
|
|
755
|
+
const executor = executors_1.ExecutorFactory.create('claude-code');
|
|
756
|
+
const spinner = outputHandler.startSpinner('Sending message...');
|
|
757
|
+
const apiStart = Date.now();
|
|
758
|
+
const result = await executor.execute(executorOptions);
|
|
759
|
+
const apiDuration = Date.now() - apiStart;
|
|
760
|
+
if (spinner)
|
|
761
|
+
spinner.succeed('Response received');
|
|
762
|
+
if (options.json) {
|
|
763
|
+
console.log(JSON.stringify(result.response, null, 2));
|
|
764
|
+
}
|
|
765
|
+
else {
|
|
766
|
+
const assistantMessage = result.response.choices[0].message;
|
|
767
|
+
const content = typeof assistantMessage.content === 'string'
|
|
768
|
+
? assistantMessage.content
|
|
769
|
+
: JSON.stringify(assistantMessage.content);
|
|
770
|
+
outputHandler.outputMessage('assistant', content, result.response.usage, assistantMessage.tool_calls);
|
|
771
|
+
outputHandler.outputComplete(result.response.usage, apiDuration);
|
|
772
|
+
}
|
|
773
|
+
process.exit(0);
|
|
774
|
+
}
|
|
775
|
+
catch (error) {
|
|
776
|
+
outputHandler.outputError(error instanceof Error ? error.message : String(error));
|
|
777
|
+
process.exit(1);
|
|
778
|
+
}
|
|
779
|
+
}
|
|
701
780
|
// Extract credential options from CLI arguments
|
|
702
781
|
function extractCredentialOptions(options) {
|
|
703
782
|
return {
|
|
@@ -790,38 +869,16 @@ async function setupChat(options) {
|
|
|
790
869
|
if (!hasValidCredentials) {
|
|
791
870
|
throw new Error('No valid API credentials found. Please provide API keys via command line options, environment variables, or .env files. Use --help to see available credential options.');
|
|
792
871
|
}
|
|
793
|
-
// Add tools if enabled
|
|
794
|
-
if (options.tools) {
|
|
795
|
-
builder
|
|
796
|
-
.withTool(new bash_tool_1.BashTool())
|
|
797
|
-
.withTool(new filesystem_tool_1.FileSystemTool())
|
|
798
|
-
.withAutoToolExecution(options.maxSteps || 5);
|
|
799
|
-
// Override default context management if user specified custom tool result limit
|
|
800
|
-
if (options.toolResultLimit && !isNaN(options.toolResultLimit) && options.toolResultLimit > 0) {
|
|
801
|
-
builder.withContextManagement({
|
|
802
|
-
enableTruncation: true,
|
|
803
|
-
maxLength: options.toolResultLimit,
|
|
804
|
-
conversationId: options.requestId || 'cli-session'
|
|
805
|
-
});
|
|
806
|
-
}
|
|
807
|
-
}
|
|
808
872
|
// Add tools - now enabled by default unless explicitly disabled
|
|
809
873
|
const shouldEnableTools = !options.disableTools; // Default to true unless --disable-tools is used
|
|
810
874
|
const enableReadOnlyTools = shouldEnableTools && (options.enableReadOnlyTools !== false); // Default to true
|
|
811
|
-
const enableCoreTools = options.enableCoreTools;
|
|
875
|
+
const enableCoreTools = options.enableCoreTools || options.tools; // --tools now enables core tools
|
|
812
876
|
const enablePlanningMode = options.planningMode;
|
|
813
877
|
if (enableCoreTools || enableReadOnlyTools || enablePlanningMode) {
|
|
814
878
|
const toolRegistry = builder.getToolRegistry();
|
|
815
879
|
if (toolRegistry) {
|
|
816
|
-
// Configure basic tools
|
|
880
|
+
// Configure basic tools
|
|
817
881
|
const basicToolsConfig = {};
|
|
818
|
-
if (enablePlanningMode) {
|
|
819
|
-
basicToolsConfig.planningMode = {
|
|
820
|
-
enabled: true,
|
|
821
|
-
reminderInterval: options.todoReminderInterval || 3,
|
|
822
|
-
autoReminders: !options.disableAutoReminders
|
|
823
|
-
};
|
|
824
|
-
}
|
|
825
882
|
// Register appropriate tool set based on flags
|
|
826
883
|
if (enableCoreTools || enablePlanningMode) {
|
|
827
884
|
// Register all tools (including write/execute tools)
|
|
@@ -835,29 +892,54 @@ async function setupChat(options) {
|
|
|
835
892
|
// Register document tools (they are inherently read-only)
|
|
836
893
|
(0, majk_chat_document_tools_1.registerDocumentTools)(toolRegistry);
|
|
837
894
|
}
|
|
838
|
-
// Setup planning mode reminders if enabled
|
|
839
|
-
if (options.planningMode) {
|
|
840
|
-
const instanceId = options.requestId || 'cli-session';
|
|
841
|
-
(0, majk_chat_basic_tools_1.setupPlanningModeReminders)(instanceId, basicToolsConfig);
|
|
842
|
-
}
|
|
843
895
|
// Apply tool filtering if specified
|
|
844
896
|
if (options.allowedTools || options.disallowedTools) {
|
|
845
897
|
applyToolFiltering(toolRegistry, options.allowedTools, options.disallowedTools);
|
|
846
898
|
}
|
|
847
|
-
// Setup
|
|
899
|
+
// Setup context management with truncation using ContextManagementExtension
|
|
848
900
|
// Handle the case where toolResultLimit might be null or NaN from commander parsing
|
|
849
901
|
let toolResultLimit = 2000; // Much smaller default to handle large files within context limits
|
|
850
902
|
if (options.toolResultLimit && !isNaN(options.toolResultLimit) && options.toolResultLimit > 0) {
|
|
851
903
|
toolResultLimit = options.toolResultLimit;
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
904
|
+
}
|
|
905
|
+
// Always setup context management with the extension (replaces legacy setupToolResultManagement)
|
|
906
|
+
builder.withContextManagement({
|
|
907
|
+
enableTruncation: true,
|
|
908
|
+
maxLength: toolResultLimit,
|
|
909
|
+
conversationId: options.requestId || 'cli-session'
|
|
910
|
+
});
|
|
911
|
+
// Setup prompt logging if requested
|
|
912
|
+
if (options.savePrompts) {
|
|
913
|
+
builder.withExtension(new majk_chat_core_1.PromptLoggingExtension({
|
|
914
|
+
filePath: options.savePrompts,
|
|
915
|
+
includeContext: true,
|
|
916
|
+
includeTools: true,
|
|
917
|
+
includeMessages: true,
|
|
918
|
+
append: true
|
|
919
|
+
}));
|
|
920
|
+
console.log(chalk_1.default.cyan(`📝 Prompt logging enabled: ${options.savePrompts}`));
|
|
921
|
+
}
|
|
922
|
+
// Setup planning mode extension if requested
|
|
923
|
+
if (enablePlanningMode) {
|
|
924
|
+
builder.withPlanningMode({
|
|
925
|
+
enabled: true,
|
|
926
|
+
autoActivation: {
|
|
927
|
+
enabled: true,
|
|
928
|
+
complexityThreshold: 70
|
|
929
|
+
},
|
|
930
|
+
guidance: {
|
|
931
|
+
reminderInterval: options.todoReminderInterval || 3,
|
|
932
|
+
enableProgressTracking: !options.disableAutoReminders
|
|
933
|
+
},
|
|
934
|
+
session: {
|
|
935
|
+
conversationId: options.requestId || 'cli-session'
|
|
936
|
+
}
|
|
857
937
|
});
|
|
938
|
+
console.log(chalk_1.default.cyan(`🎯 Planning mode enabled: Research → Plan → Execute workflow`));
|
|
858
939
|
}
|
|
859
|
-
|
|
860
|
-
|
|
940
|
+
// Set default steps based on tool type - 500 for read-only tools by default, 5 for other scenarios
|
|
941
|
+
const defaultSteps = enableReadOnlyTools && !enableCoreTools && !enablePlanningMode ? 500 : 5;
|
|
942
|
+
builder.withAutoToolExecution(options.maxSteps || defaultSteps);
|
|
861
943
|
}
|
|
862
944
|
}
|
|
863
945
|
let mcpPlugin = null;
|
|
@@ -867,14 +949,6 @@ async function setupChat(options) {
|
|
|
867
949
|
// Enable auto tool execution if MCP is configured
|
|
868
950
|
if (!options.tools) {
|
|
869
951
|
builder.withAutoToolExecution(options.maxSteps || 5);
|
|
870
|
-
// Override default context management if user specified custom tool result limit
|
|
871
|
-
if (options.toolResultLimit && !isNaN(options.toolResultLimit) && options.toolResultLimit > 0) {
|
|
872
|
-
builder.withContextManagement({
|
|
873
|
-
enableTruncation: true,
|
|
874
|
-
maxLength: options.toolResultLimit,
|
|
875
|
-
conversationId: options.requestId || 'cli-session'
|
|
876
|
-
});
|
|
877
|
-
}
|
|
878
952
|
}
|
|
879
953
|
}
|
|
880
954
|
// Set tool callbacks if provided
|
|
@@ -921,6 +995,31 @@ async function setupChat(options) {
|
|
|
921
995
|
}
|
|
922
996
|
};
|
|
923
997
|
}
|
|
998
|
+
async function loadImageFromPath(filePath) {
|
|
999
|
+
const resolvedPath = path.resolve(filePath.replace(/^~/, process.env.HOME || '~'));
|
|
1000
|
+
const ext = path.extname(resolvedPath).toLowerCase();
|
|
1001
|
+
const mediaTypeMap = {
|
|
1002
|
+
'.png': 'image/png',
|
|
1003
|
+
'.jpg': 'image/jpeg',
|
|
1004
|
+
'.jpeg': 'image/jpeg',
|
|
1005
|
+
'.gif': 'image/gif',
|
|
1006
|
+
'.webp': 'image/webp'
|
|
1007
|
+
};
|
|
1008
|
+
const media_type = mediaTypeMap[ext];
|
|
1009
|
+
if (!media_type) {
|
|
1010
|
+
throw new Error(`Unsupported image format: ${ext}. Supported: .png, .jpg, .jpeg, .gif, .webp`);
|
|
1011
|
+
}
|
|
1012
|
+
const buffer = await fs.readFile(resolvedPath);
|
|
1013
|
+
const base64Data = buffer.toString('base64');
|
|
1014
|
+
return {
|
|
1015
|
+
type: 'image',
|
|
1016
|
+
source: {
|
|
1017
|
+
type: 'base64',
|
|
1018
|
+
media_type,
|
|
1019
|
+
data: base64Data
|
|
1020
|
+
}
|
|
1021
|
+
};
|
|
1022
|
+
}
|
|
924
1023
|
async function buildMessages(options) {
|
|
925
1024
|
const messages = [];
|
|
926
1025
|
// Add system message if provided
|
|
@@ -952,7 +1051,31 @@ async function buildMessages(options) {
|
|
|
952
1051
|
// Use traditional message options
|
|
953
1052
|
const message = await getMessage(options);
|
|
954
1053
|
if (message) {
|
|
955
|
-
|
|
1054
|
+
// Check if images are provided
|
|
1055
|
+
if (options.image && Array.isArray(options.image) && options.image.length > 0) {
|
|
1056
|
+
// Build multi-modal content with text + images
|
|
1057
|
+
const contentBlocks = [];
|
|
1058
|
+
// Add text block first
|
|
1059
|
+
contentBlocks.push({
|
|
1060
|
+
type: 'text',
|
|
1061
|
+
text: message
|
|
1062
|
+
});
|
|
1063
|
+
// Add image blocks
|
|
1064
|
+
for (const imagePath of options.image) {
|
|
1065
|
+
try {
|
|
1066
|
+
const imageBlock = await loadImageFromPath(imagePath);
|
|
1067
|
+
contentBlocks.push(imageBlock);
|
|
1068
|
+
}
|
|
1069
|
+
catch (error) {
|
|
1070
|
+
throw new Error(`Failed to load image ${imagePath}: ${error instanceof Error ? error.message : error}`);
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
messages.push({ role: 'user', content: contentBlocks });
|
|
1074
|
+
}
|
|
1075
|
+
else {
|
|
1076
|
+
// Simple text message
|
|
1077
|
+
messages.push({ role: 'user', content: message });
|
|
1078
|
+
}
|
|
956
1079
|
}
|
|
957
1080
|
}
|
|
958
1081
|
return messages;
|
|
@@ -1227,52 +1350,6 @@ function applyToolFiltering(registry, allowedTools, disallowedTools) {
|
|
|
1227
1350
|
}
|
|
1228
1351
|
}
|
|
1229
1352
|
}
|
|
1230
|
-
/**
|
|
1231
|
-
* Setup tool result management with automatic ReadToolResult registration
|
|
1232
|
-
*/
|
|
1233
|
-
function setupToolResultManagement(builder, resultLimit, options) {
|
|
1234
|
-
let readToolResultRegistered = false;
|
|
1235
|
-
const truncationConfig = {
|
|
1236
|
-
maxLength: resultLimit,
|
|
1237
|
-
previewLength: Math.floor(resultLimit * 0.6),
|
|
1238
|
-
tailLength: Math.floor(resultLimit * 0.3),
|
|
1239
|
-
storeResult: true
|
|
1240
|
-
};
|
|
1241
|
-
// Set up tool result callback to handle truncation
|
|
1242
|
-
const originalOnToolResult = options.onToolResult;
|
|
1243
|
-
const onToolResult = (toolName, result, context) => {
|
|
1244
|
-
// Check if result should be truncated
|
|
1245
|
-
if (majk_chat_basic_tools_1.ToolResultTruncator.shouldTruncate(result, truncationConfig)) {
|
|
1246
|
-
// Set conversation ID from context if available
|
|
1247
|
-
const conversationId = context?.metadata?.conversationId || context?.requestId || 'cli-session';
|
|
1248
|
-
const configWithConversation = { ...truncationConfig, conversationId };
|
|
1249
|
-
// Process the result with truncation
|
|
1250
|
-
const truncatedResult = majk_chat_basic_tools_1.ToolResultTruncator.processToolResult(result, toolName, configWithConversation);
|
|
1251
|
-
// Auto-register ReadToolResult tool on first truncation
|
|
1252
|
-
if (!readToolResultRegistered && truncatedResult.truncated) {
|
|
1253
|
-
const registry = builder.getToolRegistry();
|
|
1254
|
-
if (registry && !registry.has('read_tool_result')) {
|
|
1255
|
-
registry.register(new majk_chat_basic_tools_1.ReadToolResultTool());
|
|
1256
|
-
readToolResultRegistered = true;
|
|
1257
|
-
console.log(chalk_1.default.yellow('📋 Large tool result detected. ReadToolResult tool auto-registered.'));
|
|
1258
|
-
console.log(chalk_1.default.gray(` Use read_tool_result with ID: ${truncatedResult.full_result_id}`));
|
|
1259
|
-
}
|
|
1260
|
-
}
|
|
1261
|
-
// Call original callback with truncated result
|
|
1262
|
-
if (originalOnToolResult) {
|
|
1263
|
-
originalOnToolResult(toolName, truncatedResult, context);
|
|
1264
|
-
}
|
|
1265
|
-
return truncatedResult;
|
|
1266
|
-
}
|
|
1267
|
-
// Call original callback for non-truncated results
|
|
1268
|
-
if (originalOnToolResult) {
|
|
1269
|
-
originalOnToolResult(toolName, result, context);
|
|
1270
|
-
}
|
|
1271
|
-
return result;
|
|
1272
|
-
};
|
|
1273
|
-
// Update the options to include our callback
|
|
1274
|
-
options.onToolResult = onToolResult;
|
|
1275
|
-
}
|
|
1276
1353
|
// Session helper functions
|
|
1277
1354
|
async function handleListSessions(sessionManager, workingDirectory, outputHandler) {
|
|
1278
1355
|
try {
|