jeopi-cli 16.2.25 → 16.2.26

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "jeopi-cli",
4
- "version": "16.2.25",
4
+ "version": "16.2.26",
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",
@@ -56,17 +56,17 @@
56
56
  "@agentclientprotocol/sdk": "0.25.0",
57
57
  "@babel/parser": "^7.29.7",
58
58
  "@mozilla/readability": "^0.6.0",
59
- "jeopi-hashline": "16.2.25",
60
- "jeopi-stats": "16.2.25",
61
- "jeopi-agent-core": "16.2.25",
62
- "jeopi-ai": "16.2.25",
63
- "jeopi-catalog": "16.2.25",
64
- "jeopi-mnemopi": "16.2.25",
65
- "jeopi-natives": "16.2.25",
66
- "jeopi-tui": "16.2.25",
67
- "jeopi-utils": "16.2.25",
68
- "jeopi-wire": "16.2.25",
69
- "jeopi-snapcompact": "16.2.25",
59
+ "jeopi-hashline": "16.2.26",
60
+ "jeopi-stats": "16.2.26",
61
+ "jeopi-agent-core": "16.2.26",
62
+ "jeopi-ai": "16.2.26",
63
+ "jeopi-catalog": "16.2.26",
64
+ "jeopi-mnemopi": "16.2.26",
65
+ "jeopi-natives": "16.2.26",
66
+ "jeopi-tui": "16.2.26",
67
+ "jeopi-utils": "16.2.26",
68
+ "jeopi-wire": "16.2.26",
69
+ "jeopi-snapcompact": "16.2.26",
70
70
  "@opentelemetry/api": "^1.9.1",
71
71
  "@opentelemetry/context-async-hooks": "^2.7.1",
72
72
  "@opentelemetry/exporter-trace-otlp-proto": "^0.218.0",
@@ -13,7 +13,7 @@ Look where the agent is NOT — bring the angle they skipped, NEVER re-run reaso
13
13
  Offer that view before they sink work into the wrong direction.
14
14
 
15
15
  <workflow>
16
- You receive the agent's transcript incrementally, including their thoughts.
16
+ You receive the agent's transcript incrementally — their messages, tool calls, and results.
17
17
  Use the tools this session grants you to verify suspicions — by default read-only lookup (`read`, `grep`, `glob`); operators may extend the grant via `WATCHDOG.yml`. Advising is your primary channel; touch mutating tools (when granted) only when a verify step genuinely needs them.
18
18
  Keep exploration lean:
19
19
  - 2–3 tool calls per advise.
@@ -1,7 +1,6 @@
1
1
  <system-notice type="interrupted-thinking">
2
- Your previous turn was interrupted while you were thinking.
3
- - You MUST treat the preserved reasoning as internal continuity context.
4
- - You MUST continue the user's task from the relevant unfinished point.
2
+ Your previous turn was cut off before you finished. Below is your unfinished internal work state — use it silently to resume; do not quote, repeat, or restate it back.
3
+ - Continue the user's task from the relevant unfinished point.
5
4
  ------
6
5
  {{reasoning}}
7
6
  </system-notice>
@@ -1593,6 +1593,14 @@ export class AgentSession {
1593
1593
  #retryAttempt = 0;
1594
1594
  /** Rung-4 classifier-refusal resend streak (post fallback-ladder). */
1595
1595
  #refusalBackoff: { startedAt: number; attempt: number } | undefined = undefined;
1596
+ /**
1597
+ * One-shot latch: `reasoning_extraction` classifier refusals are payload-shape-bound
1598
+ * (see advisor/runtime.ts `#includeThinking` degrade) — resending the identical batch
1599
+ * predictably re-refuses. Set the first time `#handleRetryableError` strips unsigned
1600
+ * thinking/redactedThinking from active context and resends on the same model; never
1601
+ * reset, mirroring the advisor's permanent-for-the-session degrade.
1602
+ */
1603
+ #reasoningExtractionDegraded = false;
1596
1604
  #retryPromise: Promise<void> | undefined = undefined;
1597
1605
  #retryResolve: (() => void) | undefined = undefined;
1598
1606
  #activeRetryFallback: ActiveRetryFallbackState | undefined = undefined;
@@ -12681,6 +12689,36 @@ export class AgentSession {
12681
12689
  const stopType = message.stopDetails?.type;
12682
12690
  return stopType === "refusal" || stopType === "sensitive";
12683
12691
  }
12692
+ /**
12693
+ * Strip unsigned `thinking` and every `redactedThinking` block from assistant
12694
+ * messages. Used once as a `reasoning_extraction` classifier-refusal degrade:
12695
+ * unlike {@link renderDemotedThinking}'s plain-text fallback (still a plaintext
12696
+ * reasoning replay for dialects outside the Fable/Mythos carve-out), dropping the
12697
+ * block outright removes the trigger instead of reformatting it. Signed thinking
12698
+ * is left untouched — it replays natively via the provider's structured thinking
12699
+ * block and is never demoted to plaintext.
12700
+ * @returns a rewritten array, or `undefined` if no message needed stripping.
12701
+ */
12702
+ #stripUnsignedThinkingForRefusalDegrade(messages: readonly AgentMessage[]): AgentMessage[] | undefined {
12703
+ let changed = false;
12704
+ const next: AgentMessage[] = [];
12705
+ for (const message of messages) {
12706
+ if (message.role !== "assistant") {
12707
+ next.push(message);
12708
+ continue;
12709
+ }
12710
+ const content = message.content.filter(
12711
+ block => block.type !== "redactedThinking" && (block.type !== "thinking" || !!block.thinkingSignature),
12712
+ );
12713
+ if (content.length === message.content.length) {
12714
+ next.push(message);
12715
+ continue;
12716
+ }
12717
+ changed = true;
12718
+ if (content.length > 0) next.push({ ...message, content });
12719
+ }
12720
+ return changed ? next : undefined;
12721
+ }
12684
12722
 
12685
12723
  #getRetryFallbackChains(): RetryFallbackChains {
12686
12724
  const configuredChains = this.settings.get("retry.fallbackChains");
@@ -13099,6 +13137,33 @@ export class AgentSession {
13099
13137
  }
13100
13138
 
13101
13139
  const errorMessage = message.errorMessage || "Unknown error";
13140
+ // `reasoning_extraction` is payload-shape-bound (see advisor/runtime.ts): resending
13141
+ // the identical batch predictably re-refuses, unlike probabilistic classifier flags
13142
+ // where backoff/fallback genuinely help. Degrade once — strip unsigned
13143
+ // thinking/redactedThinking from active context and resend immediately on the same
13144
+ // model — before falling through to the generic fallback-pin / backoff ladder below,
13145
+ // which would otherwise retry the unchanged, re-refusing payload.
13146
+ if (
13147
+ classifierRefusal &&
13148
+ message.stopDetails?.category === "reasoning_extraction" &&
13149
+ !this.#reasoningExtractionDegraded
13150
+ ) {
13151
+ this.#reasoningExtractionDegraded = true;
13152
+ const stripped = this.#stripUnsignedThinkingForRefusalDegrade(this.agent.state.messages);
13153
+ if (stripped) this.agent.replaceMessages(stripped);
13154
+ this.#removeAssistantMessageFromActiveContext(message, "reasoning-extraction-degrade");
13155
+ await this.#emitSessionEvent({
13156
+ type: "auto_retry_start",
13157
+ attempt: this.#retryAttempt,
13158
+ maxAttempts: retrySettings.maxRetries,
13159
+ delayMs: 0,
13160
+ errorMessage,
13161
+ errorId: message.errorId,
13162
+ });
13163
+ this.#scheduleAgentContinue({ delayMs: 1, generation });
13164
+ return true;
13165
+ }
13166
+
13102
13167
  const id = this.#classifyRetryMessage(message);
13103
13168
  const staleOpenAIResponsesReplayError = AIError.is(id, AIError.Flag.StaleResponsesItem);
13104
13169
  const parsedRetryAfterMs = this.#parseRetryAfterMsFromError(errorMessage);