@kortyx/agent 0.5.1 โ†’ 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.6.0](https://github.com/kortyx-io/kortyx/compare/agent-v0.5.1...agent-v0.6.0) (2026-02-17)
4
+
5
+
6
+ ### Features
7
+
8
+ * **hooks:** consolidate reason+interrupt contracts ([4716a4d](https://github.com/kortyx-io/kortyx/commit/4716a4d4739b4a71b7c6e84717c830cd9ff625a6))
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **hooks:** stabilize useReason interrupt resume and split internals ([fa24712](https://github.com/kortyx-io/kortyx/commit/fa247129f160d129cdf2c05f0a48a2236ea71bb8))
14
+
3
15
  ## [0.5.1](https://github.com/kortyx-io/kortyx/compare/agent-v0.5.0...agent-v0.5.1) (2026-02-17)
4
16
 
5
17
 
package/dist/index.js CHANGED
@@ -236,11 +236,19 @@ async function orchestrateGraphStream({
236
236
  schema: isText ? {
237
237
  kind,
238
238
  multiple: Boolean(input.multiple),
239
- ...input.question ? { question: input.question } : {}
239
+ ...input.question ? { question: input.question } : {},
240
+ ...typeof input.id === "string" && input.id.length > 0 ? { id: input.id } : {},
241
+ ...typeof input.schemaId === "string" && input.schemaId.length > 0 ? { schemaId: input.schemaId } : {},
242
+ ...typeof input.schemaVersion === "string" && input.schemaVersion.length > 0 ? { schemaVersion: input.schemaVersion } : {},
243
+ ...input.meta && typeof input.meta === "object" ? { meta: input.meta } : {}
240
244
  } : {
241
245
  kind,
242
246
  multiple: Boolean(input.multiple),
243
- question: String(input.question || "Please choose an option.")
247
+ question: String(input.question || "Please choose an option."),
248
+ ...typeof input.id === "string" && input.id.length > 0 ? { id: input.id } : {},
249
+ ...typeof input.schemaId === "string" && input.schemaId.length > 0 ? { schemaId: input.schemaId } : {},
250
+ ...typeof input.schemaVersion === "string" && input.schemaVersion.length > 0 ? { schemaVersion: input.schemaVersion } : {},
251
+ ...input.meta && typeof input.meta === "object" ? { meta: input.meta } : {}
244
252
  },
245
253
  options: optionsList.map((option) => ({
246
254
  id: String(option.id),
@@ -256,16 +264,28 @@ async function orchestrateGraphStream({
256
264
  console.error("[orchestrator] failed to save pending request", error);
257
265
  });
258
266
  }
267
+ const clientMeta = record.schema.meta && typeof record.schema.meta === "object" && !Array.isArray(record.schema.meta) ? Object.fromEntries(
268
+ Object.entries(record.schema.meta).filter(
269
+ ([key]) => !key.startsWith("__kortyx")
270
+ )
271
+ ) : void 0;
259
272
  out.write({
260
273
  type: "interrupt",
261
274
  requestId: record.requestId,
262
275
  resumeToken: record.token,
263
276
  workflow: record.workflow,
264
277
  node: record.node,
278
+ ...typeof record.schema.id === "string" && record.schema.id.length > 0 ? { id: record.schema.id } : {},
279
+ ...typeof record.schema.schemaId === "string" && record.schema.schemaId.length > 0 ? { schemaId: record.schema.schemaId } : {},
280
+ ...typeof record.schema.schemaVersion === "string" && record.schema.schemaVersion.length > 0 ? { schemaVersion: record.schema.schemaVersion } : {},
265
281
  input: {
266
282
  kind: record.schema.kind,
267
283
  multiple: record.schema.multiple,
268
284
  question: record.schema.question,
285
+ ...typeof record.schema.id === "string" && record.schema.id.length > 0 ? { id: record.schema.id } : {},
286
+ ...typeof record.schema.schemaId === "string" && record.schema.schemaId.length > 0 ? { schemaId: record.schema.schemaId } : {},
287
+ ...typeof record.schema.schemaVersion === "string" && record.schema.schemaVersion.length > 0 ? { schemaVersion: record.schema.schemaVersion } : {},
288
+ ...clientMeta && Object.keys(clientMeta).length > 0 ? { meta: clientMeta } : {},
269
289
  options: record.options.map((option) => ({
270
290
  id: option.id,
271
291
  label: option.label,
@@ -299,20 +319,39 @@ async function orchestrateGraphStream({
299
319
  if (event === "text-start") {
300
320
  const node = payload?.node;
301
321
  if (!node) return;
302
- out.write({ type: "text-start", node });
322
+ out.write({
323
+ type: "text-start",
324
+ node,
325
+ ...typeof payload.id === "string" ? { id: payload.id } : {},
326
+ ...typeof payload.opId === "string" ? { opId: payload.opId } : {},
327
+ ...typeof payload.segmentId === "string" ? { segmentId: payload.segmentId } : {}
328
+ });
303
329
  return;
304
330
  }
305
331
  if (event === "text-delta") {
306
332
  const node = payload?.node;
307
333
  const delta = String(payload?.delta ?? "");
308
334
  if (!node || !delta) return;
309
- out.write({ type: "text-delta", delta, node });
335
+ out.write({
336
+ type: "text-delta",
337
+ delta,
338
+ node,
339
+ ...typeof payload.id === "string" ? { id: payload.id } : {},
340
+ ...typeof payload.opId === "string" ? { opId: payload.opId } : {},
341
+ ...typeof payload.segmentId === "string" ? { segmentId: payload.segmentId } : {}
342
+ });
310
343
  return;
311
344
  }
312
345
  if (event === "text-end") {
313
346
  const node = payload?.node;
314
347
  if (!node) return;
315
- out.write({ type: "text-end", node });
348
+ out.write({
349
+ type: "text-end",
350
+ node,
351
+ ...typeof payload.id === "string" ? { id: payload.id } : {},
352
+ ...typeof payload.opId === "string" ? { opId: payload.opId } : {},
353
+ ...typeof payload.segmentId === "string" ? { segmentId: payload.segmentId } : {}
354
+ });
316
355
  return;
317
356
  }
318
357
  if (event === "message") {
@@ -326,6 +365,11 @@ async function orchestrateGraphStream({
326
365
  type: "structured-data",
327
366
  node: payload?.node,
328
367
  dataType: payload?.dataType,
368
+ mode: payload?.mode,
369
+ schemaId: payload?.schemaId,
370
+ schemaVersion: payload?.schemaVersion,
371
+ id: payload?.id,
372
+ opId: payload?.opId,
329
373
  data: payload?.data
330
374
  });
331
375
  return;
@@ -371,7 +415,7 @@ async function orchestrateGraphStream({
371
415
  activeIsResume = isResume;
372
416
  const resumeUpdate = currentGraph.config?.resumeUpdate;
373
417
  const resumeValue = currentGraph.config?.resumeValue;
374
- const invokeState = isResume ? resumeValue !== void 0 ? new import_langgraph.Command({ resume: resumeValue }) : resumeUpdate ? new import_langgraph.Command({ update: resumeUpdate }) : null : currentState;
418
+ 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;
375
419
  const runtimeStream = currentGraph.streamEvents(invokeState, {
376
420
  version: "v2",
377
421
  configurable: {
@@ -537,6 +581,8 @@ async function tryPrepareResumeStream({
537
581
  );
538
582
  const resumeData = applyResumeSelection ? applyResumeSelection({ pending, selected: meta.selected }) : meta.selected?.length ? { coordinates: String(meta.selected[0]) } : {};
539
583
  const resumeDataPatch = isRecord(resumeData) ? resumeData : {};
584
+ const pendingMeta = isRecord(pending.schema?.meta) ? pending.schema.meta : {};
585
+ const resumeMemoryPatch = isRecord(pendingMeta.__kortyxResumeMemory) ? pendingMeta.__kortyxResumeMemory : void 0;
540
586
  const pendingData = isRecord(pending.state?.data) ? pending.state?.data : {};
541
587
  const workflowId = typeof pending.workflow === "string" && pending.workflow.trim() ? pending.workflow : typeof defaultWorkflowId === "string" && defaultWorkflowId.trim() ? defaultWorkflowId : "job-search";
542
588
  const resumedState = {
@@ -555,11 +601,23 @@ async function tryPrepareResumeStream({
555
601
  }
556
602
  };
557
603
  const wf = await selectWorkflow(resumedState.currentWorkflow);
604
+ const resumeUpdate = {};
605
+ if (Object.keys(resumeDataPatch).length > 0) {
606
+ resumeUpdate.data = {
607
+ ...pendingData,
608
+ ...resumeDataPatch
609
+ };
610
+ }
611
+ if (resumeMemoryPatch) {
612
+ resumeUpdate.memory = resumeMemoryPatch;
613
+ }
614
+ const hasResumeUpdate = Object.keys(resumeUpdate).length > 0;
558
615
  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;
559
616
  const resumedGraph = await (0, import_runtime2.createLangGraph)(wf, {
560
617
  ...config,
561
618
  resume: true,
562
- ...resumeValue !== void 0 ? { resumeValue } : {}
619
+ ...resumeValue !== void 0 ? { resumeValue } : {},
620
+ ...hasResumeUpdate ? { resumeUpdate } : {}
563
621
  });
564
622
  await store.delete(pending.token);
565
623
  const args = {
@@ -570,7 +628,8 @@ async function tryPrepareResumeStream({
570
628
  config: {
571
629
  ...config,
572
630
  resume: true,
573
- ...resumeValue !== void 0 ? { resumeValue } : {}
631
+ ...resumeValue !== void 0 ? { resumeValue } : {},
632
+ ...hasResumeUpdate ? { resumeUpdate } : {}
574
633
  },
575
634
  selectWorkflow,
576
635
  ...frameworkAdapter ? { frameworkAdapter } : {}
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 parseChatRequestBody,\n processChatRequestBody,\n} from \"./adapters/http\";\nexport type { StreamChatFromRouteArgs } from \"./adapters/http-client\";\nexport { streamChatFromRoute } from \"./adapters/http-client\";\nexport type {\n Agent,\n AgentMemoryConfig,\n AgentProcessOptions,\n AgentSessionConfig,\n CreateAgentArgs,\n} from \"./chat/create-agent\";\nexport { createAgent } from \"./chat/create-agent\";\nexport type { ProcessChatArgs } from \"./chat/process-chat\";\nexport { processChat } 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 { z } from \"zod\";\nimport type { Agent } from \"../chat/create-agent\";\nimport type { ChatMessage } from \"../types/chat-message\";\n\nexport type ChatRequestBody = {\n sessionId: string;\n workflowId?: string | 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.unknown()).optional(),\n id: z.string().optional(),\n timestamp: z.number().finite().optional(),\n })\n .strict();\n\nconst chatRequestBodySchema = z\n .object({\n sessionId: z\n .string()\n .transform((value) => value.trim())\n .refine((value) => value.length > 0, {\n message: \"`sessionId` is required.\",\n }),\n workflowId: z.string().optional(),\n messages: z.array(chatMessageSchema),\n })\n .strict();\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 throw new Error(parsed.error.issues[0]?.message ?? \"Invalid chat request.\");\n }\n\n const workflowId = parsed.data.workflowId?.trim();\n\n return {\n sessionId: parsed.data.sessionId,\n ...(workflowId ? { workflowId } : {}),\n messages: parsed.data.messages as ChatMessage[],\n };\n}\n\nexport async function processChatRequestBody(args: {\n agent: Agent;\n body: ChatRequestBody;\n}): Promise<Response> {\n const { agent, body } = args;\n return agent.processChat(body.messages, {\n sessionId: body.sessionId,\n ...(body.workflowId ? { workflowId: body.workflowId } : {}),\n });\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 processChatRequestBody({ 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;\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 ...(args.workflowId ? { workflowId: args.workflowId } : {}),\n messages: args.messages,\n },\n });\n}\n","import { resolve } from \"node:path\";\nimport type { WorkflowDefinition } from \"@kortyx/core\";\nimport { createInMemoryAdapter, type MemoryAdapter } from \"@kortyx/memory\";\nimport {\n type GetProviderFn,\n getProvider as getRegisteredProvider,\n} from \"@kortyx/providers\";\nimport type { FrameworkAdapter, WorkflowRegistry } from \"@kortyx/runtime\";\nimport {\n createFileWorkflowRegistry,\n createFrameworkAdapterFromEnv,\n createInMemoryWorkflowRegistry,\n} from \"@kortyx/runtime\";\nimport { z } from \"zod\";\nimport type { ChatMessage } from \"../types/chat-message\";\nimport { processChat as runProcessChat } from \"./process-chat\";\n\nexport interface AgentSessionConfig {\n id?: string | undefined;\n}\n\nexport interface AgentMemoryConfig {\n enabled?: boolean | undefined;\n namespace?: string | undefined;\n ttlMs?: number | undefined;\n}\n\nexport interface AgentProcessOptions {\n sessionId?: string | undefined;\n workflowId?: string | undefined;\n workflow?: string | undefined;\n}\n\nexport interface CreateAgentArgs {\n getProvider?: GetProviderFn | undefined;\n workflows?: WorkflowDefinition[];\n workflowsDir?: string;\n workflowRegistry?: WorkflowRegistry;\n fallbackWorkflowId?: string;\n defaultWorkflowId?: string;\n frameworkAdapter?: FrameworkAdapter;\n session?: AgentSessionConfig;\n memory?: AgentMemoryConfig;\n}\n\nexport interface Agent {\n processChat: (\n messages: ChatMessage[],\n options?: AgentProcessOptions,\n ) => Promise<Response>;\n}\n\nconst agentProcessOptionsSchema = z\n .object({\n sessionId: z.string().optional(),\n workflowId: z.string().optional(),\n workflow: z.string().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 fallbackWorkflowId: z.string().optional(),\n defaultWorkflowId: z.string().optional(),\n frameworkAdapter: z.unknown().optional(),\n session: z\n .object({\n id: z.string().optional(),\n })\n .strict()\n .optional(),\n memory: z\n .object({\n enabled: z.boolean().optional(),\n namespace: z.string().optional(),\n ttlMs: z.number().finite().positive().optional(),\n })\n .strict()\n .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: z.ZodIssueCode.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: z.ZodIssueCode.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[0];\n throw new Error(firstIssue?.message ?? \"Invalid configuration.\");\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 resolveMemoryAdapter = (\n memory: AgentMemoryConfig | undefined,\n): MemoryAdapter | undefined => {\n if (memory?.enabled === false) return undefined;\n\n return createInMemoryAdapter({\n namespace: memory?.namespace ?? \"kortyx-agent\",\n ttlMs: memory?.ttlMs ?? 1000 * 60 * 60,\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 fallbackWorkflowId,\n defaultWorkflowId,\n frameworkAdapter,\n session,\n memory,\n } = parsedArgs;\n\n const resolvedDefaultWorkflowId = defaultWorkflowId ?? fallbackWorkflowId;\n const resolvedFrameworkAdapter: FrameworkAdapter =\n frameworkAdapter ?? createFrameworkAdapterFromEnv();\n const defaultSessionId = session?.id ?? \"anonymous-session\";\n const memoryAdapter = resolveMemoryAdapter(memory);\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: fallbackWorkflowId ?? \"general-chat\",\n });\n }\n if (workflowsDir) {\n return createFileWorkflowRegistry({\n workflowsDir,\n fallbackId: fallbackWorkflowId ?? \"general-chat\",\n });\n }\n\n const resolvedWorkflowsDir = resolve(resolvedCwd, \"src\", \"workflows\");\n return createFileWorkflowRegistry({\n workflowsDir: resolvedWorkflowsDir,\n fallbackId: fallbackWorkflowId ?? \"general-chat\",\n });\n })();\n\n return {\n processChat: async (\n messages: ChatMessage[],\n options?: AgentProcessOptions,\n ): Promise<Response> => {\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 runProcessChat({\n ...(resolvedDefaultWorkflowId\n ? { defaultWorkflowId: resolvedDefaultWorkflowId }\n : {}),\n messages,\n options: parsedOptions,\n workflowRegistry: registry,\n frameworkAdapter: resolvedFrameworkAdapter,\n getProvider: resolvedGetProvider,\n ...(memoryAdapter ? { memoryAdapter } : {}),\n loadRuntimeConfig: (runtimeOptions?: AgentProcessOptions) => ({\n session: {\n id: runtimeOptions?.sessionId ?? defaultSessionId,\n },\n }),\n });\n },\n };\n}\n","import type { MemoryEnvelope } from \"@kortyx/core\";\nimport type { MemoryAdapter } from \"@kortyx/memory\";\nimport type { GetProviderFn } from \"@kortyx/providers\";\nimport type { FrameworkAdapter, WorkflowRegistry } from \"@kortyx/runtime\";\nimport {\n buildInitialGraphState,\n createLangGraph,\n makeRequestId,\n} from \"@kortyx/runtime\";\nimport { createStreamResponse, 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 ProcessChatArgs<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 memoryAdapter?: MemoryAdapter;\n applyResumeSelection?: ApplyResumeSelection;\n}\n\nexport async function processChat<Options = unknown>({\n messages,\n options,\n sessionId,\n defaultWorkflowId,\n loadRuntimeConfig,\n selectWorkflow,\n workflowRegistry,\n frameworkAdapter,\n getProvider,\n memoryAdapter,\n applyResumeSelection,\n}: ProcessChatArgs<Options>): Promise<Response> {\n const config = await loadRuntimeConfig(options);\n const runtimeConfig: Parameters<typeof createLangGraph>[1] = {\n ...config,\n getProvider,\n ...(memoryAdapter ? { memoryAdapter } : {}),\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 \"processChat 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 memory: MemoryEnvelope = {\n ...(previousMessages.length > 0\n ? { conversationMessages: previousMessages }\n : {}),\n } as MemoryEnvelope;\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 const wf = record.workflow;\n if (typeof wf === \"string\") return wf;\n return undefined;\n })();\n if (!isResumeRequest && requestedWorkflowId) {\n if (requestedWorkflowId.trim() === \"\") delete memory.currentWorkflow;\n else memory.currentWorkflow = requestedWorkflowId;\n }\n\n const baseState = await buildInitialGraphState({\n input,\n config: runtimeConfig,\n memory,\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 createStreamResponse(resumeStream);\n\n const runId = makeRequestId(\"run\");\n const currentWorkflow = baseState.currentWorkflow;\n const selectedWorkflow = await workflowSelector(currentWorkflow as string);\n\n const graph = await createLangGraph(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 createStreamResponse(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 { createLangGraph } 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\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 memory: {},\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 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 createLangGraph(wf, {\n ...config,\n resume: true,\n ...(resumeValue !== undefined ? { resumeValue } : {}),\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 },\n selectWorkflow,\n ...(frameworkAdapter ? { 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 createLangGraph,\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\n/**\n * Orchestrates LangGraph execution with mid-stream transitions emitted via\n * ctx.emit(\"transition\", ...).\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 const debugEnabled = Boolean((config as any)?.features?.tracing);\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 ctx.emit(...)\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\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 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 // Track if current invocation is a resume, so we can de-dupe interrupt events\n let activeIsResume = false;\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 (activeIsResume || 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 }\n : {\n kind: kind as any,\n multiple: Boolean(input.multiple),\n question: String(input.question || \"Please choose an option.\"),\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 out.write({\n type: \"interrupt\",\n requestId: record.requestId,\n resumeToken: record.token,\n workflow: record.workflow,\n node: record.node,\n input: {\n kind: record.schema.kind,\n multiple: record.schema.multiple,\n question: record.schema.question,\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 msg = String((payload as { message?: unknown })?.message ?? \"\");\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({ type: \"text-start\", node });\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 out.write({ type: \"text-delta\", delta, node });\n return;\n }\n if (event === \"text-end\") {\n const node = (payload as { node?: string })?.node;\n if (!node) return;\n out.write({ type: \"text-end\", 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 out.write({ type: \"message\", node, content: text });\n return;\n }\n if (event === \"structured_data\") {\n out.write({\n type: \"structured-data\",\n node: (payload as { node?: string })?.node,\n dataType: (payload as { dataType?: string })?.dataType,\n data: (payload as { data?: unknown })?.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 (async () => {\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 activeIsResume = isResume;\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\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 createLangGraph(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 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 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 if (!finished) {\n out.write({ type: \"done\" });\n out.end();\n }\n return;\n }\n })().catch((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 LangGraph's astream_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":"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","names":["import_runtime","import_zod","import_runtime","import_runtime","getRegisteredProvider"]}
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 parseChatRequestBody,\n processChatRequestBody,\n} from \"./adapters/http\";\nexport type { StreamChatFromRouteArgs } from \"./adapters/http-client\";\nexport { streamChatFromRoute } from \"./adapters/http-client\";\nexport type {\n Agent,\n AgentMemoryConfig,\n AgentProcessOptions,\n AgentSessionConfig,\n CreateAgentArgs,\n} from \"./chat/create-agent\";\nexport { createAgent } from \"./chat/create-agent\";\nexport type { ProcessChatArgs } from \"./chat/process-chat\";\nexport { processChat } 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 { z } from \"zod\";\nimport type { Agent } from \"../chat/create-agent\";\nimport type { ChatMessage } from \"../types/chat-message\";\n\nexport type ChatRequestBody = {\n sessionId: string;\n workflowId?: string | 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.unknown()).optional(),\n id: z.string().optional(),\n timestamp: z.number().finite().optional(),\n })\n .strict();\n\nconst chatRequestBodySchema = z\n .object({\n sessionId: z\n .string()\n .transform((value) => value.trim())\n .refine((value) => value.length > 0, {\n message: \"`sessionId` is required.\",\n }),\n workflowId: z.string().optional(),\n messages: z.array(chatMessageSchema),\n })\n .strict();\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 throw new Error(parsed.error.issues[0]?.message ?? \"Invalid chat request.\");\n }\n\n const workflowId = parsed.data.workflowId?.trim();\n\n return {\n sessionId: parsed.data.sessionId,\n ...(workflowId ? { workflowId } : {}),\n messages: parsed.data.messages as ChatMessage[],\n };\n}\n\nexport async function processChatRequestBody(args: {\n agent: Agent;\n body: ChatRequestBody;\n}): Promise<Response> {\n const { agent, body } = args;\n return agent.processChat(body.messages, {\n sessionId: body.sessionId,\n ...(body.workflowId ? { workflowId: body.workflowId } : {}),\n });\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 processChatRequestBody({ 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;\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 ...(args.workflowId ? { workflowId: args.workflowId } : {}),\n messages: args.messages,\n },\n });\n}\n","import { resolve } from \"node:path\";\nimport type { WorkflowDefinition } from \"@kortyx/core\";\nimport { createInMemoryAdapter, type MemoryAdapter } from \"@kortyx/memory\";\nimport {\n type GetProviderFn,\n getProvider as getRegisteredProvider,\n} from \"@kortyx/providers\";\nimport type { FrameworkAdapter, WorkflowRegistry } from \"@kortyx/runtime\";\nimport {\n createFileWorkflowRegistry,\n createFrameworkAdapterFromEnv,\n createInMemoryWorkflowRegistry,\n} from \"@kortyx/runtime\";\nimport { z } from \"zod\";\nimport type { ChatMessage } from \"../types/chat-message\";\nimport { processChat as runProcessChat } from \"./process-chat\";\n\nexport interface AgentSessionConfig {\n id?: string | undefined;\n}\n\nexport interface AgentMemoryConfig {\n enabled?: boolean | undefined;\n namespace?: string | undefined;\n ttlMs?: number | undefined;\n}\n\nexport interface AgentProcessOptions {\n sessionId?: string | undefined;\n workflowId?: string | undefined;\n workflow?: string | undefined;\n}\n\nexport interface CreateAgentArgs {\n getProvider?: GetProviderFn | undefined;\n workflows?: WorkflowDefinition[];\n workflowsDir?: string;\n workflowRegistry?: WorkflowRegistry;\n fallbackWorkflowId?: string;\n defaultWorkflowId?: string;\n frameworkAdapter?: FrameworkAdapter;\n session?: AgentSessionConfig;\n memory?: AgentMemoryConfig;\n}\n\nexport interface Agent {\n processChat: (\n messages: ChatMessage[],\n options?: AgentProcessOptions,\n ) => Promise<Response>;\n}\n\nconst agentProcessOptionsSchema = z\n .object({\n sessionId: z.string().optional(),\n workflowId: z.string().optional(),\n workflow: z.string().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 fallbackWorkflowId: z.string().optional(),\n defaultWorkflowId: z.string().optional(),\n frameworkAdapter: z.unknown().optional(),\n session: z\n .object({\n id: z.string().optional(),\n })\n .strict()\n .optional(),\n memory: z\n .object({\n enabled: z.boolean().optional(),\n namespace: z.string().optional(),\n ttlMs: z.number().finite().positive().optional(),\n })\n .strict()\n .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: z.ZodIssueCode.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: z.ZodIssueCode.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[0];\n throw new Error(firstIssue?.message ?? \"Invalid configuration.\");\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 resolveMemoryAdapter = (\n memory: AgentMemoryConfig | undefined,\n): MemoryAdapter | undefined => {\n if (memory?.enabled === false) return undefined;\n\n return createInMemoryAdapter({\n namespace: memory?.namespace ?? \"kortyx-agent\",\n ttlMs: memory?.ttlMs ?? 1000 * 60 * 60,\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 fallbackWorkflowId,\n defaultWorkflowId,\n frameworkAdapter,\n session,\n memory,\n } = parsedArgs;\n\n const resolvedDefaultWorkflowId = defaultWorkflowId ?? fallbackWorkflowId;\n const resolvedFrameworkAdapter: FrameworkAdapter =\n frameworkAdapter ?? createFrameworkAdapterFromEnv();\n const defaultSessionId = session?.id ?? \"anonymous-session\";\n const memoryAdapter = resolveMemoryAdapter(memory);\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: fallbackWorkflowId ?? \"general-chat\",\n });\n }\n if (workflowsDir) {\n return createFileWorkflowRegistry({\n workflowsDir,\n fallbackId: fallbackWorkflowId ?? \"general-chat\",\n });\n }\n\n const resolvedWorkflowsDir = resolve(resolvedCwd, \"src\", \"workflows\");\n return createFileWorkflowRegistry({\n workflowsDir: resolvedWorkflowsDir,\n fallbackId: fallbackWorkflowId ?? \"general-chat\",\n });\n })();\n\n return {\n processChat: async (\n messages: ChatMessage[],\n options?: AgentProcessOptions,\n ): Promise<Response> => {\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 runProcessChat({\n ...(resolvedDefaultWorkflowId\n ? { defaultWorkflowId: resolvedDefaultWorkflowId }\n : {}),\n messages,\n options: parsedOptions,\n workflowRegistry: registry,\n frameworkAdapter: resolvedFrameworkAdapter,\n getProvider: resolvedGetProvider,\n ...(memoryAdapter ? { memoryAdapter } : {}),\n loadRuntimeConfig: (runtimeOptions?: AgentProcessOptions) => ({\n session: {\n id: runtimeOptions?.sessionId ?? defaultSessionId,\n },\n }),\n });\n },\n };\n}\n","import type { MemoryEnvelope } from \"@kortyx/core\";\nimport type { MemoryAdapter } from \"@kortyx/memory\";\nimport type { GetProviderFn } from \"@kortyx/providers\";\nimport type { FrameworkAdapter, WorkflowRegistry } from \"@kortyx/runtime\";\nimport {\n buildInitialGraphState,\n createLangGraph,\n makeRequestId,\n} from \"@kortyx/runtime\";\nimport { createStreamResponse, 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 ProcessChatArgs<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 memoryAdapter?: MemoryAdapter;\n applyResumeSelection?: ApplyResumeSelection;\n}\n\nexport async function processChat<Options = unknown>({\n messages,\n options,\n sessionId,\n defaultWorkflowId,\n loadRuntimeConfig,\n selectWorkflow,\n workflowRegistry,\n frameworkAdapter,\n getProvider,\n memoryAdapter,\n applyResumeSelection,\n}: ProcessChatArgs<Options>): Promise<Response> {\n const config = await loadRuntimeConfig(options);\n const runtimeConfig: Parameters<typeof createLangGraph>[1] = {\n ...config,\n getProvider,\n ...(memoryAdapter ? { memoryAdapter } : {}),\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 \"processChat 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 memory: MemoryEnvelope = {\n ...(previousMessages.length > 0\n ? { conversationMessages: previousMessages }\n : {}),\n } as MemoryEnvelope;\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 const wf = record.workflow;\n if (typeof wf === \"string\") return wf;\n return undefined;\n })();\n if (!isResumeRequest && requestedWorkflowId) {\n if (requestedWorkflowId.trim() === \"\") delete memory.currentWorkflow;\n else memory.currentWorkflow = requestedWorkflowId;\n }\n\n const baseState = await buildInitialGraphState({\n input,\n config: runtimeConfig,\n memory,\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 createStreamResponse(resumeStream);\n\n const runId = makeRequestId(\"run\");\n const currentWorkflow = baseState.currentWorkflow;\n const selectedWorkflow = await workflowSelector(currentWorkflow as string);\n\n const graph = await createLangGraph(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 createStreamResponse(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 { createLangGraph } 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 resumeMemoryPatch = isRecord(pendingMeta.__kortyxResumeMemory)\n ? pendingMeta.__kortyxResumeMemory\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 memory: {},\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 (resumeMemoryPatch) {\n resumeUpdate.memory = resumeMemoryPatch;\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 createLangGraph(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 } : {}),\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 createLangGraph,\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\n/**\n * Orchestrates LangGraph execution with mid-stream transitions emitted via\n * ctx.emit(\"transition\", ...).\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 const debugEnabled = Boolean((config as any)?.features?.tracing);\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 ctx.emit(...)\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\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 // Track if current invocation is a resume, so we can de-dupe interrupt events\n let activeIsResume = false;\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 (activeIsResume || 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 msg = String((payload as { message?: unknown })?.message ?? \"\");\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 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 === \"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 out.write({\n type: \"structured-data\",\n node: (payload as { node?: string })?.node,\n dataType: (payload as { dataType?: string })?.dataType,\n mode: (payload as { mode?: string })?.mode,\n schemaId: (payload as { schemaId?: string })?.schemaId,\n schemaVersion: (payload as { schemaVersion?: string })?.schemaVersion,\n id: (payload as { id?: string })?.id,\n opId: (payload as { opId?: string })?.opId,\n data: (payload as { data?: unknown })?.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 (async () => {\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 activeIsResume = isResume;\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 createLangGraph(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 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 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 if (!finished) {\n out.write({ type: \"done\" });\n out.end();\n }\n return;\n }\n })().catch((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 LangGraph's astream_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":"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","names":["import_runtime","import_zod","import_runtime","import_runtime","getRegisteredProvider"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kortyx/agent",
3
- "version": "0.5.1",
3
+ "version": "0.6.0",
4
4
  "private": false,
5
5
  "description": "Agent composition utilities for Kortyx.",
6
6
  "keywords": [