Dashboard › opencode › Distillation
18bf5194-a87c-4323-aa02-060aa5df1c5a["lore_tm_v1_STG6CesP54UhuRgeREyHuFNiAaUB43YKx9a38aDcTyA","lore_tm_v1_R7NXrRzhrPfi9TKhZ5ahhpM9MVhkhGXW5tYPxw_mjFM","lore_tm_v1_ote0Q3iT_IBRb43PVbbRFo1GylgWMkOtRlq0wd3ucQs","lore_tm_v1_LZi8DtI6ndg9RjkDrSB0828dQeeijLk5y11POJDr4cE","lore_tm_v1_EHa-ovJsUcx2Tvmczpp70LVdItAmyZAqPtZ8QHq-n5A"]
Date: Sep 9, 2026
/home/byk/Code/opencode/packages/plugin/src/v2/effect/README.md states V2 plugin setup registers hooks imperatively and does not return a hook object; plugin configuration is available as ctx.options.dispose can remove a registration early.ctx.agent.transform, ctx.catalog.transform, ctx.command.transform, ctx.integration.transform, ctx.reference.transform, and ctx.skill.transform.ctx.aisdk.sdk may dynamically import an AI SDK package and assign event.sdk; ctx.aisdk.language may assign event.language. Hooks execute sequentially in registration order, and later hooks observe earlier mutations.ctx.catalog.reload() reruns every active catalog transform and publishes the rebuilt catalog. Available operations are ctx.agent.reload(), ctx.catalog.reload(), ctx.command.reload(), ctx.integration.reload(), ctx.reference.reload(), and ctx.skill.reload()./home/byk/Code/opencode-lore/packages/opencode/src/internal.ts intentionally keeps helpers outside the plugin entry module ./index.ts. OpenCode’s legacy loader treats every exported function as a plugin instance and invokes it; exporting applyLoreProviderConfig from the entry module caused its undefined return value to enter the hooks array and crash dispatch with undefined is not an object (evaluating 'A.event').isLoopbackUrl(value) in /home/byk/Code/opencode-lore/packages/opencode/src/internal.ts recognizes localhost, localhost., ::1, and IPv4 addresses matching /^127(?:\.\d{1,3}){3}$/; malformed URLs return false.gatewayAccessHeadersForRemote(gatewayBase, env = process.env) strips trailing slashes from LORE_REMOTE_URL and gatewayBase, and returns { [GATEWAY_AUTH_HEADER]: LORE_GATEWAY_AUTH_TOKEN } only when the normalized URLs match and the token exists; otherwise it returns {}.shouldForwardUpstreamExtraHeader(name) rejects case-insensitive headers beginning with x-lore- and the exact names x-api-key, x-goog-api-key, and authorization; provider and Lore credentials are applied by the gateway, never this hop.probeLoopback(url, signal) uses node:http or node:https according to the parsed protocol, sends GET with the supplied AbortSignal, drains the response via response.resume(), and considers only HTTP status codes from 200 through 299 successful.applyLoreProviderConfig(cfg, gatewayBase) pins every configured OpenCode provider’s options.baseURL to ${gatewayBase}/v1; it returns immediately when gatewayBase is empty and deep-merges each provider so existing keys, custom headers, model overrides, and other options are preserved.resolveSDK() always passes options.baseURL to the @ai-sdk factory. Therefore @ai-sdk’s loadOptionalSetting() does not consult an environment variable unless the factory receives an undefined baseURL.OPENAI_BASE_URL by stripping /v1, causing requests to reach http://host/messages; the Lore gateway routes only /v1/messages, and its fetch interceptor skips 127.0.0.1 to avoid loops, so the bare /messages request returns 404.@ai-sdk providers—including Google, Mistral, Groq, Cohere, xAI, Perplexity, Together AI, Vercel, Alibaba, DeepInfra, Gateway, OpenRouter, and Cerebras—have no baseURL environment variable, making iteration over cfg.provider the universal configuration mechanism.applyLoreProviderConfig forces headerTimeout: false for provider IDs "openai" and "openai-codex" because Lore context preparation can exceed OpenCode Codex’s 10-second header deadline; OpenCode installs its default before this hook runs, so Lore overrides rather than preserves it, while the gateway owns the foreground request deadline.openai provider exists, applyLoreProviderConfig creates pinned.openai = { options: { baseURL: baseUrl, headerTimeout: false } }; it finishes with cfg.provider = { ...existingProvider, ...pinned }.applyLoreProviderConfig is exported for direct unit testing so merge logic can be verified without launching a 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(...).ok otherwise, aborts after 1500 ms by default, returns false on every caught failure, and always clears its timeout.surfaceGatewayUnavailable(client, message) calls log.error(message) for the file and Sentry sinks. In embedded/TUI mode, log.silenceStderr() makes stderr invisible to users, so the function uses an OpenCode showToast request as the user-visible, TUI-safe notification channel.showToast path never writes a raw byte to the terminal; it posts to the OpenCode server over HTTP and renders inside the TUI render loop, avoiding the screen corruption caused by the replaced process.stderr.write.surfaceGatewayUnavailable is fire-and-forget and must swallow every failure: a missing or headless TUI, or an older server lacking /tui/show-toast, must not convert a degraded-but-running session into a crash.Hooks is defined in /home/byk/Code/opencode/packages/plugin/src/v2/effect/registration.ts; it is used by SkillHooks in skill.ts, ReferenceHooks in reference.ts, IntegrationHooks in integration.ts, CommandHooks in command.ts, CatalogHooks in catalog.ts, AISDKHooks in aisdk.ts, and AgentHooks in agent.ts. context.ts imports AgentHooks, AISDKHooks, CatalogHooks, CommandHooks, IntegrationHooks, ReferenceHooks, and SkillHooks./home/byk/Code/opencode/packages/plugin/src/v2/effect/aisdk.ts defines AISDKHooks = Hooks<{ sdk: ...; language: ... }> and imports LanguageModelV3 from @ai-sdk/provider, ModelV2Info from @opencode-ai/sdk/v2/types, and Hooks from ./registration.js.AISDKHooks.sdk event has readonly model: ModelV2Info, readonly package: string, readonly options: Record<string, any>, and mutable optional sdk?: any.AISDKHooks.language event has readonly model: ModelV2Info, readonly sdk: any, readonly options: Record<string, any>, and mutable optional language?: LanguageModelV3.