@assistant-ui/react 0.4.8 → 0.5.2
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/edge.d.mts +9 -15
- package/dist/edge.d.ts +9 -15
- package/dist/edge.js +90 -16
- package/dist/edge.js.map +1 -1
- package/dist/edge.mjs +90 -16
- package/dist/edge.mjs.map +1 -1
- package/dist/index.d.mts +78 -49
- package/dist/index.d.ts +78 -49
- package/dist/index.js +313 -169
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +311 -169
- package/dist/index.mjs.map +1 -1
- package/dist/styles/index.css.map +1 -1
- package/package.json +5 -5
package/dist/index.js
CHANGED
@@ -53,11 +53,13 @@ __export(src_exports, {
|
|
53
53
|
ThreadWelcome: () => thread_welcome_default,
|
54
54
|
UserActionBar: () => user_action_bar_default,
|
55
55
|
UserMessage: () => user_message_default,
|
56
|
+
fromCoreMessage: () => fromCoreMessage,
|
56
57
|
fromCoreMessages: () => fromCoreMessages,
|
57
58
|
fromLanguageModelMessages: () => fromLanguageModelMessages,
|
58
59
|
fromLanguageModelTools: () => fromLanguageModelTools,
|
59
60
|
makeAssistantTool: () => makeAssistantTool,
|
60
61
|
makeAssistantToolUI: () => makeAssistantToolUI,
|
62
|
+
toCoreMessage: () => toCoreMessage,
|
61
63
|
toCoreMessages: () => toCoreMessages,
|
62
64
|
toLanguageModelMessages: () => toLanguageModelMessages,
|
63
65
|
toLanguageModelTools: () => toLanguageModelTools,
|
@@ -397,13 +399,17 @@ var ThreadProvider = ({
|
|
397
399
|
(0, import_react4.useCallback)(
|
398
400
|
(thread) => {
|
399
401
|
const onThreadUpdate = () => {
|
400
|
-
context.useThread.
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
402
|
+
if (thread.isRunning !== context.useThread.getState().isRunning) {
|
403
|
+
context.useThread.setState(
|
404
|
+
Object.freeze({
|
405
|
+
isRunning: thread.isRunning
|
406
|
+
}),
|
407
|
+
true
|
408
|
+
);
|
409
|
+
}
|
410
|
+
if (thread.messages !== context.useThreadMessages.getState()) {
|
411
|
+
context.useThreadMessages.setState(thread.messages, true);
|
412
|
+
}
|
407
413
|
};
|
408
414
|
onThreadUpdate();
|
409
415
|
return thread.subscribe(onThreadUpdate);
|
@@ -1256,12 +1262,35 @@ var import_react38 = require("react");
|
|
1256
1262
|
var import_react34 = require("react");
|
1257
1263
|
var import_zustand10 = require("zustand");
|
1258
1264
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
1259
|
-
var
|
1265
|
+
var COMPLETE_STATUS = {
|
1266
|
+
type: "complete"
|
1267
|
+
};
|
1268
|
+
var toContentPartStatus = (message, partIndex, part) => {
|
1269
|
+
if (message.role !== "assistant") return COMPLETE_STATUS;
|
1270
|
+
const isLastPart = partIndex === Math.max(0, message.content.length - 1);
|
1271
|
+
if (part.type !== "tool-call") {
|
1272
|
+
if ("reason" in message.status && message.status.reason === "tool-calls" && isLastPart)
|
1273
|
+
throw new Error(
|
1274
|
+
"Encountered unexpected requires-action status. This is likely an internal bug in assistant-ui."
|
1275
|
+
);
|
1276
|
+
return isLastPart ? message.status : COMPLETE_STATUS;
|
1277
|
+
}
|
1278
|
+
if (!!part.result) {
|
1279
|
+
return COMPLETE_STATUS;
|
1280
|
+
}
|
1281
|
+
return message.status;
|
1282
|
+
};
|
1283
|
+
var EMPTY_CONTENT = Object.freeze({ type: "text", text: "" });
|
1260
1284
|
var syncContentPart = ({ message }, useContentPart, partIndex) => {
|
1261
|
-
|
1262
|
-
if (!part)
|
1263
|
-
|
1264
|
-
|
1285
|
+
let part = message.content[partIndex];
|
1286
|
+
if (!part) {
|
1287
|
+
if (message.content.length === 0 && partIndex === 0) {
|
1288
|
+
part = EMPTY_CONTENT;
|
1289
|
+
} else {
|
1290
|
+
return;
|
1291
|
+
}
|
1292
|
+
}
|
1293
|
+
const status = toContentPartStatus(message, partIndex, part);
|
1265
1294
|
const currentState = useContentPart.getState();
|
1266
1295
|
if (currentState.part === part && currentState.status === status) return;
|
1267
1296
|
useContentPart.setState(
|
@@ -1386,7 +1415,7 @@ var ContentPartPrimitiveText = (0, import_react36.forwardRef)(({ smooth = true,
|
|
1386
1415
|
part: { text }
|
1387
1416
|
} = useContentPartText();
|
1388
1417
|
const smoothText = useSmooth(text, smooth);
|
1389
|
-
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_primitive4.Primitive.span, { "data-status": status, ...rest, ref: forwardedRef, children: smoothText });
|
1418
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_primitive4.Primitive.span, { "data-status": status.type, ...rest, ref: forwardedRef, children: smoothText });
|
1390
1419
|
});
|
1391
1420
|
ContentPartPrimitiveText.displayName = "ContentPartPrimitive.Text";
|
1392
1421
|
|
@@ -1414,7 +1443,7 @@ ContentPartPrimitiveDisplay.displayName = "ContentPartPrimitive.Display";
|
|
1414
1443
|
// src/primitives/contentPart/ContentPartInProgress.tsx
|
1415
1444
|
var ContentPartPrimitiveInProgress = ({ children }) => {
|
1416
1445
|
const { useContentPart } = useContentPartContext();
|
1417
|
-
const isInProgress = useContentPart((c) => c.status.type === "
|
1446
|
+
const isInProgress = useContentPart((c) => c.status.type === "running");
|
1418
1447
|
return isInProgress ? children : null;
|
1419
1448
|
};
|
1420
1449
|
ContentPartPrimitiveInProgress.displayName = "ContentPartPrimitive.InProgress";
|
@@ -1453,10 +1482,16 @@ var MessageContentPartComponent = ({
|
|
1453
1482
|
const type = part.type;
|
1454
1483
|
switch (type) {
|
1455
1484
|
case "text":
|
1485
|
+
if (status.type === "requires-action")
|
1486
|
+
throw new Error("Encountered unexpected requires-action status");
|
1456
1487
|
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Text2, { part, status });
|
1457
1488
|
case "image":
|
1489
|
+
if (status.type === "requires-action")
|
1490
|
+
throw new Error("Encountered unexpected requires-action status");
|
1458
1491
|
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Image2, { part, status });
|
1459
1492
|
case "ui":
|
1493
|
+
if (status.type === "requires-action")
|
1494
|
+
throw new Error("Encountered unexpected requires-action status");
|
1460
1495
|
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(UI, { part, status });
|
1461
1496
|
case "tool-call": {
|
1462
1497
|
const Tool = by_name[part.toolName] || Fallback2;
|
@@ -1486,7 +1521,7 @@ var MessagePrimitiveContent = ({
|
|
1486
1521
|
components
|
1487
1522
|
}) => {
|
1488
1523
|
const { useMessage } = useMessageContext();
|
1489
|
-
const contentLength = useMessage((s) => s.message.content.length);
|
1524
|
+
const contentLength = useMessage((s) => s.message.content.length) || 1;
|
1490
1525
|
return new Array(contentLength).fill(null).map((_, idx) => {
|
1491
1526
|
const partIndex = idx;
|
1492
1527
|
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
@@ -1783,7 +1818,7 @@ var useThreadViewportAutoScroll = ({
|
|
1783
1818
|
const div = divRef.current;
|
1784
1819
|
if (!div) return;
|
1785
1820
|
const isAtBottom = useViewport.getState().isAtBottom;
|
1786
|
-
const newIsAtBottom = div.scrollHeight - div.scrollTop <= div.clientHeight;
|
1821
|
+
const newIsAtBottom = div.scrollHeight - div.scrollTop <= div.clientHeight + 1;
|
1787
1822
|
if (!newIsAtBottom && lastScrollTop.current < div.scrollTop) {
|
1788
1823
|
} else {
|
1789
1824
|
if (newIsAtBottom) {
|
@@ -2019,6 +2054,40 @@ var ThreadPrimitiveSuggestion = createActionButton(
|
|
2019
2054
|
// src/runtimes/local/useLocalRuntime.tsx
|
2020
2055
|
var import_react54 = require("react");
|
2021
2056
|
|
2057
|
+
// src/runtimes/core/BaseAssistantRuntime.tsx
|
2058
|
+
var BaseAssistantRuntime = class {
|
2059
|
+
constructor(_thread) {
|
2060
|
+
this._thread = _thread;
|
2061
|
+
this._thread = _thread;
|
2062
|
+
}
|
2063
|
+
get thread() {
|
2064
|
+
return this._thread;
|
2065
|
+
}
|
2066
|
+
set thread(thread) {
|
2067
|
+
this._thread = thread;
|
2068
|
+
this.subscriptionHandler();
|
2069
|
+
}
|
2070
|
+
_subscriptions = /* @__PURE__ */ new Set();
|
2071
|
+
subscribe(callback) {
|
2072
|
+
this._subscriptions.add(callback);
|
2073
|
+
return () => this._subscriptions.delete(callback);
|
2074
|
+
}
|
2075
|
+
subscriptionHandler = () => {
|
2076
|
+
for (const callback of this._subscriptions) callback();
|
2077
|
+
};
|
2078
|
+
};
|
2079
|
+
|
2080
|
+
// src/internal.ts
|
2081
|
+
var internal_exports = {};
|
2082
|
+
__export(internal_exports, {
|
2083
|
+
BaseAssistantRuntime: () => BaseAssistantRuntime,
|
2084
|
+
MessageRepository: () => MessageRepository,
|
2085
|
+
ProxyConfigProvider: () => ProxyConfigProvider,
|
2086
|
+
TooltipIconButton: () => TooltipIconButton,
|
2087
|
+
generateId: () => generateId,
|
2088
|
+
useSmooth: () => useSmooth
|
2089
|
+
});
|
2090
|
+
|
2022
2091
|
// src/utils/idUtils.tsx
|
2023
2092
|
var import_non_secure = require("nanoid/non-secure");
|
2024
2093
|
var generateId = (0, import_non_secure.customAlphabet)(
|
@@ -2028,6 +2097,54 @@ var generateId = (0, import_non_secure.customAlphabet)(
|
|
2028
2097
|
var optimisticPrefix = "__optimistic__";
|
2029
2098
|
var generateOptimisticId = () => `${optimisticPrefix}${generateId()}`;
|
2030
2099
|
|
2100
|
+
// src/runtimes/edge/converters/fromCoreMessage.ts
|
2101
|
+
var fromCoreMessages = (message) => {
|
2102
|
+
return message.map((message2) => fromCoreMessage(message2));
|
2103
|
+
};
|
2104
|
+
var fromCoreMessage = (message, {
|
2105
|
+
id = generateId(),
|
2106
|
+
status = { type: "complete", reason: "unknown" }
|
2107
|
+
} = {}) => {
|
2108
|
+
const commonProps = {
|
2109
|
+
id,
|
2110
|
+
createdAt: /* @__PURE__ */ new Date()
|
2111
|
+
};
|
2112
|
+
const role = message.role;
|
2113
|
+
switch (role) {
|
2114
|
+
case "assistant":
|
2115
|
+
return {
|
2116
|
+
...commonProps,
|
2117
|
+
role,
|
2118
|
+
content: message.content.map((part) => {
|
2119
|
+
if (part.type === "tool-call") {
|
2120
|
+
return {
|
2121
|
+
...part,
|
2122
|
+
argsText: JSON.stringify(part.args)
|
2123
|
+
};
|
2124
|
+
}
|
2125
|
+
return part;
|
2126
|
+
}),
|
2127
|
+
status
|
2128
|
+
};
|
2129
|
+
case "user":
|
2130
|
+
return {
|
2131
|
+
...commonProps,
|
2132
|
+
role,
|
2133
|
+
content: message.content
|
2134
|
+
};
|
2135
|
+
case "system":
|
2136
|
+
return {
|
2137
|
+
...commonProps,
|
2138
|
+
role,
|
2139
|
+
content: message.content
|
2140
|
+
};
|
2141
|
+
default: {
|
2142
|
+
const unsupportedRole = role;
|
2143
|
+
throw new Error(`Unknown message role: ${unsupportedRole}`);
|
2144
|
+
}
|
2145
|
+
}
|
2146
|
+
};
|
2147
|
+
|
2031
2148
|
// src/runtimes/utils/MessageRepository.tsx
|
2032
2149
|
var findHead = (message) => {
|
2033
2150
|
if (message.next) return findHead(message.next);
|
@@ -2118,12 +2235,13 @@ var MessageRepository = class {
|
|
2118
2235
|
do {
|
2119
2236
|
optimisticId = generateOptimisticId();
|
2120
2237
|
} while (this.messages.has(optimisticId));
|
2121
|
-
this.addOrUpdateMessage(
|
2122
|
-
|
2123
|
-
|
2124
|
-
|
2125
|
-
|
2126
|
-
|
2238
|
+
this.addOrUpdateMessage(
|
2239
|
+
parentId,
|
2240
|
+
fromCoreMessage(message, {
|
2241
|
+
id: optimisticId,
|
2242
|
+
status: { type: "running" }
|
2243
|
+
})
|
2244
|
+
);
|
2127
2245
|
return optimisticId;
|
2128
2246
|
}
|
2129
2247
|
deleteMessage(messageId, replacementId) {
|
@@ -2190,40 +2308,6 @@ var MessageRepository = class {
|
|
2190
2308
|
}
|
2191
2309
|
};
|
2192
2310
|
|
2193
|
-
// src/runtimes/core/BaseAssistantRuntime.tsx
|
2194
|
-
var BaseAssistantRuntime = class {
|
2195
|
-
constructor(_thread) {
|
2196
|
-
this._thread = _thread;
|
2197
|
-
this._thread = _thread;
|
2198
|
-
}
|
2199
|
-
get thread() {
|
2200
|
-
return this._thread;
|
2201
|
-
}
|
2202
|
-
set thread(thread) {
|
2203
|
-
this._thread = thread;
|
2204
|
-
this.subscriptionHandler();
|
2205
|
-
}
|
2206
|
-
_subscriptions = /* @__PURE__ */ new Set();
|
2207
|
-
subscribe(callback) {
|
2208
|
-
this._subscriptions.add(callback);
|
2209
|
-
return () => this._subscriptions.delete(callback);
|
2210
|
-
}
|
2211
|
-
subscriptionHandler = () => {
|
2212
|
-
for (const callback of this._subscriptions) callback();
|
2213
|
-
};
|
2214
|
-
};
|
2215
|
-
|
2216
|
-
// src/internal.ts
|
2217
|
-
var internal_exports = {};
|
2218
|
-
__export(internal_exports, {
|
2219
|
-
BaseAssistantRuntime: () => BaseAssistantRuntime,
|
2220
|
-
MessageRepository: () => MessageRepository,
|
2221
|
-
ProxyConfigProvider: () => ProxyConfigProvider,
|
2222
|
-
TooltipIconButton: () => TooltipIconButton,
|
2223
|
-
generateId: () => generateId,
|
2224
|
-
useSmooth: () => useSmooth
|
2225
|
-
});
|
2226
|
-
|
2227
2311
|
// src/ui/base/tooltip-icon-button.tsx
|
2228
2312
|
var import_react52 = require("react");
|
2229
2313
|
|
@@ -2538,35 +2622,43 @@ var fromLanguageModelMessages = (lm, { mergeRoundtrips }) => {
|
|
2538
2622
|
return messages;
|
2539
2623
|
};
|
2540
2624
|
|
2541
|
-
// src/runtimes/edge/converters/fromCoreMessage.ts
|
2542
|
-
var fromCoreMessages = (message) => {
|
2543
|
-
return message.map((message2) => {
|
2544
|
-
return {
|
2545
|
-
id: generateId(),
|
2546
|
-
createdAt: /* @__PURE__ */ new Date(),
|
2547
|
-
...message2.role === "assistant" ? {
|
2548
|
-
status: { type: "done" }
|
2549
|
-
} : void 0,
|
2550
|
-
...message2
|
2551
|
-
};
|
2552
|
-
});
|
2553
|
-
};
|
2554
|
-
|
2555
2625
|
// src/runtimes/edge/converters/toCoreMessages.ts
|
2556
2626
|
var toCoreMessages = (message) => {
|
2557
|
-
return message.map(
|
2558
|
-
|
2559
|
-
|
2560
|
-
|
2561
|
-
|
2562
|
-
|
2563
|
-
|
2564
|
-
|
2565
|
-
|
2566
|
-
|
2567
|
-
|
2568
|
-
|
2569
|
-
|
2627
|
+
return message.map(toCoreMessage);
|
2628
|
+
};
|
2629
|
+
var toCoreMessage = (message) => {
|
2630
|
+
const role = message.role;
|
2631
|
+
switch (role) {
|
2632
|
+
case "assistant":
|
2633
|
+
return {
|
2634
|
+
role,
|
2635
|
+
content: message.content.map((part) => {
|
2636
|
+
if (part.type === "ui") throw new Error("UI parts are not supported");
|
2637
|
+
if (part.type === "tool-call") {
|
2638
|
+
const { argsText, ...rest } = part;
|
2639
|
+
return rest;
|
2640
|
+
}
|
2641
|
+
return part;
|
2642
|
+
})
|
2643
|
+
};
|
2644
|
+
case "user":
|
2645
|
+
return {
|
2646
|
+
role,
|
2647
|
+
content: message.content.map((part) => {
|
2648
|
+
if (part.type === "ui") throw new Error("UI parts are not supported");
|
2649
|
+
return part;
|
2650
|
+
})
|
2651
|
+
};
|
2652
|
+
case "system":
|
2653
|
+
return {
|
2654
|
+
role,
|
2655
|
+
content: message.content
|
2656
|
+
};
|
2657
|
+
default: {
|
2658
|
+
const unsupportedRole = role;
|
2659
|
+
throw new Error(`Unknown message role: ${unsupportedRole}`);
|
2660
|
+
}
|
2661
|
+
}
|
2570
2662
|
};
|
2571
2663
|
|
2572
2664
|
// src/runtimes/edge/converters/fromLanguageModelTools.ts
|
@@ -3036,9 +3128,10 @@ var parsePartialJson = (json) => {
|
|
3036
3128
|
};
|
3037
3129
|
|
3038
3130
|
// src/runtimes/edge/streams/runResultStream.ts
|
3039
|
-
function runResultStream(
|
3131
|
+
function runResultStream() {
|
3040
3132
|
let message = {
|
3041
|
-
content:
|
3133
|
+
content: [],
|
3134
|
+
status: { type: "running" }
|
3042
3135
|
};
|
3043
3136
|
const currentToolCall = { toolCallId: "", argsText: "" };
|
3044
3137
|
return new TransformStream({
|
@@ -3086,7 +3179,13 @@ function runResultStream(initialContent) {
|
|
3086
3179
|
break;
|
3087
3180
|
}
|
3088
3181
|
case "error": {
|
3089
|
-
|
3182
|
+
if (chunk.error instanceof Error && chunk.error.name === "AbortError") {
|
3183
|
+
message = appendOrUpdateCancel(message);
|
3184
|
+
controller.enqueue(message);
|
3185
|
+
break;
|
3186
|
+
} else {
|
3187
|
+
throw chunk.error;
|
3188
|
+
}
|
3090
3189
|
}
|
3091
3190
|
default: {
|
3092
3191
|
const unhandledType = chunkType;
|
@@ -3160,11 +3259,42 @@ var appendOrUpdateToolResult = (message, toolCallId, toolName, result) => {
|
|
3160
3259
|
};
|
3161
3260
|
var appendOrUpdateFinish = (message, chunk) => {
|
3162
3261
|
const { type, ...rest } = chunk;
|
3262
|
+
return {
|
3263
|
+
...message,
|
3264
|
+
status: getStatus(chunk),
|
3265
|
+
roundtrips: [
|
3266
|
+
...message.roundtrips ?? [],
|
3267
|
+
{
|
3268
|
+
logprobs: rest.logprobs,
|
3269
|
+
usage: rest.usage
|
3270
|
+
}
|
3271
|
+
]
|
3272
|
+
};
|
3273
|
+
};
|
3274
|
+
var getStatus = (chunk) => {
|
3275
|
+
if (chunk.finishReason === "tool-calls") {
|
3276
|
+
return {
|
3277
|
+
type: "requires-action",
|
3278
|
+
reason: "tool-calls"
|
3279
|
+
};
|
3280
|
+
} else if (chunk.finishReason === "stop" || chunk.finishReason === "unknown") {
|
3281
|
+
return {
|
3282
|
+
type: "complete",
|
3283
|
+
reason: chunk.finishReason
|
3284
|
+
};
|
3285
|
+
} else {
|
3286
|
+
return {
|
3287
|
+
type: "incomplete",
|
3288
|
+
reason: chunk.finishReason
|
3289
|
+
};
|
3290
|
+
}
|
3291
|
+
};
|
3292
|
+
var appendOrUpdateCancel = (message) => {
|
3163
3293
|
return {
|
3164
3294
|
...message,
|
3165
3295
|
status: {
|
3166
|
-
type: "
|
3167
|
-
|
3296
|
+
type: "incomplete",
|
3297
|
+
reason: "cancelled"
|
3168
3298
|
}
|
3169
3299
|
};
|
3170
3300
|
};
|
@@ -3264,7 +3394,7 @@ var EdgeChatAdapter = class {
|
|
3264
3394
|
constructor(options) {
|
3265
3395
|
this.options = options;
|
3266
3396
|
}
|
3267
|
-
async
|
3397
|
+
async run({ messages, abortSignal, config, onUpdate }) {
|
3268
3398
|
const result = await fetch(this.options.api, {
|
3269
3399
|
method: "POST",
|
3270
3400
|
headers: {
|
@@ -3284,46 +3414,14 @@ var EdgeChatAdapter = class {
|
|
3284
3414
|
`Edge runtime returned status ${result.status}: ${await result.text()}`
|
3285
3415
|
);
|
3286
3416
|
}
|
3287
|
-
const stream = result.body.pipeThrough(new TextDecoderStream()).pipeThrough(chunkByLineStream()).pipeThrough(assistantDecoderStream()).pipeThrough(toolResultStream(config.tools)).pipeThrough(runResultStream(
|
3288
|
-
let message;
|
3417
|
+
const stream = result.body.pipeThrough(new TextDecoderStream()).pipeThrough(chunkByLineStream()).pipeThrough(assistantDecoderStream()).pipeThrough(toolResultStream(config.tools)).pipeThrough(runResultStream());
|
3289
3418
|
let update;
|
3290
3419
|
for await (update of asAsyncIterable(stream)) {
|
3291
|
-
|
3420
|
+
onUpdate(update);
|
3292
3421
|
}
|
3293
3422
|
if (update === void 0)
|
3294
3423
|
throw new Error("No data received from Edge Runtime");
|
3295
|
-
return
|
3296
|
-
}
|
3297
|
-
async run({ messages, abortSignal, config, onUpdate }) {
|
3298
|
-
let roundtripAllowance = this.options.maxToolRoundtrips ?? 1;
|
3299
|
-
let usage = {
|
3300
|
-
promptTokens: 0,
|
3301
|
-
completionTokens: 0
|
3302
|
-
};
|
3303
|
-
let result;
|
3304
|
-
let assistantMessage;
|
3305
|
-
do {
|
3306
|
-
[assistantMessage, result] = await this.roundtrip(result?.content ?? [], {
|
3307
|
-
messages: assistantMessage ? [...messages, assistantMessage] : messages,
|
3308
|
-
abortSignal,
|
3309
|
-
config,
|
3310
|
-
onUpdate
|
3311
|
-
});
|
3312
|
-
if (result.status?.type === "done") {
|
3313
|
-
usage.promptTokens += result.status.usage?.promptTokens ?? 0;
|
3314
|
-
usage.completionTokens += result.status.usage?.completionTokens ?? 0;
|
3315
|
-
}
|
3316
|
-
} while (result.status?.type === "done" && result.status.finishReason === "tool-calls" && result.content.every((c) => c.type !== "tool-call" || !!c.result) && roundtripAllowance-- > 0);
|
3317
|
-
if (result.status?.type === "done" && usage.promptTokens > 0) {
|
3318
|
-
result = {
|
3319
|
-
...result,
|
3320
|
-
status: {
|
3321
|
-
...result.status,
|
3322
|
-
usage
|
3323
|
-
}
|
3324
|
-
};
|
3325
|
-
}
|
3326
|
-
return result;
|
3424
|
+
return update;
|
3327
3425
|
}
|
3328
3426
|
};
|
3329
3427
|
|
@@ -3336,30 +3434,10 @@ var useEdgeRuntime = ({
|
|
3336
3434
|
return useLocalRuntime(adapter, { initialMessages });
|
3337
3435
|
};
|
3338
3436
|
|
3339
|
-
// src/runtimes/local/
|
3340
|
-
var
|
3341
|
-
|
3342
|
-
|
3343
|
-
const proxyConfigProvider = new ProxyConfigProvider();
|
3344
|
-
super(new LocalThreadRuntime(proxyConfigProvider, adapter, options));
|
3345
|
-
this._proxyConfigProvider = proxyConfigProvider;
|
3346
|
-
}
|
3347
|
-
set adapter(adapter) {
|
3348
|
-
this.thread.adapter = adapter;
|
3349
|
-
}
|
3350
|
-
registerModelConfigProvider(provider) {
|
3351
|
-
return this._proxyConfigProvider.registerModelConfigProvider(provider);
|
3352
|
-
}
|
3353
|
-
switchToThread(threadId) {
|
3354
|
-
if (threadId) {
|
3355
|
-
throw new Error("LocalRuntime does not yet support switching threads");
|
3356
|
-
}
|
3357
|
-
return this.thread = new LocalThreadRuntime(
|
3358
|
-
this._proxyConfigProvider,
|
3359
|
-
this.thread.adapter
|
3360
|
-
);
|
3361
|
-
}
|
3362
|
-
};
|
3437
|
+
// src/runtimes/local/shouldContinue.tsx
|
3438
|
+
var shouldContinue = (result) => result.status?.type === "requires-action" && result.status.reason === "tool-calls" && result.content.every((c) => c.type !== "tool-call" || !!c.result);
|
3439
|
+
|
3440
|
+
// src/runtimes/local/LocalThreadRuntime.tsx
|
3363
3441
|
var CAPABILITIES = Object.freeze({
|
3364
3442
|
edit: true,
|
3365
3443
|
reload: true,
|
@@ -3370,6 +3448,7 @@ var LocalThreadRuntime = class {
|
|
3370
3448
|
constructor(configProvider, adapter, options) {
|
3371
3449
|
this.configProvider = configProvider;
|
3372
3450
|
this.adapter = adapter;
|
3451
|
+
this.options = options;
|
3373
3452
|
if (options?.initialMessages) {
|
3374
3453
|
let parentId = null;
|
3375
3454
|
const messages = fromCoreMessages(options.initialMessages);
|
@@ -3413,27 +3492,51 @@ var LocalThreadRuntime = class {
|
|
3413
3492
|
}
|
3414
3493
|
async startRun(parentId) {
|
3415
3494
|
this.repository.resetHead(parentId);
|
3416
|
-
const
|
3495
|
+
const id = generateId();
|
3417
3496
|
let message = {
|
3418
|
-
id
|
3497
|
+
id,
|
3419
3498
|
role: "assistant",
|
3420
|
-
status: { type: "
|
3421
|
-
content: [
|
3499
|
+
status: { type: "running" },
|
3500
|
+
content: [],
|
3422
3501
|
createdAt: /* @__PURE__ */ new Date()
|
3423
3502
|
};
|
3503
|
+
do {
|
3504
|
+
message = await this.performRoundtrip(parentId, message);
|
3505
|
+
} while (shouldContinue(message));
|
3506
|
+
}
|
3507
|
+
async performRoundtrip(parentId, message) {
|
3508
|
+
const messages = this.repository.getMessages();
|
3424
3509
|
this.abortController?.abort();
|
3425
3510
|
this.abortController = new AbortController();
|
3426
|
-
|
3427
|
-
|
3511
|
+
const initialContent = message.content;
|
3512
|
+
const initialRoundtrips = message.roundtrips;
|
3428
3513
|
const updateMessage = (m) => {
|
3429
3514
|
message = {
|
3430
3515
|
...message,
|
3431
|
-
...m
|
3516
|
+
...m.content ? { content: [...initialContent, ...m.content ?? []] } : void 0,
|
3517
|
+
status: m.status ?? message.status,
|
3518
|
+
...m.roundtrips?.length ? { roundtrips: [...initialRoundtrips ?? [], ...m.roundtrips] } : void 0
|
3432
3519
|
};
|
3433
3520
|
this.repository.addOrUpdateMessage(parentId, message);
|
3434
3521
|
this.notifySubscribers();
|
3435
|
-
return message;
|
3436
3522
|
};
|
3523
|
+
const maxToolRoundtrips = this.options?.maxToolRoundtrips ?? 1;
|
3524
|
+
const toolRoundtrips = message.roundtrips?.length ?? 0;
|
3525
|
+
if (toolRoundtrips > maxToolRoundtrips) {
|
3526
|
+
updateMessage({
|
3527
|
+
status: {
|
3528
|
+
type: "incomplete",
|
3529
|
+
reason: "tool-calls"
|
3530
|
+
}
|
3531
|
+
});
|
3532
|
+
return message;
|
3533
|
+
} else {
|
3534
|
+
updateMessage({
|
3535
|
+
status: {
|
3536
|
+
type: "running"
|
3537
|
+
}
|
3538
|
+
});
|
3539
|
+
}
|
3437
3540
|
try {
|
3438
3541
|
const result = await this.adapter.run({
|
3439
3542
|
messages,
|
@@ -3441,21 +3544,29 @@ var LocalThreadRuntime = class {
|
|
3441
3544
|
config: this.configProvider.getModelConfig(),
|
3442
3545
|
onUpdate: updateMessage
|
3443
3546
|
});
|
3444
|
-
if (result.status?.type === "
|
3547
|
+
if (result.status?.type === "running")
|
3445
3548
|
throw new Error(
|
3446
|
-
"Unexpected
|
3549
|
+
"Unexpected running status returned from ChatModelAdapter"
|
3447
3550
|
);
|
3448
3551
|
this.abortController = null;
|
3449
|
-
updateMessage({ status: { type: "done" }, ...result });
|
3450
|
-
this.repository.addOrUpdateMessage(parentId, { ...message });
|
3451
|
-
} catch (e) {
|
3452
|
-
const isAbortError = e instanceof Error && e.name === "AbortError";
|
3453
|
-
this.abortController = null;
|
3454
3552
|
updateMessage({
|
3455
|
-
status:
|
3553
|
+
status: { type: "complete", reason: "unknown" },
|
3554
|
+
...result
|
3456
3555
|
});
|
3457
|
-
|
3556
|
+
} catch (e) {
|
3557
|
+
this.abortController = null;
|
3558
|
+
if (e instanceof Error && e.name === "AbortError") {
|
3559
|
+
updateMessage({
|
3560
|
+
status: { type: "incomplete", reason: "cancelled" }
|
3561
|
+
});
|
3562
|
+
} else {
|
3563
|
+
updateMessage({
|
3564
|
+
status: { type: "incomplete", reason: "error", error: e }
|
3565
|
+
});
|
3566
|
+
throw e;
|
3567
|
+
}
|
3458
3568
|
}
|
3569
|
+
return message;
|
3459
3570
|
}
|
3460
3571
|
cancelRun() {
|
3461
3572
|
if (!this.abortController) return;
|
@@ -3470,14 +3581,16 @@ var LocalThreadRuntime = class {
|
|
3470
3581
|
return () => this._subscriptions.delete(callback);
|
3471
3582
|
}
|
3472
3583
|
addToolResult({ messageId, toolCallId, result }) {
|
3473
|
-
|
3584
|
+
let { parentId, message } = this.repository.getMessage(messageId);
|
3474
3585
|
if (message.role !== "assistant")
|
3475
3586
|
throw new Error("Tried to add tool result to non-assistant message");
|
3587
|
+
let added = false;
|
3476
3588
|
let found = false;
|
3477
3589
|
const newContent = message.content.map((c) => {
|
3478
3590
|
if (c.type !== "tool-call") return c;
|
3479
3591
|
if (c.toolCallId !== toolCallId) return c;
|
3480
3592
|
found = true;
|
3593
|
+
if (!c.result) added = true;
|
3481
3594
|
return {
|
3482
3595
|
...c,
|
3483
3596
|
result
|
@@ -3485,10 +3598,39 @@ var LocalThreadRuntime = class {
|
|
3485
3598
|
});
|
3486
3599
|
if (!found)
|
3487
3600
|
throw new Error("Tried to add tool result to non-existing tool call");
|
3488
|
-
|
3601
|
+
message = {
|
3489
3602
|
...message,
|
3490
3603
|
content: newContent
|
3491
|
-
}
|
3604
|
+
};
|
3605
|
+
this.repository.addOrUpdateMessage(parentId, message);
|
3606
|
+
if (added && shouldContinue(message)) {
|
3607
|
+
this.performRoundtrip(parentId, message);
|
3608
|
+
}
|
3609
|
+
}
|
3610
|
+
};
|
3611
|
+
|
3612
|
+
// src/runtimes/local/LocalRuntime.tsx
|
3613
|
+
var LocalRuntime = class extends BaseAssistantRuntime {
|
3614
|
+
_proxyConfigProvider;
|
3615
|
+
constructor(adapter, options) {
|
3616
|
+
const proxyConfigProvider = new ProxyConfigProvider();
|
3617
|
+
super(new LocalThreadRuntime(proxyConfigProvider, adapter, options));
|
3618
|
+
this._proxyConfigProvider = proxyConfigProvider;
|
3619
|
+
}
|
3620
|
+
set adapter(adapter) {
|
3621
|
+
this.thread.adapter = adapter;
|
3622
|
+
}
|
3623
|
+
registerModelConfigProvider(provider) {
|
3624
|
+
return this._proxyConfigProvider.registerModelConfigProvider(provider);
|
3625
|
+
}
|
3626
|
+
switchToThread(threadId) {
|
3627
|
+
if (threadId) {
|
3628
|
+
throw new Error("LocalRuntime does not yet support switching threads");
|
3629
|
+
}
|
3630
|
+
return this.thread = new LocalThreadRuntime(
|
3631
|
+
this._proxyConfigProvider,
|
3632
|
+
this.thread.adapter
|
3633
|
+
);
|
3492
3634
|
}
|
3493
3635
|
};
|
3494
3636
|
|
@@ -3683,7 +3825,7 @@ var Text = ({ status }) => {
|
|
3683
3825
|
{
|
3684
3826
|
className: (0, import_classnames2.default)(
|
3685
3827
|
"aui-text",
|
3686
|
-
status.type === "
|
3828
|
+
status.type === "running" && "aui-text-in-progress"
|
3687
3829
|
),
|
3688
3830
|
children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(contentPart_exports.Text, {})
|
3689
3831
|
}
|
@@ -4210,11 +4352,13 @@ var assistant_modal_default = Object.assign(AssistantModal, exports12);
|
|
4210
4352
|
ThreadWelcome,
|
4211
4353
|
UserActionBar,
|
4212
4354
|
UserMessage,
|
4355
|
+
fromCoreMessage,
|
4213
4356
|
fromCoreMessages,
|
4214
4357
|
fromLanguageModelMessages,
|
4215
4358
|
fromLanguageModelTools,
|
4216
4359
|
makeAssistantTool,
|
4217
4360
|
makeAssistantToolUI,
|
4361
|
+
toCoreMessage,
|
4218
4362
|
toCoreMessages,
|
4219
4363
|
toLanguageModelMessages,
|
4220
4364
|
toLanguageModelTools,
|