You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
π€ Skip [CONTINUE] sentinel when user message follows (#176)
## Problem
Currently we always add the `[CONTINUE]` sentinel after partial
messages:
```
[user1] β [partial assistant] β [CONTINUE] β [user2]
```
But when a user message already follows the partial, the sentinel is
**redundant** - the user message itself provides the continuation
signal.
## Solution
**Conditionally skip the sentinel when unnecessary:**
```typescript
// Before: Always add sentinel
[user] β [partial] β [CONTINUE] β [user] β ...
// After: Only add when needed
[user] β [partial] β [user] β ... // Skip - user follows
[user] β [partial] β [CONTINUE] // Keep - last message
[user] β [partial] β [CONTINUE] β [assistant] // Keep - assistant follows
```
**Implementation:**
```typescript
if (msg.role === "assistant" && msg.metadata?.partial) {
const nextMsg = messages[i + 1];
// Only add sentinel if NO user message follows
if (!nextMsg || nextMsg.role !== "user") {
result.push(createSentinel());
}
}
```
## Benefits
- β **Saves tokens** - One fewer message per resume-with-user-message
(common case!)
- β **More natural** - Models handle "user interrupts then continues"
well
- β **Cleaner history** - No redundant synthetic messages
- β **Stateless logic** - Just looks at message array structure
## When Sentinel Is Added
- Partial is **last message** (empty resume)
- Partial followed by **assistant message** (rare but possible)
## When Sentinel Is Skipped
- Partial followed by **user message** (most common!)
- User interrupts stream and adds follow-up
- This is the typical resume pattern
## Testing
**Updated tests:**
- β Multi-partial test now expects 5 messages (not 6)
- β New test specifically for skip-sentinel behavior
- β All 298 unit tests pass
**Test coverage:**
1. Sentinel added when partial is last message β
2. Sentinel skipped when user follows partial β
3. No synthetic messages when sentinel skipped β
## Risk Assessment
**Very low risk:**
- Only affects case where sentinel was already redundant
- Models naturally understand "user continues conversation"
- Existing behavior unchanged for empty resumes
- Stateless transform, no history dependencies
## Related
Builds on #170 which changed sentinel text from `[INTERRUPTED]` to
`[CONTINUE]`.
_Generated with `cmux`_
0 commit comments