Skip to content

(fix) cap emergency nudge injections per user turn (closes #108) - #119

Open
ranxianglei wants to merge 2 commits into
Tyan66666:mainfrom
ranxianglei:2026-09-06_issue108-emergency-nudge-cap
Open

(fix) cap emergency nudge injections per user turn (closes #108)#119
ranxianglei wants to merge 2 commits into
Tyan66666:mainfrom
ranxianglei:2026-09-06_issue108-emergency-nudge-cap

Conversation

@ranxianglei

@ranxianglei ranxianglei commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Closes #108.

Problem

When context pressure stays above the emergency threshold (engine default 0.85), every agent step re-injects a full emergency nudge, and each nudge is appended as a durable user/message event. If the pressure does not come down (the model no-ops, picks the wrong range, or the content is protected), the nudge's own tokens push usage even higher — a positive feedback loop that never stops. billion-context-pi hit the same failure mode (#223: retry prompt re-injected ~400×/hour, eventually removed) and fixed it with a per-user-turn cap (commit 414acd1).

Cause

src/nudge.ts dedups only normal nudges per user turn (lastNudgeTurn); the emergency path bypassed the dedup entirely (!emergency && …). No attempt counter, cap, or cooldown existed anywhere in the repo.

Fix

  • EMERGENCY_NUDGE_MAX_PER_TURN = 3 (hardcoded — a safety mechanism, not a tuning knob): emergency nudges are capped at 3 injections per user turn, tracked in a per-session emergencyNudges map ({ turn, count }). The budget resets when the user turn advances (same semantics as the normal dedup).
  • Normal nudges are unchanged: still at most one per user turn, and a normal nudge does NOT consume the emergency budget.
  • When the kernel still wants an emergency nudge but the budget is spent, the engine logs a warn (emergency nudge suppressed — per-turn budget of 3 spent …) so operators can see WHY the model stops receiving nudges (issue [compression] emergency nudge 无上限逐 step 重注入,且缺少 compress attempt 断路器 #108 review).
  • Docs updated in the same PR: README zh/en config table, config comments, AGENTS.md module map.

Scope note: this PR implements proposal #1 from the issue (the per-turn cap), which bounds the unbounded re-injection loop — the token-leak part. The compress-attempt circuit breaker (proposals #2/#3) is a follow-up; the kernel-side minPressureBenefit gate lands with the acp-kernel ≥0.0.54 bump planned in #116.

Review follow-up (2026-09-08)

Applied from the review on #108:

  • Cap regression test rewritten with explicit per-call assertions: calls 1–3 inject, call 4 returns null, later calls stay null; the cap-hit hook fires for every suppressed call.
  • New test: the cap resets on a new user turn.
  • New test: same-turn normal + emergency mix — a normal nudge does not consume the emergency budget.
  • logger.warn on cap hit (in the agent/pre-step handler, src/index.ts).
  • Cap stays hardcoded at 3 (not exposed as a config knob).
  • Branch rebased onto current main (v0.2.21 + e2e harness); no dist/ changes carried — per the current policy the dist-bot refreshes main after the merge.
  • Title renamed to the (fix) … form required by the pr-title CI check (the old fix(nudge): … form fails scripts/check-pr-title.mjs).

Verification

@ranxianglei

Copy link
Copy Markdown
Contributor Author

我来协助看一下这个问题,请分析并回复处理结果。

ework-agent added 2 commits September 8, 2026 20:20
…66666#108)

An unrelieved >= emergencyThreshold pressure re-injected a durable emergency
nudge on EVERY agent/pre-step (each appended as a user/message event), and the
nudge's own tokens pushed usage higher -> a runaway positive-feedback loop that
never stops because no-op compress calls are not terminal.

Cap emergency nudges at EMERGENCY_NUDGE_MAX_PER_TURN (3) per user turn; normal-
pressure nudges remain once-per-turn (behavior unchanged). Mirrors
billion-context-pi commit 414acd1. Adds a regression test asserting the cap
bounds re-injection (an uncapped kernel emits an emergency nudge on every step).

Note: the new per-session emergencyNudges map follows the existing lastNudgeTurn
pattern; broader per-session Map cleanup is tracked in Tyan66666#113.

<!-- ework-agent-pr -->
…ap-hit log, docs sync

- Rewrite the cap regression test with explicit per-call assertions: calls 1-3 inject, the 4th returns null, later calls stay null; assert the cap-hit hook fires for every suppressed call
- New tests: the cap resets on a new user turn; a normal nudge does not consume the emergency budget (same-turn mixed pressure)
- buildNudge takes an optional onEmergencyCapHit callback; the engine logs a warn when the per-turn emergency budget is spent, so operators can see why the model stops receiving nudges (issue Tyan66666#108 review)
- Docs sync: README zh/en config table, config comments, AGENTS.md module map
- Cap stays hardcoded at 3 (a safety mechanism, not a tuning knob — per review)
@ranxianglei
ranxianglei force-pushed the 2026-09-06_issue108-emergency-nudge-cap branch from eecbd76 to 52438ce Compare September 8, 2026 12:32
@ranxianglei ranxianglei changed the title fix(nudge): cap emergency nudge injections per user turn (closes #108) (fix) cap emergency nudge injections per user turn (closes #108) Sep 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[compression] emergency nudge 无上限逐 step 重注入,且缺少 compress attempt 断路器

1 participant