@adminforth/agent 2.0.9 → 2.1.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/README.md +333 -10
- package/dist/application/ports.d.ts +66 -0
- package/dist/application/runTurnUseCase.d.ts +68 -0
- package/dist/application/runTurnUseCase.js +358 -0
- package/dist/{agentEvents.d.ts → domain/agentEvents.d.ts} +1 -1
- package/dist/{agent → domain}/systemPrompt.js +1 -1
- package/dist/{agent/turn → domain}/turnTypes.d.ts +41 -37
- package/dist/{agent/turn/VegaLiteStreamBuffer.d.ts → domain/vegaLiteStreamBuffer.d.ts} +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +40 -35
- package/dist/{agent/runtime/AgentContext.d.ts → llm/agentContext.d.ts} +3 -3
- package/dist/{agent/simpleAgent.d.ts → llm/agentModels.d.ts} +18 -16
- package/dist/llm/agentModels.js +65 -0
- package/dist/{agent/runtime/AgentRuntime.d.ts → llm/agentRuntime.d.ts} +11 -2
- package/dist/{agent/runtime/AgentRuntime.js → llm/agentRuntime.js} +38 -6
- package/dist/llm/langGraphLlm.d.ts +25 -0
- package/dist/llm/langGraphLlm.js +54 -0
- package/dist/{agent/middleware/apiBasedTools.d.ts → llm/middleware/apiToolsMiddleware.d.ts} +1 -1
- package/dist/{agent/middleware/apiBasedTools.js → llm/middleware/apiToolsMiddleware.js} +8 -14
- package/dist/{agent → llm}/middleware/sequenceDebug.d.ts +1 -1
- package/dist/{agent/models/AgentModelFactory.d.ts → llm/modelFactory.d.ts} +1 -1
- package/dist/{agent/models/AgentModelFactory.js → llm/modelFactory.js} +1 -1
- package/dist/llm/streamAdapter.d.ts +18 -0
- package/dist/llm/streamAdapter.js +117 -0
- package/dist/{sessionStore.d.ts → persistence/sessionStore.d.ts} +12 -2
- package/dist/{sessionStore.js → persistence/sessionStore.js} +33 -0
- package/dist/{agent/tools/AgentToolProvider.d.ts → tools/agentToolProvider.d.ts} +1 -1
- package/dist/{agent/tools/AgentToolProvider.js → tools/agentToolProvider.js} +1 -1
- package/dist/{apiBasedTools.js → tools/apiBasedTools.js} +10 -6
- package/dist/{agent/tools → tools}/apiTool.d.ts +1 -1
- package/dist/{agent/tools → tools}/fetchSkill.js +1 -1
- package/dist/{agent/tools → tools}/fetchToolSchema.d.ts +1 -1
- package/dist/{agent/tools → tools}/index.d.ts +1 -1
- package/dist/{agent/tools → tools}/navigateUser.d.ts +3 -3
- package/dist/{endpoints → transport/http}/context.d.ts +2 -2
- package/dist/transport/http/context.js +1 -0
- package/dist/{endpoints/core.js → transport/http/coreEndpoints.js} +3 -3
- package/dist/{endpoints/sessions.js → transport/http/sessionEndpoints.js} +7 -1
- package/dist/transport/sse/sseWriter.d.ts +29 -0
- package/dist/{surfaces/web-sse/createSseEventEmitter.js → transport/sse/sseWriter.js} +15 -0
- package/dist/{chatSurfaceService.d.ts → transport/surfaces/chatSurfaceService.d.ts} +3 -3
- package/dist/{chatSurfaceService.js → transport/surfaces/chatSurfaceService.js} +7 -5
- package/dist/{agent/speech/SpeechTurnService.d.ts → transport/surfaces/speechTurnService.d.ts} +1 -1
- package/dist/{agent/speech/SpeechTurnService.js → transport/surfaces/speechTurnService.js} +2 -2
- package/dist/types.d.ts +10 -4
- package/package.json +11 -2
- package/.woodpecker/buildRelease.sh +0 -13
- package/.woodpecker/buildSlackNotify.sh +0 -46
- package/.woodpecker/release.yml +0 -57
- package/agent/checkpointer.ts +0 -329
- package/agent/languageDetect.ts +0 -92
- package/agent/middleware/apiBasedTools.ts +0 -174
- package/agent/middleware/openAiResponsesContinuation.ts +0 -92
- package/agent/middleware/sequenceDebug.ts +0 -429
- package/agent/models/AgentModeResolver.ts +0 -9
- package/agent/models/AgentModelFactory.ts +0 -28
- package/agent/runtime/AgentContext.ts +0 -30
- package/agent/runtime/AgentRuntime.ts +0 -89
- package/agent/simpleAgent.ts +0 -199
- package/agent/skills/registry.ts +0 -162
- package/agent/speech/SpeechTurnService.ts +0 -179
- package/agent/systemPrompt.ts +0 -133
- package/agent/toolCallEvents.ts +0 -135
- package/agent/tools/AgentToolProvider.ts +0 -28
- package/agent/tools/apiTool.ts +0 -66
- package/agent/tools/fetchSkill.ts +0 -68
- package/agent/tools/fetchToolSchema.ts +0 -47
- package/agent/tools/getUserLocation.ts +0 -45
- package/agent/tools/index.ts +0 -31
- package/agent/tools/navigateUser.ts +0 -210
- package/agent/turn/TurnContextBuilder.ts +0 -36
- package/agent/turn/TurnLifecycleService.ts +0 -47
- package/agent/turn/TurnPersistenceService.ts +0 -33
- package/agent/turn/TurnPromptBuilder.ts +0 -51
- package/agent/turn/TurnStreamConsumer.ts +0 -69
- package/agent/turn/VegaLiteStreamBuffer.ts +0 -90
- package/agent/turn/turnTypes.ts +0 -100
- package/agentEvents.ts +0 -75
- package/agentTurnService.ts +0 -314
- package/apiBasedTools.ts +0 -702
- package/build.log +0 -67
- package/chatSurfaceService.ts +0 -319
- package/custom/ChatFooter.vue +0 -173
- package/custom/ChatHeader.vue +0 -78
- package/custom/ChatSurface.vue +0 -160
- package/custom/CustomAutoScrollContainer.vue +0 -164
- package/custom/SessionsHistory.vue +0 -88
- package/custom/chat.ts +0 -82
- package/custom/composables/agentAudio/utils.ts +0 -220
- package/custom/composables/agentStore/constants.ts +0 -19
- package/custom/composables/agentStore/pageContext.ts +0 -8
- package/custom/composables/agentStore/useAgentChat.ts +0 -241
- package/custom/composables/agentStore/useAgentPlaceholder.ts +0 -142
- package/custom/composables/agentStore/useAgentSessions.ts +0 -350
- package/custom/composables/useAgentAudio.ts +0 -272
- package/custom/composables/useAgentStore.ts +0 -510
- package/custom/composables/useAgentTransitions.ts +0 -58
- package/custom/conversation_area/ConversationArea.vue +0 -301
- package/custom/conversation_area/MessageRenderer.vue +0 -49
- package/custom/conversation_area/ProcessingTimeline.vue +0 -286
- package/custom/conversation_area/ReasoningRenderer.vue +0 -79
- package/custom/conversation_area/SystemMessageRenderer.vue +0 -28
- package/custom/conversation_area/TextRenderer.vue +0 -182
- package/custom/conversation_area/ThreeDotsAnimation.vue +0 -35
- package/custom/conversation_area/ToolApprovalRenderer.vue +0 -98
- package/custom/conversation_area/ToolRenderer.vue +0 -178
- package/custom/conversation_area/ToolsGroup.vue +0 -59
- package/custom/env.d.ts +0 -7
- package/custom/incremark_code_renderers/IncremarkShikiCodeBlock.vue +0 -393
- package/custom/incremark_code_renderers/incremarkCodeHighlight.ts +0 -285
- package/custom/incremark_code_renderers/incremarkRenderer.ts +0 -653
- package/custom/incremark_code_renderers/renderIncremarkMarkdown.ts +0 -118
- package/custom/package.json +0 -30
- package/custom/pnpm-lock.yaml +0 -2394
- package/custom/public/agentAudio/agent-processing.mp3 +0 -0
- package/custom/skills/analyze_data/SKILL.md +0 -25
- package/custom/skills/charts/SKILL.md +0 -193
- package/custom/skills/fetch_data/SKILL.md +0 -31
- package/custom/skills/mutate_data/SKILL.md +0 -121
- package/custom/speech_recognition_frontend/AudioLines.vue +0 -43
- package/custom/speech_recognition_frontend/MicrophoneButon.vue +0 -185
- package/custom/speech_recognition_frontend/types/voice-activity-detection.d.ts +0 -22
- package/custom/speech_recognition_frontend/voiceActivityDetection.ts +0 -62
- package/custom/tsconfig.json +0 -15
- package/custom/types.ts +0 -108
- package/custom/utils.ts +0 -38
- package/dist/agent/middleware/openAiResponsesContinuation.d.ts +0 -1
- package/dist/agent/middleware/openAiResponsesContinuation.js +0 -66
- package/dist/agent/models/AgentModeResolver.d.ts +0 -9
- package/dist/agent/models/AgentModeResolver.js +0 -9
- package/dist/agent/simpleAgent.js +0 -118
- package/dist/agent/turn/TurnContextBuilder.d.ts +0 -14
- package/dist/agent/turn/TurnContextBuilder.js +0 -31
- package/dist/agent/turn/TurnLifecycleService.d.ts +0 -24
- package/dist/agent/turn/TurnLifecycleService.js +0 -47
- package/dist/agent/turn/TurnPersistenceService.d.ts +0 -13
- package/dist/agent/turn/TurnPersistenceService.js +0 -35
- package/dist/agent/turn/TurnPromptBuilder.d.ts +0 -19
- package/dist/agent/turn/TurnPromptBuilder.js +0 -43
- package/dist/agent/turn/TurnStreamConsumer.d.ts +0 -11
- package/dist/agent/turn/TurnStreamConsumer.js +0 -84
- package/dist/agentTurnService.d.ts +0 -24
- package/dist/agentTurnService.js +0 -269
- package/dist/surfaces/web-sse/createSseEventEmitter.d.ts +0 -14
- package/endpoints/chatSurfaces.ts +0 -66
- package/endpoints/context.ts +0 -52
- package/endpoints/core.ts +0 -181
- package/endpoints/sessions.ts +0 -183
- package/errors.ts +0 -10
- package/index.ts +0 -192
- package/pnpm-workspace.yaml +0 -4
- package/sanitizeSpeechText.ts +0 -32
- package/sessionStore.ts +0 -105
- package/surfaces/web-sse/createSseEventEmitter.ts +0 -311
- package/tsconfig.json +0 -14
- package/types.ts +0 -127
- /package/dist/{agent/turn/turnTypes.js → application/ports.js} +0 -0
- /package/dist/{agentEvents.js → domain/agentEvents.js} +0 -0
- /package/dist/{agent → domain}/languageDetect.d.ts +0 -0
- /package/dist/{agent → domain}/languageDetect.js +0 -0
- /package/dist/{agent → domain}/systemPrompt.d.ts +0 -0
- /package/dist/{agent → domain}/toolCallEvents.d.ts +0 -0
- /package/dist/{agent → domain}/toolCallEvents.js +0 -0
- /package/dist/{endpoints/context.js → domain/turnTypes.js} +0 -0
- /package/dist/{agent/turn/VegaLiteStreamBuffer.js → domain/vegaLiteStreamBuffer.js} +0 -0
- /package/dist/{agent/runtime/AgentContext.js → llm/agentContext.js} +0 -0
- /package/dist/{agent → llm}/middleware/sequenceDebug.js +0 -0
- /package/dist/{agent/checkpointer.d.ts → persistence/checkpointStore.d.ts} +0 -0
- /package/dist/{agent/checkpointer.js → persistence/checkpointStore.js} +0 -0
- /package/dist/{errors.d.ts → shared/errors.d.ts} +0 -0
- /package/dist/{errors.js → shared/errors.js} +0 -0
- /package/dist/{sanitizeSpeechText.d.ts → shared/sanitizeSpeechText.d.ts} +0 -0
- /package/dist/{sanitizeSpeechText.js → shared/sanitizeSpeechText.js} +0 -0
- /package/dist/{apiBasedTools.d.ts → tools/apiBasedTools.d.ts} +0 -0
- /package/dist/{agent/tools → tools}/apiTool.js +0 -0
- /package/dist/{agent/tools → tools}/fetchSkill.d.ts +0 -0
- /package/dist/{agent/tools → tools}/fetchToolSchema.js +0 -0
- /package/dist/{agent/tools → tools}/getUserLocation.d.ts +0 -0
- /package/dist/{agent/tools → tools}/getUserLocation.js +0 -0
- /package/dist/{agent/tools → tools}/index.js +0 -0
- /package/dist/{agent/tools → tools}/navigateUser.js +0 -0
- /package/dist/{agent → tools}/skills/registry.d.ts +0 -0
- /package/dist/{agent → tools}/skills/registry.js +0 -0
- /package/dist/{endpoints/chatSurfaces.d.ts → transport/http/chatSurfaceEndpoints.d.ts} +0 -0
- /package/dist/{endpoints/chatSurfaces.js → transport/http/chatSurfaceEndpoints.js} +0 -0
- /package/dist/{endpoints/core.d.ts → transport/http/coreEndpoints.d.ts} +0 -0
- /package/dist/{endpoints/sessions.d.ts → transport/http/sessionEndpoints.d.ts} +0 -0
|
@@ -385,7 +385,6 @@ function callOpenApiSchema(params) {
|
|
|
385
385
|
return validationErrorResponse('REQUEST_VALIDATION_FAILED', requestValidation.errors);
|
|
386
386
|
}
|
|
387
387
|
const response = createDirectToolResponse();
|
|
388
|
-
logger.info(`Calling OpenAPI tool "${toolName}" with direct handler`);
|
|
389
388
|
const lang = acceptLanguage !== null && acceptLanguage !== void 0 ? acceptLanguage : "en";
|
|
390
389
|
const tr = (msg, category, trParams, pluralizationNumber) => adminforth.tr(msg, category, lang, trParams, pluralizationNumber);
|
|
391
390
|
const output = yield withToolHandlerTimeout((handlerAbortSignal) => schema.handler({
|
|
@@ -432,6 +431,12 @@ function callOpenApiSchema(params) {
|
|
|
432
431
|
function stringifyToolOutput(output) {
|
|
433
432
|
return YAML.stringify(output === undefined ? EMPTY_HANDLER_RESPONSE_ERROR : output);
|
|
434
433
|
}
|
|
434
|
+
function attachDurationMs(output, durationMs) {
|
|
435
|
+
if (output !== null && typeof output === 'object' && !Array.isArray(output)) {
|
|
436
|
+
return Object.assign(Object.assign({}, output), { durationMs });
|
|
437
|
+
}
|
|
438
|
+
return { result: output, durationMs };
|
|
439
|
+
}
|
|
435
440
|
export function prepareApiBasedTools(adminforth, hiddenResourceIds = []) {
|
|
436
441
|
const apiBasedTools = {};
|
|
437
442
|
const openApiSchemas = adminforth.openApi.registeredSchemas;
|
|
@@ -443,19 +448,18 @@ export function prepareApiBasedTools(adminforth, hiddenResourceIds = []) {
|
|
|
443
448
|
openApiSchemasByToolName.set(toolName, schema);
|
|
444
449
|
}
|
|
445
450
|
}
|
|
446
|
-
logger.info(`AdminForth Agent OpenAPI APIs: ${formatLogNameList(adminforth.openApi.registeredSchemas.map((schema) => openApiSchemaPathToToolName(schema.path, adminforth)))}`);
|
|
447
|
-
logger.info(`AdminForth Agent OpenAPI tools connected: ${formatLogNameList([...openApiSchemasByToolName.keys()])}`);
|
|
448
451
|
for (const [toolName, schema] of openApiSchemasByToolName.entries()) {
|
|
449
452
|
apiBasedTools[toolName] = {
|
|
450
453
|
description: schema.description,
|
|
451
454
|
input_schema: schema.request_schema,
|
|
452
455
|
agent: schema.agent,
|
|
453
456
|
call: (...args_1) => __awaiter(this, [...args_1], void 0, function* ({ adminUser, adminuser, abortSignal, inputs, userTimeZone, acceptLanguage } = {}) {
|
|
457
|
+
const startedAt = Date.now();
|
|
454
458
|
if (isHiddenResourceCall(hiddenResourceIdSet, inputs)) {
|
|
455
|
-
return stringifyToolOutput({
|
|
459
|
+
return stringifyToolOutput(attachDurationMs({
|
|
456
460
|
error: 'RESOURCE_NOT_AVAILABLE',
|
|
457
461
|
message: 'This resource is not available to the agent.',
|
|
458
|
-
});
|
|
462
|
+
}, Date.now() - startedAt));
|
|
459
463
|
}
|
|
460
464
|
const output = yield callOpenApiSchema({
|
|
461
465
|
adminforth,
|
|
@@ -475,7 +479,7 @@ export function prepareApiBasedTools(adminforth, hiddenResourceIds = []) {
|
|
|
475
479
|
toolName,
|
|
476
480
|
userTimeZone,
|
|
477
481
|
});
|
|
478
|
-
return stringifyToolOutput(processedOutput);
|
|
482
|
+
return stringifyToolOutput(attachDurationMs(processedOutput, Date.now() - startedAt));
|
|
479
483
|
}),
|
|
480
484
|
};
|
|
481
485
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ApiBasedTool } from "
|
|
1
|
+
import type { ApiBasedTool } from "./apiBasedTools.js";
|
|
2
2
|
export declare function createApiTool(toolName: string, apiBasedTool: ApiBasedTool): import("langchain").DynamicStructuredTool<Record<string, unknown> | {
|
|
3
3
|
readonly type: "object";
|
|
4
4
|
readonly properties: {};
|
|
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import { tool } from "langchain";
|
|
11
11
|
import { z } from "zod";
|
|
12
|
-
import { listSkillManifests, loadSkillMarkdown, } from "
|
|
12
|
+
import { listSkillManifests, loadSkillMarkdown, } from "./skills/registry.js";
|
|
13
13
|
const fetchSkillSchema = z.object({
|
|
14
14
|
skillName: z
|
|
15
15
|
.string()
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import type { ApiBasedTool } from "
|
|
2
|
+
import type { ApiBasedTool } from "./apiBasedTools.js";
|
|
3
3
|
export declare function createFetchToolSchemaTool(apiBasedTools: Record<string, ApiBasedTool>): Promise<import("langchain").DynamicStructuredTool<z.ZodObject<{
|
|
4
4
|
toolName: z.ZodString;
|
|
5
5
|
}, z.core.$strip>, {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { ClientTool } from "@langchain/core/tools";
|
|
2
|
-
import type { ApiBasedTool } from "
|
|
2
|
+
import type { ApiBasedTool } from "./apiBasedTools.js";
|
|
3
3
|
export declare const ALWAYS_AVAILABLE_API_TOOL_NAMES: readonly ["get_resource"];
|
|
4
4
|
export declare function createAgentTools(customComponentsDir: string, apiBasedTools: Record<string, ApiBasedTool>, pluginCustomFolderPaths?: string[]): Promise<ClientTool[]>;
|
|
@@ -17,8 +17,8 @@ export declare function createNavigateUserTool(): import("langchain").DynamicStr
|
|
|
17
17
|
sort: z.ZodOptional<z.ZodObject<{
|
|
18
18
|
column: z.ZodString;
|
|
19
19
|
direction: z.ZodEnum<{
|
|
20
|
-
asc: "asc";
|
|
21
20
|
desc: "desc";
|
|
21
|
+
asc: "asc";
|
|
22
22
|
}>;
|
|
23
23
|
}, z.core.$strip>>;
|
|
24
24
|
query: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
|
|
@@ -34,7 +34,7 @@ export declare function createNavigateUserTool(): import("langchain").DynamicStr
|
|
|
34
34
|
}[] | undefined;
|
|
35
35
|
sort?: {
|
|
36
36
|
column: string;
|
|
37
|
-
direction: "
|
|
37
|
+
direction: "desc" | "asc";
|
|
38
38
|
} | undefined;
|
|
39
39
|
query?: Record<string, string | number | boolean> | undefined;
|
|
40
40
|
}, {
|
|
@@ -49,7 +49,7 @@ export declare function createNavigateUserTool(): import("langchain").DynamicStr
|
|
|
49
49
|
}[] | undefined;
|
|
50
50
|
sort?: {
|
|
51
51
|
column: string;
|
|
52
|
-
direction: "
|
|
52
|
+
direction: "desc" | "asc";
|
|
53
53
|
} | undefined;
|
|
54
54
|
query?: Record<string, string | number | boolean> | undefined;
|
|
55
55
|
}, string, unknown, "navigate_user">;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ChatSurfaceAdapter, ChatSurfaceEventSink, ChatSurfaceIncomingMessage, IAdminForth } from "adminforth";
|
|
2
|
-
import type { HandleSpeechTurnInput, HandleTurnInput, RunAndPersistAgentResponseInput, RunAndPersistAgentResponseResult } from "
|
|
3
|
-
import type { PluginOptions } from "
|
|
2
|
+
import type { HandleSpeechTurnInput, HandleTurnInput, RunAndPersistAgentResponseInput, RunAndPersistAgentResponseResult } from "../../domain/turnTypes.js";
|
|
3
|
+
import type { PluginOptions } from "../../types.js";
|
|
4
4
|
export type SessionTurn = {
|
|
5
5
|
prompt: string;
|
|
6
6
|
response: string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -8,7 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { z } from "zod";
|
|
11
|
-
import { createSseEventEmitter } from "../
|
|
11
|
+
import { createSseEventEmitter } from "../sse/sseWriter.js";
|
|
12
12
|
const currentPageContextSchema = z.object({
|
|
13
13
|
path: z.string(),
|
|
14
14
|
fullPath: z.string(),
|
|
@@ -77,7 +77,7 @@ export function setupCoreEndpoints(ctx, server) {
|
|
|
77
77
|
method: 'POST',
|
|
78
78
|
path: `/agent/response`,
|
|
79
79
|
request_schema: agentResponseBodySchema,
|
|
80
|
-
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser,
|
|
80
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, _raw_express_res, abortSignal }) {
|
|
81
81
|
var _b;
|
|
82
82
|
const data = body;
|
|
83
83
|
const emit = createSseEventEmitter(_raw_express_res, {
|
|
@@ -103,7 +103,7 @@ export function setupCoreEndpoints(ctx, server) {
|
|
|
103
103
|
method: 'POST',
|
|
104
104
|
path: `/agent/approval`,
|
|
105
105
|
request_schema: agentApprovalBodySchema,
|
|
106
|
-
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser,
|
|
106
|
+
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, _raw_express_res, abortSignal }) {
|
|
107
107
|
const data = body;
|
|
108
108
|
const emit = createSseEventEmitter(_raw_express_res, {
|
|
109
109
|
vercelAiUiMessageStream: true,
|
|
@@ -10,7 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
import { Filters, Sorts } from "adminforth";
|
|
11
11
|
import { randomUUID } from "crypto";
|
|
12
12
|
import { z } from "zod";
|
|
13
|
-
import { AGENT_SYSTEM_TURN_PROMPT } from "
|
|
13
|
+
import { AGENT_SYSTEM_TURN_PROMPT } from "../../persistence/sessionStore.js";
|
|
14
14
|
const addSystemMessageBodySchema = z.object({
|
|
15
15
|
sessionId: z.string(),
|
|
16
16
|
systemMessage: z.string(),
|
|
@@ -54,11 +54,13 @@ export function setupSessionEndpoints(ctx, server) {
|
|
|
54
54
|
const sessionId = data.sessionId;
|
|
55
55
|
const session = yield ctx.adminforth.resource(ctx.options.sessionResource.resourceId).get([Filters.EQ(ctx.options.sessionResource.idField, sessionId)]);
|
|
56
56
|
if (!session) {
|
|
57
|
+
response.setStatus(404, 'Session not found');
|
|
57
58
|
return {
|
|
58
59
|
error: 'Session not found'
|
|
59
60
|
};
|
|
60
61
|
}
|
|
61
62
|
if (session[ctx.options.sessionResource.askerIdField] !== userId) {
|
|
63
|
+
response.setStatus(403, 'Unauthorized');
|
|
62
64
|
return {
|
|
63
65
|
error: 'Unauthorized'
|
|
64
66
|
};
|
|
@@ -129,11 +131,13 @@ export function setupSessionEndpoints(ctx, server) {
|
|
|
129
131
|
const userId = adminUser.pk;
|
|
130
132
|
const session = yield ctx.adminforth.resource(ctx.options.sessionResource.resourceId).get([Filters.EQ(ctx.options.sessionResource.idField, sessionId)]);
|
|
131
133
|
if (!session) {
|
|
134
|
+
response.setStatus(404, 'Session not found');
|
|
132
135
|
return {
|
|
133
136
|
error: 'Session not found'
|
|
134
137
|
};
|
|
135
138
|
}
|
|
136
139
|
if (session[ctx.options.sessionResource.askerIdField] !== userId) {
|
|
140
|
+
response.setStatus(403, 'Unauthorized');
|
|
137
141
|
return {
|
|
138
142
|
error: 'Unauthorized'
|
|
139
143
|
};
|
|
@@ -154,11 +158,13 @@ export function setupSessionEndpoints(ctx, server) {
|
|
|
154
158
|
const data = body;
|
|
155
159
|
const session = yield ctx.adminforth.resource(ctx.options.sessionResource.resourceId).get([Filters.EQ(ctx.options.sessionResource.idField, data.sessionId)]);
|
|
156
160
|
if (!session) {
|
|
161
|
+
response.setStatus(404, 'Session not found');
|
|
157
162
|
return {
|
|
158
163
|
error: 'Session not found'
|
|
159
164
|
};
|
|
160
165
|
}
|
|
161
166
|
if (session[ctx.options.sessionResource.askerIdField] !== adminUser.pk) {
|
|
167
|
+
response.setStatus(403, 'Unauthorized');
|
|
162
168
|
return {
|
|
163
169
|
error: 'Unauthorized'
|
|
164
170
|
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { AgentEventEmitter } from "../../domain/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
|
+
/**
|
|
14
|
+
* Maps the internal {@link AgentEvent} vocabulary onto the two Server-Sent-Events
|
|
15
|
+
* wire dialects the frontend consumes. Both dialects are HARD external contracts —
|
|
16
|
+
* do not change frame names/shapes without updating the corresponding consumer:
|
|
17
|
+
*
|
|
18
|
+
* - `vercelAiUiMessageStream: true` (used by `/agent/response` and `/agent/approval`):
|
|
19
|
+
* the Vercel AI SDK message-stream v1 format (`start`, `text-start`/`text-delta`/
|
|
20
|
+
* `text-end`, `reasoning-*`, `data-*` parts, `error` with `errorText`, `finish`,
|
|
21
|
+
* `[DONE]`). Consumed by `DefaultChatTransport` and the manual approval parser in
|
|
22
|
+
* `custom/composables/agentStore/useAgentChat.ts`.
|
|
23
|
+
* - default (used by `/agent/speech-response`): bare event names
|
|
24
|
+
* (`transcript`, `speech-response`, `audio-start`/`audio-delta`/`audio-done`,
|
|
25
|
+
* `open-page`, `error`) plus the Vercel-shaped `data-tool-call`. Consumed by
|
|
26
|
+
* `custom/composables/useAgentAudio.ts`.
|
|
27
|
+
*/
|
|
28
|
+
export declare function createSseEventEmitter(res: AgentEventStreamResponse, options?: AgentEventStreamOptions): AgentEventEmitter;
|
|
29
|
+
export {};
|
|
@@ -185,6 +185,21 @@ function createAgentEventStream(res, options = {}) {
|
|
|
185
185
|
};
|
|
186
186
|
return stream;
|
|
187
187
|
}
|
|
188
|
+
/**
|
|
189
|
+
* Maps the internal {@link AgentEvent} vocabulary onto the two Server-Sent-Events
|
|
190
|
+
* wire dialects the frontend consumes. Both dialects are HARD external contracts —
|
|
191
|
+
* do not change frame names/shapes without updating the corresponding consumer:
|
|
192
|
+
*
|
|
193
|
+
* - `vercelAiUiMessageStream: true` (used by `/agent/response` and `/agent/approval`):
|
|
194
|
+
* the Vercel AI SDK message-stream v1 format (`start`, `text-start`/`text-delta`/
|
|
195
|
+
* `text-end`, `reasoning-*`, `data-*` parts, `error` with `errorText`, `finish`,
|
|
196
|
+
* `[DONE]`). Consumed by `DefaultChatTransport` and the manual approval parser in
|
|
197
|
+
* `custom/composables/agentStore/useAgentChat.ts`.
|
|
198
|
+
* - default (used by `/agent/speech-response`): bare event names
|
|
199
|
+
* (`transcript`, `speech-response`, `audio-start`/`audio-delta`/`audio-done`,
|
|
200
|
+
* `open-page`, `error`) plus the Vercel-shaped `data-tool-call`. Consumed by
|
|
201
|
+
* `custom/composables/useAgentAudio.ts`.
|
|
202
|
+
*/
|
|
188
203
|
export function createSseEventEmitter(res, options = {}) {
|
|
189
204
|
const stream = createAgentEventStream(res, options);
|
|
190
205
|
return (event) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ChatSurfaceAdapter, ChatSurfaceEventSink, ChatSurfaceIncomingMessage, IAdminForth } from "adminforth";
|
|
2
|
-
import type { HandleTurnInput, RunAndPersistAgentResponseInput, RunAndPersistAgentResponseResult } from "
|
|
3
|
-
import type { AgentSessionStore } from "
|
|
4
|
-
import type { PluginOptions } from "
|
|
2
|
+
import type { HandleTurnInput, RunAndPersistAgentResponseInput, RunAndPersistAgentResponseResult } from "../../domain/turnTypes.js";
|
|
3
|
+
import type { AgentSessionStore } from "../../persistence/sessionStore.js";
|
|
4
|
+
import type { PluginOptions } from "../../types.js";
|
|
5
5
|
export declare class ChatSurfaceService {
|
|
6
6
|
private getAdminforth;
|
|
7
7
|
private options;
|
|
@@ -8,8 +8,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { Filters, logger } from "adminforth";
|
|
11
|
-
import { getErrorMessage, isAbortError } from "
|
|
12
|
-
import { sanitizeSpeechText } from "
|
|
11
|
+
import { getErrorMessage, isAbortError } from "../../shared/errors.js";
|
|
12
|
+
import { sanitizeSpeechText } from "../../shared/sanitizeSpeechText.js";
|
|
13
13
|
export class ChatSurfaceService {
|
|
14
14
|
constructor(getAdminforth, options, sessionStore, handleTurn, runAndPersistAgentResponse) {
|
|
15
15
|
this.getAdminforth = getAdminforth;
|
|
@@ -35,9 +35,11 @@ export class ChatSurfaceService {
|
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
37
37
|
if (event.type === "error") {
|
|
38
|
+
// Full error detail is logged server-side (see runAndPersistAgentResponse);
|
|
39
|
+
// external chat users receive a generic message to avoid leaking internals.
|
|
38
40
|
yield sink.emit({
|
|
39
41
|
type: "error",
|
|
40
|
-
message:
|
|
42
|
+
message: "Agent response failed. Check server logs for details.",
|
|
41
43
|
});
|
|
42
44
|
}
|
|
43
45
|
});
|
|
@@ -122,7 +124,7 @@ export class ChatSurfaceService {
|
|
|
122
124
|
logger.error(`Agent ${incoming.surface} surface speech synthesis failed:\n${getErrorMessage(error)}`);
|
|
123
125
|
yield sink.emit({
|
|
124
126
|
type: "error",
|
|
125
|
-
message:
|
|
127
|
+
message: "Speech synthesis failed. Check server logs for details.",
|
|
126
128
|
});
|
|
127
129
|
}
|
|
128
130
|
});
|
|
@@ -165,7 +167,7 @@ export class ChatSurfaceService {
|
|
|
165
167
|
if (agentResponse.failed) {
|
|
166
168
|
yield sink.emit({
|
|
167
169
|
type: "error",
|
|
168
|
-
message:
|
|
170
|
+
message: "Agent response failed. Check server logs for details.",
|
|
169
171
|
});
|
|
170
172
|
}
|
|
171
173
|
return agentResponse;
|
package/dist/{agent/speech/SpeechTurnService.d.ts → transport/surfaces/speechTurnService.d.ts}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RunAndPersistAgentResponseInput, RunAndPersistAgentResponseResult, SpeechAgentTurnInput } from "
|
|
1
|
+
import type { RunAndPersistAgentResponseInput, RunAndPersistAgentResponseResult, SpeechAgentTurnInput } from "../../domain/turnTypes.js";
|
|
2
2
|
export declare class SpeechTurnService {
|
|
3
3
|
private readonly runAndPersistAgentResponse;
|
|
4
4
|
constructor(runAndPersistAgentResponse: (input: RunAndPersistAgentResponseInput) => Promise<RunAndPersistAgentResponseResult>);
|
|
@@ -8,8 +8,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { logger } from "adminforth";
|
|
11
|
-
import { getErrorMessage, isAbortError } from "../../errors.js";
|
|
12
|
-
import { sanitizeSpeechText } from "../../sanitizeSpeechText.js";
|
|
11
|
+
import { getErrorMessage, isAbortError } from "../../shared/errors.js";
|
|
12
|
+
import { sanitizeSpeechText } from "../../shared/sanitizeSpeechText.js";
|
|
13
13
|
export class SpeechTurnService {
|
|
14
14
|
constructor(runAndPersistAgentResponse) {
|
|
15
15
|
this.runAndPersistAgentResponse = runAndPersistAgentResponse;
|
package/dist/types.d.ts
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { type PluginsCommonOptions, type AdminUser, type HttpExtra, type AudioAdapter, type ChatSurfaceAdapter } from "adminforth";
|
|
2
|
-
import type { AgentModeCompletionAdapter } from "./
|
|
2
|
+
import type { AgentModeCompletionAdapter } from "./application/ports.js";
|
|
3
3
|
interface ISessionResource {
|
|
4
4
|
resourceId: string;
|
|
5
5
|
idField: string;
|
|
6
6
|
titleField: string;
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* @deprecated Not used by the plugin — session turns are looked up via
|
|
9
|
+
* `turnResource.sessionIdField`. Kept optional for backward compatibility;
|
|
10
|
+
* will be removed in a future major version.
|
|
11
|
+
*/
|
|
12
|
+
turnsField?: string;
|
|
8
13
|
askerIdField: string;
|
|
9
14
|
createdAtField: string;
|
|
10
15
|
}
|
|
@@ -69,8 +74,9 @@ export interface PluginOptions extends PluginsCommonOptions {
|
|
|
69
74
|
*/
|
|
70
75
|
systemPrompt?: string;
|
|
71
76
|
/**
|
|
72
|
-
*
|
|
73
|
-
*
|
|
77
|
+
* @deprecated Not applied — reasoning effort is configured on the completion
|
|
78
|
+
* adapter (e.g. `extraRequestBodyParameters.reasoning.effort`), not here.
|
|
79
|
+
* Kept for backward compatibility; will be removed in a future major version.
|
|
74
80
|
*/
|
|
75
81
|
reasoning?: "none" | "minimal" | "low" | "medium" | "high" | "xhigh";
|
|
76
82
|
/**
|
package/package.json
CHANGED
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adminforth/agent",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"type": "module",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"README.md",
|
|
10
|
+
"LICENSE"
|
|
11
|
+
],
|
|
7
12
|
"homepage": "https://adminforth.dev/docs/tutorial/Plugins/agent/",
|
|
8
13
|
"publishConfig": {
|
|
9
14
|
"access": "public"
|
|
10
15
|
},
|
|
11
16
|
"scripts": {
|
|
12
|
-
"build": "tsc && rsync -av --exclude 'node_modules' custom dist/"
|
|
17
|
+
"build": "tsc && rsync -av --exclude 'node_modules' custom dist/",
|
|
18
|
+
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --runInBand"
|
|
13
19
|
},
|
|
14
20
|
"keywords": [
|
|
15
21
|
"adminforth",
|
|
@@ -24,10 +30,13 @@
|
|
|
24
30
|
"license": "MIT",
|
|
25
31
|
"description": "AI agent plugin for AdminForth with tool-based workflows and persistent chat sessions",
|
|
26
32
|
"devDependencies": {
|
|
33
|
+
"@types/jest": "^30.0.0",
|
|
27
34
|
"@types/node": "latest",
|
|
28
35
|
"adminforth": "^3.8.2",
|
|
36
|
+
"jest": "^30.3.0",
|
|
29
37
|
"semantic-release": "^24.2.1",
|
|
30
38
|
"semantic-release-slack-bot": "^4.0.2",
|
|
39
|
+
"ts-jest": "^29.4.6",
|
|
31
40
|
"typescript": "^5.7.3"
|
|
32
41
|
},
|
|
33
42
|
"dependencies": {
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
#!/bin/bash
|
|
3
|
-
|
|
4
|
-
# write npm run output both to console and to build.log
|
|
5
|
-
npm run build 2>&1 | tee build.log
|
|
6
|
-
build_status=${PIPESTATUS[0]}
|
|
7
|
-
|
|
8
|
-
# if exist status from the npm run build is not 0
|
|
9
|
-
# then exit with the status code from the npm run build
|
|
10
|
-
if [ $build_status -ne 0 ]; then
|
|
11
|
-
echo "Build failed. Exiting with status code $build_status"
|
|
12
|
-
exit $build_status
|
|
13
|
-
fi
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
#!/bin/sh
|
|
2
|
-
|
|
3
|
-
set -x
|
|
4
|
-
|
|
5
|
-
COMMIT_SHORT_SHA=$(echo $CI_COMMIT_SHA | cut -c1-8)
|
|
6
|
-
|
|
7
|
-
STATUS=${1}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
if [ "$STATUS" = "success" ]; then
|
|
11
|
-
MESSAGE="Did a build without issues on \`$CI_REPO_NAME/$CI_COMMIT_BRANCH\`. Commit: _${CI_COMMIT_MESSAGE}_ (<$CI_COMMIT_URL|$COMMIT_SHORT_SHA>)"
|
|
12
|
-
|
|
13
|
-
curl -s -X POST -H "Content-Type: application/json" -d '{
|
|
14
|
-
"username": "'"$CI_COMMIT_AUTHOR"'",
|
|
15
|
-
"icon_url": "'"$CI_COMMIT_AUTHOR_AVATAR"'",
|
|
16
|
-
"attachments": [
|
|
17
|
-
{
|
|
18
|
-
"mrkdwn_in": ["text", "pretext"],
|
|
19
|
-
"color": "#36a64f",
|
|
20
|
-
"text": "'"$MESSAGE"'"
|
|
21
|
-
}
|
|
22
|
-
]
|
|
23
|
-
}' "$DEVELOPERS_SLACK_WEBHOOK"
|
|
24
|
-
exit 0
|
|
25
|
-
fi
|
|
26
|
-
export BUILD_LOG=$(cat ./build.log)
|
|
27
|
-
|
|
28
|
-
BUILD_LOG=$(echo $BUILD_LOG | sed 's/"/\\"/g')
|
|
29
|
-
|
|
30
|
-
MESSAGE="Broke \`$CI_REPO_NAME/$CI_COMMIT_BRANCH\` with commit _${CI_COMMIT_MESSAGE}_ (<$CI_COMMIT_URL|$COMMIT_SHORT_SHA>)"
|
|
31
|
-
CODE_BLOCK="\`\`\`$BUILD_LOG\n\`\`\`"
|
|
32
|
-
|
|
33
|
-
echo "Sending slack message to developers $MESSAGE"
|
|
34
|
-
# Send the message
|
|
35
|
-
curl -sS -X POST -H "Content-Type: application/json" -d '{
|
|
36
|
-
"username": "'"$CI_COMMIT_AUTHOR"'",
|
|
37
|
-
"icon_url": "'"$CI_COMMIT_AUTHOR_AVATAR"'",
|
|
38
|
-
"attachments": [
|
|
39
|
-
{
|
|
40
|
-
"mrkdwn_in": ["text", "pretext"],
|
|
41
|
-
"color": "#8A1C12",
|
|
42
|
-
"text": "'"$CODE_BLOCK"'",
|
|
43
|
-
"pretext": "'"$MESSAGE"'"
|
|
44
|
-
}
|
|
45
|
-
]
|
|
46
|
-
}' "$DEVELOPERS_SLACK_WEBHOOK" 2>&1
|
package/.woodpecker/release.yml
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
clone:
|
|
2
|
-
git:
|
|
3
|
-
image: woodpeckerci/plugin-git
|
|
4
|
-
settings:
|
|
5
|
-
partial: false
|
|
6
|
-
depth: 5
|
|
7
|
-
|
|
8
|
-
steps:
|
|
9
|
-
init-secrets:
|
|
10
|
-
when:
|
|
11
|
-
- event: push
|
|
12
|
-
image: infisical/cli
|
|
13
|
-
environment:
|
|
14
|
-
INFISICAL_TOKEN:
|
|
15
|
-
from_secret: VAULT_TOKEN
|
|
16
|
-
commands:
|
|
17
|
-
- infisical export --domain https://vault.devforth.io/api --format=dotenv-export --env="prod" > /woodpecker/deploy.vault.env
|
|
18
|
-
|
|
19
|
-
build:
|
|
20
|
-
image: devforth/node20-pnpm:latest
|
|
21
|
-
when:
|
|
22
|
-
- event: push
|
|
23
|
-
commands:
|
|
24
|
-
- apt update && apt install -y rsync
|
|
25
|
-
- . /woodpecker/deploy.vault.env
|
|
26
|
-
- pnpm install
|
|
27
|
-
- /bin/bash ./.woodpecker/buildRelease.sh
|
|
28
|
-
- npm audit signatures
|
|
29
|
-
|
|
30
|
-
release:
|
|
31
|
-
image: devforth/node20-pnpm:latest
|
|
32
|
-
when:
|
|
33
|
-
- event:
|
|
34
|
-
- push
|
|
35
|
-
branch:
|
|
36
|
-
- main
|
|
37
|
-
commands:
|
|
38
|
-
- . /woodpecker/deploy.vault.env
|
|
39
|
-
- pnpm exec semantic-release
|
|
40
|
-
|
|
41
|
-
slack-on-failure:
|
|
42
|
-
image: curlimages/curl
|
|
43
|
-
when:
|
|
44
|
-
- event: push
|
|
45
|
-
status: [failure]
|
|
46
|
-
commands:
|
|
47
|
-
- . /woodpecker/deploy.vault.env
|
|
48
|
-
- /bin/sh ./.woodpecker/buildSlackNotify.sh failure
|
|
49
|
-
|
|
50
|
-
slack-on-success:
|
|
51
|
-
image: curlimages/curl
|
|
52
|
-
when:
|
|
53
|
-
- event: push
|
|
54
|
-
status: [success]
|
|
55
|
-
commands:
|
|
56
|
-
- . /woodpecker/deploy.vault.env
|
|
57
|
-
- /bin/sh ./.woodpecker/buildSlackNotify.sh success
|