@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.
- package/README.md +58 -83
- package/dist/codex.d.ts +11 -2
- package/dist/codex.js +16 -8
- package/dist/context.action-calls.d.ts +48 -0
- package/dist/context.action-calls.js +123 -0
- package/dist/context.action.d.ts +55 -0
- package/dist/context.action.js +25 -0
- package/dist/context.builder.d.ts +71 -43
- package/dist/context.builder.js +123 -28
- package/dist/context.config.d.ts +2 -1
- package/dist/context.config.js +8 -3
- package/dist/context.contract.d.ts +2 -4
- package/dist/context.contract.js +3 -9
- package/dist/context.d.ts +3 -2
- package/dist/context.engine.d.ts +75 -46
- package/dist/context.engine.js +538 -302
- package/dist/context.events.js +28 -87
- package/dist/context.js +1 -0
- package/dist/context.part-identity.d.ts +40 -0
- package/dist/context.part-identity.js +270 -0
- package/dist/context.parts.d.ts +389 -164
- package/dist/context.parts.js +343 -218
- package/dist/context.registry.d.ts +1 -1
- package/dist/context.runtime.d.ts +21 -0
- package/dist/context.runtime.js +39 -0
- package/dist/context.step-stream.d.ts +16 -2
- package/dist/context.step-stream.js +58 -16
- package/dist/context.store.d.ts +63 -10
- package/dist/context.stream.d.ts +14 -4
- package/dist/context.stream.js +31 -3
- package/dist/domain.d.ts +1 -0
- package/dist/domain.js +1 -0
- package/dist/index.d.ts +13 -10
- package/dist/index.js +7 -6
- 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 +625 -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/dist/reactors/ai-sdk.chunk-map.d.ts +1 -0
- package/dist/reactors/ai-sdk.chunk-map.js +56 -5
- package/dist/reactors/ai-sdk.reactor.d.ts +8 -5
- package/dist/reactors/ai-sdk.reactor.js +10 -9
- package/dist/reactors/ai-sdk.step.d.ts +6 -6
- package/dist/reactors/ai-sdk.step.js +32 -24
- package/dist/reactors/scripted.reactor.d.ts +7 -4
- package/dist/reactors/types.d.ts +23 -8
- package/dist/runtime.d.ts +6 -0
- package/dist/runtime.js +9 -0
- package/dist/runtime.step.js +2 -2
- package/dist/schema.d.ts +268 -2
- package/dist/schema.js +5 -9
- package/dist/steps/do-context-stream-step.d.ts +2 -2
- package/dist/steps/do-context-stream-step.js +6 -8
- package/dist/steps/durable.steps.d.ts +28 -0
- package/dist/steps/durable.steps.js +34 -0
- package/dist/steps/store.steps.d.ts +121 -39
- package/dist/steps/store.steps.js +266 -111
- package/dist/steps/stream.steps.d.ts +36 -3
- package/dist/steps/stream.steps.js +137 -14
- package/dist/steps/trace.steps.d.ts +4 -2
- package/dist/steps/trace.steps.js +26 -8
- package/dist/stores/instant.store.d.ts +15 -11
- package/dist/stores/instant.store.js +155 -6
- package/dist/tools-to-model-tools.d.ts +39 -3
- package/dist/tools-to-model-tools.js +63 -6
- package/package.json +20 -6
- package/dist/context.toolcalls.d.ts +0 -60
- package/dist/context.toolcalls.js +0 -117
|
@@ -1,21 +1,78 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
function toJsonSchema(schema) {
|
|
3
|
+
if (!schema)
|
|
4
|
+
return schema;
|
|
5
|
+
const jsonSchema = schema?.jsonSchema;
|
|
6
|
+
if (jsonSchema)
|
|
7
|
+
return jsonSchema;
|
|
8
|
+
try {
|
|
9
|
+
return z.toJSONSchema(schema);
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return schema;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function asRecord(value) {
|
|
16
|
+
return value && typeof value === "object" ? value : {};
|
|
17
|
+
}
|
|
18
|
+
function isProviderDefinedTool(tool) {
|
|
19
|
+
const record = asRecord(tool);
|
|
20
|
+
return (record.type === "provider-defined" &&
|
|
21
|
+
typeof record.id === "string" &&
|
|
22
|
+
record.id.trim().length > 0);
|
|
23
|
+
}
|
|
2
24
|
/**
|
|
3
25
|
* Convert AI SDK tools to a serializable representation that can be passed to `"use-step"` functions.
|
|
4
26
|
*
|
|
5
27
|
* This matches DurableAgent's internal `toolsToModelTools` behavior:
|
|
6
28
|
* `inputSchema: asSchema(tool.inputSchema).jsonSchema`
|
|
7
29
|
*/
|
|
8
|
-
export function
|
|
30
|
+
export function actionsToActionSpecs(tools) {
|
|
9
31
|
const out = {};
|
|
10
32
|
for (const [name, tool] of Object.entries(tools)) {
|
|
11
|
-
|
|
33
|
+
if (isProviderDefinedTool(tool)) {
|
|
34
|
+
out[name] = {
|
|
35
|
+
type: "provider-defined",
|
|
36
|
+
id: tool.id,
|
|
37
|
+
name: tool.name,
|
|
38
|
+
args: tool.args,
|
|
39
|
+
};
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
const record = asRecord(tool);
|
|
43
|
+
const inputSchema = record.inputSchema ?? record.input;
|
|
12
44
|
if (!inputSchema) {
|
|
13
|
-
throw new Error(`Context:
|
|
45
|
+
throw new Error(`Context: action "${name}" is missing input/inputSchema (required for model action calls)`);
|
|
14
46
|
}
|
|
47
|
+
const outputSchema = record.outputSchema ?? record.output;
|
|
15
48
|
out[name] = {
|
|
16
|
-
|
|
17
|
-
|
|
49
|
+
type: "function",
|
|
50
|
+
description: typeof record.description === "string" ? record.description : undefined,
|
|
51
|
+
inputSchema: toJsonSchema(inputSchema),
|
|
52
|
+
outputSchema: outputSchema ? toJsonSchema(outputSchema) : undefined,
|
|
53
|
+
providerOptions: record.providerOptions,
|
|
18
54
|
};
|
|
19
55
|
}
|
|
20
56
|
return out;
|
|
21
57
|
}
|
|
58
|
+
export function actionSpecToAiSdkTool(name, spec, wrapJsonSchema) {
|
|
59
|
+
if (spec.type === "provider-defined") {
|
|
60
|
+
return {
|
|
61
|
+
type: "provider-defined",
|
|
62
|
+
id: spec.id,
|
|
63
|
+
name: spec.name ?? name,
|
|
64
|
+
args: spec.args ?? {},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
type: "function",
|
|
69
|
+
description: spec.description,
|
|
70
|
+
inputSchema: wrapJsonSchema(spec.inputSchema),
|
|
71
|
+
outputSchema: spec.outputSchema ? wrapJsonSchema(spec.outputSchema) : undefined,
|
|
72
|
+
providerOptions: spec.providerOptions,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* @deprecated Use actionsToActionSpecs.
|
|
77
|
+
*/
|
|
78
|
+
export const toolsToModelTools = actionsToActionSpecs;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ekairos/events",
|
|
3
|
-
"version": "1.22.
|
|
3
|
+
"version": "1.22.35",
|
|
4
4
|
"description": "Ekairos Events - Context-first workflow runtime",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -30,6 +30,12 @@
|
|
|
30
30
|
"require": "./dist/schema.js",
|
|
31
31
|
"default": "./dist/schema.js"
|
|
32
32
|
},
|
|
33
|
+
"./domain": {
|
|
34
|
+
"types": "./dist/domain.d.ts",
|
|
35
|
+
"import": "./dist/domain.js",
|
|
36
|
+
"require": "./dist/domain.js",
|
|
37
|
+
"default": "./dist/domain.js"
|
|
38
|
+
},
|
|
33
39
|
"./runtime": {
|
|
34
40
|
"types": "./dist/runtime.d.ts",
|
|
35
41
|
"import": "./dist/runtime.js",
|
|
@@ -78,6 +84,9 @@
|
|
|
78
84
|
"schema": [
|
|
79
85
|
"dist/schema.d.ts"
|
|
80
86
|
],
|
|
87
|
+
"domain": [
|
|
88
|
+
"dist/domain.d.ts"
|
|
89
|
+
],
|
|
81
90
|
"runtime": [
|
|
82
91
|
"dist/runtime.d.ts"
|
|
83
92
|
],
|
|
@@ -107,7 +116,9 @@
|
|
|
107
116
|
"watch": "tsc -p tsconfig.json --watch",
|
|
108
117
|
"clean": "node -e \"require('fs').rmSync('dist', {recursive:true, force:true})\"",
|
|
109
118
|
"typecheck": "tsc --noEmit",
|
|
119
|
+
"typecheck:tests": "tsc --noEmit -p tsconfig.typecheck.json",
|
|
110
120
|
"test": "vitest run -c vitest.config.mts",
|
|
121
|
+
"test:workflow": "vitest run -c vitest.workflow.config.mts",
|
|
111
122
|
"pretest:ai-sdk-reactor": "pnpm --filter @ekairos/domain build",
|
|
112
123
|
"test:ai-sdk-reactor": "vitest run -c vitest.config.mts src/tests/context.ai-sdk-reactor.instant.test.ts",
|
|
113
124
|
"test:ai-sdk-reactor:real": "vitest run -c vitest.config.mts src/tests/context.ai-sdk-reactor.real.instant.test.ts",
|
|
@@ -116,7 +127,7 @@
|
|
|
116
127
|
},
|
|
117
128
|
"dependencies": {
|
|
118
129
|
"@ai-sdk/openai": "^2.0.52",
|
|
119
|
-
"@ekairos/domain": "^1.22.
|
|
130
|
+
"@ekairos/domain": "^1.22.35",
|
|
120
131
|
"@instantdb/admin": "0.22.158",
|
|
121
132
|
"@instantdb/core": "0.22.142",
|
|
122
133
|
"@vercel/mcp-adapter": "^1.0.0",
|
|
@@ -125,18 +136,21 @@
|
|
|
125
136
|
"ajv": "^8.17.1",
|
|
126
137
|
"jose": "^6.1.3",
|
|
127
138
|
"llamaindex": "^0.12.0",
|
|
139
|
+
"partial-json": "^0.1.7",
|
|
128
140
|
"react": "^19.2.0",
|
|
129
|
-
"workflow": "
|
|
141
|
+
"workflow": "5.0.0-beta.5",
|
|
130
142
|
"xmlbuilder2": "^3.1.1",
|
|
131
|
-
"zod": "^4.
|
|
143
|
+
"zod": "^4.3.6"
|
|
132
144
|
},
|
|
133
145
|
"devDependencies": {
|
|
134
146
|
"@ekairos/testing": "workspace:*",
|
|
135
147
|
"@ekairos/tsconfig": "workspace:*",
|
|
136
148
|
"@types/node": "^24.5.0",
|
|
137
149
|
"@types/react": "^19.2.2",
|
|
150
|
+
"@workflow/serde": "5.0.0-beta.1",
|
|
151
|
+
"@workflow/vitest": "5.0.0-beta.5",
|
|
138
152
|
"dotenv": "^17.2.3",
|
|
139
|
-
"
|
|
140
|
-
"
|
|
153
|
+
"typescript": "^5.9.2",
|
|
154
|
+
"vitest": "^4.0.8"
|
|
141
155
|
}
|
|
142
156
|
}
|
|
@@ -1,60 +0,0 @@
|
|
|
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;
|
|
@@ -1,117 +0,0 @@
|
|
|
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
|
-
}
|