Files
codex/codex-rs/code-mode-host/src/grpc/validation.rs
Channing Conger 61a3dd4387 Implement the gRPC code-mode host service (#37530)
## What changed

- Export `GrpcCodeModeHost` as a transport-independent implementation of the
  code-mode gRPC API.
- Support leased sessions, execution and wait lifecycle operations, filtered
  nested tool-call subscriptions, tool completions, and notification
  acknowledgements.
- Share host-wide request and active-cell limits across the existing and gRPC
  transports, and bound identifiers, metadata, subscriptions, and pending
  callbacks.

## Testing

- Add coverage for request conversion, ordered callback routing, cancellation,
  session cleanup, backpressure, malformed input, and resource-limit handling.

GitOrigin-RevId: f146ba7e6fe4e4aa02f25dd3f961120980516d0e
2026-08-08 04:13:55 +00:00

54 lines
1.7 KiB
Rust

use codex_code_mode_protocol::grpc as proto;
use tonic::Status;
use uuid::Uuid;
pub(super) const MAX_IDENTIFIER_BYTES: usize = 256;
pub(super) const MAX_TOOL_FILTERS: usize = 64;
pub(super) const MAX_TOOL_DEFINITIONS: usize = 1_024;
pub(super) const MAX_TOOL_DESCRIPTION_BYTES: usize = 16 * 1_024;
pub(super) const MAX_TOOL_ERROR_BYTES: usize = 64 * 1_024;
pub(super) fn identifier(value: &str, field: &str) -> Result<(), Status> {
if value.is_empty() {
return Err(Status::invalid_argument(format!(
"code-mode {field} must not be empty"
)));
}
bounded(value, MAX_IDENTIFIER_BYTES, field)
}
pub(super) fn uuid(value: &str, field: &str) -> Result<Uuid, Status> {
identifier(value, field)?;
Uuid::parse_str(value)
.map_err(|_| Status::invalid_argument(format!("code-mode {field} must be a UUID")))
}
pub(super) fn bounded(value: &str, maximum: usize, field: &str) -> Result<(), Status> {
if value.len() > maximum {
return Err(Status::invalid_argument(format!(
"code-mode {field} exceeds {maximum} bytes"
)));
}
Ok(())
}
pub(super) fn tool_name(name: &proto::ToolName) -> Result<(), Status> {
identifier(&name.name, "tool name")?;
if let Some(namespace) = name.namespace.as_deref() {
bounded(namespace, MAX_IDENTIFIER_BYTES, "tool namespace")?;
}
Ok(())
}
pub(super) fn tool_filters(filters: &[proto::ToolName]) -> Result<(), Status> {
if filters.len() > MAX_TOOL_FILTERS {
return Err(Status::invalid_argument(format!(
"code-mode tool subscription exceeds {MAX_TOOL_FILTERS} filters"
)));
}
for filter in filters {
tool_name(filter)?;
}
Ok(())
}