Skip to main content

Overview

The endSession function ends the active session, marking it as complete with a success status and optional reason.

Syntax

await lai.endSession({
  task?: string,
  sessionEval?: number,
  sessionEvalReason?: string,
  isSuccessful?: boolean,
  isSuccessfulReason?: string,
  tags?: string[],
}): Promise<void>

Parameters

isSuccessful
boolean
Whether the session completed successfully.
isSuccessfulReason
string
Explanation of why the session succeeded or failed.
sessionEval
number
Numeric evaluation score for the session.
sessionEvalReason
string
Reason for the evaluation score.

Returns

Returns a Promise that resolves to void.

Examples

Basic Usage

// End successfully with default
await lai.endSession({ isSuccessful: true });

// End successfully with reason
await lai.endSession({ isSuccessful: true, isSuccessfulReason: "All tasks completed" });

// End with failure
await lai.endSession({ isSuccessful: false, isSuccessfulReason: "API rate limit exceeded" });

With Error Handling

async function runWorkflow() {
  try {
    await lai.init({ sessionName: "Data processing" });
    
    await processData();
    await generateReport();
    
    // Success case
    await lai.endSession({ isSuccessful: true, isSuccessfulReason: "Workflow completed successfully" });
    
  } catch (error) {
    // Failure case
    await lai.endSession({ isSuccessful: false, isSuccessfulReason: `Workflow failed: ${error.message}` });
    throw error;
  }
}

Conditional Success

async function batchProcessor(items: any[]) {
  await lai.init({ sessionName: "Batch processing" });
  
  const results = await processItems(items);
  
  const successCount = results.filter(r => r.success).length;
  const successRate = successCount / results.length;
  
  if (successRate === 1) {
    await lai.endSession({ isSuccessful: true, isSuccessfulReason: "All items processed successfully" });
  } else if (successRate > 0.8) {
    await lai.endSession({ isSuccessful: true, isSuccessfulReason: `Partial success: ${successCount}/${results.length} items processed` });
  } else {
    await lai.endSession({ isSuccessful: false, isSuccessfulReason: `Too many failures: only ${successCount}/${results.length} succeeded` });
  }
}

With Cleanup

async function robustWorkflow() {
  let session;
  
  try {
    session = await lai.init({ sessionName: "Critical workflow" });
    
    // Your workflow
    await performCriticalOperations();
    
    await lai.endSession({ isSuccessful: true, isSuccessfulReason: "Operations completed" });
    
  } catch (error) {
    // Ensure session ends even on error
    if (session) {
      await lai.endSession({ isSuccessful: false, isSuccessfulReason: error.message });
    }
    throw error;
    
  } finally {
    // Additional cleanup
    await cleanup();
  }
}

Auto-End Behavior

When autoEnd is enabled (default), sessions automatically end on:
  • Process exit
  • Uncaught exceptions
  • SIGINT/SIGTERM signals
// Auto-end enabled by default (configurable via autoEnd)
await lai.init({ sessionName: "My session" });

// Session will auto-end on exit; you may still call endSession() explicitly when appropriate
To disable auto-end:
await lai.init({ sessionName: "Manual session", autoEnd: false }); // Must manually call endSession()

Common Patterns

1. Success Criteria

async function taskWithCriteria() {
  await lai.init({ sessionName: "Goal-based task" });
  
  const goals = {
    accuracy: 0.95,
    performance: 1000, // ms
    errorRate: 0.01
  };
  
  const results = await runTask();
  
  const success = 
    results.accuracy >= goals.accuracy &&
    results.performanceMs <= goals.performance &&
    results.errorRate <= goals.errorRate;
    
  await lai.endSession(
    success,
    success 
      ? "All goals met"
      : `Failed criteria: accuracy=${results.accuracy}, performance=${results.performanceMs}ms`
  );
}

2. Multi-Phase Workflows

const phases = ['extract', 'transform', 'load'];
let completedPhases = [];

try {
  await lai.init({ sessionName: "ETL Pipeline" });
  
  for (const phase of phases) {
    await executePhase(phase);
    completedPhases.push(phase);
  }
  
  await lai.endSession(true, "All phases completed");
  
} catch (error) {
  await lai.endSession(
    false, 
    `Failed at ${phases[completedPhases.length]}: ${error.message}`
  );
}

3. Timeout Handling

async function timedOperation() {
  await lai.init({ sessionName: "Time-sensitive task" });
  
  const timeout = setTimeout(async () => {
    await lai.endSession({ isSuccessful: false, isSuccessfulReason: "Operation timed out after 5 minutes" });
    process.exit(1);
  }, 5 * 60 * 1000);
  
  try {
    await performOperation();
    clearTimeout(timeout);
    await lai.endSession({ isSuccessful: true, isSuccessfulReason: "Completed within time limit" });
  } catch (error) {
    clearTimeout(timeout);
    await lai.endSession(false, error.message);
  }
}

Best Practices

1. Always End Sessions

// Use try-finally to ensure ending
try {
  await lai.init({ sessionName: "Important task" });
  await doWork();
} finally {
  await lai.endSession();
}

2. Meaningful Reasons

// ✅ Good - specific and actionable
await lai.endSession({ isSuccessful: false, isSuccessfulReason: "Database connection failed after 3 retries: timeout" });

// ❌ Less helpful
await lai.endSession(false, "Error occurred");

3. Success Doesn’t Mean Perfect

// Partial success is still success
const processed = 95;
const total = 100;

await lai.endSession({
  isSuccessful: true,
  isSuccessfulReason: `Processed ${processed}/${total} items, ${total - processed} skipped due to validation`
});

Notes

  • Only the active session can be ended
  • Steps are automatically ended when session ends
  • After ending, a new session can be started
  • Telemetry spans are flushed on exit; provider shutdown is handled automatically

See Also