From 22ad54c08e54abaef2b2c50136e588e09d6c5978 Mon Sep 17 00:00:00 2001 From: Yeachan-Heo Date: Sat, 4 Apr 2026 15:23:29 +0000 Subject: [PATCH] docs: describe the runtime public API surface This adds crate-level and type-level Rustdoc to the runtime crate's core exported types so downstream crates and contributors can understand the session, prompt, permission, OAuth, usage, and tool I/O primitives without spelunking every implementation file. Constraint: The docs pass needed to stay focused on public runtime types without changing behavior Rejected: Add blanket docs to every public item in one sweep | larger churn than needed for a targeted docs pass Confidence: high Scope-risk: narrow Reversibility: clean Directive: When exporting new runtime primitives from lib.rs, add a short Rustdoc summary in the defining module at the same time Tested: cargo build --workspace; cargo test --workspace Not-tested: rustdoc HTML rendering beyond doc-test coverage --- rust/crates/runtime/src/bash.rs | 3 +++ rust/crates/runtime/src/compact.rs | 7 +++++++ rust/crates/runtime/src/config.rs | 28 ++++++++++++++++++++++++- rust/crates/runtime/src/conversation.rs | 12 +++++++++++ rust/crates/runtime/src/file_ops.rs | 13 ++++++++++++ rust/crates/runtime/src/lib.rs | 13 +++++++----- rust/crates/runtime/src/oauth.rs | 7 +++++++ rust/crates/runtime/src/permissions.rs | 8 +++++++ rust/crates/runtime/src/prompt.rs | 8 +++++++ rust/crates/runtime/src/session.rs | 7 +++++++ rust/crates/runtime/src/usage.rs | 6 ++++++ 11 files changed, 106 insertions(+), 6 deletions(-) diff --git a/rust/crates/runtime/src/bash.rs b/rust/crates/runtime/src/bash.rs index ef9ff8f..aad27f6 100644 --- a/rust/crates/runtime/src/bash.rs +++ b/rust/crates/runtime/src/bash.rs @@ -14,6 +14,7 @@ use crate::sandbox::{ }; use crate::ConfigLoader; +/// Input schema for the built-in bash execution tool. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct BashCommandInput { pub command: String, @@ -33,6 +34,7 @@ pub struct BashCommandInput { pub allowed_mounts: Option>, } +/// Output returned from a bash tool invocation. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct BashCommandOutput { pub stdout: String, @@ -64,6 +66,7 @@ pub struct BashCommandOutput { pub sandbox_status: Option, } +/// Executes a shell command with the requested sandbox settings. pub fn execute_bash(input: BashCommandInput) -> io::Result { let cwd = env::current_dir()?; let sandbox_status = sandbox_status_for_input(&input, &cwd); diff --git a/rust/crates/runtime/src/compact.rs b/rust/crates/runtime/src/compact.rs index 906d01b..76150db 100644 --- a/rust/crates/runtime/src/compact.rs +++ b/rust/crates/runtime/src/compact.rs @@ -5,6 +5,7 @@ const COMPACT_CONTINUATION_PREAMBLE: &str = const COMPACT_RECENT_MESSAGES_NOTE: &str = "Recent messages are preserved verbatim."; const COMPACT_DIRECT_RESUME_INSTRUCTION: &str = "Continue the conversation from where it left off without asking the user any further questions. Resume directly — do not acknowledge the summary, do not recap what was happening, and do not preface with continuation text."; +/// Thresholds controlling when and how a session is compacted. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CompactionConfig { pub preserve_recent_messages: usize, @@ -20,6 +21,7 @@ impl Default for CompactionConfig { } } +/// Result of compacting a session into a summary plus preserved tail messages. #[derive(Debug, Clone, PartialEq, Eq)] pub struct CompactionResult { pub summary: String, @@ -28,11 +30,13 @@ pub struct CompactionResult { pub removed_message_count: usize, } +/// Roughly estimates the token footprint of the current session transcript. #[must_use] pub fn estimate_session_tokens(session: &Session) -> usize { session.messages.iter().map(estimate_message_tokens).sum() } +/// Returns `true` when the session exceeds the configured compaction budget. #[must_use] pub fn should_compact(session: &Session, config: CompactionConfig) -> bool { let start = compacted_summary_prefix_len(session); @@ -46,6 +50,7 @@ pub fn should_compact(session: &Session, config: CompactionConfig) -> bool { >= config.max_estimated_tokens } +/// Normalizes a compaction summary into user-facing continuation text. #[must_use] pub fn format_compact_summary(summary: &str) -> String { let without_analysis = strip_tag_block(summary, "analysis"); @@ -61,6 +66,7 @@ pub fn format_compact_summary(summary: &str) -> String { collapse_blank_lines(&formatted).trim().to_string() } +/// Builds the synthetic system message used after session compaction. #[must_use] pub fn get_compact_continuation_message( summary: &str, @@ -85,6 +91,7 @@ pub fn get_compact_continuation_message( base } +/// Compacts a session by summarizing older messages and preserving the recent tail. #[must_use] pub fn compact_session(session: &Session, config: CompactionConfig) -> CompactionResult { if !should_compact(session, config) { diff --git a/rust/crates/runtime/src/config.rs b/rust/crates/runtime/src/config.rs index a07be0f..3120ac5 100644 --- a/rust/crates/runtime/src/config.rs +++ b/rust/crates/runtime/src/config.rs @@ -6,8 +6,10 @@ use std::path::{Path, PathBuf}; use crate::json::JsonValue; use crate::sandbox::{FilesystemIsolationMode, SandboxConfig}; +/// Schema name advertised by generated settings files. pub const CLAW_SETTINGS_SCHEMA_NAME: &str = "SettingsSchema"; +/// Origin of a loaded settings file in the configuration precedence chain. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub enum ConfigSource { User, @@ -15,6 +17,7 @@ pub enum ConfigSource { Local, } +/// Effective permission mode after decoding config values. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum ResolvedPermissionMode { ReadOnly, @@ -22,12 +25,14 @@ pub enum ResolvedPermissionMode { DangerFullAccess, } +/// A discovered config file and the scope it contributes to. #[derive(Debug, Clone, PartialEq, Eq)] pub struct ConfigEntry { pub source: ConfigSource, pub path: PathBuf, } +/// Fully merged runtime configuration plus parsed feature-specific views. #[derive(Debug, Clone, PartialEq, Eq)] pub struct RuntimeConfig { merged: BTreeMap, @@ -35,6 +40,7 @@ pub struct RuntimeConfig { feature_config: RuntimeFeatureConfig, } +/// Parsed plugin-related settings extracted from runtime config. #[derive(Debug, Clone, PartialEq, Eq, Default)] pub struct RuntimePluginConfig { enabled_plugins: BTreeMap, @@ -44,6 +50,7 @@ pub struct RuntimePluginConfig { bundled_root: Option, } +/// Structured feature configuration consumed by runtime subsystems. #[derive(Debug, Clone, PartialEq, Eq, Default)] pub struct RuntimeFeatureConfig { hooks: RuntimeHookConfig, @@ -56,6 +63,7 @@ pub struct RuntimeFeatureConfig { sandbox: SandboxConfig, } +/// Hook command lists grouped by lifecycle stage. #[derive(Debug, Clone, PartialEq, Eq, Default)] pub struct RuntimeHookConfig { pre_tool_use: Vec, @@ -63,6 +71,7 @@ pub struct RuntimeHookConfig { post_tool_use_failure: Vec, } +/// Raw permission rule lists grouped by allow, deny, and ask behavior. #[derive(Debug, Clone, PartialEq, Eq, Default)] pub struct RuntimePermissionRuleConfig { allow: Vec, @@ -70,17 +79,20 @@ pub struct RuntimePermissionRuleConfig { ask: Vec, } +/// Collection of configured MCP servers after scope-aware merging. #[derive(Debug, Clone, PartialEq, Eq, Default)] pub struct McpConfigCollection { servers: BTreeMap, } +/// MCP server config paired with the scope that defined it. #[derive(Debug, Clone, PartialEq, Eq)] pub struct ScopedMcpServerConfig { pub scope: ConfigSource, pub config: McpServerConfig, } +/// Transport families supported by configured MCP servers. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum McpTransport { Stdio, @@ -91,6 +103,7 @@ pub enum McpTransport { ManagedProxy, } +/// Scope-normalized MCP server configuration variants. #[derive(Debug, Clone, PartialEq, Eq)] pub enum McpServerConfig { Stdio(McpStdioServerConfig), @@ -101,6 +114,7 @@ pub enum McpServerConfig { ManagedProxy(McpManagedProxyServerConfig), } +/// Configuration for an MCP server launched as a local stdio process. #[derive(Debug, Clone, PartialEq, Eq)] pub struct McpStdioServerConfig { pub command: String, @@ -109,6 +123,7 @@ pub struct McpStdioServerConfig { pub tool_call_timeout_ms: Option, } +/// Configuration for an MCP server reached over HTTP or SSE. #[derive(Debug, Clone, PartialEq, Eq)] pub struct McpRemoteServerConfig { pub url: String, @@ -117,6 +132,7 @@ pub struct McpRemoteServerConfig { pub oauth: Option, } +/// Configuration for an MCP server reached over WebSocket. #[derive(Debug, Clone, PartialEq, Eq)] pub struct McpWebSocketServerConfig { pub url: String, @@ -124,17 +140,20 @@ pub struct McpWebSocketServerConfig { pub headers_helper: Option, } +/// Configuration for an MCP server addressed through an SDK name. #[derive(Debug, Clone, PartialEq, Eq)] pub struct McpSdkServerConfig { pub name: String, } +/// Configuration for an MCP managed-proxy endpoint. #[derive(Debug, Clone, PartialEq, Eq)] pub struct McpManagedProxyServerConfig { pub url: String, pub id: String, } +/// OAuth overrides associated with a remote MCP server. #[derive(Debug, Clone, PartialEq, Eq)] pub struct McpOAuthConfig { pub client_id: Option, @@ -143,6 +162,7 @@ pub struct McpOAuthConfig { pub xaa: Option, } +/// OAuth client configuration used by the main Claw runtime. #[derive(Debug, Clone, PartialEq, Eq)] pub struct OAuthConfig { pub client_id: String, @@ -153,6 +173,7 @@ pub struct OAuthConfig { pub scopes: Vec, } +/// Errors raised while reading or parsing runtime configuration files. #[derive(Debug)] pub enum ConfigError { Io(std::io::Error), @@ -176,6 +197,7 @@ impl From for ConfigError { } } +/// Discovers config files and merges them into a [`RuntimeConfig`]. #[derive(Debug, Clone, PartialEq, Eq)] pub struct ConfigLoader { cwd: PathBuf, @@ -441,6 +463,7 @@ impl RuntimePluginConfig { } #[must_use] +/// Returns the default per-user config directory used by the runtime. pub fn default_config_home() -> PathBuf { std::env::var_os("CLAW_CONFIG_HOME") .map(PathBuf::from) @@ -1338,7 +1361,10 @@ mod tests { .load() .expect("config should load"); - let remote_server = loaded.mcp().get("remote").expect("remote server should exist"); + let remote_server = loaded + .mcp() + .get("remote") + .expect("remote server should exist"); assert_eq!(remote_server.transport(), McpTransport::Http); match &remote_server.config { McpServerConfig::Http(config) => { diff --git a/rust/crates/runtime/src/conversation.rs b/rust/crates/runtime/src/conversation.rs index 0e44586..1010bd3 100644 --- a/rust/crates/runtime/src/conversation.rs +++ b/rust/crates/runtime/src/conversation.rs @@ -18,12 +18,14 @@ use crate::usage::{TokenUsage, UsageTracker}; const DEFAULT_AUTO_COMPACTION_INPUT_TOKENS_THRESHOLD: u32 = 100_000; const AUTO_COMPACTION_THRESHOLD_ENV_VAR: &str = "CLAUDE_CODE_AUTO_COMPACT_INPUT_TOKENS"; +/// Fully assembled request payload sent to the upstream model client. #[derive(Debug, Clone, PartialEq, Eq)] pub struct ApiRequest { pub system_prompt: Vec, pub messages: Vec, } +/// Streamed events emitted while processing a single assistant turn. #[derive(Debug, Clone, PartialEq, Eq)] pub enum AssistantEvent { TextDelta(String), @@ -37,6 +39,7 @@ pub enum AssistantEvent { MessageStop, } +/// Prompt-cache telemetry captured from the provider response stream. #[derive(Debug, Clone, PartialEq, Eq)] pub struct PromptCacheEvent { pub unexpected: bool, @@ -46,14 +49,17 @@ pub struct PromptCacheEvent { pub token_drop: u32, } +/// Minimal streaming API contract required by [`ConversationRuntime`]. pub trait ApiClient { fn stream(&mut self, request: ApiRequest) -> Result, RuntimeError>; } +/// Trait implemented by tool dispatchers that execute model-requested tools. pub trait ToolExecutor { fn execute(&mut self, tool_name: &str, input: &str) -> Result; } +/// Error returned when a tool invocation fails locally. #[derive(Debug, Clone, PartialEq, Eq)] pub struct ToolError { message: String, @@ -76,6 +82,7 @@ impl Display for ToolError { impl std::error::Error for ToolError {} +/// Error returned when a conversation turn cannot be completed. #[derive(Debug, Clone, PartialEq, Eq)] pub struct RuntimeError { message: String, @@ -98,6 +105,7 @@ impl Display for RuntimeError { impl std::error::Error for RuntimeError {} +/// Summary of one completed runtime turn, including tool results and usage. #[derive(Debug, Clone, PartialEq, Eq)] pub struct TurnSummary { pub assistant_messages: Vec, @@ -108,11 +116,13 @@ pub struct TurnSummary { pub auto_compaction: Option, } +/// Details about automatic session compaction applied during a turn. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct AutoCompactionEvent { pub removed_message_count: usize, } +/// Coordinates the model loop, tool execution, hooks, and session updates. pub struct ConversationRuntime { session: Session, api_client: C, @@ -637,6 +647,7 @@ where } } +/// Reads the automatic compaction threshold from the environment. #[must_use] pub fn auto_compaction_threshold_from_env() -> u32 { parse_auto_compaction_threshold( @@ -739,6 +750,7 @@ fn merge_hook_feedback(messages: &[String], output: String, is_error: bool) -> S type ToolHandler = Box Result>; +/// Simple in-memory tool executor for tests and lightweight integrations. #[derive(Default)] pub struct StaticToolExecutor { handlers: BTreeMap, diff --git a/rust/crates/runtime/src/file_ops.rs b/rust/crates/runtime/src/file_ops.rs index 770efd4..fde889b 100644 --- a/rust/crates/runtime/src/file_ops.rs +++ b/rust/crates/runtime/src/file_ops.rs @@ -42,6 +42,7 @@ fn validate_workspace_boundary(resolved: &Path, workspace_root: &Path) -> io::Re Ok(()) } +/// Text payload returned by file-reading operations. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct TextFilePayload { #[serde(rename = "filePath")] @@ -55,6 +56,7 @@ pub struct TextFilePayload { pub total_lines: usize, } +/// Output envelope for the `read_file` tool. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct ReadFileOutput { #[serde(rename = "type")] @@ -62,6 +64,7 @@ pub struct ReadFileOutput { pub file: TextFilePayload, } +/// Structured patch hunk emitted by write and edit operations. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct StructuredPatchHunk { #[serde(rename = "oldStart")] @@ -75,6 +78,7 @@ pub struct StructuredPatchHunk { pub lines: Vec, } +/// Output envelope for full-file write operations. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct WriteFileOutput { #[serde(rename = "type")] @@ -90,6 +94,7 @@ pub struct WriteFileOutput { pub git_diff: Option, } +/// Output envelope for targeted string-replacement edits. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct EditFileOutput { #[serde(rename = "filePath")] @@ -110,6 +115,7 @@ pub struct EditFileOutput { pub git_diff: Option, } +/// Result of a glob-based filename search. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct GlobSearchOutput { #[serde(rename = "durationMs")] @@ -120,6 +126,7 @@ pub struct GlobSearchOutput { pub truncated: bool, } +/// Parameters accepted by the grep-style search tool. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct GrepSearchInput { pub pattern: String, @@ -145,6 +152,7 @@ pub struct GrepSearchInput { pub multiline: Option, } +/// Result payload returned by the grep-style search tool. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct GrepSearchOutput { pub mode: Option, @@ -162,6 +170,7 @@ pub struct GrepSearchOutput { pub applied_offset: Option, } +/// Reads a text file and returns a line-windowed payload. pub fn read_file( path: &str, offset: Option, @@ -210,6 +219,7 @@ pub fn read_file( }) } +/// Replaces a file's contents and returns patch metadata. pub fn write_file(path: &str, content: &str) -> io::Result { if content.len() > MAX_WRITE_SIZE { return Err(io::Error::new( @@ -243,6 +253,7 @@ pub fn write_file(path: &str, content: &str) -> io::Result { }) } +/// Performs an in-file string replacement and returns patch metadata. pub fn edit_file( path: &str, old_string: &str, @@ -283,6 +294,7 @@ pub fn edit_file( }) } +/// Expands a glob pattern and returns matching filenames. pub fn glob_search(pattern: &str, path: Option<&str>) -> io::Result { let started = Instant::now(); let base_dir = path @@ -326,6 +338,7 @@ pub fn glob_search(pattern: &str, path: Option<&str>) -> io::Result io::Result { let base_path = input .path diff --git a/rust/crates/runtime/src/lib.rs b/rust/crates/runtime/src/lib.rs index 243a478..7550c49 100644 --- a/rust/crates/runtime/src/lib.rs +++ b/rust/crates/runtime/src/lib.rs @@ -1,3 +1,9 @@ +//! Core runtime primitives for the `claw` CLI and supporting crates. +//! +//! This crate owns session persistence, permission evaluation, prompt assembly, +//! MCP plumbing, tool-facing file operations, and the core conversation loop +//! that drives interactive and one-shot turns. + mod bash; pub mod bash_validation; mod bootstrap; @@ -134,17 +140,14 @@ pub use stale_branch::{ apply_policy, check_freshness, BranchFreshness, StaleBranchAction, StaleBranchEvent, StaleBranchPolicy, }; -pub use task_packet::{ - validate_packet, TaskPacket, TaskPacketValidationError, ValidatedPacket, -}; +pub use task_packet::{validate_packet, TaskPacket, TaskPacketValidationError, ValidatedPacket}; pub use trust_resolver::{TrustConfig, TrustDecision, TrustEvent, TrustPolicy, TrustResolver}; pub use usage::{ format_usd, pricing_for_model, ModelPricing, TokenUsage, UsageCostEstimate, UsageTracker, }; pub use worker_boot::{ Worker, WorkerEvent, WorkerEventKind, WorkerEventPayload, WorkerFailure, WorkerFailureKind, - WorkerPromptTarget, WorkerReadySnapshot, WorkerRegistry, WorkerStatus, - WorkerTrustResolution, + WorkerPromptTarget, WorkerReadySnapshot, WorkerRegistry, WorkerStatus, WorkerTrustResolution, }; #[cfg(test)] diff --git a/rust/crates/runtime/src/oauth.rs b/rust/crates/runtime/src/oauth.rs index f15e4db..4d2150c 100644 --- a/rust/crates/runtime/src/oauth.rs +++ b/rust/crates/runtime/src/oauth.rs @@ -9,6 +9,7 @@ use sha2::{Digest, Sha256}; use crate::config::OAuthConfig; +/// Persisted OAuth access token bundle used by the CLI. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct OAuthTokenSet { pub access_token: String, @@ -17,6 +18,7 @@ pub struct OAuthTokenSet { pub scopes: Vec, } +/// PKCE verifier/challenge pair generated for an OAuth authorization flow. #[derive(Debug, Clone, PartialEq, Eq)] pub struct PkceCodePair { pub verifier: String, @@ -24,6 +26,7 @@ pub struct PkceCodePair { pub challenge_method: PkceChallengeMethod, } +/// Challenge algorithms supported by the local PKCE helpers. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum PkceChallengeMethod { S256, @@ -38,6 +41,7 @@ impl PkceChallengeMethod { } } +/// Parameters needed to build an authorization URL for browser-based login. #[derive(Debug, Clone, PartialEq, Eq)] pub struct OAuthAuthorizationRequest { pub authorize_url: String, @@ -50,6 +54,7 @@ pub struct OAuthAuthorizationRequest { pub extra_params: BTreeMap, } +/// Request body for exchanging an OAuth authorization code for tokens. #[derive(Debug, Clone, PartialEq, Eq)] pub struct OAuthTokenExchangeRequest { pub grant_type: &'static str, @@ -60,6 +65,7 @@ pub struct OAuthTokenExchangeRequest { pub state: String, } +/// Request body for refreshing an existing OAuth token set. #[derive(Debug, Clone, PartialEq, Eq)] pub struct OAuthRefreshRequest { pub grant_type: &'static str, @@ -68,6 +74,7 @@ pub struct OAuthRefreshRequest { pub scopes: Vec, } +/// Parsed query parameters returned to the local OAuth callback endpoint. #[derive(Debug, Clone, PartialEq, Eq)] pub struct OAuthCallbackParams { pub code: Option, diff --git a/rust/crates/runtime/src/permissions.rs b/rust/crates/runtime/src/permissions.rs index 3acf5c1..81340dd 100644 --- a/rust/crates/runtime/src/permissions.rs +++ b/rust/crates/runtime/src/permissions.rs @@ -4,6 +4,7 @@ use serde_json::Value; use crate::config::RuntimePermissionRuleConfig; +/// Permission level assigned to a tool invocation or runtime session. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub enum PermissionMode { ReadOnly, @@ -26,6 +27,7 @@ impl PermissionMode { } } +/// Hook-provided override applied before standard permission evaluation. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum PermissionOverride { Allow, @@ -33,6 +35,7 @@ pub enum PermissionOverride { Ask, } +/// Additional permission context supplied by hooks or higher-level orchestration. #[derive(Debug, Clone, PartialEq, Eq, Default)] pub struct PermissionContext { override_decision: Option, @@ -62,6 +65,7 @@ impl PermissionContext { } } +/// Full authorization request presented to a permission prompt. #[derive(Debug, Clone, PartialEq, Eq)] pub struct PermissionRequest { pub tool_name: String, @@ -71,22 +75,26 @@ pub struct PermissionRequest { pub reason: Option, } +/// User-facing decision returned by a [`PermissionPrompter`]. #[derive(Debug, Clone, PartialEq, Eq)] pub enum PermissionPromptDecision { Allow, Deny { reason: String }, } +/// Prompting interface used when policy requires interactive approval. pub trait PermissionPrompter { fn decide(&mut self, request: &PermissionRequest) -> PermissionPromptDecision; } +/// Final authorization result after evaluating static rules and prompts. #[derive(Debug, Clone, PartialEq, Eq)] pub enum PermissionOutcome { Allow, Deny { reason: String }, } +/// Evaluates permission mode requirements plus allow/deny/ask rules. #[derive(Debug, Clone, PartialEq, Eq)] pub struct PermissionPolicy { active_mode: PermissionMode, diff --git a/rust/crates/runtime/src/prompt.rs b/rust/crates/runtime/src/prompt.rs index 2a56b92..307a64b 100644 --- a/rust/crates/runtime/src/prompt.rs +++ b/rust/crates/runtime/src/prompt.rs @@ -5,6 +5,7 @@ use std::process::Command; use crate::config::{ConfigError, ConfigLoader, RuntimeConfig}; +/// Errors raised while assembling the final system prompt. #[derive(Debug)] pub enum PromptBuildError { Io(std::io::Error), @@ -34,17 +35,21 @@ impl From for PromptBuildError { } } +/// Marker separating static prompt scaffolding from dynamic runtime context. pub const SYSTEM_PROMPT_DYNAMIC_BOUNDARY: &str = "__SYSTEM_PROMPT_DYNAMIC_BOUNDARY__"; +/// Human-readable default frontier model name embedded into generated prompts. pub const FRONTIER_MODEL_NAME: &str = "Claude Opus 4.6"; const MAX_INSTRUCTION_FILE_CHARS: usize = 4_000; const MAX_TOTAL_INSTRUCTION_CHARS: usize = 12_000; +/// Contents of an instruction file included in prompt construction. #[derive(Debug, Clone, PartialEq, Eq)] pub struct ContextFile { pub path: PathBuf, pub content: String, } +/// Project-local context injected into the rendered system prompt. #[derive(Debug, Clone, Default, PartialEq, Eq)] pub struct ProjectContext { pub cwd: PathBuf, @@ -81,6 +86,7 @@ impl ProjectContext { } } +/// Builder for the runtime system prompt and dynamic environment sections. #[derive(Debug, Clone, Default, PartialEq, Eq)] pub struct SystemPromptBuilder { output_style_name: Option, @@ -184,6 +190,7 @@ impl SystemPromptBuilder { } } +/// Formats each item as an indented bullet for prompt sections. #[must_use] pub fn prepend_bullets(items: Vec) -> Vec { items.into_iter().map(|item| format!(" - {item}")).collect() @@ -401,6 +408,7 @@ fn collapse_blank_lines(content: &str) -> String { result } +/// Loads config and project context, then renders the system prompt text. pub fn load_system_prompt( cwd: impl Into, current_date: impl Into, diff --git a/rust/crates/runtime/src/session.rs b/rust/crates/runtime/src/session.rs index 7b3ece5..202db6c 100644 --- a/rust/crates/runtime/src/session.rs +++ b/rust/crates/runtime/src/session.rs @@ -14,6 +14,7 @@ const ROTATE_AFTER_BYTES: u64 = 256 * 1024; const MAX_ROTATED_FILES: usize = 3; static SESSION_ID_COUNTER: AtomicU64 = AtomicU64::new(0); +/// Speaker role associated with a persisted conversation message. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum MessageRole { System, @@ -22,6 +23,7 @@ pub enum MessageRole { Tool, } +/// Structured message content stored inside a [`Session`]. #[derive(Debug, Clone, PartialEq, Eq)] pub enum ContentBlock { Text { @@ -40,6 +42,7 @@ pub enum ContentBlock { }, } +/// One conversation message with optional token-usage metadata. #[derive(Debug, Clone, PartialEq, Eq)] pub struct ConversationMessage { pub role: MessageRole, @@ -47,6 +50,7 @@ pub struct ConversationMessage { pub usage: Option, } +/// Metadata describing the latest compaction that summarized a session. #[derive(Debug, Clone, PartialEq, Eq)] pub struct SessionCompaction { pub count: u32, @@ -54,6 +58,7 @@ pub struct SessionCompaction { pub summary: String, } +/// Provenance recorded when a session is forked from another session. #[derive(Debug, Clone, PartialEq, Eq)] pub struct SessionFork { pub parent_session_id: String, @@ -65,6 +70,7 @@ struct SessionPersistence { path: PathBuf, } +/// Persisted conversational state for the runtime and CLI session manager. #[derive(Debug, Clone)] pub struct Session { pub version: u32, @@ -91,6 +97,7 @@ impl PartialEq for Session { impl Eq for Session {} +/// Errors raised while loading, parsing, or saving sessions. #[derive(Debug)] pub enum SessionError { Io(std::io::Error), diff --git a/rust/crates/runtime/src/usage.rs b/rust/crates/runtime/src/usage.rs index 4af4666..9241f7c 100644 --- a/rust/crates/runtime/src/usage.rs +++ b/rust/crates/runtime/src/usage.rs @@ -5,6 +5,7 @@ const DEFAULT_OUTPUT_COST_PER_MILLION: f64 = 75.0; const DEFAULT_CACHE_CREATION_COST_PER_MILLION: f64 = 18.75; const DEFAULT_CACHE_READ_COST_PER_MILLION: f64 = 1.5; +/// Per-million-token pricing used for cost estimation. #[derive(Debug, Clone, Copy, PartialEq)] pub struct ModelPricing { pub input_cost_per_million: f64, @@ -25,6 +26,7 @@ impl ModelPricing { } } +/// Token counters accumulated for a conversation turn or session. #[derive(Debug, Clone, Copy, Default, PartialEq, Eq)] pub struct TokenUsage { pub input_tokens: u32, @@ -33,6 +35,7 @@ pub struct TokenUsage { pub cache_read_input_tokens: u32, } +/// Estimated dollar cost derived from a [`TokenUsage`] sample. #[derive(Debug, Clone, Copy, PartialEq)] pub struct UsageCostEstimate { pub input_cost_usd: f64, @@ -51,6 +54,7 @@ impl UsageCostEstimate { } } +/// Returns pricing metadata for a known model alias or family. #[must_use] pub fn pricing_for_model(model: &str) -> Option { let normalized = model.to_ascii_lowercase(); @@ -155,10 +159,12 @@ fn cost_for_tokens(tokens: u32, usd_per_million_tokens: f64) -> f64 { } #[must_use] +/// Formats a dollar-denominated value for CLI display. pub fn format_usd(amount: f64) -> String { format!("${amount:.4}") } +/// Aggregates token usage across a running session. #[derive(Debug, Clone, Default, PartialEq, Eq)] pub struct UsageTracker { latest_turn: TokenUsage,