@botonic/plugin-ai-agents 0.46.1 → 2.23.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 (182) hide show
  1. package/CHANGELOG.md +209 -0
  2. package/package.json +23 -41
  3. package/src/index.d.ts +2 -0
  4. package/src/index.js +3 -0
  5. package/src/index.js.map +1 -0
  6. package/{lib/cjs → src/lib}/agent-builder.d.ts +5 -13
  7. package/{lib/cjs → src/lib}/agent-builder.js +31 -26
  8. package/src/lib/agent-builder.js.map +1 -0
  9. package/{lib/cjs → src/lib}/constants.d.ts +1 -3
  10. package/src/lib/constants.js +13 -0
  11. package/src/lib/constants.js.map +1 -0
  12. package/{lib/esm → src/lib}/debug-logger.d.ts +3 -5
  13. package/{lib/esm → src/lib}/debug-logger.js +44 -29
  14. package/src/lib/debug-logger.js.map +1 -0
  15. package/src/lib/guardrails/index.js +2 -0
  16. package/src/lib/guardrails/index.js.map +1 -0
  17. package/src/lib/guardrails/input.d.ts +3 -0
  18. package/src/lib/guardrails/input.js +29 -0
  19. package/src/lib/guardrails/input.js.map +1 -0
  20. package/{lib/cjs/services → src/lib}/hubtype-api-client.d.ts +13 -5
  21. package/src/lib/hubtype-api-client.js +206 -0
  22. package/src/lib/hubtype-api-client.js.map +1 -0
  23. package/{lib/esm → src/lib}/index.d.ts +2 -7
  24. package/src/lib/index.js +111 -0
  25. package/src/lib/index.js.map +1 -0
  26. package/src/lib/openai.d.ts +1 -0
  27. package/src/lib/openai.js +21 -0
  28. package/src/lib/openai.js.map +1 -0
  29. package/src/lib/runner.d.ts +12 -0
  30. package/src/lib/runner.js +96 -0
  31. package/src/lib/runner.js.map +1 -0
  32. package/{lib/esm → src/lib}/structured-output/carousel.d.ts +1 -1
  33. package/src/lib/structured-output/carousel.js +19 -0
  34. package/src/lib/structured-output/carousel.js.map +1 -0
  35. package/{lib/cjs → src/lib}/structured-output/exit.d.ts +1 -1
  36. package/src/lib/structured-output/exit.js +7 -0
  37. package/src/lib/structured-output/exit.js.map +1 -0
  38. package/src/lib/structured-output/index.d.ts +228 -0
  39. package/src/lib/structured-output/index.js +11 -0
  40. package/src/lib/structured-output/index.js.map +1 -0
  41. package/{lib/esm/structured-output/bot-executor.d.ts → src/lib/structured-output/text-with-buttons.d.ts} +13 -13
  42. package/src/lib/structured-output/text-with-buttons.js +14 -0
  43. package/src/lib/structured-output/text-with-buttons.js.map +1 -0
  44. package/{lib/esm → src/lib}/structured-output/text.d.ts +1 -1
  45. package/src/lib/structured-output/text.js +10 -0
  46. package/src/lib/structured-output/text.js.map +1 -0
  47. package/{lib/esm → src/lib}/tools/index.d.ts +1 -1
  48. package/src/lib/tools/index.js +3 -0
  49. package/src/lib/tools/index.js.map +1 -0
  50. package/{lib/cjs → src/lib}/tools/retrieve-knowledge.d.ts +2 -2
  51. package/src/lib/tools/retrieve-knowledge.js +30 -0
  52. package/src/lib/tools/retrieve-knowledge.js.map +1 -0
  53. package/{lib/esm → src/lib}/types.d.ts +11 -21
  54. package/src/lib/types.js +2 -0
  55. package/src/lib/types.js.map +1 -0
  56. package/README.md +0 -156
  57. package/lib/cjs/agent-builder.js.map +0 -1
  58. package/lib/cjs/bot-config-tools.d.ts +0 -7
  59. package/lib/cjs/bot-config-tools.js +0 -19
  60. package/lib/cjs/bot-config-tools.js.map +0 -1
  61. package/lib/cjs/constants.js +0 -17
  62. package/lib/cjs/constants.js.map +0 -1
  63. package/lib/cjs/debug-logger.d.ts +0 -33
  64. package/lib/cjs/debug-logger.js +0 -97
  65. package/lib/cjs/debug-logger.js.map +0 -1
  66. package/lib/cjs/guardrails/index.js +0 -5
  67. package/lib/cjs/guardrails/index.js.map +0 -1
  68. package/lib/cjs/guardrails/input.d.ts +0 -10
  69. package/lib/cjs/guardrails/input.js +0 -77
  70. package/lib/cjs/guardrails/input.js.map +0 -1
  71. package/lib/cjs/index.d.ts +0 -18
  72. package/lib/cjs/index.js +0 -134
  73. package/lib/cjs/index.js.map +0 -1
  74. package/lib/cjs/llm-config.d.ts +0 -15
  75. package/lib/cjs/llm-config.js +0 -66
  76. package/lib/cjs/llm-config.js.map +0 -1
  77. package/lib/cjs/runner.d.ts +0 -18
  78. package/lib/cjs/runner.js +0 -181
  79. package/lib/cjs/runner.js.map +0 -1
  80. package/lib/cjs/services/hubtype-api-client.js +0 -206
  81. package/lib/cjs/services/hubtype-api-client.js.map +0 -1
  82. package/lib/cjs/services/types.d.ts +0 -85
  83. package/lib/cjs/services/types.js +0 -13
  84. package/lib/cjs/services/types.js.map +0 -1
  85. package/lib/cjs/structured-output/bot-executor.d.ts +0 -49
  86. package/lib/cjs/structured-output/bot-executor.js +0 -18
  87. package/lib/cjs/structured-output/bot-executor.js.map +0 -1
  88. package/lib/cjs/structured-output/carousel.d.ts +0 -90
  89. package/lib/cjs/structured-output/carousel.js +0 -22
  90. package/lib/cjs/structured-output/carousel.js.map +0 -1
  91. package/lib/cjs/structured-output/exit.js +0 -11
  92. package/lib/cjs/structured-output/exit.js.map +0 -1
  93. package/lib/cjs/structured-output/index.d.ts +0 -603
  94. package/lib/cjs/structured-output/index.js +0 -28
  95. package/lib/cjs/structured-output/index.js.map +0 -1
  96. package/lib/cjs/structured-output/text-with-buttons.d.ts +0 -56
  97. package/lib/cjs/structured-output/text-with-buttons.js +0 -24
  98. package/lib/cjs/structured-output/text-with-buttons.js.map +0 -1
  99. package/lib/cjs/structured-output/text.d.ts +0 -23
  100. package/lib/cjs/structured-output/text.js +0 -13
  101. package/lib/cjs/structured-output/text.js.map +0 -1
  102. package/lib/cjs/tools/index.d.ts +0 -3
  103. package/lib/cjs/tools/index.js +0 -7
  104. package/lib/cjs/tools/index.js.map +0 -1
  105. package/lib/cjs/tools/retrieve-knowledge.js +0 -32
  106. package/lib/cjs/tools/retrieve-knowledge.js.map +0 -1
  107. package/lib/cjs/types.d.ts +0 -56
  108. package/lib/cjs/types.js +0 -3
  109. package/lib/cjs/types.js.map +0 -1
  110. package/lib/esm/agent-builder.d.ts +0 -37
  111. package/lib/esm/agent-builder.js +0 -106
  112. package/lib/esm/agent-builder.js.map +0 -1
  113. package/lib/esm/bot-config-tools.d.ts +0 -7
  114. package/lib/esm/bot-config-tools.js +0 -19
  115. package/lib/esm/bot-config-tools.js.map +0 -1
  116. package/lib/esm/constants.d.ts +0 -11
  117. package/lib/esm/constants.js +0 -17
  118. package/lib/esm/constants.js.map +0 -1
  119. package/lib/esm/debug-logger.js.map +0 -1
  120. package/lib/esm/guardrails/index.d.ts +0 -1
  121. package/lib/esm/guardrails/index.js +0 -5
  122. package/lib/esm/guardrails/index.js.map +0 -1
  123. package/lib/esm/guardrails/input.d.ts +0 -10
  124. package/lib/esm/guardrails/input.js +0 -77
  125. package/lib/esm/guardrails/input.js.map +0 -1
  126. package/lib/esm/index.js +0 -134
  127. package/lib/esm/index.js.map +0 -1
  128. package/lib/esm/llm-config.d.ts +0 -15
  129. package/lib/esm/llm-config.js +0 -66
  130. package/lib/esm/llm-config.js.map +0 -1
  131. package/lib/esm/runner.d.ts +0 -18
  132. package/lib/esm/runner.js +0 -181
  133. package/lib/esm/runner.js.map +0 -1
  134. package/lib/esm/services/hubtype-api-client.d.ts +0 -14
  135. package/lib/esm/services/hubtype-api-client.js +0 -206
  136. package/lib/esm/services/hubtype-api-client.js.map +0 -1
  137. package/lib/esm/services/types.d.ts +0 -85
  138. package/lib/esm/services/types.js +0 -13
  139. package/lib/esm/services/types.js.map +0 -1
  140. package/lib/esm/structured-output/bot-executor.js +0 -18
  141. package/lib/esm/structured-output/bot-executor.js.map +0 -1
  142. package/lib/esm/structured-output/carousel.js +0 -22
  143. package/lib/esm/structured-output/carousel.js.map +0 -1
  144. package/lib/esm/structured-output/exit.d.ts +0 -10
  145. package/lib/esm/structured-output/exit.js +0 -11
  146. package/lib/esm/structured-output/exit.js.map +0 -1
  147. package/lib/esm/structured-output/index.d.ts +0 -603
  148. package/lib/esm/structured-output/index.js +0 -28
  149. package/lib/esm/structured-output/index.js.map +0 -1
  150. package/lib/esm/structured-output/text-with-buttons.d.ts +0 -56
  151. package/lib/esm/structured-output/text-with-buttons.js +0 -24
  152. package/lib/esm/structured-output/text-with-buttons.js.map +0 -1
  153. package/lib/esm/structured-output/text.js +0 -13
  154. package/lib/esm/structured-output/text.js.map +0 -1
  155. package/lib/esm/tools/index.js +0 -7
  156. package/lib/esm/tools/index.js.map +0 -1
  157. package/lib/esm/tools/retrieve-knowledge.d.ts +0 -9
  158. package/lib/esm/tools/retrieve-knowledge.js +0 -32
  159. package/lib/esm/tools/retrieve-knowledge.js.map +0 -1
  160. package/lib/esm/types.js +0 -3
  161. package/lib/esm/types.js.map +0 -1
  162. package/src/agent-builder.ts +0 -183
  163. package/src/bot-config-tools.ts +0 -21
  164. package/src/constants.ts +0 -21
  165. package/src/debug-logger.ts +0 -166
  166. package/src/guardrails/index.ts +0 -1
  167. package/src/guardrails/input.ts +0 -122
  168. package/src/index.ts +0 -210
  169. package/src/llm-config.ts +0 -96
  170. package/src/runner.ts +0 -287
  171. package/src/services/hubtype-api-client.ts +0 -240
  172. package/src/services/types.ts +0 -106
  173. package/src/structured-output/bot-executor.ts +0 -21
  174. package/src/structured-output/carousel.ts +0 -24
  175. package/src/structured-output/exit.ts +0 -12
  176. package/src/structured-output/index.ts +0 -34
  177. package/src/structured-output/text-with-buttons.ts +0 -29
  178. package/src/structured-output/text.ts +0 -13
  179. package/src/tools/index.ts +0 -5
  180. package/src/tools/retrieve-knowledge.ts +0 -37
  181. package/src/types.ts +0 -110
  182. /package/{lib/cjs → src/lib}/guardrails/index.d.ts +0 -0
package/src/index.ts DELETED
@@ -1,210 +0,0 @@
1
- import type {
2
- AiAgentArgs,
3
- BotContext,
4
- Plugin,
5
- ResolvedPlugins,
6
- } from '@botonic/core'
7
- import { tool } from '@openai/agents'
8
- import { v7 as uuidv7 } from 'uuid'
9
- import { AIAgentBuilder } from './agent-builder'
10
- import {
11
- DEFAULT_MAX_RETRIES,
12
- DEFAULT_TIMEOUT_16_SECONDS,
13
- isProd,
14
- MAX_MEMORY_LENGTH,
15
- } from './constants'
16
- import { createDebugLogger, type DebugLogger } from './debug-logger'
17
- import { LLMConfig } from './llm-config'
18
- import { AIAgentRunner } from './runner'
19
- import { HubtypeApiClient } from './services/hubtype-api-client'
20
- import type {
21
- AgenticInputMessage,
22
- Context,
23
- CustomTool,
24
- InferenceResponse,
25
- MemoryOptions,
26
- MessageHistoryApiVersion,
27
- PluginAiAgentOptions,
28
- Tool,
29
- } from './types'
30
-
31
- export default class BotonicPluginAiAgents<
32
- TPlugins extends ResolvedPlugins = ResolvedPlugins,
33
- TExtraData = any,
34
- > implements Plugin
35
- {
36
- private readonly authToken?: string
37
- private readonly messageHistoryApiVersion: MessageHistoryApiVersion
38
- private readonly memory: MemoryOptions
39
- private readonly logger: DebugLogger
40
- private readonly timeout: number
41
- private readonly maxRetries: number
42
- public toolDefinitions: CustomTool<TPlugins, TExtraData>[] = []
43
-
44
- constructor(options?: PluginAiAgentOptions<TPlugins, TExtraData>) {
45
- if (options?.messageHistoryApiVersion === 'v1' && options?.memory) {
46
- throw new Error(
47
- 'Cannot use memory when messageHistoryApiVersion is "v1". ' +
48
- 'Either set messageHistoryApiVersion to "v2" or remove memory.'
49
- )
50
- }
51
-
52
- this.authToken = options?.authToken
53
- this.toolDefinitions = options?.customTools || []
54
- this.messageHistoryApiVersion = options?.messageHistoryApiVersion ?? 'v2'
55
- this.memory = options?.memory ?? {}
56
- this.timeout = options?.timeout ?? DEFAULT_TIMEOUT_16_SECONDS
57
- this.maxRetries = options?.maxRetries ?? DEFAULT_MAX_RETRIES
58
- this.logger = createDebugLogger(options?.enableDebug ?? false)
59
-
60
- this.logger.logInitialConfig({
61
- messageHistoryApiVersion: this.messageHistoryApiVersion,
62
- maxRetries: options?.maxRetries ?? 2,
63
- timeout: options?.timeout ?? 16000,
64
- customToolNames: this.toolDefinitions.map(t => t.name),
65
- memory: this.memory,
66
- })
67
- }
68
-
69
- pre(): void {
70
- return
71
- }
72
-
73
- async getInference(
74
- botContext: BotContext<TPlugins, TExtraData>,
75
- aiAgentArgs: AiAgentArgs
76
- ): Promise<InferenceResponse> {
77
- try {
78
- const authToken = isProd
79
- ? botContext.session._access_token
80
- : this.authToken
81
- if (!authToken) {
82
- throw new Error('Auth token is required')
83
- }
84
-
85
- const inferenceId = uuidv7()
86
-
87
- // Create client for OpenAI/Azure OpenAI
88
- const llmConfig = new LLMConfig(
89
- this.maxRetries,
90
- this.timeout,
91
- aiAgentArgs.model,
92
- aiAgentArgs.verbosity
93
- )
94
-
95
- // Build tools
96
- const tools = this.buildTools(
97
- aiAgentArgs.activeTools?.map(tool => tool.name) || []
98
- )
99
-
100
- // Build agent
101
- const agent = new AIAgentBuilder<TPlugins, TExtraData>({
102
- name: aiAgentArgs.name,
103
- instructions: aiAgentArgs.instructions,
104
- tools: tools,
105
- contactInfo: botContext.session.user.contact_info || [],
106
- inputGuardrailRules: aiAgentArgs.inputGuardrailRules || [],
107
- sourceIds: aiAgentArgs.sourceIds || [],
108
- outputMessagesSchemas: aiAgentArgs.outputMessagesSchemas || [],
109
- campaignsContext: botContext.input.context?.campaigns_v2,
110
- logger: this.logger,
111
- llmConfig,
112
- guardrailTrackingContext: {
113
- botId: botContext.session.bot.id,
114
- isTest: botContext.session.is_test_integration,
115
- authToken,
116
- inferenceId,
117
- },
118
- }).build()
119
-
120
- // Get messages
121
- const messages = await this.getMessages(
122
- botContext,
123
- authToken,
124
- MAX_MEMORY_LENGTH
125
- )
126
-
127
- // Build context
128
- const context: Context<TPlugins, TExtraData> = {
129
- authToken,
130
- sourceIds: aiAgentArgs.sourceIds || [],
131
- knowledgeUsed: {
132
- query: '',
133
- sourceIds: [],
134
- chunksIds: [],
135
- chunkTexts: [],
136
- },
137
- request: botContext,
138
- }
139
-
140
- // Log agent debug info
141
- this.logger.logAgentDebugInfo(
142
- aiAgentArgs,
143
- tools.map(t => t.name),
144
- messages
145
- )
146
-
147
- // Run agent
148
- const runner = new AIAgentRunner<TPlugins, TExtraData>(
149
- agent,
150
- llmConfig,
151
- inferenceId,
152
- this.logger
153
- )
154
- return await runner.run(messages, context)
155
- } catch (error) {
156
- console.error('error plugin returns undefined', error)
157
- return {
158
- messages: [],
159
- toolsExecuted: [],
160
- memoryLength: 0,
161
- exit: true,
162
- error: true,
163
- inputGuardrailsTriggered: [],
164
- outputGuardrailsTriggered: [],
165
- }
166
- }
167
- }
168
-
169
- private async getMessages(
170
- botContext: BotContext,
171
- authToken: string,
172
- memoryLength: number
173
- ): Promise<AgenticInputMessage[]> {
174
- const hubtypeClient = new HubtypeApiClient(authToken)
175
-
176
- if (!isProd) {
177
- return await hubtypeClient.getLocalMessages(memoryLength)
178
- }
179
-
180
- if (this.messageHistoryApiVersion === 'v1') {
181
- return await hubtypeClient.getMessages(botContext, memoryLength)
182
- }
183
-
184
- // Default to V2
185
- const result = await hubtypeClient.getMessagesV2(botContext, {
186
- maxMessages: this.memory.maxMessages ?? memoryLength,
187
- includeToolCalls: this.memory.includeToolCalls ?? true,
188
- maxFullToolResults: this.memory.maxFullToolResults ?? 1,
189
- debugMode: this.memory.debugMode ?? false,
190
- })
191
- return result.messages
192
- }
193
-
194
- private buildTools(activeToolNames: string[]): Tool<TPlugins, TExtraData>[] {
195
- const availableTools = this.toolDefinitions.filter(tool =>
196
- activeToolNames.includes(tool.name)
197
- )
198
- return availableTools.map(toolDefinition => {
199
- return tool<any, Context<TPlugins, TExtraData>, any>({
200
- name: toolDefinition.name,
201
- description: toolDefinition.description,
202
- parameters: toolDefinition.schema,
203
- execute: toolDefinition.func,
204
- })
205
- })
206
- }
207
- }
208
-
209
- export * from './bot-config-tools'
210
- export * from './types'
package/src/llm-config.ts DELETED
@@ -1,96 +0,0 @@
1
- import type { VerbosityLevel } from '@botonic/core'
2
- import {
3
- type ModelProvider,
4
- type ModelSettings,
5
- OpenAIProvider,
6
- } from '@openai/agents'
7
- import OpenAI, { AzureOpenAI } from 'openai'
8
- import {
9
- AZURE_OPENAI_API_BASE,
10
- AZURE_OPENAI_API_KEY,
11
- AZURE_OPENAI_API_VERSION,
12
- isProd,
13
- OPENAI_API_KEY,
14
- OPENAI_MODEL,
15
- OPENAI_PROVIDER,
16
- } from './constants'
17
-
18
- export class LLMConfig {
19
- private readonly maxRetries: number
20
- private readonly timeout: number
21
- public readonly modelName: string
22
- public readonly modelSettings: ModelSettings
23
- public readonly modelProvider: ModelProvider
24
-
25
- constructor(
26
- maxRetries: number,
27
- timeout: number,
28
- modelName: string,
29
- verbosity: VerbosityLevel
30
- ) {
31
- this.maxRetries = maxRetries
32
- this.timeout = timeout
33
- this.modelName = OPENAI_PROVIDER === 'openai' ? OPENAI_MODEL : modelName
34
- this.modelProvider = this.getModelProvider()
35
- this.modelSettings = this.getModelSettings(modelName, verbosity)
36
- }
37
-
38
- private getModelProvider(): ModelProvider {
39
- const client = this.getClient()
40
- return new OpenAIProvider({
41
- openAIClient: client,
42
- useResponses: false,
43
- })
44
- }
45
-
46
- private getClient(): OpenAI | AzureOpenAI {
47
- if (OPENAI_PROVIDER === 'openai') {
48
- return this.getOpenAIClient()
49
- }
50
-
51
- return this.getAzureClient()
52
- }
53
-
54
- private getOpenAIClient(): OpenAI {
55
- return new OpenAI({
56
- apiKey: OPENAI_API_KEY,
57
- timeout: this.timeout,
58
- maxRetries: this.maxRetries,
59
- dangerouslyAllowBrowser: !isProd,
60
- })
61
- }
62
-
63
- private getAzureClient(): AzureOpenAI {
64
- return new AzureOpenAI({
65
- apiKey: AZURE_OPENAI_API_KEY,
66
- apiVersion: AZURE_OPENAI_API_VERSION,
67
- deployment: this.modelName,
68
- baseURL: AZURE_OPENAI_API_BASE,
69
- timeout: this.timeout,
70
- maxRetries: this.maxRetries,
71
- dangerouslyAllowBrowser: !isProd,
72
- })
73
- }
74
-
75
- private getModelSettings(
76
- model: string,
77
- verbosity: VerbosityLevel
78
- ): ModelSettings {
79
- if (model.includes('gpt-5')) {
80
- return {
81
- reasoning: { effort: 'none' },
82
- temperature: 1,
83
- text: { verbosity },
84
- }
85
- }
86
-
87
- if (model.includes('gpt-4')) {
88
- return {
89
- temperature: 0,
90
- text: { verbosity: 'medium' },
91
- }
92
- }
93
-
94
- throw new Error(`Unsupported model: ${model}`)
95
- }
96
- }
package/src/runner.ts DELETED
@@ -1,287 +0,0 @@
1
- import type {
2
- OutputMessage,
3
- ResolvedPlugins,
4
- ToolExecution,
5
- } from '@botonic/core'
6
- import {
7
- InputGuardrailTripwireTriggered,
8
- Runner,
9
- RunToolCallItem,
10
- RunToolCallOutputItem,
11
- } from '@openai/agents'
12
- import { AZURE_OPENAI_API_VERSION, isProd, OPENAI_PROVIDER } from './constants'
13
- import type { DebugLogger } from './debug-logger'
14
- import type { LLMConfig } from './llm-config'
15
- import { HubtypeApiClient } from './services/hubtype-api-client'
16
- import { TrackFeature, TrackProductName } from './services/types'
17
- import { retrieveKnowledge } from './tools'
18
- import type {
19
- AgenticInputMessage,
20
- AgenticOutputMessage,
21
- AIAgent,
22
- Context,
23
- ResultRawResponse,
24
- RunResult,
25
- } from './types'
26
-
27
- // Minimal interface matching the properties we actually use from Runner.run() result
28
- // This bypasses strict type checking while maintaining type safety for accessed properties
29
- interface AIAgentRunnerResult {
30
- finalOutput?: {
31
- messages?: OutputMessage[]
32
- }
33
- newItems?: RunToolCallItem[]
34
- rawResponses?: ResultRawResponse[]
35
- // biome-ignore lint/suspicious/noExplicitAny: state is a complex internal type
36
- state?: any
37
- }
38
-
39
- export class AIAgentRunner<
40
- TPlugins extends ResolvedPlugins = ResolvedPlugins,
41
- TExtraData = any,
42
- > {
43
- private agent: AIAgent<TPlugins, TExtraData>
44
- private llmConfig: LLMConfig
45
- private inferenceId: string
46
- private logger: DebugLogger
47
-
48
- constructor(
49
- agent: AIAgent<TPlugins, TExtraData>,
50
- openAiClient: LLMConfig,
51
- inferenceId: string,
52
- logger: DebugLogger
53
- ) {
54
- this.agent = agent
55
- this.llmConfig = openAiClient
56
- this.inferenceId = inferenceId
57
- this.logger = logger
58
- }
59
-
60
- async run(
61
- messages: AgenticInputMessage[],
62
- context: Context<TPlugins, TExtraData>
63
- ): Promise<RunResult> {
64
- const startTime = Date.now()
65
-
66
- this.logger.logRunnerStart(
67
- this.llmConfig.modelName,
68
- this.llmConfig.modelSettings
69
- )
70
-
71
- try {
72
- const modelProvider = this.llmConfig.modelProvider
73
- const modelSettings = this.llmConfig.modelSettings
74
-
75
- const hasRetrieveKnowledge = this.agent.tools.includes(retrieveKnowledge)
76
- if (hasRetrieveKnowledge && OPENAI_PROVIDER === 'azure') {
77
- modelSettings.toolChoice = retrieveKnowledge.name
78
- }
79
-
80
- const runner = new Runner({
81
- modelSettings,
82
- modelProvider,
83
- tracingDisabled: true,
84
- })
85
- // Type assertion to bypass strict type checking - the actual return type from runner.run()
86
- // doesn't perfectly match our interface, but the properties we access are compatible
87
- const result = (await runner.run(this.agent, messages, {
88
- context,
89
- })) as AIAgentRunnerResult
90
-
91
- const endTime = Date.now()
92
-
93
- void this.sendLlmRunTracking(result, context, startTime, endTime)
94
-
95
- const { _context, ...restResult } = result.state
96
- console.log('Runner result:', restResult)
97
-
98
- const outputMessages = result.finalOutput?.messages || []
99
- const hasExit =
100
- outputMessages.length === 0 ||
101
- outputMessages.some(message => message.type === 'exit')
102
- const toolsExecuted = this.getToolsExecuted(result, context)
103
-
104
- const runResult: RunResult = {
105
- messages: hasExit
106
- ? []
107
- : (outputMessages.filter(
108
- message => message.type !== 'exit'
109
- ) as AgenticOutputMessage[]),
110
- toolsExecuted,
111
- exit: hasExit,
112
- memoryLength: messages.length,
113
- error: false,
114
- inputGuardrailsTriggered: [],
115
- outputGuardrailsTriggered: [],
116
- }
117
-
118
- this.logger.logRunResult(runResult, startTime)
119
-
120
- return runResult
121
- } catch (error) {
122
- if (error instanceof InputGuardrailTripwireTriggered) {
123
- const runResult: RunResult = {
124
- messages: [],
125
- memoryLength: 0,
126
- toolsExecuted: [],
127
- exit: true,
128
- error: false,
129
- inputGuardrailsTriggered: error.result.output.outputInfo,
130
- outputGuardrailsTriggered: [],
131
- }
132
-
133
- this.logger.logGuardrailTriggered()
134
- this.logger.logRunResult(runResult, startTime)
135
-
136
- return runResult
137
- }
138
-
139
- this.logger.logRunnerError(startTime, error)
140
-
141
- throw error
142
- }
143
- }
144
-
145
- private async sendLlmRunTracking(
146
- result: AIAgentRunnerResult,
147
- context: Context<TPlugins, TExtraData>,
148
- startTime: number,
149
- endTime: number
150
- ): Promise<void> {
151
- if (!isProd) {
152
- return
153
- }
154
- const rawResponses = result.rawResponses ?? []
155
- if (rawResponses.length === 0) {
156
- return
157
- }
158
- const botId = context.request.session.bot.id
159
- const isTest = context.request.session.is_test_integration
160
- const totalDuration = endTime - startTime
161
- const durationPerCall = Math.round(totalDuration / rawResponses.length)
162
- const temperature =
163
- (this.llmConfig.modelSettings.temperature as number | undefined) ?? 0
164
- const apiVersion =
165
- OPENAI_PROVIDER === 'azure' ? AZURE_OPENAI_API_VERSION : ''
166
-
167
- const llmRuns = rawResponses.map(response => ({
168
- inference_id: this.inferenceId,
169
- is_test: isTest,
170
- product_name: TrackProductName.AI_AGENT,
171
- deployment_name: this.llmConfig.modelName,
172
- model_name:
173
- (response.providerData?.['model'] as string | undefined) ??
174
- this.llmConfig.modelName,
175
- feature: TrackFeature.AI_AGENT_RUN,
176
- api_version: apiVersion,
177
- num_prompt_tokens: response.usage.inputTokens,
178
- num_completion_tokens: response.usage.outputTokens,
179
- duration_in_milliseconds: durationPerCall,
180
- temperature,
181
- error: null,
182
- }))
183
-
184
- const client = new HubtypeApiClient(context.authToken)
185
- await client.trackLlmRuns(botId, {
186
- llm_runs: llmRuns,
187
- })
188
- }
189
-
190
- private getToolsExecuted(
191
- result,
192
- context: Context<TPlugins, TExtraData>
193
- ): ToolExecution[] {
194
- const toolResultsByCallId = this.getToolResultsByCallId(result.newItems)
195
-
196
- return (
197
- result.newItems
198
- ?.filter(item => item instanceof RunToolCallItem)
199
- .map((item: RunToolCallItem) =>
200
- this.getToolExecutionInfo(
201
- item as RunToolCallItem,
202
- context,
203
- toolResultsByCallId
204
- )
205
- )
206
- .filter(
207
- (toolExecution: ToolExecution) => toolExecution.toolName !== ''
208
- ) || []
209
- )
210
- }
211
-
212
- private getToolResultsByCallId(newItems: unknown[]): Map<string, string> {
213
- const map = new Map<string, string>()
214
- for (const item of newItems || []) {
215
- if (!(item instanceof RunToolCallOutputItem)) {
216
- continue
217
- }
218
- const rawItem = item.rawItem as {
219
- callId?: string
220
- output?: string | { type?: string; text?: string }
221
- }
222
- const callId = rawItem?.callId
223
- const output = rawItem?.output
224
- if (callId == null || output == null) {
225
- continue
226
- }
227
- const text = this.extractToolResult(output)
228
- if (text != null) {
229
- map.set(callId, text)
230
- }
231
- }
232
- return map
233
- }
234
-
235
- private extractToolResult(
236
- output: string | { type?: string; text?: string }
237
- ): string | undefined {
238
- if (typeof output === 'string') {
239
- return output
240
- }
241
- return output?.type === 'text' && typeof output?.text === 'string'
242
- ? output.text
243
- : undefined
244
- }
245
-
246
- private getToolExecutionInfo(
247
- item: RunToolCallItem,
248
- context: Context<TPlugins, TExtraData>,
249
- toolResultsByCallId: Map<string, string>
250
- ): ToolExecution {
251
- if (item.rawItem.type !== 'function_call') {
252
- return {
253
- toolName: '',
254
- toolArguments: {},
255
- }
256
- }
257
- const toolName = item.rawItem.name
258
- const toolArguments = this.getSafeToolArguments(item.rawItem.arguments)
259
- const toolResults = item.rawItem.callId
260
- ? toolResultsByCallId.get(item.rawItem.callId)
261
- : undefined
262
-
263
- const toolExecution: ToolExecution = {
264
- toolName,
265
- toolArguments,
266
- toolResults,
267
- }
268
-
269
- if (toolName === retrieveKnowledge.name) {
270
- return {
271
- ...toolExecution,
272
- knowledgebaseSourcesIds: context.knowledgeUsed.sourceIds,
273
- knowledgebaseChunksIds: context.knowledgeUsed.chunksIds,
274
- }
275
- }
276
-
277
- return toolExecution
278
- }
279
-
280
- private getSafeToolArguments(rawToolArguments: string): Record<string, any> {
281
- try {
282
- return JSON.parse(rawToolArguments)
283
- } catch (_error) {
284
- return {}
285
- }
286
- }
287
- }