This commit is contained in:
2026-08-05 00:56:55 -05:00
parent b0ad07f6f2
commit c321e17708
44 changed files with 2005 additions and 598 deletions
+4 -1
View File
@@ -34,7 +34,10 @@ pub struct RuntimeDescriptor {
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum TurnCommand {
Cancel,
Steer { text: String },
Steer {
display_text: String,
model_text: String,
},
}
#[derive(Clone, Debug)]
@@ -103,7 +103,8 @@ fn turn_control_delivers_cancel_and_steering_in_order() {
sender
.send(TurnCommand::Steer {
text: "focus on tests".to_string(),
display_text: "focus on tests".to_string(),
model_text: "focus on tests".to_string(),
})
.await
.unwrap();
@@ -112,7 +113,8 @@ fn turn_control_delivers_cancel_and_steering_in_order() {
assert_eq!(
control.receive().await.unwrap(),
TurnCommand::Steer {
text: "focus on tests".to_string(),
display_text: "focus on tests".to_string(),
model_text: "focus on tests".to_string(),
}
);
assert_eq!(control.receive().await.unwrap(), TurnCommand::Cancel);
+47
View File
@@ -99,6 +99,13 @@ pub struct TurnRequest {
pub conversation_id: Option<String>,
pub model: ModelId,
pub system_prompt: Option<String>,
/// Current runtime input when the runtime owns conversation history.
///
/// Provider runtimes normally consume `messages`, while session-oriented
/// runtimes such as ACP consume this single prompt and retain their own
/// history. Keeping the distinction explicit prevents applications from
/// serializing a prompt into provider history and translating it back.
pub prompt: Option<MessageContent>,
pub messages: Vec<ConversationMessage>,
pub tools: Vec<ToolDefinition>,
pub max_output_tokens: Option<u64>,
@@ -111,12 +118,18 @@ impl TurnRequest {
conversation_id: None,
model: model.into(),
system_prompt: None,
prompt: None,
messages,
tools: Vec::new(),
max_output_tokens: None,
metadata: BTreeMap::new(),
}
}
pub fn with_prompt(mut self, prompt: MessageContent) -> Self {
self.prompt = Some(prompt);
self
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
@@ -233,6 +246,23 @@ pub enum StopReason {
Other(String),
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum RuntimeActivityStatus {
Pending,
InProgress,
Completed,
Failed,
Other(String),
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct RuntimeActivity {
pub id: String,
pub title: String,
pub status: Option<RuntimeActivityStatus>,
pub output: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum AgentEvent {
TurnStarted {
@@ -254,6 +284,23 @@ pub enum AgentEvent {
UsageUpdated {
usage: Usage,
},
/// Progress owned by a session runtime rather than a Galaxy-executed tool.
RuntimeActivityUpdated {
activity: RuntimeActivity,
},
/// Current context occupancy reported by a session runtime.
ContextUsageUpdated {
used_tokens: u64,
context_size: u64,
},
/// Visible user input accepted while a turn was already running.
UserInputAccepted {
text: String,
},
/// A displayable runtime lifecycle or permission notice.
RuntimeNotice {
message: String,
},
TurnStopped {
reason: StopReason,
},
@@ -91,3 +91,15 @@ fn denied_results_are_errors_but_cancelled_results_are_distinct() {
assert!(denied.is_error());
assert!(!cancelled.is_error());
}
#[test]
fn session_runtime_prompt_is_distinct_from_provider_history() {
let request = TurnRequest::new("acp:codex", Vec::new())
.with_prompt(MessageContent::Text("inspect the workspace".to_owned()));
assert_eq!(
request.prompt,
Some(MessageContent::Text("inspect the workspace".to_owned()))
);
assert!(request.messages.is_empty());
}