@adminforth/agent 1.34.2 → 1.36.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/agent/simpleAgent.ts +5 -0
- package/agent/tools/getUserLocation.ts +45 -0
- package/agent/tools/index.ts +2 -0
- package/build.log +9 -2
- package/custom/ChatSurface.vue +15 -0
- package/custom/composables/agentStore/constants.ts +12 -0
- package/custom/composables/agentStore/pageContext.ts +8 -0
- package/custom/composables/agentStore/useAgentChat.ts +69 -0
- package/custom/composables/agentStore/useAgentPlaceholder.ts +142 -0
- package/custom/composables/agentStore/useAgentSessions.ts +270 -0
- package/custom/composables/useAgentStore.ts +73 -393
- package/custom/conversation_area/ProcessingTimeline.vue +1 -1
- package/custom/env.d.ts +7 -0
- package/dist/agent/simpleAgent.js +3 -1
- package/dist/agent/tools/getUserLocation.js +31 -0
- package/dist/agent/tools/index.js +2 -0
- package/dist/custom/ChatSurface.vue +15 -0
- package/dist/custom/composables/agentStore/constants.ts +12 -0
- package/dist/custom/composables/agentStore/pageContext.ts +8 -0
- package/dist/custom/composables/agentStore/useAgentChat.ts +69 -0
- package/dist/custom/composables/agentStore/useAgentPlaceholder.ts +142 -0
- package/dist/custom/composables/agentStore/useAgentSessions.ts +270 -0
- package/dist/custom/composables/useAgentStore.ts +73 -393
- package/dist/custom/conversation_area/ProcessingTimeline.vue +1 -1
- package/dist/custom/env.d.ts +7 -0
- package/dist/index.js +264 -105
- package/index.ts +295 -103
- package/package.json +2 -2
- package/types.ts +6 -0
package/dist/index.js
CHANGED
|
@@ -47,6 +47,19 @@ function formatAgentError(error) {
|
|
|
47
47
|
}
|
|
48
48
|
return String(error);
|
|
49
49
|
}
|
|
50
|
+
function formatAgentResponseError(error) {
|
|
51
|
+
if (isAggregateErrorLike(error)) {
|
|
52
|
+
const nestedErrors = error.errors.map(formatAgentResponseError);
|
|
53
|
+
if (nestedErrors.length) {
|
|
54
|
+
return nestedErrors.join("\n");
|
|
55
|
+
}
|
|
56
|
+
return error.message || "Agent response failed";
|
|
57
|
+
}
|
|
58
|
+
if (error instanceof Error) {
|
|
59
|
+
return error.toString();
|
|
60
|
+
}
|
|
61
|
+
return String(error);
|
|
62
|
+
}
|
|
50
63
|
function formatAdminUserPrompt(adminUser, usernameField) {
|
|
51
64
|
const dbUser = adminUser.dbUser;
|
|
52
65
|
const adminUserContext = {
|
|
@@ -59,16 +72,6 @@ function formatAdminUserPrompt(adminUser, usernameField) {
|
|
|
59
72
|
"Use this admin user email when the user asks to send information to themselves, the current admin, or the logged-in user.",
|
|
60
73
|
].join("\n");
|
|
61
74
|
}
|
|
62
|
-
function formatCurrentPagePrompt(currentPage) {
|
|
63
|
-
if (!currentPage) {
|
|
64
|
-
return null;
|
|
65
|
-
}
|
|
66
|
-
return [
|
|
67
|
-
"Current user page context for the latest message:",
|
|
68
|
-
JSON.stringify(currentPage, null, 2),
|
|
69
|
-
"When the user says here, this page, current page, or opened page, treat it as this page.",
|
|
70
|
-
].join("\n");
|
|
71
|
-
}
|
|
72
75
|
function assertRequiredApiTool(apiBasedTools, toolName) {
|
|
73
76
|
if (toolName in apiBasedTools) {
|
|
74
77
|
return;
|
|
@@ -191,6 +194,7 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
|
|
|
191
194
|
modes: this.options.modes.map((mode) => ({ name: mode.name })),
|
|
192
195
|
defaultModeName: this.options.modes[0].name,
|
|
193
196
|
stickByDefault: (_b = this.options.stickByDefault) !== null && _b !== void 0 ? _b : false,
|
|
197
|
+
hasAudioAdapter: Boolean(this.options.audioAdapter),
|
|
194
198
|
}
|
|
195
199
|
});
|
|
196
200
|
if (!this.pluginOptions.sessionResource) {
|
|
@@ -199,12 +203,110 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
|
|
|
199
203
|
});
|
|
200
204
|
}
|
|
201
205
|
validateConfigAfterDiscover(adminforth, resourceConfig) {
|
|
206
|
+
var _a;
|
|
207
|
+
(_a = this.options.audioAdapter) === null || _a === void 0 ? void 0 : _a.validate();
|
|
202
208
|
this.agentSystemPromptPromise = buildAgentSystemPrompt(adminforth, this.getInternalAgentResourceIds())
|
|
203
209
|
.then((systemPrompt) => appendCustomSystemPrompt(systemPrompt, this.options.systemPrompt));
|
|
204
210
|
}
|
|
205
211
|
instanceUniqueRepresentation(pluginOptions) {
|
|
206
212
|
return `single`;
|
|
207
213
|
}
|
|
214
|
+
runAgentTurn(input) {
|
|
215
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
216
|
+
var _a, e_1, _b, _c;
|
|
217
|
+
var _d, _e, _f, _g;
|
|
218
|
+
let fullResponse = "";
|
|
219
|
+
const maxTokens = (_d = this.options.maxTokens) !== null && _d !== void 0 ? _d : 10000;
|
|
220
|
+
const selectedMode = (_e = this.options.modes.find((mode) => mode.name === input.modeName)) !== null && _e !== void 0 ? _e : this.options.modes[0];
|
|
221
|
+
const { model, summaryModel, modelMiddleware } = yield this.getModeModels(selectedMode, maxTokens);
|
|
222
|
+
const userLanguage = yield detectUserLanguage(selectedMode.completionAdapter, input.prompt)
|
|
223
|
+
.catch((error) => {
|
|
224
|
+
logger.warn(`Failed to detect user language: ${error instanceof Error ? error.message : String(error)}`);
|
|
225
|
+
return null;
|
|
226
|
+
});
|
|
227
|
+
const systemPrompt = [
|
|
228
|
+
yield this.agentSystemPromptPromise,
|
|
229
|
+
formatAdminUserPrompt(input.adminUser, this.adminforth.config.auth.usernameField),
|
|
230
|
+
formatLanguagePrompt(userLanguage),
|
|
231
|
+
].join("\n\n");
|
|
232
|
+
const apiBasedTools = buildApiBasedTools(this.adminforth, this.getInternalAgentResourceIds());
|
|
233
|
+
for (const toolName of ALWAYS_AVAILABLE_API_TOOL_NAMES) {
|
|
234
|
+
assertRequiredApiTool(apiBasedTools, toolName);
|
|
235
|
+
}
|
|
236
|
+
assertRequiredApiTool(apiBasedTools, "update_record");
|
|
237
|
+
this.apiBasedTools = apiBasedTools;
|
|
238
|
+
const stream = yield callAgent({
|
|
239
|
+
name: `adminforth-agent-${this.pluginInstanceId}`,
|
|
240
|
+
model,
|
|
241
|
+
summaryModel,
|
|
242
|
+
modelMiddleware,
|
|
243
|
+
checkpointer: this.getCheckpointer(),
|
|
244
|
+
messages: [
|
|
245
|
+
new SystemMessage(systemPrompt),
|
|
246
|
+
new HumanMessage(input.prompt),
|
|
247
|
+
],
|
|
248
|
+
adminUser: input.adminUser,
|
|
249
|
+
adminforth: this.adminforth,
|
|
250
|
+
apiBasedTools,
|
|
251
|
+
customComponentsDir: this.adminforth.config.customization.customComponentsDir,
|
|
252
|
+
sessionId: input.sessionId,
|
|
253
|
+
turnId: input.turnId,
|
|
254
|
+
currentPage: input.currentPage,
|
|
255
|
+
httpExtra: input.httpExtra,
|
|
256
|
+
userTimeZone: input.userTimeZone,
|
|
257
|
+
emitToolCallEvent: (event) => {
|
|
258
|
+
var _a;
|
|
259
|
+
input.sequenceDebugCollector.handleToolCallEvent(event);
|
|
260
|
+
(_a = input.emitToolCallEvent) === null || _a === void 0 ? void 0 : _a.call(input, event);
|
|
261
|
+
},
|
|
262
|
+
sequenceDebugSink: input.sequenceDebugCollector,
|
|
263
|
+
});
|
|
264
|
+
try {
|
|
265
|
+
for (var _h = true, _j = __asyncValues(stream), _k; _k = yield _j.next(), _a = _k.done, !_a; _h = true) {
|
|
266
|
+
_c = _k.value;
|
|
267
|
+
_h = false;
|
|
268
|
+
const rawChunk = _c;
|
|
269
|
+
const [token, metadata] = rawChunk;
|
|
270
|
+
const nodeName = typeof (metadata === null || metadata === void 0 ? void 0 : metadata.langgraph_node) === "string"
|
|
271
|
+
? metadata.langgraph_node
|
|
272
|
+
: "";
|
|
273
|
+
if (nodeName && !["model", "model_request"].includes(nodeName)) {
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
const blocks = Array.isArray(token === null || token === void 0 ? void 0 : token.contentBlocks)
|
|
277
|
+
? token.contentBlocks
|
|
278
|
+
: Array.isArray(token === null || token === void 0 ? void 0 : token.content)
|
|
279
|
+
? token.content
|
|
280
|
+
: [];
|
|
281
|
+
const reasoningDelta = blocks
|
|
282
|
+
.filter((b) => (b === null || b === void 0 ? void 0 : b.type) === "reasoning")
|
|
283
|
+
.map((b) => { var _a; return String((_a = b.reasoning) !== null && _a !== void 0 ? _a : ""); })
|
|
284
|
+
.join("");
|
|
285
|
+
const textDelta = blocks
|
|
286
|
+
.filter((b) => (b === null || b === void 0 ? void 0 : b.type) === "text")
|
|
287
|
+
.map((b) => { var _a; return String((_a = b.text) !== null && _a !== void 0 ? _a : ""); })
|
|
288
|
+
.join("");
|
|
289
|
+
if (reasoningDelta) {
|
|
290
|
+
(_f = input.emitReasoningDelta) === null || _f === void 0 ? void 0 : _f.call(input, reasoningDelta);
|
|
291
|
+
}
|
|
292
|
+
if (textDelta) {
|
|
293
|
+
fullResponse += textDelta;
|
|
294
|
+
(_g = input.emitTextDelta) === null || _g === void 0 ? void 0 : _g.call(input, textDelta);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
299
|
+
finally {
|
|
300
|
+
try {
|
|
301
|
+
if (!_h && !_a && (_b = _j.return)) yield _b.call(_j);
|
|
302
|
+
}
|
|
303
|
+
finally { if (e_1) throw e_1.error; }
|
|
304
|
+
}
|
|
305
|
+
return {
|
|
306
|
+
text: fullResponse,
|
|
307
|
+
};
|
|
308
|
+
});
|
|
309
|
+
}
|
|
208
310
|
setupEndpoints(server) {
|
|
209
311
|
server.endpoint({
|
|
210
312
|
method: 'POST',
|
|
@@ -234,13 +336,12 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
|
|
|
234
336
|
server.endpoint({
|
|
235
337
|
method: 'POST',
|
|
236
338
|
path: `/agent/response`,
|
|
237
|
-
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, query, headers, cookies, adminUser, response, requestUrl, _raw_express_res }) {
|
|
238
|
-
var _b
|
|
239
|
-
var _e, _f, _g;
|
|
339
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, query, headers, cookies, adminUser, response, requestUrl, _raw_express_res, abortSignal }) {
|
|
340
|
+
var _b;
|
|
240
341
|
const res = _raw_express_res;
|
|
241
342
|
const messageId = randomUUID();
|
|
242
343
|
const prompt = body.message;
|
|
243
|
-
const userTimeZone = (
|
|
344
|
+
const userTimeZone = (_b = body.timeZone) !== null && _b !== void 0 ? _b : 'UTC';
|
|
244
345
|
const currentPage = body.currentPage;
|
|
245
346
|
const sessionId = body.sessionId || (adminUser === null || adminUser === void 0 ? void 0 : adminUser.pk) || (adminUser === null || adminUser === void 0 ? void 0 : adminUser.username) || 'default';
|
|
246
347
|
const turnId = yield this.createNewTurn(sessionId, prompt);
|
|
@@ -264,7 +365,6 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
|
|
|
264
365
|
if (event.phase === "start") {
|
|
265
366
|
endActiveBlock();
|
|
266
367
|
}
|
|
267
|
-
sequenceDebugCollector.handleToolCallEvent(event);
|
|
268
368
|
send({
|
|
269
369
|
type: "data-tool-call",
|
|
270
370
|
data: event,
|
|
@@ -311,43 +411,14 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
|
|
|
311
411
|
type: 'start',
|
|
312
412
|
messageId,
|
|
313
413
|
});
|
|
314
|
-
const
|
|
315
|
-
|
|
316
|
-
const { model, summaryModel, modelMiddleware } = yield this.getModeModels(selectedMode, maxTokens);
|
|
317
|
-
const userLanguage = yield detectUserLanguage(selectedMode.completionAdapter, prompt)
|
|
318
|
-
.catch((error) => {
|
|
319
|
-
logger.warn(`Failed to detect user language: ${error instanceof Error ? error.message : String(error)}`);
|
|
320
|
-
return null;
|
|
321
|
-
});
|
|
322
|
-
const systemPrompt = [
|
|
323
|
-
yield this.agentSystemPromptPromise,
|
|
324
|
-
formatAdminUserPrompt(adminUser, this.adminforth.config.auth.usernameField),
|
|
325
|
-
formatLanguagePrompt(userLanguage),
|
|
326
|
-
].join("\n\n");
|
|
327
|
-
const apiBasedTools = buildApiBasedTools(this.adminforth, this.getInternalAgentResourceIds());
|
|
328
|
-
for (const toolName of ALWAYS_AVAILABLE_API_TOOL_NAMES) {
|
|
329
|
-
assertRequiredApiTool(apiBasedTools, toolName);
|
|
330
|
-
}
|
|
331
|
-
assertRequiredApiTool(apiBasedTools, "update_record");
|
|
332
|
-
this.apiBasedTools = apiBasedTools;
|
|
333
|
-
const currentPagePrompt = formatCurrentPagePrompt(currentPage);
|
|
334
|
-
const stream = yield callAgent({
|
|
335
|
-
name: `adminforth-agent-${this.pluginInstanceId}`,
|
|
336
|
-
model,
|
|
337
|
-
summaryModel,
|
|
338
|
-
modelMiddleware,
|
|
339
|
-
checkpointer: this.getCheckpointer(),
|
|
340
|
-
messages: [
|
|
341
|
-
new SystemMessage(systemPrompt),
|
|
342
|
-
...(currentPagePrompt ? [new SystemMessage(currentPagePrompt)] : []),
|
|
343
|
-
new HumanMessage(prompt),
|
|
344
|
-
],
|
|
345
|
-
adminUser,
|
|
346
|
-
adminforth: this.adminforth,
|
|
347
|
-
apiBasedTools,
|
|
348
|
-
customComponentsDir: this.adminforth.config.customization.customComponentsDir,
|
|
414
|
+
const agentResponse = yield this.runAgentTurn({
|
|
415
|
+
prompt,
|
|
349
416
|
sessionId,
|
|
350
417
|
turnId,
|
|
418
|
+
modeName: body.mode,
|
|
419
|
+
userTimeZone,
|
|
420
|
+
currentPage,
|
|
421
|
+
adminUser,
|
|
351
422
|
httpExtra: {
|
|
352
423
|
body,
|
|
353
424
|
query,
|
|
@@ -356,70 +427,37 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
|
|
|
356
427
|
requestUrl,
|
|
357
428
|
response,
|
|
358
429
|
},
|
|
359
|
-
|
|
430
|
+
sequenceDebugCollector,
|
|
360
431
|
emitToolCallEvent,
|
|
361
|
-
|
|
432
|
+
emitReasoningDelta: (reasoningDelta) => {
|
|
433
|
+
const reasoningId = startBlock('reasoning');
|
|
434
|
+
send({
|
|
435
|
+
type: 'reasoning-delta',
|
|
436
|
+
id: reasoningId,
|
|
437
|
+
delta: reasoningDelta,
|
|
438
|
+
});
|
|
439
|
+
},
|
|
440
|
+
emitTextDelta: (textDelta) => {
|
|
441
|
+
const textId = startBlock('text');
|
|
442
|
+
fullResponse += textDelta;
|
|
443
|
+
send({
|
|
444
|
+
type: 'text-delta',
|
|
445
|
+
id: textId,
|
|
446
|
+
delta: textDelta,
|
|
447
|
+
});
|
|
448
|
+
},
|
|
362
449
|
});
|
|
363
|
-
|
|
364
|
-
for (var _h = true, _j = __asyncValues(stream), _k; _k = yield _j.next(), _b = _k.done, !_b; _h = true) {
|
|
365
|
-
_d = _k.value;
|
|
366
|
-
_h = false;
|
|
367
|
-
const rawChunk = _d;
|
|
368
|
-
const [token, metadata] = rawChunk;
|
|
369
|
-
const nodeName = typeof (metadata === null || metadata === void 0 ? void 0 : metadata.langgraph_node) === "string"
|
|
370
|
-
? metadata.langgraph_node
|
|
371
|
-
: "";
|
|
372
|
-
if (nodeName && !["model", "model_request"].includes(nodeName)) {
|
|
373
|
-
continue;
|
|
374
|
-
}
|
|
375
|
-
const blocks = Array.isArray(token === null || token === void 0 ? void 0 : token.contentBlocks)
|
|
376
|
-
? token.contentBlocks
|
|
377
|
-
: Array.isArray(token === null || token === void 0 ? void 0 : token.content)
|
|
378
|
-
? token.content
|
|
379
|
-
: [];
|
|
380
|
-
const reasoningDelta = blocks
|
|
381
|
-
.filter((b) => (b === null || b === void 0 ? void 0 : b.type) === "reasoning")
|
|
382
|
-
.map((b) => { var _a; return String((_a = b.reasoning) !== null && _a !== void 0 ? _a : ""); })
|
|
383
|
-
.join("");
|
|
384
|
-
const textDelta = blocks
|
|
385
|
-
.filter((b) => (b === null || b === void 0 ? void 0 : b.type) === "text")
|
|
386
|
-
.map((b) => { var _a; return String((_a = b.text) !== null && _a !== void 0 ? _a : ""); })
|
|
387
|
-
.join("");
|
|
388
|
-
if (reasoningDelta) {
|
|
389
|
-
const reasoningId = startBlock('reasoning');
|
|
390
|
-
send({
|
|
391
|
-
type: 'reasoning-delta',
|
|
392
|
-
id: reasoningId,
|
|
393
|
-
delta: reasoningDelta,
|
|
394
|
-
});
|
|
395
|
-
}
|
|
396
|
-
if (textDelta) {
|
|
397
|
-
const textId = startBlock('text');
|
|
398
|
-
fullResponse += textDelta;
|
|
399
|
-
send({
|
|
400
|
-
type: 'text-delta',
|
|
401
|
-
id: textId,
|
|
402
|
-
delta: textDelta,
|
|
403
|
-
});
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
408
|
-
finally {
|
|
409
|
-
try {
|
|
410
|
-
if (!_h && !_b && (_c = _j.return)) yield _c.call(_j);
|
|
411
|
-
}
|
|
412
|
-
finally { if (e_1) throw e_1.error; }
|
|
413
|
-
}
|
|
450
|
+
fullResponse = agentResponse.text;
|
|
414
451
|
}
|
|
415
452
|
catch (error) {
|
|
416
453
|
logger.error(`Agent response streaming failed:\n${formatAgentError(error)}`);
|
|
417
454
|
sequenceDebugCollector.flush();
|
|
455
|
+
fullResponse = formatAgentResponseError(error);
|
|
418
456
|
const textId = startBlock('text');
|
|
419
457
|
send({
|
|
420
458
|
type: 'text-delta',
|
|
421
459
|
id: textId,
|
|
422
|
-
delta:
|
|
460
|
+
delta: fullResponse,
|
|
423
461
|
});
|
|
424
462
|
}
|
|
425
463
|
sequenceDebugCollector.flush();
|
|
@@ -434,6 +472,115 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
|
|
|
434
472
|
return null;
|
|
435
473
|
})
|
|
436
474
|
});
|
|
475
|
+
server.endpoint({
|
|
476
|
+
method: 'POST',
|
|
477
|
+
path: `/agent/speech-response`,
|
|
478
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, query, headers, cookies, adminUser, response, requestUrl }) {
|
|
479
|
+
var _b;
|
|
480
|
+
const audioAdapter = this.options.audioAdapter;
|
|
481
|
+
if (!audioAdapter) {
|
|
482
|
+
response.setStatus(400, undefined);
|
|
483
|
+
return {
|
|
484
|
+
error: "Audio adapter is not configured for AdminForth Agent",
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
const speechBody = body;
|
|
488
|
+
let transcription;
|
|
489
|
+
try {
|
|
490
|
+
transcription = yield audioAdapter.transcribe({
|
|
491
|
+
buffer: Buffer.from(speechBody.audioBase64, "base64"),
|
|
492
|
+
filename: speechBody.filename,
|
|
493
|
+
mimeType: speechBody.mimeType,
|
|
494
|
+
language: "auto",
|
|
495
|
+
prompt: speechBody.prompt,
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
catch (error) {
|
|
499
|
+
logger.error(`Agent speech transcription failed:\n${formatAgentError(error)}`);
|
|
500
|
+
response.setStatus(500, undefined);
|
|
501
|
+
return {
|
|
502
|
+
error: "Speech transcription failed. Check server logs for details.",
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
const prompt = transcription.text;
|
|
506
|
+
if (!prompt) {
|
|
507
|
+
response.setStatus(400, undefined);
|
|
508
|
+
return {
|
|
509
|
+
error: "Speech transcription is empty",
|
|
510
|
+
};
|
|
511
|
+
}
|
|
512
|
+
const sessionId = speechBody.sessionId || (adminUser === null || adminUser === void 0 ? void 0 : adminUser.pk) || (adminUser === null || adminUser === void 0 ? void 0 : adminUser.username) || 'default';
|
|
513
|
+
const turnId = yield this.createNewTurn(sessionId, prompt);
|
|
514
|
+
yield this.updateSessionDate(sessionId);
|
|
515
|
+
const sequenceDebugCollector = createSequenceDebugCollector();
|
|
516
|
+
let fullResponse = "";
|
|
517
|
+
try {
|
|
518
|
+
const agentResponse = yield this.runAgentTurn({
|
|
519
|
+
prompt,
|
|
520
|
+
sessionId,
|
|
521
|
+
turnId,
|
|
522
|
+
modeName: speechBody.mode,
|
|
523
|
+
userTimeZone: (_b = speechBody.timeZone) !== null && _b !== void 0 ? _b : 'UTC',
|
|
524
|
+
currentPage: speechBody.currentPage,
|
|
525
|
+
adminUser,
|
|
526
|
+
httpExtra: {
|
|
527
|
+
body,
|
|
528
|
+
query,
|
|
529
|
+
headers,
|
|
530
|
+
cookies,
|
|
531
|
+
requestUrl,
|
|
532
|
+
response,
|
|
533
|
+
},
|
|
534
|
+
sequenceDebugCollector,
|
|
535
|
+
emitTextDelta: (textDelta) => {
|
|
536
|
+
fullResponse += textDelta;
|
|
537
|
+
},
|
|
538
|
+
});
|
|
539
|
+
fullResponse = agentResponse.text;
|
|
540
|
+
const speech = yield audioAdapter.synthesize(Object.assign({ text: fullResponse }, speechBody.tts));
|
|
541
|
+
sequenceDebugCollector.flush();
|
|
542
|
+
const turnUpdates = {
|
|
543
|
+
[this.options.turnResource.responseField]: fullResponse,
|
|
544
|
+
};
|
|
545
|
+
if (this.options.turnResource.debugField) {
|
|
546
|
+
turnUpdates[this.options.turnResource.debugField] = sequenceDebugCollector.getHistory();
|
|
547
|
+
}
|
|
548
|
+
yield this.updateTurn(turnId, turnUpdates);
|
|
549
|
+
return {
|
|
550
|
+
transcript: {
|
|
551
|
+
text: transcription.text,
|
|
552
|
+
language: transcription.language,
|
|
553
|
+
},
|
|
554
|
+
response: {
|
|
555
|
+
text: fullResponse,
|
|
556
|
+
},
|
|
557
|
+
audio: {
|
|
558
|
+
base64: speech.audio.toString("base64"),
|
|
559
|
+
mimeType: speech.mimeType,
|
|
560
|
+
format: speech.format,
|
|
561
|
+
},
|
|
562
|
+
sessionId,
|
|
563
|
+
turnId,
|
|
564
|
+
};
|
|
565
|
+
}
|
|
566
|
+
catch (error) {
|
|
567
|
+
logger.error(`Agent speech response failed:\n${formatAgentError(error)}`);
|
|
568
|
+
sequenceDebugCollector.flush();
|
|
569
|
+
fullResponse = formatAgentResponseError(error);
|
|
570
|
+
const turnUpdates = {
|
|
571
|
+
[this.options.turnResource.responseField]: fullResponse,
|
|
572
|
+
};
|
|
573
|
+
if (this.options.turnResource.debugField) {
|
|
574
|
+
turnUpdates[this.options.turnResource.debugField] = sequenceDebugCollector.getHistory();
|
|
575
|
+
}
|
|
576
|
+
yield this.updateTurn(turnId, turnUpdates);
|
|
577
|
+
response.setStatus(500, undefined);
|
|
578
|
+
return {
|
|
579
|
+
error: fullResponse,
|
|
580
|
+
};
|
|
581
|
+
}
|
|
582
|
+
})
|
|
583
|
+
});
|
|
437
584
|
server.endpoint({
|
|
438
585
|
method: 'POST',
|
|
439
586
|
path: `/agent/get-sessions`,
|
|
@@ -543,6 +690,18 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
|
|
|
543
690
|
ok: true
|
|
544
691
|
};
|
|
545
692
|
})
|
|
546
|
-
})
|
|
693
|
+
}),
|
|
694
|
+
server.endpoint({
|
|
695
|
+
method: 'POST',
|
|
696
|
+
path: `/agent/add-system-message-to-turns`,
|
|
697
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, _raw_express_req }) {
|
|
698
|
+
const sessionId = body.sessionId;
|
|
699
|
+
const systemMessage = body.systemMessage;
|
|
700
|
+
yield this.createNewTurn(sessionId, systemMessage);
|
|
701
|
+
return {
|
|
702
|
+
ok: true
|
|
703
|
+
};
|
|
704
|
+
})
|
|
705
|
+
});
|
|
547
706
|
}
|
|
548
707
|
}
|