@adminforth/agent 1.50.1 → 1.51.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 +13 -3
- package/agent/models/AgentModeResolver.ts +9 -0
- package/agent/models/AgentModelFactory.ts +28 -0
- package/agent/runtime/AgentContext.ts +30 -0
- package/agent/runtime/AgentRuntime.ts +68 -0
- package/agent/simpleAgent.ts +2 -129
- package/agent/speech/SpeechTurnService.ts +179 -0
- package/agent/tools/AgentToolProvider.ts +28 -0
- package/agent/tools/navigateUser.ts +2 -2
- package/agent/turn/TurnContextBuilder.ts +36 -0
- package/agent/turn/TurnLifecycleService.ts +29 -0
- package/agent/turn/TurnPersistenceService.ts +33 -0
- package/agent/turn/TurnPromptBuilder.ts +51 -0
- package/agent/turn/TurnStreamConsumer.ts +61 -0
- package/agent/turn/VegaLiteStreamBuffer.ts +90 -0
- package/agent/turn/turnTypes.ts +92 -0
- package/agentTurnService.ts +88 -461
- package/build.log +1 -1
- package/dist/agent/middleware/apiBasedTools.js +9 -2
- package/dist/agent/models/AgentModeResolver.d.ts +9 -0
- package/dist/agent/models/AgentModeResolver.js +9 -0
- package/dist/agent/models/AgentModelFactory.d.ts +7 -0
- package/dist/agent/models/AgentModelFactory.js +36 -0
- package/dist/agent/runtime/AgentContext.d.ts +28 -0
- package/dist/agent/runtime/AgentContext.js +17 -0
- package/dist/agent/runtime/AgentRuntime.d.ts +15 -0
- package/dist/agent/runtime/AgentRuntime.js +57 -0
- package/dist/agent/simpleAgent.d.ts +15 -45
- package/dist/agent/simpleAgent.js +1 -67
- package/dist/agent/speech/SpeechTurnService.d.ts +6 -0
- package/dist/agent/speech/SpeechTurnService.js +168 -0
- package/dist/agent/tools/AgentToolProvider.d.ts +9 -0
- package/dist/agent/tools/AgentToolProvider.js +27 -0
- package/dist/agent/tools/navigateUser.js +1 -1
- package/dist/agent/turn/TurnContextBuilder.d.ts +14 -0
- package/dist/agent/turn/TurnContextBuilder.js +31 -0
- package/dist/agent/turn/TurnLifecycleService.d.ts +17 -0
- package/dist/agent/turn/TurnLifecycleService.js +31 -0
- package/dist/agent/turn/TurnPersistenceService.d.ts +13 -0
- package/dist/agent/turn/TurnPersistenceService.js +35 -0
- package/dist/agent/turn/TurnPromptBuilder.d.ts +19 -0
- package/dist/agent/turn/TurnPromptBuilder.js +43 -0
- package/dist/agent/turn/TurnStreamConsumer.d.ts +10 -0
- package/dist/agent/turn/TurnStreamConsumer.js +78 -0
- package/dist/agent/turn/VegaLiteStreamBuffer.d.ts +7 -0
- package/dist/agent/turn/VegaLiteStreamBuffer.js +87 -0
- package/dist/agent/turn/turnTypes.d.ts +81 -0
- package/dist/agent/turn/turnTypes.js +1 -0
- package/dist/agentTurnService.d.ts +20 -69
- package/dist/agentTurnService.js +60 -373
- package/dist/index.d.ts +1 -0
- package/dist/index.js +22 -7
- package/index.ts +35 -7
- package/package.json +1 -1
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { AdminUser } from "adminforth";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import type { AgentEventEmitter } from "../../agentEvents.js";
|
|
4
|
+
import type { SequenceDebugCollector } from "../middleware/sequenceDebug.js";
|
|
5
|
+
import type { CurrentPageContext } from "../tools/getUserLocation.js";
|
|
6
|
+
import type { AgentTurnContext } from "../turn/turnTypes.js";
|
|
7
|
+
export declare const contextSchema: z.ZodObject<{
|
|
8
|
+
adminUser: z.ZodCustom<AdminUser, AdminUser>;
|
|
9
|
+
userTimeZone: z.ZodString;
|
|
10
|
+
sessionId: z.ZodString;
|
|
11
|
+
turnId: z.ZodString;
|
|
12
|
+
abortSignal: z.ZodOptional<z.ZodCustom<AbortSignal, AbortSignal>>;
|
|
13
|
+
currentPage: z.ZodOptional<z.ZodCustom<CurrentPageContext, CurrentPageContext>>;
|
|
14
|
+
chatSurface: z.ZodOptional<z.ZodString>;
|
|
15
|
+
adminBaseUrl: z.ZodOptional<z.ZodString>;
|
|
16
|
+
adminPublicOrigin: z.ZodOptional<z.ZodString>;
|
|
17
|
+
emit: z.ZodOptional<z.ZodCustom<AgentEventEmitter, AgentEventEmitter>>;
|
|
18
|
+
sequenceDebugSink: z.ZodCustom<SequenceDebugCollector, SequenceDebugCollector>;
|
|
19
|
+
}, z.core.$strip>;
|
|
20
|
+
export declare function toLangchainAgentContext(context: AgentTurnContext & {
|
|
21
|
+
adminBaseUrl: string;
|
|
22
|
+
emit?: AgentEventEmitter;
|
|
23
|
+
sequenceDebugSink: SequenceDebugCollector;
|
|
24
|
+
}): AgentTurnContext & {
|
|
25
|
+
adminBaseUrl: string;
|
|
26
|
+
emit?: AgentEventEmitter;
|
|
27
|
+
sequenceDebugSink: SequenceDebugCollector;
|
|
28
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const contextSchema = z.object({
|
|
3
|
+
adminUser: z.custom(),
|
|
4
|
+
userTimeZone: z.string(),
|
|
5
|
+
sessionId: z.string(),
|
|
6
|
+
turnId: z.string(),
|
|
7
|
+
abortSignal: z.custom().optional(),
|
|
8
|
+
currentPage: z.custom().optional(),
|
|
9
|
+
chatSurface: z.string().optional(),
|
|
10
|
+
adminBaseUrl: z.string().optional(),
|
|
11
|
+
adminPublicOrigin: z.string().optional(),
|
|
12
|
+
emit: z.custom().optional(),
|
|
13
|
+
sequenceDebugSink: z.custom(),
|
|
14
|
+
});
|
|
15
|
+
export function toLangchainAgentContext(context) {
|
|
16
|
+
return context;
|
|
17
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { IAdminForth } from "adminforth";
|
|
2
|
+
import type { BaseCheckpointSaver } from "@langchain/langgraph";
|
|
3
|
+
import type { AgentToolProvider } from "../tools/AgentToolProvider.js";
|
|
4
|
+
import type { AgentRuntimeRunInput } from "../turn/turnTypes.js";
|
|
5
|
+
export type AgentRuntimeOptions = {
|
|
6
|
+
name: string;
|
|
7
|
+
getAdminforth: () => IAdminForth;
|
|
8
|
+
getCheckpointer: () => BaseCheckpointSaver;
|
|
9
|
+
toolProvider: AgentToolProvider;
|
|
10
|
+
};
|
|
11
|
+
export declare class AgentRuntime {
|
|
12
|
+
private readonly options;
|
|
13
|
+
constructor(options: AgentRuntimeOptions);
|
|
14
|
+
stream(input: AgentRuntimeRunInput): Promise<import("@langchain/core/utils/stream").IterableReadableStream<[import("langchain").BaseMessage<import("@langchain/core/messages").MessageStructure<import("@langchain/core/messages").MessageToolSet>, import("@langchain/core/messages").MessageType>, Record<string, any>]>>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
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 { createAgent, summarizationMiddleware } from "langchain";
|
|
11
|
+
import { createApiBasedToolsMiddleware } from "../middleware/apiBasedTools.js";
|
|
12
|
+
import { createSequenceDebugMiddleware } from "../middleware/sequenceDebug.js";
|
|
13
|
+
import { createAgentLlmMetricsLogger } from "../simpleAgent.js";
|
|
14
|
+
import { contextSchema, toLangchainAgentContext } from "./AgentContext.js";
|
|
15
|
+
export class AgentRuntime {
|
|
16
|
+
constructor(options) {
|
|
17
|
+
this.options = options;
|
|
18
|
+
}
|
|
19
|
+
stream(input) {
|
|
20
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
21
|
+
var _a;
|
|
22
|
+
const apiBasedTools = this.options.toolProvider.getApiBasedTools();
|
|
23
|
+
const tools = yield this.options.toolProvider.getTools(apiBasedTools);
|
|
24
|
+
const adminforth = this.options.getAdminforth();
|
|
25
|
+
const apiBasedToolsMiddleware = createApiBasedToolsMiddleware(apiBasedTools, adminforth);
|
|
26
|
+
const sequenceDebugMiddleware = createSequenceDebugMiddleware(input.observability.sequenceDebugSink);
|
|
27
|
+
const middleware = [
|
|
28
|
+
apiBasedToolsMiddleware,
|
|
29
|
+
...((_a = input.models.modelMiddleware) !== null && _a !== void 0 ? _a : []),
|
|
30
|
+
sequenceDebugMiddleware,
|
|
31
|
+
summarizationMiddleware({
|
|
32
|
+
model: input.models.summaryModel,
|
|
33
|
+
trigger: { tokens: 1024 * 64 },
|
|
34
|
+
keep: { messages: 10 },
|
|
35
|
+
}),
|
|
36
|
+
];
|
|
37
|
+
const agent = createAgent({
|
|
38
|
+
name: this.options.name,
|
|
39
|
+
model: input.models.model,
|
|
40
|
+
checkpointer: this.options.getCheckpointer(),
|
|
41
|
+
tools,
|
|
42
|
+
contextSchema,
|
|
43
|
+
middleware,
|
|
44
|
+
});
|
|
45
|
+
return agent.stream({ messages: input.messages }, {
|
|
46
|
+
streamMode: "messages",
|
|
47
|
+
recursionLimit: 100,
|
|
48
|
+
callbacks: [createAgentLlmMetricsLogger()],
|
|
49
|
+
signal: input.context.abortSignal,
|
|
50
|
+
configurable: {
|
|
51
|
+
thread_id: input.context.sessionId,
|
|
52
|
+
},
|
|
53
|
+
context: toLangchainAgentContext(Object.assign(Object.assign({}, input.context), { adminBaseUrl: adminforth.config.baseUrlSlashed, emit: input.observability.emit, sequenceDebugSink: input.observability.sequenceDebugSink })),
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -1,25 +1,8 @@
|
|
|
1
1
|
import type { BaseChatModel } from "@langchain/core/language_models/chat_models";
|
|
2
|
-
import { type
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { createSequenceDebugMiddleware
|
|
6
|
-
import type { ApiBasedTool } from "../apiBasedTools.js";
|
|
7
|
-
import type { ToolCallEventSink } from "./toolCallEvents.js";
|
|
8
|
-
import type { CurrentPageContext } from "./tools/getUserLocation.js";
|
|
9
|
-
import type { AgentEventEmitter } from "../agentEvents.js";
|
|
10
|
-
export declare const contextSchema: z.ZodObject<{
|
|
11
|
-
adminUser: z.ZodCustom<AdminUser, AdminUser>;
|
|
12
|
-
userTimeZone: z.ZodString;
|
|
13
|
-
sessionId: z.ZodString;
|
|
14
|
-
turnId: z.ZodString;
|
|
15
|
-
abortSignal: z.ZodOptional<z.ZodCustom<AbortSignal, AbortSignal>>;
|
|
16
|
-
currentPage: z.ZodOptional<z.ZodCustom<CurrentPageContext, CurrentPageContext>>;
|
|
17
|
-
chatSurface: z.ZodOptional<z.ZodString>;
|
|
18
|
-
adminBaseUrl: z.ZodOptional<z.ZodString>;
|
|
19
|
-
adminPublicOrigin: z.ZodOptional<z.ZodString>;
|
|
20
|
-
emitToolCallEvent: z.ZodCustom<ToolCallEventSink, ToolCallEventSink>;
|
|
21
|
-
emitAgentEvent: z.ZodOptional<z.ZodCustom<AgentEventEmitter, AgentEventEmitter>>;
|
|
22
|
-
}, z.core.$strip>;
|
|
2
|
+
import { type CompletionAdapter } from "adminforth";
|
|
3
|
+
import { BaseCallbackHandler } from "@langchain/core/callbacks/base";
|
|
4
|
+
import type { LLMResult } from "@langchain/core/outputs";
|
|
5
|
+
import { createSequenceDebugMiddleware } from "./middleware/sequenceDebug.js";
|
|
23
6
|
export type AgentChatModel = BaseChatModel<any, any>;
|
|
24
7
|
export type AgentModelPurpose = "primary" | "summary";
|
|
25
8
|
export type AgentModeCompletionAdapter = CompletionAdapter & {
|
|
@@ -34,37 +17,24 @@ export type AgentModeCompletionAdapter = CompletionAdapter & {
|
|
|
34
17
|
middleware?: unknown[];
|
|
35
18
|
};
|
|
36
19
|
};
|
|
37
|
-
type AgentMiddleware = ReturnType<typeof createSequenceDebugMiddleware>;
|
|
20
|
+
export type AgentMiddleware = ReturnType<typeof createSequenceDebugMiddleware>;
|
|
38
21
|
type AgentChatModelSpec = {
|
|
39
22
|
model: AgentChatModel;
|
|
40
23
|
middleware: AgentMiddleware[];
|
|
41
24
|
};
|
|
25
|
+
declare class AgentLlmMetricsLogger extends BaseCallbackHandler {
|
|
26
|
+
name: string;
|
|
27
|
+
lc_prefer_streaming: boolean;
|
|
28
|
+
private readonly pendingRuns;
|
|
29
|
+
handleLLMStart(_llm: unknown, _prompts: string[], runId: string): Promise<void>;
|
|
30
|
+
handleLLMNewToken(_token: string, _chunk: unknown, runId: string): Promise<void>;
|
|
31
|
+
handleLLMEnd(output: LLMResult, runId: string): Promise<void>;
|
|
32
|
+
handleLLMError(_error: unknown, runId: string): Promise<void>;
|
|
33
|
+
}
|
|
34
|
+
export declare function createAgentLlmMetricsLogger(): AgentLlmMetricsLogger;
|
|
42
35
|
export declare function createAgentChatModel(params: {
|
|
43
36
|
adapter: CompletionAdapter;
|
|
44
37
|
maxTokens: number;
|
|
45
38
|
purpose: AgentModelPurpose;
|
|
46
39
|
}): Promise<AgentChatModelSpec>;
|
|
47
|
-
export declare function callAgent(params: {
|
|
48
|
-
name: string;
|
|
49
|
-
model: AgentChatModel;
|
|
50
|
-
summaryModel: AgentChatModel;
|
|
51
|
-
modelMiddleware?: AgentMiddleware[];
|
|
52
|
-
checkpointer?: BaseCheckpointSaver;
|
|
53
|
-
messages: Messages;
|
|
54
|
-
adminUser: AdminUser;
|
|
55
|
-
adminforth: IAdminForth;
|
|
56
|
-
apiBasedTools: Record<string, ApiBasedTool>;
|
|
57
|
-
customComponentsDir: string;
|
|
58
|
-
pluginCustomFolderPaths: string[];
|
|
59
|
-
sessionId: string;
|
|
60
|
-
turnId: string;
|
|
61
|
-
currentPage?: CurrentPageContext;
|
|
62
|
-
chatSurface?: string;
|
|
63
|
-
adminPublicOrigin?: string;
|
|
64
|
-
userTimeZone: string;
|
|
65
|
-
abortSignal?: AbortSignal;
|
|
66
|
-
emitToolCallEvent: ToolCallEventSink;
|
|
67
|
-
emitAgentEvent?: AgentEventEmitter;
|
|
68
|
-
sequenceDebugSink: SequenceDebugModelCallSink;
|
|
69
|
-
}): Promise<import("@langchain/core/utils/stream").IterableReadableStream<[import("langchain").BaseMessage<import("@langchain/core/messages").MessageStructure<import("@langchain/core/messages").MessageToolSet>, import("@langchain/core/messages").MessageType>, Record<string, any>]>>;
|
|
70
40
|
export {};
|
|
@@ -7,26 +7,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import { createAgent, summarizationMiddleware } from "langchain";
|
|
11
10
|
import { logger, } from "adminforth";
|
|
12
11
|
import { BaseCallbackHandler } from "@langchain/core/callbacks/base";
|
|
13
|
-
import { z } from "zod";
|
|
14
|
-
import { createAgentTools } from "./tools/index.js";
|
|
15
|
-
import { createApiBasedToolsMiddleware } from "./middleware/apiBasedTools.js";
|
|
16
|
-
import { createSequenceDebugMiddleware, } from "./middleware/sequenceDebug.js";
|
|
17
|
-
export const contextSchema = z.object({
|
|
18
|
-
adminUser: z.custom(),
|
|
19
|
-
userTimeZone: z.string(),
|
|
20
|
-
sessionId: z.string(),
|
|
21
|
-
turnId: z.string(),
|
|
22
|
-
abortSignal: z.custom().optional(),
|
|
23
|
-
currentPage: z.custom().optional(),
|
|
24
|
-
chatSurface: z.string().optional(),
|
|
25
|
-
adminBaseUrl: z.string().optional(),
|
|
26
|
-
adminPublicOrigin: z.string().optional(),
|
|
27
|
-
emitToolCallEvent: z.custom(),
|
|
28
|
-
emitAgentEvent: z.custom().optional(),
|
|
29
|
-
});
|
|
30
12
|
function isLangChainAgentCompletionAdapter(adapter) {
|
|
31
13
|
return typeof adapter
|
|
32
14
|
.getLangChainAgentSpec === "function";
|
|
@@ -119,7 +101,7 @@ class AgentLlmMetricsLogger extends BaseCallbackHandler {
|
|
|
119
101
|
});
|
|
120
102
|
}
|
|
121
103
|
}
|
|
122
|
-
function createAgentLlmMetricsLogger() {
|
|
104
|
+
export function createAgentLlmMetricsLogger() {
|
|
123
105
|
return new AgentLlmMetricsLogger();
|
|
124
106
|
}
|
|
125
107
|
export function createAgentChatModel(params) {
|
|
@@ -134,51 +116,3 @@ export function createAgentChatModel(params) {
|
|
|
134
116
|
});
|
|
135
117
|
});
|
|
136
118
|
}
|
|
137
|
-
export function callAgent(params) {
|
|
138
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
139
|
-
const { name, model, summaryModel, modelMiddleware = [], checkpointer, messages, adminUser, adminforth, apiBasedTools, customComponentsDir, pluginCustomFolderPaths, sessionId, turnId, currentPage, chatSurface, adminPublicOrigin, userTimeZone, abortSignal, emitToolCallEvent, emitAgentEvent, sequenceDebugSink, } = params;
|
|
140
|
-
const tools = yield createAgentTools(customComponentsDir, apiBasedTools, pluginCustomFolderPaths);
|
|
141
|
-
const apiBasedToolsMiddleware = createApiBasedToolsMiddleware(apiBasedTools, adminforth);
|
|
142
|
-
const sequenceDebugMiddleware = createSequenceDebugMiddleware(sequenceDebugSink);
|
|
143
|
-
const middleware = [
|
|
144
|
-
apiBasedToolsMiddleware,
|
|
145
|
-
...modelMiddleware,
|
|
146
|
-
sequenceDebugMiddleware,
|
|
147
|
-
summarizationMiddleware({
|
|
148
|
-
model: summaryModel,
|
|
149
|
-
trigger: { tokens: 1024 * 64 },
|
|
150
|
-
keep: { messages: 10 },
|
|
151
|
-
}),
|
|
152
|
-
];
|
|
153
|
-
const agent = createAgent({
|
|
154
|
-
name,
|
|
155
|
-
model,
|
|
156
|
-
checkpointer,
|
|
157
|
-
tools,
|
|
158
|
-
contextSchema,
|
|
159
|
-
middleware,
|
|
160
|
-
});
|
|
161
|
-
return yield agent.stream({ messages }, {
|
|
162
|
-
streamMode: "messages",
|
|
163
|
-
recursionLimit: 100,
|
|
164
|
-
callbacks: [createAgentLlmMetricsLogger()],
|
|
165
|
-
signal: abortSignal,
|
|
166
|
-
configurable: {
|
|
167
|
-
thread_id: sessionId,
|
|
168
|
-
},
|
|
169
|
-
context: {
|
|
170
|
-
adminUser,
|
|
171
|
-
userTimeZone,
|
|
172
|
-
sessionId,
|
|
173
|
-
turnId,
|
|
174
|
-
abortSignal,
|
|
175
|
-
currentPage,
|
|
176
|
-
chatSurface,
|
|
177
|
-
adminBaseUrl: adminforth.config.baseUrlSlashed,
|
|
178
|
-
adminPublicOrigin,
|
|
179
|
-
emitToolCallEvent,
|
|
180
|
-
emitAgentEvent,
|
|
181
|
-
},
|
|
182
|
-
});
|
|
183
|
-
});
|
|
184
|
-
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { RunAndPersistAgentResponseInput, RunAndPersistAgentResponseResult, SpeechAgentTurnInput } from "../turn/turnTypes.js";
|
|
2
|
+
export declare class SpeechTurnService {
|
|
3
|
+
private readonly runAndPersistAgentResponse;
|
|
4
|
+
constructor(runAndPersistAgentResponse: (input: RunAndPersistAgentResponseInput) => Promise<RunAndPersistAgentResponseResult>);
|
|
5
|
+
handle(input: SpeechAgentTurnInput): Promise<RunAndPersistAgentResponseResult | null>;
|
|
6
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
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 { logger } from "adminforth";
|
|
11
|
+
import { getErrorMessage, isAbortError } from "../../errors.js";
|
|
12
|
+
import { sanitizeSpeechText } from "../../sanitizeSpeechText.js";
|
|
13
|
+
export class SpeechTurnService {
|
|
14
|
+
constructor(runAndPersistAgentResponse) {
|
|
15
|
+
this.runAndPersistAgentResponse = runAndPersistAgentResponse;
|
|
16
|
+
}
|
|
17
|
+
handle(input) {
|
|
18
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
19
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
20
|
+
let transcription;
|
|
21
|
+
try {
|
|
22
|
+
transcription = yield input.audioAdapter.transcribe({
|
|
23
|
+
buffer: input.audio.buffer,
|
|
24
|
+
filename: input.audio.filename,
|
|
25
|
+
mimeType: input.audio.mimeType,
|
|
26
|
+
language: "auto",
|
|
27
|
+
abortSignal: input.abortSignal,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
if (((_a = input.abortSignal) === null || _a === void 0 ? void 0 : _a.aborted) || isAbortError(error)) {
|
|
32
|
+
logger.info("Agent speech transcription aborted by the client");
|
|
33
|
+
yield input.emit({ type: "finish" });
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
logger.error(`Agent speech transcription failed:\n${getErrorMessage(error)}`);
|
|
37
|
+
yield input.emit({
|
|
38
|
+
type: "error",
|
|
39
|
+
error: "Speech transcription failed. Check server logs for details.",
|
|
40
|
+
});
|
|
41
|
+
yield input.emit({ type: "finish" });
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
if ((_b = input.abortSignal) === null || _b === void 0 ? void 0 : _b.aborted) {
|
|
45
|
+
yield input.emit({ type: "finish" });
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
const prompt = transcription.text;
|
|
49
|
+
if (!prompt) {
|
|
50
|
+
yield input.emit({
|
|
51
|
+
type: "error",
|
|
52
|
+
error: "Speech transcription is empty",
|
|
53
|
+
});
|
|
54
|
+
yield input.emit({ type: "finish" });
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
yield input.emit({
|
|
58
|
+
type: "transcript",
|
|
59
|
+
text: transcription.text,
|
|
60
|
+
language: transcription.language,
|
|
61
|
+
});
|
|
62
|
+
const agentResponse = yield this.runAndPersistAgentResponse({
|
|
63
|
+
prompt,
|
|
64
|
+
sessionId: input.sessionId,
|
|
65
|
+
modeName: input.modeName,
|
|
66
|
+
userTimeZone: input.userTimeZone,
|
|
67
|
+
currentPage: input.currentPage,
|
|
68
|
+
chatSurface: input.chatSurface,
|
|
69
|
+
adminPublicOrigin: input.adminPublicOrigin,
|
|
70
|
+
abortSignal: input.abortSignal,
|
|
71
|
+
adminUser: input.adminUser,
|
|
72
|
+
emit: (event) => __awaiter(this, void 0, void 0, function* () {
|
|
73
|
+
if (event.type === "tool-call") {
|
|
74
|
+
yield input.emit(event);
|
|
75
|
+
}
|
|
76
|
+
}),
|
|
77
|
+
failureLogMessage: (_c = input.failureLogMessage) !== null && _c !== void 0 ? _c : "Agent speech response failed",
|
|
78
|
+
abortLogMessage: (_d = input.abortLogMessage) !== null && _d !== void 0 ? _d : "Agent speech response aborted by the client",
|
|
79
|
+
});
|
|
80
|
+
if (agentResponse.aborted) {
|
|
81
|
+
yield input.emit({ type: "finish" });
|
|
82
|
+
return agentResponse;
|
|
83
|
+
}
|
|
84
|
+
if (agentResponse.failed) {
|
|
85
|
+
yield input.emit({
|
|
86
|
+
type: "error",
|
|
87
|
+
error: agentResponse.text,
|
|
88
|
+
});
|
|
89
|
+
yield input.emit({ type: "finish" });
|
|
90
|
+
return agentResponse;
|
|
91
|
+
}
|
|
92
|
+
try {
|
|
93
|
+
yield input.emit({
|
|
94
|
+
type: "speech-response",
|
|
95
|
+
transcript: {
|
|
96
|
+
text: transcription.text,
|
|
97
|
+
language: transcription.language,
|
|
98
|
+
},
|
|
99
|
+
response: {
|
|
100
|
+
text: agentResponse.text,
|
|
101
|
+
},
|
|
102
|
+
sessionId: input.sessionId,
|
|
103
|
+
turnId: agentResponse.turnId,
|
|
104
|
+
});
|
|
105
|
+
const speech = yield input.audioAdapter.synthesize({
|
|
106
|
+
text: sanitizeSpeechText(agentResponse.text),
|
|
107
|
+
stream: true,
|
|
108
|
+
streamFormat: "audio",
|
|
109
|
+
format: "pcm",
|
|
110
|
+
abortSignal: input.abortSignal,
|
|
111
|
+
});
|
|
112
|
+
yield input.emit({
|
|
113
|
+
type: "audio-start",
|
|
114
|
+
mimeType: speech.mimeType,
|
|
115
|
+
format: speech.format,
|
|
116
|
+
sampleRate: 24000,
|
|
117
|
+
channelCount: 1,
|
|
118
|
+
bitsPerSample: 16,
|
|
119
|
+
});
|
|
120
|
+
const reader = speech.audioStream.getReader();
|
|
121
|
+
const cancelAudioStream = () => {
|
|
122
|
+
void reader.cancel().catch(() => undefined);
|
|
123
|
+
};
|
|
124
|
+
try {
|
|
125
|
+
(_e = input.abortSignal) === null || _e === void 0 ? void 0 : _e.addEventListener("abort", cancelAudioStream, { once: true });
|
|
126
|
+
while (true) {
|
|
127
|
+
if ((_f = input.abortSignal) === null || _f === void 0 ? void 0 : _f.aborted) {
|
|
128
|
+
yield reader.cancel().catch(() => undefined);
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
const { value, done } = yield reader.read();
|
|
132
|
+
if (done) {
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
if ((_g = input.abortSignal) === null || _g === void 0 ? void 0 : _g.aborted) {
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
yield input.emit({
|
|
139
|
+
type: "audio-delta",
|
|
140
|
+
value,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
finally {
|
|
145
|
+
(_h = input.abortSignal) === null || _h === void 0 ? void 0 : _h.removeEventListener("abort", cancelAudioStream);
|
|
146
|
+
reader.releaseLock();
|
|
147
|
+
}
|
|
148
|
+
yield input.emit({ type: "audio-done" });
|
|
149
|
+
yield input.emit({ type: "finish" });
|
|
150
|
+
return agentResponse;
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
if (((_j = input.abortSignal) === null || _j === void 0 ? void 0 : _j.aborted) || isAbortError(error)) {
|
|
154
|
+
logger.info("Agent speech audio streaming aborted by the client");
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
logger.error(`Agent speech audio streaming failed:\n${getErrorMessage(error)}`);
|
|
158
|
+
yield input.emit({
|
|
159
|
+
type: "error",
|
|
160
|
+
error: getErrorMessage(error),
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
yield input.emit({ type: "finish" });
|
|
164
|
+
return agentResponse;
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { IAdminForth } from "adminforth";
|
|
2
|
+
import type { ApiBasedTool } from "../../apiBasedTools.js";
|
|
3
|
+
export declare class AgentToolProvider {
|
|
4
|
+
private readonly getAdminforth;
|
|
5
|
+
private readonly getInternalAgentResourceIds;
|
|
6
|
+
constructor(getAdminforth: () => IAdminForth, getInternalAgentResourceIds: () => string[]);
|
|
7
|
+
getApiBasedTools(): Record<string, ApiBasedTool>;
|
|
8
|
+
getTools(apiBasedTools: Record<string, ApiBasedTool>): Promise<import("@langchain/core/tools").ClientTool[]>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
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 { prepareApiBasedTools } from "../../apiBasedTools.js";
|
|
11
|
+
import { createAgentTools } from "./index.js";
|
|
12
|
+
export class AgentToolProvider {
|
|
13
|
+
constructor(getAdminforth, getInternalAgentResourceIds) {
|
|
14
|
+
this.getAdminforth = getAdminforth;
|
|
15
|
+
this.getInternalAgentResourceIds = getInternalAgentResourceIds;
|
|
16
|
+
}
|
|
17
|
+
getApiBasedTools() {
|
|
18
|
+
return prepareApiBasedTools(this.getAdminforth(), this.getInternalAgentResourceIds());
|
|
19
|
+
}
|
|
20
|
+
getTools(apiBasedTools) {
|
|
21
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
22
|
+
var _a;
|
|
23
|
+
const adminforth = this.getAdminforth();
|
|
24
|
+
return createAgentTools((_a = adminforth.config.customization.customComponentsDir) !== null && _a !== void 0 ? _a : "custom", apiBasedTools, adminforth.activatedPlugins.map((plugin) => plugin.customFolderPath));
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -145,7 +145,7 @@ export function createNavigateUserTool() {
|
|
|
145
145
|
message: `Send this link to the user: ${url}`,
|
|
146
146
|
}, null, 2);
|
|
147
147
|
}
|
|
148
|
-
yield ((_a = context.
|
|
148
|
+
yield ((_a = context.emit) === null || _a === void 0 ? void 0 : _a.call(context, {
|
|
149
149
|
type: "open-page",
|
|
150
150
|
targetPath,
|
|
151
151
|
}));
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { AdminUser, IAdminForth } from "adminforth";
|
|
2
|
+
import type { AgentTurnContext, BaseAgentTurnInput } from "./turnTypes.js";
|
|
3
|
+
export type UserContextProvider = {
|
|
4
|
+
getUserTimeZone(adminUser: AdminUser): Promise<string | null | undefined> | string | null | undefined;
|
|
5
|
+
};
|
|
6
|
+
export declare class TurnContextBuilder {
|
|
7
|
+
private readonly getAdminforth;
|
|
8
|
+
private readonly userContextProvider?;
|
|
9
|
+
constructor(getAdminforth: () => IAdminForth, userContextProvider?: UserContextProvider | undefined);
|
|
10
|
+
build(input: {
|
|
11
|
+
base: BaseAgentTurnInput;
|
|
12
|
+
turnId: string;
|
|
13
|
+
}): Promise<AgentTurnContext>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
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
|
+
export class TurnContextBuilder {
|
|
11
|
+
constructor(getAdminforth, userContextProvider) {
|
|
12
|
+
this.getAdminforth = getAdminforth;
|
|
13
|
+
this.userContextProvider = userContextProvider;
|
|
14
|
+
}
|
|
15
|
+
build(input) {
|
|
16
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
17
|
+
var _a, _b, _c, _d;
|
|
18
|
+
const adminforth = this.getAdminforth();
|
|
19
|
+
return {
|
|
20
|
+
adminUser: input.base.adminUser,
|
|
21
|
+
sessionId: input.base.sessionId,
|
|
22
|
+
turnId: input.turnId,
|
|
23
|
+
abortSignal: input.base.abortSignal,
|
|
24
|
+
currentPage: input.base.currentPage,
|
|
25
|
+
chatSurface: input.base.chatSurface,
|
|
26
|
+
userTimeZone: (_c = (_a = input.base.userTimeZone) !== null && _a !== void 0 ? _a : yield ((_b = this.userContextProvider) === null || _b === void 0 ? void 0 : _b.getUserTimeZone(input.base.adminUser))) !== null && _c !== void 0 ? _c : "UTC",
|
|
27
|
+
adminPublicOrigin: (_d = input.base.adminPublicOrigin) !== null && _d !== void 0 ? _d : adminforth.config.baseUrlSlashed,
|
|
28
|
+
};
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { AgentSessionStore } from "../../sessionStore.js";
|
|
2
|
+
import type { BaseAgentTurnInput } from "./turnTypes.js";
|
|
3
|
+
import { TurnPersistenceService } from "./TurnPersistenceService.js";
|
|
4
|
+
export declare class TurnLifecycleService {
|
|
5
|
+
private readonly sessionStore;
|
|
6
|
+
private readonly persistence;
|
|
7
|
+
constructor(sessionStore: AgentSessionStore, persistence: TurnPersistenceService);
|
|
8
|
+
start(input: BaseAgentTurnInput): Promise<{
|
|
9
|
+
turnId: any;
|
|
10
|
+
previousUserMessages: import("../languageDetect.js").PreviousUserMessage[];
|
|
11
|
+
}>;
|
|
12
|
+
finish(input: {
|
|
13
|
+
turnId: string;
|
|
14
|
+
responseText: string;
|
|
15
|
+
debugHistory?: unknown;
|
|
16
|
+
}): Promise<void>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
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
|
+
export class TurnLifecycleService {
|
|
11
|
+
constructor(sessionStore, persistence) {
|
|
12
|
+
this.sessionStore = sessionStore;
|
|
13
|
+
this.persistence = persistence;
|
|
14
|
+
}
|
|
15
|
+
start(input) {
|
|
16
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
17
|
+
const previousUserMessages = yield this.sessionStore.getPreviousUserMessages(input.sessionId);
|
|
18
|
+
const turnId = yield this.sessionStore.createNewTurn(input.sessionId, input.prompt);
|
|
19
|
+
yield this.persistence.touchSession(input.sessionId);
|
|
20
|
+
return {
|
|
21
|
+
turnId,
|
|
22
|
+
previousUserMessages,
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
finish(input) {
|
|
27
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
28
|
+
yield this.persistence.saveTurnResponse(input);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { IAdminForth } from "adminforth";
|
|
2
|
+
import type { PluginOptions } from "../../types.js";
|
|
3
|
+
export declare class TurnPersistenceService {
|
|
4
|
+
private readonly getAdminforth;
|
|
5
|
+
private readonly options;
|
|
6
|
+
constructor(getAdminforth: () => IAdminForth, options: PluginOptions);
|
|
7
|
+
touchSession(sessionId: string): Promise<void>;
|
|
8
|
+
saveTurnResponse(input: {
|
|
9
|
+
turnId: string;
|
|
10
|
+
responseText: string;
|
|
11
|
+
debugHistory?: unknown;
|
|
12
|
+
}): Promise<void>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
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
|
+
export class TurnPersistenceService {
|
|
11
|
+
constructor(getAdminforth, options) {
|
|
12
|
+
this.getAdminforth = getAdminforth;
|
|
13
|
+
this.options = options;
|
|
14
|
+
}
|
|
15
|
+
touchSession(sessionId) {
|
|
16
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
17
|
+
yield this.getAdminforth().resource(this.options.sessionResource.resourceId).update(sessionId, {
|
|
18
|
+
[this.options.sessionResource.createdAtField]: new Date().toISOString(),
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
saveTurnResponse(input) {
|
|
23
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
24
|
+
const turnUpdates = {
|
|
25
|
+
[this.options.turnResource.responseField]: input.responseText,
|
|
26
|
+
};
|
|
27
|
+
if (this.options.turnResource.debugField) {
|
|
28
|
+
turnUpdates[this.options.turnResource.debugField] = input.debugHistory;
|
|
29
|
+
}
|
|
30
|
+
yield this.getAdminforth()
|
|
31
|
+
.resource(this.options.turnResource.resourceId)
|
|
32
|
+
.update(input.turnId, turnUpdates);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|