Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions crates/goose-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,84 @@ pub struct InferenceMetadata {
pub resolved_model: Option<String>,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "camelCase")]
pub struct MessageMetadata {
pub user_visible: bool,
pub agent_visible: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub inference: Option<InferenceMetadata>,
}

impl Default for MessageMetadata {
fn default() -> Self {
Self {
user_visible: true,
agent_visible: true,
inference: None,
}
}
}

impl MessageMetadata {
pub fn agent_only() -> Self {
Self {
user_visible: false,
agent_visible: true,
..Default::default()
}
}

pub fn user_only() -> Self {
Self {
user_visible: true,
agent_visible: false,
..Default::default()
}
}

pub fn invisible() -> Self {
Self {
user_visible: false,
agent_visible: false,
..Default::default()
}
}

pub fn with_agent_invisible(self) -> Self {
Self {
agent_visible: false,
..self
}
}

pub fn with_user_invisible(self) -> Self {
Self {
user_visible: false,
..self
}
}

pub fn with_agent_visible(self) -> Self {
Self {
agent_visible: true,
..self
}
}

pub fn with_user_visible(self) -> Self {
Self {
user_visible: true,
..self
}
}

pub fn with_inference(mut self, inference: InferenceMetadata) -> Self {
self.inference = Some(inference);
self
}
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProviderUsage {
pub model: String,
Expand Down
92 changes: 3 additions & 89 deletions crates/goose/src/conversation/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ use crate::conversation::tool_result_serde;
use crate::mcp_utils::{extract_text_from_resource, ToolResult};
use crate::utils::sanitize_unicode_tags;
use chrono::Utc;
pub use goose_types::{InferenceMetadata, RedactedThinkingContent, ThinkingContent};
pub use goose_types::{
InferenceMetadata, MessageMetadata, RedactedThinkingContent, ThinkingContent,
};
use rmcp::model::{
AnnotateAble, CallToolRequestParams, CallToolResult, Content, ImageContent, JsonObject,
PromptMessage, PromptMessageContent, PromptMessageRole, RawContent, RawImageContent,
Expand Down Expand Up @@ -637,94 +639,6 @@ impl From<PromptMessage> for Message {
}
}

#[derive(ToSchema, Clone, PartialEq, Serialize, Deserialize, Debug)]
/// Metadata for message visibility and model inference details
#[serde(rename_all = "camelCase")]
pub struct MessageMetadata {
/// Whether the message should be visible to the user in the UI
pub user_visible: bool,
/// Whether the message should be included in the agent's context window
pub agent_visible: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub inference: Option<InferenceMetadata>,
}

impl Default for MessageMetadata {
fn default() -> Self {
MessageMetadata {
user_visible: true,
agent_visible: true,
inference: None,
}
}
}

impl MessageMetadata {
/// Create metadata for messages visible only to the agent
pub fn agent_only() -> Self {
MessageMetadata {
user_visible: false,
agent_visible: true,
..Default::default()
}
}

/// Create metadata for messages visible only to the user
pub fn user_only() -> Self {
MessageMetadata {
user_visible: true,
agent_visible: false,
..Default::default()
}
}

/// Create metadata for messages visible to neither user nor agent (archived)
pub fn invisible() -> Self {
MessageMetadata {
user_visible: false,
agent_visible: false,
..Default::default()
}
}

/// Return a copy with agent_visible set to false
pub fn with_agent_invisible(self) -> Self {
Self {
agent_visible: false,
..self
}
}

/// Return a copy with user_visible set to false
pub fn with_user_invisible(self) -> Self {
Self {
user_visible: false,
..self
}
}

/// Return a copy with agent_visible set to true
pub fn with_agent_visible(self) -> Self {
Self {
agent_visible: true,
..self
}
}

/// Return a copy with user_visible set to true
pub fn with_user_visible(self) -> Self {
Self {
user_visible: true,
..self
}
}

pub fn with_inference(mut self, inference: InferenceMetadata) -> Self {
self.inference = Some(inference);
self
}
}

#[derive(ToSchema, Clone, PartialEq, Serialize, Deserialize, Debug)]
/// A message to or from an LLM
#[serde(rename_all = "camelCase")]
Expand Down