Skip to content

Commit 0e5e580

Browse files
vorporealwarp-agent
andcommitted
Add the ai_types crate and move pure AI model types into it
Create a new crates/ai_types crate that holds pure AI model types with a small dependency budget (serde, uuid, anyhow, thiserror). Move AIConversationId, AIAgentActionId, TaskId, AmbientAgentTaskId, EntrypointType, PassiveSuggestionTriggerType, and WarpAiExecutionContext into it. Move SkillDescriptor into the ai crate, because it uses ai and warp_core types. The warp crate re-exports the moved types from their old paths, so most call sites do not change. The persistence conversions move into the persistence crate to satisfy the orphan rule, and WarpAiExecutionContext::new becomes the free function execution_context_for_session because it reads app Session state. Co-Authored-By: Warp <agent@warp.dev>
1 parent 702aa10 commit 0e5e580

24 files changed

Lines changed: 311 additions & 266 deletions

File tree

Cargo.lock

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ publish = false
3030
[workspace.dependencies]
3131
# Local workspace crates. This lets us reference them in other crates without specifying a path.
3232
ai = { path = "crates/ai" }
33+
ai_types = { path = "crates/ai_types" }
3334
app-installation-detection = { path = "crates/app-installation-detection" }
3435
asset_cache = { path = "crates/asset_cache" }
3536
asset_macro = { path = "crates/asset_macro" }

app/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ test = false
5656
[dependencies]
5757
addr = "0.15.6"
5858
ai.workspace = true
59+
ai_types.workspace = true
5960
alphanumeric-sort = "1.5.7"
6061
anyhow.workspace = true
6162
arrayvec.workspace = true

app/src/ai/agent/conversation.rs

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
use std::collections::{HashMap, HashSet};
2-
use std::fmt::Display;
32

43
use ai::agent::orchestration_config::{OrchestrationConfig, OrchestrationConfigStatus};
54
use ai::document::AIDocumentId;
65
use ai::skills::SkillPathOrigin;
76
use anyhow::Context as _;
87
use chrono::{DateTime, Local, TimeZone};
98
use itertools::Itertools as _;
10-
use serde::{Deserialize, Serialize};
11-
use uuid::Uuid;
129
use vec1::{Size0Error, Vec1};
1310
use warp_cli::agent::Harness;
1411
use warp_core::command::ExitCode;
@@ -4565,35 +4562,7 @@ pub enum UpdateConversationError {
45654562
NoPendingRequest,
45664563
}
45674564

4568-
/// A globally unique ID for a conversation with an AI agent.
4569-
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, Hash)]
4570-
pub struct AIConversationId(Uuid);
4571-
4572-
impl Display for AIConversationId {
4573-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4574-
write!(f, "{}", self.0)
4575-
}
4576-
}
4577-
4578-
impl AIConversationId {
4579-
pub fn new() -> Self {
4580-
Self(Uuid::new_v4())
4581-
}
4582-
}
4583-
4584-
impl Default for AIConversationId {
4585-
fn default() -> Self {
4586-
Self::new()
4587-
}
4588-
}
4589-
4590-
impl TryFrom<String> for AIConversationId {
4591-
type Error = anyhow::Error;
4592-
4593-
fn try_from(value: String) -> Result<Self, Self::Error> {
4594-
Ok(Self(Uuid::try_parse(&value)?))
4595-
}
4596-
}
4565+
pub use ai_types::AIConversationId;
45974566

45984567
/// The harness that produced an agent conversation.
45994568
#[derive(Debug, Clone, Copy, PartialEq, Eq)]

app/src/ai/agent/mod.rs

Lines changed: 2 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,13 @@ use std::ops::{AddAssign, Deref, DerefMut, Range};
1818
use std::sync::Arc;
1919
use std::time::Duration;
2020

21-
// Re-export types that were moved to the ai crate.
21+
// Re-export types that were moved to the ai and ai_types crates.
2222
pub use ai::agent::action::*;
2323
pub use ai::agent::action_result::*;
2424
use ai::agent::orchestration_config::{OrchestrationConfig, OrchestrationConfigStatus};
2525
pub use ai::agent::{AIAgentCitation, FileLocations};
2626
use ai::skills::ParsedSkill;
27+
pub use ai_types::{AIAgentActionId, EntrypointType, PassiveSuggestionTriggerType};
2728
use chrono::{DateTime, Local, TimeDelta};
2829
use comment::ReviewComment;
2930
use derivative::Derivative;
@@ -1036,43 +1037,6 @@ pub struct SuggestedAgentModeWorkflow {
10361037
pub logging_id: SuggestedLoggingId,
10371038
}
10381039

1039-
/// A ID for an AI action generated as part of an [`AIAgentOutput`].
1040-
///
1041-
/// The internal ID itself should be opaque to all callers. This ID may be relayed back to the AI with
1042-
/// the `AIAgentActionResult` from the action.
1043-
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
1044-
pub struct AIAgentActionId(String);
1045-
1046-
impl From<String> for AIAgentActionId {
1047-
fn from(value: String) -> Self {
1048-
AIAgentActionId(value)
1049-
}
1050-
}
1051-
1052-
impl From<AIAgentActionId> for String {
1053-
fn from(value: AIAgentActionId) -> Self {
1054-
value.0
1055-
}
1056-
}
1057-
1058-
impl Display for AIAgentActionId {
1059-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1060-
self.0.fmt(f)
1061-
}
1062-
}
1063-
1064-
impl From<crate::persistence::model::AIAgentActionId> for AIAgentActionId {
1065-
fn from(value: crate::persistence::model::AIAgentActionId) -> Self {
1066-
Self(value.0)
1067-
}
1068-
}
1069-
1070-
impl From<AIAgentActionId> for crate::persistence::model::AIAgentActionId {
1071-
fn from(value: AIAgentActionId) -> Self {
1072-
crate::persistence::model::AIAgentActionId(value.0)
1073-
}
1074-
}
1075-
10761040
/// An "action" included in an AI output.
10771041
#[derive(Debug, Clone, Eq, PartialEq)]
10781042
pub struct AIAgentAction {
@@ -2551,37 +2515,6 @@ pub enum StaticQueryType {
25512515
EvaluationSuite,
25522516
}
25532517

2554-
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
2555-
#[allow(clippy::enum_variant_names)]
2556-
pub enum EntrypointType {
2557-
PromptSuggestion {
2558-
is_static: bool,
2559-
is_coding: bool,
2560-
},
2561-
ZeroStateAgentModePromptSuggestion,
2562-
InitProjectRules,
2563-
TriggerPassiveSuggestion {
2564-
trigger: Option<PassiveSuggestionTriggerType>,
2565-
},
2566-
UserInitiated,
2567-
AgentInitiated,
2568-
SharedSession,
2569-
CloneRepository,
2570-
ResumeConversation,
2571-
}
2572-
2573-
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
2574-
#[allow(clippy::enum_variant_names)]
2575-
pub enum PassiveSuggestionTriggerType {
2576-
/// Used for unit test generation.
2577-
FilesChanged,
2578-
/// Used for unit test generation.
2579-
CommandRun,
2580-
2581-
ShellCommandCompleted,
2582-
AgentResponseCompleted,
2583-
}
2584-
25852518
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
25862519
pub struct ShellCommandCompletedTrigger {
25872520
// We heap-allocate this because it's large and bloats the size of the

app/src/ai/agent/task.rs

Lines changed: 6 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,14 @@ pub mod helper;
22
pub mod transaction;
33

44
use std::collections::{HashMap, HashSet};
5-
use std::fmt::Display;
6-
use std::ops::Deref;
75

86
use ai::skills::SkillPathOrigin;
7+
pub use ai_types::TaskId;
98
use anyhow::Context as _;
109
use field_mask::{FieldMaskError, FieldMaskOperation};
1110
use helper::{MessageExt, SubagentExt, ToolCallExt};
1211
use itertools::Itertools;
1312
use prost_types::FieldMask;
14-
use serde::{Deserialize, Serialize};
1513
use uuid::Uuid;
1614
use warp_errors::report_error;
1715
use warp_multi_agent_api::message::Message;
@@ -33,35 +31,6 @@ use crate::AIAgentTodoList;
3331
use crate::ai::document::ai_document_model::{AIDocumentId, AIDocumentVersion};
3432
use crate::terminal::model::block::BlockId;
3533

36-
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
37-
pub struct TaskId(String);
38-
39-
impl TaskId {
40-
pub fn new(id: String) -> Self {
41-
TaskId(id)
42-
}
43-
}
44-
45-
impl From<TaskId> for String {
46-
fn from(id: TaskId) -> Self {
47-
id.0
48-
}
49-
}
50-
51-
impl Deref for TaskId {
52-
type Target = str;
53-
54-
fn deref(&self) -> &Self::Target {
55-
&self.0
56-
}
57-
}
58-
59-
impl Display for TaskId {
60-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61-
f.write_str(&self.0)
62-
}
63-
}
64-
6534
#[derive(Debug, thiserror::Error)]
6635
pub enum UpdateTaskError {
6736
#[error("Task never initialized with CreateTask client action.")]
@@ -269,7 +238,7 @@ impl Task {
269238
restored_exchanges.sort_by_key(|exchange| exchange.start_time);
270239

271240
Self {
272-
id: TaskId(task.id.clone()),
241+
id: TaskId::new(task.id.clone()),
273242
data: TaskImpl::Server(ServerTask {
274243
source: task,
275244
subagent_params: None,
@@ -326,7 +295,7 @@ impl Task {
326295
let messages_clone = subtask.messages.clone();
327296
let new_exchange_id = new_exchange.id;
328297
let mut me = Self {
329-
id: TaskId(subtask.id.clone()),
298+
id: TaskId::new(subtask.id.clone()),
330299
exchanges: vec![new_exchange],
331300
data: TaskImpl::Server(ServerTask {
332301
source: subtask,
@@ -361,7 +330,7 @@ impl Task {
361330
});
362331

363332
Self {
364-
id: TaskId(subtask.id.clone()),
333+
id: TaskId::new(subtask.id.clone()),
365334
exchanges: restored_exchanges,
366335
data: TaskImpl::Server(ServerTask {
367336
source: subtask,
@@ -386,7 +355,7 @@ impl Task {
386355
});
387356

388357
Self {
389-
id: TaskId(subtask.id.clone()),
358+
id: TaskId::new(subtask.id.clone()),
390359
exchanges: vec![],
391360
data: TaskImpl::Server(ServerTask {
392361
source: subtask,
@@ -470,7 +439,7 @@ impl Task {
470439
pub fn parent_id(&self) -> Option<TaskId> {
471440
self.source()
472441
.and_then(|source| source.dependencies.as_ref())
473-
.map(|dependencies| TaskId(dependencies.parent_task_id.clone()))
442+
.map(|dependencies| TaskId::new(dependencies.parent_task_id.clone()))
474443
}
475444

476445
pub fn is_root_task(&self) -> bool {

app/src/ai/agent/telemetry.rs

Lines changed: 1 addition & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@ use serde::Serialize;
22
use warpui::{AppContext, SingletonEntity};
33

44
use super::conversation::AIConversationId;
5-
use super::{
6-
AIAgentCitation, AIAgentExchangeId, EntrypointType, PassiveSuggestionTriggerType,
7-
ServerOutputId,
8-
};
5+
use super::{AIAgentCitation, AIAgentExchangeId, ServerOutputId};
96
use crate::CloudModel;
107
use crate::ai::llms::LLMId;
118
use crate::server::telemetry::AgentModeCitation as CitationForTelemetry;
@@ -45,45 +42,6 @@ impl ForTelemetry for AIAgentCitation {
4542
}
4643
}
4744

48-
impl EntrypointType {
49-
pub fn entrypoint(&self) -> String {
50-
match self {
51-
Self::PromptSuggestion {
52-
is_static,
53-
is_coding,
54-
} => match (is_static, is_coding) {
55-
(true, true) => "PROMPT_SUGGESTION.CODING_STATIC".to_string(),
56-
(true, false) => "PROMPT_SUGGESTION.STATIC".to_string(),
57-
(false, true) => "PROMPT_SUGGESTION.CODING".to_string(),
58-
(false, false) => "PROMPT_SUGGESTION.SIMPLE".to_string(),
59-
},
60-
Self::ZeroStateAgentModePromptSuggestion => {
61-
"ZERO_STATE_AGENT_MODE_PROMPT_SUGGESTION".to_string()
62-
}
63-
Self::InitProjectRules => "INIT_PROJECT_RULES".to_string(),
64-
Self::UserInitiated => "USER_INITIATED".to_string(),
65-
Self::AgentInitiated => "AGENT_INITIATED".to_string(),
66-
Self::TriggerPassiveSuggestion { trigger } => {
67-
let trigger_name = match trigger {
68-
Some(PassiveSuggestionTriggerType::FilesChanged) => "FILES_CHANGED",
69-
Some(PassiveSuggestionTriggerType::CommandRun) => "COMMAND_RUN",
70-
Some(PassiveSuggestionTriggerType::ShellCommandCompleted) => {
71-
"SHELL_COMMAND_COMPLETED"
72-
}
73-
Some(PassiveSuggestionTriggerType::AgentResponseCompleted) => {
74-
"AGENT_RESPONSE_COMPLETED"
75-
}
76-
None => "NONE",
77-
};
78-
format!("TRIGGER_SUGGEST_PROMPT.{trigger_name}")
79-
}
80-
Self::CloneRepository => "CLONE_REPOSITORY".to_string(),
81-
Self::SharedSession => "SHARED_SESSION".to_string(),
82-
Self::ResumeConversation => "RESUME_CONVERSATION".to_string(),
83-
}
84-
}
85-
}
86-
8745
#[derive(Clone, Default, Debug, Serialize)]
8846
pub struct AIIdentifiers {
8947
/// Useful for joining to client-side telemetry.

0 commit comments

Comments
 (0)