Dashboard › opencode › Distillation
dd7e9d43-c5f6-485c-99d6-657355a32680["lore_tm_v1_88RleaPeyQJYc7Lrg2OCco84GSzr69_jV9QuZgApP5c","lore_tm_v1_B7k_CrV0euQsiL6L-73MonmZdolTda77NAqXrPKNQI0","lore_tm_v1_vz6xySGZrOVAgd83G0_2DgQKqpOhLYUkER8e6Cums_U","lore_tm_v1_HBdchm74MfHKTpGFB2-lWRF8Cpb1zyPT1USkdBaLYHw","lore_tm_v1_19K8BjuO39TVFLa_P_UMwmgA-EyqqFAMaQngAG885KU","lore_tm_v1_du6sxCwzqIV0OnWUpZUyUEeavjR1SRA9nORIYWIlThw","lore_tm_v1_Gm4r-CkTcvXnR8jRo8RYa-dAAp2QsoRmjQoDteFiG5Q","lore_tm_v1_t7EAXUJpKL9JTZW59j2If0q-9tIIcJq3eYu2Fi6RNPM","lore_tm_v1_Jvbb_7oGOE2bxjb03GY30nvCDeClTJIGFJlJPpzEm4U","lore_tm_v1_UGEfJN1LmwLjFm_Lgu-sjCRKwSBIXb8ucZUYLlci3Ic","lore_tm_v1_zXwEITYhV4BfOxEXjkzLgGMcd74W0oUvWtF1FcKQzQY"]
packages/opencode/src/server-runtime.ts defines shared gateway leasing through gatewayLeasePromise: Promise<GatewayLease> | undefined; each GatewayLease tracks refs, gatewayBase, gatewayHeaders, optional shutdown, and optional closing. acquireGatewayLease() waits for an in-progress close before retrying, increments refs, and clears a rejected shared promise; releaseGatewayLease() decrements refs, shuts down only at zero references, and clears the active promise after shutdown finishes.acquireServerRuntime(projectPath, dependencies) stays inactive under NODE_ENV=test or a .test. argv entry unless LORE_OPENCODE_FORCE_ACTIVE=1, and stays inactive when LORE_DISABLED=1. It resolves gitRemote via injected gitRemote or getGitRemote, and returns an idempotent release().packages/opencode/src/server-runtime.ts is: 1. probe LORE_REMOTE_URL after removing one trailing slash and fall through if unreachable; 2. probe LORE_GATEWAY_URL; 3. try @loreai/gateway’s readPortFile(); 4. probe known ports 3207 and 5673; 5. if none responds, dynamically import @loreai/gateway and call startGateway({ quiet: true, local: true }). An owned gateway contributes its shutdown; a non-owned one does not.buildServerHeaders() emits gateway access headers plus x-lore-session-id, x-lore-agent, x-lore-project, x-lore-git-remote, and x-lore-provider; it conditionally emits x-parent-session-id, reads provider-specific upstream URLs from LORE_UPSTREAM_${providerID.toUpperCase().replace(/-/g, "_")}, and forwards only approved entries parsed from LORE_UPSTREAM_EXTRA_HEADERS.wlpqmtos 151df821 lore-v2-plugin | feat(opencode): add V2 server plugin, based on uutomtup 42911412 main | fix(gateway): preserve large recall continuations (#1730), had 9 changed files, exactly 2,498 insertions and 79 deletions: added packages/core/test/fetch-interceptor-request.test.ts, packages/opencode/src/server-runtime.ts, packages/opencode/src/server.ts, packages/opencode/test/server-runtime.test.ts, and packages/opencode/test/server.test.ts; modified packages/opencode/package.json, packages/opencode/src/index.ts, packages/opencode/src/internal.ts, and pnpm-lock.yaml. pnpm-lock.yaml accounted for 1,755 added lines.packages/opencode/src/index.ts caches immutable session parentID values, including successful null results, in sessionParent: Map<string, { parentID: string | null; lastSeenAt: number }> and reaps them using SESSION_STATE_TTL_MS. Failed client.session.get({ path: { id: sessionID } }) lookups are not cached and return null, allowing retries on later turns rather than permanently misclassifying a sub-agent.parentID is forwarded as x-parent-session-id, matching Claude Code’s native Task-sub-agent signal so the gateway can flag the session as a sub-agent and size LTM injection accordingly for issue #1300.packages/opencode/src/index.ts treats NODE_ENV=test or any .test. argv entry as inert to avoid starting/probing a gateway or patching globalThis.fetch; LORE_OPENCODE_FORCE_ACTIVE=1 overrides this while retaining test-mode log suppression and DB isolation, mirroring LORE_PI_FORCE_ACTIVE./home/byk/Code/opencode-v2-pilot found at least 100 uses of location scoping. The V2 API distinguishes location.directory from location.project.directory, and often includes location.workspaceID; representative consumers include session creation/movement/context, config discovery and plugins, filesystem/file access, VCS, worktrees, snapshots, shell/PTY, RPC, and plugin host code.packages/opencode/src/server.ts imported nonexistent rewriteLoreRequest from @loreai/core, defined hidden subagents lore-distill (“Lore memory distillation worker”), lore-curator (“Lore knowledge curator worker”), and lore-query-expand (“Lore query expansion worker”), and acquired runtime using ctx.location.project.directory.ctx.agent.transform() to set each Lore worker’s description, mode="subagent", and hidden=true; 2. ctx.session.hook("model.request", ...) to fetch the session, build attribution/routing headers, mutate event.headers, and set event.baseURL to ${runtime.gatewayBase}/v1 when x-lore-upstream-url exists; 3. ctx.session.hook("http.request", ...) to rewrite event.request.Promise.all, releases the runtime, and rethrows. Normal cleanup uses Promise.allSettled across registration disposal and runtime.release(), collecting rejected reasons and throwing AggregateError(failures, "Lore plugin cleanup failed") when any cleanup operation fails.../opencode-lore-v2/packages/opencode/src/server.ts and ../opencode-lore-v2/packages/opencode/test/server.test.ts, following investigation of the invalid core rewrite import and parent-session lookup behavior.server.test.ts passed, in order: 1. exports a V2 definition without changing the legacy entrypoint; 2. registers hidden workers and location-scoped routing hooks; 3. disposes prior registrations and releases the runtime when setup fails; 4. routes without a parent header when session lookup fails. server-runtime.test.ts passed: 1. shares an owned gateway until every location releases it; 2. restarts only after the prior owned gateway finishes shutting down; 3. builds attribution headers without forwarding credentials.3.60s, transform 1.95s, setup 634ms, import 2.75s, tests 12ms, and environment 0ms.packages/core/test/fetch-interceptor-request.test.ts contains V2 Request rewrite coverage: 1. routes https://openrouter.ai/api/v1/chat/completions?stream=true&trace=abc to https://gateway.example.com/v1/chat/completions?stream=true&trace=abc while preserving POST method, body, authorization, x-api-key, dynamic Lore headers, original request body usability, upstream URL https://openrouter.ai/api, and upstream path /api/v1/chat/completions; 2. preserves caller-set x-lore-session-id=request-session over dynamic session-123; 3. returns a direct gateway request unchanged while observing its headers; 4. leaves local requests unchanged for localhost, 127.0.0.1, 0.0.0.0, and [::1]; 5. leaves a non-LLM npm registry request unchanged; 6. routes a ReadableStream body on known path /v1/messages without consuming the original; 7. leaves a streaming body on unknown path /v2/chat/completions?stream=true unchanged and unread.packages/core/src/fetch-interceptor.ts uses fetch-level interception instead of overwriting provider base URLs early, preserving original provider authentication and URL context while rerouting outgoing LLM calls through the Lore gateway./v1/..., /api/v1/..., /api/..., /openai/v1/..., /anthropic/v1/..., and ChatGPT Codex /codex/responses; canonical endpoints are messages, chat/completions, and responses. NON_STANDARD_PATH_REWRITES maps /codex/responses to /v1/codex/responses.model exists and input is an array or max_output_tokens/previous_response_id exists; Anthropic when top-level system exists alongside a messages array; OpenAI Chat as the fallback for model plus a messages array. Ambiguous markers such as store and instructions are intentionally excluded.system — it embeds” system messages inside the messages array.Request bodies are deliberately not read for body-shape detection because consuming them would break forwarding. Synchronously readable bodies are limited to strings, ArrayBuffer, and typed-array views decoded as UTF-8; failures return undefined.fetch-interceptor.ts preserves the client’s complete original endpoint pathname as x-lore-upstream-path, allowing the gateway to reconstruct origin(base) + pathname; this supports paths without /v1, including GitHub Copilot’s /chat/completions from issue #1052, and paths with non-standard prefixes.