@assistant-ui/react 0.5.42 → 0.5.45
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/dist/index.d.mts +24 -2
- package/dist/index.d.ts +24 -2
- package/dist/index.js +221 -55
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +175 -9
- package/dist/index.mjs.map +1 -1
- package/dist/styles/index.css +3 -0
- package/dist/styles/index.css.map +1 -1
- package/dist/styles/tailwindcss/thread.css +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
@@ -164,6 +164,7 @@ import { create as create4 } from "zustand";
|
|
164
164
|
var getThreadStateFromRuntime = (runtime) => {
|
165
165
|
const lastMessage = runtime.messages.at(-1);
|
166
166
|
return Object.freeze({
|
167
|
+
threadId: runtime.threadId,
|
167
168
|
capabilities: runtime.capabilities,
|
168
169
|
isDisabled: runtime.isDisabled,
|
169
170
|
isRunning: lastMessage?.role !== "assistant" ? false : lastMessage.status.type === "running"
|
@@ -636,6 +637,9 @@ var useSmooth = (state, smooth = false) => {
|
|
636
637
|
setDisplayedText(text2);
|
637
638
|
useSmoothStatus2?.setState(text2 !== state.part.text ? SMOOTH_STATUS : state.status);
|
638
639
|
});
|
640
|
+
useEffect(() => {
|
641
|
+
useSmoothStatus2?.setState(text !== displayedText ? SMOOTH_STATUS : state.status);
|
642
|
+
}, [useSmoothStatus2, text, displayedText, state.status]);
|
639
643
|
const [animatorRef] = useState2(
|
640
644
|
new TextStreamAnimator(text, setText)
|
641
645
|
);
|
@@ -1077,6 +1081,7 @@ var LocalThreadRuntime = class {
|
|
1077
1081
|
constructor(configProvider, adapter, { initialMessages, ...options }) {
|
1078
1082
|
this.configProvider = configProvider;
|
1079
1083
|
this.adapter = adapter;
|
1084
|
+
this.threadId = generateId();
|
1080
1085
|
this.options = options;
|
1081
1086
|
if (initialMessages) {
|
1082
1087
|
let parentId = null;
|
@@ -1098,6 +1103,7 @@ var LocalThreadRuntime = class {
|
|
1098
1103
|
unstable_copy: true,
|
1099
1104
|
speak: false
|
1100
1105
|
};
|
1106
|
+
threadId;
|
1101
1107
|
isDisabled = false;
|
1102
1108
|
get messages() {
|
1103
1109
|
return this.repository.getMessages();
|
@@ -1400,11 +1406,12 @@ var getAutoStatus = (isLast, isRunning) => isLast && isRunning ? AUTO_STATUS_RUN
|
|
1400
1406
|
|
1401
1407
|
// src/runtimes/external-store/ThreadMessageLike.tsx
|
1402
1408
|
var fromThreadMessageLike = (like, fallbackId, fallbackStatus) => {
|
1403
|
-
const { role,
|
1409
|
+
const { role, id, createdAt, status } = like;
|
1404
1410
|
const common = {
|
1405
1411
|
id: id ?? fallbackId,
|
1406
1412
|
createdAt: createdAt ?? /* @__PURE__ */ new Date()
|
1407
1413
|
};
|
1414
|
+
const content = typeof like.content === "string" ? [{ type: "text", text: like.content }] : like.content;
|
1408
1415
|
switch (role) {
|
1409
1416
|
case "assistant":
|
1410
1417
|
return {
|
@@ -1414,6 +1421,8 @@ var fromThreadMessageLike = (like, fallbackId, fallbackStatus) => {
|
|
1414
1421
|
const type = part.type;
|
1415
1422
|
switch (type) {
|
1416
1423
|
case "text":
|
1424
|
+
if (part.text.trim().length === 0) return null;
|
1425
|
+
return part;
|
1417
1426
|
case "ui":
|
1418
1427
|
return part;
|
1419
1428
|
case "tool-call": {
|
@@ -1428,7 +1437,7 @@ var fromThreadMessageLike = (like, fallbackId, fallbackStatus) => {
|
|
1428
1437
|
throw new Error(`Unknown content part type: ${unhandledType}`);
|
1429
1438
|
}
|
1430
1439
|
}
|
1431
|
-
}),
|
1440
|
+
}).filter((c) => !!c),
|
1432
1441
|
status: status ?? fallbackStatus
|
1433
1442
|
};
|
1434
1443
|
case "user":
|
@@ -1493,8 +1502,9 @@ var ExternalStoreThreadRuntime = class {
|
|
1493
1502
|
get capabilities() {
|
1494
1503
|
return this._capabilities;
|
1495
1504
|
}
|
1496
|
-
|
1497
|
-
|
1505
|
+
threadId;
|
1506
|
+
messages;
|
1507
|
+
isDisabled;
|
1498
1508
|
converter = new ThreadMessageConverter();
|
1499
1509
|
_store;
|
1500
1510
|
composer = {
|
@@ -1507,8 +1517,12 @@ var ExternalStoreThreadRuntime = class {
|
|
1507
1517
|
constructor(store) {
|
1508
1518
|
this.store = store;
|
1509
1519
|
}
|
1520
|
+
get store() {
|
1521
|
+
return this._store;
|
1522
|
+
}
|
1510
1523
|
set store(store) {
|
1511
1524
|
if (this._store === store) return;
|
1525
|
+
this.threadId = store.threadId ?? this.threadId ?? generateId();
|
1512
1526
|
const isRunning = store.isRunning ?? false;
|
1513
1527
|
this.isDisabled = store.isDisabled ?? false;
|
1514
1528
|
const oldStore = this._store;
|
@@ -1644,6 +1658,9 @@ var ExternalStoreRuntime = class extends BaseAssistantRuntime {
|
|
1644
1658
|
constructor(store) {
|
1645
1659
|
super(new ExternalStoreThreadRuntime(store));
|
1646
1660
|
}
|
1661
|
+
get store() {
|
1662
|
+
return this.thread.store;
|
1663
|
+
}
|
1647
1664
|
set store(store) {
|
1648
1665
|
this.thread.store = store;
|
1649
1666
|
}
|
@@ -1684,6 +1701,153 @@ var useExternalStoreRuntime = (store) => {
|
|
1684
1701
|
return runtime;
|
1685
1702
|
};
|
1686
1703
|
|
1704
|
+
// src/runtimes/external-store/external-message-converter.tsx
|
1705
|
+
import { useMemo as useMemo2 } from "react";
|
1706
|
+
var joinExternalMessages = (messages) => {
|
1707
|
+
const assistantMessage = {
|
1708
|
+
role: "assistant",
|
1709
|
+
content: []
|
1710
|
+
};
|
1711
|
+
for (const output of messages) {
|
1712
|
+
if (output.role === "tool") {
|
1713
|
+
const toolCallIdx = assistantMessage.content.findIndex(
|
1714
|
+
(c) => c.type === "tool-call" && c.toolCallId === output.toolCallId
|
1715
|
+
);
|
1716
|
+
if (toolCallIdx !== -1) {
|
1717
|
+
const toolCall = assistantMessage.content[toolCallIdx];
|
1718
|
+
if (output.toolName) {
|
1719
|
+
if (toolCall.toolName !== output.toolName)
|
1720
|
+
throw new Error(
|
1721
|
+
`Tool call name ${output.toolCallId} ${output.toolName} does not match existing tool call ${toolCall.toolName}`
|
1722
|
+
);
|
1723
|
+
}
|
1724
|
+
assistantMessage.content[toolCallIdx] = {
|
1725
|
+
...toolCall,
|
1726
|
+
result: output.result
|
1727
|
+
};
|
1728
|
+
} else {
|
1729
|
+
throw new Error(
|
1730
|
+
`Tool call ${output.toolCallId} ${output.toolName} not found in assistant message`
|
1731
|
+
);
|
1732
|
+
}
|
1733
|
+
} else {
|
1734
|
+
const content = output.content;
|
1735
|
+
const role = output.role;
|
1736
|
+
switch (role) {
|
1737
|
+
case "system":
|
1738
|
+
case "user":
|
1739
|
+
return { role, content };
|
1740
|
+
case "assistant":
|
1741
|
+
if (assistantMessage.content.length === 0) {
|
1742
|
+
assistantMessage.id = output.id;
|
1743
|
+
assistantMessage.createdAt ??= output.createdAt;
|
1744
|
+
assistantMessage.status ??= output.status;
|
1745
|
+
}
|
1746
|
+
assistantMessage.content.push(...content);
|
1747
|
+
break;
|
1748
|
+
default: {
|
1749
|
+
const unsupportedRole = role;
|
1750
|
+
throw new Error(`Unknown message role: ${unsupportedRole}`);
|
1751
|
+
}
|
1752
|
+
}
|
1753
|
+
}
|
1754
|
+
}
|
1755
|
+
return assistantMessage;
|
1756
|
+
};
|
1757
|
+
var chunkExternalMessages = (callbackResults) => {
|
1758
|
+
const results = [];
|
1759
|
+
let isAssistant = false;
|
1760
|
+
let inputs = [];
|
1761
|
+
let outputs = [];
|
1762
|
+
const flush = () => {
|
1763
|
+
if (outputs.length) {
|
1764
|
+
results.push({
|
1765
|
+
inputs,
|
1766
|
+
outputs
|
1767
|
+
});
|
1768
|
+
}
|
1769
|
+
inputs = [];
|
1770
|
+
outputs = [];
|
1771
|
+
};
|
1772
|
+
for (const callbackResult of callbackResults) {
|
1773
|
+
for (const output of callbackResult.outputs) {
|
1774
|
+
if (!isAssistant || output.role === "user" || output.role === "system") {
|
1775
|
+
flush();
|
1776
|
+
}
|
1777
|
+
isAssistant = output.role === "assistant" || output.role === "tool";
|
1778
|
+
if (inputs.at(-1) !== callbackResult.input) {
|
1779
|
+
inputs.push(callbackResult.input);
|
1780
|
+
}
|
1781
|
+
outputs.push(output);
|
1782
|
+
}
|
1783
|
+
}
|
1784
|
+
flush();
|
1785
|
+
return results;
|
1786
|
+
};
|
1787
|
+
var useExternalMessageConverter = ({
|
1788
|
+
callback,
|
1789
|
+
messages,
|
1790
|
+
isRunning
|
1791
|
+
}) => {
|
1792
|
+
const state = useMemo2(
|
1793
|
+
() => ({
|
1794
|
+
callback,
|
1795
|
+
callbackCache: /* @__PURE__ */ new WeakMap(),
|
1796
|
+
chunkCache: /* @__PURE__ */ new WeakMap(),
|
1797
|
+
converterCache: new ThreadMessageConverter()
|
1798
|
+
}),
|
1799
|
+
[callback]
|
1800
|
+
);
|
1801
|
+
return useMemo2(() => {
|
1802
|
+
const callbackResults = [];
|
1803
|
+
for (const message of messages) {
|
1804
|
+
let result = state.callbackCache.get(message);
|
1805
|
+
if (!result) {
|
1806
|
+
const output = state.callback(message);
|
1807
|
+
const outputs = Array.isArray(output) ? output : [output];
|
1808
|
+
result = { input: message, outputs };
|
1809
|
+
state.callbackCache.set(message, result);
|
1810
|
+
}
|
1811
|
+
callbackResults.push(result);
|
1812
|
+
}
|
1813
|
+
const chunks = chunkExternalMessages(callbackResults).map((m) => {
|
1814
|
+
const key = m.outputs[0];
|
1815
|
+
if (!key) return m;
|
1816
|
+
const cached = state.chunkCache.get(key);
|
1817
|
+
if (cached && shallowArrayEqual(cached.outputs, m.outputs)) return cached;
|
1818
|
+
state.chunkCache.set(key, m);
|
1819
|
+
return m;
|
1820
|
+
});
|
1821
|
+
return state.converterCache.convertMessages(
|
1822
|
+
chunks,
|
1823
|
+
(cache, message, idx) => {
|
1824
|
+
const isLast = idx === chunks.length - 1;
|
1825
|
+
const autoStatus = getAutoStatus(isLast, isRunning);
|
1826
|
+
if (cache && (cache.role !== "assistant" || !isAutoStatus(cache.status) || cache.status === autoStatus)) {
|
1827
|
+
const inputs = getExternalStoreMessage(cache);
|
1828
|
+
if (shallowArrayEqual(inputs, message.inputs)) {
|
1829
|
+
return cache;
|
1830
|
+
}
|
1831
|
+
}
|
1832
|
+
const newMessage = fromThreadMessageLike(
|
1833
|
+
joinExternalMessages(message.outputs),
|
1834
|
+
idx.toString(),
|
1835
|
+
autoStatus
|
1836
|
+
);
|
1837
|
+
newMessage[symbolInnerMessage] = message.inputs;
|
1838
|
+
return newMessage;
|
1839
|
+
}
|
1840
|
+
);
|
1841
|
+
}, [state, messages, isRunning]);
|
1842
|
+
};
|
1843
|
+
var shallowArrayEqual = (a, b) => {
|
1844
|
+
if (a.length !== b.length) return false;
|
1845
|
+
for (let i = 0; i < a.length; i++) {
|
1846
|
+
if (a[i] !== b[i]) return false;
|
1847
|
+
}
|
1848
|
+
return true;
|
1849
|
+
};
|
1850
|
+
|
1687
1851
|
// src/runtimes/dangerous-in-browser/useDangerousInBrowserRuntime.ts
|
1688
1852
|
import { useState as useState6 } from "react";
|
1689
1853
|
|
@@ -1788,7 +1952,7 @@ var ThreadProvider = ({
|
|
1788
1952
|
const thread = provider.thread;
|
1789
1953
|
const oldState = context.useThread.getState();
|
1790
1954
|
const state = getThreadStateFromRuntime(thread);
|
1791
|
-
if (oldState.isDisabled !== state.isDisabled || oldState.isRunning !== state.isRunning || // TODO ensure capabilities is memoized
|
1955
|
+
if (oldState.threadId !== state.threadId || oldState.isDisabled !== state.isDisabled || oldState.isRunning !== state.isRunning || // TODO ensure capabilities is memoized
|
1792
1956
|
oldState.capabilities !== state.capabilities) {
|
1793
1957
|
context.useThread.setState(
|
1794
1958
|
state,
|
@@ -1877,7 +2041,7 @@ var AssistantRuntimeProviderImpl = ({ children, runtime }) => {
|
|
1877
2041
|
var AssistantRuntimeProvider = memo(AssistantRuntimeProviderImpl);
|
1878
2042
|
|
1879
2043
|
// src/context/react/ComposerContext.ts
|
1880
|
-
import { useMemo as
|
2044
|
+
import { useMemo as useMemo3 } from "react";
|
1881
2045
|
|
1882
2046
|
// src/context/react/MessageContext.ts
|
1883
2047
|
import { createContext as createContext4, useContext as useContext4 } from "react";
|
@@ -1895,7 +2059,7 @@ function useMessageContext(options) {
|
|
1895
2059
|
var useComposerContext = () => {
|
1896
2060
|
const { useComposer } = useThreadContext();
|
1897
2061
|
const { useEditComposer } = useMessageContext({ optional: true }) ?? {};
|
1898
|
-
return
|
2062
|
+
return useMemo3(
|
1899
2063
|
() => ({
|
1900
2064
|
useComposer: useEditComposer ?? useComposer,
|
1901
2065
|
type: useEditComposer ? "edit" : "new"
|
@@ -2035,7 +2199,7 @@ var useAssistantInstructions = (instruction) => {
|
|
2035
2199
|
import { useCallback as useCallback3 } from "react";
|
2036
2200
|
|
2037
2201
|
// src/utils/combined/useCombinedStore.ts
|
2038
|
-
import { useMemo as
|
2202
|
+
import { useMemo as useMemo4 } from "react";
|
2039
2203
|
|
2040
2204
|
// src/utils/combined/createCombinedStore.ts
|
2041
2205
|
import { useSyncExternalStore } from "react";
|
@@ -2056,7 +2220,7 @@ var createCombinedStore = (stores) => {
|
|
2056
2220
|
|
2057
2221
|
// src/utils/combined/useCombinedStore.ts
|
2058
2222
|
var useCombinedStore = (stores, selector) => {
|
2059
|
-
const useCombined =
|
2223
|
+
const useCombined = useMemo4(() => createCombinedStore(stores), stores);
|
2060
2224
|
return useCombined(selector);
|
2061
2225
|
};
|
2062
2226
|
|
@@ -2918,6 +3082,7 @@ var MessageContentPartComponent = ({
|
|
2918
3082
|
const Tool = by_name[part.toolName] || Fallback2;
|
2919
3083
|
const addResult = (result) => addToolResult({
|
2920
3084
|
messageId: useMessage.getState().message.id,
|
3085
|
+
toolName: part.toolName,
|
2921
3086
|
toolCallId: part.toolCallId,
|
2922
3087
|
result
|
2923
3088
|
});
|
@@ -4327,6 +4492,7 @@ export {
|
|
4327
4492
|
useContentPartText,
|
4328
4493
|
useDangerousInBrowserRuntime,
|
4329
4494
|
useEdgeRuntime,
|
4495
|
+
useExternalMessageConverter,
|
4330
4496
|
useExternalStoreRuntime,
|
4331
4497
|
useLocalRuntime,
|
4332
4498
|
useMessageContext,
|