AI Employee SDK

Audit Logging

Capture tool call and step events for observability pipelines.

The membrane already tracks every tool call in m.auditLog. For sending events to an external system (Datadog, a logging pipeline, Slack), createAuditLogger gives you callbacks for tool call starts, finishes, and step completions that you wire into generateText directly.

Basic Usage

import { createAuditLogger } from '@ai-employee-sdk/core';
import { generateText, stepCountIs } from 'ai';
import { openai } from '@ai-sdk/openai';

const audit = createAuditLogger({
  onToolCall: (entry) => {
    console.log(`[${new Date(entry.timestamp).toISOString()}] Tool: ${entry.toolName}`);
    console.log('  Input:', JSON.stringify(entry.input));
    console.log('  Step:', entry.stepNumber);
  },
  onStep: (entry) => {
    console.log(`[${new Date(entry.timestamp).toISOString()}] Step ${entry.stepNumber} finished`);
    console.log('  Reason:', entry.finishReason);
    console.log('  Tokens:', entry.usage.totalTokens);
  },
});

const result = await generateText({
  model: openai('gpt-4o'),
  tools: { /* ... */ },
  experimental_onToolCallStart: audit.onToolCallStart,
  experimental_onToolCallFinish: audit.onToolCallFinish,
  onStepFinish: audit.onStepFinish,
  stopWhen: stepCountIs(10),
  prompt: '...',
});

Sending to External Systems

const audit = createAuditLogger({
  onToolCall: async (entry) => {
    // Send to your observability pipeline
    await fetch('https://logs.example.com/ingest', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        type: 'tool_call',
        ...entry,
      }),
    });
  },
  onStep: async (entry) => {
    await fetch('https://logs.example.com/ingest', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        type: 'step',
        ...entry,
      }),
    });
  },
});

With EmployeeAgent

When using EmployeeAgent, the membrane already provides an audit log. Use createAuditLogger for additional logging (e.g., sending to external systems):

import { EmployeeAgent, createAuditLogger } from '@ai-employee-sdk/core';

const audit = createAuditLogger({
  onToolCall: (entry) => console.log('Tool:', entry.toolName),
  onStep: (entry) => console.log('Step:', entry.stepNumber),
});

const agent = new EmployeeAgent({
  model: openai('gpt-4o'),
  tools: { /* ... */ },
  onStepFinish: audit.onStepFinish,
});

// The membrane audit log is also available:
// agent.auditLog → AuditEntry[]

Audit Logger vs Membrane Audit Log

FeaturecreateAuditLoggerMembrane auditLog
PurposeExternal observabilityIn-memory inspection
FormatCustom callbacks (you choose the shape)AuditEntry[] (fixed schema)
Includes tier infoNo (raw tool call events)Yes (tier, blocked flag)
PersistenceYou handle itIn-memory array (max 1,000)
When to useLogging pipelines, monitoring, analyticsDebugging, post-run inspection

Reference

createAuditLogger(config)

ParameterTypeDescription
config.onToolCall(entry) => voidCalled on tool call start and finish
config.onStep(entry) => voidCalled when a step finishes

Returns: AuditLoggerResult

PropertyTypeWire to
onToolCallStart(event) => voidexperimental_onToolCallStart
onToolCallFinish(event) => voidexperimental_onToolCallFinish
onStepFinish(event) => voidonStepFinish

onToolCall Entry

{
  toolName: string;
  input: unknown;
  stepNumber: number;
  timestamp: number; // Date.now()
}

onStep Entry

{
  stepNumber: number;
  finishReason: string;
  usage: {
    inputTokens: number;
    outputTokens: number;
    totalTokens: number;
  };
  timestamp: number;
}

On this page