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
fix(orchestrator): Fix Claude context loss + infinite loops + double alternation
**Problem:**
Three critical bugs affecting agent workflow quality:
1. Claude models received only tool results without conversation history
2. Agents looped infinitely calling same tool
3. Double alternation merging lost tool results
**Root Causes:**
1. Delta mode sent only 4 internal messages when marker not found, instead of full 19-message history
2. 16KB payload limit trimmed tool results before reaching LLM
3. Message alternation happened twice (orchestrator + provider)
**Solutions:**
1. Added useDeltaMode flag - only enable delta when marker successfully found
2. Apply payload limit only to Claude models (32KB), preserve message pairs
3. Removed duplicate alternation from GitHubCopilotProvider
4. Disabled Claude batching for GitHub Copilot (proxy handles conversion)
**Testing:**
✅ Claude receives full conversation context
✅ No infinite tool loops
✅ Tool results reach LLM properly
✅ Task completion quality improved
✅ Reddit comments test: Complete analysis on first attempt
**Impact:**
- Claude 'memory loss' eliminated
- Agent workflow stability improved
- GitHub Copilot + Claude format conflicts resolved
- Better diagnostic logging for future debugging
Copy file name to clipboardExpand all lines: Resources/whats-new.json
+83Lines changed: 83 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -1,5 +1,88 @@
1
1
{
2
2
"releases": [
3
+
{
4
+
"version": "20260107.1",
5
+
"release_date": "January 7, 2026",
6
+
"introduction": "Critical release fixing Claude model context loss and infinite loops. This release resolves three major bugs affecting agent workflow quality: tool result trimming causing infinite loops, delta mode sending incomplete context to Claude, and duplicate message alternation losing tool results. Additionally fixes false 'no tools' warnings and improves workflow guidance.",
7
+
"highlights": [
8
+
{
9
+
"id": "claude-context-loss-fix",
10
+
"icon": "brain.fill",
11
+
"title": "Claude Context Loss Fixed",
12
+
"description": "Fixed critical bug where Claude models received only tool results without conversation history. When stateful marker wasn't found, delta mode incorrectly sent only 4 internal messages instead of full conversation history (e.g., 19 messages). Claude now receives complete context, eliminating 'this is the FIRST message' errors and memory issues."
"description": "Fixed infinite loop where agents repeatedly called the same tool. Root cause: 16KB payload limit was trimming tool results before they reached the LLM, causing the agent to retry endlessly. Payload limit now only applies to Claude models (32KB) and preserves message pairs together."
"title": "GitHub Copilot + Claude Format Handling",
24
+
"description": "Disabled Claude-specific tool result batching for GitHub Copilot provider. GitHub Copilot's API handles Claude conversion internally and expects OpenAI format. Only direct Anthropic provider uses batching, preventing format conflicts and alternation issues."
25
+
}
26
+
],
27
+
"bugfixes": [
28
+
{
29
+
"id": "delta-mode-context-loss",
30
+
"icon": "chevron.left.chevron.right",
31
+
"title": "Delta Mode Context Loss Fixed",
32
+
"description": "When stateful marker wasn't found in conversation, system logged 'sending full history' but still used delta-only mode. Added useDeltaMode flag that only enables delta mode when marker is successfully found, preventing context loss."
"description": "16KB payload limit was applied to ALL models, causing tool results to be trimmed before reaching the LLM. Now only enforced for Claude models (32KB limit) and improved trimming logic keeps message pairs together (assistant+toolcalls with corresponding tool_result)."
39
+
},
40
+
{
41
+
"id": "double-alternation-merging",
42
+
"icon": "arrow.left.arrow.right",
43
+
"title": "Double Message Alternation Eliminated",
44
+
"description": "Messages were being alternated/merged twice: once in AgentOrchestrator.ensureMessageAlternation() and again in GitHubCopilotProvider.enforceMessageAlternation(). Removed duplicate alternation from provider, keeping orchestrator version with better logging."
45
+
},
46
+
{
47
+
"id": "claude-batching-provider-specific",
48
+
"icon": "server.rack",
49
+
"title": "Claude Tool Batching Made Provider-Specific",
50
+
"description": "batchToolResultsForClaude now only runs for direct Anthropic provider (anthropic/*). GitHub Copilot provider (github_copilot/claude-*) skips batching since the proxy handles conversion internally, preventing marker burial in alternation."
51
+
},
52
+
{
53
+
"id": "workflow-guidance-improvement",
54
+
"icon": "text.quote",
55
+
"title": "Workflow Guidance Improved",
56
+
"description": "Changed aggressive guidance from 'If tool results contain enough information → RESPOND NOW' to 'ANALYZE the data to address the user's specific request. Complete that task with the data you have.' Encourages proper analysis instead of premature responses."
57
+
},
58
+
{
59
+
"id": "false-no-tools-warning",
60
+
"icon": "exclamationmark.triangle",
61
+
"title": "False 'No Tools' Warning Eliminated",
62
+
"description": "Fixed premature reset of lastIterationHadToolResults causing false 'Agent executed no tools in iteration X' warnings. System now correctly tracks tool execution state across iterations, only warning when genuinely stuck."
63
+
},
64
+
{
65
+
"id": "operation-deduplication",
66
+
"icon": "arrow.triangle.merge",
67
+
"title": "Web Operations Deduplication Added",
68
+
"description": "WebOperationsTool now prevents calling the same operation with identical parameters multiple times. Reduces wasted API calls and improves efficiency when agents retry unnecessarily."
"description": "Added detailed logging to ensureMessageAlternation showing input/output message arrays with roles, sizes, tool info, and each filtering/merging decision. Critical for debugging message transformation bugs."
75
+
}
76
+
],
77
+
"known_issues": [
78
+
{
79
+
"id": "mindmap-children-not-rendering",
80
+
"icon": "diagram.tree",
81
+
"title": "Mindmap Children Not Rendering",
82
+
"description": "Mindmap shows only root node. Children are parsed correctly but have layout/positioning issues preventing display. Recursive rendering exists but child nodes render outside visible frame bounds."
useDeltaMode =true /// Successfully sliced, use delta mode
4322
4337
logger.debug("STATEFUL_MARKER_SLICING: Using message count \(markerMessageCount), sending \(conversationMessages.count) messages after marker (delta-only mode with tool results)")
4323
4338
}
4324
4339
/// FALLBACK: Search for marker in messages (timing-dependent, may fail if message not persisted yet)
useDeltaMode =true /// Successfully found marker, use delta mode
4328
4344
logger.debug("STATEFUL_MARKER_SLICING: Found marker at index \(markerIndex), sending ONLY \(conversationMessages.count) messages after marker (delta-only mode, fallback method)")
4329
4345
}else{
4330
-
logger.warning("STATEFUL_MARKER_WARNING: Marker \(marker.prefix(20))... not found in conversation AND no message count available, sending full history (\(conversationMessages.count) messages)")
4346
+
/// CRITICAL: Marker not found - cannot use delta mode safely!
4347
+
/// Send FULL conversation history to prevent context loss
4348
+
useDeltaMode =false /// Force full history mode
4349
+
logger.warning("STATEFUL_MARKER_WARNING: Marker \(marker.prefix(20))... not found in conversation AND no message count available, FORCING FULL HISTORY MODE (safety fallback)")
4331
4350
}
4332
4351
}elseif statefulMarker !=nil && !hasToolResults {
4333
4352
/// Subsequent user message scenario: statefulMarker exists but no tool results yet
4334
4353
/// Do NOT slice conversation history - user needs full context for their new message!
4354
+
useDeltaMode =false /// Full history needed for user message
4335
4355
logger.debug("SUBSEQUENT_USER_MESSAGE: StatefulMarker exists but no tool results - sending FULL conversation history (\(conversationMessages.count) messages) for user context")
4336
4356
}else{
4357
+
useDeltaMode =false /// No marker, send full history
4337
4358
logger.debug("INFO: No statefulMarker, sending all \(conversationMessages.count) conversation messages")
4338
4359
}
4339
4360
4340
-
/// When statefulMarker exists, send ONLY internalMessages (delta-only mode)
4361
+
/// When delta mode is enabled, send ONLY internalMessages (delta-only mode)
4362
+
/// When delta mode is disabled, send conversationMessages + internalMessages (full history)
4341
4363
/// This prevents duplicate assistant messages that cause Claude 400 errors
4342
4364
/// ROOT CAUSE: Assistant responses are in BOTH conversation.messages AND internalMessages
4343
4365
/// GitHub Copilot approach: With statefulMarker, only send NEW messages (delta)
4344
4366
/// Our approach: internalMessages IS the delta (tool calls + results from previous iteration)
4345
4367
/// Do NOT inject "Please continue" into messages array
4346
4368
/// GitHub Copilot API: "Please continue" is query param only, NOT a synthetic message
4347
4369
varcurrentMarker= statefulMarker /// Make mutable copy
4348
-
iflet marker = currentMarker, hasToolResults {
4370
+
ifuseDeltaMode && hasToolResults {
4349
4371
/// Delta-only mode: Server has full history up to marker, only send new tool execution context
4350
4372
/// The stateful marker tells the API to continue from the previous response
4351
4373
/// We send ONLY the tool results (delta), not the full conversation history
@@ -4497,12 +4519,21 @@ public class AgentOrchestrator: ObservableObject, IterationController {
4497
4519
4498
4520
logger.debug("callLLMStreaming: Built complete message array with \(messages.count) messages (before alternation fix)")
4499
4521
4500
-
/// CRITICAL: For Claude models, batch consecutive tool results into single user messages
4522
+
/// CRITICAL: For Claude models via DIRECT Anthropic provider, batch consecutive tool results
4501
4523
/// Claude Messages API requires ALL tool results from one iteration in ONE user message
4502
4524
/// This fixes the tool result batching issue that caused workflow loops
4503
-
if modelLower.contains("claude"){
4525
+
///
4526
+
/// IMPORTANT: Do NOT batch for GitHub Copilot + Claude!
4527
+
/// GitHub Copilot's API handles Claude conversion internally and expects OpenAI format
4528
+
/// Batching causes the marker to be buried in alternation merging
0 commit comments