diff --git a/package-lock.json b/package-lock.json index bb8a4de..eace190 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5017,6 +5017,14 @@ "@types/tar": "^6.1.0", "typescript": "^5.3.0", "vitest": "^1.2.0" + }, + "peerDependencies": { + "langsmith": "^0.3.0" + }, + "peerDependenciesMeta": { + "langsmith": { + "optional": true + } } }, "packages/communication-layer": { diff --git a/packages/autonav/README.md b/packages/autonav/README.md index 206bd26..421063f 100644 --- a/packages/autonav/README.md +++ b/packages/autonav/README.md @@ -93,8 +93,41 @@ my-docs/ ## Environment +### Required + `ANTHROPIC_API_KEY` - Required for queries. +### Optional - LangSmith Tracing + +Autonav supports optional [LangSmith](https://www.langchain.com/langsmith) tracing to monitor and debug Claude Agent SDK calls. + +To enable LangSmith tracing: + +1. Install the langsmith package: + ```bash + npm install langsmith + ``` + +2. Set environment variables: + ```bash + export LANGSMITH_TRACING="true" + export LANGSMITH_API_KEY="your-api-key" + export LANGSMITH_PROJECT="your-project-name" # Optional + ``` + +3. Run autonav commands as normal: + ```bash + autonav query my-docs "How do I deploy?" + ``` + +All queries will be traced to your LangSmith project, capturing: +- Full conversation history +- Tool calls and responses +- Model parameters +- Response validation + +**Note:** LangSmith is completely optional. Autonav works normally without it. + ## FAQ **Why would I use this instead of just using Claude Code directly?** diff --git a/packages/autonav/package.json b/packages/autonav/package.json index d2b87f6..57d380a 100644 --- a/packages/autonav/package.json +++ b/packages/autonav/package.json @@ -68,5 +68,13 @@ "@types/tar": "^6.1.0", "typescript": "^5.3.0", "vitest": "^1.2.0" + }, + "peerDependencies": { + "langsmith": "^0.3.0" + }, + "peerDependenciesMeta": { + "langsmith": { + "optional": true + } } } diff --git a/packages/autonav/src/adapter/claude-adapter.ts b/packages/autonav/src/adapter/claude-adapter.ts index 25de858..6db03af 100644 --- a/packages/autonav/src/adapter/claude-adapter.ts +++ b/packages/autonav/src/adapter/claude-adapter.ts @@ -15,6 +15,51 @@ import { createPluginManager, PluginManager, PluginConfigFileSchema } from "../p import { sanitizeError } from "../plugins/utils/security.js"; import { createSelfConfigMcpServer, createResponseMcpServer, SUBMIT_ANSWER_TOOL } from "../tools/index.js"; +/** + * Optional LangSmith integration for tracing Claude Agent SDK calls + */ +let langsmithTraceable: any = null; +let langsmithInitialized = false; + +/** + * Lazily initialize LangSmith tracing if enabled via environment variables + */ +async function initializeLangSmith(): Promise { + if (langsmithInitialized) { + return !!langsmithTraceable; + } + + langsmithInitialized = true; + + // Check if LangSmith tracing is enabled via environment variable + const tracingEnabled = process.env.LANGSMITH_TRACING === "true"; + const hasApiKey = !!process.env.LANGSMITH_API_KEY; + + if (!tracingEnabled || !hasApiKey) { + return false; + } + + try { + // Dynamically import langsmith (optional peer dependency) + // Using dynamic import with string to avoid TypeScript compile-time resolution + const moduleName = "langsmith/traceable"; + const langsmith = await import(moduleName); + langsmithTraceable = langsmith.traceable; + + console.log("✅ LangSmith tracing enabled"); + if (process.env.LANGSMITH_PROJECT) { + console.log(` Project: ${process.env.LANGSMITH_PROJECT}`); + } + + return true; + } catch (error) { + // langsmith not installed or import failed - continue without tracing + console.warn("⚠️ LangSmith tracing requested but langsmith package not found."); + console.warn(" Install with: npm install langsmith"); + return false; + } +} + /** * Configuration options for Claude Adapter */ @@ -247,6 +292,40 @@ export class ClaudeAdapter { navigator: LoadedNavigator, question: string, options: QueryOptions = {} + ): Promise { + // Initialize LangSmith if needed + const tracingEnabled = await initializeLangSmith(); + + // Wrap the query execution with LangSmith tracing if enabled + if (tracingEnabled && langsmithTraceable) { + const tracedQuery = langsmithTraceable( + this.executeQuery.bind(this), + { + name: "autonav_query", + run_type: "chain", + metadata: { + navigator: navigator.config.name, + model: this.options.model, + }, + } + ); + return tracedQuery(navigator, question, options); + } + + // Execute query without tracing + return this.executeQuery(navigator, question, options); + } + + /** + * Internal method to execute the query + * Separated to allow for LangSmith tracing wrapper + * + * @internal + */ + private async executeQuery( + navigator: LoadedNavigator, + question: string, + options: QueryOptions = {} ): Promise { const { enableSelfConfig = true,