Dashboard › opencode › Distillation
bd7ef670-1728-4c78-a53a-1783cfa74fe9["lore_tm_v1_QzPV4upRK0UPd1hB5mAzcNEQny0VCvsGOzanU0K90Vc","lore_tm_v1_k3klCTfQH3bjf4tfuoduwEsealc5zBYj1Qp6P0lSbes","lore_tm_v1_ntAPM3psrlWA_wdf4vBnzlo6JdW7KS2A4xVeejADrPw","lore_tm_v1__z0V-Z7taiuNFik1a8tbc9OiS_Un-OS2DiUHSeNOe3M","lore_tm_v1_hR3M5kGbhai2u9c4kpB5h3sAYPQo5pXnE79_o_5FvwM"]
/home/byk/Code/opencode-v2-pilot/packages/plugin/src/promise/aisdk.ts defines AISDKHooks: sdk contains readonly model: Model.Info, readonly package: string, readonly options: Record<string, any>, and optional sdk?: any; language contains readonly model: Model.Info, readonly sdk: any, readonly options: Record<string, any>, and optional language?: LanguageModelV3./home/byk/Code/opencode-v2-pilot/packages/plugin/src/promise/aisdk.ts defines AISDKDomain with readonly hook: ModelHooks<AISDKHooks>.resolveParentSession() in /home/byk/Code/opencode-lore/packages/opencode/src/index.ts is best-effort and must “never break or slow the request path on a lookup failure”; failures return null./home/byk/Code/opencode-lore/packages/opencode/src/index.ts memoizes gateway initialization in loreInitPromise: Promise<string | null> | null, preventing concurrent LorePlugin calls from racing through gateway probe and spawn.isInertTestEnv() keeps the OpenCode plugin inert when NODE_ENV === "test" or any process.argv entry contains .test.; LORE_OPENCODE_FORCE_ACTIVE=1 overrides inertness so tests can exercise discovery, interceptor, and routing through LORE_GATEWAY_URL while retaining test logging and database isolation./home/byk/Code/opencode-lore/packages/opencode/src/index.ts calls log.silenceStderr() because OpenCode owns a full-screen TUI and any stdout/stderr byte corrupts rendering; the process-global flag is shared through globalThis with the embedded gateway’s bundled core, while logs still go to the log file and Sentry sink.resolveGatewayUrl() to detect a running gateway, then calls startInProcess() only when none is found; a successful result sets processLoreActive = true and updates processLoreBase.surfaceGatewayUnavailable(ctx.client, msg). Errors matching not found, not exported, or cannot find module add stale-build guidance to run pnpm --filter @loreai/gateway run bundle or run build; otherwise the message advises ensuring @loreai/gateway is installed.ctx.project.id so concurrent worktrees/projects in one process do not clobber one another. discoverWorkspaceRoot(ctx.worktree || ctx.directory) determines thisProjectPath; getGitRemote(thisProjectPath) is reused only when the cached state has the same path, and each entry stores projectPath, gitRemote, and lastSeenAt.currentProject = { path: thisProjectPath, gitRemote: thisGitRemote } is updated on every plugin call and is only a fallback for fetches without a known session ID, such as direct SDK calls that bypass chat.headers.config hook sets cfg.compaction = { auto: false, prune: false } and registers three internal agents in exact order: 1. "lore-distill" — mode: "subagent", hidden: true, description "Lore memory distillation worker"; 2. "lore-curator" — mode: "subagent", hidden: true, description "Lore knowledge curator worker"; 3. "lore-query-expand" — mode: "subagent", hidden: true, description "Lore query expansion worker".mode: "subagent" is required for hidden: true to work because OpenCode defaults agents to mode: "all" and only hides subagent-mode agents; without it, Lore’s internal workers appear in every host project’s primary Tab picker and @-mention/skill list.config hook calls applyLoreProviderConfig(cfg, gatewayBase) to pin the Anthropic provider’s baseURL to the Lore gateway."chat.headers" hook adds gatewayAccessHeadersForRemote(gatewayBase), sets "x-lore-session-id" to input.sessionID, and sets "x-lore-agent" to input.agent."chat.headers" resolves the session parent and, when found, forwards it as "x-parent-session-id" so the gateway can size LTM injection as tracked by issue #1300; user stated this resolution “never blocks or throws on failure.”"chat.headers" hook injects per-request "x-lore-project" and "x-lore-git-remote" from that plugin invocation’s thisProjectPath and thisGitRemote, preventing concurrent sub-agents or sibling projects from clobbering one another; the fetch interceptor’s getHeaders() remains only a fallback for requests bypassing the hook, such as embedding or image generation."chat.headers" hook reads runtime input.provider.id through a cast to Record<string, unknown> and, when present, sets "x-lore-provider" so gateway routing uses the provider’s correct protocol and upstream URL rather than model-prefix guessing.vllm, ollama, and llamacpp, the plugin derives an environment variable named LORE_UPSTREAM_${providerID.toUpperCase().replace(/-/g, "_")} and sets "x-lore-upstream-url" only when that header is not already present.LORE_UPSTREAM_EXTRA_HEADERS is parsed line-by-line using /\r?\n/; blank lines and lines without a colon after at least one name character are skipped, values may contain further colons, and only headers accepted by shouldForwardUpstreamExtraHeader(name) are copied so gateway-managed headers are not clobbered.log.info() and remain visible through lore logs.installFetchInterceptor({ gatewayBase, getHeaders }), logs routing through ${gatewayBase} and dashboard: ${gatewayBase}/ui, then sets processInitDone = true.getHeaders() begins with gatewayAccessHeadersForRemote(gatewayBase) and conditionally adds "x-lore-project" plus its paired "x-lore-git-remote" from the same currentProject; user stated it must be “never a remote left over from a different project's plugin call.”log.error preserves the cause in the file and Sentry sink even while TUI stderr is silenced./home/byk/Code/opencode-lore/packages/gateway/src/cli/start.ts computes VECTOR_POOL_SHUTDOWN_DEADLINE_MS as Math.max(Math.min(DEFAULT_VECTOR_POOL_SHUTDOWN_DEADLINE_MS, SHUTDOWN_DEADLINE_MS - 500), 500), preserving a 500 ms safety floor even with an aggressive LORE_SHUTDOWN_TIMEOUT_MS, such as 1000 ms.StartOptions in /home/byk/Code/opencode-lore/packages/gateway/src/cli/start.ts supports port?: number, hosts?: string[], debug?: boolean, quiet?: boolean, remoteUrl?: string, local?: boolean, allowRemoteManagement?: boolean, bg?: boolean, and internal processBoundary?: boolean.StartOptions.remoteUrl overrides LORE_REMOTE_URL; local corresponds to CLI --local / -l; bg corresponds to --bg / --daemon and re-spawns the process detached, polls until healthy, prints address/PID/log path, and exits 0.StartOptions.processBoundary is CLI-owned and “never set by in-process plugins.”GatewayHandle exposes config: GatewayConfig, port: number, owned: boolean, owner-only managementToken: string, shutdown: () => Promise<void>, and optional internal processShutdown?: ProcessShutdownController; shutdown() is a no-op when owned is false.GatewayIdentityProbe has exact variants { kind: "authenticated"; identity: GatewayHealthIdentity }, { kind: "rejected" }, { kind: "unavailable" }, and { kind: "timeout" }; GatewayShutdownRequestResult is "accepted" | "unsupported" | "failed".StartGatewayIO contains readProcess, authenticate, writePort, removePort, writeProcess, removeProcess, startServer, resetPipelineState, and createProcessShutdownController; realStartGatewayIO.removeProcess(pid, record?) removes the supplied generation when given, otherwise removes the current record only when its PID matches.isLoopbackProbeUrl() recognizes localhost, localhost., ::1, and any host matching /^127(?:\.\d{1,3}){3}$/; invalid URLs return false.internalProbeFetch(url, init?) uses nodeHttpFetch() for loopback URLs to avoid WHATWG forbidden-port restrictions on valid local listeners, while non-loopback URLs retain normal fetch() transport and semantics.probeGatewayIdentityDetailed(baseURL, token, timeoutMs = 1500) sends an authenticated request to ${baseURL}/_lore/control; it returns "authenticated" only for an OK JSON response with status === "ok", service === "lore", and a positive safe-integer pid, returns "rejected" for non-OK or malformed identity responses, "timeout" for aborts, and "unavailable" for other transport failures.probeGatewayIdentity() is a compatibility wrapper over probeGatewayIdentityDetailed() that returns the authenticated GatewayHealthIdentity or null.probeGatewayProcessStatus(record, timeoutMs = 1500) probes every bound host concurrently and returns "authenticated" if any response authenticates with identity.pid === record.pid; otherwise precedence is "timeout", then "rejected", then "unavailable".probeGatewayStatus(baseURL, timeoutMs = 1500) probes ${baseURL}/health and distinguishes "healthy", "not-running", "error", and "timeout"; only ECONNREFUSED, including recursively uniform AggregateError or cause chains, maps to "not-running".probeGateway() is the boolean compatibility wrapper for non-destructive health checks and returns true only when probeGatewayStatus() returns "healthy".probeUrlFor(host, port) maps bind-all hosts 0.0.0.0 to 127.0.0.1 and :: to ::1, then uses bracketHost() so IPv6 probe URLs are valid, e.g. http://[::1]:3207.probeGatewayProcessHost(record, timeoutMs = 1500) authenticates the persisted process record against every bound host concurrently and returns the first host whose identity PID matches record.pid, or null; probeGatewayProcess() returns whether such a host exists.requestGatewayShutdown(record, timeoutMs = 1500) posts to each host’s /_lore/control using Authorization: Bearer ${record.token}; HTTP 404 maps to "unsupported", other non-OK responses map to "failed", and successful responses are validated against Lore service identity and record.pid.