Dashboard › opencode › Distillation
b974177f-c762-4ad6-9875-55b34a357576["lore_tm_v1_0eK1NfKo2KFYPSb1Suy2NllE3jqnoJckSi26di0omLo","lore_tm_v1_7v3Nn0WqsPfidOsR6QRVLY8nrsPQxeINxCmCymhHsCs","lore_tm_v1_vq0iWwEOd9Xm2WBM3oe9pPNHhbfY0s9YdcBgkQbYIZ8","lore_tm_v1_tN2XfOioMvlx3m8q8UbOSAToENAFpFUscgtAlexB86E","lore_tm_v1_NkWHZ0O2j17B587OtcebznOyvOVMUZYah85z_btbniU","lore_tm_v1_TvPx2tENNYmZTxt-akHXUmO1Rut10Pqu7UWuuj7pWAI","lore_tm_v1_kK4UcpWKra_y3_2RE1z7AFrH2gudyB1yu36vfeNs63U","lore_tm_v1_oZs3VgTdKPAFv-wSYy3i0HA1gfNO5is6ZXH5-ITmPQI","lore_tm_v1_QS1G-l4mQqmXR6qPRGWH5BZP8xeEc9yBxw6Yc2qc8MM","lore_tm_v1_FzGhygRvk33uJ2ka-ll469NyR3Db8OtJNSgBrKmyUmo"]
packages/opencode/src/index.ts imports log, getGitRemote, discoverWorkspaceRoot, and installFetchInterceptor from @loreai/core, while importing applyLoreProviderConfig, gatewayAccessHeadersForRemote, parseUpstreamExtraHeaders, probeGateway, shouldForwardUpstreamExtraHeader, and surfaceGatewayUnavailable from ./internal.packages/opencode/src/internal.ts rather than re-exported from the plugin entry because OpenCode’s legacy plugin loader invokes every exported function as a plugin; leaked helpers previously inserted undefined into the host hooks array and caused event dispatch to crash with undefined is not an object (evaluating 'A.event').baseURLs, preserving each provider’s original authentication, URL context, and headers while routing LLM requests through the Lore gateway.packages/opencode/src/index.ts, built-in compaction is disabled with cfg.compaction = { auto: false, prune: false } because the gateway handles compaction."chat.headers" hook adds gateway access headers from gatewayAccessHeadersForRemote(gatewayBase), sets x-lore-session-id to input.sessionID, and sets x-lore-agent to input.agent.x-session-affinity, whose nanoid is regenerated per process.parentID and forwarding it as x-parent-session-id, which the gateway already understands from Claude Code.resolveParentSession() resolution is cached and never blocks or throws on failure."chat.headers" hook injects x-lore-project from thisProjectPath and x-lore-git-remote from thisGitRemote per request, avoiding path clobbering when concurrent sub-agents or sibling projects share one OpenCode process; the fetch interceptor retains a fallback for requests bypassing the hook, such as embedding or image generation."chat.headers" hook reads the runtime-only provider .id by casting input.provider to Record<string, unknown>, then forwards it as x-lore-provider so gateway routing uses provider identity and the correct protocol/upstream rather than model-prefix guessing.LORE_UPSTREAM_${providerID.toUpperCase().replace(/-/g, "_")} and forwards its value as x-lore-upstream-url when that header is not already set.LORE_UPSTREAM_EXTRA_HEADERS and forwards each permitted literal header only when shouldForwardUpstreamExtraHeader(name) approves it, avoiding clobbering gateway-managed headers; intended consumers include corporate proxies, LiteLLM, and Cloudflare AI Gateway.packages/opencode/src/index.ts, at lines 340, 344, 376, and 386.packages/gateway/test/compaction.test.ts, anthropic-client-openai-upstream-stream.test.ts, anthropic-caching.test.ts, compact-endpoint-integration.test.ts, side-channel.test.ts, replay.test.ts, openai-caching.test.ts, recall-openai-stream.test.ts, and recall-codex-stream.test.ts.500 characters never score as a meta request.packages/core/src/session/model-transport.ts defines session WebSocket transport constants ROTATE_AFTER_MS = 55 * 60 * 1000, INBOUND_CAPACITY = 128, and IDLE_TIMEOUT = "5 minutes", plus the incremental counter opencode_session_websocket_events_total.SessionModelTransport.Service exposes bind(sessionID), close(sessionID), and closeAll; per-session state uses a one-permit Semaphore, closed, httpFallback, and an optional active Channel.${exchange.connect.url}:${Hash.sha256(JSON.stringify(Object.entries(exchange.connect.headers).sort(([a], [b]) => a.localeCompare(b))))}, binding connection reuse to the URL and a deterministic hash of sorted headers.SessionModelTransport.closeChannel() interrupts the reader, closes the connection, and fails an active queue with code: "close" and phase: "close"; delivery is "accepted" after provider observation or terminal state and otherwise "ambiguous".SessionModelTransport.poison() records queue_overflow for transport code "queue-overflow" and protocol_failure otherwise, fails the active queue, removes the owned channel, and closes the connection.SessionModelTransport.open() rejects a connection completed after owner closure with code: "owner-closed", phase: "connect", and delivery: "not-sent"; successful connections record openedAt, start a scoped message-reader fiber immediately, log session websocket connected, and increment the connect metric.code: "idle-data", rejects non-string frames as code: "message", and treats inbound queue overflow as code: "queue-overflow", phase: "receive", and delivery: "accepted"."accepted" after provider observation, terminal state, or queue overflow; close code "1009" is "rejected"; other receive failures are "ambiguous".SessionModelTransport.start() rejects requests for a closed owner with code: "owner-closed", phase: "queue", and delivery: "not-sent", while owner.httpFallback invokes exchange.fallback() and uses Effect.void for completion.packages/gateway/test/compaction.test.ts:isMetaRequest() treats a short system prompt plus one message and no tools as meta, and also treats 2 messages plus 1 tool as meta; it rejects normal conversations with 3 tools, conversations with 3 messages, system prompts of exactly 500 characters, and compaction requests handled separately.499 characters but rejects one of exactly 500, because the short-system condition is strictly < 500.isMetaRequest() gives known x-lore-agent values precedence over structural heuristics: title, summary, summarize, categorize, label, and classify always return true, while known primary agent coder returns false even for a structurally meta request; unknown agents fall through to heuristics.isMetaRequest() scoring examples assign 3 points each for few tools, few messages, and low maxTokens, 2 points for a short system prompt or eligible meta keyword, and require a score of at least 8; low maxTokens alone scores 3 and is insufficient.600-character system prompt, and maxTokens: 100 scores 9 and is meta; a short prompt with no tools, 1 message, and maxTokens: 4096 scores 8 and remains meta for backward compatibility.maxTokens: 150 scores 11 and is meta, but keywords alone with 3 tools and 3 messages score 4 and cannot trigger detection.2000 characters that casually includes “Always use a descriptive title for PRs,” together with 3 tools and 1 message, scores 3 and is not classified as a meta request because keyword scoring is disabled when the system prompt exceeds 2000 characters.packages/core/src/plugin returned at least 100 matches and was truncated; visible plugin IDs included opencode.warming, opencode.command, opencode.plan, opencode.agent, opencode.skill, opencode.variant, opencode.vcs.git, opencode.vcs.hg, provider plugins for Anthropic, OpenAI, OpenAI-compatible, OpenRouter, Amazon Bedrock, Google Vertex, Ollama, vLLM, LM Studio, Cloudflare AI Gateway, Cloudflare Workers AI, and web-search plugins for Tavily and Parallel.Plugin.define({-style matches across SDK tests, CLI configuration, simulation, browser/latex/merman plugins, server tests and fixtures, desktop tests, TUI notifications, and core plugin tests.packages/plugin/src/promise/index.ts exports PluginOptions, storage types, Plugin from ./plugin.js, and schema APIs for Agent, Command, Connection, Credential, Integration, Location, Mcp, Model, PersistentPty, Provider, Reference, Rpc, Skill, Vcs, WebSearch, and Worktree.