@@ -122,21 +122,7 @@ export abstract class BaseSamplingExecutor {
122122 this . currentIteration < this . maxIterations ;
123123 this . currentIteration ++
124124 ) {
125- // Create a span for each iteration
126- const iterationSpan : Span | null = this . tracingEnabled
127- ? startSpan (
128- "mcpc.sampling_iteration" ,
129- {
130- iteration : this . currentIteration + 1 ,
131- agent : this . name ,
132- systemPrompt : systemPrompt ( ) ,
133- maxTokens : String ( Number . MAX_SAFE_INTEGER ) ,
134- maxIterations : this . maxIterations ,
135- messages : JSON . stringify ( this . conversationHistory ) ,
136- } ,
137- loopSpan ?? undefined ,
138- )
139- : null ;
125+ let iterationSpan : Span | null = null ;
140126
141127 try {
142128 const response = await this . server . createMessage ( {
@@ -155,11 +141,20 @@ export abstract class BaseSamplingExecutor {
155141 try {
156142 parsedData = parseJSON ( responseContent . trim ( ) , true ) ;
157143 } catch ( parseError ) {
158- if ( iterationSpan ) {
159- iterationSpan . addEvent ( "parse_error" , {
160- error : String ( parseError ) ,
161- } ) ;
162- }
144+ // Create span for parse error iteration
145+ iterationSpan = this . tracingEnabled
146+ ? startSpan (
147+ "mcpc.sampling_iteration.parse_error" ,
148+ {
149+ iteration : this . currentIteration + 1 ,
150+ agent : this . name ,
151+ error : String ( parseError ) ,
152+ maxIterations : this . maxIterations ,
153+ } ,
154+ loopSpan ?? undefined ,
155+ )
156+ : null ;
157+
163158 this . addParsingErrorToHistory ( responseContent , parseError ) ;
164159 if ( iterationSpan ) endSpan ( iterationSpan ) ;
165160 continue ;
@@ -177,24 +172,27 @@ export abstract class BaseSamplingExecutor {
177172
178173 const action = parsedData [ "action" ] ;
179174
180- // If an action name is present, record it as an attribute on the iteration span for easier tracing/debugging.
181- if ( action && typeof action === "string" ) {
182- // Update the span name to include the action for clearer traces.
183- try {
184- const safeAction = String ( action ) . replace ( / \s + / g, "_" ) ;
185- // updateName is part of the OpenTelemetry Span API
186- if (
187- iterationSpan &&
188- typeof ( iterationSpan as any ) . updateName === "function"
189- ) {
190- ( iterationSpan as any ) . updateName (
191- `mcpc.sampling_iteration.${ safeAction } ` ,
192- ) ;
193- }
194- } catch {
195- // Ignore any errors while updating span name
196- }
197- }
175+ // Create span with action name
176+ const actionStr = action && typeof action === "string"
177+ ? String ( action )
178+ : "unknown_action" ;
179+ const spanName = `mcpc.sampling_iteration.${ actionStr } ` ;
180+
181+ iterationSpan = this . tracingEnabled
182+ ? startSpan (
183+ spanName ,
184+ {
185+ iteration : this . currentIteration + 1 ,
186+ agent : this . name ,
187+ action : actionStr ,
188+ systemPrompt : systemPrompt ( ) ,
189+ maxTokens : String ( Number . MAX_SAFE_INTEGER ) ,
190+ maxIterations : this . maxIterations ,
191+ messages : JSON . stringify ( this . conversationHistory ) ,
192+ } ,
193+ loopSpan ?? undefined ,
194+ )
195+ : null ;
198196
199197 // Minimal self-healing: ensure required fields exist
200198 if ( ! action || typeof parsedData [ "decision" ] !== "string" ) {
0 commit comments