@aion0/forge 0.10.29 → 0.10.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/RELEASE_NOTES.md CHANGED
@@ -1,20 +1,13 @@
1
- # Forge v0.10.29
1
+ # Forge v0.10.30
2
2
 
3
3
  Released: 2026-06-02
4
4
 
5
- ## Changes since v0.10.28
5
+ ## Changes since v0.10.29
6
6
 
7
7
  ### Other
8
- - feat(ssh): template-expand spec.timeout_sec — lets tools surface as arg
9
- - fix(help-content): drop import.meta.url branch Turbopack rejects webpackIgnore
10
- - fix(help-content): suppress Turbopack 'cannot resolve ./help-docs' warning
11
- - fix(http): empty-string body resolves to no-body
12
- - fix(http-auth): bearer-token-exchange honours connector http.verify_tls
13
- - feat(connector-test): add body_match regex for response-body validation
14
- - fix(http): reorder method-template expand to AFTER argsWithDefaults
15
- - fix(http): expand templates in spec.method before uppercase
16
- - docs(connector-authoring): add bearer-token-exchange section to 21-build-connector
17
- - feat(http-auth): bearer-token-exchange supports body-mode + bare format
8
+ - fix(chat): tune MAX_ITERATIONS 50→24
9
+ - fix(chat): raise MAX_ITERATIONS 12→50 for complex multi-step tasks
10
+ - fix(chat): raise MAX_ITERATIONS 6→12 + emit sentinel when cap hit
18
11
 
19
12
 
20
- **Full Changelog**: https://github.com/aiwatching/forge/compare/v0.10.28...v0.10.29
13
+ **Full Changelog**: https://github.com/aiwatching/forge/compare/v0.10.29...v0.10.30
@@ -41,7 +41,11 @@ import type {
41
41
  ToolUseBlock,
42
42
  } from './types';
43
43
 
44
- const MAX_ITERATIONS = 6;
44
+ // Set to 24: enough headroom for typical multi-step tool chains
45
+ // (search → paginate → drill → summarise can be 8-15; complex audits
46
+ // 15-20) without inviting runaway loops. Hitting it surfaces the
47
+ // sentinel message below so the user knows why the turn stopped.
48
+ const MAX_ITERATIONS = 24;
45
49
  const MAX_TOKENS = 16000;
46
50
  // Working-window budgets for the LLM history. Capped by message count
47
51
  // AND by token estimate (whichever hits first), see design §8. Older
@@ -596,6 +600,23 @@ export async function runTurn(args: RunTurnArgs): Promise<{ ok: boolean; error?:
596
600
  cb({ type: 'message_saved', message_id: toolResultMsg.id, data: toolResultMsg });
597
601
  }
598
602
 
603
+ // If we fell out of the while because we hit MAX_ITERATIONS (vs the
604
+ // model emitting a non-tool_use stopReason), the turn ends with no
605
+ // closing assistant text and the user sees a "no response" hang.
606
+ // Surface a sentinel assistant message so the cause is visible.
607
+ if (iter >= MAX_ITERATIONS && lastStop === 'tool_use') {
608
+ const sentinel = appendMessage({
609
+ session_id: args.sessionId,
610
+ role: 'assistant',
611
+ blocks: [{
612
+ type: 'text',
613
+ text: `⚠️ Hit the tool-call iteration limit (${MAX_ITERATIONS}) without finishing. Likely causes: a tool kept returning truncated/incomplete results so I kept retrying, or the task was too broad. Try narrowing the query or splitting it into smaller asks.`,
614
+ }],
615
+ });
616
+ cb({ type: 'message_saved', message_id: sentinel.id, data: sentinel });
617
+ cb({ type: 'error', data: { error: `iteration limit (${MAX_ITERATIONS}) exceeded` } });
618
+ }
619
+
599
620
  cb({ type: 'turn_done', data: { iterations: iter, stop_reason: lastStop } });
600
621
  return { ok: true };
601
622
  } catch (err) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aion0/forge",
3
- "version": "0.10.29",
3
+ "version": "0.10.30",
4
4
  "description": "Unified AI workflow platform — multi-model task orchestration, persistent sessions, web terminal, remote access",
5
5
  "type": "module",
6
6
  "scripts": {