@dudousxd/nestjs-agent-react 0.23.0 → 0.25.0
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/README.md +7 -4
- package/dist/{client-ioKDyV2q.d.cts → client-D4ZSbZJ8.d.cts} +56 -4
- package/dist/{client-ioKDyV2q.d.ts → client-D4ZSbZJ8.d.ts} +56 -4
- package/dist/{generative-ui-9AJNVKBZ.d.cts → generative-ui-BejHxxbR.d.cts} +4 -0
- package/dist/{generative-ui-9AJNVKBZ.d.ts → generative-ui-BejHxxbR.d.ts} +4 -0
- package/dist/genui-json-render.d.cts +1 -1
- package/dist/genui-json-render.d.ts +1 -1
- package/dist/genui.d.cts +2 -2
- package/dist/genui.d.ts +2 -2
- package/dist/index.cjs +175 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +62 -16
- package/dist/index.d.ts +62 -16
- package/dist/index.js +167 -23
- package/dist/index.js.map +1 -1
- package/dist/media.cjs +67 -3
- package/dist/media.cjs.map +1 -1
- package/dist/media.d.cts +9 -6
- package/dist/media.d.ts +9 -6
- package/dist/media.js +67 -3
- package/dist/media.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,17 +1,82 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
3
|
|
|
4
|
+
// src/http-error.ts
|
|
5
|
+
function readErrorAnswer(text) {
|
|
6
|
+
if (text == null || text === "") return {
|
|
7
|
+
body: void 0,
|
|
8
|
+
message: void 0,
|
|
9
|
+
code: void 0
|
|
10
|
+
};
|
|
11
|
+
let body = text;
|
|
12
|
+
try {
|
|
13
|
+
body = JSON.parse(text);
|
|
14
|
+
} catch {
|
|
15
|
+
return {
|
|
16
|
+
body: text,
|
|
17
|
+
message: void 0,
|
|
18
|
+
code: void 0
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
if (body === null || typeof body !== "object") return {
|
|
22
|
+
body,
|
|
23
|
+
message: void 0,
|
|
24
|
+
code: void 0
|
|
25
|
+
};
|
|
26
|
+
const record = body;
|
|
27
|
+
const message = typeof record.message === "string" && record.message !== "" ? record.message : Array.isArray(record.message) && record.message.length > 0 && record.message.every((each) => typeof each === "string") ? record.message.join("; ") : void 0;
|
|
28
|
+
const code = typeof record.code === "string" && record.code !== "" ? record.code : void 0;
|
|
29
|
+
return {
|
|
30
|
+
body,
|
|
31
|
+
message,
|
|
32
|
+
code
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
__name(readErrorAnswer, "readErrorAnswer");
|
|
36
|
+
async function readErrorResponse(response) {
|
|
37
|
+
let text;
|
|
38
|
+
try {
|
|
39
|
+
text = await response.text();
|
|
40
|
+
} catch {
|
|
41
|
+
text = void 0;
|
|
42
|
+
}
|
|
43
|
+
return readErrorAnswer(text);
|
|
44
|
+
}
|
|
45
|
+
__name(readErrorResponse, "readErrorResponse");
|
|
46
|
+
function reportHttpError(listener, error) {
|
|
47
|
+
if (listener === void 0) return;
|
|
48
|
+
try {
|
|
49
|
+
listener(error);
|
|
50
|
+
} catch {
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
__name(reportHttpError, "reportHttpError");
|
|
54
|
+
|
|
4
55
|
// src/client.ts
|
|
5
|
-
var AgentHttpError = class extends Error {
|
|
56
|
+
var AgentHttpError = class _AgentHttpError extends Error {
|
|
6
57
|
static {
|
|
7
58
|
__name(this, "AgentHttpError");
|
|
8
59
|
}
|
|
9
60
|
status;
|
|
10
61
|
method;
|
|
11
62
|
path;
|
|
12
|
-
|
|
13
|
-
|
|
63
|
+
/** The answer's body: parsed JSON, else its text; `undefined` when empty. */
|
|
64
|
+
body;
|
|
65
|
+
/** The body's `code` (`quota_exceeded`, …), when the server sent one. */
|
|
66
|
+
code;
|
|
67
|
+
constructor(status, method, path, statusText, answer = {
|
|
68
|
+
body: void 0,
|
|
69
|
+
message: void 0,
|
|
70
|
+
code: void 0
|
|
71
|
+
}) {
|
|
72
|
+
super(answer.message ?? `Agent request failed: ${method} ${path} \u2192 ${status} ${statusText}`), this.status = status, this.method = method, this.path = path;
|
|
14
73
|
this.name = "AgentHttpError";
|
|
74
|
+
this.body = answer.body;
|
|
75
|
+
this.code = answer.code;
|
|
76
|
+
}
|
|
77
|
+
/** Read a refused `response`'s body into an error. */
|
|
78
|
+
static async from(response, method, path) {
|
|
79
|
+
return new _AgentHttpError(response.status, method, path, response.statusText, await readErrorResponse(response));
|
|
15
80
|
}
|
|
16
81
|
};
|
|
17
82
|
function normalizeAgentPath(path) {
|
|
@@ -46,7 +111,7 @@ var AgentClient = class {
|
|
|
46
111
|
} : {}
|
|
47
112
|
});
|
|
48
113
|
if (!response.ok || !response.body) {
|
|
49
|
-
throw
|
|
114
|
+
throw await this.failure(response, "POST", `${this.agentPath()}/chat`);
|
|
50
115
|
}
|
|
51
116
|
return streamResponse(response);
|
|
52
117
|
}
|
|
@@ -73,7 +138,7 @@ var AgentClient = class {
|
|
|
73
138
|
return null;
|
|
74
139
|
}
|
|
75
140
|
if (!response.ok || !response.body) {
|
|
76
|
-
throw
|
|
141
|
+
throw await this.failure(response, "GET", `${this.agentPath()}${path}`);
|
|
77
142
|
}
|
|
78
143
|
return streamResponse(response);
|
|
79
144
|
}
|
|
@@ -166,7 +231,9 @@ var AgentClient = class {
|
|
|
166
231
|
};
|
|
167
232
|
xhr.onload = () => {
|
|
168
233
|
if (xhr.status < 200 || xhr.status >= 300) {
|
|
169
|
-
|
|
234
|
+
const error = new AgentHttpError(xhr.status, "POST", `${this.agentPath()}/attachments`, xhr.statusText, readErrorAnswer(xhr.responseText));
|
|
235
|
+
reportHttpError(this.options.onHttpError, error);
|
|
236
|
+
reject(error);
|
|
170
237
|
return;
|
|
171
238
|
}
|
|
172
239
|
onProgress?.(1);
|
|
@@ -229,6 +296,7 @@ var AgentClient = class {
|
|
|
229
296
|
* out takes the pre-picked default the request carried, resolved server-side against the request
|
|
230
297
|
* the run already holds. Omit the whole object and the user has confirmed every pre-picked
|
|
231
298
|
* answer — which is the point of the surface, so it is a valid submission rather than a blank.
|
|
299
|
+
* `via` names the surface the answer came through (the server records `'web'` when omitted).
|
|
232
300
|
*/
|
|
233
301
|
answerToolCall(input) {
|
|
234
302
|
return this.request("POST", "/tool-call/answer", input);
|
|
@@ -251,7 +319,10 @@ var AgentClient = class {
|
|
|
251
319
|
path: this.agentPath(),
|
|
252
320
|
headers: /* @__PURE__ */ __name(() => this.resolveHeaders(), "headers"),
|
|
253
321
|
fetch: this.fetchImpl(),
|
|
254
|
-
...this.credentials()
|
|
322
|
+
...this.credentials(),
|
|
323
|
+
...this.options.onHttpError !== void 0 ? {
|
|
324
|
+
onHttpError: this.options.onHttpError
|
|
325
|
+
} : {}
|
|
255
326
|
};
|
|
256
327
|
}
|
|
257
328
|
baseUrl() {
|
|
@@ -294,9 +365,15 @@ var AgentClient = class {
|
|
|
294
365
|
});
|
|
295
366
|
return this.handleResponse(response, method, path);
|
|
296
367
|
}
|
|
368
|
+
/** The error for a refused `response`, already reported to `onHttpError`. */
|
|
369
|
+
async failure(response, method, path) {
|
|
370
|
+
const error = await AgentHttpError.from(response, method, path);
|
|
371
|
+
reportHttpError(this.options.onHttpError, error);
|
|
372
|
+
return error;
|
|
373
|
+
}
|
|
297
374
|
async handleResponse(response, method, path) {
|
|
298
375
|
if (!response.ok) {
|
|
299
|
-
throw
|
|
376
|
+
throw await this.failure(response, method, path);
|
|
300
377
|
}
|
|
301
378
|
if (response.status === 204) return void 0;
|
|
302
379
|
const text = await response.text();
|
|
@@ -864,6 +941,13 @@ var AgentChatTransport = class {
|
|
|
864
941
|
}
|
|
865
942
|
});
|
|
866
943
|
break;
|
|
944
|
+
case "message-metadata":
|
|
945
|
+
ensureStarted();
|
|
946
|
+
controller.enqueue({
|
|
947
|
+
type: "message-metadata",
|
|
948
|
+
messageMetadata: event.metadata
|
|
949
|
+
});
|
|
950
|
+
break;
|
|
867
951
|
case "title":
|
|
868
952
|
case "cancelled":
|
|
869
953
|
forwardAsData(event, true);
|
|
@@ -1644,14 +1728,16 @@ __name(GenerativeUI, "GenerativeUI");
|
|
|
1644
1728
|
|
|
1645
1729
|
// src/provider.tsx
|
|
1646
1730
|
var AgentBackendContext = sharedContext("@dudousxd/nestjs-agent-react:agent-backend");
|
|
1647
|
-
function AgentProvider({ backend, baseUrl, path, headers, getHeaders, credentials, fetch, attachments, genui, children }) {
|
|
1731
|
+
function AgentProvider({ backend, baseUrl, path, headers, getHeaders, credentials, fetch, onHttpError, attachments, genui, children }) {
|
|
1648
1732
|
const latestHeaders = useRef2({
|
|
1649
1733
|
headers,
|
|
1650
|
-
getHeaders
|
|
1734
|
+
getHeaders,
|
|
1735
|
+
onHttpError
|
|
1651
1736
|
});
|
|
1652
1737
|
latestHeaders.current = {
|
|
1653
1738
|
headers,
|
|
1654
|
-
getHeaders
|
|
1739
|
+
getHeaders,
|
|
1740
|
+
onHttpError
|
|
1655
1741
|
};
|
|
1656
1742
|
const upload = attachments?.upload;
|
|
1657
1743
|
const value = useMemo3(() => backend ?? new AgentClient({
|
|
@@ -1672,6 +1758,7 @@ function AgentProvider({ backend, baseUrl, path, headers, getHeaders, credential
|
|
|
1672
1758
|
upload
|
|
1673
1759
|
}
|
|
1674
1760
|
} : {},
|
|
1761
|
+
onHttpError: /* @__PURE__ */ __name((error) => latestHeaders.current.onHttpError?.(error), "onHttpError"),
|
|
1675
1762
|
getHeaders: /* @__PURE__ */ __name(async () => {
|
|
1676
1763
|
const current = latestHeaders.current;
|
|
1677
1764
|
const dynamic = await current.getHeaders?.() ?? {};
|
|
@@ -2085,6 +2172,7 @@ function useModels(options = {}) {
|
|
|
2085
2172
|
providers,
|
|
2086
2173
|
models,
|
|
2087
2174
|
defaultModel: data?.default ?? null,
|
|
2175
|
+
locked: data?.locked ?? null,
|
|
2088
2176
|
find: /* @__PURE__ */ __name((id) => id == null ? void 0 : byId.get(id), "find"),
|
|
2089
2177
|
isLoading,
|
|
2090
2178
|
error,
|
|
@@ -2100,6 +2188,7 @@ function useModels(options = {}) {
|
|
|
2100
2188
|
__name(useModels, "useModels");
|
|
2101
2189
|
|
|
2102
2190
|
// src/quota/use-quota.ts
|
|
2191
|
+
import { quotaWarning } from "@dudousxd/nestjs-agent-core";
|
|
2103
2192
|
import { useEffect as useEffect6, useMemo as useMemo7 } from "react";
|
|
2104
2193
|
|
|
2105
2194
|
// src/threads/threads-events.ts
|
|
@@ -2155,6 +2244,7 @@ function useQuota(options = {}) {
|
|
|
2155
2244
|
day: windows.find((window2) => window2.period === "day"),
|
|
2156
2245
|
month: windows.find((window2) => window2.period === "month"),
|
|
2157
2246
|
blocked: data?.blocked ?? null,
|
|
2247
|
+
warning: data === void 0 || data.blocked !== void 0 ? null : data.warning ?? quotaWarning(windows) ?? null,
|
|
2158
2248
|
isLoading,
|
|
2159
2249
|
error,
|
|
2160
2250
|
refresh
|
|
@@ -3243,7 +3333,9 @@ function readElicitationOutcome(part) {
|
|
|
3243
3333
|
answers,
|
|
3244
3334
|
skipped: output.skipped,
|
|
3245
3335
|
defaulted: Array.isArray(output.defaulted) ? output.defaulted.filter((id) => typeof id === "string") : [],
|
|
3246
|
-
summary: typeof output.summary === "string" ? output.summary : null
|
|
3336
|
+
summary: typeof output.summary === "string" ? output.summary : null,
|
|
3337
|
+
answeredBy: typeof output.answeredBy === "string" ? output.answeredBy : null,
|
|
3338
|
+
answeredVia: typeof output.answeredVia === "string" ? output.answeredVia : null
|
|
3247
3339
|
};
|
|
3248
3340
|
}
|
|
3249
3341
|
__name(readElicitationOutcome, "readElicitationOutcome");
|
|
@@ -5018,13 +5110,19 @@ function storedMessageToUiMessage(message) {
|
|
|
5018
5110
|
for (const call of message.toolCalls ?? []) {
|
|
5019
5111
|
const result = message.toolResults?.find((candidate) => candidate.id === call.id);
|
|
5020
5112
|
const toolKind2 = call.kind;
|
|
5113
|
+
const toolMetadata = {
|
|
5114
|
+
...toolKind2 !== void 0 ? {
|
|
5115
|
+
toolKind: toolKind2
|
|
5116
|
+
} : {},
|
|
5117
|
+
...call.parentId !== void 0 ? {
|
|
5118
|
+
parentId: call.parentId
|
|
5119
|
+
} : {}
|
|
5120
|
+
};
|
|
5021
5121
|
parts.push({
|
|
5022
5122
|
type: `tool-${call.name}`,
|
|
5023
5123
|
toolCallId: call.id,
|
|
5024
|
-
...
|
|
5025
|
-
toolMetadata
|
|
5026
|
-
toolKind: toolKind2
|
|
5027
|
-
}
|
|
5124
|
+
...Object.keys(toolMetadata).length > 0 ? {
|
|
5125
|
+
toolMetadata
|
|
5028
5126
|
} : {},
|
|
5029
5127
|
...result !== void 0 ? isRefusal(result) ? {
|
|
5030
5128
|
// A declined action is NOT an available output. Reloading a thread used to bring one
|
|
@@ -5052,6 +5150,8 @@ function storedMessageToUiMessage(message) {
|
|
|
5052
5150
|
parts.push(...pushedByCall.get(call.id) ?? []);
|
|
5053
5151
|
}
|
|
5054
5152
|
const metadata = {
|
|
5153
|
+
// The host's own facts first: the library's keys win on a clash.
|
|
5154
|
+
...message.metadata,
|
|
5055
5155
|
...message.feedback !== void 0 ? {
|
|
5056
5156
|
feedback: message.feedback
|
|
5057
5157
|
} : {},
|
|
@@ -5111,6 +5211,8 @@ function mergeTurn(rows) {
|
|
|
5111
5211
|
const feedback = lastRow.feedback;
|
|
5112
5212
|
const createdAt = rows[0]?.createdAt;
|
|
5113
5213
|
const metadata = {
|
|
5214
|
+
// Host facts of every row, a later row's winning (the turn's final state), under the library's.
|
|
5215
|
+
...Object.assign({}, ...rows.map((row) => row.metadata ?? {})),
|
|
5114
5216
|
...usage !== void 0 ? {
|
|
5115
5217
|
usage
|
|
5116
5218
|
} : {},
|
|
@@ -5183,6 +5285,7 @@ function useAgentChat(options = {}) {
|
|
|
5183
5285
|
const [pickedModel, setPickedModel] = useState15(void 0);
|
|
5184
5286
|
const pickedModelRef = useRef12(pickedModel);
|
|
5185
5287
|
pickedModelRef.current = pickedModel;
|
|
5288
|
+
const lockedRef = useRef12(false);
|
|
5186
5289
|
const pendingPin = useRef12(void 0);
|
|
5187
5290
|
const regenerateNext = useRef12(false);
|
|
5188
5291
|
const currentThreadId = useCallback11(() => latest.current.threadId ?? createdThreadId.current, []);
|
|
@@ -5230,8 +5333,13 @@ function useAgentChat(options = {}) {
|
|
|
5230
5333
|
const regenerate2 = regenerateNext.current;
|
|
5231
5334
|
regenerateNext.current = false;
|
|
5232
5335
|
const threadId = currentThreadId();
|
|
5233
|
-
const model = current.model ?? pickedModelRef.current;
|
|
5336
|
+
const model = current.model ?? (lockedRef.current ? void 0 : pickedModelRef.current);
|
|
5234
5337
|
return {
|
|
5338
|
+
// Read per send: a host that switches agents before the first message (a picker on a
|
|
5339
|
+
// new chat) sends the one picked now, not the one this chat mounted with.
|
|
5340
|
+
...current.agent !== void 0 ? {
|
|
5341
|
+
agent: current.agent
|
|
5342
|
+
} : {},
|
|
5235
5343
|
...threadId !== void 0 ? {
|
|
5236
5344
|
threadId
|
|
5237
5345
|
} : {},
|
|
@@ -5319,6 +5427,7 @@ function useAgentChat(options = {}) {
|
|
|
5319
5427
|
setRunId(void 0);
|
|
5320
5428
|
setActiveRunId(null);
|
|
5321
5429
|
setThreadModel(null);
|
|
5430
|
+
setPickedModel(void 0);
|
|
5322
5431
|
setBackgroundRuns([]);
|
|
5323
5432
|
setHistoryError(null);
|
|
5324
5433
|
autoResumeRunIdRef.current = void 0;
|
|
@@ -5483,19 +5592,25 @@ function useAgentChat(options = {}) {
|
|
|
5483
5592
|
}, [
|
|
5484
5593
|
client
|
|
5485
5594
|
]);
|
|
5486
|
-
const answer = useCallback11(async ({ toolCallId, answers }) => {
|
|
5595
|
+
const answer = useCallback11(async ({ toolCallId, answers, via }) => {
|
|
5487
5596
|
await requireBackendMethod(client, "answerToolCall")({
|
|
5488
5597
|
toolCallId,
|
|
5489
5598
|
...answers !== void 0 ? {
|
|
5490
5599
|
answers
|
|
5600
|
+
} : {},
|
|
5601
|
+
...via !== void 0 ? {
|
|
5602
|
+
via
|
|
5491
5603
|
} : {}
|
|
5492
5604
|
});
|
|
5493
5605
|
}, [
|
|
5494
5606
|
client
|
|
5495
5607
|
]);
|
|
5496
|
-
const skip = useCallback11(async ({ toolCallId }) => {
|
|
5608
|
+
const skip = useCallback11(async ({ toolCallId, via }) => {
|
|
5497
5609
|
await requireBackendMethod(client, "skipToolCall")({
|
|
5498
|
-
toolCallId
|
|
5610
|
+
toolCallId,
|
|
5611
|
+
...via !== void 0 ? {
|
|
5612
|
+
via
|
|
5613
|
+
} : {}
|
|
5499
5614
|
});
|
|
5500
5615
|
}, [
|
|
5501
5616
|
client
|
|
@@ -5575,10 +5690,14 @@ function useAgentChat(options = {}) {
|
|
|
5575
5690
|
modelsWantedRef.current = true;
|
|
5576
5691
|
queueMicrotask(() => setModelsWanted(true));
|
|
5577
5692
|
}, []);
|
|
5578
|
-
|
|
5693
|
+
lockedRef.current = catalog.locked !== null;
|
|
5694
|
+
const selectModel = useCallback11((id) => {
|
|
5695
|
+
if (!lockedRef.current) setPickedModel(id);
|
|
5696
|
+
}, []);
|
|
5579
5697
|
const pinToThread = useCallback11(async (model) => {
|
|
5580
5698
|
const threadId = currentThreadId();
|
|
5581
5699
|
setThreadModel(model);
|
|
5700
|
+
setPickedModel(void 0);
|
|
5582
5701
|
if (threadId === void 0) {
|
|
5583
5702
|
pendingPin.current = {
|
|
5584
5703
|
model
|
|
@@ -5604,7 +5723,16 @@ function useAgentChat(options = {}) {
|
|
|
5604
5723
|
wantModels();
|
|
5605
5724
|
return catalog.providers;
|
|
5606
5725
|
},
|
|
5607
|
-
selected: options.model ?? pickedModel ?? threadModel ?? catalog.defaultModel ?? null,
|
|
5726
|
+
selected: catalog.locked?.model ?? options.model ?? pickedModel ?? threadModel ?? catalog.defaultModel ?? null,
|
|
5727
|
+
pinned: threadModel,
|
|
5728
|
+
get defaultModel() {
|
|
5729
|
+
wantModels();
|
|
5730
|
+
return catalog.defaultModel;
|
|
5731
|
+
},
|
|
5732
|
+
get locked() {
|
|
5733
|
+
wantModels();
|
|
5734
|
+
return catalog.locked;
|
|
5735
|
+
},
|
|
5608
5736
|
select: selectModel,
|
|
5609
5737
|
pinToThread,
|
|
5610
5738
|
isLoading: modelsWanted && catalog.isLoading,
|
|
@@ -5632,10 +5760,26 @@ function useAgentChat(options = {}) {
|
|
|
5632
5760
|
const current = composerRef.current;
|
|
5633
5761
|
if (current.blockedBy !== null) return;
|
|
5634
5762
|
const refs = current.files.refs;
|
|
5763
|
+
const files2 = current.files.items.flatMap((item) => item.status === "ready" && item.attachment !== void 0 ? [
|
|
5764
|
+
{
|
|
5765
|
+
type: "file",
|
|
5766
|
+
mediaType: item.attachment.contentType,
|
|
5767
|
+
filename: item.attachment.name,
|
|
5768
|
+
url: item.attachment.url,
|
|
5769
|
+
providerMetadata: {
|
|
5770
|
+
agent: {
|
|
5771
|
+
mediaId: item.attachment.mediaId
|
|
5772
|
+
}
|
|
5773
|
+
}
|
|
5774
|
+
}
|
|
5775
|
+
] : []);
|
|
5635
5776
|
const draft = current.text.trim();
|
|
5636
5777
|
setText("");
|
|
5637
5778
|
current.files.clear();
|
|
5638
|
-
await sendMessage({
|
|
5779
|
+
await sendMessage(files2.length > 0 ? {
|
|
5780
|
+
text: draft,
|
|
5781
|
+
files: files2
|
|
5782
|
+
} : {
|
|
5639
5783
|
text: draft
|
|
5640
5784
|
}, refs.length > 0 ? {
|
|
5641
5785
|
body: {
|