@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.
- package/CHANGELOG.md +16 -0
- package/build/browser/aip/chatStore.js +67 -0
- package/build/browser/aip/chatStore.js.map +1 -0
- package/build/browser/aip/chatStream.js +155 -0
- package/build/browser/aip/chatStream.js.map +1 -0
- package/build/browser/aip/useChat.js +243 -0
- package/build/browser/aip/useChat.js.map +1 -0
- package/build/browser/public/experimental/aip.js +18 -0
- package/build/browser/public/experimental/aip.js.map +1 -0
- package/build/browser/util/UserAgent.js +1 -1
- package/build/browser/util/UserAgent.js.map +1 -1
- package/build/cjs/{chunk-L33DWZUR.cjs → chunk-QNNQV2NH.cjs} +3 -3
- package/build/cjs/chunk-QNNQV2NH.cjs.map +1 -0
- package/build/cjs/index.cjs +15 -15
- package/build/cjs/public/experimental/aip.cjs +389 -0
- package/build/cjs/public/experimental/aip.cjs.map +1 -0
- package/build/cjs/public/experimental/aip.d.cts +83 -0
- package/build/cjs/public/experimental.cjs +16 -16
- package/build/esm/aip/chatStore.js +67 -0
- package/build/esm/aip/chatStore.js.map +1 -0
- package/build/esm/aip/chatStream.js +155 -0
- package/build/esm/aip/chatStream.js.map +1 -0
- package/build/esm/aip/useChat.js +243 -0
- package/build/esm/aip/useChat.js.map +1 -0
- package/build/esm/public/experimental/aip.js +18 -0
- package/build/esm/public/experimental/aip.js.map +1 -0
- package/build/esm/util/UserAgent.js +1 -1
- package/build/esm/util/UserAgent.js.map +1 -1
- package/build/types/aip/chatStore.d.ts +31 -0
- package/build/types/aip/chatStore.d.ts.map +1 -0
- package/build/types/aip/chatStream.d.ts +20 -0
- package/build/types/aip/chatStream.d.ts.map +1 -0
- package/build/types/aip/useChat.d.ts +79 -0
- package/build/types/aip/useChat.d.ts.map +1 -0
- package/build/types/public/experimental/aip.d.ts +4 -0
- package/build/types/public/experimental/aip.d.ts.map +1 -0
- package/experimental/aip.d.ts +17 -0
- package/package.json +22 -8
- package/build/cjs/chunk-L33DWZUR.cjs.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @osdkkit/react
|
|
2
2
|
|
|
3
|
+
## 2.41.0-main-d24cc61b1e7fde7722d8229ed2b6821f5ce1bf8a
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- afc63a7: Restore the AIP chat entry points (`@osdk/react/experimental/aip` and `@osdk/react-components/experimental/aip-agent-chat`) and publish `@osdk/aip-core` so the optional peer dependency resolves from the registry.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- d24cc61: Pin the `@osdk/aip-core` peerDependency range to `>=0.5.0 <1.0.0` instead of `workspace:^` so a minor bump of `@osdk/aip-core` (e.g. 0.5.0 -> 0.6.0) no longer falls out of the caret range and triggers a major-bump cascade across the release plan.
|
|
12
|
+
- Updated dependencies [afc63a7]
|
|
13
|
+
- Updated dependencies [9b150d7]
|
|
14
|
+
- Updated dependencies [15a35f2]
|
|
15
|
+
- @osdk/aip-core@0.6.0-main-d24cc61b1e7fde7722d8229ed2b6821f5ce1bf8a
|
|
16
|
+
- @osdk/client@2.41.0-main-d24cc61b1e7fde7722d8229ed2b6821f5ce1bf8a
|
|
17
|
+
- @osdk/api@2.41.0-main-d24cc61b1e7fde7722d8229ed2b6821f5ce1bf8a
|
|
18
|
+
|
|
3
19
|
## 2.40.0
|
|
4
20
|
|
|
5
21
|
### Minor Changes
|
|
@@ -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
|
|
@@ -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":[]}
|
|
@@ -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,
|
|
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":[]}
|
|
@@ -29,7 +29,7 @@ function useStableObjectSet(objectSet) {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
// src/util/UserAgent.ts
|
|
32
|
-
var REACT_USER_AGENT = `osdk-react/${"2.
|
|
32
|
+
var REACT_USER_AGENT = `osdk-react/${"2.41.0-main-d24cc61b1e7fde7722d8229ed2b6821f5ce1bf8a"}`;
|
|
33
33
|
function useDevToolsClient(baseClient, enabled) {
|
|
34
34
|
const stateRef = React5.useRef(null);
|
|
35
35
|
const prev = stateRef.current;
|
|
@@ -926,5 +926,5 @@ exports.useOsdkObject = useOsdkObject;
|
|
|
926
926
|
exports.useOsdkObjects = useOsdkObjects;
|
|
927
927
|
exports.useRegisterUserAgent = useRegisterUserAgent;
|
|
928
928
|
exports.useStableObjectSet = useStableObjectSet;
|
|
929
|
-
//# sourceMappingURL=chunk-
|
|
930
|
-
//# sourceMappingURL=chunk-
|
|
929
|
+
//# sourceMappingURL=chunk-QNNQV2NH.cjs.map
|
|
930
|
+
//# sourceMappingURL=chunk-QNNQV2NH.cjs.map
|