Skip to content

Proposal: add explicit thread/unload app-server RPC #21889

@ZichaoLong

Description

@ZichaoLong

What variant of Codex are you using?

CLI / app-server

What feature would you like to see?

I would like app-server to expose an explicit thread/unload RPC.

Problem

thread/unsubscribe is currently a delayed unload path, not an immediate unload primitive. The
README says a thread remains loaded until it has had no subscribers and no activity for 30 minutes.

That is reasonable for reconnect-friendly clients, but app-server is also a multi-thread host:
one runtime may keep many unrelated threads loaded at once. In that model, clients need a narrow
way to unload one specific loaded thread immediately, without resetting the whole backend and
disturbing other loaded threads.

This is mainly about thread-scoped settings whose contract is "takes effect on next load". Today
the choices are:

  • wait for delayed idle cleanup
  • reset the entire backend to affect one thread

This is not a request to hot-update all memory behavior on an already loaded thread.
thread/memoryMode/set already covers persisted future memory-generation eligibility. The gap is a
per-thread unload boundary for settings whose effect is bound at thread load / session
construction.

Concrete use case

Suppose thread A is loaded but idle, and threads B/C are also loaded in the same app-server
runtime. A client updates some next-load-only setting for thread A and wants the next attach/resume
of A to pick it up immediately. Waiting 30 minutes is too slow, but resetting the backend would
also disrupt B/C. A narrow thread/unload would solve exactly that case.

Proposed API

A separate thread/unload RPC would keep the contracts clear:

  • thread/unsubscribe: subscription / reconnect semantics
  • thread/unload: explicit operator action

Suggested conservative first version:

  • method: thread/unload
  • params: threadId
  • response statuses: unloaded, notLoaded, active, otherSubscribers

Suggested behavior:

  • notLoaded: already not loaded; no-op
  • active: refuse unload while the thread is active
  • otherSubscribers: refuse unload if another connection is still subscribed
  • unloaded: shutdown completed and the thread transitioned to notLoaded

Suggested notifications:

  • reuse existing thread/closed
  • reuse existing thread/status/changed to notLoaded

Suggested call sequence

  1. Client persists a next-load-only setting for thread A.
  2. Client calls thread/unload(threadId=A).
  3. Server refuses if A is active or still has other subscribers.
  4. Otherwise server unloads A and emits the existing close/status notifications.
  5. The next attach/resume of A loads a fresh session and picks up the new setting.

Why not the alternatives

I do not think changing thread/unsubscribe to mean immediate unload is the right path, especially
since there is already adjacent upstream work around unsubscribe/unload timing and reconnect
behavior (#10954, #17398, #20487).

I also do not think config/batchWrite with reloadUserConfig: true replaces this need. Runtime
config reload is useful for refreshable user-layer settings, but it is not the same thing as a
per-thread unload boundary for next-load-only behavior.

I also do not think the internal unload_thread_without_subscribers(...) helper should be exposed
directly as-is, because it appears to be a background idle-cleanup path rather than a
request/response-quality explicit unload API.

Questions

  1. Would maintainers accept a separate thread/unload RPC?
  2. Should the first version be experimental-only?
  3. Is "idle + no other subscribers" the right initial guardrail?

Additional information

I reviewed upstream main on 2026-05-09 and did not find an existing public thread/unload RPC.
I also did not find an open or merged PR whose primary goal was to add that API, though I did find
adjacent thread lifecycle work in #10954, #14137, #14997, #17398, and #20487.

If this direction is interesting, I can provide a focused implementation plan or prepare a patch
after maintainer guidance.

Metadata

Metadata

Assignees

No one assigned

    Labels

    app-serverIssues involving app server protocol or interfacesenhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions