sam-coder-cli 1.0.62 → 1.0.63
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 +95 -4
- package/package.json +1 -1
package/bin/agi-cli.js
CHANGED
|
@@ -752,6 +752,65 @@ function normalizeToolCallsFromMessage(message) {
|
|
|
752
752
|
return message;
|
|
753
753
|
}
|
|
754
754
|
|
|
755
|
+
// Parse segmented format like <|start|>channel<|message|>...<|end|>
|
|
756
|
+
function parseSegmentedTranscript(text) {
|
|
757
|
+
if (!text || typeof text !== 'string') {
|
|
758
|
+
return { content: text || '', thought: '', recoveredToolCalls: null };
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
const blockRegex = /\<\|start\|>([^<|]+)\<\|message\|>([\s\S]*?)\<\|end\|>/gi;
|
|
762
|
+
let match;
|
|
763
|
+
let visibleParts = [];
|
|
764
|
+
let thoughts = [];
|
|
765
|
+
let commentaryParts = [];
|
|
766
|
+
|
|
767
|
+
while ((match = blockRegex.exec(text)) !== null) {
|
|
768
|
+
const rawRole = (match[1] || '').trim().toLowerCase();
|
|
769
|
+
const body = (match[2] || '').trim();
|
|
770
|
+
if (!rawRole) continue;
|
|
771
|
+
|
|
772
|
+
if (rawRole === 'analysis') {
|
|
773
|
+
thoughts.push(body);
|
|
774
|
+
} else if (rawRole === 'commentary') {
|
|
775
|
+
commentaryParts.push(body);
|
|
776
|
+
} else if (rawRole === 'final' || rawRole === 'assistant' || rawRole === 'user' || rawRole === 'system' || rawRole === 'developer') {
|
|
777
|
+
// Prefer 'final' or 'assistant' as visible, but include others to preserve content order
|
|
778
|
+
visibleParts.push(body);
|
|
779
|
+
} else {
|
|
780
|
+
// Unknown channel: treat as visible content
|
|
781
|
+
visibleParts.push(body);
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
// If no blocks matched, return original
|
|
786
|
+
if (visibleParts.length === 0 && thoughts.length === 0 && commentaryParts.length === 0) {
|
|
787
|
+
return { content: text, thought: '', recoveredToolCalls: null };
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
// Look for a Reasoning: level outside blocks as a hint
|
|
791
|
+
const reasoningMatch = text.match(/Reasoning:\s*(high|medium|low)/i);
|
|
792
|
+
if (reasoningMatch) {
|
|
793
|
+
thoughts.unshift(`Reasoning level: ${reasoningMatch[1]}`);
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
// Recover tool calls from commentary channels
|
|
797
|
+
let recoveredToolCalls = null;
|
|
798
|
+
if (commentaryParts.length) {
|
|
799
|
+
for (const part of commentaryParts) {
|
|
800
|
+
const found = parseInlineToolCalls(part);
|
|
801
|
+
if (found && found.length) {
|
|
802
|
+
recoveredToolCalls = (recoveredToolCalls || []).concat(found);
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
return {
|
|
808
|
+
content: visibleParts.join('\n\n').trim(),
|
|
809
|
+
thought: thoughts.join('\n\n').trim(),
|
|
810
|
+
recoveredToolCalls: recoveredToolCalls && recoveredToolCalls.length ? recoveredToolCalls : null
|
|
811
|
+
};
|
|
812
|
+
}
|
|
813
|
+
|
|
755
814
|
// Call OpenRouter API with tool calling
|
|
756
815
|
async function callOpenRouter(messages, currentModel, useJson = false) {
|
|
757
816
|
const apiKey = OPENROUTER_API_KEY;
|
|
@@ -810,7 +869,18 @@ async function processQueryWithTools(query, conversation = [], currentModel) {
|
|
|
810
869
|
const assistantMessage = response.choices[0].message;
|
|
811
870
|
// Handle thinking tags and optionally display them
|
|
812
871
|
if (assistantMessage && typeof assistantMessage.content === 'string') {
|
|
813
|
-
|
|
872
|
+
// First handle segmented transcripts, then fallback to <think>
|
|
873
|
+
const segmented = parseSegmentedTranscript(assistantMessage.content);
|
|
874
|
+
let thought = segmented.thought;
|
|
875
|
+
let content = segmented.content;
|
|
876
|
+
if (!segmented.thought && !segmented.recoveredToolCalls) {
|
|
877
|
+
const thinkSplit = splitThinking(assistantMessage.content);
|
|
878
|
+
thought = thought || thinkSplit.thought;
|
|
879
|
+
content = content || thinkSplit.content;
|
|
880
|
+
}
|
|
881
|
+
if (segmented.recoveredToolCalls && (!assistantMessage.tool_calls)) {
|
|
882
|
+
assistantMessage.tool_calls = segmented.recoveredToolCalls;
|
|
883
|
+
}
|
|
814
884
|
if (thought && SHOW_THOUGHTS) {
|
|
815
885
|
ui.showThought(thought);
|
|
816
886
|
}
|
|
@@ -834,7 +904,14 @@ async function processQueryWithTools(query, conversation = [], currentModel) {
|
|
|
834
904
|
const finalResponseObj = await callOpenRouter(messages, currentModel);
|
|
835
905
|
const finalAssistantMessage = finalResponseObj.choices[0].message;
|
|
836
906
|
if (finalAssistantMessage && typeof finalAssistantMessage.content === 'string') {
|
|
837
|
-
const
|
|
907
|
+
const segmented = parseSegmentedTranscript(finalAssistantMessage.content);
|
|
908
|
+
let thought = segmented.thought;
|
|
909
|
+
let content = segmented.content;
|
|
910
|
+
if (!segmented.thought && !segmented.recoveredToolCalls) {
|
|
911
|
+
const thinkSplit = splitThinking(finalAssistantMessage.content);
|
|
912
|
+
thought = thought || thinkSplit.thought;
|
|
913
|
+
content = content || thinkSplit.content;
|
|
914
|
+
}
|
|
838
915
|
if (thought && SHOW_THOUGHTS) {
|
|
839
916
|
ui.showThought(thought);
|
|
840
917
|
}
|
|
@@ -859,7 +936,14 @@ async function processQueryWithTools(query, conversation = [], currentModel) {
|
|
|
859
936
|
const finalResponseObj = await callOpenRouter(messages, currentModel);
|
|
860
937
|
const finalAssistantMessage = finalResponseObj.choices[0].message;
|
|
861
938
|
if (finalAssistantMessage && typeof finalAssistantMessage.content === 'string') {
|
|
862
|
-
const
|
|
939
|
+
const segmented = parseSegmentedTranscript(finalAssistantMessage.content);
|
|
940
|
+
let thought = segmented.thought;
|
|
941
|
+
let content = segmented.content;
|
|
942
|
+
if (!segmented.thought && !segmented.recoveredToolCalls) {
|
|
943
|
+
const thinkSplit = splitThinking(finalAssistantMessage.content);
|
|
944
|
+
thought = thought || thinkSplit.thought;
|
|
945
|
+
content = content || thinkSplit.content;
|
|
946
|
+
}
|
|
863
947
|
if (thought && SHOW_THOUGHTS) {
|
|
864
948
|
ui.showThought(thought);
|
|
865
949
|
}
|
|
@@ -1001,7 +1085,14 @@ async function processQuery(query, conversation = [], currentModel) {
|
|
|
1001
1085
|
const responseObj = await callOpenRouter(messages, currentModel, true);
|
|
1002
1086
|
const assistantMessage = responseObj.choices[0].message;
|
|
1003
1087
|
if (assistantMessage && typeof assistantMessage.content === 'string') {
|
|
1004
|
-
const
|
|
1088
|
+
const segmented = parseSegmentedTranscript(assistantMessage.content);
|
|
1089
|
+
let thought = segmented.thought;
|
|
1090
|
+
let content = segmented.content;
|
|
1091
|
+
if (!segmented.thought && !segmented.recoveredToolCalls) {
|
|
1092
|
+
const thinkSplit = splitThinking(assistantMessage.content);
|
|
1093
|
+
thought = thought || thinkSplit.thought;
|
|
1094
|
+
content = content || thinkSplit.content;
|
|
1095
|
+
}
|
|
1005
1096
|
if (thought && SHOW_THOUGHTS) {
|
|
1006
1097
|
ui.showThought(thought);
|
|
1007
1098
|
}
|