@ekairos/events 1.22.34-beta.development.0 → 1.22.35

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.
Files changed (74) hide show
  1. package/README.md +58 -83
  2. package/dist/codex.d.ts +11 -2
  3. package/dist/codex.js +16 -8
  4. package/dist/context.action-calls.d.ts +48 -0
  5. package/dist/context.action-calls.js +123 -0
  6. package/dist/context.action.d.ts +55 -0
  7. package/dist/context.action.js +25 -0
  8. package/dist/context.builder.d.ts +71 -43
  9. package/dist/context.builder.js +123 -28
  10. package/dist/context.config.d.ts +2 -1
  11. package/dist/context.config.js +8 -3
  12. package/dist/context.contract.d.ts +2 -4
  13. package/dist/context.contract.js +3 -9
  14. package/dist/context.d.ts +3 -2
  15. package/dist/context.engine.d.ts +75 -46
  16. package/dist/context.engine.js +538 -302
  17. package/dist/context.events.js +28 -87
  18. package/dist/context.js +1 -0
  19. package/dist/context.part-identity.d.ts +40 -0
  20. package/dist/context.part-identity.js +270 -0
  21. package/dist/context.parts.d.ts +389 -164
  22. package/dist/context.parts.js +343 -218
  23. package/dist/context.registry.d.ts +1 -1
  24. package/dist/context.runtime.d.ts +21 -0
  25. package/dist/context.runtime.js +39 -0
  26. package/dist/context.step-stream.d.ts +16 -2
  27. package/dist/context.step-stream.js +58 -16
  28. package/dist/context.store.d.ts +63 -10
  29. package/dist/context.stream.d.ts +14 -4
  30. package/dist/context.stream.js +31 -3
  31. package/dist/domain.d.ts +1 -0
  32. package/dist/domain.js +1 -0
  33. package/dist/index.d.ts +13 -10
  34. package/dist/index.js +7 -6
  35. package/dist/react.context-event-parts.d.ts +18 -0
  36. package/dist/react.context-event-parts.js +509 -0
  37. package/dist/react.d.ts +7 -42
  38. package/dist/react.js +4 -87
  39. package/dist/react.step-stream.d.ts +39 -0
  40. package/dist/react.step-stream.js +625 -0
  41. package/dist/react.types.d.ts +121 -0
  42. package/dist/react.types.js +2 -0
  43. package/dist/react.use-context.d.ts +7 -0
  44. package/dist/react.use-context.js +867 -0
  45. package/dist/reactors/ai-sdk.chunk-map.d.ts +1 -0
  46. package/dist/reactors/ai-sdk.chunk-map.js +56 -5
  47. package/dist/reactors/ai-sdk.reactor.d.ts +8 -5
  48. package/dist/reactors/ai-sdk.reactor.js +10 -9
  49. package/dist/reactors/ai-sdk.step.d.ts +6 -6
  50. package/dist/reactors/ai-sdk.step.js +32 -24
  51. package/dist/reactors/scripted.reactor.d.ts +7 -4
  52. package/dist/reactors/types.d.ts +23 -8
  53. package/dist/runtime.d.ts +6 -0
  54. package/dist/runtime.js +9 -0
  55. package/dist/runtime.step.js +2 -2
  56. package/dist/schema.d.ts +268 -2
  57. package/dist/schema.js +5 -9
  58. package/dist/steps/do-context-stream-step.d.ts +2 -2
  59. package/dist/steps/do-context-stream-step.js +6 -8
  60. package/dist/steps/durable.steps.d.ts +28 -0
  61. package/dist/steps/durable.steps.js +34 -0
  62. package/dist/steps/store.steps.d.ts +121 -39
  63. package/dist/steps/store.steps.js +266 -111
  64. package/dist/steps/stream.steps.d.ts +36 -3
  65. package/dist/steps/stream.steps.js +137 -14
  66. package/dist/steps/trace.steps.d.ts +4 -2
  67. package/dist/steps/trace.steps.js +26 -8
  68. package/dist/stores/instant.store.d.ts +15 -11
  69. package/dist/stores/instant.store.js +155 -6
  70. package/dist/tools-to-model-tools.d.ts +39 -3
  71. package/dist/tools-to-model-tools.js +63 -6
  72. package/package.json +20 -6
  73. package/dist/context.toolcalls.d.ts +0 -60
  74. package/dist/context.toolcalls.js +0 -117
@@ -1,5 +1,13 @@
1
1
  import { z } from "zod";
2
- const metadataSchema = z.record(z.string(), z.unknown()).optional();
2
+ export const reactorMetadataSchema = z
3
+ .object({
4
+ reactorKind: z.string().min(1),
5
+ executionId: z.string().optional(),
6
+ itemId: z.string().optional(),
7
+ eventName: z.string().optional(),
8
+ actionCallId: z.string().optional(),
9
+ })
10
+ .catchall(z.unknown());
3
11
  const textContentSchema = z.object({
4
12
  type: z.literal("text"),
5
13
  text: z.string(),
@@ -45,63 +53,87 @@ export const contextPartContentSchema = z.discriminatedUnion("type", [
45
53
  sourceUrlContentSchema,
46
54
  sourceDocumentContentSchema,
47
55
  ]);
48
- const contextInlineContentSchema = z.discriminatedUnion("type", [
56
+ export const contextInlineContentSchema = z.discriminatedUnion("type", [
49
57
  textContentSchema,
50
58
  fileContentSchema,
51
59
  jsonContentSchema,
52
60
  ]);
53
- const contextContentPartSchema = z.object({
54
- type: z.literal("content"),
55
- content: z.array(contextInlineContentSchema),
56
- state: z.enum(["streaming", "done"]).optional(),
61
+ const messageContentSchema = z
62
+ .object({
63
+ text: z.string().optional(),
64
+ blocks: z.array(contextInlineContentSchema).optional(),
65
+ })
66
+ .superRefine((value, ctx) => {
67
+ const hasText = typeof value.text === "string" && value.text.length > 0;
68
+ const hasBlocks = Array.isArray(value.blocks) && value.blocks.length > 0;
69
+ if (!hasText && !hasBlocks) {
70
+ ctx.addIssue({
71
+ code: z.ZodIssueCode.custom,
72
+ message: "message content requires text or blocks",
73
+ });
74
+ }
57
75
  });
58
- const contextReasoningPartSchema = z.object({
76
+ export const contextMessagePartSchema = z.object({
77
+ type: z.literal("message"),
78
+ content: messageContentSchema,
79
+ reactorMetadata: reactorMetadataSchema.optional(),
80
+ });
81
+ export const contextReasoningPartSchema = z.object({
59
82
  type: z.literal("reasoning"),
60
- content: z.array(textContentSchema),
61
- state: z.enum(["streaming", "done"]).optional(),
83
+ content: z.object({
84
+ text: z.string(),
85
+ state: z.enum(["streaming", "done"]).optional(),
86
+ }),
87
+ reactorMetadata: reactorMetadataSchema.optional(),
62
88
  });
63
- const contextSourcePartSchema = z.object({
89
+ export const contextSourcePartSchema = z.object({
64
90
  type: z.literal("source"),
65
- content: z.array(z.discriminatedUnion("type", [sourceUrlContentSchema, sourceDocumentContentSchema])),
91
+ content: z.object({
92
+ sources: z.array(z.discriminatedUnion("type", [sourceUrlContentSchema, sourceDocumentContentSchema])),
93
+ }),
94
+ reactorMetadata: reactorMetadataSchema.optional(),
66
95
  });
67
- const contextToolCallPartSchema = z.object({
68
- type: z.literal("tool-call"),
69
- toolCallId: z.string().min(1),
70
- toolName: z.string().min(1),
71
- content: z.array(contextInlineContentSchema),
72
- state: z.enum(["input-streaming", "input-available"]).optional(),
96
+ const contextActionErrorSchema = z.object({
97
+ message: z.string(),
98
+ code: z.string().optional(),
99
+ details: z.unknown().optional(),
73
100
  });
74
- const contextToolResultPartSchema = z.object({
75
- type: z.literal("tool-result"),
76
- toolCallId: z.string().min(1),
77
- toolName: z.string().min(1),
78
- content: z.array(contextInlineContentSchema),
79
- state: z.enum(["output-available", "output-error"]).optional(),
101
+ export const contextActionPartSchema = z.object({
102
+ type: z.literal("action"),
103
+ content: z.discriminatedUnion("status", [
104
+ z.object({
105
+ status: z.literal("started"),
106
+ actionName: z.string().min(1),
107
+ actionCallId: z.string().min(1),
108
+ input: z.unknown(),
109
+ }),
110
+ z.object({
111
+ status: z.literal("completed"),
112
+ actionName: z.string().min(1),
113
+ actionCallId: z.string().min(1),
114
+ output: z.unknown(),
115
+ }),
116
+ z.object({
117
+ status: z.literal("failed"),
118
+ actionName: z.string().min(1),
119
+ actionCallId: z.string().min(1),
120
+ error: contextActionErrorSchema,
121
+ }),
122
+ ]),
123
+ reactorMetadata: reactorMetadataSchema.optional(),
80
124
  });
81
- export const contextPartSchema = z.discriminatedUnion("type", [
82
- contextContentPartSchema,
125
+ export const contextEnginePartSchema = z.discriminatedUnion("type", [
126
+ contextMessagePartSchema,
83
127
  contextReasoningPartSchema,
84
128
  contextSourcePartSchema,
85
- contextToolCallPartSchema,
86
- contextToolResultPartSchema,
87
129
  ]);
88
- export const contextPartEnvelopeSchema = z.discriminatedUnion("type", [
89
- contextContentPartSchema.extend({
90
- metadata: metadataSchema,
91
- }),
92
- contextReasoningPartSchema.extend({
93
- metadata: metadataSchema,
94
- }),
95
- contextSourcePartSchema.extend({
96
- metadata: metadataSchema,
97
- }),
98
- contextToolCallPartSchema.extend({
99
- metadata: metadataSchema,
100
- }),
101
- contextToolResultPartSchema.extend({
102
- metadata: metadataSchema,
103
- }),
130
+ export const contextPartSchema = z.discriminatedUnion("type", [
131
+ contextMessagePartSchema,
132
+ contextReasoningPartSchema,
133
+ contextSourcePartSchema,
134
+ contextActionPartSchema,
104
135
  ]);
136
+ export const contextPartEnvelopeSchema = contextPartSchema;
105
137
  function asRecord(value) {
106
138
  if (!value || typeof value !== "object")
107
139
  return null;
@@ -110,10 +142,54 @@ function asRecord(value) {
110
142
  function cleanRecord(value) {
111
143
  return Object.fromEntries(Object.entries(value).filter(([, item]) => item !== undefined));
112
144
  }
113
- function normalizeMetadata(value) {
114
- if (!value || typeof value !== "object")
115
- return undefined;
116
- return value;
145
+ function createContextActionPartSchemas(actions) {
146
+ const schemas = [];
147
+ for (const [actionName, action] of Object.entries(actions)) {
148
+ schemas.push(z.object({
149
+ type: z.literal("action"),
150
+ content: z.object({
151
+ status: z.literal("started"),
152
+ actionName: z.literal(actionName),
153
+ actionCallId: z.string().min(1),
154
+ input: action.input,
155
+ }),
156
+ reactorMetadata: reactorMetadataSchema.optional(),
157
+ }), z.object({
158
+ type: z.literal("action"),
159
+ content: z.object({
160
+ status: z.literal("completed"),
161
+ actionName: z.literal(actionName),
162
+ actionCallId: z.string().min(1),
163
+ output: action.output,
164
+ }),
165
+ reactorMetadata: reactorMetadataSchema.optional(),
166
+ }), z.object({
167
+ type: z.literal("action"),
168
+ content: z.object({
169
+ status: z.literal("failed"),
170
+ actionName: z.literal(actionName),
171
+ actionCallId: z.string().min(1),
172
+ error: contextActionErrorSchema,
173
+ }),
174
+ reactorMetadata: reactorMetadataSchema.optional(),
175
+ }));
176
+ }
177
+ return schemas;
178
+ }
179
+ export function createContextPartSchema(actions) {
180
+ const actionSchemas = actions ? createContextActionPartSchemas(actions) : [];
181
+ if (actionSchemas.length === 0) {
182
+ return contextEnginePartSchema;
183
+ }
184
+ return z.union([
185
+ contextMessagePartSchema,
186
+ contextReasoningPartSchema,
187
+ contextSourcePartSchema,
188
+ ...actionSchemas,
189
+ ]);
190
+ }
191
+ export function parseContextPart(actions, value) {
192
+ return createContextPartSchema(actions).parse(value);
117
193
  }
118
194
  export function isContextPartEnvelope(value) {
119
195
  return contextPartEnvelopeSchema.safeParse(value).success;
@@ -122,17 +198,13 @@ export function parseContextPartEnvelope(value) {
122
198
  return contextPartEnvelopeSchema.parse(value);
123
199
  }
124
200
  export function splitContextPartEnvelope(value) {
125
- const { metadata, ...part } = value;
126
201
  return {
127
- part,
128
- metadata,
202
+ part: parseContextPartEnvelope(value),
203
+ metadata: undefined,
129
204
  };
130
205
  }
131
206
  export function mergeContextPartEnvelope(params) {
132
- return parseContextPartEnvelope({
133
- ...(asRecord(params.part) ?? {}),
134
- metadata: normalizeMetadata(params.metadata),
135
- });
207
+ return parseContextPartEnvelope(params.part);
136
208
  }
137
209
  function normalizeFileContentBlock(value) {
138
210
  return contextInlineContentSchema.parse(cleanRecord({
@@ -144,217 +216,270 @@ function normalizeFileContentBlock(value) {
144
216
  fileId: typeof value.fileId === "string" ? value.fileId : undefined,
145
217
  }));
146
218
  }
147
- export function normalizeToolResultContentToBlocks(value) {
148
- if (value === undefined || value === null) {
149
- return [];
150
- }
151
- if (typeof value === "string") {
152
- return [{ type: "text", text: value }];
153
- }
219
+ function normalizeInlineContentBlock(value) {
154
220
  const record = asRecord(value);
155
- if (!record) {
156
- return [{ type: "json", value }];
221
+ if (!record || typeof record.type !== "string")
222
+ return null;
223
+ if (record.type === "text" && typeof record.text === "string") {
224
+ return contextInlineContentSchema.parse({ type: "text", text: record.text });
157
225
  }
158
226
  if (record.type === "json") {
159
- return [{ type: "json", value: record.value }];
227
+ return contextInlineContentSchema.parse({ type: "json", value: record.value });
160
228
  }
161
- if (record.type === "content" && Array.isArray(record.value)) {
162
- const blocks = [];
163
- for (const entry of record.value) {
164
- const contentRecord = asRecord(entry);
165
- if (!contentRecord || typeof contentRecord.type !== "string") {
166
- blocks.push({ type: "json", value: entry });
167
- continue;
168
- }
169
- if (contentRecord.type === "text" && typeof contentRecord.text === "string") {
170
- blocks.push({ type: "text", text: contentRecord.text });
171
- continue;
172
- }
173
- if (contentRecord.type === "image-data") {
174
- blocks.push(cleanRecord({
175
- type: "file",
176
- mediaType: typeof contentRecord.mediaType === "string"
177
- ? contentRecord.mediaType
178
- : "application/octet-stream",
179
- filename: typeof contentRecord.filename === "string"
180
- ? contentRecord.filename
181
- : undefined,
182
- data: typeof contentRecord.data === "string" ? contentRecord.data : undefined,
183
- }));
184
- continue;
185
- }
186
- if (contentRecord.type === "file") {
187
- blocks.push(normalizeFileContentBlock(contentRecord));
188
- continue;
189
- }
190
- blocks.push({ type: "json", value: entry });
191
- }
192
- return blocks;
229
+ if (record.type === "file" || record.type === "image-data") {
230
+ return normalizeFileContentBlock(record);
193
231
  }
194
- if (record.type === "file") {
195
- return [normalizeFileContentBlock(record)];
232
+ return null;
233
+ }
234
+ function normalizeInlineContentBlocks(value) {
235
+ if (!Array.isArray(value))
236
+ return [];
237
+ return value
238
+ .map((block) => normalizeInlineContentBlock(block))
239
+ .filter((block) => Boolean(block));
240
+ }
241
+ function contentBlocksToActionValue(blocks) {
242
+ if (blocks.length === 0)
243
+ return undefined;
244
+ if (blocks.length === 1) {
245
+ const [first] = blocks;
246
+ if (first.type === "json")
247
+ return first.value;
248
+ if (first.type === "text")
249
+ return first.text;
250
+ if (first.type === "file")
251
+ return first;
196
252
  }
197
- return [{ type: "json", value }];
253
+ return {
254
+ type: "content",
255
+ value: blocks,
256
+ };
198
257
  }
199
- function metadataFromUiPart(part) {
200
- const metadata = cleanRecord({
201
- provider: normalizeMetadata(part.providerMetadata),
202
- providerCall: normalizeMetadata(part.callProviderMetadata),
203
- });
204
- return Object.keys(metadata).length > 0 ? metadata : undefined;
258
+ function contentBlocksToErrorMessage(blocks) {
259
+ const text = blocks
260
+ .filter((block) => block.type === "text")
261
+ .map((block) => block.text)
262
+ .join("\n\n")
263
+ .trim();
264
+ if (text)
265
+ return text;
266
+ const jsonBlock = blocks.find((block) => block.type === "json");
267
+ if (jsonBlock)
268
+ return JSON.stringify(jsonBlock.value, null, 2);
269
+ return "";
270
+ }
271
+ function readReactorMetadata(record) {
272
+ const parsed = reactorMetadataSchema.safeParse(record.reactorMetadata);
273
+ return parsed.success ? parsed.data : undefined;
274
+ }
275
+ function messageFromBlocks(blocks, reactorMetadata) {
276
+ if (blocks.length === 0)
277
+ return [];
278
+ const text = blocks
279
+ .filter((block) => block.type === "text")
280
+ .map((block) => block.text)
281
+ .join("\n");
282
+ const hasNonText = blocks.some((block) => block.type !== "text");
283
+ return [
284
+ contextMessagePartSchema.parse(cleanRecord({
285
+ type: "message",
286
+ content: cleanRecord({
287
+ text: text || undefined,
288
+ blocks: hasNonText ? blocks : undefined,
289
+ }),
290
+ reactorMetadata,
291
+ })),
292
+ ];
293
+ }
294
+ function normalizeExternalToolCallPart(record, reactorMetadata) {
295
+ const actionName = typeof record.toolName === "string" && record.toolName.length > 0
296
+ ? record.toolName
297
+ : "";
298
+ const actionCallId = typeof record.toolCallId === "string" && record.toolCallId.length > 0
299
+ ? record.toolCallId
300
+ : "";
301
+ if (!actionName || !actionCallId)
302
+ return [];
303
+ const blocks = normalizeInlineContentBlocks(record.content);
304
+ return [
305
+ contextActionPartSchema.parse(cleanRecord({
306
+ type: "action",
307
+ content: {
308
+ status: "started",
309
+ actionName,
310
+ actionCallId,
311
+ input: contentBlocksToActionValue(blocks),
312
+ },
313
+ reactorMetadata,
314
+ })),
315
+ ];
316
+ }
317
+ function normalizeExternalToolResultPart(record, reactorMetadata) {
318
+ const actionName = typeof record.toolName === "string" && record.toolName.length > 0
319
+ ? record.toolName
320
+ : "";
321
+ const actionCallId = typeof record.toolCallId === "string" && record.toolCallId.length > 0
322
+ ? record.toolCallId
323
+ : "";
324
+ if (!actionName || !actionCallId)
325
+ return [];
326
+ const blocks = normalizeInlineContentBlocks(record.content);
327
+ const failed = record.state === "output-error";
328
+ return [
329
+ contextActionPartSchema.parse(cleanRecord({
330
+ type: "action",
331
+ content: failed
332
+ ? {
333
+ status: "failed",
334
+ actionName,
335
+ actionCallId,
336
+ error: {
337
+ message: contentBlocksToErrorMessage(blocks) || "Action execution failed.",
338
+ },
339
+ }
340
+ : {
341
+ status: "completed",
342
+ actionName,
343
+ actionCallId,
344
+ output: contentBlocksToActionValue(blocks),
345
+ },
346
+ reactorMetadata,
347
+ })),
348
+ ];
205
349
  }
206
350
  export function normalizeUiPartToContextPartEnvelopes(value) {
207
351
  const record = asRecord(value);
208
352
  if (!record || typeof record.type !== "string") {
209
353
  return [];
210
354
  }
211
- const metadata = metadataFromUiPart(record);
355
+ const reactorMetadata = readReactorMetadata(record);
212
356
  if (record.type === "text" && typeof record.text === "string") {
213
- return [
214
- {
215
- type: "content",
216
- content: [{ type: "text", text: record.text }],
217
- state: record.state === "streaming" ? "streaming" : "done",
218
- metadata,
219
- },
220
- ];
357
+ return messageFromBlocks([{ type: "text", text: record.text }], reactorMetadata);
221
358
  }
222
359
  if (record.type === "reasoning" && typeof record.text === "string") {
223
360
  return [
224
- {
361
+ contextReasoningPartSchema.parse(cleanRecord({
225
362
  type: "reasoning",
226
- content: [{ type: "text", text: record.text }],
227
- state: record.state === "streaming" ? "streaming" : "done",
228
- metadata,
229
- },
363
+ content: cleanRecord({
364
+ text: record.text,
365
+ state: record.state === "streaming" ? "streaming" : "done",
366
+ }),
367
+ reactorMetadata,
368
+ })),
230
369
  ];
231
370
  }
232
371
  if (record.type === "file") {
233
- return [
234
- {
235
- type: "content",
236
- content: [
237
- cleanRecord({
238
- type: "file",
239
- mediaType: typeof record.mediaType === "string"
240
- ? record.mediaType
241
- : "application/octet-stream",
242
- filename: typeof record.filename === "string" ? record.filename : undefined,
243
- url: typeof record.url === "string" ? record.url : undefined,
244
- data: typeof record.data === "string" ? record.data : undefined,
245
- fileId: typeof record.fileId === "string" ? record.fileId : undefined,
246
- }),
247
- ],
248
- metadata,
249
- },
250
- ];
372
+ return messageFromBlocks([normalizeFileContentBlock(record)], reactorMetadata);
251
373
  }
252
374
  if (record.type === "source-url") {
253
375
  return [
254
- {
376
+ contextSourcePartSchema.parse(cleanRecord({
255
377
  type: "source",
256
- content: [
257
- {
258
- type: "source-url",
259
- sourceId: typeof record.sourceId === "string" ? record.sourceId : "source-url",
260
- url: typeof record.url === "string" ? record.url : "",
261
- title: typeof record.title === "string" ? record.title : undefined,
262
- },
263
- ],
264
- metadata,
265
- },
378
+ content: {
379
+ sources: [
380
+ cleanRecord({
381
+ type: "source-url",
382
+ sourceId: typeof record.sourceId === "string" ? record.sourceId : "source-url",
383
+ url: typeof record.url === "string" ? record.url : "",
384
+ title: typeof record.title === "string" ? record.title : undefined,
385
+ }),
386
+ ],
387
+ },
388
+ reactorMetadata,
389
+ })),
266
390
  ];
267
391
  }
268
392
  if (record.type === "source-document") {
269
393
  return [
270
- {
394
+ contextSourcePartSchema.parse(cleanRecord({
271
395
  type: "source",
272
- content: [
273
- {
274
- type: "source-document",
275
- sourceId: typeof record.sourceId === "string"
276
- ? record.sourceId
277
- : "source-document",
278
- mediaType: typeof record.mediaType === "string"
279
- ? record.mediaType
280
- : "application/octet-stream",
281
- title: typeof record.title === "string" ? record.title : "Document",
282
- filename: typeof record.filename === "string" ? record.filename : undefined,
283
- },
284
- ],
285
- metadata,
286
- },
396
+ content: {
397
+ sources: [
398
+ cleanRecord({
399
+ type: "source-document",
400
+ sourceId: typeof record.sourceId === "string"
401
+ ? record.sourceId
402
+ : "source-document",
403
+ mediaType: typeof record.mediaType === "string"
404
+ ? record.mediaType
405
+ : "application/octet-stream",
406
+ title: typeof record.title === "string" ? record.title : "Document",
407
+ filename: typeof record.filename === "string" ? record.filename : undefined,
408
+ }),
409
+ ],
410
+ },
411
+ reactorMetadata,
412
+ })),
287
413
  ];
288
414
  }
289
415
  if (record.type.startsWith("data-")) {
290
- return [
291
- {
292
- type: "content",
293
- content: [
294
- {
295
- type: "json",
296
- value: record.data,
297
- },
298
- ],
299
- metadata: cleanRecord({
300
- ...(metadata ?? {}),
301
- app: {
302
- dataPartType: record.type.slice("data-".length),
303
- },
304
- }),
305
- },
306
- ];
416
+ return messageFromBlocks([{ type: "json", value: record.data }], reactorMetadata);
417
+ }
418
+ if (record.type === "tool-call") {
419
+ return normalizeExternalToolCallPart(record, reactorMetadata);
420
+ }
421
+ if (record.type === "tool-result") {
422
+ return normalizeExternalToolResultPart(record, reactorMetadata);
307
423
  }
308
424
  if (record.type.startsWith("tool-")) {
309
- const toolName = record.type.slice("tool-".length);
310
- const toolCallId = typeof record.toolCallId === "string" ? record.toolCallId : "";
311
- if (!toolName || !toolCallId) {
425
+ const actionName = record.type.slice("tool-".length);
426
+ const actionCallId = typeof record.toolCallId === "string" ? record.toolCallId : "";
427
+ if (!actionName || !actionCallId) {
312
428
  return [];
313
429
  }
314
- const callPart = {
315
- type: "tool-call",
316
- toolCallId,
317
- toolName,
318
- state: record.state === "input-streaming"
319
- ? "input-streaming"
320
- : "input-available",
321
- content: "input" in record && record.input !== undefined
322
- ? [{ type: "json", value: record.input }]
323
- : [],
324
- metadata,
325
- };
326
- if (record.state === "output-available" || record.state === "output-error") {
430
+ const startedPart = contextActionPartSchema.parse(cleanRecord({
431
+ type: "action",
432
+ content: cleanRecord({
433
+ status: "started",
434
+ actionName,
435
+ actionCallId,
436
+ input: "input" in record ? record.input : undefined,
437
+ }),
438
+ reactorMetadata,
439
+ }));
440
+ if (record.state === "output-available") {
327
441
  return [
328
- callPart,
329
- {
330
- type: "tool-result",
331
- toolCallId,
332
- toolName,
333
- state: record.state,
334
- content: record.state === "output-error"
335
- ? [
336
- {
337
- type: "text",
338
- text: typeof record.errorText === "string" && record.errorText.length > 0
339
- ? record.errorText
340
- : "Tool execution failed.",
341
- },
342
- ]
343
- : normalizeToolResultContentToBlocks(record.output),
344
- metadata,
345
- },
442
+ startedPart,
443
+ contextActionPartSchema.parse(cleanRecord({
444
+ type: "action",
445
+ content: {
446
+ status: "completed",
447
+ actionName,
448
+ actionCallId,
449
+ output: record.output,
450
+ },
451
+ reactorMetadata,
452
+ })),
453
+ ];
454
+ }
455
+ if (record.state === "output-error") {
456
+ return [
457
+ startedPart,
458
+ contextActionPartSchema.parse(cleanRecord({
459
+ type: "action",
460
+ content: {
461
+ status: "failed",
462
+ actionName,
463
+ actionCallId,
464
+ error: {
465
+ message: typeof record.errorText === "string" && record.errorText.length > 0
466
+ ? record.errorText
467
+ : "Action execution failed.",
468
+ },
469
+ },
470
+ reactorMetadata,
471
+ })),
346
472
  ];
347
473
  }
348
- return [callPart];
474
+ return [startedPart];
349
475
  }
350
476
  return [];
351
477
  }
352
478
  export function normalizePartsForPersistence(parts) {
353
- const normalized = parts.flatMap((part) => {
479
+ return parts.flatMap((part) => {
354
480
  if (isContextPartEnvelope(part)) {
355
481
  return [parseContextPartEnvelope(part)];
356
482
  }
357
483
  return normalizeUiPartToContextPartEnvelopes(part);
358
484
  });
359
- return normalized;
360
485
  }
@@ -1,7 +1,7 @@
1
1
  import type { ContextEnvironment } from "./context.config.js";
2
2
  import type { ContextInstance } from "./context.builder.js";
3
3
  export type ContextKey = string;
4
- type AnyContext = ContextInstance<any, any>;
4
+ type AnyContext = ContextInstance<any, any, any>;
5
5
  export type ContextFactory = () => AnyContext;
6
6
  export declare function registerContext(key: ContextKey, factory: ContextFactory): void;
7
7
  export declare function hasContext(key: ContextKey): boolean;