Scope extension capabilities to invocation lifetimes (#41020)

## What changed

- Add callback lifetimes to extension `ToolCall`, `ToolEnvironment`, turn-input context, and skill-read request types.
- Require extension tool executors to handle calls for any invocation lifetime and tie their returned futures to that lifetime.
- Update built-in extensions, adapters, and tests to use the lifetime-scoped APIs without retaining host-owned environment capabilities.

GitOrigin-RevId: aca9ce3a1b6870df550bc84ec9308cc65533f161
This commit is contained in:
Adam Perry @ OpenAI authored and copyberry committed 2026-08-27 02:00:31 +00:00
1 parent eed1dee69e
commit 81e180044d
85 files changed
+477 -202

No files matched your search

+2 -2
View File
@@ -135,7 +135,7 @@ impl ToolContributor for HistoryNotesExtension {
&self,
session_store: &ExtensionData,
thread_store: &ExtensionData,
) -> Vec<Arc<dyn ToolExecutor<ToolCall>>> {
) -> Vec<Arc<dyn for<'call> ToolExecutor<ToolCall<'call>>>> {
let Some(config) = thread_store.get::<HistoryNotesExtensionConfig>() else {
return Vec::new();
};
@@ -151,7 +151,7 @@ impl ToolContributor for HistoryNotesExtension {
config.backend.clone(),
session_store.level_id().to_string(),
identity.agent_name.clone(),
)) as Arc<dyn ToolExecutor<ToolCall>>
)) as Arc<dyn for<'call> ToolExecutor<ToolCall<'call>>>
})
.collect()
}
+9 -3
View File
@@ -260,7 +260,10 @@ impl HistoryNotesTool {
}
}
async fn handle_call(&self, call: ToolCall) -> Result<Box<dyn ToolOutput>, FunctionCallError> {
async fn handle_call(
&self,
call: ToolCall<'_>,
) -> Result<Box<dyn ToolOutput>, FunctionCallError> {
let arguments = call.function_arguments()?;
let arguments = if arguments.trim().is_empty() {
json!({})
@@ -286,7 +289,7 @@ impl HistoryNotesTool {
}
}
impl ToolExecutor<ToolCall> for HistoryNotesTool {
impl<'call> ToolExecutor<ToolCall<'call>> for HistoryNotesTool {
fn tool_name(&self) -> ToolName {
ToolName::namespaced(self.action.namespace(), self.action.name())
}
@@ -316,7 +319,10 @@ impl ToolExecutor<ToolCall> for HistoryNotesTool {
self.action.supports_parallel_tool_calls()
}
fn handle(&self, call: ToolCall) -> ToolExecutorFuture<'_> {
fn handle<'a>(&'a self, call: ToolCall<'call>) -> ToolExecutorFuture<'a>
where
'call: 'a,
{
Box::pin(self.handle_call(call))
}
}