Synced from monorepo
Synced from monorepo Changes: - Report invalid MCP server config instead of failing startup - Keep completed terminal output when the gateway connection is lost - Show a duration-only detail view for single-task task output - Don't let a stale registry turn counter hide local sessions - Raise the file-descriptor soft limit on Linux and log effective limits at startup - Stop aborting when HTTP client construction fails - Make session thread and runtime spawn failures recoverable - Fix main-prompt paste parity in the question freeform input - Fire SessionEnd hooks on /exit and headless quit - Embed the deployment-config signing public key - Repaint paste-chip background on inline panel inputs - Security: prevent acceptEdits from auto-approving agent writes into the always-trusted global hook root - Fix stacked "Worked for" markers so parks render as status and turns close with exactly one marker - Parse hooks from config files - Add a remote kill-switch for managed-config signature verification - Security: fix workspace file-reference resolution bypassing workspace filesystem confinement Source-Revision: d02693a856a54f1030695b36b91d276e96b30b23
This commit is contained in:
parent
6e38642082
commit
47348d13ec
138 changed files with 7283 additions and 5796 deletions
|
|
@ -1,7 +1,5 @@
|
|||
//! Workspace error types.
|
||||
|
||||
use crate::capability::CapabilityMode;
|
||||
|
||||
/// Errors surfaced by the workspace public API.
|
||||
///
|
||||
/// `#[non_exhaustive]` so adding new variants is a non-breaking change.
|
||||
|
|
@ -11,68 +9,48 @@ use crate::capability::CapabilityMode;
|
|||
pub enum WorkspaceError {
|
||||
#[error("parent session not found: {0}")]
|
||||
ParentSessionNotFound(String),
|
||||
|
||||
#[error("session not found: {0}")]
|
||||
SessionNotFound(String),
|
||||
|
||||
#[error("session already exists: {0}")]
|
||||
SessionAlreadyExists(String),
|
||||
|
||||
#[error("agent_id must be non-empty")]
|
||||
EmptyAgentId,
|
||||
|
||||
#[error("the main session cannot be dropped")]
|
||||
CannotDropMainSession,
|
||||
|
||||
#[error("toolset finalization failed: {0}")]
|
||||
Finalize(String),
|
||||
|
||||
#[error("capability widening rejected: child {child:?} is not a subset of parent {parent:?}")]
|
||||
CapabilityWidening {
|
||||
parent: CapabilityMode,
|
||||
child: CapabilityMode,
|
||||
},
|
||||
|
||||
#[error("session {caller:?} is not authorised to operate on session {target:?}")]
|
||||
Unauthorized { caller: String, target: String },
|
||||
|
||||
/// A toolset mutation was rejected because the target session has an
|
||||
/// active turn. Retryable at the turn boundary (`after_turn`).
|
||||
#[error("turn active for session {0}; retry the tool-config update at the turn boundary")]
|
||||
TurnActive(String),
|
||||
|
||||
#[error("maximum fork depth exceeded for parent session {parent:?}")]
|
||||
MaxDepthExceeded { parent: String },
|
||||
|
||||
#[error("internal task failure: {0}")]
|
||||
JoinError(String),
|
||||
|
||||
#[error("invalid hunk action: {0}")]
|
||||
InvalidHunkAction(String),
|
||||
|
||||
#[error("hunk action failed: {0}")]
|
||||
HunkActionFailed(String),
|
||||
|
||||
/// An error from the server connection or tool server.
|
||||
#[error("hub error: {0}")]
|
||||
HubError(String),
|
||||
|
||||
/// Deploy-service error tagged with its gRPC status class; see
|
||||
/// [`DeployError`] for how the class crosses the workspace RPC boundary.
|
||||
///
|
||||
/// [`DeployError`]: xai_grok_workspace_types::rpc::deploy::DeployError
|
||||
#[error("deploy error: {message}")]
|
||||
DeployError {
|
||||
kind: xai_grok_workspace_types::rpc::deploy::DeployError,
|
||||
#[error("github export error: {message}")]
|
||||
ExportGithub {
|
||||
kind: xai_grok_workspace_types::rpc::export_github::ExportGithubError,
|
||||
message: String,
|
||||
},
|
||||
|
||||
/// The workspace is draining/shutting down and is no longer accepting new
|
||||
/// sessions. Surfaced when a `bind`/create races a terminal drain so the
|
||||
/// shared upload queue is never torn down out from under a fresh session.
|
||||
#[error("workspace is shutting down; not accepting new sessions")]
|
||||
ShuttingDown,
|
||||
|
||||
/// The session's toolset is externally owned — installed by a local
|
||||
/// (shell) bind, its `Terminal` resource is not the session-owned
|
||||
/// backend — so an RPC-driven toolset mutation is refused instead of
|
||||
|
|
@ -81,7 +59,6 @@ pub enum WorkspaceError {
|
|||
#[error("toolset externally owned (local bind), mutation refused: {0}")]
|
||||
ToolsetExternallyOwned(String),
|
||||
}
|
||||
|
||||
impl WorkspaceError {
|
||||
/// Low-cardinality `error_kind` metric label: the variant name in
|
||||
/// snake_case; `DeployError` reports its per-kind `wire_code()`.
|
||||
|
|
@ -101,32 +78,17 @@ impl WorkspaceError {
|
|||
Self::InvalidHunkAction(_) => "invalid_hunk_action",
|
||||
Self::HunkActionFailed(_) => "hunk_action_failed",
|
||||
Self::HubError(_) => "hub_error",
|
||||
Self::DeployError { kind, .. } => kind.wire_code(),
|
||||
Self::ExportGithub { kind, .. } => kind.wire_code(),
|
||||
Self::ShuttingDown => "shutting_down",
|
||||
Self::ToolsetExternallyOwned(_) => "toolset_externally_owned",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convenience alias for the workspace's primary `Result` type.
|
||||
pub type WorkspaceResult<T> = Result<T, WorkspaceError>;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::WorkspaceError;
|
||||
use xai_grok_workspace_types::rpc::deploy::DeployError;
|
||||
|
||||
#[test]
|
||||
fn metric_kind_reports_deploy_wire_code() {
|
||||
for kind in DeployError::ALL {
|
||||
let err = WorkspaceError::DeployError {
|
||||
kind,
|
||||
message: "m".into(),
|
||||
};
|
||||
assert_eq!(err.metric_kind(), kind.wire_code());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn metric_kind_is_message_free() {
|
||||
let err = WorkspaceError::HubError("something wildly unique 12345".into());
|
||||
|
|
|
|||
Loading…
Reference in a new issue