@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.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();
|
|
@@ -967,6 +1044,13 @@ var AgentChatTransport = class {
|
|
|
967
1044
|
}
|
|
968
1045
|
});
|
|
969
1046
|
break;
|
|
1047
|
+
case "message-metadata":
|
|
1048
|
+
ensureStarted();
|
|
1049
|
+
controller.enqueue({
|
|
1050
|
+
type: "message-metadata",
|
|
1051
|
+
messageMetadata: event.metadata
|
|
1052
|
+
});
|
|
1053
|
+
break;
|
|
970
1054
|
case "title":
|
|
971
1055
|
case "cancelled":
|
|
972
1056
|
forwardAsData(event, true);
|
|
@@ -1747,14 +1831,16 @@ __name(GenerativeUI, "GenerativeUI");
|
|
|
1747
1831
|
|
|
1748
1832
|
// src/provider.tsx
|
|
1749
1833
|
var AgentBackendContext = sharedContext("@dudousxd/nestjs-agent-react:agent-backend");
|
|
1750
|
-
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 }) {
|
|
1751
1835
|
const latestHeaders = (0, import_react5.useRef)({
|
|
1752
1836
|
headers,
|
|
1753
|
-
getHeaders
|
|
1837
|
+
getHeaders,
|
|
1838
|
+
onHttpError
|
|
1754
1839
|
});
|
|
1755
1840
|
latestHeaders.current = {
|
|
1756
1841
|
headers,
|
|
1757
|
-
getHeaders
|
|
1842
|
+
getHeaders,
|
|
1843
|
+
onHttpError
|
|
1758
1844
|
};
|
|
1759
1845
|
const upload = attachments?.upload;
|
|
1760
1846
|
const value = (0, import_react5.useMemo)(() => backend ?? new AgentClient({
|
|
@@ -1775,6 +1861,7 @@ function AgentProvider({ backend, baseUrl, path, headers, getHeaders, credential
|
|
|
1775
1861
|
upload
|
|
1776
1862
|
}
|
|
1777
1863
|
} : {},
|
|
1864
|
+
onHttpError: /* @__PURE__ */ __name((error) => latestHeaders.current.onHttpError?.(error), "onHttpError"),
|
|
1778
1865
|
getHeaders: /* @__PURE__ */ __name(async () => {
|
|
1779
1866
|
const current = latestHeaders.current;
|
|
1780
1867
|
const dynamic = await current.getHeaders?.() ?? {};
|
|
@@ -2188,6 +2275,7 @@ function useModels(options = {}) {
|
|
|
2188
2275
|
providers,
|
|
2189
2276
|
models,
|
|
2190
2277
|
defaultModel: data?.default ?? null,
|
|
2278
|
+
locked: data?.locked ?? null,
|
|
2191
2279
|
find: /* @__PURE__ */ __name((id) => id == null ? void 0 : byId.get(id), "find"),
|
|
2192
2280
|
isLoading,
|
|
2193
2281
|
error,
|
|
@@ -2203,6 +2291,7 @@ function useModels(options = {}) {
|
|
|
2203
2291
|
__name(useModels, "useModels");
|
|
2204
2292
|
|
|
2205
2293
|
// src/quota/use-quota.ts
|
|
2294
|
+
var import_nestjs_agent_core = require("@dudousxd/nestjs-agent-core");
|
|
2206
2295
|
var import_react11 = require("react");
|
|
2207
2296
|
|
|
2208
2297
|
// src/threads/threads-events.ts
|
|
@@ -2258,6 +2347,7 @@ function useQuota(options = {}) {
|
|
|
2258
2347
|
day: windows.find((window2) => window2.period === "day"),
|
|
2259
2348
|
month: windows.find((window2) => window2.period === "month"),
|
|
2260
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,
|
|
2261
2351
|
isLoading,
|
|
2262
2352
|
error,
|
|
2263
2353
|
refresh
|
|
@@ -2701,11 +2791,11 @@ var import_react18 = __toESM(require("react"), 1);
|
|
|
2701
2791
|
var import_react17 = require("react");
|
|
2702
2792
|
|
|
2703
2793
|
// src/transcript/model.ts
|
|
2704
|
-
var
|
|
2794
|
+
var import_nestjs_agent_core3 = require("@dudousxd/nestjs-agent-core");
|
|
2705
2795
|
var import_ai2 = require("ai");
|
|
2706
2796
|
|
|
2707
2797
|
// src/elicitation/answers.ts
|
|
2708
|
-
var
|
|
2798
|
+
var import_nestjs_agent_core2 = require("@dudousxd/nestjs-agent-core");
|
|
2709
2799
|
function pad(value) {
|
|
2710
2800
|
return String(value).padStart(2, "0");
|
|
2711
2801
|
}
|
|
@@ -3300,7 +3390,7 @@ function readElicitationRequest(part) {
|
|
|
3300
3390
|
if (!isRecord3(candidate) || typeof candidate.id !== "string" || typeof candidate.prompt !== "string") {
|
|
3301
3391
|
return null;
|
|
3302
3392
|
}
|
|
3303
|
-
const input2 = (0,
|
|
3393
|
+
const input2 = (0, import_nestjs_agent_core3.readElicitationInput)(candidate.input) ?? null;
|
|
3304
3394
|
const rawOptions = Array.isArray(candidate.options) ? candidate.options : [];
|
|
3305
3395
|
if (rawOptions.length === 0 && (input2 === null || input2.type === "select")) {
|
|
3306
3396
|
return null;
|
|
@@ -3346,7 +3436,9 @@ function readElicitationOutcome(part) {
|
|
|
3346
3436
|
answers,
|
|
3347
3437
|
skipped: output.skipped,
|
|
3348
3438
|
defaulted: Array.isArray(output.defaulted) ? output.defaulted.filter((id) => typeof id === "string") : [],
|
|
3349
|
-
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
|
|
3350
3442
|
};
|
|
3351
3443
|
}
|
|
3352
3444
|
__name(readElicitationOutcome, "readElicitationOutcome");
|
|
@@ -3358,7 +3450,7 @@ function buildElicitationBlock(key, part, request, options) {
|
|
|
3358
3450
|
const picked = isPending ? options.picked(toolCallId, question.id) : void 0;
|
|
3359
3451
|
const selected = picked ?? outcome?.answers[question.id] ?? question.defaults;
|
|
3360
3452
|
const pick = /* @__PURE__ */ __name((values) => options.pick(toolCallId, question.id, values), "pick");
|
|
3361
|
-
const error = isPending ? (0,
|
|
3453
|
+
const error = isPending ? (0, import_nestjs_agent_core3.validateElicitationAnswer)({
|
|
3362
3454
|
id: question.id,
|
|
3363
3455
|
prompt: question.prompt,
|
|
3364
3456
|
options: question.options.map(({ value, label }) => ({
|
|
@@ -5007,7 +5099,7 @@ function useApprovalCountdown(expiresAt, options = {}) {
|
|
|
5007
5099
|
__name(useApprovalCountdown, "useApprovalCountdown");
|
|
5008
5100
|
|
|
5009
5101
|
// src/stored-message-to-ui-message.ts
|
|
5010
|
-
var
|
|
5102
|
+
var import_nestjs_agent_core4 = require("@dudousxd/nestjs-agent-core");
|
|
5011
5103
|
function isRefusal(result) {
|
|
5012
5104
|
if (result.denied === true) {
|
|
5013
5105
|
return true;
|
|
@@ -5020,7 +5112,7 @@ function refusalReason(result) {
|
|
|
5020
5112
|
const { output } = result;
|
|
5021
5113
|
if (output !== null && typeof output === "object" && "reason" in output) {
|
|
5022
5114
|
const reason = output.reason;
|
|
5023
|
-
return typeof reason === "string" && reason !==
|
|
5115
|
+
return typeof reason === "string" && reason !== import_nestjs_agent_core4.DEFAULT_REFUSAL_REASON ? reason : void 0;
|
|
5024
5116
|
}
|
|
5025
5117
|
return void 0;
|
|
5026
5118
|
}
|
|
@@ -5121,13 +5213,19 @@ function storedMessageToUiMessage(message) {
|
|
|
5121
5213
|
for (const call of message.toolCalls ?? []) {
|
|
5122
5214
|
const result = message.toolResults?.find((candidate) => candidate.id === call.id);
|
|
5123
5215
|
const toolKind2 = call.kind;
|
|
5216
|
+
const toolMetadata = {
|
|
5217
|
+
...toolKind2 !== void 0 ? {
|
|
5218
|
+
toolKind: toolKind2
|
|
5219
|
+
} : {},
|
|
5220
|
+
...call.parentId !== void 0 ? {
|
|
5221
|
+
parentId: call.parentId
|
|
5222
|
+
} : {}
|
|
5223
|
+
};
|
|
5124
5224
|
parts.push({
|
|
5125
5225
|
type: `tool-${call.name}`,
|
|
5126
5226
|
toolCallId: call.id,
|
|
5127
|
-
...
|
|
5128
|
-
toolMetadata
|
|
5129
|
-
toolKind: toolKind2
|
|
5130
|
-
}
|
|
5227
|
+
...Object.keys(toolMetadata).length > 0 ? {
|
|
5228
|
+
toolMetadata
|
|
5131
5229
|
} : {},
|
|
5132
5230
|
...result !== void 0 ? isRefusal(result) ? {
|
|
5133
5231
|
// A declined action is NOT an available output. Reloading a thread used to bring one
|
|
@@ -5155,6 +5253,8 @@ function storedMessageToUiMessage(message) {
|
|
|
5155
5253
|
parts.push(...pushedByCall.get(call.id) ?? []);
|
|
5156
5254
|
}
|
|
5157
5255
|
const metadata = {
|
|
5256
|
+
// The host's own facts first: the library's keys win on a clash.
|
|
5257
|
+
...message.metadata,
|
|
5158
5258
|
...message.feedback !== void 0 ? {
|
|
5159
5259
|
feedback: message.feedback
|
|
5160
5260
|
} : {},
|
|
@@ -5214,6 +5314,8 @@ function mergeTurn(rows) {
|
|
|
5214
5314
|
const feedback = lastRow.feedback;
|
|
5215
5315
|
const createdAt = rows[0]?.createdAt;
|
|
5216
5316
|
const metadata = {
|
|
5317
|
+
// Host facts of every row, a later row's winning (the turn's final state), under the library's.
|
|
5318
|
+
...Object.assign({}, ...rows.map((row) => row.metadata ?? {})),
|
|
5217
5319
|
...usage !== void 0 ? {
|
|
5218
5320
|
usage
|
|
5219
5321
|
} : {},
|
|
@@ -5286,6 +5388,7 @@ function useAgentChat(options = {}) {
|
|
|
5286
5388
|
const [pickedModel, setPickedModel] = (0, import_react23.useState)(void 0);
|
|
5287
5389
|
const pickedModelRef = (0, import_react23.useRef)(pickedModel);
|
|
5288
5390
|
pickedModelRef.current = pickedModel;
|
|
5391
|
+
const lockedRef = (0, import_react23.useRef)(false);
|
|
5289
5392
|
const pendingPin = (0, import_react23.useRef)(void 0);
|
|
5290
5393
|
const regenerateNext = (0, import_react23.useRef)(false);
|
|
5291
5394
|
const currentThreadId = (0, import_react23.useCallback)(() => latest.current.threadId ?? createdThreadId.current, []);
|
|
@@ -5333,8 +5436,13 @@ function useAgentChat(options = {}) {
|
|
|
5333
5436
|
const regenerate2 = regenerateNext.current;
|
|
5334
5437
|
regenerateNext.current = false;
|
|
5335
5438
|
const threadId = currentThreadId();
|
|
5336
|
-
const model = current.model ?? pickedModelRef.current;
|
|
5439
|
+
const model = current.model ?? (lockedRef.current ? void 0 : pickedModelRef.current);
|
|
5337
5440
|
return {
|
|
5441
|
+
// Read per send: a host that switches agents before the first message (a picker on a
|
|
5442
|
+
// new chat) sends the one picked now, not the one this chat mounted with.
|
|
5443
|
+
...current.agent !== void 0 ? {
|
|
5444
|
+
agent: current.agent
|
|
5445
|
+
} : {},
|
|
5338
5446
|
...threadId !== void 0 ? {
|
|
5339
5447
|
threadId
|
|
5340
5448
|
} : {},
|
|
@@ -5422,6 +5530,7 @@ function useAgentChat(options = {}) {
|
|
|
5422
5530
|
setRunId(void 0);
|
|
5423
5531
|
setActiveRunId(null);
|
|
5424
5532
|
setThreadModel(null);
|
|
5533
|
+
setPickedModel(void 0);
|
|
5425
5534
|
setBackgroundRuns([]);
|
|
5426
5535
|
setHistoryError(null);
|
|
5427
5536
|
autoResumeRunIdRef.current = void 0;
|
|
@@ -5586,19 +5695,25 @@ function useAgentChat(options = {}) {
|
|
|
5586
5695
|
}, [
|
|
5587
5696
|
client
|
|
5588
5697
|
]);
|
|
5589
|
-
const answer = (0, import_react23.useCallback)(async ({ toolCallId, answers }) => {
|
|
5698
|
+
const answer = (0, import_react23.useCallback)(async ({ toolCallId, answers, via }) => {
|
|
5590
5699
|
await requireBackendMethod(client, "answerToolCall")({
|
|
5591
5700
|
toolCallId,
|
|
5592
5701
|
...answers !== void 0 ? {
|
|
5593
5702
|
answers
|
|
5703
|
+
} : {},
|
|
5704
|
+
...via !== void 0 ? {
|
|
5705
|
+
via
|
|
5594
5706
|
} : {}
|
|
5595
5707
|
});
|
|
5596
5708
|
}, [
|
|
5597
5709
|
client
|
|
5598
5710
|
]);
|
|
5599
|
-
const skip = (0, import_react23.useCallback)(async ({ toolCallId }) => {
|
|
5711
|
+
const skip = (0, import_react23.useCallback)(async ({ toolCallId, via }) => {
|
|
5600
5712
|
await requireBackendMethod(client, "skipToolCall")({
|
|
5601
|
-
toolCallId
|
|
5713
|
+
toolCallId,
|
|
5714
|
+
...via !== void 0 ? {
|
|
5715
|
+
via
|
|
5716
|
+
} : {}
|
|
5602
5717
|
});
|
|
5603
5718
|
}, [
|
|
5604
5719
|
client
|
|
@@ -5678,10 +5793,14 @@ function useAgentChat(options = {}) {
|
|
|
5678
5793
|
modelsWantedRef.current = true;
|
|
5679
5794
|
queueMicrotask(() => setModelsWanted(true));
|
|
5680
5795
|
}, []);
|
|
5681
|
-
|
|
5796
|
+
lockedRef.current = catalog.locked !== null;
|
|
5797
|
+
const selectModel = (0, import_react23.useCallback)((id) => {
|
|
5798
|
+
if (!lockedRef.current) setPickedModel(id);
|
|
5799
|
+
}, []);
|
|
5682
5800
|
const pinToThread = (0, import_react23.useCallback)(async (model) => {
|
|
5683
5801
|
const threadId = currentThreadId();
|
|
5684
5802
|
setThreadModel(model);
|
|
5803
|
+
setPickedModel(void 0);
|
|
5685
5804
|
if (threadId === void 0) {
|
|
5686
5805
|
pendingPin.current = {
|
|
5687
5806
|
model
|
|
@@ -5707,7 +5826,16 @@ function useAgentChat(options = {}) {
|
|
|
5707
5826
|
wantModels();
|
|
5708
5827
|
return catalog.providers;
|
|
5709
5828
|
},
|
|
5710
|
-
selected: options.model ?? pickedModel ?? threadModel ?? catalog.defaultModel ?? null,
|
|
5829
|
+
selected: catalog.locked?.model ?? options.model ?? pickedModel ?? threadModel ?? catalog.defaultModel ?? null,
|
|
5830
|
+
pinned: threadModel,
|
|
5831
|
+
get defaultModel() {
|
|
5832
|
+
wantModels();
|
|
5833
|
+
return catalog.defaultModel;
|
|
5834
|
+
},
|
|
5835
|
+
get locked() {
|
|
5836
|
+
wantModels();
|
|
5837
|
+
return catalog.locked;
|
|
5838
|
+
},
|
|
5711
5839
|
select: selectModel,
|
|
5712
5840
|
pinToThread,
|
|
5713
5841
|
isLoading: modelsWanted && catalog.isLoading,
|
|
@@ -5735,10 +5863,26 @@ function useAgentChat(options = {}) {
|
|
|
5735
5863
|
const current = composerRef.current;
|
|
5736
5864
|
if (current.blockedBy !== null) return;
|
|
5737
5865
|
const refs = current.files.refs;
|
|
5866
|
+
const files2 = current.files.items.flatMap((item) => item.status === "ready" && item.attachment !== void 0 ? [
|
|
5867
|
+
{
|
|
5868
|
+
type: "file",
|
|
5869
|
+
mediaType: item.attachment.contentType,
|
|
5870
|
+
filename: item.attachment.name,
|
|
5871
|
+
url: item.attachment.url,
|
|
5872
|
+
providerMetadata: {
|
|
5873
|
+
agent: {
|
|
5874
|
+
mediaId: item.attachment.mediaId
|
|
5875
|
+
}
|
|
5876
|
+
}
|
|
5877
|
+
}
|
|
5878
|
+
] : []);
|
|
5738
5879
|
const draft = current.text.trim();
|
|
5739
5880
|
setText("");
|
|
5740
5881
|
current.files.clear();
|
|
5741
|
-
await sendMessage({
|
|
5882
|
+
await sendMessage(files2.length > 0 ? {
|
|
5883
|
+
text: draft,
|
|
5884
|
+
files: files2
|
|
5885
|
+
} : {
|
|
5742
5886
|
text: draft
|
|
5743
5887
|
}, refs.length > 0 ? {
|
|
5744
5888
|
body: {
|