@runtypelabs/sdk 1.7.1 → 1.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +7026 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +5147 -0
- package/dist/index.d.ts +5146 -27
- package/dist/index.js +6955 -77
- package/dist/index.js.map +1 -1
- package/package.json +14 -7
- package/dist/batch-builder.d.ts +0 -106
- package/dist/batch-builder.d.ts.map +0 -1
- package/dist/batch-builder.js +0 -124
- package/dist/batch-builder.js.map +0 -1
- package/dist/batches-namespace.d.ts +0 -132
- package/dist/batches-namespace.d.ts.map +0 -1
- package/dist/batches-namespace.js +0 -128
- package/dist/batches-namespace.js.map +0 -1
- package/dist/case-types.d.ts +0 -42
- package/dist/case-types.d.ts.map +0 -1
- package/dist/case-types.js +0 -16
- package/dist/case-types.js.map +0 -1
- package/dist/client-token-types.d.ts +0 -143
- package/dist/client-token-types.d.ts.map +0 -1
- package/dist/client-token-types.js +0 -11
- package/dist/client-token-types.js.map +0 -1
- package/dist/client.d.ts +0 -131
- package/dist/client.d.ts.map +0 -1
- package/dist/client.js +0 -501
- package/dist/client.js.map +0 -1
- package/dist/endpoints.d.ts +0 -1248
- package/dist/endpoints.d.ts.map +0 -1
- package/dist/endpoints.js +0 -1649
- package/dist/endpoints.js.map +0 -1
- package/dist/error-handling-types.d.ts +0 -71
- package/dist/error-handling-types.d.ts.map +0 -1
- package/dist/error-handling-types.js +0 -12
- package/dist/error-handling-types.js.map +0 -1
- package/dist/eval-builder.d.ts +0 -216
- package/dist/eval-builder.d.ts.map +0 -1
- package/dist/eval-builder.js +0 -225
- package/dist/eval-builder.js.map +0 -1
- package/dist/evals-namespace.d.ts +0 -205
- package/dist/evals-namespace.d.ts.map +0 -1
- package/dist/evals-namespace.js +0 -208
- package/dist/evals-namespace.js.map +0 -1
- package/dist/flow-builder.d.ts +0 -717
- package/dist/flow-builder.d.ts.map +0 -1
- package/dist/flow-builder.js +0 -592
- package/dist/flow-builder.js.map +0 -1
- package/dist/flow-result.d.ts +0 -117
- package/dist/flow-result.d.ts.map +0 -1
- package/dist/flow-result.js +0 -175
- package/dist/flow-result.js.map +0 -1
- package/dist/flows-namespace.d.ts +0 -442
- package/dist/flows-namespace.d.ts.map +0 -1
- package/dist/flows-namespace.js +0 -686
- package/dist/flows-namespace.js.map +0 -1
- package/dist/generated-tool-gate.d.ts +0 -75
- package/dist/generated-tool-gate.d.ts.map +0 -1
- package/dist/generated-tool-gate.js +0 -314
- package/dist/generated-tool-gate.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/prompts-namespace.d.ts +0 -237
- package/dist/prompts-namespace.d.ts.map +0 -1
- package/dist/prompts-namespace.js +0 -222
- package/dist/prompts-namespace.js.map +0 -1
- package/dist/runtype.d.ts +0 -232
- package/dist/runtype.d.ts.map +0 -1
- package/dist/runtype.js +0 -367
- package/dist/runtype.js.map +0 -1
- package/dist/stream-utils.d.ts +0 -58
- package/dist/stream-utils.d.ts.map +0 -1
- package/dist/stream-utils.js +0 -373
- package/dist/stream-utils.js.map +0 -1
- package/dist/transform.d.ts +0 -30
- package/dist/transform.d.ts.map +0 -1
- package/dist/transform.js +0 -196
- package/dist/transform.js.map +0 -1
- package/dist/types.d.ts +0 -717
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -7
- package/dist/types.js.map +0 -1
package/dist/endpoints.js
DELETED
|
@@ -1,1649 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* API endpoint handlers with automatic camelCase/snake_case transformation
|
|
4
|
-
*/
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.AgentsEndpoint = exports.ClientTokensEndpoint = exports.EvalEndpoint = exports.ToolsEndpoint = exports.ContextTemplatesEndpoint = exports.FlowStepsEndpoint = exports.AnalyticsEndpoint = exports.UsersEndpoint = exports.ChatEndpoint = exports.DispatchEndpoint = exports.ModelConfigsEndpoint = exports.ApiKeysEndpoint = exports.RecordsEndpoint = exports.PromptsEndpoint = exports.FlowsEndpoint = void 0;
|
|
7
|
-
const generated_tool_gate_1 = require("./generated-tool-gate");
|
|
8
|
-
/**
|
|
9
|
-
* Flows endpoint handlers
|
|
10
|
-
*/
|
|
11
|
-
class FlowsEndpoint {
|
|
12
|
-
constructor(client) {
|
|
13
|
-
this.client = client;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* List all flows for the authenticated user
|
|
17
|
-
*/
|
|
18
|
-
async list(params) {
|
|
19
|
-
return this.client.get('/flows', params);
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Get a specific flow by ID
|
|
23
|
-
*/
|
|
24
|
-
async get(id) {
|
|
25
|
-
const response = await this.client.get(`/flows/${id}`);
|
|
26
|
-
return response;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Create a new flow
|
|
30
|
-
*/
|
|
31
|
-
async create(data) {
|
|
32
|
-
return this.client.post('/flows', data);
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Update an existing flow
|
|
36
|
-
*/
|
|
37
|
-
async update(id, data) {
|
|
38
|
-
return this.client.put(`/flows/${id}`, data);
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Delete a flow
|
|
42
|
-
*/
|
|
43
|
-
async delete(id) {
|
|
44
|
-
return this.client.delete(`/flows/${id}`);
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Run a flow on all records of a specific type
|
|
48
|
-
*/
|
|
49
|
-
async runOnRecordType(id, recordType) {
|
|
50
|
-
return this.client.post(`/flows/${id}/run-on-record-type`, {
|
|
51
|
-
recordType,
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Publish flow (promote draft to published)
|
|
56
|
-
*/
|
|
57
|
-
async publish(id) {
|
|
58
|
-
return this.client.post(`/flows/${id}/publish`);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
exports.FlowsEndpoint = FlowsEndpoint;
|
|
62
|
-
/**
|
|
63
|
-
* Prompts endpoint handlers
|
|
64
|
-
*/
|
|
65
|
-
class PromptsEndpoint {
|
|
66
|
-
constructor(client) {
|
|
67
|
-
this.client = client;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* List all prompts for the authenticated user
|
|
71
|
-
*/
|
|
72
|
-
async list(params) {
|
|
73
|
-
return this.client.get('/prompts', params);
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Get a specific prompt by ID
|
|
77
|
-
*/
|
|
78
|
-
async get(id) {
|
|
79
|
-
return this.client.get(`/prompts/${id}`);
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Create a new prompt
|
|
83
|
-
*/
|
|
84
|
-
async create(data) {
|
|
85
|
-
return this.client.post('/prompts', data);
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Update an existing prompt
|
|
89
|
-
*/
|
|
90
|
-
async update(id, data) {
|
|
91
|
-
return this.client.put(`/prompts/${id}`, data);
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Delete a prompt
|
|
95
|
-
*/
|
|
96
|
-
async delete(id) {
|
|
97
|
-
return this.client.delete(`/prompts/${id}`);
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Run a prompt on a specific record
|
|
101
|
-
*/
|
|
102
|
-
async runOnRecord(id, recordId) {
|
|
103
|
-
return this.client.post(`/prompts/${id}/run-on-record`, { recordId });
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Get flows using this prompt
|
|
107
|
-
*/
|
|
108
|
-
async getFlows(id) {
|
|
109
|
-
return this.client.get(`/prompts/${id}/flows`);
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Update flow attachments for a prompt
|
|
113
|
-
*/
|
|
114
|
-
async updateFlows(id, flowIds) {
|
|
115
|
-
return this.client.put(`/prompts/${id}/flows`, { flowIds });
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
exports.PromptsEndpoint = PromptsEndpoint;
|
|
119
|
-
/**
|
|
120
|
-
* Records endpoint handlers
|
|
121
|
-
*/
|
|
122
|
-
class RecordsEndpoint {
|
|
123
|
-
constructor(client) {
|
|
124
|
-
this.client = client;
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* List all records for the authenticated user
|
|
128
|
-
*/
|
|
129
|
-
async list(params) {
|
|
130
|
-
return this.client.get('/records', params);
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Get a specific record by ID
|
|
134
|
-
*/
|
|
135
|
-
async get(id) {
|
|
136
|
-
return this.client.get(`/records/${id}`);
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Create a new record
|
|
140
|
-
*/
|
|
141
|
-
async create(data) {
|
|
142
|
-
return this.client.post('/records', data);
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* Update an existing record
|
|
146
|
-
*/
|
|
147
|
-
async update(id, data) {
|
|
148
|
-
return this.client.put(`/records/${id}`, data);
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* Delete a record
|
|
152
|
-
*/
|
|
153
|
-
async delete(id) {
|
|
154
|
-
return this.client.delete(`/records/${id}`);
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* Bulk delete multiple records
|
|
158
|
-
*/
|
|
159
|
-
async bulkDelete(ids) {
|
|
160
|
-
return this.client.post('/records/bulk-delete', { ids });
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Bulk edit multiple records
|
|
164
|
-
*/
|
|
165
|
-
async bulkEdit(data) {
|
|
166
|
-
return this.client.post('/records/bulk-edit', data);
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* Get results for a record
|
|
170
|
-
*/
|
|
171
|
-
async getResults(id, params) {
|
|
172
|
-
return this.client.get(`/records/${id}/results`, params);
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* Delete a specific result for a record
|
|
176
|
-
*/
|
|
177
|
-
async deleteResult(id, resultId) {
|
|
178
|
-
return this.client.delete(`/records/${id}/results`, { resultId });
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* Upload CSV file to create multiple records
|
|
182
|
-
*/
|
|
183
|
-
async uploadCsv(file, params) {
|
|
184
|
-
const formData = new FormData();
|
|
185
|
-
formData.append('file', file);
|
|
186
|
-
if (params?.typeColumn) {
|
|
187
|
-
formData.append('typeColumn', params.typeColumn);
|
|
188
|
-
}
|
|
189
|
-
if (params?.nameColumn) {
|
|
190
|
-
formData.append('nameColumn', params.nameColumn);
|
|
191
|
-
}
|
|
192
|
-
return this.client.postFormData('/records/upload-csv', formData);
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* Get record types (distinct values)
|
|
196
|
-
*/
|
|
197
|
-
async getTypes() {
|
|
198
|
-
return this.client.get('/records?distinct=types');
|
|
199
|
-
}
|
|
200
|
-
/**
|
|
201
|
-
* Get example record by type and/or name
|
|
202
|
-
*/
|
|
203
|
-
async getExample(params) {
|
|
204
|
-
return this.client.get('/records', {
|
|
205
|
-
...params,
|
|
206
|
-
includeFields: true,
|
|
207
|
-
limit: 1,
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
exports.RecordsEndpoint = RecordsEndpoint;
|
|
212
|
-
/**
|
|
213
|
-
* API Keys endpoint handlers
|
|
214
|
-
*/
|
|
215
|
-
class ApiKeysEndpoint {
|
|
216
|
-
constructor(client) {
|
|
217
|
-
this.client = client;
|
|
218
|
-
}
|
|
219
|
-
/**
|
|
220
|
-
* List all API keys for the authenticated user
|
|
221
|
-
*/
|
|
222
|
-
async list() {
|
|
223
|
-
const response = await this.client.get('/api-keys');
|
|
224
|
-
return response.apiKeys;
|
|
225
|
-
}
|
|
226
|
-
/**
|
|
227
|
-
* Get a specific API key by ID
|
|
228
|
-
*/
|
|
229
|
-
async get(id) {
|
|
230
|
-
return this.client.get(`/api-keys/${id}`);
|
|
231
|
-
}
|
|
232
|
-
/**
|
|
233
|
-
* Create a new API key
|
|
234
|
-
*/
|
|
235
|
-
async create(data) {
|
|
236
|
-
return this.client.post('/api-keys', data);
|
|
237
|
-
}
|
|
238
|
-
/**
|
|
239
|
-
* Update an existing API key
|
|
240
|
-
*/
|
|
241
|
-
async update(id, data) {
|
|
242
|
-
return this.client.put(`/api-keys/${id}`, data);
|
|
243
|
-
}
|
|
244
|
-
/**
|
|
245
|
-
* Delete an API key
|
|
246
|
-
*/
|
|
247
|
-
async delete(id) {
|
|
248
|
-
return this.client.delete(`/api-keys/${id}`);
|
|
249
|
-
}
|
|
250
|
-
/**
|
|
251
|
-
* Regenerate an API key
|
|
252
|
-
*/
|
|
253
|
-
async regenerate(id) {
|
|
254
|
-
return this.client.post(`/api-keys/${id}/regenerate`);
|
|
255
|
-
}
|
|
256
|
-
/**
|
|
257
|
-
* Get API key analytics
|
|
258
|
-
*/
|
|
259
|
-
async getAnalytics(id) {
|
|
260
|
-
return this.client.get(`/api-keys/${id}/analytics`);
|
|
261
|
-
}
|
|
262
|
-
/**
|
|
263
|
-
* Get usage logs for an API key
|
|
264
|
-
*/
|
|
265
|
-
async getUsage(id, params) {
|
|
266
|
-
return this.client.get(`/api-keys/${id}/usage`, params);
|
|
267
|
-
}
|
|
268
|
-
/**
|
|
269
|
-
* Get API key analytics (all keys or specific key)
|
|
270
|
-
*/
|
|
271
|
-
async getAnalyticsEnhanced(apiKeyId, params) {
|
|
272
|
-
const endpoint = apiKeyId === 'all' ? '/api-keys/analytics' : `/api-keys/${apiKeyId}/analytics`;
|
|
273
|
-
return this.client.get(endpoint, params);
|
|
274
|
-
}
|
|
275
|
-
/**
|
|
276
|
-
* Get API key usage logs (all keys or specific key)
|
|
277
|
-
*/
|
|
278
|
-
async getLogs(apiKeyId, params) {
|
|
279
|
-
const endpoint = apiKeyId === 'all' ? '/api-keys/logs' : `/api-keys/${apiKeyId}/logs`;
|
|
280
|
-
return this.client.get(endpoint, params);
|
|
281
|
-
}
|
|
282
|
-
/**
|
|
283
|
-
* Get API key permission options
|
|
284
|
-
*/
|
|
285
|
-
async getPermissionOptions() {
|
|
286
|
-
return this.client.get('/api-keys/options');
|
|
287
|
-
}
|
|
288
|
-
/**
|
|
289
|
-
* Get API key security logs
|
|
290
|
-
*/
|
|
291
|
-
async getSecurityLogs(id) {
|
|
292
|
-
return this.client.get(`/api-keys/${id}/security-logs`);
|
|
293
|
-
}
|
|
294
|
-
/**
|
|
295
|
-
* Update API key security settings
|
|
296
|
-
*/
|
|
297
|
-
async updateSecurity(id, data) {
|
|
298
|
-
return this.client.put(`/api-keys/${id}/security`, data);
|
|
299
|
-
}
|
|
300
|
-
/**
|
|
301
|
-
* Clear suspicious activity for API key
|
|
302
|
-
*/
|
|
303
|
-
async clearSuspiciousActivity(id) {
|
|
304
|
-
return this.client.post(`/api-keys/${id}/clear-suspicious`);
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
exports.ApiKeysEndpoint = ApiKeysEndpoint;
|
|
308
|
-
/**
|
|
309
|
-
* Model Configurations endpoint handlers
|
|
310
|
-
*/
|
|
311
|
-
class ModelConfigsEndpoint {
|
|
312
|
-
constructor(client) {
|
|
313
|
-
this.client = client;
|
|
314
|
-
}
|
|
315
|
-
/**
|
|
316
|
-
* Get available models catalog
|
|
317
|
-
*/
|
|
318
|
-
async getAvailable() {
|
|
319
|
-
const response = await this.client.get('/model-configs/available');
|
|
320
|
-
// Handle both wrapped and direct array responses
|
|
321
|
-
return Array.isArray(response) ? response : response.data || [];
|
|
322
|
-
}
|
|
323
|
-
/**
|
|
324
|
-
* Get search-capable models (all available, regardless of user configuration)
|
|
325
|
-
*/
|
|
326
|
-
async getSearchCapable() {
|
|
327
|
-
const response = await this.client.get('/model-configs/search-capable');
|
|
328
|
-
return response.data || [];
|
|
329
|
-
}
|
|
330
|
-
/**
|
|
331
|
-
* Get configured search-capable models (only user's configured and enabled models)
|
|
332
|
-
*/
|
|
333
|
-
async getSearchConfigured() {
|
|
334
|
-
const response = await this.client.get('/model-configs/search-configured');
|
|
335
|
-
return response.data || [];
|
|
336
|
-
}
|
|
337
|
-
/**
|
|
338
|
-
* List user's model configurations
|
|
339
|
-
*/
|
|
340
|
-
async list() {
|
|
341
|
-
const response = await this.client.get('/model-configs');
|
|
342
|
-
// Handle both wrapped and direct array responses
|
|
343
|
-
return Array.isArray(response) ? response : response.data || [];
|
|
344
|
-
}
|
|
345
|
-
/**
|
|
346
|
-
* Create a new model configuration
|
|
347
|
-
*/
|
|
348
|
-
async create(data) {
|
|
349
|
-
return this.client.post('/model-configs', data);
|
|
350
|
-
}
|
|
351
|
-
/**
|
|
352
|
-
* Update an existing model configuration
|
|
353
|
-
*/
|
|
354
|
-
async update(id, data) {
|
|
355
|
-
return this.client.put(`/model-configs/${id}`, data);
|
|
356
|
-
}
|
|
357
|
-
/**
|
|
358
|
-
* Delete a model configuration
|
|
359
|
-
*/
|
|
360
|
-
async delete(id) {
|
|
361
|
-
return this.client.delete(`/model-configs/${id}`);
|
|
362
|
-
}
|
|
363
|
-
/**
|
|
364
|
-
* Enable/disable a model configuration
|
|
365
|
-
*/
|
|
366
|
-
async updateStatus(id, isEnabled) {
|
|
367
|
-
return this.client.patch(`/model-configs/${id}/status`, { isEnabled });
|
|
368
|
-
}
|
|
369
|
-
/**
|
|
370
|
-
* Set a model configuration as default
|
|
371
|
-
*/
|
|
372
|
-
async setDefault(id) {
|
|
373
|
-
return this.client.patch(`/model-configs/${id}/default`);
|
|
374
|
-
}
|
|
375
|
-
/**
|
|
376
|
-
* Get usage statistics
|
|
377
|
-
*/
|
|
378
|
-
async getUsage() {
|
|
379
|
-
return this.client.get('/model-configs/usage');
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
exports.ModelConfigsEndpoint = ModelConfigsEndpoint;
|
|
383
|
-
/**
|
|
384
|
-
* Dispatch endpoint handler for atomic record/flow creation and execution
|
|
385
|
-
*/
|
|
386
|
-
class DispatchEndpoint {
|
|
387
|
-
constructor(client) {
|
|
388
|
-
this.client = client;
|
|
389
|
-
}
|
|
390
|
-
/**
|
|
391
|
-
* Dispatch: create and/or execute flows on records atomically
|
|
392
|
-
*/
|
|
393
|
-
async execute(data) {
|
|
394
|
-
return this.client.post('/dispatch', data);
|
|
395
|
-
}
|
|
396
|
-
/**
|
|
397
|
-
* Dispatch with streaming response
|
|
398
|
-
*/
|
|
399
|
-
async executeStream(data) {
|
|
400
|
-
return this.client.requestStream('/dispatch', {
|
|
401
|
-
method: 'POST',
|
|
402
|
-
body: JSON.stringify(data),
|
|
403
|
-
});
|
|
404
|
-
}
|
|
405
|
-
/**
|
|
406
|
-
* Resume paused flow execution
|
|
407
|
-
* API expects snake_case field names
|
|
408
|
-
*
|
|
409
|
-
* @param data.execution_id - The execution ID to resume
|
|
410
|
-
* @param data.tool_outputs - Tool outputs to inject into the flow
|
|
411
|
-
* @param data.stream_response - Whether to stream the response
|
|
412
|
-
* @param data.messages - Optional messages to override the original dispatch messages
|
|
413
|
-
*/
|
|
414
|
-
async resume(data) {
|
|
415
|
-
if (data.streamResponse) {
|
|
416
|
-
return this.client.requestStream('/dispatch/resume', {
|
|
417
|
-
method: 'POST',
|
|
418
|
-
body: JSON.stringify(data),
|
|
419
|
-
});
|
|
420
|
-
}
|
|
421
|
-
return this.client.post('/dispatch/resume', data);
|
|
422
|
-
}
|
|
423
|
-
/**
|
|
424
|
-
* Evaluate a model-proposed runtime tool against a configurable allowlist policy.
|
|
425
|
-
* Useful for local `propose_runtime_tool` handlers before redispatch.
|
|
426
|
-
*/
|
|
427
|
-
gateGeneratedRuntimeToolProposal(proposal, options) {
|
|
428
|
-
return (0, generated_tool_gate_1.evaluateGeneratedRuntimeToolProposal)(proposal, options);
|
|
429
|
-
}
|
|
430
|
-
/**
|
|
431
|
-
* Build standardized local-tool output for a generated tool proposal.
|
|
432
|
-
* Returns `{ approved, reason, violations, tool? }`.
|
|
433
|
-
*/
|
|
434
|
-
buildGeneratedRuntimeToolGateOutput(proposal, options) {
|
|
435
|
-
return (0, generated_tool_gate_1.buildGeneratedRuntimeToolGateOutput)(proposal, options);
|
|
436
|
-
}
|
|
437
|
-
/**
|
|
438
|
-
* Attach approved runtime tools to a prompt step in a redispatch request.
|
|
439
|
-
* Returns a new request object and does not mutate the original.
|
|
440
|
-
*/
|
|
441
|
-
attachApprovedRuntimeTools(request, runtimeTools, options) {
|
|
442
|
-
return (0, generated_tool_gate_1.attachRuntimeToolsToDispatchRequest)(request, runtimeTools, options);
|
|
443
|
-
}
|
|
444
|
-
/**
|
|
445
|
-
* Validate a generated runtime tool proposal and attach it to the redispatch
|
|
446
|
-
* request if approved, in one call.
|
|
447
|
-
*/
|
|
448
|
-
applyGeneratedRuntimeToolProposal(request, proposal, options) {
|
|
449
|
-
return (0, generated_tool_gate_1.applyGeneratedRuntimeToolProposalToDispatchRequest)(request, proposal, options);
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
exports.DispatchEndpoint = DispatchEndpoint;
|
|
453
|
-
/**
|
|
454
|
-
* Chat endpoint handler
|
|
455
|
-
*/
|
|
456
|
-
class ChatEndpoint {
|
|
457
|
-
constructor(client) {
|
|
458
|
-
this.client = client;
|
|
459
|
-
}
|
|
460
|
-
/**
|
|
461
|
-
* Send a chat message
|
|
462
|
-
*/
|
|
463
|
-
async send(message) {
|
|
464
|
-
return this.client.post('/chat', { message });
|
|
465
|
-
}
|
|
466
|
-
/**
|
|
467
|
-
* Send a chat message with streaming response
|
|
468
|
-
*/
|
|
469
|
-
async sendStream(message, options) {
|
|
470
|
-
return this.client.requestStream('/chat', {
|
|
471
|
-
method: 'POST',
|
|
472
|
-
body: JSON.stringify({ message, ...options }),
|
|
473
|
-
});
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
exports.ChatEndpoint = ChatEndpoint;
|
|
477
|
-
/**
|
|
478
|
-
* Users endpoint handlers
|
|
479
|
-
*/
|
|
480
|
-
class UsersEndpoint {
|
|
481
|
-
constructor(client) {
|
|
482
|
-
this.client = client;
|
|
483
|
-
}
|
|
484
|
-
/**
|
|
485
|
-
* Get current user profile
|
|
486
|
-
*/
|
|
487
|
-
async getProfile() {
|
|
488
|
-
return this.client.get('/users/profile');
|
|
489
|
-
}
|
|
490
|
-
/**
|
|
491
|
-
* Update user profile
|
|
492
|
-
*/
|
|
493
|
-
async updateProfile(data) {
|
|
494
|
-
return this.client.put('/users/profile', data);
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
exports.UsersEndpoint = UsersEndpoint;
|
|
498
|
-
/**
|
|
499
|
-
* Analytics endpoint handlers
|
|
500
|
-
*/
|
|
501
|
-
class AnalyticsEndpoint {
|
|
502
|
-
constructor(client) {
|
|
503
|
-
this.client = client;
|
|
504
|
-
}
|
|
505
|
-
/**
|
|
506
|
-
* Get analytics stats
|
|
507
|
-
*/
|
|
508
|
-
async getStats(params) {
|
|
509
|
-
return this.client.get('/analytics/stats', params);
|
|
510
|
-
}
|
|
511
|
-
/**
|
|
512
|
-
* Get analytics executions
|
|
513
|
-
*/
|
|
514
|
-
async getExecutions(params) {
|
|
515
|
-
return this.client.get('/analytics/record-results', params);
|
|
516
|
-
}
|
|
517
|
-
/**
|
|
518
|
-
* Get all record results (same as executions)
|
|
519
|
-
*/
|
|
520
|
-
async getAllRecordResults(params) {
|
|
521
|
-
return this.client.get('/analytics/record-results', params);
|
|
522
|
-
}
|
|
523
|
-
/**
|
|
524
|
-
* Get model usage analytics
|
|
525
|
-
*/
|
|
526
|
-
async getModelUsage(params) {
|
|
527
|
-
return this.client.get('/model-usage', params);
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
exports.AnalyticsEndpoint = AnalyticsEndpoint;
|
|
531
|
-
/**
|
|
532
|
-
* Flow Steps endpoint handlers
|
|
533
|
-
*
|
|
534
|
-
* @deprecated Flow steps are now consolidated into the flows endpoint.
|
|
535
|
-
* Use `flows.get(id)` to get a flow with embedded `flowSteps`.
|
|
536
|
-
* Use `flows.update(id, { flow_steps: [...] })` to update flow steps.
|
|
537
|
-
*/
|
|
538
|
-
class FlowStepsEndpoint {
|
|
539
|
-
constructor(client) {
|
|
540
|
-
this.client = client;
|
|
541
|
-
}
|
|
542
|
-
/**
|
|
543
|
-
* Get flow steps for a flow
|
|
544
|
-
* @deprecated Use `flows.get(flowId)` instead - flow steps are now embedded in the flow response as `flowSteps`
|
|
545
|
-
*/
|
|
546
|
-
async getByFlow(flowId) {
|
|
547
|
-
console.warn('[Runtype SDK] flowSteps.getByFlow() is deprecated. Use flows.get(flowId) instead - flow steps are now embedded in the flow response as flowSteps.');
|
|
548
|
-
return this.client.get(`/flow-steps/flow/${flowId}`);
|
|
549
|
-
}
|
|
550
|
-
/**
|
|
551
|
-
* Get a specific flow step
|
|
552
|
-
* @deprecated Use `flows.get(flowId)` and find the step in `flowSteps` array
|
|
553
|
-
*/
|
|
554
|
-
async get(id) {
|
|
555
|
-
console.warn('[Runtype SDK] flowSteps.get() is deprecated. Use flows.get(flowId) and find the step in flowSteps array.');
|
|
556
|
-
return this.client.get(`/flow-steps/${id}`);
|
|
557
|
-
}
|
|
558
|
-
/**
|
|
559
|
-
* Create a flow step
|
|
560
|
-
* @deprecated Use `flows.update(flowId, { flow_steps: [...] })` to add steps
|
|
561
|
-
*/
|
|
562
|
-
async create(data) {
|
|
563
|
-
console.warn('[Runtype SDK] flowSteps.create() is deprecated. Use flows.update(flowId, { flow_steps: [...] }) to add steps.');
|
|
564
|
-
return this.client.post('/flow-steps', data);
|
|
565
|
-
}
|
|
566
|
-
/**
|
|
567
|
-
* Update a flow step
|
|
568
|
-
* @deprecated Use `flows.update(flowId, { flow_steps: [...] })` to update steps
|
|
569
|
-
*/
|
|
570
|
-
async update(id, data) {
|
|
571
|
-
console.warn('[Runtype SDK] flowSteps.update() is deprecated. Use flows.update(flowId, { flow_steps: [...] }) to update steps.');
|
|
572
|
-
return this.client.put(`/flow-steps/${id}`, data);
|
|
573
|
-
}
|
|
574
|
-
/**
|
|
575
|
-
* Delete a flow step
|
|
576
|
-
* @deprecated Use `flows.update(flowId, { flow_steps: [...] })` with the step removed
|
|
577
|
-
*/
|
|
578
|
-
async delete(id) {
|
|
579
|
-
console.warn('[Runtype SDK] flowSteps.delete() is deprecated. Use flows.update(flowId, { flow_steps: [...] }) with the step removed.');
|
|
580
|
-
return this.client.delete(`/flow-steps/${id}`);
|
|
581
|
-
}
|
|
582
|
-
/**
|
|
583
|
-
* Reorder flow steps
|
|
584
|
-
* @deprecated Use `flows.update(flowId, { flow_steps: [...] })` with updated order values
|
|
585
|
-
*/
|
|
586
|
-
async reorder(flowId, stepOrders) {
|
|
587
|
-
console.warn('[Runtype SDK] flowSteps.reorder() is deprecated. Use flows.update(flowId, { flow_steps: [...] }) with updated order values.');
|
|
588
|
-
return this.client.post('/flow-steps/reorder', {
|
|
589
|
-
flowId,
|
|
590
|
-
stepOrders,
|
|
591
|
-
});
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
exports.FlowStepsEndpoint = FlowStepsEndpoint;
|
|
595
|
-
/**
|
|
596
|
-
* Context Templates endpoint handlers
|
|
597
|
-
*/
|
|
598
|
-
class ContextTemplatesEndpoint {
|
|
599
|
-
constructor(client) {
|
|
600
|
-
this.client = client;
|
|
601
|
-
}
|
|
602
|
-
/**
|
|
603
|
-
* List context templates
|
|
604
|
-
*/
|
|
605
|
-
async list(params) {
|
|
606
|
-
return this.client.get('/context-templates', params);
|
|
607
|
-
}
|
|
608
|
-
/**
|
|
609
|
-
* Get a specific context template
|
|
610
|
-
*/
|
|
611
|
-
async get(id) {
|
|
612
|
-
return this.client.get(`/context-templates/${id}`);
|
|
613
|
-
}
|
|
614
|
-
/**
|
|
615
|
-
* Create a context template
|
|
616
|
-
*/
|
|
617
|
-
async create(data) {
|
|
618
|
-
return this.client.post('/context-templates', data);
|
|
619
|
-
}
|
|
620
|
-
/**
|
|
621
|
-
* Update a context template
|
|
622
|
-
*/
|
|
623
|
-
async update(id, data) {
|
|
624
|
-
return this.client.put(`/context-templates/${id}`, data);
|
|
625
|
-
}
|
|
626
|
-
/**
|
|
627
|
-
* Delete a context template
|
|
628
|
-
*/
|
|
629
|
-
async delete(id) {
|
|
630
|
-
return this.client.delete(`/context-templates/${id}`);
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
exports.ContextTemplatesEndpoint = ContextTemplatesEndpoint;
|
|
634
|
-
/**
|
|
635
|
-
* Tools endpoint handlers
|
|
636
|
-
*/
|
|
637
|
-
class ToolsEndpoint {
|
|
638
|
-
constructor(client) {
|
|
639
|
-
this.client = client;
|
|
640
|
-
}
|
|
641
|
-
/**
|
|
642
|
-
* List all tools for the authenticated user
|
|
643
|
-
*/
|
|
644
|
-
async list(params) {
|
|
645
|
-
return this.client.get('/tools', params);
|
|
646
|
-
}
|
|
647
|
-
/**
|
|
648
|
-
* Get a specific tool by ID
|
|
649
|
-
*/
|
|
650
|
-
async get(id) {
|
|
651
|
-
return this.client.get(`/tools/${id}`);
|
|
652
|
-
}
|
|
653
|
-
/**
|
|
654
|
-
* Create a new tool
|
|
655
|
-
*/
|
|
656
|
-
async create(data) {
|
|
657
|
-
return this.client.post('/tools', data);
|
|
658
|
-
}
|
|
659
|
-
/**
|
|
660
|
-
* Update an existing tool
|
|
661
|
-
*/
|
|
662
|
-
async update(id, data) {
|
|
663
|
-
return this.client.put(`/tools/${id}`, data);
|
|
664
|
-
}
|
|
665
|
-
/**
|
|
666
|
-
* Delete a tool
|
|
667
|
-
*/
|
|
668
|
-
async delete(id) {
|
|
669
|
-
return this.client.delete(`/tools/${id}`);
|
|
670
|
-
}
|
|
671
|
-
/**
|
|
672
|
-
* Execute a tool
|
|
673
|
-
*/
|
|
674
|
-
async execute(id, data) {
|
|
675
|
-
return this.client.post(`/tools/${id}/execute`, data);
|
|
676
|
-
}
|
|
677
|
-
/**
|
|
678
|
-
* Execute a tool with streaming response
|
|
679
|
-
*/
|
|
680
|
-
async executeStream(id, data) {
|
|
681
|
-
return this.client.requestStream(`/tools/${id}/execute`, {
|
|
682
|
-
method: 'POST',
|
|
683
|
-
body: JSON.stringify(data),
|
|
684
|
-
});
|
|
685
|
-
}
|
|
686
|
-
/**
|
|
687
|
-
* Test a tool (same as execute but for testing purposes)
|
|
688
|
-
*/
|
|
689
|
-
async test(id, data) {
|
|
690
|
-
return this.client.post(`/tools/${id}/test`, data);
|
|
691
|
-
}
|
|
692
|
-
/**
|
|
693
|
-
* Get tool executions for a specific tool
|
|
694
|
-
*/
|
|
695
|
-
async getExecutions(toolId, params) {
|
|
696
|
-
return this.client.get(`/tools/${toolId}/executions`, params);
|
|
697
|
-
}
|
|
698
|
-
/**
|
|
699
|
-
* Get AI SDK compatible tool schemas
|
|
700
|
-
*/
|
|
701
|
-
async getSchemas(params) {
|
|
702
|
-
return this.client.get('/tools/schema', params);
|
|
703
|
-
}
|
|
704
|
-
/**
|
|
705
|
-
* Get available tools for prompts
|
|
706
|
-
*/
|
|
707
|
-
async getAvailable() {
|
|
708
|
-
const response = await this.client.get('/tools', {
|
|
709
|
-
isActive: true,
|
|
710
|
-
limit: 200,
|
|
711
|
-
});
|
|
712
|
-
const payload = response;
|
|
713
|
-
if (Array.isArray(payload?.data)) {
|
|
714
|
-
return payload.data;
|
|
715
|
-
}
|
|
716
|
-
if (Array.isArray(payload)) {
|
|
717
|
-
return payload;
|
|
718
|
-
}
|
|
719
|
-
return [];
|
|
720
|
-
}
|
|
721
|
-
/**
|
|
722
|
-
* Convert a flow to a tool
|
|
723
|
-
*/
|
|
724
|
-
async convertFromFlow(flowId, data) {
|
|
725
|
-
return this.client.post(`/flows/${flowId}/convert-to-tool`, data);
|
|
726
|
-
}
|
|
727
|
-
/**
|
|
728
|
-
* Get all built-in tools
|
|
729
|
-
*/
|
|
730
|
-
async getBuiltInTools() {
|
|
731
|
-
return this.client.get('/tools/builtin');
|
|
732
|
-
}
|
|
733
|
-
/**
|
|
734
|
-
* Get built-in tools compatible with a specific model and provider
|
|
735
|
-
*/
|
|
736
|
-
async getCompatibleBuiltInTools(model, provider) {
|
|
737
|
-
return this.client.get('/tools/builtin/compatible', {
|
|
738
|
-
model,
|
|
739
|
-
provider,
|
|
740
|
-
});
|
|
741
|
-
}
|
|
742
|
-
/**
|
|
743
|
-
* Get parameter schema for a specific built-in tool
|
|
744
|
-
*/
|
|
745
|
-
async getBuiltInToolSchema(toolId) {
|
|
746
|
-
return this.client.get(`/tools/builtin/${toolId}/schema`);
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
|
-
exports.ToolsEndpoint = ToolsEndpoint;
|
|
750
|
-
/**
|
|
751
|
-
* Eval endpoint handlers
|
|
752
|
-
*/
|
|
753
|
-
class EvalEndpoint {
|
|
754
|
-
constructor(client) {
|
|
755
|
-
this.client = client;
|
|
756
|
-
}
|
|
757
|
-
/**
|
|
758
|
-
* Run virtual eval with streaming response
|
|
759
|
-
* Executes multiple eval configs simultaneously and streams results via multiplexed SSE
|
|
760
|
-
*/
|
|
761
|
-
async runVirtualEval(data) {
|
|
762
|
-
return this.client.requestStream('/eval/stream', {
|
|
763
|
-
method: 'POST',
|
|
764
|
-
body: JSON.stringify(data),
|
|
765
|
-
});
|
|
766
|
-
}
|
|
767
|
-
}
|
|
768
|
-
exports.EvalEndpoint = EvalEndpoint;
|
|
769
|
-
/**
|
|
770
|
-
* Client Tokens endpoint handlers
|
|
771
|
-
*
|
|
772
|
-
* Manages client tokens for secure browser-to-API communication.
|
|
773
|
-
* Client tokens enable embedding chat widgets in external applications.
|
|
774
|
-
*/
|
|
775
|
-
class ClientTokensEndpoint {
|
|
776
|
-
constructor(client) {
|
|
777
|
-
this.client = client;
|
|
778
|
-
}
|
|
779
|
-
/**
|
|
780
|
-
* List all client tokens for the authenticated user
|
|
781
|
-
*/
|
|
782
|
-
async list() {
|
|
783
|
-
const response = await this.client.get('/client-tokens');
|
|
784
|
-
return response.clientTokens;
|
|
785
|
-
}
|
|
786
|
-
/**
|
|
787
|
-
* Get a specific client token by ID
|
|
788
|
-
*/
|
|
789
|
-
async get(id) {
|
|
790
|
-
return this.client.get(`/client-tokens/${id}`);
|
|
791
|
-
}
|
|
792
|
-
/**
|
|
793
|
-
* Create a new client token
|
|
794
|
-
*
|
|
795
|
-
* @returns The created token with the plain token value (shown only once)
|
|
796
|
-
*/
|
|
797
|
-
async create(data) {
|
|
798
|
-
return this.client.post('/client-tokens', data);
|
|
799
|
-
}
|
|
800
|
-
/**
|
|
801
|
-
* Update an existing client token
|
|
802
|
-
*/
|
|
803
|
-
async update(id, data) {
|
|
804
|
-
return this.client.put(`/client-tokens/${id}`, data);
|
|
805
|
-
}
|
|
806
|
-
/**
|
|
807
|
-
* Delete a client token
|
|
808
|
-
*/
|
|
809
|
-
async delete(id) {
|
|
810
|
-
return this.client.delete(`/client-tokens/${id}`);
|
|
811
|
-
}
|
|
812
|
-
/**
|
|
813
|
-
* Regenerate a client token's value
|
|
814
|
-
*
|
|
815
|
-
* @returns The updated token with the new plain token value (shown only once)
|
|
816
|
-
*/
|
|
817
|
-
async regenerate(id) {
|
|
818
|
-
return this.client.post(`/client-tokens/${id}/regenerate`);
|
|
819
|
-
}
|
|
820
|
-
/**
|
|
821
|
-
* Get the plain token value for a client token
|
|
822
|
-
*
|
|
823
|
-
* Note: Only works if the token was just created or regenerated in the same session
|
|
824
|
-
*/
|
|
825
|
-
async getToken(id) {
|
|
826
|
-
return this.client.get(`/client-tokens/${id}/token`);
|
|
827
|
-
}
|
|
828
|
-
/**
|
|
829
|
-
* List conversations for a client token
|
|
830
|
-
*/
|
|
831
|
-
async listConversations(id, params) {
|
|
832
|
-
return this.client.get(`/client-tokens/${id}/conversations`, params);
|
|
833
|
-
}
|
|
834
|
-
}
|
|
835
|
-
exports.ClientTokensEndpoint = ClientTokensEndpoint;
|
|
836
|
-
/**
|
|
837
|
-
* Parse SSE stream chunks into individual events with event type support
|
|
838
|
-
*/
|
|
839
|
-
function parseSSEChunkWithEventType(chunk, buffer) {
|
|
840
|
-
buffer += chunk;
|
|
841
|
-
// Split on double newlines to get complete events
|
|
842
|
-
const parts = buffer.split('\n\n');
|
|
843
|
-
const remainingBuffer = parts.pop() || '';
|
|
844
|
-
const events = [];
|
|
845
|
-
for (const part of parts) {
|
|
846
|
-
if (!part.trim())
|
|
847
|
-
continue;
|
|
848
|
-
const lines = part.split('\n');
|
|
849
|
-
let eventType = null;
|
|
850
|
-
let dataStr = null;
|
|
851
|
-
for (const line of lines) {
|
|
852
|
-
if (line.startsWith('event: ')) {
|
|
853
|
-
eventType = line.slice(7).trim();
|
|
854
|
-
}
|
|
855
|
-
else if (line.startsWith('data: ')) {
|
|
856
|
-
dataStr = line.slice(6).trim();
|
|
857
|
-
}
|
|
858
|
-
}
|
|
859
|
-
if (dataStr && dataStr !== '[DONE]') {
|
|
860
|
-
try {
|
|
861
|
-
const data = JSON.parse(dataStr);
|
|
862
|
-
events.push({ eventType, data });
|
|
863
|
-
}
|
|
864
|
-
catch {
|
|
865
|
-
// Invalid JSON, skip
|
|
866
|
-
}
|
|
867
|
-
}
|
|
868
|
-
}
|
|
869
|
-
return { events, remainingBuffer };
|
|
870
|
-
}
|
|
871
|
-
/**
|
|
872
|
-
* Dispatch a parsed agent event to the appropriate callback
|
|
873
|
-
*/
|
|
874
|
-
function dispatchAgentEvent(event, callbacks) {
|
|
875
|
-
const { eventType, data } = event;
|
|
876
|
-
const typedData = data;
|
|
877
|
-
// If no event type, try to get it from the data
|
|
878
|
-
const type = eventType || typedData?.type;
|
|
879
|
-
// @snake-case-ok-start: Agent event type identifiers use snake_case to match flow events
|
|
880
|
-
switch (type) {
|
|
881
|
-
case 'agent_start':
|
|
882
|
-
callbacks.onAgentStart?.(typedData);
|
|
883
|
-
break;
|
|
884
|
-
case 'agent_iteration_start':
|
|
885
|
-
callbacks.onIterationStart?.(typedData);
|
|
886
|
-
break;
|
|
887
|
-
case 'agent_turn_start':
|
|
888
|
-
callbacks.onTurnStart?.(typedData);
|
|
889
|
-
break;
|
|
890
|
-
case 'agent_turn_delta':
|
|
891
|
-
callbacks.onTurnDelta?.(typedData);
|
|
892
|
-
break;
|
|
893
|
-
case 'agent_turn_complete':
|
|
894
|
-
callbacks.onTurnComplete?.(typedData);
|
|
895
|
-
break;
|
|
896
|
-
case 'agent_tool_start':
|
|
897
|
-
callbacks.onToolStart?.(typedData);
|
|
898
|
-
break;
|
|
899
|
-
case 'agent_tool_delta':
|
|
900
|
-
callbacks.onToolDelta?.(typedData);
|
|
901
|
-
break;
|
|
902
|
-
case 'agent_tool_complete':
|
|
903
|
-
callbacks.onToolComplete?.(typedData);
|
|
904
|
-
break;
|
|
905
|
-
case 'agent_iteration_complete':
|
|
906
|
-
callbacks.onIterationComplete?.(typedData);
|
|
907
|
-
break;
|
|
908
|
-
case 'agent_reflection':
|
|
909
|
-
callbacks.onReflection?.(typedData);
|
|
910
|
-
break;
|
|
911
|
-
case 'agent_complete':
|
|
912
|
-
callbacks.onAgentComplete?.(typedData);
|
|
913
|
-
break;
|
|
914
|
-
case 'agent_error':
|
|
915
|
-
callbacks.onError?.(typedData);
|
|
916
|
-
break;
|
|
917
|
-
case 'agent_await':
|
|
918
|
-
callbacks.onAgentPaused?.(typedData);
|
|
919
|
-
break;
|
|
920
|
-
case 'agent_ping':
|
|
921
|
-
callbacks.onPing?.(typedData);
|
|
922
|
-
break;
|
|
923
|
-
default:
|
|
924
|
-
callbacks.onUnknownEvent?.(event);
|
|
925
|
-
}
|
|
926
|
-
// @snake-case-ok-end
|
|
927
|
-
}
|
|
928
|
-
/**
|
|
929
|
-
* Process agent stream with callbacks
|
|
930
|
-
*/
|
|
931
|
-
async function processAgentStream(body, callbacks) {
|
|
932
|
-
if (!body)
|
|
933
|
-
return;
|
|
934
|
-
const reader = body.getReader();
|
|
935
|
-
const decoder = new TextDecoder();
|
|
936
|
-
let buffer = '';
|
|
937
|
-
try {
|
|
938
|
-
while (true) {
|
|
939
|
-
const { done, value } = await reader.read();
|
|
940
|
-
if (done) {
|
|
941
|
-
// Process any remaining buffer
|
|
942
|
-
if (buffer.trim()) {
|
|
943
|
-
const { events } = parseSSEChunkWithEventType(buffer + '\n\n', '');
|
|
944
|
-
for (const event of events) {
|
|
945
|
-
dispatchAgentEvent(event, callbacks);
|
|
946
|
-
}
|
|
947
|
-
}
|
|
948
|
-
break;
|
|
949
|
-
}
|
|
950
|
-
const chunk = decoder.decode(value, { stream: true });
|
|
951
|
-
const { events, remainingBuffer } = parseSSEChunkWithEventType(chunk, buffer);
|
|
952
|
-
buffer = remainingBuffer;
|
|
953
|
-
for (const event of events) {
|
|
954
|
-
dispatchAgentEvent(event, callbacks);
|
|
955
|
-
}
|
|
956
|
-
}
|
|
957
|
-
}
|
|
958
|
-
finally {
|
|
959
|
-
reader.releaseLock();
|
|
960
|
-
}
|
|
961
|
-
}
|
|
962
|
-
const GENERATED_RUNTIME_TOOL_PROPOSAL_SCHEMA = {
|
|
963
|
-
type: 'object',
|
|
964
|
-
properties: {
|
|
965
|
-
name: {
|
|
966
|
-
type: 'string',
|
|
967
|
-
description: 'Tool name. Use letters/numbers/underscore only.',
|
|
968
|
-
},
|
|
969
|
-
description: {
|
|
970
|
-
type: 'string',
|
|
971
|
-
description: 'Clear description of what the generated tool does.',
|
|
972
|
-
},
|
|
973
|
-
toolType: {
|
|
974
|
-
type: 'string',
|
|
975
|
-
enum: ['custom'],
|
|
976
|
-
description: 'Must be "custom" for generated code execution tools.',
|
|
977
|
-
},
|
|
978
|
-
parametersSchema: {
|
|
979
|
-
type: 'object',
|
|
980
|
-
description: 'JSON schema for tool call arguments.',
|
|
981
|
-
},
|
|
982
|
-
config: {
|
|
983
|
-
type: 'object',
|
|
984
|
-
description: 'Runtime tool config including code, sandboxProvider, language, and timeout.',
|
|
985
|
-
},
|
|
986
|
-
reason: {
|
|
987
|
-
type: 'string',
|
|
988
|
-
description: 'Why this tool is needed.',
|
|
989
|
-
},
|
|
990
|
-
},
|
|
991
|
-
required: ['name', 'description', 'toolType', 'parametersSchema', 'config'],
|
|
992
|
-
};
|
|
993
|
-
function appendRuntimeToolsToAgentRequest(request, runtimeTools) {
|
|
994
|
-
const existing = request.tools?.runtimeTools || [];
|
|
995
|
-
const existingNames = new Set(existing.map((tool) => tool.name));
|
|
996
|
-
const converted = runtimeTools
|
|
997
|
-
.filter((tool) => !existingNames.has(tool.name))
|
|
998
|
-
.map((tool) => ({
|
|
999
|
-
name: tool.name,
|
|
1000
|
-
description: tool.description,
|
|
1001
|
-
toolType: tool.toolType,
|
|
1002
|
-
parametersSchema: tool.parametersSchema,
|
|
1003
|
-
...(tool.config ? { config: tool.config } : {}),
|
|
1004
|
-
}));
|
|
1005
|
-
return {
|
|
1006
|
-
...request,
|
|
1007
|
-
tools: {
|
|
1008
|
-
...request.tools,
|
|
1009
|
-
runtimeTools: [...existing, ...converted],
|
|
1010
|
-
},
|
|
1011
|
-
};
|
|
1012
|
-
}
|
|
1013
|
-
/**
|
|
1014
|
-
* Agents endpoint handlers
|
|
1015
|
-
*/
|
|
1016
|
-
class AgentsEndpoint {
|
|
1017
|
-
constructor(client) {
|
|
1018
|
-
this.client = client;
|
|
1019
|
-
}
|
|
1020
|
-
/**
|
|
1021
|
-
* List all agents for the authenticated user
|
|
1022
|
-
*/
|
|
1023
|
-
async list(params) {
|
|
1024
|
-
return this.client.get('/agents', params);
|
|
1025
|
-
}
|
|
1026
|
-
/**
|
|
1027
|
-
* Get a specific agent by ID
|
|
1028
|
-
*/
|
|
1029
|
-
async get(id) {
|
|
1030
|
-
return this.client.get(`/agents/${id}`);
|
|
1031
|
-
}
|
|
1032
|
-
/**
|
|
1033
|
-
* Create a new agent
|
|
1034
|
-
*/
|
|
1035
|
-
async create(data) {
|
|
1036
|
-
return this.client.post('/agents', data);
|
|
1037
|
-
}
|
|
1038
|
-
/**
|
|
1039
|
-
* Update an existing agent
|
|
1040
|
-
*/
|
|
1041
|
-
async update(id, data) {
|
|
1042
|
-
return this.client.put(`/agents/${id}`, data);
|
|
1043
|
-
}
|
|
1044
|
-
/**
|
|
1045
|
-
* Delete an agent
|
|
1046
|
-
*/
|
|
1047
|
-
async delete(id) {
|
|
1048
|
-
return this.client.delete(`/agents/${id}`);
|
|
1049
|
-
}
|
|
1050
|
-
/**
|
|
1051
|
-
* Evaluate a model-proposed runtime tool against a configurable allowlist policy.
|
|
1052
|
-
* Useful for local `propose_runtime_tool` handlers before follow-up execution.
|
|
1053
|
-
*/
|
|
1054
|
-
gateGeneratedRuntimeToolProposal(proposal, options) {
|
|
1055
|
-
return (0, generated_tool_gate_1.evaluateGeneratedRuntimeToolProposal)(proposal, options);
|
|
1056
|
-
}
|
|
1057
|
-
/**
|
|
1058
|
-
* Build standardized local-tool output for a generated tool proposal.
|
|
1059
|
-
* Returns `{ approved, reason, violations, tool? }`.
|
|
1060
|
-
*/
|
|
1061
|
-
buildGeneratedRuntimeToolGateOutput(proposal, options) {
|
|
1062
|
-
return (0, generated_tool_gate_1.buildGeneratedRuntimeToolGateOutput)(proposal, options);
|
|
1063
|
-
}
|
|
1064
|
-
/**
|
|
1065
|
-
* Create a local tool definition that validates model-proposed runtime tools.
|
|
1066
|
-
* Plug this into `executeWithLocalTools()` under a name like `propose_runtime_tool`.
|
|
1067
|
-
*/
|
|
1068
|
-
createGeneratedRuntimeToolGateLocalTool(options) {
|
|
1069
|
-
const { description, ...gateOptions } = options || {};
|
|
1070
|
-
return {
|
|
1071
|
-
description: description ||
|
|
1072
|
-
'Validate a generated runtime custom tool and return { approved, reason, violations, tool? }',
|
|
1073
|
-
parametersSchema: GENERATED_RUNTIME_TOOL_PROPOSAL_SCHEMA,
|
|
1074
|
-
execute: async (args) => (0, generated_tool_gate_1.buildGeneratedRuntimeToolGateOutput)(args, gateOptions),
|
|
1075
|
-
};
|
|
1076
|
-
}
|
|
1077
|
-
/**
|
|
1078
|
-
* Attach approved runtime tools to an agent execute request.
|
|
1079
|
-
* Returns a new request object and does not mutate the original.
|
|
1080
|
-
*/
|
|
1081
|
-
attachApprovedRuntimeTools(request, runtimeTools) {
|
|
1082
|
-
return appendRuntimeToolsToAgentRequest(request, runtimeTools);
|
|
1083
|
-
}
|
|
1084
|
-
/**
|
|
1085
|
-
* Validate a generated runtime tool proposal and append it to an agent execute
|
|
1086
|
-
* request if approved, in one call.
|
|
1087
|
-
*/
|
|
1088
|
-
applyGeneratedRuntimeToolProposal(request, proposal, options) {
|
|
1089
|
-
const decision = (0, generated_tool_gate_1.evaluateGeneratedRuntimeToolProposal)(proposal, options);
|
|
1090
|
-
if (!decision.approved || !decision.tool) {
|
|
1091
|
-
return { decision, request };
|
|
1092
|
-
}
|
|
1093
|
-
return {
|
|
1094
|
-
decision,
|
|
1095
|
-
request: appendRuntimeToolsToAgentRequest(request, [decision.tool]),
|
|
1096
|
-
};
|
|
1097
|
-
}
|
|
1098
|
-
/**
|
|
1099
|
-
* Execute an agent (non-streaming)
|
|
1100
|
-
*/
|
|
1101
|
-
async execute(id, data) {
|
|
1102
|
-
return this.client.post(`/agents/${id}/execute`, {
|
|
1103
|
-
...data,
|
|
1104
|
-
streamResponse: false,
|
|
1105
|
-
});
|
|
1106
|
-
}
|
|
1107
|
-
/**
|
|
1108
|
-
* Execute an agent with streaming response
|
|
1109
|
-
*
|
|
1110
|
-
* Returns a Response object with SSE stream.
|
|
1111
|
-
* Use `executeWithCallbacks` for easier handling.
|
|
1112
|
-
*
|
|
1113
|
-
* @example
|
|
1114
|
-
* ```typescript
|
|
1115
|
-
* const response = await client.agents.executeStream('agt_123', {
|
|
1116
|
-
* messages: [{ role: 'user', content: 'Write me a poem' }],
|
|
1117
|
-
* debugMode: true,
|
|
1118
|
-
* })
|
|
1119
|
-
*
|
|
1120
|
-
* // Process the stream manually
|
|
1121
|
-
* const reader = response.body?.getReader()
|
|
1122
|
-
* // ...
|
|
1123
|
-
* ```
|
|
1124
|
-
*/
|
|
1125
|
-
async executeStream(id, data) {
|
|
1126
|
-
return this.client.requestStream(`/agents/${id}/execute`, {
|
|
1127
|
-
method: 'POST',
|
|
1128
|
-
body: JSON.stringify({
|
|
1129
|
-
...data,
|
|
1130
|
-
streamResponse: true,
|
|
1131
|
-
}),
|
|
1132
|
-
});
|
|
1133
|
-
}
|
|
1134
|
-
/**
|
|
1135
|
-
* Execute an agent with streaming and callbacks
|
|
1136
|
-
*
|
|
1137
|
-
* Processes the SSE stream and calls the appropriate callbacks for each event type.
|
|
1138
|
-
* This is the recommended way to handle agent streaming.
|
|
1139
|
-
*
|
|
1140
|
-
* @example
|
|
1141
|
-
* ```typescript
|
|
1142
|
-
* let content = ''
|
|
1143
|
-
*
|
|
1144
|
-
* const result = await client.agents.executeWithCallbacks('agt_123', {
|
|
1145
|
-
* messages: [{ role: 'user', content: 'Write me a poem' }],
|
|
1146
|
-
* debugMode: true,
|
|
1147
|
-
* }, {
|
|
1148
|
-
* onTurnDelta: (event) => {
|
|
1149
|
-
* content += event.delta
|
|
1150
|
-
* process.stdout.write(event.delta)
|
|
1151
|
-
* },
|
|
1152
|
-
* onIterationComplete: (event) => {
|
|
1153
|
-
* console.log(`\nIteration ${event.iteration} complete`)
|
|
1154
|
-
* },
|
|
1155
|
-
* onAgentComplete: (event) => {
|
|
1156
|
-
* console.log(`\nAgent finished: ${event.stopReason}`)
|
|
1157
|
-
* },
|
|
1158
|
-
* onError: (event) => {
|
|
1159
|
-
* console.error(`Error: ${event.error.message}`)
|
|
1160
|
-
* },
|
|
1161
|
-
* })
|
|
1162
|
-
*
|
|
1163
|
-
* console.log('Final result:', result)
|
|
1164
|
-
* ```
|
|
1165
|
-
*/
|
|
1166
|
-
async executeWithCallbacks(id, data, callbacks) {
|
|
1167
|
-
const response = await this.executeStream(id, data);
|
|
1168
|
-
if (!response.ok) {
|
|
1169
|
-
const error = await response.json().catch(() => ({ error: 'Unknown error' }));
|
|
1170
|
-
throw new Error(error.error || `HTTP ${response.status}`);
|
|
1171
|
-
}
|
|
1172
|
-
let completeEvent = null;
|
|
1173
|
-
await processAgentStream(response.body, {
|
|
1174
|
-
...callbacks,
|
|
1175
|
-
onAgentComplete: (event) => {
|
|
1176
|
-
completeEvent = event;
|
|
1177
|
-
callbacks.onAgentComplete?.(event);
|
|
1178
|
-
},
|
|
1179
|
-
});
|
|
1180
|
-
return completeEvent;
|
|
1181
|
-
}
|
|
1182
|
-
/**
|
|
1183
|
-
* Execute an agent with local tool support (pause/resume loop)
|
|
1184
|
-
*
|
|
1185
|
-
* When the agent hits a tool with `toolType: 'local'`, the server emits
|
|
1186
|
-
* `agent_await`. This method automatically executes the local tool and
|
|
1187
|
-
* resumes execution, repeating until the agent completes.
|
|
1188
|
-
*
|
|
1189
|
-
* @example
|
|
1190
|
-
* ```typescript
|
|
1191
|
-
* const result = await client.agents.executeWithLocalTools('agt_123', {
|
|
1192
|
-
* messages: [{ role: 'user', content: 'Create a file called hello.txt' }],
|
|
1193
|
-
* }, {
|
|
1194
|
-
* write_file: async ({ path, content }) => {
|
|
1195
|
-
* fs.writeFileSync(path, content)
|
|
1196
|
-
* return 'ok'
|
|
1197
|
-
* },
|
|
1198
|
-
* })
|
|
1199
|
-
* ```
|
|
1200
|
-
*/
|
|
1201
|
-
async executeWithLocalTools(id, data, localTools, callbacks) {
|
|
1202
|
-
// Build runtime tool definitions from local tool schemas and inject into request
|
|
1203
|
-
const runtimeTools = Object.entries(localTools).map(([name, def]) => ({
|
|
1204
|
-
name,
|
|
1205
|
-
description: def.description,
|
|
1206
|
-
toolType: 'local',
|
|
1207
|
-
parametersSchema: def.parametersSchema,
|
|
1208
|
-
}));
|
|
1209
|
-
const requestData = {
|
|
1210
|
-
...data,
|
|
1211
|
-
tools: {
|
|
1212
|
-
...data.tools,
|
|
1213
|
-
runtimeTools: [...(data.tools?.runtimeTools || []), ...runtimeTools],
|
|
1214
|
-
},
|
|
1215
|
-
};
|
|
1216
|
-
const response = await this.executeStream(id, requestData);
|
|
1217
|
-
if (!response.ok) {
|
|
1218
|
-
const error = await response.json().catch(() => ({ error: 'Unknown error' }));
|
|
1219
|
-
throw new Error(error.error || `HTTP ${response.status}`);
|
|
1220
|
-
}
|
|
1221
|
-
let currentBody = response.body;
|
|
1222
|
-
while (true) {
|
|
1223
|
-
let pausedEvent = null;
|
|
1224
|
-
let completeEvent = null;
|
|
1225
|
-
await processAgentStream(currentBody, {
|
|
1226
|
-
...callbacks,
|
|
1227
|
-
onAgentPaused: (event) => {
|
|
1228
|
-
pausedEvent = event;
|
|
1229
|
-
callbacks?.onAgentPaused?.(event);
|
|
1230
|
-
},
|
|
1231
|
-
onAgentComplete: (event) => {
|
|
1232
|
-
completeEvent = event;
|
|
1233
|
-
callbacks?.onAgentComplete?.(event);
|
|
1234
|
-
},
|
|
1235
|
-
});
|
|
1236
|
-
if (completeEvent)
|
|
1237
|
-
return completeEvent;
|
|
1238
|
-
if (pausedEvent) {
|
|
1239
|
-
const { toolName, parameters, executionId } = pausedEvent;
|
|
1240
|
-
const toolDef = localTools[toolName];
|
|
1241
|
-
if (!toolDef) {
|
|
1242
|
-
throw new Error(`Local tool "${toolName}" required but not provided`);
|
|
1243
|
-
}
|
|
1244
|
-
// Recursively unwrap stringified parameters — the server pipeline may
|
|
1245
|
-
// double-serialize: object → JSON string → JSON string
|
|
1246
|
-
let parsedParams = {};
|
|
1247
|
-
let current = parameters;
|
|
1248
|
-
for (let i = 0; i < 3; i++) {
|
|
1249
|
-
if (typeof current === 'string') {
|
|
1250
|
-
try {
|
|
1251
|
-
current = JSON.parse(current);
|
|
1252
|
-
}
|
|
1253
|
-
catch {
|
|
1254
|
-
console.warn(`[local-tools] Failed to parse parameters (attempt ${i + 1}):`, typeof current, String(current).slice(0, 200));
|
|
1255
|
-
break;
|
|
1256
|
-
}
|
|
1257
|
-
}
|
|
1258
|
-
else {
|
|
1259
|
-
break;
|
|
1260
|
-
}
|
|
1261
|
-
}
|
|
1262
|
-
if (current && typeof current === 'object' && !Array.isArray(current)) {
|
|
1263
|
-
parsedParams = current;
|
|
1264
|
-
}
|
|
1265
|
-
else {
|
|
1266
|
-
console.warn('[local-tools] Parameters could not be resolved to an object:', typeof current, String(current).slice(0, 200));
|
|
1267
|
-
}
|
|
1268
|
-
let toolResult;
|
|
1269
|
-
try {
|
|
1270
|
-
toolResult = await toolDef.execute(parsedParams);
|
|
1271
|
-
}
|
|
1272
|
-
catch (err) {
|
|
1273
|
-
// Return the error as a tool result so the agent can recover
|
|
1274
|
-
toolResult = `Error: ${err instanceof Error ? err.message : String(err)}`;
|
|
1275
|
-
}
|
|
1276
|
-
// Resume via agent resume endpoint
|
|
1277
|
-
const resumeResponse = await this.client.requestStream(`/agents/${id}/resume`, {
|
|
1278
|
-
method: 'POST',
|
|
1279
|
-
body: JSON.stringify({
|
|
1280
|
-
executionId,
|
|
1281
|
-
toolOutputs: { [toolName]: toolResult },
|
|
1282
|
-
streamResponse: true,
|
|
1283
|
-
debugMode: data.debugMode,
|
|
1284
|
-
}),
|
|
1285
|
-
});
|
|
1286
|
-
if (!resumeResponse.ok) {
|
|
1287
|
-
const error = await resumeResponse.json().catch(() => ({ error: 'Unknown error' }));
|
|
1288
|
-
throw new Error(error.error || `HTTP ${resumeResponse.status}`);
|
|
1289
|
-
}
|
|
1290
|
-
currentBody = resumeResponse.body;
|
|
1291
|
-
continue;
|
|
1292
|
-
}
|
|
1293
|
-
// Stream ended without complete or paused
|
|
1294
|
-
return null;
|
|
1295
|
-
}
|
|
1296
|
-
}
|
|
1297
|
-
// ─── Long-Task Agent Execution ───────────────────────────────────────
|
|
1298
|
-
/**
|
|
1299
|
-
* Run a long-task agent across multiple sessions with automatic state management.
|
|
1300
|
-
*
|
|
1301
|
-
* Each session is a single agent execution. The SDK drives the loop client-side,
|
|
1302
|
-
* calling the agent's execute endpoint repeatedly and accumulating context.
|
|
1303
|
-
* Progress is optionally synced to a Runtype record for dashboard visibility.
|
|
1304
|
-
*
|
|
1305
|
-
* @example
|
|
1306
|
-
* ```typescript
|
|
1307
|
-
* const result = await client.agents.runTask('agt_123', {
|
|
1308
|
-
* message: 'Build a REST API with CRUD endpoints',
|
|
1309
|
-
* maxSessions: 20,
|
|
1310
|
-
* maxCost: 5.00,
|
|
1311
|
-
* trackProgress: true,
|
|
1312
|
-
* onSession: (state) => {
|
|
1313
|
-
* console.log(`Session ${state.sessionCount}: ${state.lastStopReason} ($${state.totalCost.toFixed(4)})`)
|
|
1314
|
-
* },
|
|
1315
|
-
* })
|
|
1316
|
-
*
|
|
1317
|
-
* console.log(`Finished: ${result.status} after ${result.sessionCount} sessions`)
|
|
1318
|
-
* ```
|
|
1319
|
-
*/
|
|
1320
|
-
async runTask(id, options) {
|
|
1321
|
-
const maxSessions = options.maxSessions ?? 50;
|
|
1322
|
-
const maxCost = options.maxCost;
|
|
1323
|
-
const useStream = options.stream ?? true;
|
|
1324
|
-
// Resolve agent metadata
|
|
1325
|
-
const agent = await this.get(id);
|
|
1326
|
-
const taskName = typeof options.trackProgress === 'string'
|
|
1327
|
-
? options.trackProgress
|
|
1328
|
-
: options.trackProgress
|
|
1329
|
-
? `${agent.name} task`
|
|
1330
|
-
: '';
|
|
1331
|
-
// Initialize state
|
|
1332
|
-
const state = {
|
|
1333
|
-
agentId: id,
|
|
1334
|
-
agentName: agent.name,
|
|
1335
|
-
taskName: taskName || `${agent.name} task`,
|
|
1336
|
-
status: 'running',
|
|
1337
|
-
sessionCount: 0,
|
|
1338
|
-
totalCost: 0,
|
|
1339
|
-
lastOutput: '',
|
|
1340
|
-
lastStopReason: 'complete',
|
|
1341
|
-
sessions: [],
|
|
1342
|
-
startedAt: new Date().toISOString(),
|
|
1343
|
-
updatedAt: new Date().toISOString(),
|
|
1344
|
-
};
|
|
1345
|
-
// Track the record ID if we're syncing
|
|
1346
|
-
let recordId;
|
|
1347
|
-
// Extract local tool names for prompt injection
|
|
1348
|
-
const localToolNames = options.localTools ? Object.keys(options.localTools) : undefined;
|
|
1349
|
-
// Session loop
|
|
1350
|
-
for (let session = 0; session < maxSessions; session++) {
|
|
1351
|
-
// Build continuation context for resumed runs (first session only)
|
|
1352
|
-
const continuationContext = session === 0 && options.previousMessages
|
|
1353
|
-
? {
|
|
1354
|
-
previousMessages: options.previousMessages,
|
|
1355
|
-
newUserMessage: options.continuationMessage,
|
|
1356
|
-
compact: options.compact,
|
|
1357
|
-
}
|
|
1358
|
-
: undefined;
|
|
1359
|
-
// Store original message on first invocation (not a continuation)
|
|
1360
|
-
if (session === 0 && !options.previousMessages) {
|
|
1361
|
-
state.originalMessage = options.message;
|
|
1362
|
-
}
|
|
1363
|
-
// Build messages for this session
|
|
1364
|
-
const messages = this.buildSessionMessages(options.message, state, session, maxSessions, localToolNames, continuationContext);
|
|
1365
|
-
// Execute one session
|
|
1366
|
-
let sessionResult;
|
|
1367
|
-
const sessionData = {
|
|
1368
|
-
messages,
|
|
1369
|
-
debugMode: options.debugMode,
|
|
1370
|
-
model: options.model,
|
|
1371
|
-
};
|
|
1372
|
-
if (useStream && options.localTools) {
|
|
1373
|
-
// Local tools require the pause/resume streaming loop
|
|
1374
|
-
const completeEvent = await this.executeWithLocalTools(id, sessionData, options.localTools, options.streamCallbacks);
|
|
1375
|
-
if (!completeEvent) {
|
|
1376
|
-
throw new Error('Agent stream ended without a complete event');
|
|
1377
|
-
}
|
|
1378
|
-
sessionResult = {
|
|
1379
|
-
success: completeEvent.success,
|
|
1380
|
-
result: completeEvent.finalOutput || '',
|
|
1381
|
-
iterations: completeEvent.iterations,
|
|
1382
|
-
totalCost: completeEvent.totalCost || 0,
|
|
1383
|
-
stopReason: completeEvent.stopReason,
|
|
1384
|
-
error: completeEvent.error,
|
|
1385
|
-
};
|
|
1386
|
-
}
|
|
1387
|
-
else if (useStream && options.streamCallbacks) {
|
|
1388
|
-
const completeEvent = await this.executeWithCallbacks(id, sessionData, options.streamCallbacks);
|
|
1389
|
-
if (!completeEvent) {
|
|
1390
|
-
throw new Error('Agent stream ended without a complete event');
|
|
1391
|
-
}
|
|
1392
|
-
sessionResult = {
|
|
1393
|
-
success: completeEvent.success,
|
|
1394
|
-
result: completeEvent.finalOutput || '',
|
|
1395
|
-
iterations: completeEvent.iterations,
|
|
1396
|
-
totalCost: completeEvent.totalCost || 0,
|
|
1397
|
-
stopReason: completeEvent.stopReason,
|
|
1398
|
-
error: completeEvent.error,
|
|
1399
|
-
};
|
|
1400
|
-
}
|
|
1401
|
-
else {
|
|
1402
|
-
sessionResult = await this.execute(id, sessionData);
|
|
1403
|
-
}
|
|
1404
|
-
// Update state
|
|
1405
|
-
const sessionCost = sessionResult.totalCost;
|
|
1406
|
-
state.sessionCount = session + 1;
|
|
1407
|
-
state.totalCost += sessionCost;
|
|
1408
|
-
state.lastOutput = sessionResult.result;
|
|
1409
|
-
state.lastStopReason = sessionResult.stopReason;
|
|
1410
|
-
state.updatedAt = new Date().toISOString();
|
|
1411
|
-
state.sessions.push({
|
|
1412
|
-
index: session + 1,
|
|
1413
|
-
cost: sessionCost,
|
|
1414
|
-
iterations: sessionResult.iterations,
|
|
1415
|
-
stopReason: sessionResult.stopReason,
|
|
1416
|
-
outputPreview: sessionResult.result.slice(0, 300),
|
|
1417
|
-
completedAt: new Date().toISOString(),
|
|
1418
|
-
});
|
|
1419
|
-
// Track cost by model
|
|
1420
|
-
const modelKey = options.model || 'default';
|
|
1421
|
-
if (!state.costByModel)
|
|
1422
|
-
state.costByModel = {};
|
|
1423
|
-
state.costByModel[modelKey] = (state.costByModel[modelKey] || 0) + sessionCost;
|
|
1424
|
-
// Accumulate messages for future continuation
|
|
1425
|
-
if (!state.messages)
|
|
1426
|
-
state.messages = [];
|
|
1427
|
-
state.messages.push(...messages);
|
|
1428
|
-
// Also store the assistant's response as a message
|
|
1429
|
-
if (sessionResult.result) {
|
|
1430
|
-
state.messages.push({ role: 'assistant', content: sessionResult.result });
|
|
1431
|
-
}
|
|
1432
|
-
// Keep session log trimmed to last 50 entries
|
|
1433
|
-
if (state.sessions.length > 50) {
|
|
1434
|
-
state.sessions = state.sessions.slice(-50);
|
|
1435
|
-
}
|
|
1436
|
-
// Check terminal conditions
|
|
1437
|
-
if (sessionResult.stopReason === 'complete') {
|
|
1438
|
-
state.status = 'complete';
|
|
1439
|
-
}
|
|
1440
|
-
else if (sessionResult.stopReason === 'error') {
|
|
1441
|
-
state.status = 'complete';
|
|
1442
|
-
}
|
|
1443
|
-
else if (sessionResult.stopReason === 'max_cost') {
|
|
1444
|
-
state.status = 'budget_exceeded';
|
|
1445
|
-
}
|
|
1446
|
-
else if (this.detectTaskCompletion(sessionResult.result)) {
|
|
1447
|
-
// Client-side stop-phrase detection for non-loop agents returning 'end_turn'
|
|
1448
|
-
state.status = 'complete';
|
|
1449
|
-
}
|
|
1450
|
-
else if (maxCost && state.totalCost >= maxCost) {
|
|
1451
|
-
state.status = 'budget_exceeded';
|
|
1452
|
-
}
|
|
1453
|
-
else if (session + 1 >= maxSessions) {
|
|
1454
|
-
state.status = 'max_sessions';
|
|
1455
|
-
}
|
|
1456
|
-
// Sync to record if enabled
|
|
1457
|
-
if (options.trackProgress) {
|
|
1458
|
-
recordId = await this.syncProgressRecord(state, recordId);
|
|
1459
|
-
}
|
|
1460
|
-
// Notify caller
|
|
1461
|
-
if (options.onSession) {
|
|
1462
|
-
const shouldStop = await options.onSession(state);
|
|
1463
|
-
if (shouldStop === false) {
|
|
1464
|
-
state.status = 'paused';
|
|
1465
|
-
}
|
|
1466
|
-
}
|
|
1467
|
-
// Stop if terminal
|
|
1468
|
-
if (state.status !== 'running') {
|
|
1469
|
-
break;
|
|
1470
|
-
}
|
|
1471
|
-
}
|
|
1472
|
-
return {
|
|
1473
|
-
status: state.status,
|
|
1474
|
-
sessionCount: state.sessionCount,
|
|
1475
|
-
totalCost: state.totalCost,
|
|
1476
|
-
lastOutput: state.lastOutput,
|
|
1477
|
-
sessions: state.sessions,
|
|
1478
|
-
recordId,
|
|
1479
|
-
};
|
|
1480
|
-
}
|
|
1481
|
-
/**
|
|
1482
|
-
* Client-side fallback for detecting task completion in agent output.
|
|
1483
|
-
* Mirrors the API's detectAutoComplete() for non-loop agents that return 'end_turn'.
|
|
1484
|
-
*/
|
|
1485
|
-
detectTaskCompletion(output) {
|
|
1486
|
-
const upper = output.toUpperCase();
|
|
1487
|
-
return AgentsEndpoint.STOP_PHRASES.some((phrase) => upper.includes(phrase.toUpperCase()));
|
|
1488
|
-
}
|
|
1489
|
-
/**
|
|
1490
|
-
* Generate a compact summary of prior work for continuation context.
|
|
1491
|
-
* Used when compact mode is enabled to keep token usage low.
|
|
1492
|
-
*/
|
|
1493
|
-
generateCompactSummary(state) {
|
|
1494
|
-
const sessionSummaries = (state.sessions ?? [])
|
|
1495
|
-
.map((s) => `- Session ${s.index}: ${s.stopReason} ($${s.cost.toFixed(4)}) -- ${s.outputPreview.slice(0, 100)}`)
|
|
1496
|
-
.join('\n');
|
|
1497
|
-
return [
|
|
1498
|
-
`Task: ${state.taskName}`,
|
|
1499
|
-
`Status: ${state.status}`,
|
|
1500
|
-
`Sessions completed: ${state.sessionCount}`,
|
|
1501
|
-
`Total cost: $${state.totalCost.toFixed(4)}`,
|
|
1502
|
-
'',
|
|
1503
|
-
'Session history:',
|
|
1504
|
-
sessionSummaries,
|
|
1505
|
-
'',
|
|
1506
|
-
'Last output (truncated):',
|
|
1507
|
-
(state.lastOutput || '').slice(0, 1500),
|
|
1508
|
-
].join('\n');
|
|
1509
|
-
}
|
|
1510
|
-
/**
|
|
1511
|
-
* Build messages for a session, injecting progress context for continuation sessions.
|
|
1512
|
-
* Optionally accepts continuation context for marathon resume scenarios.
|
|
1513
|
-
*/
|
|
1514
|
-
buildSessionMessages(originalMessage, state, sessionIndex, maxSessions, localToolNames, continuationContext) {
|
|
1515
|
-
// Build local tools guidance block when tools are available
|
|
1516
|
-
const toolsBlock = localToolNames?.length
|
|
1517
|
-
? [
|
|
1518
|
-
'',
|
|
1519
|
-
'--- Local Tools ---',
|
|
1520
|
-
`You have access to local filesystem tools (${localToolNames.join(', ')}) that execute directly on the user's machine.`,
|
|
1521
|
-
'Use these tools to create working, runnable files — not just code in your response.',
|
|
1522
|
-
'Prefer creating self-contained HTML files that the user can open in a web browser.',
|
|
1523
|
-
'For example, write a single .html file with inline CSS and JavaScript that demonstrates the result.',
|
|
1524
|
-
'Always use write_file to save your output so the user can run it immediately.',
|
|
1525
|
-
].join('\n')
|
|
1526
|
-
: '';
|
|
1527
|
-
const multiSessionInstruction = `This is a multi-session task (session ${sessionIndex + 1}/${maxSessions}). When you have fully completed the task, end your response with TASK_COMPLETE on its own line.`;
|
|
1528
|
-
// Continuation resume: first session of a resumed run with prior context
|
|
1529
|
-
if (continuationContext && sessionIndex === 0) {
|
|
1530
|
-
const defaultContinueMessage = 'Continue the task. Review your prior work above and proceed with any remaining work. If everything is already complete, respond with TASK_COMPLETE.';
|
|
1531
|
-
const userMessage = continuationContext.newUserMessage || defaultContinueMessage;
|
|
1532
|
-
if (continuationContext.compact) {
|
|
1533
|
-
// Compact mode: summarize prior work instead of full history
|
|
1534
|
-
const summary = this.generateCompactSummary(state);
|
|
1535
|
-
const messages = [
|
|
1536
|
-
{
|
|
1537
|
-
role: 'system',
|
|
1538
|
-
content: `You are continuing a previously completed task. Here is a summary of prior work:\n\n${summary}\n\nDo NOT redo any of the above work.`,
|
|
1539
|
-
},
|
|
1540
|
-
{
|
|
1541
|
-
role: 'user',
|
|
1542
|
-
content: [userMessage, toolsBlock, '', multiSessionInstruction].join('\n'),
|
|
1543
|
-
},
|
|
1544
|
-
];
|
|
1545
|
-
return messages;
|
|
1546
|
-
}
|
|
1547
|
-
// Full history mode: replay all previous messages with do-not-redo instruction
|
|
1548
|
-
const messages = [
|
|
1549
|
-
...continuationContext.previousMessages,
|
|
1550
|
-
{
|
|
1551
|
-
role: 'system',
|
|
1552
|
-
content: 'IMPORTANT: You are continuing a previously completed task. The conversation above shows your prior work. Do NOT redo any of it. Build on what was already accomplished. If there is nothing new to do, respond with TASK_COMPLETE.',
|
|
1553
|
-
},
|
|
1554
|
-
{
|
|
1555
|
-
role: 'user',
|
|
1556
|
-
content: [userMessage, toolsBlock, '', multiSessionInstruction].join('\n'),
|
|
1557
|
-
},
|
|
1558
|
-
];
|
|
1559
|
-
return messages;
|
|
1560
|
-
}
|
|
1561
|
-
// First session (non-continuation): user message + completion signal instruction
|
|
1562
|
-
if (sessionIndex === 0) {
|
|
1563
|
-
const content = [originalMessage, toolsBlock, '', multiSessionInstruction].join('\n');
|
|
1564
|
-
return [{ role: 'user', content }];
|
|
1565
|
-
}
|
|
1566
|
-
// Continuation sessions within a run: inject progress context
|
|
1567
|
-
const recentSessions = state.sessions.slice(-5);
|
|
1568
|
-
const progressSummary = recentSessions
|
|
1569
|
-
.map((s) => ` Session ${s.index}: ${s.stopReason} ($${s.cost.toFixed(4)}) — ${s.outputPreview.slice(0, 100)}`)
|
|
1570
|
-
.join('\n');
|
|
1571
|
-
const content = [
|
|
1572
|
-
originalMessage,
|
|
1573
|
-
toolsBlock,
|
|
1574
|
-
'',
|
|
1575
|
-
`--- Progress (session ${sessionIndex + 1}/${maxSessions}, $${state.totalCost.toFixed(4)} spent) ---`,
|
|
1576
|
-
`Previous sessions:`,
|
|
1577
|
-
progressSummary,
|
|
1578
|
-
'',
|
|
1579
|
-
`Last output (do NOT repeat this — build on it):`,
|
|
1580
|
-
state.lastOutput.slice(0, 1000),
|
|
1581
|
-
'',
|
|
1582
|
-
'Continue where you left off. Do not redo previous work. If the task is already complete, respond with TASK_COMPLETE.',
|
|
1583
|
-
].join('\n');
|
|
1584
|
-
return [{ role: 'user', content }];
|
|
1585
|
-
}
|
|
1586
|
-
/**
|
|
1587
|
-
* Upsert a record to sync long-task progress to the dashboard.
|
|
1588
|
-
* Creates the record on first call, updates it on subsequent calls.
|
|
1589
|
-
*/
|
|
1590
|
-
async syncProgressRecord(state, existingRecordId) {
|
|
1591
|
-
const metadata = {
|
|
1592
|
-
agentId: state.agentId,
|
|
1593
|
-
agentName: state.agentName,
|
|
1594
|
-
status: state.status,
|
|
1595
|
-
sessionCount: state.sessionCount,
|
|
1596
|
-
totalCost: state.totalCost,
|
|
1597
|
-
lastStopReason: state.lastStopReason,
|
|
1598
|
-
lastOutputPreview: state.lastOutput.slice(0, 500),
|
|
1599
|
-
sessions: state.sessions.slice(-10), // Keep last 10 in the record
|
|
1600
|
-
startedAt: state.startedAt,
|
|
1601
|
-
updatedAt: state.updatedAt,
|
|
1602
|
-
};
|
|
1603
|
-
try {
|
|
1604
|
-
if (existingRecordId) {
|
|
1605
|
-
// Update existing record
|
|
1606
|
-
const record = await this.client.put(`/records/${existingRecordId}`, {
|
|
1607
|
-
metadata,
|
|
1608
|
-
});
|
|
1609
|
-
return record.id;
|
|
1610
|
-
}
|
|
1611
|
-
else {
|
|
1612
|
-
// Try to find existing record by type + name first
|
|
1613
|
-
const existing = await this.client.get('/records', {
|
|
1614
|
-
type: 'agent-task',
|
|
1615
|
-
name: state.taskName,
|
|
1616
|
-
limit: 1,
|
|
1617
|
-
});
|
|
1618
|
-
if (existing.data.length > 0) {
|
|
1619
|
-
const record = await this.client.put(`/records/${existing.data[0].id}`, {
|
|
1620
|
-
metadata,
|
|
1621
|
-
});
|
|
1622
|
-
return record.id;
|
|
1623
|
-
}
|
|
1624
|
-
// Create new record
|
|
1625
|
-
const record = await this.client.post('/records', {
|
|
1626
|
-
type: 'agent-task',
|
|
1627
|
-
name: state.taskName,
|
|
1628
|
-
metadata,
|
|
1629
|
-
});
|
|
1630
|
-
return record.id;
|
|
1631
|
-
}
|
|
1632
|
-
}
|
|
1633
|
-
catch {
|
|
1634
|
-
// Record sync is best-effort — don't fail the task
|
|
1635
|
-
return existingRecordId || '';
|
|
1636
|
-
}
|
|
1637
|
-
}
|
|
1638
|
-
}
|
|
1639
|
-
exports.AgentsEndpoint = AgentsEndpoint;
|
|
1640
|
-
/** Stop phrases that indicate the agent considers its task complete. */
|
|
1641
|
-
AgentsEndpoint.STOP_PHRASES = [
|
|
1642
|
-
'DONE:',
|
|
1643
|
-
'TASK_COMPLETE',
|
|
1644
|
-
'FINISHED',
|
|
1645
|
-
'[COMPLETE]',
|
|
1646
|
-
'STATUS: RESOLVED',
|
|
1647
|
-
'STATUS: COMPLETE',
|
|
1648
|
-
];
|
|
1649
|
-
//# sourceMappingURL=endpoints.js.map
|