@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,389 @@
1
+ 'use strict';
2
+
3
+ var aipCore = require('@osdk/aip-core');
4
+ var React = require('react');
5
+
6
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
7
+
8
+ var React__default = /*#__PURE__*/_interopDefault(React);
9
+
10
+ // src/aip/useChat.ts
11
+
12
+ // src/aip/chatStore.ts
13
+ function createChatStore(options) {
14
+ let state = {
15
+ messages: options.initialMessages ?? [],
16
+ status: "ready",
17
+ error: void 0
18
+ };
19
+ const subscribers = /* @__PURE__ */ new Set();
20
+ const throttleMs = options.throttleMs ?? 0;
21
+ let pendingNotify;
22
+ const notifyNow = () => {
23
+ if (pendingNotify != null) {
24
+ clearTimeout(pendingNotify);
25
+ pendingNotify = void 0;
26
+ }
27
+ for (const s of subscribers) {
28
+ s();
29
+ }
30
+ };
31
+ const notifyThrottled = () => {
32
+ if (throttleMs <= 0) {
33
+ notifyNow();
34
+ return;
35
+ }
36
+ if (pendingNotify != null) {
37
+ return;
38
+ }
39
+ pendingNotify = setTimeout(notifyNow, throttleMs);
40
+ };
41
+ return {
42
+ getSnapshot: () => state,
43
+ subscribe: (notify) => {
44
+ subscribers.add(notify);
45
+ return () => {
46
+ subscribers.delete(notify);
47
+ };
48
+ },
49
+ setState: (next) => {
50
+ state = typeof next === "function" ? next(state) : next;
51
+ notifyNow();
52
+ },
53
+ setStateThrottled: (next) => {
54
+ state = typeof next === "function" ? next(state) : next;
55
+ notifyThrottled();
56
+ }
57
+ };
58
+ }
59
+ async function runChatStream(ctx, transport, chatId, seed, trigger) {
60
+ ctx.abortRef.current?.abort();
61
+ const ctrl = new AbortController();
62
+ ctx.abortRef.current = ctrl;
63
+ ctx.stoppedRef.current = false;
64
+ const assistantId = aipCore.generateMessageId();
65
+ try {
66
+ const stream = await transport.sendMessages({
67
+ trigger,
68
+ chatId,
69
+ messageId: assistantId,
70
+ messages: seed.slice(),
71
+ abortSignal: ctrl.signal
72
+ });
73
+ await drainStream(ctx, stream, assistantId, ctrl);
74
+ } catch (err) {
75
+ handleStreamError(ctx, err, ctrl);
76
+ }
77
+ }
78
+ async function drainStream(ctx, stream, assistantMessageId, capturedCtrl) {
79
+ const {
80
+ store
81
+ } = ctx;
82
+ const reader = stream.getReader();
83
+ let textBuf = "";
84
+ const isStale = () => ctx.abortRef.current != null && ctx.abortRef.current !== capturedCtrl;
85
+ const isOrphaned = () => {
86
+ const messages = store.getSnapshot().messages;
87
+ return textBuf.length > 0 && !messages.some((m) => m.id === assistantMessageId);
88
+ };
89
+ try {
90
+ while (true) {
91
+ const {
92
+ done,
93
+ value
94
+ } = await reader.read();
95
+ if (done) {
96
+ break;
97
+ }
98
+ if (isStale()) {
99
+ await reader.cancel();
100
+ return;
101
+ }
102
+ if (isOrphaned()) {
103
+ await reader.cancel();
104
+ store.setState((prev) => ({
105
+ ...prev,
106
+ status: "ready"
107
+ }));
108
+ return;
109
+ }
110
+ if (value.type === "text-delta") {
111
+ textBuf += value.delta;
112
+ upsertAssistantText(store, assistantMessageId, textBuf);
113
+ } else if (value.type === "error") {
114
+ if (ctx.stoppedRef.current || capturedCtrl.signal.aborted) {
115
+ return;
116
+ }
117
+ await reader.cancel();
118
+ throw new Error(value.errorText);
119
+ }
120
+ }
121
+ if (isStale()) {
122
+ return;
123
+ }
124
+ store.setState((prev) => ({
125
+ ...prev,
126
+ status: "ready"
127
+ }));
128
+ const finalSnap = store.getSnapshot();
129
+ const finalMessage = finalSnap.messages.find((m) => m.id === assistantMessageId);
130
+ if (finalMessage != null && ctx.onFinish != null) {
131
+ ctx.onFinish({
132
+ message: finalMessage,
133
+ messages: finalSnap.messages
134
+ });
135
+ }
136
+ } catch (err) {
137
+ handleStreamError(ctx, err, capturedCtrl);
138
+ } finally {
139
+ reader.releaseLock();
140
+ }
141
+ }
142
+ function upsertAssistantText(store, assistantMessageId, text) {
143
+ store.setStateThrottled((prev) => {
144
+ const exists = prev.messages.some((m) => m.id === assistantMessageId);
145
+ const messages = exists ? prev.messages.map((m) => m.id === assistantMessageId ? {
146
+ ...m,
147
+ parts: [{
148
+ type: "text",
149
+ text
150
+ }]
151
+ } : m) : [...prev.messages, {
152
+ id: assistantMessageId,
153
+ role: "assistant",
154
+ parts: [{
155
+ type: "text",
156
+ text
157
+ }]
158
+ }];
159
+ return {
160
+ ...prev,
161
+ status: "streaming",
162
+ messages
163
+ };
164
+ });
165
+ }
166
+ function handleStreamError(ctx, err, capturedCtrl) {
167
+ if (ctx.abortRef.current != null && ctx.abortRef.current !== capturedCtrl) {
168
+ return;
169
+ }
170
+ const error = err instanceof Error ? err : new Error(String(err));
171
+ if (ctx.stoppedRef.current || error.name === "AbortError" || capturedCtrl.signal.aborted) {
172
+ ctx.store.setState((prev) => ({
173
+ ...prev,
174
+ status: "ready",
175
+ error: void 0
176
+ }));
177
+ return;
178
+ }
179
+ ctx.store.setState((prev) => ({
180
+ ...prev,
181
+ status: "error",
182
+ error
183
+ }));
184
+ ctx.onError?.(error);
185
+ }
186
+
187
+ // src/aip/useChat.ts
188
+ function useChat(options) {
189
+ const {
190
+ onFinish,
191
+ onError
192
+ } = options;
193
+ const id = React__default.default.useMemo(() => options.id ?? aipCore.generateMessageId(), [options.id]);
194
+ const headersKey = JSON.stringify(options.headers ?? null);
195
+ const stopSequencesKey = JSON.stringify(options.stopSequences ?? null);
196
+ const transport = React__default.default.useMemo(
197
+ () => {
198
+ if (options.transport != null) {
199
+ return options.transport;
200
+ }
201
+ if (options.model == null) {
202
+ throw new Error("useChat: `model` is required when no `transport` is provided.");
203
+ }
204
+ const built = {
205
+ model: options.model,
206
+ system: options.system,
207
+ temperature: options.temperature,
208
+ maxOutputTokens: options.maxOutputTokens,
209
+ topP: options.topP,
210
+ presencePenalty: options.presencePenalty,
211
+ frequencyPenalty: options.frequencyPenalty,
212
+ stopSequences: options.stopSequences,
213
+ seed: options.seed,
214
+ headers: options.headers
215
+ };
216
+ return new aipCore.LmsChatTransport(built);
217
+ },
218
+ // eslint-disable-next-line react-hooks/exhaustive-deps
219
+ [options.transport, options.model, options.system, options.temperature, options.maxOutputTokens, options.topP, options.presencePenalty, options.frequencyPenalty, options.seed, headersKey, stopSequencesKey]
220
+ );
221
+ const store = React__default.default.useMemo(
222
+ () => createChatStore({
223
+ initialMessages: options.messages,
224
+ throttleMs: options.experimentalThrottle ?? 50
225
+ }),
226
+ // Recreating the store mid-session would drop chat state, so it's keyed
227
+ // only by `id`. Use `setMessages` to mutate messages at runtime.
228
+ // eslint-disable-next-line react-hooks/exhaustive-deps
229
+ [id]
230
+ );
231
+ const state = React__default.default.useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);
232
+ const abortRef = React__default.default.useRef(void 0);
233
+ const stoppedRef = React__default.default.useRef(false);
234
+ const ctxRef = React__default.default.useRef({
235
+ store,
236
+ abortRef,
237
+ stoppedRef,
238
+ onFinish,
239
+ onError
240
+ });
241
+ ctxRef.current = {
242
+ store,
243
+ abortRef,
244
+ stoppedRef,
245
+ onFinish,
246
+ onError
247
+ };
248
+ const runStream = React__default.default.useCallback((seed, trigger) => runChatStream(ctxRef.current, transport, id, seed, trigger), [transport, id]);
249
+ const sendMessage = React__default.default.useCallback(async (input) => {
250
+ const userMsg = normalizeUserMessage(input);
251
+ const seeded = [...store.getSnapshot().messages, userMsg];
252
+ store.setState({
253
+ messages: seeded,
254
+ status: "submitted",
255
+ error: void 0
256
+ });
257
+ await runStream(seeded, "submit-message");
258
+ }, [store, runStream]);
259
+ const regenerate = React__default.default.useCallback(async (regenerateOpts) => {
260
+ const messages = store.getSnapshot().messages;
261
+ const cutoff = resolveRegenerateCutoff(messages, regenerateOpts?.messageId);
262
+ if (cutoff.kind === "noop") {
263
+ return;
264
+ }
265
+ if (cutoff.kind === "error") {
266
+ store.setState((prev) => ({
267
+ ...prev,
268
+ status: "error",
269
+ error: cutoff.error
270
+ }));
271
+ return;
272
+ }
273
+ const truncated = messages.slice(0, cutoff.index);
274
+ store.setState({
275
+ messages: truncated,
276
+ status: "submitted",
277
+ error: void 0
278
+ });
279
+ await runStream(truncated, "regenerate-message");
280
+ }, [store, runStream]);
281
+ const stop = React__default.default.useCallback(() => {
282
+ stoppedRef.current = true;
283
+ abortRef.current?.abort();
284
+ abortRef.current = void 0;
285
+ }, []);
286
+ const resumeStream = React__default.default.useCallback(async () => {
287
+ const stream = await transport.reconnectToStream({
288
+ chatId: id
289
+ });
290
+ if (stream == null) {
291
+ return;
292
+ }
293
+ abortRef.current?.abort();
294
+ const ctrl = new AbortController();
295
+ abortRef.current = ctrl;
296
+ const assistantId = aipCore.generateMessageId();
297
+ await drainStream(ctxRef.current, stream, assistantId, ctrl);
298
+ }, [transport, id]);
299
+ const clearError = React__default.default.useCallback(() => {
300
+ store.setState((prev) => prev.status === "error" ? {
301
+ ...prev,
302
+ status: "ready",
303
+ error: void 0
304
+ } : prev);
305
+ }, [store]);
306
+ const setMessages = React__default.default.useCallback((next) => {
307
+ store.setState((prev) => {
308
+ if (prev.status === "streaming" || prev.status === "submitted") {
309
+ return prev;
310
+ }
311
+ return {
312
+ ...prev,
313
+ messages: typeof next === "function" ? next(prev.messages) : next
314
+ };
315
+ });
316
+ }, [store]);
317
+ return React__default.default.useMemo(() => ({
318
+ id,
319
+ messages: state.messages,
320
+ setMessages,
321
+ status: state.status,
322
+ error: state.error,
323
+ sendMessage,
324
+ regenerate,
325
+ stop,
326
+ resumeStream,
327
+ clearError
328
+ }), [id, state.messages, state.status, state.error, setMessages, sendMessage, regenerate, stop, resumeStream, clearError]);
329
+ }
330
+ function resolveRegenerateCutoff(messages, messageId) {
331
+ if (messageId != null) {
332
+ const index = messages.findIndex((m) => m.id === messageId);
333
+ if (index < 0) {
334
+ return {
335
+ kind: "noop"
336
+ };
337
+ }
338
+ const target = messages[index];
339
+ if (target == null || target.role !== "assistant") {
340
+ return {
341
+ kind: "error",
342
+ error: new Error(`useChat.regenerate: messageId "${messageId}" is not an assistant message; only assistant messages can be regenerated.`)
343
+ };
344
+ }
345
+ return {
346
+ kind: "ok",
347
+ index
348
+ };
349
+ }
350
+ const lastAssistant = findLastAssistantIndex(messages);
351
+ if (lastAssistant < 0) {
352
+ return {
353
+ kind: "noop"
354
+ };
355
+ }
356
+ return {
357
+ kind: "ok",
358
+ index: lastAssistant
359
+ };
360
+ }
361
+ function normalizeUserMessage(input) {
362
+ if ("text" in input) {
363
+ return {
364
+ id: aipCore.generateMessageId(),
365
+ role: "user",
366
+ parts: [{
367
+ type: "text",
368
+ text: input.text
369
+ }]
370
+ };
371
+ }
372
+ return {
373
+ id: aipCore.generateMessageId(),
374
+ role: input.role,
375
+ parts: input.parts
376
+ };
377
+ }
378
+ function findLastAssistantIndex(arr) {
379
+ for (let i = arr.length - 1; i >= 0; i--) {
380
+ if (arr[i]?.role === "assistant") {
381
+ return i;
382
+ }
383
+ }
384
+ return -1;
385
+ }
386
+
387
+ exports.useChat = useChat;
388
+ //# sourceMappingURL=aip.cjs.map
389
+ //# sourceMappingURL=aip.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/aip/chatStore.ts","../../../../src/aip/chatStream.ts","../../../../src/aip/useChat.ts"],"names":["generateMessageId","React","LmsChatTransport"],"mappings":"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","file":"aip.cjs","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\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) {\n let state = {\n messages: options.initialMessages ?? [],\n status: \"ready\",\n error: undefined\n };\n const subscribers = new Set();\n const throttleMs = options.throttleMs ?? 0;\n let pendingNotify;\n const notifyNow = () => {\n if (pendingNotify != null) {\n clearTimeout(pendingNotify);\n pendingNotify = undefined;\n }\n for (const s of subscribers) {\n s();\n }\n };\n const notifyThrottled = () => {\n if (throttleMs <= 0) {\n notifyNow();\n return;\n }\n if (pendingNotify != null) {\n return;\n }\n pendingNotify = setTimeout(notifyNow, throttleMs);\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 * 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 { generateMessageId } from \"@osdk/aip-core\";\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 */\n\nexport async function runChatStream(ctx, transport, chatId, seed, trigger) {\n ctx.abortRef.current?.abort();\n const ctrl = new AbortController();\n ctx.abortRef.current = ctrl;\n ctx.stoppedRef.current = false;\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}\nexport async function drainStream(ctx, stream, assistantMessageId, capturedCtrl) {\n const {\n store\n } = ctx;\n const reader = stream.getReader();\n let textBuf = \"\";\n const isStale = () => 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 = () => {\n const messages = store.getSnapshot().messages;\n return textBuf.length > 0 && !messages.some(m => m.id === assistantMessageId);\n };\n try {\n while (true) {\n const {\n done,\n value\n } = 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 => ({\n ...prev,\n status: \"ready\"\n }));\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 => ({\n ...prev,\n status: \"ready\"\n }));\n const finalSnap = store.getSnapshot();\n const finalMessage = finalSnap.messages.find(m => m.id === assistantMessageId);\n if (finalMessage != null && ctx.onFinish != null) {\n ctx.onFinish({\n message: finalMessage,\n messages: finalSnap.messages\n });\n }\n } catch (err) {\n handleStreamError(ctx, err, capturedCtrl);\n } finally {\n reader.releaseLock();\n }\n}\nfunction upsertAssistantText(store, assistantMessageId, text) {\n store.setStateThrottled(prev => {\n const exists = prev.messages.some(m => m.id === assistantMessageId);\n const messages = exists ? prev.messages.map(m => m.id === assistantMessageId ? {\n ...m,\n parts: [{\n type: \"text\",\n text\n }]\n } : m) : [...prev.messages, {\n id: assistantMessageId,\n role: \"assistant\",\n parts: [{\n type: \"text\",\n text\n }]\n }];\n return {\n ...prev,\n status: \"streaming\",\n messages\n };\n });\n}\nfunction handleStreamError(ctx, err, capturedCtrl) {\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 (ctx.stoppedRef.current || error.name === \"AbortError\" || capturedCtrl.signal.aborted) {\n ctx.store.setState(prev => ({\n ...prev,\n status: \"ready\",\n error: undefined\n }));\n return;\n }\n ctx.store.setState(prev => ({\n ...prev,\n status: \"error\",\n error\n }));\n ctx.onError?.(error);\n}","/*\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 { generateMessageId, LmsChatTransport } from \"@osdk/aip-core\";\nimport React from \"react\";\nimport { createChatStore } from \"./chatStore.js\";\nimport { drainStream, runChatStream } from \"./chatStream.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 */\n\n/** Return value of {@link useChat}. */\n\n/** Input shape accepted by `sendMessage`. */\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) {\n const {\n onFinish,\n onError\n } = options;\n const id = React.useMemo(() => options.id ?? generateMessageId(), [options.id]);\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(() => {\n if (options.transport != null) {\n return options.transport;\n }\n if (options.model == null) {\n throw new Error(\"useChat: `model` is required when no `transport` is provided.\");\n }\n const built = {\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 [options.transport, options.model, options.system, options.temperature, options.maxOutputTokens, options.topP, options.presencePenalty, options.frequencyPenalty, options.seed, headersKey, stopSequencesKey]);\n const store = React.useMemo(() => 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 const state = React.useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);\n const abortRef = React.useRef(undefined);\n const stoppedRef = React.useRef(false);\n const ctxRef = React.useRef({\n store,\n abortRef,\n stoppedRef,\n onFinish,\n onError\n });\n ctxRef.current = {\n store,\n abortRef,\n stoppedRef,\n onFinish,\n onError\n };\n const runStream = React.useCallback((seed, trigger) => runChatStream(ctxRef.current, transport, id, seed, trigger), [transport, id]);\n const sendMessage = React.useCallback(async input => {\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 }, [store, runStream]);\n const regenerate = React.useCallback(async regenerateOpts => {\n const messages = store.getSnapshot().messages;\n const cutoff = resolveRegenerateCutoff(messages, regenerateOpts?.messageId);\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 }, [store, runStream]);\n const stop = React.useCallback(() => {\n stoppedRef.current = true;\n abortRef.current?.abort();\n abortRef.current = undefined;\n }, []);\n const resumeStream = React.useCallback(async () => {\n const stream = await transport.reconnectToStream({\n chatId: id\n });\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 const clearError = React.useCallback(() => {\n // Resetting from streaming/submitted would race the in-flight stream, so\n // only reset when status === \"error\".\n store.setState(prev => prev.status === \"error\" ? {\n ...prev,\n status: \"ready\",\n error: undefined\n } : prev);\n }, [store]);\n const setMessages = React.useCallback(next => {\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 }, [store]);\n return React.useMemo(() => ({\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 }), [id, state.messages, state.status, state.error, setMessages, sendMessage, regenerate, stop, resumeStream, clearError]);\n}\nfunction resolveRegenerateCutoff(messages, messageId) {\n if (messageId != null) {\n const index = messages.findIndex(m => m.id === messageId);\n if (index < 0) {\n return {\n kind: \"noop\"\n };\n }\n const target = messages[index];\n if (target == null || target.role !== \"assistant\") {\n return {\n kind: \"error\",\n error: new Error(`useChat.regenerate: messageId \"${messageId}\" is ` + `not an assistant message; only assistant messages can be regenerated.`)\n };\n }\n return {\n kind: \"ok\",\n index\n };\n }\n const lastAssistant = findLastAssistantIndex(messages);\n if (lastAssistant < 0) {\n return {\n kind: \"noop\"\n };\n }\n return {\n kind: \"ok\",\n index: lastAssistant\n };\n}\nfunction normalizeUserMessage(input) {\n if (\"text\" in input) {\n return {\n id: generateMessageId(),\n role: \"user\",\n parts: [{\n type: \"text\",\n text: input.text\n }]\n };\n }\n return {\n id: generateMessageId(),\n role: input.role,\n parts: input.parts\n };\n}\nfunction findLastAssistantIndex(arr) {\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}"]}
@@ -0,0 +1,83 @@
1
+ import { UIMessage, LanguageModel, ChatTransport } from '@osdk/aip-core';
2
+ export { UIMessage, UIMessageChunk } from '@osdk/aip-core';
3
+
4
+ type ChatStatus = "ready" | "submitted" | "streaming" | "error";
5
+
6
+ /**
7
+ * Options for {@link useChat}.
8
+ *
9
+ * v0 covers text-only chat. Tools, multi-step agent loops, and stream
10
+ * resume are not supported.
11
+ */
12
+ interface UseChatOptions {
13
+ /** Required when no `transport` is provided: the LMS-backed model. */
14
+ model?: LanguageModel;
15
+ /** System prompt prepended to every request. Forwarded to the default transport. */
16
+ system?: string;
17
+ /** Sampling controls. Forwarded to the default transport. */
18
+ temperature?: number;
19
+ maxOutputTokens?: number;
20
+ topP?: number;
21
+ presencePenalty?: number;
22
+ frequencyPenalty?: number;
23
+ stopSequences?: Array<string>;
24
+ seed?: number;
25
+ headers?: Record<string, string | undefined>;
26
+ /** Stable chat id. A stable id is generated if not provided. */
27
+ id?: string;
28
+ /** Initial messages — used as the seed snapshot. */
29
+ messages?: ReadonlyArray<UIMessage>;
30
+ /** Override the transport. Defaults to a new `LmsChatTransport(options)`. */
31
+ transport?: ChatTransport<UIMessage>;
32
+ /**
33
+ * Throttle subscriber notifications during streaming (ms). Default 50ms,
34
+ * which keeps token-by-token rendering smooth without rerendering per token.
35
+ */
36
+ experimentalThrottle?: number;
37
+ /** Fires when an in-flight stream errors out. */
38
+ onError?: (error: Error) => void;
39
+ /** Fires once after a stream completes successfully. */
40
+ onFinish?: (event: {
41
+ message: UIMessage;
42
+ messages: ReadonlyArray<UIMessage>;
43
+ }) => void;
44
+ }
45
+ /** Return value of {@link useChat}. */
46
+ interface UseChatReturn {
47
+ id: string;
48
+ messages: ReadonlyArray<UIMessage>;
49
+ /** No-op while a stream is in flight (`status === "streaming" | "submitted"`). Call `stop()` first to mutate during a stream. */
50
+ setMessages: (messages: ReadonlyArray<UIMessage> | ((prev: ReadonlyArray<UIMessage>) => ReadonlyArray<UIMessage>)) => void;
51
+ status: ChatStatus;
52
+ error: Error | undefined;
53
+ sendMessage: (message: SendMessageInput) => Promise<void>;
54
+ regenerate: (options?: {
55
+ messageId?: string;
56
+ }) => Promise<void>;
57
+ stop: () => void;
58
+ /** Calls `transport.reconnectToStream`. v0: LMS returns null, so this is a no-op. */
59
+ resumeStream: () => Promise<void>;
60
+ clearError: () => void;
61
+ }
62
+ /** Input shape accepted by `sendMessage`. */
63
+ type SendMessageInput = {
64
+ text: string;
65
+ } | {
66
+ role: "user";
67
+ parts: UIMessage["parts"];
68
+ };
69
+ /**
70
+ * React hook for streaming chat completions through `@osdk/aip-core`'s
71
+ * `streamText`.
72
+ *
73
+ * @example
74
+ * ```tsx
75
+ * const { messages, status, sendMessage, stop, error } = useChat({
76
+ * model: foundryModel({ client, model: "gpt-4o" }),
77
+ * system: "You are a concise assistant.",
78
+ * });
79
+ * ```
80
+ */
81
+ declare function useChat(options: UseChatOptions): UseChatReturn;
82
+
83
+ export { type ChatStatus, type SendMessageInput, type UseChatOptions, type UseChatReturn, useChat };
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkL33DWZUR_cjs = require('../chunk-L33DWZUR.cjs');
3
+ var chunkQNNQV2NH_cjs = require('../chunk-QNNQV2NH.cjs');
4
4
  var chunkOGP2DK2V_cjs = require('../chunk-OGP2DK2V.cjs');
5
5
  require('../chunk-UKQGMTMG.cjs');
6
6
  require('../chunk-DO3NFBKN.cjs');
@@ -9,63 +9,63 @@ require('../chunk-DO3NFBKN.cjs');
9
9
 
10
10
  Object.defineProperty(exports, "OsdkProvider2", {
11
11
  enumerable: true,
12
- get: function () { return chunkL33DWZUR_cjs.OsdkProvider; }
12
+ get: function () { return chunkQNNQV2NH_cjs.OsdkProvider; }
13
13
  });
14
14
  Object.defineProperty(exports, "useDebouncedCallback", {
15
15
  enumerable: true,
16
- get: function () { return chunkL33DWZUR_cjs.useDebouncedCallback; }
16
+ get: function () { return chunkQNNQV2NH_cjs.useDebouncedCallback; }
17
17
  });
18
18
  Object.defineProperty(exports, "useLinks", {
19
19
  enumerable: true,
20
- get: function () { return chunkL33DWZUR_cjs.useLinks; }
20
+ get: function () { return chunkQNNQV2NH_cjs.useLinks; }
21
21
  });
22
22
  Object.defineProperty(exports, "useObjectSet", {
23
23
  enumerable: true,
24
- get: function () { return chunkL33DWZUR_cjs.useObjectSet; }
24
+ get: function () { return chunkQNNQV2NH_cjs.useObjectSet; }
25
25
  });
26
26
  Object.defineProperty(exports, "useOsdkAction", {
27
27
  enumerable: true,
28
- get: function () { return chunkL33DWZUR_cjs.useOsdkAction; }
28
+ get: function () { return chunkQNNQV2NH_cjs.useOsdkAction; }
29
29
  });
30
30
  Object.defineProperty(exports, "useOsdkAggregation", {
31
31
  enumerable: true,
32
- get: function () { return chunkL33DWZUR_cjs.useOsdkAggregation; }
32
+ get: function () { return chunkQNNQV2NH_cjs.useOsdkAggregation; }
33
33
  });
34
34
  Object.defineProperty(exports, "useOsdkClient", {
35
35
  enumerable: true,
36
- get: function () { return chunkL33DWZUR_cjs.useOsdkClient; }
36
+ get: function () { return chunkQNNQV2NH_cjs.useOsdkClient; }
37
37
  });
38
38
  Object.defineProperty(exports, "useOsdkClient2", {
39
39
  enumerable: true,
40
- get: function () { return chunkL33DWZUR_cjs.useOsdkClient; }
40
+ get: function () { return chunkQNNQV2NH_cjs.useOsdkClient; }
41
41
  });
42
42
  Object.defineProperty(exports, "useOsdkFunction", {
43
43
  enumerable: true,
44
- get: function () { return chunkL33DWZUR_cjs.useOsdkFunction; }
44
+ get: function () { return chunkQNNQV2NH_cjs.useOsdkFunction; }
45
45
  });
46
46
  Object.defineProperty(exports, "useOsdkFunctions", {
47
47
  enumerable: true,
48
- get: function () { return chunkL33DWZUR_cjs.useOsdkFunctions; }
48
+ get: function () { return chunkQNNQV2NH_cjs.useOsdkFunctions; }
49
49
  });
50
50
  Object.defineProperty(exports, "useOsdkMetadata", {
51
51
  enumerable: true,
52
- get: function () { return chunkL33DWZUR_cjs.useOsdkMetadata; }
52
+ get: function () { return chunkQNNQV2NH_cjs.useOsdkMetadata; }
53
53
  });
54
54
  Object.defineProperty(exports, "useOsdkObject", {
55
55
  enumerable: true,
56
- get: function () { return chunkL33DWZUR_cjs.useOsdkObject; }
56
+ get: function () { return chunkQNNQV2NH_cjs.useOsdkObject; }
57
57
  });
58
58
  Object.defineProperty(exports, "useOsdkObjects", {
59
59
  enumerable: true,
60
- get: function () { return chunkL33DWZUR_cjs.useOsdkObjects; }
60
+ get: function () { return chunkQNNQV2NH_cjs.useOsdkObjects; }
61
61
  });
62
62
  Object.defineProperty(exports, "useRegisterUserAgent", {
63
63
  enumerable: true,
64
- get: function () { return chunkL33DWZUR_cjs.useRegisterUserAgent; }
64
+ get: function () { return chunkQNNQV2NH_cjs.useRegisterUserAgent; }
65
65
  });
66
66
  Object.defineProperty(exports, "useStableObjectSet", {
67
67
  enumerable: true,
68
- get: function () { return chunkL33DWZUR_cjs.useStableObjectSet; }
68
+ get: function () { return chunkQNNQV2NH_cjs.useStableObjectSet; }
69
69
  });
70
70
  Object.defineProperty(exports, "getRegisteredDevTools", {
71
71
  enumerable: true,
@@ -0,0 +1,67 @@
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
+ /**
18
+ * Tiny pub-sub store backing `useChat`. Throttles subscriber notifications so
19
+ * fast token-delta streams don't trigger one render per token.
20
+ */
21
+ export function createChatStore(options) {
22
+ let state = {
23
+ messages: options.initialMessages ?? [],
24
+ status: "ready",
25
+ error: undefined
26
+ };
27
+ const subscribers = new Set();
28
+ const throttleMs = options.throttleMs ?? 0;
29
+ let pendingNotify;
30
+ const notifyNow = () => {
31
+ if (pendingNotify != null) {
32
+ clearTimeout(pendingNotify);
33
+ pendingNotify = undefined;
34
+ }
35
+ for (const s of subscribers) {
36
+ s();
37
+ }
38
+ };
39
+ const notifyThrottled = () => {
40
+ if (throttleMs <= 0) {
41
+ notifyNow();
42
+ return;
43
+ }
44
+ if (pendingNotify != null) {
45
+ return;
46
+ }
47
+ pendingNotify = setTimeout(notifyNow, throttleMs);
48
+ };
49
+ return {
50
+ getSnapshot: () => state,
51
+ subscribe: notify => {
52
+ subscribers.add(notify);
53
+ return () => {
54
+ subscribers.delete(notify);
55
+ };
56
+ },
57
+ setState: next => {
58
+ state = typeof next === "function" ? next(state) : next;
59
+ notifyNow();
60
+ },
61
+ setStateThrottled: next => {
62
+ state = typeof next === "function" ? next(state) : next;
63
+ notifyThrottled();
64
+ }
65
+ };
66
+ }
67
+ //# sourceMappingURL=chatStore.js.map