Dashboard › opencode › Distillation
8acc8a2d-2231-462e-8271-866a61afd3c6["lore_tm_v1_U3ByotAgIBfzZu9ieNcuVppbMKRDx9txIN95xYPcH4Y","lore_tm_v1_-wn18fhQK1ziZFQSpdTv7VsEe6jdnrEJmcyTj1mC8VA","lore_tm_v1_LTTz93PVBOQ37ElsEPUH2jliF-V_C_wHV_48XlGoT8Q","lore_tm_v1__eoScunVhDp_LMJoArI_NlW2RNGuMRVNM-mgL-F8bDo","lore_tm_v1_kIs3TPWqeXVsCS6ITRe7h0xaEneW5Rx5oFgwmt00IME","lore_tm_v1_znW_VY1biRTcFDDKSjFN2mZDMIt7nii-IWo-iNRjfk0","lore_tm_v1_umph1rmsK82LbnYWpFrL1zh-VRi0uqJoz9UmlSachPs","lore_tm_v1_IjFqHS9BNXXtAsWDrbJxWoZuyFg5ICnbw0pNDCsgSOE","lore_tm_v1_7mtMcBb96Uvc9Wxl2FJBH4a128UwIoWzUaVdBNjABNA","lore_tm_v1_tbuhRXw9Uhxp0rFIvGuOucgKCCmKqBtOTqAWctnjKUc","lore_tm_v1_NCNgSFCQXqvfMPyHmmPAkq2NSO2AHkgtrHtbfL9dhtM","lore_tm_v1_LgEPbF1EHfeVClYxJUJDn9b4qf-d7Mrt4kl05Yr4U-I"]
packages/plugin/src/promise/adapter.ts implementing fromPromise(plugin: Plugin), which adapts Promise plugins into the existing Effect-only Core runtime while attaching setup-time hook registrations to the plugin scope and preserving the captured fiber context for boot-time transform batching.packages/plugin/src/promise/adapter.ts: makeStreams() creates separately scoped async iterators, tracks their close() functions, closes all subscriptions when the plugin unloads, supports AbortSignal, removes abort listeners on close, and closes iterators on completion or error.rpcFromEffect(): client method calls use Effect.runPromiseWith(context) and pass options?.signal; event APIs expose subscribe and on; on combines cancellation through AbortSignal.any, logs asynchronous handler failures with Effect.logError, and returns a disposer that aborts its controller.ReturnedRpcError, hostRpcError(), and the handler context’s error(type, message, data); a returned ReturnedRpcError is converted into an Effect failure, while non-ReturnedRpcError values pass through unchanged.compileEndpoint() using a WeakMap<object, CompiledEndpoint> cache, rejecting payload or success schema cardinalities greater than 1 with Unsupported API schema cardinality: ${endpoint.identifier}, decoding params/query/headers/payload, treating absent success schemas as HttpApiSchema.NoContent, and unwrapping a sole data property before output encoding.adaptApiMethod() decoding API input with Schema.decodeUnknownEffect, merging decoded components through Object.assign({}, ...decoded), invoking the host method, returning undefined for no-content endpoints, and otherwise encoding the result through the compiled success schema.fromPromise() managed by Effect.acquireRelease: plugin.setup(context2) may return cleanup, and that cleanup is awaited on release when present.executePromiseTool(): progress updates run through Effect.runPromise(context.progress(update)); TypedFailure becomes Tool.Error whose message prefers a string feedback, then an Error.message, then String(error.error); other failures become Effect defects via Effect.die(error).packages/plugin/src/promise/registration.ts types: Registration.dispose(): Promise<void>; ModelHookOptions.providerID?: string; Hooks<Spec> and ModelHooks<Spec> callbacks may return Promise<void> | void; model hooks accept options only for specs containing model; and Transform<Input> returns Promise<Registration>.parentID is forwarded as x-parent-session-id.packages/opencode/src/index.ts disabling built-in compaction with cfg.compaction = { auto: false, prune: false } because the Lore gateway handles compaction.lore-distill (“Lore memory distillation worker”), lore-curator (“Lore knowledge curator worker”), and lore-query-expand (“Lore query expansion worker”). Each requires mode: "subagent" for hidden: true to prevent it appearing in the primary Tab picker and the @-mention/skill list."chat.headers" hook adding gateway access headers, stable x-lore-session-id, x-lore-agent, optional x-parent-session-id, optional x-lore-project, and optional x-lore-git-remote; per-request project metadata is set in the hook to avoid concurrent sub-agents or sibling projects clobbering one another.currentProject = { path: thisProjectPath, gitRemote: thisGitRemote } fallback updated on every plugin call, used only for requests that bypass "chat.headers" such as direct SDK fetches and embedding/image generation.packages/opencode/src/internal.ts intentionally kept separate from the plugin entry module because OpenCode’s legacy getServerPlugin/getLegacyPlugins loader treats every exported function as a plugin and invokes it. Previously, exporting applyLoreProviderConfig from the entry module caused its undefined return value to enter the hooks array and crash first hook dispatch with undefined is not an object (evaluating 'A.event').gatewayAccessHeadersForRemote() only returns { [GATEWAY_AUTH_HEADER]: LORE_GATEWAY_AUTH_TOKEN } when normalized LORE_REMOTE_URL exactly matches normalized gatewayBase and a token exists.shouldForwardUpstreamExtraHeader() rejecting all x-lore-*, x-api-key, x-goog-api-key, and authorization headers because provider and Lore credentials are applied by the gateway rather than forwarded by this hop.applyLoreProviderConfig() pinning every configured provider’s options.baseURL to ${gatewayBase}/v1 while deep-preserving provider fields and existing option keys; openai and openai-codex additionally receive headerTimeout: false, and a missing openai provider is created with { options: { baseURL: baseUrl, headerTimeout: false } }.OPENAI_BASE_URL by stripping /v1, causing requests to hit bare /messages and return 404; resolveSDK() always supplies options.baseURL, preventing @ai-sdk environment fallback, while many other providers have no baseURL environment variable. Iterating through cfg.provider was identified as the universal configuration lever.probeGateway(baseURL, timeoutMs = 1500) requesting ${baseURL}/health, using native http/https for loopback hosts and fetch otherwise, returning false on every caught failure, aborting after 1500 ms by default, and always clearing its timer.process.stderr.write, while remaining user-visible despite log.silenceStderr().@opencode/plugin version 1.18.15 with scripts test: "bun test --only-failures", typecheck: "tsgo --noEmit", and build: "tsc -p tsconfig.build.json"; exports include ".", "./effect", "./host", "./tui", and "./*".packages/plugin/tsconfig.build.json extending ./tsconfig.json with allowImportingTsExtensions: false and noEmit: false.Host.resolve must never execute plugins during resolution; packages/plugin/test/host.test.ts enforces this by making every fixture entrypoint contain throw new Error("Plugin code must not run during resolution").Host.resolve resolution scenarios in packages/plugin/test/host.test.ts, in order: 1. conventional index.ts, tui.tsx, and rpc.ts without package.json; 2. a TUI-only directory containing only tui.tsx; 3. packages without exports using either default index.js or main: "lib/backend.js", plus tui.js and rpc.js; 4. local conventional index.js, tui.js, and rpc.js with package.json but no exports; 5. explicit "./server" preferred over root ".", alongside "./tui" and "./rpc"; 6. root-export fallback using import rather than require conditions; 7. TUI-only exports without falling back to unexported index.js, server.js, or rpc.js; 8. a missing exported file producing { server: undefined, tui: undefined, rpc: undefined }.PluginModule.load() as directories; only legacy auto-discovery still permits standalone local server source files.packages/core/src/plugin/module.ts resolving absolute local file targets directly as { server: pathToFileURL(operation.target).href }, while directories and packages use Host.resolve(installed ?? { directory: operation.target }).PluginModule.load(): options?.install === false uses npm.resolve(operation.target), otherwise npm.add(operation.target); a missing unresolved entrypoint returns { pending: true } only in no-install mode, while other missing entrypoints raise PluginModule.LoadError with Plugin entrypoint not found: ${operation.target}.id plus either an effect or setup function; validation failure reports Plugin must export a default definition with an id and an effect or setup function.PluginPromise.fromPromise(value), while Effect definitions are used directly.PluginModule.load() always passes options: operation.options into the plugin host via plugin.effect({ ...host, options: operation.options }).features.tui and features.rpc, a revision serialized as JSON.stringify([operation, loaded.version]), and either a local source using fileURLToPath(entrypoint) or a package source containing target and optional installed version.packages/core/src/plugin/module.ts: each file is watched only once; watchTarget() recursively finds the nearest existing ancestor for missing dependency paths; watcher updates publish to an unbounded PubSub; and createPluginSources() is disposed through Effect.acquireRelease.