@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/build.log DELETED
@@ -1,67 +0,0 @@
1
-
2
- > @adminforth/agent@1.0.1 build
3
- > tsc && rsync -av --exclude 'node_modules' custom dist/
4
-
5
- sending incremental file list
6
- custom/
7
- custom/ChatFooter.vue
8
- custom/ChatHeader.vue
9
- custom/ChatSurface.vue
10
- custom/CustomAutoScrollContainer.vue
11
- custom/SessionsHistory.vue
12
- custom/chat.ts
13
- custom/env.d.ts
14
- custom/package.json
15
- custom/pnpm-lock.yaml
16
- custom/tsconfig.json
17
- custom/types.ts
18
- custom/utils.ts
19
- custom/composables/
20
- custom/composables/useAgentAudio.ts
21
- custom/composables/useAgentStore.ts
22
- custom/composables/useAgentTransitions.ts
23
- custom/composables/agentAudio/
24
- custom/composables/agentAudio/utils.ts
25
- custom/composables/agentStore/
26
- custom/composables/agentStore/constants.ts
27
- custom/composables/agentStore/pageContext.ts
28
- custom/composables/agentStore/useAgentChat.ts
29
- custom/composables/agentStore/useAgentPlaceholder.ts
30
- custom/composables/agentStore/useAgentSessions.ts
31
- custom/conversation_area/
32
- custom/conversation_area/ConversationArea.vue
33
- custom/conversation_area/MessageRenderer.vue
34
- custom/conversation_area/ProcessingTimeline.vue
35
- custom/conversation_area/ReasoningRenderer.vue
36
- custom/conversation_area/SystemMessageRenderer.vue
37
- custom/conversation_area/TextRenderer.vue
38
- custom/conversation_area/ThreeDotsAnimation.vue
39
- custom/conversation_area/ToolApprovalRenderer.vue
40
- custom/conversation_area/ToolRenderer.vue
41
- custom/conversation_area/ToolsGroup.vue
42
- custom/incremark_code_renderers/
43
- custom/incremark_code_renderers/IncremarkShikiCodeBlock.vue
44
- custom/incremark_code_renderers/incremarkCodeHighlight.ts
45
- custom/incremark_code_renderers/incremarkRenderer.ts
46
- custom/incremark_code_renderers/renderIncremarkMarkdown.ts
47
- custom/public/
48
- custom/public/agentAudio/
49
- custom/public/agentAudio/agent-processing.mp3
50
- custom/skills/
51
- custom/skills/analyze_data/
52
- custom/skills/analyze_data/SKILL.md
53
- custom/skills/charts/
54
- custom/skills/charts/SKILL.md
55
- custom/skills/fetch_data/
56
- custom/skills/fetch_data/SKILL.md
57
- custom/skills/mutate_data/
58
- custom/skills/mutate_data/SKILL.md
59
- custom/speech_recognition_frontend/
60
- custom/speech_recognition_frontend/AudioLines.vue
61
- custom/speech_recognition_frontend/MicrophoneButon.vue
62
- custom/speech_recognition_frontend/voiceActivityDetection.ts
63
- custom/speech_recognition_frontend/types/
64
- custom/speech_recognition_frontend/types/voice-activity-detection.d.ts
65
-
66
- sent 1,682,452 bytes received 940 bytes 3,366,784.00 bytes/sec
67
- total size is 1,678,191 speedup is 1.00
@@ -1,319 +0,0 @@
1
- import type {
2
- AdminUser,
3
- ChatSurfaceAdapter,
4
- ChatSurfaceEventSink,
5
- ChatSurfaceIncomingMessage,
6
- IAdminForth,
7
- } from "adminforth";
8
- import { Filters, logger } from "adminforth";
9
- import type { AgentEventEmitter } from "./agentEvents.js";
10
- import type {
11
- HandleTurnInput,
12
- RunAndPersistAgentResponseInput,
13
- RunAndPersistAgentResponseResult,
14
- } from "./agentTurnService.js";
15
- import { getErrorMessage, isAbortError } from "./errors.js";
16
- import type { AgentSessionStore } from "./sessionStore.js";
17
- import { sanitizeSpeechText } from "./sanitizeSpeechText.js";
18
- import type { PluginOptions } from "./types.js";
19
-
20
- type ChatSurfaceIncomingMessageWithAudio = ChatSurfaceIncomingMessage & {
21
- audio?: {
22
- buffer: Buffer;
23
- filename: string;
24
- mimeType: string;
25
- };
26
- };
27
-
28
- type ChatSurfaceEventSinkWithAudio = ChatSurfaceEventSink & {
29
- emit(event: Parameters<ChatSurfaceEventSink["emit"]>[0] | {
30
- type: "audio";
31
- audio: Buffer;
32
- filename: string;
33
- mimeType: string;
34
- }): void | Promise<void>;
35
- };
36
-
37
- export class ChatSurfaceService {
38
- constructor(
39
- private getAdminforth: () => IAdminForth,
40
- private options: PluginOptions,
41
- private sessionStore: AgentSessionStore,
42
- private handleTurn: (input: HandleTurnInput) => Promise<unknown>,
43
- private runAndPersistAgentResponse: (
44
- input: RunAndPersistAgentResponseInput,
45
- ) => Promise<RunAndPersistAgentResponseResult>,
46
- ) {}
47
-
48
- private createEventEmitter(sink: ChatSurfaceEventSink): AgentEventEmitter {
49
- return async (event) => {
50
- if (event.type === "text-delta") {
51
- await sink.emit({
52
- type: "text_delta",
53
- delta: event.delta,
54
- });
55
- return;
56
- }
57
-
58
- if (event.type === "response") {
59
- await sink.emit({
60
- type: "done",
61
- text: event.text,
62
- });
63
- return;
64
- }
65
-
66
- if (event.type === "error") {
67
- await sink.emit({
68
- type: "error",
69
- message: event.error,
70
- });
71
- }
72
- };
73
- }
74
-
75
- private async handleLink(
76
- incoming: ChatSurfaceIncomingMessage,
77
- sink: ChatSurfaceEventSink,
78
- ) {
79
- if (incoming.metadata?.isStartCommand !== true) {
80
- return false;
81
- }
82
-
83
- await sink.emit({
84
- type: "done",
85
- text: `Open AdminForth and connect your ${incoming.surface} account from Connected Accounts settings.`,
86
- });
87
- return true;
88
- }
89
-
90
- private async handleAudioMessage(
91
- incoming: ChatSurfaceIncomingMessageWithAudio,
92
- sink: ChatSurfaceEventSinkWithAudio,
93
- adminUser: AdminUser,
94
- ) {
95
- const audioAdapter = this.options.audioAdapter;
96
- if (!audioAdapter) {
97
- await sink.emit({
98
- type: "error",
99
- message: "Audio adapter is not configured for AdminForth Agent.",
100
- });
101
- return;
102
- }
103
-
104
- let transcription;
105
-
106
- try {
107
- transcription = await audioAdapter.transcribe({
108
- buffer: incoming.audio!.buffer,
109
- filename: incoming.audio!.filename,
110
- mimeType: incoming.audio!.mimeType,
111
- language: "auto",
112
- });
113
- } catch (error) {
114
- if (isAbortError(error)) {
115
- logger.info(`Agent ${incoming.surface} surface speech transcription aborted`);
116
- return;
117
- }
118
-
119
- logger.error(`Agent ${incoming.surface} surface speech transcription failed:\n${getErrorMessage(error)}`);
120
- await sink.emit({
121
- type: "error",
122
- message: "Speech transcription failed. Check server logs for details.",
123
- });
124
- return;
125
- }
126
-
127
- if (!transcription.text) {
128
- await sink.emit({
129
- type: "error",
130
- message: "Speech transcription is empty",
131
- });
132
- return;
133
- }
134
-
135
- const agentResponse = await this.handleAgentSurfaceResponse(
136
- incoming,
137
- sink,
138
- adminUser,
139
- transcription.text,
140
- { emitDone: false },
141
- );
142
-
143
- if (!agentResponse || agentResponse.aborted || agentResponse.failed) {
144
- return;
145
- }
146
-
147
- await sink.emit({
148
- type: "done",
149
- text: agentResponse.text,
150
- });
151
-
152
- try {
153
- const speech = await audioAdapter.synthesize({
154
- text: sanitizeSpeechText(agentResponse.text),
155
- stream: false,
156
- format: "opus",
157
- });
158
-
159
- await sink.emit({
160
- type: "audio",
161
- audio: speech.audio,
162
- filename: "agent-response.ogg",
163
- mimeType: speech.mimeType,
164
- });
165
- } catch (error) {
166
- if (isAbortError(error)) {
167
- logger.info(`Agent ${incoming.surface} surface speech synthesis aborted`);
168
- return;
169
- }
170
-
171
- logger.error(`Agent ${incoming.surface} surface speech synthesis failed:\n${getErrorMessage(error)}`);
172
- await sink.emit({
173
- type: "error",
174
- message: getErrorMessage(error),
175
- });
176
- }
177
- }
178
-
179
- private async handleAgentSurfaceResponse(
180
- incoming: ChatSurfaceIncomingMessage,
181
- sink: ChatSurfaceEventSink,
182
- adminUser: AdminUser,
183
- prompt: string,
184
- options?: { emitDone?: boolean },
185
- ) {
186
- const emitDone = options?.emitDone ?? true;
187
- const adminPublicOrigin = typeof incoming.metadata?.adminPublicOrigin === "string"
188
- ? incoming.metadata.adminPublicOrigin
189
- : undefined;
190
- const sessionId = await this.sessionStore.getOrCreateChatSurfaceSession(
191
- { ...incoming, prompt },
192
- adminUser,
193
- );
194
-
195
- if (emitDone) {
196
- await this.handleTurn({
197
- prompt,
198
- sessionId,
199
- modeName: incoming.modeName,
200
- userTimeZone: incoming.userTimeZone ?? "UTC",
201
- chatSurface: incoming.surface,
202
- adminPublicOrigin,
203
- adminUser,
204
- emit: this.createEventEmitter(sink),
205
- failureLogMessage: `Agent ${incoming.surface} surface response failed`,
206
- abortLogMessage: `Agent ${incoming.surface} surface response aborted`,
207
- });
208
- return null;
209
- }
210
-
211
- const agentResponse = await this.runAndPersistAgentResponse({
212
- prompt,
213
- sessionId,
214
- modeName: incoming.modeName,
215
- userTimeZone: incoming.userTimeZone ?? "UTC",
216
- chatSurface: incoming.surface,
217
- adminPublicOrigin,
218
- adminUser,
219
- emit: this.createEventEmitter(sink),
220
- failureLogMessage: `Agent ${incoming.surface} surface response failed`,
221
- abortLogMessage: `Agent ${incoming.surface} surface response aborted`,
222
- });
223
-
224
- if (agentResponse.failed) {
225
- await sink.emit({
226
- type: "error",
227
- message: agentResponse.text,
228
- });
229
- }
230
-
231
- return agentResponse;
232
- }
233
-
234
- private async getAdminUserRecordForChatSurface(
235
- adapter: ChatSurfaceAdapter,
236
- incoming: ChatSurfaceIncomingMessage,
237
- ) {
238
- const adminforth = this.getAdminforth();
239
- const authResourceId = adminforth.config.auth!.usersResourceId!;
240
- const externalIdentityResource = this.options.chatExternalIdentityResource;
241
- if (!externalIdentityResource) {
242
- return null;
243
- }
244
-
245
- const surfaceIdentityConfig = externalIdentityResource.surfaces[adapter.name];
246
- if (!surfaceIdentityConfig) {
247
- return null;
248
- }
249
-
250
- const providerField = externalIdentityResource.providerField ?? 'provider';
251
- const subjectField = externalIdentityResource.subjectField ?? 'subject';
252
- const adminUserIdField = externalIdentityResource.adminUserIdField ?? 'adminUserId';
253
- const externalUserIdField = externalIdentityResource.externalUserIdField ?? 'externalUserId';
254
- const identityFilters = [
255
- Filters.EQ(providerField, surfaceIdentityConfig.provider),
256
- Filters.EQ(externalUserIdField, incoming.externalUserId),
257
- ];
258
- const identities = await adminforth.resource(externalIdentityResource.resourceId).list(identityFilters);
259
- const identity = identities.find((identity) => {
260
- if (String(identity[externalUserIdField]) === incoming.externalUserId) {
261
- return true;
262
- }
263
-
264
- if (String(identity[subjectField]) === incoming.externalUserId) {
265
- return true;
266
- }
267
-
268
- return false;
269
- });
270
-
271
- if (!identity) {
272
- return null;
273
- }
274
-
275
- const authResource = adminforth.config.resources.find((resource) => resource.resourceId === authResourceId)!;
276
- const primaryKeyField = authResource.columns.find((column) => column.primaryKey)!.name!;
277
- return adminforth.resource(authResourceId).get([
278
- Filters.EQ(primaryKeyField, identity[adminUserIdField]),
279
- ]);
280
- }
281
-
282
- async handleMessage(
283
- adapter: ChatSurfaceAdapter,
284
- incoming: ChatSurfaceIncomingMessage,
285
- sink: ChatSurfaceEventSink,
286
- ) {
287
- if (await this.handleLink(incoming, sink)) {
288
- return;
289
- }
290
-
291
- const adminforth = this.getAdminforth();
292
- const authResourceId = adminforth.config.auth!.usersResourceId!;
293
- const authResource = adminforth.config.resources.find((resource) => resource.resourceId === authResourceId)!;
294
- const primaryKeyField = authResource.columns.find((column) => column.primaryKey)!.name!;
295
- const adminUserRecord = await this.getAdminUserRecordForChatSurface(adapter, incoming);
296
-
297
- if (!adminUserRecord) {
298
- await sink.emit({
299
- type: "error",
300
- message: "This chat account is not authorized to use AdminForth Agent.",
301
- });
302
- return;
303
- }
304
-
305
- const adminUser = {
306
- pk: adminUserRecord[primaryKeyField],
307
- username: adminUserRecord[adminforth.config.auth!.usernameField],
308
- dbUser: adminUserRecord,
309
- };
310
-
311
- const incomingWithAudio = incoming as ChatSurfaceIncomingMessageWithAudio;
312
- if (incomingWithAudio.audio) {
313
- await this.handleAudioMessage(incomingWithAudio, sink as ChatSurfaceEventSinkWithAudio, adminUser);
314
- return;
315
- }
316
-
317
- await this.handleAgentSurfaceResponse(incoming, sink, adminUser, incoming.prompt);
318
- }
319
- }
@@ -1,173 +0,0 @@
1
- <template>
2
- <div
3
- ref="promptInput"
4
- class="w-full mb-2 flex items-center justify-center px-2 bg-transparent relative translate-x-[-50%] left-1/2"
5
- :style="{
6
- maxWidth: agentStore.isFullScreen ? remToPx(agentStore.MAX_WIDTH)+'px' : '100%',
7
- transition: `transform ${agentTransitions.TRANSITION_DURATION}ms ease-in-out`
8
- }"
9
- >
10
- <div
11
- class="w-full border rounded-lg pb-8"
12
- :class="agentStore.isAudioChatMode ? 'border-none mt-8' : 'border dark:bg-gray-700'"
13
- >
14
- <textarea
15
- v-if="!agentStore.isAudioChatMode"
16
- v-model="agentStore.userMessageInput"
17
- ref="textInput"
18
- @input="autoResize"
19
- :class="[
20
- 'min-h-12 px-4 pt-4 rounded-xl w-full resize-none overflow-hidden text-lightInputText dark:text-darkInputText rounded-md bg-transparent text-sm bg-gray-50 dark:bg-gray-700 dark:border-gray-600 focus:outline-none',
21
- { '!text-base': coreStore.isIos }
22
- ]"
23
- :placeholder="agentStore.hasPendingToolApproval ? 'Approve or reject the pending action to continue' : agentStore.userMessagePlaceholder"
24
- :disabled="agentStore.isMessageInputBlocked"
25
- @keydown.enter.exact.prevent="sendMessage"
26
- />
27
- <div
28
- v-if="agentStore.availableModes.length > 1"
29
- ref="modeMenu"
30
- class="absolute bottom-2 left-4"
31
- >
32
- <button
33
- aria-label="Select mode"
34
- class="flex px-2 py-1 items-center text-sm justify-center
35
- rounded-md bg-white text-lightListTableHeadingText
36
- transition-colors duration-200 hover:bg-gray-100
37
- dark:text-darkListTableHeadingText dark:bg-gray-700 dark:hover:bg-gray-800"
38
- :class="isModeMenuOpen ? 'bg-gray-100 dark:bg-gray-700' : ''"
39
- title="Select mode"
40
- type="button"
41
- @click="toggleModeMenu"
42
- >
43
- {{ agentStore.activeModeName }}
44
- <IconAngleDownOutline
45
- class="w-4 h-4 ml-1 transition-transform duration-200"
46
- :class="isModeMenuOpen ? '!rotate-180' : '!rotate-0'"
47
- />
48
- </button>
49
-
50
- <div
51
- v-if="isModeMenuOpen"
52
- class="absolute bottom-full left-0 mb-2 min-w-40 overflow-hidden rounded-md border border-gray-200 bg-white shadow-lg dark:border-gray-600 dark:bg-gray-800"
53
- >
54
- <button
55
- v-for="mode in agentStore.availableModes"
56
- :key="mode.name"
57
- class="block w-full px-3 py-2 text-left text-sm text-lightInputText transition-colors duration-150 hover:bg-gray-100 dark:text-darkInputText dark:hover:bg-gray-700"
58
- :class="mode.name === agentStore.activeModeName ? 'bg-gray-100 dark:bg-gray-700' : ''"
59
- type="button"
60
- @click="selectMode(mode.name)"
61
- >
62
- {{ mode.name }}
63
- </button>
64
- </div>
65
- </div>
66
- <MicrophoneButton
67
- v-if="props.meta.hasAudioAdapter"
68
- />
69
- <template v-if="!agentStore.isAudioChatMode">
70
- <Button
71
- v-if="!agentStore.isResponseInProgress"
72
- class="absolute right-4 bottom-2 !p-0 h-9 w-9 transition-opacity duration-200"
73
- @click="sendMessage"
74
- :disabled="!agentStore.trimmedUserMessage || agentStore.isMessageInputBlocked"
75
- >
76
- <IconArrowUpOutline
77
- class="w-8 h-8 p-1
78
- text-white"
79
- />
80
- </Button>
81
- <Button
82
- v-else
83
- class="absolute right-4 bottom-2 !p-0 h-9 w-9"
84
- @click="stopCurrentRequest"
85
- >
86
- <div
87
- class="w-3 h-3 bg-white rounded-sm"
88
- />
89
- </Button>
90
- </template>
91
- </div>
92
- </div>
93
- </template>
94
-
95
- <script setup lang="ts">
96
- import { IconArrowUpOutline, IconAngleDownOutline } from '@iconify-prerendered/vue-flowbite';
97
- import { useTemplateRef, onMounted, ref, onUnmounted } from 'vue';
98
- import { onClickOutside } from '@vueuse/core'
99
- import { useAgentStore } from './composables/useAgentStore';
100
- import { useAgentTransitions } from './composables/useAgentTransitions';
101
- import { Button } from '@/afcl';
102
- import { useCoreStore } from '@/stores/core';
103
- import { remToPx } from './utils';
104
- import MicrophoneButton from './speech_recognition_frontend/MicrophoneButon.vue';
105
-
106
- const props = defineProps<{
107
- meta: {
108
- pluginInstanceId: string;
109
- modes: Array<{
110
- name: string;
111
- }>;
112
- defaultModeName: string | null;
113
- stickByDefault: boolean;
114
- hasAudioAdapter: boolean;
115
- }
116
- adminUser: any
117
- conversationAreaRef: any
118
- }>();
119
-
120
- const textInput = useTemplateRef('textInput');
121
- const modeMenu = useTemplateRef('modeMenu');
122
- const agentStore = useAgentStore();
123
- const agentTransitions = useAgentTransitions();
124
- const coreStore = useCoreStore();
125
- const isModeMenuOpen = ref(false);
126
-
127
- onClickOutside(modeMenu as any, () => { isModeMenuOpen.value = false; });
128
-
129
- onMounted(async () => {
130
- agentStore.setAvailableModes(props.meta.modes, props.meta.defaultModeName);
131
- agentStore.setCurrentGenerationModeFromLocalStorage();
132
- agentStore.regisrerTextInput(textInput.value);
133
- textInput.value?.focus();
134
- });
135
-
136
- function autoResize() {
137
- const el = textInput.value
138
- if (!el) return
139
-
140
- el.style.height = 'auto'
141
- //max-w-48
142
- const maxHeight = 192
143
- if (el.scrollHeight > maxHeight) {
144
- el.style.height = maxHeight + 'px'
145
- el.style.overflowY = 'auto'
146
- } else {
147
- el.style.height = el.scrollHeight + 'px'
148
- el.style.overflowY = 'hidden'
149
- }
150
- }
151
-
152
- function toggleModeMenu() {
153
- isModeMenuOpen.value = !isModeMenuOpen.value;
154
- }
155
-
156
- function selectMode(modeName: string) {
157
- agentStore.setActiveMode(modeName);
158
- isModeMenuOpen.value = false;
159
- }
160
-
161
- async function sendMessage() {
162
- if (agentStore.isAudioChatMode) return;
163
- isModeMenuOpen.value = false;
164
- await agentStore.sendMessage();
165
- autoResize();
166
- props.conversationAreaRef?.handleSendMessage();
167
- }
168
-
169
- function stopCurrentRequest() {
170
- agentStore.abortCurrentChatRequestAndAddSystemMessage();
171
- }
172
-
173
- </script>
@@ -1,78 +0,0 @@
1
- <template>
2
- <div
3
- ref="headerRef"
4
- class="flex items-center justify-between h-14 border-b border-gray-200 dark:border-gray-700"
5
- >
6
- <div
7
- class="flex items-center"
8
- >
9
- <IconBarsOutline
10
- class="m-2 w-8 h-8 p-1 cursor-pointer hover:scale-110 rounded transition-colors duration-200
11
- text-lightNavbarIcons hover:text-lightNavbarIcons/80 hover:bg-lightNavbarIcons/20
12
- dark:text-darkNavbarIcons hover:text-darkNavbarIcons/80 hover:bg-darkNavbarIcons/20 "
13
- :class="agentStore.isSessionHistoryOpen ?
14
- 'bg-lightNavbarIcons/20 text-lightNavbarIcons/80 dark:bg-darkNavbarIcons/20 dark:text-darkNavbarIcons/80' :
15
- ''"
16
- @click="agentStore.setSessionHistoryOpen(!agentStore.isSessionHistoryOpen)"
17
- />
18
- <IconOpenSidebarSolid
19
- v-if="!agentStore.isTeleportedToBody && !coreStore.isMobile && !agentStore.isFullScreen"
20
- class="m-2 w-8 h-8 p-1 cursor-pointer hover:scale-110 rounded transition-colors duration-200
21
- text-lightNavbarIcons hover:text-lightNavbarIcons/80 hover:bg-lightNavbarIcons/20
22
- dark:text-darkNavbarIcons hover:text-darkNavbarIcons/80 hover:bg-darkNavbarIcons/20 "
23
- @click="agentStore.setIsTeleportedToBody(true)"
24
- />
25
- <IconCloseSidebarSolid
26
- v-else-if="!coreStore.isMobile && !agentStore.isFullScreen"
27
- class="m-2 w-8 h-8 p-1 cursor-pointer hover:scale-110 rounded transition-colors duration-200
28
- text-lightNavbarIcons hover:text-lightNavbarIcons/80 bg-lightNavbarIcons/20
29
- dark:bg-darkNavbarIcons/20 dark:text-darkNavbarIcons/80 hover:text-darkNavbarIcons/80 hover:bg-darkNavbarIcons/20 "
30
- @click="agentStore.setIsTeleportedToBody(false)"
31
- />
32
- <IconArrowsPointingOut
33
- v-if="!agentStore.isFullScreen && !coreStore.isMobile"
34
- class="m-2 w-8 h-8 p-1 cursor-pointer hover:scale-110 rounded transition-colors duration-200
35
- text-lightNavbarIcons hover:text-lightNavbarIcons/80 hover:bg-lightNavbarIcons/20
36
- dark:text-darkNavbarIcons hover:text-darkNavbarIcons/80 hover:bg-darkNavbarIcons/20 "
37
- @click="agentStore.setFullScreen(true)"
38
- />
39
- <IconArrowsPointingIn
40
- v-else-if="!coreStore.isMobile"
41
- class="m-2 w-8 h-8 p-1 cursor-pointer hover:scale-110 rounded transition-colors duration-200
42
- text-lightNavbarIcons hover:text-lightNavbarIcons/80 hover:bg-lightNavbarIcons/20
43
- dark:text-darkNavbarIcons hover:text-darkNavbarIcons/80 hover:bg-darkNavbarIcons/20 "
44
- :class="agentStore.isFullScreen ?
45
- 'bg-lightNavbarIcons/20 text-lightNavbarIcons/80 dark:bg-darkNavbarIcons/20 dark:text-darkNavbarIcons/80' :
46
- ''"
47
- @click="agentStore.setFullScreen(false)"
48
- />
49
- </div>
50
- <div class="flex items-center justify-center">
51
- <Button
52
- @click="agentStore.createPreSession(); agentStore.setSessionHistoryOpen(false); agentStore.focusTextInput();"
53
- class="!py-1 !px-2 rounded-3xl text-gray-800 dark:text-gray-200 max-w-64 mr-2"
54
- >
55
- <IconPlusOutline class="w-5 h-5" />
56
- {{ $t('New chat') }}
57
- </Button>
58
- <IconCloseOutline
59
- class="m-2 w-8 h-8 p-1 cursor-pointer hover:scale-110 rounded transition-colors duration-200
60
- text-lightNavbarIcons hover:text-lightNavbarIcons/80 hover:bg-lightNavbarIcons/20
61
- dark:text-darkNavbarIcons hover:text-darkNavbarIcons/80 hover:bg-darkNavbarIcons/20 "
62
- @click="agentStore.setIsChatOpen(false)"
63
- />
64
- </div>
65
- </div>
66
- </template>
67
-
68
-
69
- <script setup>
70
- import { IconArrowsPointingOut, IconArrowsPointingIn } from '@iconify-prerendered/vue-heroicons';
71
- import { IconCloseOutline, IconBarsOutline, IconCloseSidebarSolid, IconOpenSidebarSolid, IconPlusOutline } from '@iconify-prerendered/vue-flowbite';
72
- import { useAgentStore } from './composables/useAgentStore';
73
- import { useCoreStore } from '@/stores/core';
74
- import { Button } from '@/afcl';
75
-
76
- const agentStore = useAgentStore();
77
- const coreStore = useCoreStore();
78
- </script>