Initial public release of Warp.

Repo-Sync-Origin: warpdotdev/warp-internal@12af1d983b
This commit is contained in:
David Stern
2026-04-28 08:43:33 -05:00
commit 0dbd3d567a
4982 changed files with 1431549 additions and 0 deletions
@@ -0,0 +1,307 @@
use crate::ai::blocklist::task_status_sync_model::classify_renderable_error;
use crate::server::server_api::ai::TaskStatusUpdate;
use warp_graphql::ai::{AgentTaskState, PlatformErrorCode};
use super::terminal::ShareSessionError;
use super::AgentDriverError;
/// Classify an `AgentDriverError` into a task state and a `TaskStatusUpdate`
/// suitable for reporting via `update_agent_task`.
pub fn classify_driver_error(error: &AgentDriverError) -> (AgentTaskState, TaskStatusUpdate) {
match error {
// --- Warp-side errors (task → ERROR) ---
AgentDriverError::TerminalUnavailable | AgentDriverError::InvalidRuntimeState => (
AgentTaskState::Error,
TaskStatusUpdate::with_error_code(
"An internal error occurred. Please try running your task again. If the issue persists, contact support.",
PlatformErrorCode::InternalError,
),
),
AgentDriverError::BootstrapFailed => (
AgentTaskState::Error,
TaskStatusUpdate::with_error_code(
"Terminal session failed to start. Please try running your task again.",
PlatformErrorCode::InternalError,
),
),
AgentDriverError::ShareSessionFailed { error: share_err } => {
let message = match share_err {
ShareSessionError::Internal(_) => {
"Failed to share agent session due to an internal error. Please try running your task again.".to_string()
}
ShareSessionError::Failed(reason) => {
// The reason string comes from the session-sharing layer and is aimed at
// interactive users (e.g. "try sharing again"). Provide a cloud-agent-
// appropriate message instead of wrapping it, which would produce
// repetitive "try again" text.
format!("Failed to share agent session: {reason}")
}
ShareSessionError::Disabled => {
"Session sharing is not enabled for your account. This is likely because \
an administrator has disabled session sharing for your team. Please \
verify that session sharing is enabled in your team settings, or try \
running without the --share flag."
.to_string()
}
ShareSessionError::Timeout => {
"Failed to share agent session: timed out waiting for the session sharing \
server to respond. Please check your network connection and try again."
.to_string()
}
ShareSessionError::Interrupted => {
"Session sharing was interrupted before it could complete. Please try running your task again.".to_string()
}
};
(
AgentTaskState::Error,
TaskStatusUpdate::with_error_code(
message,
match share_err {
ShareSessionError::Disabled => PlatformErrorCode::FeatureNotAvailable,
_ => PlatformErrorCode::InternalError,
},
),
)
}
AgentDriverError::WarpDriveSyncFailed => (
AgentTaskState::Error,
TaskStatusUpdate::with_error_code(
"Warp Drive failed to sync. Please check your network connection and try again.",
PlatformErrorCode::InternalError,
),
),
AgentDriverError::NotLoggedIn => {
let bin = warp_cli::binary_name().unwrap_or_else(|| "warp".to_string());
(
AgentTaskState::Error,
TaskStatusUpdate::with_error_code(
format!(
"Authentication required. Log in via '{bin} login', provide an API key via '--api-key', or set the WARP_API_KEY environment variable."
),
PlatformErrorCode::AuthenticationRequired,
),
)
}
AgentDriverError::CloudProviderSetupFailed(err) => (
AgentTaskState::Error,
TaskStatusUpdate::with_error_code(
format!("Error configuring cloud access: {err:#}"),
PlatformErrorCode::InternalError,
),
),
// --- User-side errors (task → FAILED) ---
AgentDriverError::MCPServerNotFound(uuid) => (
AgentTaskState::Failed,
TaskStatusUpdate::with_error_code(
format!(
"MCP server {uuid} was not found. Verify the server exists in your Warp Drive and the UUID is correct."
),
PlatformErrorCode::EnvironmentSetupFailed,
),
),
AgentDriverError::MCPStartupFailed => (
AgentTaskState::Failed,
TaskStatusUpdate::with_error_code(
"One or more MCP servers failed to start. Check that your MCP server configuration is valid and the server process is runnable.",
PlatformErrorCode::EnvironmentSetupFailed,
),
),
AgentDriverError::MCPJsonParseError(msg) => (
AgentTaskState::Failed,
TaskStatusUpdate::with_error_code(
format!("Failed to parse MCP server JSON configuration: {msg}"),
PlatformErrorCode::EnvironmentSetupFailed,
),
),
AgentDriverError::MCPMissingVariables => (
AgentTaskState::Failed,
TaskStatusUpdate::with_error_code(
"MCP server configuration is missing required variables. Provide all required environment variables or template values.",
PlatformErrorCode::EnvironmentSetupFailed,
),
),
AgentDriverError::ProfileError(name) => (
AgentTaskState::Failed,
TaskStatusUpdate::with_error_code(
format!(
"Agent profile \"{name}\" not found. Check the profile ID and ensure it exists in your team's Warp Drive."
),
PlatformErrorCode::ResourceNotFound,
),
),
AgentDriverError::AIWorkflowNotFound(id) => (
AgentTaskState::Failed,
TaskStatusUpdate::with_error_code(
format!(
"Saved prompt not found for ID {id}. Verify the prompt exists in your Warp Drive."
),
PlatformErrorCode::ResourceNotFound,
),
),
AgentDriverError::EnvironmentNotFound(id) => (
AgentTaskState::Failed,
TaskStatusUpdate::with_error_code(
format!(
"Environment '{id}' not found. Verify the environment ID and ensure it exists in your team settings."
),
PlatformErrorCode::ResourceNotFound,
),
),
AgentDriverError::EnvironmentSetupFailed(msg) => (
AgentTaskState::Failed,
TaskStatusUpdate::with_error_code(
format!(
"Environment setup failed: {msg}. Check your repository URLs and setup commands."
),
PlatformErrorCode::EnvironmentSetupFailed,
),
),
AgentDriverError::InvalidWorkingDirectory { path, .. } => (
AgentTaskState::Failed,
TaskStatusUpdate::with_error_code(
format!(
"Working directory '{}' does not exist or is not a directory. Verify the path in your environment configuration.",
path.display()
),
PlatformErrorCode::EnvironmentSetupFailed,
),
),
// --- Conversation errors ---
// Delegate to classify_renderable_error for proper ERROR vs FAILED
// distinction and PlatformErrorCode. This is a belt-and-suspenders
// fallback — TaskStatusSyncModel handles most conversation errors,
// but the driver catches them too if the conversation ends with an error.
AgentDriverError::ConversationError { error } => {
let (state, update) = classify_renderable_error(error);
(
state,
update.unwrap_or_else(|| {
TaskStatusUpdate::with_error_code(
error.to_string(),
PlatformErrorCode::InternalError,
)
}),
)
}
// --- Cancellation / Blocked (no error code) ---
AgentDriverError::ConversationCancelled { .. } => (
AgentTaskState::Cancelled,
TaskStatusUpdate::message("Task cancelled."),
),
AgentDriverError::ConversationBlocked { blocked_action } => (
AgentTaskState::Blocked,
TaskStatusUpdate::message(format!(
"The agent got stuck waiting for user confirmation on the action: {blocked_action}"
)),
),
// --- Setup errors ---
AgentDriverError::TeamMetadataRefreshTimeout => (
AgentTaskState::Error,
TaskStatusUpdate::with_error_code(
"Timed out refreshing team metadata. Please check your network connection and try again.",
PlatformErrorCode::InternalError,
),
),
AgentDriverError::SkillResolutionFailed(msg) => (
AgentTaskState::Failed,
TaskStatusUpdate::with_error_code(
format!("Skill resolution failed: {msg}"),
PlatformErrorCode::ResourceNotFound,
),
),
AgentDriverError::ConfigBuildFailed(err) => (
AgentTaskState::Failed,
TaskStatusUpdate::with_error_code(
format!("Failed to build agent configuration: {err}"),
PlatformErrorCode::EnvironmentSetupFailed,
),
),
AgentDriverError::PromptResolutionFailed(err) => (
AgentTaskState::Error,
TaskStatusUpdate::with_error_code(
format!("Failed to resolve prompt for the run: {err}"),
PlatformErrorCode::InternalError,
),
),
AgentDriverError::SecretsFetchFailed(err) => (
AgentTaskState::Error,
TaskStatusUpdate::with_error_code(
format!("Failed to fetch task secrets: {err}"),
PlatformErrorCode::InternalError,
),
),
AgentDriverError::AwsBedrockCredentialsFailed(msg) => (
AgentTaskState::Failed,
TaskStatusUpdate::with_error_code(
format!("Failed to initialize AWS Bedrock credentials: {msg}"),
PlatformErrorCode::EnvironmentSetupFailed,
),
),
AgentDriverError::ConversationLoadFailed(msg) => (
AgentTaskState::Error,
TaskStatusUpdate::with_error_code(
format!("Failed to load conversation: {msg}"),
PlatformErrorCode::InternalError,
),
),
AgentDriverError::ConversationHarnessMismatch { conversation_id, expected, got } => (
AgentTaskState::Failed,
TaskStatusUpdate::with_error_code(
format!(
"Conversation {conversation_id} was produced by the {expected} harness, but --harness {got} was requested. \
Re-run with --harness {expected} (or omit --harness) to continue this conversation."
),
PlatformErrorCode::EnvironmentSetupFailed,
),
),
AgentDriverError::TaskHarnessMismatch { task_id, expected, got } => (
AgentTaskState::Failed,
TaskStatusUpdate::with_error_code(
format!(
"Task {task_id} was created with the {expected} harness, but --harness {got} was requested. \
Re-run with --harness {expected} (or omit --harness) to continue this task."
),
PlatformErrorCode::EnvironmentSetupFailed,
),
),
AgentDriverError::ConversationResumeStateMissing { harness, conversation_id } => (
AgentTaskState::Failed,
TaskStatusUpdate::with_error_code(
format!(
"Conversation {conversation_id} has no stored transcript for the {harness} harness. \
The prior run may have crashed before saving any state."
),
PlatformErrorCode::ResourceNotFound,
),
),
AgentDriverError::HarnessCommandFailed { exit_code } => (
AgentTaskState::Failed,
TaskStatusUpdate::with_error_code(
format!("Harness command exited with code {exit_code}"),
PlatformErrorCode::InternalError,
),
),
AgentDriverError::HarnessSetupFailed { harness, reason } => (
AgentTaskState::Failed,
TaskStatusUpdate::with_error_code(
format!("Harness '{harness}' validation failed: {reason}"),
PlatformErrorCode::EnvironmentSetupFailed,
),
),
AgentDriverError::HarnessConfigSetupFailed { harness, error } => (
AgentTaskState::Failed,
TaskStatusUpdate::with_error_code(
format!("Harness '{harness}' config setup failed: {error}"),
PlatformErrorCode::EnvironmentSetupFailed,
),
),
}
}
#[cfg(test)]
#[path = "error_classification_tests.rs"]
mod tests;