Files
codex/codex-rs/guardian-context/src/entry.rs
T
felixxia-oai 0918cd2c08 Add shared Guardian transcript collection (#41422)
## What changed

- Add a reusable transcript contributor for synchronous and asynchronous Guardian context, with borrowed conversation history and request-specific configuration.
- Preserve conversation order and role or tool attribution while applying separate per-entry limits for messages, ordinary tools, and Node REPL-backed outputs.
- Make tool calls, tool outputs, and reasoning independently configurable, and expose transcript collection without requiring section composition.
- Register the transcript contributor in a process-wide default registry that retains no request state.

## Testing

- Add unit coverage for role and tool attribution, optional evidence sources, orphaned and named tool outputs, registry reuse, and request-specific entry limits.

GitOrigin-RevId: 2b60f8db4618de8a7175f8ee0183375a526a87db
2026-08-28 21:43:21 +00:00

53 lines
2.1 KiB
Rust

//! Structured transcript evidence shared by synchronous and asynchronous Guardian.
//!
//! Entry kinds preserve source attribution for consumer-specific retention and
//! rendering. Text is bounded during collection, with its original size retained
//! for truncation accounting.
/// Semantic role of one parent-conversation transcript entry.
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum ConversationTranscriptEntryKind {
/// Actual parent-thread user message.
User,
/// Explicit developer message preserving a user-approved action.
Developer,
/// Assistant commentary or an inter-agent message.
Assistant,
/// Final assistant answer eligible for stronger async retention.
ProtectedAssistant,
/// Named tool invocation, including shell and web-search calls.
ToolCall(String),
/// Tool result with a call-derived, explicit, or generic fallback label.
ToolOutput(String),
/// Result from a Node REPL-backed tool that may receive a larger sync cap.
NodeReplToolOutput(String),
/// Plaintext model reasoning that the async consumer explicitly enables.
Reasoning,
}
impl ConversationTranscriptEntryKind {
/// Returns the role label currently used in Guardian transcript prompts.
pub fn role(&self) -> &str {
match self {
Self::User => "user",
Self::Developer => "developer",
Self::Assistant | Self::ProtectedAssistant => "assistant",
Self::ToolCall(role) | Self::ToolOutput(role) | Self::NodeReplToolOutput(role) => {
role.as_str()
}
Self::Reasoning => "reasoning",
}
}
}
/// Structured text evidence shared by sync Guardian and async scoring.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ConversationTranscriptEntry {
/// Semantic role used for consumer-specific retention and truncation.
pub kind: ConversationTranscriptEntryKind,
/// Text bounded by the current request's per-entry limits.
pub text: String,
/// Size before truncation, retained for omission and truncation accounting.
pub original_bytes: usize,
}