Preserve allocated response item IDs in requests (#60977)

## Why

Providers can echo a bare reserved prefix or return an opaque item ID. Request preparation previously stripped these IDs when they lacked an underscore prefix, even if they carried allocation metadata.

## What changed

- Keep response item IDs with allocation metadata when preparing requests.
- Add `ResponseItemId::with_generation_prefix` to attach a request reservation's allocation while preserving the exact wire ID and recording a matching item-kind prefix and provider suffix.

GitOrigin-RevId: 3249c2669aca11ee5facbd8a246016490a29a4f4
This commit is contained in:
Ruslan Nigmatullin
2026-11-12 02:43:37 +00:00
committed by copyberry
parent 0702ebed4d
commit cbd4944092
2 changed files with 29 additions and 2 deletions
+22
View File
@@ -86,6 +86,28 @@ impl ResponseItemId {
}
}
/// Attach the request's reservation, preserving a matching suffix or the provider's opaque ID.
pub fn with_generation_prefix(self, reservation: &Self) -> Self {
let Some(allocation) = reservation.allocation() else {
return self;
};
let mut allocation = allocation.clone();
// Responses may prepend an item kind, as in `msg_item042_0`.
let (kind, handle) = match self.split_once('_') {
Some((kind, handle)) if !kind.is_empty() && kind != reservation.as_str() => {
(Some(kind), handle)
}
_ => (None, self.as_str()),
};
if let Some(suffix) = handle.strip_prefix(reservation.as_str())
&& suffix.starts_with('_')
{
allocation.prefix = kind.map(str::to_owned);
allocation.suffix = Some(suffix.to_owned());
}
self.with_allocation(allocation)
}
pub fn allocation(&self) -> Option<&ResponseItemIdAllocation> {
match self {
Self::Text(_) => None,