|
|
@@ -4,40 +4,47 @@ OpenCode sessions preserve durable conversational history while assembling the r
|
|
|
|
|
|
## Language
|
|
|
|
|
|
-**System Context**:
|
|
|
-The structured collection of contextual facts presented to the model as initial instructions and chronological updates.
|
|
|
-_Avoid_: System prompt
|
|
|
+**Model Context**:
|
|
|
+The complete model-visible input assembled for one **Step**, including system instructions, **Session History**, tool definitions, and step-local additions. **Instructions** are one component of Model Context, not a synonym for it.
|
|
|
+_Avoid_: System Context
|
|
|
+
|
|
|
+**Instructions**:
|
|
|
+The opaque algebra of independently refreshable typed instruction sources that render the durable instruction baseline and chronological updates shown to the model.
|
|
|
+_Avoid_: Model Context, System Context
|
|
|
|
|
|
**Session History**:
|
|
|
-The projected chronological conversation selected for a **Step** after applying the active compaction and **Context Epoch** cutoffs.
|
|
|
+The projected chronological conversation selected for a **Step** after applying the active compaction and **InstructionCheckpoint** baseline cutoffs.
|
|
|
_Avoid_: Session Context
|
|
|
|
|
|
-**Context Source**:
|
|
|
-One independently observed typed value within the **System Context**, represented by a stable key, JSON codec, infallible loader, pure baseline/update renderers, and an optional removal renderer for dynamic sources.
|
|
|
+**Instruction Source**:
|
|
|
+One independently observed typed value within **Instructions**, represented by a stable namespaced key, JSON codec, loader, pure baseline/update renderers, and an optional removal renderer.
|
|
|
_Avoid_: Prompt fragment
|
|
|
|
|
|
-**System Context Registry**:
|
|
|
-The Location-scoped registry of ordered, scoped producers that contribute to the current **System Context**.
|
|
|
+**InstructionEntry**:
|
|
|
+One API-managed, durable, per-Session instruction value. Its slash-free client key maps to the `api/<key>` **Instruction Source** key. Entries deliberately render to the model as mechanism-neutral `<context>` blocks: the model sees session context, not how it was attached.
|
|
|
+
|
|
|
+**InstructionDiscovery**:
|
|
|
+The Location-scoped service that observes ambient global and upward-project `AGENTS.md` files as one ordered aggregate **Instruction Source**.
|
|
|
|
|
|
-**Mid-Conversation System Message**:
|
|
|
-A durable chronological instruction that tells the model the newly effective state of a changed **Context Source**.
|
|
|
-_Avoid_: System update, system notification, raw text diff
|
|
|
+**InstructionCheckpoint**:
|
|
|
+The Session-owned durable instruction baseline, baseline sequence, and `Instructions.Applied` record used to prepare later Steps.
|
|
|
|
|
|
-**Context Epoch**:
|
|
|
-The span during which one initially rendered **System Context** remains the immutable provider-cache baseline, ending at completed compaction, Session movement, or an incompatible context transition that requires a fresh baseline.
|
|
|
+**Instruction Update**:
|
|
|
+A durable chronological System message published as `session.instructions.updated` that tells the model the newly effective state of one or more changed **Instruction Sources**.
|
|
|
+_Avoid_: System notification, raw text diff
|
|
|
|
|
|
-**Baseline System Context**:
|
|
|
-The full **System Context** rendered at the start of a **Context Epoch**.
|
|
|
+**Instruction Baseline**:
|
|
|
+The exact joined instruction text stored by **InstructionCheckpoint** and sent as immutable provider-cache prefix state until completed compaction rebaselines it or Session movement or committed revert resets it.
|
|
|
_Avoid_: Live system prompt
|
|
|
|
|
|
-**Context Snapshot**:
|
|
|
-The overwriteable model-hidden JSON state used to compare each **Context Source** with the value last admitted to a **Step**.
|
|
|
+**Applied Instructions**:
|
|
|
+The overwriteable model-hidden `Instructions.Applied` record in **InstructionCheckpoint**, containing what the model was last told per **Instruction Source**.
|
|
|
|
|
|
-**Unavailable Context**:
|
|
|
-An expected temporary inability to observe a **Context Source** value; the runtime retains its prior effective state and emits no update, or omits it until first successfully loaded.
|
|
|
+**Unavailable Instruction Source**:
|
|
|
+An expected temporary inability to observe an **Instruction Source** value; the runtime retains its prior effective state and emits no update, while an unavailable source blocks creation of the first complete **Instruction Baseline**.
|
|
|
|
|
|
**Safe Step Boundary**:
|
|
|
-The point immediately before a provider request, after durable input promotion and any required tool settlement, where context changes may be admitted chronologically.
|
|
|
+The point during Step preparation, after prior tool settlement and before durable input promotion, where instruction changes may be admitted chronologically.
|
|
|
|
|
|
**Admitted Prompt**:
|
|
|
A durable user input accepted into the Session inbox but not yet included in **Session History**.
|
|
|
@@ -46,7 +53,7 @@ A durable user input accepted into the Session inbox but not yet included in **S
|
|
|
The durable transition that removes an **Admitted Prompt** from pending input and appends its user message to **Session History**.
|
|
|
|
|
|
**Step**:
|
|
|
-One logical LLM call spanning pre-flight context checkpoint preparation, input promotion, request build, and compaction check; the provider stream; and tool settlement.
|
|
|
+One logical LLM call spanning pre-flight instruction checkpoint preparation, input promotion, request build, and compaction check; the provider stream; and tool settlement.
|
|
|
_Avoid_: provider turn, turn (unqualified)
|
|
|
|
|
|
**Physical Attempt**:
|
|
|
@@ -100,16 +107,22 @@ _Avoid_: Response envelope
|
|
|
|
|
|
## Relationships
|
|
|
|
|
|
-- A **System Context** is an opaque carrier composed from zero or more **Context Sources**.
|
|
|
-- **Session History** contains projected conversational messages and admitted **Mid-Conversation System Messages**; the active **Baseline System Context** remains separate provider-request state.
|
|
|
-- The **System Context Registry** uses stable-keyed scoped contributions to assemble the current **System Context**; contributor removal naturally removes its sources at the next **Safe Step Boundary**.
|
|
|
-- A changed **Context Source** may produce one **Mid-Conversation System Message** containing its newly effective state.
|
|
|
-- A **Mid-Conversation System Message** persists the exact combined rendered text sent to the model.
|
|
|
-- The current **Context Snapshot** advances atomically with the corresponding durable **Mid-Conversation System Message**.
|
|
|
-- A **Context Snapshot** stores one codec-encoded JSON value and, for removable dynamic sources, a pre-rendered removal message per stable **Context Source** key.
|
|
|
-- Changes from multiple **Context Sources** admitted at one safe boundary combine into one **Mid-Conversation System Message**.
|
|
|
-- Context changes are sampled and admitted lazily at a **Safe Step Boundary**, never pushed asynchronously when their source changes.
|
|
|
-- At a **Safe Step Boundary**, newly promoted user input or settled tool results precede any combined **Mid-Conversation System Message**.
|
|
|
+- **Instructions** is an opaque carrier composed from zero or more **Instruction Sources**.
|
|
|
+- **Model Context** is broader than **Instructions**. For each **Step**, the runner assembles the selected agent or provider system text, the **Instruction Baseline**, **Session History**, available tools, and step-local additions into one model request.
|
|
|
+- **Session History** contains projected conversational messages and admitted **Instruction Updates**; the active **Instruction Baseline** remains separate provider-request state.
|
|
|
+- The runner explicitly loads and combines instruction built-ins, **InstructionDiscovery**, selected-agent skill guidance, reference guidance, MCP guidance, and **InstructionEntry** values. There is no instruction registry.
|
|
|
+- `Instructions.combine(...)` preserves caller order and rejects duplicate stable namespaced source keys. The runner loads its producers concurrently, then combines them in its fixed declared order.
|
|
|
+- Each **Instruction Source** loader returns one coherent typed value or explicitly reports unavailability. `Instructions.make(...)` hides the value type so differently typed sources compose uniformly; its codec compares and stores the value, while pure renderers produce baseline, update, and optional removal text.
|
|
|
+- `Instructions.initialize(...)` observes composed **Instructions** once and produces a complete **Instruction Baseline** with **Applied Instructions**.
|
|
|
+- `Instructions.reconcile(...)` observes composed **Instructions** once and returns either unchanged or one combined chronological update. It never rewrites the baseline.
|
|
|
+- `Instructions.rebaseline(...)` renders a fresh baseline after completed compaction, recalling previously applied values for sources that are temporarily unavailable.
|
|
|
+- A changed **Instruction Source** may contribute text to one **Instruction Update** containing the newly effective state.
|
|
|
+- An **Instruction Update** persists the exact combined rendered text sent to the model through `session.instructions.updated`.
|
|
|
+- **Applied Instructions** advances atomically with the corresponding durable **Instruction Update**.
|
|
|
+- **Applied Instructions** stores one codec-encoded JSON value and, for removable sources, a pre-rendered removal message per stable **Instruction Source** key.
|
|
|
+- Changes from multiple **Instruction Sources** admitted at one safe boundary combine into one **Instruction Update**.
|
|
|
+- Instruction changes are sampled and admitted lazily at a **Safe Step Boundary**, never pushed asynchronously when their source changes.
|
|
|
+- At a **Safe Step Boundary**, prior tool results are already settled; instruction preparation completes before newly admitted user input promotes.
|
|
|
- An **Admitted Prompt** is replayable pending input, not yet model-visible **Session History**.
|
|
|
- **Prompt Promotion** atomically consumes the pending inbox entry and appends its model-visible user message.
|
|
|
- Steering prompts promote at the next **Safe Step Boundary** while the current **Session Drain** still requires continuation. Promoting any newly admitted user input resets the selected agent's step allowance; multiple prompts promoted at one boundary reset it once.
|
|
|
@@ -117,36 +130,28 @@ _Avoid_: Response envelope
|
|
|
- A **Session Drain** is process-local coordination rather than a durable domain entity. Durable recovery must reason from prompts, projected history, physical attempts, and tool state rather than inventing an enclosing execution identity.
|
|
|
- An **Execution** contains one or more **Session Drains**; a **Session Drain** contains one reserved assistant-turn span at a time; that span contains **Steps**; and each **Step** contains one or more **Physical Attempts** plus any tool calls it requires.
|
|
|
- A **Step** record covers only the model-visible span from first assistant output through tool settlement; pre-flight leaves no record, and one Step settles at most one record.
|
|
|
-- The first **Step** renders the latest complete **Baseline System Context** and initializes its **Context Snapshot** without emitting a redundant **Mid-Conversation System Message**; unavailable initial context blocks the Step instead of persisting an incomplete baseline.
|
|
|
-- Initial **System Context** preparation precedes the first durable input promotion so an unavailable baseline leaves that input pending and retryable; ordinary reconciliation remains after promotion.
|
|
|
-- Compaction starts a new **Context Epoch** with a freshly rendered **Baseline System Context** and **Context Snapshot**; prior **Mid-Conversation System Messages** remain durable audit history but leave projected model history.
|
|
|
-- A newly registered core or plugin-defined **Context Source** absent from the current snapshot emits its baseline rendering once at the next **Safe Step Boundary**.
|
|
|
-- **Context Source** keys are stable and namespaced; duplicate keys fail composition. `SystemContext.combine(...)` preserves caller order; the **System Context Registry** evaluates producers concurrently and combines them in stable contribution-key order so rendered context remains deterministic.
|
|
|
-- Each **Context Source** loader returns one coherent typed value. `SystemContext.make(...)` hides that value type so differently typed sources compose uniformly. Its codec compares and stores that value; its pure renderers produce model-visible baseline, update, and removal text only when needed.
|
|
|
-- `SystemContext.initialize(...)` observes a composed **System Context** once and produces a fresh **Baseline System Context** with its **Context Snapshot**.
|
|
|
-- `SystemContext.reconcile(...)` observes a composed **System Context** once and returns exactly one next action: unchanged, updated, replacement ready, or replacement blocked.
|
|
|
-- `SystemContext.replace(...)` renders a fresh generation after completed compaction or another baseline-replacing transition; it reports replacement blocked while previously admitted context is unavailable.
|
|
|
-- **Unavailable Context** uses stale-while-revalidate semantics and is distinct from a successfully loaded absence, which may emit removal text.
|
|
|
-- Ordinary **Context Source** loaders return values directly; loaders that intentionally use stale-while-revalidate may explicitly return **Unavailable Context**.
|
|
|
-- Nested project instruction discovery after successful reads remains a follow-up; when implemented, discovered instructions must be admitted durably at the next **Safe Step Boundary**.
|
|
|
-- Location-scoped services naturally re-resolve effective context when a moved session next runs in its destination location.
|
|
|
-- Moving a Session clears its active **Context Epoch**, so the destination must initialize a complete baseline before another prompt can promote.
|
|
|
-- Instruction discovery, source identity, persistence, and file loading belong to the instruction service; the **System Context** abstraction only composes effectful producers and renders loaded values.
|
|
|
-- The first instruction-service slice observes global and upward project `AGENTS.md` files as one ordered aggregate **Context Source** at each **Safe Step Boundary**.
|
|
|
-- Built-in and instruction context producers register through the **System Context Registry** with stable contribution keys. Plugin-defined context registration and hot-reload lifecycle remain a follow-up built on the same scoped registry seam.
|
|
|
-- Selected-agent available-skill guidance is a **Context Source** composed with Location-wide registry sources immediately before Context Epoch admission. It lists only names and descriptions permitted for that agent; skill bodies and locations are exposed only through the permission-checked `skill` tool.
|
|
|
+- The first **Step** renders the latest complete **Instruction Baseline** and creates its **InstructionCheckpoint** without emitting a redundant **Instruction Update**; an unavailable initial source blocks the Step instead of persisting an incomplete baseline.
|
|
|
+- Instruction preparation precedes durable input promotion on every Step so an unavailable first baseline leaves pending input untouched and later updates enter history before newly promoted input.
|
|
|
+- Completed compaction rebaselines the **InstructionCheckpoint** from current **Instructions** and removes earlier **Instruction Updates** from active projected model history while preserving durable audit history.
|
|
|
+- A newly composed **Instruction Source** absent from **Applied Instructions** emits its baseline rendering once at the next **Safe Step Boundary**.
|
|
|
+- **Unavailable Instruction Source** uses stale-while-revalidate semantics and is distinct from a successfully loaded absence, which may emit removal text.
|
|
|
+- **InstructionDiscovery** observes ambient instructions as one ordered aggregate **Instruction Source**.
|
|
|
+- Ambient discovery reads global and upward-project `AGENTS.md` files and honors `OPENCODE_DISABLE_PROJECT_CONFIG` for project files.
|
|
|
+- After a successful internal file or directory read, nearby `AGENTS.md` files toward the Location root are injected once per Session as durable synthetic instruction messages.
|
|
|
+- **InstructionEntry** stores API-managed per-Session JSON values. Each entry contributes one `api/<key>` **Instruction Source**, so adding, replacing, or removing an entry is reconciled at the next **Safe Step Boundary**.
|
|
|
+- Location-scoped instruction producers naturally re-resolve when a moved Session next runs in its destination Location.
|
|
|
+- Moving a Session resets its **InstructionCheckpoint**, so the destination must initialize a complete baseline before another prompt can promote. Committed revert also resets the checkpoint.
|
|
|
+- Selected-agent available-skill guidance is an **Instruction Source** composed explicitly by the runner. It lists only names and descriptions permitted for that agent; skill bodies and locations are exposed only through the permission-checked `skill` tool.
|
|
|
- The selected agent and model are sampled when a **Step** starts. Changes admitted after that boundary apply to the next Step and do not restart the current Step.
|
|
|
-- Selected-agent available-skill guidance remains a **Context Source**. An agent switch that changes that guidance produces a **Mid-Conversation System Message** while preserving the current baseline.
|
|
|
+- An agent switch that changes selected-agent guidance produces an **Instruction Update** while preserving the current baseline.
|
|
|
- Local tool authorization and pending permission requests retain the effective agent of the **Step** that issued the call; a later agent switch cannot change that call's policy.
|
|
|
-- Context source changes never wake idle sessions; the next naturally scheduled **Safe Step Boundary** loads and compares current values lazily.
|
|
|
-- Once admitted, a **Mid-Conversation System Message** remains durable even if the following **Physical Attempt** fails and is replayed unchanged on retry.
|
|
|
-- **Mid-Conversation System Messages** remain durable Session-message history; normal user-facing transcript surfaces may hide them.
|
|
|
-- The date **Context Source** initially preserves host-local calendar-date behavior; a configured user timezone may replace that default later.
|
|
|
-- A **Context Epoch** begins with one immutable **Baseline System Context**.
|
|
|
-- A **Baseline System Context** is stored durably and reused verbatim across process restarts within its **Context Epoch**.
|
|
|
-- A **Baseline System Context** durably preserves the exact joined text used for the active provider-cache prefix.
|
|
|
-- Completed compaction starts a new **Context Epoch** on the next **Physical Attempt**, folding the current complete **System Context** into a fresh baseline and removing earlier **Mid-Conversation System Messages** from active model history.
|
|
|
-- A model/provider switch preserves the current **Context Epoch** and chronological conversation history; the new selection applies to the next **Step**.
|
|
|
+- Instruction source changes never wake idle Sessions; the next naturally scheduled **Safe Step Boundary** loads and compares current values lazily.
|
|
|
+- Once admitted, an **Instruction Update** remains durable even if the following **Physical Attempt** fails and is replayed unchanged on retry.
|
|
|
+- **Instruction Updates** remain durable Session-message history; normal user-facing transcript surfaces may hide them.
|
|
|
+- The date **Instruction Source** initially preserves host-local calendar-date behavior; a configured user timezone may replace that default later.
|
|
|
+- An **Instruction Baseline** is stored durably and reused verbatim across process restarts until rebaseline or reset.
|
|
|
+- An **Instruction Baseline** durably preserves the exact joined text used for its part of the active provider-cache prefix.
|
|
|
+- A model/provider switch preserves the current **InstructionCheckpoint** and chronological conversation history; the new selection applies to the next **Step**.
|
|
|
- **Native Continuation Metadata** remains in durable history. Step projection includes it only for a successful exact originating provider/model match; failed Steps and incompatible models omit opaque metadata, while non-empty visible reasoning lowers to ordinary assistant text after a model switch. This conservative relation may widen only when recorded provider tests establish compatibility.
|
|
|
- **Model Request Options** remain provider-semantic through Catalog resolution. The Session runner maps them into the LLM package's provider-option namespace; the selected protocol adapter alone owns provider wire encoding.
|
|
|
- **Generation Controls**, protocol-semantic **Model Request Options**, and compatibility request body fields are separate Catalog domains. A shared ingestion adapter partitions legacy and models.dev AI-SDK-shaped options before routing.
|
|
|
@@ -190,16 +195,16 @@ _Avoid_: Response envelope
|
|
|
- `sessions.message({ sessionID, messageID })` is a required resource lookup. An unknown Session fails with `SessionNotFoundError`; a known Session with an absent or differently owned message fails with `MessageNotFoundError` without disclosing cross-Session ownership. Absence is not represented as `undefined` across the public HTTP boundary.
|
|
|
- `sessions.interrupt({ sessionID })` first verifies that the durable Session exists, failing with `SessionNotFoundError` otherwise. For a known Session, interruption is idempotent: idle, already-settled, or locally unowned execution is a no-op.
|
|
|
- `sessions.active()` snapshots the current process's foreground Session drain registry as a record of Session IDs to `{ type: "running" }`. Missing IDs are inactive; background subagents and tasks do not make their parent Session active, and process restart clears the registry.
|
|
|
-- `sessions.context({ sessionID })` preserves the existing message-only operation. It returns projected conversational messages selected as Session context; it does not include or represent the complete provider request context, whose baseline system context and other contributions remain separate.
|
|
|
-- **Open question**: Should a future, separately named operation expose the complete provider request context, including baseline system context, selected source contributions, and context-epoch metadata?
|
|
|
+- `sessions.context({ sessionID })` preserves the existing message-only operation. It returns projected **Session History**; it does not include or represent the complete **Model Context**, whose system text, **Instruction Baseline**, tools, and step-local additions remain separate.
|
|
|
+- **Open question**: Should a future, separately named operation expose complete **Model Context**, including the instruction baseline, applied instruction metadata, tools, and step-local additions?
|
|
|
- `sessions.prompt(...)` exposes `resume?: boolean`. Omitting it preserves durable admission followed by an advisory execution wake; `resume: false` requests durable admit-only behavior.
|
|
|
- The public operation remains `sessions.prompt(...)`; `SessionInput.admit` is the internal primitive, while the public `Admission` result and `resume` option express its durable admission semantics.
|
|
|
- `sessions.create(...)` accepts an optional `location`. Omission resolves through the connected OpenCode instance's default or current location; an explicit value selects a known location. Networked and embedded transports use the same handler semantics.
|
|
|
- `sessions.switchAgent({ sessionID, agent })` is part of the common client alongside `sessions.switchModel(...)`. It affects subsequent Session activity and fails with `SessionNotFoundError` for an unknown Session.
|
|
|
- The **Embedded OpenCode** Layer delegates to the same scoped creation path; it does not define a second implementation.
|
|
|
- A **PTY Environment** adapter observes plugins in the request Location while passing the resolved PTY working directory to the hook; standalone servers use an empty adapter.
|
|
|
-- A **Mid-Conversation System Message** lowers to the provider's native chronological instruction role when supported and to a wrapped chronological fallback otherwise.
|
|
|
-- When the effective aggregate instruction set changes, its **Mid-Conversation System Message** includes the complete current ordered set and supersedes the prior aggregate value; when no ambient instructions remain, the message states that previously loaded instructions no longer apply.
|
|
|
+- An **Instruction Update** lowers to the provider's native chronological instruction role when supported and to a wrapped chronological fallback otherwise.
|
|
|
+- When the aggregate discovered instruction set changes, its **Instruction Update** includes the complete current ordered set and supersedes the prior aggregate value; when no discovered instructions remain, the message states that previously loaded instructions no longer apply.
|
|
|
- Ambient project instruction discovery honors `OPENCODE_DISABLE_PROJECT_CONFIG`; global instructions remain eligible.
|
|
|
- Oversized textual **Model Tool Output** retains a bounded preview in Session history while its complete text moves to managed tool-output storage. Arbitrary structured-result size is a separate concern.
|
|
|
- One tool settlement receives one aggregate textual limit, using the configured maximum lines or UTF-8 bytes, whichever is reached first. The limit is provider-independent; token pressure belongs to context assembly and compaction.
|
|
|
@@ -232,9 +237,9 @@ Before stabilizing the client API:
|
|
|
|
|
|
## Example dialogue
|
|
|
|
|
|
-> **Dev:** "The date changed while the session was active. Should the **Mid-Conversation System Message** say what the old date was?"
|
|
|
-> **Domain expert:** "No. Emit the newly effective date so the agent can act on the current **System Context**."
|
|
|
+> **Dev:** "The date changed while the session was active. Should the **Instruction Update** say what the old date was?"
|
|
|
+> **Domain expert:** "No. Emit the newly effective date so the agent can act on the current instructions."
|
|
|
|
|
|
## Flagged ambiguities
|
|
|
|
|
|
-- Legacy `experimental.chat.system.transform` can mutate the assembled baseline system prompt arbitrarily, but V2 plugins do not yet expose an equivalent hook. Decide separately whether to port it, replace dynamic uses with plugin-defined **Context Sources**, or narrow its semantics.
|
|
|
+- Legacy `experimental.chat.system.transform` can mutate assembled system text arbitrarily, but V2 plugins do not yet expose an equivalent hook. Decide separately whether to port it, model dynamic uses as explicit **Instruction Sources**, or narrow its semantics.
|