@adminforth/agent 1.49.2 → 1.50.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/middleware/sequenceDebug.ts +42 -7
  2. package/agent/simpleAgent.ts +15 -0
  3. package/agent/systemPrompt.ts +6 -1
  4. package/agent/tools/index.ts +2 -0
  5. package/agent/tools/navigateUser.ts +210 -0
  6. package/agentEvents.ts +4 -0
  7. package/agentTurnService.ts +14 -0
  8. package/build.log +2 -2
  9. package/chatSurfaceService.ts +7 -0
  10. package/custom/composables/agentStore/useAgentChat.ts +8 -1
  11. package/custom/composables/useAgentAudio.ts +5 -0
  12. package/custom/composables/useAgentStore.ts +43 -0
  13. package/custom/tsconfig.json +0 -1
  14. package/custom/types.ts +6 -0
  15. package/dist/agent/middleware/sequenceDebug.d.ts +6 -0
  16. package/dist/agent/middleware/sequenceDebug.js +33 -6
  17. package/dist/agent/simpleAgent.d.ts +8 -0
  18. package/dist/agent/simpleAgent.js +9 -1
  19. package/dist/agent/systemPrompt.d.ts +1 -0
  20. package/dist/agent/systemPrompt.js +5 -1
  21. package/dist/agent/tools/index.js +2 -0
  22. package/dist/agent/tools/navigateUser.d.ts +55 -0
  23. package/dist/agent/tools/navigateUser.js +163 -0
  24. package/dist/agentEvents.d.ts +3 -0
  25. package/dist/agentTurnService.d.ts +2 -0
  26. package/dist/agentTurnService.js +10 -0
  27. package/dist/chatSurfaceService.js +10 -3
  28. package/dist/custom/composables/agentStore/useAgentChat.ts +8 -1
  29. package/dist/custom/composables/useAgentAudio.ts +5 -0
  30. package/dist/custom/composables/useAgentStore.ts +43 -0
  31. package/dist/custom/tsconfig.json +0 -1
  32. package/dist/custom/types.ts +6 -0
  33. package/dist/endpoints/chatSurfaces.js +20 -0
  34. package/dist/surfaces/web-sse/createSseEventEmitter.js +11 -0
  35. package/endpoints/chatSurfaces.ts +29 -0
  36. package/package.json +2 -2
  37. package/surfaces/web-sse/createSseEventEmitter.ts +12 -0
@@ -1,6 +1,7 @@
1
1
  import { defineStore } from 'pinia';
2
2
  import { IAgentSession, ISessionsListItem } from '../types';
3
3
  import { ref, nextTick, computed, watch, onMounted } from 'vue';
4
+ import { useRouter } from 'vue-router';
4
5
  import { useAdminforth } from '@/adminforth';
5
6
  import { useCoreStore } from '@/stores/core';
6
7
  import { useAgentTransitions } from './useAgentTransitions';
@@ -28,6 +29,7 @@ export const useAgentStore = defineStore('agent', () => {
28
29
  const adminforth = useAdminforth();
29
30
  const isChatOpen = ref(false);
30
31
  const isSessionHistoryOpen = ref(false);
32
+ const router = useRouter();
31
33
  const textInput = ref<HTMLTextAreaElement | null>(null);
32
34
  const userMessageInput = ref();
33
35
  const trimmedUserMessage = computed(() => userMessageInput.value ? userMessageInput.value.trim() : '');
@@ -54,6 +56,7 @@ export const useAgentStore = defineStore('agent', () => {
54
56
  } = createAgentChatManager({
55
57
  lastMessage,
56
58
  activeModeName,
59
+ onOpenPage: openAgentPage,
57
60
  });
58
61
  const {
59
62
  userMessagePlaceholder,
@@ -324,6 +327,45 @@ export const useAgentStore = defineStore('agent', () => {
324
327
  addSystemMessage(RESERVED_SYSTEM_MESSAGE_CONTENT.AGENT_RESPONSE_ABORTED);
325
328
  }
326
329
 
330
+ function resolveInternalRoute(href: string): string | null {
331
+ if (href.startsWith('#')) {
332
+ return `${window.location.pathname}${window.location.search}${href}`;
333
+ }
334
+
335
+ if (href.startsWith('//')) {
336
+ return null;
337
+ }
338
+
339
+ const isAbsoluteWithScheme = /^[a-zA-Z][a-zA-Z\d+\-.]*:/.test(href);
340
+ const baseUrl = isAbsoluteWithScheme
341
+ ? undefined
342
+ : `${window.location.origin}/`;
343
+ const resolvedUrl = new URL(href, baseUrl ?? window.location.href);
344
+
345
+ if (resolvedUrl.origin !== window.location.origin) {
346
+ return null;
347
+ }
348
+
349
+ return `${resolvedUrl.pathname}${resolvedUrl.search}${resolvedUrl.hash}`;
350
+ }
351
+
352
+ function openAgentPage(targetPath: string) {
353
+ const internalRoute = resolveInternalRoute(targetPath);
354
+
355
+ if (internalRoute === null) {
356
+ console.warn('Ignoring external agent navigation target:', targetPath);
357
+ return;
358
+ }
359
+
360
+ if (isFullScreen.value && !coreStore.isMobile) {
361
+ setFullScreen(false);
362
+ } else if (coreStore.isMobile) {
363
+ setIsChatOpen(false);
364
+ }
365
+
366
+ void router.push(internalRoute);
367
+ }
368
+
327
369
  return {
328
370
  //_________-Sessions management-_____________
329
371
  activeSessionId,
@@ -374,6 +416,7 @@ export const useAgentStore = defineStore('agent', () => {
374
416
  addAgentMessage,
375
417
  addUserMessage,
376
418
  addDataToolCallMessage,
419
+ openAgentPage,
377
420
  setCurrentChatStatus,
378
421
  updateLastAgentMessage
379
422
  }
@@ -1,6 +1,5 @@
1
1
  {
2
2
  "compilerOptions": {
3
- "baseUrl": ".", // This should point to your project root
4
3
  "paths": {
5
4
  "@/*": [
6
5
  "../node_modules/adminforth/dist/spa/src/*"
@@ -93,6 +93,12 @@ export type SpeechStreamEvent =
93
93
  type: 'data-tool-call';
94
94
  data: any;
95
95
  }
96
+ | {
97
+ type: 'open-page';
98
+ data: {
99
+ targetPath: string;
100
+ };
101
+ }
96
102
  | {
97
103
  type: 'finish';
98
104
  };
@@ -7,6 +7,25 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
+ function getHeaderValue(headers, name) {
11
+ var _a;
12
+ const value = (_a = headers[name]) !== null && _a !== void 0 ? _a : headers[name.toLowerCase()];
13
+ if (Array.isArray(value)) {
14
+ return value[0];
15
+ }
16
+ return typeof value === "string" ? value : undefined;
17
+ }
18
+ function getRequestOrigin(input) {
19
+ var _a, _b, _c, _d;
20
+ const forwardedProto = (_b = (_a = getHeaderValue(input.headers, "x-forwarded-proto")) === null || _a === void 0 ? void 0 : _a.split(",")[0]) === null || _b === void 0 ? void 0 : _b.trim();
21
+ const forwardedHost = (_d = (_c = getHeaderValue(input.headers, "x-forwarded-host")) === null || _c === void 0 ? void 0 : _c.split(",")[0]) === null || _d === void 0 ? void 0 : _d.trim();
22
+ const host = forwardedHost !== null && forwardedHost !== void 0 ? forwardedHost : getHeaderValue(input.headers, "host");
23
+ if (!host) {
24
+ return undefined;
25
+ }
26
+ const proto = forwardedProto !== null && forwardedProto !== void 0 ? forwardedProto : (host.startsWith("localhost") || host.startsWith("127.0.0.1") ? "http" : "https");
27
+ return `${proto}://${host}`;
28
+ }
10
29
  export function setupChatSurfaceEndpoints(ctx, server) {
11
30
  var _a;
12
31
  for (const adapter of (_a = ctx.options.chatSurfaceAdapters) !== null && _a !== void 0 ? _a : []) {
@@ -26,6 +45,7 @@ export function setupChatSurfaceEndpoints(ctx, server) {
26
45
  const incoming = yield adapter.parseIncomingMessage(surfaceContext);
27
46
  if (!incoming)
28
47
  return { ok: true };
48
+ incoming.metadata = Object.assign(Object.assign({}, incoming.metadata), { adminPublicOrigin: getRequestOrigin(endpointInput) });
29
49
  const sink = yield adapter.createEventSink(surfaceContext, incoming);
30
50
  try {
31
51
  yield ctx.handleChatSurfaceMessage(adapter, incoming, sink);
@@ -88,6 +88,14 @@ function createAgentEventStream(res, options = {}) {
88
88
  },
89
89
  });
90
90
  },
91
+ openPage(targetPath) {
92
+ stream.send({
93
+ type: isAiUiMessageStream ? "data-open-page" : "open-page",
94
+ data: {
95
+ targetPath,
96
+ },
97
+ });
98
+ },
91
99
  transcript(text, language) {
92
100
  stream.send({
93
101
  type: isAiUiMessageStream ? "data-transcript" : "transcript",
@@ -186,6 +194,9 @@ export function createSseEventEmitter(res, options = {}) {
186
194
  case "rendering":
187
195
  stream.rendering(event.phase, event.label);
188
196
  break;
197
+ case "open-page":
198
+ stream.openPage(event.targetPath);
199
+ break;
189
200
  case "transcript":
190
201
  stream.transcript(event.text, event.language);
191
202
  break;
@@ -4,6 +4,31 @@ import type {
4
4
  } from "adminforth";
5
5
  import type { ChatSurfaceEndpointsContext } from "./context.js";
6
6
 
7
+ function getHeaderValue(headers: Record<string, unknown>, name: string) {
8
+ const value = headers[name] ?? headers[name.toLowerCase()];
9
+
10
+ if (Array.isArray(value)) {
11
+ return value[0];
12
+ }
13
+
14
+ return typeof value === "string" ? value : undefined;
15
+ }
16
+
17
+ function getRequestOrigin(input: IAdminForthEndpointHandlerInput) {
18
+ const forwardedProto = getHeaderValue(input.headers, "x-forwarded-proto")?.split(",")[0]?.trim();
19
+ const forwardedHost = getHeaderValue(input.headers, "x-forwarded-host")?.split(",")[0]?.trim();
20
+ const host = forwardedHost ?? getHeaderValue(input.headers, "host");
21
+
22
+ if (!host) {
23
+ return undefined;
24
+ }
25
+
26
+ const proto = forwardedProto
27
+ ?? (host.startsWith("localhost") || host.startsWith("127.0.0.1") ? "http" : "https");
28
+
29
+ return `${proto}://${host}`;
30
+ }
31
+
7
32
  export function setupChatSurfaceEndpoints(ctx: ChatSurfaceEndpointsContext, server: IHttpServer) {
8
33
  for (const adapter of ctx.options.chatSurfaceAdapters ?? []) {
9
34
  server.endpoint({
@@ -21,6 +46,10 @@ export function setupChatSurfaceEndpoints(ctx: ChatSurfaceEndpointsContext, serv
21
46
 
22
47
  const incoming = await adapter.parseIncomingMessage(surfaceContext);
23
48
  if (!incoming) return { ok: true };
49
+ incoming.metadata = {
50
+ ...incoming.metadata,
51
+ adminPublicOrigin: getRequestOrigin(endpointInput),
52
+ };
24
53
 
25
54
  const sink = await adapter.createEventSink(surfaceContext, incoming);
26
55
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adminforth/agent",
3
- "version": "1.49.2",
3
+ "version": "1.50.0",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -33,7 +33,7 @@
33
33
  "@langchain/core": "^1.1.40",
34
34
  "@langchain/langgraph": "^1.2.8",
35
35
  "@langchain/langgraph-checkpoint": "^1.0.1",
36
- "adminforth": "^2.60.0",
36
+ "adminforth": "2.70.0",
37
37
  "dayjs": "^1.11.20",
38
38
  "langchain": "^1.3.3",
39
39
  "multer": "^2.1.1",
@@ -123,6 +123,15 @@ function createAgentEventStream(
123
123
  });
124
124
  },
125
125
 
126
+ openPage(targetPath: string) {
127
+ stream.send({
128
+ type: isAiUiMessageStream ? "data-open-page" : "open-page",
129
+ data: {
130
+ targetPath,
131
+ },
132
+ });
133
+ },
134
+
126
135
  transcript(text: string, language?: string) {
127
136
  stream.send({
128
137
  type: isAiUiMessageStream ? "data-transcript" : "transcript",
@@ -250,6 +259,9 @@ export function createSseEventEmitter(
250
259
  case "rendering":
251
260
  stream.rendering(event.phase, event.label);
252
261
  break;
262
+ case "open-page":
263
+ stream.openPage(event.targetPath);
264
+ break;
253
265
  case "transcript":
254
266
  stream.transcript(event.text, event.language);
255
267
  break;