@ekairos/thread 1.21.88-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.
Files changed (86) hide show
  1. package/README.md +363 -0
  2. package/dist/codex.d.ts +95 -0
  3. package/dist/codex.js +91 -0
  4. package/dist/env.d.ts +12 -0
  5. package/dist/env.js +62 -0
  6. package/dist/events.d.ts +35 -0
  7. package/dist/events.js +102 -0
  8. package/dist/index.d.ts +9 -0
  9. package/dist/index.js +9 -0
  10. package/dist/mcp.d.ts +1 -0
  11. package/dist/mcp.js +1 -0
  12. package/dist/mirror.d.ts +41 -0
  13. package/dist/mirror.js +1 -0
  14. package/dist/oidc.d.ts +7 -0
  15. package/dist/oidc.js +25 -0
  16. package/dist/polyfills/dom-events.d.ts +1 -0
  17. package/dist/polyfills/dom-events.js +89 -0
  18. package/dist/react.d.ts +62 -0
  19. package/dist/react.js +101 -0
  20. package/dist/runtime.d.ts +17 -0
  21. package/dist/runtime.js +23 -0
  22. package/dist/runtime.step.d.ts +9 -0
  23. package/dist/runtime.step.js +7 -0
  24. package/dist/schema.d.ts +2 -0
  25. package/dist/schema.js +200 -0
  26. package/dist/steps/do-story-stream-step.d.ts +29 -0
  27. package/dist/steps/do-story-stream-step.js +89 -0
  28. package/dist/steps/do-thread-stream-step.d.ts +29 -0
  29. package/dist/steps/do-thread-stream-step.js +90 -0
  30. package/dist/steps/mirror.steps.d.ts +6 -0
  31. package/dist/steps/mirror.steps.js +48 -0
  32. package/dist/steps/reaction.steps.d.ts +43 -0
  33. package/dist/steps/reaction.steps.js +354 -0
  34. package/dist/steps/store.steps.d.ts +98 -0
  35. package/dist/steps/store.steps.js +512 -0
  36. package/dist/steps/stream.steps.d.ts +41 -0
  37. package/dist/steps/stream.steps.js +99 -0
  38. package/dist/steps/trace.steps.d.ts +37 -0
  39. package/dist/steps/trace.steps.js +265 -0
  40. package/dist/stores/instant.document-parser.d.ts +6 -0
  41. package/dist/stores/instant.document-parser.js +210 -0
  42. package/dist/stores/instant.documents.d.ts +16 -0
  43. package/dist/stores/instant.documents.js +152 -0
  44. package/dist/stores/instant.store.d.ts +78 -0
  45. package/dist/stores/instant.store.js +530 -0
  46. package/dist/story.actions.d.ts +60 -0
  47. package/dist/story.actions.js +120 -0
  48. package/dist/story.builder.d.ts +115 -0
  49. package/dist/story.builder.js +130 -0
  50. package/dist/story.config.d.ts +54 -0
  51. package/dist/story.config.js +125 -0
  52. package/dist/story.d.ts +2 -0
  53. package/dist/story.engine.d.ts +224 -0
  54. package/dist/story.engine.js +464 -0
  55. package/dist/story.hooks.d.ts +21 -0
  56. package/dist/story.hooks.js +31 -0
  57. package/dist/story.js +6 -0
  58. package/dist/story.registry.d.ts +21 -0
  59. package/dist/story.registry.js +30 -0
  60. package/dist/story.store.d.ts +107 -0
  61. package/dist/story.store.js +1 -0
  62. package/dist/story.toolcalls.d.ts +60 -0
  63. package/dist/story.toolcalls.js +73 -0
  64. package/dist/thread.builder.d.ts +118 -0
  65. package/dist/thread.builder.js +134 -0
  66. package/dist/thread.config.d.ts +15 -0
  67. package/dist/thread.config.js +30 -0
  68. package/dist/thread.d.ts +3 -0
  69. package/dist/thread.engine.d.ts +229 -0
  70. package/dist/thread.engine.js +471 -0
  71. package/dist/thread.events.d.ts +35 -0
  72. package/dist/thread.events.js +105 -0
  73. package/dist/thread.hooks.d.ts +21 -0
  74. package/dist/thread.hooks.js +31 -0
  75. package/dist/thread.js +7 -0
  76. package/dist/thread.reactor.d.ts +82 -0
  77. package/dist/thread.reactor.js +65 -0
  78. package/dist/thread.registry.d.ts +21 -0
  79. package/dist/thread.registry.js +30 -0
  80. package/dist/thread.store.d.ts +121 -0
  81. package/dist/thread.store.js +1 -0
  82. package/dist/thread.toolcalls.d.ts +60 -0
  83. package/dist/thread.toolcalls.js +73 -0
  84. package/dist/tools-to-model-tools.d.ts +19 -0
  85. package/dist/tools-to-model-tools.js +21 -0
  86. package/package.json +133 -0
package/dist/events.js ADDED
@@ -0,0 +1,102 @@
1
+ import { convertToModelMessages } from "ai";
2
+ export const USER_MESSAGE_TYPE = "user.message";
3
+ export const ASSISTANT_MESSAGE_TYPE = "assistant.message";
4
+ export const SYSTEM_MESSAGE_TYPE = "system.message";
5
+ export const WEB_CHANNEL = "web";
6
+ export const AGENT_CHANNEL = "whatsapp";
7
+ export const EMAIL_CHANNEL = "email";
8
+ export function createUserEventFromUIMessages(messages) {
9
+ if (!Array.isArray(messages) || messages.length === 0) {
10
+ throw new Error("Missing messages to create event");
11
+ }
12
+ const lastMessage = messages[messages.length - 1];
13
+ return {
14
+ id: lastMessage.id,
15
+ type: USER_MESSAGE_TYPE,
16
+ channel: WEB_CHANNEL,
17
+ content: {
18
+ parts: lastMessage.parts,
19
+ },
20
+ createdAt: new Date().toISOString(),
21
+ };
22
+ }
23
+ export function createAssistantEventFromUIMessages(eventId, messages) {
24
+ if (!Array.isArray(messages) || messages.length === 0) {
25
+ throw new Error("Missing messages to create event");
26
+ }
27
+ const lastMessage = messages[messages.length - 1];
28
+ return {
29
+ id: eventId,
30
+ type: ASSISTANT_MESSAGE_TYPE,
31
+ channel: WEB_CHANNEL,
32
+ content: {
33
+ parts: lastMessage.parts,
34
+ },
35
+ createdAt: new Date().toISOString(),
36
+ };
37
+ }
38
+ export function convertToUIMessage(event) {
39
+ let role;
40
+ if (event.type === USER_MESSAGE_TYPE) {
41
+ role = "user";
42
+ }
43
+ else {
44
+ role = "assistant";
45
+ }
46
+ return {
47
+ id: event.id,
48
+ role: role,
49
+ parts: event.content.parts,
50
+ metadata: {
51
+ channel: event.channel,
52
+ type: event.type,
53
+ createdAt: event.createdAt,
54
+ }
55
+ };
56
+ }
57
+ /**
58
+ * Converts stored ContextEvents to AI SDK ModelMessages.
59
+ *
60
+ * IMPORTANT:
61
+ * - Store-agnostic and workflow-safe.
62
+ * - Attachment/document handling MUST happen in the store boundary:
63
+ * `StoryStore.eventsToModelMessages(events)`.
64
+ */
65
+ export async function convertEventsToModelMessages(events) {
66
+ const results = [];
67
+ for (const event of events) {
68
+ results.push(await convertEventToModelMessages(event));
69
+ }
70
+ return results.flat();
71
+ }
72
+ export async function convertEventToModelMessages(event) {
73
+ const message = convertToUIMessage(event);
74
+ return convertToModelMessages([message]);
75
+ }
76
+ export function convertModelMessageToEvent(eventId, message) {
77
+ let type;
78
+ switch (message.message.role) {
79
+ case "user":
80
+ type = USER_MESSAGE_TYPE;
81
+ break;
82
+ case "assistant":
83
+ type = ASSISTANT_MESSAGE_TYPE;
84
+ break;
85
+ case "system":
86
+ type = SYSTEM_MESSAGE_TYPE;
87
+ break;
88
+ default:
89
+ // Fallback for roles not mapped to our event types (e.g. tool).
90
+ type = ASSISTANT_MESSAGE_TYPE;
91
+ break;
92
+ }
93
+ return {
94
+ id: eventId,
95
+ type: type,
96
+ channel: WEB_CHANNEL,
97
+ content: {
98
+ parts: message.message.content,
99
+ },
100
+ createdAt: message.timestamp.toISOString(),
101
+ };
102
+ }
@@ -0,0 +1,9 @@
1
+ export { thread, createThread, createAiSdkReactor, type CreateAiSdkReactorOptions, type ThreadConfig, type ThreadInstance, type ThreadOptions, type ThreadStreamOptions, type ThreadReactor, type ThreadReactorParams, type ThreadReactionResult, type ThreadReactionToolCall, type ThreadReactionLLM, Thread, type RegistrableThreadBuilder, } from "./thread.js";
2
+ export type { ThreadStore, ThreadIdentifier, ContextIdentifier, StoredThread, StoredContext, ThreadItem, } from "./thread.store.js";
3
+ export type { WireDate, ThreadMirrorContext, ThreadMirrorExecution, ThreadMirrorWrite, ThreadMirrorRequest, } from "./mirror.js";
4
+ export { registerThread, getThread, getThreadFactory, hasThread, listThreads, type ThreadKey, } from "./thread.registry.js";
5
+ export { threadDomain } from "./schema.js";
6
+ export { didToolExecute, extractToolCallsFromParts } from "./thread.toolcalls.js";
7
+ export { INPUT_TEXT_ITEM_TYPE, OUTPUT_TEXT_ITEM_TYPE, SYSTEM_TEXT_ITEM_TYPE, WEB_CHANNEL, AGENT_CHANNEL, EMAIL_CHANNEL, createUserItemFromUIMessages, createAssistantItemFromUIMessages, convertToUIMessage, convertItemToModelMessages, convertItemsToModelMessages, convertModelMessageToItem, type ResponseMessage, } from "./thread.events.js";
8
+ export { DEFAULT_CODEX_TOOL_NAME, DEFAULT_CODEX_MODEL, codexToolInputSchema, buildDefaultCodexNarrative, didCodexToolExecute, createCodexThreadBuilder, type CodexThreadRuntimeMode, type CodexThreadReasoningLevel, type CodexThreadRuntime, type CodexThreadEnv, type CodexToolInput, type CodexToolOutput, type CodexExecuteArgs, type CodexThreadBuilderConfig, type CodexThreadBuilder, } from "./codex.js";
9
+ export { useThread, type ThreadSnapshot, type ThreadStreamChunk, type UseThreadOptions, } from "./react.js";
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ export {
2
+ // Thread API
3
+ thread, createThread, createAiSdkReactor, Thread, } from "./thread.js";
4
+ export { registerThread, getThread, getThreadFactory, hasThread, listThreads, } from "./thread.registry.js";
5
+ export { threadDomain } from "./schema.js";
6
+ export { didToolExecute, extractToolCallsFromParts } from "./thread.toolcalls.js";
7
+ export { INPUT_TEXT_ITEM_TYPE, OUTPUT_TEXT_ITEM_TYPE, SYSTEM_TEXT_ITEM_TYPE, WEB_CHANNEL, AGENT_CHANNEL, EMAIL_CHANNEL, createUserItemFromUIMessages, createAssistantItemFromUIMessages, convertToUIMessage, convertItemToModelMessages, convertItemsToModelMessages, convertModelMessageToItem, } from "./thread.events.js";
8
+ export { DEFAULT_CODEX_TOOL_NAME, DEFAULT_CODEX_MODEL, codexToolInputSchema, buildDefaultCodexNarrative, didCodexToolExecute, createCodexThreadBuilder, } from "./codex.js";
9
+ export { useThread, } from "./react.js";
package/dist/mcp.d.ts ADDED
@@ -0,0 +1 @@
1
+ export { createMcpHandler, withMcpAuth } from "@vercel/mcp-adapter";
package/dist/mcp.js ADDED
@@ -0,0 +1 @@
1
+ export { createMcpHandler, withMcpAuth } from "@vercel/mcp-adapter";
@@ -0,0 +1,41 @@
1
+ import type { ThreadItem, StoredContext } from "./thread.store.js";
2
+ /**
3
+ * Wire-safe (JSON) mirror types shared by:
4
+ * - the workflow sender (`@ekairos/thread` steps)
5
+ * - the ekairos-core receiver (`/api/thread`)
6
+ *
7
+ * Note: `StoredContext` contains Date objects, but over HTTP we send ISO strings.
8
+ */
9
+ export type WireDate = string;
10
+ export type ThreadMirrorContext = Omit<StoredContext<unknown>, "createdAt" | "updatedAt"> & {
11
+ createdAt: WireDate;
12
+ updatedAt?: WireDate;
13
+ };
14
+ export type ThreadMirrorExecution = Record<string, unknown> & {
15
+ createdAt?: WireDate;
16
+ updatedAt?: WireDate;
17
+ };
18
+ export type ThreadMirrorWrite = {
19
+ type: "context.upsert";
20
+ context: ThreadMirrorContext;
21
+ } | {
22
+ type: "event.upsert";
23
+ contextId: string;
24
+ event: ThreadItem;
25
+ } | {
26
+ type: "event.update";
27
+ eventId: string;
28
+ event: ThreadItem;
29
+ } | {
30
+ type: "execution.upsert";
31
+ contextId: string;
32
+ executionId: string;
33
+ execution: ThreadMirrorExecution;
34
+ triggerEventId: string;
35
+ reactionEventId: string;
36
+ setCurrentExecution?: boolean;
37
+ };
38
+ export type ThreadMirrorRequest = {
39
+ orgId: string;
40
+ writes: ThreadMirrorWrite[];
41
+ };
package/dist/mirror.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/dist/oidc.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ type VerifyOidcOptions = {
2
+ jwksUrl?: string;
3
+ issuer?: string;
4
+ audience?: string | string[];
5
+ };
6
+ export declare function verifyOidcToken(token: string, options?: VerifyOidcOptions): Promise<boolean>;
7
+ export {};
package/dist/oidc.js ADDED
@@ -0,0 +1,25 @@
1
+ import { createRemoteJWKSet, jwtVerify } from "jose";
2
+ const jwksCache = new Map();
3
+ function getJwks(jwksUrl) {
4
+ const cached = jwksCache.get(jwksUrl);
5
+ if (cached)
6
+ return cached;
7
+ const jwks = createRemoteJWKSet(new URL(jwksUrl));
8
+ jwksCache.set(jwksUrl, jwks);
9
+ return jwks;
10
+ }
11
+ export async function verifyOidcToken(token, options = {}) {
12
+ if (!token)
13
+ return false;
14
+ const jwksUrl = String(options.jwksUrl ?? "").trim();
15
+ if (!jwksUrl) {
16
+ throw new Error("Missing jwksUrl for OIDC verification");
17
+ }
18
+ const verifyOptions = {};
19
+ if (options.issuer)
20
+ verifyOptions.issuer = options.issuer;
21
+ if (options.audience)
22
+ verifyOptions.audience = options.audience;
23
+ await jwtVerify(token, getJwks(jwksUrl), verifyOptions);
24
+ return true;
25
+ }
@@ -0,0 +1 @@
1
+ export declare function ensureDomEvents(): void;
@@ -0,0 +1,89 @@
1
+ function ensureEvent() {
2
+ if (typeof globalThis.Event !== "undefined")
3
+ return;
4
+ class NodeEvent {
5
+ constructor(type, init) {
6
+ this.defaultPrevented = false;
7
+ this.cancelable = false;
8
+ this.timeStamp = Date.now();
9
+ this.type = type;
10
+ if (init && typeof init === "object") {
11
+ Object.assign(this, init);
12
+ }
13
+ }
14
+ preventDefault() {
15
+ this.defaultPrevented = true;
16
+ }
17
+ }
18
+ globalThis.Event = NodeEvent;
19
+ }
20
+ function ensureEventTarget() {
21
+ if (typeof globalThis.EventTarget !== "undefined")
22
+ return;
23
+ class NodeEventTarget {
24
+ constructor() {
25
+ this.listeners = new Map();
26
+ }
27
+ addEventListener(type, listener) {
28
+ if (!listener)
29
+ return;
30
+ const bucket = this.listeners.get(type) ?? new Set();
31
+ bucket.add(listener);
32
+ this.listeners.set(type, bucket);
33
+ }
34
+ removeEventListener(type, listener) {
35
+ if (!listener)
36
+ return;
37
+ const bucket = this.listeners.get(type);
38
+ if (!bucket)
39
+ return;
40
+ bucket.delete(listener);
41
+ if (bucket.size === 0)
42
+ this.listeners.delete(type);
43
+ }
44
+ dispatchEvent(event) {
45
+ const bucket = this.listeners.get(event?.type);
46
+ if (bucket) {
47
+ for (const listener of [...bucket]) {
48
+ try {
49
+ listener.call(this, event);
50
+ }
51
+ catch {
52
+ // ignore listener errors
53
+ }
54
+ }
55
+ }
56
+ const handler = this[`on${event?.type}`];
57
+ if (typeof handler === "function") {
58
+ try {
59
+ handler.call(this, event);
60
+ }
61
+ catch {
62
+ // ignore handler errors
63
+ }
64
+ }
65
+ return !event?.defaultPrevented;
66
+ }
67
+ }
68
+ globalThis.EventTarget = NodeEventTarget;
69
+ }
70
+ function ensureMessageEvent() {
71
+ if (typeof globalThis.MessageEvent !== "undefined")
72
+ return;
73
+ const BaseEvent = globalThis.Event;
74
+ class NodeMessageEvent extends BaseEvent {
75
+ constructor(type, init) {
76
+ super(type, init);
77
+ this.data = init?.data;
78
+ this.origin = typeof init?.origin === "string" ? init.origin : "";
79
+ this.lastEventId = typeof init?.lastEventId === "string" ? init.lastEventId : "";
80
+ }
81
+ }
82
+ globalThis.MessageEvent = NodeMessageEvent;
83
+ }
84
+ export function ensureDomEvents() {
85
+ ensureEvent();
86
+ ensureEventTarget();
87
+ ensureMessageEvent();
88
+ }
89
+ ensureDomEvents();
@@ -0,0 +1,62 @@
1
+ export type ThreadSnapshot<Context = unknown, Item = Record<string, unknown>> = {
2
+ thread: {
3
+ id: string;
4
+ key: string;
5
+ status: string;
6
+ createdAt: string | null;
7
+ updatedAt: string | null;
8
+ };
9
+ context: {
10
+ id: string;
11
+ status: string;
12
+ content: Context;
13
+ createdAt: string | null;
14
+ updatedAt: string | null;
15
+ } | null;
16
+ items: Item[];
17
+ };
18
+ export type ThreadStreamChunk = {
19
+ type: "data-context-id";
20
+ data?: {
21
+ contextId?: string;
22
+ };
23
+ id?: string;
24
+ } | {
25
+ type: "data-context-substate";
26
+ data?: {
27
+ key?: string | null;
28
+ };
29
+ transient?: boolean;
30
+ } | {
31
+ type: "tool-output-available";
32
+ toolCallId?: string;
33
+ output?: unknown;
34
+ } | {
35
+ type: "tool-output-error";
36
+ toolCallId?: string;
37
+ errorText?: string;
38
+ } | {
39
+ type: string;
40
+ [key: string]: unknown;
41
+ };
42
+ export type UseThreadOptions<Context = unknown, Item = Record<string, unknown>> = {
43
+ threadKey: string;
44
+ orgId?: string;
45
+ endpoint?: string;
46
+ refreshMs?: number;
47
+ ensure?: boolean;
48
+ enabled?: boolean;
49
+ initialData?: ThreadSnapshot<Context, Item> | null;
50
+ fetchImpl?: typeof fetch;
51
+ };
52
+ export declare function useThread<Context = unknown, Item = Record<string, unknown>>(options: UseThreadOptions<Context, Item>): {
53
+ data: ThreadSnapshot<Context, Item> | null;
54
+ isLoading: boolean;
55
+ error: string | null;
56
+ refresh: () => Promise<void>;
57
+ setData: import("react").Dispatch<import("react").SetStateAction<ThreadSnapshot<Context, Item> | null>>;
58
+ contextId: string | null;
59
+ substateKey: string | null;
60
+ applyChunk: (chunk: ThreadStreamChunk) => void;
61
+ url: string;
62
+ };
package/dist/react.js ADDED
@@ -0,0 +1,101 @@
1
+ "use client";
2
+ import { useCallback, useEffect, useMemo, useState } from "react";
3
+ function toErrorMessage(error) {
4
+ if (error instanceof Error)
5
+ return error.message;
6
+ return String(error ?? "unknown_error");
7
+ }
8
+ function buildThreadUrl(options) {
9
+ const base = String(options.endpoint || "/api/thread").replace(/\/+$/, "");
10
+ const key = encodeURIComponent(options.threadKey);
11
+ const params = new URLSearchParams();
12
+ if (options.orgId)
13
+ params.set("orgId", options.orgId);
14
+ if (options.ensure)
15
+ params.set("ensure", "1");
16
+ const query = params.toString();
17
+ return query.length > 0 ? `${base}/${key}?${query}` : `${base}/${key}`;
18
+ }
19
+ export function useThread(options) {
20
+ const [data, setData] = useState(options.initialData ?? null);
21
+ const [isLoading, setIsLoading] = useState(true);
22
+ const [error, setError] = useState(null);
23
+ const [contextId, setContextId] = useState(null);
24
+ const [substateKey, setSubstateKey] = useState(null);
25
+ const enabled = options.enabled ?? true;
26
+ const url = useMemo(() => {
27
+ if (!enabled || !options.threadKey)
28
+ return "";
29
+ return buildThreadUrl(options);
30
+ }, [enabled, options.endpoint, options.orgId, options.threadKey, options.ensure]);
31
+ const refresh = useCallback(async () => {
32
+ if (!enabled || !options.threadKey)
33
+ return;
34
+ setIsLoading(true);
35
+ setError(null);
36
+ const fetchImpl = options.fetchImpl ?? fetch;
37
+ try {
38
+ const response = await fetchImpl(url, { cache: "no-store" });
39
+ if (!response.ok) {
40
+ const body = await response.text();
41
+ throw new Error(body || `thread_fetch_failed:${response.status}`);
42
+ }
43
+ const snapshot = (await response.json());
44
+ setData(snapshot);
45
+ setContextId(snapshot.context?.id ?? null);
46
+ }
47
+ catch (err) {
48
+ setError(toErrorMessage(err));
49
+ }
50
+ finally {
51
+ setIsLoading(false);
52
+ }
53
+ }, [enabled, options.fetchImpl, options.threadKey, url]);
54
+ const applyChunk = useCallback((chunk) => {
55
+ if (!chunk || typeof chunk !== "object")
56
+ return;
57
+ if (chunk.type === "data-context-id") {
58
+ const payload = "data" in chunk && chunk.data && typeof chunk.data === "object"
59
+ ? chunk.data
60
+ : undefined;
61
+ const candidate = typeof payload?.contextId === "string"
62
+ ? payload.contextId
63
+ : typeof chunk.id === "string"
64
+ ? chunk.id
65
+ : null;
66
+ if (candidate)
67
+ setContextId(candidate);
68
+ return;
69
+ }
70
+ if (chunk.type === "data-context-substate") {
71
+ const payload = "data" in chunk && chunk.data && typeof chunk.data === "object"
72
+ ? chunk.data
73
+ : undefined;
74
+ const key = payload?.key;
75
+ setSubstateKey(typeof key === "string" ? key : null);
76
+ return;
77
+ }
78
+ }, []);
79
+ useEffect(() => {
80
+ void refresh();
81
+ }, [refresh]);
82
+ useEffect(() => {
83
+ if (!enabled || !options.refreshMs || options.refreshMs <= 0)
84
+ return;
85
+ const intervalId = setInterval(() => {
86
+ void refresh();
87
+ }, options.refreshMs);
88
+ return () => clearInterval(intervalId);
89
+ }, [enabled, options.refreshMs, refresh]);
90
+ return {
91
+ data,
92
+ isLoading,
93
+ error,
94
+ refresh,
95
+ setData,
96
+ contextId,
97
+ substateKey,
98
+ applyChunk,
99
+ url,
100
+ };
101
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Runtime-only entrypoint for @ekairos/thread.
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/thread` main entrypoint safe to import from schema/domain modules.
10
+ */
11
+ export { getThreadRuntime, } from "./runtime.step.js";
12
+ export type { ThreadEnvironment, ThreadRuntime } from "./thread.config.js";
13
+ export { registerThreadEnv, getThreadEnv } from "./env.js";
14
+ export type RegistrableThread = {
15
+ key?: string;
16
+ register: () => void;
17
+ };
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Runtime-only entrypoint for @ekairos/thread.
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/thread` 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
+ globalThis.Event = NodeEvent;
21
+ }
22
+ export { getThreadRuntime, } from "./runtime.step.js";
23
+ export { registerThreadEnv, getThreadEnv } from "./env.js";
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Internal helper to resolve Thread 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 { ThreadEnvironment, ThreadRuntime } from "./thread.config.js";
9
+ export declare function getThreadRuntime(env: ThreadEnvironment): Promise<ThreadRuntime>;
@@ -0,0 +1,7 @@
1
+ import { coerceThreadRuntime } from "./thread.config.js";
2
+ import { threadDomain } from "./schema.js";
3
+ export async function getThreadRuntime(env) {
4
+ const { resolveRuntime } = await import("@ekairos/domain/runtime");
5
+ const resolved = await resolveRuntime(threadDomain, env);
6
+ return await coerceThreadRuntime(resolved);
7
+ }
@@ -0,0 +1,2 @@
1
+ import { type DomainSchemaResult } from "@ekairos/domain";
2
+ export declare const threadDomain: DomainSchemaResult;