Dashboard › opencode › Distillation
35cf02b5-d52d-41ac-9dd2-d76b8a1ee1bc["lore_tm_v1_6GPngm8fm3v8H5BIA_oBhFg3xJZWEVJvgEQ_kBPyHVI","lore_tm_v1_a7TbcsxC8yi7XnDXPL4gjNp_PPoPQDq8-gIuxElBniY","lore_tm_v1_Vn3-c4Ve9dUyXdPWHNeWIzimUtoy7ZAx4UdYdWY5ZcE"]
packages/core/src/fetch-interceptor.ts: “Never intercept requests already going to the gateway”; direct gateway requests must remain unchanged, though their headers may be observed via onRequestHeaders.packages/core/src/fetch-interceptor.ts: “Never intercept local requests (could be local LLM or gateway itself)”; local requests must never be routed through the gateway.isLocalHost() centralizes local-host detection for localhost, 127.0.0.1, 0.0.0.0, ::1, and [::1]; both bracketed and unbracketed IPv6 loopback forms are accepted because Node’s URL.hostname keeps brackets.rewriteRequest() primitive: it “never reads the request body”; known paths can safely carry streaming bodies, while unknown paths “always pass through.”packages/core/src/fetch-interceptor.ts adds and exports DynamicRequestHeaders = Readonly<Record<string, string>> and DynamicRequestHeadersSource = DynamicRequestHeaders | (() => DynamicRequestHeaders).packages/core/src/fetch-interceptor.ts adds exported async rewriteRequest(request, gatewayBase, dynamicHeaders, onRequestHeaders?), backed by rewriteRequestForProtocol(), and packages/core/src/index.ts re-exports rewriteRequest, DynamicRequestHeaders, and DynamicRequestHeadersSource.rewriteRequest() first uses mayBeLLMRequest() to pass through URLs lacking /messages, /completions, or /responses; it then passes through direct-gateway requests after observing their headers, passes through local hosts unchanged, routes recognized LLM API paths via interceptUrl(), and returns the original Request when no rewrite applies.rewriteRequestForProtocol() creates routed requests with new Request(rewrite.gatewayUrl, request), preserving the original method, body, authorization, API key, path/query semantics, and other request properties without consuming the original body.packages/core/src/fetch-interceptor.ts was refactored from buildGatewayHeaders(input, init, ..., config) into mutating applyGatewayHeaders(headers, upstreamBase, upstreamPath, dynamicHeaders). It sets x-lore-upstream-url and x-lore-upstream-path, resolves dynamic headers from either a record or callback, and does not overwrite a dynamic header already present on the request.applyGatewayHeaders() catches failures from a dynamic-header callback and logs fetch-interceptor: getHeaders() failed:; observeRequestHeaders() accepts an optional callback directly, catches callback failures, and logs fetch-interceptor: onRequestHeaders() failed:.installFetchInterceptor() now shares mayBeLLMRequest(), isLocalHost(), rewriteRequestForProtocol(), applyGatewayHeaders(), and observeRequestHeaders() with the public request primitive while retaining body-shape protocol detection for nonstandard LLM-looking paths.${upstream.host}${upstream.pathname}; direct gateway traffic bypasses rewriting but still supports auth-header observation.packages/core/test/fetch-interceptor-request.test.ts adds 7 rewriteRequest behaviors: 1. route a V2-style OpenRouter request without losing method, body, auth, API key, path, or query; 2. preserve caller-set x-lore-session-id; 3. return a direct gateway request unchanged while observing headers; 4. return local requests unchanged for 4 loopback URL forms; 5. return a non-LLM npm registry request unchanged; 6. route a streaming body on a known path without reading it; 7. neither read nor route a streaming body on an unknown path.https://openrouter.ai/api/v1/chat/completions?stream=true&trace=abc to https://gateway.example.com/v1/chat/completions?stream=true&trace=abc, preserves POST, Bearer sk-test, api-key-test, and the JSON body, and sets x-lore-upstream-url: https://openrouter.ai/api plus x-lore-upstream-path: /api/v1/chat/completions.https://api.anthropic.com/v1/messages to https://gateway.example.com/v1/messages, leaves request.bodyUsed === false, and allows the routed request to yield stream body.https://api.example.com/v2/chat/completions?stream=true; rewriteRequest() must return the identical request, leave request.bodyUsed === false, and preserve body content containing "model":"gpt-5".packages/opencode/src/internal.ts implements parseUpstreamExtraHeaders(value) by splitting on \n, using the first :, trimming names and values, retaining empty header values, ignoring lines without a valid nonempty name, and naturally trimming CR from CRLF input.packages/opencode/src/index.ts now uses parseUpstreamExtraHeaders(process.env.LORE_UPSTREAM_EXTRA_HEADERS) instead of inline parsing, while still filtering each parsed header through shouldForwardUpstreamExtraHeader() before assigning it to output.headers.packages/opencode/package.json adds optional peer dependency @opencode/plugin: >=0.0.0, dev dependency @opencode/plugin: 0.0.0-beta-19378, includes dist/ in published files, changes build to tsx script/build.ts, and adds the ./server export while preserving the existing legacy root export.pnpm-lock.yaml records packages/opencode with @opencode/plugin specifier/version 0.0.0-beta-19378, @opencode-ai/plugin resolved to 1.2.15, and @opencode-ai/sdk resolved to 1.2.15./home/byk/Code/opencode-lore-v2/packages/core/test/fetch-interceptor-request.test.ts, /home/byk/Code/opencode-lore-v2/packages/core/test/fetch-interceptor-paths.test.ts, /home/byk/Code/opencode-lore-v2/packages/core/test/fetch-interceptor-install.test.ts, /home/byk/Code/opencode-lore-v2/packages/core/test/fetch-interceptor-global.test.ts, and /home/byk/Code/opencode-lore-v2/packages/core/test/fetch-interceptor-body.test.ts.