aboutsummaryrefslogtreecommitdiffstats
path: root/crates/atuin-ai/src/tui/state.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/atuin-ai/src/tui/state.rs')
-rw-r--r--crates/atuin-ai/src/tui/state.rs24
1 files changed, 24 insertions, 0 deletions
diff --git a/crates/atuin-ai/src/tui/state.rs b/crates/atuin-ai/src/tui/state.rs
index e008bd3c..71da6ff5 100644
--- a/crates/atuin-ai/src/tui/state.rs
+++ b/crates/atuin-ai/src/tui/state.rs
@@ -37,6 +37,14 @@ pub(crate) enum ConversationEvent {
/// 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 {
@@ -49,6 +57,7 @@ impl ConversationEvent {
ConversationEvent::ToolResult { .. } => true,
ConversationEvent::OutOfBandOutput { .. } => false,
ConversationEvent::SystemContext { .. } => false,
+ ConversationEvent::SkillInvocation { .. } => true,
}
}
@@ -206,6 +215,21 @@ pub(crate) fn events_to_messages(events: &[ConversationEvent]) -> Vec<serde_json
}));
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;
+ }
}
}