@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.
- package/README.md +115 -0
- package/dist/codex.d.ts +95 -0
- package/dist/codex.js +91 -0
- package/dist/context.builder.d.ts +62 -0
- package/dist/context.builder.js +143 -0
- package/dist/context.config.d.ts +9 -0
- package/dist/context.config.js +30 -0
- package/dist/context.contract.d.ts +47 -0
- package/dist/context.contract.js +132 -0
- package/dist/context.d.ts +4 -0
- package/dist/context.durable.d.ts +5 -0
- package/dist/context.durable.js +13 -0
- package/dist/context.engine.d.ts +216 -0
- package/dist/context.engine.js +1098 -0
- package/dist/context.events.d.ts +55 -0
- package/dist/context.events.js +431 -0
- package/dist/context.hooks.d.ts +21 -0
- package/dist/context.hooks.js +31 -0
- package/dist/context.js +3 -0
- package/dist/context.parts.d.ts +241 -0
- package/dist/context.parts.js +360 -0
- package/dist/context.reactor.d.ts +3 -0
- package/dist/context.reactor.js +2 -0
- package/dist/context.registry.d.ts +13 -0
- package/dist/context.registry.js +30 -0
- package/dist/context.skill.d.ts +9 -0
- package/dist/context.skill.js +1 -0
- package/dist/context.step-stream.d.ts +26 -0
- package/dist/context.step-stream.js +59 -0
- package/dist/context.store.d.ts +85 -0
- package/dist/context.store.js +1 -0
- package/dist/context.stream.d.ts +148 -0
- package/dist/context.stream.js +141 -0
- package/dist/context.toolcalls.d.ts +60 -0
- package/dist/context.toolcalls.js +117 -0
- package/dist/env.d.ts +3 -0
- package/dist/env.js +53 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +11 -0
- package/dist/mcp.d.ts +1 -0
- package/dist/mcp.js +1 -0
- package/dist/mirror.d.ts +41 -0
- package/dist/mirror.js +1 -0
- package/dist/oidc.d.ts +7 -0
- package/dist/oidc.js +25 -0
- package/dist/polyfills/dom-events.d.ts +1 -0
- package/dist/polyfills/dom-events.js +89 -0
- package/dist/react.d.ts +42 -0
- package/dist/react.js +88 -0
- package/dist/reactors/ai-sdk.chunk-map.d.ts +12 -0
- package/dist/reactors/ai-sdk.chunk-map.js +143 -0
- package/dist/reactors/ai-sdk.reactor.d.ts +33 -0
- package/dist/reactors/ai-sdk.reactor.js +65 -0
- package/dist/reactors/ai-sdk.step.d.ts +48 -0
- package/dist/reactors/ai-sdk.step.js +343 -0
- package/dist/reactors/scripted.reactor.d.ts +17 -0
- package/dist/reactors/scripted.reactor.js +51 -0
- package/dist/reactors/types.d.ts +52 -0
- package/dist/reactors/types.js +1 -0
- package/dist/runtime.d.ts +19 -0
- package/dist/runtime.js +26 -0
- package/dist/runtime.step.d.ts +9 -0
- package/dist/runtime.step.js +7 -0
- package/dist/schema.d.ts +2 -0
- package/dist/schema.js +191 -0
- package/dist/steps/do-context-stream-step.d.ts +34 -0
- package/dist/steps/do-context-stream-step.js +96 -0
- package/dist/steps/mirror.steps.d.ts +6 -0
- package/dist/steps/mirror.steps.js +48 -0
- package/dist/steps/store.steps.d.ts +96 -0
- package/dist/steps/store.steps.js +595 -0
- package/dist/steps/stream.steps.d.ts +86 -0
- package/dist/steps/stream.steps.js +270 -0
- package/dist/steps/trace.steps.d.ts +38 -0
- package/dist/steps/trace.steps.js +270 -0
- package/dist/stores/instant.document-parser.d.ts +6 -0
- package/dist/stores/instant.document-parser.js +210 -0
- package/dist/stores/instant.documents.d.ts +16 -0
- package/dist/stores/instant.documents.js +152 -0
- package/dist/stores/instant.store.d.ts +66 -0
- package/dist/stores/instant.store.js +575 -0
- package/dist/tools-to-model-tools.d.ts +19 -0
- package/dist/tools-to-model-tools.js +21 -0
- package/package.json +142 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { ModelMessage, UIMessageChunk } from "ai";
|
|
2
|
+
import type { ContextEnvironment } from "../context.config.js";
|
|
3
|
+
import type { ContextModelInit } from "../context.engine.js";
|
|
4
|
+
import type { ContextItem, ContextIdentifier } from "../context.store.js";
|
|
5
|
+
import type { SerializableToolForModel } from "../tools-to-model-tools.js";
|
|
6
|
+
/**
|
|
7
|
+
* AI SDK-backed reaction execution inside a single workflow step.
|
|
8
|
+
*
|
|
9
|
+
* Provider-specific responsibilities live here:
|
|
10
|
+
* - load items from store
|
|
11
|
+
* - build model messages
|
|
12
|
+
* - stream through the AI SDK
|
|
13
|
+
* - map provider chunks to the Context stream contract
|
|
14
|
+
* - emit UI chunks and persist step stream chunks
|
|
15
|
+
*/
|
|
16
|
+
export declare function executeAiSdkReaction(params: {
|
|
17
|
+
env: ContextEnvironment;
|
|
18
|
+
contextIdentifier: ContextIdentifier;
|
|
19
|
+
model: ContextModelInit;
|
|
20
|
+
system: string;
|
|
21
|
+
tools: Record<string, SerializableToolForModel>;
|
|
22
|
+
eventId: string;
|
|
23
|
+
iteration?: number;
|
|
24
|
+
maxSteps: number;
|
|
25
|
+
sendStart?: boolean;
|
|
26
|
+
silent?: boolean;
|
|
27
|
+
contextStepStream?: WritableStream<string>;
|
|
28
|
+
writable?: WritableStream<UIMessageChunk>;
|
|
29
|
+
executionId?: string;
|
|
30
|
+
contextId?: string;
|
|
31
|
+
stepId?: string;
|
|
32
|
+
}): Promise<{
|
|
33
|
+
assistantEvent: ContextItem;
|
|
34
|
+
toolCalls: any[];
|
|
35
|
+
messagesForModel: ModelMessage[];
|
|
36
|
+
llm?: {
|
|
37
|
+
provider?: string;
|
|
38
|
+
model?: string;
|
|
39
|
+
promptTokens?: number;
|
|
40
|
+
promptTokensCached?: number;
|
|
41
|
+
promptTokensUncached?: number;
|
|
42
|
+
completionTokens?: number;
|
|
43
|
+
totalTokens?: number;
|
|
44
|
+
latencyMs?: number;
|
|
45
|
+
rawUsage?: any;
|
|
46
|
+
rawProviderMetadata?: any;
|
|
47
|
+
};
|
|
48
|
+
}>;
|
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import { OUTPUT_ITEM_TYPE } from "../context.events.js";
|
|
2
|
+
import { createContextStepStreamChunk, encodeContextStepStreamChunk, } from "../context.step-stream.js";
|
|
3
|
+
import { mapAiSdkChunkToContextEvent } from "./ai-sdk.chunk-map.js";
|
|
4
|
+
import { writeContextTraceEvents } from "../steps/trace.steps.js";
|
|
5
|
+
async function readWorkflowMetadata() {
|
|
6
|
+
try {
|
|
7
|
+
const { getWorkflowMetadata } = await import("workflow");
|
|
8
|
+
return getWorkflowMetadata?.() ?? null;
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
async function resolveWorkflowRunId(env, executionId) {
|
|
15
|
+
let runId = "";
|
|
16
|
+
const meta = await readWorkflowMetadata();
|
|
17
|
+
if (meta && meta.workflowRunId !== undefined && meta.workflowRunId !== null) {
|
|
18
|
+
runId = String(meta.workflowRunId);
|
|
19
|
+
}
|
|
20
|
+
if (!runId && executionId) {
|
|
21
|
+
try {
|
|
22
|
+
const { getContextRuntime } = await import("../runtime.js");
|
|
23
|
+
const runtime = await getContextRuntime(env);
|
|
24
|
+
const db = runtime?.db;
|
|
25
|
+
if (db) {
|
|
26
|
+
const q = await db.query({
|
|
27
|
+
event_executions: {
|
|
28
|
+
$: { where: { id: String(executionId) }, limit: 1 },
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
const row = q?.event_executions?.[0];
|
|
32
|
+
if (row?.workflowRunId) {
|
|
33
|
+
runId = String(row.workflowRunId);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// ignore
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return runId || undefined;
|
|
42
|
+
}
|
|
43
|
+
function safeErrorJson(error) {
|
|
44
|
+
const seen = new WeakSet();
|
|
45
|
+
const redactKey = (k) => /token|authorization|cookie|secret|api[_-]?key|password/i.test(k);
|
|
46
|
+
const err = error;
|
|
47
|
+
const payload = {
|
|
48
|
+
name: err?.name,
|
|
49
|
+
message: err?.message,
|
|
50
|
+
status: err?.status,
|
|
51
|
+
body: err?.body,
|
|
52
|
+
data: err?.data,
|
|
53
|
+
stack: err?.stack,
|
|
54
|
+
};
|
|
55
|
+
try {
|
|
56
|
+
return JSON.stringify(payload, (k, v) => {
|
|
57
|
+
if (redactKey(k))
|
|
58
|
+
return "[redacted]";
|
|
59
|
+
if (typeof v === "string" && v.length > 5000)
|
|
60
|
+
return "[truncated-string]";
|
|
61
|
+
if (typeof v === "object" && v !== null) {
|
|
62
|
+
if (seen.has(v))
|
|
63
|
+
return "[circular]";
|
|
64
|
+
seen.add(v);
|
|
65
|
+
}
|
|
66
|
+
return v;
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return JSON.stringify({ message: String(err?.message ?? "error") });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* AI SDK-backed reaction execution inside a single workflow step.
|
|
75
|
+
*
|
|
76
|
+
* Provider-specific responsibilities live here:
|
|
77
|
+
* - load items from store
|
|
78
|
+
* - build model messages
|
|
79
|
+
* - stream through the AI SDK
|
|
80
|
+
* - map provider chunks to the Context stream contract
|
|
81
|
+
* - emit UI chunks and persist step stream chunks
|
|
82
|
+
*/
|
|
83
|
+
export async function executeAiSdkReaction(params) {
|
|
84
|
+
"use step";
|
|
85
|
+
const { getContextRuntime } = await import("../runtime.js");
|
|
86
|
+
const { store } = await getContextRuntime(params.env);
|
|
87
|
+
let events;
|
|
88
|
+
try {
|
|
89
|
+
events = await store.getItems(params.contextIdentifier);
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
console.error("[ekairos/story] ai-sdk.step store.getItems failed");
|
|
93
|
+
throw error;
|
|
94
|
+
}
|
|
95
|
+
let messagesForModel;
|
|
96
|
+
try {
|
|
97
|
+
messagesForModel = (await store.itemsToModelMessages(events));
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
console.error("[ekairos/story] ai-sdk.step store.itemsToModelMessages failed", safeErrorJson(error));
|
|
101
|
+
throw error;
|
|
102
|
+
}
|
|
103
|
+
const { jsonSchema, gateway, smoothStream, stepCountIs, streamText } = await import("ai");
|
|
104
|
+
const { extractToolCallsFromParts } = await import("../context.toolcalls.js");
|
|
105
|
+
const resolvedModel = typeof params.model === "string"
|
|
106
|
+
? gateway(params.model)
|
|
107
|
+
: typeof params.model === "function"
|
|
108
|
+
? await params.model()
|
|
109
|
+
: (() => {
|
|
110
|
+
throw new Error("Invalid model init passed to executeAiSdkReaction. Expected a model id string or an async model factory.");
|
|
111
|
+
})();
|
|
112
|
+
const toolsForStreamText = {};
|
|
113
|
+
for (const [name, t] of Object.entries(params.tools)) {
|
|
114
|
+
toolsForStreamText[name] = {
|
|
115
|
+
description: t?.description,
|
|
116
|
+
inputSchema: jsonSchema(t.inputSchema),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
const startedAtMs = Date.now();
|
|
120
|
+
const result = streamText({
|
|
121
|
+
model: resolvedModel,
|
|
122
|
+
system: params.system,
|
|
123
|
+
messages: messagesForModel,
|
|
124
|
+
tools: toolsForStreamText,
|
|
125
|
+
toolChoice: "required",
|
|
126
|
+
stopWhen: stepCountIs(params.maxSteps),
|
|
127
|
+
experimental_transform: smoothStream({ delayInMs: 30, chunking: "word" }),
|
|
128
|
+
});
|
|
129
|
+
result.consumeStream();
|
|
130
|
+
let resolveFinish;
|
|
131
|
+
let rejectFinish;
|
|
132
|
+
let chunkSequence = 0;
|
|
133
|
+
const finishPromise = new Promise((resolve, reject) => {
|
|
134
|
+
resolveFinish = resolve;
|
|
135
|
+
rejectFinish = reject;
|
|
136
|
+
});
|
|
137
|
+
const modelId = typeof params.model === "string" ? params.model : "";
|
|
138
|
+
const mappedProvider = modelId.includes("/") ? modelId.split("/")[0] : undefined;
|
|
139
|
+
const contextStepStreamWriter = params.contextStepStream?.getWriter();
|
|
140
|
+
try {
|
|
141
|
+
const uiStream = result
|
|
142
|
+
.toUIMessageStream({
|
|
143
|
+
sendStart: Boolean(params.sendStart),
|
|
144
|
+
generateMessageId: () => params.eventId,
|
|
145
|
+
messageMetadata() {
|
|
146
|
+
return { eventId: params.eventId };
|
|
147
|
+
},
|
|
148
|
+
onFinish: ({ messages }) => {
|
|
149
|
+
const lastMessage = messages[messages.length - 1];
|
|
150
|
+
const event = {
|
|
151
|
+
id: params.eventId,
|
|
152
|
+
type: OUTPUT_ITEM_TYPE,
|
|
153
|
+
channel: "web",
|
|
154
|
+
createdAt: new Date().toISOString(),
|
|
155
|
+
content: { parts: lastMessage?.parts ?? [] },
|
|
156
|
+
};
|
|
157
|
+
resolveFinish(event);
|
|
158
|
+
},
|
|
159
|
+
onError: (e) => {
|
|
160
|
+
rejectFinish(e);
|
|
161
|
+
return e instanceof Error ? e.message : String(e);
|
|
162
|
+
},
|
|
163
|
+
})
|
|
164
|
+
.pipeThrough(new TransformStream({
|
|
165
|
+
async transform(chunk, controller) {
|
|
166
|
+
const contextId = typeof params.contextId === "string" && params.contextId.length > 0
|
|
167
|
+
? params.contextId
|
|
168
|
+
: undefined;
|
|
169
|
+
if (contextId) {
|
|
170
|
+
const mapped = mapAiSdkChunkToContextEvent({
|
|
171
|
+
chunk,
|
|
172
|
+
contextId,
|
|
173
|
+
executionId: params.executionId,
|
|
174
|
+
stepId: params.stepId,
|
|
175
|
+
itemId: params.eventId,
|
|
176
|
+
provider: mappedProvider,
|
|
177
|
+
sequence: ++chunkSequence,
|
|
178
|
+
});
|
|
179
|
+
const persistedChunk = createContextStepStreamChunk({
|
|
180
|
+
at: mapped.at,
|
|
181
|
+
sequence: mapped.sequence,
|
|
182
|
+
chunkType: mapped.chunkType,
|
|
183
|
+
provider: mapped.provider,
|
|
184
|
+
providerChunkType: mapped.providerChunkType,
|
|
185
|
+
actionRef: mapped.actionRef,
|
|
186
|
+
data: mapped.data && typeof mapped.data === "object"
|
|
187
|
+
? mapped.data
|
|
188
|
+
: undefined,
|
|
189
|
+
raw: mapped.raw && typeof mapped.raw === "object"
|
|
190
|
+
? mapped.raw
|
|
191
|
+
: undefined,
|
|
192
|
+
});
|
|
193
|
+
if (contextStepStreamWriter) {
|
|
194
|
+
await contextStepStreamWriter.write(encodeContextStepStreamChunk(persistedChunk));
|
|
195
|
+
}
|
|
196
|
+
controller.enqueue({
|
|
197
|
+
type: "data-chunk.emitted",
|
|
198
|
+
data: mapped,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
if (chunk.type === "finish")
|
|
202
|
+
return;
|
|
203
|
+
controller.enqueue(chunk);
|
|
204
|
+
},
|
|
205
|
+
}));
|
|
206
|
+
if (params.writable) {
|
|
207
|
+
await uiStream.pipeTo(params.writable, { preventClose: true });
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
const reader = uiStream.getReader();
|
|
211
|
+
try {
|
|
212
|
+
while (true) {
|
|
213
|
+
const { done } = await reader.read();
|
|
214
|
+
if (done)
|
|
215
|
+
break;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
finally {
|
|
219
|
+
reader.releaseLock();
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
finally {
|
|
224
|
+
contextStepStreamWriter?.releaseLock();
|
|
225
|
+
}
|
|
226
|
+
const assistantEvent = await finishPromise;
|
|
227
|
+
const finishedAtMs = Date.now();
|
|
228
|
+
const toolCalls = extractToolCallsFromParts(assistantEvent?.content?.parts);
|
|
229
|
+
const latencyMs = Math.max(0, finishedAtMs - startedAtMs);
|
|
230
|
+
let usage = undefined;
|
|
231
|
+
let providerMetadata = undefined;
|
|
232
|
+
try {
|
|
233
|
+
usage = result?.usage;
|
|
234
|
+
if (typeof usage?.then === "function")
|
|
235
|
+
usage = await usage;
|
|
236
|
+
}
|
|
237
|
+
catch {
|
|
238
|
+
usage = undefined;
|
|
239
|
+
}
|
|
240
|
+
try {
|
|
241
|
+
providerMetadata =
|
|
242
|
+
result?.providerMetadata ??
|
|
243
|
+
result?.experimental_providerMetadata ??
|
|
244
|
+
result?.response?.providerMetadata ??
|
|
245
|
+
undefined;
|
|
246
|
+
}
|
|
247
|
+
catch {
|
|
248
|
+
providerMetadata = undefined;
|
|
249
|
+
}
|
|
250
|
+
function toPlainJson(value) {
|
|
251
|
+
if (typeof value === "undefined")
|
|
252
|
+
return undefined;
|
|
253
|
+
try {
|
|
254
|
+
return JSON.parse(JSON.stringify(value));
|
|
255
|
+
}
|
|
256
|
+
catch {
|
|
257
|
+
return undefined;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
const usageJson = toPlainJson(usage);
|
|
261
|
+
const providerMetadataJson = toPlainJson(providerMetadata);
|
|
262
|
+
const provider = modelId.includes("/") ? modelId.split("/")[0] : providerMetadata?.provider;
|
|
263
|
+
const model = modelId.includes("/") ? modelId.split("/").slice(1).join("/") : providerMetadata?.model;
|
|
264
|
+
const promptTokens = Number(usage?.promptTokens ?? usage?.prompt_tokens ?? usage?.inputTokens ?? 0) || 0;
|
|
265
|
+
const completionTokens = Number(usage?.completionTokens ?? usage?.completion_tokens ?? usage?.outputTokens ?? 0) || 0;
|
|
266
|
+
const totalTokens = Number(usage?.totalTokens ?? usage?.total_tokens ?? 0) || (promptTokens + completionTokens);
|
|
267
|
+
const cachedPromptTokens = Number(usage?.promptTokensCached ??
|
|
268
|
+
usage?.cached_prompt_tokens ??
|
|
269
|
+
usage?.prompt_tokens_details?.cached_tokens ??
|
|
270
|
+
usage?.input_tokens_details?.cached_tokens ??
|
|
271
|
+
0) || 0;
|
|
272
|
+
const uncachedPromptTokens = Math.max(0, promptTokens - cachedPromptTokens);
|
|
273
|
+
const llm = promptTokens || completionTokens || cachedPromptTokens
|
|
274
|
+
? {
|
|
275
|
+
provider,
|
|
276
|
+
model,
|
|
277
|
+
promptTokens,
|
|
278
|
+
promptTokensCached: cachedPromptTokens,
|
|
279
|
+
promptTokensUncached: uncachedPromptTokens,
|
|
280
|
+
completionTokens,
|
|
281
|
+
totalTokens,
|
|
282
|
+
latencyMs,
|
|
283
|
+
rawUsage: usageJson,
|
|
284
|
+
rawProviderMetadata: providerMetadataJson,
|
|
285
|
+
}
|
|
286
|
+
: {
|
|
287
|
+
provider,
|
|
288
|
+
model,
|
|
289
|
+
latencyMs,
|
|
290
|
+
rawUsage: usageJson,
|
|
291
|
+
rawProviderMetadata: providerMetadataJson,
|
|
292
|
+
};
|
|
293
|
+
try {
|
|
294
|
+
const runId = await resolveWorkflowRunId(params.env, params.executionId);
|
|
295
|
+
if (runId && llm) {
|
|
296
|
+
await writeContextTraceEvents({
|
|
297
|
+
env: params.env,
|
|
298
|
+
events: [
|
|
299
|
+
{
|
|
300
|
+
workflowRunId: runId,
|
|
301
|
+
eventId: `context_llm:${String(params.executionId ?? "unknown")}:${String(params.stepId ?? params.eventId)}:${String(params.iteration ?? 0)}`,
|
|
302
|
+
eventKind: "context.llm",
|
|
303
|
+
eventAt: new Date().toISOString(),
|
|
304
|
+
contextId: params.contextId,
|
|
305
|
+
executionId: params.executionId,
|
|
306
|
+
stepId: params.stepId,
|
|
307
|
+
aiProvider: typeof llm.provider === "string" ? llm.provider : undefined,
|
|
308
|
+
aiModel: typeof llm.model === "string" ? llm.model : undefined,
|
|
309
|
+
promptTokens: Number.isFinite(Number(llm.promptTokens))
|
|
310
|
+
? Number(llm.promptTokens)
|
|
311
|
+
: undefined,
|
|
312
|
+
promptTokensCached: Number.isFinite(Number(llm.promptTokensCached))
|
|
313
|
+
? Number(llm.promptTokensCached)
|
|
314
|
+
: undefined,
|
|
315
|
+
promptTokensUncached: Number.isFinite(Number(llm.promptTokensUncached))
|
|
316
|
+
? Number(llm.promptTokensUncached)
|
|
317
|
+
: undefined,
|
|
318
|
+
completionTokens: Number.isFinite(Number(llm.completionTokens))
|
|
319
|
+
? Number(llm.completionTokens)
|
|
320
|
+
: undefined,
|
|
321
|
+
totalTokens: Number.isFinite(Number(llm.totalTokens))
|
|
322
|
+
? Number(llm.totalTokens)
|
|
323
|
+
: undefined,
|
|
324
|
+
latencyMs: Number.isFinite(Number(llm.latencyMs))
|
|
325
|
+
? Number(llm.latencyMs)
|
|
326
|
+
: undefined,
|
|
327
|
+
payload: {
|
|
328
|
+
provider: llm.provider,
|
|
329
|
+
model: llm.model,
|
|
330
|
+
usage: llm.rawUsage,
|
|
331
|
+
providerMetadata: llm.rawProviderMetadata,
|
|
332
|
+
iteration: params.iteration,
|
|
333
|
+
},
|
|
334
|
+
},
|
|
335
|
+
],
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
catch {
|
|
340
|
+
// tracing must not break reaction
|
|
341
|
+
}
|
|
342
|
+
return { assistantEvent, toolCalls, messagesForModel, llm };
|
|
343
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ModelMessage } from "ai";
|
|
2
|
+
import type { ContextEnvironment } from "../context.config.js";
|
|
3
|
+
import type { ContextItem } from "../context.store.js";
|
|
4
|
+
import type { ContextReactionLLM, ContextActionRequest, ContextReactor, ContextReactorParams } from "./types.js";
|
|
5
|
+
type ScriptedReactionPayload = {
|
|
6
|
+
assistantEvent?: Partial<ContextItem>;
|
|
7
|
+
actionRequests?: ContextActionRequest[];
|
|
8
|
+
messagesForModel?: ModelMessage[];
|
|
9
|
+
llm?: ContextReactionLLM;
|
|
10
|
+
};
|
|
11
|
+
export type ScriptedReactorStep<Context = unknown, Env extends ContextEnvironment = ContextEnvironment> = ScriptedReactionPayload | ((params: ContextReactorParams<Context, Env>) => Promise<ScriptedReactionPayload> | ScriptedReactionPayload);
|
|
12
|
+
export type CreateScriptedReactorOptions<Context = unknown, Env extends ContextEnvironment = ContextEnvironment> = {
|
|
13
|
+
steps: ScriptedReactorStep<Context, Env>[];
|
|
14
|
+
repeatLast?: boolean;
|
|
15
|
+
};
|
|
16
|
+
export declare function createScriptedReactor<Context = unknown, Env extends ContextEnvironment = ContextEnvironment>(options: CreateScriptedReactorOptions<Context, Env>): ContextReactor<Context, Env>;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { OUTPUT_ITEM_TYPE } from "../context.events.js";
|
|
2
|
+
function normalizeScriptedAssistantEvent(params, assistantEvent) {
|
|
3
|
+
const fallback = {
|
|
4
|
+
id: params.eventId,
|
|
5
|
+
type: OUTPUT_ITEM_TYPE,
|
|
6
|
+
channel: params.triggerEvent.channel,
|
|
7
|
+
createdAt: new Date().toISOString(),
|
|
8
|
+
content: { parts: [] },
|
|
9
|
+
};
|
|
10
|
+
const mergedContent = {
|
|
11
|
+
...fallback.content,
|
|
12
|
+
...(assistantEvent?.content ?? {}),
|
|
13
|
+
};
|
|
14
|
+
return {
|
|
15
|
+
...fallback,
|
|
16
|
+
...assistantEvent,
|
|
17
|
+
id: assistantEvent?.id ?? fallback.id,
|
|
18
|
+
createdAt: assistantEvent?.createdAt ?? fallback.createdAt,
|
|
19
|
+
content: mergedContent,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export function createScriptedReactor(options) {
|
|
23
|
+
const steps = Array.isArray(options.steps) ? options.steps : [];
|
|
24
|
+
if (steps.length === 0) {
|
|
25
|
+
throw new Error("createScriptedReactor: options.steps must contain at least one step.");
|
|
26
|
+
}
|
|
27
|
+
let index = 0;
|
|
28
|
+
return async (params) => {
|
|
29
|
+
const hasCurrentStep = index < steps.length;
|
|
30
|
+
if (!hasCurrentStep && !options.repeatLast) {
|
|
31
|
+
throw new Error(`createScriptedReactor: no scripted step available at index ${index}. ` +
|
|
32
|
+
`Provided steps=${steps.length}. Enable repeatLast to reuse the final step.`);
|
|
33
|
+
}
|
|
34
|
+
const stepIndex = hasCurrentStep ? index : steps.length - 1;
|
|
35
|
+
const scriptedStep = steps[stepIndex];
|
|
36
|
+
if (hasCurrentStep) {
|
|
37
|
+
index += 1;
|
|
38
|
+
}
|
|
39
|
+
const payload = typeof scriptedStep === "function"
|
|
40
|
+
? await scriptedStep(params)
|
|
41
|
+
: scriptedStep;
|
|
42
|
+
return {
|
|
43
|
+
assistantEvent: normalizeScriptedAssistantEvent(params, payload.assistantEvent),
|
|
44
|
+
actionRequests: Array.isArray(payload.actionRequests) ? payload.actionRequests : [],
|
|
45
|
+
messagesForModel: Array.isArray(payload.messagesForModel)
|
|
46
|
+
? payload.messagesForModel
|
|
47
|
+
: [],
|
|
48
|
+
llm: payload.llm,
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { ModelMessage, UIMessageChunk } from "ai";
|
|
2
|
+
import type { ContextEnvironment } from "../context.config.js";
|
|
3
|
+
import type { ContextModelInit } from "../context.engine.js";
|
|
4
|
+
import type { ContextIdentifier, StoredContext, ContextItem } from "../context.store.js";
|
|
5
|
+
import type { ContextSkillPackage } from "../context.skill.js";
|
|
6
|
+
import type { SerializableToolForModel } from "../tools-to-model-tools.js";
|
|
7
|
+
export type ContextActionRequest = {
|
|
8
|
+
actionRef: string;
|
|
9
|
+
actionName: string;
|
|
10
|
+
input: unknown;
|
|
11
|
+
};
|
|
12
|
+
export type ContextReactionLLM = {
|
|
13
|
+
provider?: string;
|
|
14
|
+
model?: string;
|
|
15
|
+
promptTokens?: number;
|
|
16
|
+
promptTokensCached?: number;
|
|
17
|
+
promptTokensUncached?: number;
|
|
18
|
+
completionTokens?: number;
|
|
19
|
+
totalTokens?: number;
|
|
20
|
+
latencyMs?: number;
|
|
21
|
+
rawUsage?: unknown;
|
|
22
|
+
rawProviderMetadata?: unknown;
|
|
23
|
+
};
|
|
24
|
+
export type ContextReactionResult = {
|
|
25
|
+
assistantEvent: ContextItem;
|
|
26
|
+
actionRequests: ContextActionRequest[];
|
|
27
|
+
messagesForModel: ModelMessage[];
|
|
28
|
+
llm?: ContextReactionLLM;
|
|
29
|
+
};
|
|
30
|
+
export type ContextReactorParams<Context = unknown, Env extends ContextEnvironment = ContextEnvironment> = {
|
|
31
|
+
env: Env;
|
|
32
|
+
context: StoredContext<Context>;
|
|
33
|
+
contextIdentifier: ContextIdentifier;
|
|
34
|
+
triggerEvent: ContextItem;
|
|
35
|
+
model: ContextModelInit;
|
|
36
|
+
systemPrompt: string;
|
|
37
|
+
actions: Record<string, unknown>;
|
|
38
|
+
toolsForModel: Record<string, SerializableToolForModel>;
|
|
39
|
+
skills: ContextSkillPackage[];
|
|
40
|
+
eventId: string;
|
|
41
|
+
executionId: string;
|
|
42
|
+
contextId: string;
|
|
43
|
+
stepId: string;
|
|
44
|
+
iteration: number;
|
|
45
|
+
maxModelSteps: number;
|
|
46
|
+
sendStart: boolean;
|
|
47
|
+
silent: boolean;
|
|
48
|
+
contextStepStream?: WritableStream<string>;
|
|
49
|
+
writable?: WritableStream<UIMessageChunk>;
|
|
50
|
+
persistReactionParts?: (parts: any[]) => Promise<void>;
|
|
51
|
+
};
|
|
52
|
+
export type ContextReactor<Context = unknown, Env extends ContextEnvironment = ContextEnvironment> = (params: ContextReactorParams<Context, Env>) => Promise<ContextReactionResult>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime-only entrypoint for @ekairos/events.
|
|
3
|
+
*
|
|
4
|
+
* This file intentionally exports the "wiring" pieces that connect durable steps to a concrete
|
|
5
|
+
* store runtime (Instant/Postgres/etc).
|
|
6
|
+
*
|
|
7
|
+
* IMPORTANT:
|
|
8
|
+
* - Do NOT import this entrypoint from client/browser code.
|
|
9
|
+
* - Keep `@ekairos/events` main entrypoint safe to import from schema/domain modules.
|
|
10
|
+
*/
|
|
11
|
+
export { getContextRuntime, } from "./runtime.step.js";
|
|
12
|
+
export { createContextStepStreamClientId, createPersistedContextStepStream, readPersistedContextStepStream, resolveContextExecutionStreamPointer, waitForContextExecutionStreamPointer, } from "./steps/stream.steps.js";
|
|
13
|
+
export type { ContextEnvironment, ContextRuntime } from "./context.config.js";
|
|
14
|
+
export { registerContextEnv, getContextEnv } from "./env.js";
|
|
15
|
+
export { configureContextDurableWorkflow } from "./context.durable.js";
|
|
16
|
+
export type RegistrableContext = {
|
|
17
|
+
key?: string;
|
|
18
|
+
register: () => void;
|
|
19
|
+
};
|
package/dist/runtime.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime-only entrypoint for @ekairos/events.
|
|
3
|
+
*
|
|
4
|
+
* This file intentionally exports the "wiring" pieces that connect durable steps to a concrete
|
|
5
|
+
* store runtime (Instant/Postgres/etc).
|
|
6
|
+
*
|
|
7
|
+
* IMPORTANT:
|
|
8
|
+
* - Do NOT import this entrypoint from client/browser code.
|
|
9
|
+
* - Keep `@ekairos/events` main entrypoint safe to import from schema/domain modules.
|
|
10
|
+
*/
|
|
11
|
+
if (typeof globalThis.Event === "undefined") {
|
|
12
|
+
class NodeEvent {
|
|
13
|
+
constructor(type, init) {
|
|
14
|
+
this.type = type;
|
|
15
|
+
if (init && typeof init === "object") {
|
|
16
|
+
Object.assign(this, init);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
;
|
|
21
|
+
globalThis.Event = NodeEvent;
|
|
22
|
+
}
|
|
23
|
+
export { getContextRuntime, } from "./runtime.step.js";
|
|
24
|
+
export { createContextStepStreamClientId, createPersistedContextStepStream, readPersistedContextStepStream, resolveContextExecutionStreamPointer, waitForContextExecutionStreamPointer, } from "./steps/stream.steps.js";
|
|
25
|
+
export { registerContextEnv, getContextEnv } from "./env.js";
|
|
26
|
+
export { configureContextDurableWorkflow } from "./context.durable.js";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal helper to resolve Context runtime from within workflow steps.
|
|
3
|
+
*
|
|
4
|
+
* Why dynamic import?
|
|
5
|
+
* - Some bundlers (notably Turbopack step bundles) can drop/hoist static imports in "use-step" modules.
|
|
6
|
+
* - Keeping `resolveRuntime` behind a dynamic import makes symbol resolution local to step execution.
|
|
7
|
+
*/
|
|
8
|
+
import type { ContextEnvironment, ContextRuntime } from "./context.config.js";
|
|
9
|
+
export declare function getContextRuntime(env: ContextEnvironment): Promise<ContextRuntime>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { coerceContextRuntime } from "./context.config.js";
|
|
2
|
+
import { eventsDomain } from "./schema.js";
|
|
3
|
+
export async function getContextRuntime(env) {
|
|
4
|
+
const { resolveRuntime } = await import("@ekairos/domain/runtime-step");
|
|
5
|
+
const resolved = await resolveRuntime(eventsDomain, env);
|
|
6
|
+
return await coerceContextRuntime(resolved);
|
|
7
|
+
}
|
package/dist/schema.d.ts
ADDED