You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(sampling): require JSON responses and log model/role
Add model and role fields to LLMResponse and capture stopReason for better observability.
Initialize conversationHistory with an initial user prompt that enforces returning raw JSON
(Claude requirement) and ensures at least one message. Increase maxTokens to 55_000 to allow
larger responses. Implement minimal self-healing: when parsed responses lack required
fields (action or decision), re-prompt for JSON-only output and continue the loop.
Pass model, role, and stopReason into logIterationProgress and record them on iteration
spans (including stopReason when present). Also add a default user message for the summary
call. These changes improve robustness against malformed LLM outputs and surface model
metadata for debugging and tracing.
@@ -95,8 +97,16 @@ export abstract class BaseSamplingExecutor {
95
97
schema: Record<string,unknown>,
96
98
state?: TState,
97
99
){
98
-
// Initialize conversation
99
-
this.conversationHistory=[];
100
+
// Initialize conversation with an initial user message
101
+
// Ensure at least one message (Claude requirement) and enforce JSON-only output
102
+
this.conversationHistory=[{
103
+
role: "user",
104
+
content: {
105
+
type: "text",
106
+
text:
107
+
'Return ONLY raw JSON (no code fences or explanations). The JSON MUST include action and decision. Example: {"action":"<tool>","decision":"proceed|complete","<tool>":{}}',
108
+
},
109
+
}];
100
110
101
111
// Create a root span for the entire sampling loop
102
112
constloopSpan: Span|null=this.tracingEnabled
@@ -133,10 +143,13 @@ export abstract class BaseSamplingExecutor {
'Required fields missing: action or decision. Return ONLY raw JSON, no code fences or explanations. Example: {"action":"<tool>","decision":"proceed|complete","<tool>":{}}',
208
+
},
209
+
});
210
+
if(iterationSpan)endSpan(iterationSpan);
211
+
continue;
212
+
}
213
+
187
214
// Process the parsed data using subclass implementation
188
215
constresult=awaitthis.processAction(
189
216
parsedData,
190
217
schema,
191
218
state,
192
219
loopSpan,
193
220
);
194
-
this.logIterationProgress(parsedData,result);
221
+
this.logIterationProgress(
222
+
parsedData,
223
+
result,
224
+
model,
225
+
stopReason,
226
+
role,
227
+
);
195
228
196
229
if(iterationSpan){
197
230
// Simplified: store full raw JSON, raw LLM response, and full tool result if present (no truncation)
@@ -210,7 +243,12 @@ export abstract class BaseSamplingExecutor {
0 commit comments