@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.
Files changed (201) hide show
  1. package/README.md +333 -10
  2. package/dist/application/ports.d.ts +66 -0
  3. package/dist/application/runTurnUseCase.d.ts +71 -0
  4. package/dist/application/runTurnUseCase.js +364 -0
  5. package/dist/custom/ChatFooter.vue +58 -30
  6. package/dist/custom/SteerDebugPanel.vue +45 -0
  7. package/dist/custom/SteerQueue.vue +54 -0
  8. package/dist/custom/composables/agentStore/constants.ts +1 -0
  9. package/dist/custom/composables/agentStore/useAgentSessions.ts +35 -16
  10. package/dist/custom/composables/agentStore/useAgentSteerQueue.ts +114 -0
  11. package/dist/custom/composables/useAgentStore.ts +46 -1
  12. package/dist/custom/conversation_area/MessageRenderer.vue +7 -1
  13. package/dist/custom/speech_recognition_frontend/AudioLines.vue +1 -1
  14. package/dist/custom/speech_recognition_frontend/MicrophoneButon.vue +3 -3
  15. package/dist/{agentEvents.d.ts → domain/agentEvents.d.ts} +5 -1
  16. package/dist/domain/steerBuffer.d.ts +33 -0
  17. package/dist/domain/steerBuffer.js +51 -0
  18. package/dist/{agent → domain}/systemPrompt.js +1 -1
  19. package/dist/{agent/turn → domain}/turnTypes.d.ts +41 -37
  20. package/dist/{agent/turn/VegaLiteStreamBuffer.d.ts → domain/vegaLiteStreamBuffer.d.ts} +1 -1
  21. package/dist/index.d.ts +4 -2
  22. package/dist/index.js +49 -35
  23. package/dist/{agent/runtime/AgentContext.d.ts → llm/agentContext.d.ts} +3 -3
  24. package/dist/{agent/simpleAgent.d.ts → llm/agentModels.d.ts} +18 -16
  25. package/dist/llm/agentModels.js +65 -0
  26. package/dist/{agent/runtime/AgentRuntime.d.ts → llm/agentRuntime.d.ts} +14 -2
  27. package/dist/{agent/runtime/AgentRuntime.js → llm/agentRuntime.js} +41 -6
  28. package/dist/llm/langGraphLlm.d.ts +25 -0
  29. package/dist/llm/langGraphLlm.js +54 -0
  30. package/dist/{agent/middleware/apiBasedTools.d.ts → llm/middleware/apiToolsMiddleware.d.ts} +1 -1
  31. package/dist/{agent/middleware/apiBasedTools.js → llm/middleware/apiToolsMiddleware.js} +8 -14
  32. package/dist/{agent → llm}/middleware/sequenceDebug.d.ts +1 -1
  33. package/dist/llm/middleware/steerMiddleware.d.ts +21 -0
  34. package/dist/llm/middleware/steerMiddleware.js +50 -0
  35. package/dist/{agent/models/AgentModelFactory.d.ts → llm/modelFactory.d.ts} +1 -1
  36. package/dist/{agent/models/AgentModelFactory.js → llm/modelFactory.js} +1 -1
  37. package/dist/llm/streamAdapter.d.ts +18 -0
  38. package/dist/llm/streamAdapter.js +117 -0
  39. package/dist/{sessionStore.d.ts → persistence/sessionStore.d.ts} +19 -2
  40. package/dist/{sessionStore.js → persistence/sessionStore.js} +53 -0
  41. package/dist/{agent/tools/AgentToolProvider.d.ts → tools/agentToolProvider.d.ts} +1 -1
  42. package/dist/{agent/tools/AgentToolProvider.js → tools/agentToolProvider.js} +1 -1
  43. package/dist/{apiBasedTools.js → tools/apiBasedTools.js} +0 -3
  44. package/dist/{agent/tools → tools}/apiTool.d.ts +1 -1
  45. package/dist/{agent/tools → tools}/fetchSkill.js +1 -1
  46. package/dist/{agent/tools → tools}/fetchToolSchema.d.ts +1 -1
  47. package/dist/{agent/tools → tools}/index.d.ts +1 -1
  48. package/dist/{agent/tools → tools}/navigateUser.d.ts +3 -3
  49. package/dist/{endpoints → transport/http}/context.d.ts +12 -4
  50. package/dist/transport/http/context.js +1 -0
  51. package/dist/{endpoints/core.js → transport/http/coreEndpoints.js} +23 -3
  52. package/dist/{endpoints/sessions.js → transport/http/sessionEndpoints.js} +36 -1
  53. package/dist/transport/sse/sseWriter.d.ts +29 -0
  54. package/dist/{surfaces/web-sse/createSseEventEmitter.js → transport/sse/sseWriter.js} +27 -0
  55. package/dist/{chatSurfaceService.d.ts → transport/surfaces/chatSurfaceService.d.ts} +3 -3
  56. package/dist/{chatSurfaceService.js → transport/surfaces/chatSurfaceService.js} +7 -5
  57. package/dist/{agent/speech/SpeechTurnService.d.ts → transport/surfaces/speechTurnService.d.ts} +1 -1
  58. package/dist/{agent/speech/SpeechTurnService.js → transport/surfaces/speechTurnService.js} +2 -2
  59. package/dist/types.d.ts +10 -4
  60. package/package.json +11 -2
  61. package/.woodpecker/buildRelease.sh +0 -13
  62. package/.woodpecker/buildSlackNotify.sh +0 -46
  63. package/.woodpecker/release.yml +0 -57
  64. package/agent/checkpointer.ts +0 -329
  65. package/agent/languageDetect.ts +0 -92
  66. package/agent/middleware/apiBasedTools.ts +0 -174
  67. package/agent/middleware/openAiResponsesContinuation.ts +0 -92
  68. package/agent/middleware/sequenceDebug.ts +0 -429
  69. package/agent/models/AgentModeResolver.ts +0 -9
  70. package/agent/models/AgentModelFactory.ts +0 -28
  71. package/agent/runtime/AgentContext.ts +0 -30
  72. package/agent/runtime/AgentRuntime.ts +0 -89
  73. package/agent/simpleAgent.ts +0 -199
  74. package/agent/skills/registry.ts +0 -162
  75. package/agent/speech/SpeechTurnService.ts +0 -179
  76. package/agent/systemPrompt.ts +0 -133
  77. package/agent/toolCallEvents.ts +0 -135
  78. package/agent/tools/AgentToolProvider.ts +0 -28
  79. package/agent/tools/apiTool.ts +0 -66
  80. package/agent/tools/fetchSkill.ts +0 -68
  81. package/agent/tools/fetchToolSchema.ts +0 -47
  82. package/agent/tools/getUserLocation.ts +0 -45
  83. package/agent/tools/index.ts +0 -31
  84. package/agent/tools/navigateUser.ts +0 -210
  85. package/agent/turn/TurnContextBuilder.ts +0 -36
  86. package/agent/turn/TurnLifecycleService.ts +0 -47
  87. package/agent/turn/TurnPersistenceService.ts +0 -33
  88. package/agent/turn/TurnPromptBuilder.ts +0 -51
  89. package/agent/turn/TurnStreamConsumer.ts +0 -69
  90. package/agent/turn/VegaLiteStreamBuffer.ts +0 -90
  91. package/agent/turn/turnTypes.ts +0 -100
  92. package/agentEvents.ts +0 -75
  93. package/agentTurnService.ts +0 -314
  94. package/apiBasedTools.ts +0 -712
  95. package/build.log +0 -67
  96. package/chatSurfaceService.ts +0 -319
  97. package/custom/ChatFooter.vue +0 -173
  98. package/custom/ChatHeader.vue +0 -78
  99. package/custom/ChatSurface.vue +0 -160
  100. package/custom/CustomAutoScrollContainer.vue +0 -164
  101. package/custom/SessionsHistory.vue +0 -88
  102. package/custom/chat.ts +0 -82
  103. package/custom/composables/agentAudio/utils.ts +0 -220
  104. package/custom/composables/agentStore/constants.ts +0 -19
  105. package/custom/composables/agentStore/pageContext.ts +0 -8
  106. package/custom/composables/agentStore/useAgentChat.ts +0 -241
  107. package/custom/composables/agentStore/useAgentPlaceholder.ts +0 -142
  108. package/custom/composables/agentStore/useAgentSessions.ts +0 -350
  109. package/custom/composables/useAgentAudio.ts +0 -272
  110. package/custom/composables/useAgentStore.ts +0 -510
  111. package/custom/composables/useAgentTransitions.ts +0 -58
  112. package/custom/conversation_area/ConversationArea.vue +0 -301
  113. package/custom/conversation_area/MessageRenderer.vue +0 -49
  114. package/custom/conversation_area/ProcessingTimeline.vue +0 -286
  115. package/custom/conversation_area/ReasoningRenderer.vue +0 -79
  116. package/custom/conversation_area/SystemMessageRenderer.vue +0 -28
  117. package/custom/conversation_area/TextRenderer.vue +0 -182
  118. package/custom/conversation_area/ThreeDotsAnimation.vue +0 -35
  119. package/custom/conversation_area/ToolApprovalRenderer.vue +0 -98
  120. package/custom/conversation_area/ToolRenderer.vue +0 -178
  121. package/custom/conversation_area/ToolsGroup.vue +0 -59
  122. package/custom/env.d.ts +0 -7
  123. package/custom/incremark_code_renderers/IncremarkShikiCodeBlock.vue +0 -393
  124. package/custom/incremark_code_renderers/incremarkCodeHighlight.ts +0 -285
  125. package/custom/incremark_code_renderers/incremarkRenderer.ts +0 -653
  126. package/custom/incremark_code_renderers/renderIncremarkMarkdown.ts +0 -118
  127. package/custom/package.json +0 -30
  128. package/custom/pnpm-lock.yaml +0 -2394
  129. package/custom/public/agentAudio/agent-processing.mp3 +0 -0
  130. package/custom/skills/analyze_data/SKILL.md +0 -25
  131. package/custom/skills/charts/SKILL.md +0 -193
  132. package/custom/skills/fetch_data/SKILL.md +0 -31
  133. package/custom/skills/mutate_data/SKILL.md +0 -121
  134. package/custom/speech_recognition_frontend/AudioLines.vue +0 -43
  135. package/custom/speech_recognition_frontend/MicrophoneButon.vue +0 -185
  136. package/custom/speech_recognition_frontend/types/voice-activity-detection.d.ts +0 -22
  137. package/custom/speech_recognition_frontend/voiceActivityDetection.ts +0 -62
  138. package/custom/tsconfig.json +0 -15
  139. package/custom/types.ts +0 -108
  140. package/custom/utils.ts +0 -38
  141. package/dist/agent/middleware/openAiResponsesContinuation.d.ts +0 -1
  142. package/dist/agent/middleware/openAiResponsesContinuation.js +0 -66
  143. package/dist/agent/models/AgentModeResolver.d.ts +0 -9
  144. package/dist/agent/models/AgentModeResolver.js +0 -9
  145. package/dist/agent/simpleAgent.js +0 -118
  146. package/dist/agent/turn/TurnContextBuilder.d.ts +0 -14
  147. package/dist/agent/turn/TurnContextBuilder.js +0 -31
  148. package/dist/agent/turn/TurnLifecycleService.d.ts +0 -24
  149. package/dist/agent/turn/TurnLifecycleService.js +0 -47
  150. package/dist/agent/turn/TurnPersistenceService.d.ts +0 -13
  151. package/dist/agent/turn/TurnPersistenceService.js +0 -35
  152. package/dist/agent/turn/TurnPromptBuilder.d.ts +0 -19
  153. package/dist/agent/turn/TurnPromptBuilder.js +0 -43
  154. package/dist/agent/turn/TurnStreamConsumer.d.ts +0 -11
  155. package/dist/agent/turn/TurnStreamConsumer.js +0 -84
  156. package/dist/agentTurnService.d.ts +0 -24
  157. package/dist/agentTurnService.js +0 -269
  158. package/dist/surfaces/web-sse/createSseEventEmitter.d.ts +0 -14
  159. package/endpoints/chatSurfaces.ts +0 -66
  160. package/endpoints/context.ts +0 -52
  161. package/endpoints/core.ts +0 -181
  162. package/endpoints/sessions.ts +0 -183
  163. package/errors.ts +0 -10
  164. package/index.ts +0 -192
  165. package/pnpm-workspace.yaml +0 -4
  166. package/sanitizeSpeechText.ts +0 -32
  167. package/sessionStore.ts +0 -105
  168. package/surfaces/web-sse/createSseEventEmitter.ts +0 -311
  169. package/tsconfig.json +0 -14
  170. package/types.ts +0 -127
  171. /package/dist/{agent/turn/turnTypes.js → application/ports.js} +0 -0
  172. /package/dist/{agentEvents.js → domain/agentEvents.js} +0 -0
  173. /package/dist/{agent → domain}/languageDetect.d.ts +0 -0
  174. /package/dist/{agent → domain}/languageDetect.js +0 -0
  175. /package/dist/{agent → domain}/systemPrompt.d.ts +0 -0
  176. /package/dist/{agent → domain}/toolCallEvents.d.ts +0 -0
  177. /package/dist/{agent → domain}/toolCallEvents.js +0 -0
  178. /package/dist/{endpoints/context.js → domain/turnTypes.js} +0 -0
  179. /package/dist/{agent/turn/VegaLiteStreamBuffer.js → domain/vegaLiteStreamBuffer.js} +0 -0
  180. /package/dist/{agent/runtime/AgentContext.js → llm/agentContext.js} +0 -0
  181. /package/dist/{agent → llm}/middleware/sequenceDebug.js +0 -0
  182. /package/dist/{agent/checkpointer.d.ts → persistence/checkpointStore.d.ts} +0 -0
  183. /package/dist/{agent/checkpointer.js → persistence/checkpointStore.js} +0 -0
  184. /package/dist/{errors.d.ts → shared/errors.d.ts} +0 -0
  185. /package/dist/{errors.js → shared/errors.js} +0 -0
  186. /package/dist/{sanitizeSpeechText.d.ts → shared/sanitizeSpeechText.d.ts} +0 -0
  187. /package/dist/{sanitizeSpeechText.js → shared/sanitizeSpeechText.js} +0 -0
  188. /package/dist/{apiBasedTools.d.ts → tools/apiBasedTools.d.ts} +0 -0
  189. /package/dist/{agent/tools → tools}/apiTool.js +0 -0
  190. /package/dist/{agent/tools → tools}/fetchSkill.d.ts +0 -0
  191. /package/dist/{agent/tools → tools}/fetchToolSchema.js +0 -0
  192. /package/dist/{agent/tools → tools}/getUserLocation.d.ts +0 -0
  193. /package/dist/{agent/tools → tools}/getUserLocation.js +0 -0
  194. /package/dist/{agent/tools → tools}/index.js +0 -0
  195. /package/dist/{agent/tools → tools}/navigateUser.js +0 -0
  196. /package/dist/{agent → tools}/skills/registry.d.ts +0 -0
  197. /package/dist/{agent → tools}/skills/registry.js +0 -0
  198. /package/dist/{endpoints/chatSurfaces.d.ts → transport/http/chatSurfaceEndpoints.d.ts} +0 -0
  199. /package/dist/{endpoints/chatSurfaces.js → transport/http/chatSurfaceEndpoints.js} +0 -0
  200. /package/dist/{endpoints/core.d.ts → transport/http/coreEndpoints.d.ts} +0 -0
  201. /package/dist/{endpoints/sessions.d.ts → transport/http/sessionEndpoints.d.ts} +0 -0
package/agentEvents.ts DELETED
@@ -1,75 +0,0 @@
1
- import type { ToolCallEvent } from "./agent/toolCallEvents.js";
2
-
3
- export type AgentEvent =
4
- | {
5
- type: "turn-started";
6
- messageId: string;
7
- }
8
- | {
9
- type: "text-delta";
10
- delta: string;
11
- }
12
- | {
13
- type: "reasoning-delta";
14
- delta: string;
15
- }
16
- | {
17
- type: "tool-call";
18
- data: ToolCallEvent;
19
- }
20
- | {
21
- type: "rendering";
22
- phase: "start" | "end";
23
- label: string;
24
- }
25
- | {
26
- type: "interrupt";
27
- sessionId: string;
28
- interrupt: unknown;
29
- }
30
- | {
31
- type: "open-page";
32
- targetPath: string;
33
- }
34
- | {
35
- type: "transcript";
36
- text: string;
37
- language?: string;
38
- }
39
- | {
40
- type: "response";
41
- text: string;
42
- sessionId: string;
43
- turnId: string;
44
- }
45
- | {
46
- type: "speech-response";
47
- transcript: { text: string; language?: string };
48
- response: { text: string };
49
- sessionId: string;
50
- turnId: string;
51
- }
52
- | {
53
- type: "audio-start";
54
- mimeType: string;
55
- format: string;
56
- sampleRate: number;
57
- channelCount: number;
58
- bitsPerSample: number;
59
- }
60
- | {
61
- type: "audio-delta";
62
- value: Uint8Array;
63
- }
64
- | {
65
- type: "audio-done";
66
- }
67
- | {
68
- type: "error";
69
- error: string;
70
- }
71
- | {
72
- type: "finish";
73
- };
74
-
75
- export type AgentEventEmitter = (event: AgentEvent) => void | Promise<void>;
@@ -1,314 +0,0 @@
1
- import { logger } from "adminforth";
2
- import { randomUUID } from "crypto";
3
- import { Command } from "@langchain/langgraph";
4
- import { AgentModelFactory } from "./agent/models/AgentModelFactory.js";
5
- import { AgentModeResolver } from "./agent/models/AgentModeResolver.js";
6
- import { createSequenceDebugCollector } from "./agent/middleware/sequenceDebug.js";
7
- import { AgentRuntime } from "./agent/runtime/AgentRuntime.js";
8
- import { TurnContextBuilder } from "./agent/turn/TurnContextBuilder.js";
9
- import { TurnLifecycleService } from "./agent/turn/TurnLifecycleService.js";
10
- import { TurnPromptBuilder } from "./agent/turn/TurnPromptBuilder.js";
11
- import { TurnStreamConsumer } from "./agent/turn/TurnStreamConsumer.js";
12
- import type {
13
- BaseAgentTurnInput,
14
- HandleTurnInput,
15
- PreparedAgentTurn,
16
- RunAndPersistAgentResponseInput,
17
- RunAndPersistAgentResponseResult,
18
- } from "./agent/turn/turnTypes.js";
19
- import { getErrorMessage, isAbortError } from "./errors.js";
20
-
21
- export type {
22
- BaseAgentTurnInput,
23
- HandleSpeechTurnInput,
24
- HandleTurnInput,
25
- RunAndPersistAgentResponseInput,
26
- RunAndPersistAgentResponseResult,
27
- } from "./agent/turn/turnTypes.js";
28
-
29
- function getApprovalDecision(input: BaseAgentTurnInput) {
30
- return "approvalDecision" in input
31
- && (input.approvalDecision === "approve" || input.approvalDecision === "reject")
32
- ? input.approvalDecision
33
- : undefined;
34
- }
35
-
36
- function getInterruptItems(interrupt: unknown): unknown[] {
37
- return Array.isArray(interrupt) ? interrupt : [interrupt];
38
- }
39
-
40
- function getHitlInterrupts(interrupt: unknown): { id: string; count: number }[] {
41
- return getInterruptItems(interrupt).flatMap((item) => {
42
- const value = item && typeof item === "object" && "value" in item
43
- ? (item as { value: unknown }).value
44
- : item;
45
- const actionRequests = value && typeof value === "object"
46
- ? (value as { actionRequests?: unknown }).actionRequests
47
- : undefined;
48
- const interruptId = item && typeof item === "object"
49
- ? (item as { id?: unknown }).id
50
- : undefined;
51
-
52
- return typeof interruptId === "string" && Array.isArray(actionRequests)
53
- ? [{ id: interruptId, count: actionRequests.length }]
54
- : [];
55
- });
56
- }
57
-
58
- function buildHitlDecision(decision: "approve" | "reject", prompt?: string) {
59
- if (decision === "approve") {
60
- return { type: "approve" as const };
61
- }
62
-
63
- return {
64
- type: "reject" as const,
65
- message: prompt
66
- ? `User rejected the pending tool execution and sent a new instruction instead: ${prompt}`
67
- : "User rejected executing this tool",
68
- };
69
- }
70
-
71
- function buildHitlResumeValue(input: {
72
- decision: "approve" | "reject";
73
- count: number;
74
- prompt?: string;
75
- }) {
76
- return {
77
- decisions: Array.from({ length: input.count }, () => (
78
- buildHitlDecision(input.decision, input.prompt)
79
- )),
80
- };
81
- }
82
-
83
- function buildLangGraphResume(input: {
84
- decision: "approve" | "reject";
85
- interrupts?: { id: string; count: number }[];
86
- prompt?: string;
87
- }) {
88
- const interrupts = input.interrupts ?? [];
89
-
90
- if (interrupts.length === 0) {
91
- throw new Error("No pending approval interrupt found for resume.");
92
- }
93
-
94
- if (interrupts.length === 1) {
95
- return buildHitlResumeValue({
96
- decision: input.decision,
97
- count: interrupts[0].count,
98
- prompt: input.prompt,
99
- });
100
- }
101
-
102
- return Object.fromEntries(
103
- interrupts.map((interrupt) => [
104
- interrupt.id,
105
- buildHitlResumeValue({
106
- decision: input.decision,
107
- count: interrupt.count,
108
- prompt: input.prompt,
109
- }),
110
- ]),
111
- );
112
- }
113
-
114
- export class AgentTurnService {
115
- private readonly pendingInterrupts = new Map<string, { id: string; count: number }[]>();
116
-
117
- constructor(
118
- private readonly lifecycle: TurnLifecycleService,
119
- private readonly contextBuilder: TurnContextBuilder,
120
- private readonly modeResolver: AgentModeResolver,
121
- private readonly modelFactory: AgentModelFactory,
122
- private readonly promptBuilder: TurnPromptBuilder,
123
- private readonly runtime: AgentRuntime,
124
- private readonly streamConsumer: TurnStreamConsumer,
125
- ) {}
126
-
127
- private async prepareTurn(input: BaseAgentTurnInput): Promise<PreparedAgentTurn> {
128
- const sequenceDebugCollector = createSequenceDebugCollector();
129
- const approvalDecision = getApprovalDecision(input);
130
- const shouldResume = Boolean(approvalDecision);
131
- const pendingInterrupts = this.pendingInterrupts.get(input.sessionId);
132
- if (shouldResume && (!pendingInterrupts || pendingInterrupts.length === 0)) {
133
- throw new Error(`No pending approval interrupt found for session "${input.sessionId}".`);
134
- }
135
- const lifecycleTurn = shouldResume
136
- ? await this.lifecycle.resume(input)
137
- : await this.lifecycle.start(input);
138
- const context = await this.contextBuilder.build({
139
- base: input,
140
- turnId: lifecycleTurn.turnId,
141
- });
142
-
143
- return {
144
- prompt: input.prompt,
145
- sessionId: input.sessionId,
146
- turnId: lifecycleTurn.turnId,
147
- previousUserMessages: lifecycleTurn.previousUserMessages,
148
- modeName: input.modeName,
149
- context,
150
- observability: {
151
- emit: undefined,
152
- sequenceDebugSink: sequenceDebugCollector,
153
- },
154
- resume: shouldResume
155
- ? {
156
- decision: approvalDecision!,
157
- interrupts: pendingInterrupts,
158
- }
159
- : undefined,
160
- initialResponse: shouldResume && "initialResponse" in lifecycleTurn
161
- ? (lifecycleTurn as { initialResponse?: string }).initialResponse
162
- : undefined,
163
- };
164
- }
165
-
166
- private async runAgentTurn(input: PreparedAgentTurn) {
167
- const selectedMode = this.modeResolver.resolve(input.modeName);
168
- const [models, messages] = await Promise.all([
169
- this.modelFactory.create(selectedMode.completionAdapter),
170
- this.promptBuilder.build({
171
- prompt: input.prompt,
172
- previousUserMessages: input.previousUserMessages,
173
- adminUser: input.context.adminUser,
174
- completionAdapter: selectedMode.completionAdapter,
175
- chatSurface: input.context.chatSurface,
176
- abortSignal: input.context.abortSignal,
177
- }),
178
- ]);
179
- const stream = await this.runtime.stream({
180
- models,
181
- input: input.resume
182
- ? new Command({
183
- resume: buildLangGraphResume({
184
- decision: input.resume.decision,
185
- interrupts: input.resume.interrupts,
186
- prompt: input.prompt,
187
- }),
188
- })
189
- : { messages },
190
- context: input.context,
191
- observability: input.observability,
192
- });
193
-
194
- let interrupted = false;
195
- try {
196
- return await this.streamConsumer.consume({
197
- stream: stream as AsyncIterable<["messages", [any, any]] | ["updates", Record<string, any>]>,
198
- abortSignal: input.context.abortSignal,
199
- emit: input.observability.emit,
200
- onInterrupt: async (interrupt) => {
201
- interrupted = true;
202
- const interrupts = getHitlInterrupts(interrupt);
203
- const pendingInterrupts = this.pendingInterrupts.get(input.sessionId) ?? [];
204
- const mergedInterrupts = new Map(
205
- pendingInterrupts.map((pendingInterrupt) => [
206
- pendingInterrupt.id,
207
- pendingInterrupt.count,
208
- ]),
209
- );
210
-
211
- for (const pendingInterrupt of interrupts) {
212
- mergedInterrupts.set(pendingInterrupt.id, pendingInterrupt.count);
213
- }
214
-
215
- this.pendingInterrupts.set(
216
- input.sessionId,
217
- [...mergedInterrupts.entries()].map(([id, count]) => ({ id, count })),
218
- );
219
- await input.observability.emit?.({
220
- type: "interrupt",
221
- sessionId: input.sessionId,
222
- interrupt,
223
- });
224
- },
225
- });
226
- } finally {
227
- if (!interrupted) {
228
- this.pendingInterrupts.delete(input.sessionId);
229
- }
230
- }
231
- }
232
-
233
- async runAndPersistAgentResponse(
234
- input: RunAndPersistAgentResponseInput,
235
- ): Promise<RunAndPersistAgentResponseResult> {
236
- const preparedTurn = await this.prepareTurn(input);
237
- preparedTurn.observability.emit = input.emit;
238
-
239
- let fullResponse = preparedTurn.initialResponse ?? "";
240
- let aborted = false;
241
- let failed = false;
242
-
243
- try {
244
- const agentResponse = await this.runAgentTurn(preparedTurn);
245
- fullResponse += agentResponse.text;
246
- } catch (error) {
247
- if (input.abortSignal?.aborted || isAbortError(error)) {
248
- aborted = true;
249
- logger.info(input.abortLogMessage);
250
- } else {
251
- failed = true;
252
- fullResponse = getErrorMessage(error);
253
- logger.error(`${input.failureLogMessage}:\n${fullResponse}`);
254
- }
255
- }
256
-
257
- preparedTurn.observability.sequenceDebugSink.flush();
258
- await this.lifecycle.finish({
259
- turnId: preparedTurn.turnId,
260
- responseText: fullResponse,
261
- debugHistory: preparedTurn.observability.sequenceDebugSink.getHistory(),
262
- });
263
-
264
- return {
265
- text: fullResponse,
266
- turnId: preparedTurn.turnId,
267
- aborted,
268
- failed,
269
- };
270
- }
271
-
272
- async handleTurn(input: HandleTurnInput) {
273
- await input.emit({
274
- type: "turn-started",
275
- messageId: randomUUID(),
276
- });
277
-
278
- const agentResponse = await this.runAndPersistAgentResponse({
279
- prompt: input.prompt,
280
- sessionId: input.sessionId,
281
- modeName: input.modeName,
282
- userTimeZone: input.userTimeZone,
283
- currentPage: input.currentPage,
284
- chatSurface: input.chatSurface,
285
- adminPublicOrigin: input.adminPublicOrigin,
286
- approvalDecision: input.approvalDecision,
287
- abortSignal: input.abortSignal,
288
- adminUser: input.adminUser,
289
- emit: input.emit,
290
- failureLogMessage: input.failureLogMessage ?? "Agent response failed",
291
- abortLogMessage: input.abortLogMessage ?? "Agent response aborted",
292
- });
293
-
294
- if (agentResponse.failed) {
295
- await input.emit({
296
- type: "error",
297
- error: agentResponse.text,
298
- });
299
- } else if (!agentResponse.aborted) {
300
- await input.emit({
301
- type: "response",
302
- text: agentResponse.text,
303
- sessionId: input.sessionId,
304
- turnId: agentResponse.turnId,
305
- });
306
- }
307
-
308
- await input.emit({
309
- type: "finish",
310
- });
311
-
312
- return agentResponse;
313
- }
314
- }