@compilr-dev/agents 0.0.1
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 +1277 -0
- package/dist/agent.d.ts +1272 -0
- package/dist/agent.js +1912 -0
- package/dist/anchors/builtin.d.ts +24 -0
- package/dist/anchors/builtin.js +61 -0
- package/dist/anchors/index.d.ts +6 -0
- package/dist/anchors/index.js +5 -0
- package/dist/anchors/manager.d.ts +115 -0
- package/dist/anchors/manager.js +412 -0
- package/dist/anchors/types.d.ts +168 -0
- package/dist/anchors/types.js +10 -0
- package/dist/context/index.d.ts +12 -0
- package/dist/context/index.js +10 -0
- package/dist/context/manager.d.ts +224 -0
- package/dist/context/manager.js +770 -0
- package/dist/context/types.d.ts +377 -0
- package/dist/context/types.js +7 -0
- package/dist/costs/index.d.ts +8 -0
- package/dist/costs/index.js +7 -0
- package/dist/costs/tracker.d.ts +121 -0
- package/dist/costs/tracker.js +295 -0
- package/dist/costs/types.d.ts +157 -0
- package/dist/costs/types.js +8 -0
- package/dist/errors.d.ts +178 -0
- package/dist/errors.js +249 -0
- package/dist/guardrails/builtin.d.ts +27 -0
- package/dist/guardrails/builtin.js +223 -0
- package/dist/guardrails/index.d.ts +6 -0
- package/dist/guardrails/index.js +5 -0
- package/dist/guardrails/manager.d.ts +117 -0
- package/dist/guardrails/manager.js +288 -0
- package/dist/guardrails/types.d.ts +159 -0
- package/dist/guardrails/types.js +7 -0
- package/dist/hooks/index.d.ts +31 -0
- package/dist/hooks/index.js +29 -0
- package/dist/hooks/manager.d.ts +147 -0
- package/dist/hooks/manager.js +600 -0
- package/dist/hooks/types.d.ts +368 -0
- package/dist/hooks/types.js +12 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.js +73 -0
- package/dist/mcp/client.d.ts +93 -0
- package/dist/mcp/client.js +287 -0
- package/dist/mcp/errors.d.ts +60 -0
- package/dist/mcp/errors.js +78 -0
- package/dist/mcp/index.d.ts +43 -0
- package/dist/mcp/index.js +45 -0
- package/dist/mcp/manager.d.ts +120 -0
- package/dist/mcp/manager.js +276 -0
- package/dist/mcp/tools.d.ts +54 -0
- package/dist/mcp/tools.js +99 -0
- package/dist/mcp/types.d.ts +150 -0
- package/dist/mcp/types.js +40 -0
- package/dist/memory/index.d.ts +8 -0
- package/dist/memory/index.js +7 -0
- package/dist/memory/loader.d.ts +114 -0
- package/dist/memory/loader.js +463 -0
- package/dist/memory/types.d.ts +182 -0
- package/dist/memory/types.js +8 -0
- package/dist/messages/index.d.ts +82 -0
- package/dist/messages/index.js +155 -0
- package/dist/permissions/index.d.ts +5 -0
- package/dist/permissions/index.js +4 -0
- package/dist/permissions/manager.d.ts +125 -0
- package/dist/permissions/manager.js +379 -0
- package/dist/permissions/types.d.ts +162 -0
- package/dist/permissions/types.js +7 -0
- package/dist/providers/claude.d.ts +90 -0
- package/dist/providers/claude.js +348 -0
- package/dist/providers/index.d.ts +8 -0
- package/dist/providers/index.js +11 -0
- package/dist/providers/mock.d.ts +133 -0
- package/dist/providers/mock.js +204 -0
- package/dist/providers/types.d.ts +168 -0
- package/dist/providers/types.js +4 -0
- package/dist/rate-limit/index.d.ts +45 -0
- package/dist/rate-limit/index.js +47 -0
- package/dist/rate-limit/limiter.d.ts +104 -0
- package/dist/rate-limit/limiter.js +326 -0
- package/dist/rate-limit/provider-wrapper.d.ts +112 -0
- package/dist/rate-limit/provider-wrapper.js +201 -0
- package/dist/rate-limit/retry.d.ts +108 -0
- package/dist/rate-limit/retry.js +287 -0
- package/dist/rate-limit/types.d.ts +181 -0
- package/dist/rate-limit/types.js +22 -0
- package/dist/rehearsal/file-analyzer.d.ts +22 -0
- package/dist/rehearsal/file-analyzer.js +351 -0
- package/dist/rehearsal/git-analyzer.d.ts +22 -0
- package/dist/rehearsal/git-analyzer.js +472 -0
- package/dist/rehearsal/index.d.ts +35 -0
- package/dist/rehearsal/index.js +36 -0
- package/dist/rehearsal/manager.d.ts +100 -0
- package/dist/rehearsal/manager.js +290 -0
- package/dist/rehearsal/types.d.ts +235 -0
- package/dist/rehearsal/types.js +8 -0
- package/dist/skills/index.d.ts +160 -0
- package/dist/skills/index.js +282 -0
- package/dist/state/agent-state.d.ts +41 -0
- package/dist/state/agent-state.js +88 -0
- package/dist/state/checkpointer.d.ts +110 -0
- package/dist/state/checkpointer.js +362 -0
- package/dist/state/errors.d.ts +66 -0
- package/dist/state/errors.js +88 -0
- package/dist/state/index.d.ts +35 -0
- package/dist/state/index.js +37 -0
- package/dist/state/serializer.d.ts +55 -0
- package/dist/state/serializer.js +172 -0
- package/dist/state/types.d.ts +312 -0
- package/dist/state/types.js +14 -0
- package/dist/tools/builtin/bash-output.d.ts +61 -0
- package/dist/tools/builtin/bash-output.js +90 -0
- package/dist/tools/builtin/bash.d.ts +150 -0
- package/dist/tools/builtin/bash.js +354 -0
- package/dist/tools/builtin/edit.d.ts +50 -0
- package/dist/tools/builtin/edit.js +215 -0
- package/dist/tools/builtin/glob.d.ts +62 -0
- package/dist/tools/builtin/glob.js +244 -0
- package/dist/tools/builtin/grep.d.ts +74 -0
- package/dist/tools/builtin/grep.js +363 -0
- package/dist/tools/builtin/index.d.ts +44 -0
- package/dist/tools/builtin/index.js +69 -0
- package/dist/tools/builtin/kill-shell.d.ts +44 -0
- package/dist/tools/builtin/kill-shell.js +80 -0
- package/dist/tools/builtin/read-file.d.ts +57 -0
- package/dist/tools/builtin/read-file.js +184 -0
- package/dist/tools/builtin/shell-manager.d.ts +176 -0
- package/dist/tools/builtin/shell-manager.js +337 -0
- package/dist/tools/builtin/task.d.ts +202 -0
- package/dist/tools/builtin/task.js +350 -0
- package/dist/tools/builtin/todo.d.ts +207 -0
- package/dist/tools/builtin/todo.js +453 -0
- package/dist/tools/builtin/utils.d.ts +27 -0
- package/dist/tools/builtin/utils.js +70 -0
- package/dist/tools/builtin/web-fetch.d.ts +96 -0
- package/dist/tools/builtin/web-fetch.js +290 -0
- package/dist/tools/builtin/write-file.d.ts +54 -0
- package/dist/tools/builtin/write-file.js +147 -0
- package/dist/tools/define.d.ts +60 -0
- package/dist/tools/define.js +65 -0
- package/dist/tools/index.d.ts +10 -0
- package/dist/tools/index.js +37 -0
- package/dist/tools/registry.d.ts +79 -0
- package/dist/tools/registry.js +151 -0
- package/dist/tools/types.d.ts +59 -0
- package/dist/tools/types.js +4 -0
- package/dist/tracing/hooks.d.ts +58 -0
- package/dist/tracing/hooks.js +377 -0
- package/dist/tracing/index.d.ts +51 -0
- package/dist/tracing/index.js +55 -0
- package/dist/tracing/logging.d.ts +78 -0
- package/dist/tracing/logging.js +310 -0
- package/dist/tracing/manager.d.ts +160 -0
- package/dist/tracing/manager.js +468 -0
- package/dist/tracing/otel.d.ts +102 -0
- package/dist/tracing/otel.js +246 -0
- package/dist/tracing/types.d.ts +346 -0
- package/dist/tracing/types.js +38 -0
- package/dist/utils/index.d.ts +23 -0
- package/dist/utils/index.js +44 -0
- package/package.json +79 -0
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in Tracing Hooks
|
|
3
|
+
*
|
|
4
|
+
* Pre-built hooks for common tracing patterns that integrate with the HooksManager.
|
|
5
|
+
* These hooks automatically create spans for LLM calls, tool executions, and iterations.
|
|
6
|
+
*/
|
|
7
|
+
import { SemanticAttributes } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Truncate a value to a maximum length
|
|
10
|
+
*/
|
|
11
|
+
function truncate(value, maxLength) {
|
|
12
|
+
const str = typeof value === 'string' ? value : JSON.stringify(value);
|
|
13
|
+
if (str.length <= maxLength)
|
|
14
|
+
return str;
|
|
15
|
+
return str.slice(0, maxLength - 3) + '...';
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Create tracing hooks that automatically instrument agent execution
|
|
19
|
+
*
|
|
20
|
+
* @param manager - TracingManager instance
|
|
21
|
+
* @param config - Tracing hooks configuration
|
|
22
|
+
* @returns HooksConfig with tracing hooks
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const tracingManager = new TracingManager({ serviceName: 'my-agent' });
|
|
27
|
+
* const tracingHooks = createTracingHooks(tracingManager, {
|
|
28
|
+
* traceLLM: true,
|
|
29
|
+
* traceTools: true,
|
|
30
|
+
* traceIterations: true,
|
|
31
|
+
* });
|
|
32
|
+
*
|
|
33
|
+
* const agent = new Agent({
|
|
34
|
+
* provider,
|
|
35
|
+
* hooks: tracingHooks,
|
|
36
|
+
* });
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export function createTracingHooks(manager, config = {}) {
|
|
40
|
+
const { traceLLM = true, traceTools = true, traceIterations = true, includeIO = false, truncateAt = 1000, attributeMapper, } = config;
|
|
41
|
+
// Track active spans per session
|
|
42
|
+
const activeContexts = new Map();
|
|
43
|
+
// Get or create context for a session
|
|
44
|
+
const getContext = (sessionId) => {
|
|
45
|
+
let ctx = activeContexts.get(sessionId);
|
|
46
|
+
if (!ctx) {
|
|
47
|
+
ctx = {};
|
|
48
|
+
activeContexts.set(sessionId, ctx);
|
|
49
|
+
}
|
|
50
|
+
return ctx;
|
|
51
|
+
};
|
|
52
|
+
const hooks = {};
|
|
53
|
+
// ============================================================================
|
|
54
|
+
// Iteration Hooks
|
|
55
|
+
// ============================================================================
|
|
56
|
+
if (traceIterations) {
|
|
57
|
+
const beforeIteration = async (ctx) => {
|
|
58
|
+
await Promise.resolve(); // Ensure async function has await
|
|
59
|
+
const spanCtx = getContext(ctx.sessionId);
|
|
60
|
+
// Start iteration span
|
|
61
|
+
const span = manager.startSpan({
|
|
62
|
+
name: `iteration-${String(ctx.iteration)}`,
|
|
63
|
+
kind: 'internal',
|
|
64
|
+
attributes: {
|
|
65
|
+
[SemanticAttributes.AGENT_SESSION_ID]: ctx.sessionId,
|
|
66
|
+
[SemanticAttributes.AGENT_ITERATION]: ctx.iteration,
|
|
67
|
+
[SemanticAttributes.AGENT_MAX_ITERATIONS]: ctx.maxIterations,
|
|
68
|
+
[SemanticAttributes.MESSAGE_COUNT]: ctx.messages.length,
|
|
69
|
+
...(attributeMapper?.('iteration', { iteration: ctx.iteration }) ?? {}),
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
spanCtx.iterationSpanId = span.spanId;
|
|
73
|
+
return undefined;
|
|
74
|
+
};
|
|
75
|
+
const afterIteration = async (ctx) => {
|
|
76
|
+
await Promise.resolve(); // Ensure async function has await
|
|
77
|
+
const spanCtx = getContext(ctx.sessionId);
|
|
78
|
+
if (spanCtx.iterationSpanId) {
|
|
79
|
+
manager.setSpanAttributes(spanCtx.iterationSpanId, {
|
|
80
|
+
'iteration.tool_calls': ctx.toolCalls.length,
|
|
81
|
+
'iteration.completed_with_text': ctx.completedWithText,
|
|
82
|
+
});
|
|
83
|
+
manager.endSpan(spanCtx.iterationSpanId, {
|
|
84
|
+
status: 'ok',
|
|
85
|
+
});
|
|
86
|
+
spanCtx.iterationSpanId = undefined;
|
|
87
|
+
}
|
|
88
|
+
return undefined;
|
|
89
|
+
};
|
|
90
|
+
hooks.beforeIteration = [beforeIteration];
|
|
91
|
+
hooks.afterIteration = [afterIteration];
|
|
92
|
+
}
|
|
93
|
+
// ============================================================================
|
|
94
|
+
// LLM Hooks
|
|
95
|
+
// ============================================================================
|
|
96
|
+
if (traceLLM) {
|
|
97
|
+
const beforeLLM = async (ctx) => {
|
|
98
|
+
await Promise.resolve(); // Ensure async function has await
|
|
99
|
+
const spanCtx = getContext(ctx.sessionId);
|
|
100
|
+
const attributes = {
|
|
101
|
+
[SemanticAttributes.AGENT_SESSION_ID]: ctx.sessionId,
|
|
102
|
+
[SemanticAttributes.MESSAGE_COUNT]: ctx.messages.length,
|
|
103
|
+
'llm.tool_count': ctx.tools.length,
|
|
104
|
+
...(attributeMapper?.('llm', { messageCount: ctx.messages.length }) ?? {}),
|
|
105
|
+
};
|
|
106
|
+
// Optionally include messages (can be verbose)
|
|
107
|
+
if (includeIO && ctx.messages.length > 0) {
|
|
108
|
+
const lastMessage = ctx.messages[ctx.messages.length - 1];
|
|
109
|
+
attributes['llm.last_message_role'] = lastMessage.role;
|
|
110
|
+
if (typeof lastMessage.content === 'string') {
|
|
111
|
+
attributes['llm.last_message_content'] = truncate(lastMessage.content, truncateAt);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const span = manager.startSpan({
|
|
115
|
+
name: 'llm-call',
|
|
116
|
+
kind: 'client',
|
|
117
|
+
attributes,
|
|
118
|
+
parentContext: spanCtx.iterationSpanId
|
|
119
|
+
? {
|
|
120
|
+
traceId: manager.getSpan(spanCtx.iterationSpanId)?.traceId ?? '',
|
|
121
|
+
parentSpanId: spanCtx.iterationSpanId,
|
|
122
|
+
}
|
|
123
|
+
: undefined,
|
|
124
|
+
});
|
|
125
|
+
spanCtx.llmSpanId = span.spanId;
|
|
126
|
+
return undefined;
|
|
127
|
+
};
|
|
128
|
+
const afterLLM = async (ctx) => {
|
|
129
|
+
await Promise.resolve(); // Ensure async function has await
|
|
130
|
+
const spanCtx = getContext(ctx.sessionId);
|
|
131
|
+
if (spanCtx.llmSpanId) {
|
|
132
|
+
const attributes = {
|
|
133
|
+
'llm.has_tool_calls': ctx.toolUses.length > 0,
|
|
134
|
+
'llm.tool_call_count': ctx.toolUses.length,
|
|
135
|
+
};
|
|
136
|
+
// Add usage if available
|
|
137
|
+
if (ctx.usage) {
|
|
138
|
+
attributes[SemanticAttributes.LLM_INPUT_TOKENS] = ctx.usage.inputTokens;
|
|
139
|
+
attributes[SemanticAttributes.LLM_OUTPUT_TOKENS] = ctx.usage.outputTokens;
|
|
140
|
+
attributes[SemanticAttributes.LLM_TOTAL_TOKENS] =
|
|
141
|
+
ctx.usage.inputTokens + ctx.usage.outputTokens;
|
|
142
|
+
}
|
|
143
|
+
// Optionally include response text
|
|
144
|
+
if (includeIO && ctx.text) {
|
|
145
|
+
attributes['llm.response_text'] = truncate(ctx.text, truncateAt);
|
|
146
|
+
}
|
|
147
|
+
manager.setSpanAttributes(spanCtx.llmSpanId, attributes);
|
|
148
|
+
manager.endSpan(spanCtx.llmSpanId, {
|
|
149
|
+
status: 'ok',
|
|
150
|
+
attributes: {
|
|
151
|
+
'llm.duration_ms': ctx.durationMs,
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
spanCtx.llmSpanId = undefined;
|
|
155
|
+
}
|
|
156
|
+
return undefined;
|
|
157
|
+
};
|
|
158
|
+
hooks.beforeLLM = [beforeLLM];
|
|
159
|
+
hooks.afterLLM = [afterLLM];
|
|
160
|
+
}
|
|
161
|
+
// ============================================================================
|
|
162
|
+
// Tool Hooks
|
|
163
|
+
// ============================================================================
|
|
164
|
+
if (traceTools) {
|
|
165
|
+
const beforeTool = async (ctx) => {
|
|
166
|
+
await Promise.resolve(); // Ensure async function has await
|
|
167
|
+
const spanCtx = getContext(ctx.sessionId);
|
|
168
|
+
const attributes = {
|
|
169
|
+
[SemanticAttributes.AGENT_SESSION_ID]: ctx.sessionId,
|
|
170
|
+
[SemanticAttributes.TOOL_NAME]: ctx.toolName,
|
|
171
|
+
...(attributeMapper?.('tool', { toolName: ctx.toolName }) ?? {}),
|
|
172
|
+
};
|
|
173
|
+
// Optionally include input
|
|
174
|
+
if (includeIO) {
|
|
175
|
+
attributes[SemanticAttributes.TOOL_INPUT] = truncate(ctx.input, truncateAt);
|
|
176
|
+
}
|
|
177
|
+
// Determine parent span (prefer LLM span, fall back to iteration span)
|
|
178
|
+
let parentContext;
|
|
179
|
+
if (spanCtx.llmSpanId) {
|
|
180
|
+
const llmSpan = manager.getSpan(spanCtx.llmSpanId);
|
|
181
|
+
if (llmSpan) {
|
|
182
|
+
parentContext = { traceId: llmSpan.traceId, parentSpanId: llmSpan.spanId };
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
else if (spanCtx.iterationSpanId) {
|
|
186
|
+
const iterSpan = manager.getSpan(spanCtx.iterationSpanId);
|
|
187
|
+
if (iterSpan) {
|
|
188
|
+
parentContext = { traceId: iterSpan.traceId, parentSpanId: iterSpan.spanId };
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
const span = manager.startSpan({
|
|
192
|
+
name: `tool:${ctx.toolName}`,
|
|
193
|
+
kind: 'internal',
|
|
194
|
+
attributes,
|
|
195
|
+
parentContext,
|
|
196
|
+
});
|
|
197
|
+
spanCtx.toolSpanId = span.spanId;
|
|
198
|
+
return undefined;
|
|
199
|
+
};
|
|
200
|
+
const afterTool = async (ctx) => {
|
|
201
|
+
await Promise.resolve(); // Ensure async function has await
|
|
202
|
+
const spanCtx = getContext(ctx.sessionId);
|
|
203
|
+
if (spanCtx.toolSpanId) {
|
|
204
|
+
const attributes = {
|
|
205
|
+
[SemanticAttributes.TOOL_SUCCESS]: ctx.result.success,
|
|
206
|
+
'tool.duration_ms': ctx.durationMs,
|
|
207
|
+
};
|
|
208
|
+
if (!ctx.result.success && ctx.result.error) {
|
|
209
|
+
attributes[SemanticAttributes.TOOL_ERROR] = ctx.result.error;
|
|
210
|
+
}
|
|
211
|
+
// Optionally include result
|
|
212
|
+
if (includeIO && ctx.result.result !== undefined) {
|
|
213
|
+
attributes[SemanticAttributes.TOOL_RESULT] = truncate(ctx.result.result, truncateAt);
|
|
214
|
+
}
|
|
215
|
+
manager.setSpanAttributes(spanCtx.toolSpanId, attributes);
|
|
216
|
+
manager.endSpan(spanCtx.toolSpanId, {
|
|
217
|
+
status: ctx.result.success ? 'ok' : 'error',
|
|
218
|
+
statusMessage: ctx.result.error,
|
|
219
|
+
});
|
|
220
|
+
spanCtx.toolSpanId = undefined;
|
|
221
|
+
}
|
|
222
|
+
return undefined;
|
|
223
|
+
};
|
|
224
|
+
hooks.beforeTool = [beforeTool];
|
|
225
|
+
hooks.afterTool = [afterTool];
|
|
226
|
+
}
|
|
227
|
+
// ============================================================================
|
|
228
|
+
// Error Hooks
|
|
229
|
+
// ============================================================================
|
|
230
|
+
const onError = async (ctx) => {
|
|
231
|
+
await Promise.resolve(); // Ensure async function has await
|
|
232
|
+
const spanCtx = getContext(ctx.sessionId);
|
|
233
|
+
// Record error on the appropriate span
|
|
234
|
+
const spanId = spanCtx.toolSpanId ?? spanCtx.llmSpanId ?? spanCtx.iterationSpanId;
|
|
235
|
+
if (spanId) {
|
|
236
|
+
manager.recordError(spanId, ctx.error);
|
|
237
|
+
}
|
|
238
|
+
return undefined;
|
|
239
|
+
};
|
|
240
|
+
hooks.onError = [onError];
|
|
241
|
+
return hooks;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Create a simple logging hook that logs all agent events
|
|
245
|
+
*
|
|
246
|
+
* @param logger - Logger function (default: console.log)
|
|
247
|
+
* @returns HooksConfig with logging hooks
|
|
248
|
+
*
|
|
249
|
+
* @example
|
|
250
|
+
* ```typescript
|
|
251
|
+
* const loggingHooks = createLoggingHooks((msg) => myLogger.info(msg));
|
|
252
|
+
* const agent = new Agent({ provider, hooks: loggingHooks });
|
|
253
|
+
* ```
|
|
254
|
+
*/
|
|
255
|
+
export function createLoggingHooks(
|
|
256
|
+
// eslint-disable-next-line no-console
|
|
257
|
+
logger = console.log) {
|
|
258
|
+
return {
|
|
259
|
+
beforeIteration: [
|
|
260
|
+
async (ctx) => {
|
|
261
|
+
await Promise.resolve();
|
|
262
|
+
logger(`[iteration:${String(ctx.iteration)}] Starting`, {
|
|
263
|
+
sessionId: ctx.sessionId,
|
|
264
|
+
messageCount: ctx.messages.length,
|
|
265
|
+
});
|
|
266
|
+
return undefined;
|
|
267
|
+
},
|
|
268
|
+
],
|
|
269
|
+
afterIteration: [
|
|
270
|
+
async (ctx) => {
|
|
271
|
+
await Promise.resolve();
|
|
272
|
+
logger(`[iteration:${String(ctx.iteration)}] Completed`, {
|
|
273
|
+
sessionId: ctx.sessionId,
|
|
274
|
+
toolCalls: ctx.toolCalls.length,
|
|
275
|
+
completedWithText: ctx.completedWithText,
|
|
276
|
+
});
|
|
277
|
+
return undefined;
|
|
278
|
+
},
|
|
279
|
+
],
|
|
280
|
+
beforeLLM: [
|
|
281
|
+
async (ctx) => {
|
|
282
|
+
await Promise.resolve();
|
|
283
|
+
logger('[llm] Calling LLM', {
|
|
284
|
+
sessionId: ctx.sessionId,
|
|
285
|
+
messageCount: ctx.messages.length,
|
|
286
|
+
toolCount: ctx.tools.length,
|
|
287
|
+
});
|
|
288
|
+
return undefined;
|
|
289
|
+
},
|
|
290
|
+
],
|
|
291
|
+
afterLLM: [
|
|
292
|
+
async (ctx) => {
|
|
293
|
+
await Promise.resolve();
|
|
294
|
+
logger('[llm] LLM responded', {
|
|
295
|
+
sessionId: ctx.sessionId,
|
|
296
|
+
durationMs: ctx.durationMs,
|
|
297
|
+
hasToolUses: ctx.toolUses.length > 0,
|
|
298
|
+
usage: ctx.usage,
|
|
299
|
+
});
|
|
300
|
+
return undefined;
|
|
301
|
+
},
|
|
302
|
+
],
|
|
303
|
+
beforeTool: [
|
|
304
|
+
async (ctx) => {
|
|
305
|
+
await Promise.resolve();
|
|
306
|
+
logger(`[tool:${ctx.toolName}] Executing`, {
|
|
307
|
+
sessionId: ctx.sessionId,
|
|
308
|
+
toolName: ctx.toolName,
|
|
309
|
+
});
|
|
310
|
+
return undefined;
|
|
311
|
+
},
|
|
312
|
+
],
|
|
313
|
+
afterTool: [
|
|
314
|
+
async (ctx) => {
|
|
315
|
+
await Promise.resolve();
|
|
316
|
+
logger(`[tool:${ctx.toolName}] Completed`, {
|
|
317
|
+
sessionId: ctx.sessionId,
|
|
318
|
+
toolName: ctx.toolName,
|
|
319
|
+
durationMs: ctx.durationMs,
|
|
320
|
+
success: ctx.result.success,
|
|
321
|
+
});
|
|
322
|
+
return undefined;
|
|
323
|
+
},
|
|
324
|
+
],
|
|
325
|
+
onError: [
|
|
326
|
+
async (ctx) => {
|
|
327
|
+
await Promise.resolve();
|
|
328
|
+
logger(`[error:${ctx.phase}] Error occurred`, {
|
|
329
|
+
sessionId: ctx.sessionId,
|
|
330
|
+
phase: ctx.phase,
|
|
331
|
+
toolName: ctx.toolName,
|
|
332
|
+
error: ctx.error.message,
|
|
333
|
+
});
|
|
334
|
+
return undefined;
|
|
335
|
+
},
|
|
336
|
+
],
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Merge multiple HooksConfig objects
|
|
341
|
+
*
|
|
342
|
+
* @param configs - HooksConfig objects to merge
|
|
343
|
+
* @returns Merged HooksConfig
|
|
344
|
+
*
|
|
345
|
+
* @example
|
|
346
|
+
* ```typescript
|
|
347
|
+
* const hooks = mergeHooks(tracingHooks, loggingHooks, customHooks);
|
|
348
|
+
* const agent = new Agent({ provider, hooks });
|
|
349
|
+
* ```
|
|
350
|
+
*/
|
|
351
|
+
export function mergeHooks(...configs) {
|
|
352
|
+
const merged = {};
|
|
353
|
+
for (const config of configs) {
|
|
354
|
+
if (config.beforeIteration) {
|
|
355
|
+
merged.beforeIteration = [...(merged.beforeIteration ?? []), ...config.beforeIteration];
|
|
356
|
+
}
|
|
357
|
+
if (config.afterIteration) {
|
|
358
|
+
merged.afterIteration = [...(merged.afterIteration ?? []), ...config.afterIteration];
|
|
359
|
+
}
|
|
360
|
+
if (config.beforeLLM) {
|
|
361
|
+
merged.beforeLLM = [...(merged.beforeLLM ?? []), ...config.beforeLLM];
|
|
362
|
+
}
|
|
363
|
+
if (config.afterLLM) {
|
|
364
|
+
merged.afterLLM = [...(merged.afterLLM ?? []), ...config.afterLLM];
|
|
365
|
+
}
|
|
366
|
+
if (config.beforeTool) {
|
|
367
|
+
merged.beforeTool = [...(merged.beforeTool ?? []), ...config.beforeTool];
|
|
368
|
+
}
|
|
369
|
+
if (config.afterTool) {
|
|
370
|
+
merged.afterTool = [...(merged.afterTool ?? []), ...config.afterTool];
|
|
371
|
+
}
|
|
372
|
+
if (config.onError) {
|
|
373
|
+
merged.onError = [...(merged.onError ?? []), ...config.onError];
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
return merged;
|
|
377
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tracing System - Observability and distributed tracing for agents
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```typescript
|
|
6
|
+
* import {
|
|
7
|
+
* TracingManager,
|
|
8
|
+
* createTracingHooks,
|
|
9
|
+
* createStructuredLogger,
|
|
10
|
+
* SemanticAttributes,
|
|
11
|
+
* } from '@compilr-dev/agents';
|
|
12
|
+
*
|
|
13
|
+
* // Create tracing manager
|
|
14
|
+
* const tracingManager = new TracingManager({
|
|
15
|
+
* serviceName: 'my-agent',
|
|
16
|
+
* defaultAttributes: { environment: 'production' },
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* // Create tracing hooks for automatic instrumentation
|
|
20
|
+
* const tracingHooks = createTracingHooks(tracingManager, {
|
|
21
|
+
* traceLLM: true,
|
|
22
|
+
* traceTools: true,
|
|
23
|
+
* traceIterations: true,
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* // Create structured logger
|
|
27
|
+
* const logger = createStructuredLogger({
|
|
28
|
+
* level: 'info',
|
|
29
|
+
* serviceName: 'my-agent',
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* // Use with Agent
|
|
33
|
+
* const agent = new Agent({
|
|
34
|
+
* provider,
|
|
35
|
+
* hooks: tracingHooks,
|
|
36
|
+
* });
|
|
37
|
+
*
|
|
38
|
+
* // Manual tracing
|
|
39
|
+
* const traceId = tracingManager.startTrace();
|
|
40
|
+
* const span = tracingManager.startSpan({ name: 'process-request' });
|
|
41
|
+
* // ... do work ...
|
|
42
|
+
* tracingManager.endSpan(span.spanId, { status: 'ok' });
|
|
43
|
+
* tracingManager.endTrace(traceId);
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export { TracingManager } from './manager.js';
|
|
47
|
+
export { createTracingHooks, createLoggingHooks, mergeHooks } from './hooks.js';
|
|
48
|
+
export { createStructuredLogger, createNoopLogger, createBufferedLogger, createTracingLogger, formatDuration, formatBytes, redactSensitive, } from './logging.js';
|
|
49
|
+
export { createOTelExporter, createConsoleExporter, createBatchExporter, createMultiExporter, OTelNotInstalledError, isOTelNotInstalledError, } from './otel.js';
|
|
50
|
+
export type { Span, SpanStatus, SpanKind, SpanAttributes, SpanContext, SpanEvent, AttributeValue, Trace, TracingManagerOptions, StartSpanOptions, EndSpanOptions, TracingHooksConfig, TracingEvent, TracingEventHandler, OTelExporter, OTelSDK, OTelTracer, OTelSpan, LogLevel, LogEntry, StructuredLogger, StructuredLoggerOptions, TracingHookContext, TracingManagerInterface, } from './types.js';
|
|
51
|
+
export { SemanticAttributes } from './types.js';
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tracing System - Observability and distributed tracing for agents
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```typescript
|
|
6
|
+
* import {
|
|
7
|
+
* TracingManager,
|
|
8
|
+
* createTracingHooks,
|
|
9
|
+
* createStructuredLogger,
|
|
10
|
+
* SemanticAttributes,
|
|
11
|
+
* } from '@compilr-dev/agents';
|
|
12
|
+
*
|
|
13
|
+
* // Create tracing manager
|
|
14
|
+
* const tracingManager = new TracingManager({
|
|
15
|
+
* serviceName: 'my-agent',
|
|
16
|
+
* defaultAttributes: { environment: 'production' },
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* // Create tracing hooks for automatic instrumentation
|
|
20
|
+
* const tracingHooks = createTracingHooks(tracingManager, {
|
|
21
|
+
* traceLLM: true,
|
|
22
|
+
* traceTools: true,
|
|
23
|
+
* traceIterations: true,
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* // Create structured logger
|
|
27
|
+
* const logger = createStructuredLogger({
|
|
28
|
+
* level: 'info',
|
|
29
|
+
* serviceName: 'my-agent',
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* // Use with Agent
|
|
33
|
+
* const agent = new Agent({
|
|
34
|
+
* provider,
|
|
35
|
+
* hooks: tracingHooks,
|
|
36
|
+
* });
|
|
37
|
+
*
|
|
38
|
+
* // Manual tracing
|
|
39
|
+
* const traceId = tracingManager.startTrace();
|
|
40
|
+
* const span = tracingManager.startSpan({ name: 'process-request' });
|
|
41
|
+
* // ... do work ...
|
|
42
|
+
* tracingManager.endSpan(span.spanId, { status: 'ok' });
|
|
43
|
+
* tracingManager.endTrace(traceId);
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
// Main manager
|
|
47
|
+
export { TracingManager } from './manager.js';
|
|
48
|
+
// Built-in hooks
|
|
49
|
+
export { createTracingHooks, createLoggingHooks, mergeHooks } from './hooks.js';
|
|
50
|
+
// Structured logging
|
|
51
|
+
export { createStructuredLogger, createNoopLogger, createBufferedLogger, createTracingLogger, formatDuration, formatBytes, redactSensitive, } from './logging.js';
|
|
52
|
+
// OpenTelemetry integration
|
|
53
|
+
export { createOTelExporter, createConsoleExporter, createBatchExporter, createMultiExporter, OTelNotInstalledError, isOTelNotInstalledError, } from './otel.js';
|
|
54
|
+
// Semantic conventions
|
|
55
|
+
export { SemanticAttributes } from './types.js';
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured Logging Helpers
|
|
3
|
+
*
|
|
4
|
+
* Provides structured logging utilities for agent execution with:
|
|
5
|
+
* - JSON-formatted log output
|
|
6
|
+
* - Correlation IDs (trace, span, session)
|
|
7
|
+
* - Log levels
|
|
8
|
+
* - Child loggers with inherited context
|
|
9
|
+
*/
|
|
10
|
+
import type { LogEntry, StructuredLogger, StructuredLoggerOptions } from './types.js';
|
|
11
|
+
/**
|
|
12
|
+
* Create a structured logger
|
|
13
|
+
*
|
|
14
|
+
* @param options - Logger options
|
|
15
|
+
* @returns StructuredLogger instance
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* const logger = createStructuredLogger({
|
|
20
|
+
* level: 'info',
|
|
21
|
+
* serviceName: 'my-agent',
|
|
22
|
+
* prettyPrint: process.env.NODE_ENV !== 'production',
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* logger.info('Agent started', { version: '1.0.0' });
|
|
26
|
+
* logger.error('Tool failed', new Error('timeout'), { toolName: 'bash' });
|
|
27
|
+
*
|
|
28
|
+
* // Create child logger with context
|
|
29
|
+
* const sessionLogger = logger.child({ sessionId: 'abc123' });
|
|
30
|
+
* sessionLogger.info('Processing request'); // includes sessionId
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare function createStructuredLogger(options?: StructuredLoggerOptions): StructuredLogger;
|
|
34
|
+
/**
|
|
35
|
+
* Create a no-op logger (useful for testing or disabling logs)
|
|
36
|
+
*/
|
|
37
|
+
export declare function createNoopLogger(): StructuredLogger;
|
|
38
|
+
/**
|
|
39
|
+
* Create a logger that buffers entries (useful for testing)
|
|
40
|
+
*/
|
|
41
|
+
export declare function createBufferedLogger(): StructuredLogger & {
|
|
42
|
+
entries: LogEntry[];
|
|
43
|
+
clear: () => void;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Format duration in human-readable format
|
|
47
|
+
*/
|
|
48
|
+
export declare function formatDuration(ms: number): string;
|
|
49
|
+
/**
|
|
50
|
+
* Format bytes in human-readable format
|
|
51
|
+
*/
|
|
52
|
+
export declare function formatBytes(bytes: number): string;
|
|
53
|
+
/**
|
|
54
|
+
* Redact sensitive data from an object
|
|
55
|
+
*/
|
|
56
|
+
export declare function redactSensitive(data: Record<string, unknown>, sensitiveKeys?: string[]): Record<string, unknown>;
|
|
57
|
+
/**
|
|
58
|
+
* Create a logger that integrates with TracingManager
|
|
59
|
+
*
|
|
60
|
+
* @param tracingManager - TracingManager instance
|
|
61
|
+
* @param options - Logger options
|
|
62
|
+
* @returns StructuredLogger that auto-correlates with traces
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* const tracingManager = new TracingManager({ serviceName: 'my-agent' });
|
|
67
|
+
* const logger = createTracingLogger(tracingManager);
|
|
68
|
+
*
|
|
69
|
+
* // Logger automatically includes current trace/span IDs
|
|
70
|
+
* logger.info('Processing request');
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export declare function createTracingLogger(tracingManager: {
|
|
74
|
+
getCurrentSpan: () => {
|
|
75
|
+
spanId: string;
|
|
76
|
+
traceId: string;
|
|
77
|
+
} | undefined;
|
|
78
|
+
}, options?: StructuredLoggerOptions): StructuredLogger;
|