anomalyco / anomalyco/opencode
session.generate: solidify contract and capabilities
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- Avg merge
- 7h 2m
- Merged PRs (30d)
- 384
Description
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.warmingplugin) - 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: nonewith 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/
providerOptionsalways match the runner? - Should generate go through
SessionModelRequestwith 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:
- Guaranteed invariants
- Allowed request shape (tools / choice / prep sharing)
- Return type
- 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: nonelowering; stop forcingnoneon generate
Ask
Please grill / decide the tools policy and return-value shape first; those drive prep parity and warming correctness.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with plans/session-generate.md, then compare generate-node.ts with SessionModelRequest.prepare and the listed callers. Decide and document the tools policy, return shape, preparation parity, failure behavior, and warming requirements; update the implementation, tests, and plan so they match the written contract.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- backend-api-design, documentation
- Issue type
- Refactor
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 28/100