@ekairos/events 1.22.67-beta.development.0 → 1.22.68-beta.development.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/react.context-event-parts.d.ts +18 -0
- package/dist/react.context-event-parts.js +509 -0
- package/dist/react.d.ts +7 -42
- package/dist/react.js +4 -87
- package/dist/react.step-stream.d.ts +39 -0
- package/dist/react.step-stream.js +581 -0
- package/dist/react.types.d.ts +121 -0
- package/dist/react.types.js +2 -0
- package/dist/react.use-context.d.ts +7 -0
- package/dist/react.use-context.js +867 -0
- package/package.json +3 -2
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
type ActionStatus = "started" | "completed" | "failed";
|
|
2
|
+
export type ContextActionPartInfo = {
|
|
3
|
+
actionName: string;
|
|
4
|
+
actionCallId: string;
|
|
5
|
+
status: ActionStatus;
|
|
6
|
+
input?: unknown;
|
|
7
|
+
output?: unknown;
|
|
8
|
+
errorText?: string;
|
|
9
|
+
};
|
|
10
|
+
export declare function normalizeContextEventParts(parts: unknown[]): Record<string, unknown>[];
|
|
11
|
+
export declare function getActionPartInfo(part: unknown): ContextActionPartInfo | null;
|
|
12
|
+
export declare function getCreateMessageText(part: unknown): string;
|
|
13
|
+
export declare function getPartText(part: unknown): string;
|
|
14
|
+
export declare function getReasoningText(part: unknown): string;
|
|
15
|
+
export declare function getReasoningState(part: unknown): string;
|
|
16
|
+
export declare function getSourceParts(part: unknown): any[];
|
|
17
|
+
export declare function findNormalizedToolPart(parts: unknown[], toolName: string): Record<string, unknown> | null;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,509 @@
|
|
|
1
|
+
function asRecord(value) {
|
|
2
|
+
if (!value || typeof value !== "object")
|
|
3
|
+
return null;
|
|
4
|
+
return value;
|
|
5
|
+
}
|
|
6
|
+
function asText(value) {
|
|
7
|
+
return typeof value === "string" ? value.trim() : "";
|
|
8
|
+
}
|
|
9
|
+
function cleanRecord(value) {
|
|
10
|
+
return Object.fromEntries(Object.entries(value).filter(([, item]) => item !== undefined));
|
|
11
|
+
}
|
|
12
|
+
function buildFileUrl(block) {
|
|
13
|
+
if (typeof block.url === "string" && block.url.length > 0) {
|
|
14
|
+
return block.url;
|
|
15
|
+
}
|
|
16
|
+
if (typeof block.data === "string" && block.data.length > 0) {
|
|
17
|
+
return block.data.startsWith("data:")
|
|
18
|
+
? block.data
|
|
19
|
+
: `data:${block.mediaType};base64,${block.data}`;
|
|
20
|
+
}
|
|
21
|
+
if (typeof block.fileId === "string" && block.fileId.length > 0) {
|
|
22
|
+
return block.fileId;
|
|
23
|
+
}
|
|
24
|
+
return "";
|
|
25
|
+
}
|
|
26
|
+
function readTextPayload(value) {
|
|
27
|
+
const record = asRecord(value);
|
|
28
|
+
if (!record)
|
|
29
|
+
return asText(value);
|
|
30
|
+
return (asText(record.text) ||
|
|
31
|
+
asText(record.message) ||
|
|
32
|
+
asText(record.summary) ||
|
|
33
|
+
asText(asRecord(record.content)?.text) ||
|
|
34
|
+
asText(asRecord(record.content)?.message));
|
|
35
|
+
}
|
|
36
|
+
function normalizeContentBlock(value) {
|
|
37
|
+
const record = asRecord(value);
|
|
38
|
+
if (!record || typeof record.type !== "string")
|
|
39
|
+
return null;
|
|
40
|
+
if (record.type === "text") {
|
|
41
|
+
const text = asText(record.text);
|
|
42
|
+
return text ? { type: "text", text } : null;
|
|
43
|
+
}
|
|
44
|
+
if (record.type === "file") {
|
|
45
|
+
const mediaType = asText(record.mediaType) || "application/octet-stream";
|
|
46
|
+
const file = cleanRecord({
|
|
47
|
+
type: "file",
|
|
48
|
+
mediaType,
|
|
49
|
+
filename: asText(record.filename) || undefined,
|
|
50
|
+
data: asText(record.data) || undefined,
|
|
51
|
+
url: buildFileUrl({
|
|
52
|
+
mediaType,
|
|
53
|
+
data: asText(record.data) || undefined,
|
|
54
|
+
url: asText(record.url) || undefined,
|
|
55
|
+
fileId: asText(record.fileId) || undefined,
|
|
56
|
+
}) || undefined,
|
|
57
|
+
fileId: asText(record.fileId) || undefined,
|
|
58
|
+
});
|
|
59
|
+
return file.url || file.data || file.fileId ? file : null;
|
|
60
|
+
}
|
|
61
|
+
if (record.type === "json") {
|
|
62
|
+
return { type: "json", value: record.value };
|
|
63
|
+
}
|
|
64
|
+
if (record.type === "source-url") {
|
|
65
|
+
const url = asText(record.url);
|
|
66
|
+
if (!url)
|
|
67
|
+
return null;
|
|
68
|
+
return cleanRecord({
|
|
69
|
+
type: "source-url",
|
|
70
|
+
sourceId: asText(record.sourceId) || "source-url",
|
|
71
|
+
url,
|
|
72
|
+
title: asText(record.title) || undefined,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
if (record.type === "source-document") {
|
|
76
|
+
return cleanRecord({
|
|
77
|
+
type: "source-document",
|
|
78
|
+
sourceId: asText(record.sourceId) || "source-document",
|
|
79
|
+
mediaType: asText(record.mediaType) || "application/octet-stream",
|
|
80
|
+
title: asText(record.title) || "Document",
|
|
81
|
+
filename: asText(record.filename) || undefined,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
function normalizeBlocks(value) {
|
|
87
|
+
if (!Array.isArray(value))
|
|
88
|
+
return [];
|
|
89
|
+
return value
|
|
90
|
+
.map((block) => normalizeContentBlock(block))
|
|
91
|
+
.filter((block) => Boolean(block));
|
|
92
|
+
}
|
|
93
|
+
function blocksToMessageContent(blocks) {
|
|
94
|
+
const text = blocks
|
|
95
|
+
.filter((block) => block.type === "text")
|
|
96
|
+
.map((block) => block.text)
|
|
97
|
+
.join("\n")
|
|
98
|
+
.trim();
|
|
99
|
+
const hasNonText = blocks.some((block) => block.type !== "text");
|
|
100
|
+
return cleanRecord({
|
|
101
|
+
text: text || undefined,
|
|
102
|
+
blocks: hasNonText ? blocks : undefined,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
function blocksToValue(blocks) {
|
|
106
|
+
if (blocks.length === 0)
|
|
107
|
+
return undefined;
|
|
108
|
+
if (blocks.length === 1) {
|
|
109
|
+
const first = blocks[0];
|
|
110
|
+
if (first.type === "json")
|
|
111
|
+
return first.value;
|
|
112
|
+
if (first.type === "text")
|
|
113
|
+
return first.text;
|
|
114
|
+
if (first.type === "file")
|
|
115
|
+
return first;
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
type: "content",
|
|
119
|
+
value: blocks,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
function blocksToErrorText(blocks) {
|
|
123
|
+
const text = blocks
|
|
124
|
+
.filter((block) => block.type === "text")
|
|
125
|
+
.map((block) => block.text)
|
|
126
|
+
.join("\n\n")
|
|
127
|
+
.trim();
|
|
128
|
+
if (text)
|
|
129
|
+
return text;
|
|
130
|
+
const jsonBlock = blocks.find((block) => block.type === "json");
|
|
131
|
+
if (jsonBlock) {
|
|
132
|
+
return JSON.stringify(jsonBlock.value, null, 2);
|
|
133
|
+
}
|
|
134
|
+
return "";
|
|
135
|
+
}
|
|
136
|
+
function normalizeMessagePart(part) {
|
|
137
|
+
const content = asRecord(part.content) ?? {};
|
|
138
|
+
const rawBlocks = Array.isArray(content.blocks)
|
|
139
|
+
? content.blocks
|
|
140
|
+
: Array.isArray(part.content)
|
|
141
|
+
? part.content
|
|
142
|
+
: [];
|
|
143
|
+
const blocks = normalizeBlocks(rawBlocks);
|
|
144
|
+
const text = readTextPayload(content) || readTextPayload(part);
|
|
145
|
+
if (text) {
|
|
146
|
+
blocks.unshift({ type: "text", text });
|
|
147
|
+
}
|
|
148
|
+
const messageContent = blocksToMessageContent(blocks);
|
|
149
|
+
return Object.keys(messageContent).length > 0
|
|
150
|
+
? [{ type: "message", content: messageContent }]
|
|
151
|
+
: [];
|
|
152
|
+
}
|
|
153
|
+
function normalizeReasoningPart(part) {
|
|
154
|
+
const content = part.content;
|
|
155
|
+
const contentRecord = asRecord(content);
|
|
156
|
+
const text = Array.isArray(content)
|
|
157
|
+
? normalizeBlocks(content)
|
|
158
|
+
.filter((block) => block.type === "text")
|
|
159
|
+
.map((block) => block.text)
|
|
160
|
+
.join("\n\n")
|
|
161
|
+
: readTextPayload(contentRecord) || asText(part.text);
|
|
162
|
+
const state = asText(contentRecord?.state) ||
|
|
163
|
+
asText(part.state) ||
|
|
164
|
+
undefined;
|
|
165
|
+
return text || state
|
|
166
|
+
? [
|
|
167
|
+
{
|
|
168
|
+
type: "reasoning",
|
|
169
|
+
content: cleanRecord({
|
|
170
|
+
text,
|
|
171
|
+
state,
|
|
172
|
+
}),
|
|
173
|
+
},
|
|
174
|
+
]
|
|
175
|
+
: [];
|
|
176
|
+
}
|
|
177
|
+
function normalizeSourcePart(part) {
|
|
178
|
+
const content = part.content;
|
|
179
|
+
const rawSources = Array.isArray(content)
|
|
180
|
+
? content
|
|
181
|
+
: Array.isArray(asRecord(content)?.sources)
|
|
182
|
+
? asRecord(content)?.sources
|
|
183
|
+
: [];
|
|
184
|
+
const sources = normalizeBlocks(rawSources).filter((block) => block.type === "source-url" || block.type === "source-document");
|
|
185
|
+
return sources.length > 0
|
|
186
|
+
? [
|
|
187
|
+
{
|
|
188
|
+
type: "source",
|
|
189
|
+
content: { sources },
|
|
190
|
+
},
|
|
191
|
+
]
|
|
192
|
+
: [];
|
|
193
|
+
}
|
|
194
|
+
function normalizeActionStatus(value, fallback) {
|
|
195
|
+
const status = (asText(value) || asText(fallback)).toLowerCase();
|
|
196
|
+
if (status === "failed" || status === "error" || status === "output-error") {
|
|
197
|
+
return "failed";
|
|
198
|
+
}
|
|
199
|
+
if (status === "completed" ||
|
|
200
|
+
status === "complete" ||
|
|
201
|
+
status === "output-available") {
|
|
202
|
+
return "completed";
|
|
203
|
+
}
|
|
204
|
+
return "started";
|
|
205
|
+
}
|
|
206
|
+
function normalizeActionPart(part) {
|
|
207
|
+
const content = asRecord(part.content) ?? {};
|
|
208
|
+
const actionName = asText(content.actionName) ||
|
|
209
|
+
asText(content.toolName) ||
|
|
210
|
+
asText(part.actionName) ||
|
|
211
|
+
asText(part.toolName);
|
|
212
|
+
if (!actionName)
|
|
213
|
+
return [];
|
|
214
|
+
const output = content.output ?? part.output;
|
|
215
|
+
const error = content.error ?? content.errorText ?? part.error ?? part.errorText;
|
|
216
|
+
const status = normalizeActionStatus(content.status ?? part.status, error !== undefined ? "failed" : output !== undefined ? "completed" : "started");
|
|
217
|
+
const actionCallId = asText(content.actionCallId) ||
|
|
218
|
+
asText(content.toolCallId) ||
|
|
219
|
+
asText(content.actionRef) ||
|
|
220
|
+
asText(part.actionCallId) ||
|
|
221
|
+
asText(part.toolCallId) ||
|
|
222
|
+
asText(part.actionRef) ||
|
|
223
|
+
actionName;
|
|
224
|
+
if (status === "failed") {
|
|
225
|
+
return [
|
|
226
|
+
{
|
|
227
|
+
type: "action",
|
|
228
|
+
content: {
|
|
229
|
+
status,
|
|
230
|
+
actionName,
|
|
231
|
+
actionCallId,
|
|
232
|
+
error: {
|
|
233
|
+
message: readTextPayload(error) || "Action failed.",
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
},
|
|
237
|
+
];
|
|
238
|
+
}
|
|
239
|
+
if (status === "completed") {
|
|
240
|
+
return [
|
|
241
|
+
{
|
|
242
|
+
type: "action",
|
|
243
|
+
content: {
|
|
244
|
+
status,
|
|
245
|
+
actionName,
|
|
246
|
+
actionCallId,
|
|
247
|
+
output,
|
|
248
|
+
},
|
|
249
|
+
},
|
|
250
|
+
];
|
|
251
|
+
}
|
|
252
|
+
return [
|
|
253
|
+
{
|
|
254
|
+
type: "action",
|
|
255
|
+
content: {
|
|
256
|
+
status,
|
|
257
|
+
actionName,
|
|
258
|
+
actionCallId,
|
|
259
|
+
input: content.input ?? part.input,
|
|
260
|
+
},
|
|
261
|
+
},
|
|
262
|
+
];
|
|
263
|
+
}
|
|
264
|
+
function normalizeLegacyToolPart(part) {
|
|
265
|
+
const type = asText(part.type);
|
|
266
|
+
if (!type.startsWith("tool-"))
|
|
267
|
+
return [];
|
|
268
|
+
const actionName = type.slice("tool-".length);
|
|
269
|
+
const actionCallId = asText(part.toolCallId) || asText(part.actionCallId) || actionName;
|
|
270
|
+
const state = asText(part.state).toLowerCase();
|
|
271
|
+
const input = part.input ?? part.args;
|
|
272
|
+
const parts = [
|
|
273
|
+
{
|
|
274
|
+
type: "action",
|
|
275
|
+
content: {
|
|
276
|
+
status: "started",
|
|
277
|
+
actionName,
|
|
278
|
+
actionCallId,
|
|
279
|
+
input,
|
|
280
|
+
},
|
|
281
|
+
},
|
|
282
|
+
];
|
|
283
|
+
if (state === "output-error") {
|
|
284
|
+
parts.push({
|
|
285
|
+
type: "action",
|
|
286
|
+
content: {
|
|
287
|
+
status: "failed",
|
|
288
|
+
actionName,
|
|
289
|
+
actionCallId,
|
|
290
|
+
error: {
|
|
291
|
+
message: readTextPayload(part.errorText ?? part.error) || "Action failed.",
|
|
292
|
+
},
|
|
293
|
+
},
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
else if (state === "output-available") {
|
|
297
|
+
parts.push({
|
|
298
|
+
type: "action",
|
|
299
|
+
content: {
|
|
300
|
+
status: "completed",
|
|
301
|
+
actionName,
|
|
302
|
+
actionCallId,
|
|
303
|
+
output: part.output,
|
|
304
|
+
},
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
return parts;
|
|
308
|
+
}
|
|
309
|
+
function normalizeLegacyToolCallPart(part) {
|
|
310
|
+
const toolName = asText(part.toolName);
|
|
311
|
+
const toolCallId = asText(part.toolCallId);
|
|
312
|
+
if (!toolName || !toolCallId)
|
|
313
|
+
return [];
|
|
314
|
+
const content = normalizeBlocks(part.content);
|
|
315
|
+
return [
|
|
316
|
+
{
|
|
317
|
+
type: "action",
|
|
318
|
+
content: {
|
|
319
|
+
status: "started",
|
|
320
|
+
actionName: toolName,
|
|
321
|
+
actionCallId: toolCallId,
|
|
322
|
+
input: blocksToValue(content),
|
|
323
|
+
},
|
|
324
|
+
},
|
|
325
|
+
];
|
|
326
|
+
}
|
|
327
|
+
function normalizeLegacyToolResultPart(part) {
|
|
328
|
+
const toolName = asText(part.toolName);
|
|
329
|
+
const toolCallId = asText(part.toolCallId);
|
|
330
|
+
if (!toolName || !toolCallId)
|
|
331
|
+
return [];
|
|
332
|
+
const content = normalizeBlocks(part.content);
|
|
333
|
+
const state = asText(part.state).toLowerCase();
|
|
334
|
+
const failed = state === "output-error";
|
|
335
|
+
return [
|
|
336
|
+
failed
|
|
337
|
+
? {
|
|
338
|
+
type: "action",
|
|
339
|
+
content: {
|
|
340
|
+
status: "failed",
|
|
341
|
+
actionName: toolName,
|
|
342
|
+
actionCallId: toolCallId,
|
|
343
|
+
error: {
|
|
344
|
+
message: blocksToErrorText(content) || "Action failed.",
|
|
345
|
+
},
|
|
346
|
+
},
|
|
347
|
+
}
|
|
348
|
+
: {
|
|
349
|
+
type: "action",
|
|
350
|
+
content: {
|
|
351
|
+
status: "completed",
|
|
352
|
+
actionName: toolName,
|
|
353
|
+
actionCallId: toolCallId,
|
|
354
|
+
output: blocksToValue(content),
|
|
355
|
+
},
|
|
356
|
+
},
|
|
357
|
+
];
|
|
358
|
+
}
|
|
359
|
+
function normalizePart(part) {
|
|
360
|
+
const record = asRecord(part);
|
|
361
|
+
if (!record || typeof record.type !== "string") {
|
|
362
|
+
return record ? [record] : [];
|
|
363
|
+
}
|
|
364
|
+
if (record.type === "text" || record.type === "file") {
|
|
365
|
+
return [record];
|
|
366
|
+
}
|
|
367
|
+
if (record.type === "source-url" || record.type === "source-document") {
|
|
368
|
+
const source = normalizeContentBlock(record);
|
|
369
|
+
return source ? [source] : [];
|
|
370
|
+
}
|
|
371
|
+
if (record.type === "content") {
|
|
372
|
+
const blocks = normalizeBlocks(record.content);
|
|
373
|
+
const content = blocksToMessageContent(blocks);
|
|
374
|
+
return Object.keys(content).length > 0
|
|
375
|
+
? [{ type: "message", content }]
|
|
376
|
+
: [];
|
|
377
|
+
}
|
|
378
|
+
if (record.type === "message") {
|
|
379
|
+
return normalizeMessagePart(record);
|
|
380
|
+
}
|
|
381
|
+
if (record.type === "reasoning") {
|
|
382
|
+
return normalizeReasoningPart(record);
|
|
383
|
+
}
|
|
384
|
+
if (record.type === "source") {
|
|
385
|
+
return normalizeSourcePart(record);
|
|
386
|
+
}
|
|
387
|
+
if (record.type === "action" || record.type === "action_result") {
|
|
388
|
+
return normalizeActionPart(record);
|
|
389
|
+
}
|
|
390
|
+
if (record.type === "tool-call") {
|
|
391
|
+
return normalizeLegacyToolCallPart(record);
|
|
392
|
+
}
|
|
393
|
+
if (record.type === "tool-result") {
|
|
394
|
+
return normalizeLegacyToolResultPart(record);
|
|
395
|
+
}
|
|
396
|
+
if (record.type.startsWith("tool-")) {
|
|
397
|
+
return normalizeLegacyToolPart(record);
|
|
398
|
+
}
|
|
399
|
+
if (record.type.startsWith("data-")) {
|
|
400
|
+
return [
|
|
401
|
+
{
|
|
402
|
+
type: "message",
|
|
403
|
+
content: {
|
|
404
|
+
blocks: [{ type: "json", value: record.data }],
|
|
405
|
+
},
|
|
406
|
+
},
|
|
407
|
+
];
|
|
408
|
+
}
|
|
409
|
+
return [record];
|
|
410
|
+
}
|
|
411
|
+
export function normalizeContextEventParts(parts) {
|
|
412
|
+
return (Array.isArray(parts) ? parts : []).flatMap(normalizePart);
|
|
413
|
+
}
|
|
414
|
+
export function getActionPartInfo(part) {
|
|
415
|
+
const record = asRecord(part);
|
|
416
|
+
if (!record)
|
|
417
|
+
return null;
|
|
418
|
+
if (typeof record.type === "string" && record.type.startsWith("tool-")) {
|
|
419
|
+
const actionName = record.type.slice("tool-".length);
|
|
420
|
+
const status = normalizeActionStatus(record.state);
|
|
421
|
+
return {
|
|
422
|
+
actionName,
|
|
423
|
+
actionCallId: asText(record.toolCallId) || asText(record.actionCallId) || actionName,
|
|
424
|
+
status,
|
|
425
|
+
input: record.input ?? record.args,
|
|
426
|
+
output: record.output,
|
|
427
|
+
errorText: readTextPayload(record.errorText ?? record.error),
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
if (record.type !== "action" && record.type !== "action_result") {
|
|
431
|
+
return null;
|
|
432
|
+
}
|
|
433
|
+
const content = asRecord(record.content) ?? {};
|
|
434
|
+
const actionName = asText(content.actionName) ||
|
|
435
|
+
asText(content.toolName) ||
|
|
436
|
+
asText(record.actionName) ||
|
|
437
|
+
asText(record.toolName);
|
|
438
|
+
if (!actionName)
|
|
439
|
+
return null;
|
|
440
|
+
const output = content.output ?? record.output;
|
|
441
|
+
const error = content.error ?? content.errorText ?? record.error ?? record.errorText;
|
|
442
|
+
const status = normalizeActionStatus(content.status ?? record.status, error !== undefined ? "failed" : output !== undefined ? "completed" : "started");
|
|
443
|
+
return {
|
|
444
|
+
actionName,
|
|
445
|
+
actionCallId: asText(content.actionCallId) ||
|
|
446
|
+
asText(content.toolCallId) ||
|
|
447
|
+
asText(content.actionRef) ||
|
|
448
|
+
asText(record.actionCallId) ||
|
|
449
|
+
asText(record.toolCallId) ||
|
|
450
|
+
asText(record.actionRef) ||
|
|
451
|
+
actionName,
|
|
452
|
+
status,
|
|
453
|
+
input: content.input ?? record.input,
|
|
454
|
+
output,
|
|
455
|
+
errorText: readTextPayload(error),
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
export function getCreateMessageText(part) {
|
|
459
|
+
const action = getActionPartInfo(part);
|
|
460
|
+
if (!action || action.actionName !== "createMessage")
|
|
461
|
+
return "";
|
|
462
|
+
if (action.status === "completed") {
|
|
463
|
+
return readTextPayload(action.output) || readTextPayload(action.input);
|
|
464
|
+
}
|
|
465
|
+
return readTextPayload(action.input) || readTextPayload(action.output);
|
|
466
|
+
}
|
|
467
|
+
export function getPartText(part) {
|
|
468
|
+
const record = asRecord(part);
|
|
469
|
+
if (!record)
|
|
470
|
+
return "";
|
|
471
|
+
if (record.type === "text")
|
|
472
|
+
return asText(record.text);
|
|
473
|
+
if (record.type === "message")
|
|
474
|
+
return readTextPayload(record.content) || readTextPayload(record);
|
|
475
|
+
return "";
|
|
476
|
+
}
|
|
477
|
+
export function getReasoningText(part) {
|
|
478
|
+
const record = asRecord(part);
|
|
479
|
+
if (!record || record.type !== "reasoning")
|
|
480
|
+
return "";
|
|
481
|
+
return readTextPayload(record.content) || asText(record.text);
|
|
482
|
+
}
|
|
483
|
+
export function getReasoningState(part) {
|
|
484
|
+
const record = asRecord(part);
|
|
485
|
+
if (!record || record.type !== "reasoning")
|
|
486
|
+
return "";
|
|
487
|
+
return asText(asRecord(record.content)?.state) || asText(record.state);
|
|
488
|
+
}
|
|
489
|
+
export function getSourceParts(part) {
|
|
490
|
+
const record = asRecord(part);
|
|
491
|
+
if (!record)
|
|
492
|
+
return [];
|
|
493
|
+
if (record.type === "source-url" || record.type === "source-document") {
|
|
494
|
+
return [record];
|
|
495
|
+
}
|
|
496
|
+
if (record.type !== "source")
|
|
497
|
+
return [];
|
|
498
|
+
const sources = asRecord(record.content)?.sources;
|
|
499
|
+
return Array.isArray(sources)
|
|
500
|
+
? sources.filter((source) => asRecord(source))
|
|
501
|
+
: [];
|
|
502
|
+
}
|
|
503
|
+
export function findNormalizedToolPart(parts, toolName) {
|
|
504
|
+
const normalized = normalizeContextEventParts(parts);
|
|
505
|
+
return (normalized.find((part) => {
|
|
506
|
+
const action = getActionPartInfo(part);
|
|
507
|
+
return action?.actionName === toolName;
|
|
508
|
+
}) ?? null);
|
|
509
|
+
}
|
package/dist/react.d.ts
CHANGED
|
@@ -1,42 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
export type
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
content: Context;
|
|
9
|
-
createdAt: string | null;
|
|
10
|
-
updatedAt: string | null;
|
|
11
|
-
} | null;
|
|
12
|
-
items: Item[];
|
|
13
|
-
};
|
|
14
|
-
export type ContextStreamChunk = {
|
|
15
|
-
type: `data-context.${string}`;
|
|
16
|
-
data?: {
|
|
17
|
-
contextId?: string;
|
|
18
|
-
};
|
|
19
|
-
} | {
|
|
20
|
-
type: string;
|
|
21
|
-
[key: string]: unknown;
|
|
22
|
-
};
|
|
23
|
-
export type UseContextOptions<Context = unknown, Item = Record<string, unknown>> = {
|
|
24
|
-
contextKey: string;
|
|
25
|
-
orgId?: string;
|
|
26
|
-
endpoint?: string;
|
|
27
|
-
refreshMs?: number;
|
|
28
|
-
ensure?: boolean;
|
|
29
|
-
enabled?: boolean;
|
|
30
|
-
initialData?: ContextSnapshot<Context, Item> | null;
|
|
31
|
-
fetchImpl?: typeof fetch;
|
|
32
|
-
};
|
|
33
|
-
export declare function useContext<Context = unknown, Item = Record<string, unknown>>(options: UseContextOptions<Context, Item>): {
|
|
34
|
-
data: ContextSnapshot<Context, Item> | null;
|
|
35
|
-
isLoading: boolean;
|
|
36
|
-
error: string | null;
|
|
37
|
-
refresh: () => Promise<void>;
|
|
38
|
-
setData: import("react").Dispatch<import("react").SetStateAction<ContextSnapshot<Context, Item> | null>>;
|
|
39
|
-
contextId: string | null;
|
|
40
|
-
applyChunk: (chunk: ContextStreamChunk) => void;
|
|
41
|
-
url: string;
|
|
42
|
-
};
|
|
1
|
+
export { mergeContextStepPartsForUI, useContext } from "./react.use-context";
|
|
2
|
+
export type { AppendArgs, ContextEventForUI, ContextFirstLevel, ContextStepForUI, ContextStepRuntime, ContextStepStreamInfo, ContextStepStreamReaderInfo, ContextStatus, ContextValue, ReasoningLevel, SendStatus, UseContextArgs, UseContextOptions, UseContextState, UseContextStateHook, } from "./react.types";
|
|
3
|
+
export { ASSISTANT_MESSAGE_TYPE, INPUT_TEXT_ITEM_TYPE } from "./react.types";
|
|
4
|
+
export { findNormalizedToolPart, getActionPartInfo, getCreateMessageText, getPartText, getReasoningState, getReasoningText, getSourceParts, normalizeContextEventParts, } from "./react.context-event-parts";
|
|
5
|
+
export type { ContextActionPartInfo } from "./react.context-event-parts";
|
|
6
|
+
export { buildContextStepViews, buildEventStepsIndex, buildLiveEventFromStepChunks, consumePersistedContextStepStream, extractPersistedContextTree, isUserEvent, } from "./react.step-stream";
|
|
7
|
+
export type { PersistedContextTree } from "./react.step-stream";
|
package/dist/react.js
CHANGED
|
@@ -1,88 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
return String(error ?? "unknown_error");
|
|
7
|
-
}
|
|
8
|
-
function buildContextUrl(options) {
|
|
9
|
-
const base = String(options.endpoint || "/api/context").replace(/\/+$/, "");
|
|
10
|
-
const key = encodeURIComponent(options.contextKey);
|
|
11
|
-
const params = new URLSearchParams();
|
|
12
|
-
if (options.orgId)
|
|
13
|
-
params.set("orgId", options.orgId);
|
|
14
|
-
if (options.ensure)
|
|
15
|
-
params.set("ensure", "1");
|
|
16
|
-
const query = params.toString();
|
|
17
|
-
return query.length > 0 ? `${base}/${key}?${query}` : `${base}/${key}`;
|
|
18
|
-
}
|
|
19
|
-
export function useContext(options) {
|
|
20
|
-
const [data, setData] = useState(options.initialData ?? null);
|
|
21
|
-
const [isLoading, setIsLoading] = useState(true);
|
|
22
|
-
const [error, setError] = useState(null);
|
|
23
|
-
const [contextId, setContextId] = useState(null);
|
|
24
|
-
const enabled = options.enabled ?? true;
|
|
25
|
-
const url = useMemo(() => {
|
|
26
|
-
if (!enabled || !options.contextKey)
|
|
27
|
-
return "";
|
|
28
|
-
return buildContextUrl(options);
|
|
29
|
-
}, [enabled, options.endpoint, options.orgId, options.contextKey, options.ensure]);
|
|
30
|
-
const refresh = useCallback(async () => {
|
|
31
|
-
if (!enabled || !options.contextKey)
|
|
32
|
-
return;
|
|
33
|
-
setIsLoading(true);
|
|
34
|
-
setError(null);
|
|
35
|
-
const fetchImpl = options.fetchImpl ?? fetch;
|
|
36
|
-
try {
|
|
37
|
-
const response = await fetchImpl(url, { cache: "no-store" });
|
|
38
|
-
if (!response.ok) {
|
|
39
|
-
const body = await response.text();
|
|
40
|
-
throw new Error(body || `context_fetch_failed:${response.status}`);
|
|
41
|
-
}
|
|
42
|
-
const snapshot = (await response.json());
|
|
43
|
-
setData(snapshot);
|
|
44
|
-
setContextId(snapshot.context?.id ?? null);
|
|
45
|
-
}
|
|
46
|
-
catch (err) {
|
|
47
|
-
setError(toErrorMessage(err));
|
|
48
|
-
}
|
|
49
|
-
finally {
|
|
50
|
-
setIsLoading(false);
|
|
51
|
-
}
|
|
52
|
-
}, [enabled, options.fetchImpl, options.contextKey, url]);
|
|
53
|
-
const applyChunk = useCallback((chunk) => {
|
|
54
|
-
if (!chunk || typeof chunk !== "object")
|
|
55
|
-
return;
|
|
56
|
-
if (typeof chunk.type === "string" && chunk.type.startsWith("data-context.")) {
|
|
57
|
-
const payload = "data" in chunk && chunk.data && typeof chunk.data === "object"
|
|
58
|
-
? chunk.data
|
|
59
|
-
: undefined;
|
|
60
|
-
const candidate = typeof payload?.contextId === "string"
|
|
61
|
-
? payload.contextId
|
|
62
|
-
: null;
|
|
63
|
-
if (candidate)
|
|
64
|
-
setContextId(candidate);
|
|
65
|
-
}
|
|
66
|
-
}, []);
|
|
67
|
-
useEffect(() => {
|
|
68
|
-
void refresh();
|
|
69
|
-
}, [refresh]);
|
|
70
|
-
useEffect(() => {
|
|
71
|
-
if (!enabled || !options.refreshMs || options.refreshMs <= 0)
|
|
72
|
-
return;
|
|
73
|
-
const intervalId = setInterval(() => {
|
|
74
|
-
void refresh();
|
|
75
|
-
}, options.refreshMs);
|
|
76
|
-
return () => clearInterval(intervalId);
|
|
77
|
-
}, [enabled, options.refreshMs, refresh]);
|
|
78
|
-
return {
|
|
79
|
-
data,
|
|
80
|
-
isLoading,
|
|
81
|
-
error,
|
|
82
|
-
refresh,
|
|
83
|
-
setData,
|
|
84
|
-
contextId,
|
|
85
|
-
applyChunk,
|
|
86
|
-
url,
|
|
87
|
-
};
|
|
88
|
-
}
|
|
2
|
+
export { mergeContextStepPartsForUI, useContext } from "./react.use-context";
|
|
3
|
+
export { ASSISTANT_MESSAGE_TYPE, INPUT_TEXT_ITEM_TYPE } from "./react.types";
|
|
4
|
+
export { findNormalizedToolPart, getActionPartInfo, getCreateMessageText, getPartText, getReasoningState, getReasoningText, getSourceParts, normalizeContextEventParts, } from "./react.context-event-parts";
|
|
5
|
+
export { buildContextStepViews, buildEventStepsIndex, buildLiveEventFromStepChunks, consumePersistedContextStepStream, extractPersistedContextTree, isUserEvent, } from "./react.step-stream";
|