@kortyx/agent 0.5.0 → 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.
Files changed (38) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/browser-DxBPQjOI.d.ts +21 -0
  3. package/dist/browser.d.ts +2 -3
  4. package/dist/browser.js +44 -5
  5. package/dist/browser.js.map +1 -0
  6. package/dist/index.d.ts +136 -16
  7. package/dist/index.js +876 -22
  8. package/dist/index.js.map +1 -0
  9. package/package.json +6 -5
  10. package/dist/adapters/http-client.d.ts +0 -12
  11. package/dist/adapters/http-client.d.ts.map +0 -1
  12. package/dist/adapters/http-client.js +0 -16
  13. package/dist/adapters/http.d.ts +0 -17
  14. package/dist/adapters/http.d.ts.map +0 -1
  15. package/dist/adapters/http.js +0 -66
  16. package/dist/browser.d.ts.map +0 -1
  17. package/dist/chat/create-agent.d.ts +0 -33
  18. package/dist/chat/create-agent.d.ts.map +0 -1
  19. package/dist/chat/create-agent.js +0 -138
  20. package/dist/chat/process-chat.d.ts +0 -27
  21. package/dist/chat/process-chat.d.ts.map +0 -1
  22. package/dist/chat/process-chat.js +0 -87
  23. package/dist/index.d.ts.map +0 -1
  24. package/dist/interrupt/resume-handler.d.ts +0 -27
  25. package/dist/interrupt/resume-handler.d.ts.map +0 -1
  26. package/dist/interrupt/resume-handler.js +0 -102
  27. package/dist/orchestrator.d.ts +0 -22
  28. package/dist/orchestrator.d.ts.map +0 -1
  29. package/dist/orchestrator.js +0 -321
  30. package/dist/stream/transform-graph-stream-for-ui.d.ts +0 -9
  31. package/dist/stream/transform-graph-stream-for-ui.d.ts.map +0 -1
  32. package/dist/stream/transform-graph-stream-for-ui.js +0 -60
  33. package/dist/types/chat-message.d.ts +0 -8
  34. package/dist/types/chat-message.d.ts.map +0 -1
  35. package/dist/types/chat-message.js +0 -2
  36. package/dist/utils/extract-latest-message.d.ts +0 -3
  37. package/dist/utils/extract-latest-message.d.ts.map +0 -1
  38. package/dist/utils/extract-latest-message.js +0 -14
@@ -1,27 +0,0 @@
1
- import type { FrameworkAdapter, PendingRequestRecord } from "@kortyx/runtime";
2
- import type { StreamChunk } from "@kortyx/stream";
3
- import type { SelectWorkflowFn } from "../orchestrator";
4
- import type { ChatMessage } from "../types/chat-message";
5
- export interface ResumeMeta {
6
- token: string;
7
- requestId: string;
8
- selected: string[];
9
- cancel?: boolean;
10
- }
11
- export type ApplyResumeSelection = (args: {
12
- pending: PendingRequestRecord;
13
- selected: string[];
14
- }) => Record<string, unknown> | null | undefined;
15
- export declare function parseResumeMeta(msg: ChatMessage | undefined): ResumeMeta | null;
16
- interface TryResumeArgs {
17
- lastMessage: ChatMessage | undefined;
18
- sessionId: string;
19
- config: Record<string, unknown>;
20
- selectWorkflow: SelectWorkflowFn;
21
- defaultWorkflowId?: string;
22
- applyResumeSelection?: ApplyResumeSelection;
23
- frameworkAdapter?: FrameworkAdapter;
24
- }
25
- export declare function tryPrepareResumeStream({ lastMessage, sessionId, config, selectWorkflow, defaultWorkflowId, applyResumeSelection, frameworkAdapter, }: TryResumeArgs): Promise<AsyncIterable<StreamChunk> | null>;
26
- export {};
27
- //# sourceMappingURL=resume-handler.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"resume-handler.d.ts","sourceRoot":"","sources":["../../src/interrupt/resume-handler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,gBAAgB,EAChB,oBAAoB,EAErB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAExD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEzD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,MAAM,oBAAoB,GAAG,CAAC,IAAI,EAAE;IACxC,OAAO,EAAE,oBAAoB,CAAC;IAC9B,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;AAKjD,wBAAgB,eAAe,CAC7B,GAAG,EAAE,WAAW,GAAG,SAAS,GAC3B,UAAU,GAAG,IAAI,CAuBnB;AAED,UAAU,aAAa;IACrB,WAAW,EAAE,WAAW,GAAG,SAAS,CAAC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,cAAc,EAAE,gBAAgB,CAAC;IACjC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC;AAED,wBAAsB,sBAAsB,CAAC,EAC3C,WAAW,EACX,SAAS,EACT,MAAM,EACN,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,gBAAgB,GACjB,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,CA6F5D"}
@@ -1,102 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parseResumeMeta = parseResumeMeta;
4
- exports.tryPrepareResumeStream = tryPrepareResumeStream;
5
- const runtime_1 = require("@kortyx/runtime");
6
- const orchestrator_1 = require("../orchestrator");
7
- const isRecord = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
8
- function parseResumeMeta(msg) {
9
- if (!msg || !msg.metadata)
10
- return null;
11
- const raw = msg.metadata.resume;
12
- if (!isRecord(raw))
13
- return null;
14
- const token = typeof raw.token === "string" ? raw.token : "";
15
- const requestId = typeof raw.requestId === "string" ? raw.requestId : "";
16
- const cancel = raw.cancel === true;
17
- let selected = [];
18
- const rawSelected = raw.selected;
19
- if (typeof rawSelected === "string")
20
- selected = [rawSelected];
21
- else if (Array.isArray(rawSelected))
22
- selected = rawSelected.map(String);
23
- else if (isRecord(raw.choice) && typeof raw.choice.id === "string")
24
- selected = [raw.choice.id];
25
- else if (Array.isArray(raw.choices))
26
- selected = raw.choices
27
- .map((c) => (isRecord(c) ? c.id : undefined))
28
- .filter((id) => typeof id === "string");
29
- if (!token || !requestId)
30
- return null;
31
- return { token, requestId, selected, cancel };
32
- }
33
- async function tryPrepareResumeStream({ lastMessage, sessionId, config, selectWorkflow, defaultWorkflowId, applyResumeSelection, frameworkAdapter, }) {
34
- const meta = parseResumeMeta(lastMessage);
35
- if (!meta)
36
- return null;
37
- const store = frameworkAdapter?.pendingRequests;
38
- if (!store)
39
- return null;
40
- const pending = await store.get(meta.token);
41
- if (!pending || pending.requestId !== meta.requestId) {
42
- console.log(`[resume] pending not found or mismatched. token=${meta.token} requestId=${meta.requestId}`);
43
- return null;
44
- }
45
- if (meta.cancel) {
46
- await store.delete(pending.token);
47
- return null;
48
- }
49
- console.log(`[resume] token=${meta.token} requestId=${meta.requestId} selected=${JSON.stringify(meta.selected)} sessionId=${sessionId}`);
50
- const resumeData = applyResumeSelection
51
- ? applyResumeSelection({ pending, selected: meta.selected })
52
- : meta.selected?.length
53
- ? { coordinates: String(meta.selected[0]) }
54
- : {};
55
- const resumeDataPatch = isRecord(resumeData) ? resumeData : {};
56
- const pendingData = isRecord(pending.state?.data) ? pending.state?.data : {};
57
- const workflowId = typeof pending.workflow === "string" && pending.workflow.trim()
58
- ? pending.workflow
59
- : typeof defaultWorkflowId === "string" && defaultWorkflowId.trim()
60
- ? defaultWorkflowId
61
- : "job-search";
62
- const resumedState = {
63
- input: "",
64
- lastNode: "__start__",
65
- currentWorkflow: workflowId,
66
- config,
67
- memory: {},
68
- conversationHistory: [],
69
- awaitingHumanInput: false,
70
- data: {
71
- ...pendingData,
72
- ...resumeDataPatch,
73
- },
74
- };
75
- const wf = await selectWorkflow(resumedState.currentWorkflow);
76
- const resumeValue = meta.selected?.length && pending.schema.kind === "multi-choice"
77
- ? meta.selected.map((x) => String(x))
78
- : meta.selected?.length
79
- ? String(meta.selected[0])
80
- : undefined;
81
- const resumedGraph = await (0, runtime_1.createLangGraph)(wf, {
82
- ...config,
83
- resume: true,
84
- ...(resumeValue !== undefined ? { resumeValue } : {}),
85
- });
86
- await store.delete(pending.token);
87
- const args = {
88
- sessionId,
89
- runId: pending.runId,
90
- graph: resumedGraph,
91
- state: resumedState,
92
- config: {
93
- ...config,
94
- resume: true,
95
- ...(resumeValue !== undefined ? { resumeValue } : {}),
96
- },
97
- selectWorkflow,
98
- ...(frameworkAdapter ? { frameworkAdapter } : {}),
99
- };
100
- const stream = await (0, orchestrator_1.orchestrateGraphStream)(args);
101
- return stream;
102
- }
@@ -1,22 +0,0 @@
1
- import type { GraphState, WorkflowDefinition } from "@kortyx/core";
2
- import { type FrameworkAdapter } from "@kortyx/runtime";
3
- export type SelectWorkflowFn = (workflowId: string) => Promise<WorkflowDefinition>;
4
- export type SaveMemoryFn = (sessionId: string, state: GraphState) => Promise<void>;
5
- export interface CompiledGraphLike {
6
- config?: Record<string, unknown>;
7
- streamEvents: (state: GraphState, options?: {
8
- version?: string;
9
- configurable?: Record<string, unknown>;
10
- }) => AsyncIterable<unknown> | AsyncGenerator<unknown>;
11
- }
12
- export interface OrchestrateArgs {
13
- sessionId?: string;
14
- runId: string;
15
- graph: CompiledGraphLike;
16
- state: GraphState;
17
- config: Record<string, unknown>;
18
- selectWorkflow: SelectWorkflowFn;
19
- frameworkAdapter?: FrameworkAdapter;
20
- }
21
- export declare function orchestrateGraphStream({ sessionId, runId, graph, state, config, selectWorkflow, frameworkAdapter, }: OrchestrateArgs): Promise<NodeJS.ReadableStream>;
22
- //# sourceMappingURL=orchestrator.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../src/orchestrator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAc,MAAM,cAAc,CAAC;AAC/E,OAAO,EAEL,KAAK,gBAAgB,EAKtB,MAAM,iBAAiB,CAAC;AAKzB,MAAM,MAAM,gBAAgB,GAAG,CAC7B,UAAU,EAAE,MAAM,KACf,OAAO,CAAC,kBAAkB,CAAC,CAAC;AAEjC,MAAM,MAAM,YAAY,GAAG,CACzB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,UAAU,KACd,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,YAAY,EAAE,CACZ,KAAK,EAAE,UAAU,EACjB,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,KACnE,aAAa,CAAC,OAAO,CAAC,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;CACvD;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,iBAAiB,CAAC;IACzB,KAAK,EAAE,UAAU,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,cAAc,EAAE,gBAAgB,CAAC;IACjC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC;AAMD,wBAAsB,sBAAsB,CAAC,EAC3C,SAAS,EACT,KAAK,EACL,KAAK,EACL,KAAK,EACL,MAAM,EACN,cAAc,EACd,gBAAgB,GACjB,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAgZlD"}
@@ -1,321 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.orchestrateGraphStream = orchestrateGraphStream;
4
- const node_stream_1 = require("node:stream");
5
- const runtime_1 = require("@kortyx/runtime");
6
- const langgraph_1 = require("@langchain/langgraph");
7
- const transform_graph_stream_for_ui_1 = require("./stream/transform-graph-stream-for-ui");
8
- async function orchestrateGraphStream({ sessionId, runId, graph, state, config, selectWorkflow, frameworkAdapter, }) {
9
- const out = new node_stream_1.PassThrough({ objectMode: true });
10
- let currentGraph = graph;
11
- let currentState = state;
12
- let finished = false;
13
- const debugEnabled = Boolean(config?.features?.tracing);
14
- const namespacesUsed = new Set();
15
- try {
16
- const sid = config?.session?.id;
17
- if (sid && typeof sid === "string") {
18
- out.write({ type: "session", sessionId: sid });
19
- }
20
- }
21
- catch { }
22
- const pending = {
23
- to: null,
24
- payload: {},
25
- };
26
- let lastStatusMsg = "";
27
- let lastStatusAt = 0;
28
- let pendingRecordToken = null;
29
- let activeIsResume = false;
30
- let wroteHumanInput = false;
31
- const pendingStore = frameworkAdapter?.pendingRequests;
32
- const pendingTtlMs = frameworkAdapter?.ttlMs ?? 15 * 60 * 1000;
33
- const persistAndEmitInterrupt = async (payload) => {
34
- if (activeIsResume || wroteHumanInput)
35
- return;
36
- const token = (0, runtime_1.makeResumeToken)();
37
- const requestId = (0, runtime_1.makeRequestId)("human");
38
- pendingRecordToken = token;
39
- const input = payload.input ?? {};
40
- const optionsList = Array.isArray(input.options) ? input.options : [];
41
- const kind = input.kind || (input.multiple ? "multi-choice" : "choice");
42
- const isText = kind === "text";
43
- const record = {
44
- token,
45
- requestId,
46
- sessionId,
47
- runId,
48
- workflow: payload.workflow || currentState.currentWorkflow,
49
- node: payload.node || "",
50
- state: { ...currentState, awaitingHumanInput: true },
51
- schema: isText
52
- ? {
53
- kind: kind,
54
- multiple: Boolean(input.multiple),
55
- ...(input.question ? { question: input.question } : {}),
56
- }
57
- : {
58
- kind: kind,
59
- multiple: Boolean(input.multiple),
60
- question: String(input.question || "Please choose an option."),
61
- },
62
- options: optionsList.map((option) => ({
63
- id: String(option.id),
64
- label: String(option.label),
65
- description: typeof option.description === "string"
66
- ? option.description
67
- : undefined,
68
- value: option.value,
69
- })),
70
- createdAt: Date.now(),
71
- ttlMs: pendingTtlMs,
72
- };
73
- if (pendingStore) {
74
- pendingStore.save(record).catch((error) => {
75
- console.error("[orchestrator] failed to save pending request", error);
76
- });
77
- }
78
- out.write({
79
- type: "interrupt",
80
- requestId: record.requestId,
81
- resumeToken: record.token,
82
- workflow: record.workflow,
83
- node: record.node,
84
- input: {
85
- kind: record.schema.kind,
86
- multiple: record.schema.multiple,
87
- question: record.schema.question,
88
- options: record.options.map((option) => ({
89
- id: option.id,
90
- label: option.label,
91
- description: option.description,
92
- })),
93
- },
94
- });
95
- wroteHumanInput = true;
96
- };
97
- const forwardEmit = (event, payload) => {
98
- if (event === "error") {
99
- const msg = String(payload?.message ?? "Unexpected error");
100
- out.write({ type: "error", message: msg });
101
- out.write({ type: "done" });
102
- finished = true;
103
- out.end();
104
- return;
105
- }
106
- if (event === "status") {
107
- if (!debugEnabled)
108
- return;
109
- const msg = String(payload?.message ?? "");
110
- const now = Date.now();
111
- if (msg && msg === lastStatusMsg && now - lastStatusAt < 250)
112
- return;
113
- lastStatusMsg = msg;
114
- lastStatusAt = now;
115
- out.write({ type: "status", message: msg });
116
- return;
117
- }
118
- if (event === "text-start") {
119
- const node = payload?.node;
120
- if (!node)
121
- return;
122
- out.write({ type: "text-start", node });
123
- return;
124
- }
125
- if (event === "text-delta") {
126
- const node = payload?.node;
127
- const delta = String(payload?.delta ?? "");
128
- if (!node || !delta)
129
- return;
130
- out.write({ type: "text-delta", delta, node });
131
- return;
132
- }
133
- if (event === "text-end") {
134
- const node = payload?.node;
135
- if (!node)
136
- return;
137
- out.write({ type: "text-end", node });
138
- return;
139
- }
140
- if (event === "message") {
141
- const node = payload?.node;
142
- const text = String(payload?.content ?? "");
143
- out.write({ type: "message", node, content: text });
144
- return;
145
- }
146
- if (event === "structured_data") {
147
- out.write({
148
- type: "structured-data",
149
- node: payload?.node,
150
- dataType: payload?.dataType,
151
- data: payload?.data,
152
- });
153
- return;
154
- }
155
- if (event === "transition") {
156
- out.write({
157
- type: "transition",
158
- transitionTo: payload?.transitionTo,
159
- payload: payload?.payload ?? {},
160
- });
161
- pending.to = payload?.transitionTo ?? null;
162
- pending.payload =
163
- payload?.payload ?? {};
164
- return;
165
- }
166
- if (event === "interrupt") {
167
- const p = payload;
168
- const local = {
169
- node: p?.node,
170
- workflow: p?.workflow,
171
- input: p?.input,
172
- };
173
- void persistAndEmitInterrupt(local).catch((error) => {
174
- console.error("[orchestrator] failed to emit interrupt", error);
175
- });
176
- return;
177
- }
178
- };
179
- (async () => {
180
- while (true) {
181
- let workflowFinalState = null;
182
- currentGraph.config = currentGraph.config || {};
183
- currentGraph.config.emit = forwardEmit;
184
- const threadId = currentGraph.config?.session?.id ||
185
- sessionId ||
186
- "anonymous-session";
187
- const checkpointNs = String(currentState.currentWorkflow || "default");
188
- namespacesUsed.add(checkpointNs);
189
- if (debugEnabled) {
190
- out.write({
191
- type: "status",
192
- message: `🧵 thread_id=${threadId} run_id=${runId} workflow=${currentState.currentWorkflow}`,
193
- });
194
- }
195
- const isResume = Boolean(currentGraph.config?.resume);
196
- activeIsResume = isResume;
197
- const resumeUpdate = currentGraph.config?.resumeUpdate;
198
- const resumeValue = currentGraph.config?.resumeValue;
199
- const invokeState = isResume
200
- ? resumeValue !== undefined
201
- ? new langgraph_1.Command({ resume: resumeValue })
202
- : resumeUpdate
203
- ? new langgraph_1.Command({ update: resumeUpdate })
204
- : null
205
- : currentState;
206
- const runtimeStream = currentGraph.streamEvents(invokeState, {
207
- version: "v2",
208
- configurable: {
209
- thread_id: runId,
210
- checkpoint_ns: checkpointNs,
211
- },
212
- });
213
- if (debugEnabled) {
214
- out.write({
215
- type: "status",
216
- message: `▶️ streamEvents invoke: resume=${Boolean(currentGraph.config?.resume)} thread_id=${threadId} run_id=${runId} ns=${String(currentState.currentWorkflow || "default")}`,
217
- });
218
- }
219
- const uiStream = (0, transform_graph_stream_for_ui_1.transformGraphStreamForUI)(runtimeStream, {
220
- debug: debugEnabled,
221
- emitStatus: debugEnabled,
222
- });
223
- for await (const chunk of uiStream) {
224
- if (finished)
225
- break;
226
- out.write(chunk);
227
- if (chunk.type === "done") {
228
- workflowFinalState = chunk.data ?? null;
229
- break;
230
- }
231
- }
232
- if (finished)
233
- return;
234
- const transitionTo = pending.to;
235
- const transitionPayload = pending.payload;
236
- pending.to = null;
237
- pending.payload = {};
238
- if (transitionTo) {
239
- try {
240
- const nextWorkflow = await selectWorkflow(transitionTo);
241
- const nextGraph = await (0, runtime_1.createLangGraph)(nextWorkflow, {
242
- ...config,
243
- emit: forwardEmit,
244
- });
245
- const mergedData = {
246
- ...(workflowFinalState?.data ?? currentState.data ?? {}),
247
- ...(transitionPayload ?? {}),
248
- };
249
- const rawInputFromPayload = transitionPayload?.rawInput;
250
- const newInput = typeof rawInputFromPayload === "string"
251
- ? rawInputFromPayload
252
- : currentState.input;
253
- currentState = {
254
- ...currentState,
255
- currentWorkflow: transitionTo,
256
- input: newInput,
257
- data: mergedData,
258
- ui: {},
259
- };
260
- currentGraph = nextGraph;
261
- continue;
262
- }
263
- catch (err) {
264
- out.write({
265
- type: "error",
266
- message: `Transition failed to '${transitionTo}': ${err instanceof Error ? err.message : String(err)}`,
267
- });
268
- out.write({ type: "done" });
269
- out.end();
270
- return;
271
- }
272
- }
273
- if (workflowFinalState) {
274
- if (workflowFinalState && pendingRecordToken) {
275
- if (pendingStore) {
276
- await pendingStore.update(pendingRecordToken, {
277
- state: workflowFinalState,
278
- });
279
- }
280
- }
281
- const shouldKeepFrameworkState = Boolean(pendingRecordToken) ||
282
- Boolean(workflowFinalState?.awaitingHumanInput);
283
- if (!shouldKeepFrameworkState) {
284
- try {
285
- if (frameworkAdapter?.cleanupRun) {
286
- await frameworkAdapter.cleanupRun(runId, Array.from(namespacesUsed));
287
- }
288
- else {
289
- const cp = currentGraph.config
290
- ?.checkpointer;
291
- if (cp?.deleteThread) {
292
- await cp.deleteThread(runId);
293
- }
294
- }
295
- }
296
- catch (e) {
297
- console.error("[orchestrator] framework cleanup failed", e);
298
- }
299
- }
300
- finished = true;
301
- out.write({ type: "done", data: workflowFinalState });
302
- out.end();
303
- return;
304
- }
305
- if (!finished) {
306
- out.write({ type: "done" });
307
- out.end();
308
- }
309
- return;
310
- }
311
- })().catch((err) => {
312
- console.error("[error:orchestrateGraphStream]", err);
313
- out.write({
314
- type: "error",
315
- message: err instanceof Error ? err.message : String(err),
316
- });
317
- out.write({ type: "done" });
318
- out.end();
319
- });
320
- return out;
321
- }
@@ -1,9 +0,0 @@
1
- import type { StreamChunk } from "@kortyx/stream";
2
- import type { StreamEvent } from "@langchain/core/tracers/log_stream";
3
- interface TransformOptions {
4
- debug?: boolean;
5
- emitStatus?: boolean;
6
- }
7
- export declare function transformGraphStreamForUI(stream: AsyncIterable<StreamEvent>, options?: TransformOptions): AsyncGenerator<StreamChunk>;
8
- export {};
9
- //# sourceMappingURL=transform-graph-stream-for-ui.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"transform-graph-stream-for-ui.d.ts","sourceRoot":"","sources":["../../src/stream/transform-graph-stream-for-ui.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AAEtE,UAAU,gBAAgB;IACxB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAQD,wBAAuB,yBAAyB,CAC9C,MAAM,EAAE,aAAa,CAAC,WAAW,CAAC,EAClC,OAAO,GAAE,gBAAqB,GAC7B,cAAc,CAAC,WAAW,CAAC,CA6D7B"}
@@ -1,60 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.transformGraphStreamForUI = transformGraphStreamForUI;
4
- async function* transformGraphStreamForUI(stream, options = {}) {
5
- const { debug = false, emitStatus = debug } = options;
6
- const startedNodes = new Set();
7
- const endedNodes = new Set();
8
- for await (const event of stream) {
9
- const { event: type, name, data } = event ?? {};
10
- if (debug)
11
- console.log(`[debug:event]`, JSON.stringify(event, null, 2));
12
- switch (type) {
13
- case "on_chain_start":
14
- if (name && !name.startsWith("ChannelWrite")) {
15
- if (name === "__start__" || name === "__end__")
16
- break;
17
- if (startedNodes.has(name))
18
- break;
19
- startedNodes.add(name);
20
- if (debug)
21
- console.log(`[debug:start] node=${name}`);
22
- if (emitStatus) {
23
- yield { type: "status", message: `Processing node: ${name}` };
24
- }
25
- }
26
- break;
27
- case "on_chain_end": {
28
- const nodeName = name;
29
- const output = data?.output;
30
- if (debug)
31
- console.log(`[debug:on_chain_end:${nodeName}] output=`, JSON.stringify(output, null, 2));
32
- if (!output || nodeName?.startsWith("ChannelWrite"))
33
- break;
34
- if (nodeName !== "__start__" && nodeName !== "__end__") {
35
- if (!endedNodes.has(nodeName)) {
36
- if (emitStatus) {
37
- yield {
38
- type: "status",
39
- message: `✅ Completed node: ${nodeName}`,
40
- };
41
- }
42
- endedNodes.add(nodeName);
43
- }
44
- }
45
- break;
46
- }
47
- case "on_graph_end": {
48
- if (debug)
49
- console.log(`[debug:on_graph_end]`, JSON.stringify(data, null, 2));
50
- yield { type: "done", data: data?.output ?? null };
51
- break;
52
- }
53
- default:
54
- if (debug) {
55
- console.warn(`[debug:unknown_event]`, type);
56
- }
57
- break;
58
- }
59
- }
60
- }
@@ -1,8 +0,0 @@
1
- export type ChatMessage = {
2
- role: "user" | "assistant" | "system";
3
- content: string;
4
- timestamp?: number | undefined;
5
- id?: string | undefined;
6
- metadata?: Record<string, unknown> | undefined;
7
- };
8
- //# sourceMappingURL=chat-message.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"chat-message.d.ts","sourceRoot":"","sources":["../../src/types/chat-message.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;CAChD,CAAC"}
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,3 +0,0 @@
1
- import type { ChatMessage } from "../types/chat-message";
2
- export declare function extractLatestUserMessage(messages: ChatMessage[]): string;
3
- //# sourceMappingURL=extract-latest-message.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"extract-latest-message.d.ts","sourceRoot":"","sources":["../../src/utils/extract-latest-message.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEzD,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,MAAM,CAUxE"}
@@ -1,14 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.extractLatestUserMessage = extractLatestUserMessage;
4
- function extractLatestUserMessage(messages) {
5
- if (!messages || messages.length === 0)
6
- return "";
7
- for (let i = messages.length - 1; i >= 0; i -= 1) {
8
- const msg = messages[i];
9
- if (msg?.role === "user" && msg?.content?.trim()) {
10
- return msg.content.trim();
11
- }
12
- }
13
- return "";
14
- }