@runtypelabs/sdk 0.1.1
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 +398 -0
- package/dist/batch-builder.d.ts +106 -0
- package/dist/batch-builder.d.ts.map +1 -0
- package/dist/batch-builder.js +124 -0
- package/dist/batch-builder.js.map +1 -0
- package/dist/batches-namespace.d.ts +132 -0
- package/dist/batches-namespace.d.ts.map +1 -0
- package/dist/batches-namespace.js +128 -0
- package/dist/batches-namespace.js.map +1 -0
- package/dist/client.d.ts +121 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +485 -0
- package/dist/client.js.map +1 -0
- package/dist/endpoints.d.ts +560 -0
- package/dist/endpoints.d.ts.map +1 -0
- package/dist/endpoints.js +725 -0
- package/dist/endpoints.js.map +1 -0
- package/dist/eval-builder.d.ts +216 -0
- package/dist/eval-builder.d.ts.map +1 -0
- package/dist/eval-builder.js +225 -0
- package/dist/eval-builder.js.map +1 -0
- package/dist/evals-namespace.d.ts +205 -0
- package/dist/evals-namespace.d.ts.map +1 -0
- package/dist/evals-namespace.js +208 -0
- package/dist/evals-namespace.js.map +1 -0
- package/dist/flow-builder.d.ts +620 -0
- package/dist/flow-builder.d.ts.map +1 -0
- package/dist/flow-builder.js +565 -0
- package/dist/flow-builder.js.map +1 -0
- package/dist/flow-result.d.ts +117 -0
- package/dist/flow-result.d.ts.map +1 -0
- package/dist/flow-result.js +175 -0
- package/dist/flow-result.js.map +1 -0
- package/dist/flows-namespace.d.ts +430 -0
- package/dist/flows-namespace.d.ts.map +1 -0
- package/dist/flows-namespace.js +679 -0
- package/dist/flows-namespace.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +76 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts-namespace.d.ts +236 -0
- package/dist/prompts-namespace.d.ts.map +1 -0
- package/dist/prompts-namespace.js +222 -0
- package/dist/prompts-namespace.js.map +1 -0
- package/dist/runtype.d.ts +232 -0
- package/dist/runtype.d.ts.map +1 -0
- package/dist/runtype.js +367 -0
- package/dist/runtype.js.map +1 -0
- package/dist/stream-utils.d.ts +58 -0
- package/dist/stream-utils.d.ts.map +1 -0
- package/dist/stream-utils.js +348 -0
- package/dist/stream-utils.js.map +1 -0
- package/dist/transform.d.ts +21 -0
- package/dist/transform.d.ts.map +1 -0
- package/dist/transform.js +170 -0
- package/dist/transform.js.map +1 -0
- package/dist/types.d.ts +626 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1,679 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* FlowsNamespace - Static namespace for flow operations
|
|
4
|
+
*
|
|
5
|
+
* Provides factory methods for creating flow builders with different modes:
|
|
6
|
+
* - upsert: Create or update a flow by name
|
|
7
|
+
* - virtual: One-off execution without saving
|
|
8
|
+
* - use: Execute an existing flow by ID
|
|
9
|
+
*/
|
|
10
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
13
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
14
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
15
|
+
}
|
|
16
|
+
Object.defineProperty(o, k2, desc);
|
|
17
|
+
}) : (function(o, m, k, k2) {
|
|
18
|
+
if (k2 === undefined) k2 = k;
|
|
19
|
+
o[k2] = m[k];
|
|
20
|
+
}));
|
|
21
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
22
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
23
|
+
}) : function(o, v) {
|
|
24
|
+
o["default"] = v;
|
|
25
|
+
});
|
|
26
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
27
|
+
var ownKeys = function(o) {
|
|
28
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
29
|
+
var ar = [];
|
|
30
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
31
|
+
return ar;
|
|
32
|
+
};
|
|
33
|
+
return ownKeys(o);
|
|
34
|
+
};
|
|
35
|
+
return function (mod) {
|
|
36
|
+
if (mod && mod.__esModule) return mod;
|
|
37
|
+
var result = {};
|
|
38
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
39
|
+
__setModuleDefault(result, mod);
|
|
40
|
+
return result;
|
|
41
|
+
};
|
|
42
|
+
})();
|
|
43
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
+
exports.RuntypeFlowBuilder = exports.FlowsNamespace = void 0;
|
|
45
|
+
const flow_result_1 = require("./flow-result");
|
|
46
|
+
// ============================================================================
|
|
47
|
+
// FlowsNamespace
|
|
48
|
+
// ============================================================================
|
|
49
|
+
class FlowsNamespace {
|
|
50
|
+
constructor(getClient) {
|
|
51
|
+
this.getClient = getClient;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Create or update a flow by name (upsert mode)
|
|
55
|
+
*
|
|
56
|
+
* The recommended pattern for code-first flow management.
|
|
57
|
+
* Creates the flow if it doesn't exist, updates if steps changed.
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```typescript
|
|
61
|
+
* const result = await Runtype.flows.upsert({
|
|
62
|
+
* name: 'My Flow',
|
|
63
|
+
* createVersionOnChange: true
|
|
64
|
+
* })
|
|
65
|
+
* .prompt({ name: 'Analyze', model: 'gpt-4o', userPrompt: '...' })
|
|
66
|
+
* .stream()
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
upsert(config) {
|
|
70
|
+
return new RuntypeFlowBuilder(this.getClient, 'upsert', config);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Create a virtual flow (one-off, not saved)
|
|
74
|
+
*
|
|
75
|
+
* Use for temporary or ad-hoc flow execution.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```typescript
|
|
79
|
+
* const result = await Runtype.flows.virtual({ name: 'Temp Flow' })
|
|
80
|
+
* .prompt({ name: 'Process', model: 'gpt-4o', userPrompt: '...' })
|
|
81
|
+
* .stream()
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
virtual(config) {
|
|
85
|
+
return new RuntypeFlowBuilder(this.getClient, 'virtual', config);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Use an existing flow by ID
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```typescript
|
|
92
|
+
* const result = await Runtype.flows.use('flow_123')
|
|
93
|
+
* .withRecord({ name: 'Test', type: 'data' })
|
|
94
|
+
* .stream()
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
use(flowId) {
|
|
98
|
+
return new RuntypeFlowBuilder(this.getClient, 'existing', undefined, flowId);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Quick execution of an existing flow
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```typescript
|
|
105
|
+
* const result = await Runtype.flows.execute('flow_123', {
|
|
106
|
+
* record: { name: 'Test', type: 'data' },
|
|
107
|
+
* streamResponse: true
|
|
108
|
+
* })
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
async execute(flowId, options) {
|
|
112
|
+
const builder = this.use(flowId);
|
|
113
|
+
if (options?.record)
|
|
114
|
+
builder.withRecord(options.record);
|
|
115
|
+
if (options?.messages)
|
|
116
|
+
builder.withMessages(options.messages);
|
|
117
|
+
return options?.streamResponse !== false ? builder.stream() : builder.result();
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
exports.FlowsNamespace = FlowsNamespace;
|
|
121
|
+
// ============================================================================
|
|
122
|
+
// RuntypeFlowBuilder
|
|
123
|
+
// ============================================================================
|
|
124
|
+
/**
|
|
125
|
+
* Fluent builder for constructing and executing flows
|
|
126
|
+
*/
|
|
127
|
+
class RuntypeFlowBuilder {
|
|
128
|
+
constructor(getClient, mode, config, flowId) {
|
|
129
|
+
this.getClient = getClient;
|
|
130
|
+
this.steps = [];
|
|
131
|
+
this.stepCounter = 0;
|
|
132
|
+
this.upsertOptions = {};
|
|
133
|
+
this.dispatchOptions = {};
|
|
134
|
+
this.mode = mode;
|
|
135
|
+
if (mode === 'existing' && flowId) {
|
|
136
|
+
this.existingFlowId = flowId;
|
|
137
|
+
this.flowConfig = { name: '' };
|
|
138
|
+
}
|
|
139
|
+
else if (config) {
|
|
140
|
+
const { createVersionOnChange, allowOverwriteExternalChanges, ...flowConfig } = config;
|
|
141
|
+
this.flowConfig = flowConfig;
|
|
142
|
+
if (mode === 'upsert') {
|
|
143
|
+
this.upsertOptions = {
|
|
144
|
+
createVersionOnChange: createVersionOnChange ?? true,
|
|
145
|
+
...(allowOverwriteExternalChanges !== undefined && { allowOverwriteExternalChanges }),
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
this.flowConfig = { name: 'Untitled Flow' };
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
// ============================================================================
|
|
154
|
+
// Configuration Methods
|
|
155
|
+
// ============================================================================
|
|
156
|
+
/**
|
|
157
|
+
* Set the record configuration
|
|
158
|
+
*/
|
|
159
|
+
withRecord(config) {
|
|
160
|
+
this.recordConfig = config;
|
|
161
|
+
return this;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Set conversation messages
|
|
165
|
+
*/
|
|
166
|
+
withMessages(messages) {
|
|
167
|
+
this.messagesConfig = messages;
|
|
168
|
+
return this;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Set dispatch options
|
|
172
|
+
*/
|
|
173
|
+
withOptions(options) {
|
|
174
|
+
this.dispatchOptions = { ...this.dispatchOptions, ...options };
|
|
175
|
+
return this;
|
|
176
|
+
}
|
|
177
|
+
// ============================================================================
|
|
178
|
+
// Step Methods
|
|
179
|
+
// ============================================================================
|
|
180
|
+
/**
|
|
181
|
+
* Add a prompt step
|
|
182
|
+
*/
|
|
183
|
+
prompt(config) {
|
|
184
|
+
this.addStep('prompt', config.name, {
|
|
185
|
+
model: config.model,
|
|
186
|
+
userPrompt: config.userPrompt,
|
|
187
|
+
text: config.userPrompt,
|
|
188
|
+
systemPrompt: config.systemPrompt,
|
|
189
|
+
previousMessages: config.previousMessages,
|
|
190
|
+
outputVariable: config.outputVariable,
|
|
191
|
+
responseFormat: config.responseFormat,
|
|
192
|
+
temperature: config.temperature,
|
|
193
|
+
maxTokens: config.maxTokens,
|
|
194
|
+
reasoning: config.reasoning,
|
|
195
|
+
streamOutput: config.streamOutput,
|
|
196
|
+
tools: config.tools,
|
|
197
|
+
}, config.enabled);
|
|
198
|
+
return this;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Add a fetch URL step
|
|
202
|
+
*/
|
|
203
|
+
fetchUrl(config) {
|
|
204
|
+
this.addStep('fetch-url', config.name, {
|
|
205
|
+
http: {
|
|
206
|
+
url: config.url,
|
|
207
|
+
method: config.method || 'GET',
|
|
208
|
+
headers: config.headers,
|
|
209
|
+
body: config.body,
|
|
210
|
+
},
|
|
211
|
+
fetchMethod: config.fetchMethod,
|
|
212
|
+
firecrawl: config.firecrawl,
|
|
213
|
+
outputVariable: config.outputVariable,
|
|
214
|
+
errorHandling: config.errorHandling,
|
|
215
|
+
streamOutput: config.streamOutput,
|
|
216
|
+
}, config.enabled);
|
|
217
|
+
return this;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Add a transform data step
|
|
221
|
+
*/
|
|
222
|
+
transformData(config) {
|
|
223
|
+
this.addStep('transform-data', config.name, {
|
|
224
|
+
script: config.script,
|
|
225
|
+
outputVariable: config.outputVariable,
|
|
226
|
+
streamOutput: config.streamOutput,
|
|
227
|
+
}, config.enabled);
|
|
228
|
+
return this;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Add a set variable step
|
|
232
|
+
*/
|
|
233
|
+
setVariable(config) {
|
|
234
|
+
this.addStep('set-variable', config.name, {
|
|
235
|
+
variableName: config.variableName,
|
|
236
|
+
value: config.value,
|
|
237
|
+
}, config.enabled);
|
|
238
|
+
return this;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Add a conditional step
|
|
242
|
+
*/
|
|
243
|
+
conditional(config) {
|
|
244
|
+
this.addStep('conditional', config.name, {
|
|
245
|
+
condition: config.condition,
|
|
246
|
+
trueSteps: config.trueSteps || [],
|
|
247
|
+
falseSteps: config.falseSteps || [],
|
|
248
|
+
}, config.enabled);
|
|
249
|
+
return this;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Add a search step
|
|
253
|
+
*/
|
|
254
|
+
search(config) {
|
|
255
|
+
this.addStep('search', config.name, {
|
|
256
|
+
provider: config.provider,
|
|
257
|
+
query: config.query,
|
|
258
|
+
maxResults: config.maxResults,
|
|
259
|
+
outputVariable: config.outputVariable,
|
|
260
|
+
returnCitations: config.returnCitations,
|
|
261
|
+
errorHandling: config.errorHandling,
|
|
262
|
+
streamOutput: config.streamOutput,
|
|
263
|
+
}, config.enabled);
|
|
264
|
+
return this;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Add a send email step
|
|
268
|
+
*/
|
|
269
|
+
sendEmail(config) {
|
|
270
|
+
this.addStep('send-email', config.name, {
|
|
271
|
+
to: config.to,
|
|
272
|
+
from: config.from || 'no-reply@messages.runtype.com',
|
|
273
|
+
subject: config.subject,
|
|
274
|
+
html: config.html,
|
|
275
|
+
outputVariable: config.outputVariable,
|
|
276
|
+
errorHandling: config.errorHandling,
|
|
277
|
+
streamOutput: config.streamOutput,
|
|
278
|
+
}, config.enabled);
|
|
279
|
+
return this;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Add a send stream step
|
|
283
|
+
*/
|
|
284
|
+
sendStream(config) {
|
|
285
|
+
this.addStep('send-stream', config.name, {
|
|
286
|
+
message: config.message,
|
|
287
|
+
}, config.enabled);
|
|
288
|
+
return this;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Add a retrieve record step
|
|
292
|
+
*/
|
|
293
|
+
retrieveRecord(config) {
|
|
294
|
+
this.addStep('retrieve-record', config.name, {
|
|
295
|
+
recordType: config.recordType,
|
|
296
|
+
recordName: config.recordName,
|
|
297
|
+
fieldsToInclude: config.fieldsToInclude,
|
|
298
|
+
fieldsToExclude: config.fieldsToExclude,
|
|
299
|
+
outputVariable: config.outputVariable,
|
|
300
|
+
streamOutput: config.streamOutput,
|
|
301
|
+
}, config.enabled);
|
|
302
|
+
return this;
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Add an upsert record step
|
|
306
|
+
*/
|
|
307
|
+
upsertRecord(config) {
|
|
308
|
+
this.addStep('upsert-record', config.name, {
|
|
309
|
+
recordType: config.recordType,
|
|
310
|
+
recordName: config.recordName,
|
|
311
|
+
sourceVariable: config.sourceVariable,
|
|
312
|
+
mergeStrategy: config.mergeStrategy,
|
|
313
|
+
outputVariable: config.outputVariable,
|
|
314
|
+
errorHandling: config.errorHandling,
|
|
315
|
+
streamOutput: config.streamOutput,
|
|
316
|
+
}, config.enabled);
|
|
317
|
+
return this;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Add a vector search step
|
|
321
|
+
*/
|
|
322
|
+
vectorSearch(config) {
|
|
323
|
+
this.addStep('vector-search', config.name, {
|
|
324
|
+
query: config.query,
|
|
325
|
+
recordType: config.recordType,
|
|
326
|
+
embeddingModel: config.embeddingModel,
|
|
327
|
+
limit: config.limit,
|
|
328
|
+
threshold: config.threshold,
|
|
329
|
+
outputVariable: config.outputVariable,
|
|
330
|
+
includeDistance: config.includeDistance,
|
|
331
|
+
streamOutput: config.streamOutput,
|
|
332
|
+
}, config.enabled);
|
|
333
|
+
return this;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Add a generate embedding step
|
|
337
|
+
*/
|
|
338
|
+
generateEmbedding(config) {
|
|
339
|
+
this.addStep('generate-embedding', config.name, {
|
|
340
|
+
inputSource: 'text',
|
|
341
|
+
text: config.text,
|
|
342
|
+
embeddingModel: config.embeddingModel,
|
|
343
|
+
maxLength: config.maxLength,
|
|
344
|
+
outputVariable: config.outputVariable,
|
|
345
|
+
streamOutput: config.streamOutput,
|
|
346
|
+
}, config.enabled);
|
|
347
|
+
return this;
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Add a wait until step
|
|
351
|
+
*/
|
|
352
|
+
waitUntil(config) {
|
|
353
|
+
this.addStep('wait-until', config.name, {
|
|
354
|
+
delayMs: config.delayMs,
|
|
355
|
+
continueOnTimeout: config.continueOnTimeout,
|
|
356
|
+
poll: config.poll,
|
|
357
|
+
outputVariable: config.outputVariable,
|
|
358
|
+
errorHandling: config.errorHandling,
|
|
359
|
+
streamOutput: config.streamOutput,
|
|
360
|
+
}, config.enabled);
|
|
361
|
+
return this;
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Add a send event step
|
|
365
|
+
*/
|
|
366
|
+
sendEvent(config) {
|
|
367
|
+
this.addStep('send-event', config.name, {
|
|
368
|
+
provider: config.provider,
|
|
369
|
+
eventName: config.eventName,
|
|
370
|
+
properties: config.properties,
|
|
371
|
+
outputVariable: config.outputVariable,
|
|
372
|
+
errorHandling: config.errorHandling,
|
|
373
|
+
streamOutput: config.streamOutput,
|
|
374
|
+
}, config.enabled);
|
|
375
|
+
return this;
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Add a send text step
|
|
379
|
+
*/
|
|
380
|
+
sendText(config) {
|
|
381
|
+
this.addStep('send-text', config.name, {
|
|
382
|
+
to: config.to,
|
|
383
|
+
from: config.from,
|
|
384
|
+
message: config.message,
|
|
385
|
+
outputVariable: config.outputVariable,
|
|
386
|
+
errorHandling: config.errorHandling,
|
|
387
|
+
streamOutput: config.streamOutput,
|
|
388
|
+
}, config.enabled);
|
|
389
|
+
return this;
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Add a fetch GitHub step
|
|
393
|
+
*/
|
|
394
|
+
fetchGitHub(config) {
|
|
395
|
+
this.addStep('fetch-github', config.name, {
|
|
396
|
+
repository: config.repository,
|
|
397
|
+
branch: config.branch,
|
|
398
|
+
path: config.path,
|
|
399
|
+
outputVariable: config.outputVariable,
|
|
400
|
+
streamOutput: config.streamOutput,
|
|
401
|
+
}, config.enabled);
|
|
402
|
+
return this;
|
|
403
|
+
}
|
|
404
|
+
async stream(arg1, arg2) {
|
|
405
|
+
const config = this.build();
|
|
406
|
+
let callbacks;
|
|
407
|
+
let localTools;
|
|
408
|
+
if (arg1) {
|
|
409
|
+
if ('localTools' in arg1) {
|
|
410
|
+
localTools = arg1.localTools;
|
|
411
|
+
}
|
|
412
|
+
else {
|
|
413
|
+
callbacks = arg1;
|
|
414
|
+
if (arg2) {
|
|
415
|
+
localTools = arg2.localTools;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
// Handle local tools if provided
|
|
420
|
+
if (localTools) {
|
|
421
|
+
return this.runWithLocalTools(localTools, callbacks);
|
|
422
|
+
}
|
|
423
|
+
config.options = { ...config.options, streamResponse: true };
|
|
424
|
+
const client = this.getClient();
|
|
425
|
+
const response = await client.dispatch(config);
|
|
426
|
+
const result = new flow_result_1.FlowResult(response);
|
|
427
|
+
// If callbacks provided, process immediately
|
|
428
|
+
if (callbacks) {
|
|
429
|
+
await result.stream(callbacks);
|
|
430
|
+
}
|
|
431
|
+
return result;
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* Execute the flow and wait for complete result (no streaming)
|
|
435
|
+
*
|
|
436
|
+
* Returns a FlowResult after all steps have completed.
|
|
437
|
+
*
|
|
438
|
+
* @example
|
|
439
|
+
* ```typescript
|
|
440
|
+
* const result = await Runtype.flows.use('flow_123')
|
|
441
|
+
* .withRecord({ ... })
|
|
442
|
+
* .result()
|
|
443
|
+
*
|
|
444
|
+
* const analysis = await result.getResult('Analyze')
|
|
445
|
+
* const allResults = await result.getAllResults()
|
|
446
|
+
* ```
|
|
447
|
+
*/
|
|
448
|
+
async result(options) {
|
|
449
|
+
const config = this.build();
|
|
450
|
+
// Handle local tools if provided
|
|
451
|
+
if (options?.localTools) {
|
|
452
|
+
return this.runWithLocalTools(options.localTools);
|
|
453
|
+
}
|
|
454
|
+
config.options = { ...config.options, streamResponse: true };
|
|
455
|
+
const client = this.getClient();
|
|
456
|
+
const response = await client.dispatch(config);
|
|
457
|
+
const result = new flow_result_1.FlowResult(response);
|
|
458
|
+
// Pre-process the stream to cache results
|
|
459
|
+
await result.getSummary();
|
|
460
|
+
return result;
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Execute the flow with local tools (automatic pause/resume loop)
|
|
464
|
+
*
|
|
465
|
+
* @param localTools - Map of tool names to async functions that execute the tool logic
|
|
466
|
+
* @returns The final result of the flow execution
|
|
467
|
+
*/
|
|
468
|
+
async runWithLocalTools(localTools, callbacks) {
|
|
469
|
+
const config = this.build();
|
|
470
|
+
const isStreaming = !!callbacks;
|
|
471
|
+
// Force options
|
|
472
|
+
config.options = {
|
|
473
|
+
...config.options,
|
|
474
|
+
streamResponse: isStreaming,
|
|
475
|
+
};
|
|
476
|
+
// Add stream_response snake_case too just in case
|
|
477
|
+
if (config.options) {
|
|
478
|
+
config.options.stream_response = isStreaming;
|
|
479
|
+
}
|
|
480
|
+
const client = this.getClient();
|
|
481
|
+
// Accumulated results across pause/resume cycles - moved outside processStep
|
|
482
|
+
// so results persist when flow pauses and resumes
|
|
483
|
+
const accumulatedSummary = {
|
|
484
|
+
results: new Map(),
|
|
485
|
+
success: true
|
|
486
|
+
};
|
|
487
|
+
// Helper to process a step result (either from stream or JSON)
|
|
488
|
+
const processStep = async (response) => {
|
|
489
|
+
if (isStreaming) {
|
|
490
|
+
// Stream processing
|
|
491
|
+
let pausedState = null;
|
|
492
|
+
// Wrap user callbacks to intercept paused event
|
|
493
|
+
const wrappedCallbacks = {
|
|
494
|
+
...callbacks,
|
|
495
|
+
onFlowStart: (event) => callbacks?.onFlowStart?.(event),
|
|
496
|
+
onStepStart: (event) => callbacks?.onStepStart?.(event),
|
|
497
|
+
onStepChunk: (chunk, event) => callbacks?.onStepChunk?.(chunk, event),
|
|
498
|
+
onStepComplete: (result, event) => callbacks?.onStepComplete?.(result, event),
|
|
499
|
+
onFlowComplete: (event) => callbacks?.onFlowComplete?.(event),
|
|
500
|
+
onError: (error) => callbacks?.onError?.(error)
|
|
501
|
+
};
|
|
502
|
+
// Use streamEvents from stream-utils
|
|
503
|
+
const { streamEvents } = await Promise.resolve().then(() => __importStar(require('./stream-utils')));
|
|
504
|
+
try {
|
|
505
|
+
for await (const event of streamEvents(response)) {
|
|
506
|
+
// Check for flow_paused
|
|
507
|
+
if (event.type === 'flow_paused') {
|
|
508
|
+
pausedState = {
|
|
509
|
+
toolName: event.toolName,
|
|
510
|
+
parameters: event.parameters,
|
|
511
|
+
executionId: event.executionId
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
if (event.type === 'step_waiting_local') {
|
|
515
|
+
pausedState = {
|
|
516
|
+
toolName: event.toolName,
|
|
517
|
+
parameters: event.parameters,
|
|
518
|
+
executionId: event.executionId
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
// Handle standard events via callbacks
|
|
522
|
+
switch (event.type) {
|
|
523
|
+
case 'flow_start':
|
|
524
|
+
wrappedCallbacks.onFlowStart?.(event);
|
|
525
|
+
break;
|
|
526
|
+
case 'step_start':
|
|
527
|
+
wrappedCallbacks.onStepStart?.(event);
|
|
528
|
+
break;
|
|
529
|
+
case 'step_chunk': {
|
|
530
|
+
// Normalize API's 'text' field to 'chunk' for consistency
|
|
531
|
+
const chunkText = event.chunk || event.text || '';
|
|
532
|
+
wrappedCallbacks.onStepChunk?.(chunkText, event);
|
|
533
|
+
break;
|
|
534
|
+
}
|
|
535
|
+
case 'step_complete':
|
|
536
|
+
// Accumulate results in the outer summary that persists across pause/resume
|
|
537
|
+
accumulatedSummary.results?.set(event.name, event.result);
|
|
538
|
+
wrappedCallbacks.onStepComplete?.(event.result, event);
|
|
539
|
+
break;
|
|
540
|
+
case 'flow_complete':
|
|
541
|
+
wrappedCallbacks.onFlowComplete?.(event);
|
|
542
|
+
break;
|
|
543
|
+
case 'flow_error':
|
|
544
|
+
wrappedCallbacks.onError?.(new Error(event.error));
|
|
545
|
+
break;
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
catch (e) {
|
|
550
|
+
wrappedCallbacks.onError?.(e instanceof Error ? e : new Error(String(e)));
|
|
551
|
+
throw e;
|
|
552
|
+
}
|
|
553
|
+
if (pausedState) {
|
|
554
|
+
return { done: false, result: { status: 'paused', pausedReason: { type: 'local_action', ...pausedState } } };
|
|
555
|
+
}
|
|
556
|
+
return { done: true, result: accumulatedSummary };
|
|
557
|
+
}
|
|
558
|
+
else {
|
|
559
|
+
// Non-streaming (JSON)
|
|
560
|
+
const data = await response.json();
|
|
561
|
+
return {
|
|
562
|
+
done: data.status !== 'paused',
|
|
563
|
+
result: data
|
|
564
|
+
};
|
|
565
|
+
}
|
|
566
|
+
};
|
|
567
|
+
// Initial dispatch
|
|
568
|
+
let currentResponse;
|
|
569
|
+
if (isStreaming) {
|
|
570
|
+
currentResponse = await client.dispatch(config);
|
|
571
|
+
}
|
|
572
|
+
else {
|
|
573
|
+
const data = await client.post('/dispatch', config);
|
|
574
|
+
currentResponse = new Response(JSON.stringify(data), { headers: { 'content-type': 'application/json' } });
|
|
575
|
+
}
|
|
576
|
+
// Loop
|
|
577
|
+
while (true) {
|
|
578
|
+
const { done, result } = await processStep(currentResponse);
|
|
579
|
+
if (done) {
|
|
580
|
+
if (isStreaming) {
|
|
581
|
+
// Create FlowResult with summary
|
|
582
|
+
const finalResponse = new Response(JSON.stringify(result), { headers: { 'content-type': 'application/json' } });
|
|
583
|
+
return new flow_result_1.FlowResult(finalResponse, result);
|
|
584
|
+
}
|
|
585
|
+
return new flow_result_1.FlowResult(new Response(JSON.stringify(result), { headers: { 'content-type': 'application/json' } }));
|
|
586
|
+
}
|
|
587
|
+
// Handle Pause
|
|
588
|
+
if (result.status === 'paused' && result.pausedReason?.type === 'local_action') {
|
|
589
|
+
const { toolName, parameters, executionId } = result.pausedReason;
|
|
590
|
+
if (!localTools[toolName]) {
|
|
591
|
+
throw new Error(`Local tool "${toolName}" required but not provided in localTools map`);
|
|
592
|
+
}
|
|
593
|
+
try {
|
|
594
|
+
// Execute local tool logic
|
|
595
|
+
const toolResult = await localTools[toolName](parameters);
|
|
596
|
+
// Resume flow execution - API expects snake_case field names
|
|
597
|
+
const resumeData = {
|
|
598
|
+
execution_id: executionId,
|
|
599
|
+
tool_outputs: { [toolName]: toolResult },
|
|
600
|
+
stream_response: isStreaming
|
|
601
|
+
};
|
|
602
|
+
if (isStreaming) {
|
|
603
|
+
currentResponse = await client.requestStream('/dispatch/resume', {
|
|
604
|
+
method: 'POST',
|
|
605
|
+
body: JSON.stringify(resumeData)
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
else {
|
|
609
|
+
const data = await client.post('/dispatch/resume', resumeData);
|
|
610
|
+
currentResponse = new Response(JSON.stringify(data), { headers: { 'content-type': 'application/json' } });
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
catch (error) {
|
|
614
|
+
throw new Error(`Error executing local tool "${toolName}": ${error instanceof Error ? error.message : String(error)}`);
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
else {
|
|
618
|
+
break;
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
throw new Error('Unexpected end of flow execution loop');
|
|
622
|
+
}
|
|
623
|
+
build() {
|
|
624
|
+
const flowMode = this.mode === 'existing' ? 'existing' : this.mode;
|
|
625
|
+
const flow = this.existingFlowId
|
|
626
|
+
? { id: this.existingFlowId }
|
|
627
|
+
: { name: this.flowConfig.name, steps: this.steps };
|
|
628
|
+
const request = { flow };
|
|
629
|
+
if (this.recordConfig) {
|
|
630
|
+
request.record = this.recordConfig;
|
|
631
|
+
}
|
|
632
|
+
if (this.messagesConfig) {
|
|
633
|
+
request.messages = this.messagesConfig;
|
|
634
|
+
}
|
|
635
|
+
const options = {
|
|
636
|
+
flowMode,
|
|
637
|
+
...this.dispatchOptions,
|
|
638
|
+
};
|
|
639
|
+
// Auto-detect recordMode based on record config if not explicitly set
|
|
640
|
+
if (this.recordConfig && !this.dispatchOptions.recordMode) {
|
|
641
|
+
if (this.recordConfig.id) {
|
|
642
|
+
options.recordMode = 'existing';
|
|
643
|
+
}
|
|
644
|
+
else if (this.recordConfig.name || this.recordConfig.type) {
|
|
645
|
+
options.recordMode = 'create';
|
|
646
|
+
}
|
|
647
|
+
else {
|
|
648
|
+
options.recordMode = 'virtual';
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
if (this.mode === 'upsert' && Object.keys(this.upsertOptions).length > 0) {
|
|
652
|
+
options.upsertOptions = this.upsertOptions;
|
|
653
|
+
}
|
|
654
|
+
request.options = options;
|
|
655
|
+
return request;
|
|
656
|
+
}
|
|
657
|
+
// ============================================================================
|
|
658
|
+
// Private Helpers
|
|
659
|
+
// ============================================================================
|
|
660
|
+
addStep(type, name, config, enabled = true) {
|
|
661
|
+
this.stepCounter++;
|
|
662
|
+
const cleanConfig = {};
|
|
663
|
+
for (const [key, value] of Object.entries(config)) {
|
|
664
|
+
if (value !== undefined) {
|
|
665
|
+
cleanConfig[key] = value;
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
this.steps.push({
|
|
669
|
+
id: `step-${this.stepCounter}`,
|
|
670
|
+
type,
|
|
671
|
+
name,
|
|
672
|
+
order: this.stepCounter,
|
|
673
|
+
enabled,
|
|
674
|
+
config: cleanConfig,
|
|
675
|
+
});
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
exports.RuntypeFlowBuilder = RuntypeFlowBuilder;
|
|
679
|
+
//# sourceMappingURL=flows-namespace.js.map
|