@kortyx/react 0.3.0 → 0.3.1
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 +8 -0
- package/README.md +39 -2
- package/dist/index.d.ts +10 -1
- package/dist/index.js +27 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @kortyx/react
|
|
2
2
|
|
|
3
|
+
## [0.3.1](https://github.com/kortyx-io/kortyx/compare/react-v0.3.0...react-v0.3.1) (2026-05-22)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* **react:** preserve interrupt routing metadata ([59898e2](https://github.com/kortyx-io/kortyx/commit/59898e24e291641edcdef3d09e6be4d9e66b1bf0))
|
|
9
|
+
* **react:** preserve interrupt routing metadata ([0d258a1](https://github.com/kortyx-io/kortyx/commit/0d258a17f0c49ebb1b3c9980bea7262e1badc4e3))
|
|
10
|
+
|
|
3
11
|
## [0.3.0](https://github.com/kortyx-io/kortyx/compare/react-v0.2.1...react-v0.3.0) (2026-05-20)
|
|
4
12
|
|
|
5
13
|
|
package/README.md
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
# @kortyx/react
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@kortyx/react)
|
|
4
|
+
[](https://github.com/kortyx-io/kortyx/actions/workflows/ci.yml)
|
|
5
|
+
[](https://github.com/kortyx-io/kortyx/blob/main/LICENSE)
|
|
6
|
+
[](https://react.dev/)
|
|
7
|
+
[](https://www.typescriptlang.org/)
|
|
8
|
+
|
|
9
|
+
React hooks and transport helpers for Kortyx client streaming experiences.
|
|
4
10
|
|
|
5
11
|
## Install
|
|
6
12
|
|
|
13
|
+
```bash
|
|
14
|
+
pnpm add @kortyx/react
|
|
15
|
+
```
|
|
16
|
+
|
|
7
17
|
```bash
|
|
8
18
|
npm install @kortyx/react
|
|
9
19
|
```
|
|
@@ -41,6 +51,33 @@ transports send `{ sessionId, workflowId, messages, context }` by default, and
|
|
|
41
51
|
`prepareContextMessages` lets apps replace the default history with summaries
|
|
42
52
|
or server-owned history while `useChat` still appends the outgoing message.
|
|
43
53
|
|
|
54
|
+
## Example
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
"use client";
|
|
58
|
+
|
|
59
|
+
import { createRouteChatTransport, useChat } from "@kortyx/react";
|
|
60
|
+
|
|
61
|
+
export function Chat() {
|
|
62
|
+
const chat = useChat({
|
|
63
|
+
transport: createRouteChatTransport({ endpoint: "/api/chat" }),
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<button onClick={() => chat.send("Summarize this account")}>
|
|
68
|
+
Send
|
|
69
|
+
</button>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Documentation
|
|
75
|
+
|
|
76
|
+
- [Documentation](https://kortyx.io/docs)
|
|
77
|
+
- [React client](https://kortyx.io/docs/reference/react-client)
|
|
78
|
+
- [Quickstart: Next.js API Route](https://kortyx.io/docs/getting-started/quickstart-nextjs)
|
|
79
|
+
- [Stream protocol](https://kortyx.io/docs/reference/stream-protocol)
|
|
80
|
+
|
|
44
81
|
## License
|
|
45
82
|
|
|
46
|
-
Apache-2.0
|
|
83
|
+
Apache-2.0. See [LICENSE](https://github.com/kortyx-io/kortyx/blob/main/LICENSE).
|
package/dist/index.d.ts
CHANGED
|
@@ -14,6 +14,10 @@ type HumanInputPiece = {
|
|
|
14
14
|
label: string;
|
|
15
15
|
description?: string;
|
|
16
16
|
}>;
|
|
17
|
+
schemaId?: string;
|
|
18
|
+
schemaVersion?: string;
|
|
19
|
+
interruptId?: string;
|
|
20
|
+
meta?: Record<string, unknown>;
|
|
17
21
|
};
|
|
18
22
|
type ContentPiece = {
|
|
19
23
|
id: string;
|
|
@@ -156,6 +160,10 @@ declare function createLiveChatPieces<TStructuredData = unknown, TCustomPiece ex
|
|
|
156
160
|
getPieces: () => LiveChatPiece<TStructuredData, TCustomPiece>[];
|
|
157
161
|
};
|
|
158
162
|
|
|
163
|
+
type ToHumanInputPiece = (args: {
|
|
164
|
+
chunk: StreamChunk;
|
|
165
|
+
createId: () => string;
|
|
166
|
+
}) => HumanInputPiece;
|
|
159
167
|
declare function toHumanInputPiece(args: {
|
|
160
168
|
chunk: StreamChunk;
|
|
161
169
|
createId: () => string;
|
|
@@ -207,6 +215,7 @@ type UseChatOptions<TContext = DefaultChatContext> = {
|
|
|
207
215
|
createId?: (() => string) | undefined;
|
|
208
216
|
context?: TContext | undefined;
|
|
209
217
|
prepareContextMessages?: PrepareContextMessages<TContext> | undefined;
|
|
218
|
+
toHumanInputPiece?: ToHumanInputPiece | undefined;
|
|
210
219
|
};
|
|
211
220
|
declare function useChat<TContext = DefaultChatContext>(options: UseChatOptions<TContext>): UseChatValue;
|
|
212
221
|
|
|
@@ -463,4 +472,4 @@ declare function useChatStreamDebug(): {
|
|
|
463
472
|
};
|
|
464
473
|
};
|
|
465
474
|
|
|
466
|
-
export { type BrowserChatStorageKeys, type BrowserChatStorageOptions, type ChatMsg, type ChatStorage, type ChatTransport, type ChatTransportChunkHandler, type ChatTransportChunkSource, type ChatTransportContext, type ContentPiece, type CreateRouteChatTransportArgs, type HumanInputPiece, type LiveChatErrorPiece, type LiveChatPiece, type LiveChatStructuredPiece, type LiveChatTextPiece, type OutgoingChatMessage, type PersistedChatState, type PrepareContextMessages, type PrepareContextMessagesArgs, type RouteChatRequestBody, type StructuredData, type StructuredStreamItem, type UseChatOptions, type UseChatValue, type UseStructuredStreamsOptions, type UseStructuredStreamsResult, buildAssistantMessage, createBrowserChatStorage, createChatTransport, createLiveChatPieces, createRouteChatTransport, toHumanInputPiece, useChat, useChatStreamDebug, useStructuredStreams };
|
|
475
|
+
export { type BrowserChatStorageKeys, type BrowserChatStorageOptions, type ChatMsg, type ChatStorage, type ChatTransport, type ChatTransportChunkHandler, type ChatTransportChunkSource, type ChatTransportContext, type ContentPiece, type CreateRouteChatTransportArgs, type HumanInputPiece, type LiveChatErrorPiece, type LiveChatPiece, type LiveChatStructuredPiece, type LiveChatTextPiece, type OutgoingChatMessage, type PersistedChatState, type PrepareContextMessages, type PrepareContextMessagesArgs, type RouteChatRequestBody, type StructuredData, type StructuredStreamItem, type ToHumanInputPiece, type UseChatOptions, type UseChatValue, type UseStructuredStreamsOptions, type UseStructuredStreamsResult, buildAssistantMessage, createBrowserChatStorage, createChatTransport, createLiveChatPieces, createRouteChatTransport, toHumanInputPiece, useChat, useChatStreamDebug, useStructuredStreams };
|
package/dist/index.js
CHANGED
|
@@ -277,11 +277,29 @@ function createLiveChatPieces(args) {
|
|
|
277
277
|
}
|
|
278
278
|
|
|
279
279
|
// src/to-human-input-piece.ts
|
|
280
|
+
var isRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
281
|
+
var nonEmptyString = (value) => typeof value === "string" && value.length > 0 ? value : void 0;
|
|
282
|
+
var firstNonEmptyString = (...values) => {
|
|
283
|
+
for (const value of values) {
|
|
284
|
+
const result = nonEmptyString(value);
|
|
285
|
+
if (result) return result;
|
|
286
|
+
}
|
|
287
|
+
return void 0;
|
|
288
|
+
};
|
|
280
289
|
function toHumanInputPiece(args) {
|
|
281
290
|
const hi = args.chunk;
|
|
282
291
|
const input = hi.input ?? {};
|
|
283
292
|
const kind = input.kind || (input.multiple ? "multi-choice" : "choice");
|
|
284
293
|
const isText = kind === "text";
|
|
294
|
+
const schemaId = firstNonEmptyString(hi.schemaId, input.schemaId);
|
|
295
|
+
const schemaVersion = firstNonEmptyString(
|
|
296
|
+
hi.schemaVersion,
|
|
297
|
+
input.schemaVersion
|
|
298
|
+
);
|
|
299
|
+
const interruptId = firstNonEmptyString(hi.id, input.id);
|
|
300
|
+
const inputMeta = isRecord(input.meta) ? input.meta : void 0;
|
|
301
|
+
const chunkMeta = isRecord(hi.meta) ? hi.meta : void 0;
|
|
302
|
+
const meta = inputMeta || chunkMeta ? { ...inputMeta ?? {}, ...chunkMeta ?? {} } : void 0;
|
|
285
303
|
const question = isText ? input.question : typeof input.question === "string" ? input.question : "Please choose";
|
|
286
304
|
const optionsSrc = Array.isArray(input.options) ? input.options : [];
|
|
287
305
|
const optionsArr = optionsSrc.map((option) => ({
|
|
@@ -297,7 +315,11 @@ function toHumanInputPiece(args) {
|
|
|
297
315
|
kind,
|
|
298
316
|
...question !== void 0 ? { question } : {},
|
|
299
317
|
multiple: Boolean(input.multiple),
|
|
300
|
-
options: optionsArr
|
|
318
|
+
options: optionsArr,
|
|
319
|
+
...schemaId ? { schemaId } : {},
|
|
320
|
+
...schemaVersion ? { schemaVersion } : {},
|
|
321
|
+
...interruptId ? { interruptId } : {},
|
|
322
|
+
...meta ? { meta } : {}
|
|
301
323
|
};
|
|
302
324
|
}
|
|
303
325
|
|
|
@@ -463,6 +485,9 @@ function useChat(options) {
|
|
|
463
485
|
const resolvedStorage = options.storage ?? defaultStorage;
|
|
464
486
|
const transportRef = useLatestRef(options.transport);
|
|
465
487
|
const storageRef = useLatestRef(resolvedStorage);
|
|
488
|
+
const toHumanInputPieceRef = useLatestRef(
|
|
489
|
+
options.toHumanInputPiece ?? toHumanInputPiece
|
|
490
|
+
);
|
|
466
491
|
const requestContext = options.context ?? {};
|
|
467
492
|
const createId = (0, import_react3.useRef)(options.createId ?? defaultCreateId2).current;
|
|
468
493
|
const [messages, setMessages] = (0, import_react3.useState)([]);
|
|
@@ -581,7 +606,7 @@ function useChat(options) {
|
|
|
581
606
|
structuredStreams: {
|
|
582
607
|
applyStreamChunk
|
|
583
608
|
},
|
|
584
|
-
toHumanInputPiece: (chunk) =>
|
|
609
|
+
toHumanInputPiece: (chunk) => toHumanInputPieceRef.current({
|
|
585
610
|
chunk,
|
|
586
611
|
createId
|
|
587
612
|
})
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/build-assistant-message.ts","../src/chat-storage.ts","../src/chat-transport.ts","../src/create-live-chat-pieces.ts","../src/to-human-input-piece.ts","../src/use-chat.ts","../src/use-chat-stream-debug.ts","../src/use-structured-streams.ts"],"sourcesContent":["export * from \"./build-assistant-message\";\nexport * from \"./chat-storage\";\nexport * from \"./chat-transport\";\nexport * from \"./chat-types\";\nexport * from \"./create-live-chat-pieces\";\nexport * from \"./to-human-input-piece\";\nexport * from \"./use-chat\";\nexport * from \"./use-chat-stream-debug\";\nexport * from \"./use-structured-streams\";\n","import type { StreamChunk } from \"@kortyx/stream/browser\";\nimport type { ChatMsg, ContentPiece } from \"./chat-types\";\n\nexport function buildAssistantMessage(args: {\n createId: () => string;\n pieces: ContentPiece[];\n debug: StreamChunk[];\n}): ChatMsg {\n const plainTextContent = args.pieces\n .filter(\n (piece): piece is Extract<ContentPiece, { type: \"text\" }> =>\n piece.type === \"text\",\n )\n .map((piece) => piece.content)\n .join(\"\");\n\n const base = {\n id: args.createId(),\n role: \"assistant\" as const,\n content: plainTextContent,\n debug: args.debug,\n };\n\n return args.pieces.length > 0\n ? { ...base, contentPieces: args.pieces }\n : base;\n}\n","type MaybePromise<T> = T | Promise<T>;\ntype StorageLike = {\n getItem: (key: string) => string | null;\n setItem: (key: string, value: string) => void;\n removeItem: (key: string) => void;\n};\n\nexport type PersistedChatState<TMessage> = {\n sessionId: string | null;\n workflowId: string;\n includeHistory: boolean;\n messages: TMessage[];\n};\n\nexport type ChatStorage<TMessage> = {\n load: () => MaybePromise<Partial<PersistedChatState<TMessage>>>;\n save: (state: PersistedChatState<TMessage>) => MaybePromise<void>;\n clearMessages: () => MaybePromise<void>;\n};\n\nexport type BrowserChatStorageKeys = {\n messages: string;\n includeHistory: string;\n sessionId: string;\n workflowId: string;\n};\n\nexport type BrowserChatStorageOptions<TMessage> = {\n parseMessage?: ((value: unknown) => TMessage | null) | undefined;\n serializeMessage?: ((message: TMessage) => unknown) | undefined;\n maxMessages?: number | undefined;\n keys?: Partial<BrowserChatStorageKeys> | undefined;\n};\n\nconst DEFAULT_STORAGE_KEYS: BrowserChatStorageKeys = {\n messages: \"chat.messages.v1\",\n includeHistory: \"chat.includeHistory.v1\",\n sessionId: \"chat.sessionId\",\n workflowId: \"chat.workflowId\",\n};\n\nconst getLocalStorage = (): StorageLike | undefined => {\n const candidate = globalThis as { localStorage?: StorageLike };\n return candidate.localStorage;\n};\n\nconst defaultParseMessage = <TMessage>(value: unknown): TMessage | null =>\n value as TMessage;\n\nconst defaultSerializeMessage = <TMessage>(message: TMessage): unknown =>\n message;\n\n// TODO: Make remote/custom persistence more robust before freezing this API:\n// - add debouncing so repeated message updates do not trigger a full save each time\n// - surface save error handling/retry hooks instead of silently ignoring failures\n// - define a conflict/version strategy for multi-tab and server-synced storage\n// - support partial saves instead of rewriting the full persisted state on each change\nexport function createBrowserChatStorage<TMessage = unknown>(\n options?: BrowserChatStorageOptions<TMessage>,\n): ChatStorage<TMessage> {\n const keys = {\n ...DEFAULT_STORAGE_KEYS,\n ...(options?.keys ?? {}),\n };\n const maxMessages = options?.maxMessages ?? 60;\n const parseMessage = options?.parseMessage ?? defaultParseMessage<TMessage>;\n const serializeMessage =\n options?.serializeMessage ?? defaultSerializeMessage<TMessage>;\n\n return {\n load() {\n try {\n const storage = getLocalStorage();\n if (!storage) {\n return {};\n }\n\n const sessionId = storage.getItem(keys.sessionId);\n const workflowId = storage.getItem(keys.workflowId) ?? \"\";\n const includeHistoryRaw = storage.getItem(keys.includeHistory);\n const rawMessages = storage.getItem(keys.messages);\n const parsedMessages = rawMessages\n ? (JSON.parse(rawMessages) as unknown)\n : [];\n const messages = Array.isArray(parsedMessages)\n ? parsedMessages\n .map((item) => parseMessage(item))\n .filter((message): message is TMessage => message !== null)\n : [];\n\n return {\n sessionId,\n workflowId,\n includeHistory: includeHistoryRaw !== \"0\",\n messages,\n };\n } catch {\n return {};\n }\n },\n\n save(state) {\n try {\n const storage = getLocalStorage();\n if (!storage) return;\n\n if (state.sessionId) {\n storage.setItem(keys.sessionId, state.sessionId);\n } else {\n storage.removeItem(keys.sessionId);\n }\n\n storage.setItem(keys.workflowId, state.workflowId);\n storage.setItem(keys.includeHistory, state.includeHistory ? \"1\" : \"0\");\n\n const trimmedMessages = state.messages\n .slice(-maxMessages)\n .map((message) => serializeMessage(message));\n\n storage.setItem(keys.messages, JSON.stringify(trimmedMessages));\n } catch {}\n },\n\n clearMessages() {\n try {\n const storage = getLocalStorage();\n if (!storage) return;\n storage.removeItem(keys.messages);\n } catch {}\n },\n };\n}\n","import type { StreamChunk, StreamFromRouteArgs } from \"@kortyx/stream/browser\";\nimport { streamFromRoute } from \"@kortyx/stream/browser\";\n\ntype MaybePromise<T> = T | Promise<T>;\ntype DefaultChatContext = Record<string, unknown>;\n\nexport type OutgoingChatMessage = {\n role: \"user\" | \"assistant\" | \"system\";\n content: string;\n metadata?: Record<string, unknown>;\n};\n\nexport type ChatTransportContext<TContext = DefaultChatContext> = {\n sessionId: string;\n workflowId: string;\n messages: OutgoingChatMessage[];\n context: TContext;\n signal?: AbortSignal | undefined;\n};\n\nexport type ChatTransportChunkHandler = (\n chunk: StreamChunk,\n) => undefined | boolean | Promise<boolean | undefined>;\n\nexport type ChatTransport<TContext = DefaultChatContext> = {\n stream(\n args: ChatTransportContext<TContext> & {\n onChunk: ChatTransportChunkHandler;\n },\n ): Promise<void>;\n};\n\nexport type ChatTransportChunkSource =\n | Iterable<StreamChunk>\n | AsyncIterable<StreamChunk>;\n\nexport function createChatTransport<TContext = DefaultChatContext>(args: {\n stream: (\n context: ChatTransportContext<TContext>,\n ) => MaybePromise<ChatTransportChunkSource>;\n}): ChatTransport<TContext> {\n return {\n async stream({ onChunk, ...context }) {\n for await (const chunk of await args.stream(context)) {\n const shouldContinue = await onChunk(chunk);\n if (chunk.type === \"done\" || shouldContinue === false) {\n break;\n }\n }\n },\n };\n}\n\nexport type RouteChatRequestBody<TContext = DefaultChatContext> = {\n sessionId: string;\n workflowId: string;\n messages: OutgoingChatMessage[];\n context: TContext;\n};\n\nexport type CreateRouteChatTransportArgs<TBody, TContext> = Omit<\n StreamFromRouteArgs<TBody>,\n \"body\"\n> & {\n createBody?: ((context: ChatTransportContext<TContext>) => TBody) | undefined;\n};\n\nexport function createRouteChatTransport<\n TContext = DefaultChatContext,\n TBody = RouteChatRequestBody<TContext>,\n>(\n args: CreateRouteChatTransportArgs<TBody, TContext>,\n): ChatTransport<TContext> {\n return createChatTransport<TContext>({\n stream: (context) => {\n const body =\n args.createBody?.(context) ??\n ({\n sessionId: context.sessionId,\n workflowId: context.workflowId,\n messages: context.messages,\n context: context.context,\n } as TBody);\n const routeArgs: StreamFromRouteArgs<TBody> = {\n endpoint: args.endpoint,\n body,\n ...(args.method ? { method: args.method } : {}),\n ...(args.headers ? { headers: args.headers } : {}),\n ...(args.fetchImpl ? { fetchImpl: args.fetchImpl } : {}),\n ...(context.signal ? { signal: context.signal } : {}),\n };\n\n return streamFromRoute({\n ...routeArgs,\n });\n },\n });\n}\n","import type {\n StreamChunk,\n StructuredStreamState,\n} from \"@kortyx/stream/browser\";\nimport type { StructuredStreamItem } from \"./use-structured-streams\";\n\nexport type LiveChatTextPiece = {\n id: string;\n type: \"text\";\n content: string;\n};\n\nexport type LiveChatStructuredPiece<TStructuredData = unknown> = {\n id: string;\n type: \"structured\";\n data: StructuredStreamState<TStructuredData>;\n};\n\nexport type LiveChatErrorPiece = {\n id: string;\n type: \"error\";\n content: string;\n};\n\ntype LiveChatCustomPiece = {\n id: string;\n type: string;\n};\n\nexport type LiveChatPiece<\n TStructuredData = unknown,\n TCustomPiece extends LiveChatCustomPiece = never,\n> =\n | LiveChatTextPiece\n | LiveChatStructuredPiece<TStructuredData>\n | LiveChatErrorPiece\n | TCustomPiece;\n\ntype StructuredStreamsController<TStructuredData> = {\n applyStreamChunk: (\n chunk: StreamChunk,\n ) => StructuredStreamItem<TStructuredData> | undefined;\n};\n\nconst isNonEmptyTextPiece = <\n TStructuredData,\n TCustomPiece extends LiveChatCustomPiece,\n>(\n piece: LiveChatPiece<TStructuredData, TCustomPiece>,\n) =>\n piece.type !== \"text\" ||\n (\"content\" in piece &&\n typeof piece.content === \"string\" &&\n piece.content.length > 0);\n\nexport function createLiveChatPieces<\n TStructuredData = unknown,\n TCustomPiece extends LiveChatCustomPiece = never,\n>(args: {\n createId: () => string;\n onChange: (pieces: LiveChatPiece<TStructuredData, TCustomPiece>[]) => void;\n structuredStreams: StructuredStreamsController<TStructuredData>;\n toHumanInputPiece: (chunk: StreamChunk) => TCustomPiece;\n}) {\n const keyedPieces: Array<{\n key: string;\n piece: LiveChatPiece<TStructuredData, TCustomPiece>;\n }> = [];\n let sawTextDelta = false;\n\n const emit = () => {\n args.onChange(\n keyedPieces\n .map((entry) => entry.piece)\n .filter((piece) => isNonEmptyTextPiece(piece)),\n );\n };\n\n const findPieceIndex = (key: string) =>\n keyedPieces.findIndex((entry) => entry.key === key);\n\n const upsertPiece = (\n key: string,\n piece: LiveChatPiece<TStructuredData, TCustomPiece>,\n ) => {\n const existingIndex = findPieceIndex(key);\n if (existingIndex >= 0) {\n keyedPieces[existingIndex] = { key, piece };\n } else {\n keyedPieces.push({ key, piece });\n }\n emit();\n };\n\n const pushPiece = (piece: LiveChatPiece<TStructuredData, TCustomPiece>) => {\n keyedPieces.push({\n key: `${piece.type}:${piece.id}`,\n piece,\n });\n emit();\n };\n\n const resolveTextStreamKey = (\n chunk: StreamChunk,\n fallbackNode?: string,\n ): string => {\n if (\"segmentId\" in chunk && typeof chunk.segmentId === \"string\") {\n const seg = chunk.segmentId.trim();\n if (seg.length > 0) {\n const op =\n \"opId\" in chunk && typeof chunk.opId === \"string\"\n ? chunk.opId.trim()\n : \"\";\n return op.length > 0 ? `${op}:${seg}` : seg;\n }\n }\n\n if (\"opId\" in chunk && typeof chunk.opId === \"string\") {\n const op = chunk.opId.trim();\n if (op.length > 0) {\n const node =\n (\"node\" in chunk && typeof chunk.node === \"string\"\n ? chunk.node\n : fallbackNode) ?? \"__unknown__\";\n return `${op}:${node}`;\n }\n }\n\n return fallbackNode && fallbackNode.length > 0\n ? fallbackNode\n : \"__unknown__\";\n };\n\n const ensureTextPiece = (key: string): LiveChatTextPiece => {\n const pieceKey = `text:${key}`;\n const existingIndex = findPieceIndex(pieceKey);\n if (existingIndex >= 0) {\n return keyedPieces[existingIndex]?.piece as LiveChatTextPiece;\n }\n\n const nextPiece: LiveChatTextPiece = {\n id: args.createId(),\n type: \"text\",\n content: \"\",\n };\n keyedPieces.push({ key: pieceKey, piece: nextPiece });\n return nextPiece;\n };\n\n const processChunk = (\n chunk: StreamChunk,\n _options?: { openDebugOnInterrupt?: boolean | undefined },\n ): boolean => {\n if (chunk.type === \"text-start\") {\n ensureTextPiece(resolveTextStreamKey(chunk, chunk.node));\n emit();\n return true;\n }\n\n if (chunk.type === \"text-delta\") {\n sawTextDelta = true;\n const streamKey = resolveTextStreamKey(chunk, chunk.node);\n const current = ensureTextPiece(streamKey);\n upsertPiece(`text:${streamKey}`, {\n ...current,\n content: current.content + chunk.delta,\n });\n return true;\n }\n\n if (chunk.type === \"text-end\") {\n emit();\n return true;\n }\n\n if (chunk.type === \"structured-data\") {\n const nextItem = args.structuredStreams.applyStreamChunk(chunk);\n if (nextItem) {\n upsertPiece(`structured:${nextItem.streamId}`, {\n id: nextItem.id,\n type: \"structured\",\n data: nextItem.state,\n });\n }\n return true;\n }\n\n if (chunk.type === \"interrupt\") {\n pushPiece(args.toHumanInputPiece(chunk));\n return true;\n }\n\n if (chunk.type === \"message\") {\n if (!sawTextDelta) {\n pushPiece({\n id: args.createId(),\n type: \"text\",\n content: chunk.content ?? \"\",\n });\n }\n return true;\n }\n\n if (chunk.type === \"error\") {\n pushPiece({\n id: args.createId(),\n type: \"error\",\n content: chunk.message ?? \"An error occurred\",\n });\n return true;\n }\n\n if (chunk.type === \"done\") {\n return false;\n }\n\n return true;\n };\n\n return {\n processChunk,\n getPieces: () =>\n keyedPieces\n .map((entry) => entry.piece)\n .filter((piece) => isNonEmptyTextPiece(piece)),\n };\n}\n","import type { StreamChunk } from \"@kortyx/stream/browser\";\nimport type { HumanInputPiece } from \"./chat-types\";\n\ninterface HumanInputStreamChunk {\n type: \"interrupt\";\n requestId: string | undefined;\n resumeToken: string | undefined;\n input?: {\n kind?: \"text\" | \"choice\" | \"multi-choice\";\n question?: string;\n multiple?: boolean;\n options?: Array<{\n id?: string | number;\n label?: string;\n description?: string;\n }>;\n };\n}\n\nexport function toHumanInputPiece(args: {\n chunk: StreamChunk;\n createId: () => string;\n}): HumanInputPiece {\n const hi = args.chunk as unknown as HumanInputStreamChunk;\n const input = hi.input ?? {};\n const kind = input.kind || (input.multiple ? \"multi-choice\" : \"choice\");\n const isText = kind === \"text\";\n\n const question = isText\n ? input.question\n : typeof input.question === \"string\"\n ? input.question\n : \"Please choose\";\n\n const optionsSrc = Array.isArray(input.options) ? input.options : [];\n const optionsArr: Array<{\n id: string;\n label: string;\n description?: string;\n }> = optionsSrc\n .map((option) => ({\n id: String(option.id ?? \"\"),\n label: String(option.label ?? \"\"),\n ...(typeof option.description === \"string\" && option.description\n ? { description: option.description }\n : {}),\n }))\n .filter((option) => option.id && option.label);\n\n return {\n id: args.createId(),\n type: \"interrupt\",\n resumeToken: String(hi.resumeToken ?? \"\"),\n requestId: String(hi.requestId ?? \"\"),\n kind,\n ...(question !== undefined ? { question } : {}),\n multiple: Boolean(input.multiple),\n options: optionsArr,\n };\n}\n","\"use client\";\n\nimport type { StreamChunk } from \"@kortyx/stream/browser\";\nimport { type RefObject, useEffect, useRef, useState } from \"react\";\nimport { buildAssistantMessage } from \"./build-assistant-message\";\nimport { type ChatStorage, createBrowserChatStorage } from \"./chat-storage\";\nimport type { ChatTransport, OutgoingChatMessage } from \"./chat-transport\";\nimport type { ChatMsg, ContentPiece, HumanInputPiece } from \"./chat-types\";\nimport { createLiveChatPieces } from \"./create-live-chat-pieces\";\nimport { toHumanInputPiece } from \"./to-human-input-piece\";\nimport { useChatStreamDebug } from \"./use-chat-stream-debug\";\nimport { useStructuredStreams } from \"./use-structured-streams\";\n\nconst defaultCreateId = () => {\n try {\n if (typeof crypto !== \"undefined\" && \"randomUUID\" in crypto) {\n return crypto.randomUUID();\n }\n } catch {}\n return `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n};\n\ntype DefaultChatContext = Record<string, unknown>;\n\nexport type PrepareContextMessagesArgs<TContext = DefaultChatContext> = {\n messages: ChatMsg[];\n sessionId: string;\n workflowId: string;\n reason: \"send\" | \"resume\";\n context: TContext;\n};\n\nexport type PrepareContextMessages<TContext = DefaultChatContext> = (\n args: PrepareContextMessagesArgs<TContext>,\n) => OutgoingChatMessage[] | Promise<OutgoingChatMessage[]>;\n\nexport type UseChatValue = {\n messages: ChatMsg[];\n isStreaming: boolean;\n canAbort: boolean;\n error: Error | null;\n streamContentPieces: ContentPiece[];\n streamDebug: StreamChunk[];\n lastAssistantId: string | null;\n workflowId: string;\n setWorkflowId: React.Dispatch<React.SetStateAction<string>>;\n send: (text: string) => Promise<void> | void;\n respondToHumanInput: (args: {\n resumeToken: string;\n requestId: string;\n selected: string[];\n text?: string;\n }) => Promise<void> | void;\n respondToInterrupt: (\n piece: HumanInputPiece,\n response?: { selected?: string[] | undefined; text?: string | undefined },\n ) => Promise<void> | void;\n setMessages: React.Dispatch<React.SetStateAction<ChatMsg[]>>;\n clearMessages: () => void;\n resetSession: () => void;\n resetChat: () => void;\n clearChat: () => void;\n abort: () => void;\n clearError: () => void;\n includeHistory: boolean;\n setIncludeHistory: React.Dispatch<React.SetStateAction<boolean>>;\n};\n\nexport type UseChatOptions<TContext = DefaultChatContext> = {\n transport: ChatTransport<TContext>;\n storage?: ChatStorage<ChatMsg> | undefined;\n createId?: (() => string) | undefined;\n context?: TContext | undefined;\n prepareContextMessages?: PrepareContextMessages<TContext> | undefined;\n};\n\nconst defaultStorage = createBrowserChatStorage<ChatMsg>();\n\nfunction useLatestRef<T>(value: T): RefObject<T> {\n const ref = useRef(value);\n ref.current = value;\n return ref;\n}\n\nfunction findActiveTextInterrupt(args: {\n messages: ChatMsg[];\n streamContentPieces: ContentPiece[];\n}): HumanInputPiece | undefined {\n const liveInterrupt = args.streamContentPieces.find(\n (piece): piece is HumanInputPiece =>\n piece.type === \"interrupt\" && piece.kind === \"text\",\n );\n if (liveInterrupt) return liveInterrupt;\n\n for (const message of [...args.messages].reverse()) {\n if (message.role !== \"assistant\" || !message.contentPieces) continue;\n\n const messageInterrupt = [...message.contentPieces]\n .reverse()\n .find(\n (piece): piece is HumanInputPiece =>\n piece.type === \"interrupt\" && piece.kind === \"text\",\n );\n if (messageInterrupt) return messageInterrupt;\n }\n\n return undefined;\n}\n\nexport function useChat<TContext = DefaultChatContext>(\n options: UseChatOptions<TContext>,\n): UseChatValue {\n const resolvedStorage = options.storage ?? defaultStorage;\n const transportRef = useLatestRef(options.transport);\n const storageRef = useLatestRef(resolvedStorage);\n const requestContext =\n options.context ?? ({} as unknown as NonNullable<TContext>);\n const createId = useRef(options.createId ?? defaultCreateId).current;\n\n const [messages, setMessages] = useState<ChatMsg[]>([]);\n const [isStreaming, setIsStreaming] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [streamContentPieces, setStreamContentPieces] = useState<\n ContentPiece[]\n >([]);\n const [lastAssistantId, setLastAssistantId] = useState<string | null>(null);\n const [includeHistory, setIncludeHistory] = useState(true);\n const [workflowId, setWorkflowId] = useState(\"\");\n const [sessionId, setSessionId] = useState<string | null>(null);\n const [didHydrateStorage, setDidHydrateStorage] = useState(false);\n const abortControllerRef = useRef<AbortController | null>(null);\n const { streamDebug, clearStreamDebug, createRecorder } =\n useChatStreamDebug();\n const { applyStreamChunk, clear: clearStructuredStreams } =\n useStructuredStreams<Record<string, unknown>>({\n createId,\n });\n\n useEffect(() => {\n let cancelled = false;\n const storage = resolvedStorage;\n\n void Promise.resolve(storage.load()).then((storedState) => {\n if (cancelled) return;\n\n if (typeof storedState.sessionId === \"string\") {\n setSessionId(storedState.sessionId);\n }\n if (typeof storedState.workflowId === \"string\") {\n setWorkflowId(storedState.workflowId);\n }\n if (typeof storedState.includeHistory === \"boolean\") {\n setIncludeHistory(storedState.includeHistory);\n }\n if (\n Array.isArray(storedState.messages) &&\n storedState.messages.length > 0\n ) {\n setMessages(storedState.messages);\n }\n\n setDidHydrateStorage(true);\n });\n\n return () => {\n cancelled = true;\n };\n }, [resolvedStorage]);\n\n useEffect(() => {\n if (!didHydrateStorage) return;\n const storage = storageRef.current;\n\n void storage.save({\n sessionId,\n workflowId,\n includeHistory,\n messages,\n });\n }, [\n didHydrateStorage,\n includeHistory,\n messages,\n sessionId,\n storageRef,\n workflowId,\n ]);\n\n const clearActiveStream = () => {\n abortControllerRef.current?.abort();\n abortControllerRef.current = null;\n setIsStreaming(false);\n setMessages([]);\n setStreamContentPieces([]);\n clearStreamDebug();\n clearStructuredStreams();\n setLastAssistantId(null);\n };\n\n const clearMessages = () => {\n clearActiveStream();\n void storageRef.current.clearMessages();\n };\n\n const resetSession = () => {\n setSessionId(null);\n };\n\n const resetChat = () => {\n clearActiveStream();\n resetSession();\n setError(null);\n void storageRef.current.clearMessages();\n };\n\n const clearChat = resetChat;\n\n const clearError = () => {\n setError(null);\n };\n\n const abort = () => {\n abortControllerRef.current?.abort();\n };\n\n const persistSessionId = (sid: string) => {\n setSessionId(sid);\n };\n\n const resolveSessionId = () => {\n const sid = sessionId ?? createId();\n if (!sessionId) persistSessionId(sid);\n return sid;\n };\n\n const toOutgoingHistoryMessage = (message: ChatMsg): OutgoingChatMessage => ({\n role: message.role,\n content: message.content,\n });\n\n const prepareMessagesToSend = async (args: {\n sid: string;\n outgoingMessage: OutgoingChatMessage;\n reason: \"send\" | \"resume\";\n }): Promise<OutgoingChatMessage[]> => {\n const prepared = options.prepareContextMessages\n ? await options.prepareContextMessages({\n messages,\n sessionId: args.sid,\n workflowId,\n reason: args.reason,\n context: requestContext,\n })\n : includeHistory\n ? messages.map(toOutgoingHistoryMessage)\n : [];\n\n return [...prepared, args.outgoingMessage];\n };\n\n const streamAssistantResponse = async (args: {\n sid: string;\n messagesToSend: OutgoingChatMessage[];\n debugLabel: string;\n openDebugOnInterrupt?: boolean;\n signal: AbortSignal;\n }) => {\n clearStructuredStreams();\n setStreamContentPieces([]);\n\n const debug = createRecorder(`${args.debugLabel} sessionId=${args.sid}`);\n const pieces = createLiveChatPieces({\n createId,\n onChange: setStreamContentPieces,\n structuredStreams: {\n applyStreamChunk,\n },\n toHumanInputPiece: (chunk) =>\n toHumanInputPiece({\n chunk,\n createId,\n }),\n });\n\n await transportRef.current.stream({\n sessionId: args.sid,\n workflowId,\n messages: args.messagesToSend,\n context: requestContext,\n signal: args.signal,\n onChunk: (chunk: StreamChunk) => {\n debug.push(chunk);\n\n if (chunk.type === \"session\") {\n if (typeof chunk.sessionId === \"string\") {\n persistSessionId(chunk.sessionId);\n }\n return;\n }\n\n if (chunk.type === \"error\") {\n setError(new Error(chunk.message));\n }\n\n return pieces.processChunk(chunk, {\n openDebugOnInterrupt: args.openDebugOnInterrupt,\n });\n },\n });\n\n if (args.signal.aborted) return;\n\n const assistant = buildAssistantMessage({\n createId,\n pieces: pieces.getPieces(),\n debug: debug.getAll(),\n });\n setMessages((prev) => [...prev, assistant]);\n setLastAssistantId(assistant.id);\n clearStructuredStreams();\n setStreamContentPieces([]);\n clearStreamDebug();\n };\n\n const isAbortError = (value: unknown, signal: AbortSignal): boolean => {\n if (signal.aborted) return true;\n if (!(value instanceof Error)) return false;\n return value.name === \"AbortError\";\n };\n\n const respondToHumanInput = async ({\n resumeToken,\n requestId,\n selected,\n text,\n }: {\n resumeToken: string;\n requestId: string;\n selected: string[];\n text?: string;\n }) => {\n if (isStreaming) return;\n setError(null);\n const label: string =\n typeof text === \"string\" && text.length > 0\n ? text\n : selected.length > 0\n ? selected.length === 1\n ? (selected[0] as string)\n : selected.join(\", \")\n : \"(selection)\";\n const userId = createId();\n const userMsg: ChatMsg = { id: userId, role: \"user\", content: label };\n setMessages((prev) => [...prev, userMsg]);\n setIsStreaming(true);\n setStreamContentPieces([]);\n clearStreamDebug();\n clearStructuredStreams();\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n try {\n const resumePayload: Record<string, unknown> = {\n resume: { token: resumeToken, requestId, selected },\n };\n const outgoing = {\n role: \"user\" as const,\n content: label,\n metadata: resumePayload,\n };\n const sid = resolveSessionId();\n const messagesToSend = await prepareMessagesToSend({\n sid,\n outgoingMessage: outgoing,\n reason: \"resume\",\n });\n\n await streamAssistantResponse({\n sid,\n messagesToSend,\n debugLabel: \"runChat (resume)\",\n signal: abortController.signal,\n });\n } catch (err) {\n if (isAbortError(err, abortController.signal)) return;\n const nextError = err instanceof Error ? err : new Error(String(err));\n setError(nextError);\n throw err;\n } finally {\n if (abortControllerRef.current === abortController) {\n abortControllerRef.current = null;\n }\n setIsStreaming(false);\n }\n };\n\n const respondToInterrupt = async (\n piece: HumanInputPiece,\n response?: { selected?: string[] | undefined; text?: string | undefined },\n ) => {\n const text = response?.text;\n const selected =\n response?.selected ??\n (typeof text === \"string\" && text.length > 0 ? [text] : []);\n\n return respondToHumanInput({\n resumeToken: piece.resumeToken,\n requestId: piece.requestId,\n selected,\n ...(text !== undefined ? { text } : {}),\n });\n };\n\n const send = async (text: string) => {\n const content = text.trim();\n if (!content || isStreaming) return;\n setError(null);\n\n const activeTextInterrupt = findActiveTextInterrupt({\n messages,\n streamContentPieces,\n });\n\n if (activeTextInterrupt) {\n await respondToHumanInput({\n resumeToken: activeTextInterrupt.resumeToken,\n requestId: activeTextInterrupt.requestId,\n selected: [content],\n text: content,\n });\n return;\n }\n\n const userId = createId();\n const userMsg: ChatMsg = { id: userId, role: \"user\", content };\n setMessages((prev) => [...prev, userMsg]);\n\n setIsStreaming(true);\n setStreamContentPieces([]);\n clearStreamDebug();\n clearStructuredStreams();\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n try {\n const sid = resolveSessionId();\n const messagesToSend = await prepareMessagesToSend({\n sid,\n outgoingMessage: { role: \"user\" as const, content },\n reason: \"send\",\n });\n await streamAssistantResponse({\n sid,\n messagesToSend,\n debugLabel: \"runChat (send)\",\n openDebugOnInterrupt: true,\n signal: abortController.signal,\n });\n } catch (err) {\n if (isAbortError(err, abortController.signal)) return;\n const nextError = err instanceof Error ? err : new Error(String(err));\n setError(nextError);\n throw err;\n } finally {\n if (abortControllerRef.current === abortController) {\n abortControllerRef.current = null;\n }\n setIsStreaming(false);\n }\n };\n\n return {\n messages,\n isStreaming,\n canAbort: isStreaming,\n error,\n streamContentPieces,\n streamDebug,\n lastAssistantId,\n workflowId,\n setWorkflowId,\n send,\n respondToHumanInput,\n respondToInterrupt,\n setMessages,\n clearMessages,\n resetSession,\n resetChat,\n clearChat,\n abort,\n clearError,\n includeHistory,\n setIncludeHistory,\n };\n}\n","\"use client\";\n\nimport type { StreamChunk } from \"@kortyx/stream/browser\";\nimport { useCallback, useState } from \"react\";\n\ntype DebugChunk = StreamChunk & {\n _ts: number;\n _dt: number;\n _seq: number;\n};\n\nexport function useChatStreamDebug() {\n const [streamDebug, setStreamDebug] = useState<StreamChunk[]>([]);\n\n const clearStreamDebug = useCallback(() => {\n setStreamDebug([]);\n }, []);\n\n const createRecorder = useCallback((initialMessage: string) => {\n let seq = 0;\n let lastTs = 0;\n const accDebug: StreamChunk[] = [];\n\n const push = (chunk: StreamChunk) => {\n const ts = Date.now();\n const withMeta: DebugChunk = {\n ...(chunk as StreamChunk),\n _ts: ts,\n _dt: lastTs ? ts - lastTs : 0,\n _seq: seq++,\n };\n lastTs = ts;\n accDebug.push(withMeta);\n setStreamDebug((current) =>\n current.length > 1000\n ? [...current.slice(-1000), withMeta]\n : [...current, withMeta],\n );\n };\n\n push({\n type: \"status\",\n message: initialMessage,\n } as StreamChunk);\n\n return {\n push,\n getAll: () => accDebug,\n };\n }, []);\n\n return {\n streamDebug,\n clearStreamDebug,\n createRecorder,\n };\n}\n","import {\n createStructuredStreamAccumulator,\n type StreamChunk,\n type StructuredDataChunk,\n type StructuredStreamState,\n} from \"@kortyx/stream/browser\";\nimport { useCallback, useMemo, useRef, useState } from \"react\";\n\nexport type StructuredStreamItem<TData = unknown> = {\n id: string;\n streamId: string;\n state: StructuredStreamState<TData>;\n};\n\nexport type UseStructuredStreamsOptions<_TData = unknown> = {\n createId?: (() => string) | undefined;\n initialChunks?: Iterable<StructuredDataChunk> | undefined;\n};\n\nexport type UseStructuredStreamsResult<TData = unknown> = {\n items: StructuredStreamItem<TData>[];\n byStreamId: Record<string, StructuredStreamState<TData>>;\n applyStreamChunk: (\n chunk: StreamChunk,\n ) => StructuredStreamItem<TData> | undefined;\n clear: () => void;\n get: (streamId: string) => StructuredStreamItem<TData> | undefined;\n};\n\nconst defaultCreateId = () => {\n try {\n if (typeof crypto !== \"undefined\" && \"randomUUID\" in crypto) {\n return crypto.randomUUID();\n }\n } catch {}\n\n return `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n};\n\nexport function useStructuredStreams<TData = unknown>(\n options?: UseStructuredStreamsOptions<TData> | undefined,\n): UseStructuredStreamsResult<TData> {\n const createId = useRef(options?.createId ?? defaultCreateId).current;\n const initialChunks = useRef(options?.initialChunks ?? []).current;\n const accumulatorRef = useRef(\n createStructuredStreamAccumulator<TData>(initialChunks),\n );\n const initialItemsRef = useRef<StructuredStreamItem<TData>[] | undefined>(\n undefined,\n );\n\n if (initialItemsRef.current === undefined) {\n initialItemsRef.current = accumulatorRef.current\n .entries()\n .map(([streamId, state]) => ({\n id: createId(),\n streamId,\n state,\n }));\n }\n\n const itemsRef = useRef(initialItemsRef.current);\n const [items, setItems] = useState(initialItemsRef.current);\n\n const setNextItems = useCallback(\n (nextItems: StructuredStreamItem<TData>[]) => {\n itemsRef.current = nextItems;\n setItems(nextItems);\n },\n [],\n );\n\n const applyStreamChunk = useCallback(\n (chunk: StreamChunk): StructuredStreamItem<TData> | undefined => {\n const nextState = accumulatorRef.current.applyStreamChunk(chunk);\n if (!nextState) return undefined;\n\n const currentItems = itemsRef.current;\n const existingIndex = currentItems.findIndex(\n (item) => item.streamId === nextState.streamId,\n );\n const existingItem =\n existingIndex >= 0 ? currentItems[existingIndex] : undefined;\n\n const nextItem: StructuredStreamItem<TData> = existingItem\n ? {\n ...existingItem,\n state: nextState,\n }\n : {\n id: createId(),\n streamId: nextState.streamId,\n state: nextState,\n };\n\n const nextItems =\n existingIndex >= 0\n ? currentItems.map((item, index) =>\n index === existingIndex ? nextItem : item,\n )\n : [...currentItems, nextItem];\n\n setNextItems(nextItems);\n return nextItem;\n },\n [createId, setNextItems],\n );\n\n const clear = useCallback(() => {\n accumulatorRef.current = createStructuredStreamAccumulator<TData>();\n setNextItems([]);\n }, [setNextItems]);\n\n const get = useCallback((streamId: string) => {\n return itemsRef.current.find((item) => item.streamId === streamId);\n }, []);\n\n const byStreamId = useMemo(\n () =>\n Object.fromEntries(\n items.map((item) => [item.streamId, item.state]),\n ) as Record<string, StructuredStreamState<TData>>,\n [items],\n );\n\n return {\n items,\n byStreamId,\n applyStreamChunk,\n clear,\n get,\n };\n}\n"],"mappings":"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","names":["import_react","import_browser","import_react","defaultCreateId"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/build-assistant-message.ts","../src/chat-storage.ts","../src/chat-transport.ts","../src/create-live-chat-pieces.ts","../src/to-human-input-piece.ts","../src/use-chat.ts","../src/use-chat-stream-debug.ts","../src/use-structured-streams.ts"],"sourcesContent":["export * from \"./build-assistant-message\";\nexport * from \"./chat-storage\";\nexport * from \"./chat-transport\";\nexport * from \"./chat-types\";\nexport * from \"./create-live-chat-pieces\";\nexport * from \"./to-human-input-piece\";\nexport * from \"./use-chat\";\nexport * from \"./use-chat-stream-debug\";\nexport * from \"./use-structured-streams\";\n","import type { StreamChunk } from \"@kortyx/stream/browser\";\nimport type { ChatMsg, ContentPiece } from \"./chat-types\";\n\nexport function buildAssistantMessage(args: {\n createId: () => string;\n pieces: ContentPiece[];\n debug: StreamChunk[];\n}): ChatMsg {\n const plainTextContent = args.pieces\n .filter(\n (piece): piece is Extract<ContentPiece, { type: \"text\" }> =>\n piece.type === \"text\",\n )\n .map((piece) => piece.content)\n .join(\"\");\n\n const base = {\n id: args.createId(),\n role: \"assistant\" as const,\n content: plainTextContent,\n debug: args.debug,\n };\n\n return args.pieces.length > 0\n ? { ...base, contentPieces: args.pieces }\n : base;\n}\n","type MaybePromise<T> = T | Promise<T>;\ntype StorageLike = {\n getItem: (key: string) => string | null;\n setItem: (key: string, value: string) => void;\n removeItem: (key: string) => void;\n};\n\nexport type PersistedChatState<TMessage> = {\n sessionId: string | null;\n workflowId: string;\n includeHistory: boolean;\n messages: TMessage[];\n};\n\nexport type ChatStorage<TMessage> = {\n load: () => MaybePromise<Partial<PersistedChatState<TMessage>>>;\n save: (state: PersistedChatState<TMessage>) => MaybePromise<void>;\n clearMessages: () => MaybePromise<void>;\n};\n\nexport type BrowserChatStorageKeys = {\n messages: string;\n includeHistory: string;\n sessionId: string;\n workflowId: string;\n};\n\nexport type BrowserChatStorageOptions<TMessage> = {\n parseMessage?: ((value: unknown) => TMessage | null) | undefined;\n serializeMessage?: ((message: TMessage) => unknown) | undefined;\n maxMessages?: number | undefined;\n keys?: Partial<BrowserChatStorageKeys> | undefined;\n};\n\nconst DEFAULT_STORAGE_KEYS: BrowserChatStorageKeys = {\n messages: \"chat.messages.v1\",\n includeHistory: \"chat.includeHistory.v1\",\n sessionId: \"chat.sessionId\",\n workflowId: \"chat.workflowId\",\n};\n\nconst getLocalStorage = (): StorageLike | undefined => {\n const candidate = globalThis as { localStorage?: StorageLike };\n return candidate.localStorage;\n};\n\nconst defaultParseMessage = <TMessage>(value: unknown): TMessage | null =>\n value as TMessage;\n\nconst defaultSerializeMessage = <TMessage>(message: TMessage): unknown =>\n message;\n\n// TODO: Make remote/custom persistence more robust before freezing this API:\n// - add debouncing so repeated message updates do not trigger a full save each time\n// - surface save error handling/retry hooks instead of silently ignoring failures\n// - define a conflict/version strategy for multi-tab and server-synced storage\n// - support partial saves instead of rewriting the full persisted state on each change\nexport function createBrowserChatStorage<TMessage = unknown>(\n options?: BrowserChatStorageOptions<TMessage>,\n): ChatStorage<TMessage> {\n const keys = {\n ...DEFAULT_STORAGE_KEYS,\n ...(options?.keys ?? {}),\n };\n const maxMessages = options?.maxMessages ?? 60;\n const parseMessage = options?.parseMessage ?? defaultParseMessage<TMessage>;\n const serializeMessage =\n options?.serializeMessage ?? defaultSerializeMessage<TMessage>;\n\n return {\n load() {\n try {\n const storage = getLocalStorage();\n if (!storage) {\n return {};\n }\n\n const sessionId = storage.getItem(keys.sessionId);\n const workflowId = storage.getItem(keys.workflowId) ?? \"\";\n const includeHistoryRaw = storage.getItem(keys.includeHistory);\n const rawMessages = storage.getItem(keys.messages);\n const parsedMessages = rawMessages\n ? (JSON.parse(rawMessages) as unknown)\n : [];\n const messages = Array.isArray(parsedMessages)\n ? parsedMessages\n .map((item) => parseMessage(item))\n .filter((message): message is TMessage => message !== null)\n : [];\n\n return {\n sessionId,\n workflowId,\n includeHistory: includeHistoryRaw !== \"0\",\n messages,\n };\n } catch {\n return {};\n }\n },\n\n save(state) {\n try {\n const storage = getLocalStorage();\n if (!storage) return;\n\n if (state.sessionId) {\n storage.setItem(keys.sessionId, state.sessionId);\n } else {\n storage.removeItem(keys.sessionId);\n }\n\n storage.setItem(keys.workflowId, state.workflowId);\n storage.setItem(keys.includeHistory, state.includeHistory ? \"1\" : \"0\");\n\n const trimmedMessages = state.messages\n .slice(-maxMessages)\n .map((message) => serializeMessage(message));\n\n storage.setItem(keys.messages, JSON.stringify(trimmedMessages));\n } catch {}\n },\n\n clearMessages() {\n try {\n const storage = getLocalStorage();\n if (!storage) return;\n storage.removeItem(keys.messages);\n } catch {}\n },\n };\n}\n","import type { StreamChunk, StreamFromRouteArgs } from \"@kortyx/stream/browser\";\nimport { streamFromRoute } from \"@kortyx/stream/browser\";\n\ntype MaybePromise<T> = T | Promise<T>;\ntype DefaultChatContext = Record<string, unknown>;\n\nexport type OutgoingChatMessage = {\n role: \"user\" | \"assistant\" | \"system\";\n content: string;\n metadata?: Record<string, unknown>;\n};\n\nexport type ChatTransportContext<TContext = DefaultChatContext> = {\n sessionId: string;\n workflowId: string;\n messages: OutgoingChatMessage[];\n context: TContext;\n signal?: AbortSignal | undefined;\n};\n\nexport type ChatTransportChunkHandler = (\n chunk: StreamChunk,\n) => undefined | boolean | Promise<boolean | undefined>;\n\nexport type ChatTransport<TContext = DefaultChatContext> = {\n stream(\n args: ChatTransportContext<TContext> & {\n onChunk: ChatTransportChunkHandler;\n },\n ): Promise<void>;\n};\n\nexport type ChatTransportChunkSource =\n | Iterable<StreamChunk>\n | AsyncIterable<StreamChunk>;\n\nexport function createChatTransport<TContext = DefaultChatContext>(args: {\n stream: (\n context: ChatTransportContext<TContext>,\n ) => MaybePromise<ChatTransportChunkSource>;\n}): ChatTransport<TContext> {\n return {\n async stream({ onChunk, ...context }) {\n for await (const chunk of await args.stream(context)) {\n const shouldContinue = await onChunk(chunk);\n if (chunk.type === \"done\" || shouldContinue === false) {\n break;\n }\n }\n },\n };\n}\n\nexport type RouteChatRequestBody<TContext = DefaultChatContext> = {\n sessionId: string;\n workflowId: string;\n messages: OutgoingChatMessage[];\n context: TContext;\n};\n\nexport type CreateRouteChatTransportArgs<TBody, TContext> = Omit<\n StreamFromRouteArgs<TBody>,\n \"body\"\n> & {\n createBody?: ((context: ChatTransportContext<TContext>) => TBody) | undefined;\n};\n\nexport function createRouteChatTransport<\n TContext = DefaultChatContext,\n TBody = RouteChatRequestBody<TContext>,\n>(\n args: CreateRouteChatTransportArgs<TBody, TContext>,\n): ChatTransport<TContext> {\n return createChatTransport<TContext>({\n stream: (context) => {\n const body =\n args.createBody?.(context) ??\n ({\n sessionId: context.sessionId,\n workflowId: context.workflowId,\n messages: context.messages,\n context: context.context,\n } as TBody);\n const routeArgs: StreamFromRouteArgs<TBody> = {\n endpoint: args.endpoint,\n body,\n ...(args.method ? { method: args.method } : {}),\n ...(args.headers ? { headers: args.headers } : {}),\n ...(args.fetchImpl ? { fetchImpl: args.fetchImpl } : {}),\n ...(context.signal ? { signal: context.signal } : {}),\n };\n\n return streamFromRoute({\n ...routeArgs,\n });\n },\n });\n}\n","import type {\n StreamChunk,\n StructuredStreamState,\n} from \"@kortyx/stream/browser\";\nimport type { StructuredStreamItem } from \"./use-structured-streams\";\n\nexport type LiveChatTextPiece = {\n id: string;\n type: \"text\";\n content: string;\n};\n\nexport type LiveChatStructuredPiece<TStructuredData = unknown> = {\n id: string;\n type: \"structured\";\n data: StructuredStreamState<TStructuredData>;\n};\n\nexport type LiveChatErrorPiece = {\n id: string;\n type: \"error\";\n content: string;\n};\n\ntype LiveChatCustomPiece = {\n id: string;\n type: string;\n};\n\nexport type LiveChatPiece<\n TStructuredData = unknown,\n TCustomPiece extends LiveChatCustomPiece = never,\n> =\n | LiveChatTextPiece\n | LiveChatStructuredPiece<TStructuredData>\n | LiveChatErrorPiece\n | TCustomPiece;\n\ntype StructuredStreamsController<TStructuredData> = {\n applyStreamChunk: (\n chunk: StreamChunk,\n ) => StructuredStreamItem<TStructuredData> | undefined;\n};\n\nconst isNonEmptyTextPiece = <\n TStructuredData,\n TCustomPiece extends LiveChatCustomPiece,\n>(\n piece: LiveChatPiece<TStructuredData, TCustomPiece>,\n) =>\n piece.type !== \"text\" ||\n (\"content\" in piece &&\n typeof piece.content === \"string\" &&\n piece.content.length > 0);\n\nexport function createLiveChatPieces<\n TStructuredData = unknown,\n TCustomPiece extends LiveChatCustomPiece = never,\n>(args: {\n createId: () => string;\n onChange: (pieces: LiveChatPiece<TStructuredData, TCustomPiece>[]) => void;\n structuredStreams: StructuredStreamsController<TStructuredData>;\n toHumanInputPiece: (chunk: StreamChunk) => TCustomPiece;\n}) {\n const keyedPieces: Array<{\n key: string;\n piece: LiveChatPiece<TStructuredData, TCustomPiece>;\n }> = [];\n let sawTextDelta = false;\n\n const emit = () => {\n args.onChange(\n keyedPieces\n .map((entry) => entry.piece)\n .filter((piece) => isNonEmptyTextPiece(piece)),\n );\n };\n\n const findPieceIndex = (key: string) =>\n keyedPieces.findIndex((entry) => entry.key === key);\n\n const upsertPiece = (\n key: string,\n piece: LiveChatPiece<TStructuredData, TCustomPiece>,\n ) => {\n const existingIndex = findPieceIndex(key);\n if (existingIndex >= 0) {\n keyedPieces[existingIndex] = { key, piece };\n } else {\n keyedPieces.push({ key, piece });\n }\n emit();\n };\n\n const pushPiece = (piece: LiveChatPiece<TStructuredData, TCustomPiece>) => {\n keyedPieces.push({\n key: `${piece.type}:${piece.id}`,\n piece,\n });\n emit();\n };\n\n const resolveTextStreamKey = (\n chunk: StreamChunk,\n fallbackNode?: string,\n ): string => {\n if (\"segmentId\" in chunk && typeof chunk.segmentId === \"string\") {\n const seg = chunk.segmentId.trim();\n if (seg.length > 0) {\n const op =\n \"opId\" in chunk && typeof chunk.opId === \"string\"\n ? chunk.opId.trim()\n : \"\";\n return op.length > 0 ? `${op}:${seg}` : seg;\n }\n }\n\n if (\"opId\" in chunk && typeof chunk.opId === \"string\") {\n const op = chunk.opId.trim();\n if (op.length > 0) {\n const node =\n (\"node\" in chunk && typeof chunk.node === \"string\"\n ? chunk.node\n : fallbackNode) ?? \"__unknown__\";\n return `${op}:${node}`;\n }\n }\n\n return fallbackNode && fallbackNode.length > 0\n ? fallbackNode\n : \"__unknown__\";\n };\n\n const ensureTextPiece = (key: string): LiveChatTextPiece => {\n const pieceKey = `text:${key}`;\n const existingIndex = findPieceIndex(pieceKey);\n if (existingIndex >= 0) {\n return keyedPieces[existingIndex]?.piece as LiveChatTextPiece;\n }\n\n const nextPiece: LiveChatTextPiece = {\n id: args.createId(),\n type: \"text\",\n content: \"\",\n };\n keyedPieces.push({ key: pieceKey, piece: nextPiece });\n return nextPiece;\n };\n\n const processChunk = (\n chunk: StreamChunk,\n _options?: { openDebugOnInterrupt?: boolean | undefined },\n ): boolean => {\n if (chunk.type === \"text-start\") {\n ensureTextPiece(resolveTextStreamKey(chunk, chunk.node));\n emit();\n return true;\n }\n\n if (chunk.type === \"text-delta\") {\n sawTextDelta = true;\n const streamKey = resolveTextStreamKey(chunk, chunk.node);\n const current = ensureTextPiece(streamKey);\n upsertPiece(`text:${streamKey}`, {\n ...current,\n content: current.content + chunk.delta,\n });\n return true;\n }\n\n if (chunk.type === \"text-end\") {\n emit();\n return true;\n }\n\n if (chunk.type === \"structured-data\") {\n const nextItem = args.structuredStreams.applyStreamChunk(chunk);\n if (nextItem) {\n upsertPiece(`structured:${nextItem.streamId}`, {\n id: nextItem.id,\n type: \"structured\",\n data: nextItem.state,\n });\n }\n return true;\n }\n\n if (chunk.type === \"interrupt\") {\n pushPiece(args.toHumanInputPiece(chunk));\n return true;\n }\n\n if (chunk.type === \"message\") {\n if (!sawTextDelta) {\n pushPiece({\n id: args.createId(),\n type: \"text\",\n content: chunk.content ?? \"\",\n });\n }\n return true;\n }\n\n if (chunk.type === \"error\") {\n pushPiece({\n id: args.createId(),\n type: \"error\",\n content: chunk.message ?? \"An error occurred\",\n });\n return true;\n }\n\n if (chunk.type === \"done\") {\n return false;\n }\n\n return true;\n };\n\n return {\n processChunk,\n getPieces: () =>\n keyedPieces\n .map((entry) => entry.piece)\n .filter((piece) => isNonEmptyTextPiece(piece)),\n };\n}\n","import type { StreamChunk } from \"@kortyx/stream/browser\";\nimport type { HumanInputPiece } from \"./chat-types\";\n\ninterface HumanInputStreamChunk {\n type: \"interrupt\";\n requestId: string | undefined;\n resumeToken: string | undefined;\n id?: string;\n schemaId?: string;\n schemaVersion?: string;\n meta?: Record<string, unknown>;\n input?: {\n kind?: \"text\" | \"choice\" | \"multi-choice\";\n question?: string;\n multiple?: boolean;\n id?: string;\n schemaId?: string;\n schemaVersion?: string;\n meta?: Record<string, unknown>;\n options?: Array<{\n id?: string | number;\n label?: string;\n description?: string;\n }>;\n };\n}\n\nexport type ToHumanInputPiece = (args: {\n chunk: StreamChunk;\n createId: () => string;\n}) => HumanInputPiece;\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n value !== null && typeof value === \"object\" && !Array.isArray(value);\n\nconst nonEmptyString = (value: unknown): string | undefined =>\n typeof value === \"string\" && value.length > 0 ? value : undefined;\n\nconst firstNonEmptyString = (...values: unknown[]): string | undefined => {\n for (const value of values) {\n const result = nonEmptyString(value);\n if (result) return result;\n }\n return undefined;\n};\n\nexport function toHumanInputPiece(args: {\n chunk: StreamChunk;\n createId: () => string;\n}): HumanInputPiece {\n const hi = args.chunk as unknown as HumanInputStreamChunk;\n const input = hi.input ?? {};\n const kind = input.kind || (input.multiple ? \"multi-choice\" : \"choice\");\n const isText = kind === \"text\";\n const schemaId = firstNonEmptyString(hi.schemaId, input.schemaId);\n const schemaVersion = firstNonEmptyString(\n hi.schemaVersion,\n input.schemaVersion,\n );\n const interruptId = firstNonEmptyString(hi.id, input.id);\n const inputMeta = isRecord(input.meta) ? input.meta : undefined;\n const chunkMeta = isRecord(hi.meta) ? hi.meta : undefined;\n const meta =\n inputMeta || chunkMeta\n ? { ...(inputMeta ?? {}), ...(chunkMeta ?? {}) }\n : undefined;\n\n const question = isText\n ? input.question\n : typeof input.question === \"string\"\n ? input.question\n : \"Please choose\";\n\n const optionsSrc = Array.isArray(input.options) ? input.options : [];\n const optionsArr: Array<{\n id: string;\n label: string;\n description?: string;\n }> = optionsSrc\n .map((option) => ({\n id: String(option.id ?? \"\"),\n label: String(option.label ?? \"\"),\n ...(typeof option.description === \"string\" && option.description\n ? { description: option.description }\n : {}),\n }))\n .filter((option) => option.id && option.label);\n\n return {\n id: args.createId(),\n type: \"interrupt\",\n resumeToken: String(hi.resumeToken ?? \"\"),\n requestId: String(hi.requestId ?? \"\"),\n kind,\n ...(question !== undefined ? { question } : {}),\n multiple: Boolean(input.multiple),\n options: optionsArr,\n ...(schemaId ? { schemaId } : {}),\n ...(schemaVersion ? { schemaVersion } : {}),\n ...(interruptId ? { interruptId } : {}),\n ...(meta ? { meta } : {}),\n };\n}\n","\"use client\";\n\nimport type { StreamChunk } from \"@kortyx/stream/browser\";\nimport { type RefObject, useEffect, useRef, useState } from \"react\";\nimport { buildAssistantMessage } from \"./build-assistant-message\";\nimport { type ChatStorage, createBrowserChatStorage } from \"./chat-storage\";\nimport type { ChatTransport, OutgoingChatMessage } from \"./chat-transport\";\nimport type { ChatMsg, ContentPiece, HumanInputPiece } from \"./chat-types\";\nimport { createLiveChatPieces } from \"./create-live-chat-pieces\";\nimport {\n toHumanInputPiece as defaultToHumanInputPiece,\n type ToHumanInputPiece,\n} from \"./to-human-input-piece\";\nimport { useChatStreamDebug } from \"./use-chat-stream-debug\";\nimport { useStructuredStreams } from \"./use-structured-streams\";\n\nconst defaultCreateId = () => {\n try {\n if (typeof crypto !== \"undefined\" && \"randomUUID\" in crypto) {\n return crypto.randomUUID();\n }\n } catch {}\n return `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n};\n\ntype DefaultChatContext = Record<string, unknown>;\n\nexport type PrepareContextMessagesArgs<TContext = DefaultChatContext> = {\n messages: ChatMsg[];\n sessionId: string;\n workflowId: string;\n reason: \"send\" | \"resume\";\n context: TContext;\n};\n\nexport type PrepareContextMessages<TContext = DefaultChatContext> = (\n args: PrepareContextMessagesArgs<TContext>,\n) => OutgoingChatMessage[] | Promise<OutgoingChatMessage[]>;\n\nexport type UseChatValue = {\n messages: ChatMsg[];\n isStreaming: boolean;\n canAbort: boolean;\n error: Error | null;\n streamContentPieces: ContentPiece[];\n streamDebug: StreamChunk[];\n lastAssistantId: string | null;\n workflowId: string;\n setWorkflowId: React.Dispatch<React.SetStateAction<string>>;\n send: (text: string) => Promise<void> | void;\n respondToHumanInput: (args: {\n resumeToken: string;\n requestId: string;\n selected: string[];\n text?: string;\n }) => Promise<void> | void;\n respondToInterrupt: (\n piece: HumanInputPiece,\n response?: { selected?: string[] | undefined; text?: string | undefined },\n ) => Promise<void> | void;\n setMessages: React.Dispatch<React.SetStateAction<ChatMsg[]>>;\n clearMessages: () => void;\n resetSession: () => void;\n resetChat: () => void;\n clearChat: () => void;\n abort: () => void;\n clearError: () => void;\n includeHistory: boolean;\n setIncludeHistory: React.Dispatch<React.SetStateAction<boolean>>;\n};\n\nexport type UseChatOptions<TContext = DefaultChatContext> = {\n transport: ChatTransport<TContext>;\n storage?: ChatStorage<ChatMsg> | undefined;\n createId?: (() => string) | undefined;\n context?: TContext | undefined;\n prepareContextMessages?: PrepareContextMessages<TContext> | undefined;\n toHumanInputPiece?: ToHumanInputPiece | undefined;\n};\n\nconst defaultStorage = createBrowserChatStorage<ChatMsg>();\n\nfunction useLatestRef<T>(value: T): RefObject<T> {\n const ref = useRef(value);\n ref.current = value;\n return ref;\n}\n\nfunction findActiveTextInterrupt(args: {\n messages: ChatMsg[];\n streamContentPieces: ContentPiece[];\n}): HumanInputPiece | undefined {\n const liveInterrupt = args.streamContentPieces.find(\n (piece): piece is HumanInputPiece =>\n piece.type === \"interrupt\" && piece.kind === \"text\",\n );\n if (liveInterrupt) return liveInterrupt;\n\n for (const message of [...args.messages].reverse()) {\n if (message.role !== \"assistant\" || !message.contentPieces) continue;\n\n const messageInterrupt = [...message.contentPieces]\n .reverse()\n .find(\n (piece): piece is HumanInputPiece =>\n piece.type === \"interrupt\" && piece.kind === \"text\",\n );\n if (messageInterrupt) return messageInterrupt;\n }\n\n return undefined;\n}\n\nexport function useChat<TContext = DefaultChatContext>(\n options: UseChatOptions<TContext>,\n): UseChatValue {\n const resolvedStorage = options.storage ?? defaultStorage;\n const transportRef = useLatestRef(options.transport);\n const storageRef = useLatestRef(resolvedStorage);\n const toHumanInputPieceRef = useLatestRef(\n options.toHumanInputPiece ?? defaultToHumanInputPiece,\n );\n const requestContext =\n options.context ?? ({} as unknown as NonNullable<TContext>);\n const createId = useRef(options.createId ?? defaultCreateId).current;\n\n const [messages, setMessages] = useState<ChatMsg[]>([]);\n const [isStreaming, setIsStreaming] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [streamContentPieces, setStreamContentPieces] = useState<\n ContentPiece[]\n >([]);\n const [lastAssistantId, setLastAssistantId] = useState<string | null>(null);\n const [includeHistory, setIncludeHistory] = useState(true);\n const [workflowId, setWorkflowId] = useState(\"\");\n const [sessionId, setSessionId] = useState<string | null>(null);\n const [didHydrateStorage, setDidHydrateStorage] = useState(false);\n const abortControllerRef = useRef<AbortController | null>(null);\n const { streamDebug, clearStreamDebug, createRecorder } =\n useChatStreamDebug();\n const { applyStreamChunk, clear: clearStructuredStreams } =\n useStructuredStreams<Record<string, unknown>>({\n createId,\n });\n\n useEffect(() => {\n let cancelled = false;\n const storage = resolvedStorage;\n\n void Promise.resolve(storage.load()).then((storedState) => {\n if (cancelled) return;\n\n if (typeof storedState.sessionId === \"string\") {\n setSessionId(storedState.sessionId);\n }\n if (typeof storedState.workflowId === \"string\") {\n setWorkflowId(storedState.workflowId);\n }\n if (typeof storedState.includeHistory === \"boolean\") {\n setIncludeHistory(storedState.includeHistory);\n }\n if (\n Array.isArray(storedState.messages) &&\n storedState.messages.length > 0\n ) {\n setMessages(storedState.messages);\n }\n\n setDidHydrateStorage(true);\n });\n\n return () => {\n cancelled = true;\n };\n }, [resolvedStorage]);\n\n useEffect(() => {\n if (!didHydrateStorage) return;\n const storage = storageRef.current;\n\n void storage.save({\n sessionId,\n workflowId,\n includeHistory,\n messages,\n });\n }, [\n didHydrateStorage,\n includeHistory,\n messages,\n sessionId,\n storageRef,\n workflowId,\n ]);\n\n const clearActiveStream = () => {\n abortControllerRef.current?.abort();\n abortControllerRef.current = null;\n setIsStreaming(false);\n setMessages([]);\n setStreamContentPieces([]);\n clearStreamDebug();\n clearStructuredStreams();\n setLastAssistantId(null);\n };\n\n const clearMessages = () => {\n clearActiveStream();\n void storageRef.current.clearMessages();\n };\n\n const resetSession = () => {\n setSessionId(null);\n };\n\n const resetChat = () => {\n clearActiveStream();\n resetSession();\n setError(null);\n void storageRef.current.clearMessages();\n };\n\n const clearChat = resetChat;\n\n const clearError = () => {\n setError(null);\n };\n\n const abort = () => {\n abortControllerRef.current?.abort();\n };\n\n const persistSessionId = (sid: string) => {\n setSessionId(sid);\n };\n\n const resolveSessionId = () => {\n const sid = sessionId ?? createId();\n if (!sessionId) persistSessionId(sid);\n return sid;\n };\n\n const toOutgoingHistoryMessage = (message: ChatMsg): OutgoingChatMessage => ({\n role: message.role,\n content: message.content,\n });\n\n const prepareMessagesToSend = async (args: {\n sid: string;\n outgoingMessage: OutgoingChatMessage;\n reason: \"send\" | \"resume\";\n }): Promise<OutgoingChatMessage[]> => {\n const prepared = options.prepareContextMessages\n ? await options.prepareContextMessages({\n messages,\n sessionId: args.sid,\n workflowId,\n reason: args.reason,\n context: requestContext,\n })\n : includeHistory\n ? messages.map(toOutgoingHistoryMessage)\n : [];\n\n return [...prepared, args.outgoingMessage];\n };\n\n const streamAssistantResponse = async (args: {\n sid: string;\n messagesToSend: OutgoingChatMessage[];\n debugLabel: string;\n openDebugOnInterrupt?: boolean;\n signal: AbortSignal;\n }) => {\n clearStructuredStreams();\n setStreamContentPieces([]);\n\n const debug = createRecorder(`${args.debugLabel} sessionId=${args.sid}`);\n const pieces = createLiveChatPieces({\n createId,\n onChange: setStreamContentPieces,\n structuredStreams: {\n applyStreamChunk,\n },\n toHumanInputPiece: (chunk) =>\n toHumanInputPieceRef.current({\n chunk,\n createId,\n }),\n });\n\n await transportRef.current.stream({\n sessionId: args.sid,\n workflowId,\n messages: args.messagesToSend,\n context: requestContext,\n signal: args.signal,\n onChunk: (chunk: StreamChunk) => {\n debug.push(chunk);\n\n if (chunk.type === \"session\") {\n if (typeof chunk.sessionId === \"string\") {\n persistSessionId(chunk.sessionId);\n }\n return;\n }\n\n if (chunk.type === \"error\") {\n setError(new Error(chunk.message));\n }\n\n return pieces.processChunk(chunk, {\n openDebugOnInterrupt: args.openDebugOnInterrupt,\n });\n },\n });\n\n if (args.signal.aborted) return;\n\n const assistant = buildAssistantMessage({\n createId,\n pieces: pieces.getPieces(),\n debug: debug.getAll(),\n });\n setMessages((prev) => [...prev, assistant]);\n setLastAssistantId(assistant.id);\n clearStructuredStreams();\n setStreamContentPieces([]);\n clearStreamDebug();\n };\n\n const isAbortError = (value: unknown, signal: AbortSignal): boolean => {\n if (signal.aborted) return true;\n if (!(value instanceof Error)) return false;\n return value.name === \"AbortError\";\n };\n\n const respondToHumanInput = async ({\n resumeToken,\n requestId,\n selected,\n text,\n }: {\n resumeToken: string;\n requestId: string;\n selected: string[];\n text?: string;\n }) => {\n if (isStreaming) return;\n setError(null);\n const label: string =\n typeof text === \"string\" && text.length > 0\n ? text\n : selected.length > 0\n ? selected.length === 1\n ? (selected[0] as string)\n : selected.join(\", \")\n : \"(selection)\";\n const userId = createId();\n const userMsg: ChatMsg = { id: userId, role: \"user\", content: label };\n setMessages((prev) => [...prev, userMsg]);\n setIsStreaming(true);\n setStreamContentPieces([]);\n clearStreamDebug();\n clearStructuredStreams();\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n try {\n const resumePayload: Record<string, unknown> = {\n resume: { token: resumeToken, requestId, selected },\n };\n const outgoing = {\n role: \"user\" as const,\n content: label,\n metadata: resumePayload,\n };\n const sid = resolveSessionId();\n const messagesToSend = await prepareMessagesToSend({\n sid,\n outgoingMessage: outgoing,\n reason: \"resume\",\n });\n\n await streamAssistantResponse({\n sid,\n messagesToSend,\n debugLabel: \"runChat (resume)\",\n signal: abortController.signal,\n });\n } catch (err) {\n if (isAbortError(err, abortController.signal)) return;\n const nextError = err instanceof Error ? err : new Error(String(err));\n setError(nextError);\n throw err;\n } finally {\n if (abortControllerRef.current === abortController) {\n abortControllerRef.current = null;\n }\n setIsStreaming(false);\n }\n };\n\n const respondToInterrupt = async (\n piece: HumanInputPiece,\n response?: { selected?: string[] | undefined; text?: string | undefined },\n ) => {\n const text = response?.text;\n const selected =\n response?.selected ??\n (typeof text === \"string\" && text.length > 0 ? [text] : []);\n\n return respondToHumanInput({\n resumeToken: piece.resumeToken,\n requestId: piece.requestId,\n selected,\n ...(text !== undefined ? { text } : {}),\n });\n };\n\n const send = async (text: string) => {\n const content = text.trim();\n if (!content || isStreaming) return;\n setError(null);\n\n const activeTextInterrupt = findActiveTextInterrupt({\n messages,\n streamContentPieces,\n });\n\n if (activeTextInterrupt) {\n await respondToHumanInput({\n resumeToken: activeTextInterrupt.resumeToken,\n requestId: activeTextInterrupt.requestId,\n selected: [content],\n text: content,\n });\n return;\n }\n\n const userId = createId();\n const userMsg: ChatMsg = { id: userId, role: \"user\", content };\n setMessages((prev) => [...prev, userMsg]);\n\n setIsStreaming(true);\n setStreamContentPieces([]);\n clearStreamDebug();\n clearStructuredStreams();\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n try {\n const sid = resolveSessionId();\n const messagesToSend = await prepareMessagesToSend({\n sid,\n outgoingMessage: { role: \"user\" as const, content },\n reason: \"send\",\n });\n await streamAssistantResponse({\n sid,\n messagesToSend,\n debugLabel: \"runChat (send)\",\n openDebugOnInterrupt: true,\n signal: abortController.signal,\n });\n } catch (err) {\n if (isAbortError(err, abortController.signal)) return;\n const nextError = err instanceof Error ? err : new Error(String(err));\n setError(nextError);\n throw err;\n } finally {\n if (abortControllerRef.current === abortController) {\n abortControllerRef.current = null;\n }\n setIsStreaming(false);\n }\n };\n\n return {\n messages,\n isStreaming,\n canAbort: isStreaming,\n error,\n streamContentPieces,\n streamDebug,\n lastAssistantId,\n workflowId,\n setWorkflowId,\n send,\n respondToHumanInput,\n respondToInterrupt,\n setMessages,\n clearMessages,\n resetSession,\n resetChat,\n clearChat,\n abort,\n clearError,\n includeHistory,\n setIncludeHistory,\n };\n}\n","\"use client\";\n\nimport type { StreamChunk } from \"@kortyx/stream/browser\";\nimport { useCallback, useState } from \"react\";\n\ntype DebugChunk = StreamChunk & {\n _ts: number;\n _dt: number;\n _seq: number;\n};\n\nexport function useChatStreamDebug() {\n const [streamDebug, setStreamDebug] = useState<StreamChunk[]>([]);\n\n const clearStreamDebug = useCallback(() => {\n setStreamDebug([]);\n }, []);\n\n const createRecorder = useCallback((initialMessage: string) => {\n let seq = 0;\n let lastTs = 0;\n const accDebug: StreamChunk[] = [];\n\n const push = (chunk: StreamChunk) => {\n const ts = Date.now();\n const withMeta: DebugChunk = {\n ...(chunk as StreamChunk),\n _ts: ts,\n _dt: lastTs ? ts - lastTs : 0,\n _seq: seq++,\n };\n lastTs = ts;\n accDebug.push(withMeta);\n setStreamDebug((current) =>\n current.length > 1000\n ? [...current.slice(-1000), withMeta]\n : [...current, withMeta],\n );\n };\n\n push({\n type: \"status\",\n message: initialMessage,\n } as StreamChunk);\n\n return {\n push,\n getAll: () => accDebug,\n };\n }, []);\n\n return {\n streamDebug,\n clearStreamDebug,\n createRecorder,\n };\n}\n","import {\n createStructuredStreamAccumulator,\n type StreamChunk,\n type StructuredDataChunk,\n type StructuredStreamState,\n} from \"@kortyx/stream/browser\";\nimport { useCallback, useMemo, useRef, useState } from \"react\";\n\nexport type StructuredStreamItem<TData = unknown> = {\n id: string;\n streamId: string;\n state: StructuredStreamState<TData>;\n};\n\nexport type UseStructuredStreamsOptions<_TData = unknown> = {\n createId?: (() => string) | undefined;\n initialChunks?: Iterable<StructuredDataChunk> | undefined;\n};\n\nexport type UseStructuredStreamsResult<TData = unknown> = {\n items: StructuredStreamItem<TData>[];\n byStreamId: Record<string, StructuredStreamState<TData>>;\n applyStreamChunk: (\n chunk: StreamChunk,\n ) => StructuredStreamItem<TData> | undefined;\n clear: () => void;\n get: (streamId: string) => StructuredStreamItem<TData> | undefined;\n};\n\nconst defaultCreateId = () => {\n try {\n if (typeof crypto !== \"undefined\" && \"randomUUID\" in crypto) {\n return crypto.randomUUID();\n }\n } catch {}\n\n return `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n};\n\nexport function useStructuredStreams<TData = unknown>(\n options?: UseStructuredStreamsOptions<TData> | undefined,\n): UseStructuredStreamsResult<TData> {\n const createId = useRef(options?.createId ?? defaultCreateId).current;\n const initialChunks = useRef(options?.initialChunks ?? []).current;\n const accumulatorRef = useRef(\n createStructuredStreamAccumulator<TData>(initialChunks),\n );\n const initialItemsRef = useRef<StructuredStreamItem<TData>[] | undefined>(\n undefined,\n );\n\n if (initialItemsRef.current === undefined) {\n initialItemsRef.current = accumulatorRef.current\n .entries()\n .map(([streamId, state]) => ({\n id: createId(),\n streamId,\n state,\n }));\n }\n\n const itemsRef = useRef(initialItemsRef.current);\n const [items, setItems] = useState(initialItemsRef.current);\n\n const setNextItems = useCallback(\n (nextItems: StructuredStreamItem<TData>[]) => {\n itemsRef.current = nextItems;\n setItems(nextItems);\n },\n [],\n );\n\n const applyStreamChunk = useCallback(\n (chunk: StreamChunk): StructuredStreamItem<TData> | undefined => {\n const nextState = accumulatorRef.current.applyStreamChunk(chunk);\n if (!nextState) return undefined;\n\n const currentItems = itemsRef.current;\n const existingIndex = currentItems.findIndex(\n (item) => item.streamId === nextState.streamId,\n );\n const existingItem =\n existingIndex >= 0 ? currentItems[existingIndex] : undefined;\n\n const nextItem: StructuredStreamItem<TData> = existingItem\n ? {\n ...existingItem,\n state: nextState,\n }\n : {\n id: createId(),\n streamId: nextState.streamId,\n state: nextState,\n };\n\n const nextItems =\n existingIndex >= 0\n ? currentItems.map((item, index) =>\n index === existingIndex ? nextItem : item,\n )\n : [...currentItems, nextItem];\n\n setNextItems(nextItems);\n return nextItem;\n },\n [createId, setNextItems],\n );\n\n const clear = useCallback(() => {\n accumulatorRef.current = createStructuredStreamAccumulator<TData>();\n setNextItems([]);\n }, [setNextItems]);\n\n const get = useCallback((streamId: string) => {\n return itemsRef.current.find((item) => item.streamId === streamId);\n }, []);\n\n const byStreamId = useMemo(\n () =>\n Object.fromEntries(\n items.map((item) => [item.streamId, item.state]),\n ) as Record<string, StructuredStreamState<TData>>,\n [items],\n );\n\n return {\n items,\n byStreamId,\n applyStreamChunk,\n clear,\n get,\n };\n}\n"],"mappings":"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","names":["import_react","import_browser","import_react","defaultCreateId"]}
|