graphlit-client 1.0.20250610009 → 1.0.20250610010
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.d.ts +1 -36
- package/dist/client.js +0 -2
- package/dist/streaming/providers.d.ts +1 -1
- package/dist/streaming/ui-event-adapter.d.ts +1 -1
- package/dist/types/internal.d.ts +42 -0
- package/dist/types/internal.js +5 -0
- package/package.json +1 -1
- package/dist/stream-helpers.d.ts +0 -106
- package/dist/stream-helpers.js +0 -237
package/dist/client.d.ts
CHANGED
@@ -2,40 +2,6 @@ import { ApolloClient, NormalizedCacheObject } from "@apollo/client/core";
|
|
2
2
|
import * as Types from "./generated/graphql-types.js";
|
3
3
|
import { AgentOptions, AgentResult, StreamAgentOptions, ToolHandler } from "./types/agent.js";
|
4
4
|
import { AgentStreamEvent } from "./types/ui-events.js";
|
5
|
-
export type StreamEvent = {
|
6
|
-
type: "start";
|
7
|
-
conversationId: string;
|
8
|
-
} | {
|
9
|
-
type: "token";
|
10
|
-
token: string;
|
11
|
-
} | {
|
12
|
-
type: "message";
|
13
|
-
message: string;
|
14
|
-
} | {
|
15
|
-
type: "tool_call_start";
|
16
|
-
toolCall: {
|
17
|
-
id: string;
|
18
|
-
name: string;
|
19
|
-
};
|
20
|
-
} | {
|
21
|
-
type: "tool_call_delta";
|
22
|
-
toolCallId: string;
|
23
|
-
argumentDelta: string;
|
24
|
-
} | {
|
25
|
-
type: "tool_call_complete";
|
26
|
-
toolCall: {
|
27
|
-
id: string;
|
28
|
-
name: string;
|
29
|
-
arguments: string;
|
30
|
-
};
|
31
|
-
} | {
|
32
|
-
type: "complete";
|
33
|
-
messageId?: string;
|
34
|
-
conversationId?: string;
|
35
|
-
} | {
|
36
|
-
type: "error";
|
37
|
-
error: string;
|
38
|
-
};
|
39
5
|
export type { AgentOptions, AgentResult, StreamAgentOptions, ToolCallResult, UsageInfo, AgentError, } from "./types/agent.js";
|
40
6
|
export type { AgentStreamEvent } from "./types/ui-events.js";
|
41
7
|
declare class Graphlit {
|
@@ -376,7 +342,7 @@ declare class Graphlit {
|
|
376
342
|
* @param options - Stream agent options
|
377
343
|
* @throws Error if streaming is not supported
|
378
344
|
*/
|
379
|
-
streamAgent(prompt: string, onEvent: (event:
|
345
|
+
streamAgent(prompt: string, onEvent: (event: AgentStreamEvent) => void, conversationId?: string, specification?: Types.EntityReferenceInput, tools?: Types.ToolDefinitionInput[], toolHandlers?: Record<string, ToolHandler>, options?: StreamAgentOptions, mimeType?: string, data?: string, // base64 encoded
|
380
346
|
correlationId?: string): Promise<void>;
|
381
347
|
/**
|
382
348
|
* Execute the streaming agent workflow with tool calling loop
|
@@ -417,4 +383,3 @@ declare class Graphlit {
|
|
417
383
|
}
|
418
384
|
export { Graphlit };
|
419
385
|
export * as Types from "./generated/graphql-types.js";
|
420
|
-
export { StreamEventAggregator, AggregatedEvent, formatSSEEvent, createSSEStream, wrapToolHandlers, enhanceToolCalls, ConversationMetrics, ToolResultEmitter, ServerMapping, } from "./stream-helpers.js";
|
package/dist/client.js
CHANGED
@@ -2113,5 +2113,3 @@ class Graphlit {
|
|
2113
2113
|
}
|
2114
2114
|
export { Graphlit };
|
2115
2115
|
export * as Types from "./generated/graphql-types.js";
|
2116
|
-
// Export streaming helpers
|
2117
|
-
export { StreamEventAggregator, formatSSEEvent, createSSEStream, wrapToolHandlers, enhanceToolCalls, ConversationMetrics, } from "./stream-helpers.js";
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { ConversationToolCall, Specification, ToolDefinitionInput } from "../generated/graphql-types.js";
|
2
|
-
import { StreamEvent } from "../client.js";
|
3
2
|
import { OpenAIMessage, AnthropicMessage, GoogleMessage } from "./llm-formatters.js";
|
3
|
+
import { StreamEvent } from "../types/internal.js";
|
4
4
|
/**
|
5
5
|
* Stream with OpenAI SDK
|
6
6
|
*/
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { AgentStreamEvent } from "../types/ui-events.js";
|
2
|
-
import { StreamEvent } from "../
|
2
|
+
import { StreamEvent } from "../types/internal.js";
|
3
3
|
import { ChunkingStrategy } from "./chunk-buffer.js";
|
4
4
|
/**
|
5
5
|
* Adapter that transforms low-level streaming events into high-level UI events
|
@@ -0,0 +1,42 @@
|
|
1
|
+
/**
|
2
|
+
* Internal types used by the streaming implementation
|
3
|
+
* These are not exported to consumers of the library
|
4
|
+
*/
|
5
|
+
/**
|
6
|
+
* Low-level streaming events used internally by providers
|
7
|
+
* These get transformed into AgentStreamEvent by UIEventAdapter
|
8
|
+
*/
|
9
|
+
export type StreamEvent = {
|
10
|
+
type: "start";
|
11
|
+
conversationId: string;
|
12
|
+
} | {
|
13
|
+
type: "token";
|
14
|
+
token: string;
|
15
|
+
} | {
|
16
|
+
type: "message";
|
17
|
+
message: string;
|
18
|
+
} | {
|
19
|
+
type: "tool_call_start";
|
20
|
+
toolCall: {
|
21
|
+
id: string;
|
22
|
+
name: string;
|
23
|
+
};
|
24
|
+
} | {
|
25
|
+
type: "tool_call_delta";
|
26
|
+
toolCallId: string;
|
27
|
+
argumentDelta: string;
|
28
|
+
} | {
|
29
|
+
type: "tool_call_complete";
|
30
|
+
toolCall: {
|
31
|
+
id: string;
|
32
|
+
name: string;
|
33
|
+
arguments: string;
|
34
|
+
};
|
35
|
+
} | {
|
36
|
+
type: "complete";
|
37
|
+
messageId?: string;
|
38
|
+
conversationId?: string;
|
39
|
+
} | {
|
40
|
+
type: "error";
|
41
|
+
error: string;
|
42
|
+
};
|
package/package.json
CHANGED
package/dist/stream-helpers.d.ts
DELETED
@@ -1,106 +0,0 @@
|
|
1
|
-
import { StreamEvent } from "./client.js";
|
2
|
-
import { ConversationRoleTypes } from "./generated/graphql-types.js";
|
3
|
-
export declare class StreamEventAggregator {
|
4
|
-
private conversationId;
|
5
|
-
private messageBuffer;
|
6
|
-
private toolCallsBuffer;
|
7
|
-
private isFirstAssistantMessage;
|
8
|
-
private hasReceivedToolCalls;
|
9
|
-
private tokenBuffer;
|
10
|
-
/**
|
11
|
-
* Process a stream event and return any complete messages ready for the UI
|
12
|
-
*/
|
13
|
-
processEvent(event: StreamEvent): AggregatedEvent | null;
|
14
|
-
/**
|
15
|
-
* Reset the aggregator for a new conversation
|
16
|
-
*/
|
17
|
-
reset(): void;
|
18
|
-
/**
|
19
|
-
* Get current state (useful for debugging)
|
20
|
-
*/
|
21
|
-
getState(): {
|
22
|
-
conversationId: string;
|
23
|
-
messageBuffer: string;
|
24
|
-
toolCallsCount: number;
|
25
|
-
hasReceivedToolCalls: boolean;
|
26
|
-
isFirstAssistantMessage: boolean;
|
27
|
-
tokenCount: number;
|
28
|
-
};
|
29
|
-
}
|
30
|
-
/**
|
31
|
-
* Aggregated event types that are ready for UI consumption
|
32
|
-
*/
|
33
|
-
export type AggregatedEvent = {
|
34
|
-
type: "conversationStarted";
|
35
|
-
conversationId: string;
|
36
|
-
} | {
|
37
|
-
type: "token";
|
38
|
-
token: string;
|
39
|
-
accumulated: string;
|
40
|
-
} | {
|
41
|
-
type: "assistantMessage";
|
42
|
-
message: {
|
43
|
-
message?: string | null;
|
44
|
-
role?: ConversationRoleTypes | null;
|
45
|
-
toolCalls?: any[];
|
46
|
-
};
|
47
|
-
isFinal: boolean;
|
48
|
-
conversationId?: string;
|
49
|
-
} | {
|
50
|
-
type: "streamComplete";
|
51
|
-
conversationId?: string;
|
52
|
-
} | {
|
53
|
-
type: "error";
|
54
|
-
error: string;
|
55
|
-
};
|
56
|
-
/**
|
57
|
-
* Helper to create an SSE response with proper formatting
|
58
|
-
*/
|
59
|
-
export declare function formatSSEEvent(data: any, eventName?: string): string;
|
60
|
-
/**
|
61
|
-
* Helper to create a TransformStream for SSE with built-in ping support
|
62
|
-
*/
|
63
|
-
export declare function createSSEStream(options?: {
|
64
|
-
pingInterval?: number;
|
65
|
-
}): {
|
66
|
-
readable: ReadableStream<any>;
|
67
|
-
sendEvent: (data: any, eventName?: string) => Promise<void>;
|
68
|
-
close: () => Promise<void>;
|
69
|
-
writer: WritableStreamDefaultWriter<any>;
|
70
|
-
};
|
71
|
-
/**
|
72
|
-
* Helper to wrap tool handlers with result emission
|
73
|
-
*/
|
74
|
-
export interface ToolResultEmitter {
|
75
|
-
(toolCallId: string, result: any, status: "complete" | "error" | "blocked", duration: number): void;
|
76
|
-
}
|
77
|
-
export declare function wrapToolHandlers(handlers: Record<string, (args: any) => Promise<any>>, emitResult: ToolResultEmitter): Record<string, (args: any) => Promise<any>>;
|
78
|
-
/**
|
79
|
-
* Helper to enhance tool calls with server information
|
80
|
-
*/
|
81
|
-
export interface ServerMapping {
|
82
|
-
toolName: string;
|
83
|
-
serverName: string;
|
84
|
-
serverId: string;
|
85
|
-
}
|
86
|
-
export declare function enhanceToolCalls(toolCalls: any[], serverMappings: ServerMapping[]): any[];
|
87
|
-
/**
|
88
|
-
* Helper to track conversation metrics
|
89
|
-
*/
|
90
|
-
export declare class ConversationMetrics {
|
91
|
-
private startTime;
|
92
|
-
private tokenCount;
|
93
|
-
private toolCallCount;
|
94
|
-
private errorCount;
|
95
|
-
recordToken(): void;
|
96
|
-
recordToolCall(): void;
|
97
|
-
recordError(): void;
|
98
|
-
getMetrics(): {
|
99
|
-
duration: number;
|
100
|
-
tokenCount: number;
|
101
|
-
toolCallCount: number;
|
102
|
-
errorCount: number;
|
103
|
-
tokensPerSecond: number;
|
104
|
-
};
|
105
|
-
reset(): void;
|
106
|
-
}
|
package/dist/stream-helpers.js
DELETED
@@ -1,237 +0,0 @@
|
|
1
|
-
import { ConversationRoleTypes, } from "./generated/graphql-types.js";
|
2
|
-
export class StreamEventAggregator {
|
3
|
-
conversationId = "";
|
4
|
-
messageBuffer = "";
|
5
|
-
toolCallsBuffer = new Map();
|
6
|
-
isFirstAssistantMessage = true;
|
7
|
-
hasReceivedToolCalls = false;
|
8
|
-
tokenBuffer = [];
|
9
|
-
/**
|
10
|
-
* Process a stream event and return any complete messages ready for the UI
|
11
|
-
*/
|
12
|
-
processEvent(event) {
|
13
|
-
switch (event.type) {
|
14
|
-
case "start":
|
15
|
-
this.conversationId = event.conversationId;
|
16
|
-
return {
|
17
|
-
type: "conversationStarted",
|
18
|
-
conversationId: event.conversationId,
|
19
|
-
};
|
20
|
-
case "token":
|
21
|
-
this.messageBuffer += event.token;
|
22
|
-
this.tokenBuffer.push(event.token);
|
23
|
-
return {
|
24
|
-
type: "token",
|
25
|
-
token: event.token,
|
26
|
-
accumulated: this.messageBuffer,
|
27
|
-
};
|
28
|
-
case "message":
|
29
|
-
// SDK provides accumulated message - we can use this instead of our buffer
|
30
|
-
this.messageBuffer = event.message;
|
31
|
-
return null; // Don't emit, wait for complete event
|
32
|
-
case "tool_call_start":
|
33
|
-
this.hasReceivedToolCalls = true;
|
34
|
-
this.toolCallsBuffer.set(event.toolCall.id, {
|
35
|
-
id: event.toolCall.id,
|
36
|
-
name: event.toolCall.name,
|
37
|
-
argumentsBuffer: "",
|
38
|
-
isComplete: false,
|
39
|
-
startTime: Date.now(),
|
40
|
-
});
|
41
|
-
return null; // Buffer until complete
|
42
|
-
case "tool_call_delta":
|
43
|
-
const toolCall = this.toolCallsBuffer.get(event.toolCallId);
|
44
|
-
if (toolCall) {
|
45
|
-
toolCall.argumentsBuffer += event.argumentDelta;
|
46
|
-
}
|
47
|
-
return null; // Buffer until complete
|
48
|
-
case "tool_call_complete":
|
49
|
-
const completeToolCall = this.toolCallsBuffer.get(event.toolCall.id);
|
50
|
-
if (completeToolCall) {
|
51
|
-
completeToolCall.argumentsBuffer = event.toolCall.arguments;
|
52
|
-
completeToolCall.isComplete = true;
|
53
|
-
}
|
54
|
-
// Check if all tool calls are complete
|
55
|
-
const allComplete = Array.from(this.toolCallsBuffer.values()).every((tc) => tc.isComplete);
|
56
|
-
if (allComplete &&
|
57
|
-
this.hasReceivedToolCalls &&
|
58
|
-
this.isFirstAssistantMessage) {
|
59
|
-
// Emit complete assistant message with all tool calls
|
60
|
-
const toolCalls = Array.from(this.toolCallsBuffer.values()).map((tc) => ({
|
61
|
-
id: tc.id,
|
62
|
-
name: tc.name,
|
63
|
-
arguments: tc.argumentsBuffer,
|
64
|
-
status: "pending",
|
65
|
-
}));
|
66
|
-
this.isFirstAssistantMessage = false;
|
67
|
-
return {
|
68
|
-
type: "assistantMessage",
|
69
|
-
message: {
|
70
|
-
message: this.messageBuffer,
|
71
|
-
role: ConversationRoleTypes.Assistant,
|
72
|
-
toolCalls,
|
73
|
-
},
|
74
|
-
isFinal: false,
|
75
|
-
};
|
76
|
-
}
|
77
|
-
return null;
|
78
|
-
case "complete":
|
79
|
-
// If we haven't sent a message yet (no tool calls), send it now
|
80
|
-
if (this.isFirstAssistantMessage && !this.hasReceivedToolCalls) {
|
81
|
-
return {
|
82
|
-
type: "assistantMessage",
|
83
|
-
message: {
|
84
|
-
message: this.messageBuffer,
|
85
|
-
role: ConversationRoleTypes.Assistant,
|
86
|
-
},
|
87
|
-
isFinal: true,
|
88
|
-
conversationId: event.conversationId,
|
89
|
-
};
|
90
|
-
}
|
91
|
-
return { type: "streamComplete", conversationId: event.conversationId };
|
92
|
-
case "error":
|
93
|
-
return { type: "error", error: event.error };
|
94
|
-
default:
|
95
|
-
return null;
|
96
|
-
}
|
97
|
-
}
|
98
|
-
/**
|
99
|
-
* Reset the aggregator for a new conversation
|
100
|
-
*/
|
101
|
-
reset() {
|
102
|
-
this.conversationId = "";
|
103
|
-
this.messageBuffer = "";
|
104
|
-
this.toolCallsBuffer.clear();
|
105
|
-
this.isFirstAssistantMessage = true;
|
106
|
-
this.hasReceivedToolCalls = false;
|
107
|
-
this.tokenBuffer = [];
|
108
|
-
}
|
109
|
-
/**
|
110
|
-
* Get current state (useful for debugging)
|
111
|
-
*/
|
112
|
-
getState() {
|
113
|
-
return {
|
114
|
-
conversationId: this.conversationId,
|
115
|
-
messageBuffer: this.messageBuffer,
|
116
|
-
toolCallsCount: this.toolCallsBuffer.size,
|
117
|
-
hasReceivedToolCalls: this.hasReceivedToolCalls,
|
118
|
-
isFirstAssistantMessage: this.isFirstAssistantMessage,
|
119
|
-
tokenCount: this.tokenBuffer.length,
|
120
|
-
};
|
121
|
-
}
|
122
|
-
}
|
123
|
-
/**
|
124
|
-
* Helper to create an SSE response with proper formatting
|
125
|
-
*/
|
126
|
-
export function formatSSEEvent(data, eventName = "message") {
|
127
|
-
if (typeof data === "string") {
|
128
|
-
return `event: ${eventName}\ndata: ${data}\n\n`;
|
129
|
-
}
|
130
|
-
return `event: ${eventName}\ndata: ${JSON.stringify(data)}\n\n`;
|
131
|
-
}
|
132
|
-
/**
|
133
|
-
* Helper to create a TransformStream for SSE with built-in ping support
|
134
|
-
*/
|
135
|
-
export function createSSEStream(options) {
|
136
|
-
const encoder = new TextEncoder();
|
137
|
-
const { readable, writable } = new TransformStream();
|
138
|
-
const writer = writable.getWriter();
|
139
|
-
let pingInterval = null;
|
140
|
-
if (options?.pingInterval) {
|
141
|
-
pingInterval = globalThis.setInterval(() => {
|
142
|
-
writer.write(encoder.encode(":\n\n")).catch(() => {
|
143
|
-
// Ignore errors on ping
|
144
|
-
});
|
145
|
-
}, options.pingInterval);
|
146
|
-
}
|
147
|
-
const sendEvent = (data, eventName = "message") => {
|
148
|
-
const formatted = formatSSEEvent(data, eventName);
|
149
|
-
return writer.write(encoder.encode(formatted));
|
150
|
-
};
|
151
|
-
const close = async () => {
|
152
|
-
if (pingInterval) {
|
153
|
-
globalThis.clearInterval(pingInterval);
|
154
|
-
}
|
155
|
-
await writer.close();
|
156
|
-
};
|
157
|
-
return {
|
158
|
-
readable,
|
159
|
-
sendEvent,
|
160
|
-
close,
|
161
|
-
writer,
|
162
|
-
};
|
163
|
-
}
|
164
|
-
export function wrapToolHandlers(handlers, emitResult) {
|
165
|
-
const wrapped = {};
|
166
|
-
Object.entries(handlers).forEach(([name, handler]) => {
|
167
|
-
wrapped[name] = async (args) => {
|
168
|
-
const toolCallId = `tool_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
169
|
-
const startTime = Date.now();
|
170
|
-
try {
|
171
|
-
const result = await handler(args);
|
172
|
-
const duration = Date.now() - startTime;
|
173
|
-
// Emit success result
|
174
|
-
emitResult(toolCallId, { status: "success", result }, "complete", duration);
|
175
|
-
return result;
|
176
|
-
}
|
177
|
-
catch (error) {
|
178
|
-
const duration = Date.now() - startTime;
|
179
|
-
// Emit error result
|
180
|
-
emitResult(toolCallId, {
|
181
|
-
status: "error",
|
182
|
-
error: error instanceof Error ? error.message : String(error),
|
183
|
-
}, "error", duration);
|
184
|
-
throw error;
|
185
|
-
}
|
186
|
-
};
|
187
|
-
});
|
188
|
-
return wrapped;
|
189
|
-
}
|
190
|
-
export function enhanceToolCalls(toolCalls, serverMappings) {
|
191
|
-
const mappingDict = serverMappings.reduce((acc, mapping) => {
|
192
|
-
acc[mapping.toolName] = {
|
193
|
-
serverName: mapping.serverName,
|
194
|
-
serverId: mapping.serverId,
|
195
|
-
};
|
196
|
-
return acc;
|
197
|
-
}, {});
|
198
|
-
return toolCalls.map((toolCall) => ({
|
199
|
-
...toolCall,
|
200
|
-
serverName: mappingDict[toolCall.name]?.serverName,
|
201
|
-
serverId: mappingDict[toolCall.name]?.serverId,
|
202
|
-
}));
|
203
|
-
}
|
204
|
-
/**
|
205
|
-
* Helper to track conversation metrics
|
206
|
-
*/
|
207
|
-
export class ConversationMetrics {
|
208
|
-
startTime = Date.now();
|
209
|
-
tokenCount = 0;
|
210
|
-
toolCallCount = 0;
|
211
|
-
errorCount = 0;
|
212
|
-
recordToken() {
|
213
|
-
this.tokenCount++;
|
214
|
-
}
|
215
|
-
recordToolCall() {
|
216
|
-
this.toolCallCount++;
|
217
|
-
}
|
218
|
-
recordError() {
|
219
|
-
this.errorCount++;
|
220
|
-
}
|
221
|
-
getMetrics() {
|
222
|
-
const duration = Date.now() - this.startTime;
|
223
|
-
return {
|
224
|
-
duration,
|
225
|
-
tokenCount: this.tokenCount,
|
226
|
-
toolCallCount: this.toolCallCount,
|
227
|
-
errorCount: this.errorCount,
|
228
|
-
tokensPerSecond: this.tokenCount / (duration / 1000),
|
229
|
-
};
|
230
|
-
}
|
231
|
-
reset() {
|
232
|
-
this.startTime = Date.now();
|
233
|
-
this.tokenCount = 0;
|
234
|
-
this.toolCallCount = 0;
|
235
|
-
this.errorCount = 0;
|
236
|
-
}
|
237
|
-
}
|