diff options
| author | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2026-06-10 22:01:45 +0200 |
|---|---|---|
| committer | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2026-06-10 22:01:45 +0200 |
| commit | 5e31a81cd2207f053b8cd8ad84ebe2a2f691b29d (patch) | |
| tree | 5d76811ab0d693c01fa472d41aa2ceaf3bd0b415 /crates/atuin-ai/src/tui/state.rs | |
| parent | chore: Remove unneeded files (diff) | |
| download | atuin-5e31a81cd2207f053b8cd8ad84ebe2a2f691b29d.zip | |
chore: Remove some unused rust code
Diffstat (limited to 'crates/atuin-ai/src/tui/state.rs')
| -rw-r--r-- | crates/atuin-ai/src/tui/state.rs | 237 |
1 files changed, 0 insertions, 237 deletions
diff --git a/crates/atuin-ai/src/tui/state.rs b/crates/atuin-ai/src/tui/state.rs deleted file mode 100644 index 71da6ff5..00000000 --- a/crates/atuin-ai/src/tui/state.rs +++ /dev/null @@ -1,237 +0,0 @@ -//! Core state types for the conversation protocol. -//! -//! ConversationEvent and events_to_messages are the canonical representations -//! used by both the FSM and the context window builder. AppMode is used by -//! the view layer for component prop derivation. - -/// Conversation event types matching the API protocol. -#[derive(Debug, Clone)] -pub(crate) enum ConversationEvent { - /// User message (what the user typed) - UserMessage { content: String }, - /// Text content from assistant (streamed or complete) - Text { content: String }, - /// Tool call from assistant - ToolCall { - id: String, - name: String, - input: serde_json::Value, - }, - /// Tool result (from server-side or client-side execution) - ToolResult { - tool_use_id: String, - content: String, - is_error: bool, - /// Server-side results are stored in the DB; the client sends an opaque - /// reference (`remote: true`) instead of the full content. - remote: bool, - /// Approximate content length for token estimation of remote results. - content_length: Option<usize>, - }, - /// Out-of-band output from the system — not sent to the server - OutOfBandOutput { - name: String, - command: Option<String>, - content: String, - }, - /// Context injected for the LLM that is not rendered in the TUI. - /// Converted to a user message in the API protocol. - SystemContext { content: String }, - /// A skill was loaded and its content injected into the conversation. - /// Serialized as a full user message for the API but rendered compactly - /// in the TUI (just the `/name args` invocation line). - SkillInvocation { - name: String, - arguments: Option<String>, - content: String, - }, -} - -impl ConversationEvent { - /// Whether this event represents actual conversation content sent to the API. - pub(crate) fn is_api_content(&self) -> bool { - match self { - ConversationEvent::UserMessage { .. } => true, - ConversationEvent::Text { .. } => true, - ConversationEvent::ToolCall { .. } => true, - ConversationEvent::ToolResult { .. } => true, - ConversationEvent::OutOfBandOutput { .. } => false, - ConversationEvent::SystemContext { .. } => false, - ConversationEvent::SkillInvocation { .. } => true, - } - } - - /// Extract command from a suggest_command tool call. - pub(crate) fn as_command(&self) -> Option<&str> { - if let ConversationEvent::ToolCall { name, input, .. } = self - && name == "suggest_command" - { - return input.get("command").and_then(|v| v.as_str()); - } - None - } -} - -/// Application mode for key handling and component props. -/// -/// Derived from AgentState in the view layer via `From<&AgentState>`. -#[derive(Debug, Clone, PartialEq, Eq, Copy)] -pub(crate) enum AppMode { - /// User is typing input - Input, - /// Waiting for generation (showing spinner) - Generating, - /// Streaming SSE response - Streaming, - /// Error state, can retry - Error, -} - -/// Convert a slice of conversation events to Claude API message format. -/// -/// This is the canonical event-to-message conversion, used by the context window -/// builder to convert turn slices independently. The logic handles combining -/// adjacent Text + ToolCall events into single assistant messages with mixed -/// content blocks. -pub(crate) fn events_to_messages(events: &[ConversationEvent]) -> Vec<serde_json::Value> { - let mut messages = Vec::new(); - let mut i = 0; - - while i < events.len() { - match &events[i] { - ConversationEvent::UserMessage { content } => { - messages.push(serde_json::json!({ - "role": "user", - "content": content - })); - i += 1; - } - ConversationEvent::Text { content } if content.is_empty() => { - i += 1; - } - ConversationEvent::Text { content } => { - let next_is_tool_call = events - .get(i + 1) - .is_some_and(|e| matches!(e, ConversationEvent::ToolCall { .. })); - - if next_is_tool_call { - let mut content_blocks = Vec::new(); - - if !content.is_empty() { - content_blocks.push(serde_json::json!({ - "type": "text", - "text": content - })); - } - - while let Some(ConversationEvent::ToolCall { - id, name, input, .. - }) = events.get(i + 1) - { - content_blocks.push(serde_json::json!({ - "type": "tool_use", - "id": id, - "name": name, - "input": input - })); - i += 1; - } - - messages.push(serde_json::json!({ - "role": "assistant", - "content": content_blocks - })); - i += 1; - } else { - messages.push(serde_json::json!({ - "role": "assistant", - "content": content - })); - i += 1; - } - } - ConversationEvent::ToolCall { .. } => { - let mut tool_uses = Vec::new(); - while i < events.len() { - if let ConversationEvent::ToolCall { - id, name, input, .. - } = &events[i] - { - tool_uses.push(serde_json::json!({ - "type": "tool_use", - "id": id, - "name": name, - "input": input - })); - i += 1; - } else { - break; - } - } - messages.push(serde_json::json!({ - "role": "assistant", - "content": tool_uses - })); - } - ConversationEvent::ToolResult { - tool_use_id, - content, - is_error, - remote, - content_length, - } => { - let tool_result = if *remote { - let mut obj = serde_json::json!({ - "type": "tool_result", - "tool_use_id": tool_use_id, - "remote": true, - "is_error": is_error - }); - if let Some(len) = content_length { - obj["content_length"] = serde_json::json!(len); - } - obj - } else { - serde_json::json!({ - "type": "tool_result", - "tool_use_id": tool_use_id, - "content": content, - "is_error": is_error - }) - }; - messages.push(serde_json::json!({ - "role": "user", - "content": [tool_result] - })); - i += 1; - } - ConversationEvent::OutOfBandOutput { .. } => { - i += 1; - } - ConversationEvent::SystemContext { content } => { - messages.push(serde_json::json!({ - "role": "user", - "content": content - })); - i += 1; - } - ConversationEvent::SkillInvocation { - name, - arguments, - content, - } => { - let header = match arguments { - Some(args) => format!("[Loaded skill: {name}]\n[Arguments: {args}]"), - None => format!("[Loaded skill: {name}]"), - }; - messages.push(serde_json::json!({ - "role": "user", - "content": format!("{header}\n\n{content}") - })); - i += 1; - } - } - } - - messages -} |
