feat: add thread idle lifecycle hook (#24744)

## Why

Extensions can currently observe thread start, resume, and stop, but
they do not have a lifecycle point for the host to say that immediately
pending thread work has drained. That makes idle follow-up behavior
harder to express as extension-owned logic instead of host-specific
plumbing.

This adds an explicit idle lifecycle hook so an extension can react when
a thread becomes idle while the host keeps ownership of whether any
submitted follow-up input starts a turn, is queued, or is ignored.

## What changed

- Added `ThreadIdleInput` with access to the session-scoped and
thread-scoped extension stores.
- Added a default `on_thread_idle` method to
`ThreadLifecycleContributor`.
- Re-exported `ThreadIdleInput` from the extension API surface.

## Testing

Not run; this only extends the extension API trait surface with a
default hook and exported input type.
This commit is contained in:
jif-oai
2026-05-27 15:17:23 +02:00
committed by GitHub
parent 7df8431bbd
commit d2ebb8d8ca
3 changed files with 17 additions and 0 deletions

View File

@@ -16,6 +16,7 @@ mod turn_lifecycle;
pub use prompt::PromptFragment;
pub use prompt::PromptSlot;
pub use thread_lifecycle::ThreadIdleInput;
pub use thread_lifecycle::ThreadResumeInput;
pub use thread_lifecycle::ThreadStartInput;
pub use thread_lifecycle::ThreadStopInput;
@@ -51,6 +52,13 @@ pub trait ThreadLifecycleContributor<C: Sync>: Send + Sync {
/// Called after the host constructs a runtime from persisted history.
async fn on_thread_resume(&self, _input: ThreadResumeInput<'_>) {}
/// Called after the host has drained immediately pending thread work.
///
/// Implementations may use host capabilities captured by the extension to
/// submit follow-up input. The host remains responsible for deciding
/// whether that input starts a turn, is queued, or is ignored.
async fn on_thread_idle(&self, _input: ThreadIdleInput<'_>) {}
/// Called before the host drops the thread runtime and thread-scoped store.
async fn on_thread_stop(&self, _input: ThreadStopInput<'_>) {}
}

View File

@@ -18,6 +18,14 @@ pub struct ThreadResumeInput<'a> {
pub thread_store: &'a ExtensionData,
}
/// Input supplied when the host has no immediately pending thread work.
pub struct ThreadIdleInput<'a> {
/// Store scoped to the host session runtime.
pub session_store: &'a ExtensionData,
/// Store scoped to this thread runtime.
pub thread_store: &'a ExtensionData,
}
/// Input supplied when the host stops a thread runtime.
pub struct ThreadStopInput<'a> {
/// Store scoped to the host session runtime.

View File

@@ -27,6 +27,7 @@ pub use contributors::ConfigContributor;
pub use contributors::ContextContributor;
pub use contributors::PromptFragment;
pub use contributors::PromptSlot;
pub use contributors::ThreadIdleInput;
pub use contributors::ThreadLifecycleContributor;
pub use contributors::ThreadResumeInput;
pub use contributors::ThreadStartInput;