@hef2024/llmasaservice-ui 0.25.0 → 0.25.2
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/index.js +270 -55
- package/dist/index.mjs +270 -55
- package/package.json +1 -1
- package/src/AIAgentPanel.tsx +93 -7
- package/src/AIChatPanel.tsx +270 -55
package/src/AIAgentPanel.tsx
CHANGED
|
@@ -516,7 +516,69 @@ const parseCallMessages = (rawMessages: unknown): TranscriptMessage[] => {
|
|
|
516
516
|
};
|
|
517
517
|
|
|
518
518
|
const shouldSkipTranscriptMessage = (message: TranscriptMessage): boolean => {
|
|
519
|
-
|
|
519
|
+
const normalizedContent = message.content.trim().toLowerCase();
|
|
520
|
+
const isInternalContinuationPrompt =
|
|
521
|
+
message.role === 'user' &&
|
|
522
|
+
normalizedContent.startsWith('original request:') &&
|
|
523
|
+
normalizedContent.includes('tool execution summary for the previous request:');
|
|
524
|
+
return (
|
|
525
|
+
message.role === 'system' ||
|
|
526
|
+
(message.role === 'user' && message.content.startsWith('__system__:')) ||
|
|
527
|
+
isInternalContinuationPrompt
|
|
528
|
+
);
|
|
529
|
+
};
|
|
530
|
+
|
|
531
|
+
const looksLikeToolStubResponse = (value: string): boolean => {
|
|
532
|
+
const text = value.trim();
|
|
533
|
+
if (!text) return false;
|
|
534
|
+
return (
|
|
535
|
+
text.includes('"type":"tool_use"') ||
|
|
536
|
+
text.includes('"type": "tool_use"') ||
|
|
537
|
+
text.includes('"type":"function"') ||
|
|
538
|
+
text.includes('"type": "function"')
|
|
539
|
+
);
|
|
540
|
+
};
|
|
541
|
+
|
|
542
|
+
const pickMoreCompleteResponse = (primaryResponse: string, fallbackResponse: string): string => {
|
|
543
|
+
const primary = primaryResponse.trim();
|
|
544
|
+
const fallback = fallbackResponse.trim();
|
|
545
|
+
if (!fallback) return primary;
|
|
546
|
+
if (!primary) return fallback;
|
|
547
|
+
if (primary === fallback) return primary;
|
|
548
|
+
|
|
549
|
+
if (looksLikeToolStubResponse(primary) && !looksLikeToolStubResponse(fallback)) {
|
|
550
|
+
return fallback;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
if (fallback.startsWith(primary) || fallback.length > primary.length + 40) {
|
|
554
|
+
return fallback;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
return primary;
|
|
558
|
+
};
|
|
559
|
+
|
|
560
|
+
const mergeContinuationResponse = (baseResponse: string, continuationResponse: string): string => {
|
|
561
|
+
const base = baseResponse.trim();
|
|
562
|
+
const continuation = continuationResponse.trim();
|
|
563
|
+
if (!base) return continuation;
|
|
564
|
+
if (!continuation) return base;
|
|
565
|
+
|
|
566
|
+
if (looksLikeToolStubResponse(base) && !looksLikeToolStubResponse(continuation)) {
|
|
567
|
+
return continuation;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
if (base.includes(continuation)) {
|
|
571
|
+
return base;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
const maxOverlap = Math.min(base.length, continuation.length);
|
|
575
|
+
for (let overlap = maxOverlap; overlap > 0; overlap -= 1) {
|
|
576
|
+
if (base.slice(-overlap) === continuation.slice(0, overlap)) {
|
|
577
|
+
return `${base}${continuation.slice(overlap)}`;
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
return `${base}\n\n${continuation}`;
|
|
520
582
|
};
|
|
521
583
|
|
|
522
584
|
const parseTimestampMs = (value: unknown): number | null => {
|
|
@@ -626,14 +688,21 @@ const buildTurnsFromMessages = (
|
|
|
626
688
|
if (!prompt) continue;
|
|
627
689
|
|
|
628
690
|
let response = '';
|
|
691
|
+
let lastAssistantIndex = -1;
|
|
629
692
|
let reachedNextUser = false;
|
|
630
693
|
for (let lookAhead = index + 1; lookAhead < messages.length; lookAhead += 1) {
|
|
631
694
|
const nextMessage = messages[lookAhead];
|
|
632
695
|
if (!nextMessage) continue;
|
|
633
696
|
if (nextMessage.role === 'assistant') {
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
697
|
+
const assistantResponse = nextMessage.content.trim();
|
|
698
|
+
if (assistantResponse) {
|
|
699
|
+
// Keep scanning until the next user turn so transcript replay stores
|
|
700
|
+
// the final assistant output for this user prompt (post-tool result),
|
|
701
|
+
// not just the first assistant placeholder/tool-call message.
|
|
702
|
+
response = assistantResponse;
|
|
703
|
+
lastAssistantIndex = lookAhead;
|
|
704
|
+
}
|
|
705
|
+
continue;
|
|
637
706
|
}
|
|
638
707
|
if (nextMessage.role === 'user') {
|
|
639
708
|
reachedNextUser = true;
|
|
@@ -641,9 +710,14 @@ const buildTurnsFromMessages = (
|
|
|
641
710
|
}
|
|
642
711
|
}
|
|
643
712
|
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
713
|
+
if (lastAssistantIndex >= 0) {
|
|
714
|
+
index = lastAssistantIndex;
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
// For the final user turn in a call, prefer the call-level fallback response
|
|
718
|
+
// when it is clearly more complete than the in-message assistant stub.
|
|
719
|
+
if (!reachedNextUser) {
|
|
720
|
+
response = pickMoreCompleteResponse(response, fallbackResponse);
|
|
647
721
|
}
|
|
648
722
|
|
|
649
723
|
if (!response) continue;
|
|
@@ -700,6 +774,18 @@ const buildTranscriptTurnsFromCalls = (calls: Record<string, unknown>[]): Transc
|
|
|
700
774
|
timestampMs,
|
|
701
775
|
},
|
|
702
776
|
];
|
|
777
|
+
} else if (fallbackResponse && mergedTurns.length > 0) {
|
|
778
|
+
const previousTurn = mergedTurns[mergedTurns.length - 1]!;
|
|
779
|
+
mergedTurns = [
|
|
780
|
+
...mergedTurns.slice(0, -1),
|
|
781
|
+
{
|
|
782
|
+
...previousTurn,
|
|
783
|
+
response: mergeContinuationResponse(previousTurn.response, fallbackResponse),
|
|
784
|
+
callId: callId || previousTurn.callId,
|
|
785
|
+
timestampMs: Math.max(previousTurn.timestampMs, timestampMs),
|
|
786
|
+
},
|
|
787
|
+
];
|
|
788
|
+
continue;
|
|
703
789
|
}
|
|
704
790
|
}
|
|
705
791
|
|