@adminforth/agent 1.51.1 → 1.52.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/middleware/apiBasedTools.ts +31 -25
- package/agent/runtime/AgentRuntime.ts +24 -3
- package/agent/systemPrompt.ts +3 -6
- package/agent/turn/TurnLifecycleService.ts +18 -0
- package/agent/turn/TurnStreamConsumer.ts +11 -3
- package/agent/turn/turnTypes.ts +9 -1
- package/agentEvents.ts +5 -0
- package/agentTurnService.ts +158 -12
- package/apiBasedTools.ts +7 -0
- package/build.log +3 -2
- package/custom/ChatFooter.vue +3 -2
- package/custom/composables/agentStore/useAgentChat.ts +169 -6
- package/custom/composables/agentStore/useAgentSessions.ts +3 -1
- package/custom/composables/useAgentStore.ts +87 -0
- package/custom/conversation_area/MessageRenderer.vue +6 -1
- package/custom/conversation_area/ToolApprovalRenderer.vue +98 -0
- package/custom/skills/mutate_data/SKILL.md +10 -36
- package/custom/types.ts +4 -1
- package/dist/agent/middleware/apiBasedTools.js +26 -25
- package/dist/agent/runtime/AgentRuntime.d.ts +1 -1
- package/dist/agent/runtime/AgentRuntime.js +18 -3
- package/dist/agent/systemPrompt.js +3 -6
- package/dist/agent/turn/TurnLifecycleService.d.ts +8 -1
- package/dist/agent/turn/TurnLifecycleService.js +17 -1
- package/dist/agent/turn/TurnStreamConsumer.d.ts +2 -1
- package/dist/agent/turn/TurnStreamConsumer.js +14 -8
- package/dist/agent/turn/turnTypes.d.ts +14 -1
- package/dist/agentEvents.d.ts +4 -0
- package/dist/agentTurnService.d.ts +1 -0
- package/dist/agentTurnService.js +132 -14
- package/dist/apiBasedTools.d.ts +5 -0
- package/dist/apiBasedTools.js +1 -0
- package/dist/custom/ChatFooter.vue +3 -2
- package/dist/custom/composables/agentStore/useAgentChat.ts +169 -6
- package/dist/custom/composables/agentStore/useAgentSessions.ts +3 -1
- package/dist/custom/composables/useAgentStore.ts +87 -0
- package/dist/custom/conversation_area/MessageRenderer.vue +6 -1
- package/dist/custom/conversation_area/ToolApprovalRenderer.vue +98 -0
- package/dist/custom/skills/mutate_data/SKILL.md +10 -36
- package/dist/custom/types.ts +4 -1
- package/dist/endpoints/core.js +28 -0
- package/dist/index.js +1 -1
- package/dist/sessionStore.d.ts +1 -0
- package/dist/sessionStore.js +6 -0
- package/dist/surfaces/web-sse/createSseEventEmitter.js +13 -0
- package/endpoints/core.ts +30 -0
- package/index.ts +1 -1
- package/package.json +3 -6
- package/sessionStore.ts +11 -0
- package/surfaces/web-sse/createSseEventEmitter.ts +14 -0
package/dist/sessionStore.js
CHANGED
|
@@ -61,6 +61,12 @@ export class AgentSessionStore {
|
|
|
61
61
|
}));
|
|
62
62
|
});
|
|
63
63
|
}
|
|
64
|
+
getLatestTurn(sessionId) {
|
|
65
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
66
|
+
const turns = yield this.getAdminforth().resource(this.options.turnResource.resourceId).list([Filters.EQ(this.options.turnResource.sessionIdField, sessionId)], 1, undefined, [Sorts.DESC(this.options.turnResource.createdAtField)]);
|
|
67
|
+
return turns[0];
|
|
68
|
+
});
|
|
69
|
+
}
|
|
64
70
|
getChatSurfaceSessionId(incoming) {
|
|
65
71
|
return `${incoming.surface}:${incoming.externalConversationId}`;
|
|
66
72
|
}
|
|
@@ -88,6 +88,16 @@ function createAgentEventStream(res, options = {}) {
|
|
|
88
88
|
},
|
|
89
89
|
});
|
|
90
90
|
},
|
|
91
|
+
interrupt(sessionId, interrupt) {
|
|
92
|
+
stream.endActiveBlock();
|
|
93
|
+
stream.send({
|
|
94
|
+
type: isAiUiMessageStream ? "data-interrupt" : "interrupt",
|
|
95
|
+
data: {
|
|
96
|
+
sessionId,
|
|
97
|
+
interrupt,
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
},
|
|
91
101
|
openPage(targetPath) {
|
|
92
102
|
stream.send({
|
|
93
103
|
type: isAiUiMessageStream ? "data-open-page" : "open-page",
|
|
@@ -194,6 +204,9 @@ export function createSseEventEmitter(res, options = {}) {
|
|
|
194
204
|
case "rendering":
|
|
195
205
|
stream.rendering(event.phase, event.label);
|
|
196
206
|
break;
|
|
207
|
+
case "interrupt":
|
|
208
|
+
stream.interrupt(event.sessionId, event.interrupt);
|
|
209
|
+
break;
|
|
197
210
|
case "open-page":
|
|
198
211
|
stream.openPage(event.targetPath);
|
|
199
212
|
break;
|
package/endpoints/core.ts
CHANGED
|
@@ -20,6 +20,11 @@ const agentResponseBodySchema = z.object({
|
|
|
20
20
|
currentPage: z.custom<CurrentPageContext>().optional(),
|
|
21
21
|
}).strict();
|
|
22
22
|
|
|
23
|
+
const agentApprovalBodySchema = z.object({
|
|
24
|
+
sessionId: z.string(),
|
|
25
|
+
decision: z.enum(["approve", "reject"]),
|
|
26
|
+
}).strict();
|
|
27
|
+
|
|
23
28
|
const agentSpeechResponseBodySchema = agentResponseBodySchema.omit({ message: true });
|
|
24
29
|
|
|
25
30
|
export function setupCoreEndpoints(ctx: CoreEndpointsContext, server: IHttpServer) {
|
|
@@ -71,6 +76,31 @@ export function setupCoreEndpoints(ctx: CoreEndpointsContext, server: IHttpServe
|
|
|
71
76
|
}
|
|
72
77
|
});
|
|
73
78
|
|
|
79
|
+
server.endpoint({
|
|
80
|
+
method: 'POST',
|
|
81
|
+
path: `/agent/approval`,
|
|
82
|
+
handler: async ({ body, adminUser, response, _raw_express_res, abortSignal }) => {
|
|
83
|
+
const data = ctx.parseBody(agentApprovalBodySchema, body, response);
|
|
84
|
+
if (!data) return;
|
|
85
|
+
const emit = createSseEventEmitter(_raw_express_res, {
|
|
86
|
+
vercelAiUiMessageStream: true,
|
|
87
|
+
closeActiveBlockOnToolStart: true,
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
await ctx.handleTurn({
|
|
91
|
+
prompt: "",
|
|
92
|
+
sessionId: data.sessionId,
|
|
93
|
+
approvalDecision: data.decision,
|
|
94
|
+
abortSignal,
|
|
95
|
+
adminUser: adminUser!,
|
|
96
|
+
emit,
|
|
97
|
+
failureLogMessage: "Agent approval response streaming failed",
|
|
98
|
+
abortLogMessage: "Agent approval response streaming aborted by the client",
|
|
99
|
+
});
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
|
|
74
104
|
server.endpoint({
|
|
75
105
|
method: 'POST',
|
|
76
106
|
path: `/agent/speech-response`,
|
package/index.ts
CHANGED
|
@@ -85,7 +85,7 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
|
|
|
85
85
|
});
|
|
86
86
|
const persistence = new TurnPersistenceService(() => this.adminforth, this.options);
|
|
87
87
|
this.agentTurnService = new AgentTurnService(
|
|
88
|
-
new TurnLifecycleService(this.sessionStore, persistence),
|
|
88
|
+
new TurnLifecycleService(this.sessionStore, persistence, this.options),
|
|
89
89
|
new TurnContextBuilder(() => this.adminforth),
|
|
90
90
|
new AgentModeResolver(this.options),
|
|
91
91
|
new AgentModelFactory(this.options.maxTokens ?? 1000),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adminforth/agent",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.52.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -25,7 +25,6 @@
|
|
|
25
25
|
"description": "AI agent plugin for AdminForth with tool-based workflows and persistent chat sessions",
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@types/node": "latest",
|
|
28
|
-
"adminforth": "2.71.1",
|
|
29
28
|
"semantic-release": "^24.2.1",
|
|
30
29
|
"semantic-release-slack-bot": "^4.0.2",
|
|
31
30
|
"typescript": "^5.7.3"
|
|
@@ -34,6 +33,7 @@
|
|
|
34
33
|
"@langchain/core": "^1.1.40",
|
|
35
34
|
"@langchain/langgraph": "^1.2.8",
|
|
36
35
|
"@langchain/langgraph-checkpoint": "^1.0.1",
|
|
36
|
+
"adminforth": "2.72.0",
|
|
37
37
|
"dayjs": "^1.11.20",
|
|
38
38
|
"langchain": "^1.3.3",
|
|
39
39
|
"multer": "^2.1.1",
|
|
@@ -65,8 +65,5 @@
|
|
|
65
65
|
"name": "next",
|
|
66
66
|
"prerelease": true
|
|
67
67
|
}
|
|
68
|
-
]
|
|
69
|
-
"peerDependencies": {
|
|
70
|
-
"adminforth": "2.71.1"
|
|
71
|
-
}
|
|
68
|
+
]
|
|
72
69
|
}
|
package/sessionStore.ts
CHANGED
|
@@ -65,6 +65,17 @@ export class AgentSessionStore {
|
|
|
65
65
|
}));
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
async getLatestTurn(sessionId: string) {
|
|
69
|
+
const turns = await this.getAdminforth().resource(this.options.turnResource.resourceId).list(
|
|
70
|
+
[Filters.EQ(this.options.turnResource.sessionIdField, sessionId)],
|
|
71
|
+
1,
|
|
72
|
+
undefined,
|
|
73
|
+
[Sorts.DESC(this.options.turnResource.createdAtField)]
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
return turns[0];
|
|
77
|
+
}
|
|
78
|
+
|
|
68
79
|
getChatSurfaceSessionId(incoming: ChatSurfaceIncomingMessage) {
|
|
69
80
|
return `${incoming.surface}:${incoming.externalConversationId}`;
|
|
70
81
|
}
|
|
@@ -123,6 +123,17 @@ function createAgentEventStream(
|
|
|
123
123
|
});
|
|
124
124
|
},
|
|
125
125
|
|
|
126
|
+
interrupt(sessionId: string, interrupt: unknown) {
|
|
127
|
+
stream.endActiveBlock();
|
|
128
|
+
stream.send({
|
|
129
|
+
type: isAiUiMessageStream ? "data-interrupt" : "interrupt",
|
|
130
|
+
data: {
|
|
131
|
+
sessionId,
|
|
132
|
+
interrupt,
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
},
|
|
136
|
+
|
|
126
137
|
openPage(targetPath: string) {
|
|
127
138
|
stream.send({
|
|
128
139
|
type: isAiUiMessageStream ? "data-open-page" : "open-page",
|
|
@@ -259,6 +270,9 @@ export function createSseEventEmitter(
|
|
|
259
270
|
case "rendering":
|
|
260
271
|
stream.rendering(event.phase, event.label);
|
|
261
272
|
break;
|
|
273
|
+
case "interrupt":
|
|
274
|
+
stream.interrupt(event.sessionId, event.interrupt);
|
|
275
|
+
break;
|
|
262
276
|
case "open-page":
|
|
263
277
|
stream.openPage(event.targetPath);
|
|
264
278
|
break;
|