graphlit-client 1.0.20250613001 → 1.0.20250613002
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/client.js
CHANGED
@@ -1983,14 +1983,21 @@ class Graphlit {
|
|
1983
1983
|
}
|
1984
1984
|
currentRound++;
|
1985
1985
|
}
|
1986
|
-
// Complete the conversation
|
1986
|
+
// Complete the conversation and get token count
|
1987
|
+
let finalTokens;
|
1987
1988
|
if (fullMessage) {
|
1988
|
-
await this.completeConversation(fullMessage.trim(), conversationId, correlationId);
|
1989
|
+
const completeResponse = await this.completeConversation(fullMessage.trim(), conversationId, correlationId);
|
1990
|
+
// Extract token count from the response
|
1991
|
+
finalTokens = completeResponse.completeConversation?.message?.tokens ?? undefined;
|
1992
|
+
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
|
1993
|
+
console.log(`📊 [completeConversation] Tokens used: ${finalTokens || 'unknown'}`);
|
1994
|
+
}
|
1989
1995
|
}
|
1990
|
-
// Emit completion event
|
1996
|
+
// Emit completion event with token count
|
1991
1997
|
uiAdapter.handleEvent({
|
1992
1998
|
type: "complete",
|
1993
1999
|
conversationId,
|
2000
|
+
tokens: finalTokens,
|
1994
2001
|
});
|
1995
2002
|
}
|
1996
2003
|
/**
|
@@ -13,9 +13,11 @@ export declare class UIEventAdapter {
|
|
13
13
|
private tokenCount;
|
14
14
|
private currentMessage;
|
15
15
|
private isStreaming;
|
16
|
+
private conversationStartTime;
|
16
17
|
private streamStartTime;
|
17
18
|
private firstTokenTime;
|
18
19
|
private lastTokenTime;
|
20
|
+
private tokenDelays;
|
19
21
|
private activeToolCalls;
|
20
22
|
private lastUpdateTime;
|
21
23
|
private updateTimer?;
|
@@ -12,9 +12,11 @@ export class UIEventAdapter {
|
|
12
12
|
tokenCount = 0;
|
13
13
|
currentMessage = "";
|
14
14
|
isStreaming = false;
|
15
|
-
|
15
|
+
conversationStartTime = 0; // When user sent the message
|
16
|
+
streamStartTime = 0; // When streaming actually began
|
16
17
|
firstTokenTime = 0;
|
17
18
|
lastTokenTime = 0;
|
19
|
+
tokenDelays = [];
|
18
20
|
activeToolCalls = new Map();
|
19
21
|
lastUpdateTime = 0;
|
20
22
|
updateTimer;
|
@@ -27,6 +29,7 @@ export class UIEventAdapter {
|
|
27
29
|
this.smoothingDelay = options.smoothingDelay ?? 30;
|
28
30
|
this.model = options.model;
|
29
31
|
this.modelService = options.modelService;
|
32
|
+
this.conversationStartTime = Date.now(); // Capture when conversation began
|
30
33
|
if (options.smoothingEnabled) {
|
31
34
|
this.chunkBuffer = new ChunkBuffer(options.chunkingStrategy || "word");
|
32
35
|
}
|
@@ -55,7 +58,7 @@ export class UIEventAdapter {
|
|
55
58
|
this.handleToolCallComplete(event.toolCall);
|
56
59
|
break;
|
57
60
|
case "complete":
|
58
|
-
this.handleComplete();
|
61
|
+
this.handleComplete(event.tokens);
|
59
62
|
break;
|
60
63
|
case "error":
|
61
64
|
this.handleError(event.error);
|
@@ -94,6 +97,8 @@ export class UIEventAdapter {
|
|
94
97
|
this.streamStartTime = Date.now();
|
95
98
|
this.firstTokenTime = 0;
|
96
99
|
this.lastTokenTime = 0;
|
100
|
+
this.tokenCount = 0;
|
101
|
+
this.tokenDelays = [];
|
97
102
|
this.emitUIEvent({
|
98
103
|
type: "conversation_started",
|
99
104
|
conversationId,
|
@@ -107,7 +112,12 @@ export class UIEventAdapter {
|
|
107
112
|
if (this.firstTokenTime === 0) {
|
108
113
|
this.firstTokenTime = now;
|
109
114
|
}
|
115
|
+
// Track inter-token delays
|
116
|
+
if (this.lastTokenTime > 0) {
|
117
|
+
this.tokenDelays.push(now - this.lastTokenTime);
|
118
|
+
}
|
110
119
|
this.lastTokenTime = now;
|
120
|
+
this.tokenCount++;
|
111
121
|
if (this.chunkBuffer) {
|
112
122
|
const chunks = this.chunkBuffer.addToken(token);
|
113
123
|
// Add chunks to queue for all chunking modes (character, word, sentence)
|
@@ -165,7 +175,7 @@ export class UIEventAdapter {
|
|
165
175
|
});
|
166
176
|
}
|
167
177
|
}
|
168
|
-
handleComplete() {
|
178
|
+
handleComplete(tokens) {
|
169
179
|
// Clear any pending updates
|
170
180
|
if (this.updateTimer) {
|
171
181
|
globalThis.clearTimeout(this.updateTimer);
|
@@ -200,7 +210,7 @@ export class UIEventAdapter {
|
|
200
210
|
role: ConversationRoleTypes.Assistant,
|
201
211
|
message: this.currentMessage,
|
202
212
|
timestamp: new Date().toISOString(),
|
203
|
-
tokens:
|
213
|
+
tokens: tokens, // Now we have the actual LLM token count!
|
204
214
|
toolCalls: Array.from(this.activeToolCalls.values()).map((t) => t.toolCall),
|
205
215
|
model: this.model,
|
206
216
|
modelService: this.modelService,
|
@@ -222,9 +232,32 @@ export class UIEventAdapter {
|
|
222
232
|
}
|
223
233
|
}
|
224
234
|
}
|
235
|
+
// Build final metrics
|
236
|
+
const completionTime = Date.now();
|
237
|
+
const finalMetrics = {
|
238
|
+
totalTime: this.streamStartTime > 0 ? completionTime - this.streamStartTime : 0,
|
239
|
+
conversationDuration: this.conversationStartTime > 0 ? completionTime - this.conversationStartTime : 0,
|
240
|
+
};
|
241
|
+
// Add TTFT if we have it
|
242
|
+
if (this.firstTokenTime > 0 && this.streamStartTime > 0) {
|
243
|
+
finalMetrics.ttft = this.firstTokenTime - this.streamStartTime;
|
244
|
+
}
|
245
|
+
// Add token counts
|
246
|
+
if (this.tokenCount > 0) {
|
247
|
+
finalMetrics.tokenCount = this.tokenCount; // Streaming chunks
|
248
|
+
}
|
249
|
+
if (tokens) {
|
250
|
+
finalMetrics.llmTokens = tokens; // Actual LLM tokens used
|
251
|
+
}
|
252
|
+
// Calculate average token delay
|
253
|
+
if (this.tokenDelays.length > 0) {
|
254
|
+
const avgDelay = this.tokenDelays.reduce((a, b) => a + b, 0) / this.tokenDelays.length;
|
255
|
+
finalMetrics.avgTokenDelay = Math.round(avgDelay);
|
256
|
+
}
|
225
257
|
this.emitUIEvent({
|
226
258
|
type: "conversation_completed",
|
227
259
|
message: finalMessage,
|
260
|
+
metrics: finalMetrics,
|
228
261
|
});
|
229
262
|
}
|
230
263
|
handleError(error) {
|
@@ -330,10 +363,30 @@ export class UIEventAdapter {
|
|
330
363
|
message.completionTime = elapsedTime / 1000;
|
331
364
|
}
|
332
365
|
}
|
366
|
+
// Build metrics object
|
367
|
+
const now = Date.now();
|
368
|
+
const metrics = {
|
369
|
+
elapsedTime: this.streamStartTime > 0 ? now - this.streamStartTime : 0,
|
370
|
+
conversationDuration: this.conversationStartTime > 0 ? now - this.conversationStartTime : 0,
|
371
|
+
};
|
372
|
+
// Add TTFT if we have it
|
373
|
+
if (this.firstTokenTime > 0 && this.streamStartTime > 0) {
|
374
|
+
metrics.ttft = this.firstTokenTime - this.streamStartTime;
|
375
|
+
}
|
376
|
+
// Add token count if available
|
377
|
+
if (this.tokenCount > 0) {
|
378
|
+
metrics.tokenCount = this.tokenCount;
|
379
|
+
}
|
380
|
+
// Calculate average token delay
|
381
|
+
if (this.tokenDelays.length > 0) {
|
382
|
+
const avgDelay = this.tokenDelays.reduce((a, b) => a + b, 0) / this.tokenDelays.length;
|
383
|
+
metrics.avgTokenDelay = Math.round(avgDelay);
|
384
|
+
}
|
333
385
|
this.emitUIEvent({
|
334
386
|
type: "message_update",
|
335
387
|
message,
|
336
388
|
isStreaming,
|
389
|
+
metrics,
|
337
390
|
});
|
338
391
|
}
|
339
392
|
emitUIEvent(event) {
|
package/dist/types/internal.d.ts
CHANGED
@@ -17,6 +17,13 @@ export type AgentStreamEvent = {
|
|
17
17
|
message: string;
|
18
18
|
};
|
19
19
|
isStreaming: boolean;
|
20
|
+
metrics?: {
|
21
|
+
ttft?: number;
|
22
|
+
elapsedTime: number;
|
23
|
+
conversationDuration: number;
|
24
|
+
tokenCount?: number;
|
25
|
+
avgTokenDelay?: number;
|
26
|
+
};
|
20
27
|
} | {
|
21
28
|
type: "tool_update";
|
22
29
|
toolCall: ConversationToolCall;
|
@@ -26,6 +33,14 @@ export type AgentStreamEvent = {
|
|
26
33
|
} | {
|
27
34
|
type: "conversation_completed";
|
28
35
|
message: ConversationMessage;
|
36
|
+
metrics?: {
|
37
|
+
ttft?: number;
|
38
|
+
totalTime: number;
|
39
|
+
conversationDuration: number;
|
40
|
+
tokenCount?: number;
|
41
|
+
llmTokens?: number;
|
42
|
+
avgTokenDelay?: number;
|
43
|
+
};
|
29
44
|
} | {
|
30
45
|
type: "error";
|
31
46
|
error: {
|