Skip to content

Commit 5471bda

Browse files
jerryliang64claude
andauthored
feat(agent-tracing): rename TraceSession to Trace and support inputs in createTrace (#420)
## Summary - Rename `TraceSession` → `Trace`, `createSession()` → `createTrace()`, `CreateSessionOptions` → `CreateTraceOptions` for clearer semantics - Add `inputs` option to `CreateTraceOptions`, allowing callers to inject user messages into root run's `inputs` field - Move config fields (tools, model, mcp_servers, agents, slash_commands, session_id) from `inputs` to `extra`, aligning with LangGraph convention where `inputs` only contains user business data ## Changes - `core/agent-tracing/src/types.ts` - Rename type and add `inputs` field - `core/agent-tracing/src/ClaudeAgentTracer.ts` - Rename class/method, merge inputs in `handleInit`, move config fields to `extra` - `core/agent-tracing/claude.ts` - Update export - `core/agent-tracing/test/ClaudeAgentTracer.test.ts` - Update all references + 2 new test cases for inputs ## Root Run structure (before → after) ```diff // inputs - tools, model, session_id, mcp_servers, agents, slash_commands + {} (empty by default, populated via CreateTraceOptions.inputs) // extra metadata: { thread_id }, + tools, model, session_id, mcp_servers, agents, slash_commands, apiKeySource, claude_code_version, output_style, permissionMode ``` ## Usage ```typescript const trace = claudeTracer.createTrace({ traceId: ctx.tracer.traceId, threadId, inputs: { messages: [{ role: 'user', content: prompt }] }, }); for await (const msg of query({ prompt, options })) { await trace.processMessage(msg); } ``` ## Test plan - [x] All 56 existing tests pass - [x] New test: inputs are merged into root run when provided via `createTrace` - [x] New test: config fields are in `extra`, not `inputs` - [x] New test: no extra inputs when not provided 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for passing custom inputs during trace initialization to populate trace configuration. * **API Changes** * Renamed `createSession()` method to `createTrace()` for improved semantic clarity. * Renamed `CreateSessionOptions` type to `CreateTraceOptions`. * Enhanced trace initialization options with new `inputs` parameter. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 8a7eacc commit 5471bda

File tree

4 files changed

+107
-55
lines changed

4 files changed

+107
-55
lines changed

core/agent-tracing/claude.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
export * from './index';
2-
export { ClaudeAgentTracer, TraceSession } from './src/ClaudeAgentTracer';
2+
export { ClaudeAgentTracer } from './src/ClaudeAgentTracer';

core/agent-tracing/src/ClaudeAgentTracer.ts

Lines changed: 40 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,30 +12,32 @@ import {
1212
type ClaudeContentBlock,
1313
type ClaudeTokenUsage,
1414
type IRunCost,
15-
type CreateSessionOptions,
15+
type CreateTraceOptions,
1616
RunStatus,
1717
type TracerConfig,
1818
applyTracerConfig,
1919
} from './types';
2020

2121
/**
22-
* TraceSession - Manages state for a single agent execution with streaming support.
22+
* Manages state for a single agent execution with streaming support.
2323
* Allows processing messages one-by-one and logging them immediately.
2424
*/
25-
export class TraceSession {
25+
class Trace {
2626
private traceId: string;
2727
private threadId?: string;
28+
private inputs?: Record<string, any>;
2829
private rootRun: Run | null = null;
2930
private rootRunId: string;
3031
private startTime: number;
3132
private executionOrder = 2; // Start at 2, root is 1
3233
private pendingToolUses = new Map<string, Run>();
3334
private tracer: ClaudeAgentTracer;
3435

35-
constructor(tracer: ClaudeAgentTracer, options?: CreateSessionOptions) {
36+
constructor(tracer: ClaudeAgentTracer, options?: CreateTraceOptions) {
3637
this.tracer = tracer;
3738
this.traceId = options?.traceId || randomUUID();
3839
this.threadId = options?.threadId;
40+
this.inputs = options?.inputs;
3941
this.rootRunId = randomUUID();
4042
this.startTime = Date.now();
4143
}
@@ -69,6 +71,9 @@ export class TraceSession {
6971
this.threadId = message.session_id;
7072
}
7173
this.rootRun = this.tracer.createRootRunInternal(message, this.startTime, this.traceId, this.rootRunId, this.threadId);
74+
if (this.inputs) {
75+
Object.assign(this.rootRun.inputs, this.inputs);
76+
}
7277
this.tracer.logTrace(this.rootRun, RunStatus.START);
7378
}
7479

@@ -192,7 +197,7 @@ export class TraceSession {
192197
* ClaudeAgentTracer - Converts Claude SDK messages to LangChain Run format
193198
* and logs them to the same remote logging system as LangGraphTracer.
194199
*
195-
* Supports both batch processing (processMessages) and streaming (createSession).
200+
* Supports both batch processing (processMessages) and streaming (createTrace).
196201
*/
197202
@SingletonProto({
198203
accessLevel: AccessLevel.PUBLIC,
@@ -216,26 +221,31 @@ export class ClaudeAgentTracer {
216221
}
217222

218223
/**
219-
* Create a new trace session for streaming message processing.
220-
* Use this for real-time tracing where messages arrive one-by-one.
224+
* Create a new trace for one agent execution.
225+
* Returns a Trace object for streaming message processing.
221226
*
222227
* @param options.traceId - Server-side trace ID for call chain linking. Defaults to a random UUID.
223-
* @param options.threadId - Thread ID (Claude SDK session ID), recorded in metadata.
228+
* @param options.threadId - Thread ID (conversation/session identifier), recorded in metadata.
229+
* @param options.inputs - Additional inputs to merge into root run's inputs (e.g. user messages).
224230
*
225231
* @example
226-
* const session = claudeTracer.createSession({ traceId: ctx.tracer.traceId, threadId });
232+
* const trace = claudeTracer.createTrace({
233+
* traceId: ctx.tracer.traceId,
234+
* threadId,
235+
* inputs: { messages: [{ role: 'user', content: 'hello' }] },
236+
* });
227237
* for await (const message of agent.run('task')) {
228-
* await session.processMessage(message);
238+
* await trace.processMessage(message);
229239
* }
230240
*/
231-
public createSession(options?: CreateSessionOptions): TraceSession {
232-
return new TraceSession(this, options);
241+
public createTrace(options?: CreateTraceOptions): Trace {
242+
return new Trace(this, options);
233243
}
234244

235245
/**
236246
* Main entry point - convert SDK messages to Run trees and log them.
237247
* Use this when you have all messages collected (batch processing).
238-
* For real-time streaming, use createSession() instead.
248+
* For real-time streaming, use createTrace() instead.
239249
*
240250
* Non-tracing message types (tool_progress, stream_event, status, etc.) are automatically filtered out.
241251
*/
@@ -246,17 +256,17 @@ export class ClaudeAgentTracer {
246256
return;
247257
}
248258

249-
// Pre-validate: ensure there is an init message before creating session
259+
// Pre-validate: ensure there is an init message before creating trace
250260
const hasInit = sdkMessages.some(m => m.type === 'system' && 'subtype' in m && m.subtype === 'init');
251261
if (!hasInit) {
252262
this.logger.warn('[ClaudeAgentTracer] No system/init message found');
253263
return;
254264
}
255265

256-
// Delegate to TraceSession for message processing
257-
const session = this.createSession();
266+
// Delegate to Trace for message processing
267+
const trace = this.createTrace();
258268
for (const msg of sdkMessages) {
259-
await session.processMessage(msg);
269+
await trace.processMessage(msg);
260270
}
261271
} catch (e) {
262272
this.logger.warn('[ClaudeAgentTracer] processMessages error:', e);
@@ -322,7 +332,7 @@ export class ClaudeAgentTracer {
322332

323333
/**
324334
* @internal
325-
* Create root run from init message (used by TraceSession)
335+
* Create root run from init message (used by Trace)
326336
*/
327337
createRootRunInternal(initMsg: ClaudeMessage, startTime: number, traceId: string, rootRunId?: string, threadId?: string): Run {
328338
const runId = rootRunId || initMsg.uuid || randomUUID();
@@ -332,14 +342,7 @@ export class ClaudeAgentTracer {
332342
id: runId,
333343
name: this.name,
334344
run_type: 'chain',
335-
inputs: {
336-
tools: initMsg.tools || [],
337-
model: initMsg.model,
338-
session_id: resolvedThreadId,
339-
mcp_servers: initMsg.mcp_servers,
340-
agents: initMsg.agents,
341-
slash_commands: initMsg.slash_commands,
342-
},
345+
inputs: {},
343346
outputs: undefined,
344347
start_time: startTime,
345348
end_time: undefined,
@@ -354,6 +357,12 @@ export class ClaudeAgentTracer {
354357
metadata: {
355358
thread_id: resolvedThreadId,
356359
},
360+
tools: initMsg.tools || [],
361+
model: initMsg.model,
362+
session_id: resolvedThreadId,
363+
mcp_servers: initMsg.mcp_servers,
364+
agents: initMsg.agents,
365+
slash_commands: initMsg.slash_commands,
357366
apiKeySource: initMsg.apiKeySource,
358367
claude_code_version: initMsg.claude_code_version,
359368
output_style: initMsg.output_style,
@@ -364,7 +373,7 @@ export class ClaudeAgentTracer {
364373

365374
/**
366375
* @internal
367-
* Create LLM run from assistant message (used by TraceSession)
376+
* Create LLM run from assistant message (used by Trace)
368377
*/
369378
createLLMRunInternal(
370379
msg: ClaudeMessage,
@@ -422,7 +431,7 @@ export class ClaudeAgentTracer {
422431

423432
/**
424433
* @internal
425-
* Create tool run at start (before result, used by TraceSession)
434+
* Create tool run at start (before result, used by Trace)
426435
*/
427436
createToolRunStartInternal(
428437
toolUseBlock: ClaudeContentBlock,
@@ -460,7 +469,7 @@ export class ClaudeAgentTracer {
460469

461470
/**
462471
* @internal
463-
* Complete tool run with result (used by TraceSession)
472+
* Complete tool run with result (used by Trace)
464473
*/
465474
completeToolRunInternal(toolRun: Run, toolResultBlock: ClaudeContentBlock, startTime: number): void {
466475
const result = toolResultBlock as any;
@@ -503,7 +512,7 @@ export class ClaudeAgentTracer {
503512

504513
/**
505514
* @internal
506-
* Create run cost from result message (used by TraceSession)
515+
* Create run cost from result message (used by Trace)
507516
*/
508517
createRunCostInternal(resultMsg: ClaudeMessage): IRunCost {
509518
const cost: IRunCost = resultMsg.usage ? this.extractTokenUsage(resultMsg.usage) : {};
@@ -517,7 +526,7 @@ export class ClaudeAgentTracer {
517526

518527
/**
519528
* @internal
520-
* Log trace - delegates to TracingService (used by TraceSession)
529+
* Log trace - delegates to TracingService (used by Trace)
521530
*/
522531
logTrace(run: Run, status: RunStatus): void {
523532
this.tracingService.logTrace(run, status, this.name, this.agentName);

core/agent-tracing/src/types.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,12 +132,14 @@ export const RunStatus = {
132132
} as const;
133133
export type RunStatus = (typeof RunStatus)[keyof typeof RunStatus];
134134

135-
/** Options for creating a new trace session. */
136-
export interface CreateSessionOptions {
135+
/** All context needed to create a trace for one agent execution. */
136+
export interface CreateTraceOptions {
137137
/** Server-side trace ID for linking to the request call chain. Defaults to a random UUID. */
138138
traceId?: string;
139-
/** Thread ID (Claude SDK session ID), recorded in metadata. */
139+
/** Thread ID (conversation/session identifier), recorded in metadata. */
140140
threadId?: string;
141+
/** Additional inputs to merge into root run's inputs (e.g. user messages). */
142+
inputs?: Record<string, any>;
141143
}
142144

143145
/** User-facing config passed to tracer.configure() */

0 commit comments

Comments
 (0)