@ekairos/events 1.22.32-beta.development.0 → 1.22.33-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/README.md +61 -0
- package/dist/context.engine.js +29 -7
- package/dist/context.events.d.ts +20 -0
- package/dist/context.events.js +352 -7
- package/dist/context.parts.d.ts +241 -0
- package/dist/context.parts.js +360 -0
- package/dist/context.store.d.ts +5 -0
- package/dist/context.toolcalls.js +55 -11
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2 -1
- package/dist/schema.js +3 -2
- package/dist/stores/instant.store.d.ts +2 -0
- package/dist/stores/instant.store.js +100 -5
- package/package.json +2 -2
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* Keeping this logic here helps `context.engine.ts` read like orchestration, and keeps
|
|
13
13
|
* these transformations testable and reusable.
|
|
14
14
|
*/
|
|
15
|
+
import { isContextPartEnvelope, normalizePartsForPersistence, normalizeToolResultContentToBlocks, } from "./context.parts.js";
|
|
15
16
|
/**
|
|
16
17
|
* Extracts tool calls from an event's `parts` array.
|
|
17
18
|
*
|
|
@@ -25,6 +26,16 @@
|
|
|
25
26
|
export function extractToolCallsFromParts(parts) {
|
|
26
27
|
const safeParts = parts ?? [];
|
|
27
28
|
return safeParts.reduce((acc, p) => {
|
|
29
|
+
if (isContextPartEnvelope(p) && p.type === "tool-call") {
|
|
30
|
+
const firstContent = Array.isArray(p.content) ? p.content[0] : undefined;
|
|
31
|
+
const args = firstContent && firstContent.type === "json" ? firstContent.value : p.content;
|
|
32
|
+
acc.push({
|
|
33
|
+
toolCallId: p.toolCallId,
|
|
34
|
+
toolName: p.toolName,
|
|
35
|
+
args,
|
|
36
|
+
});
|
|
37
|
+
return acc;
|
|
38
|
+
}
|
|
28
39
|
if (typeof p?.type === "string" && p.type.startsWith("tool-")) {
|
|
29
40
|
const toolName = p.type.split("-").slice(1).join("-");
|
|
30
41
|
acc.push({ toolCallId: p.toolCallId, toolName, args: p.input });
|
|
@@ -46,15 +57,45 @@ export function extractToolCallsFromParts(parts) {
|
|
|
46
57
|
* - on failure: `{ state: "output-error", errorText: <message> }`
|
|
47
58
|
*/
|
|
48
59
|
export function applyToolExecutionResultToParts(parts, toolCall, execution) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
60
|
+
const normalized = normalizePartsForPersistence(parts);
|
|
61
|
+
const next = [];
|
|
62
|
+
let insertedResult = false;
|
|
63
|
+
const resultContent = execution.success
|
|
64
|
+
? normalizeToolResultContentToBlocks(execution.result)
|
|
65
|
+
: [
|
|
66
|
+
{
|
|
67
|
+
type: "text",
|
|
68
|
+
text: String(execution.message || "Error"),
|
|
69
|
+
},
|
|
70
|
+
];
|
|
71
|
+
for (const part of normalized) {
|
|
72
|
+
next.push(part);
|
|
73
|
+
if (part.type !== "tool-call") {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (part.toolCallId !== toolCall.toolCallId ||
|
|
77
|
+
part.toolName !== toolCall.toolName) {
|
|
78
|
+
continue;
|
|
55
79
|
}
|
|
56
|
-
|
|
57
|
-
|
|
80
|
+
next.push({
|
|
81
|
+
type: "tool-result",
|
|
82
|
+
toolCallId: toolCall.toolCallId,
|
|
83
|
+
toolName: toolCall.toolName,
|
|
84
|
+
state: execution.success ? "output-available" : "output-error",
|
|
85
|
+
content: resultContent,
|
|
86
|
+
});
|
|
87
|
+
insertedResult = true;
|
|
88
|
+
}
|
|
89
|
+
if (!insertedResult) {
|
|
90
|
+
next.push({
|
|
91
|
+
type: "tool-result",
|
|
92
|
+
toolCallId: toolCall.toolCallId,
|
|
93
|
+
toolName: toolCall.toolName,
|
|
94
|
+
state: execution.success ? "output-available" : "output-error",
|
|
95
|
+
content: resultContent,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
return next;
|
|
58
99
|
}
|
|
59
100
|
/**
|
|
60
101
|
* Returns `true` when a given tool has a **settled** execution result in an event's parts.
|
|
@@ -67,7 +108,10 @@ export function applyToolExecutionResultToParts(parts, toolCall, execution) {
|
|
|
67
108
|
* decide based on the persisted `reactionEvent` (not ephemeral in-memory arrays).
|
|
68
109
|
*/
|
|
69
110
|
export function didToolExecute(event, toolName) {
|
|
70
|
-
const parts = event.content.parts;
|
|
71
|
-
return parts.some((p) => p.type ===
|
|
72
|
-
|
|
111
|
+
const parts = (event.content.parts ?? []).flatMap((part) => isContextPartEnvelope(part) ? [part] : normalizePartsForPersistence([part]));
|
|
112
|
+
return parts.some((p) => (p.type === "tool-result" &&
|
|
113
|
+
p.toolName === toolName &&
|
|
114
|
+
(p.state === "output-available" || p.state === "output-error")) ||
|
|
115
|
+
(p.type === `tool-${toolName}` &&
|
|
116
|
+
(p.state === "output-available" || p.state === "output-error")));
|
|
73
117
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,9 @@ export type { WireDate, ContextMirrorContext, ContextMirrorExecution, ContextMir
|
|
|
4
4
|
export { registerContext, getContext, getContextFactory, hasContext, listContexts, type ContextKey, } from "./context.registry.js";
|
|
5
5
|
export { eventsDomain } from "./schema.js";
|
|
6
6
|
export { didToolExecute, extractToolCallsFromParts } from "./context.toolcalls.js";
|
|
7
|
-
export {
|
|
7
|
+
export { contextPartSchema, contextPartEnvelopeSchema, contextPartContentSchema, isContextPartEnvelope, parseContextPartEnvelope, normalizePartsForPersistence, } from "./context.parts.js";
|
|
8
|
+
export type { ContextPart, ContextPartEnvelope, ContextPartContent, } from "./context.parts.js";
|
|
9
|
+
export { INPUT_ITEM_TYPE, INPUT_TEXT_ITEM_TYPE, OUTPUT_ITEM_TYPE, WEB_CHANNEL, AGENT_CHANNEL, EMAIL_CHANNEL, createUserItemFromUIMessages, createAssistantItemFromUIMessages, convertToUIMessage, convertItemToModelMessages, convertItemsToModelMessages, convertModelMessageToItem, isContextOutputPart, normalizeContextOutputPart, type ResponseMessage, type ContextOutputPart, type ContextOutputContentPart, } from "./context.events.js";
|
|
8
10
|
export { CONTEXT_STATUSES, EXECUTION_STATUSES, STEP_STATUSES, STEP_KINDS, ITEM_STATUSES, ITEM_TYPES, CHANNELS, TRACE_EVENT_KINDS, CONTEXT_STREAM_CHUNK_TYPES, STREAM_LIFECYCLE_CHUNK_TYPES, STREAM_TEXT_CHUNK_TYPES, STREAM_REASONING_CHUNK_TYPES, STREAM_ACTION_CHUNK_TYPES, STREAM_SOURCE_CHUNK_TYPES, STREAM_METADATA_CHUNK_TYPES, STREAM_ERROR_CHUNK_TYPES, CONTEXT_TRANSITIONS, EXECUTION_TRANSITIONS, STEP_TRANSITIONS, ITEM_TRANSITIONS, canContextTransition, canExecutionTransition, canStepTransition, canItemTransition, assertContextTransition, assertExecutionTransition, assertStepTransition, assertItemTransition, isContextStreamChunkType, assertContextPartKey, } from "./context.contract.js";
|
|
9
11
|
export type { Transition, ContextStatus, ExecutionStatus, StepStatus, StepKind, ItemStatus, ItemType, Channel, TraceEventKind, ContextStreamChunkType, ContextTransition, ExecutionTransition, StepTransition, ItemTransition, } from "./context.contract.js";
|
|
10
12
|
export { DEFAULT_CODEX_TOOL_NAME, DEFAULT_CODEX_MODEL, codexToolInputSchema, buildDefaultCodexNarrative, didCodexToolExecute, createCodexContextBuilder, type CodexContextRuntimeMode, type CodexContextReasoningLevel, type CodexContextRuntime, type CodexContextEnv, type CodexToolInput, type CodexToolOutput, type CodexExecuteArgs, type CodexContextBuilderConfig, type CodexContextBuilder, } from "./codex.js";
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,8 @@ export { context, createContext, createAiSdkReactor, createScriptedReactor, Cont
|
|
|
2
2
|
export { registerContext, getContext, getContextFactory, hasContext, listContexts, } from "./context.registry.js";
|
|
3
3
|
export { eventsDomain } from "./schema.js";
|
|
4
4
|
export { didToolExecute, extractToolCallsFromParts } from "./context.toolcalls.js";
|
|
5
|
-
export {
|
|
5
|
+
export { contextPartSchema, contextPartEnvelopeSchema, contextPartContentSchema, isContextPartEnvelope, parseContextPartEnvelope, normalizePartsForPersistence, } from "./context.parts.js";
|
|
6
|
+
export { INPUT_ITEM_TYPE, INPUT_TEXT_ITEM_TYPE, OUTPUT_ITEM_TYPE, WEB_CHANNEL, AGENT_CHANNEL, EMAIL_CHANNEL, createUserItemFromUIMessages, createAssistantItemFromUIMessages, convertToUIMessage, convertItemToModelMessages, convertItemsToModelMessages, convertModelMessageToItem, isContextOutputPart, normalizeContextOutputPart, } from "./context.events.js";
|
|
6
7
|
export { CONTEXT_STATUSES, EXECUTION_STATUSES, STEP_STATUSES, STEP_KINDS, ITEM_STATUSES, ITEM_TYPES, CHANNELS, TRACE_EVENT_KINDS, CONTEXT_STREAM_CHUNK_TYPES, STREAM_LIFECYCLE_CHUNK_TYPES, STREAM_TEXT_CHUNK_TYPES, STREAM_REASONING_CHUNK_TYPES, STREAM_ACTION_CHUNK_TYPES, STREAM_SOURCE_CHUNK_TYPES, STREAM_METADATA_CHUNK_TYPES, STREAM_ERROR_CHUNK_TYPES, CONTEXT_TRANSITIONS, EXECUTION_TRANSITIONS, STEP_TRANSITIONS, ITEM_TRANSITIONS, canContextTransition, canExecutionTransition, canStepTransition, canItemTransition, assertContextTransition, assertExecutionTransition, assertStepTransition, assertItemTransition, isContextStreamChunkType, assertContextPartKey, } from "./context.contract.js";
|
|
7
8
|
export { DEFAULT_CODEX_TOOL_NAME, DEFAULT_CODEX_MODEL, codexToolInputSchema, buildDefaultCodexNarrative, didCodexToolExecute, createCodexContextBuilder, } from "./codex.js";
|
|
8
9
|
export { useContext, } from "./react.js";
|
package/dist/schema.js
CHANGED
|
@@ -52,8 +52,9 @@ export const eventsDomain = domain("events")
|
|
|
52
52
|
key: i.string().unique().indexed(), // `${stepId}:${idx}`
|
|
53
53
|
stepId: i.string().indexed(),
|
|
54
54
|
idx: i.number().indexed(),
|
|
55
|
-
type: i.string().optional().indexed(),
|
|
56
|
-
part: i.
|
|
55
|
+
type: i.string().optional().indexed(), // canonical part.type
|
|
56
|
+
part: i.json().optional(),
|
|
57
|
+
metadata: i.json().optional(), // provider/model/runtime metadata only
|
|
57
58
|
updatedAt: i.date().optional(),
|
|
58
59
|
}),
|
|
59
60
|
event_trace_events: i.entity({
|
|
@@ -20,6 +20,8 @@ export declare class InstantStore implements ContextStore {
|
|
|
20
20
|
updateItem(eventId: string, event: ContextItem): Promise<ContextItem>;
|
|
21
21
|
getItem(eventId: string): Promise<ContextItem | null>;
|
|
22
22
|
getItems(contextIdentifier: ContextIdentifier): Promise<ContextItem[]>;
|
|
23
|
+
private getExecutionIdForItem;
|
|
24
|
+
private getProjectedPartsForOutputItem;
|
|
23
25
|
createExecution(contextIdentifier: ContextIdentifier, triggerEventId: string, reactionEventId: string): Promise<{
|
|
24
26
|
id: string;
|
|
25
27
|
}>;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import "../polyfills/dom-events.js";
|
|
2
2
|
import { id, lookup } from "@instantdb/admin";
|
|
3
|
-
import {
|
|
3
|
+
import { convertItemToModelMessages } from "../context.events.js";
|
|
4
4
|
import { assertContextTransition, assertExecutionTransition, assertItemTransition, assertStepTransition, } from "../context.contract.js";
|
|
5
5
|
export { parseAndStoreDocument } from "./instant.document-parser.js";
|
|
6
6
|
import { expandEventsWithInstantDocuments } from "./instant.documents.js";
|
|
7
7
|
export { coerceDocumentTextPages, expandEventsWithInstantDocuments, } from "./instant.documents.js";
|
|
8
|
+
import { mergeContextPartEnvelope, normalizePartsForPersistence, splitContextPartEnvelope, } from "../context.parts.js";
|
|
8
9
|
function shouldDebugInstantStore() {
|
|
9
10
|
return (process.env.EKAIROS_CONTEXT_DEBUG === "1" ||
|
|
10
11
|
process.env.EKAIROS_CONTEXT_DEBUG === "1" ||
|
|
@@ -307,6 +308,81 @@ export class InstantStore {
|
|
|
307
308
|
}
|
|
308
309
|
return sortItems((res.event_items ?? []));
|
|
309
310
|
}
|
|
311
|
+
async getExecutionIdForItem(itemId) {
|
|
312
|
+
const directResult = await this.db.query({
|
|
313
|
+
event_items: {
|
|
314
|
+
$: { where: { id: itemId }, limit: 1 },
|
|
315
|
+
execution: {},
|
|
316
|
+
},
|
|
317
|
+
});
|
|
318
|
+
const directRow = directResult?.event_items?.[0];
|
|
319
|
+
const directExecutionId = directRow?.execution?.id;
|
|
320
|
+
if (typeof directExecutionId === "string" &&
|
|
321
|
+
directExecutionId.trim().length > 0) {
|
|
322
|
+
return directExecutionId;
|
|
323
|
+
}
|
|
324
|
+
const reverseResult = await this.db.query({
|
|
325
|
+
event_executions: {
|
|
326
|
+
$: { where: { "reaction.id": itemId }, limit: 1 },
|
|
327
|
+
},
|
|
328
|
+
});
|
|
329
|
+
const reverseRow = reverseResult?.event_executions?.[0];
|
|
330
|
+
const reverseExecutionId = reverseRow?.id;
|
|
331
|
+
return typeof reverseExecutionId === "string" && reverseExecutionId.trim().length > 0
|
|
332
|
+
? reverseExecutionId
|
|
333
|
+
: null;
|
|
334
|
+
}
|
|
335
|
+
async getProjectedPartsForOutputItem(itemId) {
|
|
336
|
+
const executionId = await this.getExecutionIdForItem(itemId);
|
|
337
|
+
if (!executionId) {
|
|
338
|
+
return null;
|
|
339
|
+
}
|
|
340
|
+
const stepResult = await this.db.query({
|
|
341
|
+
event_steps: {
|
|
342
|
+
$: {
|
|
343
|
+
where: { "execution.id": executionId },
|
|
344
|
+
limit: 200,
|
|
345
|
+
},
|
|
346
|
+
},
|
|
347
|
+
});
|
|
348
|
+
const steps = sortItems((stepResult?.event_steps ?? [])).sort((a, b) => {
|
|
349
|
+
const ai = typeof a?.iteration === "number" ? a.iteration : 0;
|
|
350
|
+
const bi = typeof b?.iteration === "number" ? b.iteration : 0;
|
|
351
|
+
if (ai !== bi)
|
|
352
|
+
return ai - bi;
|
|
353
|
+
return String(a?.id ?? "").localeCompare(String(b?.id ?? ""));
|
|
354
|
+
});
|
|
355
|
+
if (steps.length === 0) {
|
|
356
|
+
return null;
|
|
357
|
+
}
|
|
358
|
+
const projectedParts = [];
|
|
359
|
+
for (const step of steps) {
|
|
360
|
+
const stepId = typeof step?.id === "string" ? step.id : "";
|
|
361
|
+
if (!stepId)
|
|
362
|
+
continue;
|
|
363
|
+
const partResult = await this.db.query({
|
|
364
|
+
event_parts: {
|
|
365
|
+
$: {
|
|
366
|
+
where: { stepId: stepId },
|
|
367
|
+
limit: 500,
|
|
368
|
+
order: { idx: "asc" },
|
|
369
|
+
},
|
|
370
|
+
},
|
|
371
|
+
});
|
|
372
|
+
const partRows = (partResult?.event_parts ?? []).sort((a, b) => {
|
|
373
|
+
const ai = typeof a?.idx === "number" ? a.idx : 0;
|
|
374
|
+
const bi = typeof b?.idx === "number" ? b.idx : 0;
|
|
375
|
+
if (ai !== bi)
|
|
376
|
+
return ai - bi;
|
|
377
|
+
return 0;
|
|
378
|
+
});
|
|
379
|
+
projectedParts.push(...partRows.map((row) => mergeContextPartEnvelope({
|
|
380
|
+
part: row?.part,
|
|
381
|
+
metadata: row?.metadata,
|
|
382
|
+
})));
|
|
383
|
+
}
|
|
384
|
+
return projectedParts;
|
|
385
|
+
}
|
|
310
386
|
async createExecution(contextIdentifier, triggerEventId, reactionEventId) {
|
|
311
387
|
const normalizedTriggerEventId = ensureValidEntityId(triggerEventId, "triggerEventId");
|
|
312
388
|
const normalizedReactionEventId = ensureValidEntityId(reactionEventId, "reactionEventId");
|
|
@@ -433,17 +509,19 @@ export class InstantStore {
|
|
|
433
509
|
]);
|
|
434
510
|
}
|
|
435
511
|
async saveStepParts(params) {
|
|
436
|
-
const parts = Array.isArray(params.parts) ? params.parts : [];
|
|
512
|
+
const parts = normalizePartsForPersistence(Array.isArray(params.parts) ? params.parts : []);
|
|
437
513
|
if (parts.length === 0)
|
|
438
514
|
return;
|
|
439
515
|
const txs = parts.map((part, idx) => {
|
|
440
516
|
const key = `${params.stepId}:${idx}`;
|
|
517
|
+
const split = splitContextPartEnvelope(part);
|
|
441
518
|
return this.db.tx.event_parts[lookup("key", key)]
|
|
442
519
|
.update({
|
|
443
520
|
stepId: params.stepId,
|
|
444
521
|
idx,
|
|
445
|
-
type: typeof part?.type === "string" ? String(part.type) : undefined,
|
|
446
|
-
part,
|
|
522
|
+
type: typeof split.part?.type === "string" ? String(split.part.type) : undefined,
|
|
523
|
+
part: split.part,
|
|
524
|
+
metadata: split.metadata,
|
|
447
525
|
updatedAt: new Date(),
|
|
448
526
|
})
|
|
449
527
|
.link({ step: params.stepId });
|
|
@@ -456,7 +534,24 @@ export class InstantStore {
|
|
|
456
534
|
events,
|
|
457
535
|
derivedEventType: "output",
|
|
458
536
|
});
|
|
459
|
-
|
|
537
|
+
const messages = [];
|
|
538
|
+
for (const event of expanded) {
|
|
539
|
+
const isOutputItem = event?.type === "output";
|
|
540
|
+
const projectedParts = isOutputItem
|
|
541
|
+
? await this.getProjectedPartsForOutputItem(String(event?.id ?? ""))
|
|
542
|
+
: null;
|
|
543
|
+
const projectedEvent = projectedParts && projectedParts.length > 0
|
|
544
|
+
? {
|
|
545
|
+
...event,
|
|
546
|
+
content: {
|
|
547
|
+
...(event?.content ?? {}),
|
|
548
|
+
parts: projectedParts,
|
|
549
|
+
},
|
|
550
|
+
}
|
|
551
|
+
: event;
|
|
552
|
+
messages.push(await convertItemToModelMessages(projectedEvent));
|
|
553
|
+
}
|
|
554
|
+
return messages.flat();
|
|
460
555
|
}
|
|
461
556
|
}
|
|
462
557
|
export function createInstantStoreRuntime(params) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ekairos/events",
|
|
3
|
-
"version": "1.22.
|
|
3
|
+
"version": "1.22.33-beta.development.0",
|
|
4
4
|
"description": "Ekairos Events - Context-first workflow runtime",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -116,7 +116,7 @@
|
|
|
116
116
|
},
|
|
117
117
|
"dependencies": {
|
|
118
118
|
"@ai-sdk/openai": "^2.0.52",
|
|
119
|
-
"@ekairos/domain": "^1.22.
|
|
119
|
+
"@ekairos/domain": "^1.22.33-beta.development.0",
|
|
120
120
|
"@instantdb/admin": "0.22.158",
|
|
121
121
|
"@instantdb/core": "0.22.142",
|
|
122
122
|
"@vercel/mcp-adapter": "^1.0.0",
|