Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/__tests__/bugfixes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,27 @@ describe('Agent loop continuation nudge', () => {
expect(analyzeContinuationIntent("Here is the code:\n```typescript\nfunction test() {").shouldNudge).toBe(true)
})

test('non-Claude continuation verbs and mid-text completion markers (issue #1707)', async () => {
const { analyzeContinuationIntent } = await import('../utils/continuation.js')

// Mid-text completion marker must NOT suppress a later continuation intent.
// The completion-marker guard now only inspects the final sentence.
expect(analyzeContinuationIntent("The download is complete. Now I will install the dependencies").shouldNudge).toBe(true)
expect(analyzeContinuationIntent("Step one finished. I will now deploy the service").shouldNudge).toBe(true)

// Action verbs common to non-Claude models, gated behind intent framing.
expect(analyzeContinuationIntent("Let me compile the project").shouldNudge).toBe(true)
expect(analyzeContinuationIntent("I will now train the model").shouldNudge).toBe(true)

// Unpunctuated present-progressive action reads as in-progress work.
expect(analyzeContinuationIntent("Now downloading the dataset").shouldNudge).toBe(true)

// A genuinely completed message whose LAST sentence is a completion marker
// must still be suppressed, even if an action gerund appears earlier.
expect(analyzeContinuationIntent("Finished installing the packages. All set.").shouldNudge).toBe(false)
expect(analyzeContinuationIntent("Downloaded the files and the migration is complete.").shouldNudge).toBe(false)
})

test('nudge creates a meta user message to continue', async () => {
const content = await file('query.ts').text()

Expand Down
16 changes: 15 additions & 1 deletion src/utils/continuation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@ export const CONTINUATION_SIGNALS = [
/\blet me (go ahead and |now )?(do|create|write|edit|update|fix|implement|add|run|check|make|build|set up|proceed|start|begin|apply|update|create|identify|inspect|analyze|review|search|summarize)\b/i,
/\btime to (do|create|write|edit|update|fix|implement|add|run|check|make|build|get started|begin|start|inspect|analyze|review|search)\b/i,
/\b(moving on to|next step is to|starting to|proceeding to|applying (the|these) changes|inspecting|analyzing|reviewing|searching)\b/i,
// English: Action verbs common to non-Claude models, gated behind explicit
// first-person intent framing so they only fire as a continuation signal
// (e.g. "I will now deploy the service", "Let me install the deps").
/\b(i (will|'ll|shall|need to|have to|must|should|am going to|am about to)( now)?|let me( now)?|now i('ll| will)?)\s+(process|download|upload|compile|train|evaluate|extract|merge|deploy|install|configure|optimize|refactor|generate|fetch|validate|parse|scan|test)\b/i,
// English: Present-progressive action statements signal in-progress work.
// These intentionally do NOT override terminal punctuation downstream, so a
// punctuated completion ("Finished installing.") is still caught by the
// completion-marker guard; only an unpunctuated/truncated action nudges.
/\b(processing|downloading|uploading|compiling|training|evaluating|extracting|merging|deploying|installing|configuring|optimizing|refactoring|generating|fetching|validating|parsing|scanning)\b/i,
// French: Support for common continuation phrasing (relaxed boundaries for accents and apostrophes)
/(^|\s)(je passe (à|au)|ensuite|l'étape suivante est de|je continue avec|au suivant|passons à|je reviens vers vous|je suis en train d'|je vais maintenant)(\s|$|[a-zà-ÿ])/i,
/(^|\s)(je (vais|dois|dois maintenant|vais maintenant) (faire|créer|écrire|modifier|ajouter|tester|vérifier|lancer|exécuter|procéder|démarrer|commencer|identifier|analyser|inspecter|revoir|chercher))(\s|$|[a-zà-ÿ])/i,
Expand Down Expand Up @@ -111,7 +120,12 @@ export function analyzeContinuationIntent(
}

// 3. Completion Marker Guard (Final check for sound, completed messages)
if (COMPLETION_MARKERS.test(lowerText)) {
// Only treat a completion marker as terminal when it appears in the LAST
// sentence. A marker buried mid-text ("The download is complete. Now
// installing the deps") must not suppress a later continuation intent —
// this is the common failure mode for non-Claude models (#1707).
const lastSentence = lowerText.split(/(?<=[.!?])\s+/).pop() ?? lowerText
if (COMPLETION_MARKERS.test(lastSentence)) {
return { shouldNudge: false }
}

Expand Down