@piiiico/agent-logger
v0.2.0
Published
Framework-agnostic agent action logger with optional AgentLair backend
Maintainers
Readme
@piiiico/agent-logger
Zero-config tool call logger for AI agents. One import, full audit trail. Works with Anthropic/Claude, OpenAI, LangChain, and CrewAI.
Zero dependencies. Logs to stdout, file, or AgentLair cloud for search, compliance, and governance.
Install
npm install @piiiico/agent-logger
# or
yarn add @piiiico/agent-logger
# or
bun add @piiiico/agent-loggerQuick start
import { auditLog } from "@piiiico/agent-logger";
await auditLog({
agent: "customer-support-bot",
action: "respond",
tool: "knowledge_base_search",
input: { query: "How do I cancel my subscription?" },
output: { answer: "Go to Settings → Billing → Cancel." },
});
// → {"agent":"customer-support-bot","action":"respond","tool":"knowledge_base_search","input":{...},"output":{...},"timestamp":"2026-04-01T12:00:00.000Z"}By default, logs go to stdout as JSON lines — pipe them wherever you want.
Core API
auditLog(entry: AuditEntry, opts?: AuditLogOptions): Promise<AuditResult>AuditEntry fields
| Field | Type | Required | Description |
|---|---|---|---|
| agent | string | ✅ | Agent identifier |
| action | string | ✅ | What happened ("llm_call", "tool_use", etc.) |
| tool | string | — | Tool or function name |
| input | unknown | — | Request payload |
| output | unknown | — | Response payload |
| timestamp | string | — | ISO 8601 — defaults to Date.now() |
| metadata | Record<string, unknown> | — | Any extra context |
Transports
| Transport | When used | Config |
|---|---|---|
| "console" (default) | Always — great for dev + log aggregators | — |
| "file" | Append to a local file | filePath: "./audit.log" |
| "agentlair" | Ship to AgentLair for governed audit trail | Set AGENTLAIR_API_KEY |
| "silent" | Testing | — |
Auto-detection: if AGENTLAIR_API_KEY is set, the default transport becomes "agentlair". Otherwise, "console".
Pre-bound logger
import { createAuditLogger } from "@piiiico/agent-logger";
const log = createAuditLogger("inventory-agent");
await log({ action: "check_stock", tool: "db_query", input: { sku: "ABC-123" } });
await log({ action: "reorder", output: { orderId: "PO-9999" } });Framework adapters
LangChain
Drop AgentAuditCallback into any chain, agent, or model's callbacks array:
import { AgentAuditCallback } from "@piiiico/agent-logger/langchain";
import { LLMChain } from "langchain/chains";
import { ChatOpenAI } from "langchain/chat_models/openai";
const llm = new ChatOpenAI();
const chain = new LLMChain({
llm,
prompt,
callbacks: [new AgentAuditCallback("my-langchain-agent")],
});
await chain.call({ question: "What is 2+2?" });
// Automatically logs: llm_start, llm_end, tool_start, tool_end, chain_start, chain_endWith AgentLair backend:
new AgentAuditCallback("my-agent", { transport: "agentlair" })Anthropic / Claude SDK
Wrap your Anthropic client — zero behavior change, full logging:
import Anthropic from "@anthropic-ai/sdk";
import { wrapAnthropicClient } from "@piiiico/agent-logger/anthropic";
const client = wrapAnthropicClient(new Anthropic(), "my-claude-agent");
// Identical to normal usage — requests and responses are automatically logged
const message = await client.messages.create({
model: "claude-3-5-sonnet-20241022",
max_tokens: 1024,
messages: [{ role: "user", content: "Hello!" }],
});Logs: messages_create (with model + input) and messages_response (with content + token usage).
OpenAI
Wrap your OpenAI client — same pattern, automatic logging:
import OpenAI from "openai";
import { wrapOpenAIClient } from "@piiiico/agent-logger/openai";
const client = wrapOpenAIClient(new OpenAI(), "my-openai-agent");
// Use exactly as before — all calls are logged automatically
const completion = await client.chat.completions.create({
model: "gpt-4o",
messages: [{ role: "user", content: "Hello!" }],
});Logs: chat_completions_create (with model + input) and chat_completions_response (with content + token usage + tool calls).
Tool calls in the response are captured automatically:
// If the model calls tools, they're logged with name + arguments
const result = await client.chat.completions.create({
model: "gpt-4o",
messages: [{ role: "user", content: "Search for AI news" }],
tools: [{ type: "function", function: { name: "web_search", description: "Search" } }],
});
// → logs tool_calls: [{name: "web_search", arguments: "..."}]CrewAI
Option A — wrap a task function (JS/TS):
import { wrapCrewTask } from "@piiiico/agent-logger/crewai";
const webSearch = async (query: string) => {
// ... your search logic
return results;
};
const auditedSearch = wrapCrewTask(webSearch, {
agent: "research-crew",
taskName: "web_search",
});
const results = await auditedSearch("latest AI agent frameworks");
// Logs: crew_task_start → crew_task_end (with duration)Option B — bridge from Python CrewAI via direct log call:
import { crewAiLog } from "@piiiico/agent-logger/crewai";
// Call this from your JS bridge/API when a Python crew event fires
await crewAiLog({
agent: "python-research-crew",
task: "summarize",
input: { text: "..." },
output: { summary: "..." },
});Ship to AgentLair
AgentLair provides an agent governance layer — audit trails, approval gates, and replay for AI agents.
Set your API key and all logs automatically route to your AgentLair dashboard:
AGENTLAIR_API_KEY=your_key_here node your-agent.jsTo get access: contact us at [email protected] or open a GitHub issue — we're onboarding teams individually during early access.
File transport example
await auditLog(
{ agent: "batch-processor", action: "process", input: { jobId: "job-42" } },
{ transport: "file", filePath: "/var/log/agents/audit.log" }
);Appends JSON lines. Compatible with any log aggregator (Datadog, Loki, CloudWatch).
License
MIT
