@adminforth/agent 1.49.3 → 1.50.1
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/middleware/sequenceDebug.ts +42 -7
- package/agent/simpleAgent.ts +15 -0
- package/agent/systemPrompt.ts +6 -1
- package/agent/tools/index.ts +2 -0
- package/agent/tools/navigateUser.ts +210 -0
- package/agentEvents.ts +4 -0
- package/agentTurnService.ts +14 -0
- package/build.log +2 -2
- package/chatSurfaceService.ts +7 -0
- package/custom/composables/agentStore/useAgentChat.ts +8 -1
- package/custom/composables/useAgentAudio.ts +5 -0
- package/custom/composables/useAgentStore.ts +43 -0
- package/custom/skills/fetch_data/SKILL.md +2 -0
- package/custom/skills/mutate_data/SKILL.md +4 -0
- package/custom/tsconfig.json +0 -1
- package/custom/types.ts +6 -0
- package/dist/agent/middleware/sequenceDebug.d.ts +6 -0
- package/dist/agent/middleware/sequenceDebug.js +33 -6
- package/dist/agent/simpleAgent.d.ts +8 -0
- package/dist/agent/simpleAgent.js +9 -1
- package/dist/agent/systemPrompt.d.ts +1 -0
- package/dist/agent/systemPrompt.js +5 -1
- package/dist/agent/tools/index.js +2 -0
- package/dist/agent/tools/navigateUser.d.ts +55 -0
- package/dist/agent/tools/navigateUser.js +163 -0
- package/dist/agentEvents.d.ts +3 -0
- package/dist/agentTurnService.d.ts +2 -0
- package/dist/agentTurnService.js +10 -0
- package/dist/chatSurfaceService.js +10 -3
- package/dist/custom/composables/agentStore/useAgentChat.ts +8 -1
- package/dist/custom/composables/useAgentAudio.ts +5 -0
- package/dist/custom/composables/useAgentStore.ts +43 -0
- package/dist/custom/skills/fetch_data/SKILL.md +2 -0
- package/dist/custom/skills/mutate_data/SKILL.md +4 -0
- package/dist/custom/tsconfig.json +0 -1
- package/dist/custom/types.ts +6 -0
- package/dist/endpoints/chatSurfaces.js +20 -0
- package/dist/surfaces/web-sse/createSseEventEmitter.js +11 -0
- package/endpoints/chatSurfaces.ts +29 -0
- package/package.json +1 -1
- 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
|
}
|
|
@@ -24,6 +24,8 @@ If several rows look similar, do not guess which one is "the same" record. Show
|
|
|
24
24
|
|
|
25
25
|
For long texts show only several first words and add "..." at the end (only if user did not request this field specifically).
|
|
26
26
|
|
|
27
|
+
Never show information about more than 10 records in one message. If a tool returns more than 10 relevant records, summarize the total count if known, show only the 10 most relevant records, and offer to narrow filters, sort differently, or continue with the next 10.
|
|
28
|
+
|
|
27
29
|
Also when you communicate with user about record, add related link to this record. Build it as `{ADMIN_BASE_PATH}resource/{resourceId}/show/{primary key}`. Use _label from `get_resource_data` as anchor text for link (use markdown link). Links should always be relative paths and must start with `ADMIN_BASE_PATH`. Do not add an extra slash after `ADMIN_BASE_PATH`.
|
|
28
30
|
|
|
29
31
|
Before sending the link, verify that the `resourceId`, `{primary key}`, `_label`, and shown fields come from the same exact returned row.
|
|
@@ -27,6 +27,8 @@ Also please add related link to record with will be changed. Build it as `{ADMIN
|
|
|
27
27
|
|
|
28
28
|
Before sending the confirmation, verify that the `resourceId`, `{primary key}`, `_label`, and all shown fields come from the same exact fetched row.
|
|
29
29
|
|
|
30
|
+
Never show information about more than 10 records in one message. If a mutation plan affects more than 10 records, show only the 10 most important examples plus the total count if known, and ask the user to confirm the clearly described full batch.
|
|
31
|
+
|
|
30
32
|
And in the same message ask user for final confirmation.
|
|
31
33
|
|
|
32
34
|
When creating new record, show user all data which you gona create and in same message ask for confirmation.
|
|
@@ -123,6 +125,8 @@ For decimal fields please use string values with dot as decimal separator.
|
|
|
123
125
|
|
|
124
126
|
After creation of new record also show user a link to this record. If several records record were created, show links to all of them in list.
|
|
125
127
|
|
|
128
|
+
If more than 10 records were created, show links or details for only 10 of them and summarize the remaining count.
|
|
129
|
+
|
|
126
130
|
Omit any pictures or file paths, you are not capable of doing it. If they are not required all is good, if they are required, explain to user that you are not able to create record because of this reason.
|
|
127
131
|
|
|
128
132
|
### Working with dates
|
package/dist/custom/types.ts
CHANGED
|
@@ -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
|
@@ -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;
|