@kortyx/agent 0.14.1 โ 0.14.2
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/CHANGELOG.md +9 -0
- package/dist/index.d.ts +34 -2
- package/dist/index.js +341 -15
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.14.2](https://github.com/kortyx-io/kortyx/compare/agent-v0.14.1...agent-v0.14.2) (2026-06-12)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Dependencies
|
|
7
|
+
|
|
8
|
+
* The following workspace dependencies were updated
|
|
9
|
+
* dependencies
|
|
10
|
+
* @kortyx/runtime bumped to 0.11.0
|
|
11
|
+
|
|
3
12
|
## [0.14.1](https://github.com/kortyx-io/kortyx/compare/agent-v0.14.0...agent-v0.14.1) (2026-05-28)
|
|
4
13
|
|
|
5
14
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { WorkflowDefinition, GraphState } from '@kortyx/core';
|
|
2
2
|
import { GetProviderFn } from '@kortyx/providers';
|
|
3
|
-
import { WorkflowRegistry, FrameworkAdapter, ExecutionRuntimeConfig, PendingRequestRecord } from '@kortyx/runtime';
|
|
3
|
+
import { CheckpointSummary, CheckpointId, SessionCheckpointRecord, RollbackSessionCheckpointResult, ForkSessionCheckpointResult, WorkflowRegistry, FrameworkAdapter, ExecutionRuntimeConfig, PendingRequestRecord } from '@kortyx/runtime';
|
|
4
4
|
import { StreamChunk } from '@kortyx/stream';
|
|
5
5
|
import { C as ChatMessage } from './browser-wjeg_MwV.js';
|
|
6
6
|
export { S as StreamChatFromRouteArgs, s as streamChatFromRoute } from './browser-wjeg_MwV.js';
|
|
@@ -23,6 +23,12 @@ interface CreateAgentArgs {
|
|
|
23
23
|
}
|
|
24
24
|
interface Agent {
|
|
25
25
|
streamChat: (messages: ChatMessage[], options?: AgentProcessOptions) => Promise<AsyncIterable<StreamChunk>>;
|
|
26
|
+
listCheckpoints: (sessionId: string) => Promise<CheckpointSummary[]>;
|
|
27
|
+
getCheckpoint: (id: CheckpointId) => Promise<SessionCheckpointRecord | null>;
|
|
28
|
+
rollbackTo: (id: CheckpointId) => Promise<RollbackSessionCheckpointResult>;
|
|
29
|
+
fork: (id: CheckpointId, options?: {
|
|
30
|
+
newSessionId?: string;
|
|
31
|
+
}) => Promise<ForkSessionCheckpointResult>;
|
|
26
32
|
}
|
|
27
33
|
declare function createAgent(args: CreateAgentArgs): Agent;
|
|
28
34
|
|
|
@@ -33,7 +39,22 @@ type ChatRequestBody = {
|
|
|
33
39
|
context?: Record<string, unknown> | undefined;
|
|
34
40
|
messages: ChatMessage[];
|
|
35
41
|
};
|
|
42
|
+
type CheckpointRequestBody = {
|
|
43
|
+
action: "list";
|
|
44
|
+
sessionId: string;
|
|
45
|
+
} | {
|
|
46
|
+
action: "get";
|
|
47
|
+
checkpointId: string;
|
|
48
|
+
} | {
|
|
49
|
+
action: "rollback";
|
|
50
|
+
checkpointId: string;
|
|
51
|
+
} | {
|
|
52
|
+
action: "fork";
|
|
53
|
+
checkpointId: string;
|
|
54
|
+
newSessionId?: string | undefined;
|
|
55
|
+
};
|
|
36
56
|
declare function parseChatRequestBody(value: unknown): ChatRequestBody;
|
|
57
|
+
declare function parseCheckpointRequestBody(value: unknown): CheckpointRequestBody;
|
|
37
58
|
declare function handleChatRequestBody(args: {
|
|
38
59
|
agent: Agent;
|
|
39
60
|
body: ChatRequestBody;
|
|
@@ -42,6 +63,14 @@ declare function createChatRouteHandler(args: {
|
|
|
42
63
|
agent: Agent;
|
|
43
64
|
errorStatus?: number | undefined;
|
|
44
65
|
}): (request: Request) => Promise<Response>;
|
|
66
|
+
declare function handleCheckpointRequestBody(args: {
|
|
67
|
+
agent: Agent;
|
|
68
|
+
body: CheckpointRequestBody;
|
|
69
|
+
}): Promise<Response>;
|
|
70
|
+
declare function createCheckpointRouteHandler(args: {
|
|
71
|
+
agent: Agent;
|
|
72
|
+
errorStatus?: number | undefined;
|
|
73
|
+
}): (request: Request) => Promise<Response>;
|
|
45
74
|
|
|
46
75
|
type SelectWorkflowFn = (workflowId: string) => Promise<WorkflowDefinition>;
|
|
47
76
|
type SaveMemoryFn = (sessionId: string, state: GraphState) => Promise<void>;
|
|
@@ -51,6 +80,9 @@ interface CompiledGraphLike {
|
|
|
51
80
|
version?: string;
|
|
52
81
|
configurable?: Record<string, unknown>;
|
|
53
82
|
}) => AsyncIterable<unknown> | AsyncGenerator<unknown>;
|
|
83
|
+
getState?: (options?: {
|
|
84
|
+
configurable?: Record<string, unknown>;
|
|
85
|
+
}) => Promise<unknown>;
|
|
54
86
|
}
|
|
55
87
|
interface OrchestrateArgs {
|
|
56
88
|
sessionId?: string;
|
|
@@ -123,4 +155,4 @@ declare function transformGraphStreamForUI(stream: AsyncIterable<StreamEvent>, o
|
|
|
123
155
|
|
|
124
156
|
declare function extractLatestUserMessage(messages: ChatMessage[]): string;
|
|
125
157
|
|
|
126
|
-
export { type Agent, type AgentProcessOptions, type ApplyResumeSelection, ChatMessage, type ChatRequestBody, type CompiledGraphLike, type CreateAgentArgs, type OrchestrateArgs, type ResumeMeta, type SaveMemoryFn, type SelectWorkflowFn, type StreamChatArgs, createAgent, createChatRouteHandler, extractLatestUserMessage, handleChatRequestBody, orchestrateGraphStream, parseChatRequestBody, parseResumeMeta, streamChat, transformGraphStreamForUI, tryPrepareResumeStream };
|
|
158
|
+
export { type Agent, type AgentProcessOptions, type ApplyResumeSelection, ChatMessage, type ChatRequestBody, type CheckpointRequestBody, type CompiledGraphLike, type CreateAgentArgs, type OrchestrateArgs, type ResumeMeta, type SaveMemoryFn, type SelectWorkflowFn, type StreamChatArgs, createAgent, createChatRouteHandler, createCheckpointRouteHandler, extractLatestUserMessage, handleChatRequestBody, handleCheckpointRequestBody, orchestrateGraphStream, parseChatRequestBody, parseCheckpointRequestBody, parseResumeMeta, streamChat, transformGraphStreamForUI, tryPrepareResumeStream };
|
package/dist/index.js
CHANGED
|
@@ -21,10 +21,13 @@ var index_exports = {};
|
|
|
21
21
|
__export(index_exports, {
|
|
22
22
|
createAgent: () => createAgent,
|
|
23
23
|
createChatRouteHandler: () => createChatRouteHandler,
|
|
24
|
+
createCheckpointRouteHandler: () => createCheckpointRouteHandler,
|
|
24
25
|
extractLatestUserMessage: () => extractLatestUserMessage,
|
|
25
26
|
handleChatRequestBody: () => handleChatRequestBody,
|
|
27
|
+
handleCheckpointRequestBody: () => handleCheckpointRequestBody,
|
|
26
28
|
orchestrateGraphStream: () => orchestrateGraphStream,
|
|
27
29
|
parseChatRequestBody: () => parseChatRequestBody,
|
|
30
|
+
parseCheckpointRequestBody: () => parseCheckpointRequestBody,
|
|
28
31
|
parseResumeMeta: () => parseResumeMeta,
|
|
29
32
|
streamChat: () => streamChat,
|
|
30
33
|
streamChatFromRoute: () => streamChatFromRoute,
|
|
@@ -50,6 +53,25 @@ var chatRequestBodySchema = import_zod.z.looseObject({
|
|
|
50
53
|
context: import_zod.z.record(import_zod.z.string(), import_zod.z.unknown()).optional(),
|
|
51
54
|
messages: import_zod.z.array(chatMessageSchema)
|
|
52
55
|
});
|
|
56
|
+
var checkpointRequestBodySchema = import_zod.z.discriminatedUnion("action", [
|
|
57
|
+
import_zod.z.object({
|
|
58
|
+
action: import_zod.z.literal("list"),
|
|
59
|
+
sessionId: import_zod.z.string().min(1)
|
|
60
|
+
}).strict(),
|
|
61
|
+
import_zod.z.object({
|
|
62
|
+
action: import_zod.z.literal("get"),
|
|
63
|
+
checkpointId: import_zod.z.string().min(1)
|
|
64
|
+
}).strict(),
|
|
65
|
+
import_zod.z.object({
|
|
66
|
+
action: import_zod.z.literal("rollback"),
|
|
67
|
+
checkpointId: import_zod.z.string().min(1)
|
|
68
|
+
}).strict(),
|
|
69
|
+
import_zod.z.object({
|
|
70
|
+
action: import_zod.z.literal("fork"),
|
|
71
|
+
checkpointId: import_zod.z.string().min(1),
|
|
72
|
+
newSessionId: import_zod.z.string().min(1).optional()
|
|
73
|
+
}).strict()
|
|
74
|
+
]);
|
|
53
75
|
var toErrorMessage = (error) => error instanceof Error ? error.message : String(error);
|
|
54
76
|
function parseChatRequestBody(value) {
|
|
55
77
|
const parsed = chatRequestBodySchema.safeParse(value);
|
|
@@ -67,6 +89,12 @@ function parseChatRequestBody(value) {
|
|
|
67
89
|
messages: parsed.data.messages
|
|
68
90
|
};
|
|
69
91
|
}
|
|
92
|
+
function parseCheckpointRequestBody(value) {
|
|
93
|
+
const parsed = checkpointRequestBodySchema.safeParse(value);
|
|
94
|
+
if (parsed.success) return parsed.data;
|
|
95
|
+
const [firstIssue] = parsed.error.issues;
|
|
96
|
+
throw new Error(firstIssue.message);
|
|
97
|
+
}
|
|
70
98
|
async function handleChatRequestBody(args) {
|
|
71
99
|
const { agent, body } = args;
|
|
72
100
|
const stream = await agent.streamChat(body.messages, {
|
|
@@ -105,6 +133,38 @@ function createChatRouteHandler(args) {
|
|
|
105
133
|
}
|
|
106
134
|
};
|
|
107
135
|
}
|
|
136
|
+
async function handleCheckpointRequestBody(args) {
|
|
137
|
+
const { agent, body } = args;
|
|
138
|
+
const result = body.action === "list" ? await agent.listCheckpoints(body.sessionId) : body.action === "get" ? await agent.getCheckpoint(body.checkpointId) : body.action === "rollback" ? await agent.rollbackTo(body.checkpointId) : await agent.fork(body.checkpointId, {
|
|
139
|
+
...body.newSessionId ? { newSessionId: body.newSessionId } : {}
|
|
140
|
+
});
|
|
141
|
+
return new Response(JSON.stringify(result), {
|
|
142
|
+
headers: {
|
|
143
|
+
"content-type": "application/json"
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
function createCheckpointRouteHandler(args) {
|
|
148
|
+
const { agent, errorStatus = 400 } = args;
|
|
149
|
+
return async function POST(request) {
|
|
150
|
+
try {
|
|
151
|
+
const body = parseCheckpointRequestBody(await request.json());
|
|
152
|
+
return await handleCheckpointRequestBody({ agent, body });
|
|
153
|
+
} catch (error) {
|
|
154
|
+
return new Response(
|
|
155
|
+
JSON.stringify({
|
|
156
|
+
error: toErrorMessage(error)
|
|
157
|
+
}),
|
|
158
|
+
{
|
|
159
|
+
status: errorStatus,
|
|
160
|
+
headers: {
|
|
161
|
+
"content-type": "application/json"
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
}
|
|
108
168
|
|
|
109
169
|
// src/adapters/http-client.ts
|
|
110
170
|
var import_browser = require("@kortyx/stream/browser");
|
|
@@ -139,10 +199,12 @@ var import_runtime = require("@kortyx/runtime");
|
|
|
139
199
|
var import_langgraph = require("@langchain/langgraph");
|
|
140
200
|
|
|
141
201
|
// src/stream/transform-graph-stream-for-ui.ts
|
|
202
|
+
var isGraphStateOutput = (value) => value !== null && typeof value === "object" && !Array.isArray(value) && "currentWorkflow" in value;
|
|
142
203
|
async function* transformGraphStreamForUI(stream, options = {}) {
|
|
143
204
|
const { debug = false, emitStatus = debug } = options;
|
|
144
205
|
const startedNodes = /* @__PURE__ */ new Set();
|
|
145
206
|
const endedNodes = /* @__PURE__ */ new Set();
|
|
207
|
+
let latestGraphState = null;
|
|
146
208
|
for await (const event of stream) {
|
|
147
209
|
const { event: type, name, data } = event ?? {};
|
|
148
210
|
if (debug) console.log(`[debug:event]`, JSON.stringify(event, null, 2));
|
|
@@ -167,6 +229,7 @@ async function* transformGraphStreamForUI(stream, options = {}) {
|
|
|
167
229
|
JSON.stringify(output, null, 2)
|
|
168
230
|
);
|
|
169
231
|
if (!output || nodeName?.startsWith("ChannelWrite")) break;
|
|
232
|
+
if (isGraphStateOutput(output)) latestGraphState = output;
|
|
170
233
|
if (nodeName !== "__start__" && nodeName !== "__end__") {
|
|
171
234
|
if (!endedNodes.has(nodeName)) {
|
|
172
235
|
if (emitStatus) {
|
|
@@ -183,7 +246,11 @@ async function* transformGraphStreamForUI(stream, options = {}) {
|
|
|
183
246
|
case "on_graph_end": {
|
|
184
247
|
if (debug)
|
|
185
248
|
console.log(`[debug:on_graph_end]`, JSON.stringify(data, null, 2));
|
|
186
|
-
|
|
249
|
+
const output = data?.output;
|
|
250
|
+
yield {
|
|
251
|
+
type: "done",
|
|
252
|
+
data: isGraphStateOutput(output) ? output : latestGraphState
|
|
253
|
+
};
|
|
187
254
|
break;
|
|
188
255
|
}
|
|
189
256
|
default:
|
|
@@ -197,6 +264,14 @@ async function* transformGraphStreamForUI(stream, options = {}) {
|
|
|
197
264
|
|
|
198
265
|
// src/orchestrator.ts
|
|
199
266
|
var isRecord = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
267
|
+
var isGraphState = (value) => isRecord(value) && typeof value.currentWorkflow === "string";
|
|
268
|
+
var getGraphCheckpointId = (snapshot) => {
|
|
269
|
+
if (!isRecord(snapshot)) return void 0;
|
|
270
|
+
const config = isRecord(snapshot.config) ? snapshot.config : void 0;
|
|
271
|
+
const configurable = config && isRecord(config.configurable) ? config.configurable : void 0;
|
|
272
|
+
const checkpointId = configurable?.checkpoint_id;
|
|
273
|
+
return typeof checkpointId === "string" && checkpointId.length > 0 ? checkpointId : void 0;
|
|
274
|
+
};
|
|
200
275
|
var getTraceAdapter = (config) => {
|
|
201
276
|
const telemetry = isRecord(config.telemetry) ? config.telemetry : void 0;
|
|
202
277
|
const traceAdapter = telemetry?.trace ?? config.reasonTrace;
|
|
@@ -240,6 +315,10 @@ async function orchestrateGraphStream({
|
|
|
240
315
|
}
|
|
241
316
|
};
|
|
242
317
|
const namespacesUsed = /* @__PURE__ */ new Set();
|
|
318
|
+
const touchedNodes = /* @__PURE__ */ new Set();
|
|
319
|
+
const structuredStreamIds = /* @__PURE__ */ new Set();
|
|
320
|
+
const activePendingRequests = /* @__PURE__ */ new Map();
|
|
321
|
+
const pendingRequestWrites = [];
|
|
243
322
|
try {
|
|
244
323
|
const sid = config?.session?.id;
|
|
245
324
|
if (sid && typeof sid === "string") {
|
|
@@ -315,10 +394,12 @@ async function orchestrateGraphStream({
|
|
|
315
394
|
createdAt: Date.now(),
|
|
316
395
|
ttlMs: pendingTtlMs
|
|
317
396
|
};
|
|
397
|
+
activePendingRequests.set(record.token, record);
|
|
318
398
|
if (pendingStore) {
|
|
319
|
-
pendingStore.save(record).catch((error) => {
|
|
399
|
+
const savePromise = pendingStore.save(record).catch((error) => {
|
|
320
400
|
console.error("[orchestrator] failed to save pending request", error);
|
|
321
401
|
});
|
|
402
|
+
pendingRequestWrites.push(savePromise);
|
|
322
403
|
}
|
|
323
404
|
const clientMeta = record.schema.meta && typeof record.schema.meta === "object" && !Array.isArray(record.schema.meta) ? Object.fromEntries(
|
|
324
405
|
Object.entries(record.schema.meta).filter(
|
|
@@ -376,6 +457,7 @@ async function orchestrateGraphStream({
|
|
|
376
457
|
if (event === "text-start") {
|
|
377
458
|
const node = payload?.node;
|
|
378
459
|
if (!node) return;
|
|
460
|
+
touchedNodes.add(node);
|
|
379
461
|
out.write({
|
|
380
462
|
type: "text-start",
|
|
381
463
|
node,
|
|
@@ -389,6 +471,7 @@ async function orchestrateGraphStream({
|
|
|
389
471
|
const node = payload?.node;
|
|
390
472
|
const delta = String(payload?.delta ?? "");
|
|
391
473
|
if (!node || !delta) return;
|
|
474
|
+
touchedNodes.add(node);
|
|
392
475
|
appendAccumulatedOutput(payload, node, delta);
|
|
393
476
|
out.write({
|
|
394
477
|
type: "text-delta",
|
|
@@ -403,6 +486,7 @@ async function orchestrateGraphStream({
|
|
|
403
486
|
if (event === "text-end") {
|
|
404
487
|
const node = payload?.node;
|
|
405
488
|
if (!node) return;
|
|
489
|
+
touchedNodes.add(node);
|
|
406
490
|
out.write({
|
|
407
491
|
type: "text-end",
|
|
408
492
|
node,
|
|
@@ -426,6 +510,7 @@ async function orchestrateGraphStream({
|
|
|
426
510
|
...payloadObj.opId ? { opId: payloadObj.opId } : {},
|
|
427
511
|
...payloadObj.input !== void 0 ? { input: payloadObj.input } : {}
|
|
428
512
|
});
|
|
513
|
+
if (payloadObj.node) touchedNodes.add(payloadObj.node);
|
|
429
514
|
return;
|
|
430
515
|
}
|
|
431
516
|
if (event === "tool-call-result") {
|
|
@@ -444,6 +529,7 @@ async function orchestrateGraphStream({
|
|
|
444
529
|
...payloadObj.structuredContent !== void 0 ? { structuredContent: payloadObj.structuredContent } : {},
|
|
445
530
|
...typeof payloadObj.isError === "boolean" ? { isError: payloadObj.isError } : {}
|
|
446
531
|
});
|
|
532
|
+
if (payloadObj.node) touchedNodes.add(payloadObj.node);
|
|
447
533
|
return;
|
|
448
534
|
}
|
|
449
535
|
if (event === "tool-call-error") {
|
|
@@ -460,21 +546,26 @@ async function orchestrateGraphStream({
|
|
|
460
546
|
...payloadObj.opId ? { opId: payloadObj.opId } : {},
|
|
461
547
|
message: String(payloadObj.message ?? "")
|
|
462
548
|
});
|
|
549
|
+
if (payloadObj.node) touchedNodes.add(payloadObj.node);
|
|
463
550
|
return;
|
|
464
551
|
}
|
|
465
552
|
if (event === "message") {
|
|
466
553
|
const node = payload?.node;
|
|
467
554
|
const text = String(payload?.content ?? "");
|
|
555
|
+
if (node) touchedNodes.add(node);
|
|
468
556
|
out.write({ type: "message", node, content: text });
|
|
469
557
|
return;
|
|
470
558
|
}
|
|
471
559
|
if (event === "structured_data") {
|
|
472
560
|
const payloadObj = payload;
|
|
473
561
|
const kind = payloadObj.kind === "set" || payloadObj.kind === "append" || payloadObj.kind === "text-delta" || payloadObj.kind === "final" ? payloadObj.kind : "final";
|
|
562
|
+
const streamId = typeof payloadObj.streamId === "string" && payloadObj.streamId ? payloadObj.streamId : nextStructuredStreamId();
|
|
563
|
+
structuredStreamIds.add(streamId);
|
|
564
|
+
if (payloadObj.node) touchedNodes.add(payloadObj.node);
|
|
474
565
|
out.write({
|
|
475
566
|
type: "structured-data",
|
|
476
567
|
node: payloadObj.node,
|
|
477
|
-
streamId
|
|
568
|
+
streamId,
|
|
478
569
|
dataType: typeof payloadObj.dataType === "string" && payloadObj.dataType ? payloadObj.dataType : "generic",
|
|
479
570
|
kind,
|
|
480
571
|
...typeof payloadObj.schemaId === "string" ? { schemaId: payloadObj.schemaId } : {},
|
|
@@ -508,6 +599,7 @@ async function orchestrateGraphStream({
|
|
|
508
599
|
}
|
|
509
600
|
if (event === "interrupt") {
|
|
510
601
|
const p = payload;
|
|
602
|
+
if (typeof p?.node === "string") touchedNodes.add(p.node);
|
|
511
603
|
const local = {
|
|
512
604
|
node: p?.node,
|
|
513
605
|
workflow: p?.workflow,
|
|
@@ -522,11 +614,39 @@ async function orchestrateGraphStream({
|
|
|
522
614
|
const runLoop = async (runTraceSpan) => {
|
|
523
615
|
while (true) {
|
|
524
616
|
let workflowFinalState = null;
|
|
617
|
+
let workflowFinalGraphCheckpointId;
|
|
618
|
+
let sawWorkflowDone = false;
|
|
619
|
+
let workflowDoneData;
|
|
525
620
|
currentGraph.config = currentGraph.config || {};
|
|
526
621
|
currentGraph.config.emit = forwardEmit;
|
|
527
622
|
const threadId = currentGraph.config?.session?.id || sessionId || "anonymous-session";
|
|
528
|
-
const checkpointNs =
|
|
623
|
+
const checkpointNs = "";
|
|
529
624
|
namespacesUsed.add(checkpointNs);
|
|
625
|
+
const readLatestGraphCheckpointId = async () => {
|
|
626
|
+
const checkpointer = currentGraph.config?.checkpointer;
|
|
627
|
+
return checkpointer?.getLatestCheckpointId?.(runId, checkpointNs);
|
|
628
|
+
};
|
|
629
|
+
const readLatestGraphSnapshot = async () => {
|
|
630
|
+
if (typeof currentGraph.getState !== "function") {
|
|
631
|
+
const checkpointId2 = await readLatestGraphCheckpointId();
|
|
632
|
+
return checkpointId2 ? { state: currentState, checkpointId: checkpointId2 } : null;
|
|
633
|
+
}
|
|
634
|
+
const snapshot = await currentGraph.getState({
|
|
635
|
+
configurable: {
|
|
636
|
+
thread_id: runId,
|
|
637
|
+
checkpoint_ns: checkpointNs
|
|
638
|
+
}
|
|
639
|
+
});
|
|
640
|
+
const values = isRecord(snapshot) && "values" in snapshot ? snapshot.values : snapshot;
|
|
641
|
+
const checkpointId = getGraphCheckpointId(snapshot) ?? await readLatestGraphCheckpointId();
|
|
642
|
+
if (!isGraphState(values)) {
|
|
643
|
+
return checkpointId ? { state: currentState, checkpointId } : null;
|
|
644
|
+
}
|
|
645
|
+
return {
|
|
646
|
+
state: values,
|
|
647
|
+
...checkpointId ? { checkpointId } : {}
|
|
648
|
+
};
|
|
649
|
+
};
|
|
530
650
|
if (debugEnabled) {
|
|
531
651
|
out.write({
|
|
532
652
|
type: "status",
|
|
@@ -536,13 +656,14 @@ async function orchestrateGraphStream({
|
|
|
536
656
|
const isResume = Boolean(currentGraph.config?.resume);
|
|
537
657
|
const resumeUpdate = currentGraph.config?.resumeUpdate;
|
|
538
658
|
const resumeValue = currentGraph.config?.resumeValue;
|
|
659
|
+
const resumeCheckpointId = currentGraph.config?.resumeCheckpointId;
|
|
539
660
|
const invokeState = isResume ? resumeValue !== void 0 && resumeUpdate ? new import_langgraph.Command({ resume: resumeValue, update: resumeUpdate }) : resumeValue !== void 0 ? new import_langgraph.Command({ resume: resumeValue }) : resumeUpdate ? new import_langgraph.Command({ update: resumeUpdate }) : null : currentState;
|
|
540
661
|
const runtimeStream = currentGraph.streamEvents(invokeState, {
|
|
541
662
|
version: "v2",
|
|
542
663
|
configurable: {
|
|
543
664
|
thread_id: runId,
|
|
544
|
-
|
|
545
|
-
|
|
665
|
+
checkpoint_ns: checkpointNs,
|
|
666
|
+
...isResume && resumeCheckpointId ? { checkpoint_id: resumeCheckpointId } : {}
|
|
546
667
|
}
|
|
547
668
|
});
|
|
548
669
|
if (debugEnabled) {
|
|
@@ -557,13 +678,22 @@ async function orchestrateGraphStream({
|
|
|
557
678
|
});
|
|
558
679
|
for await (const chunk of uiStream) {
|
|
559
680
|
if (finished) break;
|
|
560
|
-
|
|
681
|
+
if ("node" in chunk && typeof chunk.node === "string") {
|
|
682
|
+
touchedNodes.add(chunk.node);
|
|
683
|
+
}
|
|
561
684
|
if (chunk.type === "done") {
|
|
562
|
-
|
|
563
|
-
|
|
685
|
+
sawWorkflowDone = true;
|
|
686
|
+
workflowDoneData = chunk.data;
|
|
687
|
+
continue;
|
|
564
688
|
}
|
|
689
|
+
out.write(chunk);
|
|
565
690
|
}
|
|
566
691
|
if (finished) return;
|
|
692
|
+
if (sawWorkflowDone) {
|
|
693
|
+
const graphSnapshot = await readLatestGraphSnapshot();
|
|
694
|
+
workflowFinalGraphCheckpointId = graphSnapshot?.checkpointId;
|
|
695
|
+
workflowFinalState = isGraphState(workflowDoneData) ? workflowDoneData : graphSnapshot?.state ?? currentState;
|
|
696
|
+
}
|
|
567
697
|
const transitionTo = pending.to;
|
|
568
698
|
const transitionPayload = pending.payload;
|
|
569
699
|
pending.to = null;
|
|
@@ -607,11 +737,26 @@ async function orchestrateGraphStream({
|
|
|
607
737
|
}
|
|
608
738
|
if (workflowFinalState) {
|
|
609
739
|
if (workflowFinalState && pendingRecordToken) {
|
|
740
|
+
if (pendingRequestWrites.length > 0) {
|
|
741
|
+
await Promise.all(pendingRequestWrites);
|
|
742
|
+
}
|
|
610
743
|
if (pendingStore) {
|
|
611
744
|
await pendingStore.update(pendingRecordToken, {
|
|
612
|
-
state: workflowFinalState
|
|
745
|
+
state: workflowFinalState,
|
|
746
|
+
...workflowFinalGraphCheckpointId ? { graphCheckpointId: workflowFinalGraphCheckpointId } : {}
|
|
613
747
|
});
|
|
614
748
|
}
|
|
749
|
+
const pendingRequest = activePendingRequests.get(pendingRecordToken);
|
|
750
|
+
if (pendingRequest) {
|
|
751
|
+
activePendingRequests.set(pendingRecordToken, {
|
|
752
|
+
...pendingRequest,
|
|
753
|
+
state: workflowFinalState,
|
|
754
|
+
...workflowFinalGraphCheckpointId ? { graphCheckpointId: workflowFinalGraphCheckpointId } : {}
|
|
755
|
+
});
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
if (!pendingRecordToken && pendingRequestWrites.length > 0) {
|
|
759
|
+
await Promise.all(pendingRequestWrites);
|
|
615
760
|
}
|
|
616
761
|
const shouldKeepFrameworkState = Boolean(pendingRecordToken) || Boolean(workflowFinalState?.awaitingHumanInput);
|
|
617
762
|
if (!shouldKeepFrameworkState) {
|
|
@@ -637,15 +782,86 @@ async function orchestrateGraphStream({
|
|
|
637
782
|
"kortyx.run.final_workflow": String(currentState.currentWorkflow)
|
|
638
783
|
});
|
|
639
784
|
runTraceSpan.end?.(runTraceEndArgs());
|
|
785
|
+
const resolvedSessionId2 = config?.session?.id || sessionId || "";
|
|
786
|
+
if (resolvedSessionId2 && frameworkAdapter?.sessionCheckpoints) {
|
|
787
|
+
try {
|
|
788
|
+
const checkpoint = await frameworkAdapter.sessionCheckpoints.append(
|
|
789
|
+
{
|
|
790
|
+
sessionId: resolvedSessionId2,
|
|
791
|
+
runId,
|
|
792
|
+
...workflowFinalGraphCheckpointId ? { graphCheckpointId: workflowFinalGraphCheckpointId } : {},
|
|
793
|
+
workflow: String(workflowFinalState.currentWorkflow),
|
|
794
|
+
state: workflowFinalState,
|
|
795
|
+
nodes: Array.from(touchedNodes),
|
|
796
|
+
structuredStreamIds: Array.from(structuredStreamIds),
|
|
797
|
+
pendingRequests: Array.from(activePendingRequests.values())
|
|
798
|
+
}
|
|
799
|
+
);
|
|
800
|
+
out.write({
|
|
801
|
+
type: "checkpoint",
|
|
802
|
+
id: checkpoint.id,
|
|
803
|
+
sessionId: checkpoint.sessionId,
|
|
804
|
+
turnIndex: checkpoint.turnIndex,
|
|
805
|
+
...checkpoint.label ? { label: checkpoint.label } : {}
|
|
806
|
+
});
|
|
807
|
+
} catch (error) {
|
|
808
|
+
console.error("[orchestrator] session checkpoint failed", error);
|
|
809
|
+
}
|
|
810
|
+
}
|
|
640
811
|
out.write({ type: "done", data: workflowFinalState });
|
|
641
812
|
out.end();
|
|
642
813
|
return;
|
|
643
814
|
}
|
|
815
|
+
const naturalGraphSnapshot = await readLatestGraphSnapshot();
|
|
816
|
+
const naturalFinalState = naturalGraphSnapshot?.state ?? currentState;
|
|
817
|
+
if (pendingRequestWrites.length > 0) {
|
|
818
|
+
await Promise.all(pendingRequestWrites);
|
|
819
|
+
}
|
|
820
|
+
if (pendingRecordToken && naturalGraphSnapshot?.checkpointId) {
|
|
821
|
+
if (pendingStore) {
|
|
822
|
+
await pendingStore.update(pendingRecordToken, {
|
|
823
|
+
state: naturalFinalState,
|
|
824
|
+
graphCheckpointId: naturalGraphSnapshot.checkpointId
|
|
825
|
+
});
|
|
826
|
+
}
|
|
827
|
+
const pendingRequest = activePendingRequests.get(pendingRecordToken);
|
|
828
|
+
if (pendingRequest) {
|
|
829
|
+
activePendingRequests.set(pendingRecordToken, {
|
|
830
|
+
...pendingRequest,
|
|
831
|
+
state: naturalFinalState,
|
|
832
|
+
graphCheckpointId: naturalGraphSnapshot.checkpointId
|
|
833
|
+
});
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
const resolvedSessionId = config?.session?.id || sessionId || "";
|
|
837
|
+
if (resolvedSessionId && frameworkAdapter?.sessionCheckpoints) {
|
|
838
|
+
try {
|
|
839
|
+
const checkpoint = await frameworkAdapter.sessionCheckpoints.append({
|
|
840
|
+
sessionId: resolvedSessionId,
|
|
841
|
+
runId,
|
|
842
|
+
...naturalGraphSnapshot?.checkpointId ? { graphCheckpointId: naturalGraphSnapshot.checkpointId } : {},
|
|
843
|
+
workflow: String(naturalFinalState.currentWorkflow),
|
|
844
|
+
state: naturalFinalState,
|
|
845
|
+
nodes: Array.from(touchedNodes),
|
|
846
|
+
structuredStreamIds: Array.from(structuredStreamIds),
|
|
847
|
+
pendingRequests: Array.from(activePendingRequests.values())
|
|
848
|
+
});
|
|
849
|
+
out.write({
|
|
850
|
+
type: "checkpoint",
|
|
851
|
+
id: checkpoint.id,
|
|
852
|
+
sessionId: checkpoint.sessionId,
|
|
853
|
+
turnIndex: checkpoint.turnIndex,
|
|
854
|
+
...checkpoint.label ? { label: checkpoint.label } : {}
|
|
855
|
+
});
|
|
856
|
+
} catch (error) {
|
|
857
|
+
console.error("[orchestrator] session checkpoint failed", error);
|
|
858
|
+
}
|
|
859
|
+
}
|
|
644
860
|
runTraceSpan.setAttributes?.({
|
|
645
|
-
"kortyx.run.final_workflow": String(
|
|
861
|
+
"kortyx.run.final_workflow": String(naturalFinalState.currentWorkflow)
|
|
646
862
|
});
|
|
647
863
|
runTraceSpan.end?.(runTraceEndArgs());
|
|
648
|
-
out.write({ type: "done" });
|
|
864
|
+
out.write({ type: "done", data: naturalFinalState });
|
|
649
865
|
out.end();
|
|
650
866
|
return;
|
|
651
867
|
}
|
|
@@ -765,10 +981,12 @@ async function tryPrepareResumeStream({
|
|
|
765
981
|
}
|
|
766
982
|
const hasResumeUpdate = Object.keys(resumeUpdate).length > 0;
|
|
767
983
|
const resumeValue = meta.selected?.length && pending.schema.kind === "multi-choice" ? meta.selected.map((x) => String(x)) : meta.selected?.length ? String(meta.selected[0]) : void 0;
|
|
984
|
+
const resumeCheckpointId = typeof pending.graphCheckpointId === "string" && pending.graphCheckpointId.length > 0 ? pending.graphCheckpointId : void 0;
|
|
768
985
|
const resumedGraph = await (0, import_runtime2.createExecutionGraph)(wf, {
|
|
769
986
|
...config,
|
|
770
987
|
resume: true,
|
|
771
988
|
...resumeValue !== void 0 ? { resumeValue } : {},
|
|
989
|
+
...resumeCheckpointId ? { resumeCheckpointId } : {},
|
|
772
990
|
...hasResumeUpdate ? { resumeUpdate } : {}
|
|
773
991
|
});
|
|
774
992
|
await store.delete(pending.token);
|
|
@@ -781,6 +999,7 @@ async function tryPrepareResumeStream({
|
|
|
781
999
|
...config,
|
|
782
1000
|
resume: true,
|
|
783
1001
|
...resumeValue !== void 0 ? { resumeValue } : {},
|
|
1002
|
+
...resumeCheckpointId ? { resumeCheckpointId } : {},
|
|
784
1003
|
...hasResumeUpdate ? { resumeUpdate } : {}
|
|
785
1004
|
},
|
|
786
1005
|
selectWorkflow,
|
|
@@ -865,14 +1084,43 @@ async function streamChat({
|
|
|
865
1084
|
});
|
|
866
1085
|
if (resumeStream) return resumeStream;
|
|
867
1086
|
const runId = (0, import_runtime3.makeRequestId)("run");
|
|
868
|
-
|
|
1087
|
+
let headCheckpoint = !isResumeRequest && frameworkAdapter?.sessionCheckpoints ? await frameworkAdapter.sessionCheckpoints.getHead(resolvedSessionId) : null;
|
|
1088
|
+
if (!isResumeRequest && !headCheckpoint && frameworkAdapter?.sessionCheckpoints) {
|
|
1089
|
+
headCheckpoint = await frameworkAdapter.sessionCheckpoints.append({
|
|
1090
|
+
sessionId: resolvedSessionId,
|
|
1091
|
+
runId,
|
|
1092
|
+
workflow: String(baseState.currentWorkflow),
|
|
1093
|
+
state: {
|
|
1094
|
+
...baseState,
|
|
1095
|
+
input: "",
|
|
1096
|
+
awaitingHumanInput: false
|
|
1097
|
+
},
|
|
1098
|
+
nodes: [],
|
|
1099
|
+
structuredStreamIds: [],
|
|
1100
|
+
pendingRequests: [],
|
|
1101
|
+
label: "session start"
|
|
1102
|
+
});
|
|
1103
|
+
}
|
|
1104
|
+
const currentWorkflow = requestedWorkflowId ? baseState.currentWorkflow : headCheckpoint?.state.currentWorkflow ?? baseState.currentWorkflow;
|
|
869
1105
|
const selectedWorkflow = await workflowSelector(currentWorkflow);
|
|
870
1106
|
const graph = await (0, import_runtime3.createExecutionGraph)(selectedWorkflow, runtimeConfig);
|
|
1107
|
+
const initialState = headCheckpoint ? {
|
|
1108
|
+
...headCheckpoint.state,
|
|
1109
|
+
input,
|
|
1110
|
+
config: runtimeConfig,
|
|
1111
|
+
currentWorkflow,
|
|
1112
|
+
awaitingHumanInput: false,
|
|
1113
|
+
runtime: {
|
|
1114
|
+
...headCheckpoint.state.runtime ?? {},
|
|
1115
|
+
...runtime.requestedWorkflow ? { requestedWorkflow: runtime.requestedWorkflow } : {},
|
|
1116
|
+
...runtime.priorMessages ? { priorMessages: runtime.priorMessages } : {}
|
|
1117
|
+
}
|
|
1118
|
+
} : { ...baseState, currentWorkflow };
|
|
871
1119
|
const orchestratedStream = await orchestrateGraphStream({
|
|
872
1120
|
sessionId: resolvedSessionId,
|
|
873
1121
|
runId,
|
|
874
1122
|
graph,
|
|
875
|
-
state:
|
|
1123
|
+
state: initialState,
|
|
876
1124
|
config: runtimeConfig,
|
|
877
1125
|
selectWorkflow: workflowSelector,
|
|
878
1126
|
...frameworkAdapter ? { frameworkAdapter } : {}
|
|
@@ -928,6 +1176,32 @@ var parseAgentProcessOptions = (value) => {
|
|
|
928
1176
|
if (value === void 0) return void 0;
|
|
929
1177
|
return parseSchema(agentProcessOptionsSchema, value);
|
|
930
1178
|
};
|
|
1179
|
+
var hydratePendingGraphCheckpoint = async (frameworkAdapter, request) => {
|
|
1180
|
+
if (request.graphCheckpointId) return request;
|
|
1181
|
+
const checkpointer = frameworkAdapter.checkpointer;
|
|
1182
|
+
const graphCheckpointId = await checkpointer?.getLatestCheckpointId?.(
|
|
1183
|
+
request.runId,
|
|
1184
|
+
request.workflow
|
|
1185
|
+
) ?? await checkpointer?.getLatestCheckpointId?.(request.runId, "");
|
|
1186
|
+
return graphCheckpointId ? { ...request, graphCheckpointId } : request;
|
|
1187
|
+
};
|
|
1188
|
+
var clearPendingGraphWrites = async (frameworkAdapter, request) => {
|
|
1189
|
+
if (!request.graphCheckpointId) return;
|
|
1190
|
+
const checkpointer = frameworkAdapter.checkpointer;
|
|
1191
|
+
if (!checkpointer?.deleteCheckpointWrites) return;
|
|
1192
|
+
await Promise.all([
|
|
1193
|
+
checkpointer.deleteCheckpointWrites(
|
|
1194
|
+
request.runId,
|
|
1195
|
+
request.workflow,
|
|
1196
|
+
request.graphCheckpointId
|
|
1197
|
+
),
|
|
1198
|
+
checkpointer.deleteCheckpointWrites(
|
|
1199
|
+
request.runId,
|
|
1200
|
+
"",
|
|
1201
|
+
request.graphCheckpointId
|
|
1202
|
+
)
|
|
1203
|
+
]);
|
|
1204
|
+
};
|
|
931
1205
|
function createAgent(args) {
|
|
932
1206
|
const parsedArgs = parseCreateAgentArgs(args);
|
|
933
1207
|
const {
|
|
@@ -988,16 +1262,68 @@ function createAgent(args) {
|
|
|
988
1262
|
})
|
|
989
1263
|
});
|
|
990
1264
|
};
|
|
991
|
-
|
|
1265
|
+
const listCheckpoints = (sessionId) => resolvedFrameworkAdapter.sessionCheckpoints.list(sessionId);
|
|
1266
|
+
const getCheckpoint = (id) => resolvedFrameworkAdapter.sessionCheckpoints.get(id);
|
|
1267
|
+
const rollbackTo = async (id) => {
|
|
1268
|
+
const result = await resolvedFrameworkAdapter.sessionCheckpoints.rollbackTo(id);
|
|
1269
|
+
const activePendingRequests = await Promise.all(
|
|
1270
|
+
result.activePendingRequests.map(
|
|
1271
|
+
(request) => hydratePendingGraphCheckpoint(resolvedFrameworkAdapter, request)
|
|
1272
|
+
)
|
|
1273
|
+
);
|
|
1274
|
+
await Promise.all(
|
|
1275
|
+
activePendingRequests.map(
|
|
1276
|
+
(request) => clearPendingGraphWrites(resolvedFrameworkAdapter, request)
|
|
1277
|
+
)
|
|
1278
|
+
);
|
|
1279
|
+
await Promise.all([
|
|
1280
|
+
...result.invalidatedInterruptTokens.map(
|
|
1281
|
+
(token) => resolvedFrameworkAdapter.pendingRequests.delete(token)
|
|
1282
|
+
),
|
|
1283
|
+
...activePendingRequests.map(
|
|
1284
|
+
(request) => resolvedFrameworkAdapter.pendingRequests.save(request)
|
|
1285
|
+
)
|
|
1286
|
+
]);
|
|
1287
|
+
return { ...result, activePendingRequests };
|
|
1288
|
+
};
|
|
1289
|
+
const fork = async (id, options) => {
|
|
1290
|
+
const result = await resolvedFrameworkAdapter.sessionCheckpoints.fork(
|
|
1291
|
+
id,
|
|
1292
|
+
options
|
|
1293
|
+
);
|
|
1294
|
+
const activePendingRequests = await Promise.all(
|
|
1295
|
+
result.checkpoint.activePendingRequests.map(
|
|
1296
|
+
(request) => hydratePendingGraphCheckpoint(resolvedFrameworkAdapter, request)
|
|
1297
|
+
)
|
|
1298
|
+
);
|
|
1299
|
+
await Promise.all(
|
|
1300
|
+
activePendingRequests.map(
|
|
1301
|
+
(request) => clearPendingGraphWrites(resolvedFrameworkAdapter, request)
|
|
1302
|
+
)
|
|
1303
|
+
);
|
|
1304
|
+
await Promise.all(
|
|
1305
|
+
activePendingRequests.map(
|
|
1306
|
+
(request) => resolvedFrameworkAdapter.pendingRequests.save(request)
|
|
1307
|
+
)
|
|
1308
|
+
);
|
|
1309
|
+
return {
|
|
1310
|
+
...result,
|
|
1311
|
+
checkpoint: { ...result.checkpoint, activePendingRequests }
|
|
1312
|
+
};
|
|
1313
|
+
};
|
|
1314
|
+
return { streamChat: streamChat2, listCheckpoints, getCheckpoint, rollbackTo, fork };
|
|
992
1315
|
}
|
|
993
1316
|
// Annotate the CommonJS export names for ESM import in node:
|
|
994
1317
|
0 && (module.exports = {
|
|
995
1318
|
createAgent,
|
|
996
1319
|
createChatRouteHandler,
|
|
1320
|
+
createCheckpointRouteHandler,
|
|
997
1321
|
extractLatestUserMessage,
|
|
998
1322
|
handleChatRequestBody,
|
|
1323
|
+
handleCheckpointRequestBody,
|
|
999
1324
|
orchestrateGraphStream,
|
|
1000
1325
|
parseChatRequestBody,
|
|
1326
|
+
parseCheckpointRequestBody,
|
|
1001
1327
|
parseResumeMeta,
|
|
1002
1328
|
streamChat,
|
|
1003
1329
|
streamChatFromRoute,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/adapters/http.ts","../src/adapters/http-client.ts","../src/chat/create-agent.ts","../src/chat/process-chat.ts","../src/interrupt/resume-handler.ts","../src/orchestrator.ts","../src/stream/transform-graph-stream-for-ui.ts","../src/utils/extract-latest-message.ts"],"sourcesContent":["// release-test: 2026-01-22\n\nexport type { ChatRequestBody } from \"./adapters/http\";\nexport {\n createChatRouteHandler,\n handleChatRequestBody,\n parseChatRequestBody,\n} from \"./adapters/http\";\nexport type { StreamChatFromRouteArgs } from \"./adapters/http-client\";\nexport { streamChatFromRoute } from \"./adapters/http-client\";\nexport type {\n Agent,\n AgentProcessOptions,\n CreateAgentArgs,\n} from \"./chat/create-agent\";\nexport { createAgent } from \"./chat/create-agent\";\nexport type { StreamChatArgs } from \"./chat/process-chat\";\nexport { streamChat } from \"./chat/process-chat\";\nexport type {\n ApplyResumeSelection,\n ResumeMeta,\n} from \"./interrupt/resume-handler\";\nexport {\n parseResumeMeta,\n tryPrepareResumeStream,\n} from \"./interrupt/resume-handler\";\nexport type {\n CompiledGraphLike,\n OrchestrateArgs,\n SaveMemoryFn,\n SelectWorkflowFn,\n} from \"./orchestrator\";\nexport { orchestrateGraphStream } from \"./orchestrator\";\nexport { transformGraphStreamForUI } from \"./stream/transform-graph-stream-for-ui\";\nexport type { ChatMessage } from \"./types/chat-message\";\nexport { extractLatestUserMessage } from \"./utils/extract-latest-message\";\n","import { collectBufferedStream, toSSE } from \"@kortyx/stream\";\nimport { z } from \"zod\";\nimport type { Agent } from \"../chat/create-agent\";\nimport type { ChatMessage } from \"../types/chat-message\";\n\nexport type ChatRequestBody = {\n sessionId?: string | undefined;\n workflowId?: string | undefined;\n stream?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n messages: ChatMessage[];\n};\n\nconst chatMessageSchema = z\n .object({\n role: z.enum([\"user\", \"assistant\", \"system\"]),\n content: z.string(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n id: z.string().optional(),\n timestamp: z.number().refine(Number.isFinite).optional(),\n })\n .strict();\n\nconst chatRequestBodySchema = z.looseObject({\n sessionId: z.string().optional(),\n workflowId: z.string().optional(),\n stream: z.boolean().optional(),\n context: z.record(z.string(), z.unknown()).optional(),\n messages: z.array(chatMessageSchema),\n});\n\nconst toErrorMessage = (error: unknown): string =>\n error instanceof Error ? error.message : String(error);\n\nexport function parseChatRequestBody(value: unknown): ChatRequestBody {\n const parsed = chatRequestBodySchema.safeParse(value);\n if (!parsed.success) {\n const [firstIssue] = parsed.error.issues as unknown as [\n { message: string },\n ...Array<{ message: string }>,\n ];\n throw new Error(firstIssue.message);\n }\n\n const sessionId = parsed.data.sessionId?.trim();\n const workflowId = parsed.data.workflowId?.trim();\n\n return {\n ...(sessionId ? { sessionId } : {}),\n ...(workflowId ? { workflowId } : {}),\n ...(typeof parsed.data.stream === \"boolean\"\n ? { stream: parsed.data.stream }\n : {}),\n ...(parsed.data.context ? { context: parsed.data.context } : {}),\n messages: parsed.data.messages as ChatMessage[],\n };\n}\n\nexport async function handleChatRequestBody(args: {\n agent: Agent;\n body: ChatRequestBody;\n}): Promise<Response> {\n const { agent, body } = args;\n const stream = await agent.streamChat(body.messages, {\n sessionId: body.sessionId,\n workflowId: body.workflowId,\n context: body.context,\n });\n\n if (body.stream === false) {\n const buffered = await collectBufferedStream(stream);\n return new Response(JSON.stringify(buffered), {\n headers: {\n \"content-type\": \"application/json\",\n },\n });\n }\n\n return toSSE(stream);\n}\n\nexport function createChatRouteHandler(args: {\n agent: Agent;\n errorStatus?: number | undefined;\n}): (request: Request) => Promise<Response> {\n const { agent, errorStatus = 400 } = args;\n\n return async function POST(request: Request): Promise<Response> {\n try {\n const body = parseChatRequestBody(await request.json());\n return await handleChatRequestBody({ agent, body });\n } catch (error) {\n return new Response(\n JSON.stringify({\n error: toErrorMessage(error),\n }),\n {\n status: errorStatus,\n headers: {\n \"content-type\": \"application/json\",\n },\n },\n );\n }\n };\n}\n","import { type StreamChunk, streamFromRoute } from \"@kortyx/stream/browser\";\nimport type { ChatMessage } from \"../types/chat-message\";\n\nexport interface StreamChatFromRouteArgs {\n endpoint: string;\n sessionId?: string | undefined;\n workflowId?: string | undefined;\n messages: ChatMessage[];\n fetchImpl?: typeof fetch;\n headers?: Record<string, string> | undefined;\n}\n\nexport async function* streamChatFromRoute(\n args: StreamChatFromRouteArgs,\n): AsyncGenerator<StreamChunk, void, void> {\n yield* streamFromRoute({\n endpoint: args.endpoint,\n ...(args.fetchImpl ? { fetchImpl: args.fetchImpl } : {}),\n ...(args.headers ? { headers: args.headers } : {}),\n body: {\n sessionId: args.sessionId,\n workflowId: args.workflowId,\n messages: args.messages,\n },\n });\n}\n","import { resolve } from \"node:path\";\nimport type { WorkflowDefinition } from \"@kortyx/core\";\nimport {\n type GetProviderFn,\n getProvider as getRegisteredProvider,\n} from \"@kortyx/providers\";\nimport type {\n ExecutionRuntimeConfig,\n FrameworkAdapter,\n WorkflowRegistry,\n} from \"@kortyx/runtime\";\nimport {\n createFileWorkflowRegistry,\n createFrameworkAdapterFromEnv,\n createInMemoryWorkflowRegistry,\n} from \"@kortyx/runtime\";\nimport type { StreamChunk } from \"@kortyx/stream\";\nimport { z } from \"zod\";\nimport type { ChatMessage } from \"../types/chat-message\";\nimport { streamChat as runStreamChat } from \"./process-chat\";\n\nexport interface AgentProcessOptions {\n sessionId?: string | undefined;\n workflowId?: string | undefined;\n context?: Record<string, unknown> | undefined;\n}\n\nexport interface CreateAgentArgs {\n getProvider?: GetProviderFn | undefined;\n workflows?: WorkflowDefinition[];\n workflowsDir?: string;\n workflowRegistry?: WorkflowRegistry;\n defaultWorkflowId?: string;\n frameworkAdapter?: FrameworkAdapter;\n telemetry?: ExecutionRuntimeConfig[\"telemetry\"];\n}\n\nexport interface Agent {\n streamChat: (\n messages: ChatMessage[],\n options?: AgentProcessOptions,\n ) => Promise<AsyncIterable<StreamChunk>>;\n}\n\nconst agentProcessOptionsSchema = z\n .object({\n sessionId: z.string().optional(),\n workflowId: z.string().optional(),\n context: z.record(z.string(), z.unknown()).optional(),\n })\n .strict();\n\nconst createAgentArgsBaseSchema = z\n .object({\n getProvider: z.unknown().optional(),\n workflows: z.array(z.unknown()).optional(),\n workflowsDir: z.string().optional(),\n workflowRegistry: z.unknown().optional(),\n defaultWorkflowId: z.string().optional(),\n frameworkAdapter: z.unknown().optional(),\n telemetry: z.unknown().optional(),\n })\n .strict();\n\nconst createAgentArgsSchema = createAgentArgsBaseSchema.superRefine(\n (value: z.infer<typeof createAgentArgsBaseSchema>, ctx: z.RefinementCtx) => {\n if (\n value.getProvider !== undefined &&\n typeof value.getProvider !== \"function\"\n ) {\n ctx.addIssue({\n code: \"custom\",\n message: \"Expected `args.getProvider` to be a function.\",\n path: [\"getProvider\"],\n });\n }\n\n const workflowSources = [\n value.workflows !== undefined,\n value.workflowsDir !== undefined,\n value.workflowRegistry !== undefined,\n ].filter(Boolean).length;\n\n if (workflowSources > 1) {\n ctx.addIssue({\n code: \"custom\",\n message:\n \"Use only one workflow source: `workflows`, `workflowsDir`, or `workflowRegistry`.\",\n });\n }\n },\n);\n\nconst parseSchema = <T>(schema: z.ZodType<T>, value: unknown): T => {\n const parsed = schema.safeParse(value);\n if (parsed.success) return parsed.data;\n const [firstIssue] = parsed.error.issues as unknown as [\n { message: string },\n ...Array<{ message: string }>,\n ];\n throw new Error(firstIssue.message);\n};\n\nconst parseCreateAgentArgs = (value: unknown): CreateAgentArgs =>\n parseSchema(createAgentArgsSchema, value) as CreateAgentArgs;\n\nconst parseAgentProcessOptions = (\n value: unknown,\n): AgentProcessOptions | undefined => {\n if (value === undefined) return undefined;\n return parseSchema(agentProcessOptionsSchema, value);\n};\n\nexport function createAgent(args: CreateAgentArgs): Agent {\n const parsedArgs = parseCreateAgentArgs(args);\n\n const {\n getProvider,\n workflows,\n workflowsDir,\n workflowRegistry,\n defaultWorkflowId,\n frameworkAdapter,\n telemetry,\n } = parsedArgs;\n\n const resolvedDefaultWorkflowId = defaultWorkflowId;\n const resolvedFrameworkAdapter: FrameworkAdapter =\n frameworkAdapter ?? createFrameworkAdapterFromEnv();\n const resolvedGetProvider = getProvider ?? getRegisteredProvider;\n\n const resolvedCwd = process.cwd();\n\n const registryPromise: Promise<WorkflowRegistry | undefined> = (async () => {\n if (workflowRegistry) return workflowRegistry;\n if (workflows) {\n return createInMemoryWorkflowRegistry(workflows, {\n fallbackId: resolvedDefaultWorkflowId ?? \"general-chat\",\n });\n }\n if (workflowsDir) {\n return createFileWorkflowRegistry({\n workflowsDir,\n fallbackId: resolvedDefaultWorkflowId ?? \"general-chat\",\n });\n }\n\n const resolvedWorkflowsDir = resolve(resolvedCwd, \"src\", \"workflows\");\n return createFileWorkflowRegistry({\n workflowsDir: resolvedWorkflowsDir,\n fallbackId: resolvedDefaultWorkflowId ?? \"general-chat\",\n });\n })();\n\n const streamChat = async (\n messages: ChatMessage[],\n options?: AgentProcessOptions,\n ): Promise<AsyncIterable<StreamChunk>> => {\n const parsedOptions = parseAgentProcessOptions(options);\n\n const registry = await registryPromise;\n if (!registry) {\n throw new Error(\n \"createAgent requires workflows, workflowsDir, or workflowRegistry.\",\n );\n }\n\n return runStreamChat({\n ...(resolvedDefaultWorkflowId\n ? { defaultWorkflowId: resolvedDefaultWorkflowId }\n : {}),\n messages,\n options: parsedOptions,\n workflowRegistry: registry,\n frameworkAdapter: resolvedFrameworkAdapter,\n getProvider: resolvedGetProvider,\n loadRuntimeConfig: (runtimeOptions?: AgentProcessOptions) => ({\n ...(runtimeOptions?.sessionId\n ? {\n session: {\n id: runtimeOptions.sessionId,\n },\n }\n : {}),\n ...(runtimeOptions?.context ? { context: runtimeOptions.context } : {}),\n ...(telemetry ? { telemetry } : {}),\n }),\n });\n };\n\n return { streamChat };\n}\n","import type { RuntimeEnvelope } from \"@kortyx/core\";\nimport type { GetProviderFn } from \"@kortyx/providers\";\nimport type { FrameworkAdapter, WorkflowRegistry } from \"@kortyx/runtime\";\nimport {\n buildInitialGraphState,\n createExecutionGraph,\n makeRequestId,\n} from \"@kortyx/runtime\";\nimport type { StreamChunk } from \"@kortyx/stream\";\nimport type { ApplyResumeSelection } from \"../interrupt/resume-handler\";\nimport {\n parseResumeMeta,\n tryPrepareResumeStream,\n} from \"../interrupt/resume-handler\";\nimport type { SelectWorkflowFn } from \"../orchestrator\";\nimport { orchestrateGraphStream } from \"../orchestrator\";\nimport type { ChatMessage } from \"../types/chat-message\";\nimport { extractLatestUserMessage } from \"../utils/extract-latest-message\";\n\nexport interface RuntimeConfig {\n session?: { id?: string };\n [key: string]: unknown;\n}\n\nexport interface StreamChatArgs<Options> {\n messages: ChatMessage[];\n options?: Options | undefined;\n sessionId?: string;\n defaultWorkflowId?: string;\n loadRuntimeConfig: (\n options?: Options,\n ) => RuntimeConfig | Promise<RuntimeConfig>;\n selectWorkflow?: SelectWorkflowFn;\n workflowRegistry?: WorkflowRegistry;\n frameworkAdapter?: FrameworkAdapter;\n getProvider: GetProviderFn;\n applyResumeSelection?: ApplyResumeSelection;\n}\n\nexport async function streamChat<Options = unknown>({\n messages,\n options,\n sessionId,\n defaultWorkflowId,\n loadRuntimeConfig,\n selectWorkflow,\n workflowRegistry,\n frameworkAdapter,\n getProvider,\n applyResumeSelection,\n}: StreamChatArgs<Options>): Promise<AsyncIterable<StreamChunk>> {\n const config = await loadRuntimeConfig(options);\n const runtimeConfig: Parameters<typeof createExecutionGraph>[1] = {\n ...config,\n getProvider,\n ...(frameworkAdapter\n ? { checkpointer: frameworkAdapter.checkpointer }\n : {}),\n };\n\n const workflowSelector: SelectWorkflowFn | null =\n selectWorkflow ??\n (workflowRegistry ? (id) => workflowRegistry.select(id) : null);\n if (!workflowSelector) {\n throw new Error(\n \"streamChat requires selectWorkflow or workflowRegistry to resolve workflows.\",\n );\n }\n\n const fallbackSessionId = (options as { sessionId?: string } | undefined)\n ?.sessionId;\n const resolvedSessionId =\n sessionId || fallbackSessionId || \"anonymous-session\";\n const last = messages[messages.length - 1];\n const input = extractLatestUserMessage(messages);\n\n const previousMessages = messages.slice(0, -1);\n const runtime: RuntimeEnvelope = {\n ...(previousMessages.length > 0 ? { priorMessages: previousMessages } : {}),\n } as RuntimeEnvelope;\n\n const isResumeRequest = Boolean(parseResumeMeta(last));\n const requestedWorkflowId = (() => {\n if (!options) return undefined;\n if (typeof options !== \"object\") return undefined;\n const record = options as Record<string, unknown>;\n const wfId = record.workflowId;\n if (typeof wfId === \"string\") return wfId;\n return undefined;\n })();\n if (!isResumeRequest && requestedWorkflowId) {\n if (requestedWorkflowId.trim() === \"\") delete runtime.requestedWorkflow;\n else runtime.requestedWorkflow = requestedWorkflowId;\n }\n\n const baseState = await buildInitialGraphState({\n input,\n config: runtimeConfig,\n runtime,\n ...(defaultWorkflowId ? { defaultWorkflowId } : {}),\n });\n\n const resumeStream = await tryPrepareResumeStream({\n lastMessage: last,\n sessionId: resolvedSessionId,\n config: runtimeConfig,\n selectWorkflow: workflowSelector,\n ...(frameworkAdapter ? { frameworkAdapter } : {}),\n ...(defaultWorkflowId ? { defaultWorkflowId } : {}),\n ...(applyResumeSelection ? { applyResumeSelection } : {}),\n });\n if (resumeStream) return resumeStream as AsyncIterable<StreamChunk>;\n\n const runId = makeRequestId(\"run\");\n const currentWorkflow = baseState.currentWorkflow;\n const selectedWorkflow = await workflowSelector(currentWorkflow as string);\n\n const graph = await createExecutionGraph(selectedWorkflow, runtimeConfig);\n\n const orchestratedStream = await orchestrateGraphStream({\n sessionId: resolvedSessionId,\n runId,\n graph,\n state: { ...baseState, currentWorkflow },\n config: runtimeConfig,\n selectWorkflow: workflowSelector,\n ...(frameworkAdapter ? { frameworkAdapter } : {}),\n });\n\n return orchestratedStream as AsyncIterable<StreamChunk>;\n}\n","import type { GraphState } from \"@kortyx/core\";\nimport type {\n FrameworkAdapter,\n PendingRequestRecord,\n PendingRequestStore,\n} from \"@kortyx/runtime\";\nimport { createExecutionGraph } from \"@kortyx/runtime\";\nimport type { StreamChunk } from \"@kortyx/stream\";\nimport type { SelectWorkflowFn } from \"../orchestrator\";\nimport { type OrchestrateArgs, orchestrateGraphStream } from \"../orchestrator\";\nimport type { ChatMessage } from \"../types/chat-message\";\n\nexport interface ResumeMeta {\n token: string;\n requestId: string;\n selected: string[]; // normalized to array for consistency\n cancel?: boolean;\n}\n\nexport type ApplyResumeSelection = (args: {\n pending: PendingRequestRecord;\n selected: string[];\n}) => Record<string, unknown> | null | undefined;\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n\nexport function parseResumeMeta(\n msg: ChatMessage | undefined,\n): ResumeMeta | null {\n if (!msg || !msg.metadata) return null;\n const raw = msg.metadata.resume;\n if (!isRecord(raw)) return null;\n\n const token = typeof raw.token === \"string\" ? raw.token : \"\";\n const requestId = typeof raw.requestId === \"string\" ? raw.requestId : \"\";\n const cancel = raw.cancel === true;\n\n // Accept multiple shapes; normalize to selected: string[]\n let selected: string[] = [];\n const rawSelected = raw.selected;\n if (typeof rawSelected === \"string\") selected = [rawSelected];\n else if (Array.isArray(rawSelected)) selected = rawSelected.map(String);\n else if (isRecord(raw.choice) && typeof raw.choice.id === \"string\")\n selected = [raw.choice.id];\n else if (Array.isArray(raw.choices))\n selected = raw.choices\n .map((c) => (isRecord(c) ? c.id : undefined))\n .filter((id): id is string => typeof id === \"string\");\n\n if (!token || !requestId) return null;\n return { token, requestId, selected, cancel };\n}\n\ninterface TryResumeArgs {\n lastMessage: ChatMessage | undefined;\n sessionId: string;\n config: Record<string, unknown>;\n selectWorkflow: SelectWorkflowFn;\n defaultWorkflowId?: string;\n applyResumeSelection?: ApplyResumeSelection;\n frameworkAdapter?: FrameworkAdapter;\n}\n\nexport async function tryPrepareResumeStream({\n lastMessage,\n sessionId,\n config,\n selectWorkflow,\n defaultWorkflowId,\n applyResumeSelection,\n frameworkAdapter,\n}: TryResumeArgs): Promise<AsyncIterable<StreamChunk> | null> {\n const meta = parseResumeMeta(lastMessage);\n if (!meta) return null;\n\n const store: PendingRequestStore | undefined =\n frameworkAdapter?.pendingRequests;\n if (!store) return null;\n\n const pending = await store.get(meta.token);\n if (!pending || pending.requestId !== meta.requestId) {\n // Invalid/expired; ignore and continue normal flow\n // eslint-disable-next-line no-console\n console.log(\n `[resume] pending not found or mismatched. token=${meta.token} requestId=${meta.requestId}`,\n );\n return null;\n }\n\n if (meta.cancel) {\n await store.delete(pending.token);\n return null;\n }\n\n // Build a minimal state; the checkpointer (keyed by sessionId) will restore paused context\n // eslint-disable-next-line no-console\n console.log(\n `[resume] token=${meta.token} requestId=${meta.requestId} selected=${JSON.stringify(\n meta.selected,\n )} sessionId=${sessionId}`,\n );\n\n const resumeData = applyResumeSelection\n ? applyResumeSelection({ pending, selected: meta.selected })\n : meta.selected?.length\n ? { coordinates: String(meta.selected[0]) }\n : {};\n\n const resumeDataPatch = isRecord(resumeData) ? resumeData : {};\n const pendingMeta = isRecord(pending.schema?.meta) ? pending.schema.meta : {};\n const resumeStatePatch = isRecord(pendingMeta.__kortyxResumeStatePatch)\n ? pendingMeta.__kortyxResumeStatePatch\n : undefined;\n\n const pendingData = isRecord(pending.state?.data) ? pending.state?.data : {};\n const workflowId =\n typeof pending.workflow === \"string\" && pending.workflow.trim()\n ? pending.workflow\n : typeof defaultWorkflowId === \"string\" && defaultWorkflowId.trim()\n ? defaultWorkflowId\n : \"job-search\";\n\n const resumedState = {\n // For static breakpoints, resume with null input (set in orchestrator),\n // and stash the user selection into data so the next node can read it.\n input: \"\",\n lastNode: \"__start__\",\n currentWorkflow: workflowId,\n config,\n runtime: {},\n conversationHistory: [],\n awaitingHumanInput: false,\n data: {\n ...pendingData,\n ...resumeDataPatch,\n },\n } satisfies GraphState;\n\n const wf = await selectWorkflow(resumedState.currentWorkflow as string);\n const resumeUpdate: Record<string, unknown> = {};\n if (Object.keys(resumeDataPatch).length > 0) {\n resumeUpdate.data = {\n ...pendingData,\n ...resumeDataPatch,\n };\n }\n if (resumeStatePatch) {\n resumeUpdate.runtime = resumeStatePatch;\n }\n const hasResumeUpdate = Object.keys(resumeUpdate).length > 0;\n const resumeValue =\n meta.selected?.length && pending.schema.kind === \"multi-choice\"\n ? meta.selected.map((x) => String(x))\n : meta.selected?.length\n ? String(meta.selected[0])\n : undefined;\n const resumedGraph = await createExecutionGraph(wf, {\n ...config,\n resume: true,\n ...(resumeValue !== undefined ? { resumeValue } : {}),\n ...(hasResumeUpdate ? { resumeUpdate } : {}),\n });\n await store.delete(pending.token);\n\n const args = {\n sessionId,\n runId: pending.runId,\n graph: resumedGraph,\n state: resumedState,\n config: {\n ...config,\n resume: true,\n ...(resumeValue !== undefined ? { resumeValue } : {}),\n ...(hasResumeUpdate ? { resumeUpdate } : {}),\n },\n selectWorkflow,\n frameworkAdapter: frameworkAdapter as FrameworkAdapter,\n } satisfies OrchestrateArgs;\n\n const stream = await orchestrateGraphStream(args);\n return stream as unknown as AsyncIterable<StreamChunk>;\n}\n","import { PassThrough } from \"node:stream\";\nimport type { GraphState, WorkflowDefinition, WorkflowId } from \"@kortyx/core\";\nimport {\n createExecutionGraph,\n type FrameworkAdapter,\n makeRequestId,\n makeResumeToken,\n type PendingRequestRecord,\n type PendingRequestStore,\n} from \"@kortyx/runtime\";\nimport type { StreamChunk } from \"@kortyx/stream\";\nimport { Command } from \"@langchain/langgraph\";\nimport { transformGraphStreamForUI } from \"./stream/transform-graph-stream-for-ui\";\n\nexport type SelectWorkflowFn = (\n workflowId: string,\n) => Promise<WorkflowDefinition>;\n\nexport type SaveMemoryFn = (\n sessionId: string,\n state: GraphState,\n) => Promise<void>;\n\nexport interface CompiledGraphLike {\n config?: Record<string, unknown>;\n streamEvents: (\n state: GraphState,\n options?: { version?: string; configurable?: Record<string, unknown> },\n ) => AsyncIterable<unknown> | AsyncGenerator<unknown>;\n}\n\nexport interface OrchestrateArgs {\n sessionId?: string;\n runId: string;\n graph: CompiledGraphLike; // minimal graph surface used here\n state: GraphState; // initial state\n config: Record<string, unknown>; // runtime config\n selectWorkflow: SelectWorkflowFn;\n frameworkAdapter?: FrameworkAdapter;\n}\n\ntype TraceSpanLike = {\n setAttributes?: (attributes: Record<string, unknown>) => void;\n addEvent?: (name: string, attributes?: Record<string, unknown>) => void;\n end?: (args?: {\n attributes?: Record<string, unknown>;\n telemetry?: Record<string, unknown>;\n }) => void;\n fail?: (\n error: unknown,\n args?: {\n attributes?: Record<string, unknown>;\n telemetry?: Record<string, unknown>;\n },\n ) => void;\n};\n\ntype TraceAdapterLike = {\n startSpan?: (args: {\n name: string;\n attributes?: Record<string, unknown>;\n telemetry?: unknown;\n }) => TraceSpanLike | undefined;\n withSpan?: <T>(\n args: {\n name: string;\n attributes?: Record<string, unknown>;\n telemetry?: unknown;\n },\n fn: (span: TraceSpanLike) => T | Promise<T>,\n ) => Promise<T>;\n getActiveContext?: () =>\n | {\n traceId: string;\n spanId: string;\n }\n | undefined;\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n\nconst getTraceAdapter = (\n config: Record<string, unknown>,\n): TraceAdapterLike | undefined => {\n const telemetry = isRecord(config.telemetry) ? config.telemetry : undefined;\n const traceAdapter = telemetry?.trace ?? config.reasonTrace;\n return isRecord(traceAdapter)\n ? (traceAdapter as TraceAdapterLike)\n : undefined;\n};\n\n/**\n * Orchestrates runtime execution with mid-stream transitions emitted by\n * runtime events.\n */\nexport async function orchestrateGraphStream({\n sessionId,\n runId,\n graph,\n state,\n config,\n selectWorkflow,\n frameworkAdapter,\n}: OrchestrateArgs): Promise<NodeJS.ReadableStream> {\n const out = new PassThrough({ objectMode: true });\n\n let currentGraph = graph;\n let currentState: GraphState = state;\n let finished = false;\n let structuredSeq = 0;\n const debugEnabled = Boolean((config as any)?.features?.tracing);\n const traceAdapter = getTraceAdapter(config);\n const contextMeta = isRecord(config.context) ? config.context : {};\n const telemetryConfig = isRecord(config.telemetry) ? config.telemetry : {};\n const runSpanArgs = {\n name: \"kortyx.run\",\n attributes: {\n ...(sessionId ? { sessionId } : {}),\n runId,\n workflowId: state.currentWorkflow,\n ...(typeof contextMeta.userId === \"string\"\n ? { userId: contextMeta.userId }\n : {}),\n ...(typeof contextMeta.tenantId === \"string\"\n ? { tenantId: contextMeta.tenantId }\n : {}),\n },\n telemetry: {\n metadata: {\n ...(isRecord(telemetryConfig.metadata) ? telemetryConfig.metadata : {}),\n ...contextMeta,\n },\n tags: Array.isArray(telemetryConfig.tags)\n ? telemetryConfig.tags\n : undefined,\n captureContent: telemetryConfig.captureContent,\n ...(typeof state.input === \"string\" ? { input: state.input } : {}),\n },\n };\n const namespacesUsed = new Set<string>();\n\n // Announce session id to clients so they can persist it\n try {\n const sid = (config as any)?.session?.id as string | undefined;\n if (sid && typeof sid === \"string\") {\n out.write({ type: \"session\", sessionId: sid } as any);\n }\n } catch {}\n\n // Pending transition captured from runtime transition events.\n const pending: { to: string | null; payload: Record<string, unknown> } = {\n to: null,\n payload: {},\n };\n\n // Bridge internal graph emits to our stream AND capture transitions\n let lastStatusMsg = \"\";\n let lastStatusAt = 0;\n let accumulatedOutput = \"\";\n let lastOutputSegmentId: string | undefined;\n const appendAccumulatedOutput = (\n payload: unknown,\n node: string,\n delta: string,\n ) => {\n const payloadObj = payload as {\n segmentId?: unknown;\n opId?: unknown;\n id?: unknown;\n };\n const opId =\n typeof payloadObj.opId === \"string\" && payloadObj.opId.length > 0\n ? payloadObj.opId\n : undefined;\n const segmentId =\n typeof payloadObj.segmentId === \"string\" &&\n payloadObj.segmentId.length > 0\n ? payloadObj.segmentId\n : undefined;\n const textStreamId =\n opId && segmentId\n ? `${opId}:${segmentId}`\n : segmentId ||\n opId ||\n (typeof payloadObj.id === \"string\" && payloadObj.id.length > 0\n ? payloadObj.id\n : undefined) ||\n node;\n\n if (\n textStreamId &&\n lastOutputSegmentId &&\n textStreamId !== lastOutputSegmentId &&\n accumulatedOutput.length > 0 &&\n !/\\s$/.test(accumulatedOutput) &&\n !/^\\s/.test(delta)\n ) {\n accumulatedOutput += \" \";\n }\n\n lastOutputSegmentId = textStreamId;\n accumulatedOutput += delta;\n };\n const nextStructuredStreamId = () => `${runId}:structured:${structuredSeq++}`;\n const runTraceEndArgs = () =>\n accumulatedOutput.length > 0\n ? { telemetry: { output: accumulatedOutput } }\n : undefined;\n\n // Capture interrupt payloads emitted by runtime hooks and forward them as\n // resumable interrupt chunks.\n interface HumanInputPayload {\n node?: string;\n workflow?: string;\n input?: {\n kind?: string;\n multiple?: boolean;\n question?: string;\n id?: string;\n schemaId?: string;\n schemaVersion?: string;\n meta?: Record<string, unknown>;\n options?: Array<{\n id: string;\n label: string;\n description?: string;\n value?: unknown;\n }>;\n };\n }\n // Track latest interrupt token for updating stored snapshot at end\n let pendingRecordToken: string | null = null;\n // Avoid emitting duplicate interrupt chunks in the same run.\n let wroteHumanInput = false;\n\n const pendingStore: PendingRequestStore | undefined =\n frameworkAdapter?.pendingRequests;\n const pendingTtlMs = frameworkAdapter?.ttlMs ?? 15 * 60 * 1000;\n\n const persistAndEmitInterrupt = async (\n payload: HumanInputPayload,\n ): Promise<void> => {\n if (wroteHumanInput) return;\n\n const token = makeResumeToken();\n const requestId = makeRequestId(\"human\");\n pendingRecordToken = token;\n const input = payload.input ?? {};\n const optionsList = Array.isArray(input.options) ? input.options : [];\n const kind = input.kind || (input.multiple ? \"multi-choice\" : \"choice\");\n const isText = kind === \"text\";\n\n const record: PendingRequestRecord = {\n token,\n requestId,\n sessionId,\n runId,\n workflow: payload.workflow || (currentState.currentWorkflow as string),\n node: payload.node || \"\",\n state: { ...(currentState as GraphState), awaitingHumanInput: true },\n schema: isText\n ? {\n kind: kind as any,\n multiple: Boolean(input.multiple),\n ...(input.question ? { question: input.question } : {}),\n ...(typeof input.id === \"string\" && input.id.length > 0\n ? { id: input.id }\n : {}),\n ...(typeof input.schemaId === \"string\" && input.schemaId.length > 0\n ? { schemaId: input.schemaId }\n : {}),\n ...(typeof input.schemaVersion === \"string\" &&\n input.schemaVersion.length > 0\n ? { schemaVersion: input.schemaVersion }\n : {}),\n ...(input.meta && typeof input.meta === \"object\"\n ? { meta: input.meta }\n : {}),\n }\n : {\n kind: kind as any,\n multiple: Boolean(input.multiple),\n question: String(input.question || \"Please choose an option.\"),\n ...(typeof input.id === \"string\" && input.id.length > 0\n ? { id: input.id }\n : {}),\n ...(typeof input.schemaId === \"string\" && input.schemaId.length > 0\n ? { schemaId: input.schemaId }\n : {}),\n ...(typeof input.schemaVersion === \"string\" &&\n input.schemaVersion.length > 0\n ? { schemaVersion: input.schemaVersion }\n : {}),\n ...(input.meta && typeof input.meta === \"object\"\n ? { meta: input.meta }\n : {}),\n },\n options: optionsList.map((option: any) => ({\n id: String(option.id),\n label: String(option.label),\n description:\n typeof option.description === \"string\"\n ? option.description\n : undefined,\n value: option.value,\n })),\n createdAt: Date.now(),\n ttlMs: pendingTtlMs,\n };\n\n if (pendingStore) {\n pendingStore.save(record).catch((error) => {\n // eslint-disable-next-line no-console\n console.error(\"[orchestrator] failed to save pending request\", error);\n });\n }\n\n const clientMeta =\n record.schema.meta &&\n typeof record.schema.meta === \"object\" &&\n !Array.isArray(record.schema.meta)\n ? Object.fromEntries(\n Object.entries(record.schema.meta).filter(\n ([key]) => !key.startsWith(\"__kortyx\"),\n ),\n )\n : undefined;\n\n out.write({\n type: \"interrupt\",\n requestId: record.requestId,\n resumeToken: record.token,\n workflow: record.workflow,\n node: record.node,\n ...(typeof record.schema.id === \"string\" && record.schema.id.length > 0\n ? { id: record.schema.id }\n : {}),\n ...(typeof record.schema.schemaId === \"string\" &&\n record.schema.schemaId.length > 0\n ? { schemaId: record.schema.schemaId }\n : {}),\n ...(typeof record.schema.schemaVersion === \"string\" &&\n record.schema.schemaVersion.length > 0\n ? { schemaVersion: record.schema.schemaVersion }\n : {}),\n input: {\n kind: record.schema.kind,\n multiple: record.schema.multiple,\n question: record.schema.question,\n ...(typeof record.schema.id === \"string\" && record.schema.id.length > 0\n ? { id: record.schema.id }\n : {}),\n ...(typeof record.schema.schemaId === \"string\" &&\n record.schema.schemaId.length > 0\n ? { schemaId: record.schema.schemaId }\n : {}),\n ...(typeof record.schema.schemaVersion === \"string\" &&\n record.schema.schemaVersion.length > 0\n ? { schemaVersion: record.schema.schemaVersion }\n : {}),\n ...(clientMeta && Object.keys(clientMeta).length > 0\n ? { meta: clientMeta }\n : {}),\n options: record.options.map((option) => ({\n id: option.id,\n label: option.label,\n description: option.description,\n })),\n },\n } as any);\n wroteHumanInput = true;\n };\n\n const forwardEmit = (event: string, payload: unknown) => {\n if (event === \"error\") {\n const msg = String(\n (payload as { message?: unknown })?.message ?? \"Unexpected error\",\n );\n out.write({ type: \"error\", message: msg });\n out.write({ type: \"done\" });\n finished = true;\n out.end();\n return;\n }\n if (event === \"status\") {\n if (!debugEnabled) return;\n const statusMessage = (\n payload as { message?: unknown } | null | undefined\n )?.message;\n const msg =\n statusMessage === null || statusMessage === undefined\n ? \"\"\n : String(statusMessage);\n const now = Date.now();\n if (msg && msg === lastStatusMsg && now - lastStatusAt < 250) return; // de-dupe rapid duplicates\n lastStatusMsg = msg;\n lastStatusAt = now;\n out.write({ type: \"status\", message: msg });\n return;\n }\n if (event === \"text-start\") {\n const node = (payload as { node?: string })?.node;\n if (!node) return;\n out.write({\n type: \"text-start\",\n node,\n ...(typeof (payload as { id?: string }).id === \"string\"\n ? { id: (payload as { id?: string }).id }\n : {}),\n ...(typeof (payload as { opId?: string }).opId === \"string\"\n ? { opId: (payload as { opId?: string }).opId }\n : {}),\n ...(typeof (payload as { segmentId?: string }).segmentId === \"string\"\n ? { segmentId: (payload as { segmentId?: string }).segmentId }\n : {}),\n });\n return;\n }\n if (event === \"text-delta\") {\n const node = (payload as { node?: string })?.node;\n const delta = String((payload as { delta?: unknown })?.delta ?? \"\");\n if (!node || !delta) return;\n appendAccumulatedOutput(payload, node, delta);\n out.write({\n type: \"text-delta\",\n delta,\n node,\n ...(typeof (payload as { id?: string }).id === \"string\"\n ? { id: (payload as { id?: string }).id }\n : {}),\n ...(typeof (payload as { opId?: string }).opId === \"string\"\n ? { opId: (payload as { opId?: string }).opId }\n : {}),\n ...(typeof (payload as { segmentId?: string }).segmentId === \"string\"\n ? { segmentId: (payload as { segmentId?: string }).segmentId }\n : {}),\n });\n return;\n }\n if (event === \"text-end\") {\n const node = (payload as { node?: string })?.node;\n if (!node) return;\n out.write({\n type: \"text-end\",\n node,\n ...(typeof (payload as { id?: string }).id === \"string\"\n ? { id: (payload as { id?: string }).id }\n : {}),\n ...(typeof (payload as { opId?: string }).opId === \"string\"\n ? { opId: (payload as { opId?: string }).opId }\n : {}),\n ...(typeof (payload as { segmentId?: string }).segmentId === \"string\"\n ? { segmentId: (payload as { segmentId?: string }).segmentId }\n : {}),\n });\n return;\n }\n if (event === \"tool-call-start\") {\n const payloadObj = payload as {\n tool?: unknown;\n toolCallId?: unknown;\n node?: string;\n id?: string;\n opId?: string;\n input?: unknown;\n };\n if (\n typeof payloadObj.tool !== \"string\" ||\n typeof payloadObj.toolCallId !== \"string\"\n ) {\n return;\n }\n out.write({\n type: \"tool-call-start\",\n tool: payloadObj.tool,\n toolCallId: payloadObj.toolCallId,\n ...(payloadObj.node ? { node: payloadObj.node } : {}),\n ...(payloadObj.id ? { id: payloadObj.id } : {}),\n ...(payloadObj.opId ? { opId: payloadObj.opId } : {}),\n ...(payloadObj.input !== undefined ? { input: payloadObj.input } : {}),\n });\n return;\n }\n if (event === \"tool-call-result\") {\n const payloadObj = payload as {\n tool?: unknown;\n toolCallId?: unknown;\n node?: string;\n id?: string;\n opId?: string;\n content?: unknown;\n structuredContent?: unknown;\n isError?: unknown;\n };\n if (\n typeof payloadObj.tool !== \"string\" ||\n typeof payloadObj.toolCallId !== \"string\"\n ) {\n return;\n }\n out.write({\n type: \"tool-call-result\",\n tool: payloadObj.tool,\n toolCallId: payloadObj.toolCallId,\n ...(payloadObj.node ? { node: payloadObj.node } : {}),\n ...(payloadObj.id ? { id: payloadObj.id } : {}),\n ...(payloadObj.opId ? { opId: payloadObj.opId } : {}),\n content: payloadObj.content,\n ...(payloadObj.structuredContent !== undefined\n ? { structuredContent: payloadObj.structuredContent }\n : {}),\n ...(typeof payloadObj.isError === \"boolean\"\n ? { isError: payloadObj.isError }\n : {}),\n });\n return;\n }\n if (event === \"tool-call-error\") {\n const payloadObj = payload as {\n tool?: unknown;\n toolCallId?: unknown;\n node?: string;\n id?: string;\n opId?: string;\n message?: unknown;\n };\n if (\n typeof payloadObj.tool !== \"string\" ||\n typeof payloadObj.toolCallId !== \"string\"\n ) {\n return;\n }\n out.write({\n type: \"tool-call-error\",\n tool: payloadObj.tool,\n toolCallId: payloadObj.toolCallId,\n ...(payloadObj.node ? { node: payloadObj.node } : {}),\n ...(payloadObj.id ? { id: payloadObj.id } : {}),\n ...(payloadObj.opId ? { opId: payloadObj.opId } : {}),\n message: String(payloadObj.message ?? \"\"),\n });\n return;\n }\n if (event === \"message\") {\n const node = (payload as { node?: string })?.node;\n const text = String((payload as { content?: unknown })?.content ?? \"\");\n out.write({ type: \"message\", node, content: text });\n return;\n }\n if (event === \"structured_data\") {\n const payloadObj = payload as {\n streamId?: string;\n dataType?: string;\n kind?: string;\n schemaId?: string;\n schemaVersion?: string;\n id?: string;\n node?: string;\n path?: string;\n value?: unknown;\n items?: unknown[];\n delta?: string;\n data?: unknown;\n };\n const kind =\n payloadObj.kind === \"set\" ||\n payloadObj.kind === \"append\" ||\n payloadObj.kind === \"text-delta\" ||\n payloadObj.kind === \"final\"\n ? payloadObj.kind\n : \"final\";\n\n out.write({\n type: \"structured-data\",\n node: payloadObj.node,\n streamId:\n typeof payloadObj.streamId === \"string\" && payloadObj.streamId\n ? payloadObj.streamId\n : nextStructuredStreamId(),\n dataType:\n typeof payloadObj.dataType === \"string\" && payloadObj.dataType\n ? payloadObj.dataType\n : \"generic\",\n kind,\n ...(typeof payloadObj.schemaId === \"string\"\n ? { schemaId: payloadObj.schemaId }\n : {}),\n ...(typeof payloadObj.schemaVersion === \"string\"\n ? { schemaVersion: payloadObj.schemaVersion }\n : {}),\n ...(typeof payloadObj.id === \"string\" ? { id: payloadObj.id } : {}),\n ...(kind === \"set\"\n ? {\n path: String(payloadObj.path ?? \"\"),\n value: payloadObj.value,\n }\n : {}),\n ...(kind === \"append\"\n ? {\n path: String(payloadObj.path ?? \"\"),\n items: Array.isArray(payloadObj.items) ? payloadObj.items : [],\n }\n : {}),\n ...(kind === \"text-delta\"\n ? {\n path: String(payloadObj.path ?? \"\"),\n delta: String(payloadObj.delta ?? \"\"),\n }\n : {}),\n ...(kind === \"final\" ? { data: payloadObj.data } : {}),\n });\n return;\n }\n // legacy 'human_required' removed โ dynamic interrupts are used instead\n if (event === \"transition\") {\n // 1) surface to the client (useful for dev tools)\n out.write({\n type: \"transition\",\n transitionTo: (payload as { transitionTo?: string })?.transitionTo,\n payload:\n (payload as { payload?: Record<string, unknown> })?.payload ?? {},\n });\n // 2) capture for orchestration\n pending.to = (payload as { transitionTo?: string })?.transitionTo ?? null;\n pending.payload =\n (payload as { payload?: Record<string, unknown> })?.payload ?? {};\n return;\n }\n if (event === \"interrupt\") {\n const p = payload as any;\n const local: HumanInputPayload = {\n node: p?.node,\n workflow: p?.workflow,\n input: p?.input,\n };\n void persistAndEmitInterrupt(local).catch((error) => {\n // eslint-disable-next-line no-console\n console.error(\"[orchestrator] failed to emit interrupt\", error);\n });\n return;\n }\n };\n\n const runLoop = async (runTraceSpan: TraceSpanLike) => {\n while (true) {\n let workflowFinalState: GraphState | null = null;\n\n // Ensure the compiled graph uses our forwardEmit\n currentGraph.config = currentGraph.config || {};\n currentGraph.config.emit = forwardEmit;\n const threadId =\n ((currentGraph.config as any)?.session?.id as string | undefined) ||\n sessionId ||\n \"anonymous-session\";\n const checkpointNs = String(currentState.currentWorkflow || \"default\");\n namespacesUsed.add(checkpointNs);\n if (debugEnabled) {\n out.write({\n type: \"status\",\n message: `๐งต thread_id=${threadId} run_id=${runId} workflow=${currentState.currentWorkflow}`,\n });\n }\n\n // Stream runtime events (LLM deltas, node starts/ends, etc.)\n const isResume = Boolean((currentGraph.config as any)?.resume);\n // For static breakpoints, resume with null input; if a resumeUpdate was provided,\n // use Command({ update }) to merge selection into state at resume time.\n const resumeUpdate = (currentGraph.config as any)?.resumeUpdate as\n | Record<string, unknown>\n | undefined;\n const resumeValue = (currentGraph.config as any)?.resumeValue as\n | unknown\n | undefined;\n const invokeState = isResume\n ? resumeValue !== undefined && resumeUpdate\n ? (new Command({ resume: resumeValue, update: resumeUpdate }) as any)\n : resumeValue !== undefined\n ? (new Command({ resume: resumeValue }) as any)\n : resumeUpdate\n ? (new Command({ update: resumeUpdate }) as any)\n : (null as any)\n : (currentState as any);\n const runtimeStream = currentGraph.streamEvents(invokeState, {\n version: \"v2\",\n configurable: {\n thread_id: runId,\n // Use a stable namespace so checkpoints survive across recompiles of same workflow\n checkpoint_ns: checkpointNs,\n },\n });\n\n if (debugEnabled) {\n out.write({\n type: \"status\",\n message: `โถ๏ธ streamEvents invoke: resume=${Boolean((currentGraph.config as any)?.resume)} thread_id=${threadId} run_id=${runId} ns=${String(currentState.currentWorkflow || \"default\")}`,\n } as any);\n }\n\n const uiStream = transformGraphStreamForUI(runtimeStream as any, {\n debug: debugEnabled,\n emitStatus: debugEnabled,\n });\n\n for await (const chunk of uiStream as AsyncIterable<StreamChunk>) {\n if (finished) break;\n out.write(chunk);\n\n if (chunk.type === \"done\") {\n workflowFinalState = (chunk.data as GraphState) ?? null;\n break;\n }\n }\n\n if (finished) return;\n\n const transitionTo = pending.to;\n const transitionPayload = pending.payload;\n\n // Reset pending so we don't carry it accidentally\n pending.to = null;\n pending.payload = {};\n\n if (transitionTo) {\n // ๐ Handoff to the next workflow\n try {\n const nextWorkflow = await selectWorkflow(transitionTo);\n const nextGraph = await createExecutionGraph(nextWorkflow, {\n ...(config as Record<string, unknown>),\n emit: forwardEmit, // keep forwarding emits\n });\n\n // Merge data: prefer the final state's data if present, then add transition payload\n const mergedData = {\n ...(workflowFinalState?.data ?? currentState.data ?? {}),\n ...transitionPayload,\n };\n\n const rawInputFromPayload = (\n transitionPayload as {\n rawInput?: unknown;\n }\n )?.rawInput;\n const newInput =\n typeof rawInputFromPayload === \"string\"\n ? rawInputFromPayload\n : currentState.input;\n\n currentState = {\n ...currentState,\n currentWorkflow: transitionTo as WorkflowId,\n input: newInput,\n data: mergedData,\n ui: {}, // reset UI layer on new graph\n };\n\n currentGraph = nextGraph;\n continue; // run the next graph\n } catch (err) {\n runTraceSpan.addEvent?.(\"kortyx.transition.error\", {\n transitionTo,\n });\n out.write({\n type: \"error\",\n message: `Transition failed to '${transitionTo}': ${\n err instanceof Error ? err.message : String(err)\n }`,\n });\n out.write({ type: \"done\" });\n out.end();\n return;\n }\n }\n\n // No transition โ either graph returned done or ended naturally\n if (workflowFinalState) {\n // If we paused for an interrupt, persist a pending request and emit an interrupt chunk\n // Attach final state to pending record if we have one\n if (workflowFinalState && pendingRecordToken) {\n if (pendingStore) {\n await pendingStore.update(pendingRecordToken, {\n state: workflowFinalState,\n });\n }\n }\n\n const shouldKeepFrameworkState =\n Boolean(pendingRecordToken) ||\n Boolean((workflowFinalState as any)?.awaitingHumanInput);\n if (!shouldKeepFrameworkState) {\n // Best-effort cleanup: completed runs don't need to retain checkpoints.\n try {\n if (frameworkAdapter?.cleanupRun) {\n await frameworkAdapter.cleanupRun(\n runId,\n Array.from(namespacesUsed),\n );\n } else {\n const cp = (currentGraph.config as any)\n ?.checkpointer as unknown as {\n deleteThread?: (id: string) => any;\n };\n if (cp?.deleteThread) {\n await cp.deleteThread(runId);\n }\n }\n } catch (e) {\n // eslint-disable-next-line no-console\n console.error(\"[orchestrator] framework cleanup failed\", e);\n }\n }\n\n finished = true;\n runTraceSpan.setAttributes?.({\n \"kortyx.run.awaiting_human_input\": shouldKeepFrameworkState,\n \"kortyx.run.final_workflow\": String(currentState.currentWorkflow),\n });\n runTraceSpan.end?.(runTraceEndArgs());\n out.write({ type: \"done\", data: workflowFinalState } as any);\n out.end();\n return;\n }\n\n // Natural end with no explicit \"done\" (defensive close)\n runTraceSpan.setAttributes?.({\n \"kortyx.run.final_workflow\": String(currentState.currentWorkflow),\n });\n runTraceSpan.end?.(runTraceEndArgs());\n out.write({ type: \"done\" });\n out.end();\n return;\n }\n };\n\n const emitTraceChunk = () => {\n const traceContext = traceAdapter?.getActiveContext?.();\n if (!traceContext) return;\n\n out.write({\n type: \"trace\",\n traceId: traceContext.traceId,\n spanId: traceContext.spanId,\n runId,\n rootSpanName: \"kortyx.run\",\n } satisfies StreamChunk);\n };\n\n const fallbackRunSpan = traceAdapter?.withSpan\n ? undefined\n : traceAdapter?.startSpan?.(runSpanArgs);\n if (!traceAdapter?.withSpan) {\n emitTraceChunk();\n }\n const runPromise = traceAdapter?.withSpan\n ? traceAdapter.withSpan(runSpanArgs, (runTraceSpan) => {\n emitTraceChunk();\n return runLoop(runTraceSpan);\n })\n : runLoop(fallbackRunSpan ?? {});\n\n runPromise.catch((err) => {\n fallbackRunSpan?.fail?.(err);\n console.error(\"[error:orchestrateGraphStream]\", err);\n out.write({\n type: \"error\",\n message: err instanceof Error ? err.message : String(err),\n });\n out.write({ type: \"done\" });\n out.end();\n });\n\n return out;\n}\n","import type { StreamChunk } from \"@kortyx/stream\";\nimport type { StreamEvent } from \"@langchain/core/tracers/log_stream\";\n\ninterface TransformOptions {\n debug?: boolean;\n emitStatus?: boolean;\n}\n\n/**\n * Transforms runtime stream events into standardized UI chunks.\n * Runtime emits (`message`, `structured_data`, `interrupt`, `transition`) are\n * forwarded directly by the orchestrator, so this transformer only handles\n * graph lifecycle + completion signals.\n */\nexport async function* transformGraphStreamForUI(\n stream: AsyncIterable<StreamEvent>,\n options: TransformOptions = {},\n): AsyncGenerator<StreamChunk> {\n const { debug = false, emitStatus = debug } = options;\n const startedNodes = new Set<string>();\n const endedNodes = new Set<string>();\n\n for await (const event of stream) {\n const { event: type, name, data } = event ?? {};\n if (debug) console.log(`[debug:event]`, JSON.stringify(event, null, 2));\n\n switch (type) {\n case \"on_chain_start\":\n if (name && !name.startsWith(\"ChannelWrite\")) {\n if (name === \"__start__\" || name === \"__end__\") break;\n if (startedNodes.has(name)) break; // de-dupe\n startedNodes.add(name);\n if (debug) console.log(`[debug:start] node=${name}`);\n if (emitStatus) {\n yield { type: \"status\", message: `Processing node: ${name}` };\n }\n }\n break;\n\n case \"on_chain_end\": {\n const nodeName = name;\n const output = data?.output;\n if (debug)\n console.log(\n `[debug:on_chain_end:${nodeName}] output=`,\n JSON.stringify(output, null, 2),\n );\n if (!output || nodeName?.startsWith(\"ChannelWrite\")) break;\n\n // Emit a simple completion status for UI progress feedback (de-dupe + skip internal nodes)\n if (nodeName !== \"__start__\" && nodeName !== \"__end__\") {\n if (!endedNodes.has(nodeName)) {\n if (emitStatus) {\n yield {\n type: \"status\",\n message: `โ
Completed node: ${nodeName}`,\n };\n }\n endedNodes.add(nodeName);\n }\n }\n break;\n }\n\n case \"on_graph_end\": {\n if (debug)\n console.log(`[debug:on_graph_end]`, JSON.stringify(data, null, 2));\n yield { type: \"done\", data: (data as any)?.output ?? null };\n break;\n }\n\n default:\n if (debug) {\n console.warn(`[debug:unknown_event]`, type);\n }\n break;\n }\n }\n}\n","import type { ChatMessage } from \"../types/chat-message\";\n\nexport function extractLatestUserMessage(messages: ChatMessage[]): string {\n if (!messages || messages.length === 0) return \"\";\n // Find last message with role = \"user\"\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n const msg = messages[i];\n if (msg?.role === \"user\" && msg?.content?.trim()) {\n return msg.content.trim();\n }\n }\n return \"\";\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,oBAA6C;AAC7C,iBAAkB;AAYlB,IAAM,oBAAoB,aACvB,OAAO;AAAA,EACN,MAAM,aAAE,KAAK,CAAC,QAAQ,aAAa,QAAQ,CAAC;AAAA,EAC5C,SAAS,aAAE,OAAO;AAAA,EAClB,UAAU,aAAE,OAAO,aAAE,OAAO,GAAG,aAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,EACrD,IAAI,aAAE,OAAO,EAAE,SAAS;AAAA,EACxB,WAAW,aAAE,OAAO,EAAE,OAAO,OAAO,QAAQ,EAAE,SAAS;AACzD,CAAC,EACA,OAAO;AAEV,IAAM,wBAAwB,aAAE,YAAY;AAAA,EAC1C,WAAW,aAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,YAAY,aAAE,OAAO,EAAE,SAAS;AAAA,EAChC,QAAQ,aAAE,QAAQ,EAAE,SAAS;AAAA,EAC7B,SAAS,aAAE,OAAO,aAAE,OAAO,GAAG,aAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,EACpD,UAAU,aAAE,MAAM,iBAAiB;AACrC,CAAC;AAED,IAAM,iBAAiB,CAAC,UACtB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAEhD,SAAS,qBAAqB,OAAiC;AACpE,QAAM,SAAS,sBAAsB,UAAU,KAAK;AACpD,MAAI,CAAC,OAAO,SAAS;AACnB,UAAM,CAAC,UAAU,IAAI,OAAO,MAAM;AAIlC,UAAM,IAAI,MAAM,WAAW,OAAO;AAAA,EACpC;AAEA,QAAM,YAAY,OAAO,KAAK,WAAW,KAAK;AAC9C,QAAM,aAAa,OAAO,KAAK,YAAY,KAAK;AAEhD,SAAO;AAAA,IACL,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;AAAA,IACjC,GAAI,aAAa,EAAE,WAAW,IAAI,CAAC;AAAA,IACnC,GAAI,OAAO,OAAO,KAAK,WAAW,YAC9B,EAAE,QAAQ,OAAO,KAAK,OAAO,IAC7B,CAAC;AAAA,IACL,GAAI,OAAO,KAAK,UAAU,EAAE,SAAS,OAAO,KAAK,QAAQ,IAAI,CAAC;AAAA,IAC9D,UAAU,OAAO,KAAK;AAAA,EACxB;AACF;AAEA,eAAsB,sBAAsB,MAGtB;AACpB,QAAM,EAAE,OAAO,KAAK,IAAI;AACxB,QAAM,SAAS,MAAM,MAAM,WAAW,KAAK,UAAU;AAAA,IACnD,WAAW,KAAK;AAAA,IAChB,YAAY,KAAK;AAAA,IACjB,SAAS,KAAK;AAAA,EAChB,CAAC;AAED,MAAI,KAAK,WAAW,OAAO;AACzB,UAAM,WAAW,UAAM,qCAAsB,MAAM;AACnD,WAAO,IAAI,SAAS,KAAK,UAAU,QAAQ,GAAG;AAAA,MAC5C,SAAS;AAAA,QACP,gBAAgB;AAAA,MAClB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,aAAO,qBAAM,MAAM;AACrB;AAEO,SAAS,uBAAuB,MAGK;AAC1C,QAAM,EAAE,OAAO,cAAc,IAAI,IAAI;AAErC,SAAO,eAAe,KAAK,SAAqC;AAC9D,QAAI;AACF,YAAM,OAAO,qBAAqB,MAAM,QAAQ,KAAK,CAAC;AACtD,aAAO,MAAM,sBAAsB,EAAE,OAAO,KAAK,CAAC;AAAA,IACpD,SAAS,OAAO;AACd,aAAO,IAAI;AAAA,QACT,KAAK,UAAU;AAAA,UACb,OAAO,eAAe,KAAK;AAAA,QAC7B,CAAC;AAAA,QACD;AAAA,UACE,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,gBAAgB;AAAA,UAClB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACzGA,qBAAkD;AAYlD,gBAAuB,oBACrB,MACyC;AACzC,aAAO,gCAAgB;AAAA,IACrB,UAAU,KAAK;AAAA,IACf,GAAI,KAAK,YAAY,EAAE,WAAW,KAAK,UAAU,IAAI,CAAC;AAAA,IACtD,GAAI,KAAK,UAAU,EAAE,SAAS,KAAK,QAAQ,IAAI,CAAC;AAAA,IAChD,MAAM;AAAA,MACJ,WAAW,KAAK;AAAA,MAChB,YAAY,KAAK;AAAA,MACjB,UAAU,KAAK;AAAA,IACjB;AAAA,EACF,CAAC;AACH;;;ACzBA,uBAAwB;AAExB,uBAGO;AAMP,IAAAA,kBAIO;AAEP,IAAAC,cAAkB;;;ACdlB,IAAAC,kBAIO;;;ACDP,IAAAC,kBAAqC;;;ACNrC,yBAA4B;AAE5B,qBAOO;AAEP,uBAAwB;;;ACGxB,gBAAuB,0BACrB,QACA,UAA4B,CAAC,GACA;AAC7B,QAAM,EAAE,QAAQ,OAAO,aAAa,MAAM,IAAI;AAC9C,QAAM,eAAe,oBAAI,IAAY;AACrC,QAAM,aAAa,oBAAI,IAAY;AAEnC,mBAAiB,SAAS,QAAQ;AAChC,UAAM,EAAE,OAAO,MAAM,MAAM,KAAK,IAAI,SAAS,CAAC;AAC9C,QAAI,MAAO,SAAQ,IAAI,iBAAiB,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;AAEtE,YAAQ,MAAM;AAAA,MACZ,KAAK;AACH,YAAI,QAAQ,CAAC,KAAK,WAAW,cAAc,GAAG;AAC5C,cAAI,SAAS,eAAe,SAAS,UAAW;AAChD,cAAI,aAAa,IAAI,IAAI,EAAG;AAC5B,uBAAa,IAAI,IAAI;AACrB,cAAI,MAAO,SAAQ,IAAI,sBAAsB,IAAI,EAAE;AACnD,cAAI,YAAY;AACd,kBAAM,EAAE,MAAM,UAAU,SAAS,oBAAoB,IAAI,GAAG;AAAA,UAC9D;AAAA,QACF;AACA;AAAA,MAEF,KAAK,gBAAgB;AACnB,cAAM,WAAW;AACjB,cAAM,SAAS,MAAM;AACrB,YAAI;AACF,kBAAQ;AAAA,YACN,uBAAuB,QAAQ;AAAA,YAC/B,KAAK,UAAU,QAAQ,MAAM,CAAC;AAAA,UAChC;AACF,YAAI,CAAC,UAAU,UAAU,WAAW,cAAc,EAAG;AAGrD,YAAI,aAAa,eAAe,aAAa,WAAW;AACtD,cAAI,CAAC,WAAW,IAAI,QAAQ,GAAG;AAC7B,gBAAI,YAAY;AACd,oBAAM;AAAA,gBACJ,MAAM;AAAA,gBACN,SAAS,0BAAqB,QAAQ;AAAA,cACxC;AAAA,YACF;AACA,uBAAW,IAAI,QAAQ;AAAA,UACzB;AAAA,QACF;AACA;AAAA,MACF;AAAA,MAEA,KAAK,gBAAgB;AACnB,YAAI;AACF,kBAAQ,IAAI,wBAAwB,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;AACnE,cAAM,EAAE,MAAM,QAAQ,MAAO,MAAc,UAAU,KAAK;AAC1D;AAAA,MACF;AAAA,MAEA;AACE,YAAI,OAAO;AACT,kBAAQ,KAAK,yBAAyB,IAAI;AAAA,QAC5C;AACA;AAAA,IACJ;AAAA,EACF;AACF;;;ADCA,IAAM,WAAW,CAAC,UAChB,QAAQ,KAAK,KAAK,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AAErE,IAAM,kBAAkB,CACtB,WACiC;AACjC,QAAM,YAAY,SAAS,OAAO,SAAS,IAAI,OAAO,YAAY;AAClE,QAAM,eAAe,WAAW,SAAS,OAAO;AAChD,SAAO,SAAS,YAAY,IACvB,eACD;AACN;AAMA,eAAsB,uBAAuB;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAoD;AAClD,QAAM,MAAM,IAAI,+BAAY,EAAE,YAAY,KAAK,CAAC;AAEhD,MAAI,eAAe;AACnB,MAAI,eAA2B;AAC/B,MAAI,WAAW;AACf,MAAI,gBAAgB;AACpB,QAAM,eAAe,QAAS,QAAgB,UAAU,OAAO;AAC/D,QAAM,eAAe,gBAAgB,MAAM;AAC3C,QAAM,cAAc,SAAS,OAAO,OAAO,IAAI,OAAO,UAAU,CAAC;AACjE,QAAM,kBAAkB,SAAS,OAAO,SAAS,IAAI,OAAO,YAAY,CAAC;AACzE,QAAM,cAAc;AAAA,IAClB,MAAM;AAAA,IACN,YAAY;AAAA,MACV,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;AAAA,MACjC;AAAA,MACA,YAAY,MAAM;AAAA,MAClB,GAAI,OAAO,YAAY,WAAW,WAC9B,EAAE,QAAQ,YAAY,OAAO,IAC7B,CAAC;AAAA,MACL,GAAI,OAAO,YAAY,aAAa,WAChC,EAAE,UAAU,YAAY,SAAS,IACjC,CAAC;AAAA,IACP;AAAA,IACA,WAAW;AAAA,MACT,UAAU;AAAA,QACR,GAAI,SAAS,gBAAgB,QAAQ,IAAI,gBAAgB,WAAW,CAAC;AAAA,QACrE,GAAG;AAAA,MACL;AAAA,MACA,MAAM,MAAM,QAAQ,gBAAgB,IAAI,IACpC,gBAAgB,OAChB;AAAA,MACJ,gBAAgB,gBAAgB;AAAA,MAChC,GAAI,OAAO,MAAM,UAAU,WAAW,EAAE,OAAO,MAAM,MAAM,IAAI,CAAC;AAAA,IAClE;AAAA,EACF;AACA,QAAM,iBAAiB,oBAAI,IAAY;AAGvC,MAAI;AACF,UAAM,MAAO,QAAgB,SAAS;AACtC,QAAI,OAAO,OAAO,QAAQ,UAAU;AAClC,UAAI,MAAM,EAAE,MAAM,WAAW,WAAW,IAAI,CAAQ;AAAA,IACtD;AAAA,EACF,QAAQ;AAAA,EAAC;AAGT,QAAM,UAAmE;AAAA,IACvE,IAAI;AAAA,IACJ,SAAS,CAAC;AAAA,EACZ;AAGA,MAAI,gBAAgB;AACpB,MAAI,eAAe;AACnB,MAAI,oBAAoB;AACxB,MAAI;AACJ,QAAM,0BAA0B,CAC9B,SACA,MACA,UACG;AACH,UAAM,aAAa;AAKnB,UAAM,OACJ,OAAO,WAAW,SAAS,YAAY,WAAW,KAAK,SAAS,IAC5D,WAAW,OACX;AACN,UAAM,YACJ,OAAO,WAAW,cAAc,YAChC,WAAW,UAAU,SAAS,IAC1B,WAAW,YACX;AACN,UAAM,eACJ,QAAQ,YACJ,GAAG,IAAI,IAAI,SAAS,KACpB,aACA,SACC,OAAO,WAAW,OAAO,YAAY,WAAW,GAAG,SAAS,IACzD,WAAW,KACX,WACJ;AAEN,QACE,gBACA,uBACA,iBAAiB,uBACjB,kBAAkB,SAAS,KAC3B,CAAC,MAAM,KAAK,iBAAiB,KAC7B,CAAC,MAAM,KAAK,KAAK,GACjB;AACA,2BAAqB;AAAA,IACvB;AAEA,0BAAsB;AACtB,yBAAqB;AAAA,EACvB;AACA,QAAM,yBAAyB,MAAM,GAAG,KAAK,eAAe,eAAe;AAC3E,QAAM,kBAAkB,MACtB,kBAAkB,SAAS,IACvB,EAAE,WAAW,EAAE,QAAQ,kBAAkB,EAAE,IAC3C;AAwBN,MAAI,qBAAoC;AAExC,MAAI,kBAAkB;AAEtB,QAAM,eACJ,kBAAkB;AACpB,QAAM,eAAe,kBAAkB,SAAS,KAAK,KAAK;AAE1D,QAAM,0BAA0B,OAC9B,YACkB;AAClB,QAAI,gBAAiB;AAErB,UAAM,YAAQ,gCAAgB;AAC9B,UAAM,gBAAY,8BAAc,OAAO;AACvC,yBAAqB;AACrB,UAAM,QAAQ,QAAQ,SAAS,CAAC;AAChC,UAAM,cAAc,MAAM,QAAQ,MAAM,OAAO,IAAI,MAAM,UAAU,CAAC;AACpE,UAAM,OAAO,MAAM,SAAS,MAAM,WAAW,iBAAiB;AAC9D,UAAM,SAAS,SAAS;AAExB,UAAM,SAA+B;AAAA,MACnC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU,QAAQ,YAAa,aAAa;AAAA,MAC5C,MAAM,QAAQ,QAAQ;AAAA,MACtB,OAAO,EAAE,GAAI,cAA6B,oBAAoB,KAAK;AAAA,MACnE,QAAQ,SACJ;AAAA,QACE;AAAA,QACA,UAAU,QAAQ,MAAM,QAAQ;AAAA,QAChC,GAAI,MAAM,WAAW,EAAE,UAAU,MAAM,SAAS,IAAI,CAAC;AAAA,QACrD,GAAI,OAAO,MAAM,OAAO,YAAY,MAAM,GAAG,SAAS,IAClD,EAAE,IAAI,MAAM,GAAG,IACf,CAAC;AAAA,QACL,GAAI,OAAO,MAAM,aAAa,YAAY,MAAM,SAAS,SAAS,IAC9D,EAAE,UAAU,MAAM,SAAS,IAC3B,CAAC;AAAA,QACL,GAAI,OAAO,MAAM,kBAAkB,YACnC,MAAM,cAAc,SAAS,IACzB,EAAE,eAAe,MAAM,cAAc,IACrC,CAAC;AAAA,QACL,GAAI,MAAM,QAAQ,OAAO,MAAM,SAAS,WACpC,EAAE,MAAM,MAAM,KAAK,IACnB,CAAC;AAAA,MACP,IACA;AAAA,QACE;AAAA,QACA,UAAU,QAAQ,MAAM,QAAQ;AAAA,QAChC,UAAU,OAAO,MAAM,YAAY,0BAA0B;AAAA,QAC7D,GAAI,OAAO,MAAM,OAAO,YAAY,MAAM,GAAG,SAAS,IAClD,EAAE,IAAI,MAAM,GAAG,IACf,CAAC;AAAA,QACL,GAAI,OAAO,MAAM,aAAa,YAAY,MAAM,SAAS,SAAS,IAC9D,EAAE,UAAU,MAAM,SAAS,IAC3B,CAAC;AAAA,QACL,GAAI,OAAO,MAAM,kBAAkB,YACnC,MAAM,cAAc,SAAS,IACzB,EAAE,eAAe,MAAM,cAAc,IACrC,CAAC;AAAA,QACL,GAAI,MAAM,QAAQ,OAAO,MAAM,SAAS,WACpC,EAAE,MAAM,MAAM,KAAK,IACnB,CAAC;AAAA,MACP;AAAA,MACJ,SAAS,YAAY,IAAI,CAAC,YAAiB;AAAA,QACzC,IAAI,OAAO,OAAO,EAAE;AAAA,QACpB,OAAO,OAAO,OAAO,KAAK;AAAA,QAC1B,aACE,OAAO,OAAO,gBAAgB,WAC1B,OAAO,cACP;AAAA,QACN,OAAO,OAAO;AAAA,MAChB,EAAE;AAAA,MACF,WAAW,KAAK,IAAI;AAAA,MACpB,OAAO;AAAA,IACT;AAEA,QAAI,cAAc;AAChB,mBAAa,KAAK,MAAM,EAAE,MAAM,CAAC,UAAU;AAEzC,gBAAQ,MAAM,iDAAiD,KAAK;AAAA,MACtE,CAAC;AAAA,IACH;AAEA,UAAM,aACJ,OAAO,OAAO,QACd,OAAO,OAAO,OAAO,SAAS,YAC9B,CAAC,MAAM,QAAQ,OAAO,OAAO,IAAI,IAC7B,OAAO;AAAA,MACL,OAAO,QAAQ,OAAO,OAAO,IAAI,EAAE;AAAA,QACjC,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,WAAW,UAAU;AAAA,MACvC;AAAA,IACF,IACA;AAEN,QAAI,MAAM;AAAA,MACR,MAAM;AAAA,MACN,WAAW,OAAO;AAAA,MAClB,aAAa,OAAO;AAAA,MACpB,UAAU,OAAO;AAAA,MACjB,MAAM,OAAO;AAAA,MACb,GAAI,OAAO,OAAO,OAAO,OAAO,YAAY,OAAO,OAAO,GAAG,SAAS,IAClE,EAAE,IAAI,OAAO,OAAO,GAAG,IACvB,CAAC;AAAA,MACL,GAAI,OAAO,OAAO,OAAO,aAAa,YACtC,OAAO,OAAO,SAAS,SAAS,IAC5B,EAAE,UAAU,OAAO,OAAO,SAAS,IACnC,CAAC;AAAA,MACL,GAAI,OAAO,OAAO,OAAO,kBAAkB,YAC3C,OAAO,OAAO,cAAc,SAAS,IACjC,EAAE,eAAe,OAAO,OAAO,cAAc,IAC7C,CAAC;AAAA,MACL,OAAO;AAAA,QACL,MAAM,OAAO,OAAO;AAAA,QACpB,UAAU,OAAO,OAAO;AAAA,QACxB,UAAU,OAAO,OAAO;AAAA,QACxB,GAAI,OAAO,OAAO,OAAO,OAAO,YAAY,OAAO,OAAO,GAAG,SAAS,IAClE,EAAE,IAAI,OAAO,OAAO,GAAG,IACvB,CAAC;AAAA,QACL,GAAI,OAAO,OAAO,OAAO,aAAa,YACtC,OAAO,OAAO,SAAS,SAAS,IAC5B,EAAE,UAAU,OAAO,OAAO,SAAS,IACnC,CAAC;AAAA,QACL,GAAI,OAAO,OAAO,OAAO,kBAAkB,YAC3C,OAAO,OAAO,cAAc,SAAS,IACjC,EAAE,eAAe,OAAO,OAAO,cAAc,IAC7C,CAAC;AAAA,QACL,GAAI,cAAc,OAAO,KAAK,UAAU,EAAE,SAAS,IAC/C,EAAE,MAAM,WAAW,IACnB,CAAC;AAAA,QACL,SAAS,OAAO,QAAQ,IAAI,CAAC,YAAY;AAAA,UACvC,IAAI,OAAO;AAAA,UACX,OAAO,OAAO;AAAA,UACd,aAAa,OAAO;AAAA,QACtB,EAAE;AAAA,MACJ;AAAA,IACF,CAAQ;AACR,sBAAkB;AAAA,EACpB;AAEA,QAAM,cAAc,CAAC,OAAe,YAAqB;AACvD,QAAI,UAAU,SAAS;AACrB,YAAM,MAAM;AAAA,QACT,SAAmC,WAAW;AAAA,MACjD;AACA,UAAI,MAAM,EAAE,MAAM,SAAS,SAAS,IAAI,CAAC;AACzC,UAAI,MAAM,EAAE,MAAM,OAAO,CAAC;AAC1B,iBAAW;AACX,UAAI,IAAI;AACR;AAAA,IACF;AACA,QAAI,UAAU,UAAU;AACtB,UAAI,CAAC,aAAc;AACnB,YAAM,gBACJ,SACC;AACH,YAAM,MACJ,kBAAkB,QAAQ,kBAAkB,SACxC,KACA,OAAO,aAAa;AAC1B,YAAM,MAAM,KAAK,IAAI;AACrB,UAAI,OAAO,QAAQ,iBAAiB,MAAM,eAAe,IAAK;AAC9D,sBAAgB;AAChB,qBAAe;AACf,UAAI,MAAM,EAAE,MAAM,UAAU,SAAS,IAAI,CAAC;AAC1C;AAAA,IACF;AACA,QAAI,UAAU,cAAc;AAC1B,YAAM,OAAQ,SAA+B;AAC7C,UAAI,CAAC,KAAM;AACX,UAAI,MAAM;AAAA,QACR,MAAM;AAAA,QACN;AAAA,QACA,GAAI,OAAQ,QAA4B,OAAO,WAC3C,EAAE,IAAK,QAA4B,GAAG,IACtC,CAAC;AAAA,QACL,GAAI,OAAQ,QAA8B,SAAS,WAC/C,EAAE,MAAO,QAA8B,KAAK,IAC5C,CAAC;AAAA,QACL,GAAI,OAAQ,QAAmC,cAAc,WACzD,EAAE,WAAY,QAAmC,UAAU,IAC3D,CAAC;AAAA,MACP,CAAC;AACD;AAAA,IACF;AACA,QAAI,UAAU,cAAc;AAC1B,YAAM,OAAQ,SAA+B;AAC7C,YAAM,QAAQ,OAAQ,SAAiC,SAAS,EAAE;AAClE,UAAI,CAAC,QAAQ,CAAC,MAAO;AACrB,8BAAwB,SAAS,MAAM,KAAK;AAC5C,UAAI,MAAM;AAAA,QACR,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA,GAAI,OAAQ,QAA4B,OAAO,WAC3C,EAAE,IAAK,QAA4B,GAAG,IACtC,CAAC;AAAA,QACL,GAAI,OAAQ,QAA8B,SAAS,WAC/C,EAAE,MAAO,QAA8B,KAAK,IAC5C,CAAC;AAAA,QACL,GAAI,OAAQ,QAAmC,cAAc,WACzD,EAAE,WAAY,QAAmC,UAAU,IAC3D,CAAC;AAAA,MACP,CAAC;AACD;AAAA,IACF;AACA,QAAI,UAAU,YAAY;AACxB,YAAM,OAAQ,SAA+B;AAC7C,UAAI,CAAC,KAAM;AACX,UAAI,MAAM;AAAA,QACR,MAAM;AAAA,QACN;AAAA,QACA,GAAI,OAAQ,QAA4B,OAAO,WAC3C,EAAE,IAAK,QAA4B,GAAG,IACtC,CAAC;AAAA,QACL,GAAI,OAAQ,QAA8B,SAAS,WAC/C,EAAE,MAAO,QAA8B,KAAK,IAC5C,CAAC;AAAA,QACL,GAAI,OAAQ,QAAmC,cAAc,WACzD,EAAE,WAAY,QAAmC,UAAU,IAC3D,CAAC;AAAA,MACP,CAAC;AACD;AAAA,IACF;AACA,QAAI,UAAU,mBAAmB;AAC/B,YAAM,aAAa;AAQnB,UACE,OAAO,WAAW,SAAS,YAC3B,OAAO,WAAW,eAAe,UACjC;AACA;AAAA,MACF;AACA,UAAI,MAAM;AAAA,QACR,MAAM;AAAA,QACN,MAAM,WAAW;AAAA,QACjB,YAAY,WAAW;AAAA,QACvB,GAAI,WAAW,OAAO,EAAE,MAAM,WAAW,KAAK,IAAI,CAAC;AAAA,QACnD,GAAI,WAAW,KAAK,EAAE,IAAI,WAAW,GAAG,IAAI,CAAC;AAAA,QAC7C,GAAI,WAAW,OAAO,EAAE,MAAM,WAAW,KAAK,IAAI,CAAC;AAAA,QACnD,GAAI,WAAW,UAAU,SAAY,EAAE,OAAO,WAAW,MAAM,IAAI,CAAC;AAAA,MACtE,CAAC;AACD;AAAA,IACF;AACA,QAAI,UAAU,oBAAoB;AAChC,YAAM,aAAa;AAUnB,UACE,OAAO,WAAW,SAAS,YAC3B,OAAO,WAAW,eAAe,UACjC;AACA;AAAA,MACF;AACA,UAAI,MAAM;AAAA,QACR,MAAM;AAAA,QACN,MAAM,WAAW;AAAA,QACjB,YAAY,WAAW;AAAA,QACvB,GAAI,WAAW,OAAO,EAAE,MAAM,WAAW,KAAK,IAAI,CAAC;AAAA,QACnD,GAAI,WAAW,KAAK,EAAE,IAAI,WAAW,GAAG,IAAI,CAAC;AAAA,QAC7C,GAAI,WAAW,OAAO,EAAE,MAAM,WAAW,KAAK,IAAI,CAAC;AAAA,QACnD,SAAS,WAAW;AAAA,QACpB,GAAI,WAAW,sBAAsB,SACjC,EAAE,mBAAmB,WAAW,kBAAkB,IAClD,CAAC;AAAA,QACL,GAAI,OAAO,WAAW,YAAY,YAC9B,EAAE,SAAS,WAAW,QAAQ,IAC9B,CAAC;AAAA,MACP,CAAC;AACD;AAAA,IACF;AACA,QAAI,UAAU,mBAAmB;AAC/B,YAAM,aAAa;AAQnB,UACE,OAAO,WAAW,SAAS,YAC3B,OAAO,WAAW,eAAe,UACjC;AACA;AAAA,MACF;AACA,UAAI,MAAM;AAAA,QACR,MAAM;AAAA,QACN,MAAM,WAAW;AAAA,QACjB,YAAY,WAAW;AAAA,QACvB,GAAI,WAAW,OAAO,EAAE,MAAM,WAAW,KAAK,IAAI,CAAC;AAAA,QACnD,GAAI,WAAW,KAAK,EAAE,IAAI,WAAW,GAAG,IAAI,CAAC;AAAA,QAC7C,GAAI,WAAW,OAAO,EAAE,MAAM,WAAW,KAAK,IAAI,CAAC;AAAA,QACnD,SAAS,OAAO,WAAW,WAAW,EAAE;AAAA,MAC1C,CAAC;AACD;AAAA,IACF;AACA,QAAI,UAAU,WAAW;AACvB,YAAM,OAAQ,SAA+B;AAC7C,YAAM,OAAO,OAAQ,SAAmC,WAAW,EAAE;AACrE,UAAI,MAAM,EAAE,MAAM,WAAW,MAAM,SAAS,KAAK,CAAC;AAClD;AAAA,IACF;AACA,QAAI,UAAU,mBAAmB;AAC/B,YAAM,aAAa;AAcnB,YAAM,OACJ,WAAW,SAAS,SACpB,WAAW,SAAS,YACpB,WAAW,SAAS,gBACpB,WAAW,SAAS,UAChB,WAAW,OACX;AAEN,UAAI,MAAM;AAAA,QACR,MAAM;AAAA,QACN,MAAM,WAAW;AAAA,QACjB,UACE,OAAO,WAAW,aAAa,YAAY,WAAW,WAClD,WAAW,WACX,uBAAuB;AAAA,QAC7B,UACE,OAAO,WAAW,aAAa,YAAY,WAAW,WAClD,WAAW,WACX;AAAA,QACN;AAAA,QACA,GAAI,OAAO,WAAW,aAAa,WAC/B,EAAE,UAAU,WAAW,SAAS,IAChC,CAAC;AAAA,QACL,GAAI,OAAO,WAAW,kBAAkB,WACpC,EAAE,eAAe,WAAW,cAAc,IAC1C,CAAC;AAAA,QACL,GAAI,OAAO,WAAW,OAAO,WAAW,EAAE,IAAI,WAAW,GAAG,IAAI,CAAC;AAAA,QACjE,GAAI,SAAS,QACT;AAAA,UACE,MAAM,OAAO,WAAW,QAAQ,EAAE;AAAA,UAClC,OAAO,WAAW;AAAA,QACpB,IACA,CAAC;AAAA,QACL,GAAI,SAAS,WACT;AAAA,UACE,MAAM,OAAO,WAAW,QAAQ,EAAE;AAAA,UAClC,OAAO,MAAM,QAAQ,WAAW,KAAK,IAAI,WAAW,QAAQ,CAAC;AAAA,QAC/D,IACA,CAAC;AAAA,QACL,GAAI,SAAS,eACT;AAAA,UACE,MAAM,OAAO,WAAW,QAAQ,EAAE;AAAA,UAClC,OAAO,OAAO,WAAW,SAAS,EAAE;AAAA,QACtC,IACA,CAAC;AAAA,QACL,GAAI,SAAS,UAAU,EAAE,MAAM,WAAW,KAAK,IAAI,CAAC;AAAA,MACtD,CAAC;AACD;AAAA,IACF;AAEA,QAAI,UAAU,cAAc;AAE1B,UAAI,MAAM;AAAA,QACR,MAAM;AAAA,QACN,cAAe,SAAuC;AAAA,QACtD,SACG,SAAmD,WAAW,CAAC;AAAA,MACpE,CAAC;AAED,cAAQ,KAAM,SAAuC,gBAAgB;AACrE,cAAQ,UACL,SAAmD,WAAW,CAAC;AAClE;AAAA,IACF;AACA,QAAI,UAAU,aAAa;AACzB,YAAM,IAAI;AACV,YAAM,QAA2B;AAAA,QAC/B,MAAM,GAAG;AAAA,QACT,UAAU,GAAG;AAAA,QACb,OAAO,GAAG;AAAA,MACZ;AACA,WAAK,wBAAwB,KAAK,EAAE,MAAM,CAAC,UAAU;AAEnD,gBAAQ,MAAM,2CAA2C,KAAK;AAAA,MAChE,CAAC;AACD;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAU,OAAO,iBAAgC;AACrD,WAAO,MAAM;AACX,UAAI,qBAAwC;AAG5C,mBAAa,SAAS,aAAa,UAAU,CAAC;AAC9C,mBAAa,OAAO,OAAO;AAC3B,YAAM,WACF,aAAa,QAAgB,SAAS,MACxC,aACA;AACF,YAAM,eAAe,OAAO,aAAa,mBAAmB,SAAS;AACrE,qBAAe,IAAI,YAAY;AAC/B,UAAI,cAAc;AAChB,YAAI,MAAM;AAAA,UACR,MAAM;AAAA,UACN,SAAS,uBAAgB,QAAQ,WAAW,KAAK,aAAa,aAAa,eAAe;AAAA,QAC5F,CAAC;AAAA,MACH;AAGA,YAAM,WAAW,QAAS,aAAa,QAAgB,MAAM;AAG7D,YAAM,eAAgB,aAAa,QAAgB;AAGnD,YAAM,cAAe,aAAa,QAAgB;AAGlD,YAAM,cAAc,WAChB,gBAAgB,UAAa,eAC1B,IAAI,yBAAQ,EAAE,QAAQ,aAAa,QAAQ,aAAa,CAAC,IAC1D,gBAAgB,SACb,IAAI,yBAAQ,EAAE,QAAQ,YAAY,CAAC,IACpC,eACG,IAAI,yBAAQ,EAAE,QAAQ,aAAa,CAAC,IACpC,OACN;AACL,YAAM,gBAAgB,aAAa,aAAa,aAAa;AAAA,QAC3D,SAAS;AAAA,QACT,cAAc;AAAA,UACZ,WAAW;AAAA;AAAA,UAEX,eAAe;AAAA,QACjB;AAAA,MACF,CAAC;AAED,UAAI,cAAc;AAChB,YAAI,MAAM;AAAA,UACR,MAAM;AAAA,UACN,SAAS,4CAAkC,QAAS,aAAa,QAAgB,MAAM,CAAC,cAAc,QAAQ,WAAW,KAAK,OAAO,OAAO,aAAa,mBAAmB,SAAS,CAAC;AAAA,QACxL,CAAQ;AAAA,MACV;AAEA,YAAM,WAAW,0BAA0B,eAAsB;AAAA,QAC/D,OAAO;AAAA,QACP,YAAY;AAAA,MACd,CAAC;AAED,uBAAiB,SAAS,UAAwC;AAChE,YAAI,SAAU;AACd,YAAI,MAAM,KAAK;AAEf,YAAI,MAAM,SAAS,QAAQ;AACzB,+BAAsB,MAAM,QAAuB;AACnD;AAAA,QACF;AAAA,MACF;AAEA,UAAI,SAAU;AAEd,YAAM,eAAe,QAAQ;AAC7B,YAAM,oBAAoB,QAAQ;AAGlC,cAAQ,KAAK;AACb,cAAQ,UAAU,CAAC;AAEnB,UAAI,cAAc;AAEhB,YAAI;AACF,gBAAM,eAAe,MAAM,eAAe,YAAY;AACtD,gBAAM,YAAY,UAAM,qCAAqB,cAAc;AAAA,YACzD,GAAI;AAAA,YACJ,MAAM;AAAA;AAAA,UACR,CAAC;AAGD,gBAAM,aAAa;AAAA,YACjB,GAAI,oBAAoB,QAAQ,aAAa,QAAQ,CAAC;AAAA,YACtD,GAAG;AAAA,UACL;AAEA,gBAAM,sBACJ,mBAGC;AACH,gBAAM,WACJ,OAAO,wBAAwB,WAC3B,sBACA,aAAa;AAEnB,yBAAe;AAAA,YACb,GAAG;AAAA,YACH,iBAAiB;AAAA,YACjB,OAAO;AAAA,YACP,MAAM;AAAA,YACN,IAAI,CAAC;AAAA;AAAA,UACP;AAEA,yBAAe;AACf;AAAA,QACF,SAAS,KAAK;AACZ,uBAAa,WAAW,2BAA2B;AAAA,YACjD;AAAA,UACF,CAAC;AACD,cAAI,MAAM;AAAA,YACR,MAAM;AAAA,YACN,SAAS,yBAAyB,YAAY,MAC5C,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CACjD;AAAA,UACF,CAAC;AACD,cAAI,MAAM,EAAE,MAAM,OAAO,CAAC;AAC1B,cAAI,IAAI;AACR;AAAA,QACF;AAAA,MACF;AAGA,UAAI,oBAAoB;AAGtB,YAAI,sBAAsB,oBAAoB;AAC5C,cAAI,cAAc;AAChB,kBAAM,aAAa,OAAO,oBAAoB;AAAA,cAC5C,OAAO;AAAA,YACT,CAAC;AAAA,UACH;AAAA,QACF;AAEA,cAAM,2BACJ,QAAQ,kBAAkB,KAC1B,QAAS,oBAA4B,kBAAkB;AACzD,YAAI,CAAC,0BAA0B;AAE7B,cAAI;AACF,gBAAI,kBAAkB,YAAY;AAChC,oBAAM,iBAAiB;AAAA,gBACrB;AAAA,gBACA,MAAM,KAAK,cAAc;AAAA,cAC3B;AAAA,YACF,OAAO;AACL,oBAAM,KAAM,aAAa,QACrB;AAGJ,kBAAI,IAAI,cAAc;AACpB,sBAAM,GAAG,aAAa,KAAK;AAAA,cAC7B;AAAA,YACF;AAAA,UACF,SAAS,GAAG;AAEV,oBAAQ,MAAM,2CAA2C,CAAC;AAAA,UAC5D;AAAA,QACF;AAEA,mBAAW;AACX,qBAAa,gBAAgB;AAAA,UAC3B,mCAAmC;AAAA,UACnC,6BAA6B,OAAO,aAAa,eAAe;AAAA,QAClE,CAAC;AACD,qBAAa,MAAM,gBAAgB,CAAC;AACpC,YAAI,MAAM,EAAE,MAAM,QAAQ,MAAM,mBAAmB,CAAQ;AAC3D,YAAI,IAAI;AACR;AAAA,MACF;AAGA,mBAAa,gBAAgB;AAAA,QAC3B,6BAA6B,OAAO,aAAa,eAAe;AAAA,MAClE,CAAC;AACD,mBAAa,MAAM,gBAAgB,CAAC;AACpC,UAAI,MAAM,EAAE,MAAM,OAAO,CAAC;AAC1B,UAAI,IAAI;AACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,iBAAiB,MAAM;AAC3B,UAAM,eAAe,cAAc,mBAAmB;AACtD,QAAI,CAAC,aAAc;AAEnB,QAAI,MAAM;AAAA,MACR,MAAM;AAAA,MACN,SAAS,aAAa;AAAA,MACtB,QAAQ,aAAa;AAAA,MACrB;AAAA,MACA,cAAc;AAAA,IAChB,CAAuB;AAAA,EACzB;AAEA,QAAM,kBAAkB,cAAc,WAClC,SACA,cAAc,YAAY,WAAW;AACzC,MAAI,CAAC,cAAc,UAAU;AAC3B,mBAAe;AAAA,EACjB;AACA,QAAM,aAAa,cAAc,WAC7B,aAAa,SAAS,aAAa,CAAC,iBAAiB;AACnD,mBAAe;AACf,WAAO,QAAQ,YAAY;AAAA,EAC7B,CAAC,IACD,QAAQ,mBAAmB,CAAC,CAAC;AAEjC,aAAW,MAAM,CAAC,QAAQ;AACxB,qBAAiB,OAAO,GAAG;AAC3B,YAAQ,MAAM,kCAAkC,GAAG;AACnD,QAAI,MAAM;AAAA,MACR,MAAM;AAAA,MACN,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,IAC1D,CAAC;AACD,QAAI,MAAM,EAAE,MAAM,OAAO,CAAC;AAC1B,QAAI,IAAI;AAAA,EACV,CAAC;AAED,SAAO;AACT;;;ADh1BA,IAAMC,YAAW,CAAC,UAChB,QAAQ,KAAK,KAAK,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AAE9D,SAAS,gBACd,KACmB;AACnB,MAAI,CAAC,OAAO,CAAC,IAAI,SAAU,QAAO;AAClC,QAAM,MAAM,IAAI,SAAS;AACzB,MAAI,CAACA,UAAS,GAAG,EAAG,QAAO;AAE3B,QAAM,QAAQ,OAAO,IAAI,UAAU,WAAW,IAAI,QAAQ;AAC1D,QAAM,YAAY,OAAO,IAAI,cAAc,WAAW,IAAI,YAAY;AACtE,QAAM,SAAS,IAAI,WAAW;AAG9B,MAAI,WAAqB,CAAC;AAC1B,QAAM,cAAc,IAAI;AACxB,MAAI,OAAO,gBAAgB,SAAU,YAAW,CAAC,WAAW;AAAA,WACnD,MAAM,QAAQ,WAAW,EAAG,YAAW,YAAY,IAAI,MAAM;AAAA,WAC7DA,UAAS,IAAI,MAAM,KAAK,OAAO,IAAI,OAAO,OAAO;AACxD,eAAW,CAAC,IAAI,OAAO,EAAE;AAAA,WAClB,MAAM,QAAQ,IAAI,OAAO;AAChC,eAAW,IAAI,QACZ,IAAI,CAAC,MAAOA,UAAS,CAAC,IAAI,EAAE,KAAK,MAAU,EAC3C,OAAO,CAAC,OAAqB,OAAO,OAAO,QAAQ;AAExD,MAAI,CAAC,SAAS,CAAC,UAAW,QAAO;AACjC,SAAO,EAAE,OAAO,WAAW,UAAU,OAAO;AAC9C;AAYA,eAAsB,uBAAuB;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA8D;AAC5D,QAAM,OAAO,gBAAgB,WAAW;AACxC,MAAI,CAAC,KAAM,QAAO;AAElB,QAAM,QACJ,kBAAkB;AACpB,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,UAAU,MAAM,MAAM,IAAI,KAAK,KAAK;AAC1C,MAAI,CAAC,WAAW,QAAQ,cAAc,KAAK,WAAW;AAGpD,YAAQ;AAAA,MACN,mDAAmD,KAAK,KAAK,cAAc,KAAK,SAAS;AAAA,IAC3F;AACA,WAAO;AAAA,EACT;AAEA,MAAI,KAAK,QAAQ;AACf,UAAM,MAAM,OAAO,QAAQ,KAAK;AAChC,WAAO;AAAA,EACT;AAIA,UAAQ;AAAA,IACN,kBAAkB,KAAK,KAAK,cAAc,KAAK,SAAS,aAAa,KAAK;AAAA,MACxE,KAAK;AAAA,IACP,CAAC,cAAc,SAAS;AAAA,EAC1B;AAEA,QAAM,aAAa,uBACf,qBAAqB,EAAE,SAAS,UAAU,KAAK,SAAS,CAAC,IACzD,KAAK,UAAU,SACb,EAAE,aAAa,OAAO,KAAK,SAAS,CAAC,CAAC,EAAE,IACxC,CAAC;AAEP,QAAM,kBAAkBA,UAAS,UAAU,IAAI,aAAa,CAAC;AAC7D,QAAM,cAAcA,UAAS,QAAQ,QAAQ,IAAI,IAAI,QAAQ,OAAO,OAAO,CAAC;AAC5E,QAAM,mBAAmBA,UAAS,YAAY,wBAAwB,IAClE,YAAY,2BACZ;AAEJ,QAAM,cAAcA,UAAS,QAAQ,OAAO,IAAI,IAAI,QAAQ,OAAO,OAAO,CAAC;AAC3E,QAAM,aACJ,OAAO,QAAQ,aAAa,YAAY,QAAQ,SAAS,KAAK,IAC1D,QAAQ,WACR,OAAO,sBAAsB,YAAY,kBAAkB,KAAK,IAC9D,oBACA;AAER,QAAM,eAAe;AAAA;AAAA;AAAA,IAGnB,OAAO;AAAA,IACP,UAAU;AAAA,IACV,iBAAiB;AAAA,IACjB;AAAA,IACA,SAAS,CAAC;AAAA,IACV,qBAAqB,CAAC;AAAA,IACtB,oBAAoB;AAAA,IACpB,MAAM;AAAA,MACJ,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AAAA,EACF;AAEA,QAAM,KAAK,MAAM,eAAe,aAAa,eAAyB;AACtE,QAAM,eAAwC,CAAC;AAC/C,MAAI,OAAO,KAAK,eAAe,EAAE,SAAS,GAAG;AAC3C,iBAAa,OAAO;AAAA,MAClB,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AAAA,EACF;AACA,MAAI,kBAAkB;AACpB,iBAAa,UAAU;AAAA,EACzB;AACA,QAAM,kBAAkB,OAAO,KAAK,YAAY,EAAE,SAAS;AAC3D,QAAM,cACJ,KAAK,UAAU,UAAU,QAAQ,OAAO,SAAS,iBAC7C,KAAK,SAAS,IAAI,CAAC,MAAM,OAAO,CAAC,CAAC,IAClC,KAAK,UAAU,SACb,OAAO,KAAK,SAAS,CAAC,CAAC,IACvB;AACR,QAAM,eAAe,UAAM,sCAAqB,IAAI;AAAA,IAClD,GAAG;AAAA,IACH,QAAQ;AAAA,IACR,GAAI,gBAAgB,SAAY,EAAE,YAAY,IAAI,CAAC;AAAA,IACnD,GAAI,kBAAkB,EAAE,aAAa,IAAI,CAAC;AAAA,EAC5C,CAAC;AACD,QAAM,MAAM,OAAO,QAAQ,KAAK;AAEhC,QAAM,OAAO;AAAA,IACX;AAAA,IACA,OAAO,QAAQ;AAAA,IACf,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,MACN,GAAG;AAAA,MACH,QAAQ;AAAA,MACR,GAAI,gBAAgB,SAAY,EAAE,YAAY,IAAI,CAAC;AAAA,MACnD,GAAI,kBAAkB,EAAE,aAAa,IAAI,CAAC;AAAA,IAC5C;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,SAAS,MAAM,uBAAuB,IAAI;AAChD,SAAO;AACT;;;AGpLO,SAAS,yBAAyB,UAAiC;AACxE,MAAI,CAAC,YAAY,SAAS,WAAW,EAAG,QAAO;AAE/C,WAAS,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG;AAChD,UAAM,MAAM,SAAS,CAAC;AACtB,QAAI,KAAK,SAAS,UAAU,KAAK,SAAS,KAAK,GAAG;AAChD,aAAO,IAAI,QAAQ,KAAK;AAAA,IAC1B;AAAA,EACF;AACA,SAAO;AACT;;;AJ2BA,eAAsB,WAA8B;AAAA,EAClD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAiE;AAC/D,QAAM,SAAS,MAAM,kBAAkB,OAAO;AAC9C,QAAM,gBAA4D;AAAA,IAChE,GAAG;AAAA,IACH;AAAA,IACA,GAAI,mBACA,EAAE,cAAc,iBAAiB,aAAa,IAC9C,CAAC;AAAA,EACP;AAEA,QAAM,mBACJ,mBACC,mBAAmB,CAAC,OAAO,iBAAiB,OAAO,EAAE,IAAI;AAC5D,MAAI,CAAC,kBAAkB;AACrB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,oBAAqB,SACvB;AACJ,QAAM,oBACJ,aAAa,qBAAqB;AACpC,QAAM,OAAO,SAAS,SAAS,SAAS,CAAC;AACzC,QAAM,QAAQ,yBAAyB,QAAQ;AAE/C,QAAM,mBAAmB,SAAS,MAAM,GAAG,EAAE;AAC7C,QAAM,UAA2B;AAAA,IAC/B,GAAI,iBAAiB,SAAS,IAAI,EAAE,eAAe,iBAAiB,IAAI,CAAC;AAAA,EAC3E;AAEA,QAAM,kBAAkB,QAAQ,gBAAgB,IAAI,CAAC;AACrD,QAAM,uBAAuB,MAAM;AACjC,QAAI,CAAC,QAAS,QAAO;AACrB,QAAI,OAAO,YAAY,SAAU,QAAO;AACxC,UAAM,SAAS;AACf,UAAM,OAAO,OAAO;AACpB,QAAI,OAAO,SAAS,SAAU,QAAO;AACrC,WAAO;AAAA,EACT,GAAG;AACH,MAAI,CAAC,mBAAmB,qBAAqB;AAC3C,QAAI,oBAAoB,KAAK,MAAM,GAAI,QAAO,QAAQ;AAAA,QACjD,SAAQ,oBAAoB;AAAA,EACnC;AAEA,QAAM,YAAY,UAAM,wCAAuB;AAAA,IAC7C;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,IACA,GAAI,oBAAoB,EAAE,kBAAkB,IAAI,CAAC;AAAA,EACnD,CAAC;AAED,QAAM,eAAe,MAAM,uBAAuB;AAAA,IAChD,aAAa;AAAA,IACb,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,gBAAgB;AAAA,IAChB,GAAI,mBAAmB,EAAE,iBAAiB,IAAI,CAAC;AAAA,IAC/C,GAAI,oBAAoB,EAAE,kBAAkB,IAAI,CAAC;AAAA,IACjD,GAAI,uBAAuB,EAAE,qBAAqB,IAAI,CAAC;AAAA,EACzD,CAAC;AACD,MAAI,aAAc,QAAO;AAEzB,QAAM,YAAQ,+BAAc,KAAK;AACjC,QAAM,kBAAkB,UAAU;AAClC,QAAM,mBAAmB,MAAM,iBAAiB,eAAyB;AAEzE,QAAM,QAAQ,UAAM,sCAAqB,kBAAkB,aAAa;AAExE,QAAM,qBAAqB,MAAM,uBAAuB;AAAA,IACtD,WAAW;AAAA,IACX;AAAA,IACA;AAAA,IACA,OAAO,EAAE,GAAG,WAAW,gBAAgB;AAAA,IACvC,QAAQ;AAAA,IACR,gBAAgB;AAAA,IAChB,GAAI,mBAAmB,EAAE,iBAAiB,IAAI,CAAC;AAAA,EACjD,CAAC;AAED,SAAO;AACT;;;ADtFA,IAAM,4BAA4B,cAC/B,OAAO;AAAA,EACN,WAAW,cAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,YAAY,cAAE,OAAO,EAAE,SAAS;AAAA,EAChC,SAAS,cAAE,OAAO,cAAE,OAAO,GAAG,cAAE,QAAQ,CAAC,EAAE,SAAS;AACtD,CAAC,EACA,OAAO;AAEV,IAAM,4BAA4B,cAC/B,OAAO;AAAA,EACN,aAAa,cAAE,QAAQ,EAAE,SAAS;AAAA,EAClC,WAAW,cAAE,MAAM,cAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,EACzC,cAAc,cAAE,OAAO,EAAE,SAAS;AAAA,EAClC,kBAAkB,cAAE,QAAQ,EAAE,SAAS;AAAA,EACvC,mBAAmB,cAAE,OAAO,EAAE,SAAS;AAAA,EACvC,kBAAkB,cAAE,QAAQ,EAAE,SAAS;AAAA,EACvC,WAAW,cAAE,QAAQ,EAAE,SAAS;AAClC,CAAC,EACA,OAAO;AAEV,IAAM,wBAAwB,0BAA0B;AAAA,EACtD,CAAC,OAAkD,QAAyB;AAC1E,QACE,MAAM,gBAAgB,UACtB,OAAO,MAAM,gBAAgB,YAC7B;AACA,UAAI,SAAS;AAAA,QACX,MAAM;AAAA,QACN,SAAS;AAAA,QACT,MAAM,CAAC,aAAa;AAAA,MACtB,CAAC;AAAA,IACH;AAEA,UAAM,kBAAkB;AAAA,MACtB,MAAM,cAAc;AAAA,MACpB,MAAM,iBAAiB;AAAA,MACvB,MAAM,qBAAqB;AAAA,IAC7B,EAAE,OAAO,OAAO,EAAE;AAElB,QAAI,kBAAkB,GAAG;AACvB,UAAI,SAAS;AAAA,QACX,MAAM;AAAA,QACN,SACE;AAAA,MACJ,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEA,IAAM,cAAc,CAAI,QAAsB,UAAsB;AAClE,QAAM,SAAS,OAAO,UAAU,KAAK;AACrC,MAAI,OAAO,QAAS,QAAO,OAAO;AAClC,QAAM,CAAC,UAAU,IAAI,OAAO,MAAM;AAIlC,QAAM,IAAI,MAAM,WAAW,OAAO;AACpC;AAEA,IAAM,uBAAuB,CAAC,UAC5B,YAAY,uBAAuB,KAAK;AAE1C,IAAM,2BAA2B,CAC/B,UACoC;AACpC,MAAI,UAAU,OAAW,QAAO;AAChC,SAAO,YAAY,2BAA2B,KAAK;AACrD;AAEO,SAAS,YAAY,MAA8B;AACxD,QAAM,aAAa,qBAAqB,IAAI;AAE5C,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,QAAM,4BAA4B;AAClC,QAAM,2BACJ,wBAAoB,+CAA8B;AACpD,QAAM,sBAAsB,eAAe,iBAAAC;AAE3C,QAAM,cAAc,QAAQ,IAAI;AAEhC,QAAM,mBAA0D,YAAY;AAC1E,QAAI,iBAAkB,QAAO;AAC7B,QAAI,WAAW;AACb,iBAAO,gDAA+B,WAAW;AAAA,QAC/C,YAAY,6BAA6B;AAAA,MAC3C,CAAC;AAAA,IACH;AACA,QAAI,cAAc;AAChB,iBAAO,4CAA2B;AAAA,QAChC;AAAA,QACA,YAAY,6BAA6B;AAAA,MAC3C,CAAC;AAAA,IACH;AAEA,UAAM,2BAAuB,0BAAQ,aAAa,OAAO,WAAW;AACpE,eAAO,4CAA2B;AAAA,MAChC,cAAc;AAAA,MACd,YAAY,6BAA6B;AAAA,IAC3C,CAAC;AAAA,EACH,GAAG;AAEH,QAAMC,cAAa,OACjB,UACA,YACwC;AACxC,UAAM,gBAAgB,yBAAyB,OAAO;AAEtD,UAAM,WAAW,MAAM;AACvB,QAAI,CAAC,UAAU;AACb,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,WAAO,WAAc;AAAA,MACnB,GAAI,4BACA,EAAE,mBAAmB,0BAA0B,IAC/C,CAAC;AAAA,MACL;AAAA,MACA,SAAS;AAAA,MACT,kBAAkB;AAAA,MAClB,kBAAkB;AAAA,MAClB,aAAa;AAAA,MACb,mBAAmB,CAAC,oBAA0C;AAAA,QAC5D,GAAI,gBAAgB,YAChB;AAAA,UACE,SAAS;AAAA,YACP,IAAI,eAAe;AAAA,UACrB;AAAA,QACF,IACA,CAAC;AAAA,QACL,GAAI,gBAAgB,UAAU,EAAE,SAAS,eAAe,QAAQ,IAAI,CAAC;AAAA,QACrE,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;AAAA,MACnC;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO,EAAE,YAAAA,YAAW;AACtB;","names":["import_runtime","import_zod","import_runtime","import_runtime","isRecord","getRegisteredProvider","streamChat"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/adapters/http.ts","../src/adapters/http-client.ts","../src/chat/create-agent.ts","../src/chat/process-chat.ts","../src/interrupt/resume-handler.ts","../src/orchestrator.ts","../src/stream/transform-graph-stream-for-ui.ts","../src/utils/extract-latest-message.ts"],"sourcesContent":["// release-test: 2026-01-22\n\nexport type { ChatRequestBody, CheckpointRequestBody } from \"./adapters/http\";\nexport {\n createChatRouteHandler,\n createCheckpointRouteHandler,\n handleChatRequestBody,\n handleCheckpointRequestBody,\n parseChatRequestBody,\n parseCheckpointRequestBody,\n} from \"./adapters/http\";\nexport type { StreamChatFromRouteArgs } from \"./adapters/http-client\";\nexport { streamChatFromRoute } from \"./adapters/http-client\";\nexport type {\n Agent,\n AgentProcessOptions,\n CreateAgentArgs,\n} from \"./chat/create-agent\";\nexport { createAgent } from \"./chat/create-agent\";\nexport type { StreamChatArgs } from \"./chat/process-chat\";\nexport { streamChat } from \"./chat/process-chat\";\nexport type {\n ApplyResumeSelection,\n ResumeMeta,\n} from \"./interrupt/resume-handler\";\nexport {\n parseResumeMeta,\n tryPrepareResumeStream,\n} from \"./interrupt/resume-handler\";\nexport type {\n CompiledGraphLike,\n OrchestrateArgs,\n SaveMemoryFn,\n SelectWorkflowFn,\n} from \"./orchestrator\";\nexport { orchestrateGraphStream } from \"./orchestrator\";\nexport { transformGraphStreamForUI } from \"./stream/transform-graph-stream-for-ui\";\nexport type { ChatMessage } from \"./types/chat-message\";\nexport { extractLatestUserMessage } from \"./utils/extract-latest-message\";\n","import { collectBufferedStream, toSSE } from \"@kortyx/stream\";\nimport { z } from \"zod\";\nimport type { Agent } from \"../chat/create-agent\";\nimport type { ChatMessage } from \"../types/chat-message\";\n\nexport type ChatRequestBody = {\n sessionId?: string | undefined;\n workflowId?: string | undefined;\n stream?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n messages: ChatMessage[];\n};\n\nexport type CheckpointRequestBody =\n | {\n action: \"list\";\n sessionId: string;\n }\n | {\n action: \"get\";\n checkpointId: string;\n }\n | {\n action: \"rollback\";\n checkpointId: string;\n }\n | {\n action: \"fork\";\n checkpointId: string;\n newSessionId?: string | undefined;\n };\n\nconst chatMessageSchema = z\n .object({\n role: z.enum([\"user\", \"assistant\", \"system\"]),\n content: z.string(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n id: z.string().optional(),\n timestamp: z.number().refine(Number.isFinite).optional(),\n })\n .strict();\n\nconst chatRequestBodySchema = z.looseObject({\n sessionId: z.string().optional(),\n workflowId: z.string().optional(),\n stream: z.boolean().optional(),\n context: z.record(z.string(), z.unknown()).optional(),\n messages: z.array(chatMessageSchema),\n});\n\nconst checkpointRequestBodySchema = z.discriminatedUnion(\"action\", [\n z\n .object({\n action: z.literal(\"list\"),\n sessionId: z.string().min(1),\n })\n .strict(),\n z\n .object({\n action: z.literal(\"get\"),\n checkpointId: z.string().min(1),\n })\n .strict(),\n z\n .object({\n action: z.literal(\"rollback\"),\n checkpointId: z.string().min(1),\n })\n .strict(),\n z\n .object({\n action: z.literal(\"fork\"),\n checkpointId: z.string().min(1),\n newSessionId: z.string().min(1).optional(),\n })\n .strict(),\n]);\n\nconst toErrorMessage = (error: unknown): string =>\n error instanceof Error ? error.message : String(error);\n\nexport function parseChatRequestBody(value: unknown): ChatRequestBody {\n const parsed = chatRequestBodySchema.safeParse(value);\n if (!parsed.success) {\n const [firstIssue] = parsed.error.issues as unknown as [\n { message: string },\n ...Array<{ message: string }>,\n ];\n throw new Error(firstIssue.message);\n }\n\n const sessionId = parsed.data.sessionId?.trim();\n const workflowId = parsed.data.workflowId?.trim();\n\n return {\n ...(sessionId ? { sessionId } : {}),\n ...(workflowId ? { workflowId } : {}),\n ...(typeof parsed.data.stream === \"boolean\"\n ? { stream: parsed.data.stream }\n : {}),\n ...(parsed.data.context ? { context: parsed.data.context } : {}),\n messages: parsed.data.messages as ChatMessage[],\n };\n}\n\nexport function parseCheckpointRequestBody(\n value: unknown,\n): CheckpointRequestBody {\n const parsed = checkpointRequestBodySchema.safeParse(value);\n if (parsed.success) return parsed.data;\n const [firstIssue] = parsed.error.issues as unknown as [\n { message: string },\n ...Array<{ message: string }>,\n ];\n throw new Error(firstIssue.message);\n}\n\nexport async function handleChatRequestBody(args: {\n agent: Agent;\n body: ChatRequestBody;\n}): Promise<Response> {\n const { agent, body } = args;\n const stream = await agent.streamChat(body.messages, {\n sessionId: body.sessionId,\n workflowId: body.workflowId,\n context: body.context,\n });\n\n if (body.stream === false) {\n const buffered = await collectBufferedStream(stream);\n return new Response(JSON.stringify(buffered), {\n headers: {\n \"content-type\": \"application/json\",\n },\n });\n }\n\n return toSSE(stream);\n}\n\nexport function createChatRouteHandler(args: {\n agent: Agent;\n errorStatus?: number | undefined;\n}): (request: Request) => Promise<Response> {\n const { agent, errorStatus = 400 } = args;\n\n return async function POST(request: Request): Promise<Response> {\n try {\n const body = parseChatRequestBody(await request.json());\n return await handleChatRequestBody({ agent, body });\n } catch (error) {\n return new Response(\n JSON.stringify({\n error: toErrorMessage(error),\n }),\n {\n status: errorStatus,\n headers: {\n \"content-type\": \"application/json\",\n },\n },\n );\n }\n };\n}\n\nexport async function handleCheckpointRequestBody(args: {\n agent: Agent;\n body: CheckpointRequestBody;\n}): Promise<Response> {\n const { agent, body } = args;\n const result =\n body.action === \"list\"\n ? await agent.listCheckpoints(body.sessionId)\n : body.action === \"get\"\n ? await agent.getCheckpoint(body.checkpointId)\n : body.action === \"rollback\"\n ? await agent.rollbackTo(body.checkpointId)\n : await agent.fork(body.checkpointId, {\n ...(body.newSessionId ? { newSessionId: body.newSessionId } : {}),\n });\n\n return new Response(JSON.stringify(result), {\n headers: {\n \"content-type\": \"application/json\",\n },\n });\n}\n\nexport function createCheckpointRouteHandler(args: {\n agent: Agent;\n errorStatus?: number | undefined;\n}): (request: Request) => Promise<Response> {\n const { agent, errorStatus = 400 } = args;\n\n return async function POST(request: Request): Promise<Response> {\n try {\n const body = parseCheckpointRequestBody(await request.json());\n return await handleCheckpointRequestBody({ agent, body });\n } catch (error) {\n return new Response(\n JSON.stringify({\n error: toErrorMessage(error),\n }),\n {\n status: errorStatus,\n headers: {\n \"content-type\": \"application/json\",\n },\n },\n );\n }\n };\n}\n","import { type StreamChunk, streamFromRoute } from \"@kortyx/stream/browser\";\nimport type { ChatMessage } from \"../types/chat-message\";\n\nexport interface StreamChatFromRouteArgs {\n endpoint: string;\n sessionId?: string | undefined;\n workflowId?: string | undefined;\n messages: ChatMessage[];\n fetchImpl?: typeof fetch;\n headers?: Record<string, string> | undefined;\n}\n\nexport async function* streamChatFromRoute(\n args: StreamChatFromRouteArgs,\n): AsyncGenerator<StreamChunk, void, void> {\n yield* streamFromRoute({\n endpoint: args.endpoint,\n ...(args.fetchImpl ? { fetchImpl: args.fetchImpl } : {}),\n ...(args.headers ? { headers: args.headers } : {}),\n body: {\n sessionId: args.sessionId,\n workflowId: args.workflowId,\n messages: args.messages,\n },\n });\n}\n","import { resolve } from \"node:path\";\nimport type { WorkflowDefinition } from \"@kortyx/core\";\nimport {\n type GetProviderFn,\n getProvider as getRegisteredProvider,\n} from \"@kortyx/providers\";\nimport type {\n CheckpointId,\n CheckpointSummary,\n ExecutionRuntimeConfig,\n ForkSessionCheckpointResult,\n FrameworkAdapter,\n PendingRequestRecord,\n RollbackSessionCheckpointResult,\n SessionCheckpointRecord,\n WorkflowRegistry,\n} from \"@kortyx/runtime\";\nimport {\n createFileWorkflowRegistry,\n createFrameworkAdapterFromEnv,\n createInMemoryWorkflowRegistry,\n} from \"@kortyx/runtime\";\nimport type { StreamChunk } from \"@kortyx/stream\";\nimport { z } from \"zod\";\nimport type { ChatMessage } from \"../types/chat-message\";\nimport { streamChat as runStreamChat } from \"./process-chat\";\n\nexport interface AgentProcessOptions {\n sessionId?: string | undefined;\n workflowId?: string | undefined;\n context?: Record<string, unknown> | undefined;\n}\n\nexport interface CreateAgentArgs {\n getProvider?: GetProviderFn | undefined;\n workflows?: WorkflowDefinition[];\n workflowsDir?: string;\n workflowRegistry?: WorkflowRegistry;\n defaultWorkflowId?: string;\n frameworkAdapter?: FrameworkAdapter;\n telemetry?: ExecutionRuntimeConfig[\"telemetry\"];\n}\n\nexport interface Agent {\n streamChat: (\n messages: ChatMessage[],\n options?: AgentProcessOptions,\n ) => Promise<AsyncIterable<StreamChunk>>;\n listCheckpoints: (sessionId: string) => Promise<CheckpointSummary[]>;\n getCheckpoint: (id: CheckpointId) => Promise<SessionCheckpointRecord | null>;\n rollbackTo: (id: CheckpointId) => Promise<RollbackSessionCheckpointResult>;\n fork: (\n id: CheckpointId,\n options?: { newSessionId?: string },\n ) => Promise<ForkSessionCheckpointResult>;\n}\n\nconst agentProcessOptionsSchema = z\n .object({\n sessionId: z.string().optional(),\n workflowId: z.string().optional(),\n context: z.record(z.string(), z.unknown()).optional(),\n })\n .strict();\n\nconst createAgentArgsBaseSchema = z\n .object({\n getProvider: z.unknown().optional(),\n workflows: z.array(z.unknown()).optional(),\n workflowsDir: z.string().optional(),\n workflowRegistry: z.unknown().optional(),\n defaultWorkflowId: z.string().optional(),\n frameworkAdapter: z.unknown().optional(),\n telemetry: z.unknown().optional(),\n })\n .strict();\n\nconst createAgentArgsSchema = createAgentArgsBaseSchema.superRefine(\n (value: z.infer<typeof createAgentArgsBaseSchema>, ctx: z.RefinementCtx) => {\n if (\n value.getProvider !== undefined &&\n typeof value.getProvider !== \"function\"\n ) {\n ctx.addIssue({\n code: \"custom\",\n message: \"Expected `args.getProvider` to be a function.\",\n path: [\"getProvider\"],\n });\n }\n\n const workflowSources = [\n value.workflows !== undefined,\n value.workflowsDir !== undefined,\n value.workflowRegistry !== undefined,\n ].filter(Boolean).length;\n\n if (workflowSources > 1) {\n ctx.addIssue({\n code: \"custom\",\n message:\n \"Use only one workflow source: `workflows`, `workflowsDir`, or `workflowRegistry`.\",\n });\n }\n },\n);\n\nconst parseSchema = <T>(schema: z.ZodType<T>, value: unknown): T => {\n const parsed = schema.safeParse(value);\n if (parsed.success) return parsed.data;\n const [firstIssue] = parsed.error.issues as unknown as [\n { message: string },\n ...Array<{ message: string }>,\n ];\n throw new Error(firstIssue.message);\n};\n\nconst parseCreateAgentArgs = (value: unknown): CreateAgentArgs =>\n parseSchema(createAgentArgsSchema, value) as CreateAgentArgs;\n\nconst parseAgentProcessOptions = (\n value: unknown,\n): AgentProcessOptions | undefined => {\n if (value === undefined) return undefined;\n return parseSchema(agentProcessOptionsSchema, value);\n};\n\nconst hydratePendingGraphCheckpoint = async (\n frameworkAdapter: FrameworkAdapter,\n request: PendingRequestRecord,\n): Promise<PendingRequestRecord> => {\n if (request.graphCheckpointId) return request;\n const checkpointer = frameworkAdapter.checkpointer as\n | {\n getLatestCheckpointId?: (\n threadId: string,\n checkpointNs?: string,\n ) => Promise<string | undefined>;\n }\n | undefined;\n const graphCheckpointId =\n (await checkpointer?.getLatestCheckpointId?.(\n request.runId,\n request.workflow,\n )) ?? (await checkpointer?.getLatestCheckpointId?.(request.runId, \"\"));\n return graphCheckpointId ? { ...request, graphCheckpointId } : request;\n};\n\nconst clearPendingGraphWrites = async (\n frameworkAdapter: FrameworkAdapter,\n request: PendingRequestRecord,\n): Promise<void> => {\n if (!request.graphCheckpointId) return;\n const checkpointer = frameworkAdapter.checkpointer as\n | {\n deleteCheckpointWrites?: (\n threadId: string,\n checkpointNs: string,\n checkpointId: string,\n ) => Promise<void>;\n }\n | undefined;\n if (!checkpointer?.deleteCheckpointWrites) return;\n\n await Promise.all([\n checkpointer.deleteCheckpointWrites(\n request.runId,\n request.workflow,\n request.graphCheckpointId,\n ),\n checkpointer.deleteCheckpointWrites(\n request.runId,\n \"\",\n request.graphCheckpointId,\n ),\n ]);\n};\n\nexport function createAgent(args: CreateAgentArgs): Agent {\n const parsedArgs = parseCreateAgentArgs(args);\n\n const {\n getProvider,\n workflows,\n workflowsDir,\n workflowRegistry,\n defaultWorkflowId,\n frameworkAdapter,\n telemetry,\n } = parsedArgs;\n\n const resolvedDefaultWorkflowId = defaultWorkflowId;\n const resolvedFrameworkAdapter: FrameworkAdapter =\n frameworkAdapter ?? createFrameworkAdapterFromEnv();\n const resolvedGetProvider = getProvider ?? getRegisteredProvider;\n\n const resolvedCwd = process.cwd();\n\n const registryPromise: Promise<WorkflowRegistry | undefined> = (async () => {\n if (workflowRegistry) return workflowRegistry;\n if (workflows) {\n return createInMemoryWorkflowRegistry(workflows, {\n fallbackId: resolvedDefaultWorkflowId ?? \"general-chat\",\n });\n }\n if (workflowsDir) {\n return createFileWorkflowRegistry({\n workflowsDir,\n fallbackId: resolvedDefaultWorkflowId ?? \"general-chat\",\n });\n }\n\n const resolvedWorkflowsDir = resolve(resolvedCwd, \"src\", \"workflows\");\n return createFileWorkflowRegistry({\n workflowsDir: resolvedWorkflowsDir,\n fallbackId: resolvedDefaultWorkflowId ?? \"general-chat\",\n });\n })();\n\n const streamChat = async (\n messages: ChatMessage[],\n options?: AgentProcessOptions,\n ): Promise<AsyncIterable<StreamChunk>> => {\n const parsedOptions = parseAgentProcessOptions(options);\n\n const registry = await registryPromise;\n if (!registry) {\n throw new Error(\n \"createAgent requires workflows, workflowsDir, or workflowRegistry.\",\n );\n }\n\n return runStreamChat({\n ...(resolvedDefaultWorkflowId\n ? { defaultWorkflowId: resolvedDefaultWorkflowId }\n : {}),\n messages,\n options: parsedOptions,\n workflowRegistry: registry,\n frameworkAdapter: resolvedFrameworkAdapter,\n getProvider: resolvedGetProvider,\n loadRuntimeConfig: (runtimeOptions?: AgentProcessOptions) => ({\n ...(runtimeOptions?.sessionId\n ? {\n session: {\n id: runtimeOptions.sessionId,\n },\n }\n : {}),\n ...(runtimeOptions?.context ? { context: runtimeOptions.context } : {}),\n ...(telemetry ? { telemetry } : {}),\n }),\n });\n };\n\n const listCheckpoints = (sessionId: string) =>\n resolvedFrameworkAdapter.sessionCheckpoints.list(sessionId);\n\n const getCheckpoint = (id: CheckpointId) =>\n resolvedFrameworkAdapter.sessionCheckpoints.get(id);\n\n const rollbackTo = async (\n id: CheckpointId,\n ): Promise<RollbackSessionCheckpointResult> => {\n const result =\n await resolvedFrameworkAdapter.sessionCheckpoints.rollbackTo(id);\n const activePendingRequests = await Promise.all(\n result.activePendingRequests.map((request) =>\n hydratePendingGraphCheckpoint(resolvedFrameworkAdapter, request),\n ),\n );\n await Promise.all(\n activePendingRequests.map((request) =>\n clearPendingGraphWrites(resolvedFrameworkAdapter, request),\n ),\n );\n\n await Promise.all([\n ...result.invalidatedInterruptTokens.map((token) =>\n resolvedFrameworkAdapter.pendingRequests.delete(token),\n ),\n ...activePendingRequests.map((request) =>\n resolvedFrameworkAdapter.pendingRequests.save(request),\n ),\n ]);\n\n return { ...result, activePendingRequests };\n };\n\n const fork = async (\n id: CheckpointId,\n options?: { newSessionId?: string },\n ): Promise<ForkSessionCheckpointResult> => {\n const result = await resolvedFrameworkAdapter.sessionCheckpoints.fork(\n id,\n options,\n );\n const activePendingRequests = await Promise.all(\n result.checkpoint.activePendingRequests.map((request) =>\n hydratePendingGraphCheckpoint(resolvedFrameworkAdapter, request),\n ),\n );\n await Promise.all(\n activePendingRequests.map((request) =>\n clearPendingGraphWrites(resolvedFrameworkAdapter, request),\n ),\n );\n await Promise.all(\n activePendingRequests.map((request) =>\n resolvedFrameworkAdapter.pendingRequests.save(request),\n ),\n );\n return {\n ...result,\n checkpoint: { ...result.checkpoint, activePendingRequests },\n };\n };\n\n return { streamChat, listCheckpoints, getCheckpoint, rollbackTo, fork };\n}\n","import type { RuntimeEnvelope } from \"@kortyx/core\";\nimport type { GetProviderFn } from \"@kortyx/providers\";\nimport type { FrameworkAdapter, WorkflowRegistry } from \"@kortyx/runtime\";\nimport {\n buildInitialGraphState,\n createExecutionGraph,\n makeRequestId,\n} from \"@kortyx/runtime\";\nimport type { StreamChunk } from \"@kortyx/stream\";\nimport type { ApplyResumeSelection } from \"../interrupt/resume-handler\";\nimport {\n parseResumeMeta,\n tryPrepareResumeStream,\n} from \"../interrupt/resume-handler\";\nimport type { SelectWorkflowFn } from \"../orchestrator\";\nimport { orchestrateGraphStream } from \"../orchestrator\";\nimport type { ChatMessage } from \"../types/chat-message\";\nimport { extractLatestUserMessage } from \"../utils/extract-latest-message\";\n\nexport interface RuntimeConfig {\n session?: { id?: string };\n [key: string]: unknown;\n}\n\nexport interface StreamChatArgs<Options> {\n messages: ChatMessage[];\n options?: Options | undefined;\n sessionId?: string;\n defaultWorkflowId?: string;\n loadRuntimeConfig: (\n options?: Options,\n ) => RuntimeConfig | Promise<RuntimeConfig>;\n selectWorkflow?: SelectWorkflowFn;\n workflowRegistry?: WorkflowRegistry;\n frameworkAdapter?: FrameworkAdapter;\n getProvider: GetProviderFn;\n applyResumeSelection?: ApplyResumeSelection;\n}\n\nexport async function streamChat<Options = unknown>({\n messages,\n options,\n sessionId,\n defaultWorkflowId,\n loadRuntimeConfig,\n selectWorkflow,\n workflowRegistry,\n frameworkAdapter,\n getProvider,\n applyResumeSelection,\n}: StreamChatArgs<Options>): Promise<AsyncIterable<StreamChunk>> {\n const config = await loadRuntimeConfig(options);\n const runtimeConfig: Parameters<typeof createExecutionGraph>[1] = {\n ...config,\n getProvider,\n ...(frameworkAdapter\n ? { checkpointer: frameworkAdapter.checkpointer }\n : {}),\n };\n\n const workflowSelector: SelectWorkflowFn | null =\n selectWorkflow ??\n (workflowRegistry ? (id) => workflowRegistry.select(id) : null);\n if (!workflowSelector) {\n throw new Error(\n \"streamChat requires selectWorkflow or workflowRegistry to resolve workflows.\",\n );\n }\n\n const fallbackSessionId = (options as { sessionId?: string } | undefined)\n ?.sessionId;\n const resolvedSessionId =\n sessionId || fallbackSessionId || \"anonymous-session\";\n const last = messages[messages.length - 1];\n const input = extractLatestUserMessage(messages);\n\n const previousMessages = messages.slice(0, -1);\n const runtime: RuntimeEnvelope = {\n ...(previousMessages.length > 0 ? { priorMessages: previousMessages } : {}),\n } as RuntimeEnvelope;\n\n const isResumeRequest = Boolean(parseResumeMeta(last));\n const requestedWorkflowId = (() => {\n if (!options) return undefined;\n if (typeof options !== \"object\") return undefined;\n const record = options as Record<string, unknown>;\n const wfId = record.workflowId;\n if (typeof wfId === \"string\") return wfId;\n return undefined;\n })();\n if (!isResumeRequest && requestedWorkflowId) {\n if (requestedWorkflowId.trim() === \"\") delete runtime.requestedWorkflow;\n else runtime.requestedWorkflow = requestedWorkflowId;\n }\n\n const baseState = await buildInitialGraphState({\n input,\n config: runtimeConfig,\n runtime,\n ...(defaultWorkflowId ? { defaultWorkflowId } : {}),\n });\n\n const resumeStream = await tryPrepareResumeStream({\n lastMessage: last,\n sessionId: resolvedSessionId,\n config: runtimeConfig,\n selectWorkflow: workflowSelector,\n ...(frameworkAdapter ? { frameworkAdapter } : {}),\n ...(defaultWorkflowId ? { defaultWorkflowId } : {}),\n ...(applyResumeSelection ? { applyResumeSelection } : {}),\n });\n if (resumeStream) return resumeStream as AsyncIterable<StreamChunk>;\n\n const runId = makeRequestId(\"run\");\n let headCheckpoint =\n !isResumeRequest && frameworkAdapter?.sessionCheckpoints\n ? await frameworkAdapter.sessionCheckpoints.getHead(resolvedSessionId)\n : null;\n if (\n !isResumeRequest &&\n !headCheckpoint &&\n frameworkAdapter?.sessionCheckpoints\n ) {\n headCheckpoint = await frameworkAdapter.sessionCheckpoints.append({\n sessionId: resolvedSessionId,\n runId,\n workflow: String(baseState.currentWorkflow),\n state: {\n ...baseState,\n input: \"\",\n awaitingHumanInput: false,\n },\n nodes: [],\n structuredStreamIds: [],\n pendingRequests: [],\n label: \"session start\",\n });\n }\n const currentWorkflow = requestedWorkflowId\n ? baseState.currentWorkflow\n : (headCheckpoint?.state.currentWorkflow ?? baseState.currentWorkflow);\n const selectedWorkflow = await workflowSelector(currentWorkflow as string);\n\n const graph = await createExecutionGraph(selectedWorkflow, runtimeConfig);\n const initialState = headCheckpoint\n ? {\n ...headCheckpoint.state,\n input,\n config: runtimeConfig,\n currentWorkflow,\n awaitingHumanInput: false,\n runtime: {\n ...(headCheckpoint.state.runtime ?? {}),\n ...(runtime.requestedWorkflow\n ? { requestedWorkflow: runtime.requestedWorkflow }\n : {}),\n ...(runtime.priorMessages\n ? { priorMessages: runtime.priorMessages }\n : {}),\n },\n }\n : { ...baseState, currentWorkflow };\n\n const orchestratedStream = await orchestrateGraphStream({\n sessionId: resolvedSessionId,\n runId,\n graph,\n state: initialState,\n config: runtimeConfig,\n selectWorkflow: workflowSelector,\n ...(frameworkAdapter ? { frameworkAdapter } : {}),\n });\n\n return orchestratedStream as AsyncIterable<StreamChunk>;\n}\n","import type { GraphState } from \"@kortyx/core\";\nimport type {\n FrameworkAdapter,\n PendingRequestRecord,\n PendingRequestStore,\n} from \"@kortyx/runtime\";\nimport { createExecutionGraph } from \"@kortyx/runtime\";\nimport type { StreamChunk } from \"@kortyx/stream\";\nimport type { SelectWorkflowFn } from \"../orchestrator\";\nimport { type OrchestrateArgs, orchestrateGraphStream } from \"../orchestrator\";\nimport type { ChatMessage } from \"../types/chat-message\";\n\nexport interface ResumeMeta {\n token: string;\n requestId: string;\n selected: string[]; // normalized to array for consistency\n cancel?: boolean;\n}\n\nexport type ApplyResumeSelection = (args: {\n pending: PendingRequestRecord;\n selected: string[];\n}) => Record<string, unknown> | null | undefined;\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n\nexport function parseResumeMeta(\n msg: ChatMessage | undefined,\n): ResumeMeta | null {\n if (!msg || !msg.metadata) return null;\n const raw = msg.metadata.resume;\n if (!isRecord(raw)) return null;\n\n const token = typeof raw.token === \"string\" ? raw.token : \"\";\n const requestId = typeof raw.requestId === \"string\" ? raw.requestId : \"\";\n const cancel = raw.cancel === true;\n\n // Accept multiple shapes; normalize to selected: string[]\n let selected: string[] = [];\n const rawSelected = raw.selected;\n if (typeof rawSelected === \"string\") selected = [rawSelected];\n else if (Array.isArray(rawSelected)) selected = rawSelected.map(String);\n else if (isRecord(raw.choice) && typeof raw.choice.id === \"string\")\n selected = [raw.choice.id];\n else if (Array.isArray(raw.choices))\n selected = raw.choices\n .map((c) => (isRecord(c) ? c.id : undefined))\n .filter((id): id is string => typeof id === \"string\");\n\n if (!token || !requestId) return null;\n return { token, requestId, selected, cancel };\n}\n\ninterface TryResumeArgs {\n lastMessage: ChatMessage | undefined;\n sessionId: string;\n config: Record<string, unknown>;\n selectWorkflow: SelectWorkflowFn;\n defaultWorkflowId?: string;\n applyResumeSelection?: ApplyResumeSelection;\n frameworkAdapter?: FrameworkAdapter;\n}\n\nexport async function tryPrepareResumeStream({\n lastMessage,\n sessionId,\n config,\n selectWorkflow,\n defaultWorkflowId,\n applyResumeSelection,\n frameworkAdapter,\n}: TryResumeArgs): Promise<AsyncIterable<StreamChunk> | null> {\n const meta = parseResumeMeta(lastMessage);\n if (!meta) return null;\n\n const store: PendingRequestStore | undefined =\n frameworkAdapter?.pendingRequests;\n if (!store) return null;\n\n const pending = await store.get(meta.token);\n if (!pending || pending.requestId !== meta.requestId) {\n // Invalid/expired; ignore and continue normal flow\n // eslint-disable-next-line no-console\n console.log(\n `[resume] pending not found or mismatched. token=${meta.token} requestId=${meta.requestId}`,\n );\n return null;\n }\n\n if (meta.cancel) {\n await store.delete(pending.token);\n return null;\n }\n\n // Build a minimal state; the checkpointer (keyed by sessionId) will restore paused context\n // eslint-disable-next-line no-console\n console.log(\n `[resume] token=${meta.token} requestId=${meta.requestId} selected=${JSON.stringify(\n meta.selected,\n )} sessionId=${sessionId}`,\n );\n\n const resumeData = applyResumeSelection\n ? applyResumeSelection({ pending, selected: meta.selected })\n : meta.selected?.length\n ? { coordinates: String(meta.selected[0]) }\n : {};\n\n const resumeDataPatch = isRecord(resumeData) ? resumeData : {};\n const pendingMeta = isRecord(pending.schema?.meta) ? pending.schema.meta : {};\n const resumeStatePatch = isRecord(pendingMeta.__kortyxResumeStatePatch)\n ? pendingMeta.__kortyxResumeStatePatch\n : undefined;\n\n const pendingData = isRecord(pending.state?.data) ? pending.state?.data : {};\n const workflowId =\n typeof pending.workflow === \"string\" && pending.workflow.trim()\n ? pending.workflow\n : typeof defaultWorkflowId === \"string\" && defaultWorkflowId.trim()\n ? defaultWorkflowId\n : \"job-search\";\n\n const resumedState = {\n // For static breakpoints, resume with null input (set in orchestrator),\n // and stash the user selection into data so the next node can read it.\n input: \"\",\n lastNode: \"__start__\",\n currentWorkflow: workflowId,\n config,\n runtime: {},\n conversationHistory: [],\n awaitingHumanInput: false,\n data: {\n ...pendingData,\n ...resumeDataPatch,\n },\n } satisfies GraphState;\n\n const wf = await selectWorkflow(resumedState.currentWorkflow as string);\n const resumeUpdate: Record<string, unknown> = {};\n if (Object.keys(resumeDataPatch).length > 0) {\n resumeUpdate.data = {\n ...pendingData,\n ...resumeDataPatch,\n };\n }\n if (resumeStatePatch) {\n resumeUpdate.runtime = resumeStatePatch;\n }\n const hasResumeUpdate = Object.keys(resumeUpdate).length > 0;\n const resumeValue =\n meta.selected?.length && pending.schema.kind === \"multi-choice\"\n ? meta.selected.map((x) => String(x))\n : meta.selected?.length\n ? String(meta.selected[0])\n : undefined;\n const resumeCheckpointId =\n typeof pending.graphCheckpointId === \"string\" &&\n pending.graphCheckpointId.length > 0\n ? pending.graphCheckpointId\n : undefined;\n const resumedGraph = await createExecutionGraph(wf, {\n ...config,\n resume: true,\n ...(resumeValue !== undefined ? { resumeValue } : {}),\n ...(resumeCheckpointId ? { resumeCheckpointId } : {}),\n ...(hasResumeUpdate ? { resumeUpdate } : {}),\n });\n await store.delete(pending.token);\n\n const args = {\n sessionId,\n runId: pending.runId,\n graph: resumedGraph,\n state: resumedState,\n config: {\n ...config,\n resume: true,\n ...(resumeValue !== undefined ? { resumeValue } : {}),\n ...(resumeCheckpointId ? { resumeCheckpointId } : {}),\n ...(hasResumeUpdate ? { resumeUpdate } : {}),\n },\n selectWorkflow,\n frameworkAdapter: frameworkAdapter as FrameworkAdapter,\n } satisfies OrchestrateArgs;\n\n const stream = await orchestrateGraphStream(args);\n return stream as unknown as AsyncIterable<StreamChunk>;\n}\n","import { PassThrough } from \"node:stream\";\nimport type { GraphState, WorkflowDefinition, WorkflowId } from \"@kortyx/core\";\nimport {\n createExecutionGraph,\n type FrameworkAdapter,\n makeRequestId,\n makeResumeToken,\n type PendingRequestRecord,\n type PendingRequestStore,\n} from \"@kortyx/runtime\";\nimport type { StreamChunk } from \"@kortyx/stream\";\nimport { Command } from \"@langchain/langgraph\";\nimport { transformGraphStreamForUI } from \"./stream/transform-graph-stream-for-ui\";\n\nexport type SelectWorkflowFn = (\n workflowId: string,\n) => Promise<WorkflowDefinition>;\n\nexport type SaveMemoryFn = (\n sessionId: string,\n state: GraphState,\n) => Promise<void>;\n\nexport interface CompiledGraphLike {\n config?: Record<string, unknown>;\n streamEvents: (\n state: GraphState,\n options?: { version?: string; configurable?: Record<string, unknown> },\n ) => AsyncIterable<unknown> | AsyncGenerator<unknown>;\n getState?: (options?: {\n configurable?: Record<string, unknown>;\n }) => Promise<unknown>;\n}\n\nexport interface OrchestrateArgs {\n sessionId?: string;\n runId: string;\n graph: CompiledGraphLike; // minimal graph surface used here\n state: GraphState; // initial state\n config: Record<string, unknown>; // runtime config\n selectWorkflow: SelectWorkflowFn;\n frameworkAdapter?: FrameworkAdapter;\n}\n\ntype TraceSpanLike = {\n setAttributes?: (attributes: Record<string, unknown>) => void;\n addEvent?: (name: string, attributes?: Record<string, unknown>) => void;\n end?: (args?: {\n attributes?: Record<string, unknown>;\n telemetry?: Record<string, unknown>;\n }) => void;\n fail?: (\n error: unknown,\n args?: {\n attributes?: Record<string, unknown>;\n telemetry?: Record<string, unknown>;\n },\n ) => void;\n};\n\ntype TraceAdapterLike = {\n startSpan?: (args: {\n name: string;\n attributes?: Record<string, unknown>;\n telemetry?: unknown;\n }) => TraceSpanLike | undefined;\n withSpan?: <T>(\n args: {\n name: string;\n attributes?: Record<string, unknown>;\n telemetry?: unknown;\n },\n fn: (span: TraceSpanLike) => T | Promise<T>,\n ) => Promise<T>;\n getActiveContext?: () =>\n | {\n traceId: string;\n spanId: string;\n }\n | undefined;\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n\nconst isGraphState = (value: unknown): value is GraphState =>\n isRecord(value) && typeof value.currentWorkflow === \"string\";\n\ntype GraphSnapshot = {\n state: GraphState;\n checkpointId?: string;\n};\n\nconst getGraphCheckpointId = (snapshot: unknown): string | undefined => {\n if (!isRecord(snapshot)) return undefined;\n const config = isRecord(snapshot.config) ? snapshot.config : undefined;\n const configurable =\n config && isRecord(config.configurable) ? config.configurable : undefined;\n const checkpointId = configurable?.checkpoint_id;\n return typeof checkpointId === \"string\" && checkpointId.length > 0\n ? checkpointId\n : undefined;\n};\n\nconst getTraceAdapter = (\n config: Record<string, unknown>,\n): TraceAdapterLike | undefined => {\n const telemetry = isRecord(config.telemetry) ? config.telemetry : undefined;\n const traceAdapter = telemetry?.trace ?? config.reasonTrace;\n return isRecord(traceAdapter)\n ? (traceAdapter as TraceAdapterLike)\n : undefined;\n};\n\n/**\n * Orchestrates runtime execution with mid-stream transitions emitted by\n * runtime events.\n */\nexport async function orchestrateGraphStream({\n sessionId,\n runId,\n graph,\n state,\n config,\n selectWorkflow,\n frameworkAdapter,\n}: OrchestrateArgs): Promise<NodeJS.ReadableStream> {\n const out = new PassThrough({ objectMode: true });\n\n let currentGraph = graph;\n let currentState: GraphState = state;\n let finished = false;\n let structuredSeq = 0;\n const debugEnabled = Boolean((config as any)?.features?.tracing);\n const traceAdapter = getTraceAdapter(config);\n const contextMeta = isRecord(config.context) ? config.context : {};\n const telemetryConfig = isRecord(config.telemetry) ? config.telemetry : {};\n const runSpanArgs = {\n name: \"kortyx.run\",\n attributes: {\n ...(sessionId ? { sessionId } : {}),\n runId,\n workflowId: state.currentWorkflow,\n ...(typeof contextMeta.userId === \"string\"\n ? { userId: contextMeta.userId }\n : {}),\n ...(typeof contextMeta.tenantId === \"string\"\n ? { tenantId: contextMeta.tenantId }\n : {}),\n },\n telemetry: {\n metadata: {\n ...(isRecord(telemetryConfig.metadata) ? telemetryConfig.metadata : {}),\n ...contextMeta,\n },\n tags: Array.isArray(telemetryConfig.tags)\n ? telemetryConfig.tags\n : undefined,\n captureContent: telemetryConfig.captureContent,\n ...(typeof state.input === \"string\" ? { input: state.input } : {}),\n },\n };\n const namespacesUsed = new Set<string>();\n const touchedNodes = new Set<string>();\n const structuredStreamIds = new Set<string>();\n const activePendingRequests = new Map<string, PendingRequestRecord>();\n const pendingRequestWrites: Promise<void>[] = [];\n\n // Announce session id to clients so they can persist it\n try {\n const sid = (config as any)?.session?.id as string | undefined;\n if (sid && typeof sid === \"string\") {\n out.write({ type: \"session\", sessionId: sid } as any);\n }\n } catch {}\n\n // Pending transition captured from runtime transition events.\n const pending: { to: string | null; payload: Record<string, unknown> } = {\n to: null,\n payload: {},\n };\n\n // Bridge internal graph emits to our stream AND capture transitions\n let lastStatusMsg = \"\";\n let lastStatusAt = 0;\n let accumulatedOutput = \"\";\n let lastOutputSegmentId: string | undefined;\n const appendAccumulatedOutput = (\n payload: unknown,\n node: string,\n delta: string,\n ) => {\n const payloadObj = payload as {\n segmentId?: unknown;\n opId?: unknown;\n id?: unknown;\n };\n const opId =\n typeof payloadObj.opId === \"string\" && payloadObj.opId.length > 0\n ? payloadObj.opId\n : undefined;\n const segmentId =\n typeof payloadObj.segmentId === \"string\" &&\n payloadObj.segmentId.length > 0\n ? payloadObj.segmentId\n : undefined;\n const textStreamId =\n opId && segmentId\n ? `${opId}:${segmentId}`\n : segmentId ||\n opId ||\n (typeof payloadObj.id === \"string\" && payloadObj.id.length > 0\n ? payloadObj.id\n : undefined) ||\n node;\n\n if (\n textStreamId &&\n lastOutputSegmentId &&\n textStreamId !== lastOutputSegmentId &&\n accumulatedOutput.length > 0 &&\n !/\\s$/.test(accumulatedOutput) &&\n !/^\\s/.test(delta)\n ) {\n accumulatedOutput += \" \";\n }\n\n lastOutputSegmentId = textStreamId;\n accumulatedOutput += delta;\n };\n const nextStructuredStreamId = () => `${runId}:structured:${structuredSeq++}`;\n const runTraceEndArgs = () =>\n accumulatedOutput.length > 0\n ? { telemetry: { output: accumulatedOutput } }\n : undefined;\n\n // Capture interrupt payloads emitted by runtime hooks and forward them as\n // resumable interrupt chunks.\n interface HumanInputPayload {\n node?: string;\n workflow?: string;\n input?: {\n kind?: string;\n multiple?: boolean;\n question?: string;\n id?: string;\n schemaId?: string;\n schemaVersion?: string;\n meta?: Record<string, unknown>;\n options?: Array<{\n id: string;\n label: string;\n description?: string;\n value?: unknown;\n }>;\n };\n }\n // Track latest interrupt token for updating stored snapshot at end\n let pendingRecordToken: string | null = null;\n // Avoid emitting duplicate interrupt chunks in the same run.\n let wroteHumanInput = false;\n\n const pendingStore: PendingRequestStore | undefined =\n frameworkAdapter?.pendingRequests;\n const pendingTtlMs = frameworkAdapter?.ttlMs ?? 15 * 60 * 1000;\n\n const persistAndEmitInterrupt = async (\n payload: HumanInputPayload,\n ): Promise<void> => {\n if (wroteHumanInput) return;\n\n const token = makeResumeToken();\n const requestId = makeRequestId(\"human\");\n pendingRecordToken = token;\n const input = payload.input ?? {};\n const optionsList = Array.isArray(input.options) ? input.options : [];\n const kind = input.kind || (input.multiple ? \"multi-choice\" : \"choice\");\n const isText = kind === \"text\";\n\n const record: PendingRequestRecord = {\n token,\n requestId,\n sessionId,\n runId,\n workflow: payload.workflow || (currentState.currentWorkflow as string),\n node: payload.node || \"\",\n state: { ...(currentState as GraphState), awaitingHumanInput: true },\n schema: isText\n ? {\n kind: kind as any,\n multiple: Boolean(input.multiple),\n ...(input.question ? { question: input.question } : {}),\n ...(typeof input.id === \"string\" && input.id.length > 0\n ? { id: input.id }\n : {}),\n ...(typeof input.schemaId === \"string\" && input.schemaId.length > 0\n ? { schemaId: input.schemaId }\n : {}),\n ...(typeof input.schemaVersion === \"string\" &&\n input.schemaVersion.length > 0\n ? { schemaVersion: input.schemaVersion }\n : {}),\n ...(input.meta && typeof input.meta === \"object\"\n ? { meta: input.meta }\n : {}),\n }\n : {\n kind: kind as any,\n multiple: Boolean(input.multiple),\n question: String(input.question || \"Please choose an option.\"),\n ...(typeof input.id === \"string\" && input.id.length > 0\n ? { id: input.id }\n : {}),\n ...(typeof input.schemaId === \"string\" && input.schemaId.length > 0\n ? { schemaId: input.schemaId }\n : {}),\n ...(typeof input.schemaVersion === \"string\" &&\n input.schemaVersion.length > 0\n ? { schemaVersion: input.schemaVersion }\n : {}),\n ...(input.meta && typeof input.meta === \"object\"\n ? { meta: input.meta }\n : {}),\n },\n options: optionsList.map((option: any) => ({\n id: String(option.id),\n label: String(option.label),\n description:\n typeof option.description === \"string\"\n ? option.description\n : undefined,\n value: option.value,\n })),\n createdAt: Date.now(),\n ttlMs: pendingTtlMs,\n };\n activePendingRequests.set(record.token, record);\n\n if (pendingStore) {\n const savePromise = pendingStore.save(record).catch((error) => {\n // eslint-disable-next-line no-console\n console.error(\"[orchestrator] failed to save pending request\", error);\n });\n pendingRequestWrites.push(savePromise);\n }\n\n const clientMeta =\n record.schema.meta &&\n typeof record.schema.meta === \"object\" &&\n !Array.isArray(record.schema.meta)\n ? Object.fromEntries(\n Object.entries(record.schema.meta).filter(\n ([key]) => !key.startsWith(\"__kortyx\"),\n ),\n )\n : undefined;\n\n out.write({\n type: \"interrupt\",\n requestId: record.requestId,\n resumeToken: record.token,\n workflow: record.workflow,\n node: record.node,\n ...(typeof record.schema.id === \"string\" && record.schema.id.length > 0\n ? { id: record.schema.id }\n : {}),\n ...(typeof record.schema.schemaId === \"string\" &&\n record.schema.schemaId.length > 0\n ? { schemaId: record.schema.schemaId }\n : {}),\n ...(typeof record.schema.schemaVersion === \"string\" &&\n record.schema.schemaVersion.length > 0\n ? { schemaVersion: record.schema.schemaVersion }\n : {}),\n input: {\n kind: record.schema.kind,\n multiple: record.schema.multiple,\n question: record.schema.question,\n ...(typeof record.schema.id === \"string\" && record.schema.id.length > 0\n ? { id: record.schema.id }\n : {}),\n ...(typeof record.schema.schemaId === \"string\" &&\n record.schema.schemaId.length > 0\n ? { schemaId: record.schema.schemaId }\n : {}),\n ...(typeof record.schema.schemaVersion === \"string\" &&\n record.schema.schemaVersion.length > 0\n ? { schemaVersion: record.schema.schemaVersion }\n : {}),\n ...(clientMeta && Object.keys(clientMeta).length > 0\n ? { meta: clientMeta }\n : {}),\n options: record.options.map((option) => ({\n id: option.id,\n label: option.label,\n description: option.description,\n })),\n },\n } as any);\n wroteHumanInput = true;\n };\n\n const forwardEmit = (event: string, payload: unknown) => {\n if (event === \"error\") {\n const msg = String(\n (payload as { message?: unknown })?.message ?? \"Unexpected error\",\n );\n out.write({ type: \"error\", message: msg });\n out.write({ type: \"done\" });\n finished = true;\n out.end();\n return;\n }\n if (event === \"status\") {\n if (!debugEnabled) return;\n const statusMessage = (\n payload as { message?: unknown } | null | undefined\n )?.message;\n const msg =\n statusMessage === null || statusMessage === undefined\n ? \"\"\n : String(statusMessage);\n const now = Date.now();\n if (msg && msg === lastStatusMsg && now - lastStatusAt < 250) return; // de-dupe rapid duplicates\n lastStatusMsg = msg;\n lastStatusAt = now;\n out.write({ type: \"status\", message: msg });\n return;\n }\n if (event === \"text-start\") {\n const node = (payload as { node?: string })?.node;\n if (!node) return;\n touchedNodes.add(node);\n out.write({\n type: \"text-start\",\n node,\n ...(typeof (payload as { id?: string }).id === \"string\"\n ? { id: (payload as { id?: string }).id }\n : {}),\n ...(typeof (payload as { opId?: string }).opId === \"string\"\n ? { opId: (payload as { opId?: string }).opId }\n : {}),\n ...(typeof (payload as { segmentId?: string }).segmentId === \"string\"\n ? { segmentId: (payload as { segmentId?: string }).segmentId }\n : {}),\n });\n return;\n }\n if (event === \"text-delta\") {\n const node = (payload as { node?: string })?.node;\n const delta = String((payload as { delta?: unknown })?.delta ?? \"\");\n if (!node || !delta) return;\n touchedNodes.add(node);\n appendAccumulatedOutput(payload, node, delta);\n out.write({\n type: \"text-delta\",\n delta,\n node,\n ...(typeof (payload as { id?: string }).id === \"string\"\n ? { id: (payload as { id?: string }).id }\n : {}),\n ...(typeof (payload as { opId?: string }).opId === \"string\"\n ? { opId: (payload as { opId?: string }).opId }\n : {}),\n ...(typeof (payload as { segmentId?: string }).segmentId === \"string\"\n ? { segmentId: (payload as { segmentId?: string }).segmentId }\n : {}),\n });\n return;\n }\n if (event === \"text-end\") {\n const node = (payload as { node?: string })?.node;\n if (!node) return;\n touchedNodes.add(node);\n out.write({\n type: \"text-end\",\n node,\n ...(typeof (payload as { id?: string }).id === \"string\"\n ? { id: (payload as { id?: string }).id }\n : {}),\n ...(typeof (payload as { opId?: string }).opId === \"string\"\n ? { opId: (payload as { opId?: string }).opId }\n : {}),\n ...(typeof (payload as { segmentId?: string }).segmentId === \"string\"\n ? { segmentId: (payload as { segmentId?: string }).segmentId }\n : {}),\n });\n return;\n }\n if (event === \"tool-call-start\") {\n const payloadObj = payload as {\n tool?: unknown;\n toolCallId?: unknown;\n node?: string;\n id?: string;\n opId?: string;\n input?: unknown;\n };\n if (\n typeof payloadObj.tool !== \"string\" ||\n typeof payloadObj.toolCallId !== \"string\"\n ) {\n return;\n }\n out.write({\n type: \"tool-call-start\",\n tool: payloadObj.tool,\n toolCallId: payloadObj.toolCallId,\n ...(payloadObj.node ? { node: payloadObj.node } : {}),\n ...(payloadObj.id ? { id: payloadObj.id } : {}),\n ...(payloadObj.opId ? { opId: payloadObj.opId } : {}),\n ...(payloadObj.input !== undefined ? { input: payloadObj.input } : {}),\n });\n if (payloadObj.node) touchedNodes.add(payloadObj.node);\n return;\n }\n if (event === \"tool-call-result\") {\n const payloadObj = payload as {\n tool?: unknown;\n toolCallId?: unknown;\n node?: string;\n id?: string;\n opId?: string;\n content?: unknown;\n structuredContent?: unknown;\n isError?: unknown;\n };\n if (\n typeof payloadObj.tool !== \"string\" ||\n typeof payloadObj.toolCallId !== \"string\"\n ) {\n return;\n }\n out.write({\n type: \"tool-call-result\",\n tool: payloadObj.tool,\n toolCallId: payloadObj.toolCallId,\n ...(payloadObj.node ? { node: payloadObj.node } : {}),\n ...(payloadObj.id ? { id: payloadObj.id } : {}),\n ...(payloadObj.opId ? { opId: payloadObj.opId } : {}),\n content: payloadObj.content,\n ...(payloadObj.structuredContent !== undefined\n ? { structuredContent: payloadObj.structuredContent }\n : {}),\n ...(typeof payloadObj.isError === \"boolean\"\n ? { isError: payloadObj.isError }\n : {}),\n });\n if (payloadObj.node) touchedNodes.add(payloadObj.node);\n return;\n }\n if (event === \"tool-call-error\") {\n const payloadObj = payload as {\n tool?: unknown;\n toolCallId?: unknown;\n node?: string;\n id?: string;\n opId?: string;\n message?: unknown;\n };\n if (\n typeof payloadObj.tool !== \"string\" ||\n typeof payloadObj.toolCallId !== \"string\"\n ) {\n return;\n }\n out.write({\n type: \"tool-call-error\",\n tool: payloadObj.tool,\n toolCallId: payloadObj.toolCallId,\n ...(payloadObj.node ? { node: payloadObj.node } : {}),\n ...(payloadObj.id ? { id: payloadObj.id } : {}),\n ...(payloadObj.opId ? { opId: payloadObj.opId } : {}),\n message: String(payloadObj.message ?? \"\"),\n });\n if (payloadObj.node) touchedNodes.add(payloadObj.node);\n return;\n }\n if (event === \"message\") {\n const node = (payload as { node?: string })?.node;\n const text = String((payload as { content?: unknown })?.content ?? \"\");\n if (node) touchedNodes.add(node);\n out.write({ type: \"message\", node, content: text });\n return;\n }\n if (event === \"structured_data\") {\n const payloadObj = payload as {\n streamId?: string;\n dataType?: string;\n kind?: string;\n schemaId?: string;\n schemaVersion?: string;\n id?: string;\n node?: string;\n path?: string;\n value?: unknown;\n items?: unknown[];\n delta?: string;\n data?: unknown;\n };\n const kind =\n payloadObj.kind === \"set\" ||\n payloadObj.kind === \"append\" ||\n payloadObj.kind === \"text-delta\" ||\n payloadObj.kind === \"final\"\n ? payloadObj.kind\n : \"final\";\n\n const streamId =\n typeof payloadObj.streamId === \"string\" && payloadObj.streamId\n ? payloadObj.streamId\n : nextStructuredStreamId();\n structuredStreamIds.add(streamId);\n if (payloadObj.node) touchedNodes.add(payloadObj.node);\n\n out.write({\n type: \"structured-data\",\n node: payloadObj.node,\n streamId,\n dataType:\n typeof payloadObj.dataType === \"string\" && payloadObj.dataType\n ? payloadObj.dataType\n : \"generic\",\n kind,\n ...(typeof payloadObj.schemaId === \"string\"\n ? { schemaId: payloadObj.schemaId }\n : {}),\n ...(typeof payloadObj.schemaVersion === \"string\"\n ? { schemaVersion: payloadObj.schemaVersion }\n : {}),\n ...(typeof payloadObj.id === \"string\" ? { id: payloadObj.id } : {}),\n ...(kind === \"set\"\n ? {\n path: String(payloadObj.path ?? \"\"),\n value: payloadObj.value,\n }\n : {}),\n ...(kind === \"append\"\n ? {\n path: String(payloadObj.path ?? \"\"),\n items: Array.isArray(payloadObj.items) ? payloadObj.items : [],\n }\n : {}),\n ...(kind === \"text-delta\"\n ? {\n path: String(payloadObj.path ?? \"\"),\n delta: String(payloadObj.delta ?? \"\"),\n }\n : {}),\n ...(kind === \"final\" ? { data: payloadObj.data } : {}),\n });\n return;\n }\n // legacy 'human_required' removed โ dynamic interrupts are used instead\n if (event === \"transition\") {\n // 1) surface to the client (useful for dev tools)\n out.write({\n type: \"transition\",\n transitionTo: (payload as { transitionTo?: string })?.transitionTo,\n payload:\n (payload as { payload?: Record<string, unknown> })?.payload ?? {},\n });\n // 2) capture for orchestration\n pending.to = (payload as { transitionTo?: string })?.transitionTo ?? null;\n pending.payload =\n (payload as { payload?: Record<string, unknown> })?.payload ?? {};\n return;\n }\n if (event === \"interrupt\") {\n const p = payload as any;\n if (typeof p?.node === \"string\") touchedNodes.add(p.node);\n const local: HumanInputPayload = {\n node: p?.node,\n workflow: p?.workflow,\n input: p?.input,\n };\n void persistAndEmitInterrupt(local).catch((error) => {\n // eslint-disable-next-line no-console\n console.error(\"[orchestrator] failed to emit interrupt\", error);\n });\n return;\n }\n };\n\n const runLoop = async (runTraceSpan: TraceSpanLike) => {\n while (true) {\n let workflowFinalState: GraphState | null = null;\n let workflowFinalGraphCheckpointId: string | undefined;\n let sawWorkflowDone = false;\n let workflowDoneData: unknown;\n\n // Ensure the compiled graph uses our forwardEmit\n currentGraph.config = currentGraph.config || {};\n currentGraph.config.emit = forwardEmit;\n const threadId =\n ((currentGraph.config as any)?.session?.id as string | undefined) ||\n sessionId ||\n \"anonymous-session\";\n const checkpointNs = \"\";\n namespacesUsed.add(checkpointNs);\n const readLatestGraphCheckpointId = async (): Promise<\n string | undefined\n > => {\n const checkpointer = (currentGraph.config as any)?.checkpointer as\n | {\n getLatestCheckpointId?: (\n threadId: string,\n checkpointNs?: string,\n ) => Promise<string | undefined>;\n }\n | undefined;\n return checkpointer?.getLatestCheckpointId?.(runId, checkpointNs);\n };\n const readLatestGraphSnapshot =\n async (): Promise<GraphSnapshot | null> => {\n if (typeof currentGraph.getState !== \"function\") {\n const checkpointId = await readLatestGraphCheckpointId();\n return checkpointId ? { state: currentState, checkpointId } : null;\n }\n const snapshot = await currentGraph.getState({\n configurable: {\n thread_id: runId,\n checkpoint_ns: checkpointNs,\n },\n });\n const values =\n isRecord(snapshot) && \"values\" in snapshot\n ? snapshot.values\n : snapshot;\n const checkpointId =\n getGraphCheckpointId(snapshot) ??\n (await readLatestGraphCheckpointId());\n /* v8 ignore next -- snapshot shape branches are covered above; v8 reports a synthetic negative branch for this type guard. */\n if (!isGraphState(values)) {\n return checkpointId ? { state: currentState, checkpointId } : null;\n }\n return {\n state: values,\n ...(checkpointId ? { checkpointId } : {}),\n };\n };\n if (debugEnabled) {\n out.write({\n type: \"status\",\n message: `๐งต thread_id=${threadId} run_id=${runId} workflow=${currentState.currentWorkflow}`,\n });\n }\n\n // Stream runtime events (LLM deltas, node starts/ends, etc.)\n const isResume = Boolean((currentGraph.config as any)?.resume);\n // For static breakpoints, resume with null input; if a resumeUpdate was provided,\n // use Command({ update }) to merge selection into state at resume time.\n const resumeUpdate = (currentGraph.config as any)?.resumeUpdate as\n | Record<string, unknown>\n | undefined;\n const resumeValue = (currentGraph.config as any)?.resumeValue as\n | unknown\n | undefined;\n const resumeCheckpointId = (currentGraph.config as any)\n ?.resumeCheckpointId as string | undefined;\n const invokeState = isResume\n ? resumeValue !== undefined && resumeUpdate\n ? (new Command({ resume: resumeValue, update: resumeUpdate }) as any)\n : resumeValue !== undefined\n ? (new Command({ resume: resumeValue }) as any)\n : resumeUpdate\n ? (new Command({ update: resumeUpdate }) as any)\n : (null as any)\n : (currentState as any);\n const runtimeStream = currentGraph.streamEvents(invokeState, {\n version: \"v2\",\n configurable: {\n thread_id: runId,\n checkpoint_ns: checkpointNs,\n ...(isResume && resumeCheckpointId\n ? { checkpoint_id: resumeCheckpointId }\n : {}),\n },\n });\n\n if (debugEnabled) {\n out.write({\n type: \"status\",\n message: `โถ๏ธ streamEvents invoke: resume=${Boolean((currentGraph.config as any)?.resume)} thread_id=${threadId} run_id=${runId} ns=${String(currentState.currentWorkflow || \"default\")}`,\n } as any);\n }\n\n const uiStream = transformGraphStreamForUI(runtimeStream as any, {\n debug: debugEnabled,\n emitStatus: debugEnabled,\n });\n\n for await (const chunk of uiStream as AsyncIterable<StreamChunk>) {\n if (finished) break;\n if (\"node\" in chunk && typeof chunk.node === \"string\") {\n touchedNodes.add(chunk.node);\n }\n\n if (chunk.type === \"done\") {\n sawWorkflowDone = true;\n workflowDoneData = chunk.data;\n continue;\n }\n\n out.write(chunk);\n }\n\n if (finished) return;\n\n if (sawWorkflowDone) {\n const graphSnapshot = await readLatestGraphSnapshot();\n workflowFinalGraphCheckpointId = graphSnapshot?.checkpointId;\n workflowFinalState = isGraphState(workflowDoneData)\n ? workflowDoneData\n : (graphSnapshot?.state ?? currentState);\n }\n\n const transitionTo = pending.to;\n const transitionPayload = pending.payload;\n\n // Reset pending so we don't carry it accidentally\n pending.to = null;\n pending.payload = {};\n\n if (transitionTo) {\n // ๐ Handoff to the next workflow\n try {\n const nextWorkflow = await selectWorkflow(transitionTo);\n const nextGraph = await createExecutionGraph(nextWorkflow, {\n ...(config as Record<string, unknown>),\n emit: forwardEmit, // keep forwarding emits\n });\n\n // Merge data: prefer the final state's data if present, then add transition payload\n const mergedData = {\n ...(workflowFinalState?.data ?? currentState.data ?? {}),\n ...transitionPayload,\n };\n\n const rawInputFromPayload = (\n transitionPayload as {\n rawInput?: unknown;\n }\n )?.rawInput;\n const newInput =\n typeof rawInputFromPayload === \"string\"\n ? rawInputFromPayload\n : currentState.input;\n\n currentState = {\n ...currentState,\n currentWorkflow: transitionTo as WorkflowId,\n input: newInput,\n data: mergedData,\n ui: {}, // reset UI layer on new graph\n };\n\n currentGraph = nextGraph;\n continue; // run the next graph\n } catch (err) {\n runTraceSpan.addEvent?.(\"kortyx.transition.error\", {\n transitionTo,\n });\n out.write({\n type: \"error\",\n message: `Transition failed to '${transitionTo}': ${\n err instanceof Error ? err.message : String(err)\n }`,\n });\n out.write({ type: \"done\" });\n out.end();\n return;\n }\n }\n\n // No transition โ either graph returned done or ended naturally\n if (workflowFinalState) {\n // If we paused for an interrupt, persist a pending request and emit an interrupt chunk\n // Attach final state to pending record if we have one\n if (workflowFinalState && pendingRecordToken) {\n if (pendingRequestWrites.length > 0) {\n await Promise.all(pendingRequestWrites);\n }\n if (pendingStore) {\n await pendingStore.update(pendingRecordToken, {\n state: workflowFinalState,\n ...(workflowFinalGraphCheckpointId\n ? { graphCheckpointId: workflowFinalGraphCheckpointId }\n : {}),\n });\n }\n const pendingRequest = activePendingRequests.get(pendingRecordToken);\n /* v8 ignore next -- pendingRecordToken is assigned only after the active request is inserted. */\n if (pendingRequest) {\n activePendingRequests.set(pendingRecordToken, {\n ...pendingRequest,\n state: workflowFinalState,\n ...(workflowFinalGraphCheckpointId\n ? { graphCheckpointId: workflowFinalGraphCheckpointId }\n : {}),\n });\n }\n }\n /* v8 ignore next -- pending writes are created only by interrupt persistence, which also sets pendingRecordToken. */\n if (!pendingRecordToken && pendingRequestWrites.length > 0) {\n await Promise.all(pendingRequestWrites);\n }\n\n const shouldKeepFrameworkState =\n Boolean(pendingRecordToken) ||\n Boolean((workflowFinalState as any)?.awaitingHumanInput);\n if (!shouldKeepFrameworkState) {\n // Best-effort cleanup: completed runs don't need to retain checkpoints.\n try {\n if (frameworkAdapter?.cleanupRun) {\n await frameworkAdapter.cleanupRun(\n runId,\n Array.from(namespacesUsed),\n );\n } else {\n const cp = (currentGraph.config as any)\n ?.checkpointer as unknown as {\n deleteThread?: (id: string) => any;\n };\n if (cp?.deleteThread) {\n await cp.deleteThread(runId);\n }\n }\n } catch (e) {\n // eslint-disable-next-line no-console\n console.error(\"[orchestrator] framework cleanup failed\", e);\n }\n }\n\n finished = true;\n runTraceSpan.setAttributes?.({\n \"kortyx.run.awaiting_human_input\": shouldKeepFrameworkState,\n \"kortyx.run.final_workflow\": String(currentState.currentWorkflow),\n });\n runTraceSpan.end?.(runTraceEndArgs());\n const resolvedSessionId =\n ((config as any)?.session?.id as string | undefined) ||\n sessionId ||\n \"\";\n if (resolvedSessionId && frameworkAdapter?.sessionCheckpoints) {\n try {\n const checkpoint = await frameworkAdapter.sessionCheckpoints.append(\n {\n sessionId: resolvedSessionId,\n runId,\n ...(workflowFinalGraphCheckpointId\n ? { graphCheckpointId: workflowFinalGraphCheckpointId }\n : {}),\n workflow: String(workflowFinalState.currentWorkflow),\n state: workflowFinalState,\n nodes: Array.from(touchedNodes),\n structuredStreamIds: Array.from(structuredStreamIds),\n pendingRequests: Array.from(activePendingRequests.values()),\n },\n );\n out.write({\n type: \"checkpoint\",\n id: checkpoint.id,\n sessionId: checkpoint.sessionId,\n turnIndex: checkpoint.turnIndex,\n ...(checkpoint.label ? { label: checkpoint.label } : {}),\n } as StreamChunk);\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(\"[orchestrator] session checkpoint failed\", error);\n }\n }\n out.write({ type: \"done\", data: workflowFinalState } as any);\n out.end();\n return;\n }\n\n // Natural end with no explicit \"done\" (defensive close)\n const naturalGraphSnapshot = await readLatestGraphSnapshot();\n const naturalFinalState = naturalGraphSnapshot?.state ?? currentState;\n if (pendingRequestWrites.length > 0) {\n await Promise.all(pendingRequestWrites);\n }\n if (pendingRecordToken && naturalGraphSnapshot?.checkpointId) {\n if (pendingStore) {\n await pendingStore.update(pendingRecordToken, {\n state: naturalFinalState,\n graphCheckpointId: naturalGraphSnapshot.checkpointId,\n });\n }\n const pendingRequest = activePendingRequests.get(pendingRecordToken);\n /* v8 ignore next -- pendingRecordToken is assigned only after the active request is inserted. */\n if (pendingRequest) {\n activePendingRequests.set(pendingRecordToken, {\n ...pendingRequest,\n state: naturalFinalState,\n graphCheckpointId: naturalGraphSnapshot.checkpointId,\n });\n }\n }\n const resolvedSessionId =\n ((config as any)?.session?.id as string | undefined) || sessionId || \"\";\n if (resolvedSessionId && frameworkAdapter?.sessionCheckpoints) {\n try {\n const checkpoint = await frameworkAdapter.sessionCheckpoints.append({\n sessionId: resolvedSessionId,\n runId,\n ...(naturalGraphSnapshot?.checkpointId\n ? { graphCheckpointId: naturalGraphSnapshot.checkpointId }\n : {}),\n workflow: String(naturalFinalState.currentWorkflow),\n state: naturalFinalState,\n nodes: Array.from(touchedNodes),\n structuredStreamIds: Array.from(structuredStreamIds),\n pendingRequests: Array.from(activePendingRequests.values()),\n });\n out.write({\n type: \"checkpoint\",\n id: checkpoint.id,\n sessionId: checkpoint.sessionId,\n turnIndex: checkpoint.turnIndex,\n ...(checkpoint.label ? { label: checkpoint.label } : {}),\n } as StreamChunk);\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(\"[orchestrator] session checkpoint failed\", error);\n }\n }\n runTraceSpan.setAttributes?.({\n \"kortyx.run.final_workflow\": String(naturalFinalState.currentWorkflow),\n });\n runTraceSpan.end?.(runTraceEndArgs());\n out.write({ type: \"done\", data: naturalFinalState } as any);\n out.end();\n return;\n }\n };\n\n const emitTraceChunk = () => {\n const traceContext = traceAdapter?.getActiveContext?.();\n if (!traceContext) return;\n\n out.write({\n type: \"trace\",\n traceId: traceContext.traceId,\n spanId: traceContext.spanId,\n runId,\n rootSpanName: \"kortyx.run\",\n } satisfies StreamChunk);\n };\n\n const fallbackRunSpan = traceAdapter?.withSpan\n ? undefined\n : traceAdapter?.startSpan?.(runSpanArgs);\n if (!traceAdapter?.withSpan) {\n emitTraceChunk();\n }\n const runPromise = traceAdapter?.withSpan\n ? traceAdapter.withSpan(runSpanArgs, (runTraceSpan) => {\n emitTraceChunk();\n return runLoop(runTraceSpan);\n })\n : runLoop(fallbackRunSpan ?? {});\n\n runPromise.catch((err) => {\n fallbackRunSpan?.fail?.(err);\n console.error(\"[error:orchestrateGraphStream]\", err);\n out.write({\n type: \"error\",\n message: err instanceof Error ? err.message : String(err),\n });\n out.write({ type: \"done\" });\n out.end();\n });\n\n return out;\n}\n","import type { StreamChunk } from \"@kortyx/stream\";\nimport type { StreamEvent } from \"@langchain/core/tracers/log_stream\";\n\ninterface TransformOptions {\n debug?: boolean;\n emitStatus?: boolean;\n}\n\nconst isGraphStateOutput = (value: unknown): value is Record<string, unknown> =>\n value !== null &&\n typeof value === \"object\" &&\n !Array.isArray(value) &&\n \"currentWorkflow\" in value;\n\n/**\n * Transforms runtime stream events into standardized UI chunks.\n * Runtime emits (`message`, `structured_data`, `interrupt`, `transition`) are\n * forwarded directly by the orchestrator, so this transformer only handles\n * graph lifecycle + completion signals.\n */\nexport async function* transformGraphStreamForUI(\n stream: AsyncIterable<StreamEvent>,\n options: TransformOptions = {},\n): AsyncGenerator<StreamChunk> {\n const { debug = false, emitStatus = debug } = options;\n const startedNodes = new Set<string>();\n const endedNodes = new Set<string>();\n let latestGraphState: Record<string, unknown> | null = null;\n\n for await (const event of stream) {\n const { event: type, name, data } = event ?? {};\n if (debug) console.log(`[debug:event]`, JSON.stringify(event, null, 2));\n\n switch (type) {\n case \"on_chain_start\":\n if (name && !name.startsWith(\"ChannelWrite\")) {\n if (name === \"__start__\" || name === \"__end__\") break;\n if (startedNodes.has(name)) break; // de-dupe\n startedNodes.add(name);\n if (debug) console.log(`[debug:start] node=${name}`);\n if (emitStatus) {\n yield { type: \"status\", message: `Processing node: ${name}` };\n }\n }\n break;\n\n case \"on_chain_end\": {\n const nodeName = name;\n const output = data?.output;\n if (debug)\n console.log(\n `[debug:on_chain_end:${nodeName}] output=`,\n JSON.stringify(output, null, 2),\n );\n if (!output || nodeName?.startsWith(\"ChannelWrite\")) break;\n if (isGraphStateOutput(output)) latestGraphState = output;\n\n // Emit a simple completion status for UI progress feedback (de-dupe + skip internal nodes)\n if (nodeName !== \"__start__\" && nodeName !== \"__end__\") {\n if (!endedNodes.has(nodeName)) {\n if (emitStatus) {\n yield {\n type: \"status\",\n message: `โ
Completed node: ${nodeName}`,\n };\n }\n endedNodes.add(nodeName);\n }\n }\n break;\n }\n\n case \"on_graph_end\": {\n if (debug)\n console.log(`[debug:on_graph_end]`, JSON.stringify(data, null, 2));\n const output = (data as any)?.output;\n yield {\n type: \"done\",\n data: isGraphStateOutput(output) ? output : latestGraphState,\n };\n break;\n }\n\n default:\n if (debug) {\n console.warn(`[debug:unknown_event]`, type);\n }\n break;\n }\n }\n}\n","import type { ChatMessage } from \"../types/chat-message\";\n\nexport function extractLatestUserMessage(messages: ChatMessage[]): string {\n if (!messages || messages.length === 0) return \"\";\n // Find last message with role = \"user\"\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n const msg = messages[i];\n if (msg?.role === \"user\" && msg?.content?.trim()) {\n return msg.content.trim();\n }\n }\n return \"\";\n}\n"],"mappings":"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","names":["import_runtime","import_zod","import_runtime","import_runtime","checkpointId","resolvedSessionId","isRecord","getRegisteredProvider","streamChat"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kortyx/agent",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Agent composition utilities for Kortyx.",
|
|
6
6
|
"keywords": [
|
|
@@ -39,10 +39,10 @@
|
|
|
39
39
|
"@langchain/langgraph": "^1.1.4",
|
|
40
40
|
"zod": "^4.3.6",
|
|
41
41
|
"@kortyx/core": "0.5.3",
|
|
42
|
-
"@kortyx/stream": "0.9.0",
|
|
43
42
|
"@kortyx/providers": "0.5.0",
|
|
43
|
+
"@kortyx/runtime": "0.11.0",
|
|
44
44
|
"@kortyx/utils": "0.2.6",
|
|
45
|
-
"@kortyx/
|
|
45
|
+
"@kortyx/stream": "0.9.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"turbo": "2.6.1",
|