anomalyco / anomalyco/opencode

[FEATURE]: Five session capabilities that exist in core but are unreachable from a plugin

Open
#49,389 1 comment 0 reactions 1 assignee View on GitHub

@nexxeln is already working on this.

Since Sep 16, 2026.

Dominant language
TypeScript
Stars
209k
Forks
27.5k
PR merge metrics
PR metrics pending

Description

Feature hasn't been suggested before.
  • I searched existing issues. #43517 asks for read-only session enumeration and #40863 asks for hidden/ephemeral sessions; both are adjacent but neither covers the write-side gaps below. #34957 and #35364 track the tool-context gaps, which I have left out of this.
Describe the enhancement you want to request

Five capabilities exist and work in core, but are unreachable from a plugin because the value is either omitted from the plugin projection or not forwarded internally. Four are a forwarding change at a single call site; the fifth needs a design decision.

All references are upstream/v2 at 2cdd938152. We hit these porting three plugins to the v2 API.

1. session.compact is not projected. SessionDomain is a Pick of create | get | switchAgent | switchModel | prompt | generate | command | synthetic | interrupt | update | move | wait | context (packages/plugin/src/effect/session.ts:126). compact exists on the core interface (packages/core/src/session.ts:422) and is reachable over HTTP. A plugin that owns compaction via the compaction hook can respond to a fold the host starts, but cannot start one.

2. session.remove is not projected. Same Pick. Combined with (3), a plugin that creates sessions has no way to delete them.

3. parentID is not forwarded on session.create. Core accepts it — the input is { location } | { parentID } (packages/core/src/session.ts:91) — but the plugin projection enumerates fields and omits it (packages/core/src/plugin/host.ts:519). Since location is always supplied there, the parentID arm is unreachable, so every plugin-created session is a root. Removal cascades to children (packages/core/src/session.ts:356), so a parented child would be collected automatically; as it stands, plugin-created worker sessions accumulate with no host-side cleanup path. #40863 describes the create-child-then-delete pattern this prevents.

4. session.generate cannot use a different model. The input is { sessionID, prompt } (packages/core/src/session.ts:182) and the model is resolved from the session (packages/core/src/session/generate.ts:32). model is also readonly on the hook draft (packages/plugin/src/effect/session.ts:63), and prepare never reads it, so an override attempt fails silently rather than erroring. The use case is running a hidden, non-persisted completion — summarisation, classification — on a cheaper model than the session's. This one is a genuine new input rather than a forwarded field.

5. The subagent tool does not pass metadata to the child session. sessions.create is called with parentID, title, agent, model (packages/core/src/tool/plugin/subagent.ts:188). Session.create accepts metadata and the column exists, so the destination is already there — it is simply never populated. Forwarding an optional metadata argument would let a plugin read delegation context from the child's session row instead of parsing it back out of the prompt text. Today the only spawn-time channel is mutating the prompt string.

parentID itself is reliable for task-spawned children on both lines, and is the correct join key; the gap is that a plugin can neither set it nor remove what it creates.

Happy to open a PR for any subset of these if the shape is agreeable — 1, 2, 3 and 5 look like one-line changes each, and 4 would want a design opinion first.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.