@dreb/coding-agent 2.32.1 → 2.33.0
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/README.md +2 -0
- package/dist/core/agent-session.d.ts +14 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +59 -8
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/settings-manager.d.ts +18 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +22 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +7 -0
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/docs/settings.md +20 -0
- package/package.json +1 -1
|
@@ -34,6 +34,7 @@ import { expandPromptTemplate } from "./prompt-templates.js";
|
|
|
34
34
|
import { scrubSecrets } from "./secret-scrubber.js";
|
|
35
35
|
import { isSensitivePath } from "./sensitive-paths.js";
|
|
36
36
|
import { CURRENT_SESSION_VERSION, getLatestCompactionEntry } from "./session-manager.js";
|
|
37
|
+
import { DEFAULT_BG_PARENT_TURN_LIMIT } from "./settings-manager.js";
|
|
37
38
|
import { createSyntheticSourceInfo } from "./source-info.js";
|
|
38
39
|
import { buildSystemPrompt } from "./system-prompt.js";
|
|
39
40
|
import { resolveThinkingDisplay } from "./thinking.js";
|
|
@@ -127,10 +128,14 @@ export class AgentSession {
|
|
|
127
128
|
_modelRegistry;
|
|
128
129
|
// Session tasks (in-memory, lost on session end)
|
|
129
130
|
_tasks = [];
|
|
130
|
-
// Background agent turn limiter (Layer D): counts LLM turns while bg agents
|
|
131
|
+
// Background agent turn limiter (Layer D): counts LLM turns that started while bg agents were running.
|
|
131
132
|
// Reset when a bg agent delivers results. No limit when no bg agents are active.
|
|
133
|
+
// BG_TURN_LIMIT is the default cap; users can retune or disable it via
|
|
134
|
+
// settings (backgroundAgents.parentTurnLimit / parentTurnGuardrail).
|
|
132
135
|
_bgTurnCounter = 0;
|
|
133
|
-
|
|
136
|
+
_bgRunningAtTurnStart = false;
|
|
137
|
+
_bgPauseNotified = false;
|
|
138
|
+
static BG_TURN_LIMIT = DEFAULT_BG_PARENT_TURN_LIMIT;
|
|
134
139
|
// Sentinel monitor state (Layer B): tracks whether we've already steered for this streaming response
|
|
135
140
|
_sentinelSteered = false;
|
|
136
141
|
// Guardrail unsubscribe functions (must be cleaned up on dispose)
|
|
@@ -426,30 +431,76 @@ export class AgentSession {
|
|
|
426
431
|
}
|
|
427
432
|
});
|
|
428
433
|
// Layer D: Turn limiter — cap parent turns while bg agents are running.
|
|
429
|
-
//
|
|
434
|
+
// Count only turns that started with bg agents already running; the launch turn itself is excluded.
|
|
430
435
|
this._unsubscribeGuardrailCounter = this.agent.subscribe((event) => {
|
|
436
|
+
if (event.type === "turn_start") {
|
|
437
|
+
this._bgRunningAtTurnStart = getRunningBackgroundAgents().length > 0;
|
|
438
|
+
// Re-arm the pause notification for each new run. Within a single paused
|
|
439
|
+
// episode the loop breaks (shouldContinue → false) before turn_start fires,
|
|
440
|
+
// so re-entrant shouldContinue polls stay deduped; a genuinely new run
|
|
441
|
+
// (e.g. the user sends a message to continue) re-arms and re-notifies if it
|
|
442
|
+
// re-pauses, instead of breaking silently.
|
|
443
|
+
this._bgPauseNotified = false;
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
431
446
|
if (event.type !== "turn_end")
|
|
432
447
|
return;
|
|
433
448
|
const bgRunning = getRunningBackgroundAgents();
|
|
434
449
|
if (bgRunning.length === 0) {
|
|
435
|
-
this.
|
|
450
|
+
this._resetBgGuardrailState();
|
|
436
451
|
return;
|
|
437
452
|
}
|
|
438
|
-
this.
|
|
453
|
+
if (this._bgRunningAtTurnStart) {
|
|
454
|
+
this._bgTurnCounter++;
|
|
455
|
+
}
|
|
439
456
|
});
|
|
440
457
|
// shouldContinue callback — checked before each subsequent LLM call.
|
|
441
458
|
// Does NOT inject a steer warning — the loop is already stopping, and any
|
|
442
459
|
// queued warning would go stale (consumed in the next run after bg agents
|
|
443
460
|
// have already delivered results, making the warning factually wrong).
|
|
461
|
+
//
|
|
462
|
+
// Instead, when the guardrail halts the parent, we emit a frontend/session
|
|
463
|
+
// event (`parent_paused_for_background_agents`) so the TUI and Telegram can surface a
|
|
464
|
+
// friendly, non-error notification. The guardrail can be disabled or its
|
|
465
|
+
// turn limit retuned via settings (backgroundAgents.parentTurnGuardrail /
|
|
466
|
+
// parentTurnLimit).
|
|
444
467
|
this.agent.setShouldContinue(() => {
|
|
445
468
|
const bgRunning = getRunningBackgroundAgents();
|
|
446
469
|
if (bgRunning.length === 0) {
|
|
447
|
-
this.
|
|
470
|
+
this._resetBgGuardrailState();
|
|
448
471
|
return true;
|
|
449
472
|
}
|
|
450
|
-
|
|
473
|
+
const { enabled, turnLimit } = this.settingsManager?.getBackgroundAgentGuardrailSettings() ?? {
|
|
474
|
+
enabled: true,
|
|
475
|
+
turnLimit: AgentSession.BG_TURN_LIMIT,
|
|
476
|
+
};
|
|
477
|
+
// Guardrail disabled — advanced opt-out: parent keeps running while bg agents work.
|
|
478
|
+
if (!enabled)
|
|
479
|
+
return true;
|
|
480
|
+
if (this._bgTurnCounter >= turnLimit) {
|
|
481
|
+
if (!this._bgPauseNotified) {
|
|
482
|
+
this._emit({
|
|
483
|
+
type: "parent_paused_for_background_agents",
|
|
484
|
+
runningAgentCount: bgRunning.length,
|
|
485
|
+
turnsUsed: this._bgTurnCounter,
|
|
486
|
+
turnLimit,
|
|
487
|
+
});
|
|
488
|
+
this._bgPauseNotified = true;
|
|
489
|
+
}
|
|
490
|
+
return false;
|
|
491
|
+
}
|
|
492
|
+
return true;
|
|
451
493
|
});
|
|
452
494
|
}
|
|
495
|
+
/**
|
|
496
|
+
* Reset the background-agent guardrail counter and the pause-notified flag together.
|
|
497
|
+
* These two fields are one logical unit — they must always reset in lockstep so a new
|
|
498
|
+
* pause episode both restarts the turn budget and re-arms the pause notification.
|
|
499
|
+
*/
|
|
500
|
+
_resetBgGuardrailState() {
|
|
501
|
+
this._bgTurnCounter = 0;
|
|
502
|
+
this._bgPauseNotified = false;
|
|
503
|
+
}
|
|
453
504
|
/**
|
|
454
505
|
* Handle background agent completion — builds the delivery message and routes
|
|
455
506
|
* it to the parent agent via the appropriate channel (steer, prompt, or appendMessage).
|
|
@@ -503,7 +554,7 @@ export class AgentSession {
|
|
|
503
554
|
}
|
|
504
555
|
else {
|
|
505
556
|
// Reset bg turn counter on delivery — parent gets fresh turns
|
|
506
|
-
this.
|
|
557
|
+
this._resetBgGuardrailState();
|
|
507
558
|
// Normal completion — deliver and trigger a response
|
|
508
559
|
// If the agent is already streaming, steer (injects after current tool calls)
|
|
509
560
|
// instead of followUp (waits until agent would fully stop)
|