@antipopp/agno-client 0.8.0 → 0.9.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 CHANGED
@@ -68,6 +68,8 @@ new AgnoClient(config: AgnoClientConfig)
68
68
  - `dbId` (string, optional) - Database ID
69
69
  - `sessionId` (string, optional) - Current session ID
70
70
  - `userId` (string, optional) - User ID to link sessions to a specific user
71
+ - `headers` (Record<string, string>, optional) - Global custom headers for all API requests
72
+ - `params` (Record<string, string>, optional) - Global query parameters for all API requests
71
73
 
72
74
  ### Methods
73
75
 
@@ -88,6 +90,17 @@ await client.sendMessage(formData);
88
90
  await client.sendMessage('Hello!', {
89
91
  headers: { 'X-Custom-Header': 'value' }
90
92
  });
93
+
94
+ // With query parameters
95
+ await client.sendMessage('Hello!', {
96
+ params: { temperature: '0.7', max_tokens: '500' }
97
+ });
98
+
99
+ // With both headers and params
100
+ await client.sendMessage('Hello!', {
101
+ headers: { 'X-Request-ID': '12345' },
102
+ params: { debug: 'true' }
103
+ });
91
104
  ```
92
105
 
93
106
  #### `getMessages()`
@@ -241,6 +254,94 @@ try {
241
254
  }
242
255
  ```
243
256
 
257
+ ### Custom Headers and Query Parameters
258
+
259
+ The client supports both global and per-request headers and query parameters.
260
+
261
+ #### Global Configuration
262
+
263
+ Set headers and params in the client config to apply them to all API requests:
264
+
265
+ ```typescript
266
+ const client = new AgnoClient({
267
+ endpoint: 'http://localhost:7777',
268
+ agentId: 'agent-123',
269
+ headers: {
270
+ 'X-API-Version': 'v2',
271
+ 'X-Client-ID': 'my-app'
272
+ },
273
+ params: {
274
+ locale: 'en-US',
275
+ environment: 'production'
276
+ }
277
+ });
278
+ ```
279
+
280
+ #### Per-Request Options
281
+
282
+ Override or add headers/params for specific requests:
283
+
284
+ ```typescript
285
+ // Per-request overrides global settings
286
+ await client.sendMessage('Hello!', {
287
+ headers: { 'X-Request-ID': '12345' },
288
+ params: { temperature: '0.7' }
289
+ });
290
+
291
+ // All methods support headers and params
292
+ await client.loadSession('session-123', {
293
+ params: { include_metadata: 'true' }
294
+ });
295
+
296
+ await client.fetchSessions({
297
+ params: { limit: '50', status: 'active' }
298
+ });
299
+
300
+ await client.continueRun(tools, {
301
+ headers: { 'X-Trace-ID': 'abc123' },
302
+ params: { debug: 'true' }
303
+ });
304
+ ```
305
+
306
+ #### Merge Behavior
307
+
308
+ **Headers:**
309
+ 1. Global headers from `config.headers` (lowest precedence)
310
+ 2. Per-request headers (overrides global)
311
+ 3. Authorization header from `authToken` (highest precedence - always overrides)
312
+
313
+ **Query Parameters:**
314
+ 1. Global params from `config.params` (lowest precedence)
315
+ 2. Per-request params (highest precedence - overrides global)
316
+
317
+ ```typescript
318
+ const client = new AgnoClient({
319
+ endpoint: 'http://localhost:7777',
320
+ agentId: 'agent-123',
321
+ params: { version: 'v1', locale: 'en-US' }
322
+ });
323
+
324
+ // This request will have: version=v2 (overridden), locale=en-US (from global), debug=true (added)
325
+ await client.sendMessage('Hello!', {
326
+ params: { version: 'v2', debug: 'true' }
327
+ });
328
+ ```
329
+
330
+ #### Common Use Cases
331
+
332
+ **Headers:**
333
+ - Request tracking: `{ 'X-Request-ID': uuid() }`
334
+ - API versioning: `{ 'X-API-Version': 'v2' }`
335
+ - Client identification: `{ 'X-Client-ID': 'mobile-app' }`
336
+ - Custom auth: `{ 'X-Custom-Auth': 'token' }`
337
+
338
+ **Query Parameters:**
339
+ - Model configuration: `{ temperature: '0.7', max_tokens: '500' }`
340
+ - Feature flags: `{ enable_streaming: 'true' }`
341
+ - Locale/language: `{ locale: 'en-US', timezone: 'America/New_York' }`
342
+ - Debugging: `{ debug: 'true', trace_id: 'xyz' }`
343
+ - Pagination: `{ page: '1', limit: '50' }`
344
+
244
345
  ### Request Cancellation
245
346
 
246
347
  Use `AbortController` to cancel ongoing requests. This is essential for preventing memory leaks when components unmount or users navigate away during streaming:
package/dist/index.d.mts CHANGED
@@ -40,6 +40,7 @@ declare class AgnoClient extends EventEmitter {
40
40
  */
41
41
  sendMessage(message: string | FormData, options?: {
42
42
  headers?: Record<string, string>;
43
+ params?: Record<string, string>;
43
44
  }): Promise<void>;
44
45
  /**
45
46
  * Handle streaming chunk
@@ -59,15 +60,21 @@ declare class AgnoClient extends EventEmitter {
59
60
  /**
60
61
  * Load a session
61
62
  */
62
- loadSession(sessionId: string): Promise<ChatMessage[]>;
63
+ loadSession(sessionId: string, options?: {
64
+ params?: Record<string, string>;
65
+ }): Promise<ChatMessage[]>;
63
66
  /**
64
67
  * Fetch all sessions
65
68
  */
66
- fetchSessions(): Promise<SessionEntry[]>;
69
+ fetchSessions(options?: {
70
+ params?: Record<string, string>;
71
+ }): Promise<SessionEntry[]>;
67
72
  /**
68
73
  * Delete a session
69
74
  */
70
- deleteSession(sessionId: string): Promise<void>;
75
+ deleteSession(sessionId: string, options?: {
76
+ params?: Record<string, string>;
77
+ }): Promise<void>;
71
78
  /**
72
79
  * Add tool calls to the last message
73
80
  * Used by frontend execution to add tool calls that were executed locally
@@ -91,30 +98,39 @@ declare class AgnoClient extends EventEmitter {
91
98
  * Teams do not support the continue endpoint.
92
99
  *
93
100
  * @param tools - Array of tool calls with execution results
94
- * @param options - Optional request headers
101
+ * @param options - Optional request headers and query parameters
95
102
  * @throws Error if no paused run exists
96
103
  * @throws Error if called with team mode (teams don't support HITL)
97
104
  */
98
105
  continueRun(tools: ToolCall[], options?: {
99
106
  headers?: Record<string, string>;
107
+ params?: Record<string, string>;
100
108
  }): Promise<void>;
101
109
  /**
102
110
  * Check endpoint status
103
111
  */
104
- checkStatus(): Promise<boolean>;
112
+ checkStatus(options?: {
113
+ params?: Record<string, string>;
114
+ }): Promise<boolean>;
105
115
  /**
106
116
  * Fetch agents from endpoint
107
117
  */
108
- fetchAgents(): Promise<AgentDetails[]>;
118
+ fetchAgents(options?: {
119
+ params?: Record<string, string>;
120
+ }): Promise<AgentDetails[]>;
109
121
  /**
110
122
  * Fetch teams from endpoint
111
123
  */
112
- fetchTeams(): Promise<TeamDetails[]>;
124
+ fetchTeams(options?: {
125
+ params?: Record<string, string>;
126
+ }): Promise<TeamDetails[]>;
113
127
  /**
114
128
  * Initialize client (check status and fetch agents/teams)
115
129
  * Automatically selects the first available agent or team if none is configured
116
130
  */
117
- initialize(): Promise<{
131
+ initialize(options?: {
132
+ params?: Record<string, string>;
133
+ }): Promise<{
118
134
  agents: AgentDetails[];
119
135
  teams: TeamDetails[];
120
136
  }>;
package/dist/index.d.ts CHANGED
@@ -40,6 +40,7 @@ declare class AgnoClient extends EventEmitter {
40
40
  */
41
41
  sendMessage(message: string | FormData, options?: {
42
42
  headers?: Record<string, string>;
43
+ params?: Record<string, string>;
43
44
  }): Promise<void>;
44
45
  /**
45
46
  * Handle streaming chunk
@@ -59,15 +60,21 @@ declare class AgnoClient extends EventEmitter {
59
60
  /**
60
61
  * Load a session
61
62
  */
62
- loadSession(sessionId: string): Promise<ChatMessage[]>;
63
+ loadSession(sessionId: string, options?: {
64
+ params?: Record<string, string>;
65
+ }): Promise<ChatMessage[]>;
63
66
  /**
64
67
  * Fetch all sessions
65
68
  */
66
- fetchSessions(): Promise<SessionEntry[]>;
69
+ fetchSessions(options?: {
70
+ params?: Record<string, string>;
71
+ }): Promise<SessionEntry[]>;
67
72
  /**
68
73
  * Delete a session
69
74
  */
70
- deleteSession(sessionId: string): Promise<void>;
75
+ deleteSession(sessionId: string, options?: {
76
+ params?: Record<string, string>;
77
+ }): Promise<void>;
71
78
  /**
72
79
  * Add tool calls to the last message
73
80
  * Used by frontend execution to add tool calls that were executed locally
@@ -91,30 +98,39 @@ declare class AgnoClient extends EventEmitter {
91
98
  * Teams do not support the continue endpoint.
92
99
  *
93
100
  * @param tools - Array of tool calls with execution results
94
- * @param options - Optional request headers
101
+ * @param options - Optional request headers and query parameters
95
102
  * @throws Error if no paused run exists
96
103
  * @throws Error if called with team mode (teams don't support HITL)
97
104
  */
98
105
  continueRun(tools: ToolCall[], options?: {
99
106
  headers?: Record<string, string>;
107
+ params?: Record<string, string>;
100
108
  }): Promise<void>;
101
109
  /**
102
110
  * Check endpoint status
103
111
  */
104
- checkStatus(): Promise<boolean>;
112
+ checkStatus(options?: {
113
+ params?: Record<string, string>;
114
+ }): Promise<boolean>;
105
115
  /**
106
116
  * Fetch agents from endpoint
107
117
  */
108
- fetchAgents(): Promise<AgentDetails[]>;
118
+ fetchAgents(options?: {
119
+ params?: Record<string, string>;
120
+ }): Promise<AgentDetails[]>;
109
121
  /**
110
122
  * Fetch teams from endpoint
111
123
  */
112
- fetchTeams(): Promise<TeamDetails[]>;
124
+ fetchTeams(options?: {
125
+ params?: Record<string, string>;
126
+ }): Promise<TeamDetails[]>;
113
127
  /**
114
128
  * Initialize client (check status and fetch agents/teams)
115
129
  * Automatically selects the first available agent or team if none is configured
116
130
  */
117
- initialize(): Promise<{
131
+ initialize(options?: {
132
+ params?: Record<string, string>;
133
+ }): Promise<{
118
134
  agents: AgentDetails[];
119
135
  teams: TeamDetails[];
120
136
  }>;
package/dist/index.js CHANGED
@@ -250,6 +250,18 @@ var ConfigManager = class {
250
250
  setHeaders(headers) {
251
251
  this.updateField("headers", headers);
252
252
  }
253
+ /**
254
+ * Get global query parameters
255
+ */
256
+ getParams() {
257
+ return this.config.params;
258
+ }
259
+ /**
260
+ * Set global query parameters
261
+ */
262
+ setParams(params) {
263
+ this.updateField("params", params);
264
+ }
253
265
  /**
254
266
  * Get current entity ID (agent or team based on mode)
255
267
  */
@@ -297,6 +309,26 @@ var ConfigManager = class {
297
309
  }
298
310
  return headers;
299
311
  }
312
+ /**
313
+ * Build query string by merging global params and per-request params.
314
+ * Merge order (lowest to highest precedence):
315
+ * 1. Global params from config
316
+ * 2. Per-request params (overrides global)
317
+ *
318
+ * @param perRequestParams - Optional query parameters for this specific request
319
+ * @returns URLSearchParams object ready to append to URLs
320
+ */
321
+ buildQueryString(perRequestParams) {
322
+ const params = {};
323
+ const globalParams = this.getParams();
324
+ if (globalParams) {
325
+ Object.assign(params, globalParams);
326
+ }
327
+ if (perRequestParams) {
328
+ Object.assign(params, perRequestParams);
329
+ }
330
+ return new URLSearchParams(params);
331
+ }
300
332
  };
301
333
 
302
334
  // src/managers/session-manager.ts
@@ -304,11 +336,16 @@ var SessionManager = class {
304
336
  /**
305
337
  * Fetch all sessions for an entity
306
338
  */
307
- async fetchSessions(endpoint, entityType, entityId, dbId, headers) {
339
+ async fetchSessions(endpoint, entityType, entityId, dbId, headers, params) {
308
340
  const url = new URL(`${endpoint}/sessions`);
309
341
  url.searchParams.set("type", entityType);
310
342
  url.searchParams.set("component_id", entityId);
311
343
  url.searchParams.set("db_id", dbId);
344
+ if (params) {
345
+ params.forEach((value, key) => {
346
+ url.searchParams.set(key, value);
347
+ });
348
+ }
312
349
  const response = await fetch(url.toString(), { headers });
313
350
  if (!response.ok) {
314
351
  if (response.status === 404) {
@@ -323,7 +360,7 @@ var SessionManager = class {
323
360
  * Fetch a specific session's runs
324
361
  * Returns an array of RunSchema directly (not wrapped in { data, meta })
325
362
  */
326
- async fetchSession(endpoint, entityType, sessionId, dbId, headers, userId) {
363
+ async fetchSession(endpoint, entityType, sessionId, dbId, headers, userId, params) {
327
364
  const url = new URL(`${endpoint}/sessions/${sessionId}/runs`);
328
365
  url.searchParams.set("type", entityType);
329
366
  if (dbId) {
@@ -332,6 +369,11 @@ var SessionManager = class {
332
369
  if (userId) {
333
370
  url.searchParams.set("user_id", userId);
334
371
  }
372
+ if (params) {
373
+ params.forEach((value, key) => {
374
+ url.searchParams.set(key, value);
375
+ });
376
+ }
335
377
  const response = await fetch(url.toString(), { headers });
336
378
  if (!response.ok) {
337
379
  throw new Error(`Failed to fetch session: ${response.statusText}`);
@@ -341,11 +383,16 @@ var SessionManager = class {
341
383
  /**
342
384
  * Delete a session
343
385
  */
344
- async deleteSession(endpoint, sessionId, dbId, headers) {
386
+ async deleteSession(endpoint, sessionId, dbId, headers, params) {
345
387
  const url = new URL(`${endpoint}/sessions/${sessionId}`);
346
388
  if (dbId) {
347
389
  url.searchParams.set("db_id", dbId);
348
390
  }
391
+ if (params) {
392
+ params.forEach((value, key) => {
393
+ url.searchParams.set(key, value);
394
+ });
395
+ }
349
396
  const response = await fetch(url.toString(), {
350
397
  method: "DELETE",
351
398
  headers
@@ -716,6 +763,7 @@ async function streamResponse(options) {
716
763
  const {
717
764
  apiUrl,
718
765
  headers = {},
766
+ params,
719
767
  requestBody,
720
768
  onChunk,
721
769
  onError,
@@ -723,8 +771,9 @@ async function streamResponse(options) {
723
771
  signal
724
772
  } = options;
725
773
  let buffer = "";
774
+ const finalUrl = params && params.toString() ? `${apiUrl}?${params.toString()}` : apiUrl;
726
775
  try {
727
- const response = await fetch(apiUrl, {
776
+ const response = await fetch(finalUrl, {
728
777
  method: "POST",
729
778
  headers: {
730
779
  ...!(requestBody instanceof FormData) && {
@@ -960,9 +1009,11 @@ var AgnoClient = class extends import_eventemitter3.default {
960
1009
  formData.append("user_id", userId);
961
1010
  }
962
1011
  const headers = this.configManager.buildRequestHeaders(options?.headers);
1012
+ const params = this.configManager.buildQueryString(options?.params);
963
1013
  await streamResponse({
964
1014
  apiUrl: runUrl,
965
1015
  headers,
1016
+ params,
966
1017
  requestBody: formData,
967
1018
  onChunk: (chunk) => {
968
1019
  this.handleChunk(chunk, newSessionId, formData.get("message"));
@@ -1102,13 +1153,15 @@ var AgnoClient = class extends import_eventemitter3.default {
1102
1153
  const dbId = this.configManager.getDbId() || "";
1103
1154
  const userId = this.configManager.getUserId();
1104
1155
  const headers = this.configManager.buildRequestHeaders();
1156
+ const params = this.configManager.buildQueryString();
1105
1157
  const response = await this.sessionManager.fetchSession(
1106
1158
  config.endpoint,
1107
1159
  entityType,
1108
1160
  sessionId,
1109
1161
  dbId,
1110
1162
  headers,
1111
- userId
1163
+ userId,
1164
+ params
1112
1165
  );
1113
1166
  const messages = this.sessionManager.convertSessionToMessages(response);
1114
1167
  if (existingUIComponents.size > 0) {
@@ -1139,7 +1192,7 @@ var AgnoClient = class extends import_eventemitter3.default {
1139
1192
  /**
1140
1193
  * Load a session
1141
1194
  */
1142
- async loadSession(sessionId) {
1195
+ async loadSession(sessionId, options) {
1143
1196
  Logger.debug("[AgnoClient] loadSession called with sessionId:", sessionId);
1144
1197
  const config = this.configManager.getConfig();
1145
1198
  const entityType = this.configManager.getMode();
@@ -1147,13 +1200,15 @@ var AgnoClient = class extends import_eventemitter3.default {
1147
1200
  const userId = this.configManager.getUserId();
1148
1201
  Logger.debug("[AgnoClient] Loading session with:", { entityType, dbId, userId });
1149
1202
  const headers = this.configManager.buildRequestHeaders();
1203
+ const params = this.configManager.buildQueryString(options?.params);
1150
1204
  const response = await this.sessionManager.fetchSession(
1151
1205
  config.endpoint,
1152
1206
  entityType,
1153
1207
  sessionId,
1154
1208
  dbId,
1155
1209
  headers,
1156
- userId
1210
+ userId,
1211
+ params
1157
1212
  );
1158
1213
  const messages = this.sessionManager.convertSessionToMessages(response);
1159
1214
  Logger.debug("[AgnoClient] Setting messages to store:", `${messages.length} messages`);
@@ -1169,7 +1224,7 @@ var AgnoClient = class extends import_eventemitter3.default {
1169
1224
  /**
1170
1225
  * Fetch all sessions
1171
1226
  */
1172
- async fetchSessions() {
1227
+ async fetchSessions(options) {
1173
1228
  const config = this.configManager.getConfig();
1174
1229
  const entityType = this.configManager.getMode();
1175
1230
  const entityId = this.configManager.getCurrentEntityId();
@@ -1178,12 +1233,14 @@ var AgnoClient = class extends import_eventemitter3.default {
1178
1233
  throw new Error("Entity ID must be configured");
1179
1234
  }
1180
1235
  const headers = this.configManager.buildRequestHeaders();
1236
+ const params = this.configManager.buildQueryString(options?.params);
1181
1237
  const sessions = await this.sessionManager.fetchSessions(
1182
1238
  config.endpoint,
1183
1239
  entityType,
1184
1240
  entityId,
1185
1241
  dbId,
1186
- headers
1242
+ headers,
1243
+ params
1187
1244
  );
1188
1245
  this.state.sessions = sessions;
1189
1246
  this.emit("state:change", this.getState());
@@ -1192,15 +1249,17 @@ var AgnoClient = class extends import_eventemitter3.default {
1192
1249
  /**
1193
1250
  * Delete a session
1194
1251
  */
1195
- async deleteSession(sessionId) {
1252
+ async deleteSession(sessionId, options) {
1196
1253
  const config = this.configManager.getConfig();
1197
1254
  const dbId = this.configManager.getDbId() || "";
1198
1255
  const headers = this.configManager.buildRequestHeaders();
1256
+ const params = this.configManager.buildQueryString(options?.params);
1199
1257
  await this.sessionManager.deleteSession(
1200
1258
  config.endpoint,
1201
1259
  sessionId,
1202
1260
  dbId,
1203
- headers
1261
+ headers,
1262
+ params
1204
1263
  );
1205
1264
  this.state.sessions = this.state.sessions.filter(
1206
1265
  (s) => s.session_id !== sessionId
@@ -1314,7 +1373,7 @@ var AgnoClient = class extends import_eventemitter3.default {
1314
1373
  * Teams do not support the continue endpoint.
1315
1374
  *
1316
1375
  * @param tools - Array of tool calls with execution results
1317
- * @param options - Optional request headers
1376
+ * @param options - Optional request headers and query parameters
1318
1377
  * @throws Error if no paused run exists
1319
1378
  * @throws Error if called with team mode (teams don't support HITL)
1320
1379
  */
@@ -1352,10 +1411,12 @@ var AgnoClient = class extends import_eventemitter3.default {
1352
1411
  formData.append("user_id", userId);
1353
1412
  }
1354
1413
  const headers = this.configManager.buildRequestHeaders(options?.headers);
1414
+ const params = this.configManager.buildQueryString(options?.params);
1355
1415
  try {
1356
1416
  await streamResponse({
1357
1417
  apiUrl: continueUrl,
1358
1418
  headers,
1419
+ params,
1359
1420
  requestBody: formData,
1360
1421
  onChunk: (chunk) => {
1361
1422
  this.handleChunk(chunk, currentSessionId, "");
@@ -1386,10 +1447,17 @@ var AgnoClient = class extends import_eventemitter3.default {
1386
1447
  /**
1387
1448
  * Check endpoint status
1388
1449
  */
1389
- async checkStatus() {
1450
+ async checkStatus(options) {
1390
1451
  try {
1391
1452
  const headers = this.configManager.buildRequestHeaders();
1392
- const response = await fetch(`${this.configManager.getEndpoint()}/health`, { headers });
1453
+ const params = this.configManager.buildQueryString(options?.params);
1454
+ const url = new URL(`${this.configManager.getEndpoint()}/health`);
1455
+ if (params.toString()) {
1456
+ params.forEach((value, key) => {
1457
+ url.searchParams.set(key, value);
1458
+ });
1459
+ }
1460
+ const response = await fetch(url.toString(), { headers });
1393
1461
  const isActive = response.ok;
1394
1462
  this.state.isEndpointActive = isActive;
1395
1463
  this.emit("state:change", this.getState());
@@ -1403,9 +1471,16 @@ var AgnoClient = class extends import_eventemitter3.default {
1403
1471
  /**
1404
1472
  * Fetch agents from endpoint
1405
1473
  */
1406
- async fetchAgents() {
1474
+ async fetchAgents(options) {
1407
1475
  const headers = this.configManager.buildRequestHeaders();
1408
- const response = await fetch(`${this.configManager.getEndpoint()}/agents`, { headers });
1476
+ const params = this.configManager.buildQueryString(options?.params);
1477
+ const url = new URL(`${this.configManager.getEndpoint()}/agents`);
1478
+ if (params.toString()) {
1479
+ params.forEach((value, key) => {
1480
+ url.searchParams.set(key, value);
1481
+ });
1482
+ }
1483
+ const response = await fetch(url.toString(), { headers });
1409
1484
  if (!response.ok) {
1410
1485
  throw new Error("Failed to fetch agents");
1411
1486
  }
@@ -1417,9 +1492,16 @@ var AgnoClient = class extends import_eventemitter3.default {
1417
1492
  /**
1418
1493
  * Fetch teams from endpoint
1419
1494
  */
1420
- async fetchTeams() {
1495
+ async fetchTeams(options) {
1421
1496
  const headers = this.configManager.buildRequestHeaders();
1422
- const response = await fetch(`${this.configManager.getEndpoint()}/teams`, { headers });
1497
+ const params = this.configManager.buildQueryString(options?.params);
1498
+ const url = new URL(`${this.configManager.getEndpoint()}/teams`);
1499
+ if (params.toString()) {
1500
+ params.forEach((value, key) => {
1501
+ url.searchParams.set(key, value);
1502
+ });
1503
+ }
1504
+ const response = await fetch(url.toString(), { headers });
1423
1505
  if (!response.ok) {
1424
1506
  throw new Error("Failed to fetch teams");
1425
1507
  }
@@ -1432,14 +1514,14 @@ var AgnoClient = class extends import_eventemitter3.default {
1432
1514
  * Initialize client (check status and fetch agents/teams)
1433
1515
  * Automatically selects the first available agent or team if none is configured
1434
1516
  */
1435
- async initialize() {
1436
- const isActive = await this.checkStatus();
1517
+ async initialize(options) {
1518
+ const isActive = await this.checkStatus(options);
1437
1519
  if (!isActive) {
1438
1520
  return { agents: [], teams: [] };
1439
1521
  }
1440
1522
  const [agents, teams] = await Promise.all([
1441
- this.fetchAgents(),
1442
- this.fetchTeams()
1523
+ this.fetchAgents(options),
1524
+ this.fetchTeams(options)
1443
1525
  ]);
1444
1526
  const currentConfig = this.configManager.getConfig();
1445
1527
  const hasAgentConfigured = currentConfig.agentId;
package/dist/index.mjs CHANGED
@@ -212,6 +212,18 @@ var ConfigManager = class {
212
212
  setHeaders(headers) {
213
213
  this.updateField("headers", headers);
214
214
  }
215
+ /**
216
+ * Get global query parameters
217
+ */
218
+ getParams() {
219
+ return this.config.params;
220
+ }
221
+ /**
222
+ * Set global query parameters
223
+ */
224
+ setParams(params) {
225
+ this.updateField("params", params);
226
+ }
215
227
  /**
216
228
  * Get current entity ID (agent or team based on mode)
217
229
  */
@@ -259,6 +271,26 @@ var ConfigManager = class {
259
271
  }
260
272
  return headers;
261
273
  }
274
+ /**
275
+ * Build query string by merging global params and per-request params.
276
+ * Merge order (lowest to highest precedence):
277
+ * 1. Global params from config
278
+ * 2. Per-request params (overrides global)
279
+ *
280
+ * @param perRequestParams - Optional query parameters for this specific request
281
+ * @returns URLSearchParams object ready to append to URLs
282
+ */
283
+ buildQueryString(perRequestParams) {
284
+ const params = {};
285
+ const globalParams = this.getParams();
286
+ if (globalParams) {
287
+ Object.assign(params, globalParams);
288
+ }
289
+ if (perRequestParams) {
290
+ Object.assign(params, perRequestParams);
291
+ }
292
+ return new URLSearchParams(params);
293
+ }
262
294
  };
263
295
 
264
296
  // src/managers/session-manager.ts
@@ -266,11 +298,16 @@ var SessionManager = class {
266
298
  /**
267
299
  * Fetch all sessions for an entity
268
300
  */
269
- async fetchSessions(endpoint, entityType, entityId, dbId, headers) {
301
+ async fetchSessions(endpoint, entityType, entityId, dbId, headers, params) {
270
302
  const url = new URL(`${endpoint}/sessions`);
271
303
  url.searchParams.set("type", entityType);
272
304
  url.searchParams.set("component_id", entityId);
273
305
  url.searchParams.set("db_id", dbId);
306
+ if (params) {
307
+ params.forEach((value, key) => {
308
+ url.searchParams.set(key, value);
309
+ });
310
+ }
274
311
  const response = await fetch(url.toString(), { headers });
275
312
  if (!response.ok) {
276
313
  if (response.status === 404) {
@@ -285,7 +322,7 @@ var SessionManager = class {
285
322
  * Fetch a specific session's runs
286
323
  * Returns an array of RunSchema directly (not wrapped in { data, meta })
287
324
  */
288
- async fetchSession(endpoint, entityType, sessionId, dbId, headers, userId) {
325
+ async fetchSession(endpoint, entityType, sessionId, dbId, headers, userId, params) {
289
326
  const url = new URL(`${endpoint}/sessions/${sessionId}/runs`);
290
327
  url.searchParams.set("type", entityType);
291
328
  if (dbId) {
@@ -294,6 +331,11 @@ var SessionManager = class {
294
331
  if (userId) {
295
332
  url.searchParams.set("user_id", userId);
296
333
  }
334
+ if (params) {
335
+ params.forEach((value, key) => {
336
+ url.searchParams.set(key, value);
337
+ });
338
+ }
297
339
  const response = await fetch(url.toString(), { headers });
298
340
  if (!response.ok) {
299
341
  throw new Error(`Failed to fetch session: ${response.statusText}`);
@@ -303,11 +345,16 @@ var SessionManager = class {
303
345
  /**
304
346
  * Delete a session
305
347
  */
306
- async deleteSession(endpoint, sessionId, dbId, headers) {
348
+ async deleteSession(endpoint, sessionId, dbId, headers, params) {
307
349
  const url = new URL(`${endpoint}/sessions/${sessionId}`);
308
350
  if (dbId) {
309
351
  url.searchParams.set("db_id", dbId);
310
352
  }
353
+ if (params) {
354
+ params.forEach((value, key) => {
355
+ url.searchParams.set(key, value);
356
+ });
357
+ }
311
358
  const response = await fetch(url.toString(), {
312
359
  method: "DELETE",
313
360
  headers
@@ -678,6 +725,7 @@ async function streamResponse(options) {
678
725
  const {
679
726
  apiUrl,
680
727
  headers = {},
728
+ params,
681
729
  requestBody,
682
730
  onChunk,
683
731
  onError,
@@ -685,8 +733,9 @@ async function streamResponse(options) {
685
733
  signal
686
734
  } = options;
687
735
  let buffer = "";
736
+ const finalUrl = params && params.toString() ? `${apiUrl}?${params.toString()}` : apiUrl;
688
737
  try {
689
- const response = await fetch(apiUrl, {
738
+ const response = await fetch(finalUrl, {
690
739
  method: "POST",
691
740
  headers: {
692
741
  ...!(requestBody instanceof FormData) && {
@@ -922,9 +971,11 @@ var AgnoClient = class extends EventEmitter {
922
971
  formData.append("user_id", userId);
923
972
  }
924
973
  const headers = this.configManager.buildRequestHeaders(options?.headers);
974
+ const params = this.configManager.buildQueryString(options?.params);
925
975
  await streamResponse({
926
976
  apiUrl: runUrl,
927
977
  headers,
978
+ params,
928
979
  requestBody: formData,
929
980
  onChunk: (chunk) => {
930
981
  this.handleChunk(chunk, newSessionId, formData.get("message"));
@@ -1064,13 +1115,15 @@ var AgnoClient = class extends EventEmitter {
1064
1115
  const dbId = this.configManager.getDbId() || "";
1065
1116
  const userId = this.configManager.getUserId();
1066
1117
  const headers = this.configManager.buildRequestHeaders();
1118
+ const params = this.configManager.buildQueryString();
1067
1119
  const response = await this.sessionManager.fetchSession(
1068
1120
  config.endpoint,
1069
1121
  entityType,
1070
1122
  sessionId,
1071
1123
  dbId,
1072
1124
  headers,
1073
- userId
1125
+ userId,
1126
+ params
1074
1127
  );
1075
1128
  const messages = this.sessionManager.convertSessionToMessages(response);
1076
1129
  if (existingUIComponents.size > 0) {
@@ -1101,7 +1154,7 @@ var AgnoClient = class extends EventEmitter {
1101
1154
  /**
1102
1155
  * Load a session
1103
1156
  */
1104
- async loadSession(sessionId) {
1157
+ async loadSession(sessionId, options) {
1105
1158
  Logger.debug("[AgnoClient] loadSession called with sessionId:", sessionId);
1106
1159
  const config = this.configManager.getConfig();
1107
1160
  const entityType = this.configManager.getMode();
@@ -1109,13 +1162,15 @@ var AgnoClient = class extends EventEmitter {
1109
1162
  const userId = this.configManager.getUserId();
1110
1163
  Logger.debug("[AgnoClient] Loading session with:", { entityType, dbId, userId });
1111
1164
  const headers = this.configManager.buildRequestHeaders();
1165
+ const params = this.configManager.buildQueryString(options?.params);
1112
1166
  const response = await this.sessionManager.fetchSession(
1113
1167
  config.endpoint,
1114
1168
  entityType,
1115
1169
  sessionId,
1116
1170
  dbId,
1117
1171
  headers,
1118
- userId
1172
+ userId,
1173
+ params
1119
1174
  );
1120
1175
  const messages = this.sessionManager.convertSessionToMessages(response);
1121
1176
  Logger.debug("[AgnoClient] Setting messages to store:", `${messages.length} messages`);
@@ -1131,7 +1186,7 @@ var AgnoClient = class extends EventEmitter {
1131
1186
  /**
1132
1187
  * Fetch all sessions
1133
1188
  */
1134
- async fetchSessions() {
1189
+ async fetchSessions(options) {
1135
1190
  const config = this.configManager.getConfig();
1136
1191
  const entityType = this.configManager.getMode();
1137
1192
  const entityId = this.configManager.getCurrentEntityId();
@@ -1140,12 +1195,14 @@ var AgnoClient = class extends EventEmitter {
1140
1195
  throw new Error("Entity ID must be configured");
1141
1196
  }
1142
1197
  const headers = this.configManager.buildRequestHeaders();
1198
+ const params = this.configManager.buildQueryString(options?.params);
1143
1199
  const sessions = await this.sessionManager.fetchSessions(
1144
1200
  config.endpoint,
1145
1201
  entityType,
1146
1202
  entityId,
1147
1203
  dbId,
1148
- headers
1204
+ headers,
1205
+ params
1149
1206
  );
1150
1207
  this.state.sessions = sessions;
1151
1208
  this.emit("state:change", this.getState());
@@ -1154,15 +1211,17 @@ var AgnoClient = class extends EventEmitter {
1154
1211
  /**
1155
1212
  * Delete a session
1156
1213
  */
1157
- async deleteSession(sessionId) {
1214
+ async deleteSession(sessionId, options) {
1158
1215
  const config = this.configManager.getConfig();
1159
1216
  const dbId = this.configManager.getDbId() || "";
1160
1217
  const headers = this.configManager.buildRequestHeaders();
1218
+ const params = this.configManager.buildQueryString(options?.params);
1161
1219
  await this.sessionManager.deleteSession(
1162
1220
  config.endpoint,
1163
1221
  sessionId,
1164
1222
  dbId,
1165
- headers
1223
+ headers,
1224
+ params
1166
1225
  );
1167
1226
  this.state.sessions = this.state.sessions.filter(
1168
1227
  (s) => s.session_id !== sessionId
@@ -1276,7 +1335,7 @@ var AgnoClient = class extends EventEmitter {
1276
1335
  * Teams do not support the continue endpoint.
1277
1336
  *
1278
1337
  * @param tools - Array of tool calls with execution results
1279
- * @param options - Optional request headers
1338
+ * @param options - Optional request headers and query parameters
1280
1339
  * @throws Error if no paused run exists
1281
1340
  * @throws Error if called with team mode (teams don't support HITL)
1282
1341
  */
@@ -1314,10 +1373,12 @@ var AgnoClient = class extends EventEmitter {
1314
1373
  formData.append("user_id", userId);
1315
1374
  }
1316
1375
  const headers = this.configManager.buildRequestHeaders(options?.headers);
1376
+ const params = this.configManager.buildQueryString(options?.params);
1317
1377
  try {
1318
1378
  await streamResponse({
1319
1379
  apiUrl: continueUrl,
1320
1380
  headers,
1381
+ params,
1321
1382
  requestBody: formData,
1322
1383
  onChunk: (chunk) => {
1323
1384
  this.handleChunk(chunk, currentSessionId, "");
@@ -1348,10 +1409,17 @@ var AgnoClient = class extends EventEmitter {
1348
1409
  /**
1349
1410
  * Check endpoint status
1350
1411
  */
1351
- async checkStatus() {
1412
+ async checkStatus(options) {
1352
1413
  try {
1353
1414
  const headers = this.configManager.buildRequestHeaders();
1354
- const response = await fetch(`${this.configManager.getEndpoint()}/health`, { headers });
1415
+ const params = this.configManager.buildQueryString(options?.params);
1416
+ const url = new URL(`${this.configManager.getEndpoint()}/health`);
1417
+ if (params.toString()) {
1418
+ params.forEach((value, key) => {
1419
+ url.searchParams.set(key, value);
1420
+ });
1421
+ }
1422
+ const response = await fetch(url.toString(), { headers });
1355
1423
  const isActive = response.ok;
1356
1424
  this.state.isEndpointActive = isActive;
1357
1425
  this.emit("state:change", this.getState());
@@ -1365,9 +1433,16 @@ var AgnoClient = class extends EventEmitter {
1365
1433
  /**
1366
1434
  * Fetch agents from endpoint
1367
1435
  */
1368
- async fetchAgents() {
1436
+ async fetchAgents(options) {
1369
1437
  const headers = this.configManager.buildRequestHeaders();
1370
- const response = await fetch(`${this.configManager.getEndpoint()}/agents`, { headers });
1438
+ const params = this.configManager.buildQueryString(options?.params);
1439
+ const url = new URL(`${this.configManager.getEndpoint()}/agents`);
1440
+ if (params.toString()) {
1441
+ params.forEach((value, key) => {
1442
+ url.searchParams.set(key, value);
1443
+ });
1444
+ }
1445
+ const response = await fetch(url.toString(), { headers });
1371
1446
  if (!response.ok) {
1372
1447
  throw new Error("Failed to fetch agents");
1373
1448
  }
@@ -1379,9 +1454,16 @@ var AgnoClient = class extends EventEmitter {
1379
1454
  /**
1380
1455
  * Fetch teams from endpoint
1381
1456
  */
1382
- async fetchTeams() {
1457
+ async fetchTeams(options) {
1383
1458
  const headers = this.configManager.buildRequestHeaders();
1384
- const response = await fetch(`${this.configManager.getEndpoint()}/teams`, { headers });
1459
+ const params = this.configManager.buildQueryString(options?.params);
1460
+ const url = new URL(`${this.configManager.getEndpoint()}/teams`);
1461
+ if (params.toString()) {
1462
+ params.forEach((value, key) => {
1463
+ url.searchParams.set(key, value);
1464
+ });
1465
+ }
1466
+ const response = await fetch(url.toString(), { headers });
1385
1467
  if (!response.ok) {
1386
1468
  throw new Error("Failed to fetch teams");
1387
1469
  }
@@ -1394,14 +1476,14 @@ var AgnoClient = class extends EventEmitter {
1394
1476
  * Initialize client (check status and fetch agents/teams)
1395
1477
  * Automatically selects the first available agent or team if none is configured
1396
1478
  */
1397
- async initialize() {
1398
- const isActive = await this.checkStatus();
1479
+ async initialize(options) {
1480
+ const isActive = await this.checkStatus(options);
1399
1481
  if (!isActive) {
1400
1482
  return { agents: [], teams: [] };
1401
1483
  }
1402
1484
  const [agents, teams] = await Promise.all([
1403
- this.fetchAgents(),
1404
- this.fetchTeams()
1485
+ this.fetchAgents(options),
1486
+ this.fetchTeams(options)
1405
1487
  ]);
1406
1488
  const currentConfig = this.configManager.getConfig();
1407
1489
  const hasAgentConfigured = currentConfig.agentId;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antipopp/agno-client",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "Core client library for Agno agents with streaming support and HITL frontend tool execution",
5
5
  "author": "antipopp",
6
6
  "license": "MIT",
@@ -34,7 +34,7 @@
34
34
  ],
35
35
  "dependencies": {
36
36
  "eventemitter3": "^5.0.1",
37
- "@antipopp/agno-types": "0.8.0"
37
+ "@antipopp/agno-types": "0.9.0"
38
38
  },
39
39
  "devDependencies": {
40
40
  "tsup": "^8.0.1",