@hmharness/kernel 0.5.3 → 0.5.4

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/dist/loop.js CHANGED
@@ -8,12 +8,16 @@
8
8
  * transcript is compacted against the context budget.
9
9
  */
10
10
  import { compactMessages, compactWithDigest, transcriptChars } from "./context.js";
11
- import { adaptiveContextChars } from "./window.js";
11
+ import { adaptiveContextChars, adaptiveMaxTurns } from "./window.js";
12
12
  import { chat } from "./provider.js";
13
13
  export async function runLoop(opts) {
14
14
  const { provider, registry, ctx, events } = opts;
15
15
  const modelCall = opts.chatImpl ?? chat;
16
- const maxTurns = opts.maxTurns ?? 25;
16
+ // Turn limit scales with the model's context window: 25 for small models,
17
+ // up to 80 for 1M-window models. The context compaction keeps the
18
+ // transcript within budget throughout, so the real ceiling is how many
19
+ // reasoning turns the model can sustain, not raw token count.
20
+ const maxTurns = opts.maxTurns ?? adaptiveMaxTurns(provider);
17
21
  const budget = opts.maxContextChars ?? adaptiveContextChars(provider);
18
22
  const working = [...opts.messages];
19
23
  let toolUses = 0;
@@ -108,7 +112,7 @@ export async function runLoop(opts) {
108
112
  });
109
113
  }
110
114
  }
111
- const text = `Turn budget exhausted (${maxTurns}). Last state preserved in the session log.`;
115
+ const text = `Turn limit reached (${maxTurns} turns). The session is preserved continue with "hmh resume" or just send another message to pick up where this left off.`;
112
116
  events?.onFinal?.(text, maxTurns);
113
117
  return { text, turns: maxTurns, toolUses, messages: working, usage };
114
118
  }
package/dist/window.d.ts CHANGED
@@ -38,3 +38,13 @@ export declare function adaptiveContextChars(p: {
38
38
  model: string;
39
39
  contextWindow?: number;
40
40
  }): number;
41
+ /** Adaptive turn limit: larger context windows sustain more turns before
42
+ * quality degrades (the context budget system compacts throughout, so the
43
+ * real ceiling is how many turns the model can reason over, not raw token
44
+ * count). Floor 25 (small models), cap 80 (even 1M windows don't need more).
45
+ * This fixes the "25 turns auto-stop" complaint — the context engineering
46
+ * was working fine, the turn cap was the bottleneck. */
47
+ export declare function adaptiveMaxTurns(p: {
48
+ model: string;
49
+ contextWindow?: number;
50
+ }): number;
package/dist/window.js CHANGED
@@ -45,3 +45,13 @@ export function contextBudgetChars(windowTokens) {
45
45
  export function adaptiveContextChars(p) {
46
46
  return contextBudgetChars(contextWindowFor(p).windowTokens);
47
47
  }
48
+ /** Adaptive turn limit: larger context windows sustain more turns before
49
+ * quality degrades (the context budget system compacts throughout, so the
50
+ * real ceiling is how many turns the model can reason over, not raw token
51
+ * count). Floor 25 (small models), cap 80 (even 1M windows don't need more).
52
+ * This fixes the "25 turns auto-stop" complaint — the context engineering
53
+ * was working fine, the turn cap was the bottleneck. */
54
+ export function adaptiveMaxTurns(p) {
55
+ const budget = contextBudgetChars(contextWindowFor(p).windowTokens);
56
+ return Math.max(25, Math.min(80, Math.floor(budget / 4000)));
57
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hmharness/kernel",
3
- "version": "0.5.3",
3
+ "version": "0.5.4",
4
4
  "description": "hmharness kernel: tool registry, provider adapters, the agent loop, session log, config. Zero runtime dependencies (Node >=22 native fetch).",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",