@dudousxd/nestjs-agent-react 0.24.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 +128 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +58 -16
- package/dist/index.d.ts +58 -16
- package/dist/index.js +120 -18
- 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.cjs
CHANGED
|
@@ -99,22 +99,87 @@ __export(src_exports, {
|
|
|
99
99
|
useThreads: () => useThreads,
|
|
100
100
|
useToolCatalog: () => useToolCatalog,
|
|
101
101
|
useTranscriptItem: () => useTranscriptItem,
|
|
102
|
-
validateAnswer: () =>
|
|
103
|
-
validateAnswerValue: () =>
|
|
102
|
+
validateAnswer: () => import_nestjs_agent_core2.validateElicitationAnswer,
|
|
103
|
+
validateAnswerValue: () => import_nestjs_agent_core2.validateElicitationValue
|
|
104
104
|
});
|
|
105
105
|
module.exports = __toCommonJS(src_exports);
|
|
106
106
|
|
|
107
|
+
// src/http-error.ts
|
|
108
|
+
function readErrorAnswer(text) {
|
|
109
|
+
if (text == null || text === "") return {
|
|
110
|
+
body: void 0,
|
|
111
|
+
message: void 0,
|
|
112
|
+
code: void 0
|
|
113
|
+
};
|
|
114
|
+
let body = text;
|
|
115
|
+
try {
|
|
116
|
+
body = JSON.parse(text);
|
|
117
|
+
} catch {
|
|
118
|
+
return {
|
|
119
|
+
body: text,
|
|
120
|
+
message: void 0,
|
|
121
|
+
code: void 0
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
if (body === null || typeof body !== "object") return {
|
|
125
|
+
body,
|
|
126
|
+
message: void 0,
|
|
127
|
+
code: void 0
|
|
128
|
+
};
|
|
129
|
+
const record = body;
|
|
130
|
+
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;
|
|
131
|
+
const code = typeof record.code === "string" && record.code !== "" ? record.code : void 0;
|
|
132
|
+
return {
|
|
133
|
+
body,
|
|
134
|
+
message,
|
|
135
|
+
code
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
__name(readErrorAnswer, "readErrorAnswer");
|
|
139
|
+
async function readErrorResponse(response) {
|
|
140
|
+
let text;
|
|
141
|
+
try {
|
|
142
|
+
text = await response.text();
|
|
143
|
+
} catch {
|
|
144
|
+
text = void 0;
|
|
145
|
+
}
|
|
146
|
+
return readErrorAnswer(text);
|
|
147
|
+
}
|
|
148
|
+
__name(readErrorResponse, "readErrorResponse");
|
|
149
|
+
function reportHttpError(listener, error) {
|
|
150
|
+
if (listener === void 0) return;
|
|
151
|
+
try {
|
|
152
|
+
listener(error);
|
|
153
|
+
} catch {
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
__name(reportHttpError, "reportHttpError");
|
|
157
|
+
|
|
107
158
|
// src/client.ts
|
|
108
|
-
var AgentHttpError = class extends Error {
|
|
159
|
+
var AgentHttpError = class _AgentHttpError extends Error {
|
|
109
160
|
static {
|
|
110
161
|
__name(this, "AgentHttpError");
|
|
111
162
|
}
|
|
112
163
|
status;
|
|
113
164
|
method;
|
|
114
165
|
path;
|
|
115
|
-
|
|
116
|
-
|
|
166
|
+
/** The answer's body: parsed JSON, else its text; `undefined` when empty. */
|
|
167
|
+
body;
|
|
168
|
+
/** The body's `code` (`quota_exceeded`, …), when the server sent one. */
|
|
169
|
+
code;
|
|
170
|
+
constructor(status, method, path, statusText, answer = {
|
|
171
|
+
body: void 0,
|
|
172
|
+
message: void 0,
|
|
173
|
+
code: void 0
|
|
174
|
+
}) {
|
|
175
|
+
super(answer.message ?? `Agent request failed: ${method} ${path} \u2192 ${status} ${statusText}`), this.status = status, this.method = method, this.path = path;
|
|
117
176
|
this.name = "AgentHttpError";
|
|
177
|
+
this.body = answer.body;
|
|
178
|
+
this.code = answer.code;
|
|
179
|
+
}
|
|
180
|
+
/** Read a refused `response`'s body into an error. */
|
|
181
|
+
static async from(response, method, path) {
|
|
182
|
+
return new _AgentHttpError(response.status, method, path, response.statusText, await readErrorResponse(response));
|
|
118
183
|
}
|
|
119
184
|
};
|
|
120
185
|
function normalizeAgentPath(path) {
|
|
@@ -149,7 +214,7 @@ var AgentClient = class {
|
|
|
149
214
|
} : {}
|
|
150
215
|
});
|
|
151
216
|
if (!response.ok || !response.body) {
|
|
152
|
-
throw
|
|
217
|
+
throw await this.failure(response, "POST", `${this.agentPath()}/chat`);
|
|
153
218
|
}
|
|
154
219
|
return streamResponse(response);
|
|
155
220
|
}
|
|
@@ -176,7 +241,7 @@ var AgentClient = class {
|
|
|
176
241
|
return null;
|
|
177
242
|
}
|
|
178
243
|
if (!response.ok || !response.body) {
|
|
179
|
-
throw
|
|
244
|
+
throw await this.failure(response, "GET", `${this.agentPath()}${path}`);
|
|
180
245
|
}
|
|
181
246
|
return streamResponse(response);
|
|
182
247
|
}
|
|
@@ -269,7 +334,9 @@ var AgentClient = class {
|
|
|
269
334
|
};
|
|
270
335
|
xhr.onload = () => {
|
|
271
336
|
if (xhr.status < 200 || xhr.status >= 300) {
|
|
272
|
-
|
|
337
|
+
const error = new AgentHttpError(xhr.status, "POST", `${this.agentPath()}/attachments`, xhr.statusText, readErrorAnswer(xhr.responseText));
|
|
338
|
+
reportHttpError(this.options.onHttpError, error);
|
|
339
|
+
reject(error);
|
|
273
340
|
return;
|
|
274
341
|
}
|
|
275
342
|
onProgress?.(1);
|
|
@@ -332,6 +399,7 @@ var AgentClient = class {
|
|
|
332
399
|
* out takes the pre-picked default the request carried, resolved server-side against the request
|
|
333
400
|
* the run already holds. Omit the whole object and the user has confirmed every pre-picked
|
|
334
401
|
* answer — which is the point of the surface, so it is a valid submission rather than a blank.
|
|
402
|
+
* `via` names the surface the answer came through (the server records `'web'` when omitted).
|
|
335
403
|
*/
|
|
336
404
|
answerToolCall(input) {
|
|
337
405
|
return this.request("POST", "/tool-call/answer", input);
|
|
@@ -354,7 +422,10 @@ var AgentClient = class {
|
|
|
354
422
|
path: this.agentPath(),
|
|
355
423
|
headers: /* @__PURE__ */ __name(() => this.resolveHeaders(), "headers"),
|
|
356
424
|
fetch: this.fetchImpl(),
|
|
357
|
-
...this.credentials()
|
|
425
|
+
...this.credentials(),
|
|
426
|
+
...this.options.onHttpError !== void 0 ? {
|
|
427
|
+
onHttpError: this.options.onHttpError
|
|
428
|
+
} : {}
|
|
358
429
|
};
|
|
359
430
|
}
|
|
360
431
|
baseUrl() {
|
|
@@ -397,9 +468,15 @@ var AgentClient = class {
|
|
|
397
468
|
});
|
|
398
469
|
return this.handleResponse(response, method, path);
|
|
399
470
|
}
|
|
471
|
+
/** The error for a refused `response`, already reported to `onHttpError`. */
|
|
472
|
+
async failure(response, method, path) {
|
|
473
|
+
const error = await AgentHttpError.from(response, method, path);
|
|
474
|
+
reportHttpError(this.options.onHttpError, error);
|
|
475
|
+
return error;
|
|
476
|
+
}
|
|
400
477
|
async handleResponse(response, method, path) {
|
|
401
478
|
if (!response.ok) {
|
|
402
|
-
throw
|
|
479
|
+
throw await this.failure(response, method, path);
|
|
403
480
|
}
|
|
404
481
|
if (response.status === 204) return void 0;
|
|
405
482
|
const text = await response.text();
|
|
@@ -1754,14 +1831,16 @@ __name(GenerativeUI, "GenerativeUI");
|
|
|
1754
1831
|
|
|
1755
1832
|
// src/provider.tsx
|
|
1756
1833
|
var AgentBackendContext = sharedContext("@dudousxd/nestjs-agent-react:agent-backend");
|
|
1757
|
-
function AgentProvider({ backend, baseUrl, path, headers, getHeaders, credentials, fetch, attachments, genui, children }) {
|
|
1834
|
+
function AgentProvider({ backend, baseUrl, path, headers, getHeaders, credentials, fetch, onHttpError, attachments, genui, children }) {
|
|
1758
1835
|
const latestHeaders = (0, import_react5.useRef)({
|
|
1759
1836
|
headers,
|
|
1760
|
-
getHeaders
|
|
1837
|
+
getHeaders,
|
|
1838
|
+
onHttpError
|
|
1761
1839
|
});
|
|
1762
1840
|
latestHeaders.current = {
|
|
1763
1841
|
headers,
|
|
1764
|
-
getHeaders
|
|
1842
|
+
getHeaders,
|
|
1843
|
+
onHttpError
|
|
1765
1844
|
};
|
|
1766
1845
|
const upload = attachments?.upload;
|
|
1767
1846
|
const value = (0, import_react5.useMemo)(() => backend ?? new AgentClient({
|
|
@@ -1782,6 +1861,7 @@ function AgentProvider({ backend, baseUrl, path, headers, getHeaders, credential
|
|
|
1782
1861
|
upload
|
|
1783
1862
|
}
|
|
1784
1863
|
} : {},
|
|
1864
|
+
onHttpError: /* @__PURE__ */ __name((error) => latestHeaders.current.onHttpError?.(error), "onHttpError"),
|
|
1785
1865
|
getHeaders: /* @__PURE__ */ __name(async () => {
|
|
1786
1866
|
const current = latestHeaders.current;
|
|
1787
1867
|
const dynamic = await current.getHeaders?.() ?? {};
|
|
@@ -2195,6 +2275,7 @@ function useModels(options = {}) {
|
|
|
2195
2275
|
providers,
|
|
2196
2276
|
models,
|
|
2197
2277
|
defaultModel: data?.default ?? null,
|
|
2278
|
+
locked: data?.locked ?? null,
|
|
2198
2279
|
find: /* @__PURE__ */ __name((id) => id == null ? void 0 : byId.get(id), "find"),
|
|
2199
2280
|
isLoading,
|
|
2200
2281
|
error,
|
|
@@ -2210,6 +2291,7 @@ function useModels(options = {}) {
|
|
|
2210
2291
|
__name(useModels, "useModels");
|
|
2211
2292
|
|
|
2212
2293
|
// src/quota/use-quota.ts
|
|
2294
|
+
var import_nestjs_agent_core = require("@dudousxd/nestjs-agent-core");
|
|
2213
2295
|
var import_react11 = require("react");
|
|
2214
2296
|
|
|
2215
2297
|
// src/threads/threads-events.ts
|
|
@@ -2265,6 +2347,7 @@ function useQuota(options = {}) {
|
|
|
2265
2347
|
day: windows.find((window2) => window2.period === "day"),
|
|
2266
2348
|
month: windows.find((window2) => window2.period === "month"),
|
|
2267
2349
|
blocked: data?.blocked ?? null,
|
|
2350
|
+
warning: data === void 0 || data.blocked !== void 0 ? null : data.warning ?? (0, import_nestjs_agent_core.quotaWarning)(windows) ?? null,
|
|
2268
2351
|
isLoading,
|
|
2269
2352
|
error,
|
|
2270
2353
|
refresh
|
|
@@ -2708,11 +2791,11 @@ var import_react18 = __toESM(require("react"), 1);
|
|
|
2708
2791
|
var import_react17 = require("react");
|
|
2709
2792
|
|
|
2710
2793
|
// src/transcript/model.ts
|
|
2711
|
-
var
|
|
2794
|
+
var import_nestjs_agent_core3 = require("@dudousxd/nestjs-agent-core");
|
|
2712
2795
|
var import_ai2 = require("ai");
|
|
2713
2796
|
|
|
2714
2797
|
// src/elicitation/answers.ts
|
|
2715
|
-
var
|
|
2798
|
+
var import_nestjs_agent_core2 = require("@dudousxd/nestjs-agent-core");
|
|
2716
2799
|
function pad(value) {
|
|
2717
2800
|
return String(value).padStart(2, "0");
|
|
2718
2801
|
}
|
|
@@ -3307,7 +3390,7 @@ function readElicitationRequest(part) {
|
|
|
3307
3390
|
if (!isRecord3(candidate) || typeof candidate.id !== "string" || typeof candidate.prompt !== "string") {
|
|
3308
3391
|
return null;
|
|
3309
3392
|
}
|
|
3310
|
-
const input2 = (0,
|
|
3393
|
+
const input2 = (0, import_nestjs_agent_core3.readElicitationInput)(candidate.input) ?? null;
|
|
3311
3394
|
const rawOptions = Array.isArray(candidate.options) ? candidate.options : [];
|
|
3312
3395
|
if (rawOptions.length === 0 && (input2 === null || input2.type === "select")) {
|
|
3313
3396
|
return null;
|
|
@@ -3353,7 +3436,9 @@ function readElicitationOutcome(part) {
|
|
|
3353
3436
|
answers,
|
|
3354
3437
|
skipped: output.skipped,
|
|
3355
3438
|
defaulted: Array.isArray(output.defaulted) ? output.defaulted.filter((id) => typeof id === "string") : [],
|
|
3356
|
-
summary: typeof output.summary === "string" ? output.summary : null
|
|
3439
|
+
summary: typeof output.summary === "string" ? output.summary : null,
|
|
3440
|
+
answeredBy: typeof output.answeredBy === "string" ? output.answeredBy : null,
|
|
3441
|
+
answeredVia: typeof output.answeredVia === "string" ? output.answeredVia : null
|
|
3357
3442
|
};
|
|
3358
3443
|
}
|
|
3359
3444
|
__name(readElicitationOutcome, "readElicitationOutcome");
|
|
@@ -3365,7 +3450,7 @@ function buildElicitationBlock(key, part, request, options) {
|
|
|
3365
3450
|
const picked = isPending ? options.picked(toolCallId, question.id) : void 0;
|
|
3366
3451
|
const selected = picked ?? outcome?.answers[question.id] ?? question.defaults;
|
|
3367
3452
|
const pick = /* @__PURE__ */ __name((values) => options.pick(toolCallId, question.id, values), "pick");
|
|
3368
|
-
const error = isPending ? (0,
|
|
3453
|
+
const error = isPending ? (0, import_nestjs_agent_core3.validateElicitationAnswer)({
|
|
3369
3454
|
id: question.id,
|
|
3370
3455
|
prompt: question.prompt,
|
|
3371
3456
|
options: question.options.map(({ value, label }) => ({
|
|
@@ -5014,7 +5099,7 @@ function useApprovalCountdown(expiresAt, options = {}) {
|
|
|
5014
5099
|
__name(useApprovalCountdown, "useApprovalCountdown");
|
|
5015
5100
|
|
|
5016
5101
|
// src/stored-message-to-ui-message.ts
|
|
5017
|
-
var
|
|
5102
|
+
var import_nestjs_agent_core4 = require("@dudousxd/nestjs-agent-core");
|
|
5018
5103
|
function isRefusal(result) {
|
|
5019
5104
|
if (result.denied === true) {
|
|
5020
5105
|
return true;
|
|
@@ -5027,7 +5112,7 @@ function refusalReason(result) {
|
|
|
5027
5112
|
const { output } = result;
|
|
5028
5113
|
if (output !== null && typeof output === "object" && "reason" in output) {
|
|
5029
5114
|
const reason = output.reason;
|
|
5030
|
-
return typeof reason === "string" && reason !==
|
|
5115
|
+
return typeof reason === "string" && reason !== import_nestjs_agent_core4.DEFAULT_REFUSAL_REASON ? reason : void 0;
|
|
5031
5116
|
}
|
|
5032
5117
|
return void 0;
|
|
5033
5118
|
}
|
|
@@ -5303,6 +5388,7 @@ function useAgentChat(options = {}) {
|
|
|
5303
5388
|
const [pickedModel, setPickedModel] = (0, import_react23.useState)(void 0);
|
|
5304
5389
|
const pickedModelRef = (0, import_react23.useRef)(pickedModel);
|
|
5305
5390
|
pickedModelRef.current = pickedModel;
|
|
5391
|
+
const lockedRef = (0, import_react23.useRef)(false);
|
|
5306
5392
|
const pendingPin = (0, import_react23.useRef)(void 0);
|
|
5307
5393
|
const regenerateNext = (0, import_react23.useRef)(false);
|
|
5308
5394
|
const currentThreadId = (0, import_react23.useCallback)(() => latest.current.threadId ?? createdThreadId.current, []);
|
|
@@ -5350,7 +5436,7 @@ function useAgentChat(options = {}) {
|
|
|
5350
5436
|
const regenerate2 = regenerateNext.current;
|
|
5351
5437
|
regenerateNext.current = false;
|
|
5352
5438
|
const threadId = currentThreadId();
|
|
5353
|
-
const model = current.model ?? pickedModelRef.current;
|
|
5439
|
+
const model = current.model ?? (lockedRef.current ? void 0 : pickedModelRef.current);
|
|
5354
5440
|
return {
|
|
5355
5441
|
// Read per send: a host that switches agents before the first message (a picker on a
|
|
5356
5442
|
// new chat) sends the one picked now, not the one this chat mounted with.
|
|
@@ -5444,6 +5530,7 @@ function useAgentChat(options = {}) {
|
|
|
5444
5530
|
setRunId(void 0);
|
|
5445
5531
|
setActiveRunId(null);
|
|
5446
5532
|
setThreadModel(null);
|
|
5533
|
+
setPickedModel(void 0);
|
|
5447
5534
|
setBackgroundRuns([]);
|
|
5448
5535
|
setHistoryError(null);
|
|
5449
5536
|
autoResumeRunIdRef.current = void 0;
|
|
@@ -5608,19 +5695,25 @@ function useAgentChat(options = {}) {
|
|
|
5608
5695
|
}, [
|
|
5609
5696
|
client
|
|
5610
5697
|
]);
|
|
5611
|
-
const answer = (0, import_react23.useCallback)(async ({ toolCallId, answers }) => {
|
|
5698
|
+
const answer = (0, import_react23.useCallback)(async ({ toolCallId, answers, via }) => {
|
|
5612
5699
|
await requireBackendMethod(client, "answerToolCall")({
|
|
5613
5700
|
toolCallId,
|
|
5614
5701
|
...answers !== void 0 ? {
|
|
5615
5702
|
answers
|
|
5703
|
+
} : {},
|
|
5704
|
+
...via !== void 0 ? {
|
|
5705
|
+
via
|
|
5616
5706
|
} : {}
|
|
5617
5707
|
});
|
|
5618
5708
|
}, [
|
|
5619
5709
|
client
|
|
5620
5710
|
]);
|
|
5621
|
-
const skip = (0, import_react23.useCallback)(async ({ toolCallId }) => {
|
|
5711
|
+
const skip = (0, import_react23.useCallback)(async ({ toolCallId, via }) => {
|
|
5622
5712
|
await requireBackendMethod(client, "skipToolCall")({
|
|
5623
|
-
toolCallId
|
|
5713
|
+
toolCallId,
|
|
5714
|
+
...via !== void 0 ? {
|
|
5715
|
+
via
|
|
5716
|
+
} : {}
|
|
5624
5717
|
});
|
|
5625
5718
|
}, [
|
|
5626
5719
|
client
|
|
@@ -5700,10 +5793,14 @@ function useAgentChat(options = {}) {
|
|
|
5700
5793
|
modelsWantedRef.current = true;
|
|
5701
5794
|
queueMicrotask(() => setModelsWanted(true));
|
|
5702
5795
|
}, []);
|
|
5703
|
-
|
|
5796
|
+
lockedRef.current = catalog.locked !== null;
|
|
5797
|
+
const selectModel = (0, import_react23.useCallback)((id) => {
|
|
5798
|
+
if (!lockedRef.current) setPickedModel(id);
|
|
5799
|
+
}, []);
|
|
5704
5800
|
const pinToThread = (0, import_react23.useCallback)(async (model) => {
|
|
5705
5801
|
const threadId = currentThreadId();
|
|
5706
5802
|
setThreadModel(model);
|
|
5803
|
+
setPickedModel(void 0);
|
|
5707
5804
|
if (threadId === void 0) {
|
|
5708
5805
|
pendingPin.current = {
|
|
5709
5806
|
model
|
|
@@ -5729,11 +5826,16 @@ function useAgentChat(options = {}) {
|
|
|
5729
5826
|
wantModels();
|
|
5730
5827
|
return catalog.providers;
|
|
5731
5828
|
},
|
|
5732
|
-
selected: options.model ?? pickedModel ?? threadModel ?? catalog.defaultModel ?? null,
|
|
5829
|
+
selected: catalog.locked?.model ?? options.model ?? pickedModel ?? threadModel ?? catalog.defaultModel ?? null,
|
|
5830
|
+
pinned: threadModel,
|
|
5733
5831
|
get defaultModel() {
|
|
5734
5832
|
wantModels();
|
|
5735
5833
|
return catalog.defaultModel;
|
|
5736
5834
|
},
|
|
5835
|
+
get locked() {
|
|
5836
|
+
wantModels();
|
|
5837
|
+
return catalog.locked;
|
|
5838
|
+
},
|
|
5737
5839
|
select: selectModel,
|
|
5738
5840
|
pinToThread,
|
|
5739
5841
|
isLoading: modelsWanted && catalog.isLoading,
|