mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-20 22:22:57 +03:00
fix(opencode-plugin): honor geminiSanitization & fetchInterceptor feature flags (#2546)
Follow-up fix for #2529 feature-flag gating. Integrated into release/v3.8.2.
This commit is contained in:
committed by
GitHub
parent
c96ba2d7eb
commit
e3ba13bd09
4
.github/workflows/opencode-plugin-ci.yml
vendored
4
.github/workflows/opencode-plugin-ci.yml
vendored
@@ -2,11 +2,11 @@ name: opencode-plugin CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, release/v3.8.1, release/v3.8.2]
|
||||
branches: [main, release/v3.8.2]
|
||||
paths:
|
||||
- "@omniroute/opencode-plugin/**"
|
||||
pull_request:
|
||||
branches: [main, release/v3.8.1, release/v3.8.2]
|
||||
branches: [main, release/v3.8.2]
|
||||
paths:
|
||||
- "@omniroute/opencode-plugin/**"
|
||||
types: [opened, synchronize, reopened, ready_for_review]
|
||||
|
||||
@@ -241,7 +241,13 @@ function coercePluginOptions(opts?: PluginOptions): OmniRoutePluginOptions {
|
||||
* user instead of dispatching a request with bogus credentials.
|
||||
*/
|
||||
export function createOmniRouteAuthHook(opts?: OmniRoutePluginOptions): AuthHook {
|
||||
const { providerId, displayName, baseURL } = resolveOmniRoutePluginOptions(opts);
|
||||
const { providerId, displayName, baseURL, features } = resolveOmniRoutePluginOptions(opts);
|
||||
// Both fetch-layer features default ON (parity with the rest of the plugin's
|
||||
// `features.X !== false` convention). Honoring them here lets users disable
|
||||
// the interceptor/sanitizer from opencode.json — previously these flags were
|
||||
// documented and schema-validated but silently ignored.
|
||||
const wantFetchInterceptor = (features ?? {}).fetchInterceptor !== false;
|
||||
const wantGeminiSanitization = (features ?? {}).geminiSanitization !== false;
|
||||
|
||||
const hook: AuthHook = {
|
||||
provider: providerId,
|
||||
@@ -285,22 +291,26 @@ export function createOmniRouteAuthHook(opts?: OmniRoutePluginOptions): AuthHook
|
||||
if (!resolvedBaseURL) {
|
||||
return { apiKey };
|
||||
}
|
||||
return {
|
||||
apiKey,
|
||||
baseURL: resolvedBaseURL,
|
||||
// Composition: sanitise Gemini tool schemas FIRST (T-06), then
|
||||
// inject Bearer (T-04). Both layers are pure with respect to the
|
||||
// other's concern (body vs headers) so order is logically free;
|
||||
// wrapping the pure body-transform around the header-injecting
|
||||
// interceptor reads cleaner and keeps T-06 testable in isolation
|
||||
// against any inner fetch (real or stub).
|
||||
fetch: createGeminiSanitizingFetch(
|
||||
createOmniRouteFetchInterceptor({
|
||||
apiKey,
|
||||
baseURL: resolvedBaseURL,
|
||||
})
|
||||
),
|
||||
};
|
||||
// Composition: sanitise Gemini tool schemas FIRST (T-06), then inject
|
||||
// Bearer (T-04). Both layers are pure with respect to the other's
|
||||
// concern (body vs headers) so order is logically free; wrapping the
|
||||
// pure body-transform around the header-injecting interceptor reads
|
||||
// cleaner and keeps T-06 testable in isolation against any inner fetch
|
||||
// (real or stub). Each layer is gated by its feature flag; when both
|
||||
// are disabled we fall back to the SDK's default fetch (apiKey only).
|
||||
let composedFetch: typeof fetch | undefined;
|
||||
if (wantFetchInterceptor) {
|
||||
composedFetch = createOmniRouteFetchInterceptor({
|
||||
apiKey,
|
||||
baseURL: resolvedBaseURL,
|
||||
});
|
||||
}
|
||||
if (wantGeminiSanitization) {
|
||||
composedFetch = createGeminiSanitizingFetch(composedFetch ?? fetch);
|
||||
}
|
||||
return composedFetch
|
||||
? { apiKey, baseURL: resolvedBaseURL, fetch: composedFetch }
|
||||
: { apiKey, baseURL: resolvedBaseURL };
|
||||
}
|
||||
return {};
|
||||
},
|
||||
|
||||
@@ -82,6 +82,41 @@ test("loader: valid api auth → {apiKey, baseURL, fetch} when baseURL option se
|
||||
);
|
||||
});
|
||||
|
||||
test("loader: features.fetchInterceptor=false AND geminiSanitization=false → no custom fetch (flags honored)", async () => {
|
||||
// Regression: both fetch-layer flags were documented + schema-validated but
|
||||
// silently ignored. Disabling both must fall back to the SDK default fetch.
|
||||
const hook = createOmniRouteAuthHook({
|
||||
baseURL: "https://or.example.com/v1",
|
||||
features: { fetchInterceptor: false, geminiSanitization: false },
|
||||
});
|
||||
const result = await hook.loader!(
|
||||
async () => ({ type: "api", key: "sk-x" }) as never,
|
||||
{} as never
|
||||
);
|
||||
assert.deepEqual(result, { apiKey: "sk-x", baseURL: "https://or.example.com/v1" });
|
||||
assert.equal(
|
||||
(result as { fetch?: unknown }).fetch,
|
||||
undefined,
|
||||
"both flags off must omit the custom fetch"
|
||||
);
|
||||
});
|
||||
|
||||
test("loader: features.fetchInterceptor=false but geminiSanitization=true → fetch still wired (sanitizer only)", async () => {
|
||||
const hook = createOmniRouteAuthHook({
|
||||
baseURL: "https://or.example.com/v1",
|
||||
features: { fetchInterceptor: false, geminiSanitization: true },
|
||||
});
|
||||
const result = await hook.loader!(
|
||||
async () => ({ type: "api", key: "sk-x" }) as never,
|
||||
{} as never
|
||||
);
|
||||
assert.equal(
|
||||
typeof (result as { fetch?: unknown }).fetch,
|
||||
"function",
|
||||
"geminiSanitization alone must still provide a fetch wrapper"
|
||||
);
|
||||
});
|
||||
|
||||
test("loader: null/undefined auth → {} (no creds yet, OC surfaces /connect)", async () => {
|
||||
const hook = createOmniRouteAuthHook();
|
||||
const r1 = await hook.loader!(async () => null as never, {} as never);
|
||||
|
||||
Reference in New Issue
Block a user