10xgraph-client 0.0.0-stage → 0.6.0

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.
Files changed (125) hide show
  1. package/CHANGELOG.md +276 -0
  2. package/LICENSE +21 -0
  3. package/README.md +400 -2
  4. package/dist/agent.d.ts +22 -0
  5. package/dist/agent.d.ts.map +1 -0
  6. package/dist/client.d.ts +479 -0
  7. package/dist/client.d.ts.map +1 -0
  8. package/dist/compat.d.ts +28 -0
  9. package/dist/compat.d.ts.map +1 -0
  10. package/dist/endpoints/addThreadMessages.d.ts +22 -0
  11. package/dist/endpoints/addThreadMessages.d.ts.map +1 -0
  12. package/dist/endpoints/clearThreadState.d.ts +15 -0
  13. package/dist/endpoints/clearThreadState.d.ts.map +1 -0
  14. package/dist/endpoints/deleteMemory.d.ts +19 -0
  15. package/dist/endpoints/deleteMemory.d.ts.map +1 -0
  16. package/dist/endpoints/deleteThread.d.ts +19 -0
  17. package/dist/endpoints/deleteThread.d.ts.map +1 -0
  18. package/dist/endpoints/deleteThreadMessage.d.ts +20 -0
  19. package/dist/endpoints/deleteThreadMessage.d.ts.map +1 -0
  20. package/dist/endpoints/files.d.ts +83 -0
  21. package/dist/endpoints/files.d.ts.map +1 -0
  22. package/dist/endpoints/fixGraph.d.ts +29 -0
  23. package/dist/endpoints/fixGraph.d.ts.map +1 -0
  24. package/dist/endpoints/forgetMemories.d.ts +22 -0
  25. package/dist/endpoints/forgetMemories.d.ts.map +1 -0
  26. package/dist/endpoints/getMemory.d.ts +19 -0
  27. package/dist/endpoints/getMemory.d.ts.map +1 -0
  28. package/dist/endpoints/graph.d.ts +39 -0
  29. package/dist/endpoints/graph.d.ts.map +1 -0
  30. package/dist/endpoints/graphTools.d.ts +32 -0
  31. package/dist/endpoints/graphTools.d.ts.map +1 -0
  32. package/dist/endpoints/invoke.d.ts +59 -0
  33. package/dist/endpoints/invoke.d.ts.map +1 -0
  34. package/dist/endpoints/listMemories.d.ts +19 -0
  35. package/dist/endpoints/listMemories.d.ts.map +1 -0
  36. package/dist/endpoints/metadata.d.ts +6 -0
  37. package/dist/endpoints/metadata.d.ts.map +1 -0
  38. package/dist/endpoints/observability.d.ts +58 -0
  39. package/dist/endpoints/observability.d.ts.map +1 -0
  40. package/dist/endpoints/ping.d.ts +10 -0
  41. package/dist/endpoints/ping.d.ts.map +1 -0
  42. package/dist/endpoints/realtime.d.ts +134 -0
  43. package/dist/endpoints/realtime.d.ts.map +1 -0
  44. package/dist/endpoints/searchMemory.d.ts +57 -0
  45. package/dist/endpoints/searchMemory.d.ts.map +1 -0
  46. package/dist/endpoints/stateSchema.d.ts +50 -0
  47. package/dist/endpoints/stateSchema.d.ts.map +1 -0
  48. package/dist/endpoints/stopGraph.d.ts +26 -0
  49. package/dist/endpoints/stopGraph.d.ts.map +1 -0
  50. package/dist/endpoints/storeMemory.d.ts +33 -0
  51. package/dist/endpoints/storeMemory.d.ts.map +1 -0
  52. package/dist/endpoints/stream.d.ts +60 -0
  53. package/dist/endpoints/stream.d.ts.map +1 -0
  54. package/dist/endpoints/threadDetails.d.ts +19 -0
  55. package/dist/endpoints/threadDetails.d.ts.map +1 -0
  56. package/dist/endpoints/threadMessage.d.ts +17 -0
  57. package/dist/endpoints/threadMessage.d.ts.map +1 -0
  58. package/dist/endpoints/threadMessages.d.ts +23 -0
  59. package/dist/endpoints/threadMessages.d.ts.map +1 -0
  60. package/dist/endpoints/threadState.d.ts +14 -0
  61. package/dist/endpoints/threadState.d.ts.map +1 -0
  62. package/dist/endpoints/threads.d.ts +30 -0
  63. package/dist/endpoints/threads.d.ts.map +1 -0
  64. package/dist/endpoints/updateMemory.d.ts +21 -0
  65. package/dist/endpoints/updateMemory.d.ts.map +1 -0
  66. package/dist/endpoints/updateThreadState.d.ts +18 -0
  67. package/dist/endpoints/updateThreadState.d.ts.map +1 -0
  68. package/dist/endpoints/wsStream.d.ts +33 -0
  69. package/dist/endpoints/wsStream.d.ts.map +1 -0
  70. package/dist/errors.d.ts +155 -0
  71. package/dist/errors.d.ts.map +1 -0
  72. package/dist/index.cjs +6 -0
  73. package/dist/index.cjs.map +1 -0
  74. package/dist/index.d.ts +39 -0
  75. package/dist/index.d.ts.map +1 -0
  76. package/dist/index.js +2664 -0
  77. package/dist/index.js.map +1 -0
  78. package/dist/message.d.ts +174 -0
  79. package/dist/message.d.ts.map +1 -0
  80. package/dist/request.d.ts +33 -0
  81. package/dist/request.d.ts.map +1 -0
  82. package/dist/tools.d.ts +67 -0
  83. package/dist/tools.d.ts.map +1 -0
  84. package/dist/ws.d.ts +48 -0
  85. package/dist/ws.d.ts.map +1 -0
  86. package/package.json +99 -4
  87. package/src/agent.ts +43 -0
  88. package/src/client.ts +1044 -0
  89. package/src/compat.ts +35 -0
  90. package/src/endpoints/addThreadMessages.ts +83 -0
  91. package/src/endpoints/clearThreadState.ts +75 -0
  92. package/src/endpoints/deleteMemory.ts +91 -0
  93. package/src/endpoints/deleteThread.ts +78 -0
  94. package/src/endpoints/deleteThreadMessage.ts +83 -0
  95. package/src/endpoints/files.ts +274 -0
  96. package/src/endpoints/fixGraph.ts +91 -0
  97. package/src/endpoints/forgetMemories.ts +95 -0
  98. package/src/endpoints/getMemory.ts +82 -0
  99. package/src/endpoints/graph.ts +97 -0
  100. package/src/endpoints/graphTools.ts +90 -0
  101. package/src/endpoints/invoke.ts +318 -0
  102. package/src/endpoints/listMemories.ts +97 -0
  103. package/src/endpoints/metadata.ts +6 -0
  104. package/src/endpoints/observability.ts +107 -0
  105. package/src/endpoints/ping.ts +58 -0
  106. package/src/endpoints/realtime.ts +326 -0
  107. package/src/endpoints/searchMemory.ts +132 -0
  108. package/src/endpoints/stateSchema.ts +106 -0
  109. package/src/endpoints/stopGraph.ts +85 -0
  110. package/src/endpoints/storeMemory.ts +98 -0
  111. package/src/endpoints/stream.ts +440 -0
  112. package/src/endpoints/threadDetails.ts +78 -0
  113. package/src/endpoints/threadMessage.ts +76 -0
  114. package/src/endpoints/threadMessages.ts +97 -0
  115. package/src/endpoints/threadState.ts +74 -0
  116. package/src/endpoints/threads.ts +112 -0
  117. package/src/endpoints/updateMemory.ts +90 -0
  118. package/src/endpoints/updateThreadState.ts +82 -0
  119. package/src/endpoints/wsStream.ts +251 -0
  120. package/src/errors.ts +553 -0
  121. package/src/index.ts +108 -0
  122. package/src/message.ts +436 -0
  123. package/src/request.ts +168 -0
  124. package/src/tools.ts +225 -0
  125. package/src/ws.ts +100 -0
package/src/client.ts ADDED
@@ -0,0 +1,1044 @@
1
+ import { ToolHandler, ToolRegistration, ToolExecutor } from './tools.js';
2
+ import { Message } from './message.js';
3
+ import { ping, PingContext, PingResponse } from './endpoints/ping.js';
4
+ import { graph, GraphContext, GraphResponse } from './endpoints/graph.js';
5
+ import { graphTools, GraphToolsContext, GraphToolsResponse } from './endpoints/graphTools.js';
6
+ import {
7
+ observability,
8
+ ObservabilityContext,
9
+ ObservabilityResponse,
10
+ } from './endpoints/observability.js';
11
+ import { stateSchema, StateSchemaContext, StateSchemaResponse } from './endpoints/stateSchema.js';
12
+ import { threadState, ThreadStateContext, ThreadStateResponse } from './endpoints/threadState.js';
13
+ import {
14
+ updateThreadState,
15
+ UpdateThreadStateContext,
16
+ UpdateThreadStateRequest,
17
+ UpdateThreadStateResponse,
18
+ } from './endpoints/updateThreadState.js';
19
+ import {
20
+ clearThreadState,
21
+ ClearThreadStateContext,
22
+ ClearThreadStateResponse,
23
+ } from './endpoints/clearThreadState.js';
24
+ import {
25
+ threadMessages,
26
+ ThreadMessagesContext,
27
+ ThreadMessagesRequest,
28
+ ThreadMessagesResponse,
29
+ } from './endpoints/threadMessages.js';
30
+ import {
31
+ addThreadMessages,
32
+ AddThreadMessagesContext,
33
+ AddThreadMessagesRequest,
34
+ AddThreadMessagesResponse,
35
+ } from './endpoints/addThreadMessages.js';
36
+ import {
37
+ threadMessage,
38
+ ThreadMessageContext,
39
+ ThreadMessageRequest,
40
+ ThreadMessageResponse,
41
+ } from './endpoints/threadMessage.js';
42
+ import {
43
+ threadDetails,
44
+ ThreadDetailsContext,
45
+ ThreadDetailsResponse,
46
+ } from './endpoints/threadDetails.js';
47
+ import {
48
+ deleteThreadMessage,
49
+ DeleteThreadMessageContext,
50
+ DeleteThreadMessageRequest,
51
+ DeleteThreadMessageResponse,
52
+ } from './endpoints/deleteThreadMessage.js';
53
+ import {
54
+ deleteThread,
55
+ DeleteThreadContext,
56
+ DeleteThreadRequest,
57
+ DeleteThreadResponse,
58
+ } from './endpoints/deleteThread.js';
59
+ import { threads, ThreadsContext, ThreadsRequest, ThreadsResponse } from './endpoints/threads.js';
60
+ import {
61
+ invoke as invokeEndpoint,
62
+ InvokeContext,
63
+ InvokeRequest,
64
+ InvokeResult,
65
+ InvokeCallback,
66
+ } from './endpoints/invoke.js';
67
+ import {
68
+ streamInvoke as streamInvokeEndpoint,
69
+ StreamContext,
70
+ StreamRequest,
71
+ StreamChunk,
72
+ } from './endpoints/stream.js';
73
+ import { wsStreamInvoke, WsStreamContext } from './endpoints/wsStream.js';
74
+ import {
75
+ RealtimeSession,
76
+ RealtimeInit,
77
+ RealtimeOptions,
78
+ RealtimeContext,
79
+ } from './endpoints/realtime.js';
80
+ import type { WebSocketImpl } from './ws.js';
81
+ import {
82
+ storeMemory as storeMemoryEndpoint,
83
+ StoreMemoryContext,
84
+ StoreMemoryRequest,
85
+ StoreMemoryResponse,
86
+ } from './endpoints/storeMemory.js';
87
+ import {
88
+ searchMemory as searchMemoryEndpoint,
89
+ SearchMemoryContext,
90
+ SearchMemoryRequest,
91
+ SearchMemoryResponse,
92
+ } from './endpoints/searchMemory.js';
93
+ import {
94
+ getMemory as getMemoryEndpoint,
95
+ GetMemoryContext,
96
+ GetMemoryRequest,
97
+ GetMemoryResponse,
98
+ } from './endpoints/getMemory.js';
99
+ import {
100
+ updateMemory as updateMemoryEndpoint,
101
+ UpdateMemoryContext,
102
+ UpdateMemoryRequest,
103
+ UpdateMemoryResponse,
104
+ } from './endpoints/updateMemory.js';
105
+ import {
106
+ deleteMemory as deleteMemoryEndpoint,
107
+ DeleteMemoryContext,
108
+ DeleteMemoryRequest,
109
+ DeleteMemoryResponse,
110
+ } from './endpoints/deleteMemory.js';
111
+ import {
112
+ listMemories as listMemoriesEndpoint,
113
+ ListMemoriesContext,
114
+ ListMemoriesRequest,
115
+ ListMemoriesResponse,
116
+ } from './endpoints/listMemories.js';
117
+ import {
118
+ forgetMemories as forgetMemoriesEndpoint,
119
+ ForgetMemoriesContext,
120
+ ForgetMemoriesRequest,
121
+ ForgetMemoriesResponse,
122
+ } from './endpoints/forgetMemories.js';
123
+ import {
124
+ stopGraph as stopGraphEndpoint,
125
+ StopGraphContext,
126
+ StopGraphRequest,
127
+ StopGraphResponse,
128
+ } from './endpoints/stopGraph.js';
129
+ import {
130
+ fixGraph as fixGraphEndpoint,
131
+ FixGraphContext,
132
+ FixGraphRequest,
133
+ FixGraphResponse,
134
+ } from './endpoints/fixGraph.js';
135
+ import {
136
+ uploadFile as uploadFileEndpoint,
137
+ getFile as getFileEndpoint,
138
+ getFileInfo as getFileInfoEndpoint,
139
+ getFileAccessUrl as getFileAccessUrlEndpoint,
140
+ getMultimodalConfig as getMultimodalConfigEndpoint,
141
+ FileUploadContext,
142
+ FileUploadResponse,
143
+ FileAccessUrlResponse,
144
+ FileInfoResponse,
145
+ MultimodalConfigResponse,
146
+ } from './endpoints/files.js';
147
+ import { TenxGraphAuth, RequestContext } from './request.js';
148
+
149
+ export interface TenxGraphConfig {
150
+ baseUrl: string;
151
+ authToken?: string | null;
152
+ auth?: TenxGraphAuth | null;
153
+ headers?: HeadersInit;
154
+ credentials?: RequestCredentials;
155
+ timeout?: number; // default 5min
156
+ debug?: boolean;
157
+ webSocketImpl?: WebSocketImpl;
158
+ }
159
+
160
+ function isThreadsRequest(value?: string | ThreadsRequest): value is ThreadsRequest {
161
+ return typeof value === 'object' && value !== null;
162
+ }
163
+
164
+ function normalizeThreadsRequest(
165
+ value?: string | ThreadsRequest,
166
+ offset?: number,
167
+ limit?: number
168
+ ): ThreadsRequest {
169
+ if (isThreadsRequest(value)) {
170
+ return {
171
+ search: value.search,
172
+ offset: value.offset,
173
+ limit: value.limit,
174
+ };
175
+ }
176
+
177
+ return {
178
+ search: value,
179
+ offset,
180
+ limit,
181
+ };
182
+ }
183
+
184
+ function isThreadMessagesRequest(
185
+ value?: string | Omit<ThreadMessagesRequest, 'threadId'>
186
+ ): value is Omit<ThreadMessagesRequest, 'threadId'> {
187
+ return typeof value === 'object' && value !== null;
188
+ }
189
+
190
+ function normalizeThreadMessagesRequest(
191
+ threadId: string | number,
192
+ value?: string | Omit<ThreadMessagesRequest, 'threadId'>,
193
+ offset?: number,
194
+ limit?: number
195
+ ): ThreadMessagesRequest {
196
+ if (isThreadMessagesRequest(value)) {
197
+ return {
198
+ threadId,
199
+ search: value.search,
200
+ offset: value.offset,
201
+ limit: value.limit,
202
+ };
203
+ }
204
+
205
+ return {
206
+ threadId,
207
+ search: value,
208
+ offset,
209
+ limit,
210
+ };
211
+ }
212
+
213
+ export class TenxGraphClient {
214
+ private baseUrl: string;
215
+ private authToken?: string | null;
216
+ private auth?: TenxGraphAuth | null;
217
+ private headers?: HeadersInit;
218
+ private credentials?: RequestCredentials;
219
+ private timeout: number;
220
+ private debug: boolean;
221
+ private webSocketImpl?: WebSocketImpl;
222
+ private toolExecutor: ToolExecutor;
223
+
224
+ constructor(config: TenxGraphConfig) {
225
+ this.baseUrl = config.baseUrl;
226
+ this.authToken = config.authToken;
227
+ this.auth = config.auth;
228
+ this.headers = config.headers;
229
+ this.credentials = config.credentials;
230
+ this.timeout = config.timeout || 300000; // 5 min
231
+ this.debug = config.debug || false;
232
+ this.webSocketImpl = config.webSocketImpl;
233
+ this.toolExecutor = new ToolExecutor([]);
234
+ }
235
+
236
+ private createContext<T extends RequestContext>(): T {
237
+ return {
238
+ baseUrl: this.baseUrl,
239
+ authToken: this.authToken,
240
+ auth: this.auth,
241
+ headers: this.headers,
242
+ credentials: this.credentials,
243
+ timeout: this.timeout,
244
+ debug: this.debug,
245
+ webSocketImpl: this.webSocketImpl,
246
+ } as T;
247
+ }
248
+
249
+ /**
250
+ * Register a tool for remote execution
251
+ */
252
+ registerTool(registration: ToolRegistration): void {
253
+ this.toolExecutor.registerTool(registration);
254
+
255
+ if (this.debug) {
256
+ console.debug(`TenxGraphClient: Registered remote tool handler '${registration.name}'`);
257
+ }
258
+ }
259
+
260
+ /**
261
+ * Register only the client-side implementation of a remote tool.
262
+ * The trusted schema must be declared in the server's 10xgraph.json.
263
+ */
264
+ registerToolHandler(name: string, handler: ToolHandler): void {
265
+ this.registerTool({ name, handler });
266
+ }
267
+
268
+ /**
269
+ * Ping the server to check connectivity
270
+ */
271
+ async ping(): Promise<PingResponse> {
272
+ const context = this.createContext<PingContext>();
273
+
274
+ return ping(context);
275
+ }
276
+
277
+ /**
278
+ * Fetch the agent graph
279
+ */
280
+ async graph(): Promise<GraphResponse> {
281
+ const context = this.createContext<GraphContext>();
282
+
283
+ return graph(context);
284
+ }
285
+
286
+ /**
287
+ * Fetch the tools exposed by the graph's tool nodes, grouped by node.
288
+ * Each tool is tagged with its source (local / mcp / remote).
289
+ */
290
+ async graphTools(): Promise<GraphToolsResponse> {
291
+ const context = this.createContext<GraphToolsContext>();
292
+
293
+ return graphTools(context);
294
+ }
295
+
296
+ /**
297
+ * Fetch the reconstructed observability trace (spans, events, cost) for a
298
+ * thread. Returns the latest run by default, or a specific run when given.
299
+ */
300
+ async observability(threadId: string, runId?: string): Promise<ObservabilityResponse> {
301
+ const context = this.createContext<ObservabilityContext>();
302
+
303
+ return observability(context, threadId, runId);
304
+ }
305
+
306
+ /**
307
+ * Stop a running graph execution for a specific thread
308
+ * @param threadId - The ID of the thread to stop execution for
309
+ * @param config - Optional configuration for the stop operation
310
+ * @returns StopGraphResponse with the stop operation result
311
+ */
312
+ async stopGraph(threadId: string, config?: Record<string, any>): Promise<StopGraphResponse> {
313
+ const context = this.createContext<StopGraphContext>();
314
+
315
+ const request: StopGraphRequest = {
316
+ thread_id: threadId,
317
+ config,
318
+ };
319
+
320
+ return stopGraphEndpoint(context, request);
321
+ }
322
+
323
+ /**
324
+ * Fix graph state by removing messages with empty tool calls
325
+ * This is useful for cleaning up incomplete tool call messages that may have
326
+ * failed or been interrupted during execution.
327
+ *
328
+ * @param threadId - The ID of the thread to fix state for
329
+ * @param config - Optional configuration for the fix operation
330
+ * @returns FixGraphResponse with the fix operation result including removed_count
331
+ */
332
+ async fixGraph(threadId: string, config?: Record<string, any>): Promise<FixGraphResponse> {
333
+ const context = this.createContext<FixGraphContext>();
334
+
335
+ const request: FixGraphRequest = {
336
+ thread_id: threadId,
337
+ config,
338
+ };
339
+
340
+ return fixGraphEndpoint(context, request);
341
+ }
342
+
343
+ /**
344
+ *
345
+
346
+ /**
347
+ * Fetch the state schema of the agent
348
+ */
349
+ async graphStateSchema(): Promise<StateSchemaResponse> {
350
+ const context = this.createContext<StateSchemaContext>();
351
+
352
+ return stateSchema(context);
353
+ }
354
+
355
+ /**
356
+ * ***************** ALL THREAD APIS *****************
357
+ */
358
+
359
+ /**
360
+ * Fetch the state of a specific thread
361
+ * @param threadId - The ID of the thread to fetch state for
362
+ * @returns ThreadStateResponse containing the thread's current state
363
+ */
364
+ async threadState(threadId: string | number): Promise<ThreadStateResponse> {
365
+ const context = this.createContext<ThreadStateContext>();
366
+
367
+ return threadState(context, threadId);
368
+ }
369
+
370
+ /**
371
+ * Update the state of a specific thread (checkpoint)
372
+ * @param threadId - The ID of the thread to update
373
+ * @param config - Configuration map for the thread
374
+ * @param state - New AgentState for the thread
375
+ * @returns UpdateThreadStateResponse with the updated state
376
+ */
377
+ async updateThreadState(
378
+ threadId: string | number,
379
+ config: Record<string, any>,
380
+ state: any // AgentState
381
+ ): Promise<UpdateThreadStateResponse> {
382
+ const context = this.createContext<UpdateThreadStateContext>();
383
+
384
+ const request: UpdateThreadStateRequest = {
385
+ config,
386
+ state,
387
+ };
388
+
389
+ return updateThreadState(context, threadId, request);
390
+ }
391
+
392
+ /**
393
+ * Clear the state of a specific thread (delete checkpoint)
394
+ * @param threadId - The ID of the thread to clear state for
395
+ * @returns ClearThreadStateResponse with the clear operation result
396
+ */
397
+ async clearThreadState(threadId: string | number): Promise<ClearThreadStateResponse> {
398
+ const context = this.createContext<ClearThreadStateContext>();
399
+
400
+ return clearThreadState(context, threadId);
401
+ }
402
+
403
+ /**
404
+ * Fetch details for a specific thread
405
+ * @param threadId - The ID of the thread to fetch
406
+ * @returns ThreadDetailsResponse containing thread details
407
+ */
408
+ async threadDetails(threadId: string | number): Promise<ThreadDetailsResponse> {
409
+ const context = this.createContext<ThreadDetailsContext>();
410
+
411
+ return threadDetails(context, threadId);
412
+ }
413
+
414
+ /**
415
+ * Fetch list of threads with optional search and pagination
416
+ * @param search - Optional search term to filter threads
417
+ * @param offset - Optional offset for pagination (default 0)
418
+ * @param limit - Optional limit for pagination (default no limit)
419
+ * @returns ThreadsResponse containing the list of threads and metadata
420
+ */
421
+ async threads(): Promise<ThreadsResponse>;
422
+ async threads(request: ThreadsRequest): Promise<ThreadsResponse>;
423
+ async threads(
424
+ search?: string | ThreadsRequest,
425
+ offset?: number,
426
+ limit?: number
427
+ ): Promise<ThreadsResponse> {
428
+ const context = this.createContext<ThreadsContext>();
429
+ const request = normalizeThreadsRequest(search, offset, limit);
430
+
431
+ return threads(context, request);
432
+ }
433
+
434
+ /**
435
+ * Fetch messages from a specific thread with optional search and pagination
436
+ * @param threadId - The ID of the thread to fetch messages from
437
+ * @param search - Optional search term to filter messages
438
+ * @param offset - Optional offset for pagination (default 0)
439
+ * @param limit - Optional limit for pagination (default no limit)
440
+ * @returns ThreadMessagesResponse containing the messages and metadata
441
+ */
442
+ async threadMessages(
443
+ threadId: string | number,
444
+ request: Omit<ThreadMessagesRequest, 'threadId'>
445
+ ): Promise<ThreadMessagesResponse>;
446
+ async threadMessages(
447
+ threadId: string | number,
448
+ search?: string | Omit<ThreadMessagesRequest, 'threadId'>,
449
+ offset?: number,
450
+ limit?: number
451
+ ): Promise<ThreadMessagesResponse> {
452
+ const context = this.createContext<ThreadMessagesContext>();
453
+ const request = normalizeThreadMessagesRequest(threadId, search, offset, limit);
454
+
455
+ return threadMessages(context, request);
456
+ }
457
+
458
+ /**
459
+ * Add messages to a specific thread checkpoint
460
+ * @param threadId - The ID of the thread to add messages to
461
+ * @param messages - Array of messages to add to the checkpoint
462
+ * @param config - Configuration map for the checkpoint
463
+ * @param metadata - Optional metadata for the checkpoint
464
+ * @returns AddCheckpointMessagesResponse containing the operation result
465
+ */
466
+ async addThreadMessages(
467
+ threadId: string | number,
468
+ messages: Message[],
469
+ config: Record<string, any> = {},
470
+ metadata?: Record<string, any>
471
+ ): Promise<AddThreadMessagesResponse> {
472
+ const context = this.createContext<AddThreadMessagesContext>();
473
+
474
+ const request: AddThreadMessagesRequest = {
475
+ threadId,
476
+ config,
477
+ messages,
478
+ metadata,
479
+ };
480
+
481
+ return addThreadMessages(context, request);
482
+ }
483
+
484
+ /**
485
+ * Fetch a specific message from a thread by message ID
486
+ * @param threadId - The ID of the thread
487
+ * @param messageId - The ID of the message to fetch
488
+ * @returns ThreadMessageResponse containing the message and metadata
489
+ */
490
+ async singleMessage(
491
+ threadId: string | number,
492
+ messageId: string
493
+ ): Promise<ThreadMessageResponse> {
494
+ const context = this.createContext<ThreadMessageContext>();
495
+
496
+ const request: ThreadMessageRequest = {
497
+ threadId,
498
+ messageId,
499
+ };
500
+
501
+ return threadMessage(context, request);
502
+ }
503
+
504
+ /**
505
+ * Delete a specific message from a thread
506
+ * @param threadId - The ID of the thread
507
+ * @param messageId - The ID of the message to delete
508
+ * @param config - Optional configuration map to send with the request body
509
+ * @returns DeleteThreadMessageResponse containing the deletion result
510
+ */
511
+ async deleteMessage(
512
+ threadId: string | number,
513
+ messageId: string,
514
+ config?: Record<string, any>
515
+ ): Promise<DeleteThreadMessageResponse> {
516
+ const context = this.createContext<DeleteThreadMessageContext>();
517
+
518
+ const request: DeleteThreadMessageRequest = {
519
+ threadId,
520
+ messageId,
521
+ config,
522
+ };
523
+
524
+ return deleteThreadMessage(context, request);
525
+ }
526
+
527
+ /**
528
+ * Delete a specific thread
529
+ * @param threadId - The ID of the thread to delete
530
+ * @param config - Optional configuration map to send with the request body
531
+ * @returns DeleteThreadResponse containing the deletion result
532
+ */
533
+ async deleteThread(
534
+ threadId: string | number,
535
+ config?: Record<string, any>
536
+ ): Promise<DeleteThreadResponse> {
537
+ const context = this.createContext<DeleteThreadContext>();
538
+
539
+ const request: DeleteThreadRequest = {
540
+ threadId,
541
+ config,
542
+ };
543
+
544
+ return deleteThread(context, request);
545
+ }
546
+
547
+ /**
548
+ * Invoke the agent graph with automatic tool execution loop
549
+ * @param messages - Array of messages to send
550
+ * @param options - Invoke options
551
+ * @returns InvokeResult with all messages and intermediate steps
552
+ */
553
+ async invoke(
554
+ messages: Message[],
555
+ options?: {
556
+ initial_state?: Record<string, any>;
557
+ config?: Record<string, any>;
558
+ recursion_limit?: number;
559
+ response_granularity?: 'full' | 'partial' | 'low';
560
+ onPartialResult?: InvokeCallback;
561
+ }
562
+ ): Promise<InvokeResult> {
563
+ const context: InvokeContext = {
564
+ ...this.createContext<InvokeContext>(),
565
+ toolExecutor: this.toolExecutor,
566
+ };
567
+
568
+ // Prepare request
569
+ const request: InvokeRequest = {
570
+ messages: messages.map((msg) => this.serializeMessage(msg)),
571
+ initial_state: options?.initial_state,
572
+ config: options?.config,
573
+ recursion_limit: options?.recursion_limit || 25,
574
+ response_granularity: options?.response_granularity || 'full',
575
+ };
576
+
577
+ // Call the invoke endpoint (which handles the recursion loop)
578
+ return invokeEndpoint(context, request, options?.onPartialResult);
579
+ }
580
+
581
+ /**
582
+ * Stream invoke to the agent graph
583
+ * Returns an async iterable that yields stream chunks as they arrive
584
+ *
585
+ * @param messages - Array of messages to send
586
+ * @param options - Stream options
587
+ * @returns AsyncGenerator of StreamChunk objects
588
+ *
589
+ * @example
590
+ * ```ts
591
+ * const stream = client.streamInvoke([userMessage], {
592
+ * initial_state: {},
593
+ * response_granularity: 'low'
594
+ * });
595
+ *
596
+ * for await (const chunk of stream) {
597
+ * if (chunk.event === 'message') {
598
+ * console.log('Message:', chunk.message?.content);
599
+ * } else if (chunk.event === 'updates') {
600
+ * console.log('State updated:', chunk.state);
601
+ * }
602
+ * }
603
+ * ```
604
+ */
605
+ stream(
606
+ messages: Message[],
607
+ options?: {
608
+ initial_state?: Record<string, any>;
609
+ config?: Record<string, any>;
610
+ recursion_limit?: number;
611
+ response_granularity?: 'full' | 'partial' | 'low';
612
+ }
613
+ ): AsyncGenerator<StreamChunk, void, unknown> {
614
+ const context: StreamContext = {
615
+ ...this.createContext<StreamContext>(),
616
+ toolExecutor: this.toolExecutor,
617
+ };
618
+
619
+ // Prepare request
620
+ const request: StreamRequest = {
621
+ messages: messages.map((msg) => this.serializeMessage(msg)),
622
+ initial_state: options?.initial_state,
623
+ config: options?.config,
624
+ recursion_limit: options?.recursion_limit || 25,
625
+ response_granularity: options?.response_granularity || 'low',
626
+ };
627
+
628
+ // Return async generator from the stream endpoint
629
+ return streamInvokeEndpoint(context, request);
630
+ }
631
+
632
+ /**
633
+ * Stream invoke via a persistent WebSocket connection.
634
+ *
635
+ * Identical API to ``stream()`` — same message types, same chunk format,
636
+ * same tool-execution loop — but uses a single WebSocket instead of one
637
+ * HTTP request per tool-call iteration. Switch from ``stream()`` to
638
+ * ``wsStream()`` by changing one method name; everything else stays the
639
+ * same.
640
+ *
641
+ * The WebSocket stays open for the full lifecycle of the call (fresh run +
642
+ * any resume runs triggered by remote tool calls). The server sends a
643
+ * ``{ event:"updates", data:{ status:"done" } }`` chunk after each run so
644
+ * the client knows when to send the next resume request.
645
+ *
646
+ * Auth: the bearer token is sent via the ``10xgraph-bearer`` WebSocket
647
+ * subprotocol (browser-safe; never placed in the URL), with the Authorization
648
+ * header also set on Node runtimes.
649
+ *
650
+ * @param messages - Array of messages to send
651
+ * @param options - Same options as ``stream()``
652
+ * @returns AsyncGenerator of StreamChunk objects
653
+ *
654
+ * @example
655
+ * ```ts
656
+ * const stream = client.wsStream([userMessage], {
657
+ * config: { thread_id: 'my-thread' },
658
+ * response_granularity: 'low',
659
+ * });
660
+ *
661
+ * for await (const chunk of stream) {
662
+ * if (chunk.event === 'message') {
663
+ * console.log('Message:', chunk.message?.content);
664
+ * }
665
+ * }
666
+ * ```
667
+ */
668
+ wsStream(
669
+ messages: Message[],
670
+ options?: {
671
+ initial_state?: Record<string, any>;
672
+ config?: Record<string, any>;
673
+ recursion_limit?: number;
674
+ response_granularity?: 'full' | 'partial' | 'low';
675
+ }
676
+ ): AsyncGenerator<StreamChunk, void, unknown> {
677
+ const context: WsStreamContext = {
678
+ ...this.createContext<WsStreamContext>(),
679
+ toolExecutor: this.toolExecutor,
680
+ };
681
+
682
+ const request: StreamRequest = {
683
+ messages: messages.map((msg) => this.serializeMessage(msg)),
684
+ initial_state: options?.initial_state,
685
+ config: options?.config,
686
+ recursion_limit: options?.recursion_limit ?? 25,
687
+ response_granularity: options?.response_granularity ?? 'low',
688
+ };
689
+
690
+ return wsStreamInvoke(context, request);
691
+ }
692
+
693
+ /**
694
+ * Open a realtime (audio-to-audio) session over ``/v1/graph/live``.
695
+ *
696
+ * Transport-only: send PCM16 input via ``session.sendAudio(...)`` and receive
697
+ * PCM16 output via ``session.on('audio', ...)``. Mic capture and audio playback
698
+ * are the caller's responsibility. The session auto-reconnects (with backoff)
699
+ * on an unexpected drop and resumes the same ``thread_id``.
700
+ *
701
+ * @example
702
+ * ```ts
703
+ * const session = client.realtime({ model: 'gemini-2.5-flash-live' });
704
+ * session.on('audio', (pcm) => speaker.write(pcm));
705
+ * session.on('output_transcript', (e) => console.log(e.text));
706
+ * await session.ready;
707
+ * session.sendAudio(micChunk);
708
+ * ```
709
+ */
710
+ realtime(init: RealtimeInit, options?: RealtimeOptions): RealtimeSession {
711
+ const context = this.createContext<RealtimeContext>();
712
+ return new RealtimeSession(context, init, options);
713
+ }
714
+
715
+ /**
716
+ * Store a memory in the agent's memory system
717
+ *
718
+ * @param request - Memory storage request parameters
719
+ * @returns Promise<StoreMemoryResponse> containing the memory_id
720
+ *
721
+ * @example
722
+ * ```ts
723
+ * const result = await client.storeMemory({
724
+ * content: "User prefers dark mode",
725
+ * memory_type: MemoryType.SEMANTIC,
726
+ * category: "preferences",
727
+ * metadata: { source: "user_settings" }
728
+ * });
729
+ * console.log('Memory stored with ID:', result.data.memory_id);
730
+ * ```
731
+ */
732
+ async storeMemory(request: StoreMemoryRequest): Promise<StoreMemoryResponse> {
733
+ const context = this.createContext<StoreMemoryContext>();
734
+
735
+ return storeMemoryEndpoint(context, request);
736
+ }
737
+
738
+ /**
739
+ * Search for memories in the agent's memory system
740
+ *
741
+ * @param request - Memory search request parameters
742
+ * @returns Promise<SearchMemoryResponse> containing matching memories
743
+ *
744
+ * @example
745
+ * ```ts
746
+ * const results = await client.searchMemory({
747
+ * query: "dark mode preferences",
748
+ * memory_type: MemoryType.SEMANTIC,
749
+ * limit: 5,
750
+ * retrieval_strategy: RetrievalStrategy.SIMILARITY
751
+ * });
752
+ * results.data.results.forEach(result => {
753
+ * console.log('Memory:', result.content, 'Score:', result.score);
754
+ * });
755
+ * ```
756
+ */
757
+ async searchMemory(request: SearchMemoryRequest): Promise<SearchMemoryResponse> {
758
+ const context = this.createContext<SearchMemoryContext>();
759
+
760
+ return searchMemoryEndpoint(context, request);
761
+ }
762
+
763
+ /**
764
+ * Get a specific memory by ID
765
+ *
766
+ * @param memoryId - The ID of the memory to retrieve
767
+ * @param options - Optional config and options
768
+ * @returns Promise<GetMemoryResponse> containing the memory details
769
+ *
770
+ * @example
771
+ * ```ts
772
+ * const memory = await client.getMemory('mem-12345', {
773
+ * config: { include_vector: true }
774
+ * });
775
+ * console.log('Memory:', memory.data.memory.content);
776
+ * console.log('Score:', memory.data.memory.score);
777
+ * ```
778
+ */
779
+ async getMemory(
780
+ memoryId: string,
781
+ options?: { config?: Record<string, any>; options?: Record<string, any> }
782
+ ): Promise<GetMemoryResponse> {
783
+ const context = this.createContext<GetMemoryContext>();
784
+
785
+ const request: GetMemoryRequest = {
786
+ memoryId,
787
+ config: options?.config,
788
+ options: options?.options,
789
+ };
790
+
791
+ return getMemoryEndpoint(context, request);
792
+ }
793
+
794
+ /**
795
+ * Update an existing memory by ID
796
+ *
797
+ * @param memoryId - The ID of the memory to update
798
+ * @param content - The updated content for the memory
799
+ * @param options - Optional config, options, and metadata
800
+ * @returns Promise<UpdateMemoryResponse> containing success status and updated data
801
+ *
802
+ * @example
803
+ * ```ts
804
+ * const result = await client.updateMemory('mem-12345', 'Updated content', {
805
+ * metadata: { tags: ['important', 'updated'] }
806
+ * });
807
+ * console.log('Update success:', result.data.success);
808
+ * ```
809
+ */
810
+ async updateMemory(
811
+ memoryId: string,
812
+ content: string,
813
+ options?: {
814
+ config?: Record<string, any>;
815
+ options?: Record<string, any>;
816
+ metadata?: Record<string, any>;
817
+ }
818
+ ): Promise<UpdateMemoryResponse> {
819
+ const context = this.createContext<UpdateMemoryContext>();
820
+
821
+ const request: UpdateMemoryRequest = {
822
+ memoryId,
823
+ content,
824
+ config: options?.config,
825
+ options: options?.options,
826
+ metadata: options?.metadata,
827
+ };
828
+
829
+ return updateMemoryEndpoint(context, request);
830
+ }
831
+
832
+ /**
833
+ * Delete a memory by ID
834
+ *
835
+ * @param memoryId - The ID of the memory to delete
836
+ * @param options - Optional config and options
837
+ * @returns Promise<DeleteMemoryResponse> containing success status and deletion confirmation
838
+ *
839
+ * @example
840
+ * ```ts
841
+ * const result = await client.deleteMemory('mem-12345', {
842
+ * config: { soft_delete: true }
843
+ * });
844
+ * console.log('Delete success:', result.data.success);
845
+ * console.log('Deleted:', result.data.data);
846
+ * ```
847
+ */
848
+ async deleteMemory(
849
+ memoryId: string,
850
+ options?: { config?: Record<string, any>; options?: Record<string, any> }
851
+ ): Promise<DeleteMemoryResponse> {
852
+ const context = this.createContext<DeleteMemoryContext>();
853
+
854
+ const request: DeleteMemoryRequest = {
855
+ memoryId,
856
+ config: options?.config,
857
+ options: options?.options,
858
+ };
859
+
860
+ return deleteMemoryEndpoint(context, request);
861
+ }
862
+
863
+ /**
864
+ * List all memories with optional pagination
865
+ *
866
+ * @param options - Optional config, options, and limit
867
+ * @returns Promise<ListMemoriesResponse> containing array of memories
868
+ *
869
+ * @example
870
+ * ```ts
871
+ * const result = await client.listMemories({
872
+ * limit: 50,
873
+ * config: { include_vectors: false }
874
+ * });
875
+ * console.log('Found memories:', result.data.memories.length);
876
+ * result.data.memories.forEach(memory => {
877
+ * console.log('Memory:', memory.content, 'Type:', memory.memory_type);
878
+ * });
879
+ * ```
880
+ */
881
+ async listMemories(options?: {
882
+ config?: Record<string, any>;
883
+ options?: Record<string, any>;
884
+ limit?: number;
885
+ }): Promise<ListMemoriesResponse> {
886
+ const context = this.createContext<ListMemoriesContext>();
887
+
888
+ const request: ListMemoriesRequest = {
889
+ config: options?.config,
890
+ options: options?.options,
891
+ limit: options?.limit,
892
+ };
893
+
894
+ return listMemoriesEndpoint(context, request);
895
+ }
896
+
897
+ /**
898
+ * Forget (delete) memories based on filters and criteria
899
+ *
900
+ * @param options - Optional config, options, memory type, category, and filters
901
+ * @returns Promise<ForgetMemoriesResponse> containing success status
902
+ *
903
+ * @example
904
+ * ```ts
905
+ * // Forget all episodic memories in a category
906
+ * const result = await client.forgetMemories({
907
+ * memory_type: MemoryType.EPISODIC,
908
+ * category: 'temporary',
909
+ * filters: { tag: 'delete-me' }
910
+ * });
911
+ * console.log('Forget success:', result.data.success);
912
+ * ```
913
+ */
914
+ async forgetMemories(options?: {
915
+ config?: Record<string, any>;
916
+ options?: Record<string, any>;
917
+ memory_type?: any;
918
+ category?: string;
919
+ filters?: Record<string, any>;
920
+ }): Promise<ForgetMemoriesResponse> {
921
+ const context = this.createContext<ForgetMemoriesContext>();
922
+
923
+ const request: ForgetMemoriesRequest = {
924
+ config: options?.config,
925
+ options: options?.options,
926
+ memory_type: options?.memory_type,
927
+ category: options?.category,
928
+ filters: options?.filters,
929
+ };
930
+
931
+ return forgetMemoriesEndpoint(context, request);
932
+ }
933
+
934
+ // ------------------------------------------------------------------
935
+ // Files / Multimodal API
936
+ // ------------------------------------------------------------------
937
+
938
+ /**
939
+ * Upload a file (image, audio, document) to the server.
940
+ * Returns file metadata including file_id for use in multimodal messages.
941
+ *
942
+ * @param file - A File, Blob, or { data: Blob; filename: string } object
943
+ * @returns FileUploadResponse with file_id and metadata
944
+ *
945
+ * @example
946
+ * ```ts
947
+ * const result = await client.uploadFile(file);
948
+ * const msg = Message.withImage('Describe this', result.data.url);
949
+ * ```
950
+ */
951
+ async uploadFile(
952
+ file: File | Blob | { data: Blob; filename: string }
953
+ ): Promise<FileUploadResponse> {
954
+ const context = this.createContext<FileUploadContext>();
955
+ return uploadFileEndpoint(context, file);
956
+ }
957
+
958
+ /**
959
+ * Download a file by its file_id. Returns raw Blob.
960
+ */
961
+ async getFile(fileId: string): Promise<Blob> {
962
+ const context = this.createContext<FileUploadContext>();
963
+ return getFileEndpoint(context, fileId);
964
+ }
965
+
966
+ /**
967
+ * Get metadata about a stored file.
968
+ */
969
+ async getFileInfo(fileId: string): Promise<FileInfoResponse> {
970
+ const context = this.createContext<FileUploadContext>();
971
+ return getFileInfoEndpoint(context, fileId);
972
+ }
973
+
974
+ /**
975
+ * Get the best access URL for a stored file.
976
+ * For cloud-backed media this will typically be a signed URL.
977
+ * For local or memory-backed media this may fall back to the API file route.
978
+ */
979
+ async getFileAccessUrl(fileId: string): Promise<FileAccessUrlResponse> {
980
+ const context = this.createContext<FileUploadContext>();
981
+ return getFileAccessUrlEndpoint(context, fileId);
982
+ }
983
+
984
+ /**
985
+ * Get the current multimodal configuration from the server.
986
+ */
987
+ async getMultimodalConfig(): Promise<MultimodalConfigResponse> {
988
+ const context = this.createContext<FileUploadContext>();
989
+ return getMultimodalConfigEndpoint(context);
990
+ }
991
+
992
+ /**
993
+ * Serialize a Message object for API transmission
994
+ * Converts Message class instances to plain objects
995
+ */
996
+ private serializeMessage(message: Message): any {
997
+ const serialized: any = {
998
+ role: message.role,
999
+ content: this.cleanContent(message.content),
1000
+ };
1001
+
1002
+ // message_id: use "0" if not set (server will generate one)
1003
+ if (message.message_id !== null && message.message_id !== undefined) {
1004
+ serialized.message_id = String(message.message_id);
1005
+ } else {
1006
+ serialized.message_id = '0';
1007
+ }
1008
+
1009
+ // Only include optional fields if they are explicitly set
1010
+ if (message.tools_calls) {
1011
+ serialized.tools_calls = message.tools_calls;
1012
+ }
1013
+ if (message.metadata && Object.keys(message.metadata).length > 0) {
1014
+ serialized.metadata = message.metadata;
1015
+ }
1016
+
1017
+ return serialized;
1018
+ }
1019
+
1020
+ /**
1021
+ * Clean content blocks by removing empty arrays and undefined values
1022
+ * Server requires array of content blocks, not simplified string
1023
+ */
1024
+ private cleanContent(content: any[]): any[] {
1025
+ // Always return as array of blocks (server requires this format)
1026
+ return content.map((block) => {
1027
+ const cleaned: any = {};
1028
+
1029
+ for (const [key, value] of Object.entries(block)) {
1030
+ // Skip empty arrays
1031
+ if (Array.isArray(value) && value.length === 0) {
1032
+ continue;
1033
+ }
1034
+ // Skip undefined values
1035
+ if (value === undefined) {
1036
+ continue;
1037
+ }
1038
+ cleaned[key] = value;
1039
+ }
1040
+
1041
+ return cleaned;
1042
+ });
1043
+ }
1044
+ }