Skip to content

[FEATURE]: Plugin API: bridge session revert, and expose server self-endpoint to plugins #51599

Open

Description

@yangyaofei

Feature hasn't been suggested before.

  • I have verified this feature I'm about to request hasn't suggested before. Related issues were found but all were auto-closed by the stale bot without official resolution — see "Related issues" below.

Describe the enhancement you want to request

While porting a quota-aware retry plugin (429 handling with unlimited round continuation) to the opencode 2.0 plugin API, we hit two platform gaps in the same area: plugins cannot manage session messages (revert), and plugins cannot discover the HTTP API of the server instance they run inside.

1. session.revert is not exposed to plugins

The capability exists end-to-end except at the plugin boundary:

  • Core service: revert stage/clear/commit are implemented (packages/core/src/session.ts ~:451-454)
  • HTTP API: POST /api/session/:id/revert/stage, DELETE .../revert, POST .../revert/commit (packages/protocol/src/groups/session.ts)
  • Plugin Host session domain (packages/core/src/plugin/host.ts ~:518-546) and the promise adapter (packages/plugin/src/promise/adapter.ts) bridge create/get/prompt/synthetic/interrupt/update/move/wait/context — but not revert. Same for the effect-form session domain (packages/plugin/src/effect/session.ts).

Use case: when a provider quota exhausts mid-turn, our plugin re-drives execution via ctx.session.synthetic (works great). To keep the transcript clean we would like to remove the failed assistant message and the previous internal marker — currently impossible from a plugin, forcing either HTTP self-calls (with server port/password configuration) or accepting a growing list of failed messages.

Request: bridge revert.stage/clear/commit (or at minimum a remove(messageID)) into the plugin session domain.

2. Plugins cannot discover their own server's HTTP endpoint

Plugins run in-process with the server, yet there is no way to learn which server instance they belong to:

  • ctx.app only exposes name/version/channel
  • No url/port/auth anywhere in the plugin context
  • The official discovery file (~/.local/state/opencode/service.json, written only in service mode) contains url/pid/password, but a plugin reading it cannot safely assume it maps to its own instance (multi-instance machines), and serve mode does not write it at all

Request: expose the server's own endpoint + auth (e.g. ctx.app.server = { url, password } or similar) so plugins can call their own instance's HTTP API without user configuration.

Related issues

Environment

opencode 2.0.15 (linux/arm64 binary + packages/core source). Plugin form: promise (define/{id, setup}).

Activity

  1. changed the title [-]Plugin API: expose session revert, and server self-endpoint discovery for plugins[/-] [+][FEATURE]: Plugin API: bridge session revert, and expose server self-endpoint to plugins[/+] on Sep 27, 2026
  2. github-actions commented on Sep 27, 2026

    @github-actions
    Contributor

    Thanks for updating the issue with the required feature verification checkbox and [FEATURE]: title prefix!

  3. Shalin-Shah-2002 commented on Sep 27, 2026

    @Shalin-Shah-2002

    Implementation PR opened: #51601. It adds plugin session revert operations and instance-specific ctx.app.server endpoint credentials. The PR targets v2, includes focused validation, and uses Fixes #51599 for automatic tracking.

  4. Shalin-Shah-2002 commented on Sep 27, 2026

    @Shalin-Shah-2002

    PR #51601 was rebased onto v2 to remove unrelated pre-existing worktree history. It now contains only the focused implementation commit and nine issue-related files.

  5. opencodejr commented on Oct 28, 2026

    @opencodejr
    Contributor

    Thanks for the detailed request! You're asking for two additions to the v2 plugin API:

    1. Bridge session revert (stage/clear/commit, or a simpler remove(messageID)) into the plugin session domain, so a plugin can remove failed assistant messages.
    2. Expose the running server's own endpoint and auth in the plugin context, so a plugin can call its own instance's HTTP API without extra configuration.

    I checked the current code. The promise and effect plugin session domains bridge synthetic, interrupt and other methods, but not revert, and the plugin context has no server URL or credentials. Neither of these can be worked around inside a plugin right now. Maintainers will consider the request.

    Related issues:

  6. OpeOginni commented on Nov 6, 2026

    @OpeOginni
    Contributor

    Another use case for the server self-endpoint request is a server plugin that moves the current session to a remote OpenCode server. This cannot work with --standalone without a change in OpenCode.

    Problem and use case

    This needs session.export on the local server, session.import on the remote, session.form.create/get/cancel for user confirmation, and session.active plus session.inbox.list to check that the local session is idle. The plugin context's session domain exposes none of these. ctx.rpc only reaches plugin-registered methods, not the server's own API.

    What we tried

    A plugin can build an OpenCode.make client using Service.discover() or explicitly configured server credentials. But opencode --standalone starts a private opencode serve --stdio --port 0 with a random port. Plugins receive no address, and the server deletes OPENCODE_SERVER_PASSWORD from its environment after reading it. Discovery finds the background service instead, which is not hosting the session. The private URL cannot be configured ahead of time.

    The only workaround today is opencode serve --port 4096, attach with opencode --server http://127.0.0.1:4096, and configure the plugin to use that address.

    Verified with OpenCode 2.2.5, @opencode/plugin 2.0.30, and @opencode/client 2.2.1.

    Proposal

    1. Give server plugins an authenticated client for their host server, for example ctx.client, an OpenCodeClient scoped to that plugin. It should work in service, standalone, and serve modes without discovery, ports, or passwords.
    2. Or, as a smaller alternative, add export, import, form with create/get/cancel, active, and inbox.list to the plugin session domain.

    We're happy to send a PR if maintainers say which option they prefer.

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