Skip to content

Commit e463c95

Browse files
committed
Version bump 1.0.68 (build 156) + iteration cap enforcement
1 parent be60b11 commit e463c95

3 files changed

Lines changed: 46 additions & 4 deletions

File tree

Agent.xcodeproj/project.pbxproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1499,7 +1499,7 @@
14991499
CODE_SIGN_IDENTITY = "Apple Development";
15001500
CODE_SIGN_STYLE = Automatic;
15011501
COMBINE_HIDPI_IMAGES = YES;
1502-
CURRENT_PROJECT_VERSION = 155;
1502+
CURRENT_PROJECT_VERSION = 156;
15031503
DEAD_CODE_STRIPPING = YES;
15041504
DEVELOPMENT_TEAM = 469UCUB275;
15051505
ENABLE_APP_SANDBOX = NO;
@@ -1553,7 +1553,7 @@
15531553
"@executable_path/../Frameworks",
15541554
);
15551555
MACOSX_DEPLOYMENT_TARGET = 26.4;
1556-
MARKETING_VERSION = 1.0.67;
1556+
MARKETING_VERSION = 1.0.68;
15571557
PRODUCT_BUNDLE_IDENTIFIER = Agent.app.toddbruss;
15581558
PRODUCT_NAME = "$(TARGET_NAME)";
15591559
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -1578,7 +1578,7 @@
15781578
CODE_SIGN_IDENTITY = "Apple Development";
15791579
CODE_SIGN_STYLE = Automatic;
15801580
COMBINE_HIDPI_IMAGES = YES;
1581-
CURRENT_PROJECT_VERSION = 155;
1581+
CURRENT_PROJECT_VERSION = 156;
15821582
DEAD_CODE_STRIPPING = YES;
15831583
DEVELOPMENT_TEAM = 469UCUB275;
15841584
ENABLE_APP_SANDBOX = NO;
@@ -1632,7 +1632,7 @@
16321632
"@executable_path/../Frameworks",
16331633
);
16341634
MACOSX_DEPLOYMENT_TARGET = 26.4;
1635-
MARKETING_VERSION = 1.0.67;
1635+
MARKETING_VERSION = 1.0.68;
16361636
PRODUCT_BUNDLE_IDENTIFIER = Agent.app.toddbruss;
16371637
PRODUCT_NAME = "$(TARGET_NAME)";
16381638
PROVISIONING_PROFILE_SPECIFIER = "";

Agent/AgentViewModel/TabTask/TabTask.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,26 @@ extension AgentViewModel {
181181
mainLoop: while !Task.isCancelled {
182182
iterations += 1
183183

184+
// Iteration cap — force task_complete when the LLM refuses to end.
185+
if iterations == maxIterations {
186+
tab.appendLog("⏱ Iteration \(iterations)/\(maxIterations) — nudging LLM to call task_complete")
187+
tab.flush()
188+
messages.append([
189+
"role": "user",
190+
"content": "You have reached the iteration limit. Call task_complete with a summary of what you accomplished on your next turn. This is your last chance — no more tool calls."
191+
])
192+
}
193+
if iterations > maxIterations {
194+
let summary = completionSummary.isEmpty
195+
? (commandsRun.isEmpty ? "(no actions — iteration cap reached)" : "Forced completion after \(iterations - 1) iterations. Last actions: \(commandsRun.suffix(5).joined(separator: ", "))")
196+
: completionSummary
197+
completionSummary = summary
198+
tab.appendLog("⏱ Forced task_complete — hit iteration cap (\(maxIterations))")
199+
tab.appendLog("✅ Completed: \(summary)")
200+
tab.flush()
201+
break mainLoop
202+
}
203+
184204
// Mode auto-switching removed: every user-enabled tool is available on
185205
// every turn. ToolPreferencesService UI toggles are the only filter.
186206

Agent/AgentViewModel/TaskExecution/TaskExecution.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,28 @@ extension AgentViewModel {
174174
taskLoop: while !Task.isCancelled {
175175
iterations += 1
176176

177+
// Iteration cap — the LLM can loop forever calling tools without ever
178+
// invoking task_complete (common with smaller/local models). Enforce a
179+
// hard stop one turn after a "wrap up" nudge.
180+
if iterations == maxIterations {
181+
appendLog("⏱ Iteration \(iterations)/\(maxIterations) — nudging LLM to call task_complete")
182+
flushLog()
183+
messages.append([
184+
"role": "user",
185+
"content": "You have reached the iteration limit. Call task_complete with a summary of what you accomplished on your next turn. This is your last chance — no more tool calls."
186+
])
187+
}
188+
if iterations > maxIterations {
189+
let summary = completionSummary.isEmpty
190+
? (commandsRun.isEmpty ? "(no actions — iteration cap reached)" : "Forced completion after \(iterations - 1) iterations. Last actions: \(commandsRun.suffix(5).joined(separator: ", "))")
191+
: completionSummary
192+
completionSummary = summary
193+
appendLog("⏱ Forced task_complete — hit iteration cap (\(maxIterations))")
194+
appendLog("✅ Completed: \(summary)")
195+
flushLog()
196+
break taskLoop
197+
}
198+
177199
// No prompt tiering and no mode auto-switching: every turn sends the full system prompt with full tool
178200
// descriptions, filtered only by the user's UI toggles in ToolPreferencesService.
179201

0 commit comments

Comments
 (0)