fraim-hub 2.0.306 → 2.0.308

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.
@@ -495,6 +495,8 @@ function readAgentFromArgs(args) {
495
495
  function readToolName(candidate) {
496
496
  if (typeof candidate.name === 'string')
497
497
  return candidate.name;
498
+ if (typeof candidate.mcpToolName === 'string')
499
+ return candidate.mcpToolName;
498
500
  if (typeof candidate.tool_name === 'string')
499
501
  return candidate.tool_name;
500
502
  if (typeof candidate.tool === 'string')
@@ -591,6 +593,118 @@ function normalizeToolArgs(rawArgs) {
591
593
  }
592
594
  return null;
593
595
  }
596
+ function stringifyMentorCallArgs(rawArgs) {
597
+ const args = normalizeToolArgs(rawArgs);
598
+ if (!args)
599
+ return null;
600
+ return JSON.stringify(args, null, 2);
601
+ }
602
+ function resultTextFromValue(value) {
603
+ if (typeof value === 'string')
604
+ return value.trim() || null;
605
+ if (Array.isArray(value)) {
606
+ const parts = value
607
+ .map((entry) => resultTextFromValue(entry))
608
+ .filter((entry) => Boolean(entry));
609
+ return parts.length > 0 ? parts.join('\n') : null;
610
+ }
611
+ if (!value || typeof value !== 'object')
612
+ return null;
613
+ const record = value;
614
+ for (const key of ['text', 'message', 'output', 'result', 'content']) {
615
+ const text = resultTextFromValue(record[key]);
616
+ if (text)
617
+ return text;
618
+ }
619
+ return null;
620
+ }
621
+ function microEventFromToolCall(candidate) {
622
+ if (!isFraimTool(readToolName(candidate), 'seekMentoring'))
623
+ return undefined;
624
+ const text = stringifyMentorCallArgs(candidate.input || candidate.arguments || candidate.parameters);
625
+ return text ? [{ kind: 'mentor_call', text }] : undefined;
626
+ }
627
+ function microEventFromToolResult(candidate) {
628
+ if (!isFraimTool(readToolName(candidate), 'seekMentoring'))
629
+ return undefined;
630
+ const text = resultTextFromValue(candidate.result ?? candidate.output ?? candidate.content ?? candidate.message);
631
+ return text ? [{ kind: 'mentor_reply', text }] : undefined;
632
+ }
633
+ function readToolUseId(candidate) {
634
+ return stringValue(candidate.id) || stringValue(candidate.tool_use_id) || stringValue(candidate.toolUseId);
635
+ }
636
+ function parseMicroEventsSignal(line) {
637
+ let parsed;
638
+ try {
639
+ parsed = JSON.parse(line);
640
+ }
641
+ catch {
642
+ return {};
643
+ }
644
+ if (!parsed || typeof parsed !== 'object')
645
+ return {};
646
+ const root = parsed;
647
+ const events = [];
648
+ const mentorToolUseIds = [];
649
+ const mentorToolResults = [];
650
+ const item = root.item && typeof root.item === 'object' ? root.item : null;
651
+ if (item && item.type === 'mcp_tool_call' && isFraimTool(readToolName(item), 'seekMentoring')) {
652
+ const rootType = typeof root.type === 'string' ? root.type : '';
653
+ const argsText = stringifyMentorCallArgs(item.arguments);
654
+ if (argsText && rootType !== 'item.completed')
655
+ events.push({ kind: 'mentor_call', text: argsText });
656
+ const replyText = resultTextFromValue(item.result);
657
+ if (replyText)
658
+ events.push({ kind: 'mentor_reply', text: replyText });
659
+ }
660
+ const data = root.data && typeof root.data === 'object' ? root.data : null;
661
+ if (data && isFraimTool(readToolName(data), 'seekMentoring')) {
662
+ if (root.type === 'tool.execution_start') {
663
+ const argsText = stringifyMentorCallArgs(data.arguments ?? data.input ?? data.parameters);
664
+ if (argsText)
665
+ events.push({ kind: 'mentor_call', text: argsText });
666
+ }
667
+ if (root.type === 'tool.execution_complete' || root.type === 'model.tool_execution') {
668
+ const replyText = resultTextFromValue(data.result ?? data.output ?? data.content);
669
+ if (replyText)
670
+ events.push({ kind: 'mentor_reply', text: replyText });
671
+ }
672
+ }
673
+ const contents = [];
674
+ if (Array.isArray(root.content))
675
+ contents.push(...root.content.filter((entry) => !!entry && typeof entry === 'object' && !Array.isArray(entry)));
676
+ const message = root.message && typeof root.message === 'object' ? root.message : null;
677
+ if (message && Array.isArray(message.content))
678
+ contents.push(...message.content.filter((entry) => !!entry && typeof entry === 'object' && !Array.isArray(entry)));
679
+ for (const content of contents) {
680
+ if (content.type === 'tool_use' || content.type === 'function_call') {
681
+ const call = microEventFromToolCall(content);
682
+ if (call) {
683
+ events.push(...call);
684
+ const id = readToolUseId(content);
685
+ if (id)
686
+ mentorToolUseIds.push(id);
687
+ }
688
+ }
689
+ if (content.type === 'tool_result') {
690
+ const reply = microEventFromToolResult(content);
691
+ if (reply) {
692
+ events.push(...reply);
693
+ }
694
+ else {
695
+ const toolUseId = readToolUseId(content);
696
+ const text = resultTextFromValue(content.result ?? content.output ?? content.content ?? content.message);
697
+ if (toolUseId && text)
698
+ mentorToolResults.push({ toolUseId, text });
699
+ }
700
+ }
701
+ }
702
+ return {
703
+ ...(events.length > 0 ? { microEvents: events } : {}),
704
+ ...(mentorToolUseIds.length > 0 ? { mentorToolUseIds } : {}),
705
+ ...(mentorToolResults.length > 0 ? { mentorToolResults } : {}),
706
+ };
707
+ }
594
708
  function numberOrNull(v) {
595
709
  return typeof v === 'number' && Number.isFinite(v) ? v : null;
596
710
  }
@@ -627,6 +741,10 @@ function extractSignalFromArgs(args) {
627
741
  const reviewHandoff = extractReviewHandoffFromArgs(args);
628
742
  const delegationLedger = extractDelegationLedgerFromArgs(args);
629
743
  const nextJobRecommendations = extractNextJobRecommendationsFromArgs(args);
744
+ const deliveryActionId = readNullableString(evidenceArgs?.deliveryActionId);
745
+ const completedDeliveryActionId = readNullableString(evidenceArgs?.completedDeliveryActionId);
746
+ const selectedReviewAction = readReviewActionCandidate(evidenceArgs?.selectedReviewAction);
747
+ const deliveryActionResult = readDeliveryActionResultCandidate(evidenceArgs?.deliveryActionResult);
630
748
  return {
631
749
  phaseId,
632
750
  phaseStatus,
@@ -638,6 +756,64 @@ function extractSignalFromArgs(args) {
638
756
  ...(reviewHandoff ? { reviewHandoff } : {}),
639
757
  ...(delegationLedger ? { delegationLedger } : {}),
640
758
  ...(nextJobRecommendations ? { nextJobRecommendations } : {}),
759
+ ...(deliveryActionId !== undefined ? { deliveryActionId } : {}),
760
+ ...(selectedReviewAction !== undefined ? { selectedReviewAction } : {}),
761
+ ...(completedDeliveryActionId !== undefined ? { completedDeliveryActionId } : {}),
762
+ ...(deliveryActionResult ? { deliveryActionResult } : {}),
763
+ };
764
+ }
765
+ function readNullableString(value) {
766
+ if (value === null)
767
+ return null;
768
+ if (typeof value !== 'string')
769
+ return undefined;
770
+ const trimmed = value.trim();
771
+ return trimmed.length > 0 ? trimmed : null;
772
+ }
773
+ function readReviewActionCandidate(value) {
774
+ if (value === null)
775
+ return null;
776
+ if (!value || typeof value !== 'object' || Array.isArray(value))
777
+ return undefined;
778
+ const action = value;
779
+ const id = typeof action.id === 'string' && action.id.trim().length > 0 ? action.id.trim() : '';
780
+ const label = typeof action.label === 'string' && action.label.trim().length > 0 ? action.label.trim() : '';
781
+ const kind = typeof action.kind === 'string' && action.kind.trim().length > 0 ? action.kind.trim() : '';
782
+ if (!id || !label || !kind)
783
+ return undefined;
784
+ const target = action.target && typeof action.target === 'object' && !Array.isArray(action.target)
785
+ ? action.target
786
+ : undefined;
787
+ return {
788
+ id,
789
+ label,
790
+ kind,
791
+ ...(typeof action.style === 'string' ? { style: action.style } : {}),
792
+ ...(typeof action.deliveryActionId === 'string' && action.deliveryActionId.trim().length > 0 ? { deliveryActionId: action.deliveryActionId.trim() } : {}),
793
+ ...(typeof action.description === 'string' ? { description: action.description } : {}),
794
+ ...(target ? { target } : {}),
795
+ };
796
+ }
797
+ function readDeliveryActionResultCandidate(value) {
798
+ if (!value || typeof value !== 'object' || Array.isArray(value))
799
+ return null;
800
+ const result = value;
801
+ const actionId = typeof result.actionId === 'string' && result.actionId.trim().length > 0
802
+ ? result.actionId.trim()
803
+ : typeof result.deliveryActionId === 'string' && result.deliveryActionId.trim().length > 0
804
+ ? result.deliveryActionId.trim()
805
+ : '';
806
+ if (!actionId)
807
+ return null;
808
+ return {
809
+ actionId,
810
+ ...(typeof result.prNumber === 'number' && Number.isFinite(result.prNumber) ? { prNumber: result.prNumber } : {}),
811
+ ...(typeof result.pushed === 'boolean' ? { pushed: result.pushed } : {}),
812
+ ...(typeof result.merged === 'boolean' ? { merged: result.merged } : {}),
813
+ ...(typeof result.defaultBranchVerified === 'boolean' ? { defaultBranchVerified: result.defaultBranchVerified } : {}),
814
+ ...(typeof result.issueClosed === 'boolean' ? { issueClosed: result.issueClosed } : {}),
815
+ ...(typeof result.branchCleaned === 'boolean' ? { branchCleaned: result.branchCleaned } : {}),
816
+ ...(typeof result.domainActionCompleted === 'boolean' ? { domainActionCompleted: result.domainActionCompleted } : {}),
641
817
  };
642
818
  }
643
819
  function extractDelegationLedgerFromArgs(args) {
@@ -1808,11 +1984,15 @@ function parseHostLine(hostId, line) {
1808
1984
  const usage = parseUsageSignal(trimmed);
1809
1985
  const agentIdentity = parseAgentIdentitySignal(trimmed);
1810
1986
  const recurringPark = parseRecurringParkSignal(trimmed);
1987
+ const microSignals = parseMicroEventsSignal(trimmed);
1988
+ const microEvents = microSignals.microEvents;
1989
+ const mentorToolUseIds = microSignals.mentorToolUseIds;
1990
+ const mentorToolResults = microSignals.mentorToolResults;
1811
1991
  // Issue #1264 (R3): only worth checking when seekMentoring itself did not
1812
1992
  // already resolve — a recognized call has nothing to diagnose.
1813
1993
  const unrecognizedReviewHandoffError = seekMentoring ? null : detectUnrecognizedReviewHandoffCall(trimmed);
1814
1994
  const withSignal = (event) => {
1815
- if (!seekMentoring && !fraimJob && !executionMode && !usage && !agentIdentity && !recurringPark && !unrecognizedReviewHandoffError)
1995
+ if (!seekMentoring && !fraimJob && !executionMode && !usage && !agentIdentity && !recurringPark && !microEvents && !mentorToolUseIds && !mentorToolResults && !unrecognizedReviewHandoffError)
1816
1996
  return event;
1817
1997
  return {
1818
1998
  ...event,
@@ -1822,6 +2002,9 @@ function parseHostLine(hostId, line) {
1822
2002
  ...(usage ? { usage } : {}),
1823
2003
  ...(agentIdentity ? { agentIdentity } : {}),
1824
2004
  ...(recurringPark ? { recurringPark: true } : {}),
2005
+ ...(microEvents ? { microEvents } : {}),
2006
+ ...(mentorToolUseIds ? { mentorToolUseIds } : {}),
2007
+ ...(mentorToolResults ? { mentorToolResults } : {}),
1825
2008
  ...(unrecognizedReviewHandoffError && !event.hostError ? { hostError: unrecognizedReviewHandoffError } : {}),
1826
2009
  };
1827
2010
  };