graphlit-client 1.0.20250613004 → 1.0.20250613006

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
@@ -1950,7 +1950,9 @@ class Graphlit {
1950
1950
  continue;
1951
1951
  }
1952
1952
  }
1953
- // Update UI - emit the full tool call with arguments
1953
+ // Execute tool
1954
+ const result = await handler(args);
1955
+ // Update UI with complete event including result
1954
1956
  uiAdapter.handleEvent({
1955
1957
  type: "tool_call_complete",
1956
1958
  toolCall: {
@@ -1958,11 +1960,8 @@ class Graphlit {
1958
1960
  name: toolCall.name,
1959
1961
  arguments: toolCall.arguments,
1960
1962
  },
1963
+ result: result,
1961
1964
  });
1962
- // Execute tool
1963
- const result = await handler(args);
1964
- // Update UI with result
1965
- uiAdapter.setToolResult(toolCall.id, result);
1966
1965
  // Add tool response to messages
1967
1966
  messages.push({
1968
1967
  __typename: "ConversationMessage",
@@ -1975,8 +1974,16 @@ class Graphlit {
1975
1974
  catch (error) {
1976
1975
  const errorMessage = error instanceof Error ? error.message : "Unknown error";
1977
1976
  console.error(`Tool execution error for ${toolCall.name}:`, error);
1978
- // Update UI with error
1979
- uiAdapter.setToolResult(toolCall.id, undefined, errorMessage);
1977
+ // Update UI with complete event including error
1978
+ uiAdapter.handleEvent({
1979
+ type: "tool_call_complete",
1980
+ toolCall: {
1981
+ id: toolCall.id,
1982
+ name: toolCall.name,
1983
+ arguments: toolCall.arguments,
1984
+ },
1985
+ error: errorMessage,
1986
+ });
1980
1987
  // Add error response
1981
1988
  messages.push({
1982
1989
  __typename: "ConversationMessage",
@@ -1995,9 +2002,10 @@ class Graphlit {
1995
2002
  if (fullMessage) {
1996
2003
  const completeResponse = await this.completeConversation(fullMessage.trim(), conversationId, correlationId);
1997
2004
  // Extract token count from the response
1998
- finalTokens = completeResponse.completeConversation?.message?.tokens ?? undefined;
2005
+ finalTokens =
2006
+ completeResponse.completeConversation?.message?.tokens ?? undefined;
1999
2007
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2000
- console.log(`📊 [completeConversation] Tokens used: ${finalTokens || 'unknown'}`);
2008
+ console.log(`📊 [completeConversation] Tokens used: ${finalTokens || "unknown"}`);
2001
2009
  }
2002
2010
  }
2003
2011
  // Emit completion event with token count
@@ -2049,17 +2057,41 @@ class Graphlit {
2049
2057
  return;
2050
2058
  const handler = toolHandlers[toolCall.name];
2051
2059
  if (!handler) {
2052
- uiAdapter.setToolResult(toolCall.id, null, `No handler for tool: ${toolCall.name}`);
2060
+ uiAdapter.handleEvent({
2061
+ type: "tool_call_complete",
2062
+ toolCall: {
2063
+ id: toolCall.id,
2064
+ name: toolCall.name,
2065
+ arguments: toolCall.arguments,
2066
+ },
2067
+ error: `No handler for tool: ${toolCall.name}`,
2068
+ });
2053
2069
  return;
2054
2070
  }
2055
2071
  try {
2056
2072
  const args = toolCall.arguments ? JSON.parse(toolCall.arguments) : {};
2057
2073
  const result = await handler(args);
2058
- uiAdapter.setToolResult(toolCall.id, result);
2074
+ uiAdapter.handleEvent({
2075
+ type: "tool_call_complete",
2076
+ toolCall: {
2077
+ id: toolCall.id,
2078
+ name: toolCall.name,
2079
+ arguments: toolCall.arguments,
2080
+ },
2081
+ result: result,
2082
+ });
2059
2083
  }
2060
2084
  catch (error) {
2061
2085
  const errorMessage = error instanceof Error ? error.message : "Tool execution failed";
2062
- uiAdapter.setToolResult(toolCall.id, null, errorMessage);
2086
+ uiAdapter.handleEvent({
2087
+ type: "tool_call_complete",
2088
+ toolCall: {
2089
+ id: toolCall.id,
2090
+ name: toolCall.name,
2091
+ arguments: toolCall.arguments,
2092
+ },
2093
+ error: errorMessage,
2094
+ });
2063
2095
  }
2064
2096
  });
2065
2097
  await Promise.all(toolPromises);
@@ -209,7 +209,7 @@ onEvent, onComplete) {
209
209
  console.log(toolCall.arguments);
210
210
  }
211
211
  onEvent({
212
- type: "tool_call_complete",
212
+ type: "tool_call_parsed",
213
213
  toolCall: {
214
214
  id: toolCall.id,
215
215
  name: toolCall.name,
@@ -484,7 +484,7 @@ onEvent, onComplete) {
484
484
  }
485
485
  }
486
486
  onEvent({
487
- type: "tool_call_complete",
487
+ type: "tool_call_parsed",
488
488
  toolCall: {
489
489
  id: currentTool.id,
490
490
  name: currentTool.name,
@@ -505,7 +505,7 @@ onEvent, onComplete) {
505
505
  // Only emit tool_call_complete if we have valid JSON
506
506
  if (isValidJSON(currentTool.arguments)) {
507
507
  onEvent({
508
- type: "tool_call_complete",
508
+ type: "tool_call_parsed",
509
509
  toolCall: {
510
510
  id: currentTool.id,
511
511
  name: currentTool.name,
@@ -789,7 +789,7 @@ onEvent, onComplete) {
789
789
  console.log(toolCall.arguments);
790
790
  }
791
791
  onEvent({
792
- type: "tool_call_complete",
792
+ type: "tool_call_parsed",
793
793
  toolCall: {
794
794
  id: toolCall.id,
795
795
  name: toolCall.name,
@@ -853,7 +853,7 @@ onEvent, onComplete) {
853
853
  },
854
854
  });
855
855
  onEvent({
856
- type: "tool_call_complete",
856
+ type: "tool_call_parsed",
857
857
  toolCall: {
858
858
  id: toolCall.id,
859
859
  name: toolCall.name,
@@ -35,15 +35,12 @@ export declare class UIEventAdapter {
35
35
  * Process a raw streaming event and emit appropriate UI events
36
36
  */
37
37
  handleEvent(event: StreamEvent): void;
38
- /**
39
- * Set tool execution result directly (for tool handlers)
40
- */
41
- setToolResult(toolCallId: string, result: unknown, error?: string): void;
42
38
  private handleStart;
43
39
  private handleToken;
44
40
  private handleMessage;
45
41
  private handleToolCallStart;
46
42
  private handleToolCallDelta;
43
+ private handleToolCallParsed;
47
44
  private handleToolCallComplete;
48
45
  private handleComplete;
49
46
  private handleError;
@@ -54,8 +54,11 @@ export class UIEventAdapter {
54
54
  case "tool_call_delta":
55
55
  this.handleToolCallDelta(event.toolCallId, event.argumentDelta);
56
56
  break;
57
+ case "tool_call_parsed":
58
+ this.handleToolCallParsed(event.toolCall);
59
+ break;
57
60
  case "tool_call_complete":
58
- this.handleToolCallComplete(event.toolCall);
61
+ this.handleToolCallComplete(event.toolCall, event.result, event.error);
59
62
  break;
60
63
  case "complete":
61
64
  this.handleComplete(event.tokens);
@@ -65,32 +68,6 @@ export class UIEventAdapter {
65
68
  break;
66
69
  }
67
70
  }
68
- /**
69
- * Set tool execution result directly (for tool handlers)
70
- */
71
- setToolResult(toolCallId, result, error) {
72
- const toolData = this.activeToolCalls.get(toolCallId);
73
- if (toolData) {
74
- if (error) {
75
- toolData.status = "failed";
76
- this.emitUIEvent({
77
- type: "tool_update",
78
- toolCall: toolData.toolCall,
79
- status: "failed",
80
- error,
81
- });
82
- }
83
- else {
84
- toolData.status = "completed";
85
- this.emitUIEvent({
86
- type: "tool_update",
87
- toolCall: toolData.toolCall,
88
- status: "completed",
89
- result,
90
- });
91
- }
92
- }
93
- }
94
71
  handleStart(conversationId) {
95
72
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
96
73
  console.log(`🚀 [UIEventAdapter] Handle start - Conversation ID: ${conversationId}`);
@@ -192,9 +169,9 @@ export class UIEventAdapter {
192
169
  console.warn(`🔧 [UIEventAdapter] WARNING: Tool call delta for unknown tool ID: ${toolCallId}`);
193
170
  }
194
171
  }
195
- handleToolCallComplete(toolCall) {
172
+ handleToolCallParsed(toolCall) {
196
173
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
197
- console.log(`🔧 [UIEventAdapter] Tool call complete - ID: ${toolCall.id}, Name: ${toolCall.name}`);
174
+ console.log(`🔧 [UIEventAdapter] Tool call parsed - ID: ${toolCall.id}, Name: ${toolCall.name}`);
198
175
  console.log(`🔧 [UIEventAdapter] Final arguments length: ${toolCall.arguments.length}`);
199
176
  console.log(`🔧 [UIEventAdapter] Final arguments: ${toolCall.arguments.substring(0, 200)}...`);
200
177
  }
@@ -202,16 +179,17 @@ export class UIEventAdapter {
202
179
  if (toolData) {
203
180
  // Update the arguments with the final complete version
204
181
  toolData.toolCall.arguments = toolCall.arguments;
205
- toolData.status = "completed";
182
+ // Mark as ready for execution, not completed
183
+ toolData.status = "ready";
206
184
  this.emitUIEvent({
207
185
  type: "tool_update",
208
186
  toolCall: toolData.toolCall,
209
- status: "completed",
187
+ status: "ready",
210
188
  });
211
189
  }
212
190
  else {
213
191
  // If we don't have this tool call tracked, create it now
214
- console.warn(`🔧 [UIEventAdapter] Tool call complete for untracked tool ID: ${toolCall.id}, creating entry`);
192
+ console.warn(`🔧 [UIEventAdapter] Tool call parsed for untracked tool ID: ${toolCall.id}, creating entry`);
215
193
  const conversationToolCall = {
216
194
  __typename: "ConversationToolCall",
217
195
  id: toolCall.id,
@@ -220,15 +198,36 @@ export class UIEventAdapter {
220
198
  };
221
199
  this.activeToolCalls.set(toolCall.id, {
222
200
  toolCall: conversationToolCall,
223
- status: "completed",
201
+ status: "ready",
224
202
  });
225
203
  this.emitUIEvent({
226
204
  type: "tool_update",
227
205
  toolCall: conversationToolCall,
228
- status: "completed",
206
+ status: "ready",
229
207
  });
230
208
  }
231
209
  }
210
+ handleToolCallComplete(toolCall, result, error) {
211
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
212
+ console.log(`🔧 [UIEventAdapter] Tool call complete - ID: ${toolCall.id}, Name: ${toolCall.name}`);
213
+ console.log(`🔧 [UIEventAdapter] Has result: ${!!result}, Has error: ${!!error}`);
214
+ }
215
+ const toolData = this.activeToolCalls.get(toolCall.id);
216
+ if (toolData) {
217
+ // Update with execution result
218
+ toolData.status = error ? "failed" : "completed";
219
+ this.emitUIEvent({
220
+ type: "tool_update",
221
+ toolCall: toolData.toolCall,
222
+ status: toolData.status,
223
+ result: result,
224
+ error: error,
225
+ });
226
+ }
227
+ else {
228
+ console.warn(`🔧 [UIEventAdapter] Tool call complete for unknown tool ID: ${toolCall.id}`);
229
+ }
230
+ }
232
231
  handleComplete(tokens) {
233
232
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
234
233
  console.log(`🔚 [UIEventAdapter] Handle complete - Active tool calls: ${this.activeToolCalls.size}`);
@@ -244,7 +243,7 @@ export class UIEventAdapter {
244
243
  // Process any remaining chunks before completing
245
244
  if (this.chunkQueue.length > 0) {
246
245
  // Add all remaining chunks to current message
247
- const remainingChunks = this.chunkQueue.join('');
246
+ const remainingChunks = this.chunkQueue.join("");
248
247
  const chunkCount = this.chunkQueue.length;
249
248
  this.currentMessage += remainingChunks;
250
249
  this.chunkQueue.length = 0; // Clear the queue after processing
@@ -256,7 +255,7 @@ export class UIEventAdapter {
256
255
  if (this.chunkBuffer) {
257
256
  const finalChunks = this.chunkBuffer.flush();
258
257
  if (finalChunks.length > 0) {
259
- const finalContent = finalChunks.join('');
258
+ const finalContent = finalChunks.join("");
260
259
  this.currentMessage += finalContent;
261
260
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
262
261
  console.log(`🔚 [UIEventAdapter] Flushed buffer with ${finalChunks.length} chunks: "${finalContent}"`);
@@ -278,10 +277,11 @@ export class UIEventAdapter {
278
277
  // Add final timing metadata
279
278
  if (this.streamStartTime > 0) {
280
279
  const totalTime = Date.now() - this.streamStartTime;
281
- // Final throughput (chars/second)
282
- finalMessage.throughput = totalTime > 0
283
- ? Math.round((this.currentMessage.length / totalTime) * 1000)
284
- : 0;
280
+ // Final throughput (chars/second) - includes entire duration
281
+ finalMessage.throughput =
282
+ totalTime > 0
283
+ ? Math.round((this.currentMessage.length / totalTime) * 1000)
284
+ : 0;
285
285
  // Total completion time in seconds
286
286
  finalMessage.completionTime = totalTime / 1000;
287
287
  // Add time to first token if we have it (useful metric)
@@ -296,7 +296,9 @@ export class UIEventAdapter {
296
296
  const completionTime = Date.now();
297
297
  const finalMetrics = {
298
298
  totalTime: this.streamStartTime > 0 ? completionTime - this.streamStartTime : 0,
299
- conversationDuration: this.conversationStartTime > 0 ? completionTime - this.conversationStartTime : 0,
299
+ conversationDuration: this.conversationStartTime > 0
300
+ ? completionTime - this.conversationStartTime
301
+ : 0,
300
302
  };
301
303
  // Add TTFT if we have it
302
304
  if (this.firstTokenTime > 0 && this.streamStartTime > 0) {
@@ -314,6 +316,13 @@ export class UIEventAdapter {
314
316
  const avgDelay = this.tokenDelays.reduce((a, b) => a + b, 0) / this.tokenDelays.length;
315
317
  finalMetrics.avgTokenDelay = Math.round(avgDelay);
316
318
  }
319
+ // Calculate streaming throughput (excludes TTFT)
320
+ if (this.firstTokenTime > 0 && this.streamStartTime > 0) {
321
+ const streamingTime = completionTime - this.firstTokenTime;
322
+ if (streamingTime > 0) {
323
+ finalMetrics.streamingThroughput = Math.round((this.currentMessage.length / streamingTime) * 1000);
324
+ }
325
+ }
317
326
  this.emitUIEvent({
318
327
  type: "conversation_completed",
319
328
  message: finalMessage,
@@ -25,6 +25,13 @@ export type StreamEvent = {
25
25
  type: "tool_call_delta";
26
26
  toolCallId: string;
27
27
  argumentDelta: string;
28
+ } | {
29
+ type: "tool_call_parsed";
30
+ toolCall: {
31
+ id: string;
32
+ name: string;
33
+ arguments: string;
34
+ };
28
35
  } | {
29
36
  type: "tool_call_complete";
30
37
  toolCall: {
@@ -32,6 +39,8 @@ export type StreamEvent = {
32
39
  name: string;
33
40
  arguments: string;
34
41
  };
42
+ result?: unknown;
43
+ error?: string;
35
44
  } | {
36
45
  type: "complete";
37
46
  messageId?: string;
@@ -2,7 +2,7 @@ import { ConversationMessage, ConversationToolCall } from "../generated/graphql-
2
2
  /**
3
3
  * Tool execution status for streaming
4
4
  */
5
- export type ToolExecutionStatus = "preparing" | "executing" | "completed" | "failed";
5
+ export type ToolExecutionStatus = "preparing" | "executing" | "ready" | "completed" | "failed";
6
6
  /**
7
7
  * Simplified UI-focused streaming events using GraphQL types
8
8
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "graphlit-client",
3
- "version": "1.0.20250613004",
3
+ "version": "1.0.20250613006",
4
4
  "description": "Graphlit API Client for TypeScript",
5
5
  "type": "module",
6
6
  "main": "./dist/client.js",