jeopi-cli 16.4.1 → 16.4.2
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/CHANGELOG.md +6 -0
- package/dist/cli.js +372 -372
- package/package.json +12 -12
- package/src/session/agent-session.ts +65 -25
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "jeopi-cli",
|
|
4
|
-
"version": "16.4.
|
|
4
|
+
"version": "16.4.2",
|
|
5
5
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://github.com/akillness/jeopi",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -57,17 +57,17 @@
|
|
|
57
57
|
"@agentclientprotocol/sdk": "0.25.0",
|
|
58
58
|
"@babel/parser": "^7.29.7",
|
|
59
59
|
"@mozilla/readability": "^0.6.0",
|
|
60
|
-
"jeopi-hashline": "16.4.
|
|
61
|
-
"jeopi-stats": "16.4.
|
|
62
|
-
"jeopi-agent-core": "16.4.
|
|
63
|
-
"jeopi-ai": "16.4.
|
|
64
|
-
"jeopi-catalog": "16.4.
|
|
65
|
-
"jeopi-mnemopi": "16.4.
|
|
66
|
-
"jeopi-natives": "16.4.
|
|
67
|
-
"jeopi-tui": "16.4.
|
|
68
|
-
"jeopi-utils": "16.4.
|
|
69
|
-
"jeopi-wire": "16.4.
|
|
70
|
-
"jeopi-snapcompact": "16.4.
|
|
60
|
+
"jeopi-hashline": "16.4.2",
|
|
61
|
+
"jeopi-stats": "16.4.2",
|
|
62
|
+
"jeopi-agent-core": "16.4.2",
|
|
63
|
+
"jeopi-ai": "16.4.2",
|
|
64
|
+
"jeopi-catalog": "16.4.2",
|
|
65
|
+
"jeopi-mnemopi": "16.4.2",
|
|
66
|
+
"jeopi-natives": "16.4.2",
|
|
67
|
+
"jeopi-tui": "16.4.2",
|
|
68
|
+
"jeopi-utils": "16.4.2",
|
|
69
|
+
"jeopi-wire": "16.4.2",
|
|
70
|
+
"jeopi-snapcompact": "16.4.2",
|
|
71
71
|
"@opentelemetry/api": "^1.9.1",
|
|
72
72
|
"@opentelemetry/context-async-hooks": "^2.7.1",
|
|
73
73
|
"@opentelemetry/exporter-trace-otlp-proto": "^0.218.0",
|
|
@@ -522,6 +522,17 @@ const RETRY_BACKOFF_MAX_DELAY_MS = 8_000;
|
|
|
522
522
|
const REFUSAL_BACKOFF_BASE_MS = 2_000;
|
|
523
523
|
const REFUSAL_BACKOFF_MAX_MS = 30_000;
|
|
524
524
|
const REFUSAL_BACKOFF_BUDGET_MS = 30 * 60_000;
|
|
525
|
+
/**
|
|
526
|
+
* Consecutive-use cap on the `reasoning_extraction` fast-degrade path (strip
|
|
527
|
+
* unsigned thinking, resend same-model, zero delay — see
|
|
528
|
+
* `#reasoningExtractionDegradeStreak` below). Bounds the worst case where a
|
|
529
|
+
* pathological classifier state (documented: 1,164 refusals over ~4 hours in
|
|
530
|
+
* one incident) refuses every turn's fresh thinking in a row — after this
|
|
531
|
+
* many back-to-back fast-degrades with no intervening success, fall through
|
|
532
|
+
* to the Rung-4 ladder above, which already wall-clock-bounds via
|
|
533
|
+
* {@link REFUSAL_BACKOFF_BUDGET_MS}.
|
|
534
|
+
*/
|
|
535
|
+
const REASONING_EXTRACTION_DEGRADE_STREAK_CAP = 3;
|
|
525
536
|
|
|
526
537
|
function positiveEnvMs(name: string): number | undefined {
|
|
527
538
|
const raw = process.env[name];
|
|
@@ -1611,13 +1622,31 @@ export class AgentSession {
|
|
|
1611
1622
|
/** Rung-4 classifier-refusal resend streak (post fallback-ladder). */
|
|
1612
1623
|
#refusalBackoff: { startedAt: number; attempt: number } | undefined = undefined;
|
|
1613
1624
|
/**
|
|
1614
|
-
*
|
|
1615
|
-
*
|
|
1616
|
-
* predictably re-refuses
|
|
1617
|
-
*
|
|
1618
|
-
*
|
|
1619
|
-
|
|
1620
|
-
|
|
1625
|
+
* `reasoning_extraction` classifier refusals are payload-shape-bound (see
|
|
1626
|
+
* advisor/runtime.ts `#includeThinking` degrade): resending the IDENTICAL
|
|
1627
|
+
* batch predictably re-refuses, so a bare retry can't help. But this is a
|
|
1628
|
+
* point-in-time strip of the CURRENT active context, not a persistent
|
|
1629
|
+
* setting — unlike the advisor's permanent-for-the-session
|
|
1630
|
+
* `includeThinking` flag, it does not prevent NEW unsigned thinking from a
|
|
1631
|
+
* LATER turn (a fresh advisor exchange, another interrupt, plain
|
|
1632
|
+
* continued conversation) from independently triggering its own,
|
|
1633
|
+
* genuinely-different refusal. A one-shot latch here previously left every
|
|
1634
|
+
* occurrence after the first to fall through to the generic Rung-4
|
|
1635
|
+
* backoff ladder unstripped — resending the same unstripped payload until
|
|
1636
|
+
* the wall-clock budget expired and the turn failed visibly.
|
|
1637
|
+
*
|
|
1638
|
+
* Fixed by gating on whether {@link #stripUnsignedThinkingForRefusalDegrade}
|
|
1639
|
+
* actually found something to strip THIS time (it already returns
|
|
1640
|
+
* `undefined` when there is nothing new to remove, which is itself proof
|
|
1641
|
+
* the resend would be payload-identical and degrading again cannot help)
|
|
1642
|
+
* rather than a permanent flag — each distinct occurrence gets its own
|
|
1643
|
+
* degrade attempt. Bounded by {@link REASONING_EXTRACTION_DEGRADE_STREAK_CAP}
|
|
1644
|
+
* consecutive uses (reset on any turn that actually succeeds) so a
|
|
1645
|
+
* pathological classifier state that refuses every turn's fresh thinking
|
|
1646
|
+
* in a row still falls through to the wall-clock-bounded ladder instead
|
|
1647
|
+
* of resending at zero delay indefinitely.
|
|
1648
|
+
*/
|
|
1649
|
+
#reasoningExtractionDegradeStreak = 0;
|
|
1621
1650
|
#retryPromise: Promise<void> | undefined = undefined;
|
|
1622
1651
|
#retryResolve: (() => void) | undefined = undefined;
|
|
1623
1652
|
#activeRetryFallback: ActiveRetryFallbackState | undefined = undefined;
|
|
@@ -3674,6 +3703,7 @@ export class AgentSession {
|
|
|
3674
3703
|
});
|
|
3675
3704
|
this.#retryAttempt = 0;
|
|
3676
3705
|
this.#refusalBackoff = undefined;
|
|
3706
|
+
this.#reasoningExtractionDegradeStreak = 0;
|
|
3677
3707
|
}
|
|
3678
3708
|
if (assistantMsg.provider === "opencode-go") {
|
|
3679
3709
|
this.#modelRegistry.authStorage.recordUsageCost(assistantMsg.provider, assistantMsg.usage.cost.total, {
|
|
@@ -13224,29 +13254,39 @@ export class AgentSession {
|
|
|
13224
13254
|
const errorMessage = message.errorMessage || "Unknown error";
|
|
13225
13255
|
// `reasoning_extraction` is payload-shape-bound (see advisor/runtime.ts): resending
|
|
13226
13256
|
// the identical batch predictably re-refuses, unlike probabilistic classifier flags
|
|
13227
|
-
// where backoff/fallback genuinely help.
|
|
13228
|
-
//
|
|
13229
|
-
//
|
|
13230
|
-
//
|
|
13257
|
+
// where backoff/fallback genuinely help. Strip unsigned thinking/redactedThinking
|
|
13258
|
+
// from active context and resend immediately on the same model — before falling
|
|
13259
|
+
// through to the generic fallback-pin / backoff ladder below, which would otherwise
|
|
13260
|
+
// retry the unchanged, re-refusing payload. Gated on the strip itself finding
|
|
13261
|
+
// something to remove THIS time (not a one-shot flag): a later turn can
|
|
13262
|
+
// independently accumulate fresh unsigned thinking and trigger its own genuinely
|
|
13263
|
+
// different refusal, and `#stripUnsignedThinkingForRefusalDegrade` already reports
|
|
13264
|
+
// "nothing to strip" via `undefined` when the payload truly is unchanged — which is
|
|
13265
|
+
// itself the correct signal to fall through instead of degrading again. Bounded by
|
|
13266
|
+
// `REASONING_EXTRACTION_DEGRADE_STREAK_CAP` consecutive uses so a pathological
|
|
13267
|
+
// classifier state refusing every turn's fresh thinking in a row still reaches the
|
|
13268
|
+
// wall-clock-bounded ladder instead of resending at zero delay indefinitely.
|
|
13231
13269
|
if (
|
|
13232
13270
|
classifierRefusal &&
|
|
13233
13271
|
message.stopDetails?.category === "reasoning_extraction" &&
|
|
13234
|
-
|
|
13272
|
+
this.#reasoningExtractionDegradeStreak < REASONING_EXTRACTION_DEGRADE_STREAK_CAP
|
|
13235
13273
|
) {
|
|
13236
|
-
this.#reasoningExtractionDegraded = true;
|
|
13237
13274
|
const stripped = this.#stripUnsignedThinkingForRefusalDegrade(this.agent.state.messages);
|
|
13238
|
-
if (stripped)
|
|
13239
|
-
|
|
13240
|
-
|
|
13241
|
-
|
|
13242
|
-
|
|
13243
|
-
|
|
13244
|
-
|
|
13245
|
-
|
|
13246
|
-
|
|
13247
|
-
|
|
13248
|
-
|
|
13249
|
-
|
|
13275
|
+
if (stripped) {
|
|
13276
|
+
this.#reasoningExtractionDegradeStreak++;
|
|
13277
|
+
this.agent.replaceMessages(stripped);
|
|
13278
|
+
this.#removeAssistantMessageFromActiveContext(message, "reasoning-extraction-degrade");
|
|
13279
|
+
await this.#emitSessionEvent({
|
|
13280
|
+
type: "auto_retry_start",
|
|
13281
|
+
attempt: this.#retryAttempt,
|
|
13282
|
+
maxAttempts: retrySettings.maxRetries,
|
|
13283
|
+
delayMs: 0,
|
|
13284
|
+
errorMessage,
|
|
13285
|
+
errorId: message.errorId,
|
|
13286
|
+
});
|
|
13287
|
+
this.#scheduleAgentContinue({ delayMs: 1, generation });
|
|
13288
|
+
return true;
|
|
13289
|
+
}
|
|
13250
13290
|
}
|
|
13251
13291
|
|
|
13252
13292
|
const id = this.#classifyRetryMessage(message);
|