Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -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`);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
24 changes: 17 additions & 7 deletions src/tracing/tracer-factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,53 +165,63 @@ function httpPost(url: string, data: any, headers: Record<string, string>): 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)
*
* // 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: {
apiKey?: string;
runId?: string;
apiUrl?: string;
logger?: SentienceLogger;
uploadTrace?: boolean;
}): Promise<Tracer> {
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
});
}

// 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(
Expand Down
Loading