@adminforth/agent 2.0.10 → 2.2.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 +71 -0
- package/dist/application/runTurnUseCase.js +364 -0
- package/dist/custom/ChatFooter.vue +58 -30
- package/dist/custom/SteerDebugPanel.vue +45 -0
- package/dist/custom/SteerQueue.vue +54 -0
- package/dist/custom/composables/agentStore/constants.ts +1 -0
- package/dist/custom/composables/agentStore/useAgentSessions.ts +35 -16
- package/dist/custom/composables/agentStore/useAgentSteerQueue.ts +114 -0
- package/dist/custom/composables/useAgentStore.ts +46 -1
- package/dist/custom/conversation_area/MessageRenderer.vue +7 -1
- package/dist/custom/speech_recognition_frontend/AudioLines.vue +1 -1
- package/dist/custom/speech_recognition_frontend/MicrophoneButon.vue +3 -3
- package/dist/{agentEvents.d.ts → domain/agentEvents.d.ts} +5 -1
- package/dist/domain/steerBuffer.d.ts +33 -0
- package/dist/domain/steerBuffer.js +51 -0
- 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 +4 -2
- package/dist/index.js +49 -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} +14 -2
- package/dist/{agent/runtime/AgentRuntime.js → llm/agentRuntime.js} +41 -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/llm/middleware/steerMiddleware.d.ts +21 -0
- package/dist/llm/middleware/steerMiddleware.js +50 -0
- 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} +19 -2
- package/dist/{sessionStore.js → persistence/sessionStore.js} +53 -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} +0 -3
- 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 +12 -4
- package/dist/transport/http/context.js +1 -0
- package/dist/{endpoints/core.js → transport/http/coreEndpoints.js} +23 -3
- package/dist/{endpoints/sessions.js → transport/http/sessionEndpoints.js} +36 -1
- package/dist/transport/sse/sseWriter.d.ts +29 -0
- package/dist/{surfaces/web-sse/createSseEventEmitter.js → transport/sse/sseWriter.js} +27 -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 -712
- 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
package/dist/index.js
CHANGED
|
@@ -7,26 +7,23 @@ 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 { AdminForthPlugin } from "adminforth";
|
|
10
|
+
import { AdminForthPlugin, logger } from "adminforth";
|
|
11
11
|
import { MemorySaver } from "@langchain/langgraph";
|
|
12
|
-
import { AdminForthCheckpointSaver } from "./
|
|
13
|
-
import { appendCustomSystemPrompt, buildAgentSystemPrompt, DEFAULT_AGENT_SYSTEM_PROMPT } from "./
|
|
14
|
-
import { setupCoreEndpoints } from "./
|
|
15
|
-
import { setupSessionEndpoints } from "./
|
|
16
|
-
import { setupChatSurfaceEndpoints } from "./
|
|
17
|
-
import { AgentSessionStore } from "./sessionStore.js";
|
|
18
|
-
import { ChatSurfaceService } from "./chatSurfaceService.js";
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import { TurnPersistenceService } from "./agent/turn/TurnPersistenceService.js";
|
|
28
|
-
import { TurnPromptBuilder } from "./agent/turn/TurnPromptBuilder.js";
|
|
29
|
-
import { TurnStreamConsumer } from "./agent/turn/TurnStreamConsumer.js";
|
|
12
|
+
import { AdminForthCheckpointSaver } from "./persistence/checkpointStore.js";
|
|
13
|
+
import { appendCustomSystemPrompt, buildAgentSystemPrompt, DEFAULT_AGENT_SYSTEM_PROMPT } from "./domain/systemPrompt.js";
|
|
14
|
+
import { setupCoreEndpoints } from "./transport/http/coreEndpoints.js";
|
|
15
|
+
import { setupSessionEndpoints } from "./transport/http/sessionEndpoints.js";
|
|
16
|
+
import { setupChatSurfaceEndpoints } from "./transport/http/chatSurfaceEndpoints.js";
|
|
17
|
+
import { AgentSessionStore } from "./persistence/sessionStore.js";
|
|
18
|
+
import { ChatSurfaceService } from "./transport/surfaces/chatSurfaceService.js";
|
|
19
|
+
import { RunTurnUseCase } from "./application/runTurnUseCase.js";
|
|
20
|
+
import { createSequenceDebugCollector } from "./llm/middleware/sequenceDebug.js";
|
|
21
|
+
import { LangGraphLlm } from "./llm/langGraphLlm.js";
|
|
22
|
+
import { AgentModelFactory } from "./llm/modelFactory.js";
|
|
23
|
+
import { AgentRuntime } from "./llm/agentRuntime.js";
|
|
24
|
+
import { SpeechTurnService } from "./transport/surfaces/speechTurnService.js";
|
|
25
|
+
import { AgentToolProvider } from "./tools/agentToolProvider.js";
|
|
26
|
+
import { SteerBuffer } from "./domain/steerBuffer.js";
|
|
30
27
|
export default class AdminForthAgentPlugin extends AdminForthPlugin {
|
|
31
28
|
getCheckpointer() {
|
|
32
29
|
if (this.checkpointer)
|
|
@@ -44,6 +41,18 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
|
|
|
44
41
|
(_a = this.options.checkpointResource) === null || _a === void 0 ? void 0 : _a.resourceId,
|
|
45
42
|
].filter((resourceId) => Boolean(resourceId));
|
|
46
43
|
}
|
|
44
|
+
getAgentSystemPrompt() {
|
|
45
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
46
|
+
if (!this.agentSystemPrompt) {
|
|
47
|
+
const systemPrompt = yield buildAgentSystemPrompt(this.adminforth, this.getInternalAgentResourceIds()).catch((err) => {
|
|
48
|
+
logger.error(`Failed to build agent system prompt, falling back to default: ${err instanceof Error ? err.message : String(err)}`);
|
|
49
|
+
return DEFAULT_AGENT_SYSTEM_PROMPT;
|
|
50
|
+
});
|
|
51
|
+
this.agentSystemPrompt = appendCustomSystemPrompt(systemPrompt, this.options.systemPrompt);
|
|
52
|
+
}
|
|
53
|
+
return this.agentSystemPrompt;
|
|
54
|
+
});
|
|
55
|
+
}
|
|
47
56
|
constructor(options) {
|
|
48
57
|
var _a;
|
|
49
58
|
super(options, import.meta.url);
|
|
@@ -52,28 +61,28 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
|
|
|
52
61
|
this.checkpointer = null;
|
|
53
62
|
this.options = options;
|
|
54
63
|
this.sessionStore = new AgentSessionStore(() => this.adminforth, this.options);
|
|
64
|
+
this.steerBuffer = new SteerBuffer();
|
|
55
65
|
const toolProvider = new AgentToolProvider(() => this.adminforth, this.getInternalAgentResourceIds.bind(this));
|
|
56
66
|
const runtime = new AgentRuntime({
|
|
57
67
|
name: `adminforth-agent-${this.pluginInstanceId}`,
|
|
58
68
|
getAdminforth: () => this.adminforth,
|
|
59
69
|
getCheckpointer: this.getCheckpointer.bind(this),
|
|
60
70
|
toolProvider,
|
|
71
|
+
steerBuffer: this.steerBuffer,
|
|
61
72
|
});
|
|
62
|
-
const
|
|
63
|
-
this.
|
|
73
|
+
const llm = new LangGraphLlm(runtime, new AgentModelFactory((_a = this.options.maxTokens) !== null && _a !== void 0 ? _a : 1000));
|
|
74
|
+
this.runTurnUseCase = new RunTurnUseCase({
|
|
75
|
+
llm,
|
|
76
|
+
sessions: this.sessionStore,
|
|
77
|
+
steerBuffer: this.steerBuffer,
|
|
78
|
+
modes: this.options.modes,
|
|
64
79
|
getAdminforth: () => this.adminforth,
|
|
65
|
-
getAgentSystemPrompt: ()
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
return this.agentSystemPrompt;
|
|
73
|
-
}),
|
|
74
|
-
}), runtime, new TurnStreamConsumer());
|
|
75
|
-
this.speechTurnService = new SpeechTurnService(this.agentTurnService.runAndPersistAgentResponse.bind(this.agentTurnService));
|
|
76
|
-
this.chatSurfaceService = new ChatSurfaceService(() => this.adminforth, this.options, this.sessionStore, this.agentTurnService.handleTurn.bind(this.agentTurnService), this.agentTurnService.runAndPersistAgentResponse.bind(this.agentTurnService));
|
|
80
|
+
getAgentSystemPrompt: this.getAgentSystemPrompt.bind(this),
|
|
81
|
+
hasPersistentCheckpointer: Boolean(this.options.checkpointResource),
|
|
82
|
+
createDebugSink: createSequenceDebugCollector,
|
|
83
|
+
});
|
|
84
|
+
this.speechTurnService = new SpeechTurnService(this.runTurnUseCase.runAndPersistAgentResponse.bind(this.runTurnUseCase));
|
|
85
|
+
this.chatSurfaceService = new ChatSurfaceService(() => this.adminforth, this.options, this.sessionStore, this.runTurnUseCase.handleTurn.bind(this.runTurnUseCase), this.runTurnUseCase.runAndPersistAgentResponse.bind(this.runTurnUseCase));
|
|
77
86
|
this.agentSystemPromptPromise = Promise.resolve(appendCustomSystemPrompt(DEFAULT_AGENT_SYSTEM_PROMPT, this.options.systemPrompt));
|
|
78
87
|
this.shouldHaveSingleInstancePerWholeApp = () => false;
|
|
79
88
|
}
|
|
@@ -139,12 +148,17 @@ export default class AdminForthAgentPlugin extends AdminForthPlugin {
|
|
|
139
148
|
const endpointContext = {
|
|
140
149
|
adminforth: this.adminforth,
|
|
141
150
|
options: this.options,
|
|
142
|
-
handleTurn: this.
|
|
151
|
+
handleTurn: this.runTurnUseCase.handleTurn.bind(this.runTurnUseCase),
|
|
143
152
|
handleSpeechTurn: this.speechTurnService.handle.bind(this.speechTurnService),
|
|
144
|
-
|
|
153
|
+
steer: ({ sessionId, message }) => {
|
|
154
|
+
const { id } = this.steerBuffer.add(sessionId, message);
|
|
155
|
+
return { id, queued: this.steerBuffer.size(sessionId) };
|
|
156
|
+
},
|
|
157
|
+
runAndPersistAgentResponse: this.runTurnUseCase.runAndPersistAgentResponse.bind(this.runTurnUseCase),
|
|
145
158
|
getSessionTurns: this.sessionStore.getSessionTurns.bind(this.sessionStore),
|
|
146
159
|
createNewTurn: this.sessionStore.createNewTurn.bind(this.sessionStore),
|
|
147
160
|
createSystemTurn: this.sessionStore.createSystemTurn.bind(this.sessionStore),
|
|
161
|
+
appendSteerToCurrentTurn: this.sessionStore.appendSteerToCurrentTurn.bind(this.sessionStore),
|
|
148
162
|
handleChatSurfaceMessage: this.chatSurfaceService.handleMessage.bind(this.chatSurfaceService),
|
|
149
163
|
};
|
|
150
164
|
setupCoreEndpoints(endpointContext, server);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { AdminUser } from "adminforth";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import type { AgentEventEmitter } from "
|
|
4
|
-
import type { SequenceDebugCollector } from "
|
|
3
|
+
import type { AgentEventEmitter } from "../domain/agentEvents.js";
|
|
4
|
+
import type { SequenceDebugCollector } from "./middleware/sequenceDebug.js";
|
|
5
5
|
import type { CurrentPageContext } from "../tools/getUserLocation.js";
|
|
6
|
-
import type { AgentTurnContext } from "../
|
|
6
|
+
import type { AgentTurnContext } from "../domain/turnTypes.js";
|
|
7
7
|
export declare const contextSchema: z.ZodObject<{
|
|
8
8
|
adminUser: z.ZodCustom<AdminUser, AdminUser>;
|
|
9
9
|
userTimeZone: z.ZodString;
|
|
@@ -2,22 +2,26 @@ import type { BaseChatModel } from "@langchain/core/language_models/chat_models"
|
|
|
2
2
|
import { type CompletionAdapter } from "adminforth";
|
|
3
3
|
import { BaseCallbackHandler } from "@langchain/core/callbacks/base";
|
|
4
4
|
import type { LLMResult } from "@langchain/core/outputs";
|
|
5
|
+
import type { Messages, Command } from "@langchain/langgraph";
|
|
5
6
|
import { createSequenceDebugMiddleware } from "./middleware/sequenceDebug.js";
|
|
7
|
+
import type { AgentModelPurpose } from "../application/ports.js";
|
|
8
|
+
import type { AgentTurnContext, AgentTurnObservability } from "../domain/turnTypes.js";
|
|
9
|
+
export type { AgentModeCompletionAdapter, AgentModelPurpose } from "../application/ports.js";
|
|
6
10
|
export type AgentChatModel = BaseChatModel<any, any>;
|
|
7
|
-
export type AgentModelPurpose = "primary" | "summary";
|
|
8
|
-
export type AgentModeCompletionAdapter = CompletionAdapter & {
|
|
9
|
-
getLangChainAgentSpec(params: {
|
|
10
|
-
maxTokens: number;
|
|
11
|
-
purpose: AgentModelPurpose;
|
|
12
|
-
}): Promise<{
|
|
13
|
-
model: unknown;
|
|
14
|
-
middleware?: unknown[];
|
|
15
|
-
}> | {
|
|
16
|
-
model: unknown;
|
|
17
|
-
middleware?: unknown[];
|
|
18
|
-
};
|
|
19
|
-
};
|
|
20
11
|
export type AgentMiddleware = ReturnType<typeof createSequenceDebugMiddleware>;
|
|
12
|
+
export type AgentTurnModels = {
|
|
13
|
+
model: AgentChatModel;
|
|
14
|
+
summaryModel: AgentChatModel;
|
|
15
|
+
modelMiddleware?: AgentMiddleware[];
|
|
16
|
+
};
|
|
17
|
+
export type AgentRuntimeRunInput = {
|
|
18
|
+
models: AgentTurnModels;
|
|
19
|
+
input: {
|
|
20
|
+
messages: Messages;
|
|
21
|
+
} | Command;
|
|
22
|
+
context: AgentTurnContext;
|
|
23
|
+
observability: AgentTurnObservability;
|
|
24
|
+
};
|
|
21
25
|
type AgentChatModelSpec = {
|
|
22
26
|
model: AgentChatModel;
|
|
23
27
|
middleware: AgentMiddleware[];
|
|
@@ -27,8 +31,7 @@ declare class AgentLlmMetricsLogger extends BaseCallbackHandler {
|
|
|
27
31
|
lc_prefer_streaming: boolean;
|
|
28
32
|
private readonly pendingRuns;
|
|
29
33
|
handleLLMStart(_llm: unknown, _prompts: string[], runId: string): Promise<void>;
|
|
30
|
-
|
|
31
|
-
handleLLMEnd(output: LLMResult, runId: string): Promise<void>;
|
|
34
|
+
handleLLMEnd(_output: LLMResult, runId: string): Promise<void>;
|
|
32
35
|
handleLLMError(_error: unknown, runId: string): Promise<void>;
|
|
33
36
|
}
|
|
34
37
|
export declare function createAgentLlmMetricsLogger(): AgentLlmMetricsLogger;
|
|
@@ -37,4 +40,3 @@ export declare function createAgentChatModel(params: {
|
|
|
37
40
|
maxTokens: number;
|
|
38
41
|
purpose: AgentModelPurpose;
|
|
39
42
|
}): Promise<AgentChatModelSpec>;
|
|
40
|
-
export {};
|
|
@@ -0,0 +1,65 @@
|
|
|
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 { BaseCallbackHandler } from "@langchain/core/callbacks/base";
|
|
11
|
+
function isLangChainAgentCompletionAdapter(adapter) {
|
|
12
|
+
return typeof adapter
|
|
13
|
+
.getLangChainAgentSpec === "function";
|
|
14
|
+
}
|
|
15
|
+
function getAgentChatModelSpec(params) {
|
|
16
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
17
|
+
var _a;
|
|
18
|
+
const spec = yield params.adapter.getLangChainAgentSpec({
|
|
19
|
+
maxTokens: params.maxTokens,
|
|
20
|
+
purpose: params.purpose,
|
|
21
|
+
});
|
|
22
|
+
return {
|
|
23
|
+
model: spec.model,
|
|
24
|
+
middleware: ((_a = spec.middleware) !== null && _a !== void 0 ? _a : []),
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
class AgentLlmMetricsLogger extends BaseCallbackHandler {
|
|
29
|
+
constructor() {
|
|
30
|
+
super(...arguments);
|
|
31
|
+
this.name = "AgentLlmMetricsLogger";
|
|
32
|
+
this.lc_prefer_streaming = true;
|
|
33
|
+
this.pendingRuns = new Map();
|
|
34
|
+
}
|
|
35
|
+
handleLLMStart(_llm, _prompts, runId) {
|
|
36
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
37
|
+
this.pendingRuns.set(runId, { startedAt: Date.now() });
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
handleLLMEnd(_output, runId) {
|
|
41
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
42
|
+
this.pendingRuns.delete(runId);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
handleLLMError(_error, runId) {
|
|
46
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
47
|
+
this.pendingRuns.delete(runId);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export function createAgentLlmMetricsLogger() {
|
|
52
|
+
return new AgentLlmMetricsLogger();
|
|
53
|
+
}
|
|
54
|
+
export function createAgentChatModel(params) {
|
|
55
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
56
|
+
if (!isLangChainAgentCompletionAdapter(params.adapter)) {
|
|
57
|
+
throw new Error("AdminForth Agent requires completionAdapter to implement getLangChainAgentSpec({ maxTokens, purpose }).");
|
|
58
|
+
}
|
|
59
|
+
return yield getAgentChatModelSpec({
|
|
60
|
+
adapter: params.adapter,
|
|
61
|
+
maxTokens: params.maxTokens,
|
|
62
|
+
purpose: params.purpose,
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
}
|
|
@@ -1,15 +1,27 @@
|
|
|
1
1
|
import type { IAdminForth } from "adminforth";
|
|
2
2
|
import type { BaseCheckpointSaver } from "@langchain/langgraph";
|
|
3
|
-
import type {
|
|
4
|
-
import type {
|
|
3
|
+
import type { SteerBuffer } from "../domain/steerBuffer.js";
|
|
4
|
+
import type { AgentToolProvider } from "../tools/agentToolProvider.js";
|
|
5
|
+
import type { AgentRuntimeRunInput, AgentTurnModels } from "./agentModels.js";
|
|
5
6
|
export type AgentRuntimeOptions = {
|
|
6
7
|
name: string;
|
|
7
8
|
getAdminforth: () => IAdminForth;
|
|
8
9
|
getCheckpointer: () => BaseCheckpointSaver;
|
|
9
10
|
toolProvider: AgentToolProvider;
|
|
11
|
+
/** Per-session buffer of mid-turn steering instructions drained by the steer middleware. */
|
|
12
|
+
steerBuffer: SteerBuffer;
|
|
10
13
|
};
|
|
11
14
|
export declare class AgentRuntime {
|
|
12
15
|
private readonly options;
|
|
13
16
|
constructor(options: AgentRuntimeOptions);
|
|
14
17
|
stream(input: AgentRuntimeRunInput): Promise<import("@langchain/core/utils/stream").IterableReadableStream<["messages", [import("langchain").BaseMessage<import("@langchain/core/messages").MessageStructure<import("@langchain/core/messages").MessageToolSet>, import("@langchain/core/messages").MessageType>, Record<string, any>]] | ["updates", Record<string, Omit<import("langchain").BuiltInState<import("@langchain/core/messages").MessageStructure<import("langchain").ToolsToMessageToolSet<readonly (import("@langchain/core/tools").ClientTool | import("@langchain/core/tools").ServerTool)[]>>>, "jumpTo">>]>>;
|
|
18
|
+
/**
|
|
19
|
+
* Read the pending human-in-the-loop interrupts persisted for a thread from the
|
|
20
|
+
* checkpointer. Builds a minimal agent (model + checkpointer + HITL middleware) and
|
|
21
|
+
* queries its state — no model call is made. Returns raw LangGraph interrupt objects.
|
|
22
|
+
*/
|
|
23
|
+
getPendingInterrupts(input: {
|
|
24
|
+
models: AgentTurnModels;
|
|
25
|
+
sessionId: string;
|
|
26
|
+
}): Promise<unknown[]>;
|
|
15
27
|
}
|
|
@@ -8,10 +8,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { createAgent, summarizationMiddleware, humanInTheLoopMiddleware } from "langchain";
|
|
11
|
-
import { createApiBasedToolsMiddleware } from "
|
|
12
|
-
import { createSequenceDebugMiddleware } from "
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
11
|
+
import { createApiBasedToolsMiddleware } from "./middleware/apiToolsMiddleware.js";
|
|
12
|
+
import { createSequenceDebugMiddleware } from "./middleware/sequenceDebug.js";
|
|
13
|
+
import { createSteerMiddleware } from "./middleware/steerMiddleware.js";
|
|
14
|
+
import { createAgentLlmMetricsLogger } from "./agentModels.js";
|
|
15
|
+
import { contextSchema, toLangchainAgentContext } from "./agentContext.js";
|
|
15
16
|
function createHumanInTheLoopInterrupts(apiBasedTools) {
|
|
16
17
|
return Object.fromEntries(Object.entries(apiBasedTools)
|
|
17
18
|
.filter(([, apiBasedTool]) => { var _a; return ((_a = apiBasedTool.agent) === null || _a === void 0 ? void 0 : _a.isDangerous) === true; })
|
|
@@ -33,12 +34,17 @@ export class AgentRuntime {
|
|
|
33
34
|
const tools = yield this.options.toolProvider.getTools(apiBasedTools);
|
|
34
35
|
const adminforth = this.options.getAdminforth();
|
|
35
36
|
const apiBasedToolsMiddleware = createApiBasedToolsMiddleware(apiBasedTools, adminforth);
|
|
36
|
-
|
|
37
|
+
// The domain exposes only the narrow DebugSink; the concrete collector (with the
|
|
38
|
+
// model-call hooks the debug middleware needs) is an llm-layer detail.
|
|
39
|
+
const sequenceDebugSink = input.observability.sequenceDebugSink;
|
|
40
|
+
const sequenceDebugMiddleware = createSequenceDebugMiddleware(sequenceDebugSink);
|
|
37
41
|
const hitlMiddleware = humanInTheLoopMiddleware({
|
|
38
42
|
interruptOn: createHumanInTheLoopInterrupts(apiBasedTools),
|
|
39
43
|
descriptionPrefix: "Tool execution pending approval",
|
|
40
44
|
});
|
|
45
|
+
const steerMiddleware = createSteerMiddleware(this.options.steerBuffer);
|
|
41
46
|
const middleware = [
|
|
47
|
+
steerMiddleware,
|
|
42
48
|
apiBasedToolsMiddleware,
|
|
43
49
|
hitlMiddleware,
|
|
44
50
|
...((_a = input.models.modelMiddleware) !== null && _a !== void 0 ? _a : []),
|
|
@@ -65,8 +71,37 @@ export class AgentRuntime {
|
|
|
65
71
|
configurable: {
|
|
66
72
|
thread_id: input.context.sessionId,
|
|
67
73
|
},
|
|
68
|
-
context: toLangchainAgentContext(Object.assign(Object.assign({}, input.context), { adminBaseUrl: adminforth.config.baseUrlSlashed, emit: input.observability.emit, sequenceDebugSink
|
|
74
|
+
context: toLangchainAgentContext(Object.assign(Object.assign({}, input.context), { adminBaseUrl: adminforth.config.baseUrlSlashed, emit: input.observability.emit, sequenceDebugSink })),
|
|
69
75
|
});
|
|
70
76
|
});
|
|
71
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* Read the pending human-in-the-loop interrupts persisted for a thread from the
|
|
80
|
+
* checkpointer. Builds a minimal agent (model + checkpointer + HITL middleware) and
|
|
81
|
+
* queries its state — no model call is made. Returns raw LangGraph interrupt objects.
|
|
82
|
+
*/
|
|
83
|
+
getPendingInterrupts(input) {
|
|
84
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
85
|
+
const apiBasedTools = this.options.toolProvider.getApiBasedTools();
|
|
86
|
+
const tools = yield this.options.toolProvider.getTools(apiBasedTools);
|
|
87
|
+
const agent = createAgent({
|
|
88
|
+
name: this.options.name,
|
|
89
|
+
model: input.models.model,
|
|
90
|
+
checkpointer: this.options.getCheckpointer(),
|
|
91
|
+
tools,
|
|
92
|
+
contextSchema,
|
|
93
|
+
middleware: [
|
|
94
|
+
humanInTheLoopMiddleware({
|
|
95
|
+
interruptOn: createHumanInTheLoopInterrupts(apiBasedTools),
|
|
96
|
+
descriptionPrefix: "Tool execution pending approval",
|
|
97
|
+
}),
|
|
98
|
+
],
|
|
99
|
+
});
|
|
100
|
+
const state = yield agent.getState({
|
|
101
|
+
configurable: { thread_id: input.sessionId },
|
|
102
|
+
});
|
|
103
|
+
const tasks = Array.isArray(state === null || state === void 0 ? void 0 : state.tasks) ? state.tasks : [];
|
|
104
|
+
return tasks.flatMap((task) => (Array.isArray(task === null || task === void 0 ? void 0 : task.interrupts) ? task.interrupts : []));
|
|
105
|
+
});
|
|
106
|
+
}
|
|
72
107
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { AgentRuntime } from "./agentRuntime.js";
|
|
2
|
+
import type { AgentModelFactory } from "./modelFactory.js";
|
|
3
|
+
import { type PreviousUserMessage } from "../domain/languageDetect.js";
|
|
4
|
+
import type { AgentModeCompletionAdapter, LlmPort, LlmStreamInput } from "../application/ports.js";
|
|
5
|
+
import type { PendingInterrupt } from "../domain/turnTypes.js";
|
|
6
|
+
/**
|
|
7
|
+
* LangChain/LangGraph implementation of {@link LlmPort}. This is the single
|
|
8
|
+
* place that knows about the agent graph, model construction, and the raw
|
|
9
|
+
* stream shape; the application layer talks only to the port.
|
|
10
|
+
*/
|
|
11
|
+
export declare class LangGraphLlm implements LlmPort {
|
|
12
|
+
private readonly runtime;
|
|
13
|
+
private readonly modelFactory;
|
|
14
|
+
constructor(runtime: AgentRuntime, modelFactory: AgentModelFactory);
|
|
15
|
+
streamTurn(input: LlmStreamInput): Promise<AsyncGenerator<import("../domain/turnTypes.js").AgentStreamChunk, any, any>>;
|
|
16
|
+
detectLanguage(input: {
|
|
17
|
+
completionAdapter: AgentModeCompletionAdapter;
|
|
18
|
+
prompt: string;
|
|
19
|
+
previousUserMessages: PreviousUserMessage[];
|
|
20
|
+
}): Promise<import("../domain/languageDetect.js").DetectedLanguage | null>;
|
|
21
|
+
getPendingInterrupts(input: {
|
|
22
|
+
completionAdapter: AgentModeCompletionAdapter;
|
|
23
|
+
sessionId: string;
|
|
24
|
+
}): Promise<PendingInterrupt[]>;
|
|
25
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
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 { Command } from "@langchain/langgraph";
|
|
11
|
+
import { HumanMessage, SystemMessage } from "langchain";
|
|
12
|
+
import { detectUserLanguage } from "../domain/languageDetect.js";
|
|
13
|
+
import { adaptRawStream, normalizeInterrupts } from "./streamAdapter.js";
|
|
14
|
+
function toLangchainMessages(messages) {
|
|
15
|
+
return messages.map((message) => message.role === "system"
|
|
16
|
+
? new SystemMessage(message.content)
|
|
17
|
+
: new HumanMessage(message.content));
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* LangChain/LangGraph implementation of {@link LlmPort}. This is the single
|
|
21
|
+
* place that knows about the agent graph, model construction, and the raw
|
|
22
|
+
* stream shape; the application layer talks only to the port.
|
|
23
|
+
*/
|
|
24
|
+
export class LangGraphLlm {
|
|
25
|
+
constructor(runtime, modelFactory) {
|
|
26
|
+
this.runtime = runtime;
|
|
27
|
+
this.modelFactory = modelFactory;
|
|
28
|
+
}
|
|
29
|
+
streamTurn(input) {
|
|
30
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
31
|
+
const models = yield this.modelFactory.create(input.completionAdapter);
|
|
32
|
+
const runtimeInput = "resume" in input.input
|
|
33
|
+
? new Command({ resume: input.input.resume })
|
|
34
|
+
: { messages: toLangchainMessages(input.input.messages) };
|
|
35
|
+
const rawStream = yield this.runtime.stream({
|
|
36
|
+
models,
|
|
37
|
+
input: runtimeInput,
|
|
38
|
+
context: input.context,
|
|
39
|
+
observability: input.observability,
|
|
40
|
+
});
|
|
41
|
+
return adaptRawStream(rawStream);
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
detectLanguage(input) {
|
|
45
|
+
return detectUserLanguage(input.completionAdapter, input.prompt, input.previousUserMessages);
|
|
46
|
+
}
|
|
47
|
+
getPendingInterrupts(input) {
|
|
48
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
49
|
+
const models = yield this.modelFactory.create(input.completionAdapter);
|
|
50
|
+
const raw = yield this.runtime.getPendingInterrupts({ models, sessionId: input.sessionId });
|
|
51
|
+
return normalizeInterrupts(raw);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { type IAdminForth } from "adminforth";
|
|
2
|
-
import { type ApiBasedTool } from "../../apiBasedTools.js";
|
|
2
|
+
import { type ApiBasedTool } from "../../tools/apiBasedTools.js";
|
|
3
3
|
export declare function createApiBasedToolsMiddleware(apiBasedTools: Record<string, ApiBasedTool>, adminforth: IAdminForth): import("langchain").AgentMiddleware<undefined, undefined, unknown, readonly (import("@langchain/core/tools").ClientTool | import("@langchain/core/tools").ServerTool)[]>;
|
|
@@ -11,11 +11,11 @@ import { ToolMessage } from "@langchain/core/messages";
|
|
|
11
11
|
import { isGraphInterrupt } from "@langchain/langgraph";
|
|
12
12
|
import { createMiddleware } from "langchain";
|
|
13
13
|
import { logger } from "adminforth";
|
|
14
|
-
import { formatApiBasedToolCall, } from "../../apiBasedTools.js";
|
|
15
|
-
import { createToolCallTracker, } from "
|
|
16
|
-
import { ALWAYS_AVAILABLE_API_TOOL_NAMES } from "
|
|
17
|
-
import { createApiTool } from "
|
|
18
|
-
import { isAbortError } from "../../errors.js";
|
|
14
|
+
import { formatApiBasedToolCall, } from "../../tools/apiBasedTools.js";
|
|
15
|
+
import { createToolCallTracker, } from "../../domain/toolCallEvents.js";
|
|
16
|
+
import { ALWAYS_AVAILABLE_API_TOOL_NAMES } from "../../tools/index.js";
|
|
17
|
+
import { createApiTool } from "../../tools/apiTool.js";
|
|
18
|
+
import { isAbortError } from "../../shared/errors.js";
|
|
19
19
|
function getEnabledApiToolNames(messages) {
|
|
20
20
|
const enabledToolNames = new Set();
|
|
21
21
|
for (const message of messages) {
|
|
@@ -58,15 +58,13 @@ export function createApiBasedToolsMiddleware(apiBasedTools, adminforth) {
|
|
|
58
58
|
.filter((toolName) => !alwaysAvailableApiToolNames.has(toolName))
|
|
59
59
|
.map((toolName) => dynamicTools[toolName]);
|
|
60
60
|
const availableTools = [...request.tools, ...tools];
|
|
61
|
-
logger.info(`AdminForth Agent callable tools: ${availableTools.map((tool) => tool.name).join(", ")}`);
|
|
62
61
|
return handler(Object.assign(Object.assign({}, request), { tools: availableTools }));
|
|
63
62
|
});
|
|
64
63
|
},
|
|
65
64
|
wrapToolCall(request, handler) {
|
|
66
65
|
return __awaiter(this, void 0, void 0, function* () {
|
|
67
|
-
var _a, _b
|
|
66
|
+
var _a, _b;
|
|
68
67
|
const startedAt = Date.now();
|
|
69
|
-
const toolInput = JSON.stringify((_a = request.toolCall.args) !== null && _a !== void 0 ? _a : {});
|
|
70
68
|
if (!request.toolCall.id) {
|
|
71
69
|
throw new Error(`Tool call "${request.toolCall.name}" has no id.`);
|
|
72
70
|
}
|
|
@@ -79,7 +77,7 @@ export function createApiBasedToolsMiddleware(apiBasedTools, adminforth) {
|
|
|
79
77
|
data: event,
|
|
80
78
|
}));
|
|
81
79
|
};
|
|
82
|
-
const toolArgs = ((
|
|
80
|
+
const toolArgs = ((_a = request.toolCall.args) !== null && _a !== void 0 ? _a : {});
|
|
83
81
|
let toolInfo;
|
|
84
82
|
if (request.toolCall.name === "fetch_skill") {
|
|
85
83
|
toolInfo = `Load ${toolArgs.skillName.split("_").join(" ")} skill`;
|
|
@@ -105,7 +103,6 @@ export function createApiBasedToolsMiddleware(apiBasedTools, adminforth) {
|
|
|
105
103
|
startedAt,
|
|
106
104
|
});
|
|
107
105
|
toolCallTracker.start();
|
|
108
|
-
logger.info(`Invoking tool "${request.toolCall.name}" with input: ${toolInput}`);
|
|
109
106
|
try {
|
|
110
107
|
const result = getEnabledApiToolNames(request.state.messages).has(request.toolCall.name)
|
|
111
108
|
? yield handler(Object.assign(Object.assign({}, request), { tool: dynamicTools[request.toolCall.name] }))
|
|
@@ -120,7 +117,7 @@ export function createApiBasedToolsMiddleware(apiBasedTools, adminforth) {
|
|
|
120
117
|
throw error;
|
|
121
118
|
}
|
|
122
119
|
const message = error instanceof Error ? error.message : String(error);
|
|
123
|
-
logger.error(`Error calling tool "${request.toolCall.name}": ${error instanceof Error ? (
|
|
120
|
+
logger.error(`Error calling tool "${request.toolCall.name}": ${error instanceof Error ? (_b = error.stack) !== null && _b !== void 0 ? _b : error.message : String(error)}`);
|
|
124
121
|
toolCallTracker.finishError(`Error: ${message}`);
|
|
125
122
|
return new ToolMessage({
|
|
126
123
|
name: request.toolCall.name,
|
|
@@ -129,9 +126,6 @@ export function createApiBasedToolsMiddleware(apiBasedTools, adminforth) {
|
|
|
129
126
|
content: `Error: ${message}`,
|
|
130
127
|
});
|
|
131
128
|
}
|
|
132
|
-
finally {
|
|
133
|
-
logger.info(`Tool "${request.toolCall.name}" finished in ${Date.now() - startedAt}ms`);
|
|
134
|
-
}
|
|
135
129
|
});
|
|
136
130
|
},
|
|
137
131
|
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { AgentEventEmitter } from "../../domain/agentEvents.js";
|
|
3
|
+
import type { SteerBuffer } from "../../domain/steerBuffer.js";
|
|
4
|
+
/**
|
|
5
|
+
* `beforeModel` middleware that folds user "steering" instructions into a running
|
|
6
|
+
* turn. Before every model call in the agent loop it drains the per-session
|
|
7
|
+
* {@link SteerBuffer}; any buffered steers are appended to the conversation as
|
|
8
|
+
* user messages (so the model sees them on the very next call) and a
|
|
9
|
+
* `steer-applied` event is emitted on the turn's already-open SSE stream so the
|
|
10
|
+
* frontend knows the steer was actually consumed (not just received/queued).
|
|
11
|
+
*
|
|
12
|
+
* Placed first in the middleware array so the injected messages are present for
|
|
13
|
+
* every downstream `beforeModel` hook (e.g. summarization) and the model itself.
|
|
14
|
+
*/
|
|
15
|
+
export declare function createSteerMiddleware(steerBuffer: SteerBuffer): import("langchain").AgentMiddleware<undefined, z.ZodObject<{
|
|
16
|
+
sessionId: z.ZodString;
|
|
17
|
+
emit: z.ZodOptional<z.ZodCustom<AgentEventEmitter, AgentEventEmitter>>;
|
|
18
|
+
}, z.core.$strip>, {
|
|
19
|
+
sessionId: string;
|
|
20
|
+
emit?: AgentEventEmitter | undefined;
|
|
21
|
+
}, readonly (import("@langchain/core/tools").ClientTool | import("@langchain/core/tools").ServerTool)[]>;
|
|
@@ -0,0 +1,50 @@
|
|
|
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 { HumanMessage } from "langchain";
|
|
11
|
+
import { createMiddleware } from "langchain";
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
const steerContextSchema = z.object({
|
|
14
|
+
sessionId: z.string(),
|
|
15
|
+
emit: z.custom().optional(),
|
|
16
|
+
});
|
|
17
|
+
/**
|
|
18
|
+
* `beforeModel` middleware that folds user "steering" instructions into a running
|
|
19
|
+
* turn. Before every model call in the agent loop it drains the per-session
|
|
20
|
+
* {@link SteerBuffer}; any buffered steers are appended to the conversation as
|
|
21
|
+
* user messages (so the model sees them on the very next call) and a
|
|
22
|
+
* `steer-applied` event is emitted on the turn's already-open SSE stream so the
|
|
23
|
+
* frontend knows the steer was actually consumed (not just received/queued).
|
|
24
|
+
*
|
|
25
|
+
* Placed first in the middleware array so the injected messages are present for
|
|
26
|
+
* every downstream `beforeModel` hook (e.g. summarization) and the model itself.
|
|
27
|
+
*/
|
|
28
|
+
export function createSteerMiddleware(steerBuffer) {
|
|
29
|
+
return createMiddleware({
|
|
30
|
+
name: "SteerMiddleware",
|
|
31
|
+
contextSchema: steerContextSchema,
|
|
32
|
+
beforeModel(_state, runtime) {
|
|
33
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
34
|
+
const { sessionId, emit } = runtime.context;
|
|
35
|
+
const steers = steerBuffer.drain(sessionId);
|
|
36
|
+
if (steers.length === 0) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
void (emit === null || emit === void 0 ? void 0 : emit({
|
|
40
|
+
type: "steer-applied",
|
|
41
|
+
count: steers.length,
|
|
42
|
+
ids: steers.map((steer) => steer.id),
|
|
43
|
+
}));
|
|
44
|
+
return {
|
|
45
|
+
messages: steers.map((steer) => new HumanMessage(`[User steering — new instruction sent mid-turn, take it into account from now on]\n${steer.text}`)),
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CompletionAdapter } from "adminforth";
|
|
2
|
-
import type
|
|
2
|
+
import { type AgentTurnModels } from "./agentModels.js";
|
|
3
3
|
export declare class AgentModelFactory {
|
|
4
4
|
private readonly maxTokens;
|
|
5
5
|
constructor(maxTokens: number);
|
|
@@ -7,7 +7,7 @@ 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 { createAgentChatModel } from "
|
|
10
|
+
import { createAgentChatModel } from "./agentModels.js";
|
|
11
11
|
export class AgentModelFactory {
|
|
12
12
|
constructor(maxTokens) {
|
|
13
13
|
this.maxTokens = maxTokens;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { AgentStreamChunk, PendingInterrupt } from "../domain/turnTypes.js";
|
|
2
|
+
/**
|
|
3
|
+
* Normalize raw LangGraph interrupt object(s) into provider-agnostic descriptors.
|
|
4
|
+
* Kept in the llm layer so the LangGraph interrupt shape never reaches the app.
|
|
5
|
+
*/
|
|
6
|
+
export declare function normalizeInterrupts(interrupt: unknown): PendingInterrupt[];
|
|
7
|
+
type RawStreamEntry = ["messages", [any, any]] | ["updates", Record<string, any>];
|
|
8
|
+
/**
|
|
9
|
+
* Convert one raw LangGraph stream entry into zero or more normalized chunks.
|
|
10
|
+
* Pure and synchronous so the parsing rules can be unit-tested in isolation.
|
|
11
|
+
*/
|
|
12
|
+
export declare function parseRawStreamChunk(entry: RawStreamEntry): AgentStreamChunk[];
|
|
13
|
+
/**
|
|
14
|
+
* Adapt the raw LangGraph `["messages" | "updates", ...]` stream into a typed
|
|
15
|
+
* `AgentStreamChunk` stream for the application layer.
|
|
16
|
+
*/
|
|
17
|
+
export declare function adaptRawStream(raw: AsyncIterable<RawStreamEntry>): AsyncGenerator<AgentStreamChunk>;
|
|
18
|
+
export {};
|