@adminforth/agent 1.45.0 → 1.45.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/agentTurnService.ts +526 -0
- package/build.log +1 -1
- package/chatSurfaceService.ts +189 -0
- package/dist/agentTurnService.d.ts +70 -0
- package/dist/agentTurnService.js +453 -0
- package/dist/chatSurfaceService.d.ts +29 -0
- package/dist/chatSurfaceService.js +142 -0
- package/dist/endpoints/chatSurfaces.d.ts +3 -0
- package/dist/endpoints/chatSurfaces.js +91 -0
- package/dist/endpoints/context.d.ts +30 -0
- package/dist/endpoints/context.js +1 -0
- package/dist/endpoints/core.d.ts +3 -0
- package/dist/endpoints/core.js +106 -0
- package/dist/endpoints/sessions.d.ts +3 -0
- package/dist/endpoints/sessions.js +177 -0
- package/dist/errors.d.ts +2 -0
- package/dist/errors.js +9 -0
- package/dist/index.d.ts +4 -47
- package/dist/index.js +37 -917
- package/dist/sessionStore.d.ts +19 -0
- package/dist/sessionStore.js +83 -0
- package/endpoints/chatSurfaces.ts +93 -0
- package/endpoints/context.ts +66 -0
- package/endpoints/core.ts +113 -0
- package/endpoints/sessions.ts +183 -0
- package/errors.ts +10 -0
- package/index.ts +47 -1053
- package/package.json +1 -1
- package/sessionStore.ts +94 -0
- package/agentResponseEvents.ts +0 -1
- package/dist/agentResponseEvents.d.ts +0 -1
- package/dist/agentResponseEvents.js +0 -1
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
const DEFAULT_ADMIN_USER_EXTERNAL_USER_ID_FIELD = "externalUserId";
|
|
11
|
+
export function setupChatSurfaceEndpoints(ctx, server) {
|
|
12
|
+
var _a;
|
|
13
|
+
if (ctx.getChatSurfaceConnectActionAdapters().length) {
|
|
14
|
+
server.endpoint({
|
|
15
|
+
method: "POST",
|
|
16
|
+
path: "/agent/surfaces/connectable",
|
|
17
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ adminUser }) {
|
|
18
|
+
var _b, _c;
|
|
19
|
+
const externalUserIdField = (_b = ctx.options.chatExternalIdsField) !== null && _b !== void 0 ? _b : DEFAULT_ADMIN_USER_EXTERNAL_USER_ID_FIELD;
|
|
20
|
+
const externalIds = (_c = adminUser.dbUser[externalUserIdField]) !== null && _c !== void 0 ? _c : {};
|
|
21
|
+
return {
|
|
22
|
+
surfaces: ctx.getChatSurfaceConnectActionAdapters().map((adapter) => {
|
|
23
|
+
var _a;
|
|
24
|
+
return ({
|
|
25
|
+
name: adapter.name,
|
|
26
|
+
externalUserId: (_a = externalIds[adapter.name]) !== null && _a !== void 0 ? _a : null,
|
|
27
|
+
});
|
|
28
|
+
}),
|
|
29
|
+
};
|
|
30
|
+
}),
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
for (const adapter of (_a = ctx.options.chatSurfaceAdapters) !== null && _a !== void 0 ? _a : []) {
|
|
34
|
+
const connectActionAdapter = adapter;
|
|
35
|
+
if (connectActionAdapter.createConnectAction) {
|
|
36
|
+
server.endpoint({
|
|
37
|
+
method: "POST",
|
|
38
|
+
path: `/agent/surface/${adapter.name}/connect-action`,
|
|
39
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ adminUser }) {
|
|
40
|
+
const token = ctx.createChatSurfaceLinkToken(adapter.name, adminUser);
|
|
41
|
+
const action = yield connectActionAdapter.createConnectAction({ token });
|
|
42
|
+
return {
|
|
43
|
+
action,
|
|
44
|
+
};
|
|
45
|
+
}),
|
|
46
|
+
});
|
|
47
|
+
server.endpoint({
|
|
48
|
+
method: "POST",
|
|
49
|
+
path: `/agent/surface/${adapter.name}/disconnect`,
|
|
50
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ adminUser }) {
|
|
51
|
+
var _b, _c;
|
|
52
|
+
const externalUserIdField = (_b = ctx.options.chatExternalIdsField) !== null && _b !== void 0 ? _b : DEFAULT_ADMIN_USER_EXTERNAL_USER_ID_FIELD;
|
|
53
|
+
const externalIds = Object.assign({}, ((_c = adminUser.dbUser[externalUserIdField]) !== null && _c !== void 0 ? _c : {}));
|
|
54
|
+
delete externalIds[adapter.name];
|
|
55
|
+
yield ctx.adminforth.resource(ctx.adminforth.config.auth.usersResourceId).update(adminUser.pk, {
|
|
56
|
+
[externalUserIdField]: externalIds,
|
|
57
|
+
});
|
|
58
|
+
return {
|
|
59
|
+
ok: true,
|
|
60
|
+
};
|
|
61
|
+
}),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
server.endpoint({
|
|
65
|
+
method: "POST",
|
|
66
|
+
noAuth: true,
|
|
67
|
+
path: `/agent/surface/${adapter.name}/webhook`,
|
|
68
|
+
handler: (endpointInput) => __awaiter(this, void 0, void 0, function* () {
|
|
69
|
+
var _a;
|
|
70
|
+
const surfaceContext = {
|
|
71
|
+
body: endpointInput.body,
|
|
72
|
+
headers: endpointInput.headers,
|
|
73
|
+
abortSignal: endpointInput.abortSignal,
|
|
74
|
+
rawRequest: endpointInput._raw_express_req,
|
|
75
|
+
rawResponse: endpointInput._raw_express_res,
|
|
76
|
+
};
|
|
77
|
+
const incoming = yield adapter.parseIncomingMessage(surfaceContext);
|
|
78
|
+
if (!incoming)
|
|
79
|
+
return { ok: true };
|
|
80
|
+
const sink = yield adapter.createEventSink(surfaceContext, incoming);
|
|
81
|
+
try {
|
|
82
|
+
yield ctx.handleChatSurfaceMessage(adapter, incoming, sink);
|
|
83
|
+
}
|
|
84
|
+
finally {
|
|
85
|
+
yield ((_a = sink.close) === null || _a === void 0 ? void 0 : _a.call(sink));
|
|
86
|
+
}
|
|
87
|
+
return { ok: true };
|
|
88
|
+
}),
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { AdminUser, ChatSurfaceAdapter, ChatSurfaceEventSink, ChatSurfaceIncomingMessage, IAdminForth } from "adminforth";
|
|
2
|
+
import type { ZodType } from "zod";
|
|
3
|
+
import type { HandleSpeechTurnInput, HandleTurnInput, RunAndPersistAgentResponseInput, RunAndPersistAgentResponseResult } from "../agentTurnService.js";
|
|
4
|
+
import type { ChatSurfaceAdapterWithConnectAction } from "../chatSurfaceService.js";
|
|
5
|
+
import type { PluginOptions } from "../types.js";
|
|
6
|
+
export type { ChatSurfaceAdapterWithConnectAction } from "../chatSurfaceService.js";
|
|
7
|
+
export type EndpointResponse = {
|
|
8
|
+
setStatus: (code: number, message: string) => void;
|
|
9
|
+
};
|
|
10
|
+
export type SessionTurn = {
|
|
11
|
+
prompt: string;
|
|
12
|
+
response: string;
|
|
13
|
+
};
|
|
14
|
+
export type AgentEndpointsContext = {
|
|
15
|
+
adminforth: IAdminForth;
|
|
16
|
+
options: PluginOptions;
|
|
17
|
+
parseBody<T>(schema: ZodType<T>, body: unknown, response: EndpointResponse): T | null;
|
|
18
|
+
handleTurn(input: HandleTurnInput): Promise<RunAndPersistAgentResponseResult>;
|
|
19
|
+
handleSpeechTurn(input: HandleSpeechTurnInput): Promise<RunAndPersistAgentResponseResult | null>;
|
|
20
|
+
runAndPersistAgentResponse(input: RunAndPersistAgentResponseInput): Promise<RunAndPersistAgentResponseResult>;
|
|
21
|
+
getSessionTurns(sessionId: string): Promise<SessionTurn[]>;
|
|
22
|
+
createNewTurn(sessionId: string, prompt: string, response?: string): Promise<string>;
|
|
23
|
+
createSystemTurn(sessionId: string, systemMessage: string): Promise<string>;
|
|
24
|
+
getChatSurfaceConnectActionAdapters(): ChatSurfaceAdapterWithConnectAction[];
|
|
25
|
+
createChatSurfaceLinkToken(surface: string, adminUser: AdminUser): string;
|
|
26
|
+
handleChatSurfaceMessage(adapter: ChatSurfaceAdapter, incoming: ChatSurfaceIncomingMessage, sink: ChatSurfaceEventSink): Promise<void>;
|
|
27
|
+
};
|
|
28
|
+
export type CoreEndpointsContext = Pick<AgentEndpointsContext, "options" | "parseBody" | "handleTurn" | "handleSpeechTurn">;
|
|
29
|
+
export type SessionEndpointsContext = Pick<AgentEndpointsContext, "adminforth" | "options" | "parseBody" | "getSessionTurns" | "createNewTurn" | "createSystemTurn">;
|
|
30
|
+
export type ChatSurfaceEndpointsContext = Pick<AgentEndpointsContext, "adminforth" | "options" | "getChatSurfaceConnectActionAdapters" | "createChatSurfaceLinkToken" | "handleChatSurfaceMessage">;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
import { createSseEventEmitter } from "../surfaces/web-sse/createSseEventEmitter.js";
|
|
12
|
+
const agentResponseBodySchema = z.object({
|
|
13
|
+
message: z.string(),
|
|
14
|
+
sessionId: z.string(),
|
|
15
|
+
mode: z.string().nullish(),
|
|
16
|
+
timeZone: z.string().optional(),
|
|
17
|
+
currentPage: z.custom().optional(),
|
|
18
|
+
}).strict();
|
|
19
|
+
const agentSpeechResponseBodySchema = agentResponseBodySchema.omit({ message: true });
|
|
20
|
+
export function setupCoreEndpoints(ctx, server) {
|
|
21
|
+
server.endpoint({
|
|
22
|
+
method: 'POST',
|
|
23
|
+
path: `/agent/get-placeholder-messages`,
|
|
24
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ headers, adminUser }) {
|
|
25
|
+
if (!ctx.options.placeholderMessages) {
|
|
26
|
+
return {
|
|
27
|
+
messages: [],
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
const messages = yield ctx.options.placeholderMessages({
|
|
31
|
+
adminUser: adminUser,
|
|
32
|
+
headers,
|
|
33
|
+
});
|
|
34
|
+
return {
|
|
35
|
+
messages,
|
|
36
|
+
};
|
|
37
|
+
})
|
|
38
|
+
});
|
|
39
|
+
server.endpoint({
|
|
40
|
+
method: 'POST',
|
|
41
|
+
path: `/agent/response`,
|
|
42
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, response, _raw_express_res, abortSignal }) {
|
|
43
|
+
var _b;
|
|
44
|
+
const data = ctx.parseBody(agentResponseBodySchema, body, response);
|
|
45
|
+
if (!data)
|
|
46
|
+
return;
|
|
47
|
+
const emit = createSseEventEmitter(_raw_express_res, {
|
|
48
|
+
vercelAiUiMessageStream: true,
|
|
49
|
+
closeActiveBlockOnToolStart: true,
|
|
50
|
+
});
|
|
51
|
+
yield ctx.handleTurn({
|
|
52
|
+
prompt: data.message,
|
|
53
|
+
sessionId: data.sessionId,
|
|
54
|
+
modeName: data.mode,
|
|
55
|
+
userTimeZone: (_b = data.timeZone) !== null && _b !== void 0 ? _b : 'UTC',
|
|
56
|
+
currentPage: data.currentPage,
|
|
57
|
+
abortSignal,
|
|
58
|
+
adminUser: adminUser,
|
|
59
|
+
emit,
|
|
60
|
+
failureLogMessage: "Agent response streaming failed",
|
|
61
|
+
abortLogMessage: "Agent response streaming aborted by the client",
|
|
62
|
+
});
|
|
63
|
+
return null;
|
|
64
|
+
})
|
|
65
|
+
});
|
|
66
|
+
server.endpoint({
|
|
67
|
+
method: 'POST',
|
|
68
|
+
path: `/agent/speech-response`,
|
|
69
|
+
target: 'upload',
|
|
70
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, response, _raw_express_req, _raw_express_res, abortSignal }) {
|
|
71
|
+
var _b;
|
|
72
|
+
const req = _raw_express_req;
|
|
73
|
+
const audioAdapter = ctx.options.audioAdapter;
|
|
74
|
+
if (!audioAdapter) {
|
|
75
|
+
response.setStatus(400, "Audio adapter is not configured for AdminForth Agent");
|
|
76
|
+
return { error: "Audio adapter is not configured for AdminForth Agent" };
|
|
77
|
+
}
|
|
78
|
+
const data = ctx.parseBody(agentSpeechResponseBodySchema, body, response);
|
|
79
|
+
if (!data)
|
|
80
|
+
return;
|
|
81
|
+
if (!req.file) {
|
|
82
|
+
response.setStatus(400, "Audio file is required");
|
|
83
|
+
return { error: "Audio file is required" };
|
|
84
|
+
}
|
|
85
|
+
const emit = createSseEventEmitter(_raw_express_res);
|
|
86
|
+
yield ctx.handleSpeechTurn({
|
|
87
|
+
audioAdapter,
|
|
88
|
+
audio: {
|
|
89
|
+
buffer: req.file.buffer,
|
|
90
|
+
filename: req.file.originalname,
|
|
91
|
+
mimeType: req.file.mimetype,
|
|
92
|
+
},
|
|
93
|
+
sessionId: data.sessionId,
|
|
94
|
+
modeName: data.mode,
|
|
95
|
+
userTimeZone: (_b = data.timeZone) !== null && _b !== void 0 ? _b : 'UTC',
|
|
96
|
+
currentPage: data.currentPage,
|
|
97
|
+
abortSignal,
|
|
98
|
+
adminUser: adminUser,
|
|
99
|
+
emit,
|
|
100
|
+
failureLogMessage: "Agent speech response failed",
|
|
101
|
+
abortLogMessage: "Agent speech response aborted by the client",
|
|
102
|
+
});
|
|
103
|
+
return null;
|
|
104
|
+
})
|
|
105
|
+
});
|
|
106
|
+
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { Filters, Sorts } from "adminforth";
|
|
11
|
+
import { randomUUID } from "crypto";
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
import { AGENT_SYSTEM_TURN_PROMPT } from "../sessionStore.js";
|
|
14
|
+
const addSystemMessageBodySchema = z.object({
|
|
15
|
+
sessionId: z.string(),
|
|
16
|
+
systemMessage: z.string(),
|
|
17
|
+
}).strict();
|
|
18
|
+
const getSessionsBodySchema = z.object({
|
|
19
|
+
limit: z.number().int().min(1).max(100).optional(),
|
|
20
|
+
}).strict();
|
|
21
|
+
const sessionIdBodySchema = z.object({
|
|
22
|
+
sessionId: z.string(),
|
|
23
|
+
}).strict();
|
|
24
|
+
const createSessionBodySchema = z.object({
|
|
25
|
+
triggerMessage: z.string().optional(),
|
|
26
|
+
}).strict();
|
|
27
|
+
export function setupSessionEndpoints(ctx, server) {
|
|
28
|
+
server.endpoint({
|
|
29
|
+
method: 'POST',
|
|
30
|
+
path: `/agent/get-sessions`,
|
|
31
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, response }) {
|
|
32
|
+
var _b;
|
|
33
|
+
const data = ctx.parseBody(getSessionsBodySchema, body, response);
|
|
34
|
+
if (!data)
|
|
35
|
+
return;
|
|
36
|
+
const userId = adminUser.pk;
|
|
37
|
+
const limit = (_b = data.limit) !== null && _b !== void 0 ? _b : 20;
|
|
38
|
+
const sessions = yield ctx.adminforth.resource(ctx.options.sessionResource.resourceId).list([Filters.EQ(ctx.options.sessionResource.askerIdField, userId)], limit, undefined, [Sorts.DESC(ctx.options.sessionResource.createdAtField)]);
|
|
39
|
+
return {
|
|
40
|
+
sessions: sessions.map((session) => ({
|
|
41
|
+
sessionId: session[ctx.options.sessionResource.idField],
|
|
42
|
+
title: session[ctx.options.sessionResource.titleField],
|
|
43
|
+
timestamp: session[ctx.options.sessionResource.createdAtField],
|
|
44
|
+
})),
|
|
45
|
+
};
|
|
46
|
+
})
|
|
47
|
+
});
|
|
48
|
+
server.endpoint({
|
|
49
|
+
method: 'POST',
|
|
50
|
+
path: `/agent/get-session-info`,
|
|
51
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, response }) {
|
|
52
|
+
const data = ctx.parseBody(sessionIdBodySchema, body, response);
|
|
53
|
+
if (!data)
|
|
54
|
+
return;
|
|
55
|
+
const userId = adminUser.pk;
|
|
56
|
+
const sessionId = data.sessionId;
|
|
57
|
+
const session = yield ctx.adminforth.resource(ctx.options.sessionResource.resourceId).get([Filters.EQ(ctx.options.sessionResource.idField, sessionId)]);
|
|
58
|
+
if (!session) {
|
|
59
|
+
return {
|
|
60
|
+
error: 'Session not found'
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
if (session[ctx.options.sessionResource.askerIdField] !== userId) {
|
|
64
|
+
return {
|
|
65
|
+
error: 'Unauthorized'
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
const turns = yield ctx.getSessionTurns(sessionId);
|
|
69
|
+
return {
|
|
70
|
+
session: {
|
|
71
|
+
sessionId,
|
|
72
|
+
title: session[ctx.options.sessionResource.titleField],
|
|
73
|
+
timestamp: session[ctx.options.sessionResource.createdAtField],
|
|
74
|
+
messages: turns.flatMap(turn => {
|
|
75
|
+
const messages = [];
|
|
76
|
+
if (turn.prompt === AGENT_SYSTEM_TURN_PROMPT) {
|
|
77
|
+
messages.push({
|
|
78
|
+
text: turn.response,
|
|
79
|
+
role: 'system',
|
|
80
|
+
});
|
|
81
|
+
return messages;
|
|
82
|
+
}
|
|
83
|
+
if (turn.prompt) {
|
|
84
|
+
messages.push({
|
|
85
|
+
text: turn.prompt,
|
|
86
|
+
role: 'user',
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
if (turn.response && turn.response !== "not_finished") {
|
|
90
|
+
messages.push({
|
|
91
|
+
text: turn.response,
|
|
92
|
+
role: 'assistant',
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
return messages;
|
|
96
|
+
}),
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
})
|
|
100
|
+
});
|
|
101
|
+
server.endpoint({
|
|
102
|
+
method: 'POST',
|
|
103
|
+
path: `/agent/create-session`,
|
|
104
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, response }) {
|
|
105
|
+
const data = ctx.parseBody(createSessionBodySchema, body, response);
|
|
106
|
+
if (!data)
|
|
107
|
+
return;
|
|
108
|
+
const triggerMessage = data.triggerMessage;
|
|
109
|
+
const userId = adminUser.pk;
|
|
110
|
+
const title = (triggerMessage === null || triggerMessage === void 0 ? void 0 : triggerMessage.slice(0, 40)) || "New Session";
|
|
111
|
+
const newSession = {
|
|
112
|
+
[ctx.options.sessionResource.idField]: randomUUID(),
|
|
113
|
+
[ctx.options.sessionResource.titleField]: title,
|
|
114
|
+
[ctx.options.sessionResource.askerIdField]: userId,
|
|
115
|
+
};
|
|
116
|
+
const { createdRecord } = yield ctx.adminforth.resource(ctx.options.sessionResource.resourceId).create(newSession);
|
|
117
|
+
return {
|
|
118
|
+
sessionId: createdRecord[ctx.options.sessionResource.idField],
|
|
119
|
+
title: createdRecord[ctx.options.sessionResource.titleField],
|
|
120
|
+
timestamp: createdRecord[ctx.options.sessionResource.createdAtField],
|
|
121
|
+
messages: []
|
|
122
|
+
};
|
|
123
|
+
})
|
|
124
|
+
});
|
|
125
|
+
server.endpoint({
|
|
126
|
+
method: 'POST',
|
|
127
|
+
path: `/agent/delete-session`,
|
|
128
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, response }) {
|
|
129
|
+
const data = ctx.parseBody(sessionIdBodySchema, body, response);
|
|
130
|
+
if (!data)
|
|
131
|
+
return;
|
|
132
|
+
const sessionId = data.sessionId;
|
|
133
|
+
const userId = adminUser.pk;
|
|
134
|
+
const session = yield ctx.adminforth.resource(ctx.options.sessionResource.resourceId).get([Filters.EQ(ctx.options.sessionResource.idField, sessionId)]);
|
|
135
|
+
if (!session) {
|
|
136
|
+
return {
|
|
137
|
+
error: 'Session not found'
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
if (session[ctx.options.sessionResource.askerIdField] !== userId) {
|
|
141
|
+
return {
|
|
142
|
+
error: 'Unauthorized'
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
yield ctx.adminforth.resource(ctx.options.sessionResource.resourceId).delete(sessionId);
|
|
146
|
+
const turns = yield ctx.adminforth.resource(ctx.options.turnResource.resourceId).list([Filters.EQ(ctx.options.turnResource.sessionIdField, sessionId)]);
|
|
147
|
+
yield Promise.all(turns.map(turn => ctx.adminforth.resource(ctx.options.turnResource.resourceId).delete(turn[ctx.options.turnResource.idField])));
|
|
148
|
+
return {
|
|
149
|
+
ok: true
|
|
150
|
+
};
|
|
151
|
+
})
|
|
152
|
+
});
|
|
153
|
+
server.endpoint({
|
|
154
|
+
method: 'POST',
|
|
155
|
+
path: `/agent/add-system-message-to-turns`,
|
|
156
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, response }) {
|
|
157
|
+
const data = ctx.parseBody(addSystemMessageBodySchema, body, response);
|
|
158
|
+
if (!data)
|
|
159
|
+
return;
|
|
160
|
+
const session = yield ctx.adminforth.resource(ctx.options.sessionResource.resourceId).get([Filters.EQ(ctx.options.sessionResource.idField, data.sessionId)]);
|
|
161
|
+
if (!session) {
|
|
162
|
+
return {
|
|
163
|
+
error: 'Session not found'
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
if (session[ctx.options.sessionResource.askerIdField] !== adminUser.pk) {
|
|
167
|
+
return {
|
|
168
|
+
error: 'Unauthorized'
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
yield ctx.createSystemTurn(data.sessionId, data.systemMessage);
|
|
172
|
+
return {
|
|
173
|
+
ok: true
|
|
174
|
+
};
|
|
175
|
+
})
|
|
176
|
+
});
|
|
177
|
+
}
|
package/dist/errors.d.ts
ADDED
package/dist/errors.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export function isAbortError(error) {
|
|
2
|
+
return typeof error === "object" &&
|
|
3
|
+
error !== null &&
|
|
4
|
+
"name" in error &&
|
|
5
|
+
(error.name === "AbortError" || error.name === "APIUserAbortError");
|
|
6
|
+
}
|
|
7
|
+
export function getErrorMessage(error) {
|
|
8
|
+
return error instanceof Error ? error.message : String(error);
|
|
9
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,64 +1,21 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AdminForthResource, IAdminForth, IHttpServer } from "adminforth";
|
|
2
2
|
import { AdminForthPlugin } from "adminforth";
|
|
3
3
|
import type { PluginOptions } from './types.js';
|
|
4
|
-
import { createSequenceDebugCollector } from "./agent/middleware/sequenceDebug.js";
|
|
5
|
-
import { type PreviousUserMessage } from "./agent/languageDetect.js";
|
|
6
|
-
import type { AgentEventEmitter } from "./agentEvents.js";
|
|
7
|
-
import type { CurrentPageContext } from "./agent/tools/getUserLocation.js";
|
|
8
4
|
export type { AgentEvent, AgentEventEmitter } from "./agentEvents.js";
|
|
9
|
-
type AgentTurnRunInput = {
|
|
10
|
-
prompt: string;
|
|
11
|
-
sessionId: string;
|
|
12
|
-
turnId: string;
|
|
13
|
-
previousUserMessages: PreviousUserMessage[];
|
|
14
|
-
modeName?: string | null;
|
|
15
|
-
userTimeZone: string;
|
|
16
|
-
currentPage?: CurrentPageContext;
|
|
17
|
-
abortSignal?: AbortSignal;
|
|
18
|
-
adminUser: AdminUser;
|
|
19
|
-
sequenceDebugCollector: ReturnType<typeof createSequenceDebugCollector>;
|
|
20
|
-
emit?: AgentEventEmitter;
|
|
21
|
-
};
|
|
22
|
-
type RunAndPersistAgentResponseInput = Omit<AgentTurnRunInput, "turnId" | "sequenceDebugCollector" | "previousUserMessages"> & {
|
|
23
|
-
failureLogMessage: string;
|
|
24
|
-
abortLogMessage: string;
|
|
25
|
-
};
|
|
26
|
-
type HandleTurnInput = Omit<RunAndPersistAgentResponseInput, "failureLogMessage" | "abortLogMessage"> & {
|
|
27
|
-
emit: AgentEventEmitter;
|
|
28
|
-
failureLogMessage?: string;
|
|
29
|
-
abortLogMessage?: string;
|
|
30
|
-
};
|
|
31
5
|
export default class AdminForthAgentPlugin extends AdminForthPlugin {
|
|
32
6
|
options: PluginOptions;
|
|
33
7
|
agentSystemPromptPromise: Promise<string>;
|
|
34
8
|
private checkpointer;
|
|
35
|
-
private
|
|
9
|
+
private sessionStore;
|
|
10
|
+
private agentTurnService;
|
|
11
|
+
private chatSurfaceService;
|
|
36
12
|
private chatSurfaceSettingsPageRegistered;
|
|
37
13
|
private parseBody;
|
|
38
|
-
private createNewTurn;
|
|
39
|
-
private getSessionTurns;
|
|
40
|
-
private getPreviousUserMessages;
|
|
41
|
-
private getChatSurfaceSessionId;
|
|
42
|
-
private getOrCreateChatSurfaceSession;
|
|
43
14
|
private getCheckpointer;
|
|
44
15
|
private getInternalAgentResourceIds;
|
|
45
|
-
private getChatSurfaceConnectActionAdapters;
|
|
46
16
|
constructor(options: PluginOptions);
|
|
47
17
|
modifyResourceConfig(adminforth: IAdminForth, resourceConfig: AdminForthResource): Promise<void>;
|
|
48
18
|
validateConfigAfterDiscover(adminforth: IAdminForth, resourceConfig: AdminForthResource): void;
|
|
49
19
|
instanceUniqueRepresentation(pluginOptions: any): string;
|
|
50
|
-
private runAgentTurn;
|
|
51
|
-
private runAndPersistAgentResponse;
|
|
52
|
-
handleTurn(input: HandleTurnInput): Promise<{
|
|
53
|
-
text: string;
|
|
54
|
-
turnId: any;
|
|
55
|
-
aborted: boolean;
|
|
56
|
-
failed: boolean;
|
|
57
|
-
}>;
|
|
58
|
-
private createChatSurfaceEventEmitter;
|
|
59
|
-
private createChatSurfaceLinkToken;
|
|
60
|
-
private consumeChatSurfaceLinkToken;
|
|
61
|
-
private handleChatSurfaceLink;
|
|
62
|
-
private handleChatSurfaceMessage;
|
|
63
20
|
setupEndpoints(server: IHttpServer): void;
|
|
64
21
|
}
|