@tangle-network/agent-app 0.43.7 → 0.43.9
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/assistant/index.d.ts +11 -2
- package/dist/assistant/index.js +125 -49
- package/dist/assistant/index.js.map +1 -1
- package/dist/{chunk-TV45QGCV.js → chunk-77RLNLFP.js} +3 -2
- package/dist/chunk-77RLNLFP.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/stream/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-TV45QGCV.js.map +0 -1
|
@@ -15,9 +15,12 @@ import '@tangle-network/agent-interface';
|
|
|
15
15
|
* is the source of truth for what it accepts and emits.
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
+
type AssistantDeliveryMode = "steering" | "queue";
|
|
18
19
|
/** Request body for `POST /api/v1/assistant/chat`. */
|
|
19
20
|
interface ChatRequest {
|
|
20
21
|
message: string;
|
|
22
|
+
/** How to deliver text when a session may already be active. Defaults to steering. */
|
|
23
|
+
deliveryMode?: AssistantDeliveryMode;
|
|
21
24
|
/** Model slug to run this turn against; omit to use the server default. */
|
|
22
25
|
model?: string;
|
|
23
26
|
/** Omit to start a new thread; pass to continue an existing one. */
|
|
@@ -321,6 +324,9 @@ type ConfirmResult = {
|
|
|
321
324
|
ok: false;
|
|
322
325
|
error: string;
|
|
323
326
|
};
|
|
327
|
+
declare class AssistantClientInputError extends Error {
|
|
328
|
+
readonly code = "INVALID_REQUEST";
|
|
329
|
+
}
|
|
324
330
|
/** The assistant network surface, bound to one host's transport config. */
|
|
325
331
|
interface AssistantClient {
|
|
326
332
|
fetchModels(signal?: AbortSignal): Promise<AssistantModelsResult>;
|
|
@@ -410,6 +416,9 @@ interface AssistantState {
|
|
|
410
416
|
* helpers; this hook is the glue between them and the network.
|
|
411
417
|
*/
|
|
412
418
|
|
|
419
|
+
interface AssistantSendOptions {
|
|
420
|
+
deliveryMode?: AssistantDeliveryMode;
|
|
421
|
+
}
|
|
413
422
|
/** Host integration callbacks for {@link useAssistantChat}. */
|
|
414
423
|
interface UseAssistantChatOptions {
|
|
415
424
|
/**
|
|
@@ -428,7 +437,7 @@ interface AssistantChat {
|
|
|
428
437
|
selectedModel: string | null;
|
|
429
438
|
/** Choose the model for subsequent turns (persisted per user). */
|
|
430
439
|
setModel: (model: string | null) => void;
|
|
431
|
-
send: (message: string) => void;
|
|
440
|
+
send: (message: string, options?: AssistantSendOptions) => void;
|
|
432
441
|
stop: () => void;
|
|
433
442
|
confirm: (proposal: PendingProposal) => Promise<void>;
|
|
434
443
|
cancel: (proposal: PendingProposal) => void;
|
|
@@ -621,4 +630,4 @@ declare function AssistantLauncherProvider({ children, }: {
|
|
|
621
630
|
}): react.JSX.Element;
|
|
622
631
|
declare function useAssistantLauncher(): AssistantLauncher;
|
|
623
632
|
|
|
624
|
-
export { type AssistantChat, type AssistantClient, type AssistantClientConfig, AssistantClientProvider, AssistantDock, type AssistantDockProps, type AssistantLauncher, AssistantLauncherProvider, type AssistantModelOption, type AssistantModels, type AssistantModelsResult, AssistantPanel, type AssistantPanelProps, type AssistantStreamEvent, type AssistantThreadSummary, type AssistantThreads, AssistantTranscript, type AssistantTranscriptProps, type AssistantTranscriptView, type ChatMessage, type ChatRequest, type ChatRole, type ConfirmResult, type ConnectionRequirement, type ConnectionRequirementKind, type DeltaEventData, type DoneEventData, type ErrorEventData, type PendingProposal, ProposalCard, type ProposalCardProps, type ReasoningEventData, type ThreadEventData, type ThreadHistoryResult, type ToolActivityStatus, type ToolCallEventData, type ToolOutcome, type ToolProposalEventData, type ToolResultEventData, type UsageEventData, type UsageInfo, type UseAssistantChatOptions, adaptTranscript, assistantIsThinking, createAssistantClient, useAssistantChat, useAssistantClient, useAssistantLauncher, useAssistantModels, useAssistantThreads };
|
|
633
|
+
export { type AssistantChat, type AssistantClient, type AssistantClientConfig, AssistantClientInputError, AssistantClientProvider, type AssistantDeliveryMode, AssistantDock, type AssistantDockProps, type AssistantLauncher, AssistantLauncherProvider, type AssistantModelOption, type AssistantModels, type AssistantModelsResult, AssistantPanel, type AssistantPanelProps, type AssistantSendOptions, type AssistantStreamEvent, type AssistantThreadSummary, type AssistantThreads, AssistantTranscript, type AssistantTranscriptProps, type AssistantTranscriptView, type ChatMessage, type ChatRequest, type ChatRole, type ConfirmResult, type ConnectionRequirement, type ConnectionRequirementKind, type DeltaEventData, type DoneEventData, type ErrorEventData, type PendingProposal, ProposalCard, type ProposalCardProps, type ReasoningEventData, type ThreadEventData, type ThreadHistoryResult, type ToolActivityStatus, type ToolCallEventData, type ToolOutcome, type ToolProposalEventData, type ToolResultEventData, type UsageEventData, type UsageInfo, type UseAssistantChatOptions, adaptTranscript, assistantIsThinking, createAssistantClient, useAssistantChat, useAssistantClient, useAssistantLauncher, useAssistantModels, useAssistantThreads };
|
package/dist/assistant/index.js
CHANGED
|
@@ -98,7 +98,23 @@ async function readSSEEvents(body, onEvent) {
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
// src/assistant/client.ts
|
|
101
|
+
var AssistantClientInputError = class extends Error {
|
|
102
|
+
code = "INVALID_REQUEST";
|
|
103
|
+
};
|
|
101
104
|
var EMPTY_MODELS = { default: null, models: [] };
|
|
105
|
+
var ASSISTANT_DELIVERY_MODES = /* @__PURE__ */ new Set([
|
|
106
|
+
"steering",
|
|
107
|
+
"queue"
|
|
108
|
+
]);
|
|
109
|
+
function resolveDeliveryMode(value) {
|
|
110
|
+
if (value === void 0) return "steering";
|
|
111
|
+
if (typeof value === "string" && ASSISTANT_DELIVERY_MODES.has(value)) {
|
|
112
|
+
return value;
|
|
113
|
+
}
|
|
114
|
+
throw new AssistantClientInputError(
|
|
115
|
+
`Invalid assistant delivery mode: ${String(value)}`
|
|
116
|
+
);
|
|
117
|
+
}
|
|
102
118
|
function asObject(v) {
|
|
103
119
|
return v && typeof v === "object" && !Array.isArray(v) ? v : null;
|
|
104
120
|
}
|
|
@@ -391,6 +407,10 @@ function createAssistantClient(config) {
|
|
|
391
407
|
}
|
|
392
408
|
},
|
|
393
409
|
async streamChat(req, onEvent, signal) {
|
|
410
|
+
const body = {
|
|
411
|
+
...req,
|
|
412
|
+
deliveryMode: resolveDeliveryMode(req.deliveryMode)
|
|
413
|
+
};
|
|
394
414
|
const res = await fetch(url("/chat"), {
|
|
395
415
|
method: "POST",
|
|
396
416
|
headers: {
|
|
@@ -399,7 +419,7 @@ function createAssistantClient(config) {
|
|
|
399
419
|
Accept: "text/event-stream"
|
|
400
420
|
},
|
|
401
421
|
credentials,
|
|
402
|
-
body: JSON.stringify(
|
|
422
|
+
body: JSON.stringify(body),
|
|
403
423
|
signal
|
|
404
424
|
});
|
|
405
425
|
if (!res.ok) {
|
|
@@ -1087,6 +1107,7 @@ function useAssistantChat(userId, options) {
|
|
|
1087
1107
|
}
|
|
1088
1108
|
);
|
|
1089
1109
|
const abortRef = useRef(null);
|
|
1110
|
+
const pendingQueuedSendRef = useRef(null);
|
|
1090
1111
|
const historyAbortRef = useRef(null);
|
|
1091
1112
|
const hydratedUserRef = useRef(userId);
|
|
1092
1113
|
const streamSeqRef = useRef(0);
|
|
@@ -1114,11 +1135,60 @@ function useAssistantChat(userId, options) {
|
|
|
1114
1135
|
);
|
|
1115
1136
|
const selectedModelRef = useRef(selectedModel);
|
|
1116
1137
|
selectedModelRef.current = selectedModel;
|
|
1138
|
+
const clearPendingQueuedSend = useCallback(() => {
|
|
1139
|
+
pendingQueuedSendRef.current = null;
|
|
1140
|
+
}, []);
|
|
1141
|
+
const abortActiveStream = useCallback(() => {
|
|
1142
|
+
abortRef.current?.abort();
|
|
1143
|
+
abortRef.current = null;
|
|
1144
|
+
}, []);
|
|
1145
|
+
const startChatStream = useCallback(
|
|
1146
|
+
(text, deliveryMode, model, threadId) => {
|
|
1147
|
+
dispatch({
|
|
1148
|
+
type: "send",
|
|
1149
|
+
messageId: uuid(),
|
|
1150
|
+
assistantId: uuid(),
|
|
1151
|
+
text
|
|
1152
|
+
});
|
|
1153
|
+
const seq = ++streamSeqRef.current;
|
|
1154
|
+
const ac = new AbortController();
|
|
1155
|
+
abortRef.current = ac;
|
|
1156
|
+
sendingRef.current = true;
|
|
1157
|
+
clientRef.current.streamChat(
|
|
1158
|
+
{
|
|
1159
|
+
message: text,
|
|
1160
|
+
deliveryMode,
|
|
1161
|
+
// null → omit, so the server applies its default model.
|
|
1162
|
+
model,
|
|
1163
|
+
threadId,
|
|
1164
|
+
turnKey: uuid()
|
|
1165
|
+
},
|
|
1166
|
+
(event) => {
|
|
1167
|
+
if (streamSeqRef.current === seq) dispatch({ type: "stream", event });
|
|
1168
|
+
},
|
|
1169
|
+
ac.signal
|
|
1170
|
+
).catch((err) => {
|
|
1171
|
+
if (ac.signal.aborted || streamSeqRef.current !== seq) return;
|
|
1172
|
+
dispatch({
|
|
1173
|
+
type: "stream_failed",
|
|
1174
|
+
error: {
|
|
1175
|
+
code: err instanceof AssistantClientInputError ? err.code : "NETWORK",
|
|
1176
|
+
message: err instanceof Error ? err.message : "The connection failed"
|
|
1177
|
+
}
|
|
1178
|
+
});
|
|
1179
|
+
}).finally(() => {
|
|
1180
|
+
if (streamSeqRef.current === seq) sendingRef.current = false;
|
|
1181
|
+
if (abortRef.current === ac) abortRef.current = null;
|
|
1182
|
+
});
|
|
1183
|
+
},
|
|
1184
|
+
[]
|
|
1185
|
+
);
|
|
1117
1186
|
useEffect(() => {
|
|
1118
1187
|
if (hydratedUserRef.current === userId) return;
|
|
1119
1188
|
streamSeqRef.current += 1;
|
|
1120
1189
|
confirmSeqRef.current += 1;
|
|
1121
|
-
|
|
1190
|
+
abortActiveStream();
|
|
1191
|
+
clearPendingQueuedSend();
|
|
1122
1192
|
historyAbortRef.current?.abort();
|
|
1123
1193
|
setRestoringBoth(false);
|
|
1124
1194
|
sendingRef.current = false;
|
|
@@ -1134,7 +1204,21 @@ function useAssistantChat(userId, options) {
|
|
|
1134
1204
|
threadId: loadThread(userId).threadId,
|
|
1135
1205
|
messages: []
|
|
1136
1206
|
});
|
|
1137
|
-
}, [userId, setRestoringBoth]);
|
|
1207
|
+
}, [userId, abortActiveStream, clearPendingQueuedSend, setRestoringBoth]);
|
|
1208
|
+
useEffect(() => {
|
|
1209
|
+
const pending = pendingQueuedSendRef.current;
|
|
1210
|
+
if (!pending || state.status === "streaming") return;
|
|
1211
|
+
pendingQueuedSendRef.current = null;
|
|
1212
|
+
if (pending.ownerId !== userIdRef.current || state.pendingProposals.length > 0) {
|
|
1213
|
+
return;
|
|
1214
|
+
}
|
|
1215
|
+
startChatStream(
|
|
1216
|
+
pending.text,
|
|
1217
|
+
"queue",
|
|
1218
|
+
pending.model,
|
|
1219
|
+
state.threadId ?? void 0
|
|
1220
|
+
);
|
|
1221
|
+
}, [state.status, state.pendingProposals.length, startChatStream]);
|
|
1138
1222
|
useEffect(() => {
|
|
1139
1223
|
const threadId = loadThread(userId).threadId;
|
|
1140
1224
|
if (!userId || !threadId) return;
|
|
@@ -1169,57 +1253,46 @@ function useAssistantChat(userId, options) {
|
|
|
1169
1253
|
});
|
|
1170
1254
|
}, [state.ownerId, state.threadId, state.status]);
|
|
1171
1255
|
useEffect(() => {
|
|
1172
|
-
return () =>
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1256
|
+
return () => {
|
|
1257
|
+
abortActiveStream();
|
|
1258
|
+
clearPendingQueuedSend();
|
|
1259
|
+
};
|
|
1260
|
+
}, [abortActiveStream, clearPendingQueuedSend]);
|
|
1261
|
+
const send = useCallback((message, options2) => {
|
|
1262
|
+
const deliveryMode = options2?.deliveryMode;
|
|
1263
|
+
const shouldQueue = deliveryMode === "queue";
|
|
1264
|
+
if (sendingRef.current && !shouldQueue) return;
|
|
1265
|
+
if (!shouldQueue && pendingQueuedSendRef.current) return;
|
|
1266
|
+
if (shouldQueue && pendingQueuedSendRef.current) return;
|
|
1176
1267
|
const text = message.trim();
|
|
1177
1268
|
const current = stateRef.current;
|
|
1178
1269
|
if (current.ownerId !== userIdRef.current) return;
|
|
1179
1270
|
if (restoringRef.current) return;
|
|
1180
|
-
if (!text
|
|
1271
|
+
if (!text) return;
|
|
1181
1272
|
if (current.pendingProposals.length > 0) return;
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
turnKey: uuid()
|
|
1199
|
-
},
|
|
1200
|
-
(event) => {
|
|
1201
|
-
if (streamSeqRef.current === seq) dispatch({ type: "stream", event });
|
|
1202
|
-
},
|
|
1203
|
-
ac.signal
|
|
1204
|
-
).catch((err) => {
|
|
1205
|
-
if (ac.signal.aborted || streamSeqRef.current !== seq) return;
|
|
1206
|
-
dispatch({
|
|
1207
|
-
type: "stream_failed",
|
|
1208
|
-
error: {
|
|
1209
|
-
code: "NETWORK",
|
|
1210
|
-
message: err instanceof Error ? err.message : "The connection failed"
|
|
1211
|
-
}
|
|
1212
|
-
});
|
|
1213
|
-
}).finally(() => {
|
|
1214
|
-
if (streamSeqRef.current === seq) sendingRef.current = false;
|
|
1215
|
-
});
|
|
1216
|
-
}, []);
|
|
1273
|
+
if (current.status === "streaming") {
|
|
1274
|
+
if (!shouldQueue) return;
|
|
1275
|
+
pendingQueuedSendRef.current = {
|
|
1276
|
+
ownerId: current.ownerId,
|
|
1277
|
+
text,
|
|
1278
|
+
model: selectedModelRef.current ?? void 0
|
|
1279
|
+
};
|
|
1280
|
+
return;
|
|
1281
|
+
}
|
|
1282
|
+
startChatStream(
|
|
1283
|
+
text,
|
|
1284
|
+
deliveryMode,
|
|
1285
|
+
selectedModelRef.current ?? void 0,
|
|
1286
|
+
current.threadId ?? void 0
|
|
1287
|
+
);
|
|
1288
|
+
}, [startChatStream]);
|
|
1217
1289
|
const stop = useCallback(() => {
|
|
1218
1290
|
streamSeqRef.current += 1;
|
|
1219
|
-
|
|
1291
|
+
abortActiveStream();
|
|
1292
|
+
clearPendingQueuedSend();
|
|
1220
1293
|
sendingRef.current = false;
|
|
1221
1294
|
dispatch({ type: "stopped" });
|
|
1222
|
-
}, []);
|
|
1295
|
+
}, [abortActiveStream, clearPendingQueuedSend]);
|
|
1223
1296
|
const confirm = useCallback(async (proposal) => {
|
|
1224
1297
|
const pid = proposal.proposalId;
|
|
1225
1298
|
if (!pid) {
|
|
@@ -1292,14 +1365,15 @@ function useAssistantChat(userId, options) {
|
|
|
1292
1365
|
const reset = useCallback(() => {
|
|
1293
1366
|
streamSeqRef.current += 1;
|
|
1294
1367
|
confirmSeqRef.current += 1;
|
|
1295
|
-
|
|
1368
|
+
abortActiveStream();
|
|
1369
|
+
clearPendingQueuedSend();
|
|
1296
1370
|
historyAbortRef.current?.abort();
|
|
1297
1371
|
setRestoringBoth(false);
|
|
1298
1372
|
sendingRef.current = false;
|
|
1299
1373
|
confirmingRef.current.clear();
|
|
1300
1374
|
setConfirmingIds(EMPTY_IDS);
|
|
1301
1375
|
dispatch({ type: "reset" });
|
|
1302
|
-
}, [setRestoringBoth]);
|
|
1376
|
+
}, [abortActiveStream, clearPendingQueuedSend, setRestoringBoth]);
|
|
1303
1377
|
const switchThread = useCallback(
|
|
1304
1378
|
(threadId) => {
|
|
1305
1379
|
const current = stateRef.current;
|
|
@@ -1311,7 +1385,8 @@ function useAssistantChat(userId, options) {
|
|
|
1311
1385
|
}
|
|
1312
1386
|
streamSeqRef.current += 1;
|
|
1313
1387
|
confirmSeqRef.current += 1;
|
|
1314
|
-
|
|
1388
|
+
abortActiveStream();
|
|
1389
|
+
clearPendingQueuedSend();
|
|
1315
1390
|
sendingRef.current = false;
|
|
1316
1391
|
confirmingRef.current.clear();
|
|
1317
1392
|
setConfirmingIds(EMPTY_IDS);
|
|
@@ -1351,7 +1426,7 @@ function useAssistantChat(userId, options) {
|
|
|
1351
1426
|
if (!ac.signal.aborted) setRestoringBoth(false);
|
|
1352
1427
|
});
|
|
1353
1428
|
},
|
|
1354
|
-
[setRestoringBoth]
|
|
1429
|
+
[abortActiveStream, clearPendingQueuedSend, setRestoringBoth]
|
|
1355
1430
|
);
|
|
1356
1431
|
const setModel = useCallback((model) => {
|
|
1357
1432
|
selectedModelRef.current = model;
|
|
@@ -2763,6 +2838,7 @@ function AssistantDock({
|
|
|
2763
2838
|
] });
|
|
2764
2839
|
}
|
|
2765
2840
|
export {
|
|
2841
|
+
AssistantClientInputError,
|
|
2766
2842
|
AssistantClientProvider,
|
|
2767
2843
|
AssistantDock,
|
|
2768
2844
|
AssistantLauncherProvider,
|