llmz 0.0.12 → 0.0.14
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/CLAUDE.md +363 -0
- package/README.md +61 -34
- package/dist/abort-signal.d.ts +40 -0
- package/dist/chat.d.ts +325 -0
- package/dist/{chunk-PRVFVXT4.js → chunk-2Z5SFF6R.js} +302 -2
- package/dist/{chunk-HJKOSEH2.cjs → chunk-GOJY4GRL.cjs} +307 -7
- package/dist/chunk-KG7DT7WD.cjs +476 -0
- package/dist/chunk-OKTHMXRT.js +476 -0
- package/dist/chunk-WL7ZIMYD.cjs +231 -0
- package/dist/chunk-XAN7HQP5.js +231 -0
- package/dist/context.d.ts +212 -0
- package/dist/{exit-YORW76T3.js → exit-7HDRH27N.js} +1 -1
- package/dist/{exit-TRXEU4OU.cjs → exit-O2WZUEFS.cjs} +2 -2
- package/dist/exit.d.ts +333 -0
- package/dist/index.cjs +206 -9
- package/dist/index.d.ts +62 -0
- package/dist/index.js +204 -7
- package/dist/{llmz-ROOX7RYI.js → llmz-MCHRHRTD.js} +109 -35
- package/dist/{llmz-QLZBDG2Z.cjs → llmz-TR4CQK4F.cjs} +116 -42
- package/dist/llmz.d.ts +142 -5
- package/dist/objects.d.ts +314 -0
- package/dist/result.d.ts +430 -0
- package/dist/snapshots.d.ts +169 -0
- package/dist/{tool-N6ODRRGH.js → tool-4AJIJ3QB.js} +1 -1
- package/dist/{tool-QP4MVRWI.cjs → tool-NS7EGK7Z.cjs} +2 -2
- package/dist/tool.d.ts +441 -0
- package/docs/TODO.md +919 -0
- package/package.json +5 -5
- package/dist/chunk-C6WNNTEV.cjs +0 -212
- package/dist/chunk-GWFYZDUR.cjs +0 -105
- package/dist/chunk-JAGB2AOU.js +0 -212
- package/dist/chunk-JMSZKB4T.js +0 -105
package/dist/result.d.ts
CHANGED
|
@@ -2,32 +2,462 @@ import { Context, Iteration } from './context.js';
|
|
|
2
2
|
import { SnapshotSignal } from './errors.js';
|
|
3
3
|
import { Exit, ExitResult } from './exit.js';
|
|
4
4
|
import { Snapshot } from './snapshots.js';
|
|
5
|
+
/**
|
|
6
|
+
* Base class for all execution results returned by the `execute()` function.
|
|
7
|
+
*
|
|
8
|
+
* ExecutionResult provides a type-safe way to handle the different outcomes of LLMz
|
|
9
|
+
* agent execution. All results contain the execution context and provide methods
|
|
10
|
+
* to check the final status and access relevant data.
|
|
11
|
+
*
|
|
12
|
+
* ## Result Types
|
|
13
|
+
*
|
|
14
|
+
* LLMz execution can result in three different outcomes:
|
|
15
|
+
* - **Success**: Agent completed with an Exit (SuccessExecutionResult)
|
|
16
|
+
* - **Error**: Execution failed with an unrecoverable error (ErrorExecutionResult)
|
|
17
|
+
* - **Interrupted**: Execution was paused for snapshots or cancellation (PartialExecutionResult)
|
|
18
|
+
*
|
|
19
|
+
* ## Usage Patterns
|
|
20
|
+
*
|
|
21
|
+
* ### Basic Status Checking
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const result = await execute({
|
|
24
|
+
* instructions: 'Calculate the sum of numbers 1 to 100',
|
|
25
|
+
* client,
|
|
26
|
+
* })
|
|
27
|
+
*
|
|
28
|
+
* if (result.isSuccess()) {
|
|
29
|
+
* console.log('Success:', result.output)
|
|
30
|
+
* } else if (result.isError()) {
|
|
31
|
+
* console.error('Error:', result.error)
|
|
32
|
+
* } else if (result.isInterrupted()) {
|
|
33
|
+
* console.log('Interrupted - snapshot available:', !!result.snapshot)
|
|
34
|
+
* }
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* ### Type-Safe Exit Checking
|
|
38
|
+
* ```typescript
|
|
39
|
+
* const dataExit = new Exit({
|
|
40
|
+
* name: 'dataProcessed',
|
|
41
|
+
* schema: z.object({
|
|
42
|
+
* recordCount: z.number(),
|
|
43
|
+
* processingTime: z.number(),
|
|
44
|
+
* }),
|
|
45
|
+
* })
|
|
46
|
+
*
|
|
47
|
+
* const result = await execute({
|
|
48
|
+
* instructions: 'Process the data',
|
|
49
|
+
* exits: [dataExit],
|
|
50
|
+
* client,
|
|
51
|
+
* })
|
|
52
|
+
*
|
|
53
|
+
* // Type-safe exit checking with typed output access
|
|
54
|
+
* if (result.is(dataExit)) {
|
|
55
|
+
* console.log(`Processed ${result.output.recordCount} records`)
|
|
56
|
+
* console.log(`Processing took ${result.output.processingTime}ms`)
|
|
57
|
+
* }
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* ### Accessing Execution Details
|
|
61
|
+
* ```typescript
|
|
62
|
+
* if (result.isSuccess()) {
|
|
63
|
+
* // Access the generated code from the final iteration
|
|
64
|
+
* console.log('Generated code:', result.iteration.code)
|
|
65
|
+
*
|
|
66
|
+
* // Access all iterations to see the full execution flow
|
|
67
|
+
* result.iterations.forEach((iteration, index) => {
|
|
68
|
+
* console.log(`Iteration ${index + 1}:`, iteration.status.type)
|
|
69
|
+
* })
|
|
70
|
+
*
|
|
71
|
+
* // Access execution context
|
|
72
|
+
* console.log('Original instructions:', result.context.instructions)
|
|
73
|
+
* }
|
|
74
|
+
* ```
|
|
75
|
+
*
|
|
76
|
+
* ### Snapshot Handling
|
|
77
|
+
* ```typescript
|
|
78
|
+
* if (result.isInterrupted()) {
|
|
79
|
+
* // Serialize snapshot for persistence
|
|
80
|
+
* const serialized = result.snapshot.toJSON()
|
|
81
|
+
* await database.saveSnapshot(serialized)
|
|
82
|
+
*
|
|
83
|
+
* // Later, resume from snapshot
|
|
84
|
+
* const snapshot = Snapshot.fromJSON(serialized)
|
|
85
|
+
* snapshot.resolve({ data: 'resolved data' })
|
|
86
|
+
*
|
|
87
|
+
* const continuation = await execute({
|
|
88
|
+
* snapshot,
|
|
89
|
+
* instructions: result.context.instructions,
|
|
90
|
+
* tools: result.context.tools,
|
|
91
|
+
* exits: result.context.exits,
|
|
92
|
+
* client,
|
|
93
|
+
* })
|
|
94
|
+
* }
|
|
95
|
+
* ```
|
|
96
|
+
*
|
|
97
|
+
* @see {@link SuccessExecutionResult} For successful execution results
|
|
98
|
+
* @see {@link ErrorExecutionResult} For failed execution results
|
|
99
|
+
* @see {@link PartialExecutionResult} For interrupted execution results
|
|
100
|
+
*/
|
|
5
101
|
export declare abstract class ExecutionResult {
|
|
6
102
|
readonly status: 'success' | 'error' | 'interrupted';
|
|
7
103
|
readonly context: Context;
|
|
8
104
|
protected constructor(status: 'success' | 'error' | 'interrupted', context: Context);
|
|
105
|
+
/**
|
|
106
|
+
* Type guard to check if the execution completed successfully.
|
|
107
|
+
*
|
|
108
|
+
* @returns True if the execution completed with an Exit, false otherwise
|
|
109
|
+
* @example
|
|
110
|
+
* ```typescript
|
|
111
|
+
* const result = await execute({ ... })
|
|
112
|
+
*
|
|
113
|
+
* if (result.isSuccess()) {
|
|
114
|
+
* // TypeScript knows this is SuccessExecutionResult
|
|
115
|
+
* console.log('Output:', result.output)
|
|
116
|
+
* console.log('Exit name:', result.result.exit.name)
|
|
117
|
+
* }
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
9
120
|
isSuccess(): this is SuccessExecutionResult;
|
|
121
|
+
/**
|
|
122
|
+
* Type guard to check if the execution failed with an error.
|
|
123
|
+
*
|
|
124
|
+
* @returns True if the execution failed with an unrecoverable error, false otherwise
|
|
125
|
+
* @example
|
|
126
|
+
* ```typescript
|
|
127
|
+
* const result = await execute({ ... })
|
|
128
|
+
*
|
|
129
|
+
* if (result.isError()) {
|
|
130
|
+
* // TypeScript knows this is ErrorExecutionResult
|
|
131
|
+
* console.error('Execution failed:', result.error)
|
|
132
|
+
*
|
|
133
|
+
* // Access error details from the last iteration
|
|
134
|
+
* const lastIteration = result.iteration
|
|
135
|
+
* if (lastIteration?.status.type === 'execution_error') {
|
|
136
|
+
* console.error('Stack trace:', lastIteration.status.execution_error.stack)
|
|
137
|
+
* }
|
|
138
|
+
* }
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
10
141
|
isError(): this is ErrorExecutionResult;
|
|
142
|
+
/**
|
|
143
|
+
* Type guard to check if the execution was interrupted.
|
|
144
|
+
* Interrupted means there's a snapshot available and the execution was paused and needs resuming.
|
|
145
|
+
*
|
|
146
|
+
* @returns True if the execution was interrupted, false otherwise
|
|
147
|
+
* @example
|
|
148
|
+
* ```typescript
|
|
149
|
+
* const result = await execute({ ... })
|
|
150
|
+
*
|
|
151
|
+
* if (result.isInterrupted()) {
|
|
152
|
+
* // TypeScript knows this is PartialExecutionResult
|
|
153
|
+
* console.log('Execution paused:', result.signal.message)
|
|
154
|
+
*
|
|
155
|
+
* // Access snapshot for later resumption
|
|
156
|
+
* const snapshot = result.snapshot
|
|
157
|
+
* const serialized = snapshot.toJSON()
|
|
158
|
+
* await storage.save('execution-state', serialized)
|
|
159
|
+
* }
|
|
160
|
+
* ```
|
|
161
|
+
*/
|
|
11
162
|
isInterrupted(): this is PartialExecutionResult;
|
|
163
|
+
/**
|
|
164
|
+
* Type guard to check if the execution completed with a specific exit.
|
|
165
|
+
*
|
|
166
|
+
* This method provides type-safe access to the output data based on the exit's schema.
|
|
167
|
+
* It's the recommended way to handle different exit types in complex agents.
|
|
168
|
+
*
|
|
169
|
+
* @param exit - The Exit instance to check against
|
|
170
|
+
* @returns True if the execution completed with the specified exit, false otherwise
|
|
171
|
+
* @template T - The output type of the exit
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* ```typescript
|
|
175
|
+
* // Define typed exits
|
|
176
|
+
* const successExit = new Exit({
|
|
177
|
+
* name: 'success',
|
|
178
|
+
* schema: z.object({
|
|
179
|
+
* message: z.string(),
|
|
180
|
+
* count: z.number(),
|
|
181
|
+
* }),
|
|
182
|
+
* })
|
|
183
|
+
*
|
|
184
|
+
* const errorExit = new Exit({
|
|
185
|
+
* name: 'error',
|
|
186
|
+
* schema: z.object({
|
|
187
|
+
* errorCode: z.string(),
|
|
188
|
+
* details: z.string(),
|
|
189
|
+
* }),
|
|
190
|
+
* })
|
|
191
|
+
*
|
|
192
|
+
* const result = await execute({
|
|
193
|
+
* instructions: 'Process the data',
|
|
194
|
+
* exits: [successExit, errorExit],
|
|
195
|
+
* client,
|
|
196
|
+
* })
|
|
197
|
+
*
|
|
198
|
+
* // Type-safe exit handling
|
|
199
|
+
* if (result.is(successExit)) {
|
|
200
|
+
* // TypeScript knows result.output has { message: string, count: number }
|
|
201
|
+
* console.log(`Success: ${result.output.message}`)
|
|
202
|
+
* console.log(`Processed ${result.output.count} items`)
|
|
203
|
+
* } else if (result.is(errorExit)) {
|
|
204
|
+
* // TypeScript knows result.output has { errorCode: string, details: string }
|
|
205
|
+
* console.error(`Error ${result.output.errorCode}: ${result.output.details}`)
|
|
206
|
+
* }
|
|
207
|
+
* ```
|
|
208
|
+
*/
|
|
12
209
|
is<T>(exit: Exit<T>): this is SuccessExecutionResult<T>;
|
|
210
|
+
/**
|
|
211
|
+
* Gets the output data from the last successful iteration.
|
|
212
|
+
*
|
|
213
|
+
* For successful executions, returns the data produced by the exit.
|
|
214
|
+
* For failed or interrupted executions, returns null.
|
|
215
|
+
*
|
|
216
|
+
* @returns The output data for successful executions, null otherwise
|
|
217
|
+
* @example
|
|
218
|
+
* ```typescript
|
|
219
|
+
* const result = await execute({ ... })
|
|
220
|
+
*
|
|
221
|
+
* // Generic output access
|
|
222
|
+
* if (result.isSuccess()) {
|
|
223
|
+
* console.log('Output:', result.output)
|
|
224
|
+
* }
|
|
225
|
+
*
|
|
226
|
+
* // Type-safe output access with specific exits
|
|
227
|
+
* if (result.is(myExit)) {
|
|
228
|
+
* // result.output is now typed based on myExit's schema
|
|
229
|
+
* console.log(result.output.specificField)
|
|
230
|
+
* }
|
|
231
|
+
* ```
|
|
232
|
+
*/
|
|
13
233
|
get output(): unknown | null;
|
|
234
|
+
/**
|
|
235
|
+
* Gets the most recent (last) iteration from the execution.
|
|
236
|
+
*
|
|
237
|
+
* Iterations represent individual steps in the execution loop where the LLM
|
|
238
|
+
* generates code, executes it, and processes the results. The last iteration
|
|
239
|
+
* contains the final generated code and execution status.
|
|
240
|
+
*
|
|
241
|
+
* @returns The last iteration, or null if no iterations were completed
|
|
242
|
+
* @example
|
|
243
|
+
* ```typescript
|
|
244
|
+
* const result = await execute({ ... })
|
|
245
|
+
*
|
|
246
|
+
* const lastIteration = result.iteration
|
|
247
|
+
* if (lastIteration) {
|
|
248
|
+
* console.log('Generated code:', lastIteration.code)
|
|
249
|
+
* console.log('Status:', lastIteration.status.type)
|
|
250
|
+
* console.log('Variables:', lastIteration.variables)
|
|
251
|
+
* console.log('Tool calls:', lastIteration.toolCalls)
|
|
252
|
+
* }
|
|
253
|
+
* ```
|
|
254
|
+
*/
|
|
14
255
|
get iteration(): Iteration | null;
|
|
256
|
+
/**
|
|
257
|
+
* Gets all iterations from the execution.
|
|
258
|
+
*
|
|
259
|
+
* This provides access to the complete execution history, showing how the agent
|
|
260
|
+
* progressed through multiple iterations to reach the final result. Useful for
|
|
261
|
+
* debugging, logging, or understanding the agent's reasoning process.
|
|
262
|
+
*
|
|
263
|
+
* @returns Array of all iterations in execution order
|
|
264
|
+
* @example
|
|
265
|
+
* ```typescript
|
|
266
|
+
* const result = await execute({ ... })
|
|
267
|
+
*
|
|
268
|
+
* // Analyze the full execution flow
|
|
269
|
+
* result.iterations.forEach((iteration, index) => {
|
|
270
|
+
* console.log(`Iteration ${index + 1}:`)
|
|
271
|
+
* console.log(' Status:', iteration.status.type)
|
|
272
|
+
* console.log(' Code length:', iteration.code?.length || 0)
|
|
273
|
+
* console.log(' Tool calls:', iteration.toolCalls.length)
|
|
274
|
+
* console.log(' Variables:', Object.keys(iteration.variables).length)
|
|
275
|
+
* })
|
|
276
|
+
*
|
|
277
|
+
* // Find iterations with specific characteristics
|
|
278
|
+
* const iterationsWithErrors = result.iterations.filter(
|
|
279
|
+
* iter => iter.status.type === 'execution_error'
|
|
280
|
+
* )
|
|
281
|
+
*
|
|
282
|
+
* // Calculate total execution time
|
|
283
|
+
* const totalTime = result.iterations.reduce(
|
|
284
|
+
* (sum, iter) => sum + (iter.duration || 0), 0
|
|
285
|
+
* )
|
|
286
|
+
* ```
|
|
287
|
+
*/
|
|
15
288
|
get iterations(): Iteration[];
|
|
16
289
|
}
|
|
290
|
+
/**
|
|
291
|
+
* Result for successful executions that completed with an Exit.
|
|
292
|
+
*
|
|
293
|
+
* SuccessExecutionResult indicates that the agent successfully completed its task
|
|
294
|
+
* and returned structured data through one of the provided exits. This is the
|
|
295
|
+
* most common positive outcome for LLMz executions.
|
|
296
|
+
*
|
|
297
|
+
* In *Worker Mode* (ie. no `chat` provided), if no exits were provided, the "DefaultExit" will be used.
|
|
298
|
+
* If *Chat Mode* is enabled, most likely the "ListenExit" will be used if no exits were provided.
|
|
299
|
+
*
|
|
300
|
+
* You can check for a specific exit using the `is()` method, which provides type-safe access to the output data of the exit.
|
|
301
|
+
* You can import "ListenExit" and "DefaultExit" from `llmz`.
|
|
302
|
+
*
|
|
303
|
+
* @template TOutput - The type of the output data based on the exit schema
|
|
304
|
+
*
|
|
305
|
+
* @example
|
|
306
|
+
* ```typescript
|
|
307
|
+
* import { execute, Exit, DefaultExit, ListenExit } from 'llmz'
|
|
308
|
+
*
|
|
309
|
+
* const exit = new Exit({
|
|
310
|
+
* name: 'dataProcessed',
|
|
311
|
+
* schema: z.object({
|
|
312
|
+
* recordCount: z.number(),
|
|
313
|
+
* summary: z.string(),
|
|
314
|
+
* }),
|
|
315
|
+
* })
|
|
316
|
+
*
|
|
317
|
+
* const result = await execute({
|
|
318
|
+
* instructions: 'Process the user data',
|
|
319
|
+
* exits: [exit],
|
|
320
|
+
* client,
|
|
321
|
+
* })
|
|
322
|
+
*
|
|
323
|
+
* if (result.isSuccess() && result.is(exit)) {
|
|
324
|
+
* // Access the exit information
|
|
325
|
+
* console.log('Exit name:', result.result.exit.name)
|
|
326
|
+
*
|
|
327
|
+
* // Access typed output data
|
|
328
|
+
* console.log('Records processed:', result.output.recordCount)
|
|
329
|
+
* console.log('Summary:', result.output.summary)
|
|
330
|
+
*
|
|
331
|
+
* // Access the final iteration (guaranteed to exist)
|
|
332
|
+
* console.log('Generated code:', result.iteration.code)
|
|
333
|
+
* }
|
|
334
|
+
* ```
|
|
335
|
+
*/
|
|
17
336
|
export declare class SuccessExecutionResult<TOutput = unknown> extends ExecutionResult {
|
|
18
337
|
readonly result: ExitResult<TOutput>;
|
|
19
338
|
constructor(context: Context, result: ExitResult<TOutput>);
|
|
339
|
+
/**
|
|
340
|
+
* Gets the typed output data from the successful execution.
|
|
341
|
+
*
|
|
342
|
+
* This overrides the base class output property to provide proper typing
|
|
343
|
+
* based on the exit schema. The output is guaranteed to match the schema
|
|
344
|
+
* of the exit that was triggered.
|
|
345
|
+
*
|
|
346
|
+
* @returns The typed output data
|
|
347
|
+
*/
|
|
20
348
|
get output(): TOutput;
|
|
349
|
+
/**
|
|
350
|
+
* Gets the final iteration from the successful execution.
|
|
351
|
+
*
|
|
352
|
+
* For successful executions, there is always at least one iteration,
|
|
353
|
+
* so this method returns the guaranteed non-null final iteration.
|
|
354
|
+
*
|
|
355
|
+
* @returns The final iteration (guaranteed to exist)
|
|
356
|
+
*/
|
|
21
357
|
get iteration(): Iteration;
|
|
22
358
|
}
|
|
359
|
+
/**
|
|
360
|
+
* Result for executions that failed with an unrecoverable error.
|
|
361
|
+
*
|
|
362
|
+
* ErrorExecutionResult indicates that the execution encountered an error that could not be recovered from, such as:
|
|
363
|
+
* - Execution has been aborted by the user (eg. via the `signal` AbortSignal parameter)
|
|
364
|
+
* - Iterations exceeded the maximum allowed limit
|
|
365
|
+
*
|
|
366
|
+
* Upon iteration failure, the execution will continue until the maximum iteration limit is reached or an exit is triggered.
|
|
367
|
+
*
|
|
368
|
+
* @example
|
|
369
|
+
* ```typescript
|
|
370
|
+
* const result = await execute({
|
|
371
|
+
* instructions: 'Call a non-existent function',
|
|
372
|
+
* client,
|
|
373
|
+
* })
|
|
374
|
+
*
|
|
375
|
+
* if (result.isError()) {
|
|
376
|
+
* console.error('Execution failed:', result.error)
|
|
377
|
+
*
|
|
378
|
+
* // Access error details from the last iteration
|
|
379
|
+
* const lastIteration = result.iteration
|
|
380
|
+
* if (lastIteration?.status.type === 'execution_error') {
|
|
381
|
+
* console.error('Error type:', lastIteration.status.execution_error.type)
|
|
382
|
+
* console.error('Stack trace:', lastIteration.status.execution_error.stack)
|
|
383
|
+
* console.error('Generated code:', lastIteration.code)
|
|
384
|
+
* }
|
|
385
|
+
*
|
|
386
|
+
* // Access all iterations to understand the failure progression
|
|
387
|
+
* console.log('Total iterations before failure:', result.iterations.length)
|
|
388
|
+
* }
|
|
389
|
+
* ```
|
|
390
|
+
*/
|
|
23
391
|
export declare class ErrorExecutionResult extends ExecutionResult {
|
|
24
392
|
readonly error: unknown;
|
|
25
393
|
constructor(context: Context, error: unknown);
|
|
394
|
+
/**
|
|
395
|
+
* Gets the output data (always null for error results).
|
|
396
|
+
*
|
|
397
|
+
* @returns Always null since error executions don't produce output
|
|
398
|
+
*/
|
|
26
399
|
get output(): null;
|
|
27
400
|
}
|
|
401
|
+
/**
|
|
402
|
+
* Result for executions that were interrupted before completion.
|
|
403
|
+
*
|
|
404
|
+
* PartialExecutionResult indicates that a snapshot was created during the execution.
|
|
405
|
+
* Interrupted executions can be resumed using the provided snapshot.
|
|
406
|
+
*
|
|
407
|
+
* @example
|
|
408
|
+
* ```typescript
|
|
409
|
+
* // Tool that throws SnapshotSignal for long-running operations
|
|
410
|
+
* const longRunningTool = new Tool({
|
|
411
|
+
* name: 'processLargeDataset',
|
|
412
|
+
* async handler({ datasetId }) {
|
|
413
|
+
* // Start background processing
|
|
414
|
+
* const jobId = await startBackgroundJob(datasetId)
|
|
415
|
+
*
|
|
416
|
+
* // Pause execution until job completes
|
|
417
|
+
* throw new SnapshotSignal('Processing dataset', 'Waiting for background job completion', {
|
|
418
|
+
* jobId,
|
|
419
|
+
* datasetId,
|
|
420
|
+
* startTime: Date.now(),
|
|
421
|
+
* })
|
|
422
|
+
* },
|
|
423
|
+
* })
|
|
424
|
+
*
|
|
425
|
+
* const result = await execute({
|
|
426
|
+
* instructions: 'Process the large dataset',
|
|
427
|
+
* tools: [longRunningTool],
|
|
428
|
+
* client,
|
|
429
|
+
* })
|
|
430
|
+
*
|
|
431
|
+
* if (result.isInterrupted()) {
|
|
432
|
+
* console.log('Execution paused:', result.signal.message)
|
|
433
|
+
* console.log('Reason:', result.signal.longMessage)
|
|
434
|
+
*
|
|
435
|
+
* // Serialize snapshot for later resumption
|
|
436
|
+
* const serialized = result.snapshot.toJSON()
|
|
437
|
+
* await database.saveSnapshot('job-123', serialized)
|
|
438
|
+
*
|
|
439
|
+
* // Later, when the background job completes...
|
|
440
|
+
* const snapshot = Snapshot.fromJSON(serialized)
|
|
441
|
+
* snapshot.resolve({ jobResult: 'Processing completed successfully' })
|
|
442
|
+
*
|
|
443
|
+
* const continuation = await execute({
|
|
444
|
+
* snapshot,
|
|
445
|
+
* instructions: result.context.instructions,
|
|
446
|
+
* tools: result.context.tools,
|
|
447
|
+
* exits: result.context.exits,
|
|
448
|
+
* client,
|
|
449
|
+
* })
|
|
450
|
+
* }
|
|
451
|
+
* ```
|
|
452
|
+
*/
|
|
28
453
|
export declare class PartialExecutionResult extends ExecutionResult {
|
|
29
454
|
readonly signal: SnapshotSignal;
|
|
30
455
|
readonly snapshot: Snapshot;
|
|
31
456
|
constructor(context: Context, signal: SnapshotSignal, snapshot: Snapshot);
|
|
457
|
+
/**
|
|
458
|
+
* Gets the output data (always null for interrupted results).
|
|
459
|
+
*
|
|
460
|
+
* @returns Always null since interrupted executions don't produce final output
|
|
461
|
+
*/
|
|
32
462
|
get output(): null;
|
|
33
463
|
}
|
package/dist/snapshots.d.ts
CHANGED
|
@@ -27,6 +27,79 @@ export declare namespace SnapshotStatuses {
|
|
|
27
27
|
error: unknown;
|
|
28
28
|
};
|
|
29
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Snapshot represents a captured execution state that can be persisted and restored later.
|
|
32
|
+
*
|
|
33
|
+
* Snapshots are created when a SnapshotSignal is thrown during execution, typically from
|
|
34
|
+
* within a tool handler to pause execution for long-running operations that need to be
|
|
35
|
+
* completed asynchronously (e.g., background jobs, external API calls, user input).
|
|
36
|
+
*
|
|
37
|
+
* ## Use Cases
|
|
38
|
+
* - **Long-running operations**: Pause execution while waiting for external processes
|
|
39
|
+
* - **User interaction**: Collect input from users before continuing execution
|
|
40
|
+
* - **Resource management**: Defer expensive operations to background workers
|
|
41
|
+
* - **Workflow persistence**: Save execution state across process restarts
|
|
42
|
+
*
|
|
43
|
+
* ## Basic Usage
|
|
44
|
+
*
|
|
45
|
+
* ### Creating a Snapshot
|
|
46
|
+
* From within a tool handler, throw a SnapshotSignal to create a snapshot:
|
|
47
|
+
* ```typescript
|
|
48
|
+
* const tool = new Tool({
|
|
49
|
+
* handler: async ({ input }) => {
|
|
50
|
+
* // Start long-running operation
|
|
51
|
+
* throw new SnapshotSignal('Waiting for external API response')
|
|
52
|
+
* }
|
|
53
|
+
* })
|
|
54
|
+
* ```
|
|
55
|
+
*
|
|
56
|
+
* ### Handling Interrupted Execution
|
|
57
|
+
* ```typescript
|
|
58
|
+
* const result = await execute({ tools: [tool], ... })
|
|
59
|
+
*
|
|
60
|
+
* if (result.isInterrupted()) {
|
|
61
|
+
* const snapshot = result.snapshot
|
|
62
|
+
*
|
|
63
|
+
* // Serialize for persistence
|
|
64
|
+
* const serialized = snapshot.toJSON()
|
|
65
|
+
* await database.saveSnapshot(serialized)
|
|
66
|
+
* }
|
|
67
|
+
* ```
|
|
68
|
+
*
|
|
69
|
+
* ### Resuming from Snapshot
|
|
70
|
+
* ```typescript
|
|
71
|
+
* // Restore from persistence
|
|
72
|
+
* const serialized = await database.getSnapshot(id)
|
|
73
|
+
* const snapshot = Snapshot.fromJSON(serialized)
|
|
74
|
+
*
|
|
75
|
+
* // Resolve with the result of the long-running operation
|
|
76
|
+
* snapshot.resolve({ result: 'Operation completed!' })
|
|
77
|
+
*
|
|
78
|
+
* // Continue execution
|
|
79
|
+
* const continuation = await execute({
|
|
80
|
+
* snapshot,
|
|
81
|
+
* instructions: originalInstructions,
|
|
82
|
+
* tools: originalTools,
|
|
83
|
+
* exits: originalExits,
|
|
84
|
+
* client
|
|
85
|
+
* })
|
|
86
|
+
* ```
|
|
87
|
+
*
|
|
88
|
+
* ## Snapshot Lifecycle
|
|
89
|
+
* 1. **Created**: When SnapshotSignal is thrown (status: pending)
|
|
90
|
+
* 2. **Serialized**: Convert to JSON for persistence with toJSON()
|
|
91
|
+
* 3. **Restored**: Recreate from JSON with fromJSON()
|
|
92
|
+
* 4. **Resolved/Rejected**: Provide result data with resolve() or reject()
|
|
93
|
+
* 5. **Resumed**: Continue execution with the resolved snapshot
|
|
94
|
+
*
|
|
95
|
+
* ## What's Captured
|
|
96
|
+
* - **Execution stack**: Current code position and call stack
|
|
97
|
+
* - **Variables**: All local variables and their values (up to size limit)
|
|
98
|
+
* - **Tool context**: Information about the tool call that triggered the snapshot
|
|
99
|
+
* - **Reason**: Human-readable description of why the snapshot was created
|
|
100
|
+
*
|
|
101
|
+
* @see {@link https://github.com/botpress/botpress/blob/master/packages/llmz/examples/14_worker_snapshot/index.ts} Example usage
|
|
102
|
+
*/
|
|
30
103
|
export declare class Snapshot {
|
|
31
104
|
#private;
|
|
32
105
|
readonly id: string;
|
|
@@ -34,6 +107,11 @@ export declare class Snapshot {
|
|
|
34
107
|
readonly stack: string;
|
|
35
108
|
readonly variables: Variable[];
|
|
36
109
|
readonly toolCall?: ToolCall;
|
|
110
|
+
/**
|
|
111
|
+
* Gets the current status of the snapshot.
|
|
112
|
+
*
|
|
113
|
+
* @returns The snapshot status (pending, resolved, or rejected)
|
|
114
|
+
*/
|
|
37
115
|
get status(): Readonly<{
|
|
38
116
|
type: "pending";
|
|
39
117
|
} | {
|
|
@@ -44,7 +122,32 @@ export declare class Snapshot {
|
|
|
44
122
|
error: unknown;
|
|
45
123
|
}>;
|
|
46
124
|
private constructor();
|
|
125
|
+
/**
|
|
126
|
+
* Creates a new Snapshot from a SnapshotSignal.
|
|
127
|
+
*
|
|
128
|
+
* This method is called internally by the LLMz execution engine when a SnapshotSignal
|
|
129
|
+
* is thrown during execution. It captures the current execution state including
|
|
130
|
+
* variables, stack trace, and tool context.
|
|
131
|
+
*
|
|
132
|
+
* @param signal The SnapshotSignal containing execution state
|
|
133
|
+
* @returns A new Snapshot instance in pending status
|
|
134
|
+
* @internal
|
|
135
|
+
*/
|
|
47
136
|
static fromSignal(signal: SnapshotSignal): Snapshot;
|
|
137
|
+
/**
|
|
138
|
+
* Serializes the snapshot to a JSON-compatible object for persistence.
|
|
139
|
+
*
|
|
140
|
+
* Use this method to save snapshots to databases, files, or other storage systems.
|
|
141
|
+
* The serialized snapshot can be restored later using fromJSON().
|
|
142
|
+
*
|
|
143
|
+
* @returns A JSON-serializable representation of the snapshot
|
|
144
|
+
* @example
|
|
145
|
+
* ```typescript
|
|
146
|
+
* const snapshot = result.snapshot
|
|
147
|
+
* const serialized = snapshot.toJSON()
|
|
148
|
+
* await database.save('snapshots', snapshot.id, serialized)
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
48
151
|
toJSON(): {
|
|
49
152
|
id: string;
|
|
50
153
|
reason: string | undefined;
|
|
@@ -53,6 +156,20 @@ export declare class Snapshot {
|
|
|
53
156
|
toolCall: ToolCall | undefined;
|
|
54
157
|
status: SnapshotStatus;
|
|
55
158
|
};
|
|
159
|
+
/**
|
|
160
|
+
* Restores a snapshot from its JSON representation.
|
|
161
|
+
*
|
|
162
|
+
* Use this method to recreate snapshots from persistent storage. The restored
|
|
163
|
+
* snapshot will maintain its original state and can be resolved/rejected as needed.
|
|
164
|
+
*
|
|
165
|
+
* @param json The serialized snapshot data from toJSON()
|
|
166
|
+
* @returns A restored Snapshot instance
|
|
167
|
+
* @example
|
|
168
|
+
* ```typescript
|
|
169
|
+
* const serialized = await database.get('snapshots', snapshotId)
|
|
170
|
+
* const snapshot = Snapshot.fromJSON(serialized)
|
|
171
|
+
* ```
|
|
172
|
+
*/
|
|
56
173
|
static fromJSON(json: {
|
|
57
174
|
id: string;
|
|
58
175
|
reason?: string;
|
|
@@ -61,9 +178,61 @@ export declare class Snapshot {
|
|
|
61
178
|
toolCall?: ToolCall;
|
|
62
179
|
status: SnapshotStatus;
|
|
63
180
|
}): Snapshot;
|
|
181
|
+
/**
|
|
182
|
+
* Creates a deep copy of the snapshot.
|
|
183
|
+
*
|
|
184
|
+
* @returns A new Snapshot instance with identical data
|
|
185
|
+
*/
|
|
64
186
|
clone(): Snapshot;
|
|
187
|
+
/**
|
|
188
|
+
* Resets the snapshot status back to pending.
|
|
189
|
+
*
|
|
190
|
+
* This allows a previously resolved or rejected snapshot to be resolved/rejected
|
|
191
|
+
* again with different data. Useful for retry scenarios.
|
|
192
|
+
*/
|
|
65
193
|
reset(): void;
|
|
194
|
+
/**
|
|
195
|
+
* Resolves the snapshot with a successful result value.
|
|
196
|
+
*
|
|
197
|
+
* Call this method when the long-running operation that caused the snapshot
|
|
198
|
+
* has completed successfully. The provided value will be returned as the
|
|
199
|
+
* result of the original tool call when execution resumes.
|
|
200
|
+
*
|
|
201
|
+
* @param value The result value from the completed operation
|
|
202
|
+
* @throws Error if the snapshot is not in pending status
|
|
203
|
+
* @example
|
|
204
|
+
* ```typescript
|
|
205
|
+
* // After a background job completes
|
|
206
|
+
* const result = await backgroundJob.getResult()
|
|
207
|
+
* snapshot.resolve(result)
|
|
208
|
+
*
|
|
209
|
+
* // Continue execution
|
|
210
|
+
* const continuation = await execute({ snapshot, ... })
|
|
211
|
+
* ```
|
|
212
|
+
*/
|
|
66
213
|
resolve(value: any): void;
|
|
214
|
+
/**
|
|
215
|
+
* Rejects the snapshot with an error.
|
|
216
|
+
*
|
|
217
|
+
* Call this method when the long-running operation that caused the snapshot
|
|
218
|
+
* has failed or encountered an error. The provided error will be thrown
|
|
219
|
+
* when execution resumes, allowing the generated code to handle it.
|
|
220
|
+
*
|
|
221
|
+
* @param error The error that occurred during the operation
|
|
222
|
+
* @throws Error if the snapshot is not in pending status
|
|
223
|
+
* @example
|
|
224
|
+
* ```typescript
|
|
225
|
+
* try {
|
|
226
|
+
* const result = await externalAPI.call()
|
|
227
|
+
* snapshot.resolve(result)
|
|
228
|
+
* } catch (error) {
|
|
229
|
+
* snapshot.reject(error)
|
|
230
|
+
* }
|
|
231
|
+
*
|
|
232
|
+
* // Continue execution (will throw the error)
|
|
233
|
+
* const continuation = await execute({ snapshot, ... })
|
|
234
|
+
* ```
|
|
235
|
+
*/
|
|
67
236
|
reject(error: any): void;
|
|
68
237
|
}
|
|
69
238
|
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunkKG7DT7WDcjs = require('./chunk-KG7DT7WD.cjs');
|
|
4
4
|
require('./chunk-4L6D2A6O.cjs');
|
|
5
5
|
require('./chunk-JDABP4SD.cjs');
|
|
6
6
|
require('./chunk-IKSIOIIP.cjs');
|
|
@@ -8,4 +8,4 @@ require('./chunk-276Q6EWP.cjs');
|
|
|
8
8
|
require('./chunk-UQOBUJIQ.cjs');
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
exports.Tool =
|
|
11
|
+
exports.Tool = _chunkKG7DT7WDcjs.Tool;
|