@osdk/react 2.40.0 → 2.41.0-main-d24cc61b1e7fde7722d8229ed2b6821f5ce1bf8a

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 (39) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/build/browser/aip/chatStore.js +67 -0
  3. package/build/browser/aip/chatStore.js.map +1 -0
  4. package/build/browser/aip/chatStream.js +155 -0
  5. package/build/browser/aip/chatStream.js.map +1 -0
  6. package/build/browser/aip/useChat.js +243 -0
  7. package/build/browser/aip/useChat.js.map +1 -0
  8. package/build/browser/public/experimental/aip.js +18 -0
  9. package/build/browser/public/experimental/aip.js.map +1 -0
  10. package/build/browser/util/UserAgent.js +1 -1
  11. package/build/browser/util/UserAgent.js.map +1 -1
  12. package/build/cjs/{chunk-L33DWZUR.cjs → chunk-QNNQV2NH.cjs} +3 -3
  13. package/build/cjs/chunk-QNNQV2NH.cjs.map +1 -0
  14. package/build/cjs/index.cjs +15 -15
  15. package/build/cjs/public/experimental/aip.cjs +389 -0
  16. package/build/cjs/public/experimental/aip.cjs.map +1 -0
  17. package/build/cjs/public/experimental/aip.d.cts +83 -0
  18. package/build/cjs/public/experimental.cjs +16 -16
  19. package/build/esm/aip/chatStore.js +67 -0
  20. package/build/esm/aip/chatStore.js.map +1 -0
  21. package/build/esm/aip/chatStream.js +155 -0
  22. package/build/esm/aip/chatStream.js.map +1 -0
  23. package/build/esm/aip/useChat.js +243 -0
  24. package/build/esm/aip/useChat.js.map +1 -0
  25. package/build/esm/public/experimental/aip.js +18 -0
  26. package/build/esm/public/experimental/aip.js.map +1 -0
  27. package/build/esm/util/UserAgent.js +1 -1
  28. package/build/esm/util/UserAgent.js.map +1 -1
  29. package/build/types/aip/chatStore.d.ts +31 -0
  30. package/build/types/aip/chatStore.d.ts.map +1 -0
  31. package/build/types/aip/chatStream.d.ts +20 -0
  32. package/build/types/aip/chatStream.d.ts.map +1 -0
  33. package/build/types/aip/useChat.d.ts +79 -0
  34. package/build/types/aip/useChat.d.ts.map +1 -0
  35. package/build/types/public/experimental/aip.d.ts +4 -0
  36. package/build/types/public/experimental/aip.d.ts.map +1 -0
  37. package/experimental/aip.d.ts +17 -0
  38. package/package.json +22 -8
  39. package/build/cjs/chunk-L33DWZUR.cjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chatStore.js","names":["createChatStore","options","state","messages","initialMessages","status","error","undefined","subscribers","Set","throttleMs","pendingNotify","notifyNow","clearTimeout","s","notifyThrottled","setTimeout","getSnapshot","subscribe","notify","add","delete","setState","next","setStateThrottled"],"sources":["chatStore.ts"],"sourcesContent":["/*\n * Copyright 2026 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { UIMessage } from \"@osdk/aip-core\";\n\nexport type ChatStatus = \"ready\" | \"submitted\" | \"streaming\" | \"error\";\n\nexport interface ChatState {\n messages: ReadonlyArray<UIMessage>;\n status: ChatStatus;\n error: Error | undefined;\n}\n\nexport interface ChatStore {\n getSnapshot: () => ChatState;\n /** Subscribe to state changes. Returns the unsubscribe function. */\n subscribe: (notify: () => void) => () => void;\n /** Replace state and notify subscribers synchronously. */\n setState: (\n next: ChatState | ((prev: ChatState) => ChatState),\n ) => void;\n /**\n * Replace state and coalesce subscriber notifications across rapid calls.\n * Notifications fire `throttleMs` after the first change in a quiet window.\n * Use for high-frequency updates (e.g. token streaming) where one render per\n * change is wasteful.\n */\n setStateThrottled: (\n next: ChatState | ((prev: ChatState) => ChatState),\n ) => void;\n}\n\nexport interface CreateChatStoreOptions {\n initialMessages?: ReadonlyArray<UIMessage>;\n /** Min ms between subscriber notifications. 0 = synchronous. Defaults to 0. */\n throttleMs?: number;\n}\n\n/**\n * Tiny pub-sub store backing `useChat`. Throttles subscriber notifications so\n * fast token-delta streams don't trigger one render per token.\n */\nexport function createChatStore(options: CreateChatStoreOptions): ChatStore {\n let state: ChatState = {\n messages: options.initialMessages ?? [],\n status: \"ready\",\n error: undefined,\n };\n\n const subscribers = new Set<() => void>();\n const throttleMs = options.throttleMs ?? 0;\n let pendingNotify: ReturnType<typeof setTimeout> | undefined;\n\n const notifyNow = (): void => {\n if (pendingNotify != null) {\n clearTimeout(pendingNotify);\n pendingNotify = undefined;\n }\n for (const s of subscribers) {\n s();\n }\n };\n\n const notifyThrottled = (): void => {\n if (throttleMs <= 0) {\n notifyNow();\n return;\n }\n if (pendingNotify != null) {\n return;\n }\n pendingNotify = setTimeout(notifyNow, throttleMs);\n };\n\n return {\n getSnapshot: () => state,\n subscribe: (notify) => {\n subscribers.add(notify);\n return () => {\n subscribers.delete(notify);\n };\n },\n setState: (next) => {\n state = typeof next === \"function\" ? next(state) : next;\n notifyNow();\n },\n setStateThrottled: (next) => {\n state = typeof next === \"function\" ? next(state) : next;\n notifyThrottled();\n },\n };\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAqCA;AACA;AACA;AACA;AACA,OAAO,SAASA,eAAeA,CAACC,OAA+B,EAAa;EAC1E,IAAIC,KAAgB,GAAG;IACrBC,QAAQ,EAAEF,OAAO,CAACG,eAAe,IAAI,EAAE;IACvCC,MAAM,EAAE,OAAO;IACfC,KAAK,EAAEC;EACT,CAAC;EAED,MAAMC,WAAW,GAAG,IAAIC,GAAG,CAAa,CAAC;EACzC,MAAMC,UAAU,GAAGT,OAAO,CAACS,UAAU,IAAI,CAAC;EAC1C,IAAIC,aAAwD;EAE5D,MAAMC,SAAS,GAAGA,CAAA,KAAY;IAC5B,IAAID,aAAa,IAAI,IAAI,EAAE;MACzBE,YAAY,CAACF,aAAa,CAAC;MAC3BA,aAAa,GAAGJ,SAAS;IAC3B;IACA,KAAK,MAAMO,CAAC,IAAIN,WAAW,EAAE;MAC3BM,CAAC,CAAC,CAAC;IACL;EACF,CAAC;EAED,MAAMC,eAAe,GAAGA,CAAA,KAAY;IAClC,IAAIL,UAAU,IAAI,CAAC,EAAE;MACnBE,SAAS,CAAC,CAAC;MACX;IACF;IACA,IAAID,aAAa,IAAI,IAAI,EAAE;MACzB;IACF;IACAA,aAAa,GAAGK,UAAU,CAACJ,SAAS,EAAEF,UAAU,CAAC;EACnD,CAAC;EAED,OAAO;IACLO,WAAW,EAAEA,CAAA,KAAMf,KAAK;IACxBgB,SAAS,EAAGC,MAAM,IAAK;MACrBX,WAAW,CAACY,GAAG,CAACD,MAAM,CAAC;MACvB,OAAO,MAAM;QACXX,WAAW,CAACa,MAAM,CAACF,MAAM,CAAC;MAC5B,CAAC;IACH,CAAC;IACDG,QAAQ,EAAGC,IAAI,IAAK;MAClBrB,KAAK,GAAG,OAAOqB,IAAI,KAAK,UAAU,GAAGA,IAAI,CAACrB,KAAK,CAAC,GAAGqB,IAAI;MACvDX,SAAS,CAAC,CAAC;IACb,CAAC;IACDY,iBAAiB,EAAGD,IAAI,IAAK;MAC3BrB,KAAK,GAAG,OAAOqB,IAAI,KAAK,UAAU,GAAGA,IAAI,CAACrB,KAAK,CAAC,GAAGqB,IAAI;MACvDR,eAAe,CAAC,CAAC;IACnB;EACF,CAAC;AACH","ignoreList":[]}
@@ -0,0 +1,155 @@
1
+ /*
2
+ * Copyright 2026 Palantir Technologies, Inc. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { generateMessageId } from "@osdk/aip-core";
18
+
19
+ /**
20
+ * Mutable orchestration handle threaded through the streaming functions.
21
+ * Holds everything they need to read snapshots, mutate state, and check
22
+ * whether their stream is still the active one.
23
+ */
24
+
25
+ export async function runChatStream(ctx, transport, chatId, seed, trigger) {
26
+ ctx.abortRef.current?.abort();
27
+ const ctrl = new AbortController();
28
+ ctx.abortRef.current = ctrl;
29
+ ctx.stoppedRef.current = false;
30
+ const assistantId = generateMessageId();
31
+ try {
32
+ const stream = await transport.sendMessages({
33
+ trigger,
34
+ chatId,
35
+ messageId: assistantId,
36
+ messages: seed.slice(),
37
+ abortSignal: ctrl.signal
38
+ });
39
+ await drainStream(ctx, stream, assistantId, ctrl);
40
+ } catch (err) {
41
+ handleStreamError(ctx, err, ctrl);
42
+ }
43
+ }
44
+ export async function drainStream(ctx, stream, assistantMessageId, capturedCtrl) {
45
+ const {
46
+ store
47
+ } = ctx;
48
+ const reader = stream.getReader();
49
+ let textBuf = "";
50
+ const isStale = () => ctx.abortRef.current != null && ctx.abortRef.current !== capturedCtrl;
51
+
52
+ // Caller dropped our assistant message via `setMessages` mid-stream.
53
+ // Treat as "the consumer no longer wants this stream" — quietly stop.
54
+ const isOrphaned = () => {
55
+ const messages = store.getSnapshot().messages;
56
+ return textBuf.length > 0 && !messages.some(m => m.id === assistantMessageId);
57
+ };
58
+ try {
59
+ while (true) {
60
+ const {
61
+ done,
62
+ value
63
+ } = await reader.read();
64
+ if (done) {
65
+ break;
66
+ }
67
+ if (isStale()) {
68
+ await reader.cancel();
69
+ return;
70
+ }
71
+ if (isOrphaned()) {
72
+ await reader.cancel();
73
+ store.setState(prev => ({
74
+ ...prev,
75
+ status: "ready"
76
+ }));
77
+ return;
78
+ }
79
+ if (value.type === "text-delta") {
80
+ textBuf += value.delta;
81
+ upsertAssistantText(store, assistantMessageId, textBuf);
82
+ } else if (value.type === "error") {
83
+ if (ctx.stoppedRef.current || capturedCtrl.signal.aborted) {
84
+ return;
85
+ }
86
+ await reader.cancel();
87
+ throw new Error(value.errorText);
88
+ }
89
+ }
90
+ if (isStale()) {
91
+ return;
92
+ }
93
+ store.setState(prev => ({
94
+ ...prev,
95
+ status: "ready"
96
+ }));
97
+ const finalSnap = store.getSnapshot();
98
+ const finalMessage = finalSnap.messages.find(m => m.id === assistantMessageId);
99
+ if (finalMessage != null && ctx.onFinish != null) {
100
+ ctx.onFinish({
101
+ message: finalMessage,
102
+ messages: finalSnap.messages
103
+ });
104
+ }
105
+ } catch (err) {
106
+ handleStreamError(ctx, err, capturedCtrl);
107
+ } finally {
108
+ reader.releaseLock();
109
+ }
110
+ }
111
+ function upsertAssistantText(store, assistantMessageId, text) {
112
+ store.setStateThrottled(prev => {
113
+ const exists = prev.messages.some(m => m.id === assistantMessageId);
114
+ const messages = exists ? prev.messages.map(m => m.id === assistantMessageId ? {
115
+ ...m,
116
+ parts: [{
117
+ type: "text",
118
+ text
119
+ }]
120
+ } : m) : [...prev.messages, {
121
+ id: assistantMessageId,
122
+ role: "assistant",
123
+ parts: [{
124
+ type: "text",
125
+ text
126
+ }]
127
+ }];
128
+ return {
129
+ ...prev,
130
+ status: "streaming",
131
+ messages
132
+ };
133
+ });
134
+ }
135
+ function handleStreamError(ctx, err, capturedCtrl) {
136
+ if (ctx.abortRef.current != null && ctx.abortRef.current !== capturedCtrl) {
137
+ return;
138
+ }
139
+ const error = err instanceof Error ? err : new Error(String(err));
140
+ if (ctx.stoppedRef.current || error.name === "AbortError" || capturedCtrl.signal.aborted) {
141
+ ctx.store.setState(prev => ({
142
+ ...prev,
143
+ status: "ready",
144
+ error: undefined
145
+ }));
146
+ return;
147
+ }
148
+ ctx.store.setState(prev => ({
149
+ ...prev,
150
+ status: "error",
151
+ error
152
+ }));
153
+ ctx.onError?.(error);
154
+ }
155
+ //# sourceMappingURL=chatStream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chatStream.js","names":["generateMessageId","runChatStream","ctx","transport","chatId","seed","trigger","abortRef","current","abort","ctrl","AbortController","stoppedRef","assistantId","stream","sendMessages","messageId","messages","slice","abortSignal","signal","drainStream","err","handleStreamError","assistantMessageId","capturedCtrl","store","reader","getReader","textBuf","isStale","isOrphaned","getSnapshot","length","some","m","id","done","value","read","cancel","setState","prev","status","type","delta","upsertAssistantText","aborted","Error","errorText","finalSnap","finalMessage","find","onFinish","message","releaseLock","text","setStateThrottled","exists","map","parts","role","error","String","name","undefined","onError"],"sources":["chatStream.ts"],"sourcesContent":["/*\n * Copyright 2026 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n type ChatTransport,\n generateMessageId,\n type UIMessage,\n type UIMessageChunk,\n} from \"@osdk/aip-core\";\nimport type React from \"react\";\nimport type { ChatStore } from \"./chatStore.js\";\n\n/**\n * Mutable orchestration handle threaded through the streaming functions.\n * Holds everything they need to read snapshots, mutate state, and check\n * whether their stream is still the active one.\n */\nexport interface StreamContext {\n store: ChatStore;\n abortRef: React.MutableRefObject<AbortController | undefined>;\n stoppedRef: React.MutableRefObject<boolean>;\n onFinish:\n | ((event: {\n message: UIMessage;\n messages: ReadonlyArray<UIMessage>;\n }) => void)\n | undefined;\n onError: ((error: Error) => void) | undefined;\n}\n\nexport async function runChatStream(\n ctx: StreamContext,\n transport: ChatTransport<UIMessage>,\n chatId: string,\n seed: ReadonlyArray<UIMessage>,\n trigger: \"submit-message\" | \"regenerate-message\",\n): Promise<void> {\n ctx.abortRef.current?.abort();\n const ctrl = new AbortController();\n ctx.abortRef.current = ctrl;\n ctx.stoppedRef.current = false;\n\n const assistantId = generateMessageId();\n try {\n const stream = await transport.sendMessages({\n trigger,\n chatId,\n messageId: assistantId,\n messages: seed.slice(),\n abortSignal: ctrl.signal,\n });\n await drainStream(ctx, stream, assistantId, ctrl);\n } catch (err) {\n handleStreamError(ctx, err, ctrl);\n }\n}\n\nexport async function drainStream(\n ctx: StreamContext,\n stream: ReadableStream<UIMessageChunk>,\n assistantMessageId: string,\n capturedCtrl: AbortController,\n): Promise<void> {\n const { store } = ctx;\n const reader = stream.getReader();\n let textBuf = \"\";\n\n const isStale = (): boolean =>\n ctx.abortRef.current != null && ctx.abortRef.current !== capturedCtrl;\n\n // Caller dropped our assistant message via `setMessages` mid-stream.\n // Treat as \"the consumer no longer wants this stream\" — quietly stop.\n const isOrphaned = (): boolean => {\n const messages = store.getSnapshot().messages;\n return textBuf.length > 0\n && !messages.some((m) => m.id === assistantMessageId);\n };\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n if (isStale()) {\n await reader.cancel();\n return;\n }\n if (isOrphaned()) {\n await reader.cancel();\n store.setState((prev) => ({ ...prev, status: \"ready\" }));\n return;\n }\n if (value.type === \"text-delta\") {\n textBuf += value.delta;\n upsertAssistantText(store, assistantMessageId, textBuf);\n } else if (value.type === \"error\") {\n if (ctx.stoppedRef.current || capturedCtrl.signal.aborted) {\n return;\n }\n await reader.cancel();\n throw new Error(value.errorText);\n }\n }\n if (isStale()) {\n return;\n }\n store.setState((prev) => ({ ...prev, status: \"ready\" }));\n const finalSnap = store.getSnapshot();\n const finalMessage = finalSnap.messages.find(\n (m) => m.id === assistantMessageId,\n );\n if (finalMessage != null && ctx.onFinish != null) {\n ctx.onFinish({ message: finalMessage, messages: finalSnap.messages });\n }\n } catch (err) {\n handleStreamError(ctx, err, capturedCtrl);\n } finally {\n reader.releaseLock();\n }\n}\n\nfunction upsertAssistantText(\n store: ChatStore,\n assistantMessageId: string,\n text: string,\n): void {\n store.setStateThrottled((prev) => {\n const exists = prev.messages.some((m) => m.id === assistantMessageId);\n const messages = exists\n ? prev.messages.map((m) =>\n m.id === assistantMessageId\n ? { ...m, parts: [{ type: \"text\" as const, text }] }\n : m\n )\n : [\n ...prev.messages,\n {\n id: assistantMessageId,\n role: \"assistant\" as const,\n parts: [{ type: \"text\" as const, text }],\n },\n ];\n return { ...prev, status: \"streaming\", messages };\n });\n}\n\nfunction handleStreamError(\n ctx: StreamContext,\n err: unknown,\n capturedCtrl: AbortController,\n): void {\n if (ctx.abortRef.current != null && ctx.abortRef.current !== capturedCtrl) {\n return;\n }\n const error = err instanceof Error ? err : new Error(String(err));\n if (\n ctx.stoppedRef.current\n || error.name === \"AbortError\"\n || capturedCtrl.signal.aborted\n ) {\n ctx.store.setState((prev) => ({\n ...prev,\n status: \"ready\",\n error: undefined,\n }));\n return;\n }\n ctx.store.setState((prev) => ({ ...prev, status: \"error\", error }));\n ctx.onError?.(error);\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,243 @@
1
+ /*
2
+ * Copyright 2026 Palantir Technologies, Inc. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { generateMessageId, LmsChatTransport } from "@osdk/aip-core";
18
+ import React from "react";
19
+ import { createChatStore } from "./chatStore.js";
20
+ import { drainStream, runChatStream } from "./chatStream.js";
21
+
22
+ /**
23
+ * Options for {@link useChat}.
24
+ *
25
+ * v0 covers text-only chat. Tools, multi-step agent loops, and stream
26
+ * resume are not supported.
27
+ */
28
+
29
+ /** Return value of {@link useChat}. */
30
+
31
+ /** Input shape accepted by `sendMessage`. */
32
+
33
+ /**
34
+ * React hook for streaming chat completions through `@osdk/aip-core`'s
35
+ * `streamText`.
36
+ *
37
+ * @example
38
+ * ```tsx
39
+ * const { messages, status, sendMessage, stop, error } = useChat({
40
+ * model: foundryModel({ client, model: "gpt-4o" }),
41
+ * system: "You are a concise assistant.",
42
+ * });
43
+ * ```
44
+ */
45
+ export function useChat(options) {
46
+ const {
47
+ onFinish,
48
+ onError
49
+ } = options;
50
+ const id = React.useMemo(() => options.id ?? generateMessageId(), [options.id]);
51
+
52
+ // JSON-stringify keys keep the memo stable when callers pass inline objects.
53
+ const headersKey = JSON.stringify(options.headers ?? null);
54
+ const stopSequencesKey = JSON.stringify(options.stopSequences ?? null);
55
+ const transport = React.useMemo(() => {
56
+ if (options.transport != null) {
57
+ return options.transport;
58
+ }
59
+ if (options.model == null) {
60
+ throw new Error("useChat: `model` is required when no `transport` is provided.");
61
+ }
62
+ const built = {
63
+ model: options.model,
64
+ system: options.system,
65
+ temperature: options.temperature,
66
+ maxOutputTokens: options.maxOutputTokens,
67
+ topP: options.topP,
68
+ presencePenalty: options.presencePenalty,
69
+ frequencyPenalty: options.frequencyPenalty,
70
+ stopSequences: options.stopSequences,
71
+ seed: options.seed,
72
+ headers: options.headers
73
+ };
74
+ return new LmsChatTransport(built);
75
+ },
76
+ // eslint-disable-next-line react-hooks/exhaustive-deps
77
+ [options.transport, options.model, options.system, options.temperature, options.maxOutputTokens, options.topP, options.presencePenalty, options.frequencyPenalty, options.seed, headersKey, stopSequencesKey]);
78
+ const store = React.useMemo(() => createChatStore({
79
+ initialMessages: options.messages,
80
+ throttleMs: options.experimentalThrottle ?? 50
81
+ }),
82
+ // Recreating the store mid-session would drop chat state, so it's keyed
83
+ // only by `id`. Use `setMessages` to mutate messages at runtime.
84
+ // eslint-disable-next-line react-hooks/exhaustive-deps
85
+ [id]);
86
+ const state = React.useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);
87
+ const abortRef = React.useRef(undefined);
88
+ const stoppedRef = React.useRef(false);
89
+ const ctxRef = React.useRef({
90
+ store,
91
+ abortRef,
92
+ stoppedRef,
93
+ onFinish,
94
+ onError
95
+ });
96
+ ctxRef.current = {
97
+ store,
98
+ abortRef,
99
+ stoppedRef,
100
+ onFinish,
101
+ onError
102
+ };
103
+ const runStream = React.useCallback((seed, trigger) => runChatStream(ctxRef.current, transport, id, seed, trigger), [transport, id]);
104
+ const sendMessage = React.useCallback(async input => {
105
+ const userMsg = normalizeUserMessage(input);
106
+ const seeded = [...store.getSnapshot().messages, userMsg];
107
+ store.setState({
108
+ messages: seeded,
109
+ status: "submitted",
110
+ error: undefined
111
+ });
112
+ await runStream(seeded, "submit-message");
113
+ }, [store, runStream]);
114
+ const regenerate = React.useCallback(async regenerateOpts => {
115
+ const messages = store.getSnapshot().messages;
116
+ const cutoff = resolveRegenerateCutoff(messages, regenerateOpts?.messageId);
117
+ if (cutoff.kind === "noop") {
118
+ return;
119
+ }
120
+ if (cutoff.kind === "error") {
121
+ store.setState(prev => ({
122
+ ...prev,
123
+ status: "error",
124
+ error: cutoff.error
125
+ }));
126
+ return;
127
+ }
128
+ const truncated = messages.slice(0, cutoff.index);
129
+ store.setState({
130
+ messages: truncated,
131
+ status: "submitted",
132
+ error: undefined
133
+ });
134
+ await runStream(truncated, "regenerate-message");
135
+ }, [store, runStream]);
136
+ const stop = React.useCallback(() => {
137
+ stoppedRef.current = true;
138
+ abortRef.current?.abort();
139
+ abortRef.current = undefined;
140
+ }, []);
141
+ const resumeStream = React.useCallback(async () => {
142
+ const stream = await transport.reconnectToStream({
143
+ chatId: id
144
+ });
145
+ if (stream == null) {
146
+ return;
147
+ }
148
+ abortRef.current?.abort();
149
+ const ctrl = new AbortController();
150
+ abortRef.current = ctrl;
151
+ const assistantId = generateMessageId();
152
+ await drainStream(ctxRef.current, stream, assistantId, ctrl);
153
+ }, [transport, id]);
154
+ const clearError = React.useCallback(() => {
155
+ // Resetting from streaming/submitted would race the in-flight stream, so
156
+ // only reset when status === "error".
157
+ store.setState(prev => prev.status === "error" ? {
158
+ ...prev,
159
+ status: "ready",
160
+ error: undefined
161
+ } : prev);
162
+ }, [store]);
163
+ const setMessages = React.useCallback(next => {
164
+ store.setState(prev => {
165
+ if (prev.status === "streaming" || prev.status === "submitted") {
166
+ return prev;
167
+ }
168
+ return {
169
+ ...prev,
170
+ messages: typeof next === "function" ? next(prev.messages) : next
171
+ };
172
+ });
173
+ }, [store]);
174
+ return React.useMemo(() => ({
175
+ id,
176
+ messages: state.messages,
177
+ setMessages,
178
+ status: state.status,
179
+ error: state.error,
180
+ sendMessage,
181
+ regenerate,
182
+ stop,
183
+ resumeStream,
184
+ clearError
185
+ }), [id, state.messages, state.status, state.error, setMessages, sendMessage, regenerate, stop, resumeStream, clearError]);
186
+ }
187
+ function resolveRegenerateCutoff(messages, messageId) {
188
+ if (messageId != null) {
189
+ const index = messages.findIndex(m => m.id === messageId);
190
+ if (index < 0) {
191
+ return {
192
+ kind: "noop"
193
+ };
194
+ }
195
+ const target = messages[index];
196
+ if (target == null || target.role !== "assistant") {
197
+ return {
198
+ kind: "error",
199
+ error: new Error(`useChat.regenerate: messageId "${messageId}" is ` + `not an assistant message; only assistant messages can be regenerated.`)
200
+ };
201
+ }
202
+ return {
203
+ kind: "ok",
204
+ index
205
+ };
206
+ }
207
+ const lastAssistant = findLastAssistantIndex(messages);
208
+ if (lastAssistant < 0) {
209
+ return {
210
+ kind: "noop"
211
+ };
212
+ }
213
+ return {
214
+ kind: "ok",
215
+ index: lastAssistant
216
+ };
217
+ }
218
+ function normalizeUserMessage(input) {
219
+ if ("text" in input) {
220
+ return {
221
+ id: generateMessageId(),
222
+ role: "user",
223
+ parts: [{
224
+ type: "text",
225
+ text: input.text
226
+ }]
227
+ };
228
+ }
229
+ return {
230
+ id: generateMessageId(),
231
+ role: input.role,
232
+ parts: input.parts
233
+ };
234
+ }
235
+ function findLastAssistantIndex(arr) {
236
+ for (let i = arr.length - 1; i >= 0; i--) {
237
+ if (arr[i]?.role === "assistant") {
238
+ return i;
239
+ }
240
+ }
241
+ return -1;
242
+ }
243
+ //# sourceMappingURL=useChat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useChat.js","names":["generateMessageId","LmsChatTransport","React","createChatStore","drainStream","runChatStream","useChat","options","onFinish","onError","id","useMemo","headersKey","JSON","stringify","headers","stopSequencesKey","stopSequences","transport","model","Error","built","system","temperature","maxOutputTokens","topP","presencePenalty","frequencyPenalty","seed","store","initialMessages","messages","throttleMs","experimentalThrottle","state","useSyncExternalStore","subscribe","getSnapshot","abortRef","useRef","undefined","stoppedRef","ctxRef","current","runStream","useCallback","trigger","sendMessage","input","userMsg","normalizeUserMessage","seeded","setState","status","error","regenerate","regenerateOpts","cutoff","resolveRegenerateCutoff","messageId","kind","prev","truncated","slice","index","stop","abort","resumeStream","stream","reconnectToStream","chatId","ctrl","AbortController","assistantId","clearError","setMessages","next","findIndex","m","target","role","lastAssistant","findLastAssistantIndex","parts","type","text","arr","i","length"],"sources":["useChat.ts"],"sourcesContent":["/*\n * Copyright 2026 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n type ChatTransport,\n generateMessageId,\n type LanguageModel,\n LmsChatTransport,\n type LmsChatTransportOptions,\n type UIMessage,\n} from \"@osdk/aip-core\";\nimport React from \"react\";\nimport {\n type ChatStatus,\n type ChatStore,\n createChatStore,\n} from \"./chatStore.js\";\nimport {\n drainStream,\n runChatStream,\n type StreamContext,\n} from \"./chatStream.js\";\n\nexport type { ChatStatus } from \"./chatStore.js\";\n\n/**\n * Options for {@link useChat}.\n *\n * v0 covers text-only chat. Tools, multi-step agent loops, and stream\n * resume are not supported.\n */\nexport interface UseChatOptions {\n /** Required when no `transport` is provided: the LMS-backed model. */\n model?: LanguageModel;\n\n /** System prompt prepended to every request. Forwarded to the default transport. */\n system?: string;\n\n /** Sampling controls. Forwarded to the default transport. */\n temperature?: number;\n maxOutputTokens?: number;\n topP?: number;\n presencePenalty?: number;\n frequencyPenalty?: number;\n stopSequences?: Array<string>;\n seed?: number;\n headers?: Record<string, string | undefined>;\n\n /** Stable chat id. A stable id is generated if not provided. */\n id?: string;\n\n /** Initial messages — used as the seed snapshot. */\n messages?: ReadonlyArray<UIMessage>;\n\n /** Override the transport. Defaults to a new `LmsChatTransport(options)`. */\n transport?: ChatTransport<UIMessage>;\n\n /**\n * Throttle subscriber notifications during streaming (ms). Default 50ms,\n * which keeps token-by-token rendering smooth without rerendering per token.\n */\n experimentalThrottle?: number;\n\n /** Fires when an in-flight stream errors out. */\n onError?: (error: Error) => void;\n\n /** Fires once after a stream completes successfully. */\n onFinish?: (event: {\n message: UIMessage;\n messages: ReadonlyArray<UIMessage>;\n }) => void;\n}\n\n/** Return value of {@link useChat}. */\nexport interface UseChatReturn {\n id: string;\n messages: ReadonlyArray<UIMessage>;\n /** No-op while a stream is in flight (`status === \"streaming\" | \"submitted\"`). Call `stop()` first to mutate during a stream. */\n setMessages: (\n messages:\n | ReadonlyArray<UIMessage>\n | ((prev: ReadonlyArray<UIMessage>) => ReadonlyArray<UIMessage>),\n ) => void;\n\n status: ChatStatus;\n error: Error | undefined;\n\n sendMessage: (message: SendMessageInput) => Promise<void>;\n regenerate: (options?: { messageId?: string }) => Promise<void>;\n stop: () => void;\n /** Calls `transport.reconnectToStream`. v0: LMS returns null, so this is a no-op. */\n resumeStream: () => Promise<void>;\n clearError: () => void;\n}\n\n/** Input shape accepted by `sendMessage`. */\nexport type SendMessageInput =\n | { text: string }\n | { role: \"user\"; parts: UIMessage[\"parts\"] };\n\n/**\n * React hook for streaming chat completions through `@osdk/aip-core`'s\n * `streamText`.\n *\n * @example\n * ```tsx\n * const { messages, status, sendMessage, stop, error } = useChat({\n * model: foundryModel({ client, model: \"gpt-4o\" }),\n * system: \"You are a concise assistant.\",\n * });\n * ```\n */\nexport function useChat(options: UseChatOptions): UseChatReturn {\n const { onFinish, onError } = options;\n\n const id = React.useMemo(\n () => options.id ?? generateMessageId(),\n [options.id],\n );\n\n // JSON-stringify keys keep the memo stable when callers pass inline objects.\n const headersKey = JSON.stringify(options.headers ?? null);\n const stopSequencesKey = JSON.stringify(options.stopSequences ?? null);\n const transport = React.useMemo<ChatTransport<UIMessage>>(\n () => {\n if (options.transport != null) {\n return options.transport;\n }\n if (options.model == null) {\n throw new Error(\n \"useChat: `model` is required when no `transport` is provided.\",\n );\n }\n const built: LmsChatTransportOptions = {\n model: options.model,\n system: options.system,\n temperature: options.temperature,\n maxOutputTokens: options.maxOutputTokens,\n topP: options.topP,\n presencePenalty: options.presencePenalty,\n frequencyPenalty: options.frequencyPenalty,\n stopSequences: options.stopSequences,\n seed: options.seed,\n headers: options.headers,\n };\n return new LmsChatTransport(built);\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n options.transport,\n options.model,\n options.system,\n options.temperature,\n options.maxOutputTokens,\n options.topP,\n options.presencePenalty,\n options.frequencyPenalty,\n options.seed,\n headersKey,\n stopSequencesKey,\n ],\n );\n\n const store = React.useMemo<ChatStore>(\n () =>\n createChatStore({\n initialMessages: options.messages,\n throttleMs: options.experimentalThrottle ?? 50,\n }),\n // Recreating the store mid-session would drop chat state, so it's keyed\n // only by `id`. Use `setMessages` to mutate messages at runtime.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [id],\n );\n\n const state = React.useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getSnapshot,\n );\n\n const abortRef = React.useRef<AbortController | undefined>(undefined);\n const stoppedRef = React.useRef<boolean>(false);\n\n const ctxRef = React.useRef<StreamContext>({\n store,\n abortRef,\n stoppedRef,\n onFinish,\n onError,\n });\n ctxRef.current = { store, abortRef, stoppedRef, onFinish, onError };\n\n const runStream = React.useCallback(\n (\n seed: ReadonlyArray<UIMessage>,\n trigger: \"submit-message\" | \"regenerate-message\",\n ): Promise<void> =>\n runChatStream(ctxRef.current, transport, id, seed, trigger),\n [transport, id],\n );\n\n const sendMessage = React.useCallback(\n async (input: SendMessageInput): Promise<void> => {\n const userMsg = normalizeUserMessage(input);\n const seeded = [...store.getSnapshot().messages, userMsg];\n store.setState({\n messages: seeded,\n status: \"submitted\",\n error: undefined,\n });\n await runStream(seeded, \"submit-message\");\n },\n [store, runStream],\n );\n\n const regenerate = React.useCallback(\n async (regenerateOpts?: { messageId?: string }): Promise<void> => {\n const messages = store.getSnapshot().messages;\n const cutoff = resolveRegenerateCutoff(\n messages,\n regenerateOpts?.messageId,\n );\n if (cutoff.kind === \"noop\") {\n return;\n }\n if (cutoff.kind === \"error\") {\n store.setState((prev) => ({\n ...prev,\n status: \"error\",\n error: cutoff.error,\n }));\n return;\n }\n const truncated = messages.slice(0, cutoff.index);\n store.setState({\n messages: truncated,\n status: \"submitted\",\n error: undefined,\n });\n await runStream(truncated, \"regenerate-message\");\n },\n [store, runStream],\n );\n\n const stop = React.useCallback((): void => {\n stoppedRef.current = true;\n abortRef.current?.abort();\n abortRef.current = undefined;\n }, []);\n\n const resumeStream = React.useCallback(async (): Promise<void> => {\n const stream = await transport.reconnectToStream({ chatId: id });\n if (stream == null) {\n return;\n }\n abortRef.current?.abort();\n const ctrl = new AbortController();\n abortRef.current = ctrl;\n const assistantId = generateMessageId();\n await drainStream(ctxRef.current, stream, assistantId, ctrl);\n }, [transport, id]);\n\n const clearError = React.useCallback((): void => {\n // Resetting from streaming/submitted would race the in-flight stream, so\n // only reset when status === \"error\".\n store.setState(\n (prev) =>\n prev.status === \"error\"\n ? { ...prev, status: \"ready\", error: undefined }\n : prev,\n );\n }, [store]);\n\n const setMessages = React.useCallback(\n (\n next:\n | ReadonlyArray<UIMessage>\n | ((prev: ReadonlyArray<UIMessage>) => ReadonlyArray<UIMessage>),\n ): void => {\n store.setState((prev) => {\n if (prev.status === \"streaming\" || prev.status === \"submitted\") {\n return prev;\n }\n return {\n ...prev,\n messages: typeof next === \"function\" ? next(prev.messages) : next,\n };\n });\n },\n [store],\n );\n\n return React.useMemo(\n () => ({\n id,\n messages: state.messages,\n setMessages,\n status: state.status,\n error: state.error,\n sendMessage,\n regenerate,\n stop,\n resumeStream,\n clearError,\n }),\n [\n id,\n state.messages,\n state.status,\n state.error,\n setMessages,\n sendMessage,\n regenerate,\n stop,\n resumeStream,\n clearError,\n ],\n );\n}\n\ntype RegenerateCutoff =\n | { kind: \"noop\" }\n | { kind: \"error\"; error: Error }\n | { kind: \"ok\"; index: number };\n\nfunction resolveRegenerateCutoff(\n messages: ReadonlyArray<UIMessage>,\n messageId: string | undefined,\n): RegenerateCutoff {\n if (messageId != null) {\n const index = messages.findIndex((m) => m.id === messageId);\n if (index < 0) {\n return { kind: \"noop\" };\n }\n const target = messages[index];\n if (target == null || target.role !== \"assistant\") {\n return {\n kind: \"error\",\n error: new Error(\n `useChat.regenerate: messageId \"${messageId}\" is `\n + `not an assistant message; only assistant messages can be regenerated.`,\n ),\n };\n }\n return { kind: \"ok\", index };\n }\n const lastAssistant = findLastAssistantIndex(messages);\n if (lastAssistant < 0) {\n return { kind: \"noop\" };\n }\n return { kind: \"ok\", index: lastAssistant };\n}\n\nfunction normalizeUserMessage(input: SendMessageInput): UIMessage {\n if (\"text\" in input) {\n return {\n id: generateMessageId(),\n role: \"user\",\n parts: [{ type: \"text\", text: input.text }],\n };\n }\n return {\n id: generateMessageId(),\n role: input.role,\n parts: input.parts,\n };\n}\n\nfunction findLastAssistantIndex(arr: ReadonlyArray<UIMessage>): number {\n for (let i = arr.length - 1; i >= 0; i--) {\n if (arr[i]?.role === \"assistant\") {\n return i;\n }\n }\n return -1;\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,18 @@
1
+ /*
2
+ * Copyright 2026 Palantir Technologies, Inc. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ export { useChat } from "../../aip/useChat.js";
18
+ //# sourceMappingURL=aip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aip.js","names":["useChat"],"sources":["aip.ts"],"sourcesContent":["/*\n * Copyright 2026 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport type { ChatStatus } from \"../../aip/chatStore.js\";\nexport { useChat } from \"../../aip/useChat.js\";\nexport type {\n SendMessageInput,\n UseChatOptions,\n UseChatReturn,\n} from \"../../aip/useChat.js\";\n\nexport type { UIMessage, UIMessageChunk } from \"@osdk/aip-core\";\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA,SAASA,OAAO,QAAQ,sBAAsB","ignoreList":[]}
@@ -14,5 +14,5 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- export const REACT_USER_AGENT = `osdk-react/${"2.40.0"}`;
17
+ export const REACT_USER_AGENT = `osdk-react/${"2.41.0-main-d24cc61b1e7fde7722d8229ed2b6821f5ce1bf8a"}`;
18
18
  //# sourceMappingURL=UserAgent.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"UserAgent.js","names":["REACT_USER_AGENT"],"sources":["UserAgent.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport const REACT_USER_AGENT: string =\n `osdk-react/${process.env.PACKAGE_VERSION}`;\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,OAAO,MAAMA,gBAAwB,GACnC,wBAA2C","ignoreList":[]}
1
+ {"version":3,"file":"UserAgent.js","names":["REACT_USER_AGENT"],"sources":["UserAgent.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport const REACT_USER_AGENT: string =\n `osdk-react/${process.env.PACKAGE_VERSION}`;\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,OAAO,MAAMA,gBAAwB,GACnC,sEAA2C","ignoreList":[]}
@@ -0,0 +1,31 @@
1
+ import type { UIMessage } from "@osdk/aip-core";
2
+ export type ChatStatus = "ready" | "submitted" | "streaming" | "error";
3
+ export interface ChatState {
4
+ messages: ReadonlyArray<UIMessage>;
5
+ status: ChatStatus;
6
+ error: Error | undefined;
7
+ }
8
+ export interface ChatStore {
9
+ getSnapshot: () => ChatState;
10
+ /** Subscribe to state changes. Returns the unsubscribe function. */
11
+ subscribe: (notify: () => void) => () => void;
12
+ /** Replace state and notify subscribers synchronously. */
13
+ setState: (next: ChatState | ((prev: ChatState) => ChatState)) => void;
14
+ /**
15
+ * Replace state and coalesce subscriber notifications across rapid calls.
16
+ * Notifications fire `throttleMs` after the first change in a quiet window.
17
+ * Use for high-frequency updates (e.g. token streaming) where one render per
18
+ * change is wasteful.
19
+ */
20
+ setStateThrottled: (next: ChatState | ((prev: ChatState) => ChatState)) => void;
21
+ }
22
+ export interface CreateChatStoreOptions {
23
+ initialMessages?: ReadonlyArray<UIMessage>;
24
+ /** Min ms between subscriber notifications. 0 = synchronous. Defaults to 0. */
25
+ throttleMs?: number;
26
+ }
27
+ /**
28
+ * Tiny pub-sub store backing `useChat`. Throttles subscriber notifications so
29
+ * fast token-delta streams don't trigger one render per token.
30
+ */
31
+ export declare function createChatStore(options: CreateChatStoreOptions): ChatStore;
@@ -0,0 +1 @@
1
+ {"mappings":"AAgBA,cAAc,iBAAiB,gBAAiB;AAEhD,YAAY,aAAa,UAAU,cAAc,cAAc;AAE/D,iBAAiB,UAAU;CACzB,UAAU,cAAc;CACxB,QAAQ;CACR,OAAO;AACR;AAED,iBAAiB,UAAU;CACzB,mBAAmB;;CAEnB,YAAYA;;CAEZ,WACEC,MAAM,cAAcC,MAAM,cAAc;;;;;;;CAQ1C,oBACED,MAAM,cAAcC,MAAM,cAAc;AAE3C;AAED,iBAAiB,uBAAuB;CACtC,kBAAkB,cAAc;;CAEhC;AACD;;;;;AAMD,OAAO,iBAAS,gBAAgBC,SAAS,yBAAyB","names":["notify: () => void","next: ChatState | ((prev: ChatState) => ChatState)","prev: ChatState","options: CreateChatStoreOptions"],"sources":["../../../src/aip/chatStore.ts"],"version":3,"file":"chatStore.d.ts"}
@@ -0,0 +1,20 @@
1
+ import { type ChatTransport, type UIMessage, type UIMessageChunk } from "@osdk/aip-core";
2
+ import type React from "react";
3
+ import type { ChatStore } from "./chatStore.js";
4
+ /**
5
+ * Mutable orchestration handle threaded through the streaming functions.
6
+ * Holds everything they need to read snapshots, mutate state, and check
7
+ * whether their stream is still the active one.
8
+ */
9
+ export interface StreamContext {
10
+ store: ChatStore;
11
+ abortRef: React.MutableRefObject<AbortController | undefined>;
12
+ stoppedRef: React.MutableRefObject<boolean>;
13
+ onFinish: ((event: {
14
+ message: UIMessage
15
+ messages: ReadonlyArray<UIMessage>
16
+ }) => void) | undefined;
17
+ onError: ((error: Error) => void) | undefined;
18
+ }
19
+ export declare function runChatStream(ctx: StreamContext, transport: ChatTransport<UIMessage>, chatId: string, seed: ReadonlyArray<UIMessage>, trigger: "submit-message" | "regenerate-message"): Promise<void>;
20
+ export declare function drainStream(ctx: StreamContext, stream: ReadableStream<UIMessageChunk>, assistantMessageId: string, capturedCtrl: AbortController): Promise<void>;
@@ -0,0 +1 @@
1
+ {"mappings":"AAgBA,cACO,oBAEA,gBACA,sBACA,gBAAiB;AACxB,YAAY,WAAW,OAAQ;AAC/B,cAAc,iBAAiB,gBAAiB;;;;;;AAOhD,iBAAiB,cAAc;CAC7B,OAAO;CACP,UAAU,MAAM,iBAAiB;CACjC,YAAY,MAAM;CAClB,YACMA,OAAO;EACT,SAAS;EACT,UAAU,cAAc;CACzB;CAEH,WAAWC,OAAO;AACnB;AAED,OAAO,iBAAe,cACpBC,KAAK,eACLC,WAAW,cAAc,YACzBC,gBACAC,MAAM,cAAc,YACpBC,SAAS,mBAAmB,uBAC3B;AAqBH,OAAO,iBAAe,YACpBJ,KAAK,eACLK,QAAQ,eAAe,iBACvBC,4BACAC,cAAc,kBACb","names":["event: {\n message: UIMessage;\n messages: ReadonlyArray<UIMessage>;\n }","error: Error","ctx: StreamContext","transport: ChatTransport<UIMessage>","chatId: string","seed: ReadonlyArray<UIMessage>","trigger: \"submit-message\" | \"regenerate-message\"","stream: ReadableStream<UIMessageChunk>","assistantMessageId: string","capturedCtrl: AbortController"],"sources":["../../../src/aip/chatStream.ts"],"version":3,"file":"chatStream.d.ts"}