Lifecycle Methods

Report when your agent starts, stays alive, and finishes.

Lifecycle events are Tier 1 in the AOP spec. Every conforming agent should emit session.started at the beginning and session.ended at the end. Heartbeats are optional but recommended for long-running agents.

sessionStarted()

Emits a session.started event. Call this once at the beginning of each agent session.

aop.sessionStarted(payload?: {
  goal?: string
  agent_version?: string
  metadata?: Record<string, unknown>
}): void

Example

await aop.sessionStarted({
  goal: 'Summarize all customer feedback from Q1',
  metadata: { source: 'slack', channel: '#feedback' }
})

heartbeat()

Emits a session.heartbeat event. Use this for long-running agents to signal they have not hung or crashed. A common pattern is to call it on a timer interval.

aop.heartbeat(
  status: 'running' | 'idle' | 'waiting',
  metadata?: Record<string, unknown>
): void

Example

// Send a heartbeat every 30 seconds
const interval = setInterval(() => {
  aop.heartbeat('running')
}, 30_000)

// Clean up when done
clearInterval(interval)
The dashboard uses heartbeats to show live status indicators. Without heartbeats, a session may appear stale even if the agent is still active.

sessionEnded()

Emits a session.ended event. Call this once when the agent session terminates.

aop.sessionEnded(
  outcome: 'completed' | 'failed' | 'cancelled' | 'timeout',
  payload?: {
    outcome_summary?: string
    error_message?: string
    metadata?: Record<string, unknown>
  }
): void

Example

// Successful completion
await aop.sessionEnded('completed', {
  outcome_summary: 'Generated 3-page report with 12 citations'
})

// Failure
await aop.sessionEnded('failed', {
  error_message: 'Rate limited by upstream API after 3 retries'
})

Typical lifecycle pattern

const aop = new AOPClient({ agentId: 'my-agent' })

try {
  await aop.sessionStarted({ goal: 'Process invoices' })

  // ... agent work ...

  await aop.sessionEnded('completed', {
    outcome_summary: 'Processed 47 invoices'
  })
} catch (err) {
  await aop.sessionEnded('failed', {
    error_message: err instanceof Error ? err.message : String(err)
  })
}

Related