diff options
| author | main <main@swarm.moe> | 2026-03-19 10:15:18 -0400 |
|---|---|---|
| committer | main <main@swarm.moe> | 2026-03-19 10:15:18 -0400 |
| commit | 7b9bd8b42883f82b090718175b8316296ef18236 (patch) | |
| tree | 16f2c70b0f630c7757d72a20bd90d17c2e3a8414 /crates/fidget-spinner-cli/src/mcp/fault.rs | |
| download | fidget_spinner-7b9bd8b42883f82b090718175b8316296ef18236.zip | |
Initial Fidget Spinner MVP
Diffstat (limited to 'crates/fidget-spinner-cli/src/mcp/fault.rs')
| -rw-r--r-- | crates/fidget-spinner-cli/src/mcp/fault.rs | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/crates/fidget-spinner-cli/src/mcp/fault.rs b/crates/fidget-spinner-cli/src/mcp/fault.rs new file mode 100644 index 0000000..e9d1fce --- /dev/null +++ b/crates/fidget-spinner-cli/src/mcp/fault.rs @@ -0,0 +1,99 @@ +use serde::{Deserialize, Serialize}; +use serde_json::{Value, json}; +use time::OffsetDateTime; + +#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub(crate) enum FaultKind { + InvalidInput, + NotInitialized, + Unavailable, + Transient, + Internal, +} + +#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub(crate) enum FaultStage { + Host, + Worker, + Store, + Transport, + Protocol, + Rollout, +} + +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub(crate) struct FaultRecord { + pub kind: FaultKind, + pub stage: FaultStage, + pub operation: String, + pub message: String, + pub retryable: bool, + pub retried: bool, + pub worker_generation: Option<u64>, + pub occurred_at: OffsetDateTime, +} + +impl FaultRecord { + #[must_use] + pub fn new( + kind: FaultKind, + stage: FaultStage, + operation: impl Into<String>, + message: impl Into<String>, + ) -> Self { + Self { + kind, + stage, + operation: operation.into(), + message: message.into(), + retryable: false, + retried: false, + worker_generation: None, + occurred_at: OffsetDateTime::now_utc(), + } + } + + #[must_use] + pub fn retryable(mut self, worker_generation: Option<u64>) -> Self { + self.retryable = true; + self.worker_generation = worker_generation; + self + } + + #[must_use] + pub fn mark_retried(mut self) -> Self { + self.retried = true; + self + } + + #[must_use] + pub fn into_jsonrpc_error(self) -> Value { + json!({ + "code": self.jsonrpc_code(), + "message": self.message.clone(), + "data": self, + }) + } + + #[must_use] + pub fn into_tool_result(self) -> Value { + json!({ + "content": [{ + "type": "text", + "text": self.message, + }], + "structuredContent": self, + "isError": true, + }) + } + + #[must_use] + pub const fn jsonrpc_code(&self) -> i64 { + match self.kind { + FaultKind::InvalidInput => -32602, + FaultKind::NotInitialized => -32002, + FaultKind::Unavailable => -32004, + FaultKind::Transient | FaultKind::Internal => -32603, + } + } +} |