@cortexkit/opencode-anthropic-auth 1.17.0 → 1.19.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 +20 -4
- package/dist/cli.js +1 -1
- package/dist/fable-fallback.d.ts +15 -2
- package/dist/{index-y2n9h7p6.js → index-1ets4bf8.js} +1 -1
- package/dist/{index-f5r96vyv.js → index-9aeag0wm.js} +1 -1
- package/dist/index-h0pmqm96.js +422 -0
- package/dist/{index-63keqwnf.js → index-k5enth8h.js} +1 -1
- package/dist/{index-am5pq04s.js → index-kckdabb4.js} +1 -1
- package/dist/index-szybnfvk.js +2 -0
- package/dist/index.js +20 -12
- package/dist/{logger-ywfmddsw.js → logger-whpn7rjx.js} +1 -1
- package/dist/rpc/port-file.js +1 -1
- package/dist/rpc/rpc-client.js +1 -1
- package/dist/rpc/rpc-dir.js +1 -1
- package/dist/server-fallback.d.ts +25 -0
- package/dist/sidebar-state.d.ts +15 -1
- package/dist/sidebar-state.js +1 -1
- package/dist/transform.d.ts +5 -0
- package/dist/tui-preferences.js +1 -1
- package/package.json +2 -2
- package/src/sidebar-state.ts +41 -3
- package/src/tui-compiled/sidebar-state.ts +41 -3
- package/src/tui-compiled/tui.tsx +1 -1
- package/src/tui.tsx +3 -3
- package/dist/index-gj7emmj5.js +0 -2
- package/dist/index-xvfesm3w.js +0 -422
package/README.md
CHANGED
|
@@ -31,8 +31,8 @@ This repo is a Bun workspace monorepo with two user-facing integrations and one
|
|
|
31
31
|
- **Persistent Claude cache controls**: manage Anthropic 1-hour prompt caching from `/claude-cache` with explicit, automatic, or hybrid modes.
|
|
32
32
|
- **Cache keepalive**: use `/claude-cachekeep always` or `/claude-cachekeep HH-HH` to pre-warm hybrid cache anchors for active sessions before the 1-hour TTL expires.
|
|
33
33
|
- **Fast mode toggle**: use `/claude-fast on|off` to request Anthropic fast mode for supported Opus models.
|
|
34
|
-
- **
|
|
35
|
-
- **Fable
|
|
34
|
+
- **Adaptive reasoning visibility**: request summarized adaptive thinking for Claude Fable 5, Mythos 5, and Opus 5. OpenCode receives native `low`, `medium`, `high`, `xhigh`, and `max` Opus 5 effort variants rather than legacy manual-thinking budgets.
|
|
35
|
+
- **Fable/Opus 5 safety fallback**: eligible OAuth requests opt into Anthropic's server-side safety fallback by default. The plugin preserves Anthropic's fallback conversation boundary across OpenCode history, and the TUI sidebar and OpenCode Desktop report the active target model and restoration. Set `OPENCODE_ANTHROPIC_AUTH_FALLBACK_MODE=legacy` to restore the previous deterministic 10-response Opus 4.8 recovery with source-model prewarming.
|
|
36
36
|
- **Live quota visibility**: use `/claude-quota` to see main and fallback quota state, reset times, and refresh errors.
|
|
37
37
|
- **Killswitch**: per-account hard-block thresholds that stop requests before hitting Anthropic's rate limits, with synthetic 429 retry-after when all accounts are exhausted.
|
|
38
38
|
- **User-owned Cloudflare relay**: optionally provision your own Worker relay to reduce repeated client upload bytes for large OpenCode or Pi requests.
|
|
@@ -289,6 +289,20 @@ In OpenCode, this includes the main Anthropic account and sidecar fallback accou
|
|
|
289
289
|
|
|
290
290
|
Reset times are rendered as relative durations, such as `resets in 10m` or `resets in 1h 15m`.
|
|
291
291
|
|
|
292
|
+
## Safety fallback
|
|
293
|
+
|
|
294
|
+
Eligible Fable 5 and Opus 5 OAuth requests use Anthropic's server-side safety fallback by default. The plugin sends `fallbacks: "default"` with Anthropic's server-side fallback beta, preserves fallback conversation boundaries in OpenCode history, and reports model handoffs and restoration in the TUI sidebar or OpenCode Desktop. Follow-up requests may remain on Anthropic's selected fallback model for approximately one hour.
|
|
295
|
+
|
|
296
|
+
Custom API-key routes do not receive the server-side fallback beta or request field.
|
|
297
|
+
|
|
298
|
+
To return to CortexKit's previous deterministic recovery mechanism, start OpenCode with:
|
|
299
|
+
|
|
300
|
+
```bash
|
|
301
|
+
OPENCODE_ANTHROPIC_AUTH_FALLBACK_MODE=legacy opencode
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
Legacy mode routes a refused Fable 5 or Opus 5 session through Opus 4.8 for 10 successful responses, prewarms the selected source model's cache, and then restores that model. Unset the variable and restart OpenCode to use Anthropic's server-side fallback again.
|
|
305
|
+
|
|
292
306
|
## Killswitch
|
|
293
307
|
|
|
294
308
|
The killswitch is a per-account hard-block that stops requests when remaining quota drops below configured thresholds, even if Anthropic's API would still accept them. Unlike `minimumRemaining` (which routes to fallback accounts), the killswitch removes accounts from the routing pool entirely.
|
|
@@ -387,7 +401,7 @@ Both OpenCode and Pi packages can persistently request Anthropic fast mode for s
|
|
|
387
401
|
/claude-fast off
|
|
388
402
|
```
|
|
389
403
|
|
|
390
|
-
When enabled, supported requests add `speed: "fast"` to the Anthropic JSON body and include the `fast-mode-2026-02-01` beta header. Unsupported models are left at standard speed. Anthropic currently documents fast mode for `claude-opus-4-6`, `claude-opus-4-7`,
|
|
404
|
+
When enabled, supported requests add `speed: "fast"` to the Anthropic JSON body and include the `fast-mode-2026-02-01` beta header. Unsupported models are left at standard speed. Anthropic currently documents fast mode for `claude-opus-4-6`, `claude-opus-4-7`, `claude-opus-4-8`, and `claude-opus-5`; Claude Fable 5 and Mythos 5 are not fast-mode models.
|
|
391
405
|
|
|
392
406
|
Fast and standard speeds do not share prompt-cache prefixes, so switching this setting can cause cache misses.
|
|
393
407
|
|
|
@@ -517,6 +531,7 @@ Dump state is persisted in the active sidecar config as `dump.enabled` (`~/.conf
|
|
|
517
531
|
| `ANTHROPIC_BASE_URL` | Override the Anthropic API endpoint. Must be HTTP(S). |
|
|
518
532
|
| `ANTHROPIC_INSECURE` | Set to `1` or `true` to skip TLS verification when `ANTHROPIC_BASE_URL` is set. |
|
|
519
533
|
| `OPENCODE_ANTHROPIC_AUTH_FILE` | Override the OpenCode sidecar config path. |
|
|
534
|
+
| `OPENCODE_ANTHROPIC_AUTH_FALLBACK_MODE` | Set to `legacy` to use the previous deterministic 10-response client-side refusal recovery. The default is Anthropic server-side safety fallback. |
|
|
520
535
|
| `PI_ANTHROPIC_AUTH_FILE` | Override the Pi sidecar config path. |
|
|
521
536
|
| `PI_AGENT_DIR` | Override Pi's agent directory when deriving the default sidecar path. |
|
|
522
537
|
| `CLOUDFLARE_API_TOKEN` | Cloudflare token used by `bunx @cortexkit/opencode-anthropic-auth relay setup`. Not stored. |
|
|
@@ -532,7 +547,8 @@ For Claude Pro/Max OAuth requests, the plugin works at the final Anthropic wire-
|
|
|
532
547
|
4. Prepends Claude Code identity and billing-header blocks.
|
|
533
548
|
5. Rewrites cache controls according to `/claude-cache` mode.
|
|
534
549
|
6. Renames MCP tool names into Claude-compatible PascalCase form.
|
|
535
|
-
7.
|
|
550
|
+
7. Opts eligible Fable 5 and Opus 5 OAuth requests into Anthropic's server-side safety fallback and restores stored fallback boundary markers.
|
|
551
|
+
8. Computes final-body `cch` over the fully serialized request body.
|
|
536
552
|
|
|
537
553
|
The sanitizer is anchor-based: it removes paragraphs containing known OpenCode documentation or source anchors, performs a small set of inline replacements, and preserves the rest of the prompt including user/project instructions, tool policy, environment context, and file paths.
|
|
538
554
|
|
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{
|
|
2
|
+
import{D as z,E as N,G as P,I as L,K as E,M as K,N as S,Ob as T,Qb as q,za as U}from"./index-h0pmqm96.js";import"./index-1ets4bf8.js";import{uc as w}from"./index-9aeag0wm.js";import{stdin as x,stdout as v}from"node:process";import{createInterface as y}from"node:readline/promises";function R(){return{version:1,main:{type:"opencode",provider:"anthropic"},fallbackOn:[401,403,429],refresh:{enabled:!0,intervalMinutes:10,refreshBeforeExpiryMinutes:240},quota:{enabled:!0,checkIntervalMinutes:5,minimumRemaining:{five_hour:10,seven_day:20},failClosedOnUnknownQuota:!0},accounts:[]}}function _(){console.log(`Usage:
|
|
3
3
|
opencode-anthropic-auth login [label]
|
|
4
4
|
opencode-anthropic-auth api add [label]
|
|
5
5
|
opencode-anthropic-auth list
|
package/dist/fable-fallback.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export type FableStandbyCacheAnchor = {
|
|
|
8
8
|
};
|
|
9
9
|
export type FableFallbackPlan = {
|
|
10
10
|
sessionId: string;
|
|
11
|
+
recoveryKey: string;
|
|
11
12
|
requestedModel: string;
|
|
12
13
|
effectiveModel: string;
|
|
13
14
|
bodyText: string;
|
|
@@ -18,9 +19,21 @@ export type FableFallbackPlan = {
|
|
|
18
19
|
requestSequence?: number;
|
|
19
20
|
completed?: boolean;
|
|
20
21
|
};
|
|
22
|
+
/**
|
|
23
|
+
* Models whose content-filter refusal we recover from by downgrading to Opus 4.8
|
|
24
|
+
* for a short window. Fable 5 is the original case; Opus 5 is identical in
|
|
25
|
+
* shape (cyber safety classifiers that can return `stop_reason: "refusal"`,
|
|
26
|
+
* Anthropic's own fallback default is `claude-opus-4-8`, same pricing). Mythos
|
|
27
|
+
* has no classifiers and Sonnet 5 is not flagged — both stay outside this
|
|
28
|
+
* gate. The single shared fallback id matches Anthropic's default for both
|
|
29
|
+
* source models, so the recovery period is uniform.
|
|
30
|
+
*/
|
|
31
|
+
export type RecoverableRefusalFamily = 'fable-5' | 'opus-5';
|
|
32
|
+
export declare function recoverableRefusalFamily(model: unknown): RecoverableRefusalFamily | null;
|
|
33
|
+
export declare function isRecoverableRefusalModel(model: unknown): model is string;
|
|
21
34
|
export declare class FableFallbackManager {
|
|
22
35
|
private readonly now;
|
|
23
|
-
private readonly
|
|
36
|
+
private readonly recoveries;
|
|
24
37
|
private nextCycle;
|
|
25
38
|
constructor(now?: () => number);
|
|
26
39
|
private prune;
|
|
@@ -32,5 +45,5 @@ export declare class FableFallbackManager {
|
|
|
32
45
|
counted: boolean;
|
|
33
46
|
remaining: number;
|
|
34
47
|
};
|
|
35
|
-
remaining(
|
|
48
|
+
remaining(plan: FableFallbackPlan): number;
|
|
36
49
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import*as j from"node:fs";import*as P from"node:os";import*as V from"node:path";var U={error:0,warn:1,info:2,debug:3,trace:4},O=new Set(Object.keys(U));function F(q){if(!q)return null;let Q=q.trim().toLowerCase();return O.has(Q)?Q:null}var S=F(process.env.OPENCODE_ANTHROPIC_AUTH_LOG_LEVEL),M=S??"info";function L(q){M=q}function i(){return M}function X(q){return U[q]<=U[M]}var J=process.env.OPENCODE_ANTHROPIC_AUTH_LOG_FILE??V.join(P.tmpdir(),"opencode-anthropic-auth.log");function h(){return J}var R=5242880,N=3;function I(){try{if(!j.existsSync(J))return;if(j.statSync(J).size<R)return}catch{return}try{for(let q=N;q>=1;q--){let Q=q===1?J:`${J}.${q-1}`,W=`${J}.${q}`;try{if(q===N)try{j.unlinkSync(W)}catch{}if(j.existsSync(Q))j.renameSync(Q,W)}catch{}}}catch{}}var T=/^(authorization|x-api-key|cookie|set-cookie|refresh|access|token)$/i;function k(q){if(T.test(q))return!0;let Q=q.toLowerCase().replace(/[-_]/g,"");if(Q.includes("apikey"))return!0;if(Q.endsWith("secret")||Q.endsWith("password"))return!0;if(Q.endsWith("token")&&!Q.endsWith("tokens"))return!0;return!1}var f=[/Bearer\s+\S+/,/sk-[A-Za-z0-9-]+/,/eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/];function _(q){if(typeof q!=="string")return!1;return f.some((Q)=>Q.test(q))}function G(q){if(q==null||Object.keys(q).length===0)return;let Q=new WeakSet;function W($){if($==null||typeof $!=="object"){if(_($))return"***REDACTED***";return $}if(Q.has($))return"[Circular]";Q.add($);try{if(Array.isArray($))return $.map(W);let x=$,B={};for(let[H,C]of Object.entries(x)){if(k(H)){B[H]="***REDACTED***";continue}B[H]=W(C)}return B}finally{Q.delete($)}}return W(q)}function g(q,Q,W,$){let x=new Date().toISOString(),B=q.toUpperCase().padEnd(5),H=Q?` [${Q}]`:"",C=(()=>{try{let w=G($),A=w?{...w,pid:process.pid}:{pid:process.pid};return` ${JSON.stringify(A)}`}catch{return` {"pid":${process.pid},"payload":"[unserializable]"}`}})();return`[${x}] ${B}${H} ${W}${C}`}var D=null;function E(q){D=q}function Y(q,Q,W,$){if(!X(q))return;if(D)try{D({level:q,channel:Q,message:W,payload:G($)})}catch{}if(Z)return;try{let x=`${g(q,Q,W,$)}
|
|
2
2
|
`;if(K.push(x),K.length>=p)b();else r()}catch{}}var m={error(q,Q,W){Y("error",q,Q,W)},warn(q,Q,W){Y("warn",q,Q,W)},info(q,Q,W){Y("info",q,Q,W)},debug(q,Q,W){Y("debug",q,Q,W)},trace(q,Q,W){Y("trace",q,Q,W)}},Z=!1,c=500,p=50,K=[],z=null;function b(){if(z)clearTimeout(z),z=null;if(K.length===0)return;let q=K.join("");K=[];try{I(),j.appendFileSync(J,q)}catch{}}function r(){if(z)return;z=setTimeout(()=>{z=null,b()},c)}var y=/^\[([\w-]+)\]\s*/;function o(q,Q){if(!X("debug"))return;if(Z)return;try{let W="",$=q,x=q.match(y);if(x)W=x[1]??"",$=q.slice(x[0].length);let B;if(Q!=null){if(Q instanceof Error)B={error:`${Q.message}${Q.stack?`
|
|
3
3
|
${Q.stack}`:""}`};else if(typeof Q==="object")B=Q}Y("debug",W,$,B)}catch{}}function v(q,Q){if(!X("debug"))return;if(Z)return;try{let W;if(Q!=null){if(typeof Q==="object"&&!(Q instanceof Error))W=Q}Y("debug","relay",q,W)}catch{}}if(!Z)process.on("exit",b);
|
|
4
|
-
export{F as
|
|
4
|
+
export{F as bc,L as cc,i as dc,X as ec,h as fc,T as gc,k as hc,G as ic,g as jc,E as kc,m as lc,o as mc,v as nc};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import{createRequire as q}from"node:module";var j=Object.create;var{getPrototypeOf:k,defineProperty:i,getOwnPropertyNames:l}=Object;var m=Object.prototype.hasOwnProperty;function n(a){return this[a]}var o,p,r=(a,b,d)=>{var f=a!=null&&typeof a==="object";if(f){var g=b?o??=new WeakMap:p??=new WeakMap,h=g.get(a);if(h)return h}d=a!=null?j(k(a)):{};let c=b||!a||!a.__esModule?i(d,"default",{value:a,enumerable:!0}):d;for(let e of l(a))if(!m.call(c,e))i(c,e,{get:n.bind(a,e),enumerable:!0});if(f)g.set(a,c);return c};var s=(a,b)=>()=>(b||a((b={exports:{}}).exports,b),b.exports);var u=q(import.meta.url);
|
|
2
|
-
export{r as
|
|
2
|
+
export{r as sc,s as tc,u as uc};
|