From 0372304ee73b39181d2573c83ee3562033b1b873 Mon Sep 17 00:00:00 2001 From: Oriol Raventos Date: Mon, 6 Jul 2026 09:05:06 +0200 Subject: [PATCH] WIP --- package-lock.json | 63 ++++++++++++++++++- .../botonic-plugin-ai-agents/package.json | 1 + .../botonic-plugin-ai-agents/src/constants.ts | 4 ++ .../botonic-plugin-ai-agents/src/index.ts | 4 +- .../src/llm-config.ts | 2 + .../src/runners/base-runner.ts | 2 +- .../src/trace-processor.ts | 33 ++++++++++ 7 files changed, 105 insertions(+), 4 deletions(-) create mode 100644 packages/botonic-plugin-ai-agents/src/trace-processor.ts diff --git a/package-lock.json b/package-lock.json index 7ed4f8b563..8979bbad2b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16645,6 +16645,39 @@ "json-buffer": "3.0.1" } }, + "node_modules/langsmith": { + "version": "0.7.15", + "resolved": "https://registry.npmjs.org/langsmith/-/langsmith-0.7.15.tgz", + "integrity": "sha512-huRfzLKcREE+ABkqKEriXK8Ax9V+xuV3d3x4PINEGi+hi4qyTvB4Nc2dpLSyfW/Ioj6+6d7T8majjWCe7mXc8A==", + "license": "MIT", + "dependencies": { + "p-queue": "6.6.2" + }, + "peerDependencies": { + "@opentelemetry/api": "*", + "@opentelemetry/exporter-trace-otlp-proto": "*", + "@opentelemetry/sdk-trace-base": "*", + "openai": "*", + "ws": ">=7" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@opentelemetry/exporter-trace-otlp-proto": { + "optional": true + }, + "@opentelemetry/sdk-trace-base": { + "optional": true + }, + "openai": { + "optional": true + }, + "ws": { + "optional": true + } + } + }, "node_modules/launch-editor": { "version": "2.12.0", "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.12.0.tgz", @@ -18372,7 +18405,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", - "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -18408,6 +18440,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-queue": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", + "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.4", + "p-timeout": "^3.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-retry": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz", @@ -18425,6 +18473,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "license": "MIT", + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -23904,6 +23964,7 @@ "@botonic/core": "^0.51.1", "@openai/agents": "^0.10.1", "axios": "^1.15.2", + "langsmith": "^0.7.15", "openai": "^6.36.0", "uuid": "^10.0.0", "zod": "^4.3.6" diff --git a/packages/botonic-plugin-ai-agents/package.json b/packages/botonic-plugin-ai-agents/package.json index be2b2884dd..4c2001a29e 100644 --- a/packages/botonic-plugin-ai-agents/package.json +++ b/packages/botonic-plugin-ai-agents/package.json @@ -17,6 +17,7 @@ "@botonic/core": "^0.51.1", "@openai/agents": "^0.10.1", "axios": "^1.15.2", + "langsmith": "^0.7.15", "openai": "^6.36.0", "uuid": "^10.0.0", "zod": "^4.3.6" diff --git a/packages/botonic-plugin-ai-agents/src/constants.ts b/packages/botonic-plugin-ai-agents/src/constants.ts index e564fb903e..3c903ac722 100644 --- a/packages/botonic-plugin-ai-agents/src/constants.ts +++ b/packages/botonic-plugin-ai-agents/src/constants.ts @@ -30,3 +30,7 @@ export const MAX_MEMORY_LENGTH = 25 export const DEFAULT_TIMEOUT_16_SECONDS = 16000 export const DEFAULT_MAX_RETRIES = 2 + +export const LANGSMITH_ENDPOINT = process.env.LANGSMITH_ENDPOINT +export const LANGSMITH_API_KEY = process.env.LANGSMITH_API_KEY +export const LANGSMITH_WORKSPACE_ID = process.env.LANGSMITH_WORKSPACE_ID diff --git a/packages/botonic-plugin-ai-agents/src/index.ts b/packages/botonic-plugin-ai-agents/src/index.ts index bd123a5231..c263b680b3 100644 --- a/packages/botonic-plugin-ai-agents/src/index.ts +++ b/packages/botonic-plugin-ai-agents/src/index.ts @@ -9,7 +9,7 @@ import { type ReasoningEffort, type ResolvedPlugins, } from '@botonic/core' -import { handoff, setTracingDisabled, tool } from '@openai/agents' +import { handoff, tool } from '@openai/agents' import { v7 as uuidv7 } from 'uuid' import type { ZodObject } from 'zod' import { RouterAgent, SpecialistAgent } from './agents' @@ -54,7 +54,7 @@ export default class BotonicPluginAiAgents< this.maxRetries = options?.maxRetries ?? DEFAULT_MAX_RETRIES this.logger = createDebugLogger(options?.enableDebug ?? false) this.localStorageKey = options?.localStorageKey ?? 'botonicState' - setTracingDisabled(true) + // setTracingDisabled(true) this.logger.logInitialConfig({ messageHistoryApiVersion: 'v2', diff --git a/packages/botonic-plugin-ai-agents/src/llm-config.ts b/packages/botonic-plugin-ai-agents/src/llm-config.ts index 3ad83de62a..63fe2d1fbe 100644 --- a/packages/botonic-plugin-ai-agents/src/llm-config.ts +++ b/packages/botonic-plugin-ai-agents/src/llm-config.ts @@ -17,6 +17,7 @@ import { LLM_PROVIDERS, type LLMProviderType, } from './constants' +import { setTraceProcessor } from './trace-processor' export interface LLMConfigParams { maxRetries: number @@ -60,6 +61,7 @@ export class LLMConfig { private getModelProvider(): ModelProvider { const client = this.getClient() + setTraceProcessor(client) return new OpenAIProvider({ openAIClient: client, useResponses: false, diff --git a/packages/botonic-plugin-ai-agents/src/runners/base-runner.ts b/packages/botonic-plugin-ai-agents/src/runners/base-runner.ts index 65b4ee4e1c..bea5daef01 100644 --- a/packages/botonic-plugin-ai-agents/src/runners/base-runner.ts +++ b/packages/botonic-plugin-ai-agents/src/runners/base-runner.ts @@ -75,7 +75,7 @@ export abstract class BaseRunner< try { const runner = new Runner({ - tracingDisabled: true, + tracingDisabled: false, }) const result = (await runner.run(this.agent, messages, { context, diff --git a/packages/botonic-plugin-ai-agents/src/trace-processor.ts b/packages/botonic-plugin-ai-agents/src/trace-processor.ts new file mode 100644 index 0000000000..c58fd28618 --- /dev/null +++ b/packages/botonic-plugin-ai-agents/src/trace-processor.ts @@ -0,0 +1,33 @@ +import { setDefaultOpenAIClient, setTraceProcessors } from '@openai/agents' +import { Client } from 'langsmith' +import { OpenAIAgentsTracingProcessor } from 'langsmith/wrappers/openai_agents' +import type OpenAI from 'openai' +import type { AzureOpenAI } from 'openai' +import { + LANGSMITH_API_KEY, + LANGSMITH_ENDPOINT, + LANGSMITH_WORKSPACE_ID, +} from './constants' + +export function setTraceProcessor(litellmClient: OpenAI | AzureOpenAI) { + setDefaultOpenAIClient(litellmClient) + + const langsmithClient = new Client({ + apiKey: LANGSMITH_API_KEY, + apiUrl: LANGSMITH_ENDPOINT, + workspaceId: LANGSMITH_WORKSPACE_ID, + }) + + const langsmithProcessor = new OpenAIAgentsTracingProcessor({ + client: langsmithClient, + projectName: 'ai-agents-bots', + name: 'AI Agents workflow', + tags: ['openai-agents', 'litellm'], + metadata: { + environment: process.env.NODE_ENV ?? 'development', + gateway: 'litellm', + }, + }) + + setTraceProcessors([langsmithProcessor]) +}