Dashboard › opencode › Distillation
7a92f097-af1a-441b-a38f-2c0a2f60aa8f["lore_tm_v1_P8WMyn7Mv-EcIDo0e5Sx0S2Q-bl3Bu_q7cVmgYJghsE","lore_tm_v1__Lidmx9AADD5S3DwsCuEty0hf9GoxMznfaIdqjVIhwc","lore_tm_v1_9n_qUCjtKg7a0uPMuy7GF3Dvb6RDrcTyGx-YHOL1sTc","lore_tm_v1_JxMG4lDxhO3xm9niX8cqprbA8xh5TI9H-ncVhGV12Dc","lore_tm_v1_Zt0jRrqhuGLJBoJZb5m9u7SdwyH3XPffYjUkwHNZFJg","lore_tm_v1_acdazJUmM-0NRHU0NKJx7Jx-HsBcWBJ4gdFoo1MOils","lore_tm_v1_LzaAuS55XGsWSneFPP0Ey1xBszRg5fUKtyetrteW3Yw","lore_tm_v1_zWRwPDCBe5dWZ7bmhPLUGrCZogJWslLBxM-K7n1uop8","lore_tm_v1_HrYjH_5IgegYFApfUApIFArPa-OpgOdvySiA2aXeT1s","lore_tm_v1_RJcuCCWueiC99lyfXcB1UNYcf2y6PF1ljyIuQ35yWAA","lore_tm_v1_qM7vw10NeOZLBtzDG72U9jzDfFOnPN3J7lBw7zkb2Fw","lore_tm_v1_YccWa16U9sFY4sxfvfnZtmknxpZyGstFzovPeLupTV8","lore_tm_v1_dGtPJcLNN2Jv88GpBt9_F8DvML_eBHgAfLREifKgbOo","lore_tm_v1_FGZgt80UQwLrRic9vb4VjvmkLMraepiiqhuKeZbwotw"]
jj-guide workflow: if .jj/ exists, use jj rather than git for mutations; never use interactive flags; always pass -m "msg" when describing/committing; verify mutations with jj st and jj log; prefer stable letter-based change IDs over hex commit IDs; never rebase or describe immutable commits; use jj undo, jj op log, or jj op restore <op-id> for recovery.@, edits auto-amend it without staging, commits remain mutable until pushed, bookmarks do not auto-advance, and the operation log replaces reflog.jj conflict handling must avoid interactive jj resolve; after rebase, new, or squash, run jj st, manually edit conflict markers, and verify that jj st shows the conflict cleared.jj st β jj commit -m "feat: ..." and leaves content in @- with a new empty @; Style B uses jj describe -m "feat: ..." before editing, leaves the completed work in @, and does not run jj new at the end.x..y as set difference from x::y as a DAG path; they are not interchangeable.wlpqmtos, commit 52e6687e1eae, description feat(opencode): add V2 server plugin, with parent change uutomtup, commit 429114122aa1, bookmark main, description fix(gateway): preserve large recall continuations (#1730).2904 insertions(+), 196 deletions(-): modified packages/core/src/fetch-interceptor.ts, packages/core/src/index.ts, packages/opencode/package.json, packages/opencode/src/index.ts, packages/opencode/src/internal.ts, packages/opencode/test/internal.test.ts, and pnpm-lock.yaml; added packages/core/test/fetch-interceptor-request.test.ts, packages/opencode/script/build.ts, packages/opencode/src/server-core.ts, packages/opencode/src/server-runtime.ts, packages/opencode/src/server.ts, packages/opencode/test/package.test.ts, packages/opencode/test/server-runtime.test.ts, and packages/opencode/test/server.test.ts.packages/opencode/test/package.test.ts builds @loreai/opencode, packs it as loreai-opencode.tgz, extracts it to a temporary lore-opencode-package- directory, and removes that directory in afterAll.packages/opencode/test/package.test.ts expects the packed ./server export to be { types: "./src/server.ts", bun: "./dist/server.js", default: "./dist/server.js" }; it verifies dist/server.js contains neither interface LoreServerRuntime, import type , nor @opencode/plugin.packages/opencode/test/package.test.ts imports packed package/dist/server.js via Node --input-type=module --eval without a host SDK and expects the default export to serialize as { id: "lore", setup: "function" }./home/byk/Code/opencode-lore-v2 passed all 5 test files and all 89 tests in 2.09s; transform took 1.63s, setup 2.51s, import 355ms, tests 307ms, and environment 1ms.packages/core/src/fetch-interceptor.ts found exactly 3 gatewayBase prefix guards: line 291 if (url.startsWith(gatewayBase)) return false;, line 354 if (request.url.startsWith(gatewayBase)), and line 531 const targetsGateway = url.startsWith(gatewayBase);.packages/core/test/fetch-interceptor-request.test.ts defines GATEWAY = "https://gateway.example.com" and dynamic headers "x-lore-project": "/home/me/project" plus "x-lore-session-id": "session-123".packages/core/test/fetch-interceptor-request.test.ts verifies rewriteRequest() routes a V2-style POST Request from 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 the JSON body, authorization: Bearer sk-test, content-type: application/json, x-api-key: api-key-test, path, query, and an unused original body.x-lore-project: /home/me/project, x-lore-session-id: session-123, x-lore-upstream-url: https://openrouter.ai/api, and x-lore-upstream-path: /api/v1/chat/completions; its observer is called exactly once with the routed headers.rewriteRequest() preserves a caller-provided dynamic header: a Request with x-lore-session-id: request-session retains that value instead of receiving session-123.${GATEWAY}/v1/messages expects object identity to be preserved, no x-lore-project injection, and the header observer to be called exactly once with the original headers.http://localhost:8000/v1/messages, http://127.0.0.1:8000/v1/messages, http://0.0.0.0:8000/v1/messages, and http://[::1]:8000/v1/messages.https://registry.npmjs.org/package passes through unchanged.https://api.anthropic.com/v1/messages is routed to ${GATEWAY}/v1/messages without reading the original body; the routed body remains "stream body".https://api.example.com/v2/chat/completions?stream=true, preserves Request identity and bodyUsed === false, and later reads content containing "model":"gpt-5".packages/opencode/src/server-runtime.ts defines knownGatewayPorts = [3207, 5673] and dynamically imports gateway package @loreai/gateway.LoreServerRuntime contains gatewayBase, projectPath, gitRemote, gatewayHeaders, and async release; ServerRuntimeDependencies permits injected resolveGateway() and gitRemote(path).acquireServerRuntime() returns undefined in test execution unless LORE_OPENCODE_FORCE_ACTIVE === "1", and returns undefined when LORE_DISABLED is "1" or "true".acquireServerRuntime() acquires a shared gateway lease, obtains the project Git remote with injected gitRemote or getGitRemote, releases the lease if Git-remote discovery throws, and returns an idempotent release() closure.packages/opencode/src/server-runtime.ts are process-shared through gatewayLeasePromise, reference-counted via refs, wait for an active closing promise before reacquisition, clear the shared promise on acquisition failure, and shut down only after the final release.createGatewayLease() first calls resolveGatewayUrl(); when none is found it logs No Lore gateway found, starting in-processβ¦, invokes startGateway({ quiet: true, local: true }), uses http://127.0.0.1:${handle.port}, and retains handle.shutdown only when handle.owned is true.LORE_REMOTE_URL (trim one trailing slash and probe; on failure log and continue), LORE_GATEWAY_URL (trim and probe), an optional @loreai/gateway port-file value, then known ports 3207 and 5673, each probed at http://127.0.0.1:${port}.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.buildServerHeaders() reads provider-specific upstream URLs from LORE_UPSTREAM_${providerID.toUpperCase().replace(/-/g, "_")} into x-lore-upstream-url, and forwards only allowed entries parsed from LORE_UPSTREAM_EXTRA_HEADERS.shouldIntercept() only intercepts known LLM API paths on remote hosts.shouldIntercept() never intercepts Requests already going to the gateway.shouldIntercept() never intercepts local Requests because they may target a local LLM or the gateway itself and could otherwise create an infinite loop.shouldIntercept() never intercepts non-LLM API paths, including arbitrary plugin HTTP calls and health checks.isLocalHost() recognizes exactly localhost, 127.0.0.1, 0.0.0.0, ::1, and [::1].mayBeLLMRequest() considers URLs containing /messages, /completions, or /responses.rewriteRequest() never reads the Request body: known paths can carry streaming bodies safely, while unknown paths always pass through.rewriteRequestForProtocol() observes direct-gateway Request headers before returning the original Request, bypasses local hosts, routes known paths with interceptUrl(), optionally routes body-detected protocols with interceptUrlForProtocol(), and otherwise returns the original Request.applyGatewayHeaders() preserves original headers, sets x-lore-upstream-url, sets x-lore-upstream-path only for an absolute path beginning with /, and adds dynamic headers only when the Request does not already contain them.getHeaders() and onRequestHeaders() callbacks are caught and logged rather than failing the Request.installFetchInterceptor() uses process-global Symbol.for("lore.fetchInterceptor.originalFetch") to prevent interceptor stacking across multiple bundled copies of @loreai/core; a subsequent install returns a no-op cleanup.gateway β interceptor β gateway β β¦, makes it safe to inline core into the Bun gateway bundle for issue #1027, and is reset to null by cleanup./messages, /completions, and /responses; malformed URLs and local non-gateway URLs also call the original fetch unchanged.${upstream.host}${upstream.pathname} via warnedPaths and bypasses the Lore gateway.Object.assign(interceptor, originalFetch) and cleanup restores globalThis.fetch to the captured original.normalize under packages/core/src found exactly 8 matches: normalizeWarmupHistogram() in warmup-histogram.ts:126, normalizeRank() in search.ts:488, normalize() in markdown.ts:152, normalizeHeaderName() in credential-headers.ts:63, normalizeRemoteUrl() in git.ts:37 plus a call at git.ts:150, its export in index.ts:201, and normalizeProvider() in import/auth/opencode.ts:74.@loreai/core@0.40.0 typecheck completed successfully using tsc --noEmit && tsc --noEmit -p tsconfig.eval.json.jj diff --check failed because jj diff does not accept --check; the CLI suggested using -- --check to pass it as a value and displayed jj diff [OPTIONS] [FILESETS]....packages/opencode/test/server.test.ts mocks acquireServerRuntime() with gateway http://127.0.0.1:3207, project /workspace/project, Git remote github.com/example/project, and a release spy; it mocks rewriteRequest() to route to http://127.0.0.1:3207/v1/chat/completions."lore" with a function-valued setup, while the legacy packages/opencode/src/index.ts export surface remains exactly ["LorePlugin", "default"] and default === LorePlugin.lore-distill, description Lore memory distillation worker; 2. lore-curator, description Lore knowledge curator worker; 3. lore-query-expand, description Lore query expansion worker.model.request and http.request hooks and acquires runtime using the project-level location /workspace/project, not nested directory /workspace/project/nested.model.request hook looks up session ses_1, supplies parent ses_parent, agent build, and provider openai to buildServerHeaders(), preserves authorization: Bearer provider, adds x-lore-session-id: ses_1, and rewrites baseURL from https://api.openai.com/v1 to http://127.0.0.1:3207/v1.http.request hook calls rewriteRequest(original, "http://127.0.0.1:3207", {}) and replaces the event Request URL with http://127.0.0.1:3207/v1/chat/completions."registration failed" and disposal also throws "dispose failed", setup still disposes the one prior registration, releases the runtime once, and rejects with the original registration error."unavailable", model routing continues without a parentID/x-parent-session-id while retaining x-lore-session-id: ses_1./workspace/a releases only runtime A, runtime B at /workspace/b remains usable for ses_b, and B is released only when its own cleanup runs.