Skip to content

session.generate: solidify contract and capabilities #38558

Description

@rekram1-node

Context

V2 has session.generate (SessionGenerate): one physical LLM attempt from the current Session model context, with a transient prompt, that must not mutate the Session.

Primary callers today:

  • Session warming (opencode.warming plugin)
  • HTTP POST /api/session/:sessionID/generate
  • Plugin ctx.session.generate

Original design notes live in plans/session-generate.md (status: in progress). Implementation has drifted from parts of that plan and needs an explicit product/architecture contract.

Current behavior (as implemented)

Aspect Today
Input { sessionID, prompt }
Output string (assistant text only)
History Read-only preview of committed context + in-memory prompt
Tools Tool definitions are included (for prompt-cache parity with agent turns)
toolChoice Not forced to none (aligned with normal agent request shape after recent fix)
Tool calls If the model emits tool calls: ignored — not executed, not settled, not written to the Session
Durability No admission, events, usage, instruction commit, or compaction
Prep path Own request construction in generate-node.ts, not fully shared with SessionModelRequest.prepare

Open questions to solidify

1. What is generate for?

Rank and lock intended use cases:

  • Cache warming / keep-alive (must preserve provider prompt-cache identity with agent turns)
  • Ephemeral recap / title / UI blurbs
  • Plugin one-shots over live Session context
  • Something closer to “run one step without durability”?

2. Tools policy

Choose one explicit contract:

  • A. Definitions only, ignore calls (current) — best cache match; empty text possible if model only tool-calls
  • B. No tools on the wire — simpler semantics; breaks Anthropic/Bedrock tool-prefix cache for warming
  • C. toolChoice: none with tools present — forbid calls where API supports it; Bedrock still cannot
  • D. Execute tools once, still non-durable — AI SDK–like; blurs the no-settlement boundary

3. Request preparation parity

Plan required sharing prep with the durable runner then diverging before settlement. Today generate rebuilds the request separately.

  • Must generate be byte-equivalent to a durable step’s prepared request (minus the transient user message)?
  • Should thinking/effort/variant/providerOptions always match the runner?
  • Should generate go through SessionModelRequest with a generate-specific shape?

4. Return value / API surface

Is text-only enough, or do callers need:

  • usage / cache read-write diagnostics
  • finish reason
  • toolCalls (even if not executed)
  • model identity
  • optional revision/seq for stale-result detection

5. Failure modes

Lock behavior for:

  • context overflow (no auto-compaction today — correct?)
  • unsettled assistant / open tool loop in history
  • concurrent durable drain while generate is in flight (snapshot semantics)
  • instruction initialization blocked

6. Warming-specific requirements

If warming remains a first-class consumer:

  • Same tools + system + history prefix as agent turns
  • Cache breakpoint placement (not on the keep-alive placeholder user message?)
  • TTL / interval interaction with Anthropic 5m vs 1h ephemeral cache
  • Whether warm requests should be tagged for hooks (today prompt-text matching)

Non-goals (unless we explicitly promote them)

  • Mutating Session history or usage
  • Multi-step tool loops
  • Auto-compaction from generate
  • Becoming a second full runner

Proposed outcome

A short written contract (docs or design note) that answers:

  1. Guaranteed invariants
  2. Allowed request shape (tools / choice / prep sharing)
  3. Return type
  4. Supported callers and what they may rely on

Then align implementation + tests to that contract (and update plans/session-generate.md).

Related

  • Warming + Anthropic cache investigation (tools stripped on toolChoice: none, auto breakpoints on warm prompt)
  • PRs: Anthropic/Gemini toolChoice: none lowering; stop forcing none on generate

Ask

Please grill / decide the tools policy and return-value shape first; those drive prep parity and warming correctness.

Metadata

Metadata

Assignees

No one assigned

    Labels

    2.0coreAnything pertaining to core functionality of the application (opencode server stuff)discussionUsed for feature requests, proposals, ideas, etc. Open discussion

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions