Dashboard › opencode › Distillation
ed15eef8-5f91-4174-9b91-4bf18fea98e6["lore_tm_v1_1bTxCWObJvooWXtbrcupnVKruTvL-THDMH_p0RFN36M","lore_tm_v1_k4X__oIEFSF7ViVvNpy-xam2o26ho_a39bjHafTAmmk","lore_tm_v1_IkiW1dbF835b8NlHCiVFvb6MTAJFzbtiNf58fdEk3ec","lore_tm_v1_nEeZy4QJuj-6EDUwl6FceN54N61nS_u_BoLpq3NPYBY","lore_tm_v1_X8JqZYNW1equY48Jnq2dhL-LTavyeR-N2GlhmyEjT1k","lore_tm_v1_EzJhqkwUylSBgNtFC3kXLFULFTzVAZdHj2ll9d_Ot6Q","lore_tm_v1_jlEg9h8FG1eGNilnG21uF7EJpejm7jtPflRM_61CGQY","lore_tm_v1_Ht-rKhai-F7kEN41uUtrSC0A8190M5g-vMG3Be-PoY4","lore_tm_v1_M0Mw_3YmbbyjtNBELmyLQ-U0l1EEnaqM8enN6sdfUco","lore_tm_v1_J8qRuayMK5crXL6gScBTjnMy9csdYcirr6rnLeDCADo","lore_tm_v1_wgIez0kc4PgsDmSbveLtg1_MGgZrXe93eh7NJRZguq8","lore_tm_v1_qlz-xRYE5DAbqGU8Ezy61E4kbhIP_G8jCOkm5ehgNSk"]
/home/byk/Code/opencode-lore-v2/packages/opencode/package.json defines @loreai/opencode version 0.40.0, ESM ("type": "module"), license FSL-1.1-Apache-2.0, description "Three-tier memory architecture for OpenCode — distillation, not summarization", and author BYK.@loreai/opencode uses ./src/index.ts for main and types; package export "." maps types, bun, and default to ./src/index.ts, while "./server" maps types to ./src/server.ts and bun/default to ./dist/server.js.@loreai/opencode scripts are "typecheck": "tsc --noEmit" and "build": "tsx script/build.ts".@loreai/opencode peer dependencies are @opencode-ai/plugin >=1.1.0 and optional @opencode/plugin >=0.0.0; dependencies are @loreai/core: workspace:* and @loreai/gateway: workspace:*; dev dependencies are @opencode-ai/plugin ^1.1.39, @opencode-ai/sdk ^1.1.39, @opencode/plugin 0.0.0-beta-19378, and @types/bun ^1.2.0.@loreai/opencode publishes src/, dist/, README.md, and LICENSE publicly; repository is git+https://github.com/BYK/loreai.git, directory packages/opencode; keywords are opencode, plugin, memory, agent, distillation, and llm./home/byk/Code/opencode-lore/packages/gateway/src/lifecycle-lock.ts uses AsyncLocalStorage<LifecycleLock> as lockContext, exports withoutLifecycleLock<T>(), acquireLifecycleLock(), and withLifecycleLock<T>().withLifecycleLock<T>() in /home/byk/Code/opencode-lore/packages/gateway/src/lifecycle-lock.ts provides async-context reentrancy: an inherited lock is validated with inherited.assertOwned() and reused; otherwise it calls acquireLifecycleLock(operation, options), runs the action under lockContext.run(), and releases the lock in finally.withLifecycleLock<T>() performs a post-action invariant for operation === "hosted-install": if readUninstallTombstone(lock.path) !== null, it throws "Fresh install did not clear the uninstall marker after verifying its binary/receipt generation"./home/byk/Code/opencode-lore-v2/packages/opencode/script/build.ts deletes and recreates dist, then bundles src/server.ts to dist/server.js with esbuild using format: "esm", platform: "node", target: "esnext", sourcemap: true, logLevel: "info", and externals ["@opencode/plugin", "@loreai/gateway"]./home/byk/Code/opencode-lore/packages/gateway/src/index.ts imports ../instrument and exports loadConfig, DEFAULT_PORTS, DEFAULT_PORT, GatewayConfig, startServer, handleRequest, resetPipelineState, readPortFile, readGatewayProcessFile, startGateway, probeGateway, probeGatewayProcess, probeGatewayProcessHost, probeUrlFor, GatewayHandle, StartOptions, and runCli.runCli is the Stricli-driven entry for help, version, whoami, logs, stop, log, and diff, with fallback to legacy _cli() for commands not yet migrated; _cli() remains exported for compatibility during the migration window./home/byk/Code/opencode-lore-v2/packages/core/src/fetch-interceptor.ts only intercepts known LLM API paths on remote hosts.rewriteRequest() never reads the request body, allowing known paths to carry streaming bodies safely.shouldIntercept() checks url.startsWith(gatewayBase), and rewriteRequestForProtocol() returns the original request for that case after observing its headers.isLocalHost() are localhost, 127.0.0.1, 0.0.0.0, ::1, and [::1].mayBeLLMRequest() considers URLs containing /messages, /completions, or /responses as potentially requiring LLM routing or direct-gateway authentication observation.rewriteRequest(request, gatewayBase, dynamicHeaders, onRequestHeaders?) delegates to rewriteRequestForProtocol() with new URL(gatewayBase).rewriteRequestForProtocol() returns the original request when mayBeLLMRequest(request.url) is false, when the upstream hostname is local, or when neither matchesLLMApiPath() nor protocol-based routing produces a rewrite.new Request(rewrite.gatewayUrl, request), then receives gateway headers via applyGatewayHeaders(routed.headers, rewrite.upstreamBase, rewrite.upstreamPath, dynamicHeaders) and is passed to observeRequestHeaders().X-Lore-Upstream-URL for the upstream base and X-Lore-Upstream-Path for the original endpoint pathname/verbatim forwarding; 4. inject dynamic X-Lore-* context headers from getHeaders(); 5. preserve all original headers, including authorization and content type./home/byk/Code/opencode-lore-v2/packages/core/src/index.ts exports rewriteRequest./home/byk/Code/opencode-lore-v2/packages/opencode/src/internal.ts intentionally keeps helper functions out of ./index.ts because OpenCode’s legacy getServerPlugin/getLegacyPlugins loader invokes every exported function as a plugin.applyLoreProviderConfig() from the plugin entry caused the loader to invoke it as a plugin and push its undefined return value into the host hooks array; first dispatch then crashed with undefined is not an object (evaluating 'A.event') because optional chaining guarded .event, not the undefined hook-array element. Fix/design: keep helpers in src/internal.ts so src/index.ts exposes only the plugin function while tests import helpers directly.isLoopbackUrl() recognizes case-normalized localhost, localhost., ::1, and any address matching /^127(?:\.\d{1,3}){3}$/, stripping IPv6 brackets first.gatewayAccessHeadersForRemote() injects { [GATEWAY_AUTH_HEADER]: LORE_GATEWAY_AUTH_TOKEN } only when LORE_REMOTE_URL, after trimming trailing slashes, exactly matches gatewayBase with trailing slashes removed and a token exists.shouldForwardUpstreamExtraHeader() rejects all x-lore-* headers plus x-api-key, x-goog-api-key, and authorization, case-insensitively.parseUpstreamExtraHeaders() splits newline-delimited headers at the first :, trims names and values, ignores lines without a colon after a nonempty name, and returns Array<[string, string]>.probeLoopback() uses Node http.request or https.request with method GET and an AbortSignal, consumes the response, and considers status codes from 200 through 299 successful.applyLoreProviderConfig() pins every configured OpenCode provider’s options.baseURL to ${gatewayBase}/v1, deep-merging each provider so custom headers, model overrides, and other existing provider keys/options are preserved.OPENAI_BASE_URL while stripping /v1, causing the SDK to send http://host/messages; the gateway routes only /v1/messages, and the fetch interceptor intentionally skips 127.0.0.1, so the bare /messages request returned 404.resolveSDK() always supplies options.baseURL to the @ai-sdk factory, while loadOptionalSetting() consults an environment variable only when the factory gets an undefined baseURL; providers including Google, Mistral, Groq, Cohere, xAI, Perplexity, Together AI, Vercel, Alibaba, DeepInfra, Gateway, OpenRouter, and Cerebras have no base-URL environment variable. Iterating over cfg.provider is therefore the universal lever.applyLoreProviderConfig() sets headerTimeout: false for provider IDs openai and openai-codex, overriding OpenCode’s Codex 10s header deadline because Lore may take longer while preparing context and the gateway owns the foreground request deadline.applyLoreProviderConfig() creates a default openai provider with { options: { baseURL: baseUrl, headerTimeout: false } } if one does not already exist; it does nothing when gatewayBase is empty.applyLoreProviderConfig() is exported for direct unit testing because its config-hook merge logic can be tested without starting a real gateway; the surrounding LorePlugin skips gateway startup when NODE_ENV=test.probeGateway(baseURL, timeoutMs = 1500) checks ${baseURL}/health, uses probeLoopback() for loopback URLs and fetch() otherwise, returns false on any exception, aborts after 1500ms by default, and always clears its timer.surfaceGatewayUnavailable() reports a fatal Lore-unavailable condition both through log.error(message) and a TUI-safe toast with { title: "Lore", message, variant: "error" }.process.stderr.write: embedded/TUI mode hard-silences the core logger’s stderr, whereas showToast posts over HTTP and renders inside OpenCode’s TUI loop without corrupting the full-screen display./tui/show-toast, rejected promises, and synchronous showToast failures are all swallowed./home/byk/Code/opencode-lore-v2/packages/core/src/log.ts treats only LORE_DEBUG=1 or case-insensitive LORE_DEBUG=true as enabling debug output; the prior truthiness check incorrectly enabled logging for nonempty values such as LORE_DEBUG=0 and LORE_DEBUG=false.~/.local/share/lore/lore.log independently of LORE_DEBUG; informational and warning messages are otherwise suppressed unless debug is enabled.silenceStderr() suppresses all stderr output, including errors and output when LORE_DEBUG=1, because the TUI is considered sacrosanct; the file and other sinks remain available.