@nofendian17/opencode-relay-plugin 2.0.6 → 2.0.7
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 +1 -1
- package/index.ts +12 -10
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ gateways and are left untouched (no rewrite, no forced retries).
|
|
|
16
16
|
V1 patched `provider.options.fetch` + `globalThis.fetch`. V2 providers no longer expose `fetch`,
|
|
17
17
|
so this plugin uses the documented v2 interception points:
|
|
18
18
|
|
|
19
|
-
- `ctx.session.hook("http.request")` — rewrite provider HTTP →
|
|
19
|
+
- `ctx.session.hook("http.request")` — rewrite provider HTTP → `<relay>` (original method/body/headers preserved) with
|
|
20
20
|
`x-relay-target: <origin>` + `x-relay-path: <path+query>` (round-robin)
|
|
21
21
|
- `ctx.session.hook("http.response")` — on relay `429 / 5xx`, try remaining relays, then direct
|
|
22
22
|
- `ctx.session.hook("retry")` — relay network errors never reach `http.response`, so force a
|
package/index.ts
CHANGED
|
@@ -50,15 +50,6 @@ function normalizeRelays(raw: string | string[] | undefined): string[] {
|
|
|
50
50
|
return [...seen]
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
function createRoundRobin(count: number): () => number {
|
|
54
|
-
let idx = 0
|
|
55
|
-
return () => {
|
|
56
|
-
const cur = idx
|
|
57
|
-
idx = (idx + 1) % count
|
|
58
|
-
return cur
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
53
|
function buildRelayOrigins(relays: readonly string[]): ReadonlySet<string> {
|
|
63
54
|
const origins = new Set<string>()
|
|
64
55
|
for (const relay of relays) {
|
|
@@ -242,6 +233,7 @@ function parseOptions(options: Record<string, unknown> | undefined): {
|
|
|
242
233
|
}
|
|
243
234
|
|
|
244
235
|
const PATCH_MARKER = "__opencodeRelayZenPatched"
|
|
236
|
+
const ROUND_ROBIN_KEY = "__opencodeRelayRoundRobinIdx"
|
|
245
237
|
|
|
246
238
|
export default Plugin.define({
|
|
247
239
|
id: "relay",
|
|
@@ -307,7 +299,15 @@ export default Plugin.define({
|
|
|
307
299
|
// Bind the pristine fetch, not a possibly already-patched one from a
|
|
308
300
|
// prior setup without cleanup (avoids wrapping the patch recursively).
|
|
309
301
|
const directFetch = originalForPatch.bind(globalThis)
|
|
310
|
-
|
|
302
|
+
// Round-robin index is global (module/process-wide) so that setups created
|
|
303
|
+
// per session/conversation still rotate through the pool instead of every
|
|
304
|
+
// one starting at relay 0. Stored next to the patch marker.
|
|
305
|
+
if (g[ROUND_ROBIN_KEY] === undefined) g[ROUND_ROBIN_KEY] = 0
|
|
306
|
+
const pickIndex = () => {
|
|
307
|
+
const cur = (g[ROUND_ROBIN_KEY] as number) ?? 0
|
|
308
|
+
g[ROUND_ROBIN_KEY] = cur + 1
|
|
309
|
+
return cur % relays.length
|
|
310
|
+
}
|
|
311
311
|
const relayOrigins = buildRelayOrigins(relays)
|
|
312
312
|
const relayFetch = createRelayFetch(relays, pickIndex, directFetch, debug, log, emit)
|
|
313
313
|
|
|
@@ -316,6 +316,7 @@ export default Plugin.define({
|
|
|
316
316
|
// else that calls fetch("https://opencode.ai/...") directly.
|
|
317
317
|
if (!g[PATCH_MARKER]) {
|
|
318
318
|
g[PATCH_MARKER] = originalForPatch
|
|
319
|
+
g[ROUND_ROBIN_KEY] = 0
|
|
319
320
|
globalThis.fetch = (async (input: RequestInfo | URL, init?: RequestInit) => {
|
|
320
321
|
const urlStr =
|
|
321
322
|
typeof input === "string" ? input : input instanceof URL ? input.href : input.url
|
|
@@ -515,6 +516,7 @@ export default Plugin.define({
|
|
|
515
516
|
// ignore
|
|
516
517
|
}
|
|
517
518
|
delete g[PATCH_MARKER]
|
|
519
|
+
delete g[ROUND_ROBIN_KEY]
|
|
518
520
|
}
|
|
519
521
|
},
|
|
520
522
|
})
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nofendian17/opencode-relay-plugin",
|
|
3
|
-
"version": "2.0.
|
|
4
|
-
"description": "Route OpenCode v2
|
|
3
|
+
"version": "2.0.7",
|
|
4
|
+
"description": "Route OpenCode v2 opencode.ai traffic through relay endpoint(s) with round-robin, failover, and direct fallback. Other providers are left untouched.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./index.ts",
|
|
7
7
|
"exports": {
|