Repository navigation
[FEATURE]: Five session capabilities that exist in core but are unreachable from a plugin #49389
Description
Feature hasn't been suggested before.
- I searched existing issues. [FEATURE]: Expose read-only persisted session history APIs to v2 plugins #43517 asks for read-only session enumeration and [FEATURE]: Add explicit hidden or ephemeral sessions for plugin background tasks #40863 asks for hidden/ephemeral sessions; both are adjacent but neither covers the write-side gaps below. v2: internal tool plugins expose gaps in the public plugin API #34957 and V2: revisit tool plugin APIs and execute integration architecture #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.
Activity
github-actions commentedon Sep 16, 2026
This issue might be a duplicate of existing issues. Please check:
session.compact— the overlap with points 1 and potentially others here is significantparentIDforwarding andsession.remove(points 2 and 3)metadataon subagent sessions so plugins can surface it at runtime (overlaps with point 5)It may be worth coordinating with those issues or consolidating, though the specific framing here (forwarding gaps at call sites) is distinct enough that a separate issue is defensible.
sergiopadure commentedon Sep 23, 2026
Another use case for item 1 (
session.compact): a server plugin that keeps idle sessions' prompt caches warm wants to compact the session when its idle window ends, so the first message after a long break doesn't re-send the whole context uncached. It can detect the end of the window but has no way to start the compaction. Idle-time compaction in core is tracked separately in #50777; exposingcompacthere would let a plugin cover it.jakujur commentedon Sep 24, 2026
+1 on points 2 and 3.
Use case: a plugin tool,
ask_file, that asks a cheap reader agent about a file in a short-lived session. In V1 I created it withparentID: toolContext.sessionID, so it stayed nested under the caller. In V2 (@opencode/plugin2.0.12) every call creates a root session, and sincesession.removeisn't exposed, the session list fills up with stray reader sessions that can't be cleaned up.ctx.generate.textavoids the session but loses tools, and the built-in subagent tool counts towardsubagent_depth. ForwardingparentIDin the plugin projection (host.ts:519) would fix it.TheStaticMage commentedon Sep 27, 2026
+1 for point 3, I create sessions from plugins and would prefer to keep them organized as child sessions like I could in v1.
LordMike commentedon Sep 28, 2026
Came here as I just converted to v2, and found that a plugin I use which generates subagents in a special way is unable to assign the
parentIdproperty, which severely screws up my session lists.. :)So looking forward to ensuring parentId being used, on new sessions.
antoniodavid commentedon Sep 28, 2026
+1 on item 3 (
parentIDis not forwarded onsession.create). Live evidence on OpenCode 2.0.18:POST /api/sessionwith{"title": "probe", "parentID": "ses_..."}returns the created session withoutparentID; the field is ignored (and is absent from the request schema).SessionDomainis aPickthat cannot passparentIDeither. A plugin that creates sessions for delegation can therefore never produce a child session — no subtask row, and no child navigation, which keys off session records'parentID.Use case: a harness plugin (ODF, a spec-driven Odoo workflow pack) spawns one session per phase through
ctx.session.create/prompt/wait/contextand currently emulates delegation with top-level sessions. We can set a title and emitcontext.progressmetadata, but the sessions stay unlinked and users cannot follow the delegated agent.If item 3 really is a single forwarding change, it unlocks real child sessions for plugin-created delegation without any plugin-side redesign. Item 2 (
session.remove) is valuable for the same flow: a plugin that creates sessions has no cleanup path today.acramsay commentedon Sep 29, 2026
PR #47745 was created ~3 weeks ago and directly addresses item 3. Looks a little stale but it looks like a very targeted change. It needs attention from maintainers
LordMike commentedon Sep 29, 2026
How do we do that? Poke on discord? @-tag in the PR? Thumbs-up the PR?
..
ualtinok commentedon Sep 29, 2026
I believe most of the time there's no way to get attention to Issues/PRs until the opencode team themselves encounter the issue. That's my experience for the past 6 months, so I stopped trying.
rekram1-node commentedon Sep 30, 2026
Discord is the best way currently, github is a bit of a shit storm rn unfortunately, there is a heap of spam that we deal with and it's very difficult to sift through noise. We also have agents try to find high traction things.
We are going to be better tho, we are trying to fix this process.
I only saw this because of someone on discord
sergiopadure commentedon Sep 30, 2026
I understand the difficulty of filtering out spam, and I appreciate that you’re working to improve the process. That said, given OpenCode’s scale, I would expect more reliable triage of issues and PRs to bring urgent problems and requests with strong community support to the team’s attention.
You mention that agents are already helping. I believe this is a task AI can support effectively, particularly with newer decision models such as Jev and Solar Decide, but those tools need to translate into a process customers can rely on. Getting an issue noticed should not depend on someone raising it on Discord.
For me, this is about improving not only the product but also the customer-facing processes that build and maintain trust, rather than leave customers feeling ignored or forgotten. I would be more understanding of these limitations in a single-developer tool like Paseo. With a full team and a business behind OpenCode, I think expecting a more reliable triage and communication process is reasonable.
rekram1-node commentedon Sep 30, 2026
Yeah we are going to work more on that very soon, it's not an acceptable state.
rekram1-node commentedon Oct 1, 2026
Merged fixes for most of these, I think 2 are left.
rekram1-node commentedon Oct 1, 2026
What are you looking for here exactly? I don't want to add new parameters to a tool... Ideally you can use the session patch instead:
I did find a bug in update for plugins but wndering why u cant use this (once it's fixed)
rekram1-node commentedon Oct 1, 2026
Have a pr for the final one. Prolly will be in next release. All items are addressed by merged fixes, the open pr, and then hopefully the workaround^ is sufficient.
Lmk if anyone has any complaints or concerns here.
acramsay commentedon Oct 2, 2026
Thank you for working on this rekham