Dashboard › opencode › Distillation
7e7395b8-447a-493e-aa6a-dd5f499c02c9["lore_tm_v1_4nxAHVcPjRi-Az0-NJiSc65SRw_3RdQ5qXin3k_jRyM","lore_tm_v1_1gba34g1Y1UFH41OdDkXAOQZoRTcKbyv86WgDSEDRYM","lore_tm_v1_tPSeT0JoBBJvBxuc2z-lw6K-1r_NqZJa7p4DNwT2_20","lore_tm_v1_50eVGQ_QcBC5KFBsYRTuCzBjxeDZ1bbQUynj52wfkJ0","lore_tm_v1_RbKypIWvTUhGHXTYHDu6jHoBEfyZbyxIblumU5q2DdE","lore_tm_v1_rjqFyBCfbHF5aIE41VhQ-COjE2ppGl7YtfCaqPOByVc"]
Date: Sep 16, 2026
"never dispatches a provider after ownership changes"."never publishes streamed output after ownership changes"."never starts a local tool after ownership changes"."never fails interrupted tools after ownership changes"."never commits continuation before unresolved hosted tools are reconciled".SessionHistory.entriesForRunner(db, session.id, system.baselineSeq) and treats currentStep >= agent.info.steps as the last step; on the last step it omits tool materialization, appends Message.assistant(MAX_STEPS_PROMPT), and sets toolChoice: "none"."x-session-affinity": session.id, "X-Session-Id": session.id, and optional "x-parent-session-id": session.parentID; OpenAI promptCacheKey strips the ses_ prefix only when the session ID matches /^ses_[0-9a-f]{64}$/.compaction.compactIfNeeded({ sessionID: session.id, entries, model, request }); a positive result dies with continueAfterCompaction(currentStep).Semaphore.makeUnsafe(1).withPermit; provider streams always run publisher.flush() via Effect.ensuring."tool-call" events, the runner sets needsContinuation = true, obtains assistantMessageID through publisher.assistantMessageID(event.id), settles the tool inside Effect.uninterruptibleMask, and publishes LLMEvent.toolResult(...) with settlement.outputPaths ?? [].publisher.failUnsettledTools("Tools are disabled after the maximum agent steps")."Provider did not return a tool result", "Tool execution interrupted", "Provider turn interrupted", and `Tool execution failed: ${message}`; user-declined tool settlement clears toolFibers, fails unsettled tools, and interrupts.SessionEvent.Step.Ended only when publisher.stepSettlement() exists and publisher.hasProviderError() is false; the event includes assistantMessageID, finish, cost: 0, tokens, optional ending snapshot, and optional changed files.needsContinuation: !publisher.hasProviderError() && needsContinuation; stream failures propagate with Effect.failCause(stream.cause), as do interrupted tool-settlement failures.runAfterOverflowCompaction rejects a second overflow recovery with defect "Post-compaction provider attempt cannot recover another overflow" and otherwise retries after Effect.yieldNow."sessionID" and version 1, while step-settlement events use aggregate "sessionID" and version 2.SessionEvent.Step.Ended is event type "session.next.step.ended" with fields assistantMessageID, finish, finite cost, token counts for input, output, reasoning, and cache read/write, plus optional snapshot and files.SessionEvent.Step.Failed is event type "session.next.step.failed" with assistantMessageID and UnknownError.SessionEvent.Text.Delta ("session.next.text.delta") is live-only, while SessionEvent.Text.Ended ("session.next.text.ended") is the replayable full-value boundary.packages/core/src/event.ts, packages/core/src/event/sql.ts, packages/core/src/session/event.ts, and packages/core/src/session/runner/publish-llm-event.ts.