@botonic/plugin-ai-agents 0.57.0-rslib-esm.1 → 0.58.0-alpha-new-stack.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/lib/index.js CHANGED
@@ -73,6 +73,7 @@ class BotonicPluginAiAgents {
73
73
  memoryLength: 0,
74
74
  exit: true,
75
75
  error: true,
76
+ doNothing: false,
76
77
  inputGuardrailsTriggered: [],
77
78
  outputGuardrailsTriggered: [],
78
79
  startingAgentName: '',
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import {\n type AIAgentRouterArgs,\n type AiAgentArgs,\n type AiAgentSpecialistArgs,\n AiAgentType,\n type BotContext,\n type HubtypeAssistantMessage,\n type Plugin,\n type ResolvedPlugins,\n} from '@botonic/core'\nimport { handoff, setTracingDisabled, tool } from '@openai/agents'\nimport { v7 as uuidv7 } from 'uuid'\nimport type { ZodObject } from 'zod'\nimport { RouterAgent, SpecialistAgent } from './agents'\nimport {\n DEFAULT_MAX_RETRIES,\n DEFAULT_TIMEOUT_16_SECONDS,\n isProd,\n MAX_MEMORY_LENGTH,\n} from './constants'\nimport { createDebugLogger, type DebugLogger } from './debug-logger'\nimport { LLMConfig } from './llm-config'\nimport { RouterRunner, SpecialistRunner } from './runners'\nimport { HubtypeApiClient } from './services/hubtype-api-client'\nimport type {\n AgenticInputMessage,\n Context,\n CustomTool,\n InferenceResponse,\n MemoryOptions,\n PluginAiAgentOptions,\n Tool,\n} from './types'\n\nexport default class BotonicPluginAiAgents<\n TPlugins extends ResolvedPlugins = ResolvedPlugins,\n TExtraData = any,\n> implements Plugin\n{\n private readonly authToken?: string\n private readonly memory: MemoryOptions\n private readonly logger: DebugLogger\n private readonly timeout: number\n private readonly maxRetries: number\n public toolDefinitions: CustomTool<TPlugins, TExtraData>[] = []\n private readonly localStorageKey: string\n\n constructor(options?: PluginAiAgentOptions<TPlugins, TExtraData>) {\n this.authToken = options?.authToken\n this.toolDefinitions = options?.customTools || []\n this.memory = this.getMemoryOptions(options?.memory)\n this.timeout = options?.timeout ?? DEFAULT_TIMEOUT_16_SECONDS\n this.maxRetries = options?.maxRetries ?? DEFAULT_MAX_RETRIES\n this.logger = createDebugLogger(options?.enableDebug ?? false)\n this.localStorageKey = options?.localStorageKey ?? 'botonicState'\n setTracingDisabled(true)\n\n this.logger.logInitialConfig({\n messageHistoryApiVersion: 'v2',\n maxRetries: options?.maxRetries ?? DEFAULT_MAX_RETRIES,\n timeout: options?.timeout ?? DEFAULT_TIMEOUT_16_SECONDS,\n customToolNames: this.toolDefinitions.map(t => t.name),\n memory: this.memory,\n })\n }\n\n private getMemoryOptions(memory?: Partial<MemoryOptions>): MemoryOptions {\n return {\n maxMessages: memory?.maxMessages ?? MAX_MEMORY_LENGTH,\n includeToolCalls: memory?.includeToolCalls ?? true,\n maxFullToolResults: memory?.maxFullToolResults ?? 1,\n debugMode: memory?.debugMode ?? false,\n }\n }\n\n pre(): void {\n return\n }\n\n async getInference(\n botContext: BotContext<TPlugins, TExtraData>,\n aiAgentArgs: AiAgentArgs\n ): Promise<InferenceResponse> {\n const authToken = isProd ? botContext.session._access_token : this.authToken\n if (!authToken) {\n throw new Error('Auth token is required')\n }\n\n const inferenceId = uuidv7()\n\n try {\n if (aiAgentArgs.type === AiAgentType.Specialist) {\n return await this.executeSpecialistAIAgent(\n botContext,\n aiAgentArgs,\n authToken,\n inferenceId\n )\n }\n\n if (aiAgentArgs.type === AiAgentType.Router) {\n return await this.executeRouterAIAgent(\n botContext,\n aiAgentArgs,\n authToken,\n inferenceId\n )\n }\n\n throw new Error('Invalid agent type')\n } catch (error) {\n console.error('error plugin returns undefined', error)\n return {\n messages: [],\n toolsExecuted: [],\n memoryLength: 0,\n exit: true,\n error: true,\n inputGuardrailsTriggered: [],\n outputGuardrailsTriggered: [],\n startingAgentName: '',\n lastAgentName: '',\n availableSpecialists: [],\n isTransferredToSpecialist: false,\n }\n }\n }\n\n private async executeSpecialistAIAgent(\n botContext: BotContext<TPlugins, TExtraData>,\n aiAgentArgs: AiAgentSpecialistArgs,\n authToken: string,\n inferenceId: string\n ) {\n const llmConfig = new LLMConfig({\n maxRetries: this.maxRetries,\n timeout: this.timeout,\n modelName: aiAgentArgs.model,\n verbosity: aiAgentArgs.verbosity,\n botContext,\n reasoningEffort: aiAgentArgs.reasoningEffort,\n })\n\n // Get LLM config, tools and agent\n const { tools, agent } = await this.getSpecialistAgentAndTools(\n botContext,\n aiAgentArgs,\n aiAgentArgs.outputMessagesSchemas || [],\n authToken,\n inferenceId,\n llmConfig\n )\n\n // Get messages\n const messages = await this.getMessages(\n botContext,\n authToken,\n aiAgentArgs.previousHubtypeMessages || []\n )\n\n // Build context\n const context: Context<TPlugins, TExtraData> = {\n authToken,\n knowledgeUsed: {\n query: '',\n sourceIds: [],\n chunksIds: [],\n chunkTexts: [],\n },\n request: botContext,\n }\n\n // Log agent debug info\n this.logger.logAgentDebugInfo(\n aiAgentArgs,\n tools.map(t => t.name),\n messages\n )\n\n // Run agent\n const runner = new SpecialistRunner<TPlugins, TExtraData>(\n agent,\n llmConfig,\n inferenceId,\n this.logger\n )\n return await runner.run(messages, context)\n }\n\n private async executeRouterAIAgent(\n botContext: BotContext<TPlugins, TExtraData>,\n aiAgentArgs: AIAgentRouterArgs,\n authToken: string,\n inferenceId: string\n ) {\n const { specialists, name, instructions } = aiAgentArgs\n\n const llmConfig = new LLMConfig({\n maxRetries: this.maxRetries,\n timeout: this.timeout,\n modelName: aiAgentArgs.model,\n verbosity: aiAgentArgs.verbosity,\n botContext,\n reasoningEffort: aiAgentArgs.reasoningEffort,\n })\n\n const specialistsAgents = await Promise.all(\n specialists.map(async specialistData => {\n // If the forceToolNameOverride is set, we force this override for all specialists\n const forceToolNameOverride = aiAgentArgs.forceToolNameOverride\n const reasoningEffort = aiAgentArgs.reasoningEffort\n const disableForceRetrieveKnowledge =\n aiAgentArgs.disableForceRetrieveKnowledge\n\n // Create AiAgentArgs for the specialist, with values from AIAgentRouterArgs\n const aiAgentSpecialistArgs: AiAgentArgs = {\n ...specialistData,\n forceToolNameOverride,\n reasoningEffort,\n disableForceRetrieveKnowledge,\n }\n\n const { agent } = await this.getSpecialistAgentAndTools(\n botContext,\n aiAgentSpecialistArgs,\n aiAgentArgs.outputMessagesSchemas || [],\n authToken,\n inferenceId,\n llmConfig\n )\n\n return handoff(agent, {\n toolNameOverride: specialistData.name,\n toolDescriptionOverride: specialistData.description,\n })\n })\n )\n\n const router = await RouterAgent.create<TPlugins, TExtraData>({\n name,\n instructions,\n llmConfig,\n handoffs: specialistsAgents,\n inputGuardrailRules: aiAgentArgs.inputGuardrailRules || [],\n outputMessagesSchemas: aiAgentArgs.outputMessagesSchemas || [],\n guardrailTrackingContext: {\n botId: botContext.session.bot.id,\n isTest: botContext.session.is_test_integration,\n authToken,\n inferenceId,\n },\n })\n\n // Get messages\n const messages = await this.getMessages(\n botContext,\n authToken,\n aiAgentArgs.previousHubtypeMessages || []\n )\n\n // Build context\n const context: Context<TPlugins, TExtraData> = {\n authToken,\n knowledgeUsed: {\n query: '',\n sourceIds: [],\n chunksIds: [],\n chunkTexts: [],\n },\n request: botContext,\n }\n\n // Run agent\n const routerAgent = router.getAgent()\n const runner = new RouterRunner<TPlugins, TExtraData>(\n routerAgent,\n llmConfig,\n inferenceId,\n this.logger\n )\n\n return await runner.run(messages, context)\n }\n\n private async getSpecialistAgentAndTools(\n botContext: BotContext,\n aiAgentArgs: AiAgentArgs,\n outputMessagesSchemas: ZodObject<any>[],\n authToken: string,\n inferenceId: string,\n llmConfig: LLMConfig\n ) {\n // Build tools\n const tools = this.buildTools(aiAgentArgs)\n\n // Build agent\n const sourceIds =\n aiAgentArgs.type === AiAgentType.Specialist ? aiAgentArgs.sourceIds : []\n\n const specialist = await SpecialistAgent.create<TPlugins, TExtraData>({\n name: aiAgentArgs.name,\n instructions: aiAgentArgs.instructions,\n tools: tools,\n contactInfo: botContext.session.user.contact_info || [],\n inputGuardrailRules: aiAgentArgs.inputGuardrailRules || [],\n sourceIds,\n outputMessagesSchemas: outputMessagesSchemas || [],\n campaignsContext: botContext.input.context?.campaigns_v2,\n logger: this.logger,\n llmConfig,\n guardrailTrackingContext: {\n botId: botContext.session.bot.id,\n isTest: botContext.session.is_test_integration,\n authToken,\n inferenceId,\n },\n forceToolNameOverride: aiAgentArgs.forceToolNameOverride,\n disableForceRetrieveKnowledge: aiAgentArgs.disableForceRetrieveKnowledge,\n })\n const specialistAgent = specialist.getAgent()\n\n return { agent: specialistAgent, tools }\n }\n\n private async getMessages(\n botContext: BotContext,\n authToken: string,\n previousHubtypeMessages: HubtypeAssistantMessage[]\n ): Promise<AgenticInputMessage[]> {\n const hubtypeClient = new HubtypeApiClient(authToken)\n if (!isProd) {\n return await hubtypeClient.getLocalMessages(\n MAX_MEMORY_LENGTH,\n previousHubtypeMessages,\n this.localStorageKey\n )\n }\n\n // Default to V2\n const result = await hubtypeClient.getMessagesV2(\n botContext,\n this.memory,\n previousHubtypeMessages\n )\n return result.messages\n }\n\n private buildTools(aiAgentArgs: AiAgentArgs): Tool<TPlugins, TExtraData>[] {\n const activeTools =\n aiAgentArgs.type === AiAgentType.Router ? [] : aiAgentArgs.activeTools\n const activeToolNames = activeTools.map(tool => tool.name)\n const availableTools = this.toolDefinitions.filter(tool =>\n activeToolNames.includes(tool.name)\n )\n return availableTools.map(toolDefinition => {\n return tool<any, Context<TPlugins, TExtraData>, any>({\n name: toolDefinition.name,\n description: toolDefinition.description,\n parameters: toolDefinition.schema,\n execute: toolDefinition.func,\n })\n })\n }\n}\n\nexport * from './bot-config-tools'\nexport * from './types'\n"],"names":["AiAgentType","handoff","setTracingDisabled","tool","v7","uuidv7","RouterAgent","SpecialistAgent","DEFAULT_MAX_RETRIES","DEFAULT_TIMEOUT_16_SECONDS","isProd","MAX_MEMORY_LENGTH","createDebugLogger","LLMConfig","RouterRunner","SpecialistRunner","HubtypeApiClient","BotonicPluginAiAgents","memory","botContext","aiAgentArgs","authToken","Error","inferenceId","error","console","llmConfig","tools","agent","messages","context","t","runner","specialists","name","instructions","specialistsAgents","Promise","specialistData","forceToolNameOverride","reasoningEffort","disableForceRetrieveKnowledge","aiAgentSpecialistArgs","router","routerAgent","outputMessagesSchemas","sourceIds","specialist","specialistAgent","previousHubtypeMessages","hubtypeClient","result","activeTools","activeToolNames","availableTools","toolDefinition","options"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import {\n type AIAgentRouterArgs,\n type AiAgentArgs,\n type AiAgentSpecialistArgs,\n AiAgentType,\n type BotContext,\n type HubtypeAssistantMessage,\n type Plugin,\n type ResolvedPlugins,\n} from '@botonic/core'\nimport { handoff, setTracingDisabled, tool } from '@openai/agents'\nimport { v7 as uuidv7 } from 'uuid'\nimport type { ZodObject } from 'zod'\nimport { RouterAgent, SpecialistAgent } from './agents'\nimport {\n DEFAULT_MAX_RETRIES,\n DEFAULT_TIMEOUT_16_SECONDS,\n isProd,\n MAX_MEMORY_LENGTH,\n} from './constants'\nimport { createDebugLogger, type DebugLogger } from './debug-logger'\nimport { LLMConfig } from './llm-config'\nimport { RouterRunner, SpecialistRunner } from './runners'\nimport { HubtypeApiClient } from './services/hubtype-api-client'\nimport type {\n AgenticInputMessage,\n Context,\n CustomTool,\n InferenceResponse,\n MemoryOptions,\n PluginAiAgentOptions,\n Tool,\n} from './types'\n\nexport default class BotonicPluginAiAgents<\n TPlugins extends ResolvedPlugins = ResolvedPlugins,\n TExtraData = any,\n> implements Plugin\n{\n private readonly authToken?: string\n private readonly memory: MemoryOptions\n private readonly logger: DebugLogger\n private readonly timeout: number\n private readonly maxRetries: number\n public toolDefinitions: CustomTool<TPlugins, TExtraData>[] = []\n private readonly localStorageKey: string\n\n constructor(options?: PluginAiAgentOptions<TPlugins, TExtraData>) {\n this.authToken = options?.authToken\n this.toolDefinitions = options?.customTools || []\n this.memory = this.getMemoryOptions(options?.memory)\n this.timeout = options?.timeout ?? DEFAULT_TIMEOUT_16_SECONDS\n this.maxRetries = options?.maxRetries ?? DEFAULT_MAX_RETRIES\n this.logger = createDebugLogger(options?.enableDebug ?? false)\n this.localStorageKey = options?.localStorageKey ?? 'botonicState'\n setTracingDisabled(true)\n\n this.logger.logInitialConfig({\n messageHistoryApiVersion: 'v2',\n maxRetries: options?.maxRetries ?? DEFAULT_MAX_RETRIES,\n timeout: options?.timeout ?? DEFAULT_TIMEOUT_16_SECONDS,\n customToolNames: this.toolDefinitions.map(t => t.name),\n memory: this.memory,\n })\n }\n\n private getMemoryOptions(memory?: Partial<MemoryOptions>): MemoryOptions {\n return {\n maxMessages: memory?.maxMessages ?? MAX_MEMORY_LENGTH,\n includeToolCalls: memory?.includeToolCalls ?? true,\n maxFullToolResults: memory?.maxFullToolResults ?? 1,\n debugMode: memory?.debugMode ?? false,\n }\n }\n\n pre(): void {\n return\n }\n\n async getInference(\n botContext: BotContext<TPlugins, TExtraData>,\n aiAgentArgs: AiAgentArgs\n ): Promise<InferenceResponse> {\n const authToken = isProd ? botContext.session._access_token : this.authToken\n if (!authToken) {\n throw new Error('Auth token is required')\n }\n\n const inferenceId = uuidv7()\n\n try {\n if (aiAgentArgs.type === AiAgentType.Specialist) {\n return await this.executeSpecialistAIAgent(\n botContext,\n aiAgentArgs,\n authToken,\n inferenceId\n )\n }\n\n if (aiAgentArgs.type === AiAgentType.Router) {\n return await this.executeRouterAIAgent(\n botContext,\n aiAgentArgs,\n authToken,\n inferenceId\n )\n }\n\n throw new Error('Invalid agent type')\n } catch (error) {\n console.error('error plugin returns undefined', error)\n return {\n messages: [],\n toolsExecuted: [],\n memoryLength: 0,\n exit: true,\n error: true,\n doNothing: false,\n inputGuardrailsTriggered: [],\n outputGuardrailsTriggered: [],\n startingAgentName: '',\n lastAgentName: '',\n availableSpecialists: [],\n isTransferredToSpecialist: false,\n }\n }\n }\n\n private async executeSpecialistAIAgent(\n botContext: BotContext<TPlugins, TExtraData>,\n aiAgentArgs: AiAgentSpecialistArgs,\n authToken: string,\n inferenceId: string\n ) {\n const llmConfig = new LLMConfig({\n maxRetries: this.maxRetries,\n timeout: this.timeout,\n modelName: aiAgentArgs.model,\n verbosity: aiAgentArgs.verbosity,\n botContext,\n reasoningEffort: aiAgentArgs.reasoningEffort,\n })\n\n // Get LLM config, tools and agent\n const { tools, agent } = await this.getSpecialistAgentAndTools(\n botContext,\n aiAgentArgs,\n aiAgentArgs.outputMessagesSchemas || [],\n authToken,\n inferenceId,\n llmConfig\n )\n\n // Get messages\n const messages = await this.getMessages(\n botContext,\n authToken,\n aiAgentArgs.previousHubtypeMessages || []\n )\n\n // Build context\n const context: Context<TPlugins, TExtraData> = {\n authToken,\n knowledgeUsed: {\n query: '',\n sourceIds: [],\n chunksIds: [],\n chunkTexts: [],\n },\n request: botContext,\n }\n\n // Log agent debug info\n this.logger.logAgentDebugInfo(\n aiAgentArgs,\n tools.map(t => t.name),\n messages\n )\n\n // Run agent\n const runner = new SpecialistRunner<TPlugins, TExtraData>(\n agent,\n llmConfig,\n inferenceId,\n this.logger\n )\n return await runner.run(messages, context)\n }\n\n private async executeRouterAIAgent(\n botContext: BotContext<TPlugins, TExtraData>,\n aiAgentArgs: AIAgentRouterArgs,\n authToken: string,\n inferenceId: string\n ) {\n const { specialists, name, instructions } = aiAgentArgs\n\n const llmConfig = new LLMConfig({\n maxRetries: this.maxRetries,\n timeout: this.timeout,\n modelName: aiAgentArgs.model,\n verbosity: aiAgentArgs.verbosity,\n botContext,\n reasoningEffort: aiAgentArgs.reasoningEffort,\n })\n\n const specialistsAgents = await Promise.all(\n specialists.map(async specialistData => {\n // If the forceToolNameOverride is set, we force this override for all specialists\n const forceToolNameOverride = aiAgentArgs.forceToolNameOverride\n const reasoningEffort = aiAgentArgs.reasoningEffort\n const disableForceRetrieveKnowledge =\n aiAgentArgs.disableForceRetrieveKnowledge\n\n // Create AiAgentArgs for the specialist, with values from AIAgentRouterArgs\n const aiAgentSpecialistArgs: AiAgentArgs = {\n ...specialistData,\n forceToolNameOverride,\n reasoningEffort,\n disableForceRetrieveKnowledge,\n }\n\n const { agent } = await this.getSpecialistAgentAndTools(\n botContext,\n aiAgentSpecialistArgs,\n aiAgentArgs.outputMessagesSchemas || [],\n authToken,\n inferenceId,\n llmConfig\n )\n\n return handoff(agent, {\n toolNameOverride: specialistData.name,\n toolDescriptionOverride: specialistData.description,\n })\n })\n )\n\n const router = await RouterAgent.create<TPlugins, TExtraData>({\n name,\n instructions,\n llmConfig,\n handoffs: specialistsAgents,\n inputGuardrailRules: aiAgentArgs.inputGuardrailRules || [],\n outputMessagesSchemas: aiAgentArgs.outputMessagesSchemas || [],\n guardrailTrackingContext: {\n botId: botContext.session.bot.id,\n isTest: botContext.session.is_test_integration,\n authToken,\n inferenceId,\n },\n })\n\n // Get messages\n const messages = await this.getMessages(\n botContext,\n authToken,\n aiAgentArgs.previousHubtypeMessages || []\n )\n\n // Build context\n const context: Context<TPlugins, TExtraData> = {\n authToken,\n knowledgeUsed: {\n query: '',\n sourceIds: [],\n chunksIds: [],\n chunkTexts: [],\n },\n request: botContext,\n }\n\n // Run agent\n const routerAgent = router.getAgent()\n const runner = new RouterRunner<TPlugins, TExtraData>(\n routerAgent,\n llmConfig,\n inferenceId,\n this.logger\n )\n\n return await runner.run(messages, context)\n }\n\n private async getSpecialistAgentAndTools(\n botContext: BotContext,\n aiAgentArgs: AiAgentArgs,\n outputMessagesSchemas: ZodObject<any>[],\n authToken: string,\n inferenceId: string,\n llmConfig: LLMConfig\n ) {\n // Build tools\n const tools = this.buildTools(aiAgentArgs)\n\n // Build agent\n const sourceIds =\n aiAgentArgs.type === AiAgentType.Specialist ? aiAgentArgs.sourceIds : []\n\n const specialist = await SpecialistAgent.create<TPlugins, TExtraData>({\n name: aiAgentArgs.name,\n instructions: aiAgentArgs.instructions,\n tools: tools,\n contactInfo: botContext.session.user.contact_info || [],\n inputGuardrailRules: aiAgentArgs.inputGuardrailRules || [],\n sourceIds,\n outputMessagesSchemas: outputMessagesSchemas || [],\n campaignsContext: botContext.input.context?.campaigns_v2,\n logger: this.logger,\n llmConfig,\n guardrailTrackingContext: {\n botId: botContext.session.bot.id,\n isTest: botContext.session.is_test_integration,\n authToken,\n inferenceId,\n },\n forceToolNameOverride: aiAgentArgs.forceToolNameOverride,\n disableForceRetrieveKnowledge: aiAgentArgs.disableForceRetrieveKnowledge,\n })\n const specialistAgent = specialist.getAgent()\n\n return { agent: specialistAgent, tools }\n }\n\n private async getMessages(\n botContext: BotContext,\n authToken: string,\n previousHubtypeMessages: HubtypeAssistantMessage[]\n ): Promise<AgenticInputMessage[]> {\n const hubtypeClient = new HubtypeApiClient(authToken)\n if (!isProd) {\n return await hubtypeClient.getLocalMessages(\n MAX_MEMORY_LENGTH,\n previousHubtypeMessages,\n this.localStorageKey\n )\n }\n\n // Default to V2\n const result = await hubtypeClient.getMessagesV2(\n botContext,\n this.memory,\n previousHubtypeMessages\n )\n return result.messages\n }\n\n private buildTools(aiAgentArgs: AiAgentArgs): Tool<TPlugins, TExtraData>[] {\n const activeTools =\n aiAgentArgs.type === AiAgentType.Router ? [] : aiAgentArgs.activeTools\n const activeToolNames = activeTools.map(tool => tool.name)\n const availableTools = this.toolDefinitions.filter(tool =>\n activeToolNames.includes(tool.name)\n )\n return availableTools.map(toolDefinition => {\n return tool<any, Context<TPlugins, TExtraData>, any>({\n name: toolDefinition.name,\n description: toolDefinition.description,\n parameters: toolDefinition.schema,\n execute: toolDefinition.func,\n })\n })\n }\n}\n\nexport * from './bot-config-tools'\nexport * from './types'\n"],"names":["AiAgentType","handoff","setTracingDisabled","tool","v7","uuidv7","RouterAgent","SpecialistAgent","DEFAULT_MAX_RETRIES","DEFAULT_TIMEOUT_16_SECONDS","isProd","MAX_MEMORY_LENGTH","createDebugLogger","LLMConfig","RouterRunner","SpecialistRunner","HubtypeApiClient","BotonicPluginAiAgents","memory","botContext","aiAgentArgs","authToken","Error","inferenceId","error","console","llmConfig","tools","agent","messages","context","t","runner","specialists","name","instructions","specialistsAgents","Promise","specialistData","forceToolNameOverride","reasoningEffort","disableForceRetrieveKnowledge","aiAgentSpecialistArgs","router","routerAgent","outputMessagesSchemas","sourceIds","specialist","specialistAgent","previousHubtypeMessages","hubtypeClient","result","activeTools","activeToolNames","availableTools","toolDefinition","options"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { OutputMessage, ResolvedPlugins, ToolExecution } from '@botonic/core';
1
+ import { type OutputMessage, type ResolvedPlugins, type ToolExecution } from '@botonic/core';
2
2
  import type { DebugLogger } from '../debug-logger.js';
3
3
  import type { LLMConfig } from '../llm-config.js';
4
4
  import type { AgenticInputMessage, AIAgent, Context, ResultRawResponse, RunResult } from '../types.js';
@@ -1,3 +1,4 @@
1
+ import { OutputMessageType } from "@botonic/core";
1
2
  import { InputGuardrailTripwireTriggered, RunContext, RunToolCallItem, RunToolCallOutputItem, Runner } from "@openai/agents";
2
3
  import { LLM_PROVIDERS, isProd } from "../constants.js";
3
4
  import { HubtypeApiClient } from "../services/hubtype-api-client.js";
@@ -9,6 +10,7 @@ import { RETRIEVE_KNOWLEDGE_TOOL_NAME } from "../tools/index.js";
9
10
 
10
11
 
11
12
 
13
+
12
14
  function _define_property(obj, key, value) {
13
15
  if (key in obj) {
14
16
  Object.defineProperty(obj, key, {
@@ -25,6 +27,7 @@ function _define_property(obj, key, value) {
25
27
 
26
28
 
27
29
 
30
+
28
31
  class BaseRunner {
29
32
  async run(messages, context) {
30
33
  const startTime = Date.now();
@@ -114,17 +117,19 @@ class BaseRunner {
114
117
  }
115
118
  buildRunResult(result, context, memoryLength) {
116
119
  const outputMessages = result.finalOutput?.messages || [];
117
- const hasExit = outputMessages.length === 0 || outputMessages.some((message)=>message.type === 'exit');
120
+ const hasExit = outputMessages.length === 0 || outputMessages.some((message)=>message.type === OutputMessageType.Exit);
121
+ const hasDoNothing = outputMessages.some((message)=>message.type === OutputMessageType.DoNothing);
118
122
  return {
119
123
  startingAgentName: '',
120
124
  lastAgentName: '',
121
125
  availableSpecialists: [],
122
126
  isTransferredToSpecialist: false,
123
- messages: hasExit ? [] : outputMessages.filter((message)=>message.type !== 'exit'),
127
+ messages: hasExit || hasDoNothing ? [] : outputMessages.filter((message)=>message.type !== OutputMessageType.Exit && message.type !== OutputMessageType.DoNothing),
124
128
  toolsExecuted: this.getToolsExecuted(result, context),
125
129
  exit: hasExit,
126
130
  memoryLength,
127
131
  error: false,
132
+ doNothing: hasDoNothing,
128
133
  inputGuardrailsTriggered: [],
129
134
  outputGuardrailsTriggered: []
130
135
  };
@@ -176,6 +181,7 @@ class BaseRunner {
176
181
  toolsExecuted: [],
177
182
  exit: true,
178
183
  error: false,
184
+ doNothing: false,
179
185
  inputGuardrailsTriggered: error.result.output.outputInfo,
180
186
  outputGuardrailsTriggered: []
181
187
  };
@@ -1 +1 @@
1
- {"version":3,"file":"runners/base-runner.js","sources":["../../src/runners/base-runner.ts"],"sourcesContent":["import type {\n OutputMessage,\n ResolvedPlugins,\n ToolExecution,\n} from '@botonic/core'\nimport {\n InputGuardrailTripwireTriggered,\n RunContext,\n Runner,\n RunToolCallItem,\n RunToolCallOutputItem,\n} from '@openai/agents'\nimport { isProd, LLM_PROVIDERS } from '../constants'\nimport type { DebugLogger } from '../debug-logger'\nimport type { LLMConfig } from '../llm-config'\nimport { HubtypeApiClient } from '../services/hubtype-api-client'\nimport { TrackFeature, TrackProductName } from '../services/types'\nimport { RETRIEVE_KNOWLEDGE_TOOL_NAME } from '../tools'\nimport type {\n AgenticInputMessage,\n AgenticOutputMessage,\n AIAgent,\n Context,\n ResultRawResponse,\n RunResult,\n} from '../types'\n\n// Minimal interface matching the properties we actually use from Runner.run() result.\n// This bypasses strict type checking while maintaining type safety for accessed properties.\nexport interface RunnerResult {\n finalOutput?: {\n messages?: OutputMessage[]\n }\n rawResponses?: ResultRawResponse[]\n newItems?: unknown[]\n lastAgent?: { name?: string }\n // biome-ignore lint/suspicious/noExplicitAny: state is a complex internal type\n state?: any\n}\n\nexport abstract class BaseRunner<\n TPlugins extends ResolvedPlugins = ResolvedPlugins,\n TExtraData = unknown,\n> {\n protected agent: AIAgent<TPlugins, TExtraData>\n protected llmConfig: LLMConfig\n protected inferenceId: string\n protected logger: DebugLogger\n\n constructor(\n agent: AIAgent<TPlugins, TExtraData>,\n llmConfig: LLMConfig,\n inferenceId: string,\n logger: DebugLogger\n ) {\n this.agent = agent\n this.llmConfig = llmConfig\n this.inferenceId = inferenceId\n this.logger = logger\n }\n\n async run(\n messages: AgenticInputMessage[],\n context: Context<TPlugins, TExtraData>\n ): Promise<RunResult> {\n const startTime = Date.now()\n\n const runContext = new RunContext(context)\n const prompt = (await this.agent.getSystemPrompt(runContext)) ?? ''\n this.logger.logRunnerStart(\n this.llmConfig.modelName,\n this.llmConfig.modelSettings,\n prompt\n )\n\n try {\n const runner = new Runner({\n tracingDisabled: true,\n })\n const result = (await runner.run(this.agent, messages, {\n context,\n })) as RunnerResult\n const endTime = Date.now()\n\n await this.sendLlmRunTracking(result, context, startTime, endTime)\n\n const runResult = this.buildRunResult(result, context, messages.length)\n\n this.logger.logRunResult(runResult, startTime)\n\n return runResult\n } catch (error) {\n const runResult = this.handleInputGuardrailTripwireTriggered(\n error,\n startTime\n )\n if (runResult) {\n return runResult\n }\n\n this.logger.logRunnerError(startTime, error)\n\n throw error\n }\n }\n\n protected getToolsExecuted(\n result: RunnerResult,\n context: Context<TPlugins, TExtraData>\n ): ToolExecution[] {\n const toolResultsByCallId = this.getToolResultsByCallId(result.newItems)\n\n return (\n result.newItems\n ?.filter(item => item instanceof RunToolCallItem)\n .map((item: RunToolCallItem) =>\n this.getToolExecutionInfo(\n item as RunToolCallItem,\n context,\n toolResultsByCallId\n )\n )\n .filter(\n (toolExecution: ToolExecution) => toolExecution.toolName !== ''\n ) || []\n )\n }\n\n private getToolResultsByCallId(\n newItems: unknown[] = []\n ): Map<string, string> {\n const map = new Map<string, string>()\n for (const item of newItems) {\n if (!(item instanceof RunToolCallOutputItem)) {\n continue\n }\n const rawItem = item.rawItem as {\n callId?: string\n output?: string | { type?: string; text?: string }\n }\n const callId = rawItem?.callId\n const output = rawItem?.output\n if (callId == null || output == null) {\n continue\n }\n const text = this.extractToolResult(output)\n if (text != null) {\n map.set(callId, text)\n }\n }\n return map\n }\n\n private extractToolResult(\n output: string | { type?: string; text?: string }\n ): string | undefined {\n if (typeof output === 'string') {\n return output\n }\n return output?.type === 'text' && typeof output?.text === 'string'\n ? output.text\n : undefined\n }\n\n private getToolExecutionInfo(\n item: RunToolCallItem,\n context: Context<TPlugins, TExtraData>,\n toolResultsByCallId: Map<string, string>\n ): ToolExecution {\n if (item.rawItem.type !== 'function_call') {\n return {\n toolName: '',\n toolArguments: {},\n }\n }\n const toolName = item.rawItem.name\n const toolArguments = this.getSafeToolArguments(item.rawItem.arguments)\n const toolResults = item.rawItem.callId\n ? toolResultsByCallId.get(item.rawItem.callId)\n : undefined\n\n const toolExecution: ToolExecution = {\n toolName,\n toolArguments,\n toolResults,\n }\n\n if (toolName === RETRIEVE_KNOWLEDGE_TOOL_NAME) {\n return {\n ...toolExecution,\n knowledgebaseSourcesIds: context.knowledgeUsed.sourceIds,\n knowledgebaseChunksIds: context.knowledgeUsed.chunksIds,\n }\n }\n\n return toolExecution\n }\n\n private getSafeToolArguments(\n rawToolArguments: string\n ): Record<string, unknown> {\n try {\n return JSON.parse(rawToolArguments)\n } catch (_error) {\n return {}\n }\n }\n\n protected buildRunResult(\n result: RunnerResult,\n context: Context<TPlugins, TExtraData>,\n memoryLength: number\n ): RunResult {\n const outputMessages = result.finalOutput?.messages || []\n const hasExit =\n outputMessages.length === 0 ||\n outputMessages.some(message => message.type === 'exit')\n\n return {\n startingAgentName: '',\n lastAgentName: '',\n availableSpecialists: [],\n isTransferredToSpecialist: false,\n messages: hasExit\n ? []\n : (outputMessages.filter(\n message => message.type !== 'exit'\n ) as AgenticOutputMessage[]),\n toolsExecuted: this.getToolsExecuted(result, context),\n exit: hasExit,\n memoryLength,\n error: false,\n inputGuardrailsTriggered: [],\n outputGuardrailsTriggered: [],\n }\n }\n\n private async sendLlmRunTracking(\n result: RunnerResult,\n context: Context<TPlugins, TExtraData>,\n startTime: number,\n endTime: number\n ): Promise<void> {\n if (!isProd) {\n return\n }\n if (this.llmConfig.getProviderName() === LLM_PROVIDERS.LITELLM) {\n return\n }\n const rawResponses = result.rawResponses ?? []\n if (rawResponses.length === 0) {\n return\n }\n const botId = context.request.session.bot.id\n const isTest = context.request.session.is_test_integration\n const totalDuration = endTime - startTime\n const durationPerCall = Math.round(totalDuration / rawResponses.length)\n const temperature =\n (this.llmConfig.modelSettings.temperature as number | undefined) ?? 0\n const llmRuns = rawResponses.map(response => ({\n inference_id: this.inferenceId,\n is_test: isTest,\n product_name: TrackProductName.AI_AGENT,\n deployment_name: this.llmConfig.modelName,\n model_name:\n (response.providerData?.model as string | undefined) ??\n this.llmConfig.modelName,\n feature: TrackFeature.AI_AGENT_RUN,\n api_version: this.llmConfig.getApiVersion(),\n num_prompt_tokens: response.usage.inputTokens,\n num_completion_tokens: response.usage.outputTokens,\n duration_in_milliseconds: durationPerCall,\n temperature,\n error: null,\n }))\n\n const client = new HubtypeApiClient(context.authToken)\n await client.trackLlmRuns(botId, {\n llm_runs: llmRuns,\n })\n }\n\n protected handleInputGuardrailTripwireTriggered(\n error: unknown,\n startTime: number\n ): RunResult | undefined {\n if (error instanceof InputGuardrailTripwireTriggered) {\n const runResult: RunResult = {\n startingAgentName: '',\n lastAgentName: '',\n availableSpecialists: [],\n isTransferredToSpecialist: false,\n messages: [],\n memoryLength: 0,\n toolsExecuted: [],\n exit: true,\n error: false,\n inputGuardrailsTriggered: error.result.output.outputInfo,\n outputGuardrailsTriggered: [],\n }\n\n this.logger.logGuardrailTriggered()\n this.logger.logRunResult(runResult, startTime)\n\n return runResult\n }\n }\n}\n"],"names":["InputGuardrailTripwireTriggered","RunContext","Runner","RunToolCallItem","RunToolCallOutputItem","isProd","LLM_PROVIDERS","HubtypeApiClient","TrackFeature","TrackProductName","RETRIEVE_KNOWLEDGE_TOOL_NAME","BaseRunner","messages","context","startTime","Date","runContext","prompt","runner","result","endTime","runResult","error","toolResultsByCallId","item","toolExecution","newItems","map","Map","rawItem","callId","output","text","undefined","toolName","toolArguments","toolResults","rawToolArguments","JSON","_error","memoryLength","outputMessages","hasExit","message","rawResponses","botId","isTest","totalDuration","durationPerCall","Math","temperature","llmRuns","response","client","agent","llmConfig","inferenceId","logger"],"mappings":"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"}
1
+ {"version":3,"file":"runners/base-runner.js","sources":["../../src/runners/base-runner.ts"],"sourcesContent":["import {\n type OutputMessage,\n OutputMessageType,\n type ResolvedPlugins,\n type ToolExecution,\n} from '@botonic/core'\nimport {\n InputGuardrailTripwireTriggered,\n RunContext,\n Runner,\n RunToolCallItem,\n RunToolCallOutputItem,\n} from '@openai/agents'\nimport { isProd, LLM_PROVIDERS } from '../constants'\nimport type { DebugLogger } from '../debug-logger'\nimport type { LLMConfig } from '../llm-config'\nimport { HubtypeApiClient } from '../services/hubtype-api-client'\nimport { TrackFeature, TrackProductName } from '../services/types'\nimport { RETRIEVE_KNOWLEDGE_TOOL_NAME } from '../tools'\nimport type {\n AgenticInputMessage,\n AgenticOutputMessage,\n AIAgent,\n Context,\n ResultRawResponse,\n RunResult,\n} from '../types'\n\n// Minimal interface matching the properties we actually use from Runner.run() result.\n// This bypasses strict type checking while maintaining type safety for accessed properties.\nexport interface RunnerResult {\n finalOutput?: {\n messages?: OutputMessage[]\n }\n rawResponses?: ResultRawResponse[]\n newItems?: unknown[]\n lastAgent?: { name?: string }\n // biome-ignore lint/suspicious/noExplicitAny: state is a complex internal type\n state?: any\n}\n\nexport abstract class BaseRunner<\n TPlugins extends ResolvedPlugins = ResolvedPlugins,\n TExtraData = unknown,\n> {\n protected agent: AIAgent<TPlugins, TExtraData>\n protected llmConfig: LLMConfig\n protected inferenceId: string\n protected logger: DebugLogger\n\n constructor(\n agent: AIAgent<TPlugins, TExtraData>,\n llmConfig: LLMConfig,\n inferenceId: string,\n logger: DebugLogger\n ) {\n this.agent = agent\n this.llmConfig = llmConfig\n this.inferenceId = inferenceId\n this.logger = logger\n }\n\n async run(\n messages: AgenticInputMessage[],\n context: Context<TPlugins, TExtraData>\n ): Promise<RunResult> {\n const startTime = Date.now()\n\n const runContext = new RunContext(context)\n const prompt = (await this.agent.getSystemPrompt(runContext)) ?? ''\n this.logger.logRunnerStart(\n this.llmConfig.modelName,\n this.llmConfig.modelSettings,\n prompt\n )\n\n try {\n const runner = new Runner({\n tracingDisabled: true,\n })\n const result = (await runner.run(this.agent, messages, {\n context,\n })) as RunnerResult\n const endTime = Date.now()\n\n await this.sendLlmRunTracking(result, context, startTime, endTime)\n\n const runResult = this.buildRunResult(result, context, messages.length)\n\n this.logger.logRunResult(runResult, startTime)\n\n return runResult\n } catch (error) {\n const runResult = this.handleInputGuardrailTripwireTriggered(\n error,\n startTime\n )\n if (runResult) {\n return runResult\n }\n\n this.logger.logRunnerError(startTime, error)\n\n throw error\n }\n }\n\n protected getToolsExecuted(\n result: RunnerResult,\n context: Context<TPlugins, TExtraData>\n ): ToolExecution[] {\n const toolResultsByCallId = this.getToolResultsByCallId(result.newItems)\n\n return (\n result.newItems\n ?.filter(item => item instanceof RunToolCallItem)\n .map((item: RunToolCallItem) =>\n this.getToolExecutionInfo(\n item as RunToolCallItem,\n context,\n toolResultsByCallId\n )\n )\n .filter(\n (toolExecution: ToolExecution) => toolExecution.toolName !== ''\n ) || []\n )\n }\n\n private getToolResultsByCallId(\n newItems: unknown[] = []\n ): Map<string, string> {\n const map = new Map<string, string>()\n for (const item of newItems) {\n if (!(item instanceof RunToolCallOutputItem)) {\n continue\n }\n const rawItem = item.rawItem as {\n callId?: string\n output?: string | { type?: string; text?: string }\n }\n const callId = rawItem?.callId\n const output = rawItem?.output\n if (callId == null || output == null) {\n continue\n }\n const text = this.extractToolResult(output)\n if (text != null) {\n map.set(callId, text)\n }\n }\n return map\n }\n\n private extractToolResult(\n output: string | { type?: string; text?: string }\n ): string | undefined {\n if (typeof output === 'string') {\n return output\n }\n return output?.type === 'text' && typeof output?.text === 'string'\n ? output.text\n : undefined\n }\n\n private getToolExecutionInfo(\n item: RunToolCallItem,\n context: Context<TPlugins, TExtraData>,\n toolResultsByCallId: Map<string, string>\n ): ToolExecution {\n if (item.rawItem.type !== 'function_call') {\n return {\n toolName: '',\n toolArguments: {},\n }\n }\n const toolName = item.rawItem.name\n const toolArguments = this.getSafeToolArguments(item.rawItem.arguments)\n const toolResults = item.rawItem.callId\n ? toolResultsByCallId.get(item.rawItem.callId)\n : undefined\n\n const toolExecution: ToolExecution = {\n toolName,\n toolArguments,\n toolResults,\n }\n\n if (toolName === RETRIEVE_KNOWLEDGE_TOOL_NAME) {\n return {\n ...toolExecution,\n knowledgebaseSourcesIds: context.knowledgeUsed.sourceIds,\n knowledgebaseChunksIds: context.knowledgeUsed.chunksIds,\n }\n }\n\n return toolExecution\n }\n\n private getSafeToolArguments(\n rawToolArguments: string\n ): Record<string, unknown> {\n try {\n return JSON.parse(rawToolArguments)\n } catch (_error) {\n return {}\n }\n }\n\n protected buildRunResult(\n result: RunnerResult,\n context: Context<TPlugins, TExtraData>,\n memoryLength: number\n ): RunResult {\n const outputMessages = result.finalOutput?.messages || []\n const hasExit =\n outputMessages.length === 0 ||\n outputMessages.some(message => message.type === OutputMessageType.Exit)\n\n const hasDoNothing = outputMessages.some(\n message => message.type === OutputMessageType.DoNothing\n )\n\n return {\n startingAgentName: '',\n lastAgentName: '',\n availableSpecialists: [],\n isTransferredToSpecialist: false,\n messages:\n hasExit || hasDoNothing\n ? []\n : (outputMessages.filter(\n message =>\n message.type !== OutputMessageType.Exit &&\n message.type !== OutputMessageType.DoNothing\n ) as AgenticOutputMessage[]),\n toolsExecuted: this.getToolsExecuted(result, context),\n exit: hasExit,\n memoryLength,\n error: false,\n doNothing: hasDoNothing,\n inputGuardrailsTriggered: [],\n outputGuardrailsTriggered: [],\n }\n }\n\n private async sendLlmRunTracking(\n result: RunnerResult,\n context: Context<TPlugins, TExtraData>,\n startTime: number,\n endTime: number\n ): Promise<void> {\n if (!isProd) {\n return\n }\n if (this.llmConfig.getProviderName() === LLM_PROVIDERS.LITELLM) {\n return\n }\n const rawResponses = result.rawResponses ?? []\n if (rawResponses.length === 0) {\n return\n }\n const botId = context.request.session.bot.id\n const isTest = context.request.session.is_test_integration\n const totalDuration = endTime - startTime\n const durationPerCall = Math.round(totalDuration / rawResponses.length)\n const temperature =\n (this.llmConfig.modelSettings.temperature as number | undefined) ?? 0\n const llmRuns = rawResponses.map(response => ({\n inference_id: this.inferenceId,\n is_test: isTest,\n product_name: TrackProductName.AI_AGENT,\n deployment_name: this.llmConfig.modelName,\n model_name:\n (response.providerData?.model as string | undefined) ??\n this.llmConfig.modelName,\n feature: TrackFeature.AI_AGENT_RUN,\n api_version: this.llmConfig.getApiVersion(),\n num_prompt_tokens: response.usage.inputTokens,\n num_completion_tokens: response.usage.outputTokens,\n duration_in_milliseconds: durationPerCall,\n temperature,\n error: null,\n }))\n\n const client = new HubtypeApiClient(context.authToken)\n await client.trackLlmRuns(botId, {\n llm_runs: llmRuns,\n })\n }\n\n protected handleInputGuardrailTripwireTriggered(\n error: unknown,\n startTime: number\n ): RunResult | undefined {\n if (error instanceof InputGuardrailTripwireTriggered) {\n const runResult: RunResult = {\n startingAgentName: '',\n lastAgentName: '',\n availableSpecialists: [],\n isTransferredToSpecialist: false,\n messages: [],\n memoryLength: 0,\n toolsExecuted: [],\n exit: true,\n error: false,\n doNothing: false,\n inputGuardrailsTriggered: error.result.output.outputInfo,\n outputGuardrailsTriggered: [],\n }\n\n this.logger.logGuardrailTriggered()\n this.logger.logRunResult(runResult, startTime)\n\n return runResult\n }\n }\n}\n"],"names":["OutputMessageType","InputGuardrailTripwireTriggered","RunContext","Runner","RunToolCallItem","RunToolCallOutputItem","isProd","LLM_PROVIDERS","HubtypeApiClient","TrackFeature","TrackProductName","RETRIEVE_KNOWLEDGE_TOOL_NAME","BaseRunner","messages","context","startTime","Date","runContext","prompt","runner","result","endTime","runResult","error","toolResultsByCallId","item","toolExecution","newItems","map","Map","rawItem","callId","output","text","undefined","toolName","toolArguments","toolResults","rawToolArguments","JSON","_error","memoryLength","outputMessages","hasExit","message","hasDoNothing","rawResponses","botId","isTest","totalDuration","durationPerCall","Math","temperature","llmRuns","response","client","agent","llmConfig","inferenceId","logger"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { type DoNothingMessage, OutputMessageType } from '@botonic/core';
2
+ import { z } from 'zod';
3
+ export type { DoNothingMessage };
4
+ export declare const DoNothingSchema: z.ZodObject<{
5
+ type: z.ZodLiteral<OutputMessageType.DoNothing>;
6
+ }, z.core.$strip>;
@@ -0,0 +1,14 @@
1
+ import { OutputMessageType } from "@botonic/core";
2
+ import { z } from "zod";
3
+
4
+
5
+
6
+
7
+
8
+ const DoNothingSchema = z.object({
9
+ type: z.literal(OutputMessageType.DoNothing)
10
+ }).describe('A do nothing message is used to end the conversation without send a reply. Use it only when asked explicitly in the prompt.');
11
+
12
+ export { DoNothingSchema };
13
+
14
+ //# sourceMappingURL=do-nothing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structured-output/do-nothing.js","sources":["../../src/structured-output/do-nothing.ts"],"sourcesContent":["import { type DoNothingMessage, OutputMessageType } from '@botonic/core'\nimport { z } from 'zod'\n\nexport type { DoNothingMessage }\n\nexport const DoNothingSchema = z\n .object({\n type: z.literal(OutputMessageType.DoNothing),\n })\n .describe(\n 'A do nothing message is used to end the conversation without send a reply. Use it only when asked explicitly in the prompt.'\n )\n"],"names":["OutputMessageType","z","DoNothingSchema"],"mappings":";;;;;AAAwE;AACjD;AAIhB,MAAME,eAAeA,GAAGD,QACtB,CAAC;IACN,MAAMA,SAAS,CAACD,2BAA2B;AAC7C,GACC,QAAQ,CACP,+HACD"}
@@ -36,6 +36,8 @@ export declare const OutputSchema: z.ZodObject<{
36
36
  }, z.core.$strip>;
37
37
  }, z.core.$strip>>;
38
38
  }, z.core.$strip>;
39
+ }, z.core.$strip>, z.ZodObject<{
40
+ type: z.ZodLiteral<import("@botonic/core").OutputMessageType.DoNothing>;
39
41
  }, z.core.$strip>, z.ZodObject<{
40
42
  type: z.ZodLiteral<import("@botonic/core").OutputMessageType.Exit>;
41
43
  }, z.core.$strip>, z.ZodObject<{
@@ -47,6 +49,11 @@ export declare const OutputSchema: z.ZodObject<{
47
49
  payload: z.ZodString;
48
50
  }, z.core.$strip>>;
49
51
  }, z.core.$strip>;
52
+ }, z.core.$strip>, z.ZodObject<{
53
+ type: z.ZodLiteral<import("@botonic/core").OutputMessageType.RequestContactInfo>;
54
+ content: z.ZodObject<{
55
+ text: z.ZodString;
56
+ }, z.core.$strip>;
50
57
  }, z.core.$strip>]>>;
51
58
  }, z.core.$strip>;
52
59
  export declare function getOutputSchema(externalOutputMessagesSchemas: z.ZodObject<any>[]): z.ZodObject<{
@@ -82,6 +89,8 @@ export declare function getOutputSchema(externalOutputMessagesSchemas: z.ZodObje
82
89
  }, z.core.$strip>;
83
90
  }, z.core.$strip>>;
84
91
  }, z.core.$strip>;
92
+ }, z.core.$strip>, z.ZodObject<{
93
+ type: z.ZodLiteral<import("@botonic/core").OutputMessageType.DoNothing>;
85
94
  }, z.core.$strip>, z.ZodObject<{
86
95
  type: z.ZodLiteral<import("@botonic/core").OutputMessageType.Exit>;
87
96
  }, z.core.$strip>, z.ZodObject<{
@@ -93,6 +102,11 @@ export declare function getOutputSchema(externalOutputMessagesSchemas: z.ZodObje
93
102
  payload: z.ZodString;
94
103
  }, z.core.$strip>>;
95
104
  }, z.core.$strip>;
105
+ }, z.core.$strip>, z.ZodObject<{
106
+ type: z.ZodLiteral<import("@botonic/core").OutputMessageType.RequestContactInfo>;
107
+ content: z.ZodObject<{
108
+ text: z.ZodString;
109
+ }, z.core.$strip>;
96
110
  }, z.core.$strip>, ...z.ZodObject<any, z.core.$strip>[]]>>;
97
111
  }, z.core.$strip>;
98
112
  export declare function getOutputInstructions(): string;
@@ -1,7 +1,9 @@
1
1
  import { z } from "zod";
2
2
  import { BotExecutorSchema } from "./bot-executor.js";
3
3
  import { CarouselSchema } from "./carousel.js";
4
+ import { DoNothingSchema } from "./do-nothing.js";
4
5
  import { ExitSchema } from "./exit.js";
6
+ import { RequestContactInfoSchema } from "./request-contact-info.js";
5
7
  import { TextSchema } from "./text.js";
6
8
  import { TextWithButtonsSchema } from "./text-with-buttons.js";
7
9
 
@@ -17,12 +19,18 @@ import { TextWithButtonsSchema } from "./text-with-buttons.js";
17
19
 
18
20
 
19
21
 
22
+
23
+
24
+
25
+
20
26
  const baseMessageSchemas = [
21
27
  TextSchema,
22
28
  TextWithButtonsSchema,
23
29
  CarouselSchema,
30
+ DoNothingSchema,
24
31
  ExitSchema,
25
- BotExecutorSchema
32
+ BotExecutorSchema,
33
+ RequestContactInfoSchema
26
34
  ];
27
35
  const OutputSchema = z.object({
28
36
  messages: z.array(z.union(baseMessageSchemas))
@@ -1 +1 @@
1
- {"version":3,"file":"structured-output/index.js","sources":["../../src/structured-output/index.ts"],"sourcesContent":["import type { OutputMessage } from '@botonic/core'\nimport { z } from 'zod'\nimport { BotExecutorSchema } from './bot-executor'\nimport { CarouselSchema } from './carousel'\nimport { ExitSchema } from './exit'\nimport { TextSchema } from './text'\nimport { TextWithButtonsSchema } from './text-with-buttons'\n\nexport interface Output {\n messages: OutputMessage[]\n}\n\nconst baseMessageSchemas = [\n TextSchema,\n TextWithButtonsSchema,\n CarouselSchema,\n ExitSchema,\n BotExecutorSchema,\n] as const\nexport const OutputSchema = z\n .object({\n messages: z.array(z.union(baseMessageSchemas)),\n })\n .describe('The messages to be sent to the user')\n\nexport function getOutputSchema(\n externalOutputMessagesSchemas: z.ZodObject<any>[]\n) {\n return z.object({\n messages: z.array(\n z.union([...baseMessageSchemas, ...externalOutputMessagesSchemas])\n ),\n })\n}\n\nexport function getOutputInstructions(): string {\n const example = {\n messages: [\n {\n type: 'text',\n content: {\n text: 'Hello, how can I help you today?',\n },\n },\n ],\n }\n const output = `Return a JSON that follows the output schema provided. Never return multiple output schemas concatenated by a line break.\\n<example>\\n${JSON.stringify(example)}\\n</example>`\n return `<output>\\n${output}\\n</output>`\n}\n"],"names":["z","BotExecutorSchema","CarouselSchema","ExitSchema","TextSchema","TextWithButtonsSchema","baseMessageSchemas","OutputSchema","getOutputSchema","externalOutputMessagesSchemas","getOutputInstructions","example","output","JSON"],"mappings":";;;;;;;;;;;;;AACuB;AAC2B;AACP;AACR;AACA;AACwB;AAM3D,MAAMM,kBAAkBA,GAAG;IACzBF,UAAUA;IACVC,qBAAqBA;IACrBH,cAAcA;IACdC,UAAUA;IACVF,iBAAiBA;CAClB;AACM,MAAMM,YAAYA,GAAGP,QACnB,CAAC;IACN,UAAUA,OAAO,CAACA,OAAO,CAACM,kBAAkBA;AAC9C,GACC,QAAQ,CAAC,uCAAsC;AAE3C,SAASE,eAAeA,CAC7BC,6BAAiD;IAEjD,OAAOT,QAAQ,CAAC;QACd,UAAUA,OAAO,CACfA,OAAO,CAAC;eAAIM,kBAAkBA;eAAKG;SAA8B;IAErE;AACF;AAEO,SAASC,qBAAqBA;IACnC,MAAMC,UAAU;QACd,UAAU;YACR;gBACE,MAAM;gBACN,SAAS;oBACP,MAAM;gBACR;YACF;SACD;IACH;IACA,MAAMC,SAAS,CAAC,sIAAsI,EAAEC,KAAK,SAAS,CAACF,SAAS,YAAY,CAAC;IAC7L,OAAO,CAAC,UAAU,EAAEC,OAAO,WAAW,CAAC;AACzC"}
1
+ {"version":3,"file":"structured-output/index.js","sources":["../../src/structured-output/index.ts"],"sourcesContent":["import type { OutputMessage } from '@botonic/core'\nimport { z } from 'zod'\nimport { BotExecutorSchema } from './bot-executor'\nimport { CarouselSchema } from './carousel'\nimport { DoNothingSchema } from './do-nothing'\nimport { ExitSchema } from './exit'\nimport { RequestContactInfoSchema } from './request-contact-info'\nimport { TextSchema } from './text'\nimport { TextWithButtonsSchema } from './text-with-buttons'\n\nexport interface Output {\n messages: OutputMessage[]\n}\n\nconst baseMessageSchemas = [\n TextSchema,\n TextWithButtonsSchema,\n CarouselSchema,\n DoNothingSchema,\n ExitSchema,\n BotExecutorSchema,\n RequestContactInfoSchema,\n] as const\nexport const OutputSchema = z\n .object({\n messages: z.array(z.union(baseMessageSchemas)),\n })\n .describe('The messages to be sent to the user')\n\nexport function getOutputSchema(\n externalOutputMessagesSchemas: z.ZodObject<any>[]\n) {\n return z.object({\n messages: z.array(\n z.union([...baseMessageSchemas, ...externalOutputMessagesSchemas])\n ),\n })\n}\n\nexport function getOutputInstructions(): string {\n const example = {\n messages: [\n {\n type: 'text',\n content: {\n text: 'Hello, how can I help you today?',\n },\n },\n ],\n }\n const output = `Return a JSON that follows the output schema provided. Never return multiple output schemas concatenated by a line break.\\n<example>\\n${JSON.stringify(example)}\\n</example>`\n return `<output>\\n${output}\\n</output>`\n}\n"],"names":["z","BotExecutorSchema","CarouselSchema","DoNothingSchema","ExitSchema","RequestContactInfoSchema","TextSchema","TextWithButtonsSchema","baseMessageSchemas","OutputSchema","getOutputSchema","externalOutputMessagesSchemas","getOutputInstructions","example","output","JSON"],"mappings":";;;;;;;;;;;;;;;;;AACuB;AAC2B;AACP;AACG;AACX;AAC8B;AAC9B;AACwB;AAM3D,MAAMQ,kBAAkBA,GAAG;IACzBF,UAAUA;IACVC,qBAAqBA;IACrBL,cAAcA;IACdC,eAAeA;IACfC,UAAUA;IACVH,iBAAiBA;IACjBI,wBAAwBA;CACzB;AACM,MAAMI,YAAYA,GAAGT,QACnB,CAAC;IACN,UAAUA,OAAO,CAACA,OAAO,CAACQ,kBAAkBA;AAC9C,GACC,QAAQ,CAAC,uCAAsC;AAE3C,SAASE,eAAeA,CAC7BC,6BAAiD;IAEjD,OAAOX,QAAQ,CAAC;QACd,UAAUA,OAAO,CACfA,OAAO,CAAC;eAAIQ,kBAAkBA;eAAKG;SAA8B;IAErE;AACF;AAEO,SAASC,qBAAqBA;IACnC,MAAMC,UAAU;QACd,UAAU;YACR;gBACE,MAAM;gBACN,SAAS;oBACP,MAAM;gBACR;YACF;SACD;IACH;IACA,MAAMC,SAAS,CAAC,sIAAsI,EAAEC,KAAK,SAAS,CAACF,SAAS,YAAY,CAAC;IAC7L,OAAO,CAAC,UAAU,EAAEC,OAAO,WAAW,CAAC;AACzC"}
@@ -0,0 +1,9 @@
1
+ import { OutputMessageType, type RequestContactInfoMessage } from '@botonic/core';
2
+ import { z } from 'zod';
3
+ export type { RequestContactInfoMessage };
4
+ export declare const RequestContactInfoSchema: z.ZodObject<{
5
+ type: z.ZodLiteral<OutputMessageType.RequestContactInfo>;
6
+ content: z.ZodObject<{
7
+ text: z.ZodString;
8
+ }, z.core.$strip>;
9
+ }, z.core.$strip>;
@@ -0,0 +1,17 @@
1
+ import { OutputMessageType } from "@botonic/core";
2
+ import { z } from "zod";
3
+
4
+
5
+
6
+
7
+
8
+ const RequestContactInfoSchema = z.object({
9
+ type: z.literal(OutputMessageType.RequestContactInfo),
10
+ content: z.object({
11
+ text: z.string().describe('The text of the message')
12
+ })
13
+ }).describe('A message to request phone number from the user. Use it only when asked explicitly in the prompt.');
14
+
15
+ export { RequestContactInfoSchema };
16
+
17
+ //# sourceMappingURL=request-contact-info.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structured-output/request-contact-info.js","sources":["../../src/structured-output/request-contact-info.ts"],"sourcesContent":["import {\n OutputMessageType,\n type RequestContactInfoMessage,\n} from '@botonic/core'\nimport { z } from 'zod'\n\nexport type { RequestContactInfoMessage }\n\nexport const RequestContactInfoSchema = z\n .object({\n type: z.literal(OutputMessageType.RequestContactInfo),\n content: z.object({\n text: z.string().describe('The text of the message'),\n }),\n })\n .describe(\n 'A message to request phone number from the user. Use it only when asked explicitly in the prompt.'\n )\n"],"names":["OutputMessageType","z","RequestContactInfoSchema"],"mappings":";;;;;AAGsB;AACC;AAIhB,MAAME,wBAAwBA,GAAGD,QAC/B,CAAC;IACN,MAAMA,SAAS,CAACD,oCAAoC;IACpD,SAASC,QAAQ,CAAC;QAChB,MAAMA,QAAQ,GAAG,QAAQ,CAAC;IAC5B;AACF,GACC,QAAQ,CACP,qGACD"}
package/package.json CHANGED
@@ -1,21 +1,21 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@botonic/plugin-ai-agents",
4
- "version": "0.57.0-rslib-esm.1",
4
+ "version": "0.58.0-alpha-new-stack.0",
5
5
  "main": "./lib/index.js",
6
6
  "module": "./lib/index.js",
7
7
  "description": "Use AI Agents to generate your contents",
8
8
  "scripts": {
9
9
  "build": "rslib build --no-env",
10
10
  "build:watch": "rslib build --watch --no-env",
11
- "test": "../../node_modules/.bin/jest --coverage",
11
+ "test": "vitest run --coverage",
12
12
  "prepublishOnly": "npm run build && npm run test && npm run lint",
13
13
  "lint": "biome check --write src/ tests/",
14
14
  "lint:check": "biome check src/ tests/",
15
15
  "format": "biome format --write src/ tests/"
16
16
  },
17
17
  "dependencies": {
18
- "@botonic/core": "0.57.0-rslib-esm.1",
18
+ "@botonic/core": "0.58.0-alpha-new-stack.0",
19
19
  "@openai/agents": "^0.10.1",
20
20
  "axios": "^1.18.1",
21
21
  "openai": "^6.36.0",
@@ -31,7 +31,7 @@
31
31
  "README.md"
32
32
  ],
33
33
  "engines": {
34
- "node": ">=22.19.0",
34
+ "node": ">=22.23.2",
35
35
  "npm": ">=10.0.0"
36
36
  },
37
37
  "repository": {
package/src/index.ts CHANGED
@@ -116,6 +116,7 @@ export default class BotonicPluginAiAgents<
116
116
  memoryLength: 0,
117
117
  exit: true,
118
118
  error: true,
119
+ doNothing: false,
119
120
  inputGuardrailsTriggered: [],
120
121
  outputGuardrailsTriggered: [],
121
122
  startingAgentName: '',
@@ -1,7 +1,8 @@
1
- import type {
2
- OutputMessage,
3
- ResolvedPlugins,
4
- ToolExecution,
1
+ import {
2
+ type OutputMessage,
3
+ OutputMessageType,
4
+ type ResolvedPlugins,
5
+ type ToolExecution,
5
6
  } from '@botonic/core'
6
7
  import {
7
8
  InputGuardrailTripwireTriggered,
@@ -214,22 +215,30 @@ export abstract class BaseRunner<
214
215
  const outputMessages = result.finalOutput?.messages || []
215
216
  const hasExit =
216
217
  outputMessages.length === 0 ||
217
- outputMessages.some(message => message.type === 'exit')
218
+ outputMessages.some(message => message.type === OutputMessageType.Exit)
219
+
220
+ const hasDoNothing = outputMessages.some(
221
+ message => message.type === OutputMessageType.DoNothing
222
+ )
218
223
 
219
224
  return {
220
225
  startingAgentName: '',
221
226
  lastAgentName: '',
222
227
  availableSpecialists: [],
223
228
  isTransferredToSpecialist: false,
224
- messages: hasExit
225
- ? []
226
- : (outputMessages.filter(
227
- message => message.type !== 'exit'
228
- ) as AgenticOutputMessage[]),
229
+ messages:
230
+ hasExit || hasDoNothing
231
+ ? []
232
+ : (outputMessages.filter(
233
+ message =>
234
+ message.type !== OutputMessageType.Exit &&
235
+ message.type !== OutputMessageType.DoNothing
236
+ ) as AgenticOutputMessage[]),
229
237
  toolsExecuted: this.getToolsExecuted(result, context),
230
238
  exit: hasExit,
231
239
  memoryLength,
232
240
  error: false,
241
+ doNothing: hasDoNothing,
233
242
  inputGuardrailsTriggered: [],
234
243
  outputGuardrailsTriggered: [],
235
244
  }
@@ -295,6 +304,7 @@ export abstract class BaseRunner<
295
304
  toolsExecuted: [],
296
305
  exit: true,
297
306
  error: false,
307
+ doNothing: false,
298
308
  inputGuardrailsTriggered: error.result.output.outputInfo,
299
309
  outputGuardrailsTriggered: [],
300
310
  }
@@ -0,0 +1,12 @@
1
+ import { type DoNothingMessage, OutputMessageType } from '@botonic/core'
2
+ import { z } from 'zod'
3
+
4
+ export type { DoNothingMessage }
5
+
6
+ export const DoNothingSchema = z
7
+ .object({
8
+ type: z.literal(OutputMessageType.DoNothing),
9
+ })
10
+ .describe(
11
+ 'A do nothing message is used to end the conversation without send a reply. Use it only when asked explicitly in the prompt.'
12
+ )
@@ -2,7 +2,9 @@ import type { OutputMessage } from '@botonic/core'
2
2
  import { z } from 'zod'
3
3
  import { BotExecutorSchema } from './bot-executor'
4
4
  import { CarouselSchema } from './carousel'
5
+ import { DoNothingSchema } from './do-nothing'
5
6
  import { ExitSchema } from './exit'
7
+ import { RequestContactInfoSchema } from './request-contact-info'
6
8
  import { TextSchema } from './text'
7
9
  import { TextWithButtonsSchema } from './text-with-buttons'
8
10
 
@@ -14,8 +16,10 @@ const baseMessageSchemas = [
14
16
  TextSchema,
15
17
  TextWithButtonsSchema,
16
18
  CarouselSchema,
19
+ DoNothingSchema,
17
20
  ExitSchema,
18
21
  BotExecutorSchema,
22
+ RequestContactInfoSchema,
19
23
  ] as const
20
24
  export const OutputSchema = z
21
25
  .object({
@@ -0,0 +1,18 @@
1
+ import {
2
+ OutputMessageType,
3
+ type RequestContactInfoMessage,
4
+ } from '@botonic/core'
5
+ import { z } from 'zod'
6
+
7
+ export type { RequestContactInfoMessage }
8
+
9
+ export const RequestContactInfoSchema = z
10
+ .object({
11
+ type: z.literal(OutputMessageType.RequestContactInfo),
12
+ content: z.object({
13
+ text: z.string().describe('The text of the message'),
14
+ }),
15
+ })
16
+ .describe(
17
+ 'A message to request phone number from the user. Use it only when asked explicitly in the prompt.'
18
+ )