Dashboard › opencode › Distillation
40e058a5-6825-4be4-a31e-d77bc4e5a940["lore_tm_v1_fh65F4sWjGPJAWT4LU9UUq0ht38r3_p6vvFtsNX5yYo","lore_tm_v1_stgBQ1NtRn8E08OxzXKQzGCkmPUymI4j4nzpXoU_f-w","lore_tm_v1_rWq9Zg2fs83Fr9VxJ94uAGZKq6kzPXF68DygSWkHdVA","lore_tm_v1_yG4NDqGNy4Fhoah6BYUXEslP34BQoJJWExYwWwKdIoc","lore_tm_v1_gfCQx1iosMjCsi0OXGyAy_Eze6AmHGkbKSszf0spAWA","lore_tm_v1_JxVA1sJtVmkywGOssSamOSBe0stiLuIGFd0Lptq4FXs","lore_tm_v1_gcePfBrIuQEyVdOi1AmZtHFt1QcDdQD-s5A6CxMKDHY"]
/home/byk/Code/opencode-v2-pilot/packages/core/src/location-service-map.ts defines Service as LayerMap.LayerMap<Location.Ref, Instance.Services, Instance.Error> under context key "@opencode/example/LocationServiceMap"; Service.get(ref) unwraps locations.get(ref), and node is LayerNode.unbound(Service, Node.tags.values.global).LocationServiceMap.canonical(ref) normalizes equivalent placements before resource-cache keying: on Windows it applies path.normalize(ref.directory), on other platforms it retains ref.directory, then preserves workspaceID in a new Location.Ref./home/byk/Code/opencode-v2-pilot/packages/core/src/instance.ts compiles the location graph in this exact node order: 1. Location.node, 2. Environment.node, 3. Config.node, 4. Agent.node, 5. Command.node, 6. Reference.node, 7. Rpc.node, 8. WebSearch.node, 9. Integration.node, 10. Catalog.node, 11. ModelResolver.node, 12. AISDK.node, 13. Plugin.node, 14. PluginHooks.node, 15. InstancePlugins.node, 16. PluginSupervisor.node, 17. WorktreeRefresh.node, 18. Worktree.node, 19. FileSystemSearch.node, 20. FileSystem.node, 21. ShellSelect.node, 22. Pty.node, 23. Shell.node, 24. Skill.node, 25. InstructionBuiltIns.node, 26. InstructionDiscovery.node, 27. FileAccess.node, 28. FileMutation.node, 29. Formatter.node, 30. Mcp.node, 31. Permission.node, 32. Tool.node, 33. ToolOutput.node, 34. Image.node, 35. SkillInstructions.node, 36. ReferenceInstructions.node, 37. InstructionEntry.node, 38. Form.node, 39. Generate.node, 40. ReadToolFileSystem.node, 41. McpTool.node, 42. SessionInstructions.node, 43. SessionRunnerModel.node, 44. SessionCompaction.node, 45. SessionTitle.node, 46. SessionContext.node, 47. Snapshot.node, 48. SessionRunnerLLM.node, 49. Vcs.node, 50. LocationWatcher.node.LocationWatcher.node intentionally comes last so repository watches start only after boot-critical filesystem and Git work.Instance.Options supports optional plugins?: InstancePlugins.List, discovery?: boolean, and replacements?: LayerNode.Replacements; absent and empty plugin lists are equivalent, while discovery defaults to current filesystem-discovery behavior.discovery: false gives an instance a vanilla boot: no upward config scan, global config directory, plugin-directory loading, ambient plugin-module imports, or boot-time AGENTS.md discovery; well-known integration config and host-injected values still apply, explicitly named file-backed resources such as a skill path or MCP command remain requests, and reading a file can still inject nested AGENTS.md instructions at session time.vanillaReplacements contains Config.node.replace(Config.configured({ project: false, global: false })) and InstructionDiscovery.node.replace(InstructionDiscovery.configured({ project: false, global: false })); plugin-directory discovery needs no replacement because implicit scanning requires Directory config entries that no-scan Config does not produce, while explicit plugin operations remain supported.Instance.layer(ref, options) orders replacements as vanilla defaults first, then options.replacements so caller replacements win, then Location.node.replace(Location.boundNode(ref, { discovery: options.discovery })) and InstancePlugins.node.replace(InstancePlugins.bound(options.plugins ?? [])) so instance bindings win over everything.LayerNode.compile(graph, { replacements, shared: Node.tags.values.global }) shares global nodes, converts instance boot failures to defects via Layer.orDie, and logs "location services booted" with directory, workspaceID, and rounded durationMs. Provided operations retain their typed errors./home/byk/Code/opencode-v2-pilot/services/www/src/docs/content/build/plugins/index.mdx documents plugin config forms in this order: "opencode-acme-plugin", "opencode-acme-plugin@1.2.0", "@acme/opencode-plugin", "./plugins/local", "../shared/plugin", "/absolute/path/plugin", "file:///home/me/plugins/local", and object { package: "@acme/opencode-plugin", options: { agent: "reviewer", strict: true } }.setup runs on load and may return an unload cleanup function; the documented context is essentially an OpenCode server client plus plugin-only transforms, runtime hooks, reloads, registrations, and options.ctx.location identifies where that plugin instance loadedβnot every session or event it can accessβand includes directory, optional workspaceID, and project metadata id, directory, and canonical for both Promise and Effect plugins.ctx.options during setup, with the example checking ctx.options.strict === true.ctx.catalog.model.list() reflect all registrations made so far, including during plugin setup."company.models" updates model ("acme", "reasoner") to name "Acme Reasoner" and cost [{ input: 2, output: 12, cache: { read: 0.2, write: 2 } }]; a following ctx.catalog.model.list() includes that newly registered model.reload() marks a registry changed; the next read rebuilds it by replaying every active transform in registration order onto a fresh value, so transforms should remain cheap and repeatable."company.model-budget" can inspect models added by earlier plugins and remove every model whose any cost tier has output > 20.ctx.catalog.reload(); the example refresh interval is 60_000 ms and cleanup calls clearInterval(timer).reload() replays every catalog transform in order, ensuring the output-price policy continues filtering refreshed models.ctx.agent.list(), ctx.agent.get({ agentID: "build" }), and a transform whose editor calls, in order, list(), get("build"), default("build"), update("build", ...) to set description "Builds features and fixes bugs", and remove("legacy"); external transform state changes are applied via ctx.agent.reload().ctx.session.hook("context", () => {}) followed by registration.dispose(); multiple pluginsβ hooks run in plugin registration order, allowing later hooks to observe earlier mutations."prompt" hook runs before attachment and skill resolution and durable inbox admission; the example redacts "company-secret" to "[redacted]", initializes event.prompt.files, adds { uri: "file:///project/policy.md" }, sets metadata source "company-policy", and changes delivery to "queue".prompt includes text, attachment files, agent mentions in agents, and selected skills; metadata is application-defined; delivery defaults to "steer" and may become "queue"; session and message IDs are readonly and cannot be used to redirect admission.mention offsets, and agent mentions do not switch the sessionβs active agent.session.prompt run them; 3. synthetic messages, shell messages, compaction controls, and move controls do not; 4. each hook runs once during admission rather than before every model call; 5. provider scoping is unavailable because model resolution follows admission."context" hook can modify assembled system instructions, messages, tools, generation settings, and provider options immediately before dispatch; the example appends "Keep the review focused on correctness.", deletes event.tools.write, sets temperature = 0.2, and sets maxTokens = 8_000.compaction agent identity for provider-specific handling.generation and providerOptions start empty for every model call and omit resolved model settings; 2. hooks run in registration order and see earlier overrides; 3. request overrides beat model defaults, which beat route defaults; 4. provider-option objects merge recursively while arrays and scalar values replace prior values; 5. deletion or undefined falls back to configured defaults rather than removing them; 6. raw HTTP-body overlays run after protocol lowering and may override resulting fields.event.providerOptions.reasoningEffort = "high" under { providerID: "openai" }.maxTokens is the semantic output-token limit; Gemini supports topK, whereas OpenAI Responses does not expose it."model.request" hook can modify model-request settings and be provider-scoped; the example adds header x-plugin: review for { providerID: "anthropic" }, and its event carries the same kind as HTTP hooks."http.request" and "http.response" hooks can alter native provider traffic, but request and response bodies are one-shot streams and must be cloned or replaced before reading.event.kind distinguishes "primary" agent-loop calls, "compaction" checkpoint summaries, "title" title generation, and "generate" transient ctx.session.generate calls, and should be used instead of agent ID to distinguish auxiliary requests."x-session-id" to event.sessionID, adds "x-priority": "background" for title requests, and replaces the response while preserving body/status/current headers and adding "x-plugin": "review"."retry" hook runs after OpenCode classifies a provider failure and proposes a policy but before scheduling a retry; it may override retryability or delay in milliseconds but does not reveal internal execution of the next attempt.429 becomes { retry: true, delay: 10_000 }; error type "provider.invalid-request" on attempt 2 becomes { retry: true, delay: 0 }; attempts >= 3 become { retry: false }.attempt is the physical attempt, initial request 1, first retry 2; 4. NaN, infinite, or negative delays fall back to the computed delay; 5. context-overflow recovery is separate because it compacts instead of retrying the same request.SessionHooks fields are prompt, context, "model.request", "http.request", "http.response", and retry; RetryDecision is { retry: false } | { retry: true; delay: number }, and SessionRetryHook has readonly sessionID, agent, model { providerID, id, variant? }, error { type, message, status? }, and attempt, plus mutable decision./home/byk/Code/opencode-v2-pilot/services/www/src/docs/AGENTS.md: keep prose sections brief and focused, prefer 1β3 sentences, interleave explanations with concrete examples, put each relevant example immediately after its introducing text, require every syntax/field/API subsection to have its own minimal example, split long explanations with headings/examples, lead with the common task, avoid stacked prose paragraphs, use bullets or tables for independent rules, and order workflows as readers perform them./config; remark-links.ts applies site/docs base paths, lib/navigation.ts controls header sections and sidebar order, thin routes live in ../pages/docs/, and no documentation frontend framework should be added.bun typecheck, bun run check:generated, and bun run build from services/www, with errors treated as blockers; however, while the dev server is active, no bun typecheck, bun run build, or second Astro process should run because they share Viteβs dependency cache, so validation is left to the user.