code-yeongyu / code-yeongyu/senpi

Extension-triggered turns bypass before_agent_start, so proactive compaction never runs in goal/wake-driven sessions

Open
#1,329 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
429
Forks
98
Avg merge
5h 3m
Merged PRs (30d)
526

Description

## Summary

Turns started by extensions through `pi.sendMessage(..., { triggerTurn: true })` never emit `before_agent_start`, so the compaction extension's proactive machinery in `packages/coding-agent/src/core/extensions/builtin/compaction/index.ts` (`threshold_trigger`, speculative warm-up, `hard_limit_trigger` valve, token-budget reminder) does not run for them. Only the core `_enforceCompactionBeforeProvider(..., "pre_prompt")` gate (`window - reserveTokens`) and idle compaction remain.

## Where

`packages/coding-agent/src/core/agent-session.ts` `sendCustomMessage()` (the `options?.triggerTurn` branch on an idle session):

```ts
await this._enforceCompactionBeforeProvider(this._findLastAssistantMessage(), false, "pre_prompt");
await this._enforceFinalProviderAdmission([appMessage]);
...
await this._promptAgent(appMessage, deferredTurnClaim);
```

The user-prompt path in `prompt()` calls `this._extensionRunner.emitBeforeAgentStart(...)` between those steps; this path does not.

## Evidence

Session `01a06520` (2026-09-03, omo-senpi ulw run on anthropic/claude-fable-5-1, 1M window): 5 user prompts vs 35 `goal-continuation` + 40 `omo-senpi:wake` extension-triggered turns. The context grew 108K -> 996K over 8 h. `~/.omo/agent/logs/compaction.log` has no `threshold_trigger` / `speculative_started` / `hard_limit_trigger` attributable to that session even after the estimate passed both the 80% adaptive threshold (~09:00Z) and the hard-limit line (`window - 40,000`, from 10:42Z). In that session auto-compaction was also disabled in settings, which explains the core gate staying silent, but the extension's hard-limit valve does not check `settings.enabled` and still never fired: the only prompt-shaped entry points in that window were goal continuations, and they bypass `before_agent_start`.

Consequence for goal-driven / wake-driven sessions (the norm under ulw-loop): compaction is emergency-only (core pre_prompt gate at ~98% of the window) instead of proactive at 80%, and speculative warm summaries are never produced.

## Suggested direction

Either emit `before_agent_start` (or a dedicated `before_turn_start`) for extension-triggered turns so the compaction extension sees them, or move the proactive checks to a hook that every turn passes through (e.g. the `context` event already runs per request but is read-only for compaction). Related: with `compaction.enabled: false` nothing warns the user as the window fills; the footer percentage is the only signal. #1328 stops the doomed `max_tokens=1` requests at the wall but does not restore proactive compaction for these turns.

Contributor guide

Open the contributing guide

Research direction

Compare the triggerTurn branch in packages/coding-agent/src/core/agent-session.ts sendCustomMessage() with prompt(), focusing on where before_agent_start is emitted. Read the compaction hooks in packages/coding-agent/src/core/extensions/builtin/compaction/index.ts and verify that extension-triggered turns run the proactive checks, including threshold, speculative warm-up, hard-limit, and token-budget behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
ai-infra-agents, cli
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.