graphlit-client 1.0.20260306001 → 1.0.20260307002
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.
|
@@ -31,6 +31,10 @@ export declare class UIEventAdapter {
|
|
|
31
31
|
private reasoningFormat?;
|
|
32
32
|
private reasoningSignature?;
|
|
33
33
|
private isInReasoning;
|
|
34
|
+
private reasoningBuffer?;
|
|
35
|
+
private reasoningEmitTimer?;
|
|
36
|
+
private lastReasoningEmitTime;
|
|
37
|
+
private static readonly REASONING_THROTTLE_MS;
|
|
34
38
|
private usageData?;
|
|
35
39
|
private hasToolCallsInProgress;
|
|
36
40
|
private hadToolCallsBeforeResume;
|
|
@@ -64,6 +68,8 @@ export declare class UIEventAdapter {
|
|
|
64
68
|
private handleContextManagement;
|
|
65
69
|
private handleReasoningStart;
|
|
66
70
|
private handleReasoningDelta;
|
|
71
|
+
private scheduleReasoningEmission;
|
|
72
|
+
private emitReasoningUpdate;
|
|
67
73
|
private handleReasoningEnd;
|
|
68
74
|
/**
|
|
69
75
|
* Build a ReasoningMetadata object from accumulated reasoning state.
|
|
@@ -30,6 +30,10 @@ export class UIEventAdapter {
|
|
|
30
30
|
reasoningFormat;
|
|
31
31
|
reasoningSignature;
|
|
32
32
|
isInReasoning = false;
|
|
33
|
+
reasoningBuffer;
|
|
34
|
+
reasoningEmitTimer;
|
|
35
|
+
lastReasoningEmitTime = 0;
|
|
36
|
+
static REASONING_THROTTLE_MS = 250;
|
|
33
37
|
usageData;
|
|
34
38
|
hasToolCallsInProgress = false;
|
|
35
39
|
hadToolCallsBeforeResume = false;
|
|
@@ -43,6 +47,10 @@ export class UIEventAdapter {
|
|
|
43
47
|
this.conversationStartTime = Date.now(); // Capture when conversation began
|
|
44
48
|
if (options.smoothingEnabled) {
|
|
45
49
|
this.chunkBuffer = new ChunkBuffer(options.chunkingStrategy || "word");
|
|
50
|
+
// Reasoning always uses sentence-level chunking regardless of the
|
|
51
|
+
// developer's choice — thinking content is secondary UI and benefits
|
|
52
|
+
// from fewer, larger updates rather than token-by-token emission.
|
|
53
|
+
this.reasoningBuffer = new ChunkBuffer("sentence");
|
|
46
54
|
}
|
|
47
55
|
}
|
|
48
56
|
/**
|
|
@@ -111,6 +119,14 @@ export class UIEventAdapter {
|
|
|
111
119
|
this.reasoningFormat = undefined;
|
|
112
120
|
this.reasoningSignature = undefined;
|
|
113
121
|
this.isInReasoning = false;
|
|
122
|
+
this.lastReasoningEmitTime = 0;
|
|
123
|
+
if (this.reasoningEmitTimer) {
|
|
124
|
+
globalThis.clearTimeout(this.reasoningEmitTimer);
|
|
125
|
+
this.reasoningEmitTimer = undefined;
|
|
126
|
+
}
|
|
127
|
+
if (this.reasoningBuffer) {
|
|
128
|
+
this.reasoningBuffer.flush();
|
|
129
|
+
}
|
|
114
130
|
// Reset tool call tracking flags
|
|
115
131
|
this.hasToolCallsInProgress = false;
|
|
116
132
|
this.hadToolCallsBeforeResume = false;
|
|
@@ -662,6 +678,15 @@ export class UIEventAdapter {
|
|
|
662
678
|
this.isInReasoning = true;
|
|
663
679
|
this.reasoningFormat = format;
|
|
664
680
|
this.reasoningContent = "";
|
|
681
|
+
this.lastReasoningEmitTime = 0;
|
|
682
|
+
// Reset the reasoning buffer for a fresh thinking block
|
|
683
|
+
if (this.reasoningBuffer) {
|
|
684
|
+
this.reasoningBuffer.flush();
|
|
685
|
+
}
|
|
686
|
+
if (this.reasoningEmitTimer) {
|
|
687
|
+
globalThis.clearTimeout(this.reasoningEmitTimer);
|
|
688
|
+
this.reasoningEmitTimer = undefined;
|
|
689
|
+
}
|
|
665
690
|
}
|
|
666
691
|
handleReasoningDelta(content, format) {
|
|
667
692
|
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
|
|
@@ -669,13 +694,51 @@ export class UIEventAdapter {
|
|
|
669
694
|
}
|
|
670
695
|
this.reasoningContent += content;
|
|
671
696
|
this.reasoningFormat = format;
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
697
|
+
if (this.reasoningBuffer) {
|
|
698
|
+
// Feed through sentence-level buffer — only emit when a complete
|
|
699
|
+
// sentence is available. No partial-sentence heartbeat: reasoning
|
|
700
|
+
// is secondary UI and handleReasoningEnd flushes the remainder.
|
|
701
|
+
const sentences = this.reasoningBuffer.addToken(content);
|
|
702
|
+
if (sentences.length > 0) {
|
|
703
|
+
this.scheduleReasoningEmission();
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
else {
|
|
707
|
+
// No smoothing — emit every delta immediately (original behavior)
|
|
708
|
+
this.emitUIEvent({
|
|
709
|
+
type: "reasoning_update",
|
|
710
|
+
content: this.reasoningContent,
|
|
711
|
+
format: format,
|
|
712
|
+
isComplete: false,
|
|
713
|
+
});
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
scheduleReasoningEmission() {
|
|
717
|
+
if (this.reasoningEmitTimer)
|
|
718
|
+
return;
|
|
719
|
+
const now = Date.now();
|
|
720
|
+
const elapsed = now - this.lastReasoningEmitTime;
|
|
721
|
+
if (elapsed >= UIEventAdapter.REASONING_THROTTLE_MS) {
|
|
722
|
+
this.emitReasoningUpdate();
|
|
723
|
+
}
|
|
724
|
+
else {
|
|
725
|
+
const delay = UIEventAdapter.REASONING_THROTTLE_MS - elapsed;
|
|
726
|
+
this.reasoningEmitTimer = globalThis.setTimeout(() => {
|
|
727
|
+
this.emitReasoningUpdate();
|
|
728
|
+
}, delay);
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
emitReasoningUpdate() {
|
|
732
|
+
this.reasoningEmitTimer = undefined;
|
|
733
|
+
this.lastReasoningEmitTime = Date.now();
|
|
734
|
+
if (this.reasoningFormat) {
|
|
735
|
+
this.emitUIEvent({
|
|
736
|
+
type: "reasoning_update",
|
|
737
|
+
content: this.reasoningContent,
|
|
738
|
+
format: this.reasoningFormat,
|
|
739
|
+
isComplete: false,
|
|
740
|
+
});
|
|
741
|
+
}
|
|
679
742
|
}
|
|
680
743
|
handleReasoningEnd(fullContent, signature) {
|
|
681
744
|
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
|
|
@@ -684,6 +747,15 @@ export class UIEventAdapter {
|
|
|
684
747
|
console.log(`🤔 [UIEventAdapter] Reasoning signature: ${signature}`);
|
|
685
748
|
}
|
|
686
749
|
}
|
|
750
|
+
// Cancel any pending throttled emission
|
|
751
|
+
if (this.reasoningEmitTimer) {
|
|
752
|
+
globalThis.clearTimeout(this.reasoningEmitTimer);
|
|
753
|
+
this.reasoningEmitTimer = undefined;
|
|
754
|
+
}
|
|
755
|
+
// Flush the reasoning buffer — any remaining partial sentence
|
|
756
|
+
if (this.reasoningBuffer) {
|
|
757
|
+
this.reasoningBuffer.flush();
|
|
758
|
+
}
|
|
687
759
|
this.isInReasoning = false;
|
|
688
760
|
this.reasoningContent = fullContent;
|
|
689
761
|
this.reasoningSignature = signature;
|
|
@@ -722,6 +794,10 @@ export class UIEventAdapter {
|
|
|
722
794
|
globalThis.clearTimeout(this.updateTimer);
|
|
723
795
|
this.updateTimer = undefined;
|
|
724
796
|
}
|
|
797
|
+
if (this.reasoningEmitTimer) {
|
|
798
|
+
globalThis.clearTimeout(this.reasoningEmitTimer);
|
|
799
|
+
this.reasoningEmitTimer = undefined;
|
|
800
|
+
}
|
|
725
801
|
this.activeToolCalls.clear();
|
|
726
802
|
}
|
|
727
803
|
/**
|