@ekairos/events 1.22.4-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.
Files changed (84) hide show
  1. package/README.md +115 -0
  2. package/dist/codex.d.ts +95 -0
  3. package/dist/codex.js +91 -0
  4. package/dist/context.builder.d.ts +62 -0
  5. package/dist/context.builder.js +143 -0
  6. package/dist/context.config.d.ts +9 -0
  7. package/dist/context.config.js +30 -0
  8. package/dist/context.contract.d.ts +47 -0
  9. package/dist/context.contract.js +132 -0
  10. package/dist/context.d.ts +4 -0
  11. package/dist/context.durable.d.ts +5 -0
  12. package/dist/context.durable.js +13 -0
  13. package/dist/context.engine.d.ts +216 -0
  14. package/dist/context.engine.js +1098 -0
  15. package/dist/context.events.d.ts +55 -0
  16. package/dist/context.events.js +431 -0
  17. package/dist/context.hooks.d.ts +21 -0
  18. package/dist/context.hooks.js +31 -0
  19. package/dist/context.js +3 -0
  20. package/dist/context.parts.d.ts +241 -0
  21. package/dist/context.parts.js +360 -0
  22. package/dist/context.reactor.d.ts +3 -0
  23. package/dist/context.reactor.js +2 -0
  24. package/dist/context.registry.d.ts +13 -0
  25. package/dist/context.registry.js +30 -0
  26. package/dist/context.skill.d.ts +9 -0
  27. package/dist/context.skill.js +1 -0
  28. package/dist/context.step-stream.d.ts +26 -0
  29. package/dist/context.step-stream.js +59 -0
  30. package/dist/context.store.d.ts +85 -0
  31. package/dist/context.store.js +1 -0
  32. package/dist/context.stream.d.ts +148 -0
  33. package/dist/context.stream.js +141 -0
  34. package/dist/context.toolcalls.d.ts +60 -0
  35. package/dist/context.toolcalls.js +117 -0
  36. package/dist/env.d.ts +3 -0
  37. package/dist/env.js +53 -0
  38. package/dist/index.d.ts +18 -0
  39. package/dist/index.js +11 -0
  40. package/dist/mcp.d.ts +1 -0
  41. package/dist/mcp.js +1 -0
  42. package/dist/mirror.d.ts +41 -0
  43. package/dist/mirror.js +1 -0
  44. package/dist/oidc.d.ts +7 -0
  45. package/dist/oidc.js +25 -0
  46. package/dist/polyfills/dom-events.d.ts +1 -0
  47. package/dist/polyfills/dom-events.js +89 -0
  48. package/dist/react.d.ts +42 -0
  49. package/dist/react.js +88 -0
  50. package/dist/reactors/ai-sdk.chunk-map.d.ts +12 -0
  51. package/dist/reactors/ai-sdk.chunk-map.js +143 -0
  52. package/dist/reactors/ai-sdk.reactor.d.ts +33 -0
  53. package/dist/reactors/ai-sdk.reactor.js +65 -0
  54. package/dist/reactors/ai-sdk.step.d.ts +48 -0
  55. package/dist/reactors/ai-sdk.step.js +343 -0
  56. package/dist/reactors/scripted.reactor.d.ts +17 -0
  57. package/dist/reactors/scripted.reactor.js +51 -0
  58. package/dist/reactors/types.d.ts +52 -0
  59. package/dist/reactors/types.js +1 -0
  60. package/dist/runtime.d.ts +19 -0
  61. package/dist/runtime.js +26 -0
  62. package/dist/runtime.step.d.ts +9 -0
  63. package/dist/runtime.step.js +7 -0
  64. package/dist/schema.d.ts +2 -0
  65. package/dist/schema.js +191 -0
  66. package/dist/steps/do-context-stream-step.d.ts +34 -0
  67. package/dist/steps/do-context-stream-step.js +96 -0
  68. package/dist/steps/mirror.steps.d.ts +6 -0
  69. package/dist/steps/mirror.steps.js +48 -0
  70. package/dist/steps/store.steps.d.ts +96 -0
  71. package/dist/steps/store.steps.js +595 -0
  72. package/dist/steps/stream.steps.d.ts +86 -0
  73. package/dist/steps/stream.steps.js +270 -0
  74. package/dist/steps/trace.steps.d.ts +38 -0
  75. package/dist/steps/trace.steps.js +270 -0
  76. package/dist/stores/instant.document-parser.d.ts +6 -0
  77. package/dist/stores/instant.document-parser.js +210 -0
  78. package/dist/stores/instant.documents.d.ts +16 -0
  79. package/dist/stores/instant.documents.js +152 -0
  80. package/dist/stores/instant.store.d.ts +66 -0
  81. package/dist/stores/instant.store.js +575 -0
  82. package/dist/tools-to-model-tools.d.ts +19 -0
  83. package/dist/tools-to-model-tools.js +21 -0
  84. package/package.json +142 -0
@@ -0,0 +1,26 @@
1
+ import { type ContextStreamChunkType } from "./context.contract.js";
2
+ export declare const CONTEXT_STEP_STREAM_VERSION: 1;
3
+ export type ContextStepStreamChunk = {
4
+ version: typeof CONTEXT_STEP_STREAM_VERSION;
5
+ at: string;
6
+ sequence: number;
7
+ chunkType: ContextStreamChunkType;
8
+ provider?: string;
9
+ providerChunkType?: string;
10
+ actionRef?: string;
11
+ data?: unknown;
12
+ raw?: unknown;
13
+ };
14
+ export declare function createContextStepStreamChunk(params: {
15
+ at?: string;
16
+ sequence: number;
17
+ chunkType: ContextStreamChunkType;
18
+ provider?: string;
19
+ providerChunkType?: string;
20
+ actionRef?: string;
21
+ data?: unknown;
22
+ raw?: unknown;
23
+ }): ContextStepStreamChunk;
24
+ export declare function parseContextStepStreamChunk(value: string | unknown): ContextStepStreamChunk;
25
+ export declare function encodeContextStepStreamChunk(chunk: ContextStepStreamChunk): string;
26
+ export declare function contextStreamByteLength(value: string): number;
@@ -0,0 +1,59 @@
1
+ import { isContextStreamChunkType, } from "./context.contract.js";
2
+ export const CONTEXT_STEP_STREAM_VERSION = 1;
3
+ function assertObject(value, label) {
4
+ if (!value || typeof value !== "object") {
5
+ throw new Error(`Invalid ${label}: expected object.`);
6
+ }
7
+ }
8
+ function assertString(value, label) {
9
+ if (typeof value !== "string" || value.length === 0) {
10
+ throw new Error(`Invalid ${label}: expected non-empty string.`);
11
+ }
12
+ }
13
+ function assertNumber(value, label) {
14
+ if (typeof value !== "number" || Number.isNaN(value)) {
15
+ throw new Error(`Invalid ${label}: expected number.`);
16
+ }
17
+ }
18
+ function assertOptionalString(value, label) {
19
+ if (typeof value === "undefined")
20
+ return;
21
+ assertString(value, label);
22
+ }
23
+ export function createContextStepStreamChunk(params) {
24
+ return {
25
+ version: CONTEXT_STEP_STREAM_VERSION,
26
+ at: params.at ?? new Date().toISOString(),
27
+ sequence: params.sequence,
28
+ chunkType: params.chunkType,
29
+ provider: params.provider,
30
+ providerChunkType: params.providerChunkType,
31
+ actionRef: params.actionRef,
32
+ data: params.data,
33
+ raw: params.raw,
34
+ };
35
+ }
36
+ export function parseContextStepStreamChunk(value) {
37
+ const parsed = typeof value === "string" ? JSON.parse(value) : value;
38
+ assertObject(parsed, "context step stream chunk");
39
+ assertNumber(parsed.version, "context step stream chunk.version");
40
+ if (parsed.version !== CONTEXT_STEP_STREAM_VERSION) {
41
+ throw new Error(`Unsupported context step stream chunk version: ${String(parsed.version)}`);
42
+ }
43
+ assertString(parsed.at, "context step stream chunk.at");
44
+ assertNumber(parsed.sequence, "context step stream chunk.sequence");
45
+ assertString(parsed.chunkType, "context step stream chunk.chunkType");
46
+ if (!isContextStreamChunkType(parsed.chunkType)) {
47
+ throw new Error(`Invalid context step stream chunk.chunkType: ${String(parsed.chunkType)}`);
48
+ }
49
+ assertOptionalString(parsed.provider, "context step stream chunk.provider");
50
+ assertOptionalString(parsed.providerChunkType, "context step stream chunk.providerChunkType");
51
+ assertOptionalString(parsed.actionRef, "context step stream chunk.actionRef");
52
+ return parsed;
53
+ }
54
+ export function encodeContextStepStreamChunk(chunk) {
55
+ return `${JSON.stringify(chunk)}\n`;
56
+ }
57
+ export function contextStreamByteLength(value) {
58
+ return new TextEncoder().encode(value).length;
59
+ }
@@ -0,0 +1,85 @@
1
+ import type { ModelMessage } from "ai";
2
+ import type { ContextStatus, ExecutionStatus, StepStatus, StepKind, ItemStatus, ItemType, Channel } from "./context.contract.js";
3
+ export type ContextIdentifier = {
4
+ id: string;
5
+ key?: never;
6
+ } | {
7
+ key: string;
8
+ id?: never;
9
+ };
10
+ export type { ContextStatus } from "./context.contract.js";
11
+ export type StoredContext<Context> = {
12
+ id: string;
13
+ key: string | null;
14
+ name?: string | null;
15
+ status: ContextStatus;
16
+ createdAt: Date;
17
+ updatedAt?: Date;
18
+ content: Context | null;
19
+ };
20
+ export type ContextItem = {
21
+ id: string;
22
+ type: ItemType;
23
+ channel: Channel;
24
+ createdAt: string;
25
+ status?: ItemStatus;
26
+ content: {
27
+ /**
28
+ * Deprecated as the source of truth for output items.
29
+ * The engine maintains this field as a compatibility mirror, but
30
+ * step-level `event_parts` should be used for replay and inspection.
31
+ */
32
+ parts?: unknown[];
33
+ [key: string]: unknown;
34
+ };
35
+ };
36
+ export type ContextStep = {
37
+ id: string;
38
+ createdAt: Date;
39
+ updatedAt?: Date;
40
+ status: StepStatus;
41
+ iteration: number;
42
+ kind?: StepKind;
43
+ actionName?: string;
44
+ actionInput?: unknown;
45
+ actionOutput?: unknown;
46
+ actionError?: string;
47
+ actionRequests?: any;
48
+ actionResults?: any;
49
+ continueLoop?: boolean;
50
+ errorText?: string;
51
+ };
52
+ export type ContextExecution = {
53
+ id: string;
54
+ status: ExecutionStatus;
55
+ };
56
+ export interface ContextStore {
57
+ getOrCreateContext<C>(contextIdentifier: ContextIdentifier | null): Promise<StoredContext<C>>;
58
+ getContext<C>(contextIdentifier: ContextIdentifier): Promise<StoredContext<C> | null>;
59
+ updateContextContent<C>(contextIdentifier: ContextIdentifier, content: C): Promise<StoredContext<C>>;
60
+ updateContextStatus(contextIdentifier: ContextIdentifier, status: ContextStatus): Promise<void>;
61
+ saveItem(contextIdentifier: ContextIdentifier, item: ContextItem): Promise<ContextItem>;
62
+ updateItem(itemId: string, item: ContextItem): Promise<ContextItem>;
63
+ getItem(itemId: string): Promise<ContextItem | null>;
64
+ getItems(contextIdentifier: ContextIdentifier): Promise<ContextItem[]>;
65
+ createExecution(contextIdentifier: ContextIdentifier, triggerEventId: string, reactionEventId: string): Promise<{
66
+ id: string;
67
+ }>;
68
+ completeExecution(contextIdentifier: ContextIdentifier, executionId: string, status: Exclude<ExecutionStatus, "executing">): Promise<void>;
69
+ createStep(params: {
70
+ executionId: string;
71
+ iteration: number;
72
+ }): Promise<{
73
+ id: string;
74
+ }>;
75
+ updateStep(stepId: string, patch: Partial<Pick<ContextStep, "status" | "kind" | "actionName" | "actionInput" | "actionOutput" | "actionError" | "actionRequests" | "actionResults" | "continueLoop" | "errorText" | "updatedAt">>): Promise<void>;
76
+ saveStepParts(params: {
77
+ stepId: string;
78
+ parts: any[];
79
+ }): Promise<void>;
80
+ linkItemToExecution(params: {
81
+ itemId: string;
82
+ executionId: string;
83
+ }): Promise<void>;
84
+ itemsToModelMessages(items: ContextItem[]): Promise<ModelMessage[]>;
85
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,148 @@
1
+ import type { ContextStatus, ExecutionStatus, ItemStatus, ItemType, StepKind, StepStatus, ContextStreamChunkType } from "./context.contract.js";
2
+ type IsoDateString = string;
3
+ type ContextStreamEventBase = {
4
+ type: string;
5
+ at: IsoDateString;
6
+ };
7
+ export type ContextCreatedEvent = ContextStreamEventBase & {
8
+ type: "context.created";
9
+ contextId: string;
10
+ status: ContextStatus;
11
+ };
12
+ export type ContextResolvedEvent = ContextStreamEventBase & {
13
+ type: "context.resolved";
14
+ contextId: string;
15
+ status: ContextStatus;
16
+ };
17
+ export type ContextStatusChangedEvent = ContextStreamEventBase & {
18
+ type: "context.status_changed";
19
+ contextId: string;
20
+ status: ContextStatus;
21
+ };
22
+ export type ContextContentUpdatedEvent = ContextStreamEventBase & {
23
+ type: "context.content_updated";
24
+ contextId: string;
25
+ };
26
+ export type ExecutionCreatedEvent = ContextStreamEventBase & {
27
+ type: "execution.created";
28
+ executionId: string;
29
+ contextId: string;
30
+ status: Extract<ExecutionStatus, "executing">;
31
+ };
32
+ export type ExecutionCompletedEvent = ContextStreamEventBase & {
33
+ type: "execution.completed";
34
+ executionId: string;
35
+ contextId: string;
36
+ status: Extract<ExecutionStatus, "completed">;
37
+ };
38
+ export type ExecutionFailedEvent = ContextStreamEventBase & {
39
+ type: "execution.failed";
40
+ executionId: string;
41
+ contextId: string;
42
+ status: Extract<ExecutionStatus, "failed">;
43
+ };
44
+ export type ItemCreatedEvent = ContextStreamEventBase & {
45
+ type: "item.created";
46
+ itemId: string;
47
+ contextId: string;
48
+ executionId?: string;
49
+ status: ItemStatus;
50
+ itemType?: ItemType;
51
+ };
52
+ export type ItemUpdatedEvent = ContextStreamEventBase & {
53
+ type: "item.updated";
54
+ itemId: string;
55
+ contextId: string;
56
+ executionId?: string;
57
+ status?: ItemStatus;
58
+ };
59
+ export type ItemPendingEvent = ContextStreamEventBase & {
60
+ type: "item.pending";
61
+ itemId: string;
62
+ contextId: string;
63
+ executionId?: string;
64
+ status: "pending";
65
+ };
66
+ export type ItemCompletedEvent = ContextStreamEventBase & {
67
+ type: "item.completed";
68
+ itemId: string;
69
+ contextId: string;
70
+ executionId?: string;
71
+ status: "completed";
72
+ };
73
+ export type StepCreatedEvent = ContextStreamEventBase & {
74
+ type: "step.created";
75
+ stepId: string;
76
+ executionId: string;
77
+ iteration: number;
78
+ status: "running";
79
+ };
80
+ export type StepUpdatedEvent = ContextStreamEventBase & {
81
+ type: "step.updated";
82
+ stepId: string;
83
+ executionId: string;
84
+ iteration?: number;
85
+ status?: StepStatus;
86
+ kind?: StepKind;
87
+ actionName?: string;
88
+ };
89
+ export type StepCompletedEvent = ContextStreamEventBase & {
90
+ type: "step.completed";
91
+ stepId: string;
92
+ executionId: string;
93
+ iteration?: number;
94
+ status: "completed";
95
+ };
96
+ export type StepFailedEvent = ContextStreamEventBase & {
97
+ type: "step.failed";
98
+ stepId: string;
99
+ executionId: string;
100
+ iteration?: number;
101
+ status: "failed";
102
+ errorText?: string;
103
+ };
104
+ export type PartCreatedEvent = ContextStreamEventBase & {
105
+ type: "part.created";
106
+ partKey: string;
107
+ stepId: string;
108
+ idx: number;
109
+ partType?: string;
110
+ partPreview?: string;
111
+ partState?: string;
112
+ partToolCallId?: string;
113
+ };
114
+ export type PartUpdatedEvent = ContextStreamEventBase & {
115
+ type: "part.updated";
116
+ partKey: string;
117
+ stepId: string;
118
+ idx: number;
119
+ partType?: string;
120
+ partPreview?: string;
121
+ partState?: string;
122
+ partToolCallId?: string;
123
+ };
124
+ export type ChunkEmittedEvent = ContextStreamEventBase & {
125
+ type: "chunk.emitted";
126
+ chunkType: ContextStreamChunkType;
127
+ contextId: string;
128
+ executionId?: string;
129
+ stepId?: string;
130
+ itemId?: string;
131
+ partKey?: string;
132
+ actionRef?: string;
133
+ provider?: string;
134
+ providerChunkType?: string;
135
+ sequence: number;
136
+ data?: unknown;
137
+ raw?: unknown;
138
+ };
139
+ export type ContextLifecycleEvent = ContextCreatedEvent | ContextResolvedEvent | ContextStatusChangedEvent | ContextContentUpdatedEvent;
140
+ export type ExecutionEvent = ExecutionCreatedEvent | ExecutionCompletedEvent | ExecutionFailedEvent;
141
+ export type ItemEvent = ItemCreatedEvent | ItemUpdatedEvent | ItemPendingEvent | ItemCompletedEvent;
142
+ export type StepEvent = StepCreatedEvent | StepUpdatedEvent | StepCompletedEvent | StepFailedEvent;
143
+ export type PartEvent = PartCreatedEvent | PartUpdatedEvent;
144
+ export type ContextStreamEvent = ContextLifecycleEvent | ExecutionEvent | ItemEvent | StepEvent | PartEvent | ChunkEmittedEvent;
145
+ export declare function parseContextStreamEvent(value: unknown): ContextStreamEvent;
146
+ export declare function assertContextStreamTransitions(_event: ContextStreamEvent): void;
147
+ export declare function validateContextStreamTimeline(events: readonly ContextStreamEvent[]): void;
148
+ export {};
@@ -0,0 +1,141 @@
1
+ import { isContextStreamChunkType } from "./context.contract.js";
2
+ function assertObject(value, label) {
3
+ if (!value || typeof value !== "object") {
4
+ throw new Error(`Invalid ${label}: expected object.`);
5
+ }
6
+ }
7
+ function assertString(value, label) {
8
+ if (typeof value !== "string" || value.length === 0) {
9
+ throw new Error(`Invalid ${label}: expected non-empty string.`);
10
+ }
11
+ }
12
+ function assertNumber(value, label) {
13
+ if (typeof value !== "number" || Number.isNaN(value)) {
14
+ throw new Error(`Invalid ${label}: expected number.`);
15
+ }
16
+ }
17
+ function assertOptionalString(value, label) {
18
+ if (value !== undefined) {
19
+ assertString(value, label);
20
+ }
21
+ }
22
+ function assertOptionalNumber(value, label) {
23
+ if (value !== undefined) {
24
+ assertNumber(value, label);
25
+ }
26
+ }
27
+ export function parseContextStreamEvent(value) {
28
+ assertObject(value, "context stream event");
29
+ assertString(value.type, "context stream event.type");
30
+ assertString(value.at, "context stream event.at");
31
+ const type = value.type;
32
+ switch (type) {
33
+ case "context.created":
34
+ case "context.resolved":
35
+ case "context.status_changed": {
36
+ assertString(value.contextId, `${type}.contextId`);
37
+ assertString(value.status, `${type}.status`);
38
+ return value;
39
+ }
40
+ case "context.content_updated": {
41
+ assertString(value.contextId, `${type}.contextId`);
42
+ return value;
43
+ }
44
+ case "execution.created":
45
+ case "execution.completed":
46
+ case "execution.failed": {
47
+ assertString(value.executionId, `${type}.executionId`);
48
+ assertString(value.contextId, `${type}.contextId`);
49
+ assertString(value.status, `${type}.status`);
50
+ return value;
51
+ }
52
+ case "item.created": {
53
+ assertString(value.itemId, `${type}.itemId`);
54
+ assertString(value.contextId, `${type}.contextId`);
55
+ assertString(value.status, `${type}.status`);
56
+ assertOptionalString(value.executionId, `${type}.executionId`);
57
+ assertOptionalString(value.itemType, `${type}.itemType`);
58
+ return value;
59
+ }
60
+ case "item.updated": {
61
+ assertString(value.itemId, `${type}.itemId`);
62
+ assertString(value.contextId, `${type}.contextId`);
63
+ assertOptionalString(value.executionId, `${type}.executionId`);
64
+ assertOptionalString(value.status, `${type}.status`);
65
+ return value;
66
+ }
67
+ case "item.pending":
68
+ case "item.completed": {
69
+ assertString(value.itemId, `${type}.itemId`);
70
+ assertString(value.contextId, `${type}.contextId`);
71
+ assertOptionalString(value.executionId, `${type}.executionId`);
72
+ assertString(value.status, `${type}.status`);
73
+ return value;
74
+ }
75
+ case "step.created": {
76
+ assertString(value.stepId, `${type}.stepId`);
77
+ assertString(value.executionId, `${type}.executionId`);
78
+ assertNumber(value.iteration, `${type}.iteration`);
79
+ assertString(value.status, `${type}.status`);
80
+ return value;
81
+ }
82
+ case "step.updated": {
83
+ assertString(value.stepId, `${type}.stepId`);
84
+ assertString(value.executionId, `${type}.executionId`);
85
+ if (value.iteration !== undefined)
86
+ assertNumber(value.iteration, `${type}.iteration`);
87
+ assertOptionalString(value.status, `${type}.status`);
88
+ assertOptionalString(value.kind, `${type}.kind`);
89
+ assertOptionalString(value.actionName, `${type}.actionName`);
90
+ return value;
91
+ }
92
+ case "step.completed":
93
+ case "step.failed": {
94
+ assertString(value.stepId, `${type}.stepId`);
95
+ assertString(value.executionId, `${type}.executionId`);
96
+ if (value.iteration !== undefined)
97
+ assertNumber(value.iteration, `${type}.iteration`);
98
+ assertString(value.status, `${type}.status`);
99
+ if (type === "step.failed")
100
+ assertOptionalString(value.errorText, `${type}.errorText`);
101
+ return value;
102
+ }
103
+ case "part.created":
104
+ case "part.updated": {
105
+ assertString(value.partKey, `${type}.partKey`);
106
+ assertString(value.stepId, `${type}.stepId`);
107
+ assertNumber(value.idx, `${type}.idx`);
108
+ assertOptionalString(value.partType, `${type}.partType`);
109
+ assertOptionalString(value.partPreview, `${type}.partPreview`);
110
+ assertOptionalString(value.partState, `${type}.partState`);
111
+ assertOptionalString(value.partToolCallId, `${type}.partToolCallId`);
112
+ return value;
113
+ }
114
+ case "chunk.emitted": {
115
+ assertString(value.chunkType, `${type}.chunkType`);
116
+ if (!isContextStreamChunkType(value.chunkType)) {
117
+ throw new Error(`Invalid ${type}.chunkType: ${String(value.chunkType)}`);
118
+ }
119
+ assertString(value.contextId, `${type}.contextId`);
120
+ assertOptionalString(value.executionId, `${type}.executionId`);
121
+ assertOptionalString(value.stepId, `${type}.stepId`);
122
+ assertOptionalString(value.itemId, `${type}.itemId`);
123
+ assertOptionalString(value.partKey, `${type}.partKey`);
124
+ assertOptionalString(value.actionRef, `${type}.actionRef`);
125
+ assertOptionalString(value.provider, `${type}.provider`);
126
+ assertOptionalString(value.providerChunkType, `${type}.providerChunkType`);
127
+ assertOptionalNumber(value.sequence, `${type}.sequence`);
128
+ return value;
129
+ }
130
+ default:
131
+ throw new Error(`Unsupported context stream event type: ${type}`);
132
+ }
133
+ }
134
+ export function assertContextStreamTransitions(_event) {
135
+ return;
136
+ }
137
+ export function validateContextStreamTimeline(events) {
138
+ for (const event of events) {
139
+ assertContextStreamTransitions(event);
140
+ }
141
+ }
@@ -0,0 +1,60 @@
1
+ /**
2
+ * ## context.toolcalls.ts
3
+ *
4
+ * This module isolates the **tool-call plumbing** used by `context.engine.ts`.
5
+ *
6
+ * In our runtime, tool calls are represented as **event parts** produced by the AI SDK.
7
+ * The engine needs to:
8
+ * - extract a normalized list of tool calls from `event.content.parts`, and
9
+ * - merge tool execution outcomes back into those parts (so the persisted event reflects
10
+ * `output-available` / `output-error`, etc.).
11
+ *
12
+ * Keeping this logic here helps `context.engine.ts` read like orchestration, and keeps
13
+ * these transformations testable and reusable.
14
+ */
15
+ import type { ContextItem } from "./context.store.js";
16
+ export type ToolCall = {
17
+ toolCallId: string;
18
+ toolName: string;
19
+ args: any;
20
+ };
21
+ /**
22
+ * Extracts tool calls from an event's `parts` array.
23
+ *
24
+ * Expected part shape (loosely):
25
+ * - `type`: string like `"tool-<toolName>"`
26
+ * - `toolCallId`: string
27
+ * - `input`: any (tool args)
28
+ *
29
+ * We intentionally treat the input as `any` because the part schema is produced by the AI SDK.
30
+ */
31
+ export declare function extractToolCallsFromParts(parts: any[] | undefined | null): ToolCall[];
32
+ /**
33
+ * Applies a tool execution outcome to the matching tool part.
34
+ *
35
+ * This does not mutate `parts` — it returns a new array.
36
+ *
37
+ * We match the tool part by:
38
+ * - `type === "tool-<toolName>"` and
39
+ * - `toolCallId` equality
40
+ *
41
+ * Then we set:
42
+ * - on success: `{ state: "output-available", output: <result> }`
43
+ * - on failure: `{ state: "output-error", errorText: <message> }`
44
+ */
45
+ export declare function applyToolExecutionResultToParts(parts: any[], toolCall: Pick<ToolCall, "toolCallId" | "toolName">, execution: {
46
+ success: boolean;
47
+ result: any;
48
+ message?: string;
49
+ }): any[];
50
+ /**
51
+ * Returns `true` when a given tool has a **settled** execution result in an event's parts.
52
+ *
53
+ * We treat a tool part as "executed" once it has either:
54
+ * - `state: "output-available"` (success), or
55
+ * - `state: "output-error"` (failure).
56
+ *
57
+ * This is useful for stop/continue logic in `context.shouldContinue(...)` where you want to
58
+ * decide based on the persisted `reactionEvent` (not ephemeral in-memory arrays).
59
+ */
60
+ export declare function didToolExecute(event: Pick<ContextItem, "content">, toolName: string): boolean;
@@ -0,0 +1,117 @@
1
+ /**
2
+ * ## context.toolcalls.ts
3
+ *
4
+ * This module isolates the **tool-call plumbing** used by `context.engine.ts`.
5
+ *
6
+ * In our runtime, tool calls are represented as **event parts** produced by the AI SDK.
7
+ * The engine needs to:
8
+ * - extract a normalized list of tool calls from `event.content.parts`, and
9
+ * - merge tool execution outcomes back into those parts (so the persisted event reflects
10
+ * `output-available` / `output-error`, etc.).
11
+ *
12
+ * Keeping this logic here helps `context.engine.ts` read like orchestration, and keeps
13
+ * these transformations testable and reusable.
14
+ */
15
+ import { isContextPartEnvelope, normalizePartsForPersistence, normalizeToolResultContentToBlocks, } from "./context.parts.js";
16
+ /**
17
+ * Extracts tool calls from an event's `parts` array.
18
+ *
19
+ * Expected part shape (loosely):
20
+ * - `type`: string like `"tool-<toolName>"`
21
+ * - `toolCallId`: string
22
+ * - `input`: any (tool args)
23
+ *
24
+ * We intentionally treat the input as `any` because the part schema is produced by the AI SDK.
25
+ */
26
+ export function extractToolCallsFromParts(parts) {
27
+ const safeParts = parts ?? [];
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
+ }
39
+ if (typeof p?.type === "string" && p.type.startsWith("tool-")) {
40
+ const toolName = p.type.split("-").slice(1).join("-");
41
+ acc.push({ toolCallId: p.toolCallId, toolName, args: p.input });
42
+ }
43
+ return acc;
44
+ }, []);
45
+ }
46
+ /**
47
+ * Applies a tool execution outcome to the matching tool part.
48
+ *
49
+ * This does not mutate `parts` — it returns a new array.
50
+ *
51
+ * We match the tool part by:
52
+ * - `type === "tool-<toolName>"` and
53
+ * - `toolCallId` equality
54
+ *
55
+ * Then we set:
56
+ * - on success: `{ state: "output-available", output: <result> }`
57
+ * - on failure: `{ state: "output-error", errorText: <message> }`
58
+ */
59
+ export function applyToolExecutionResultToParts(parts, toolCall, execution) {
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;
79
+ }
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;
99
+ }
100
+ /**
101
+ * Returns `true` when a given tool has a **settled** execution result in an event's parts.
102
+ *
103
+ * We treat a tool part as "executed" once it has either:
104
+ * - `state: "output-available"` (success), or
105
+ * - `state: "output-error"` (failure).
106
+ *
107
+ * This is useful for stop/continue logic in `context.shouldContinue(...)` where you want to
108
+ * decide based on the persisted `reactionEvent` (not ephemeral in-memory arrays).
109
+ */
110
+ export function didToolExecute(event, toolName) {
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")));
117
+ }
package/dist/env.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import type { ContextEnvironment } from "./context.config.js";
2
+ export declare function registerContextEnv(env: ContextEnvironment, runId?: string | null): void;
3
+ export declare function getContextEnv(): Promise<ContextEnvironment>;