Dashboard › opencode › Distillation
e38594e1-442e-431a-9753-81f87d6486e4["lore_tm_v1_x-vrso4841RvVFE7WCYH1XI3WP_SbnUPDgODuuBuQkc","lore_tm_v1_qL2u7YtOsBHmctzeGXaEsgerLbWjGKMl1M8eGcIm7X4","lore_tm_v1_5P0Yxe9XPi_343wYe-M2vM4pt15VCTV4MN9eIUq9mJk","lore_tm_v1_ufIb2yDElUmSqO3ZjYaCyuo5-qG35829QGTE5lEqXGc","lore_tm_v1_KUv3CS7mTttREvhCckmZCgxWLKop9mXGrQk8dM1qMLs","lore_tm_v1_xEWSMDhxT39h0TP-KNSebwPuE5bRQanXgunDCFhlmbQ","lore_tm_v1_BHlCJ_qTEz3aWXPN32brgI-EtytGqAnrgwnD-XCBsi4","lore_tm_v1_RSsJdrHXAwxWL--m-OZ38kgQFxX9oX0nPbBoxGvpMTc","lore_tm_v1_kPoAopycCuRndWWqYFzSkFxYqHr_QqTFRAKy0Nfs_IE","lore_tm_v1_xP4OPsvmZS4zwF1PP2C0ec8AAYWOxH2_MtuB5NGAOf8","lore_tm_v1_dC4Hc8Ymx_4GMJS9675aifhzyvm80vcvoLKpSqodgYI","lore_tm_v1_7HChs0EtqdWiPkKPyEcX4u1MAG03fJ3MWVGVIKT6GgI","lore_tm_v1_dyCp9K6s-ih_baX3V7MT8UbOoyxg3qpTbETn2UbAaT8"]
/home/byk/Code/opencode/packages/schema/src/v1/session.ts defines SessionSummary with finite additions, deletions, and files, plus optional diffs: Schema.Array(FileDiff.Info); SessionTokens has finite input, output, reasoning, and cache read/write; SessionShare has url: Schema.String./home/byk/Code/opencode/packages/core/src/session/sql.ts defines SessionTable as SQLite table "session": primary key id; cascade-referenced project_id; optional workspace_id, parent_id, and path; required slug, directory, title, and version; optional share/summary/metadata/revert/permission/agent/model fields; cost and 5 token counters default to 0; timestamps plus time_compacting and time_archived. Indexes are session_project_idx, session_workspace_idx, and session_parent_idx.SessionTable.model stores JSON { id: string, providerID: string, variant?: string }; summary_diffs stores Snapshot.LegacyFileDiff[], metadata stores Record<string, unknown>, revert stores Revert.State, and permission stores PermissionV1.Ruleset./home/byk/Code/opencode/packages/core/src/session/sql.ts defines MessageTable as "message" with primary-key id, cascade-referenced required session_id, timestamps, and required JSON data: V1MessageData; index message_session_time_created_id_idx orders by session_id, time_created, and id./home/byk/Code/opencode/packages/core/src/session/sql.ts defines PartTable as "part" with primary-key id, cascade-referenced required message_id, required session_id, timestamps, and required JSON data: V1PartData; indexes are part_message_id_id_idx and part_session_idx./home/byk/Code/opencode/packages/core/src/session/sql.ts defines TodoTable as "todo" with cascade-referenced session_id, required content, status, priority, position, and timestamps; its composite primary key is (session_id, position) and its index is todo_session_idx./home/byk/Code/opencode/packages/core/src/session/sql.ts defines SessionMessageTable as "session_message" with primary-key id, cascade-referenced session_id, required type, required seq, timestamps, and required JSON data: SessionMessageData; unique index session_message_session_seq_idx covers (session_id, seq), while secondary indexes cover (session_id, type, seq), (session_id, time_created, id), and time_created./home/byk/Code/opencode/packages/core/src/session/sql.ts defines SessionInputTable as "session_input" with primary-key id, cascade-referenced session_id, required JSON prompt, required delivery, required admitted_seq, optional promoted_seq, and time_created defaulting to Date.now(). Indexes are session_input_session_pending_delivery_seq_idx on (session_id, promoted_seq, delivery, admitted_seq), unique session_input_session_admitted_seq_idx, and unique session_input_session_promoted_seq_idx./home/byk/Code/opencode/packages/core/src/session/sql.ts defines SessionContextEpochTable as "session_context_epoch" with cascade-referenced primary-key session_id, required baseline, required JSON snapshot: SystemContext.Snapshot, and required baseline_seq./home/byk/Code/opencode/packages/core/src/session/sql.ts strip persisted identity/discriminator fields: SessionMessageData omits "type" | "id", V1MessageData omits "id" | "sessionID", and V1PartData omits "id" | "sessionID" | "messageID".SessionPrompt.loop is implemented in /home/byk/Code/opencode/packages/opencode/src/session/prompt.ts:1343; the instance HTTP session handler invokes it at /home/byk/Code/opencode/packages/opencode/src/server/routes/instance/httpapi/handlers/session.ts:291.SessionRunState is wired into /home/byk/Code/opencode/packages/opencode/src/effect/app-runtime.ts, /home/byk/Code/opencode/packages/opencode/src/session/prompt.ts, /home/byk/Code/opencode/packages/opencode/src/session/revert.ts, and the instance HTTP server/handler. /home/byk/Code/opencode/packages/opencode/src/session/run-state.ts exposes state, runner, assertNotBusy, cancel, ensureRunning, startShell, and cancelBackgroundJobs./home/byk/Code/opencode/packages/opencode/src/session/prompt.ts, loop delegates through state.ensureRunning(input.sessionID, lastAssistant(input.sessionID), runLoop(input.sessionID)); shell execution delegates through state.startShell(input.sessionID, lastAssistant(input.sessionID), shellImpl(input, ready), ready)./home/byk/Code/opencode/packages/opencode/src/background/job.ts keeps the legacy BackgroundJob service instance-scoped while reusing @opencode-ai/core/background-jobβs registry engine. It creates state via InstanceState.make(() => CoreBackgroundJob.make) and wraps exact operations list, get, start, extend, wait, waitForPromotion, promote, and cancel with InstanceState.useEffect./home/byk/Code/opencode/packages/opencode/src/background/job.ts re-exports Service, ExtendInput, Info, Interface, StartInput, Status, WaitInput, and WaitResult from @opencode-ai/core/background-job; its node is LayerNode.make({ service: CoreBackgroundJob.Service, layer, deps: [] }).2 * 1024 * 1024 byte limit, maintains const locks = new Map<string, Semaphore.Semaphore>(), invokes Git with rm --cached -f --ignore-unmatch --pathspec-from-file=- --pathspec-file-nul, checks config via (yield* config.get()).snapshot !== false, and uses git diff --no-index semantics so pattern matching also applies to already tracked paths./home/byk/Code/opencode/packages/opencode/src/effect/app-runtime.ts builds AppLayer from nodes in this exact order: 1. Npm.node, 2. FSUtil.node, 3. Database.node, 4. Auth.node, 5. Account.node, 6. Config.node, 7. Git.node, 8. Storage.node, 9. Snapshot.node, 10. Plugin.node, 11. ModelsDev.node, 12. Provider.node, 13. ProviderAuth.node, 14. Agent.node, 15. Skill.node, 16. Discovery.node, 17. Question.node, 18. Permission.node, 19. Todo.node, 20. Session.node, 21. SessionProjector.node, 22. SessionStatus.node, 23. BackgroundJob.node, 24. RuntimeFlags.node, 25. EventV2Bridge.node, 26. SessionRunState.node, 27. SessionProcessor.node, 28. SessionCompaction.node, 29. SessionRevert.node, 30. SessionSummary.node, 31. SessionPrompt.node, 32. Instruction.node, 33. LLM.node, 34. LSP.node, 35. MCP.node, 36. McpAuth.node, 37. Command.node, 38. Truncate.node, 39. ToolRegistry.node, 40. Format.node, 41. InstanceStore.node, 42. Project.node, 43. Vcs.node, 44. Workspace.node, 45. Worktree.node, 46. Installation.node, 47. ShareNext.node, 48. SessionShare.node.AppLayer additionally provides merged Ripgrep.node and Observability.layer. ManagedRuntime.make(AppLayer, { memoMap }) creates the runtime, and all exposed execution methods (runSync, runPromise, runPromiseExit, runFork, and runCallback) first wrap effects with attach; dispose delegates to rt.dispose()./home/byk/Code/opencode/packages/core/src/database/database.ts initializes SQLite with EffectDrizzleSqlite.makeWithDefaults() and exact pragmas: journal_mode = WAL, synchronous = NORMAL, busy_timeout = 5000, cache_size = -64000, foreign_keys = ON, and wal_checkpoint(PASSIVE), then runs DatabaseMigration.apply(db); initialization errors are converted to defects with Effect.orDie.Database.path() uses Flag.OPENCODE_DB directly when it is ":memory:" or absolute, otherwise resolves it under Global.Path.data. Without that flag, channels latest, beta, and prod, or OPENCODE_DISABLE_CHANNEL_DB equal to "1" or "true", use Global.Path.data/opencode.db; other channels use opencode-${InstallationChannel.replace(/[^a-zA-Z0-9._-]/g, "-")}.db.makeGlobalNode({ service: Service, layer: layerFromPath(path()), deps: [] }); layerFromPath(filename) provides sqliteLayer({ filename })./home/byk/Code/opencode/packages/opencode/src/session/prompt.ts, command model selection precedence is: 1. cmd.model parsed by Provider.parseModel, 2. cmd.agentβs configured model, 3. input.model parsed by Provider.parseModel, 4. currentModel(input.sessionID). The selected model is validated through getModel(taskModel.providerID, taskModel.modelID, input.sessionID).agentName or agents.defaultInfo(). If missing, it gathers non-hidden agent names and publishes Session.Event.Error before throwing NamedError.Unknown with Agent not found: "${agentName}". and, when available, Available agents: ${available.join(", ")}.input.parts by converting file URLs with fileURLToPath, and defines subtask mode as (agent.mode === "subagent" && cmd.subtask !== false) || cmd.subtask === true.type: "subtask", agent: agent.name, description: cmd.description ?? "", command: input.command, selected { providerID, modelID }, and the first template text as prompt or "". Otherwise parts are uniqueTemplateParts followed by input.parts.userAgent is input.agent or the default agent name, while userModel is parsed from input.model or obtained from currentModel(input.sessionID); for a non-subtask command, they are agent.name and taskModel."command.execute.before" with { command, sessionID, arguments } and mutable { parts }. It then calls prompt with sessionID, optional messageID, resolved model, resolved agent, parts, and variant, and publishes Command.Event.Executed with command name, sessionID, arguments, and the resulting message ID.SessionPrompt.PromptInput contains required sessionID and parts, with optional messageID, model, agent, noReply, tools, format, system, and variant. parts accepts SessionV1.TextPartInput, FilePartInput, AgentPartInput, or SubtaskPartInput; tools is deprecated because tools and permissions were merged.SessionPrompt.LoopInput contains only sessionID. ShellInput contains sessionID, optional messageID, required agent, optional model, and required command.SessionPrompt.CommandInput contains optional messageID, required sessionID, optional agent, optional string model, required arguments, required command, optional variant, and optional file-only parts whose fields are optional id, literal type: "file", required mime, optional filename, required url, and optional source.createStructuredOutputTool() in /home/byk/Code/opencode/packages/opencode/src/session/prompt.ts removes $schema from the provided schema, creates an AI SDK tool using jsonSchema(toolSchema), calls input.onSuccess(args) after SDK validation, and returns { output: "Structured output captured successfully.", title: "Structured Output", metadata: { valid: true } }; toModelOutput maps that to { type: "text", value: output.output }.bashRegex = /!\([^`]+)`/g, argsRegex = /(?:[Image\s+\d+]|"[^"]"|'[^']'|[^\s"']+)/gi, placeholderRegex = /$(\d+)/g, and quoteTrimRegex = /^["']|["']$/g`.SessionPrompt.node depends on, in exact order: 1. SessionStatus.node, 2. Session.node, 3. Agent.node, 4. Provider.node, 5. SessionProcessor.node, 6. SessionCompaction.node, 7. Plugin.node, 8. Command.node, 9. Config.node, 10. Permission.node, 11. FSUtil.node, 12. MCP.node, 13. LSP.node, 14. ToolRegistry.node, 15. Truncate.node, 16. Image.node, 17. CrossSpawnSpawner.node, 18. Instruction.node, 19. SessionRunState.node, 20. SessionRevert.node, 21. SessionSummary.node, 22. SystemPrompt.node, 23. LLM.node, 24. EventV2Bridge.node, 25. RuntimeFlags.node, 26. Database.node./home/byk/Code/opencode/packages/opencode/src/session/message-v2.ts, errored assistant messages are skipped unless the error is AbortedError and at least one part is neither "step-start" nor "reasoning".part.metadata?.anthropic?.signature != null; when signed reasoning exists, an empty assistant text part is converted from "" to a single space " " so it survives AI SDK filtering and preserves signed-thinking positions across step-start splitting/provider regrouping.tool-${part.tool} UI parts with state "output-available", toolCallId, input, output, optional providerExecuted, and same-model callProviderMetadata. Compacted outputs become "[Old tool result content cleared]"; otherwise output is truncated by truncateToolOutput(part.state.output, options?.toolOutputMaxChars).options?.stripMedia is set. Media unsupported inside tool results is extracted into a later synthetic user message; supported media and non-media remain in the tool output, represented as { text, attachments } when any remain.part.state.metadata?.interrupted === true with string metadata.output as "output-available" using that output; other errors become "output-error" with errorText: part.state.error."output-error" with errorText: "[Tool execution was interrupted]" so Anthropic/Claude does not receive dangling tool_use blocks without corresponding tool_result."reasoning" part with provider metadata. Provider metadata and tool call provider metadata are omitted when replaying against a different model.id: MessageID.ascending(), text SYNTHETIC_ATTACHMENT_PROMPT, and file parts carrying url, mediaType: attachment.mime, and optional filename./home/byk/Code/opencode/packages/opencode/src/cli/effect-cmd.ts defines user-visible CliError with required message and optional numeric exitCode; fail(message, exitCode = 1) returns Effect.fail(new CliError({ message, exitCode })).effectCmd accepts command, optional aliases, describe, optional yargs builder, optional instance, optional directory, and an Effect handler. instance defaults to enabled, may be a boolean or per-invocation function, and directory defaults to process.cwd().instance: false, effectCmd runs the handler directly under AppRuntime; such handlers can yield AppServices but must not yield InstanceRef. Intended instance-free examples are models, serve, web, account, db, and upgrade; a function form supports cases such as run --attach <url>.effectCmd dynamically imports InstanceStore and InstanceRef, loads context through store.load({ directory }), provides InstanceRef to the handler, and guarantees store.dispose(ctx) in a JavaScript finally block after success or failure.effectCmd dynamically imports AppRuntime, casts yargsβ rawArgs to WithDoubleDash<Args> at the boundary, and propagates errors to the existing top-level handler in src/index.ts; CliError is recognized by FormatError in src/cli/error.ts.