sam-coder-cli 1.0.63 → 1.0.64

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.
Files changed (2) hide show
  1. package/bin/agi-cli.js +71 -3
  2. package/package.json +1 -1
package/bin/agi-cli.js CHANGED
@@ -755,7 +755,7 @@ function normalizeToolCallsFromMessage(message) {
755
755
  // Parse segmented format like <|start|>channel<|message|>...<|end|>
756
756
  function parseSegmentedTranscript(text) {
757
757
  if (!text || typeof text !== 'string') {
758
- return { content: text || '', thought: '', recoveredToolCalls: null };
758
+ return { content: text || '', thought: '', recoveredToolCalls: null, segmented: false };
759
759
  }
760
760
 
761
761
  const blockRegex = /\<\|start\|>([^<|]+)\<\|message\|>([\s\S]*?)\<\|end\|>/gi;
@@ -763,11 +763,13 @@ function parseSegmentedTranscript(text) {
763
763
  let visibleParts = [];
764
764
  let thoughts = [];
765
765
  let commentaryParts = [];
766
+ let segmentedFound = false;
766
767
 
767
768
  while ((match = blockRegex.exec(text)) !== null) {
768
769
  const rawRole = (match[1] || '').trim().toLowerCase();
769
770
  const body = (match[2] || '').trim();
770
771
  if (!rawRole) continue;
772
+ segmentedFound = true;
771
773
 
772
774
  if (rawRole === 'analysis') {
773
775
  thoughts.push(body);
@@ -784,7 +786,72 @@ function parseSegmentedTranscript(text) {
784
786
 
785
787
  // If no blocks matched, return original
786
788
  if (visibleParts.length === 0 && thoughts.length === 0 && commentaryParts.length === 0) {
787
- return { content: text, thought: '', recoveredToolCalls: null };
789
+ // Try channel-only segments: <|channel|>X [to=Y] [<|constrain|>Z] <|message|>... (<|end|>|<|call|>|<|return|>)
790
+ const chanRegex = /\<\|channel\|>\s*([a-zA-Z]+)\s*(?:to=([^\s<]+))?\s*(?:\<\|constrain\|>(\w+))?\s*\<\|message\|>([\s\S]*?)(?:\<\|end\|>|\<\|call\|>|\<\|return\|>)/gi;
791
+ let anyChannel = false;
792
+ let commsWithRecipients = [];
793
+ while ((match = chanRegex.exec(text)) !== null) {
794
+ anyChannel = true;
795
+ segmentedFound = true;
796
+ const channel = (match[1] || '').trim().toLowerCase();
797
+ const recipient = (match[2] || '').trim();
798
+ const constraint = (match[3] || '').trim().toLowerCase();
799
+ const body = (match[4] || '').trim();
800
+ if (channel === 'analysis') {
801
+ thoughts.push(body);
802
+ } else if (channel === 'commentary') {
803
+ if (recipient) {
804
+ commsWithRecipients.push({ recipient, constraint, body });
805
+ } else {
806
+ // preamble visible to user per spec
807
+ visibleParts.push(body);
808
+ }
809
+ } else if (channel === 'final') {
810
+ visibleParts.push(body);
811
+ } else {
812
+ visibleParts.push(body);
813
+ }
814
+ }
815
+ // Build recovered tool calls from commentary with recipients
816
+ let recoveredToolCalls = null;
817
+ if (commsWithRecipients.length) {
818
+ recoveredToolCalls = [];
819
+ for (const item of commsWithRecipients) {
820
+ // recipient format like functions.get_weather
821
+ let funcName = item.recipient;
822
+ if (funcName.startsWith('functions.')) {
823
+ funcName = funcName.slice('functions.'.length);
824
+ }
825
+ // parse args
826
+ let args = {};
827
+ if (item.constraint === 'json' || item.body.startsWith('{') || item.body.startsWith('[')) {
828
+ try {
829
+ const parsed = JSON.parse(item.body);
830
+ args = parsed;
831
+ } catch (_) {
832
+ // ignore parse error; leave empty
833
+ }
834
+ }
835
+ recoveredToolCalls.push({
836
+ id: `inline-${recoveredToolCalls.length + 1}`,
837
+ type: 'function',
838
+ function: {
839
+ name: funcName,
840
+ arguments: typeof args === 'string' ? args : JSON.stringify(args)
841
+ }
842
+ });
843
+ }
844
+ }
845
+
846
+ if (!anyChannel) {
847
+ return { content: text, thought: '', recoveredToolCalls: null, segmented: false };
848
+ }
849
+ return {
850
+ content: visibleParts.join('\n\n').trim(),
851
+ thought: thoughts.join('\n\n').trim(),
852
+ recoveredToolCalls: recoveredToolCalls && recoveredToolCalls.length ? recoveredToolCalls : null,
853
+ segmented: segmentedFound
854
+ };
788
855
  }
789
856
 
790
857
  // Look for a Reasoning: level outside blocks as a hint
@@ -807,7 +874,8 @@ function parseSegmentedTranscript(text) {
807
874
  return {
808
875
  content: visibleParts.join('\n\n').trim(),
809
876
  thought: thoughts.join('\n\n').trim(),
810
- recoveredToolCalls: recoveredToolCalls && recoveredToolCalls.length ? recoveredToolCalls : null
877
+ recoveredToolCalls: recoveredToolCalls && recoveredToolCalls.length ? recoveredToolCalls : null,
878
+ segmented: segmentedFound
811
879
  };
812
880
  }
813
881
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sam-coder-cli",
3
- "version": "1.0.63",
3
+ "version": "1.0.64",
4
4
  "description": "SAM-CODER: An animated command-line AI assistant with agency capabilities.",
5
5
  "main": "bin/agi-cli.js",
6
6
  "bin": {