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
- // Emit reasoning update
673
- this.emitUIEvent({
674
- type: "reasoning_update",
675
- content: this.reasoningContent,
676
- format: format,
677
- isComplete: false,
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
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "graphlit-client",
3
- "version": "1.0.20260306001",
3
+ "version": "1.0.20260307002",
4
4
  "description": "Graphlit API Client for TypeScript",
5
5
  "type": "module",
6
6
  "main": "./dist/client.js",