@agentlair/audit-logger 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,173 @@
1
+ # @agentlair/audit-logger
2
+
3
+ A lightweight, framework-agnostic agent action logger. Log locally by default. Connect to [AgentLair](https://agentlair.dev) for persistent, queryable audit trails.
4
+
5
+ Zero runtime dependencies. Works in Node ≥ 18, Bun, Deno, and modern browsers.
6
+
7
+ ---
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install @agentlair/audit-logger
13
+ # or
14
+ bun add @agentlair/audit-logger
15
+ ```
16
+
17
+ ---
18
+
19
+ ## Quick start
20
+
21
+ ```typescript
22
+ import { auditLog } from '@agentlair/audit-logger';
23
+
24
+ // Logs to console — no config needed
25
+ await auditLog({
26
+ agent: 'my-agent',
27
+ action: 'tool_call',
28
+ tool: 'web_search',
29
+ input: 'latest AI news',
30
+ output: results,
31
+ });
32
+ ```
33
+
34
+ **Output:**
35
+ ```
36
+ [audit 14:32:01] my-agent → tool_call [web_search]
37
+ ```
38
+
39
+ ---
40
+
41
+ ## Connect to AgentLair
42
+
43
+ Set `AGENTLAIR_API_KEY` to ship audit logs to AgentLair for persistent storage and querying.
44
+
45
+ ```bash
46
+ export AGENTLAIR_API_KEY=aal_...
47
+ ```
48
+
49
+ That's it. All `auditLog()` calls will now also POST to AgentLair asynchronously (non-blocking, fire-and-forget).
50
+
51
+ Get a free API key at [agentlair.dev](https://agentlair.dev).
52
+
53
+ ---
54
+
55
+ ## API
56
+
57
+ ### `auditLog(entry)` — module-level convenience
58
+
59
+ ```typescript
60
+ await auditLog({
61
+ agent: string; // Name/ID of the agent
62
+ action: string; // Action category (e.g. "tool_call", "llm_response", "decision")
63
+ tool?: string; // Tool name, if this is a tool call
64
+ input?: unknown; // Input to the tool or LLM
65
+ output?: unknown; // Output from the tool or LLM
66
+ timestamp?: string; // ISO 8601 — defaults to now
67
+ metadata?: Record<string, unknown>; // Any additional context
68
+ });
69
+ ```
70
+
71
+ ### `configureLogger(options)` — configure defaults
72
+
73
+ ```typescript
74
+ import { configureLogger } from '@agentlair/audit-logger';
75
+
76
+ configureLogger({
77
+ apiKey: 'aal_...', // or set AGENTLAIR_API_KEY
78
+ console: true, // write to console (default: true)
79
+ silent: false, // suppress all output (useful in tests)
80
+ sinks: [ // custom sinks
81
+ { write(entry) { myDb.insert(entry); } }
82
+ ],
83
+ });
84
+ ```
85
+
86
+ ### `AuditLogger` — class-based API
87
+
88
+ ```typescript
89
+ import { AuditLogger } from '@agentlair/audit-logger';
90
+
91
+ const logger = new AuditLogger({ apiKey: process.env.AGENTLAIR_API_KEY });
92
+
93
+ await logger.log({ agent: 'my-agent', action: 'tool_call', tool: 'search', input: q });
94
+ await logger.logAll([entry1, entry2, entry3]);
95
+ ```
96
+
97
+ ---
98
+
99
+ ## Framework adapters
100
+
101
+ ### LangChain.js
102
+
103
+ ```typescript
104
+ import { AgentExecutor } from 'langchain/agents';
105
+ import { AuditLoggerCallbackHandler } from '@agentlair/audit-logger/langchain';
106
+
107
+ const handler = new AuditLoggerCallbackHandler({ agentName: 'my-agent' });
108
+ const executor = new AgentExecutor({ agent, tools, callbacks: [handler] });
109
+
110
+ // All tool calls and LLM invocations are now logged
111
+ const result = await executor.invoke({ input: 'What is AgentLair?' });
112
+ ```
113
+
114
+ Captured events: `handleToolStart`, `handleToolEnd`, `handleToolError`, `handleLLMStart`, `handleLLMEnd`, `handleChainStart`, `handleChainEnd`.
115
+
116
+ ### Anthropic / Claude SDK
117
+
118
+ ```typescript
119
+ import Anthropic from '@anthropic-ai/sdk';
120
+ import { wrapAnthropicClient } from '@agentlair/audit-logger/anthropic';
121
+
122
+ const client = new Anthropic();
123
+ const audited = wrapAnthropicClient(client, { agentName: 'researcher' });
124
+
125
+ // Use exactly like normal client
126
+ const msg = await audited.messages.create({
127
+ model: 'claude-opus-4-5',
128
+ max_tokens: 1024,
129
+ messages: [{ role: 'user', content: 'Explain AgentLair in one sentence.' }],
130
+ });
131
+ ```
132
+
133
+ Logged: request params summary + response usage (input/output tokens, stop reason).
134
+
135
+ ---
136
+
137
+ ## Custom sinks
138
+
139
+ Implement the `AuditSink` interface to write to any backend:
140
+
141
+ ```typescript
142
+ import type { AuditSink, ResolvedAuditEntry } from '@agentlair/audit-logger';
143
+
144
+ const postgresSink: AuditSink = {
145
+ async write(entry: ResolvedAuditEntry) {
146
+ await db.insert('audit_log', entry);
147
+ },
148
+ };
149
+
150
+ const logger = new AuditLogger({ sinks: [postgresSink], console: false });
151
+ ```
152
+
153
+ ---
154
+
155
+ ## AgentLair storage
156
+
157
+ When `AGENTLAIR_API_KEY` is set, audit entries are stored as Observations under the `audit-log` topic. You can query them using the AgentLair SDK:
158
+
159
+ ```typescript
160
+ import { AgentLair } from '@agentlair/sdk';
161
+
162
+ const lair = new AgentLair(process.env.AGENTLAIR_API_KEY!);
163
+ const { observations } = await lair.observations.read({
164
+ topic: 'audit-log',
165
+ limit: 50,
166
+ });
167
+ ```
168
+
169
+ ---
170
+
171
+ ## License
172
+
173
+ MIT © [AgentLair](https://agentlair.dev)
@@ -0,0 +1,48 @@
1
+ import type { AuditLoggerOptions } from '../types.js';
2
+ /** Minimal Anthropic message params we care about for logging */
3
+ interface AnthropicMessageParams {
4
+ model?: string;
5
+ messages?: Array<{
6
+ role: string;
7
+ content: unknown;
8
+ }>;
9
+ tools?: unknown[];
10
+ max_tokens?: number;
11
+ system?: string;
12
+ [key: string]: unknown;
13
+ }
14
+ /** Minimal Anthropic message response */
15
+ interface AnthropicMessage {
16
+ id?: string;
17
+ model?: string;
18
+ stop_reason?: string;
19
+ usage?: {
20
+ input_tokens?: number;
21
+ output_tokens?: number;
22
+ };
23
+ content?: unknown[];
24
+ [key: string]: unknown;
25
+ }
26
+ /** Minimal Anthropic client interface */
27
+ interface AnthropicClientLike {
28
+ messages: {
29
+ create(params: AnthropicMessageParams): Promise<AnthropicMessage>;
30
+ [key: string]: unknown;
31
+ };
32
+ [key: string]: unknown;
33
+ }
34
+ export interface WrapAnthropicOptions extends AuditLoggerOptions {
35
+ /** Name to use as the 'agent' field in audit entries */
36
+ agentName?: string;
37
+ }
38
+ /**
39
+ * Wraps an Anthropic client to automatically audit all messages.create() calls.
40
+ * Returns a proxy that behaves identically to the original client.
41
+ *
42
+ * @example
43
+ * const audited = wrapAnthropicClient(new Anthropic(), { agentName: 'researcher' });
44
+ * const msg = await audited.messages.create({ model: 'claude-opus-4-5', ... });
45
+ */
46
+ export declare function wrapAnthropicClient<T extends AnthropicClientLike>(client: T, options?: WrapAnthropicOptions): T;
47
+ export {};
48
+ //# sourceMappingURL=anthropic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/adapters/anthropic.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAGtD,iEAAiE;AACjE,UAAU,sBAAsB;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACrD,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,yCAAyC;AACzC,UAAU,gBAAgB;IACxB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1D,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IACpB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,yCAAyC;AACzC,UAAU,mBAAmB;IAC3B,QAAQ,EAAE;QACR,MAAM,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;QAClE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,oBAAqB,SAAQ,kBAAkB;IAC9D,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,mBAAmB,EAC/D,MAAM,EAAE,CAAC,EACT,OAAO,GAAE,oBAAyB,GACjC,CAAC,CAkEH"}
@@ -0,0 +1,99 @@
1
+ // ─── Anthropic / Claude SDK Adapter ─────────────────────────────────────────
2
+ // Middleware wrapper for Anthropic SDK message calls.
3
+ //
4
+ // Usage:
5
+ // import Anthropic from '@anthropic-ai/sdk';
6
+ // import { wrapAnthropicClient } from '@agentlair/audit-logger/anthropic';
7
+ //
8
+ // const client = new Anthropic();
9
+ // const audited = wrapAnthropicClient(client, { agentName: 'my-agent' });
10
+ //
11
+ // // Use exactly like normal client — audit happens automatically
12
+ // const msg = await audited.messages.create({ model: 'claude-3-5-sonnet', ... });
13
+ //
14
+ // No @anthropic-ai/sdk dependency required — uses duck-typing.
15
+ import { AuditLogger } from '../logger.js';
16
+ /**
17
+ * Wraps an Anthropic client to automatically audit all messages.create() calls.
18
+ * Returns a proxy that behaves identically to the original client.
19
+ *
20
+ * @example
21
+ * const audited = wrapAnthropicClient(new Anthropic(), { agentName: 'researcher' });
22
+ * const msg = await audited.messages.create({ model: 'claude-opus-4-5', ... });
23
+ */
24
+ export function wrapAnthropicClient(client, options = {}) {
25
+ const { agentName, ...loggerOptions } = options;
26
+ const logger = new AuditLogger(loggerOptions);
27
+ const name = agentName ?? 'claude-agent';
28
+ const originalCreate = client.messages.create.bind(client.messages);
29
+ const wrappedMessages = {
30
+ ...client.messages,
31
+ async create(params) {
32
+ const startedAt = new Date().toISOString();
33
+ // Log the request
34
+ await logger.log({
35
+ agent: name,
36
+ action: 'llm_request',
37
+ tool: 'messages.create',
38
+ input: {
39
+ model: params.model,
40
+ messageCount: Array.isArray(params.messages) ? params.messages.length : 0,
41
+ hasTools: Array.isArray(params.tools) && params.tools.length > 0,
42
+ maxTokens: params.max_tokens,
43
+ hasSystem: !!params.system,
44
+ // Last user message content (truncated for privacy)
45
+ lastMessage: Array.isArray(params.messages) && params.messages.length > 0
46
+ ? summarize(params.messages[params.messages.length - 1]?.content)
47
+ : undefined,
48
+ },
49
+ timestamp: startedAt,
50
+ });
51
+ let response;
52
+ try {
53
+ response = await originalCreate(params);
54
+ }
55
+ catch (err) {
56
+ // Log error
57
+ await logger.log({
58
+ agent: name,
59
+ action: 'llm_error',
60
+ tool: 'messages.create',
61
+ output: err.message,
62
+ metadata: { error: true, startedAt },
63
+ });
64
+ throw err;
65
+ }
66
+ // Log the response
67
+ await logger.log({
68
+ agent: name,
69
+ action: 'llm_response',
70
+ tool: 'messages.create',
71
+ output: {
72
+ model: response.model,
73
+ stopReason: response.stop_reason,
74
+ inputTokens: response.usage?.input_tokens,
75
+ outputTokens: response.usage?.output_tokens,
76
+ contentBlocks: Array.isArray(response.content) ? response.content.length : 0,
77
+ },
78
+ metadata: { startedAt, messageId: response.id },
79
+ });
80
+ return response;
81
+ },
82
+ };
83
+ return { ...client, messages: wrappedMessages };
84
+ }
85
+ /** Summarize content for safe logging (truncate long strings) */
86
+ function summarize(content) {
87
+ if (typeof content === 'string') {
88
+ return content.length > 200 ? content.slice(0, 200) + '…' : content;
89
+ }
90
+ if (Array.isArray(content)) {
91
+ const text = content.find((b) => typeof b === 'object' && b !== null && b.type === 'text');
92
+ if (text && typeof text.text === 'string') {
93
+ const t = text.text;
94
+ return t.length > 200 ? t.slice(0, 200) + '…' : t;
95
+ }
96
+ }
97
+ return '[non-text content]';
98
+ }
99
+ //# sourceMappingURL=anthropic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/adapters/anthropic.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import type { AuditLoggerOptions } from '../types.js';
2
+ /** Minimal interface we need from LangChain's BaseCallbackHandler */
3
+ interface LangChainCallbackHandlerInterface {
4
+ handleToolStart?: (tool: Record<string, unknown>, input: string, runId: string) => void | Promise<void>;
5
+ handleToolEnd?: (output: string, runId: string) => void | Promise<void>;
6
+ handleToolError?: (err: Error, runId: string) => void | Promise<void>;
7
+ handleLLMStart?: (llm: Record<string, unknown>, prompts: string[], runId: string) => void | Promise<void>;
8
+ handleLLMEnd?: (output: Record<string, unknown>, runId: string) => void | Promise<void>;
9
+ handleChainStart?: (chain: Record<string, unknown>, inputs: Record<string, unknown>, runId: string) => void | Promise<void>;
10
+ handleChainEnd?: (outputs: Record<string, unknown>, runId: string) => void | Promise<void>;
11
+ }
12
+ export interface AuditLoggerCallbackHandlerOptions extends AuditLoggerOptions {
13
+ /** Name to use as the 'agent' field in audit entries */
14
+ agentName?: string;
15
+ }
16
+ /**
17
+ * LangChain callback handler that logs all tool calls and LLM invocations.
18
+ *
19
+ * Compatible with LangChain.js >=0.1.0 (callback interface).
20
+ * Import langchain separately — this adapter uses duck-typing, no hard dep.
21
+ */
22
+ export declare class AuditLoggerCallbackHandler implements LangChainCallbackHandlerInterface {
23
+ private readonly logger;
24
+ private readonly agentName;
25
+ private readonly pendingTools;
26
+ constructor(options?: AuditLoggerCallbackHandlerOptions);
27
+ handleToolStart(tool: Record<string, unknown>, input: string, runId: string): Promise<void>;
28
+ handleToolEnd(output: string, runId: string): Promise<void>;
29
+ handleToolError(err: Error, runId: string): Promise<void>;
30
+ handleLLMStart(_llm: Record<string, unknown>, prompts: string[], _runId: string): Promise<void>;
31
+ handleLLMEnd(output: Record<string, unknown>, _runId: string): Promise<void>;
32
+ handleChainStart(chain: Record<string, unknown>, inputs: Record<string, unknown>, _runId: string): Promise<void>;
33
+ handleChainEnd(outputs: Record<string, unknown>, _runId: string): Promise<void>;
34
+ }
35
+ export {};
36
+ //# sourceMappingURL=langchain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"langchain.d.ts","sourceRoot":"","sources":["../../src/adapters/langchain.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ // ─── LangChain Adapter ───────────────────────────────────────────────────────
2
+ // Provides a LangChain BaseCallbackHandler subclass that forwards tool calls
3
+ // and LLM events to @agentlair/audit-logger.
4
+ //
5
+ // Usage (LangChain.js):
6
+ // import { AuditLoggerCallbackHandler } from '@agentlair/audit-logger/langchain';
7
+ // const handler = new AuditLoggerCallbackHandler({ agentName: 'my-agent' });
8
+ // const chain = new AgentExecutor({ ..., callbacks: [handler] });
9
+ //
10
+ // No langchain dependency required at runtime — uses duck-typing interface.
11
+ import { AuditLogger } from '../logger.js';
12
+ /**
13
+ * LangChain callback handler that logs all tool calls and LLM invocations.
14
+ *
15
+ * Compatible with LangChain.js >=0.1.0 (callback interface).
16
+ * Import langchain separately — this adapter uses duck-typing, no hard dep.
17
+ */
18
+ export class AuditLoggerCallbackHandler {
19
+ logger;
20
+ agentName;
21
+ pendingTools = new Map();
22
+ constructor(options = {}) {
23
+ const { agentName, ...loggerOptions } = options;
24
+ this.logger = new AuditLogger(loggerOptions);
25
+ this.agentName = agentName ?? 'langchain-agent';
26
+ }
27
+ async handleToolStart(tool, input, runId) {
28
+ const toolName = tool.name ?? 'unknown_tool';
29
+ this.pendingTools.set(runId, { name: toolName, input, startedAt: new Date().toISOString() });
30
+ await this.logger.log({
31
+ agent: this.agentName,
32
+ action: 'tool_start',
33
+ tool: toolName,
34
+ input,
35
+ });
36
+ }
37
+ async handleToolEnd(output, runId) {
38
+ const pending = this.pendingTools.get(runId);
39
+ this.pendingTools.delete(runId);
40
+ await this.logger.log({
41
+ agent: this.agentName,
42
+ action: 'tool_end',
43
+ tool: pending?.name ?? 'unknown_tool',
44
+ input: pending?.input,
45
+ output,
46
+ metadata: pending ? { startedAt: pending.startedAt } : undefined,
47
+ });
48
+ }
49
+ async handleToolError(err, runId) {
50
+ const pending = this.pendingTools.get(runId);
51
+ this.pendingTools.delete(runId);
52
+ await this.logger.log({
53
+ agent: this.agentName,
54
+ action: 'tool_error',
55
+ tool: pending?.name ?? 'unknown_tool',
56
+ output: err.message,
57
+ metadata: { error: true, errorClass: err.constructor.name },
58
+ });
59
+ }
60
+ async handleLLMStart(_llm, prompts, _runId) {
61
+ await this.logger.log({
62
+ agent: this.agentName,
63
+ action: 'llm_start',
64
+ input: prompts[0],
65
+ metadata: { promptCount: prompts.length },
66
+ });
67
+ }
68
+ async handleLLMEnd(output, _runId) {
69
+ await this.logger.log({
70
+ agent: this.agentName,
71
+ action: 'llm_end',
72
+ output,
73
+ });
74
+ }
75
+ async handleChainStart(chain, inputs, _runId) {
76
+ await this.logger.log({
77
+ agent: this.agentName,
78
+ action: 'chain_start',
79
+ metadata: { chainType: chain.id, inputs },
80
+ });
81
+ }
82
+ async handleChainEnd(outputs, _runId) {
83
+ await this.logger.log({
84
+ agent: this.agentName,
85
+ action: 'chain_end',
86
+ output: outputs,
87
+ });
88
+ }
89
+ }
90
+ //# sourceMappingURL=langchain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"langchain.js","sourceRoot":"","sources":["../../src/adapters/langchain.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @agentlair/audit-logger
3
+ *
4
+ * Framework-agnostic agent action logger. Zero runtime dependencies.
5
+ * Works in Node ≥ 18, Bun, Deno, and modern browsers.
6
+ *
7
+ * --- Quick start ---
8
+ *
9
+ * import { auditLog } from '@agentlair/audit-logger';
10
+ *
11
+ * // Just log locally:
12
+ * await auditLog({ agent: 'my-agent', action: 'tool_call', tool: 'search', input: query });
13
+ *
14
+ * // Connect to AgentLair (set AGENTLAIR_API_KEY env var):
15
+ * await auditLog({ agent: 'my-agent', action: 'decision', output: result });
16
+ *
17
+ * --- Framework adapters ---
18
+ *
19
+ * import { AuditLoggerCallbackHandler } from '@agentlair/audit-logger/langchain';
20
+ * import { wrapAnthropicClient } from '@agentlair/audit-logger/anthropic';
21
+ *
22
+ * @see https://agentlair.dev/docs/audit-logger
23
+ */
24
+ export { AuditLogger, auditLog, configureLogger } from './logger.js';
25
+ export type { AuditLogEntry, ResolvedAuditEntry, AuditSink, AuditLoggerOptions, } from './types.js';
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACrE,YAAY,EACV,aAAa,EACb,kBAAkB,EAClB,SAAS,EACT,kBAAkB,GACnB,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @agentlair/audit-logger
3
+ *
4
+ * Framework-agnostic agent action logger. Zero runtime dependencies.
5
+ * Works in Node ≥ 18, Bun, Deno, and modern browsers.
6
+ *
7
+ * --- Quick start ---
8
+ *
9
+ * import { auditLog } from '@agentlair/audit-logger';
10
+ *
11
+ * // Just log locally:
12
+ * await auditLog({ agent: 'my-agent', action: 'tool_call', tool: 'search', input: query });
13
+ *
14
+ * // Connect to AgentLair (set AGENTLAIR_API_KEY env var):
15
+ * await auditLog({ agent: 'my-agent', action: 'decision', output: result });
16
+ *
17
+ * --- Framework adapters ---
18
+ *
19
+ * import { AuditLoggerCallbackHandler } from '@agentlair/audit-logger/langchain';
20
+ * import { wrapAnthropicClient } from '@agentlair/audit-logger/anthropic';
21
+ *
22
+ * @see https://agentlair.dev/docs/audit-logger
23
+ */
24
+ export { AuditLogger, auditLog, configureLogger } from './logger.js';
25
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,35 @@
1
+ import type { AuditLogEntry, AuditLoggerOptions, ResolvedAuditEntry } from './types.js';
2
+ export declare class AuditLogger {
3
+ private readonly apiKey;
4
+ private readonly baseUrl;
5
+ private readonly sinks;
6
+ private readonly useConsole;
7
+ private readonly silent;
8
+ constructor(options?: AuditLoggerOptions);
9
+ /**
10
+ * Log a single agent action.
11
+ * - Always writes to console (unless silent/disabled)
12
+ * - Writes to any configured sinks
13
+ * - If apiKey is present, ships to AgentLair async (non-blocking)
14
+ */
15
+ log(entry: AuditLogEntry): Promise<ResolvedAuditEntry>;
16
+ /** Convenience: log multiple entries in sequence */
17
+ logAll(entries: AuditLogEntry[]): Promise<ResolvedAuditEntry[]>;
18
+ private writeConsole;
19
+ private shipToAgentLair;
20
+ }
21
+ /**
22
+ * Log an agent action using the default logger.
23
+ * Reads AGENTLAIR_API_KEY from environment automatically.
24
+ *
25
+ * @example
26
+ * import { auditLog } from '@agentlair/audit-logger';
27
+ * await auditLog({ agent: 'researcher', action: 'tool_call', tool: 'web_search', input: query });
28
+ */
29
+ export declare function auditLog(entry: AuditLogEntry): Promise<ResolvedAuditEntry>;
30
+ /**
31
+ * Configure the default logger instance.
32
+ * Call this once at startup before any auditLog() calls.
33
+ */
34
+ export declare function configureLogger(options: AuditLoggerOptions): void;
35
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,aAAa,EAAE,kBAAkB,EAAa,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEnG,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAc;IACpC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAU;IACrC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;gBAErB,OAAO,GAAE,kBAAuB;IAW5C;;;;;OAKG;IACG,GAAG,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,kBAAkB,CAAC;IA6B5D,oDAAoD;IAC9C,MAAM,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAQrE,OAAO,CAAC,YAAY;YAMN,eAAe;CAsB9B;AAcD;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAEhF;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI,CAEjE"}
package/dist/logger.js ADDED
@@ -0,0 +1,113 @@
1
+ // ─── AuditLogger ─────────────────────────────────────────────────────────────
2
+ // Core logger class. Logs agent actions locally and optionally ships to AgentLair.
3
+ //
4
+ // Usage:
5
+ // import { AuditLogger } from '@agentlair/audit-logger';
6
+ // const logger = new AuditLogger(); // reads AGENTLAIR_API_KEY automatically
7
+ // await logger.log({ agent: 'my-agent', action: 'tool_call', tool: 'search', input: query, output: results });
8
+ export class AuditLogger {
9
+ apiKey;
10
+ baseUrl;
11
+ sinks;
12
+ useConsole;
13
+ silent;
14
+ constructor(options = {}) {
15
+ // Resolve API key from options or env
16
+ this.apiKey = options.apiKey ?? (typeof process !== 'undefined' ? process.env.AGENTLAIR_API_KEY : undefined);
17
+ this.baseUrl = (options.baseUrl ?? 'https://agentlair.dev').replace(/\/$/, '');
18
+ this.sinks = options.sinks ?? [];
19
+ this.useConsole = options.console !== false;
20
+ this.silent = options.silent ?? false;
21
+ }
22
+ /**
23
+ * Log a single agent action.
24
+ * - Always writes to console (unless silent/disabled)
25
+ * - Writes to any configured sinks
26
+ * - If apiKey is present, ships to AgentLair async (non-blocking)
27
+ */
28
+ async log(entry) {
29
+ const resolved = {
30
+ ...entry,
31
+ timestamp: entry.timestamp ?? new Date().toISOString(),
32
+ };
33
+ if (!this.silent) {
34
+ // Console output
35
+ if (this.useConsole) {
36
+ this.writeConsole(resolved);
37
+ }
38
+ // Custom sinks
39
+ for (const sink of this.sinks) {
40
+ await sink.write(resolved);
41
+ }
42
+ // AgentLair backend (fire-and-forget, non-blocking)
43
+ if (this.apiKey) {
44
+ this.shipToAgentLair(resolved).catch((err) => {
45
+ // Non-fatal — log locally but don't throw
46
+ console.warn('[audit-logger] AgentLair upload failed:', err.message);
47
+ });
48
+ }
49
+ }
50
+ return resolved;
51
+ }
52
+ /** Convenience: log multiple entries in sequence */
53
+ async logAll(entries) {
54
+ const results = [];
55
+ for (const entry of entries) {
56
+ results.push(await this.log(entry));
57
+ }
58
+ return results;
59
+ }
60
+ writeConsole(entry) {
61
+ const tool = entry.tool ? ` [${entry.tool}]` : '';
62
+ const ts = entry.timestamp.slice(11, 19); // HH:MM:SS
63
+ console.log(`[audit ${ts}] ${entry.agent} → ${entry.action}${tool}`);
64
+ }
65
+ async shipToAgentLair(entry) {
66
+ // Use AgentLair Observations API with topic "audit-log"
67
+ // Content is serialized JSON of the full entry
68
+ const payload = {
69
+ topic: 'audit-log',
70
+ content: JSON.stringify(entry),
71
+ };
72
+ const res = await fetch(`${this.baseUrl}/v1/observations`, {
73
+ method: 'POST',
74
+ headers: {
75
+ 'Content-Type': 'application/json',
76
+ Authorization: `Bearer ${this.apiKey}`,
77
+ },
78
+ body: JSON.stringify(payload),
79
+ });
80
+ if (!res.ok) {
81
+ const text = await res.text().catch(() => '');
82
+ throw new Error(`AgentLair ${res.status}: ${text}`);
83
+ }
84
+ }
85
+ }
86
+ // ─── Module-level convenience API ────────────────────────────────────────────
87
+ // Uses a default logger instance (lazy-initialized on first call).
88
+ let _defaultLogger = null;
89
+ function getDefaultLogger() {
90
+ if (!_defaultLogger) {
91
+ _defaultLogger = new AuditLogger();
92
+ }
93
+ return _defaultLogger;
94
+ }
95
+ /**
96
+ * Log an agent action using the default logger.
97
+ * Reads AGENTLAIR_API_KEY from environment automatically.
98
+ *
99
+ * @example
100
+ * import { auditLog } from '@agentlair/audit-logger';
101
+ * await auditLog({ agent: 'researcher', action: 'tool_call', tool: 'web_search', input: query });
102
+ */
103
+ export async function auditLog(entry) {
104
+ return getDefaultLogger().log(entry);
105
+ }
106
+ /**
107
+ * Configure the default logger instance.
108
+ * Call this once at startup before any auditLog() calls.
109
+ */
110
+ export function configureLogger(options) {
111
+ _defaultLogger = new AuditLogger(options);
112
+ }
113
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,mFAAmF;AACnF,EAAE;AACF,SAAS;AACT,2DAA2D;AAC3D,+EAA+E;AAC/E,iHAAiH;AAIjH,MAAM,OAAO,WAAW;IACL,MAAM,CAAqB;IAC3B,OAAO,CAAS;IAChB,KAAK,CAAc;IACnB,UAAU,CAAU;IACpB,MAAM,CAAU;IAEjC,YAAY,UAA8B,EAAE;QAC1C,sCAAsC;QACtC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,CAC9B,OAAO,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,SAAS,CAC3E,CAAC;QACF,IAAI,CAAC,OAAO,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,uBAAuB,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC/E,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;QACjC,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,OAAO,KAAK,KAAK,CAAC;QAC5C,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC;IACxC,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,GAAG,CAAC,KAAoB;QAC5B,MAAM,QAAQ,GAAuB;YACnC,GAAG,KAAK;YACR,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACvD,CAAC;QAEF,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,iBAAiB;YACjB,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACpB,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;YAC9B,CAAC;YAED,eAAe;YACf,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBAC9B,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC7B,CAAC;YAED,oDAAoD;YACpD,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChB,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;oBAC3C,0CAA0C;oBAC1C,OAAO,CAAC,IAAI,CAAC,yCAAyC,EAAG,GAAa,CAAC,OAAO,CAAC,CAAC;gBAClF,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,oDAAoD;IACpD,KAAK,CAAC,MAAM,CAAC,OAAwB;QACnC,MAAM,OAAO,GAAyB,EAAE,CAAC;QACzC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;QACtC,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,YAAY,CAAC,KAAyB;QAC5C,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAClD,MAAM,EAAE,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW;QACrD,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,KAAK,CAAC,KAAK,MAAM,KAAK,CAAC,MAAM,GAAG,IAAI,EAAE,CAAC,CAAC;IACvE,CAAC;IAEO,KAAK,CAAC,eAAe,CAAC,KAAyB;QACrD,wDAAwD;QACxD,+CAA+C;QAC/C,MAAM,OAAO,GAAG;YACd,KAAK,EAAE,WAAW;YAClB,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;SAC/B,CAAC;QAEF,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,kBAAkB,EAAE;YACzD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;aACvC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;SAC9B,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YAC9C,MAAM,IAAI,KAAK,CAAC,aAAa,GAAG,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;CACF;AAED,gFAAgF;AAChF,mEAAmE;AAEnE,IAAI,cAAc,GAAuB,IAAI,CAAC;AAE9C,SAAS,gBAAgB;IACvB,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,cAAc,GAAG,IAAI,WAAW,EAAE,CAAC;IACrC,CAAC;IACD,OAAO,cAAc,CAAC;AACxB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,KAAoB;IACjD,OAAO,gBAAgB,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AACvC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,OAA2B;IACzD,cAAc,GAAG,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,45 @@
1
+ /** A single agent action to log */
2
+ export interface AuditLogEntry {
3
+ /** Name/ID of the agent performing the action */
4
+ agent: string;
5
+ /** High-level action category (e.g. "tool_call", "llm_response", "decision") */
6
+ action: string;
7
+ /** Tool name, if this is a tool call */
8
+ tool?: string;
9
+ /** Input passed to the tool or LLM */
10
+ input?: unknown;
11
+ /** Output from the tool or LLM */
12
+ output?: unknown;
13
+ /** ISO 8601 timestamp — defaults to now */
14
+ timestamp?: string;
15
+ /** Additional metadata */
16
+ metadata?: Record<string, unknown>;
17
+ }
18
+ /** A log entry with all fields resolved (timestamp guaranteed) */
19
+ export interface ResolvedAuditEntry extends AuditLogEntry {
20
+ timestamp: string;
21
+ }
22
+ /** Sink: where to write audit logs */
23
+ export interface AuditSink {
24
+ write(entry: ResolvedAuditEntry): Promise<void> | void;
25
+ }
26
+ /** Options for configuring the audit logger */
27
+ export interface AuditLoggerOptions {
28
+ /**
29
+ * AgentLair API key. If set (or AGENTLAIR_API_KEY env var), logs are also
30
+ * shipped to AgentLair for persistent querying.
31
+ */
32
+ apiKey?: string;
33
+ /** Base URL for AgentLair API. Defaults to https://agentlair.dev */
34
+ baseUrl?: string;
35
+ /**
36
+ * Local sinks to write to in addition to (or instead of) console.
37
+ * Pass an empty array to suppress console output.
38
+ */
39
+ sinks?: AuditSink[];
40
+ /** If false, suppress console output. Default: true */
41
+ console?: boolean;
42
+ /** If true, suppress all output (useful in tests) */
43
+ silent?: boolean;
44
+ }
45
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAGA,mCAAmC;AACnC,MAAM,WAAW,aAAa;IAC5B,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,sCAAsC;IACtC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,kCAAkC;IAClC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0BAA0B;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,kEAAkE;AAClE,MAAM,WAAW,kBAAmB,SAAQ,aAAa;IACvD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,sCAAsC;AACtC,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACxD;AAED,+CAA+C;AAC/C,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC;IACpB,uDAAuD;IACvD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,qDAAqD;IACrD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB"}
package/dist/types.js ADDED
@@ -0,0 +1,4 @@
1
+ // ─── Types ───────────────────────────────────────────────────────────────────
2
+ // Core types for @agentlair/audit-logger
3
+ export {};
4
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,yCAAyC"}
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@agentlair/audit-logger",
3
+ "version": "0.1.0",
4
+ "description": "Framework-agnostic agent action logger. Logs locally by default. Connect to AgentLair for persistent, queryable audit trails.",
5
+ "keywords": [
6
+ "ai-agent",
7
+ "audit",
8
+ "logging",
9
+ "langchain",
10
+ "crewai",
11
+ "claude",
12
+ "anthropic",
13
+ "agentlair",
14
+ "observability",
15
+ "agent-monitoring"
16
+ ],
17
+ "homepage": "https://agentlair.dev",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/piiiico/agentlair"
21
+ },
22
+ "license": "MIT",
23
+ "author": "AgentLair",
24
+ "type": "module",
25
+ "main": "./dist/index.js",
26
+ "module": "./dist/index.js",
27
+ "types": "./dist/index.d.ts",
28
+ "exports": {
29
+ ".": {
30
+ "import": "./dist/index.js",
31
+ "types": "./dist/index.d.ts"
32
+ },
33
+ "./langchain": {
34
+ "import": "./dist/adapters/langchain.js",
35
+ "types": "./dist/adapters/langchain.d.ts"
36
+ },
37
+ "./anthropic": {
38
+ "import": "./dist/adapters/anthropic.js",
39
+ "types": "./dist/adapters/anthropic.d.ts"
40
+ }
41
+ },
42
+ "files": [
43
+ "dist",
44
+ "README.md"
45
+ ],
46
+ "scripts": {
47
+ "build": "tsc",
48
+ "test": "bun test",
49
+ "typecheck": "tsc --noEmit",
50
+ "prepublishOnly": "bun run build"
51
+ },
52
+ "engines": {
53
+ "node": ">=18.0.0"
54
+ },
55
+ "devDependencies": {
56
+ "@types/node": "^25.5.0",
57
+ "bun-types": "^1.3.11",
58
+ "typescript": "^6.0.2"
59
+ }
60
+ }