Dashboard › opencode › Distillation
b8ecc78d-84a9-4b83-8dde-3d26a68bf3f7["lore_tm_v1_SL6tByHvSvI6m8AG8aZyhvx22L-OPxR6r_cJF3BHiPE","lore_tm_v1_jxJBzwcmUlzNg6wBah1fBr-VuzmXoNO-zomAOhgITHQ","lore_tm_v1_VMx3rch4XUXwIUPyq0jWgZTMOBRhpOd2cPnh3mZis1I","lore_tm_v1_QOy8_BWRuG45-Y012x5cfAuCslz3CeC5olvqjBgDT2M","lore_tm_v1_g4zQAKaavwKUJc9yu7sXpbAS01AL3OTIqPXbXorTy6A"]
packages/opencode/src/session/prompt.ts defines MCP helpers mcpResourceBase64Size(value: string), formatMcpResourceBytes(value: number), and isOrphanedInterruptedTool(part: SessionV1.ToolPart); formatMcpResourceBytes(...) formats bytes as ${Math.ceil(value / (1024 * 1024))} MB.isOrphanedInterruptedTool(...) distinguishes interrupted tool parts that are no longer pending work and therefore must not trigger an assistant-prefill request.SessionPrompt.Service exposes prompt(input: PromptInput): Effect.Effect<SessionV1.WithParts, Image.Error> along with cancellation and other prompt operations; its implementation captures services including Provider.Service, Command.Service, Permission.Service, Truncate.Service, SessionRunState.Service, EventV2Bridge.Service, InstanceState, Database, SessionReminders, ToolRegistry, and CrossSpawnSpawner.SessionPrompt.ops is traced as "SessionPrompt.ops", while SessionPrompt.cancel is traced as "SessionPrompt.cancel" and delegates cancellation by sessionID: SessionID.SessionPrompt.resolvePromptParts(template) deduplicates referenced names with Set<string>; relative paths resolve against ctx.worktree, recognized agents become { type: "agent", name: found.name }, and remaining references become file parts. Resolution runs concurrently with { concurrency: "unbounded", discard: true }.SessionPrompt.ensureTitle ignores user messages whose parts are all marked synthetic, detects when the first real user message contains only subtask parts, selects an agent-specific model when configured, converts context through MessageV2.toModelMessagesEffect(...), and requests a small-model completion with the leading message Generate a title for this conversation:\n.SessionPrompt.shellImpl(input: ShellInput, ready?: Latch.Latch) resolves the requested agent, selects input.model ?? agent.model ?? currentModel(input.sessionID), creates user and assistant records with generated ascending IDs, records path metadata as { cwd: ctx.directory, root: ctx.worktree }, and creates a shell tool part identified by ShellID.ToolID.SessionPrompt.shellImpl accumulates output, updates the persisted tool-part state as execution progresses, obtains environment customization through plugin.trigger(...), and launches the command through CrossSpawnSpawner.spawn(cmd). A failure exit containing interrupts but no defects is handled as interruption rather than an ordinary command failure.SessionPrompt.getModel is traced as "SessionPrompt.getModel"; model lookup failures are inspected through Cause.squash(exit.cause) and converted into a published Session.Event.Error.SessionPrompt.createUserMessage is traced as "SessionPrompt.createUserMessage"; it resolves agent/model/variant information, persists model changes when the current session model differs, publishes session errors through EventV2Bridge, and registers instruction.clear(info.id) as a finalizer.createUserMessage logs mcp resource with clientName, uri, and MIME type, emits the explanatory text Reading MCP resource: ${part.filename} (${uri}), supports either a single content.contents item or an array, and calculates decoded blob size with mcpResourceBase64Size(...).[Binary MCP resource omitted: ${filename ?? uri} (${mime}, ${formatMcpResourceBytes(size)}) is not a supported attachment type]; failures are logged as failed to read MCP resource with error, clientName, and uri. application/pdf is among the supported attachment MIME types.createUserMessage obtains the named Read tool through registry.named(), converts optional textual ranges with parseInt(...), records a synthetic text part saying Called the Read tool with the following input: ${JSON.stringify(args)}, incorporates returned text and attachments, and turns read failures into text using error instanceof Error ? error.message : String(error).application/x-directory receive dedicated directory handling; other binary files are read through fsys.readFile(filepath).pipe(Effect.catch(Effect.die)) and encoded with Buffer.from(...).toString("base64"). Image parts are recognized with part.type === "file" && part.mime.startsWith("image/")."SessionPrompt.prompt" and initializes a PermissionV1.Rule[] collection before creating the user message and entering the session loop.MessageV2.filterCompactedEffect(sessionID), checks the most recent assistant message for tool calls, and detects orphaned interrupted tool parts. On detecting one, it logs loop exit with orphaned interrupted tool including its callID and exits rather than issuing an assistant-prefill request.1, the implementation invokes ensureTitle; it then resolves the model from lastUser.model.providerID and lastUser.model.modelID, creates an assistant message, and defines finalizeInterruptedAssistant to finalize and persist an interrupted assistant response.lastUserMsg?.parts.some((p) => p.type === "agent")), supplies ToolRegistry.Service to processing, conditionally installs tools["StructuredOutput"] = createStructuredOutputTool(...), and includes sys.skills(agent) plus optional MCP instructions in the system prompt.You MUST call this tool exactly once at the end of your response."content-filter" receives dedicated handling; overflow can trigger compaction.create(...), and each iteration returns an explicit "break" or "continue" outcome.SessionPrompt.loop, SessionPrompt.shell, and SessionPrompt.command. SessionPrompt.command logs command, validates against names from (yield* commands.list()).map((c) => c.name), chooses cmd.agent ?? input.agent, substitutes positional arguments and $ARGUMENTS, and expands shell blocks identified by ConfigMarkdown.shell(template).