soma_codemode/
openapi_feature.rs1use crate::ToolError;
2
3#[cfg(feature = "openapi")]
4use serde_json::Value;
5
6#[cfg(feature = "openapi")]
7pub use soma_openapi::OpenApiRegistry;
8
9#[cfg(feature = "openapi")]
10#[must_use]
11pub fn split_openapi_method(method: &str) -> Option<(&str, &str)> {
12 let (label, operation_id) = method.split_once('.')?;
13 if label.is_empty() || operation_id.is_empty() {
14 return None;
15 }
16 Some((label, operation_id))
17}
18
19#[cfg(not(feature = "openapi"))]
20#[must_use]
21pub fn openapi_provider_unavailable_error() -> ToolError {
22 ToolError::UnknownAction {
23 message: "unknown Code Mode local provider `openapi`".to_string(),
24 valid: vec!["state".to_string(), "git".to_string()],
25 hint: None,
26 }
27}
28
29#[cfg(feature = "openapi")]
30pub async fn dispatch_openapi_provider(
31 registry: &soma_openapi::OpenApiRegistry,
32 client: &reqwest::Client,
33 method: &str,
34 params: Value,
35) -> Result<Value, ToolError> {
36 let (label, operation_id) =
37 split_openapi_method(method).ok_or_else(|| ToolError::InvalidParam {
38 message: "openapi call must be openapi::<label>.<operationId>".to_string(),
39 param: "id".to_string(),
40 })?;
41 soma_openapi::dispatch_openapi_call(registry, client, label, operation_id, params)
42 .await
43 .map_err(openapi_error_to_tool_error)
44}
45
46#[cfg(feature = "openapi")]
47#[must_use]
48pub fn openapi_error_to_tool_error(error: soma_openapi::OpenApiError) -> ToolError {
49 match error {
50 soma_openapi::OpenApiError::UnknownInstance { label, valid } => {
51 ToolError::UnknownInstance {
52 message: format!("unknown OpenAPI spec label `{label}`"),
53 valid,
54 }
55 }
56 soma_openapi::OpenApiError::UnknownOperation {
57 label,
58 operation_id,
59 } => ToolError::UnknownAction {
60 message: format!("unknown OpenAPI operation `{operation_id}` in `{label}`"),
61 valid: Vec::new(),
62 hint: None,
63 },
64 soma_openapi::OpenApiError::InvalidPathParam { label, param } => ToolError::InvalidParam {
65 message: format!(
66 "OpenAPI operation `{label}` path parameter `{param}` is missing or invalid"
67 ),
68 param,
69 },
70 soma_openapi::OpenApiError::RequestBlockedPrivateAddr { .. } => ToolError::Forbidden {
71 message: error.to_string(),
72 required_scopes: vec!["openapi".to_string()],
73 },
74 soma_openapi::OpenApiError::UpstreamTimeout { .. } => ToolError::Sdk {
75 sdk_kind: "timeout".to_string(),
76 message: error.to_string(),
77 },
78 other => ToolError::Sdk {
79 sdk_kind: other.kind().to_string(),
80 message: other.to_string(),
81 },
82 }
83}