@antipopp/agno-client 0.8.0 → 0.10.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.
- package/README.md +101 -0
- package/dist/index.d.mts +42 -15
- package/dist/index.d.ts +42 -15
- package/dist/index.js +474 -293
- package/dist/index.mjs +476 -293
- package/package.json +8 -4
package/dist/index.mjs
CHANGED
|
@@ -1,85 +1,9 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { RunEvent as RunEvent2 } from "@antipopp/agno-types";
|
|
3
|
+
|
|
1
4
|
// src/client.ts
|
|
2
|
-
import EventEmitter from "eventemitter3";
|
|
3
5
|
import { RunEvent } from "@antipopp/agno-types";
|
|
4
|
-
|
|
5
|
-
// src/stores/message-store.ts
|
|
6
|
-
var MessageStore = class {
|
|
7
|
-
constructor() {
|
|
8
|
-
this.messages = [];
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Get all messages
|
|
12
|
-
*/
|
|
13
|
-
getMessages() {
|
|
14
|
-
return [...this.messages];
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Set messages (replaces all)
|
|
18
|
-
*/
|
|
19
|
-
setMessages(messages) {
|
|
20
|
-
this.messages = [...messages];
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Add a message
|
|
24
|
-
*/
|
|
25
|
-
addMessage(message) {
|
|
26
|
-
this.messages = [...this.messages, message];
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Update the last message
|
|
30
|
-
*/
|
|
31
|
-
updateLastMessage(updater) {
|
|
32
|
-
if (this.messages.length === 0)
|
|
33
|
-
return void 0;
|
|
34
|
-
const lastMessage = this.messages[this.messages.length - 1];
|
|
35
|
-
const updatedMessage = updater(lastMessage);
|
|
36
|
-
this.messages = [
|
|
37
|
-
...this.messages.slice(0, -1),
|
|
38
|
-
updatedMessage
|
|
39
|
-
];
|
|
40
|
-
return updatedMessage;
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Update a specific message by index
|
|
44
|
-
*/
|
|
45
|
-
updateMessage(index, updater) {
|
|
46
|
-
if (index < 0 || index >= this.messages.length)
|
|
47
|
-
return void 0;
|
|
48
|
-
const message = this.messages[index];
|
|
49
|
-
const updatedMessage = updater(message);
|
|
50
|
-
this.messages = [
|
|
51
|
-
...this.messages.slice(0, index),
|
|
52
|
-
updatedMessage,
|
|
53
|
-
...this.messages.slice(index + 1)
|
|
54
|
-
];
|
|
55
|
-
return updatedMessage;
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Remove last N messages
|
|
59
|
-
*/
|
|
60
|
-
removeLastMessages(count) {
|
|
61
|
-
this.messages = this.messages.slice(0, -count);
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Clear all messages
|
|
65
|
-
*/
|
|
66
|
-
clear() {
|
|
67
|
-
this.messages = [];
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Get the last message
|
|
71
|
-
*/
|
|
72
|
-
getLastMessage() {
|
|
73
|
-
return this.messages.length > 0 ? this.messages[this.messages.length - 1] : void 0;
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Check if last message has streaming error
|
|
77
|
-
*/
|
|
78
|
-
hasLastMessageError() {
|
|
79
|
-
const lastMessage = this.getLastMessage();
|
|
80
|
-
return lastMessage?.streamingError === true;
|
|
81
|
-
}
|
|
82
|
-
};
|
|
6
|
+
import EventEmitter from "eventemitter3";
|
|
83
7
|
|
|
84
8
|
// src/managers/config-manager.ts
|
|
85
9
|
var ConfigManager = class {
|
|
@@ -212,6 +136,18 @@ var ConfigManager = class {
|
|
|
212
136
|
setHeaders(headers) {
|
|
213
137
|
this.updateField("headers", headers);
|
|
214
138
|
}
|
|
139
|
+
/**
|
|
140
|
+
* Get global query parameters
|
|
141
|
+
*/
|
|
142
|
+
getParams() {
|
|
143
|
+
return this.config.params;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Set global query parameters
|
|
147
|
+
*/
|
|
148
|
+
setParams(params) {
|
|
149
|
+
this.updateField("params", params);
|
|
150
|
+
}
|
|
215
151
|
/**
|
|
216
152
|
* Get current entity ID (agent or team based on mode)
|
|
217
153
|
*/
|
|
@@ -225,14 +161,14 @@ var ConfigManager = class {
|
|
|
225
161
|
const mode = this.getMode();
|
|
226
162
|
const endpoint = this.getEndpoint();
|
|
227
163
|
const entityId = this.getCurrentEntityId();
|
|
228
|
-
if (!entityId)
|
|
164
|
+
if (!entityId) {
|
|
229
165
|
return null;
|
|
166
|
+
}
|
|
230
167
|
const encodedEntityId = encodeURIComponent(entityId);
|
|
231
168
|
if (mode === "team") {
|
|
232
169
|
return `${endpoint}/teams/${encodedEntityId}/runs`;
|
|
233
|
-
} else {
|
|
234
|
-
return `${endpoint}/agents/${encodedEntityId}/runs`;
|
|
235
170
|
}
|
|
171
|
+
return `${endpoint}/agents/${encodedEntityId}/runs`;
|
|
236
172
|
}
|
|
237
173
|
/**
|
|
238
174
|
* Build request headers by merging global headers, per-request headers, and auth token.
|
|
@@ -255,10 +191,30 @@ var ConfigManager = class {
|
|
|
255
191
|
}
|
|
256
192
|
const authToken = this.getAuthToken();
|
|
257
193
|
if (authToken) {
|
|
258
|
-
headers
|
|
194
|
+
headers.Authorization = `Bearer ${authToken}`;
|
|
259
195
|
}
|
|
260
196
|
return headers;
|
|
261
197
|
}
|
|
198
|
+
/**
|
|
199
|
+
* Build query string by merging global params and per-request params.
|
|
200
|
+
* Merge order (lowest to highest precedence):
|
|
201
|
+
* 1. Global params from config
|
|
202
|
+
* 2. Per-request params (overrides global)
|
|
203
|
+
*
|
|
204
|
+
* @param perRequestParams - Optional query parameters for this specific request
|
|
205
|
+
* @returns URLSearchParams object ready to append to URLs
|
|
206
|
+
*/
|
|
207
|
+
buildQueryString(perRequestParams) {
|
|
208
|
+
const params = {};
|
|
209
|
+
const globalParams = this.getParams();
|
|
210
|
+
if (globalParams) {
|
|
211
|
+
Object.assign(params, globalParams);
|
|
212
|
+
}
|
|
213
|
+
if (perRequestParams) {
|
|
214
|
+
Object.assign(params, perRequestParams);
|
|
215
|
+
}
|
|
216
|
+
return new URLSearchParams(params);
|
|
217
|
+
}
|
|
262
218
|
};
|
|
263
219
|
|
|
264
220
|
// src/managers/session-manager.ts
|
|
@@ -266,11 +222,16 @@ var SessionManager = class {
|
|
|
266
222
|
/**
|
|
267
223
|
* Fetch all sessions for an entity
|
|
268
224
|
*/
|
|
269
|
-
async fetchSessions(endpoint, entityType, entityId, dbId, headers) {
|
|
225
|
+
async fetchSessions(endpoint, entityType, entityId, dbId, headers, params) {
|
|
270
226
|
const url = new URL(`${endpoint}/sessions`);
|
|
271
227
|
url.searchParams.set("type", entityType);
|
|
272
228
|
url.searchParams.set("component_id", entityId);
|
|
273
229
|
url.searchParams.set("db_id", dbId);
|
|
230
|
+
if (params) {
|
|
231
|
+
params.forEach((value, key) => {
|
|
232
|
+
url.searchParams.set(key, value);
|
|
233
|
+
});
|
|
234
|
+
}
|
|
274
235
|
const response = await fetch(url.toString(), { headers });
|
|
275
236
|
if (!response.ok) {
|
|
276
237
|
if (response.status === 404) {
|
|
@@ -285,7 +246,7 @@ var SessionManager = class {
|
|
|
285
246
|
* Fetch a specific session's runs
|
|
286
247
|
* Returns an array of RunSchema directly (not wrapped in { data, meta })
|
|
287
248
|
*/
|
|
288
|
-
async fetchSession(endpoint, entityType, sessionId, dbId, headers, userId) {
|
|
249
|
+
async fetchSession(endpoint, entityType, sessionId, dbId, headers, userId, params) {
|
|
289
250
|
const url = new URL(`${endpoint}/sessions/${sessionId}/runs`);
|
|
290
251
|
url.searchParams.set("type", entityType);
|
|
291
252
|
if (dbId) {
|
|
@@ -294,6 +255,11 @@ var SessionManager = class {
|
|
|
294
255
|
if (userId) {
|
|
295
256
|
url.searchParams.set("user_id", userId);
|
|
296
257
|
}
|
|
258
|
+
if (params) {
|
|
259
|
+
params.forEach((value, key) => {
|
|
260
|
+
url.searchParams.set(key, value);
|
|
261
|
+
});
|
|
262
|
+
}
|
|
297
263
|
const response = await fetch(url.toString(), { headers });
|
|
298
264
|
if (!response.ok) {
|
|
299
265
|
throw new Error(`Failed to fetch session: ${response.statusText}`);
|
|
@@ -303,11 +269,16 @@ var SessionManager = class {
|
|
|
303
269
|
/**
|
|
304
270
|
* Delete a session
|
|
305
271
|
*/
|
|
306
|
-
async deleteSession(endpoint, sessionId, dbId, headers) {
|
|
272
|
+
async deleteSession(endpoint, sessionId, dbId, headers, params) {
|
|
307
273
|
const url = new URL(`${endpoint}/sessions/${sessionId}`);
|
|
308
274
|
if (dbId) {
|
|
309
275
|
url.searchParams.set("db_id", dbId);
|
|
310
276
|
}
|
|
277
|
+
if (params) {
|
|
278
|
+
params.forEach((value, key) => {
|
|
279
|
+
url.searchParams.set(key, value);
|
|
280
|
+
});
|
|
281
|
+
}
|
|
311
282
|
const response = await fetch(url.toString(), {
|
|
312
283
|
method: "DELETE",
|
|
313
284
|
headers
|
|
@@ -366,7 +337,9 @@ var SessionManager = class {
|
|
|
366
337
|
tool_name: reasoningMsg.tool_name ?? "",
|
|
367
338
|
tool_args: reasoningMsg.tool_args ?? {},
|
|
368
339
|
tool_call_error: reasoningMsg.tool_call_error ?? false,
|
|
369
|
-
metrics: reasoningMsg.metrics ?? {
|
|
340
|
+
metrics: reasoningMsg.metrics ?? {
|
|
341
|
+
time: 0
|
|
342
|
+
},
|
|
370
343
|
created_at: reasoningMsg.created_at ?? timestamp
|
|
371
344
|
});
|
|
372
345
|
}
|
|
@@ -400,6 +373,164 @@ var SessionManager = class {
|
|
|
400
373
|
}
|
|
401
374
|
};
|
|
402
375
|
|
|
376
|
+
// src/parsers/stream-parser.ts
|
|
377
|
+
function isLegacyFormat(data) {
|
|
378
|
+
return typeof data === "object" && data !== null && "event" in data && !("data" in data) && typeof data.event === "string";
|
|
379
|
+
}
|
|
380
|
+
function convertNewFormatToLegacy(newFormatData) {
|
|
381
|
+
const { event, data } = newFormatData;
|
|
382
|
+
let parsedData;
|
|
383
|
+
if (typeof data === "string") {
|
|
384
|
+
try {
|
|
385
|
+
parsedData = JSON.parse(data);
|
|
386
|
+
} catch {
|
|
387
|
+
parsedData = {};
|
|
388
|
+
}
|
|
389
|
+
} else {
|
|
390
|
+
parsedData = data;
|
|
391
|
+
}
|
|
392
|
+
return {
|
|
393
|
+
event,
|
|
394
|
+
...parsedData
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
function processChunk(chunk, onChunk) {
|
|
398
|
+
onChunk(chunk);
|
|
399
|
+
}
|
|
400
|
+
function parseBuffer(buffer, onChunk) {
|
|
401
|
+
let currentIndex = 0;
|
|
402
|
+
let jsonStartIndex = buffer.indexOf("{", currentIndex);
|
|
403
|
+
while (jsonStartIndex !== -1 && jsonStartIndex < buffer.length) {
|
|
404
|
+
let braceCount = 0;
|
|
405
|
+
let inString = false;
|
|
406
|
+
let escapeNext = false;
|
|
407
|
+
let jsonEndIndex = -1;
|
|
408
|
+
let i = jsonStartIndex;
|
|
409
|
+
for (; i < buffer.length; i++) {
|
|
410
|
+
const char = buffer[i];
|
|
411
|
+
if (inString) {
|
|
412
|
+
if (escapeNext) {
|
|
413
|
+
escapeNext = false;
|
|
414
|
+
} else if (char === "\\") {
|
|
415
|
+
escapeNext = true;
|
|
416
|
+
} else if (char === '"') {
|
|
417
|
+
inString = false;
|
|
418
|
+
}
|
|
419
|
+
} else if (char === '"') {
|
|
420
|
+
inString = true;
|
|
421
|
+
} else if (char === "{") {
|
|
422
|
+
braceCount++;
|
|
423
|
+
} else if (char === "}") {
|
|
424
|
+
braceCount--;
|
|
425
|
+
if (braceCount === 0) {
|
|
426
|
+
jsonEndIndex = i;
|
|
427
|
+
break;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
if (jsonEndIndex !== -1) {
|
|
432
|
+
const jsonString = buffer.slice(jsonStartIndex, jsonEndIndex + 1);
|
|
433
|
+
try {
|
|
434
|
+
const parsed = JSON.parse(jsonString);
|
|
435
|
+
if (isLegacyFormat(parsed)) {
|
|
436
|
+
processChunk(parsed, onChunk);
|
|
437
|
+
} else {
|
|
438
|
+
const legacyChunk = convertNewFormatToLegacy(parsed);
|
|
439
|
+
processChunk(legacyChunk, onChunk);
|
|
440
|
+
}
|
|
441
|
+
} catch (error) {
|
|
442
|
+
if (typeof process !== "undefined" && process.env?.NODE_ENV === "development") {
|
|
443
|
+
console.error("Failed to parse JSON chunk:", {
|
|
444
|
+
error,
|
|
445
|
+
chunk: jsonString.substring(0, 100) + (jsonString.length > 100 ? "..." : ""),
|
|
446
|
+
position: jsonStartIndex
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
if (jsonString.length > 1e4) {
|
|
450
|
+
throw new Error(
|
|
451
|
+
`Failed to parse large JSON chunk at position ${jsonStartIndex}`
|
|
452
|
+
);
|
|
453
|
+
}
|
|
454
|
+
jsonStartIndex = buffer.indexOf("{", jsonStartIndex + 1);
|
|
455
|
+
continue;
|
|
456
|
+
}
|
|
457
|
+
currentIndex = jsonEndIndex + 1;
|
|
458
|
+
buffer = buffer.slice(currentIndex).trim();
|
|
459
|
+
currentIndex = 0;
|
|
460
|
+
jsonStartIndex = buffer.indexOf("{", currentIndex);
|
|
461
|
+
} else {
|
|
462
|
+
break;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
return buffer;
|
|
466
|
+
}
|
|
467
|
+
async function streamResponse(options) {
|
|
468
|
+
const {
|
|
469
|
+
apiUrl,
|
|
470
|
+
headers = {},
|
|
471
|
+
params,
|
|
472
|
+
requestBody,
|
|
473
|
+
onChunk,
|
|
474
|
+
onError,
|
|
475
|
+
onComplete,
|
|
476
|
+
signal
|
|
477
|
+
} = options;
|
|
478
|
+
let buffer = "";
|
|
479
|
+
const finalUrl = params?.toString() ? `${apiUrl}?${params.toString()}` : apiUrl;
|
|
480
|
+
try {
|
|
481
|
+
const response = await fetch(finalUrl, {
|
|
482
|
+
method: "POST",
|
|
483
|
+
headers: {
|
|
484
|
+
...!(requestBody instanceof FormData) && {
|
|
485
|
+
"Content-Type": "application/json"
|
|
486
|
+
},
|
|
487
|
+
...headers
|
|
488
|
+
},
|
|
489
|
+
body: requestBody instanceof FormData ? requestBody : JSON.stringify(requestBody),
|
|
490
|
+
signal
|
|
491
|
+
});
|
|
492
|
+
if (!response.ok) {
|
|
493
|
+
let errorMessage = `HTTP ${response.status}: ${response.statusText}`;
|
|
494
|
+
const contentType = response.headers.get("content-type");
|
|
495
|
+
if (contentType?.includes("application/json")) {
|
|
496
|
+
try {
|
|
497
|
+
const errorData = await response.json();
|
|
498
|
+
errorMessage = errorData.detail || errorData.message || errorMessage;
|
|
499
|
+
} catch {
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
throw new Error(errorMessage);
|
|
503
|
+
}
|
|
504
|
+
if (!response.body) {
|
|
505
|
+
throw new Error("No response body");
|
|
506
|
+
}
|
|
507
|
+
const reader = response.body.getReader();
|
|
508
|
+
const decoder = new TextDecoder();
|
|
509
|
+
const processStream = async () => {
|
|
510
|
+
while (true) {
|
|
511
|
+
const { done, value } = await reader.read();
|
|
512
|
+
if (done) {
|
|
513
|
+
buffer = parseBuffer(buffer, onChunk);
|
|
514
|
+
onComplete();
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
buffer += decoder.decode(value, { stream: true });
|
|
518
|
+
buffer = parseBuffer(buffer, onChunk);
|
|
519
|
+
}
|
|
520
|
+
};
|
|
521
|
+
await processStream();
|
|
522
|
+
} catch (error) {
|
|
523
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
if (typeof error === "object" && error !== null && "detail" in error) {
|
|
527
|
+
onError(new Error(String(error.detail)));
|
|
528
|
+
} else {
|
|
529
|
+
onError(new Error(String(error)));
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
|
|
403
534
|
// src/processors/event-processor.ts
|
|
404
535
|
import { RunEvent as RunEventEnum } from "@antipopp/agno-types";
|
|
405
536
|
|
|
@@ -428,9 +559,8 @@ function processToolCall(toolCall, prevToolCalls = []) {
|
|
|
428
559
|
...toolCall
|
|
429
560
|
};
|
|
430
561
|
return updatedToolCalls;
|
|
431
|
-
} else {
|
|
432
|
-
return [...prevToolCalls, toolCall];
|
|
433
562
|
}
|
|
563
|
+
return [...prevToolCalls, toolCall];
|
|
434
564
|
}
|
|
435
565
|
function processChunkToolCalls(chunk, existingToolCalls = []) {
|
|
436
566
|
let updatedToolCalls = [...existingToolCalls];
|
|
@@ -518,7 +648,7 @@ var EventProcessor = class {
|
|
|
518
648
|
}
|
|
519
649
|
break;
|
|
520
650
|
case RunEventEnum.ReasoningStep:
|
|
521
|
-
case RunEventEnum.TeamReasoningStep:
|
|
651
|
+
case RunEventEnum.TeamReasoningStep: {
|
|
522
652
|
const existingSteps = lastMessage.extra_data?.reasoning_steps ?? [];
|
|
523
653
|
const incomingSteps = chunk.extra_data?.reasoning_steps ?? [];
|
|
524
654
|
updatedMessage.extra_data = {
|
|
@@ -526,6 +656,7 @@ var EventProcessor = class {
|
|
|
526
656
|
reasoning_steps: [...existingSteps, ...incomingSteps]
|
|
527
657
|
};
|
|
528
658
|
break;
|
|
659
|
+
}
|
|
529
660
|
case RunEventEnum.ReasoningCompleted:
|
|
530
661
|
case RunEventEnum.TeamReasoningCompleted:
|
|
531
662
|
if (chunk.extra_data?.reasoning_steps) {
|
|
@@ -536,7 +667,7 @@ var EventProcessor = class {
|
|
|
536
667
|
}
|
|
537
668
|
break;
|
|
538
669
|
case RunEventEnum.RunCompleted:
|
|
539
|
-
case RunEventEnum.TeamRunCompleted:
|
|
670
|
+
case RunEventEnum.TeamRunCompleted: {
|
|
540
671
|
let updatedContent;
|
|
541
672
|
if (typeof chunk.content === "string") {
|
|
542
673
|
updatedContent = chunk.content;
|
|
@@ -561,6 +692,7 @@ var EventProcessor = class {
|
|
|
561
692
|
references: chunk.extra_data?.references ?? lastMessage.extra_data?.references
|
|
562
693
|
};
|
|
563
694
|
break;
|
|
695
|
+
}
|
|
564
696
|
case RunEventEnum.UpdatingMemory:
|
|
565
697
|
case RunEventEnum.TeamMemoryUpdateStarted:
|
|
566
698
|
case RunEventEnum.TeamMemoryUpdateCompleted:
|
|
@@ -583,164 +715,95 @@ var EventProcessor = class {
|
|
|
583
715
|
}
|
|
584
716
|
};
|
|
585
717
|
|
|
586
|
-
// src/
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
function convertNewFormatToLegacy(newFormatData) {
|
|
591
|
-
const { event, data } = newFormatData;
|
|
592
|
-
let parsedData;
|
|
593
|
-
if (typeof data === "string") {
|
|
594
|
-
try {
|
|
595
|
-
parsedData = JSON.parse(data);
|
|
596
|
-
} catch {
|
|
597
|
-
parsedData = {};
|
|
598
|
-
}
|
|
599
|
-
} else {
|
|
600
|
-
parsedData = data;
|
|
718
|
+
// src/stores/message-store.ts
|
|
719
|
+
var MessageStore = class {
|
|
720
|
+
constructor() {
|
|
721
|
+
this.messages = [];
|
|
601
722
|
}
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
function processChunk(chunk, onChunk) {
|
|
608
|
-
onChunk(chunk);
|
|
609
|
-
}
|
|
610
|
-
function parseBuffer(buffer, onChunk) {
|
|
611
|
-
let currentIndex = 0;
|
|
612
|
-
let jsonStartIndex = buffer.indexOf("{", currentIndex);
|
|
613
|
-
while (jsonStartIndex !== -1 && jsonStartIndex < buffer.length) {
|
|
614
|
-
let braceCount = 0;
|
|
615
|
-
let inString = false;
|
|
616
|
-
let escapeNext = false;
|
|
617
|
-
let jsonEndIndex = -1;
|
|
618
|
-
let i = jsonStartIndex;
|
|
619
|
-
for (; i < buffer.length; i++) {
|
|
620
|
-
const char = buffer[i];
|
|
621
|
-
if (inString) {
|
|
622
|
-
if (escapeNext) {
|
|
623
|
-
escapeNext = false;
|
|
624
|
-
} else if (char === "\\") {
|
|
625
|
-
escapeNext = true;
|
|
626
|
-
} else if (char === '"') {
|
|
627
|
-
inString = false;
|
|
628
|
-
}
|
|
629
|
-
} else {
|
|
630
|
-
if (char === '"') {
|
|
631
|
-
inString = true;
|
|
632
|
-
} else if (char === "{") {
|
|
633
|
-
braceCount++;
|
|
634
|
-
} else if (char === "}") {
|
|
635
|
-
braceCount--;
|
|
636
|
-
if (braceCount === 0) {
|
|
637
|
-
jsonEndIndex = i;
|
|
638
|
-
break;
|
|
639
|
-
}
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
if (jsonEndIndex !== -1) {
|
|
644
|
-
const jsonString = buffer.slice(jsonStartIndex, jsonEndIndex + 1);
|
|
645
|
-
try {
|
|
646
|
-
const parsed = JSON.parse(jsonString);
|
|
647
|
-
if (isLegacyFormat(parsed)) {
|
|
648
|
-
processChunk(parsed, onChunk);
|
|
649
|
-
} else {
|
|
650
|
-
const legacyChunk = convertNewFormatToLegacy(parsed);
|
|
651
|
-
processChunk(legacyChunk, onChunk);
|
|
652
|
-
}
|
|
653
|
-
} catch (error) {
|
|
654
|
-
if (typeof process !== "undefined" && process.env?.NODE_ENV === "development") {
|
|
655
|
-
console.error("Failed to parse JSON chunk:", {
|
|
656
|
-
error,
|
|
657
|
-
chunk: jsonString.substring(0, 100) + (jsonString.length > 100 ? "..." : ""),
|
|
658
|
-
position: jsonStartIndex
|
|
659
|
-
});
|
|
660
|
-
}
|
|
661
|
-
if (jsonString.length > 1e4) {
|
|
662
|
-
throw new Error(`Failed to parse large JSON chunk at position ${jsonStartIndex}`);
|
|
663
|
-
}
|
|
664
|
-
jsonStartIndex = buffer.indexOf("{", jsonStartIndex + 1);
|
|
665
|
-
continue;
|
|
666
|
-
}
|
|
667
|
-
currentIndex = jsonEndIndex + 1;
|
|
668
|
-
buffer = buffer.slice(currentIndex).trim();
|
|
669
|
-
currentIndex = 0;
|
|
670
|
-
jsonStartIndex = buffer.indexOf("{", currentIndex);
|
|
671
|
-
} else {
|
|
672
|
-
break;
|
|
673
|
-
}
|
|
723
|
+
/**
|
|
724
|
+
* Get all messages
|
|
725
|
+
*/
|
|
726
|
+
getMessages() {
|
|
727
|
+
return [...this.messages];
|
|
674
728
|
}
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
}
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
"Content-Type": "application/json"
|
|
694
|
-
},
|
|
695
|
-
...headers
|
|
696
|
-
},
|
|
697
|
-
body: requestBody instanceof FormData ? requestBody : JSON.stringify(requestBody),
|
|
698
|
-
signal
|
|
699
|
-
});
|
|
700
|
-
if (!response.ok) {
|
|
701
|
-
let errorMessage = `HTTP ${response.status}: ${response.statusText}`;
|
|
702
|
-
const contentType = response.headers.get("content-type");
|
|
703
|
-
if (contentType?.includes("application/json")) {
|
|
704
|
-
try {
|
|
705
|
-
const errorData = await response.json();
|
|
706
|
-
errorMessage = errorData.detail || errorData.message || errorMessage;
|
|
707
|
-
} catch {
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
throw new Error(errorMessage);
|
|
711
|
-
}
|
|
712
|
-
if (!response.body) {
|
|
713
|
-
throw new Error("No response body");
|
|
729
|
+
/**
|
|
730
|
+
* Set messages (replaces all)
|
|
731
|
+
*/
|
|
732
|
+
setMessages(messages) {
|
|
733
|
+
this.messages = [...messages];
|
|
734
|
+
}
|
|
735
|
+
/**
|
|
736
|
+
* Add a message
|
|
737
|
+
*/
|
|
738
|
+
addMessage(message) {
|
|
739
|
+
this.messages = [...this.messages, message];
|
|
740
|
+
}
|
|
741
|
+
/**
|
|
742
|
+
* Update the last message
|
|
743
|
+
*/
|
|
744
|
+
updateLastMessage(updater) {
|
|
745
|
+
if (this.messages.length === 0) {
|
|
746
|
+
return void 0;
|
|
714
747
|
}
|
|
715
|
-
const
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
while (true) {
|
|
719
|
-
const { done, value } = await reader.read();
|
|
720
|
-
if (done) {
|
|
721
|
-
buffer = parseBuffer(buffer, onChunk);
|
|
722
|
-
onComplete();
|
|
723
|
-
return;
|
|
724
|
-
}
|
|
725
|
-
buffer += decoder.decode(value, { stream: true });
|
|
726
|
-
buffer = parseBuffer(buffer, onChunk);
|
|
727
|
-
}
|
|
728
|
-
};
|
|
729
|
-
await processStream();
|
|
730
|
-
} catch (error) {
|
|
731
|
-
if (error instanceof Error && error.name === "AbortError") {
|
|
732
|
-
return;
|
|
748
|
+
const lastMessage = this.messages.at(-1);
|
|
749
|
+
if (!lastMessage) {
|
|
750
|
+
return void 0;
|
|
733
751
|
}
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
752
|
+
const updatedMessage = updater(lastMessage);
|
|
753
|
+
this.messages = [...this.messages.slice(0, -1), updatedMessage];
|
|
754
|
+
return updatedMessage;
|
|
755
|
+
}
|
|
756
|
+
/**
|
|
757
|
+
* Update a specific message by index
|
|
758
|
+
*/
|
|
759
|
+
updateMessage(index, updater) {
|
|
760
|
+
if (index < 0 || index >= this.messages.length) {
|
|
761
|
+
return void 0;
|
|
738
762
|
}
|
|
763
|
+
const message = this.messages[index];
|
|
764
|
+
const updatedMessage = updater(message);
|
|
765
|
+
this.messages = [
|
|
766
|
+
...this.messages.slice(0, index),
|
|
767
|
+
updatedMessage,
|
|
768
|
+
...this.messages.slice(index + 1)
|
|
769
|
+
];
|
|
770
|
+
return updatedMessage;
|
|
739
771
|
}
|
|
740
|
-
|
|
772
|
+
/**
|
|
773
|
+
* Remove last N messages
|
|
774
|
+
*/
|
|
775
|
+
removeLastMessages(count) {
|
|
776
|
+
this.messages = this.messages.slice(0, -count);
|
|
777
|
+
}
|
|
778
|
+
/**
|
|
779
|
+
* Clear all messages
|
|
780
|
+
*/
|
|
781
|
+
clear() {
|
|
782
|
+
this.messages = [];
|
|
783
|
+
}
|
|
784
|
+
/**
|
|
785
|
+
* Get the last message
|
|
786
|
+
*/
|
|
787
|
+
getLastMessage() {
|
|
788
|
+
return this.messages.length > 0 ? this.messages.at(-1) : void 0;
|
|
789
|
+
}
|
|
790
|
+
/**
|
|
791
|
+
* Check if last message has streaming error
|
|
792
|
+
*/
|
|
793
|
+
hasLastMessageError() {
|
|
794
|
+
const lastMessage = this.getLastMessage();
|
|
795
|
+
return lastMessage?.streamingError === true;
|
|
796
|
+
}
|
|
797
|
+
};
|
|
741
798
|
|
|
742
799
|
// src/utils/logger.ts
|
|
743
|
-
var SENSITIVE_KEYS = [
|
|
800
|
+
var SENSITIVE_KEYS = [
|
|
801
|
+
"authToken",
|
|
802
|
+
"Authorization",
|
|
803
|
+
"token",
|
|
804
|
+
"password",
|
|
805
|
+
"apiKey"
|
|
806
|
+
];
|
|
744
807
|
function sanitizeObject(obj) {
|
|
745
808
|
if (obj === null || obj === void 0) {
|
|
746
809
|
return obj;
|
|
@@ -828,6 +891,7 @@ var AgnoClient = class extends EventEmitter {
|
|
|
828
891
|
this.state = {
|
|
829
892
|
isStreaming: false,
|
|
830
893
|
isRefreshing: false,
|
|
894
|
+
isCancelling: false,
|
|
831
895
|
isEndpointActive: false,
|
|
832
896
|
agents: [],
|
|
833
897
|
teams: [],
|
|
@@ -872,6 +936,49 @@ var AgnoClient = class extends EventEmitter {
|
|
|
872
936
|
this.emit("message:update", this.messageStore.getMessages());
|
|
873
937
|
this.emit("state:change", this.getState());
|
|
874
938
|
}
|
|
939
|
+
/**
|
|
940
|
+
* Cancel an active or paused run
|
|
941
|
+
*/
|
|
942
|
+
async cancelRun() {
|
|
943
|
+
if (!(this.state.isStreaming || this.state.isPaused)) {
|
|
944
|
+
throw new Error("No active or paused run to cancel");
|
|
945
|
+
}
|
|
946
|
+
const runUrl = this.configManager.getRunUrl();
|
|
947
|
+
if (!runUrl) {
|
|
948
|
+
throw new Error("No agent or team selected");
|
|
949
|
+
}
|
|
950
|
+
const runId = this.state.pausedRunId || this.currentRunId;
|
|
951
|
+
if (!runId) {
|
|
952
|
+
throw new Error("No run ID available to cancel");
|
|
953
|
+
}
|
|
954
|
+
const cancelUrl = `${runUrl}/${runId}/cancel`;
|
|
955
|
+
const headers = this.configManager.buildRequestHeaders();
|
|
956
|
+
this.state.isCancelling = true;
|
|
957
|
+
this.emit("state:change", this.getState());
|
|
958
|
+
try {
|
|
959
|
+
const response = await fetch(cancelUrl, {
|
|
960
|
+
method: "POST",
|
|
961
|
+
headers
|
|
962
|
+
});
|
|
963
|
+
if (!response.ok) {
|
|
964
|
+
throw new Error("Failed to cancel run");
|
|
965
|
+
}
|
|
966
|
+
this.state.isStreaming = false;
|
|
967
|
+
this.state.isPaused = false;
|
|
968
|
+
this.state.isCancelling = false;
|
|
969
|
+
this.state.pausedRunId = void 0;
|
|
970
|
+
this.state.toolsAwaitingExecution = void 0;
|
|
971
|
+
this.currentRunId = void 0;
|
|
972
|
+
this.emit("run:cancelled", { runId });
|
|
973
|
+
this.emit("state:change", this.getState());
|
|
974
|
+
} catch (error) {
|
|
975
|
+
this.state.isCancelling = false;
|
|
976
|
+
this.emit("state:change", this.getState());
|
|
977
|
+
throw new Error(
|
|
978
|
+
`Error cancelling run: ${error instanceof Error ? error.message : String(error)}`
|
|
979
|
+
);
|
|
980
|
+
}
|
|
981
|
+
}
|
|
875
982
|
/**
|
|
876
983
|
* Send a message to the agent/team (streaming)
|
|
877
984
|
*/
|
|
@@ -922,17 +1029,21 @@ var AgnoClient = class extends EventEmitter {
|
|
|
922
1029
|
formData.append("user_id", userId);
|
|
923
1030
|
}
|
|
924
1031
|
const headers = this.configManager.buildRequestHeaders(options?.headers);
|
|
1032
|
+
const params = this.configManager.buildQueryString(options?.params);
|
|
925
1033
|
await streamResponse({
|
|
926
1034
|
apiUrl: runUrl,
|
|
927
1035
|
headers,
|
|
1036
|
+
params,
|
|
928
1037
|
requestBody: formData,
|
|
929
1038
|
onChunk: (chunk) => {
|
|
930
|
-
this.handleChunk(
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
1039
|
+
this.handleChunk(
|
|
1040
|
+
chunk,
|
|
1041
|
+
newSessionId,
|
|
1042
|
+
formData.get("message")
|
|
1043
|
+
);
|
|
1044
|
+
if ((chunk.event === RunEvent.RunStarted || chunk.event === RunEvent.TeamRunStarted || chunk.event === RunEvent.ReasoningStarted || chunk.event === RunEvent.TeamReasoningStarted) && chunk.session_id) {
|
|
1045
|
+
newSessionId = chunk.session_id;
|
|
1046
|
+
this.configManager.setSessionId(chunk.session_id);
|
|
936
1047
|
}
|
|
937
1048
|
},
|
|
938
1049
|
onError: (error) => {
|
|
@@ -940,6 +1051,7 @@ var AgnoClient = class extends EventEmitter {
|
|
|
940
1051
|
},
|
|
941
1052
|
onComplete: async () => {
|
|
942
1053
|
this.state.isStreaming = false;
|
|
1054
|
+
this.currentRunId = void 0;
|
|
943
1055
|
this.emit("stream:end");
|
|
944
1056
|
this.emit("message:complete", this.messageStore.getMessages());
|
|
945
1057
|
this.emit("state:change", this.getState());
|
|
@@ -961,20 +1073,21 @@ var AgnoClient = class extends EventEmitter {
|
|
|
961
1073
|
*/
|
|
962
1074
|
handleChunk(chunk, currentSessionId, messageContent) {
|
|
963
1075
|
const event = chunk.event;
|
|
964
|
-
if (event === RunEvent.RunStarted || event === RunEvent.TeamRunStarted
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
1076
|
+
if ((event === RunEvent.RunStarted || event === RunEvent.TeamRunStarted) && chunk.run_id) {
|
|
1077
|
+
this.currentRunId = chunk.run_id;
|
|
1078
|
+
}
|
|
1079
|
+
if ((event === RunEvent.RunStarted || event === RunEvent.TeamRunStarted || event === RunEvent.ReasoningStarted || event === RunEvent.TeamReasoningStarted) && chunk.session_id && (!currentSessionId || currentSessionId !== chunk.session_id)) {
|
|
1080
|
+
const sessionData = {
|
|
1081
|
+
session_id: chunk.session_id,
|
|
1082
|
+
session_name: messageContent,
|
|
1083
|
+
created_at: toSafeISOString(chunk.created_at)
|
|
1084
|
+
};
|
|
1085
|
+
const sessionExists = this.state.sessions.some(
|
|
1086
|
+
(s) => s.session_id === chunk.session_id
|
|
1087
|
+
);
|
|
1088
|
+
if (!sessionExists) {
|
|
1089
|
+
this.state.sessions = [sessionData, ...this.state.sessions];
|
|
1090
|
+
this.emit("session:created", sessionData);
|
|
978
1091
|
}
|
|
979
1092
|
}
|
|
980
1093
|
if (event === RunEvent.RunPaused) {
|
|
@@ -1054,7 +1167,10 @@ var AgnoClient = class extends EventEmitter {
|
|
|
1054
1167
|
if (message.tool_calls) {
|
|
1055
1168
|
for (const toolCall of message.tool_calls) {
|
|
1056
1169
|
if (toolCall.ui_component) {
|
|
1057
|
-
existingUIComponents.set(
|
|
1170
|
+
existingUIComponents.set(
|
|
1171
|
+
toolCall.tool_call_id,
|
|
1172
|
+
toolCall.ui_component
|
|
1173
|
+
);
|
|
1058
1174
|
}
|
|
1059
1175
|
}
|
|
1060
1176
|
}
|
|
@@ -1064,13 +1180,15 @@ var AgnoClient = class extends EventEmitter {
|
|
|
1064
1180
|
const dbId = this.configManager.getDbId() || "";
|
|
1065
1181
|
const userId = this.configManager.getUserId();
|
|
1066
1182
|
const headers = this.configManager.buildRequestHeaders();
|
|
1183
|
+
const params = this.configManager.buildQueryString();
|
|
1067
1184
|
const response = await this.sessionManager.fetchSession(
|
|
1068
1185
|
config.endpoint,
|
|
1069
1186
|
entityType,
|
|
1070
1187
|
sessionId,
|
|
1071
1188
|
dbId,
|
|
1072
1189
|
headers,
|
|
1073
|
-
userId
|
|
1190
|
+
userId,
|
|
1191
|
+
params
|
|
1074
1192
|
);
|
|
1075
1193
|
const messages = this.sessionManager.convertSessionToMessages(response);
|
|
1076
1194
|
if (existingUIComponents.size > 0) {
|
|
@@ -1078,7 +1196,9 @@ var AgnoClient = class extends EventEmitter {
|
|
|
1078
1196
|
if (message.tool_calls) {
|
|
1079
1197
|
for (let i = 0; i < message.tool_calls.length; i++) {
|
|
1080
1198
|
const toolCall = message.tool_calls[i];
|
|
1081
|
-
const uiComponent = existingUIComponents.get(
|
|
1199
|
+
const uiComponent = existingUIComponents.get(
|
|
1200
|
+
toolCall.tool_call_id
|
|
1201
|
+
);
|
|
1082
1202
|
if (uiComponent) {
|
|
1083
1203
|
message.tool_calls[i].ui_component = uiComponent;
|
|
1084
1204
|
}
|
|
@@ -1087,12 +1207,18 @@ var AgnoClient = class extends EventEmitter {
|
|
|
1087
1207
|
}
|
|
1088
1208
|
}
|
|
1089
1209
|
this.messageStore.setMessages(messages);
|
|
1090
|
-
Logger.debug(
|
|
1210
|
+
Logger.debug(
|
|
1211
|
+
"[AgnoClient] Session refreshed:",
|
|
1212
|
+
`${messages.length} messages`
|
|
1213
|
+
);
|
|
1091
1214
|
this.emit("message:refreshed", messages);
|
|
1092
1215
|
this.emit("message:update", messages);
|
|
1093
1216
|
} catch (error) {
|
|
1094
1217
|
Logger.error("[AgnoClient] Failed to refresh session:", error);
|
|
1095
|
-
this.emit(
|
|
1218
|
+
this.emit(
|
|
1219
|
+
"message:error",
|
|
1220
|
+
`Session refresh failed: ${error instanceof Error ? error.message : String(error)}`
|
|
1221
|
+
);
|
|
1096
1222
|
} finally {
|
|
1097
1223
|
this.state.isRefreshing = false;
|
|
1098
1224
|
this.emit("state:change", this.getState());
|
|
@@ -1101,24 +1227,33 @@ var AgnoClient = class extends EventEmitter {
|
|
|
1101
1227
|
/**
|
|
1102
1228
|
* Load a session
|
|
1103
1229
|
*/
|
|
1104
|
-
async loadSession(sessionId) {
|
|
1230
|
+
async loadSession(sessionId, options) {
|
|
1105
1231
|
Logger.debug("[AgnoClient] loadSession called with sessionId:", sessionId);
|
|
1106
1232
|
const config = this.configManager.getConfig();
|
|
1107
1233
|
const entityType = this.configManager.getMode();
|
|
1108
1234
|
const dbId = this.configManager.getDbId() || "";
|
|
1109
1235
|
const userId = this.configManager.getUserId();
|
|
1110
|
-
Logger.debug("[AgnoClient] Loading session with:", {
|
|
1236
|
+
Logger.debug("[AgnoClient] Loading session with:", {
|
|
1237
|
+
entityType,
|
|
1238
|
+
dbId,
|
|
1239
|
+
userId
|
|
1240
|
+
});
|
|
1111
1241
|
const headers = this.configManager.buildRequestHeaders();
|
|
1242
|
+
const params = this.configManager.buildQueryString(options?.params);
|
|
1112
1243
|
const response = await this.sessionManager.fetchSession(
|
|
1113
1244
|
config.endpoint,
|
|
1114
1245
|
entityType,
|
|
1115
1246
|
sessionId,
|
|
1116
1247
|
dbId,
|
|
1117
1248
|
headers,
|
|
1118
|
-
userId
|
|
1249
|
+
userId,
|
|
1250
|
+
params
|
|
1119
1251
|
);
|
|
1120
1252
|
const messages = this.sessionManager.convertSessionToMessages(response);
|
|
1121
|
-
Logger.debug(
|
|
1253
|
+
Logger.debug(
|
|
1254
|
+
"[AgnoClient] Setting messages to store:",
|
|
1255
|
+
`${messages.length} messages`
|
|
1256
|
+
);
|
|
1122
1257
|
this.messageStore.setMessages(messages);
|
|
1123
1258
|
this.configManager.setSessionId(sessionId);
|
|
1124
1259
|
Logger.debug("[AgnoClient] Emitting events...");
|
|
@@ -1131,7 +1266,7 @@ var AgnoClient = class extends EventEmitter {
|
|
|
1131
1266
|
/**
|
|
1132
1267
|
* Fetch all sessions
|
|
1133
1268
|
*/
|
|
1134
|
-
async fetchSessions() {
|
|
1269
|
+
async fetchSessions(options) {
|
|
1135
1270
|
const config = this.configManager.getConfig();
|
|
1136
1271
|
const entityType = this.configManager.getMode();
|
|
1137
1272
|
const entityId = this.configManager.getCurrentEntityId();
|
|
@@ -1140,12 +1275,14 @@ var AgnoClient = class extends EventEmitter {
|
|
|
1140
1275
|
throw new Error("Entity ID must be configured");
|
|
1141
1276
|
}
|
|
1142
1277
|
const headers = this.configManager.buildRequestHeaders();
|
|
1278
|
+
const params = this.configManager.buildQueryString(options?.params);
|
|
1143
1279
|
const sessions = await this.sessionManager.fetchSessions(
|
|
1144
1280
|
config.endpoint,
|
|
1145
1281
|
entityType,
|
|
1146
1282
|
entityId,
|
|
1147
1283
|
dbId,
|
|
1148
|
-
headers
|
|
1284
|
+
headers,
|
|
1285
|
+
params
|
|
1149
1286
|
);
|
|
1150
1287
|
this.state.sessions = sessions;
|
|
1151
1288
|
this.emit("state:change", this.getState());
|
|
@@ -1154,15 +1291,17 @@ var AgnoClient = class extends EventEmitter {
|
|
|
1154
1291
|
/**
|
|
1155
1292
|
* Delete a session
|
|
1156
1293
|
*/
|
|
1157
|
-
async deleteSession(sessionId) {
|
|
1294
|
+
async deleteSession(sessionId, options) {
|
|
1158
1295
|
const config = this.configManager.getConfig();
|
|
1159
1296
|
const dbId = this.configManager.getDbId() || "";
|
|
1160
1297
|
const headers = this.configManager.buildRequestHeaders();
|
|
1298
|
+
const params = this.configManager.buildQueryString(options?.params);
|
|
1161
1299
|
await this.sessionManager.deleteSession(
|
|
1162
1300
|
config.endpoint,
|
|
1163
1301
|
sessionId,
|
|
1164
1302
|
dbId,
|
|
1165
|
-
headers
|
|
1303
|
+
headers,
|
|
1304
|
+
params
|
|
1166
1305
|
);
|
|
1167
1306
|
this.state.sessions = this.state.sessions.filter(
|
|
1168
1307
|
(s) => s.session_id !== sessionId
|
|
@@ -1183,7 +1322,9 @@ var AgnoClient = class extends EventEmitter {
|
|
|
1183
1322
|
}
|
|
1184
1323
|
const existingToolCalls = lastMessage.tool_calls || [];
|
|
1185
1324
|
const existingIds = new Set(existingToolCalls.map((t) => t.tool_call_id));
|
|
1186
|
-
const newToolCalls = toolCalls.filter(
|
|
1325
|
+
const newToolCalls = toolCalls.filter(
|
|
1326
|
+
(t) => !existingIds.has(t.tool_call_id)
|
|
1327
|
+
);
|
|
1187
1328
|
if (newToolCalls.length > 0) {
|
|
1188
1329
|
this.messageStore.updateLastMessage((msg) => ({
|
|
1189
1330
|
...msg,
|
|
@@ -1230,8 +1371,9 @@ var AgnoClient = class extends EventEmitter {
|
|
|
1230
1371
|
* Batches all updates to emit only one message:update event
|
|
1231
1372
|
*/
|
|
1232
1373
|
applyPendingUISpecs() {
|
|
1233
|
-
if (this.pendingUISpecs.size === 0)
|
|
1374
|
+
if (this.pendingUISpecs.size === 0) {
|
|
1234
1375
|
return;
|
|
1376
|
+
}
|
|
1235
1377
|
const messages = this.messageStore.getMessages();
|
|
1236
1378
|
const updatedMessages = [];
|
|
1237
1379
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
@@ -1276,7 +1418,7 @@ var AgnoClient = class extends EventEmitter {
|
|
|
1276
1418
|
* Teams do not support the continue endpoint.
|
|
1277
1419
|
*
|
|
1278
1420
|
* @param tools - Array of tool calls with execution results
|
|
1279
|
-
* @param options - Optional request headers
|
|
1421
|
+
* @param options - Optional request headers and query parameters
|
|
1280
1422
|
* @throws Error if no paused run exists
|
|
1281
1423
|
* @throws Error if called with team mode (teams don't support HITL)
|
|
1282
1424
|
*/
|
|
@@ -1286,7 +1428,7 @@ var AgnoClient = class extends EventEmitter {
|
|
|
1286
1428
|
"HITL (Human-in-the-Loop) frontend tool execution is not supported for teams. Only agents support the continue endpoint."
|
|
1287
1429
|
);
|
|
1288
1430
|
}
|
|
1289
|
-
if (!this.state.isPaused
|
|
1431
|
+
if (!(this.state.isPaused && this.state.pausedRunId)) {
|
|
1290
1432
|
throw new Error("No paused run to continue");
|
|
1291
1433
|
}
|
|
1292
1434
|
const runUrl = this.configManager.getRunUrl();
|
|
@@ -1314,10 +1456,12 @@ var AgnoClient = class extends EventEmitter {
|
|
|
1314
1456
|
formData.append("user_id", userId);
|
|
1315
1457
|
}
|
|
1316
1458
|
const headers = this.configManager.buildRequestHeaders(options?.headers);
|
|
1459
|
+
const params = this.configManager.buildQueryString(options?.params);
|
|
1317
1460
|
try {
|
|
1318
1461
|
await streamResponse({
|
|
1319
1462
|
apiUrl: continueUrl,
|
|
1320
1463
|
headers,
|
|
1464
|
+
params,
|
|
1321
1465
|
requestBody: formData,
|
|
1322
1466
|
onChunk: (chunk) => {
|
|
1323
1467
|
this.handleChunk(chunk, currentSessionId, "");
|
|
@@ -1348,10 +1492,17 @@ var AgnoClient = class extends EventEmitter {
|
|
|
1348
1492
|
/**
|
|
1349
1493
|
* Check endpoint status
|
|
1350
1494
|
*/
|
|
1351
|
-
async checkStatus() {
|
|
1495
|
+
async checkStatus(options) {
|
|
1352
1496
|
try {
|
|
1353
1497
|
const headers = this.configManager.buildRequestHeaders();
|
|
1354
|
-
const
|
|
1498
|
+
const params = this.configManager.buildQueryString(options?.params);
|
|
1499
|
+
const url = new URL(`${this.configManager.getEndpoint()}/health`);
|
|
1500
|
+
if (params.toString()) {
|
|
1501
|
+
params.forEach((value, key) => {
|
|
1502
|
+
url.searchParams.set(key, value);
|
|
1503
|
+
});
|
|
1504
|
+
}
|
|
1505
|
+
const response = await fetch(url.toString(), { headers });
|
|
1355
1506
|
const isActive = response.ok;
|
|
1356
1507
|
this.state.isEndpointActive = isActive;
|
|
1357
1508
|
this.emit("state:change", this.getState());
|
|
@@ -1365,9 +1516,16 @@ var AgnoClient = class extends EventEmitter {
|
|
|
1365
1516
|
/**
|
|
1366
1517
|
* Fetch agents from endpoint
|
|
1367
1518
|
*/
|
|
1368
|
-
async fetchAgents() {
|
|
1519
|
+
async fetchAgents(options) {
|
|
1369
1520
|
const headers = this.configManager.buildRequestHeaders();
|
|
1370
|
-
const
|
|
1521
|
+
const params = this.configManager.buildQueryString(options?.params);
|
|
1522
|
+
const url = new URL(`${this.configManager.getEndpoint()}/agents`);
|
|
1523
|
+
if (params.toString()) {
|
|
1524
|
+
params.forEach((value, key) => {
|
|
1525
|
+
url.searchParams.set(key, value);
|
|
1526
|
+
});
|
|
1527
|
+
}
|
|
1528
|
+
const response = await fetch(url.toString(), { headers });
|
|
1371
1529
|
if (!response.ok) {
|
|
1372
1530
|
throw new Error("Failed to fetch agents");
|
|
1373
1531
|
}
|
|
@@ -1379,9 +1537,16 @@ var AgnoClient = class extends EventEmitter {
|
|
|
1379
1537
|
/**
|
|
1380
1538
|
* Fetch teams from endpoint
|
|
1381
1539
|
*/
|
|
1382
|
-
async fetchTeams() {
|
|
1540
|
+
async fetchTeams(options) {
|
|
1383
1541
|
const headers = this.configManager.buildRequestHeaders();
|
|
1384
|
-
const
|
|
1542
|
+
const params = this.configManager.buildQueryString(options?.params);
|
|
1543
|
+
const url = new URL(`${this.configManager.getEndpoint()}/teams`);
|
|
1544
|
+
if (params.toString()) {
|
|
1545
|
+
params.forEach((value, key) => {
|
|
1546
|
+
url.searchParams.set(key, value);
|
|
1547
|
+
});
|
|
1548
|
+
}
|
|
1549
|
+
const response = await fetch(url.toString(), { headers });
|
|
1385
1550
|
if (!response.ok) {
|
|
1386
1551
|
throw new Error("Failed to fetch teams");
|
|
1387
1552
|
}
|
|
@@ -1394,19 +1559,19 @@ var AgnoClient = class extends EventEmitter {
|
|
|
1394
1559
|
* Initialize client (check status and fetch agents/teams)
|
|
1395
1560
|
* Automatically selects the first available agent or team if none is configured
|
|
1396
1561
|
*/
|
|
1397
|
-
async initialize() {
|
|
1398
|
-
const isActive = await this.checkStatus();
|
|
1562
|
+
async initialize(options) {
|
|
1563
|
+
const isActive = await this.checkStatus(options);
|
|
1399
1564
|
if (!isActive) {
|
|
1400
1565
|
return { agents: [], teams: [] };
|
|
1401
1566
|
}
|
|
1402
1567
|
const [agents, teams] = await Promise.all([
|
|
1403
|
-
this.fetchAgents(),
|
|
1404
|
-
this.fetchTeams()
|
|
1568
|
+
this.fetchAgents(options),
|
|
1569
|
+
this.fetchTeams(options)
|
|
1405
1570
|
]);
|
|
1406
1571
|
const currentConfig = this.configManager.getConfig();
|
|
1407
1572
|
const hasAgentConfigured = currentConfig.agentId;
|
|
1408
1573
|
const hasTeamConfigured = currentConfig.teamId;
|
|
1409
|
-
if (!hasAgentConfigured
|
|
1574
|
+
if (!(hasAgentConfigured || hasTeamConfigured)) {
|
|
1410
1575
|
if (agents.length > 0) {
|
|
1411
1576
|
const firstAgent = agents[0];
|
|
1412
1577
|
this.configManager.updateConfig({
|
|
@@ -1427,10 +1592,28 @@ var AgnoClient = class extends EventEmitter {
|
|
|
1427
1592
|
}
|
|
1428
1593
|
return { agents, teams };
|
|
1429
1594
|
}
|
|
1595
|
+
/**
|
|
1596
|
+
* Dispose of the client and clean up all resources.
|
|
1597
|
+
* Call this method when the client is no longer needed to prevent memory leaks.
|
|
1598
|
+
* After calling dispose(), the client instance should not be reused.
|
|
1599
|
+
*/
|
|
1600
|
+
dispose() {
|
|
1601
|
+
this.removeAllListeners();
|
|
1602
|
+
this.messageStore.clear();
|
|
1603
|
+
this.pendingUISpecs.clear();
|
|
1604
|
+
this.eventProcessor.reset();
|
|
1605
|
+
this.state.isStreaming = false;
|
|
1606
|
+
this.state.isRefreshing = false;
|
|
1607
|
+
this.state.isEndpointActive = false;
|
|
1608
|
+
this.state.agents = [];
|
|
1609
|
+
this.state.teams = [];
|
|
1610
|
+
this.state.sessions = [];
|
|
1611
|
+
this.state.isPaused = false;
|
|
1612
|
+
this.state.pausedRunId = void 0;
|
|
1613
|
+
this.state.toolsAwaitingExecution = void 0;
|
|
1614
|
+
this.state.errorMessage = void 0;
|
|
1615
|
+
}
|
|
1430
1616
|
};
|
|
1431
|
-
|
|
1432
|
-
// src/index.ts
|
|
1433
|
-
import { RunEvent as RunEvent2 } from "@antipopp/agno-types";
|
|
1434
1617
|
export {
|
|
1435
1618
|
AgnoClient,
|
|
1436
1619
|
Logger,
|