@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
package/dist/env.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
const envByRunIdSymbol = Symbol.for("ekairos.context.envByRunId");
|
|
2
|
+
const defaultEnvSymbol = Symbol.for("ekairos.context.defaultEnv");
|
|
3
|
+
function getEnvMap() {
|
|
4
|
+
if (typeof globalThis === "undefined")
|
|
5
|
+
return new Map();
|
|
6
|
+
const existing = globalThis[envByRunIdSymbol];
|
|
7
|
+
if (existing)
|
|
8
|
+
return existing;
|
|
9
|
+
const created = new Map();
|
|
10
|
+
globalThis[envByRunIdSymbol] = created;
|
|
11
|
+
return created;
|
|
12
|
+
}
|
|
13
|
+
function setDefaultEnv(env) {
|
|
14
|
+
if (typeof globalThis === "undefined")
|
|
15
|
+
return;
|
|
16
|
+
globalThis[defaultEnvSymbol] = env ?? null;
|
|
17
|
+
}
|
|
18
|
+
function getDefaultEnv() {
|
|
19
|
+
if (typeof globalThis === "undefined")
|
|
20
|
+
return null;
|
|
21
|
+
return globalThis[defaultEnvSymbol] ?? null;
|
|
22
|
+
}
|
|
23
|
+
export function registerContextEnv(env, runId) {
|
|
24
|
+
if (runId) {
|
|
25
|
+
getEnvMap().set(String(runId), env);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
setDefaultEnv(env);
|
|
29
|
+
}
|
|
30
|
+
async function tryGetWorkflowRunId() {
|
|
31
|
+
try {
|
|
32
|
+
const mod = await import("workflow");
|
|
33
|
+
const meta = mod?.getWorkflowMetadata?.();
|
|
34
|
+
const runId = meta?.workflowRunId;
|
|
35
|
+
return runId ? String(runId) : null;
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export async function getContextEnv() {
|
|
42
|
+
const runId = await tryGetWorkflowRunId();
|
|
43
|
+
if (runId) {
|
|
44
|
+
const stored = getEnvMap().get(runId);
|
|
45
|
+
if (stored)
|
|
46
|
+
return stored;
|
|
47
|
+
}
|
|
48
|
+
const fallback = getDefaultEnv();
|
|
49
|
+
if (fallback)
|
|
50
|
+
return fallback;
|
|
51
|
+
throw new Error("@ekairos/events: env is not configured for this workflow run. " +
|
|
52
|
+
"Call registerContextEnv(env) at workflow start or ensure the context runtime registers env.");
|
|
53
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export { context, createContext, createAiSdkReactor, createScriptedReactor, type CreateAiSdkReactorOptions, type CreateScriptedReactorOptions, type ScriptedReactorStep, type ContextConfig, type ContextInstance, type ContextOptions, type ContextStreamOptions, type ContextReactor, type ContextReactorParams, type ContextReactionResult, type ContextActionRequest, type ContextReactionLLM, ContextEngine, type RegistrableContextBuilder, type ContextReactParams, type ContextReactResult, type ContextDurableWorkflowPayload, type ContextDurableWorkflowFunction, type ContextModelInit, type ContextTool, runContextReactionDirect, } from "./context.js";
|
|
2
|
+
export type { ContextStore, ContextIdentifier, StoredContext, ContextItem, ContextExecution, } from "./context.store.js";
|
|
3
|
+
export type { WireDate, ContextMirrorContext, ContextMirrorExecution, ContextMirrorWrite, ContextMirrorRequest, } from "./mirror.js";
|
|
4
|
+
export { registerContext, getContext, getContextFactory, hasContext, listContexts, type ContextKey, } from "./context.registry.js";
|
|
5
|
+
export { eventsDomain } from "./schema.js";
|
|
6
|
+
export { didToolExecute, extractToolCallsFromParts } from "./context.toolcalls.js";
|
|
7
|
+
export { contextPartSchema, contextPartEnvelopeSchema, contextPartContentSchema, isContextPartEnvelope, parseContextPartEnvelope, normalizePartsForPersistence, } from "./context.parts.js";
|
|
8
|
+
export type { ContextPart, ContextPartEnvelope, ContextPartContent, } from "./context.parts.js";
|
|
9
|
+
export { INPUT_ITEM_TYPE, INPUT_TEXT_ITEM_TYPE, OUTPUT_ITEM_TYPE, WEB_CHANNEL, AGENT_CHANNEL, EMAIL_CHANNEL, createUserItemFromUIMessages, createAssistantItemFromUIMessages, convertToUIMessage, convertItemToModelMessages, convertItemsToModelMessages, convertModelMessageToItem, isContextOutputPart, normalizeContextOutputPart, type ResponseMessage, type ContextOutputPart, type ContextOutputContentPart, } from "./context.events.js";
|
|
10
|
+
export { CONTEXT_STATUSES, EXECUTION_STATUSES, STEP_STATUSES, STEP_KINDS, ITEM_STATUSES, ITEM_TYPES, CHANNELS, TRACE_EVENT_KINDS, CONTEXT_STREAM_CHUNK_TYPES, STREAM_LIFECYCLE_CHUNK_TYPES, STREAM_TEXT_CHUNK_TYPES, STREAM_REASONING_CHUNK_TYPES, STREAM_ACTION_CHUNK_TYPES, STREAM_SOURCE_CHUNK_TYPES, STREAM_METADATA_CHUNK_TYPES, STREAM_ERROR_CHUNK_TYPES, CONTEXT_TRANSITIONS, EXECUTION_TRANSITIONS, STEP_TRANSITIONS, ITEM_TRANSITIONS, canContextTransition, canExecutionTransition, canStepTransition, canItemTransition, assertContextTransition, assertExecutionTransition, assertStepTransition, assertItemTransition, isContextStreamChunkType, assertContextPartKey, } from "./context.contract.js";
|
|
11
|
+
export type { Transition, ContextStatus, ExecutionStatus, StepStatus, StepKind, ItemStatus, ItemType, Channel, TraceEventKind, ContextStreamChunkType, ContextTransition, ExecutionTransition, StepTransition, ItemTransition, } from "./context.contract.js";
|
|
12
|
+
export { DEFAULT_CODEX_TOOL_NAME, DEFAULT_CODEX_MODEL, codexToolInputSchema, buildDefaultCodexNarrative, didCodexToolExecute, createCodexContextBuilder, type CodexContextRuntimeMode, type CodexContextReasoningLevel, type CodexContextRuntime, type CodexContextEnv, type CodexToolInput, type CodexToolOutput, type CodexExecuteArgs, type CodexContextBuilderConfig, type CodexContextBuilder, } from "./codex.js";
|
|
13
|
+
export { useContext, type ContextSnapshot, type ContextStreamChunk, type UseContextOptions, } from "./react.js";
|
|
14
|
+
export { parseContextStreamEvent, assertContextStreamTransitions, validateContextStreamTimeline, } from "./context.stream.js";
|
|
15
|
+
export { CONTEXT_STEP_STREAM_VERSION, createContextStepStreamChunk, parseContextStepStreamChunk, encodeContextStepStreamChunk, } from "./context.step-stream.js";
|
|
16
|
+
export type { ContextStreamEvent, ContextCreatedEvent, ContextResolvedEvent, ContextStatusChangedEvent, ContextContentUpdatedEvent, ExecutionCreatedEvent, ExecutionCompletedEvent, ExecutionFailedEvent, ItemCreatedEvent, ItemUpdatedEvent, ItemPendingEvent, ItemCompletedEvent, StepCreatedEvent, StepUpdatedEvent, StepCompletedEvent, StepFailedEvent, PartCreatedEvent, PartUpdatedEvent, ChunkEmittedEvent, } from "./context.stream.js";
|
|
17
|
+
export type { ContextStepStreamChunk } from "./context.step-stream.js";
|
|
18
|
+
export type { ContextSkillPackage, ContextSkillPackageFile } from "./context.skill.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { context, createContext, createAiSdkReactor, createScriptedReactor, ContextEngine, runContextReactionDirect, } from "./context.js";
|
|
2
|
+
export { registerContext, getContext, getContextFactory, hasContext, listContexts, } from "./context.registry.js";
|
|
3
|
+
export { eventsDomain } from "./schema.js";
|
|
4
|
+
export { didToolExecute, extractToolCallsFromParts } from "./context.toolcalls.js";
|
|
5
|
+
export { contextPartSchema, contextPartEnvelopeSchema, contextPartContentSchema, isContextPartEnvelope, parseContextPartEnvelope, normalizePartsForPersistence, } from "./context.parts.js";
|
|
6
|
+
export { INPUT_ITEM_TYPE, INPUT_TEXT_ITEM_TYPE, OUTPUT_ITEM_TYPE, WEB_CHANNEL, AGENT_CHANNEL, EMAIL_CHANNEL, createUserItemFromUIMessages, createAssistantItemFromUIMessages, convertToUIMessage, convertItemToModelMessages, convertItemsToModelMessages, convertModelMessageToItem, isContextOutputPart, normalizeContextOutputPart, } from "./context.events.js";
|
|
7
|
+
export { CONTEXT_STATUSES, EXECUTION_STATUSES, STEP_STATUSES, STEP_KINDS, ITEM_STATUSES, ITEM_TYPES, CHANNELS, TRACE_EVENT_KINDS, CONTEXT_STREAM_CHUNK_TYPES, STREAM_LIFECYCLE_CHUNK_TYPES, STREAM_TEXT_CHUNK_TYPES, STREAM_REASONING_CHUNK_TYPES, STREAM_ACTION_CHUNK_TYPES, STREAM_SOURCE_CHUNK_TYPES, STREAM_METADATA_CHUNK_TYPES, STREAM_ERROR_CHUNK_TYPES, CONTEXT_TRANSITIONS, EXECUTION_TRANSITIONS, STEP_TRANSITIONS, ITEM_TRANSITIONS, canContextTransition, canExecutionTransition, canStepTransition, canItemTransition, assertContextTransition, assertExecutionTransition, assertStepTransition, assertItemTransition, isContextStreamChunkType, assertContextPartKey, } from "./context.contract.js";
|
|
8
|
+
export { DEFAULT_CODEX_TOOL_NAME, DEFAULT_CODEX_MODEL, codexToolInputSchema, buildDefaultCodexNarrative, didCodexToolExecute, createCodexContextBuilder, } from "./codex.js";
|
|
9
|
+
export { useContext, } from "./react.js";
|
|
10
|
+
export { parseContextStreamEvent, assertContextStreamTransitions, validateContextStreamTimeline, } from "./context.stream.js";
|
|
11
|
+
export { CONTEXT_STEP_STREAM_VERSION, createContextStepStreamChunk, parseContextStepStreamChunk, encodeContextStepStreamChunk, } from "./context.step-stream.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";
|
package/dist/mirror.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { ContextItem, StoredContext } from "./context.store.js";
|
|
2
|
+
/**
|
|
3
|
+
* Wire-safe (JSON) mirror types shared by:
|
|
4
|
+
* - the workflow sender (`@ekairos/events` steps)
|
|
5
|
+
* - the ekairos-core receiver (`/api/context`)
|
|
6
|
+
*
|
|
7
|
+
* Note: `StoredContext` contains Date objects, but over HTTP we send ISO strings.
|
|
8
|
+
*/
|
|
9
|
+
export type WireDate = string;
|
|
10
|
+
export type ContextMirrorContext = Omit<StoredContext<unknown>, "createdAt" | "updatedAt"> & {
|
|
11
|
+
createdAt: WireDate;
|
|
12
|
+
updatedAt?: WireDate;
|
|
13
|
+
};
|
|
14
|
+
export type ContextMirrorExecution = Record<string, unknown> & {
|
|
15
|
+
createdAt?: WireDate;
|
|
16
|
+
updatedAt?: WireDate;
|
|
17
|
+
};
|
|
18
|
+
export type ContextMirrorWrite = {
|
|
19
|
+
type: "context.upsert";
|
|
20
|
+
context: ContextMirrorContext;
|
|
21
|
+
} | {
|
|
22
|
+
type: "event.upsert";
|
|
23
|
+
contextId: string;
|
|
24
|
+
event: ContextItem;
|
|
25
|
+
} | {
|
|
26
|
+
type: "event.update";
|
|
27
|
+
eventId: string;
|
|
28
|
+
event: ContextItem;
|
|
29
|
+
} | {
|
|
30
|
+
type: "execution.upsert";
|
|
31
|
+
contextId: string;
|
|
32
|
+
executionId: string;
|
|
33
|
+
execution: ContextMirrorExecution;
|
|
34
|
+
triggerEventId: string;
|
|
35
|
+
reactionEventId: string;
|
|
36
|
+
setCurrentExecution?: boolean;
|
|
37
|
+
};
|
|
38
|
+
export type ContextMirrorRequest = {
|
|
39
|
+
orgId: string;
|
|
40
|
+
writes: ContextMirrorWrite[];
|
|
41
|
+
};
|
package/dist/mirror.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/oidc.d.ts
ADDED
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();
|
package/dist/react.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { ContextStatus } from "./context.contract.js";
|
|
2
|
+
export type ContextSnapshot<Context = unknown, Item = Record<string, unknown>> = {
|
|
3
|
+
context: {
|
|
4
|
+
id: string;
|
|
5
|
+
key: string | null;
|
|
6
|
+
name?: string | null;
|
|
7
|
+
status: ContextStatus;
|
|
8
|
+
content: Context;
|
|
9
|
+
createdAt: string | null;
|
|
10
|
+
updatedAt: string | null;
|
|
11
|
+
} | null;
|
|
12
|
+
items: Item[];
|
|
13
|
+
};
|
|
14
|
+
export type ContextStreamChunk = {
|
|
15
|
+
type: `data-context.${string}`;
|
|
16
|
+
data?: {
|
|
17
|
+
contextId?: string;
|
|
18
|
+
};
|
|
19
|
+
} | {
|
|
20
|
+
type: string;
|
|
21
|
+
[key: string]: unknown;
|
|
22
|
+
};
|
|
23
|
+
export type UseContextOptions<Context = unknown, Item = Record<string, unknown>> = {
|
|
24
|
+
contextKey: string;
|
|
25
|
+
orgId?: string;
|
|
26
|
+
endpoint?: string;
|
|
27
|
+
refreshMs?: number;
|
|
28
|
+
ensure?: boolean;
|
|
29
|
+
enabled?: boolean;
|
|
30
|
+
initialData?: ContextSnapshot<Context, Item> | null;
|
|
31
|
+
fetchImpl?: typeof fetch;
|
|
32
|
+
};
|
|
33
|
+
export declare function useContext<Context = unknown, Item = Record<string, unknown>>(options: UseContextOptions<Context, Item>): {
|
|
34
|
+
data: ContextSnapshot<Context, Item> | null;
|
|
35
|
+
isLoading: boolean;
|
|
36
|
+
error: string | null;
|
|
37
|
+
refresh: () => Promise<void>;
|
|
38
|
+
setData: import("react").Dispatch<import("react").SetStateAction<ContextSnapshot<Context, Item> | null>>;
|
|
39
|
+
contextId: string | null;
|
|
40
|
+
applyChunk: (chunk: ContextStreamChunk) => void;
|
|
41
|
+
url: string;
|
|
42
|
+
};
|
package/dist/react.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
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 buildContextUrl(options) {
|
|
9
|
+
const base = String(options.endpoint || "/api/context").replace(/\/+$/, "");
|
|
10
|
+
const key = encodeURIComponent(options.contextKey);
|
|
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 useContext(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 enabled = options.enabled ?? true;
|
|
25
|
+
const url = useMemo(() => {
|
|
26
|
+
if (!enabled || !options.contextKey)
|
|
27
|
+
return "";
|
|
28
|
+
return buildContextUrl(options);
|
|
29
|
+
}, [enabled, options.endpoint, options.orgId, options.contextKey, options.ensure]);
|
|
30
|
+
const refresh = useCallback(async () => {
|
|
31
|
+
if (!enabled || !options.contextKey)
|
|
32
|
+
return;
|
|
33
|
+
setIsLoading(true);
|
|
34
|
+
setError(null);
|
|
35
|
+
const fetchImpl = options.fetchImpl ?? fetch;
|
|
36
|
+
try {
|
|
37
|
+
const response = await fetchImpl(url, { cache: "no-store" });
|
|
38
|
+
if (!response.ok) {
|
|
39
|
+
const body = await response.text();
|
|
40
|
+
throw new Error(body || `context_fetch_failed:${response.status}`);
|
|
41
|
+
}
|
|
42
|
+
const snapshot = (await response.json());
|
|
43
|
+
setData(snapshot);
|
|
44
|
+
setContextId(snapshot.context?.id ?? null);
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
setError(toErrorMessage(err));
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
setIsLoading(false);
|
|
51
|
+
}
|
|
52
|
+
}, [enabled, options.fetchImpl, options.contextKey, url]);
|
|
53
|
+
const applyChunk = useCallback((chunk) => {
|
|
54
|
+
if (!chunk || typeof chunk !== "object")
|
|
55
|
+
return;
|
|
56
|
+
if (typeof chunk.type === "string" && chunk.type.startsWith("data-context.")) {
|
|
57
|
+
const payload = "data" in chunk && chunk.data && typeof chunk.data === "object"
|
|
58
|
+
? chunk.data
|
|
59
|
+
: undefined;
|
|
60
|
+
const candidate = typeof payload?.contextId === "string"
|
|
61
|
+
? payload.contextId
|
|
62
|
+
: null;
|
|
63
|
+
if (candidate)
|
|
64
|
+
setContextId(candidate);
|
|
65
|
+
}
|
|
66
|
+
}, []);
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
void refresh();
|
|
69
|
+
}, [refresh]);
|
|
70
|
+
useEffect(() => {
|
|
71
|
+
if (!enabled || !options.refreshMs || options.refreshMs <= 0)
|
|
72
|
+
return;
|
|
73
|
+
const intervalId = setInterval(() => {
|
|
74
|
+
void refresh();
|
|
75
|
+
}, options.refreshMs);
|
|
76
|
+
return () => clearInterval(intervalId);
|
|
77
|
+
}, [enabled, options.refreshMs, refresh]);
|
|
78
|
+
return {
|
|
79
|
+
data,
|
|
80
|
+
isLoading,
|
|
81
|
+
error,
|
|
82
|
+
refresh,
|
|
83
|
+
setData,
|
|
84
|
+
contextId,
|
|
85
|
+
applyChunk,
|
|
86
|
+
url,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { UIMessageChunk } from "ai";
|
|
2
|
+
import type { ChunkEmittedEvent } from "../context.stream.js";
|
|
3
|
+
export type MapAiSdkChunkToContextEventParams = {
|
|
4
|
+
chunk: UIMessageChunk | Record<string, unknown>;
|
|
5
|
+
contextId: string;
|
|
6
|
+
executionId?: string;
|
|
7
|
+
stepId?: string;
|
|
8
|
+
itemId?: string;
|
|
9
|
+
provider?: string;
|
|
10
|
+
sequence: number;
|
|
11
|
+
};
|
|
12
|
+
export declare function mapAiSdkChunkToContextEvent(params: MapAiSdkChunkToContextEventParams): ChunkEmittedEvent;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
const REDACT_KEY = /token|authorization|cookie|secret|api[_-]?key|password/i;
|
|
2
|
+
function asRecord(value) {
|
|
3
|
+
if (!value || typeof value !== "object")
|
|
4
|
+
return {};
|
|
5
|
+
return value;
|
|
6
|
+
}
|
|
7
|
+
function readString(record, key) {
|
|
8
|
+
const value = record[key];
|
|
9
|
+
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
10
|
+
}
|
|
11
|
+
function toJsonSafe(value) {
|
|
12
|
+
if (typeof value === "undefined")
|
|
13
|
+
return undefined;
|
|
14
|
+
try {
|
|
15
|
+
return JSON.parse(JSON.stringify(value));
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function sanitizeRaw(value) {
|
|
22
|
+
const seen = new WeakSet();
|
|
23
|
+
try {
|
|
24
|
+
return JSON.parse(JSON.stringify(value, (key, currentValue) => {
|
|
25
|
+
if (REDACT_KEY.test(key))
|
|
26
|
+
return "[redacted]";
|
|
27
|
+
if (typeof currentValue === "string" && currentValue.length > 20000) {
|
|
28
|
+
return "[truncated-string]";
|
|
29
|
+
}
|
|
30
|
+
if (currentValue && typeof currentValue === "object") {
|
|
31
|
+
if (seen.has(currentValue))
|
|
32
|
+
return "[circular]";
|
|
33
|
+
seen.add(currentValue);
|
|
34
|
+
}
|
|
35
|
+
return currentValue;
|
|
36
|
+
}));
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function mapAiSdkChunkType(providerChunkType) {
|
|
43
|
+
switch (providerChunkType) {
|
|
44
|
+
case "start":
|
|
45
|
+
case "stream-start":
|
|
46
|
+
return "chunk.start";
|
|
47
|
+
case "start-step":
|
|
48
|
+
return "chunk.start_step";
|
|
49
|
+
case "finish-step":
|
|
50
|
+
return "chunk.finish_step";
|
|
51
|
+
case "finish":
|
|
52
|
+
return "chunk.finish";
|
|
53
|
+
case "text-start":
|
|
54
|
+
return "chunk.text_start";
|
|
55
|
+
case "text-delta":
|
|
56
|
+
return "chunk.text_delta";
|
|
57
|
+
case "text-end":
|
|
58
|
+
return "chunk.text_end";
|
|
59
|
+
case "reasoning-start":
|
|
60
|
+
return "chunk.reasoning_start";
|
|
61
|
+
case "reasoning-delta":
|
|
62
|
+
return "chunk.reasoning_delta";
|
|
63
|
+
case "reasoning-end":
|
|
64
|
+
return "chunk.reasoning_end";
|
|
65
|
+
case "tool-input-start":
|
|
66
|
+
case "tool-call-start":
|
|
67
|
+
return "chunk.action_input_start";
|
|
68
|
+
case "tool-input-delta":
|
|
69
|
+
case "tool-call-delta":
|
|
70
|
+
return "chunk.action_input_delta";
|
|
71
|
+
case "tool-input-available":
|
|
72
|
+
case "tool-input-end":
|
|
73
|
+
case "tool-call":
|
|
74
|
+
case "tool-call-end":
|
|
75
|
+
return "chunk.action_input_available";
|
|
76
|
+
case "tool-output-available":
|
|
77
|
+
return "chunk.action_output_available";
|
|
78
|
+
case "tool-output-error":
|
|
79
|
+
return "chunk.action_output_error";
|
|
80
|
+
case "source-url":
|
|
81
|
+
return "chunk.source_url";
|
|
82
|
+
case "source-document":
|
|
83
|
+
return "chunk.source_document";
|
|
84
|
+
case "file":
|
|
85
|
+
return "chunk.file";
|
|
86
|
+
case "message-metadata":
|
|
87
|
+
return "chunk.message_metadata";
|
|
88
|
+
case "response-metadata":
|
|
89
|
+
return "chunk.response_metadata";
|
|
90
|
+
case "error":
|
|
91
|
+
return "chunk.error";
|
|
92
|
+
default:
|
|
93
|
+
return "chunk.unknown";
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function buildNormalizedData(chunk) {
|
|
97
|
+
const normalized = {};
|
|
98
|
+
const fields = [
|
|
99
|
+
"id",
|
|
100
|
+
"text",
|
|
101
|
+
"delta",
|
|
102
|
+
"state",
|
|
103
|
+
"toolName",
|
|
104
|
+
"toolCallId",
|
|
105
|
+
"finishReason",
|
|
106
|
+
"url",
|
|
107
|
+
"title",
|
|
108
|
+
"name",
|
|
109
|
+
"mimeType",
|
|
110
|
+
];
|
|
111
|
+
for (const field of fields) {
|
|
112
|
+
const value = chunk[field];
|
|
113
|
+
if (typeof value !== "undefined") {
|
|
114
|
+
normalized[field] = value;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (Object.keys(normalized).length === 0) {
|
|
118
|
+
return {};
|
|
119
|
+
}
|
|
120
|
+
return toJsonSafe(normalized) ?? {};
|
|
121
|
+
}
|
|
122
|
+
export function mapAiSdkChunkToContextEvent(params) {
|
|
123
|
+
const chunk = asRecord(params.chunk);
|
|
124
|
+
const providerChunkType = readString(chunk, "type") ?? "unknown";
|
|
125
|
+
const chunkType = mapAiSdkChunkType(providerChunkType);
|
|
126
|
+
const actionRef = readString(chunk, "toolCallId") ??
|
|
127
|
+
readString(chunk, "id");
|
|
128
|
+
return {
|
|
129
|
+
type: "chunk.emitted",
|
|
130
|
+
at: new Date().toISOString(),
|
|
131
|
+
chunkType,
|
|
132
|
+
contextId: params.contextId,
|
|
133
|
+
executionId: params.executionId,
|
|
134
|
+
stepId: params.stepId,
|
|
135
|
+
itemId: params.itemId,
|
|
136
|
+
actionRef: chunkType.startsWith("chunk.action_") ? actionRef : undefined,
|
|
137
|
+
provider: params.provider,
|
|
138
|
+
providerChunkType,
|
|
139
|
+
sequence: params.sequence,
|
|
140
|
+
data: buildNormalizedData(chunk),
|
|
141
|
+
raw: sanitizeRaw(chunk),
|
|
142
|
+
};
|
|
143
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ContextEnvironment } from "../context.config.js";
|
|
2
|
+
import type { ContextModelInit } from "../context.engine.js";
|
|
3
|
+
import type { ContextIdentifier, StoredContext, ContextItem } from "../context.store.js";
|
|
4
|
+
import type { ContextReactor } from "./types.js";
|
|
5
|
+
export type CreateAiSdkReactorOptions<Context = unknown, Env extends ContextEnvironment = ContextEnvironment, Config = unknown> = {
|
|
6
|
+
resolveConfig?: (params: {
|
|
7
|
+
env: Env;
|
|
8
|
+
context: StoredContext<Context>;
|
|
9
|
+
contextIdentifier: ContextIdentifier;
|
|
10
|
+
triggerEvent: ContextItem;
|
|
11
|
+
model: ContextModelInit;
|
|
12
|
+
eventId: string;
|
|
13
|
+
executionId: string;
|
|
14
|
+
contextId: string;
|
|
15
|
+
stepId: string;
|
|
16
|
+
iteration: number;
|
|
17
|
+
}) => Promise<Config> | Config;
|
|
18
|
+
selectModel?: (params: {
|
|
19
|
+
env: Env;
|
|
20
|
+
context: StoredContext<Context>;
|
|
21
|
+
triggerEvent: ContextItem;
|
|
22
|
+
baseModel: ContextModelInit;
|
|
23
|
+
config: Config;
|
|
24
|
+
}) => Promise<ContextModelInit> | ContextModelInit;
|
|
25
|
+
selectMaxModelSteps?: (params: {
|
|
26
|
+
env: Env;
|
|
27
|
+
context: StoredContext<Context>;
|
|
28
|
+
triggerEvent: ContextItem;
|
|
29
|
+
baseMaxModelSteps: number;
|
|
30
|
+
config: Config;
|
|
31
|
+
}) => Promise<number> | number;
|
|
32
|
+
};
|
|
33
|
+
export declare function createAiSdkReactor<Context = unknown, Env extends ContextEnvironment = ContextEnvironment, Config = unknown>(options?: CreateAiSdkReactorOptions<Context, Env, Config>): ContextReactor<Context, Env>;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { executeAiSdkReaction } from "./ai-sdk.step.js";
|
|
2
|
+
export function createAiSdkReactor(options) {
|
|
3
|
+
return async (params) => {
|
|
4
|
+
let config;
|
|
5
|
+
if (options?.resolveConfig) {
|
|
6
|
+
config = await options.resolveConfig({
|
|
7
|
+
env: params.env,
|
|
8
|
+
context: params.context,
|
|
9
|
+
contextIdentifier: params.contextIdentifier,
|
|
10
|
+
triggerEvent: params.triggerEvent,
|
|
11
|
+
model: params.model,
|
|
12
|
+
eventId: params.eventId,
|
|
13
|
+
executionId: params.executionId,
|
|
14
|
+
contextId: params.contextId,
|
|
15
|
+
stepId: params.stepId,
|
|
16
|
+
iteration: params.iteration,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
const model = options?.selectModel && config !== undefined
|
|
20
|
+
? await options.selectModel({
|
|
21
|
+
env: params.env,
|
|
22
|
+
context: params.context,
|
|
23
|
+
triggerEvent: params.triggerEvent,
|
|
24
|
+
baseModel: params.model,
|
|
25
|
+
config,
|
|
26
|
+
})
|
|
27
|
+
: params.model;
|
|
28
|
+
const maxSteps = options?.selectMaxModelSteps && config !== undefined
|
|
29
|
+
? await options.selectMaxModelSteps({
|
|
30
|
+
env: params.env,
|
|
31
|
+
context: params.context,
|
|
32
|
+
triggerEvent: params.triggerEvent,
|
|
33
|
+
baseMaxModelSteps: params.maxModelSteps,
|
|
34
|
+
config,
|
|
35
|
+
})
|
|
36
|
+
: params.maxModelSteps;
|
|
37
|
+
const result = await executeAiSdkReaction({
|
|
38
|
+
env: params.env,
|
|
39
|
+
contextIdentifier: params.contextIdentifier,
|
|
40
|
+
model,
|
|
41
|
+
system: params.systemPrompt,
|
|
42
|
+
tools: params.toolsForModel,
|
|
43
|
+
eventId: params.eventId,
|
|
44
|
+
iteration: params.iteration,
|
|
45
|
+
maxSteps,
|
|
46
|
+
sendStart: params.sendStart,
|
|
47
|
+
silent: params.silent,
|
|
48
|
+
contextStepStream: params.contextStepStream,
|
|
49
|
+
writable: params.writable,
|
|
50
|
+
executionId: params.executionId,
|
|
51
|
+
contextId: params.contextId,
|
|
52
|
+
stepId: params.stepId,
|
|
53
|
+
});
|
|
54
|
+
return {
|
|
55
|
+
assistantEvent: result.assistantEvent,
|
|
56
|
+
actionRequests: result.toolCalls.map((entry) => ({
|
|
57
|
+
actionRef: String(entry.toolCallId),
|
|
58
|
+
actionName: String(entry.toolName),
|
|
59
|
+
input: entry.args,
|
|
60
|
+
})),
|
|
61
|
+
messagesForModel: result.messagesForModel,
|
|
62
|
+
llm: result.llm,
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
}
|