@ekairos/story 1.21.40-beta.0 → 1.21.43-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ekairos.config.js +1 -16
- package/dist/index.d.ts +6 -6
- package/dist/index.js +5 -5
- package/dist/next.d.ts +2 -1
- package/dist/next.js +40 -27
- package/dist/runtime.d.ts +1 -2
- package/dist/runtime.js +1 -2
- package/dist/steps/reaction.steps.d.ts +25 -0
- package/dist/steps/reaction.steps.js +135 -0
- package/dist/steps/store.steps.d.ts +13 -28
- package/dist/steps/store.steps.js +20 -56
- package/dist/steps/stream.steps.d.ts +7 -0
- package/dist/steps/stream.steps.js +15 -0
- package/dist/stores/instant.document-parser.d.ts +1 -1
- package/dist/stores/instant.document-parser.js +175 -39
- package/dist/stores/instant.documents.js +82 -6
- package/dist/stores/instant.store.d.ts +2 -0
- package/dist/stores/instant.store.js +13 -0
- package/dist/story.builder.d.ts +4 -4
- package/dist/story.builder.js +2 -2
- package/dist/story.config.d.ts +0 -2
- package/dist/story.config.js +46 -39
- package/dist/story.d.ts +2 -2
- package/dist/story.engine.d.ts +2 -2
- package/dist/story.engine.js +19 -17
- package/dist/story.js +2 -2
- package/package.json +2 -2
package/dist/ekairos.config.js
CHANGED
|
@@ -1,15 +1,4 @@
|
|
|
1
1
|
import { configureStoryRuntime, configureStoryRuntimeBootstrap, isStoryRuntimeConfigured, } from "./story.config";
|
|
2
|
-
const GLOBAL_EKAIROS_CONFIG = Symbol.for("@ekairos/story.ekairosConfig");
|
|
3
|
-
function setGlobalEkairosConfig(config) {
|
|
4
|
-
try {
|
|
5
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6
|
-
;
|
|
7
|
-
globalThis[GLOBAL_EKAIROS_CONFIG] = config;
|
|
8
|
-
}
|
|
9
|
-
catch {
|
|
10
|
-
// ignore
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
2
|
/**
|
|
14
3
|
* Creates a small "framework-style" config object that can be executed in the step runtime.
|
|
15
4
|
*
|
|
@@ -18,7 +7,7 @@ function setGlobalEkairosConfig(config) {
|
|
|
18
7
|
*/
|
|
19
8
|
export function createEkairosConfig(params) {
|
|
20
9
|
const stories = params.stories ?? [];
|
|
21
|
-
|
|
10
|
+
return {
|
|
22
11
|
stories,
|
|
23
12
|
runtime: params.runtime,
|
|
24
13
|
setup() {
|
|
@@ -34,8 +23,4 @@ export function createEkairosConfig(params) {
|
|
|
34
23
|
s.register();
|
|
35
24
|
},
|
|
36
25
|
};
|
|
37
|
-
// Register globally (process-level) so libraries/steps can access it transparently.
|
|
38
|
-
// Note: This does NOT call `setup()` (no runtime side-effects).
|
|
39
|
-
setGlobalEkairosConfig(config);
|
|
40
|
-
return config;
|
|
41
26
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { story, createStory, type StoryConfig, type StoryInstance, type StoryOptions, type StoryStreamOptions, Story, type RegistrableStoryBuilder, } from "./story";
|
|
2
|
-
export type { StoryStore, ContextIdentifier, StoredContext, ContextEvent, } from "./story.store";
|
|
3
|
-
export { registerStory, getStory, getStoryFactory, hasStory, listStories, type StoryKey, } from "./story.registry";
|
|
4
|
-
export { storyDomain } from "./schema";
|
|
5
|
-
export { didToolExecute } from "./story.toolcalls";
|
|
6
|
-
export { USER_MESSAGE_TYPE, ASSISTANT_MESSAGE_TYPE, SYSTEM_MESSAGE_TYPE, WEB_CHANNEL, AGENT_CHANNEL, EMAIL_CHANNEL, createUserEventFromUIMessages, createAssistantEventFromUIMessages, convertToUIMessage, convertEventToModelMessages, convertEventsToModelMessages, convertModelMessageToEvent, type ResponseMessage, } from "./events";
|
|
1
|
+
export { story, createStory, type StoryConfig, type StoryInstance, type StoryOptions, type StoryStreamOptions, Story, type RegistrableStoryBuilder, } from "./story.js";
|
|
2
|
+
export type { StoryStore, ContextIdentifier, StoredContext, ContextEvent, } from "./story.store.js";
|
|
3
|
+
export { registerStory, getStory, getStoryFactory, hasStory, listStories, type StoryKey, } from "./story.registry.js";
|
|
4
|
+
export { storyDomain } from "./schema.js";
|
|
5
|
+
export { didToolExecute } from "./story.toolcalls.js";
|
|
6
|
+
export { USER_MESSAGE_TYPE, ASSISTANT_MESSAGE_TYPE, SYSTEM_MESSAGE_TYPE, WEB_CHANNEL, AGENT_CHANNEL, EMAIL_CHANNEL, createUserEventFromUIMessages, createAssistantEventFromUIMessages, convertToUIMessage, convertEventToModelMessages, convertEventsToModelMessages, convertModelMessageToEvent, type ResponseMessage, } from "./events.js";
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export {
|
|
2
2
|
// Story API
|
|
3
|
-
story, createStory, Story, } from "./story";
|
|
4
|
-
export { registerStory, getStory, getStoryFactory, hasStory, listStories, } from "./story.registry";
|
|
5
|
-
export { storyDomain } from "./schema";
|
|
6
|
-
export { didToolExecute } from "./story.toolcalls";
|
|
7
|
-
export { USER_MESSAGE_TYPE, ASSISTANT_MESSAGE_TYPE, SYSTEM_MESSAGE_TYPE, WEB_CHANNEL, AGENT_CHANNEL, EMAIL_CHANNEL, createUserEventFromUIMessages, createAssistantEventFromUIMessages, convertToUIMessage, convertEventToModelMessages, convertEventsToModelMessages, convertModelMessageToEvent, } from "./events";
|
|
3
|
+
story, createStory, Story, } from "./story.js";
|
|
4
|
+
export { registerStory, getStory, getStoryFactory, hasStory, listStories, } from "./story.registry.js";
|
|
5
|
+
export { storyDomain } from "./schema.js";
|
|
6
|
+
export { didToolExecute } from "./story.toolcalls.js";
|
|
7
|
+
export { USER_MESSAGE_TYPE, ASSISTANT_MESSAGE_TYPE, SYSTEM_MESSAGE_TYPE, WEB_CHANNEL, AGENT_CHANNEL, EMAIL_CHANNEL, createUserEventFromUIMessages, createAssistantEventFromUIMessages, convertToUIMessage, convertEventToModelMessages, convertEventsToModelMessages, convertModelMessageToEvent, } from "./events.js";
|
package/dist/next.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ type WithEkairosRuntimeOptions = {
|
|
|
11
11
|
*/
|
|
12
12
|
bootstrapModule: string;
|
|
13
13
|
};
|
|
14
|
+
type NextConfigFnLike = (phase: string, ctx: any) => Promise<any> | any;
|
|
14
15
|
/**
|
|
15
16
|
* Next.js helper to ensure the story runtime factory is registered in *every* server bundle.
|
|
16
17
|
*
|
|
@@ -19,5 +20,5 @@ type WithEkairosRuntimeOptions = {
|
|
|
19
20
|
* - No "magic" root bootstrap file
|
|
20
21
|
* - Works for step runtimes because the server entry will always evaluate your bootstrap module
|
|
21
22
|
*/
|
|
22
|
-
export declare function withEkairosRuntime(
|
|
23
|
+
export declare function withEkairosRuntime(nextConfigOrFn: NextConfigLike | NextConfigFnLike, opts: WithEkairosRuntimeOptions): any;
|
|
23
24
|
export {};
|
package/dist/next.js
CHANGED
|
@@ -72,34 +72,47 @@ function injectBootstrapIntoEntries(entries, bootstrap) {
|
|
|
72
72
|
* - No "magic" root bootstrap file
|
|
73
73
|
* - Works for step runtimes because the server entry will always evaluate your bootstrap module
|
|
74
74
|
*/
|
|
75
|
-
export function withEkairosRuntime(
|
|
75
|
+
export function withEkairosRuntime(nextConfigOrFn, opts) {
|
|
76
76
|
const bootstrapModule = opts.bootstrapModule;
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
77
|
+
const apply = (nextConfig) => {
|
|
78
|
+
const userWebpack = nextConfig.webpack ?? undefined;
|
|
79
|
+
return {
|
|
80
|
+
...nextConfig,
|
|
81
|
+
webpack: (config, options) => {
|
|
82
|
+
const out = userWebpack ? userWebpack(config, options) : config;
|
|
83
|
+
// NOTE:
|
|
84
|
+
// - We still attempt the patch here for webpack builds.
|
|
85
|
+
// - But for Turbopack builds, this hook may never run, so we ALSO patch
|
|
86
|
+
// in the config-function wrapper below (after withWorkflow generates the file).
|
|
87
|
+
patchWorkflowStepRouteToImportBootstrap(bootstrapModule);
|
|
88
|
+
if (!options?.isServer)
|
|
89
|
+
return out;
|
|
90
|
+
const req = createRequire(import.meta.url);
|
|
91
|
+
const contextDir = (out && out.context) || process.cwd();
|
|
92
|
+
// Resolve relative to the app project (webpack context), not to this package.
|
|
93
|
+
const resolvedBootstrap = req.resolve(bootstrapModule, {
|
|
94
|
+
paths: [contextDir],
|
|
95
|
+
});
|
|
96
|
+
const originalEntry = out.entry;
|
|
97
|
+
out.entry = async () => {
|
|
98
|
+
const entries = typeof originalEntry === "function" ? await originalEntry() : originalEntry;
|
|
99
|
+
injectBootstrapIntoEntries(entries, resolvedBootstrap);
|
|
100
|
+
return entries;
|
|
101
|
+
};
|
|
89
102
|
return out;
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
// Resolve relative to the app project (webpack context), not to this package.
|
|
93
|
-
const resolvedBootstrap = req.resolve(bootstrapModule, {
|
|
94
|
-
paths: [contextDir],
|
|
95
|
-
});
|
|
96
|
-
const originalEntry = out.entry;
|
|
97
|
-
out.entry = async () => {
|
|
98
|
-
const entries = typeof originalEntry === "function" ? await originalEntry() : originalEntry;
|
|
99
|
-
injectBootstrapIntoEntries(entries, resolvedBootstrap);
|
|
100
|
-
return entries;
|
|
101
|
-
};
|
|
102
|
-
return out;
|
|
103
|
-
},
|
|
103
|
+
},
|
|
104
|
+
};
|
|
104
105
|
};
|
|
106
|
+
// Critical path for Vercel/Turbopack:
|
|
107
|
+
// `@workflow/next` generates `src/app/.well-known/workflow/v1/step/route.js` inside its config function.
|
|
108
|
+
// So we must patch AFTER that function runs (not inside webpack).
|
|
109
|
+
if (typeof nextConfigOrFn === "function") {
|
|
110
|
+
return async (phase, ctx) => {
|
|
111
|
+
const cfg = await nextConfigOrFn(phase, ctx);
|
|
112
|
+
patchWorkflowStepRouteToImportBootstrap(bootstrapModule);
|
|
113
|
+
return apply(cfg);
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
// Object config: best-effort patch (file may not exist yet here)
|
|
117
|
+
return apply(nextConfigOrFn);
|
|
105
118
|
}
|
package/dist/runtime.d.ts
CHANGED
|
@@ -8,6 +8,5 @@
|
|
|
8
8
|
* - Do NOT import this entrypoint from client/browser code.
|
|
9
9
|
* - Keep `@ekairos/story` main entrypoint safe to import from schema/domain modules.
|
|
10
10
|
*/
|
|
11
|
-
export { configureStoryRuntime, configureStoryRuntimeBootstrap,
|
|
11
|
+
export { configureStoryRuntime, configureStoryRuntimeBootstrap, isStoryRuntimeConfigured, resolveStoryRuntime, type StoryEnvironment, type StoryRuntime, type StoryRuntimeResolver, } from "./story.config";
|
|
12
12
|
export { createEkairosConfig, type EkairosConfig, type RegistrableStory, } from "./ekairos.config";
|
|
13
|
-
export { withEkairosRuntime } from "./next";
|
package/dist/runtime.js
CHANGED
|
@@ -8,6 +8,5 @@
|
|
|
8
8
|
* - Do NOT import this entrypoint from client/browser code.
|
|
9
9
|
* - Keep `@ekairos/story` main entrypoint safe to import from schema/domain modules.
|
|
10
10
|
*/
|
|
11
|
-
export { configureStoryRuntime, configureStoryRuntimeBootstrap,
|
|
11
|
+
export { configureStoryRuntime, configureStoryRuntimeBootstrap, isStoryRuntimeConfigured, resolveStoryRuntime, } from "./story.config";
|
|
12
12
|
export { createEkairosConfig, } from "./ekairos.config";
|
|
13
|
-
export { withEkairosRuntime } from "./next";
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type ModelMessage } from "ai";
|
|
2
|
+
import type { StoryEnvironment } from "../story.config";
|
|
3
|
+
import type { ContextEvent, ContextIdentifier } from "../story.store";
|
|
4
|
+
import type { SerializableToolForModel } from "../tools-to-model-tools";
|
|
5
|
+
/**
|
|
6
|
+
* Executes a full "reaction" inside a single workflow step:
|
|
7
|
+
* - load events from store
|
|
8
|
+
* - convert events to model messages
|
|
9
|
+
* - run the streaming model call and emit chunks
|
|
10
|
+
* - extract tool calls from the resulting assistant event
|
|
11
|
+
*/
|
|
12
|
+
export declare function executeReaction(params: {
|
|
13
|
+
env: StoryEnvironment;
|
|
14
|
+
contextIdentifier: ContextIdentifier;
|
|
15
|
+
model: any;
|
|
16
|
+
system: string;
|
|
17
|
+
tools: Record<string, SerializableToolForModel>;
|
|
18
|
+
eventId: string;
|
|
19
|
+
maxSteps: number;
|
|
20
|
+
sendStart?: boolean;
|
|
21
|
+
}): Promise<{
|
|
22
|
+
assistantEvent: ContextEvent;
|
|
23
|
+
toolCalls: any[];
|
|
24
|
+
messagesForModel: ModelMessage[];
|
|
25
|
+
}>;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { jsonSchema, gateway, smoothStream, stepCountIs, streamText, } from "ai";
|
|
2
|
+
import { getWritable } from "workflow";
|
|
3
|
+
import { resolveStoryRuntime } from "../story.config";
|
|
4
|
+
import { extractToolCallsFromParts } from "../story.toolcalls";
|
|
5
|
+
function safeErrorJson(error) {
|
|
6
|
+
const seen = new WeakSet();
|
|
7
|
+
const redactKey = (k) => /token|authorization|cookie|secret|api[_-]?key|password/i.test(k);
|
|
8
|
+
const err = error;
|
|
9
|
+
const payload = {
|
|
10
|
+
name: err?.name,
|
|
11
|
+
message: err?.message,
|
|
12
|
+
status: err?.status,
|
|
13
|
+
body: err?.body,
|
|
14
|
+
data: err?.data,
|
|
15
|
+
stack: err?.stack,
|
|
16
|
+
};
|
|
17
|
+
try {
|
|
18
|
+
return JSON.stringify(payload, (k, v) => {
|
|
19
|
+
if (redactKey(k))
|
|
20
|
+
return "[redacted]";
|
|
21
|
+
if (typeof v === "string" && v.length > 5000)
|
|
22
|
+
return "[truncated-string]";
|
|
23
|
+
if (typeof v === "object" && v !== null) {
|
|
24
|
+
if (seen.has(v))
|
|
25
|
+
return "[circular]";
|
|
26
|
+
seen.add(v);
|
|
27
|
+
}
|
|
28
|
+
return v;
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return JSON.stringify({ message: String(err?.message ?? "error") });
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Executes a full "reaction" inside a single workflow step:
|
|
37
|
+
* - load events from store
|
|
38
|
+
* - convert events to model messages
|
|
39
|
+
* - run the streaming model call and emit chunks
|
|
40
|
+
* - extract tool calls from the resulting assistant event
|
|
41
|
+
*/
|
|
42
|
+
export async function executeReaction(params) {
|
|
43
|
+
"use step";
|
|
44
|
+
const { store } = await resolveStoryRuntime(params.env);
|
|
45
|
+
console.log("executeReaction: begin");
|
|
46
|
+
let events;
|
|
47
|
+
try {
|
|
48
|
+
console.log("executeReaction: store.getEvents begin");
|
|
49
|
+
events = await store.getEvents(params.contextIdentifier);
|
|
50
|
+
console.log("executeReaction: store.getEvents ok");
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
console.error("executeReaction: store.getEvents failed");
|
|
54
|
+
throw error;
|
|
55
|
+
}
|
|
56
|
+
let messagesForModel;
|
|
57
|
+
try {
|
|
58
|
+
console.log("executeReaction: store.eventsToModelMessages begin");
|
|
59
|
+
messagesForModel = (await store.eventsToModelMessages(events));
|
|
60
|
+
console.log("executeReaction: store.eventsToModelMessages ok");
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
console.error("executeReaction: store.eventsToModelMessages failed", safeErrorJson(error));
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
66
|
+
const writable = getWritable();
|
|
67
|
+
// Match DurableAgent-style model init behavior:
|
|
68
|
+
const resolvedModel = typeof params.model === "string"
|
|
69
|
+
? gateway(params.model)
|
|
70
|
+
: typeof params.model === "function"
|
|
71
|
+
? await params.model()
|
|
72
|
+
: params.model;
|
|
73
|
+
// Wrap plain JSON Schema objects so the AI SDK doesn't attempt Zod conversion at runtime.
|
|
74
|
+
const toolsForStreamText = {};
|
|
75
|
+
for (const [name, t] of Object.entries(params.tools)) {
|
|
76
|
+
toolsForStreamText[name] = {
|
|
77
|
+
description: t?.description,
|
|
78
|
+
inputSchema: jsonSchema(t.inputSchema),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
console.log("executeReaction: streamText begin");
|
|
82
|
+
const result = streamText({
|
|
83
|
+
model: resolvedModel,
|
|
84
|
+
system: params.system,
|
|
85
|
+
messages: messagesForModel,
|
|
86
|
+
tools: toolsForStreamText,
|
|
87
|
+
toolChoice: "required",
|
|
88
|
+
stopWhen: stepCountIs(params.maxSteps),
|
|
89
|
+
experimental_transform: smoothStream({ delayInMs: 30, chunking: "word" }),
|
|
90
|
+
});
|
|
91
|
+
console.log("executeReaction: streamText ok");
|
|
92
|
+
// Ensure the underlying stream is consumed (AI SDK requirement)
|
|
93
|
+
result.consumeStream();
|
|
94
|
+
let resolveFinish;
|
|
95
|
+
let rejectFinish;
|
|
96
|
+
const finishPromise = new Promise((resolve, reject) => {
|
|
97
|
+
resolveFinish = resolve;
|
|
98
|
+
rejectFinish = reject;
|
|
99
|
+
});
|
|
100
|
+
const uiStream = result
|
|
101
|
+
.toUIMessageStream({
|
|
102
|
+
sendStart: Boolean(params.sendStart),
|
|
103
|
+
generateMessageId: () => params.eventId,
|
|
104
|
+
messageMetadata() {
|
|
105
|
+
return { eventId: params.eventId };
|
|
106
|
+
},
|
|
107
|
+
onFinish: ({ messages }) => {
|
|
108
|
+
const lastMessage = messages[messages.length - 1];
|
|
109
|
+
const event = {
|
|
110
|
+
id: params.eventId,
|
|
111
|
+
type: "assistant.message",
|
|
112
|
+
channel: "web",
|
|
113
|
+
createdAt: new Date().toISOString(),
|
|
114
|
+
content: { parts: lastMessage?.parts ?? [] },
|
|
115
|
+
};
|
|
116
|
+
resolveFinish(event);
|
|
117
|
+
},
|
|
118
|
+
onError: (e) => {
|
|
119
|
+
rejectFinish(e);
|
|
120
|
+
return e instanceof Error ? e.message : String(e);
|
|
121
|
+
},
|
|
122
|
+
})
|
|
123
|
+
// Filter out per-step finish boundary. Workflow will emit a single finish.
|
|
124
|
+
.pipeThrough(new TransformStream({
|
|
125
|
+
transform(chunk, controller) {
|
|
126
|
+
if (chunk.type === "finish")
|
|
127
|
+
return;
|
|
128
|
+
controller.enqueue(chunk);
|
|
129
|
+
},
|
|
130
|
+
}));
|
|
131
|
+
await uiStream.pipeTo(writable, { preventClose: true });
|
|
132
|
+
const assistantEvent = await finishPromise;
|
|
133
|
+
const toolCalls = extractToolCallsFromParts(assistantEvent?.content?.parts);
|
|
134
|
+
return { assistantEvent, toolCalls, messagesForModel };
|
|
135
|
+
}
|
|
@@ -1,43 +1,28 @@
|
|
|
1
|
-
import type { ModelMessage } from "ai";
|
|
2
1
|
import { type StoryEnvironment } from "../story.config";
|
|
3
2
|
import type { ContextEvent, ContextIdentifier, StoredContext } from "../story.store";
|
|
4
|
-
export declare function generateId(): Promise<string>;
|
|
5
|
-
export declare function getOrCreateContext<C>(env: StoryEnvironment, contextIdentifier: ContextIdentifier | null): Promise<{
|
|
6
|
-
context: StoredContext<C>;
|
|
7
|
-
isNew: boolean;
|
|
8
|
-
}>;
|
|
9
3
|
/**
|
|
10
|
-
*
|
|
4
|
+
* Initializes/ensures the story context exists and emits a single `data-context-id` chunk.
|
|
11
5
|
*
|
|
12
|
-
*
|
|
13
|
-
* - `getOrCreateContext(...)` and `writeContextIdChunk(...)` are semantically coupled.
|
|
14
|
-
* - Keeping them in a single step reduces step invocations per run (cheaper) without changing behavior.
|
|
6
|
+
* This is the "context init" boundary for the story engine.
|
|
15
7
|
*/
|
|
16
|
-
export declare function
|
|
8
|
+
export declare function initializeContext<C>(env: StoryEnvironment, contextIdentifier: ContextIdentifier | null): Promise<{
|
|
17
9
|
context: StoredContext<C>;
|
|
18
10
|
isNew: boolean;
|
|
19
11
|
}>;
|
|
20
|
-
export declare function getContext<C>(env: StoryEnvironment, contextIdentifier: ContextIdentifier): Promise<StoredContext<C> | null>;
|
|
21
|
-
/**
|
|
22
|
-
* Loads the state needed for a single Story loop iteration.
|
|
23
|
-
*
|
|
24
|
-
* This is a "read aggregation" step: it groups read-only store calls into a single workflow step
|
|
25
|
-
* invocation to reduce step overhead (cheaper) without changing behavior.
|
|
26
|
-
*/
|
|
27
|
-
export declare function loadTurnState<C>(params: {
|
|
28
|
-
env: StoryEnvironment;
|
|
29
|
-
contextIdentifier: ContextIdentifier;
|
|
30
|
-
}): Promise<{
|
|
31
|
-
context: StoredContext<C> | null;
|
|
32
|
-
events: ContextEvent[];
|
|
33
|
-
}>;
|
|
34
12
|
export declare function updateContextContent<C>(env: StoryEnvironment, contextIdentifier: ContextIdentifier, content: C): Promise<StoredContext<C>>;
|
|
35
13
|
export declare function updateContextStatus(env: StoryEnvironment, contextIdentifier: ContextIdentifier, status: "open" | "streaming" | "closed"): Promise<void>;
|
|
36
|
-
export declare function
|
|
14
|
+
export declare function saveTriggerEvent(env: StoryEnvironment, contextIdentifier: ContextIdentifier, event: ContextEvent): Promise<ContextEvent>;
|
|
15
|
+
export declare function saveReactionEvent(env: StoryEnvironment, contextIdentifier: ContextIdentifier, event: ContextEvent): Promise<ContextEvent>;
|
|
37
16
|
export declare function updateEvent(env: StoryEnvironment, eventId: string, event: ContextEvent): Promise<ContextEvent>;
|
|
38
|
-
export declare function getEvents(env: StoryEnvironment, contextIdentifier: ContextIdentifier): Promise<ContextEvent[]>;
|
|
39
17
|
export declare function createExecution(env: StoryEnvironment, contextIdentifier: ContextIdentifier, triggerEventId: string, reactionEventId: string): Promise<{
|
|
40
18
|
id: string;
|
|
41
19
|
}>;
|
|
20
|
+
export declare function createReactionEvent(params: {
|
|
21
|
+
env: StoryEnvironment;
|
|
22
|
+
contextIdentifier: ContextIdentifier;
|
|
23
|
+
triggerEventId: string;
|
|
24
|
+
}): Promise<{
|
|
25
|
+
reactionEventId: string;
|
|
26
|
+
executionId: string;
|
|
27
|
+
}>;
|
|
42
28
|
export declare function completeExecution(env: StoryEnvironment, contextIdentifier: ContextIdentifier, executionId: string, status: "completed" | "failed"): Promise<void>;
|
|
43
|
-
export declare function eventsToModelMessages(env: StoryEnvironment, events: ContextEvent[]): Promise<ModelMessage[]>;
|
|
@@ -1,36 +1,11 @@
|
|
|
1
1
|
import { getWritable } from "workflow";
|
|
2
2
|
import { resolveStoryRuntime } from "../story.config";
|
|
3
|
-
export async function generateId() {
|
|
4
|
-
"use step";
|
|
5
|
-
// Use crypto.randomUUID when available (Node 18+)
|
|
6
|
-
const uuid = globalThis.crypto?.randomUUID?.();
|
|
7
|
-
if (uuid)
|
|
8
|
-
return uuid;
|
|
9
|
-
// Fallback
|
|
10
|
-
return `${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
11
|
-
}
|
|
12
|
-
export async function getOrCreateContext(env, contextIdentifier) {
|
|
13
|
-
"use step";
|
|
14
|
-
const { store } = await resolveStoryRuntime(env);
|
|
15
|
-
// Detect creation explicitly so the engine can run onContextCreated hooks.
|
|
16
|
-
if (!contextIdentifier) {
|
|
17
|
-
const context = await store.getOrCreateContext(null);
|
|
18
|
-
return { context, isNew: true };
|
|
19
|
-
}
|
|
20
|
-
const existing = await store.getContext(contextIdentifier);
|
|
21
|
-
if (existing)
|
|
22
|
-
return { context: existing, isNew: false };
|
|
23
|
-
const created = await store.getOrCreateContext(contextIdentifier);
|
|
24
|
-
return { context: created, isNew: true };
|
|
25
|
-
}
|
|
26
3
|
/**
|
|
27
|
-
*
|
|
4
|
+
* Initializes/ensures the story context exists and emits a single `data-context-id` chunk.
|
|
28
5
|
*
|
|
29
|
-
*
|
|
30
|
-
* - `getOrCreateContext(...)` and `writeContextIdChunk(...)` are semantically coupled.
|
|
31
|
-
* - Keeping them in a single step reduces step invocations per run (cheaper) without changing behavior.
|
|
6
|
+
* This is the "context init" boundary for the story engine.
|
|
32
7
|
*/
|
|
33
|
-
export async function
|
|
8
|
+
export async function initializeContext(env, contextIdentifier) {
|
|
34
9
|
"use step";
|
|
35
10
|
const { store } = await resolveStoryRuntime(env);
|
|
36
11
|
// Detect creation explicitly so the engine can run onContextCreated hooks.
|
|
@@ -63,24 +38,6 @@ export async function ensureContextAndEmitContextId(env, contextIdentifier) {
|
|
|
63
38
|
}
|
|
64
39
|
return result;
|
|
65
40
|
}
|
|
66
|
-
export async function getContext(env, contextIdentifier) {
|
|
67
|
-
"use step";
|
|
68
|
-
const { store } = await resolveStoryRuntime(env);
|
|
69
|
-
return await store.getContext(contextIdentifier);
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Loads the state needed for a single Story loop iteration.
|
|
73
|
-
*
|
|
74
|
-
* This is a "read aggregation" step: it groups read-only store calls into a single workflow step
|
|
75
|
-
* invocation to reduce step overhead (cheaper) without changing behavior.
|
|
76
|
-
*/
|
|
77
|
-
export async function loadTurnState(params) {
|
|
78
|
-
"use step";
|
|
79
|
-
const { store } = await resolveStoryRuntime(params.env);
|
|
80
|
-
const context = await store.getContext(params.contextIdentifier);
|
|
81
|
-
const events = await store.getEvents(params.contextIdentifier);
|
|
82
|
-
return { context, events };
|
|
83
|
-
}
|
|
84
41
|
export async function updateContextContent(env, contextIdentifier, content) {
|
|
85
42
|
"use step";
|
|
86
43
|
const { store } = await resolveStoryRuntime(env);
|
|
@@ -91,33 +48,40 @@ export async function updateContextStatus(env, contextIdentifier, status) {
|
|
|
91
48
|
const { store } = await resolveStoryRuntime(env);
|
|
92
49
|
await store.updateContextStatus(contextIdentifier, status);
|
|
93
50
|
}
|
|
94
|
-
export async function
|
|
51
|
+
export async function saveTriggerEvent(env, contextIdentifier, event) {
|
|
95
52
|
"use step";
|
|
96
53
|
const { store } = await resolveStoryRuntime(env);
|
|
97
54
|
return await store.saveEvent(contextIdentifier, event);
|
|
98
55
|
}
|
|
99
|
-
export async function
|
|
56
|
+
export async function saveReactionEvent(env, contextIdentifier, event) {
|
|
100
57
|
"use step";
|
|
101
58
|
const { store } = await resolveStoryRuntime(env);
|
|
102
|
-
return await store.
|
|
59
|
+
return await store.saveEvent(contextIdentifier, event);
|
|
103
60
|
}
|
|
104
|
-
export async function
|
|
61
|
+
export async function updateEvent(env, eventId, event) {
|
|
105
62
|
"use step";
|
|
106
63
|
const { store } = await resolveStoryRuntime(env);
|
|
107
|
-
return await store.
|
|
64
|
+
return await store.updateEvent(eventId, event);
|
|
108
65
|
}
|
|
109
66
|
export async function createExecution(env, contextIdentifier, triggerEventId, reactionEventId) {
|
|
110
67
|
"use step";
|
|
111
68
|
const { store } = await resolveStoryRuntime(env);
|
|
112
69
|
return await store.createExecution(contextIdentifier, triggerEventId, reactionEventId);
|
|
113
70
|
}
|
|
114
|
-
export async function
|
|
71
|
+
export async function createReactionEvent(params) {
|
|
115
72
|
"use step";
|
|
116
|
-
const { store } = await resolveStoryRuntime(env);
|
|
117
|
-
|
|
73
|
+
const { store } = await resolveStoryRuntime(params.env);
|
|
74
|
+
// Generate a new reaction event id inside the step boundary.
|
|
75
|
+
const uuid = globalThis.crypto?.randomUUID?.();
|
|
76
|
+
const reactionEventId = typeof uuid === "string"
|
|
77
|
+
? uuid
|
|
78
|
+
: `${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
79
|
+
await store.updateContextStatus(params.contextIdentifier, "streaming");
|
|
80
|
+
const execution = await store.createExecution(params.contextIdentifier, params.triggerEventId, reactionEventId);
|
|
81
|
+
return { reactionEventId, executionId: execution.id };
|
|
118
82
|
}
|
|
119
|
-
export async function
|
|
83
|
+
export async function completeExecution(env, contextIdentifier, executionId, status) {
|
|
120
84
|
"use step";
|
|
121
85
|
const { store } = await resolveStoryRuntime(env);
|
|
122
|
-
|
|
86
|
+
await store.completeExecution(contextIdentifier, executionId, status);
|
|
123
87
|
}
|
|
@@ -11,6 +11,13 @@ export declare function writeContextSubstate(params: {
|
|
|
11
11
|
export declare function writeContextIdChunk(params: {
|
|
12
12
|
contextId: string;
|
|
13
13
|
}): Promise<void>;
|
|
14
|
+
export declare function writeStoryPing(params: {
|
|
15
|
+
/**
|
|
16
|
+
* Simple ping event to validate that the workflow stream is alive.
|
|
17
|
+
* This is intentionally generic so clients can ignore it safely.
|
|
18
|
+
*/
|
|
19
|
+
label?: string;
|
|
20
|
+
}): Promise<void>;
|
|
14
21
|
export declare function writeToolOutputs(params: {
|
|
15
22
|
results: Array<{
|
|
16
23
|
toolCallId: string;
|
|
@@ -29,6 +29,21 @@ export async function writeContextIdChunk(params) {
|
|
|
29
29
|
writer.releaseLock();
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
|
+
export async function writeStoryPing(params) {
|
|
33
|
+
"use step";
|
|
34
|
+
const writable = getWritable();
|
|
35
|
+
const writer = writable.getWriter();
|
|
36
|
+
try {
|
|
37
|
+
await writer.write({
|
|
38
|
+
type: "data-story-ping",
|
|
39
|
+
data: { label: params.label ?? "story-ping" },
|
|
40
|
+
transient: true,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
finally {
|
|
44
|
+
writer.releaseLock();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
32
47
|
export async function writeToolOutputs(params) {
|
|
33
48
|
"use step";
|
|
34
49
|
const writable = getWritable();
|
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
* Parses a document with LlamaParse and stores it in InstantDB (document_documents + link to file).
|
|
3
3
|
* Returns the created documentId.
|
|
4
4
|
*/
|
|
5
|
-
export declare function parseAndStoreDocument(db: any, buffer: Buffer, fileName: string,
|
|
5
|
+
export declare function parseAndStoreDocument(db: any, buffer: Buffer, fileName: string, fileId: string): Promise<string>;
|