sam-coder-cli 1.0.61 → 1.0.62
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/bin/agi-cli.js +6 -83
- package/bin/ui.js +21 -1
- package/package.json +1 -1
package/bin/agi-cli.js
CHANGED
|
@@ -557,7 +557,6 @@ const agentUtils = {
|
|
|
557
557
|
// Extract JSON from markdown code blocks
|
|
558
558
|
function extractJsonFromMarkdown(text) {
|
|
559
559
|
if (!text || typeof text !== 'string') {
|
|
560
|
-
console.error('Invalid input to extractJsonFromMarkdown:', typeof text);
|
|
561
560
|
return null;
|
|
562
561
|
}
|
|
563
562
|
|
|
@@ -569,13 +568,11 @@ function extractJsonFromMarkdown(text) {
|
|
|
569
568
|
try {
|
|
570
569
|
const jsonStr = match[1].trim();
|
|
571
570
|
if (!jsonStr) {
|
|
572
|
-
console.error('Empty JSON content in markdown block');
|
|
573
571
|
return null;
|
|
574
572
|
}
|
|
575
573
|
return JSON.parse(jsonStr);
|
|
576
574
|
} catch (error) {
|
|
577
|
-
|
|
578
|
-
console.error('JSON content was:', match[1]);
|
|
575
|
+
// ignore
|
|
579
576
|
}
|
|
580
577
|
}
|
|
581
578
|
|
|
@@ -615,8 +612,6 @@ function extractJsonFromMarkdown(text) {
|
|
|
615
612
|
// Last resort failed
|
|
616
613
|
}
|
|
617
614
|
|
|
618
|
-
console.error('Failed to extract valid JSON from response');
|
|
619
|
-
console.error('Response text was:', text);
|
|
620
615
|
return null;
|
|
621
616
|
}
|
|
622
617
|
|
|
@@ -757,27 +752,6 @@ function normalizeToolCallsFromMessage(message) {
|
|
|
757
752
|
return message;
|
|
758
753
|
}
|
|
759
754
|
|
|
760
|
-
// Ask the model to produce a structured follow-up with thinking and either tool_calls or JSON action
|
|
761
|
-
async function requestStructuredFollowup(messages, currentModel, preferTools = true) {
|
|
762
|
-
const instruction = preferTools
|
|
763
|
-
? 'Think step-by-step inside <think></think>. Then, if any tools are needed, call them via tool_calls. If no tools are required, output a single markdown ```json code block with an action object (type, data, reasoning) per the schema. Do not include any other text.'
|
|
764
|
-
: 'Think step-by-step inside <think></think>, then output a single markdown ```json code block with an action object (type, data, reasoning) per the schema. Do not include any other text.';
|
|
765
|
-
|
|
766
|
-
const followupUser = { role: 'user', content: instruction };
|
|
767
|
-
const followupMessages = [...messages, followupUser];
|
|
768
|
-
const responseObj = await callOpenRouter(followupMessages, currentModel, !preferTools);
|
|
769
|
-
const assistantMessage = responseObj.choices[0].message;
|
|
770
|
-
if (assistantMessage && typeof assistantMessage.content === 'string') {
|
|
771
|
-
const { thought, content } = splitThinking(assistantMessage.content);
|
|
772
|
-
if (thought && SHOW_THOUGHTS) {
|
|
773
|
-
ui.showInfo(`Thinking:\n${thought}`);
|
|
774
|
-
}
|
|
775
|
-
assistantMessage.content = content;
|
|
776
|
-
}
|
|
777
|
-
normalizeToolCallsFromMessage(assistantMessage);
|
|
778
|
-
return { assistantMessage, updatedMessages: [...followupMessages, assistantMessage] };
|
|
779
|
-
}
|
|
780
|
-
|
|
781
755
|
// Call OpenRouter API with tool calling
|
|
782
756
|
async function callOpenRouter(messages, currentModel, useJson = false) {
|
|
783
757
|
const apiKey = OPENROUTER_API_KEY;
|
|
@@ -838,7 +812,7 @@ async function processQueryWithTools(query, conversation = [], currentModel) {
|
|
|
838
812
|
if (assistantMessage && typeof assistantMessage.content === 'string') {
|
|
839
813
|
const { thought, content } = splitThinking(assistantMessage.content);
|
|
840
814
|
if (thought && SHOW_THOUGHTS) {
|
|
841
|
-
ui.
|
|
815
|
+
ui.showThought(thought);
|
|
842
816
|
}
|
|
843
817
|
assistantMessage.content = content;
|
|
844
818
|
}
|
|
@@ -862,7 +836,7 @@ async function processQueryWithTools(query, conversation = [], currentModel) {
|
|
|
862
836
|
if (finalAssistantMessage && typeof finalAssistantMessage.content === 'string') {
|
|
863
837
|
const { thought, content } = splitThinking(finalAssistantMessage.content);
|
|
864
838
|
if (thought && SHOW_THOUGHTS) {
|
|
865
|
-
ui.
|
|
839
|
+
ui.showThought(thought);
|
|
866
840
|
}
|
|
867
841
|
finalAssistantMessage.content = content;
|
|
868
842
|
}
|
|
@@ -887,7 +861,7 @@ async function processQueryWithTools(query, conversation = [], currentModel) {
|
|
|
887
861
|
if (finalAssistantMessage && typeof finalAssistantMessage.content === 'string') {
|
|
888
862
|
const { thought, content } = splitThinking(finalAssistantMessage.content);
|
|
889
863
|
if (thought && SHOW_THOUGHTS) {
|
|
890
|
-
ui.
|
|
864
|
+
ui.showThought(thought);
|
|
891
865
|
}
|
|
892
866
|
finalAssistantMessage.content = content;
|
|
893
867
|
}
|
|
@@ -900,57 +874,6 @@ async function processQueryWithTools(query, conversation = [], currentModel) {
|
|
|
900
874
|
// If fallback execution fails, just return original assistant content
|
|
901
875
|
}
|
|
902
876
|
}
|
|
903
|
-
// Final attempt: request a structured follow-up that includes thinking and tool calls
|
|
904
|
-
try {
|
|
905
|
-
ui.startThinking();
|
|
906
|
-
const { assistantMessage: structuredMsg, updatedMessages } = await requestStructuredFollowup(messages, currentModel, true);
|
|
907
|
-
messages.length = 0; updatedMessages.forEach(m => messages.push(m));
|
|
908
|
-
|
|
909
|
-
// If tool calls present now, execute them
|
|
910
|
-
if (structuredMsg.tool_calls && structuredMsg.tool_calls.length) {
|
|
911
|
-
const toolResults2 = await handleToolCalls(structuredMsg.tool_calls, messages);
|
|
912
|
-
messages.push(...toolResults2);
|
|
913
|
-
const finalResponseObj2 = await callOpenRouter(messages, currentModel);
|
|
914
|
-
const finalAssistantMessage2 = finalResponseObj2.choices[0].message;
|
|
915
|
-
if (finalAssistantMessage2 && typeof finalAssistantMessage2.content === 'string') {
|
|
916
|
-
const { thought, content } = splitThinking(finalAssistantMessage2.content);
|
|
917
|
-
if (thought && SHOW_THOUGHTS) ui.showInfo(`Thinking:\n${thought}`);
|
|
918
|
-
finalAssistantMessage2.content = content;
|
|
919
|
-
}
|
|
920
|
-
messages.push(finalAssistantMessage2);
|
|
921
|
-
ui.stopThinking();
|
|
922
|
-
return { response: finalAssistantMessage2.content, conversation: messages };
|
|
923
|
-
}
|
|
924
|
-
|
|
925
|
-
// Else try JSON action again from the structured response
|
|
926
|
-
const structuredAction = extractJsonFromMarkdown(structuredMsg.content);
|
|
927
|
-
if (structuredAction && structuredAction.type) {
|
|
928
|
-
try {
|
|
929
|
-
const result2 = await executeAction(structuredAction);
|
|
930
|
-
messages.push({ role: 'user', content: `Action result (${structuredAction.type}): ${result2}` });
|
|
931
|
-
const finalResponseObj3 = await callOpenRouter(messages, currentModel);
|
|
932
|
-
const finalAssistantMessage3 = finalResponseObj3.choices[0].message;
|
|
933
|
-
if (finalAssistantMessage3 && typeof finalAssistantMessage3.content === 'string') {
|
|
934
|
-
const { thought, content } = splitThinking(finalAssistantMessage3.content);
|
|
935
|
-
if (thought && SHOW_THOUGHTS) ui.showInfo(`Thinking:\n${thought}`);
|
|
936
|
-
finalAssistantMessage3.content = content;
|
|
937
|
-
}
|
|
938
|
-
messages.push(finalAssistantMessage3);
|
|
939
|
-
ui.stopThinking();
|
|
940
|
-
return { response: finalAssistantMessage3.content, conversation: messages };
|
|
941
|
-
} catch (_) {
|
|
942
|
-
ui.stopThinking();
|
|
943
|
-
}
|
|
944
|
-
}
|
|
945
|
-
|
|
946
|
-
ui.stopThinking();
|
|
947
|
-
return {
|
|
948
|
-
response: structuredMsg.content,
|
|
949
|
-
conversation: messages
|
|
950
|
-
};
|
|
951
|
-
} catch (_) {
|
|
952
|
-
// ignore and fall back to original assistant message
|
|
953
|
-
}
|
|
954
877
|
ui.stopThinking();
|
|
955
878
|
return {
|
|
956
879
|
response: assistantMessage.content,
|
|
@@ -1080,7 +1003,7 @@ async function processQuery(query, conversation = [], currentModel) {
|
|
|
1080
1003
|
if (assistantMessage && typeof assistantMessage.content === 'string') {
|
|
1081
1004
|
const { thought, content } = splitThinking(assistantMessage.content);
|
|
1082
1005
|
if (thought && SHOW_THOUGHTS) {
|
|
1083
|
-
ui.
|
|
1006
|
+
ui.showThought(thought);
|
|
1084
1007
|
}
|
|
1085
1008
|
assistantMessage.content = content;
|
|
1086
1009
|
}
|
|
@@ -1140,7 +1063,7 @@ async function processQuery(query, conversation = [], currentModel) {
|
|
|
1140
1063
|
if (finalAssistantMessage && typeof finalAssistantMessage.content === 'string') {
|
|
1141
1064
|
const { thought, content } = splitThinking(finalAssistantMessage.content);
|
|
1142
1065
|
if (thought && SHOW_THOUGHTS) {
|
|
1143
|
-
ui.
|
|
1066
|
+
ui.showThought(thought);
|
|
1144
1067
|
}
|
|
1145
1068
|
finalResponse = content;
|
|
1146
1069
|
} else {
|
package/bin/ui.js
CHANGED
|
@@ -72,6 +72,25 @@ function showAGIStatus(status) {
|
|
|
72
72
|
console.log(chalk.cyanBright(statusBox));
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
function showThought(thought) {
|
|
76
|
+
if (!thought) return;
|
|
77
|
+
const top = chalk.gray('┌' + '─'.repeat(30) + '┐');
|
|
78
|
+
const title = chalk.magenta.bold('│ ✧ Thinking');
|
|
79
|
+
const pad = ' '.repeat(Math.max(0, 30 - ' ✧ Thinking'.length));
|
|
80
|
+
const titleLine = title + pad + chalk.gray(' │');
|
|
81
|
+
const separator = chalk.gray('├' + '─'.repeat(30) + '┤');
|
|
82
|
+
const bottom = chalk.gray('└' + '─'.repeat(30) + '┘');
|
|
83
|
+
console.log(top);
|
|
84
|
+
console.log(titleLine);
|
|
85
|
+
console.log(separator);
|
|
86
|
+
// Print each line of thought dimmed
|
|
87
|
+
String(thought).split('\n').forEach(line => {
|
|
88
|
+
const truncated = line; // keep full line; rely on terminal wrap
|
|
89
|
+
console.log(chalk.gray('│ ') + chalk.dim(truncated) + chalk.gray(' │'));
|
|
90
|
+
});
|
|
91
|
+
console.log(bottom);
|
|
92
|
+
}
|
|
93
|
+
|
|
75
94
|
module.exports = {
|
|
76
95
|
showHeader,
|
|
77
96
|
showLegacyHeader,
|
|
@@ -84,5 +103,6 @@ module.exports = {
|
|
|
84
103
|
showWarning,
|
|
85
104
|
showSuccess,
|
|
86
105
|
showInfo,
|
|
87
|
-
showAGIStatus
|
|
106
|
+
showAGIStatus,
|
|
107
|
+
showThought
|
|
88
108
|
};
|