@botonic/plugin-ai-agents 0.46.0 → 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.
- package/CHANGELOG.md +209 -0
- package/package.json +23 -41
- package/src/index.d.ts +2 -0
- package/src/index.js +3 -0
- package/src/index.js.map +1 -0
- package/{lib/cjs → src/lib}/agent-builder.d.ts +5 -10
- package/{lib/cjs → src/lib}/agent-builder.js +31 -25
- package/src/lib/agent-builder.js.map +1 -0
- package/{lib/cjs → src/lib}/constants.d.ts +1 -3
- package/src/lib/constants.js +13 -0
- package/src/lib/constants.js.map +1 -0
- package/{lib/esm → src/lib}/debug-logger.d.ts +3 -5
- package/{lib/esm → src/lib}/debug-logger.js +44 -29
- package/src/lib/debug-logger.js.map +1 -0
- package/src/lib/guardrails/index.js +2 -0
- package/src/lib/guardrails/index.js.map +1 -0
- package/src/lib/guardrails/input.d.ts +3 -0
- package/src/lib/guardrails/input.js +29 -0
- package/src/lib/guardrails/input.js.map +1 -0
- package/{lib/cjs/services → src/lib}/hubtype-api-client.d.ts +13 -5
- package/src/lib/hubtype-api-client.js +206 -0
- package/src/lib/hubtype-api-client.js.map +1 -0
- package/{lib/cjs → src/lib}/index.d.ts +2 -7
- package/src/lib/index.js +111 -0
- package/src/lib/index.js.map +1 -0
- package/src/lib/openai.d.ts +1 -0
- package/src/lib/openai.js +21 -0
- package/src/lib/openai.js.map +1 -0
- package/src/lib/runner.d.ts +12 -0
- package/src/lib/runner.js +96 -0
- package/src/lib/runner.js.map +1 -0
- package/{lib/esm → src/lib}/structured-output/carousel.d.ts +1 -1
- package/src/lib/structured-output/carousel.js +19 -0
- package/src/lib/structured-output/carousel.js.map +1 -0
- package/{lib/cjs → src/lib}/structured-output/exit.d.ts +1 -1
- package/src/lib/structured-output/exit.js +7 -0
- package/src/lib/structured-output/exit.js.map +1 -0
- package/{lib/cjs → src/lib}/structured-output/index.d.ts +10 -73
- package/src/lib/structured-output/index.js +11 -0
- package/src/lib/structured-output/index.js.map +1 -0
- package/{lib/esm → src/lib}/structured-output/text-with-buttons.d.ts +8 -8
- package/src/lib/structured-output/text-with-buttons.js +14 -0
- package/src/lib/structured-output/text-with-buttons.js.map +1 -0
- package/{lib/esm → src/lib}/structured-output/text.d.ts +1 -1
- package/src/lib/structured-output/text.js +10 -0
- package/src/lib/structured-output/text.js.map +1 -0
- package/{lib/esm → src/lib}/tools/index.d.ts +1 -1
- package/src/lib/tools/index.js +3 -0
- package/src/lib/tools/index.js.map +1 -0
- package/{lib/cjs → src/lib}/tools/retrieve-knowledge.d.ts +2 -2
- package/src/lib/tools/retrieve-knowledge.js +30 -0
- package/src/lib/tools/retrieve-knowledge.js.map +1 -0
- package/{lib/esm → src/lib}/types.d.ts +11 -21
- package/src/lib/types.js +2 -0
- package/src/lib/types.js.map +1 -0
- package/README.md +0 -156
- package/lib/cjs/agent-builder.js.map +0 -1
- package/lib/cjs/bot-config-tools.d.ts +0 -7
- package/lib/cjs/bot-config-tools.js +0 -19
- package/lib/cjs/bot-config-tools.js.map +0 -1
- package/lib/cjs/constants.js +0 -17
- package/lib/cjs/constants.js.map +0 -1
- package/lib/cjs/debug-logger.d.ts +0 -33
- package/lib/cjs/debug-logger.js +0 -97
- package/lib/cjs/debug-logger.js.map +0 -1
- package/lib/cjs/guardrails/index.js +0 -5
- package/lib/cjs/guardrails/index.js.map +0 -1
- package/lib/cjs/guardrails/input.d.ts +0 -10
- package/lib/cjs/guardrails/input.js +0 -77
- package/lib/cjs/guardrails/input.js.map +0 -1
- package/lib/cjs/index.js +0 -133
- package/lib/cjs/index.js.map +0 -1
- package/lib/cjs/llm-config.d.ts +0 -15
- package/lib/cjs/llm-config.js +0 -66
- package/lib/cjs/llm-config.js.map +0 -1
- package/lib/cjs/runner.d.ts +0 -18
- package/lib/cjs/runner.js +0 -181
- package/lib/cjs/runner.js.map +0 -1
- package/lib/cjs/services/hubtype-api-client.js +0 -206
- package/lib/cjs/services/hubtype-api-client.js.map +0 -1
- package/lib/cjs/services/types.d.ts +0 -85
- package/lib/cjs/services/types.js +0 -13
- package/lib/cjs/services/types.js.map +0 -1
- package/lib/cjs/structured-output/bot-executor.d.ts +0 -49
- package/lib/cjs/structured-output/bot-executor.js +0 -18
- package/lib/cjs/structured-output/bot-executor.js.map +0 -1
- package/lib/cjs/structured-output/carousel.d.ts +0 -90
- package/lib/cjs/structured-output/carousel.js +0 -22
- package/lib/cjs/structured-output/carousel.js.map +0 -1
- package/lib/cjs/structured-output/exit.js +0 -11
- package/lib/cjs/structured-output/exit.js.map +0 -1
- package/lib/cjs/structured-output/index.js +0 -21
- package/lib/cjs/structured-output/index.js.map +0 -1
- package/lib/cjs/structured-output/text-with-buttons.d.ts +0 -49
- package/lib/cjs/structured-output/text-with-buttons.js +0 -18
- package/lib/cjs/structured-output/text-with-buttons.js.map +0 -1
- package/lib/cjs/structured-output/text.d.ts +0 -23
- package/lib/cjs/structured-output/text.js +0 -13
- package/lib/cjs/structured-output/text.js.map +0 -1
- package/lib/cjs/tools/index.d.ts +0 -3
- package/lib/cjs/tools/index.js +0 -7
- package/lib/cjs/tools/index.js.map +0 -1
- package/lib/cjs/tools/retrieve-knowledge.js +0 -32
- package/lib/cjs/tools/retrieve-knowledge.js.map +0 -1
- package/lib/cjs/types.d.ts +0 -56
- package/lib/cjs/types.js +0 -3
- package/lib/cjs/types.js.map +0 -1
- package/lib/esm/agent-builder.d.ts +0 -34
- package/lib/esm/agent-builder.js +0 -105
- package/lib/esm/agent-builder.js.map +0 -1
- package/lib/esm/bot-config-tools.d.ts +0 -7
- package/lib/esm/bot-config-tools.js +0 -19
- package/lib/esm/bot-config-tools.js.map +0 -1
- package/lib/esm/constants.d.ts +0 -11
- package/lib/esm/constants.js +0 -17
- package/lib/esm/constants.js.map +0 -1
- package/lib/esm/debug-logger.js.map +0 -1
- package/lib/esm/guardrails/index.d.ts +0 -1
- package/lib/esm/guardrails/index.js +0 -5
- package/lib/esm/guardrails/index.js.map +0 -1
- package/lib/esm/guardrails/input.d.ts +0 -10
- package/lib/esm/guardrails/input.js +0 -77
- package/lib/esm/guardrails/input.js.map +0 -1
- package/lib/esm/index.d.ts +0 -18
- package/lib/esm/index.js +0 -133
- package/lib/esm/index.js.map +0 -1
- package/lib/esm/llm-config.d.ts +0 -15
- package/lib/esm/llm-config.js +0 -66
- package/lib/esm/llm-config.js.map +0 -1
- package/lib/esm/runner.d.ts +0 -18
- package/lib/esm/runner.js +0 -181
- package/lib/esm/runner.js.map +0 -1
- package/lib/esm/services/hubtype-api-client.d.ts +0 -14
- package/lib/esm/services/hubtype-api-client.js +0 -206
- package/lib/esm/services/hubtype-api-client.js.map +0 -1
- package/lib/esm/services/types.d.ts +0 -85
- package/lib/esm/services/types.js +0 -13
- package/lib/esm/services/types.js.map +0 -1
- package/lib/esm/structured-output/bot-executor.d.ts +0 -49
- package/lib/esm/structured-output/bot-executor.js +0 -18
- package/lib/esm/structured-output/bot-executor.js.map +0 -1
- package/lib/esm/structured-output/carousel.js +0 -22
- package/lib/esm/structured-output/carousel.js.map +0 -1
- package/lib/esm/structured-output/exit.d.ts +0 -10
- package/lib/esm/structured-output/exit.js +0 -11
- package/lib/esm/structured-output/exit.js.map +0 -1
- package/lib/esm/structured-output/index.d.ts +0 -291
- package/lib/esm/structured-output/index.js +0 -21
- package/lib/esm/structured-output/index.js.map +0 -1
- package/lib/esm/structured-output/text-with-buttons.js +0 -18
- package/lib/esm/structured-output/text-with-buttons.js.map +0 -1
- package/lib/esm/structured-output/text.js +0 -13
- package/lib/esm/structured-output/text.js.map +0 -1
- package/lib/esm/tools/index.js +0 -7
- package/lib/esm/tools/index.js.map +0 -1
- package/lib/esm/tools/retrieve-knowledge.d.ts +0 -9
- package/lib/esm/tools/retrieve-knowledge.js +0 -32
- package/lib/esm/tools/retrieve-knowledge.js.map +0 -1
- package/lib/esm/types.js +0 -3
- package/lib/esm/types.js.map +0 -1
- package/src/agent-builder.ts +0 -179
- package/src/bot-config-tools.ts +0 -21
- package/src/constants.ts +0 -21
- package/src/debug-logger.ts +0 -166
- package/src/guardrails/index.ts +0 -1
- package/src/guardrails/input.ts +0 -122
- package/src/index.ts +0 -209
- package/src/llm-config.ts +0 -96
- package/src/runner.ts +0 -287
- package/src/services/hubtype-api-client.ts +0 -240
- package/src/services/types.ts +0 -106
- package/src/structured-output/bot-executor.ts +0 -21
- package/src/structured-output/carousel.ts +0 -24
- package/src/structured-output/exit.ts +0 -12
- package/src/structured-output/index.ts +0 -25
- package/src/structured-output/text-with-buttons.ts +0 -21
- package/src/structured-output/text.ts +0 -13
- package/src/tools/index.ts +0 -5
- package/src/tools/retrieve-knowledge.ts +0 -37
- package/src/types.ts +0 -110
- /package/{lib/cjs → src/lib}/guardrails/index.d.ts +0 -0
package/src/index.ts
DELETED
|
@@ -1,209 +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
|
-
campaignsContext: botContext.input.context?.campaigns_v2,
|
|
109
|
-
logger: this.logger,
|
|
110
|
-
llmConfig,
|
|
111
|
-
guardrailTrackingContext: {
|
|
112
|
-
botId: botContext.session.bot.id,
|
|
113
|
-
isTest: botContext.session.is_test_integration,
|
|
114
|
-
authToken,
|
|
115
|
-
inferenceId,
|
|
116
|
-
},
|
|
117
|
-
}).build()
|
|
118
|
-
|
|
119
|
-
// Get messages
|
|
120
|
-
const messages = await this.getMessages(
|
|
121
|
-
botContext,
|
|
122
|
-
authToken,
|
|
123
|
-
MAX_MEMORY_LENGTH
|
|
124
|
-
)
|
|
125
|
-
|
|
126
|
-
// Build context
|
|
127
|
-
const context: Context<TPlugins, TExtraData> = {
|
|
128
|
-
authToken,
|
|
129
|
-
sourceIds: aiAgentArgs.sourceIds || [],
|
|
130
|
-
knowledgeUsed: {
|
|
131
|
-
query: '',
|
|
132
|
-
sourceIds: [],
|
|
133
|
-
chunksIds: [],
|
|
134
|
-
chunkTexts: [],
|
|
135
|
-
},
|
|
136
|
-
request: botContext,
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// Log agent debug info
|
|
140
|
-
this.logger.logAgentDebugInfo(
|
|
141
|
-
aiAgentArgs,
|
|
142
|
-
tools.map(t => t.name),
|
|
143
|
-
messages
|
|
144
|
-
)
|
|
145
|
-
|
|
146
|
-
// Run agent
|
|
147
|
-
const runner = new AIAgentRunner<TPlugins, TExtraData>(
|
|
148
|
-
agent,
|
|
149
|
-
llmConfig,
|
|
150
|
-
inferenceId,
|
|
151
|
-
this.logger
|
|
152
|
-
)
|
|
153
|
-
return await runner.run(messages, context)
|
|
154
|
-
} catch (error) {
|
|
155
|
-
console.error('error plugin returns undefined', error)
|
|
156
|
-
return {
|
|
157
|
-
messages: [],
|
|
158
|
-
toolsExecuted: [],
|
|
159
|
-
memoryLength: 0,
|
|
160
|
-
exit: true,
|
|
161
|
-
error: true,
|
|
162
|
-
inputGuardrailsTriggered: [],
|
|
163
|
-
outputGuardrailsTriggered: [],
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
private async getMessages(
|
|
169
|
-
botContext: BotContext,
|
|
170
|
-
authToken: string,
|
|
171
|
-
memoryLength: number
|
|
172
|
-
): Promise<AgenticInputMessage[]> {
|
|
173
|
-
const hubtypeClient = new HubtypeApiClient(authToken)
|
|
174
|
-
|
|
175
|
-
if (!isProd) {
|
|
176
|
-
return await hubtypeClient.getLocalMessages(memoryLength)
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
if (this.messageHistoryApiVersion === 'v1') {
|
|
180
|
-
return await hubtypeClient.getMessages(botContext, memoryLength)
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
// Default to V2
|
|
184
|
-
const result = await hubtypeClient.getMessagesV2(botContext, {
|
|
185
|
-
maxMessages: this.memory.maxMessages ?? memoryLength,
|
|
186
|
-
includeToolCalls: this.memory.includeToolCalls ?? true,
|
|
187
|
-
maxFullToolResults: this.memory.maxFullToolResults ?? 1,
|
|
188
|
-
debugMode: this.memory.debugMode ?? false,
|
|
189
|
-
})
|
|
190
|
-
return result.messages
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
private buildTools(activeToolNames: string[]): Tool<TPlugins, TExtraData>[] {
|
|
194
|
-
const availableTools = this.toolDefinitions.filter(tool =>
|
|
195
|
-
activeToolNames.includes(tool.name)
|
|
196
|
-
)
|
|
197
|
-
return availableTools.map(toolDefinition => {
|
|
198
|
-
return tool<any, Context<TPlugins, TExtraData>, any>({
|
|
199
|
-
name: toolDefinition.name,
|
|
200
|
-
description: toolDefinition.description,
|
|
201
|
-
parameters: toolDefinition.schema,
|
|
202
|
-
execute: toolDefinition.func,
|
|
203
|
-
})
|
|
204
|
-
})
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
export * from './bot-config-tools'
|
|
209
|
-
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
|
-
}
|