diff --git a/examples/cloud-tracing-agent.ts b/examples/local-tracing-agent.ts similarity index 87% rename from examples/cloud-tracing-agent.ts rename to examples/local-tracing-agent.ts index a447fb9b..b03c06c3 100644 --- a/examples/cloud-tracing-agent.ts +++ b/examples/local-tracing-agent.ts @@ -1,17 +1,17 @@ /** - * Example: Agent with Cloud Tracing + * Example: Agent with Local Tracing * - * Demonstrates how to use cloud tracing with SentienceAgent to upload traces - * and screenshots to cloud storage for remote viewing and analysis. + * Demonstrates how to use local tracing with SentienceAgent to save traces + * and screenshots to local storage for offline viewing and analysis. * * Requirements: * - Pro or Enterprise tier API key (SENTIENCE_API_KEY) * - OpenAI API key (OPENAI_API_KEY) for LLM * * Usage: - * ts-node examples/cloud-tracing-agent.ts + * ts-node examples/local-tracing-agent.ts * or - * npm run example:cloud-tracing + * npm run example:local-tracing */ import { SentienceBrowser } from '../src/browser'; @@ -39,12 +39,15 @@ async function main() { console.log('🚀 Starting Agent with Cloud Tracing Demo\n'); // 1. Create tracer with automatic tier detection - // If apiKey is Pro/Enterprise, uses CloudTraceSink - // If apiKey is missing/invalid, falls back to local JsonlTraceSink - const runId = 'cloud-tracing-demo'; + // If apiKey is Pro/Enterprise AND uploadTrace is true, uses CloudTraceSink + // If apiKey is missing/invalid or uploadTrace is false, falls back to local JsonlTraceSink + // Note: uploadTrace defaults to true for backward compatibility + const runId = 'local-tracing-demo'; + // if apiKey is provided and uploadTrace is true, will use cloud storage tracer const tracer = await createTracer({ apiKey: sentienceKey, - runId: runId + runId: runId, + uploadTrace: false // local storage tracer }); console.log(`🆔 Run ID: ${runId}\n`); diff --git a/package.json b/package.json index b6c397d7..6319a793 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sentienceapi", - "version": "0.90.5", + "version": "0.90.7", "description": "TypeScript SDK for Sentience AI Agent Browser Automation", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/src/tracing/tracer-factory.ts b/src/tracing/tracer-factory.ts index 8b75e848..a3155e4d 100644 --- a/src/tracing/tracer-factory.ts +++ b/src/tracing/tracer-factory.ts @@ -165,22 +165,27 @@ function httpPost(url: string, data: any, headers: Record): Prom * Create tracer with automatic tier detection * * Tier Detection: - * - If apiKey is provided: Try to initialize CloudTraceSink (Pro/Enterprise) - * - If cloud init fails or no apiKey: Fall back to JsonlTraceSink (Free tier) + * - If apiKey is provided AND uploadTrace is true: Try to initialize CloudTraceSink (Pro/Enterprise) + * - If cloud init fails, no apiKey, or uploadTrace is false: Fall back to JsonlTraceSink (Free tier) * * @param options - Configuration options * @param options.apiKey - Sentience API key (e.g., "sk_pro_xxxxx") * @param options.runId - Unique identifier for this agent run (generates UUID if not provided) * @param options.apiUrl - Sentience API base URL (default: https://api.sentienceapi.com) * @param options.logger - Optional logger instance for logging file sizes and errors + * @param options.uploadTrace - Enable cloud trace upload (default: true for backward compatibility) * @returns Tracer configured with appropriate sink * * @example * ```typescript - * // Pro tier user - * const tracer = await createTracer({ apiKey: "sk_pro_xyz", runId: "demo" }); + * // Pro tier user with cloud upload + * const tracer = await createTracer({ apiKey: "sk_pro_xyz", runId: "demo", uploadTrace: true }); * // Returns: Tracer with CloudTraceSink * + * // Pro tier user with local-only tracing + * const tracer = await createTracer({ apiKey: "sk_pro_xyz", runId: "demo", uploadTrace: false }); + * // Returns: Tracer with JsonlTraceSink (local-only) + * * // Free tier user * const tracer = await createTracer({ runId: "demo" }); * // Returns: Tracer with JsonlTraceSink (local-only) @@ -188,7 +193,7 @@ function httpPost(url: string, data: any, headers: Record): Prom * // Use with agent * const agent = new SentienceAgent(browser, llm, 50, true, tracer); * await agent.act("Click search"); - * await tracer.close(); // Uploads to cloud if Pro tier + * await tracer.close(); // Uploads to cloud if uploadTrace: true and Pro tier * ``` */ export async function createTracer(options: { @@ -196,14 +201,18 @@ export async function createTracer(options: { runId?: string; apiUrl?: string; logger?: SentienceLogger; + uploadTrace?: boolean; }): Promise { const runId = options.runId || randomUUID(); const apiUrl = options.apiUrl || SENTIENCE_API_URL; + // Default uploadTrace to true for backward compatibility + const uploadTrace = options.uploadTrace !== false; // PRODUCTION FIX: Recover orphaned traces from previous crashes // Note: This is skipped in test environments (see recoverOrphanedTraces function) // Run in background to avoid blocking tracer creation - if (options.apiKey) { + // Only recover if uploadTrace is enabled + if (options.apiKey && uploadTrace) { // Don't await - run in background to avoid blocking recoverOrphanedTraces(options.apiKey, apiUrl).catch(() => { // Silently fail - orphan recovery should not block tracer creation @@ -211,7 +220,8 @@ export async function createTracer(options: { } // 1. Try to initialize Cloud Sink (Pro/Enterprise tier) - if (options.apiKey) { + // Only attempt cloud init if uploadTrace is enabled + if (options.apiKey && uploadTrace) { try { // Request pre-signed upload URL from backend const response = await httpPost(