@adminforth/agent 1.43.28 → 1.44.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.
Files changed (37) hide show
  1. package/agent/checkpointer.ts +2 -1
  2. package/agent/systemPrompt.ts +2 -1
  3. package/agentEvents.ts +61 -0
  4. package/agentResponseEvents.ts +1 -206
  5. package/apiBasedTools.ts +7 -3
  6. package/dist/agent/checkpointer.d.ts +29 -0
  7. package/dist/agent/languageDetect.d.ts +10 -0
  8. package/dist/agent/middleware/apiBasedTools.d.ts +3 -0
  9. package/dist/agent/middleware/openAiResponsesContinuation.d.ts +1 -0
  10. package/dist/agent/middleware/sequenceDebug.d.ts +46 -0
  11. package/dist/agent/simpleAgent.d.ts +61 -0
  12. package/dist/agent/skills/registry.d.ts +13 -0
  13. package/dist/agent/systemPrompt.d.ts +11 -0
  14. package/dist/agent/systemPrompt.js +3 -1
  15. package/dist/agent/toolCallEvents.d.ts +27 -0
  16. package/dist/agent/tools/apiTool.d.ts +6 -0
  17. package/dist/agent/tools/fetchSkill.d.ts +8 -0
  18. package/dist/agent/tools/fetchToolSchema.d.ts +9 -0
  19. package/dist/agent/tools/getUserLocation.d.ts +8 -0
  20. package/dist/agent/tools/index.d.ts +4 -0
  21. package/dist/agentEvents.d.ts +52 -0
  22. package/dist/agentEvents.js +1 -0
  23. package/dist/agentResponseEvents.d.ts +1 -0
  24. package/dist/agentResponseEvents.js +1 -144
  25. package/dist/apiBasedTools.d.ts +29 -0
  26. package/dist/apiBasedTools.js +5 -3
  27. package/dist/index.d.ts +58 -0
  28. package/dist/index.js +251 -59
  29. package/dist/sanitizeSpeechText.d.ts +1 -0
  30. package/dist/surfaces/web-sse/createSseEventEmitter.d.ts +14 -0
  31. package/dist/surfaces/web-sse/createSseEventEmitter.js +196 -0
  32. package/dist/types.d.ts +94 -0
  33. package/index.ts +279 -59
  34. package/package.json +2 -2
  35. package/surfaces/web-sse/createSseEventEmitter.ts +261 -0
  36. package/tsconfig.json +2 -1
  37. package/types.ts +6 -0
package/dist/index.js CHANGED
@@ -24,7 +24,7 @@ import { AdminForthCheckpointSaver } from "./agent/checkpointer.js";
24
24
  import { createSequenceDebugCollector } from "./agent/middleware/sequenceDebug.js";
25
25
  import { detectUserLanguage } from "./agent/languageDetect.js";
26
26
  import { prepareApiBasedTools as buildApiBasedTools } from './apiBasedTools.js';
27
- import { createAgentEventStream } from "./agentResponseEvents.js";
27
+ import { createSseEventEmitter } from "./surfaces/web-sse/createSseEventEmitter.js";
28
28
  import { appendCustomSystemPrompt, buildAgentSystemPrompt, buildAgentTurnSystemPrompt, DEFAULT_AGENT_SYSTEM_PROMPT } from "./agent/systemPrompt.js";
29
29
  import { sanitizeSpeechText } from "./sanitizeSpeechText.js";
30
30
  const agentResponseBodySchema = z.object({
@@ -57,6 +57,12 @@ function isAbortError(error) {
57
57
  function getErrorMessage(error) {
58
58
  return error instanceof Error ? error.message : String(error);
59
59
  }
60
+ function requireAdminUser(adminUser) {
61
+ if (!adminUser) {
62
+ throw new Error("AdminForth Agent endpoint requires an authenticated admin user");
63
+ }
64
+ return adminUser;
65
+ }
60
66
  export default class AdminForthAgentPlugin extends AdminForthPlugin {
61
67
  parseBody(schema, body, response) {
62
68
  const parsed = schema.safeParse(body !== null && body !== void 0 ? body : {});
@@ -98,6 +104,25 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
98
104
  }));
99
105
  });
100
106
  }
107
+ getChatSurfaceSessionId(incoming) {
108
+ return `${incoming.surface}:${incoming.externalConversationId}`;
109
+ }
110
+ getOrCreateChatSurfaceSession(incoming, adminUser) {
111
+ return __awaiter(this, void 0, void 0, function* () {
112
+ const sessionId = this.getChatSurfaceSessionId(incoming);
113
+ const sessionResource = this.adminforth.resource(this.options.sessionResource.resourceId);
114
+ const session = yield sessionResource.get([Filters.EQ(this.options.sessionResource.idField, sessionId)]);
115
+ if (session) {
116
+ return sessionId;
117
+ }
118
+ yield sessionResource.create({
119
+ [this.options.sessionResource.idField]: sessionId,
120
+ [this.options.sessionResource.titleField]: incoming.prompt.slice(0, 40) || "New Session",
121
+ [this.options.sessionResource.askerIdField]: adminUser.pk,
122
+ });
123
+ return sessionId;
124
+ });
125
+ }
101
126
  getCheckpointer() {
102
127
  if (this.checkpointer)
103
128
  return this.checkpointer;
@@ -164,8 +189,11 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
164
189
  });
165
190
  }
166
191
  validateConfigAfterDiscover(adminforth, resourceConfig) {
167
- var _a;
192
+ var _a, _b;
168
193
  (_a = this.options.audioAdapter) === null || _a === void 0 ? void 0 : _a.validate();
194
+ for (const chatSurfaceAdapter of (_b = this.options.chatSurfaceAdapters) !== null && _b !== void 0 ? _b : []) {
195
+ chatSurfaceAdapter.validate();
196
+ }
169
197
  this.agentSystemPromptPromise = buildAgentSystemPrompt(adminforth, this.getInternalAgentResourceIds())
170
198
  .then((systemPrompt) => appendCustomSystemPrompt(systemPrompt, this.options.systemPrompt));
171
199
  }
@@ -175,7 +203,7 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
175
203
  runAgentTurn(input) {
176
204
  return __awaiter(this, void 0, void 0, function* () {
177
205
  var _a, e_1, _b, _c;
178
- var _d, _e, _f, _g, _h;
206
+ var _d, _e, _f, _g, _h, _j;
179
207
  let fullResponse = "";
180
208
  const maxTokens = (_d = this.options.maxTokens) !== null && _d !== void 0 ? _d : 1000;
181
209
  const selectedMode = (_e = this.options.modes.find((mode) => mode.name === input.modeName)) !== null && _e !== void 0 ? _e : this.options.modes[0];
@@ -223,7 +251,7 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
223
251
  adminUser: input.adminUser,
224
252
  adminforth: this.adminforth,
225
253
  apiBasedTools,
226
- customComponentsDir: this.adminforth.config.customization.customComponentsDir,
254
+ customComponentsDir: (_f = this.adminforth.config.customization.customComponentsDir) !== null && _f !== void 0 ? _f : "custom",
227
255
  sessionId: input.sessionId,
228
256
  turnId: input.turnId,
229
257
  currentPage: input.currentPage,
@@ -232,16 +260,19 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
232
260
  emitToolCallEvent: (event) => {
233
261
  var _a;
234
262
  input.sequenceDebugCollector.handleToolCallEvent(event);
235
- (_a = input.emitToolCallEvent) === null || _a === void 0 ? void 0 : _a.call(input, event);
263
+ void ((_a = input.emit) === null || _a === void 0 ? void 0 : _a.call(input, {
264
+ type: "tool-call",
265
+ data: event,
266
+ }));
236
267
  },
237
268
  sequenceDebugSink: input.sequenceDebugCollector,
238
269
  });
239
270
  try {
240
- for (var _j = true, _k = __asyncValues(stream), _l; _l = yield _k.next(), _a = _l.done, !_a; _j = true) {
241
- _c = _l.value;
242
- _j = false;
271
+ for (var _k = true, _l = __asyncValues(stream), _m; _m = yield _l.next(), _a = _m.done, !_a; _k = true) {
272
+ _c = _m.value;
273
+ _k = false;
243
274
  const rawChunk = _c;
244
- if ((_f = input.abortSignal) === null || _f === void 0 ? void 0 : _f.aborted) {
275
+ if ((_g = input.abortSignal) === null || _g === void 0 ? void 0 : _g.aborted) {
245
276
  throw new DOMException("This operation was aborted", "AbortError");
246
277
  }
247
278
  const [token, metadata] = rawChunk;
@@ -265,18 +296,24 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
265
296
  .map((b) => { var _a; return String((_a = b.text) !== null && _a !== void 0 ? _a : ""); })
266
297
  .join("");
267
298
  if (reasoningDelta) {
268
- (_g = input.emitReasoningDelta) === null || _g === void 0 ? void 0 : _g.call(input, reasoningDelta);
299
+ yield ((_h = input.emit) === null || _h === void 0 ? void 0 : _h.call(input, {
300
+ type: "reasoning-delta",
301
+ delta: reasoningDelta,
302
+ }));
269
303
  }
270
304
  if (textDelta) {
271
305
  fullResponse += textDelta;
272
- (_h = input.emitTextDelta) === null || _h === void 0 ? void 0 : _h.call(input, textDelta);
306
+ yield ((_j = input.emit) === null || _j === void 0 ? void 0 : _j.call(input, {
307
+ type: "text-delta",
308
+ delta: textDelta,
309
+ }));
273
310
  }
274
311
  }
275
312
  }
276
313
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
277
314
  finally {
278
315
  try {
279
- if (!_j && !_a && (_b = _k.return)) yield _b.call(_k);
316
+ if (!_k && !_a && (_b = _l.return)) yield _b.call(_l);
280
317
  }
281
318
  finally { if (e_1) throw e_1.error; }
282
319
  }
@@ -287,7 +324,7 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
287
324
  }
288
325
  runAndPersistAgentResponse(input) {
289
326
  return __awaiter(this, void 0, void 0, function* () {
290
- var _a, _b;
327
+ var _a;
291
328
  const previousUserMessages = yield this.getPreviousUserMessages(input.sessionId);
292
329
  const turnId = yield this.createNewTurn(input.sessionId, input.prompt);
293
330
  yield this.adminforth.resource(this.options.sessionResource.resourceId).update(input.sessionId, {
@@ -309,9 +346,7 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
309
346
  abortSignal: input.abortSignal,
310
347
  adminUser: input.adminUser,
311
348
  sequenceDebugCollector,
312
- emitToolCallEvent: input.emitToolCallEvent,
313
- emitReasoningDelta: input.emitReasoningDelta,
314
- emitTextDelta: input.emitTextDelta,
349
+ emit: input.emit,
315
350
  });
316
351
  fullResponse = agentResponse.text;
317
352
  }
@@ -324,7 +359,6 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
324
359
  failed = true;
325
360
  fullResponse = getErrorMessage(error);
326
361
  logger.error(`${input.failureLogMessage}:\n${fullResponse}`);
327
- (_b = input.emitErrorResponse) === null || _b === void 0 ? void 0 : _b.call(input, fullResponse);
328
362
  }
329
363
  }
330
364
  sequenceDebugCollector.flush();
@@ -343,18 +377,137 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
343
377
  };
344
378
  });
345
379
  }
380
+ handleTurn(input) {
381
+ return __awaiter(this, void 0, void 0, function* () {
382
+ var _a, _b;
383
+ yield input.emit({
384
+ type: "turn-started",
385
+ messageId: randomUUID(),
386
+ });
387
+ const agentResponse = yield this.runAndPersistAgentResponse({
388
+ prompt: input.prompt,
389
+ sessionId: input.sessionId,
390
+ modeName: input.modeName,
391
+ userTimeZone: input.userTimeZone,
392
+ currentPage: input.currentPage,
393
+ abortSignal: input.abortSignal,
394
+ adminUser: input.adminUser,
395
+ emit: input.emit,
396
+ failureLogMessage: (_a = input.failureLogMessage) !== null && _a !== void 0 ? _a : "Agent response failed",
397
+ abortLogMessage: (_b = input.abortLogMessage) !== null && _b !== void 0 ? _b : "Agent response aborted",
398
+ });
399
+ if (agentResponse.failed) {
400
+ yield input.emit({
401
+ type: "error",
402
+ error: agentResponse.text,
403
+ });
404
+ }
405
+ else if (!agentResponse.aborted) {
406
+ yield input.emit({
407
+ type: "response",
408
+ text: agentResponse.text,
409
+ sessionId: input.sessionId,
410
+ turnId: agentResponse.turnId,
411
+ });
412
+ }
413
+ yield input.emit({
414
+ type: "finish",
415
+ });
416
+ return agentResponse;
417
+ });
418
+ }
419
+ createChatSurfaceEventEmitter(sink) {
420
+ return (event) => __awaiter(this, void 0, void 0, function* () {
421
+ if (event.type === "text-delta") {
422
+ yield sink.emit({
423
+ type: "text_delta",
424
+ delta: event.delta,
425
+ });
426
+ return;
427
+ }
428
+ if (event.type === "response") {
429
+ yield sink.emit({
430
+ type: "done",
431
+ text: event.text,
432
+ });
433
+ return;
434
+ }
435
+ if (event.type === "error") {
436
+ yield sink.emit({
437
+ type: "error",
438
+ message: event.error,
439
+ });
440
+ }
441
+ });
442
+ }
443
+ handleChatSurfaceMessage(adapter, incoming, sink) {
444
+ return __awaiter(this, void 0, void 0, function* () {
445
+ var _a;
446
+ const adminUser = yield adapter.resolveAdminUser({
447
+ adminforth: this.adminforth,
448
+ incoming,
449
+ });
450
+ if (!adminUser) {
451
+ yield sink.emit({
452
+ type: "error",
453
+ message: "This chat account is not authorized to use AdminForth Agent.",
454
+ });
455
+ return;
456
+ }
457
+ yield this.handleTurn({
458
+ prompt: incoming.prompt,
459
+ sessionId: yield this.getOrCreateChatSurfaceSession(incoming, adminUser),
460
+ modeName: incoming.modeName,
461
+ userTimeZone: (_a = incoming.userTimeZone) !== null && _a !== void 0 ? _a : "UTC",
462
+ adminUser,
463
+ emit: this.createChatSurfaceEventEmitter(sink),
464
+ failureLogMessage: `Agent ${incoming.surface} surface response failed`,
465
+ abortLogMessage: `Agent ${incoming.surface} surface response aborted`,
466
+ });
467
+ });
468
+ }
346
469
  setupEndpoints(server) {
470
+ var _a;
471
+ for (const adapter of (_a = this.options.chatSurfaceAdapters) !== null && _a !== void 0 ? _a : []) {
472
+ server.endpoint({
473
+ method: "POST",
474
+ noAuth: true,
475
+ path: `/agent/surface/${adapter.name}/webhook`,
476
+ handler: (ctx) => __awaiter(this, void 0, void 0, function* () {
477
+ var _a;
478
+ const surfaceContext = {
479
+ body: ctx.body,
480
+ headers: ctx.headers,
481
+ abortSignal: ctx.abortSignal,
482
+ rawRequest: ctx._raw_express_req,
483
+ rawResponse: ctx._raw_express_res,
484
+ };
485
+ const incoming = yield adapter.parseIncomingMessage(surfaceContext);
486
+ if (!incoming)
487
+ return { ok: true };
488
+ const sink = yield adapter.createEventSink(surfaceContext, incoming);
489
+ try {
490
+ yield this.handleChatSurfaceMessage(adapter, incoming, sink);
491
+ }
492
+ finally {
493
+ yield ((_a = sink.close) === null || _a === void 0 ? void 0 : _a.call(sink));
494
+ }
495
+ return { ok: true };
496
+ }),
497
+ });
498
+ }
347
499
  server.endpoint({
348
500
  method: 'POST',
349
501
  path: `/agent/get-placeholder-messages`,
350
502
  handler: (_a) => __awaiter(this, [_a], void 0, function* ({ headers, adminUser }) {
503
+ const currentAdminUser = requireAdminUser(adminUser);
351
504
  if (!this.options.placeholderMessages) {
352
505
  return {
353
506
  messages: [],
354
507
  };
355
508
  }
356
509
  const messages = yield this.options.placeholderMessages({
357
- adminUser,
510
+ adminUser: currentAdminUser,
358
511
  headers,
359
512
  });
360
513
  return {
@@ -367,28 +520,26 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
367
520
  path: `/agent/response`,
368
521
  handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, response, _raw_express_res, abortSignal }) {
369
522
  var _b;
523
+ const currentAdminUser = requireAdminUser(adminUser);
370
524
  const data = this.parseBody(agentResponseBodySchema, body, response);
371
525
  if (!data)
372
526
  return;
373
- const stream = createAgentEventStream(_raw_express_res, { vercelAiUiMessageStream: true, closeActiveBlockOnToolStart: true });
374
- const messageId = randomUUID();
375
- stream.start(messageId);
376
- yield this.runAndPersistAgentResponse({
527
+ const emit = createSseEventEmitter(_raw_express_res, {
528
+ vercelAiUiMessageStream: true,
529
+ closeActiveBlockOnToolStart: true,
530
+ });
531
+ yield this.handleTurn({
377
532
  prompt: data.message,
378
533
  sessionId: data.sessionId,
379
534
  modeName: data.mode,
380
535
  userTimeZone: (_b = data.timeZone) !== null && _b !== void 0 ? _b : 'UTC',
381
536
  currentPage: data.currentPage,
382
537
  abortSignal,
383
- adminUser,
384
- emitToolCallEvent: stream.toolCall,
385
- emitReasoningDelta: stream.reasoningDelta,
386
- emitTextDelta: stream.textDelta,
387
- emitErrorResponse: stream.textDelta,
538
+ adminUser: currentAdminUser,
539
+ emit,
388
540
  failureLogMessage: "Agent response streaming failed",
389
541
  abortLogMessage: "Agent response streaming aborted by the client",
390
542
  });
391
- stream.end();
392
543
  return null;
393
544
  })
394
545
  });
@@ -398,20 +549,21 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
398
549
  target: 'upload',
399
550
  handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, response, _raw_express_req, _raw_express_res, abortSignal }) {
400
551
  var _b;
552
+ const currentAdminUser = requireAdminUser(adminUser);
401
553
  const req = _raw_express_req;
402
554
  const audioAdapter = this.options.audioAdapter;
403
555
  if (!audioAdapter) {
404
- response.setStatus(400, undefined);
556
+ response.setStatus(400, "Audio adapter is not configured for AdminForth Agent");
405
557
  return { error: "Audio adapter is not configured for AdminForth Agent" };
406
558
  }
407
559
  const data = this.parseBody(agentSpeechResponseBodySchema, body, response);
408
560
  if (!data)
409
561
  return;
410
562
  if (!req.file) {
411
- response.setStatus(400, undefined);
563
+ response.setStatus(400, "Audio file is required");
412
564
  return { error: "Audio file is required" };
413
565
  }
414
- const stream = createAgentEventStream(_raw_express_res);
566
+ const emit = createSseEventEmitter(_raw_express_res);
415
567
  let transcription;
416
568
  try {
417
569
  transcription = yield audioAdapter.transcribe({
@@ -425,25 +577,35 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
425
577
  catch (error) {
426
578
  if (abortSignal.aborted || isAbortError(error)) {
427
579
  logger.info("Agent speech transcription aborted by the client");
428
- stream.end();
580
+ yield emit({ type: "finish" });
429
581
  return null;
430
582
  }
431
583
  logger.error(`Agent speech transcription failed:\n${getErrorMessage(error)}`);
432
- stream.error("Speech transcription failed. Check server logs for details.");
433
- stream.end();
584
+ yield emit({
585
+ type: "error",
586
+ error: "Speech transcription failed. Check server logs for details.",
587
+ });
588
+ yield emit({ type: "finish" });
434
589
  return null;
435
590
  }
436
591
  if (abortSignal.aborted) {
437
- stream.end();
592
+ yield emit({ type: "finish" });
438
593
  return null;
439
594
  }
440
595
  const prompt = transcription.text;
441
596
  if (!prompt) {
442
- stream.error("Speech transcription is empty");
443
- stream.end();
597
+ yield emit({
598
+ type: "error",
599
+ error: "Speech transcription is empty",
600
+ });
601
+ yield emit({ type: "finish" });
444
602
  return null;
445
603
  }
446
- stream.transcript(transcription.text, transcription.language);
604
+ yield emit({
605
+ type: "transcript",
606
+ text: transcription.text,
607
+ language: transcription.language,
608
+ });
447
609
  const sessionId = data.sessionId;
448
610
  const currentPage = data.currentPage;
449
611
  const agentResponse = yield this.runAndPersistAgentResponse({
@@ -453,27 +615,40 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
453
615
  userTimeZone: (_b = data.timeZone) !== null && _b !== void 0 ? _b : 'UTC',
454
616
  currentPage,
455
617
  abortSignal,
456
- adminUser,
457
- emitToolCallEvent: stream.toolCall,
618
+ adminUser: currentAdminUser,
619
+ emit: (event) => __awaiter(this, void 0, void 0, function* () {
620
+ if (event.type === "tool-call") {
621
+ yield emit(event);
622
+ }
623
+ }),
458
624
  failureLogMessage: "Agent speech response failed",
459
625
  abortLogMessage: "Agent speech response aborted by the client",
460
626
  });
461
627
  if (agentResponse.aborted) {
462
- stream.end();
628
+ yield emit({ type: "finish" });
463
629
  return null;
464
630
  }
465
631
  if (agentResponse.failed) {
466
- stream.error(agentResponse.text);
467
- stream.end();
632
+ yield emit({
633
+ type: "error",
634
+ error: agentResponse.text,
635
+ });
636
+ yield emit({ type: "finish" });
468
637
  return null;
469
638
  }
470
639
  try {
471
- stream.speechResponse({
472
- text: transcription.text,
473
- language: transcription.language,
474
- }, {
475
- text: agentResponse.text,
476
- }, sessionId, agentResponse.turnId);
640
+ yield emit({
641
+ type: "speech-response",
642
+ transcript: {
643
+ text: transcription.text,
644
+ language: transcription.language,
645
+ },
646
+ response: {
647
+ text: agentResponse.text,
648
+ },
649
+ sessionId,
650
+ turnId: agentResponse.turnId,
651
+ });
477
652
  const speech = yield audioAdapter.synthesize({
478
653
  text: sanitizeSpeechText(agentResponse.text),
479
654
  stream: true,
@@ -481,7 +656,14 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
481
656
  format: "pcm",
482
657
  abortSignal,
483
658
  });
484
- stream.audioStart(speech.mimeType, speech.format, 24000, 1, 16);
659
+ yield emit({
660
+ type: "audio-start",
661
+ mimeType: speech.mimeType,
662
+ format: speech.format,
663
+ sampleRate: 24000,
664
+ channelCount: 1,
665
+ bitsPerSample: 16,
666
+ });
485
667
  const reader = speech.audioStream.getReader();
486
668
  const cancelAudioStream = () => {
487
669
  void reader.cancel().catch(() => undefined);
@@ -500,15 +682,18 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
500
682
  if (abortSignal.aborted) {
501
683
  break;
502
684
  }
503
- stream.audioDelta(value);
685
+ yield emit({
686
+ type: "audio-delta",
687
+ value,
688
+ });
504
689
  }
505
690
  }
506
691
  finally {
507
692
  abortSignal.removeEventListener("abort", cancelAudioStream);
508
693
  reader.releaseLock();
509
694
  }
510
- stream.audioDone();
511
- stream.end();
695
+ yield emit({ type: "audio-done" });
696
+ yield emit({ type: "finish" });
512
697
  return null;
513
698
  }
514
699
  catch (error) {
@@ -517,9 +702,12 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
517
702
  }
518
703
  else {
519
704
  logger.error(`Agent speech audio streaming failed:\n${error}`);
520
- stream.error(error);
705
+ yield emit({
706
+ type: "error",
707
+ error: getErrorMessage(error),
708
+ });
521
709
  }
522
- stream.end();
710
+ yield emit({ type: "finish" });
523
711
  return null;
524
712
  }
525
713
  })
@@ -529,10 +717,11 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
529
717
  path: `/agent/get-sessions`,
530
718
  handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, response }) {
531
719
  var _b;
720
+ const currentAdminUser = requireAdminUser(adminUser);
532
721
  const data = this.parseBody(getSessionsBodySchema, body, response);
533
722
  if (!data)
534
723
  return;
535
- const userId = adminUser.pk;
724
+ const userId = currentAdminUser.pk;
536
725
  const limit = (_b = data.limit) !== null && _b !== void 0 ? _b : 20;
537
726
  const sessions = yield this.adminforth.resource(this.options.sessionResource.resourceId).list([Filters.EQ(this.options.sessionResource.askerIdField, userId)], limit, undefined, [Sorts.DESC(this.options.sessionResource.createdAtField)]);
538
727
  return {
@@ -548,12 +737,13 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
548
737
  method: 'POST',
549
738
  path: `/agent/get-session-info`,
550
739
  handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, response }) {
740
+ const currentAdminUser = requireAdminUser(adminUser);
551
741
  const parsedBody = sessionIdBodySchema.safeParse(body);
552
742
  if (!parsedBody.success) {
553
743
  response.setStatus(422, parsedBody.error.message);
554
744
  return;
555
745
  }
556
- const userId = adminUser.pk;
746
+ const userId = currentAdminUser.pk;
557
747
  const sessionId = parsedBody.data.sessionId;
558
748
  const session = yield this.adminforth.resource(this.options.sessionResource.resourceId).get([Filters.EQ(this.options.sessionResource.idField, sessionId)]);
559
749
  if (!session) {
@@ -596,11 +786,12 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
596
786
  method: 'POST',
597
787
  path: `/agent/create-session`,
598
788
  handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, response }) {
789
+ const currentAdminUser = requireAdminUser(adminUser);
599
790
  const data = this.parseBody(createSessionBodySchema, body, response);
600
791
  if (!data)
601
792
  return;
602
793
  const triggerMessage = data.triggerMessage;
603
- const userId = adminUser.pk;
794
+ const userId = currentAdminUser.pk;
604
795
  const title = (triggerMessage === null || triggerMessage === void 0 ? void 0 : triggerMessage.slice(0, 40)) || "New Session";
605
796
  const newSession = {
606
797
  [this.options.sessionResource.idField]: randomUUID(),
@@ -620,11 +811,12 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
620
811
  method: 'POST',
621
812
  path: `/agent/delete-session`,
622
813
  handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, response }) {
814
+ const currentAdminUser = requireAdminUser(adminUser);
623
815
  const data = this.parseBody(sessionIdBodySchema, body, response);
624
816
  if (!data)
625
817
  return;
626
818
  const sessionId = data.sessionId;
627
- const userId = adminUser.pk;
819
+ const userId = currentAdminUser.pk;
628
820
  const session = yield this.adminforth.resource(this.options.sessionResource.resourceId).get([Filters.EQ(this.options.sessionResource.idField, sessionId)]);
629
821
  if (!session) {
630
822
  return {
@@ -0,0 +1 @@
1
+ export declare function sanitizeSpeechText(input: string): string;
@@ -0,0 +1,14 @@
1
+ import type { AgentEventEmitter } from "../../agentEvents.js";
2
+ type AgentEventStreamResponse = {
3
+ writeHead: (statusCode: number, headers: Record<string, string>) => void;
4
+ write: (chunk: string) => unknown;
5
+ end: () => unknown;
6
+ writableEnded: boolean;
7
+ destroyed: boolean;
8
+ };
9
+ type AgentEventStreamOptions = {
10
+ vercelAiUiMessageStream?: boolean;
11
+ closeActiveBlockOnToolStart?: boolean;
12
+ };
13
+ export declare function createSseEventEmitter(res: AgentEventStreamResponse, options?: AgentEventStreamOptions): AgentEventEmitter;
14
+ export {};