Expose invocation sources to extension tools (#40382)

## What changed

- Add `ToolCallSource` to extension `ToolCall`s and propagate direct or Code Mode
  invocation metadata, including the runtime cell and nested tool-call IDs.
- Add `ToolCall::response_byte_budget` so extension tools can bound direct-call
  responses by the host truncation policy while allowing Code Mode responses up
  to the tool's own limit.
- Share the skills extension's response-size limit between its `list` and `read`
  tools.

## Testing

- Verify that Code Mode source metadata is preserved when core constructs an
  extension tool call.

GitOrigin-RevId: b10aef01be30d35b67bee3af24a1a4175c9ee112
This commit is contained in:
Tamir Duberstein authored and copyberry committed 2026-08-24 11:02:14 +00:00
1 parent 6771ae7ac3
commit e3609f2d02
14 files changed
+70 -24

No files matched your search

+33
View File
@@ -86,6 +86,20 @@ impl TurnItemEmitter for NoopTurnItemEmitter {
}
}
/// Host-visible source for a model tool call.
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum ToolCallSource {
/// The model invoked the tool directly.
Direct,
/// Code mode invoked the tool while executing a runtime cell.
CodeMode {
/// Runtime cell that issued the nested tool request.
cell_id: String,
/// Code-mode's per-cell tool invocation id.
runtime_tool_call_id: String,
},
}
#[derive(Clone)]
pub struct ToolCall {
pub turn_id: String,
@@ -94,6 +108,7 @@ pub struct ToolCall {
pub model: String,
pub codex_turn_metadata: Option<String>,
pub truncation_policy: TruncationPolicy,
pub source: ToolCallSource,
pub conversation_history: ConversationHistory,
pub turn_item_emitter: Arc<dyn TurnItemEmitter>,
pub environments: Vec<ToolEnvironment>,
@@ -112,6 +127,7 @@ impl std::fmt::Debug for ToolCall {
&self.codex_turn_metadata.is_some(),
)
.field("truncation_policy", &self.truncation_policy)
.field("source", &self.source)
.field("conversation_history", &self.conversation_history)
.field("turn_item_emitter", &"<host turn item emitter>")
.field("environment_count", &self.environments.len())
@@ -121,6 +137,23 @@ impl std::fmt::Debug for ToolCall {
}
impl ToolCall {
/// Returns the response-content budget, bounded by the tool's own size limit.
///
/// Direct calls use the host's effective text-output allowance. Code Mode receives
/// typed results without that truncation, so only the tool's limit applies.
/// Callers must include serialization overhead when fitting a response to this budget.
pub fn response_byte_budget(&self, max_response_bytes: usize) -> usize {
match &self.source {
ToolCallSource::Direct => {
max_response_bytes.min((self.truncation_policy * 1.2).byte_budget())
}
ToolCallSource::CodeMode {
cell_id: _,
runtime_tool_call_id: _,
} => max_response_bytes,
}
}
pub fn function_arguments(&self) -> Result<&str, FunctionCallError> {
match &self.payload {
ToolPayload::Function { arguments } => Ok(arguments),