Skip to content

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

Description

@ualtinok

Feature hasn't been suggested before.

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

  1. github-actions commented on Sep 16, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

    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.

  2. sergiopadure commented on Sep 23, 2026

    @sergiopadure

    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; exposing compact here would let a plugin cover it.

  3. jakujur commented on Sep 24, 2026

    @jakujur

    +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 with parentID: toolContext.sessionID, so it stayed nested under the caller. In V2 (@opencode/plugin 2.0.12) every call creates a root session, and since session.remove isn't exposed, the session list fills up with stray reader sessions that can't be cleaned up.

    ctx.generate.text avoids the session but loses tools, and the built-in subagent tool counts toward subagent_depth. Forwarding parentID in the plugin projection (host.ts:519) would fix it.

  4. TheStaticMage commented on Sep 27, 2026

    @TheStaticMage

    +1 for point 3, I create sessions from plugins and would prefer to keep them organized as child sessions like I could in v1.

  5. LordMike commented on Sep 28, 2026

    @LordMike

    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 parentId property, which severely screws up my session lists.. :)

    So looking forward to ensuring parentId being used, on new sessions.

  6. antoniodavid commented on Sep 28, 2026

    @antoniodavid

    +1 on item 3 (parentID is not forwarded on session.create). Live evidence on OpenCode 2.0.18:

    • POST /api/session with {"title": "probe", "parentID": "ses_..."} returns the created session without parentID; the field is ignored (and is absent from the request schema).
    • The plugin projection is the other half: SessionDomain is a Pick that cannot pass parentID either. 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/context and currently emulates delegation with top-level sessions. We can set a title and emit context.progress metadata, 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.

  7. acramsay commented on Sep 29, 2026

    @acramsay

    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

  8. LordMike commented on Sep 29, 2026

    @LordMike

    How do we do that? Poke on discord? @-tag in the PR? Thumbs-up the PR?
    ..

  9. ualtinok commented on Sep 29, 2026

    @ualtinok
    ContributorAuthor

    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.

  10. rekram1-node commented on Sep 30, 2026

    @rekram1-node
    Collaborator

    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

  11. sergiopadure commented on Sep 30, 2026

    @sergiopadure

    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

    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.

  12. rekram1-node commented on Sep 30, 2026

    @rekram1-node
    Collaborator

    Yeah we are going to work more on that very soon, it's not an acceptable state.

  13. rekram1-node commented on Oct 1, 2026

    @rekram1-node
    Collaborator

    Merged fixes for most of these, I think 2 are left.

  14. rekram1-node commented on Oct 1, 2026

    @rekram1-node
    Collaborator
    1. 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.

    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:

    await ctx.session.update({
      sessionID,
      metadata: { phase: "review" },
    })
    

    I did find a bug in update for plugins but wndering why u cant use this (once it's fixed)

  15. rekram1-node commented on Oct 1, 2026

    @rekram1-node
    Collaborator

    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.

  16. acramsay commented on Oct 2, 2026

    @acramsay

    Thank you for working on this rekham

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions