use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash)]
#[schemars(rename = "viewer.ApiCallSubType")]
pub enum ApiCallSubType {
#[serde(rename = "POST_/agent/completions")]
PostAgentCompletions,
#[serde(rename = "POST_/vector/completions")]
PostVectorCompletions,
#[serde(rename = "POST_/vector/completions/votes")]
PostVectorCompletionsVotes,
#[serde(rename = "POST_/vector/completions/cache")]
PostVectorCompletionsCache,
#[serde(rename = "POST_/functions/list")]
PostFunctionsList,
#[serde(rename = "POST_/functions")]
PostFunctions,
#[serde(rename = "POST_/functions/usage")]
PostFunctionsUsage,
#[serde(rename = "POST_/functions/executions")]
PostFunctionsExecutions,
#[serde(rename = "POST_/functions/profiles/list")]
PostFunctionsProfilesList,
#[serde(rename = "POST_/functions/profiles")]
PostFunctionsProfiles,
#[serde(rename = "POST_/functions/profiles/usage")]
PostFunctionsProfilesUsage,
#[serde(rename = "POST_/functions/profiles/pairs/list")]
PostFunctionsProfilesPairsList,
#[serde(rename = "POST_/functions/profiles/pairs/usage")]
PostFunctionsProfilesPairsUsage,
#[serde(rename = "POST_/functions/inventions")]
PostFunctionsInventions,
#[serde(rename = "POST_/functions/inventions/recursive")]
PostFunctionsInventionsRecursive,
#[serde(rename = "POST_/functions/inventions/prompts/list")]
PostFunctionsInventionsPromptsList,
#[serde(rename = "POST_/functions/inventions/prompts")]
PostFunctionsInventionsPrompts,
#[serde(rename = "POST_/functions/inventions/prompts/usage")]
PostFunctionsInventionsPromptsUsage,
#[serde(rename = "POST_/functions/inventions/state")]
PostFunctionsInventionsState,
#[serde(rename = "POST_/functions/profiles/compute")]
PostFunctionsProfilesCompute,
#[serde(rename = "POST_/auth/keys")]
PostAuthKeys,
#[serde(rename = "POST_/auth/keys/openrouter")]
PostAuthKeysOpenrouter,
#[serde(rename = "DELETE_/auth/keys")]
DeleteAuthKeys,
#[serde(rename = "DELETE_/auth/keys/openrouter")]
DeleteAuthKeysOpenrouter,
#[serde(rename = "GET_/auth/keys")]
GetAuthKeys,
#[serde(rename = "GET_/auth/keys/openrouter")]
GetAuthKeysOpenrouter,
#[serde(rename = "GET_/auth/credits")]
GetAuthCredits,
#[serde(rename = "POST_/swarms/list")]
PostSwarmsList,
#[serde(rename = "POST_/swarms")]
PostSwarms,
#[serde(rename = "POST_/swarms/usage")]
PostSwarmsUsage,
#[serde(rename = "POST_/agents/list")]
PostAgentsList,
#[serde(rename = "POST_/agents")]
PostAgents,
#[serde(rename = "POST_/agents/usage")]
PostAgentsUsage,
#[serde(rename = "POST_/error")]
PostError,
#[serde(rename = "POST_/laboratories/executions")]
PostLaboratoriesExecutions,
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash)]
#[serde(rename_all = "UPPERCASE")]
#[schemars(rename = "viewer.HttpMethod")]
pub enum HttpMethod {
Get,
Post,
Delete,
}
impl HttpMethod {
pub fn as_str(&self) -> &'static str {
match self {
HttpMethod::Get => "GET",
HttpMethod::Post => "POST",
HttpMethod::Delete => "DELETE",
}
}
}
impl ApiCallSubType {
pub fn method(&self) -> HttpMethod {
match self {
ApiCallSubType::GetAuthKeys
| ApiCallSubType::GetAuthKeysOpenrouter
| ApiCallSubType::GetAuthCredits => HttpMethod::Get,
ApiCallSubType::DeleteAuthKeys
| ApiCallSubType::DeleteAuthKeysOpenrouter => HttpMethod::Delete,
_ => HttpMethod::Post,
}
}
pub fn path(&self) -> &'static str {
match self {
ApiCallSubType::PostAgentCompletions => "/agent/completions",
ApiCallSubType::PostVectorCompletions => "/vector/completions",
ApiCallSubType::PostVectorCompletionsVotes => "/vector/completions/votes",
ApiCallSubType::PostVectorCompletionsCache => "/vector/completions/cache",
ApiCallSubType::PostFunctionsList => "/functions/list",
ApiCallSubType::PostFunctions => "/functions",
ApiCallSubType::PostFunctionsUsage => "/functions/usage",
ApiCallSubType::PostFunctionsExecutions => "/functions/executions",
ApiCallSubType::PostFunctionsProfilesList => "/functions/profiles/list",
ApiCallSubType::PostFunctionsProfiles => "/functions/profiles",
ApiCallSubType::PostFunctionsProfilesUsage => "/functions/profiles/usage",
ApiCallSubType::PostFunctionsProfilesPairsList => "/functions/profiles/pairs/list",
ApiCallSubType::PostFunctionsProfilesPairsUsage => "/functions/profiles/pairs/usage",
ApiCallSubType::PostFunctionsInventions => "/functions/inventions",
ApiCallSubType::PostFunctionsInventionsRecursive => "/functions/inventions/recursive",
ApiCallSubType::PostFunctionsInventionsPromptsList => "/functions/inventions/prompts/list",
ApiCallSubType::PostFunctionsInventionsPrompts => "/functions/inventions/prompts",
ApiCallSubType::PostFunctionsInventionsPromptsUsage => "/functions/inventions/prompts/usage",
ApiCallSubType::PostFunctionsInventionsState => "/functions/inventions/state",
ApiCallSubType::PostFunctionsProfilesCompute => "/functions/profiles/compute",
ApiCallSubType::PostAuthKeys => "/auth/keys",
ApiCallSubType::PostAuthKeysOpenrouter => "/auth/keys/openrouter",
ApiCallSubType::DeleteAuthKeys => "/auth/keys",
ApiCallSubType::DeleteAuthKeysOpenrouter => "/auth/keys/openrouter",
ApiCallSubType::GetAuthKeys => "/auth/keys",
ApiCallSubType::GetAuthKeysOpenrouter => "/auth/keys/openrouter",
ApiCallSubType::GetAuthCredits => "/auth/credits",
ApiCallSubType::PostSwarmsList => "/swarms/list",
ApiCallSubType::PostSwarms => "/swarms",
ApiCallSubType::PostSwarmsUsage => "/swarms/usage",
ApiCallSubType::PostAgentsList => "/agents/list",
ApiCallSubType::PostAgents => "/agents",
ApiCallSubType::PostAgentsUsage => "/agents/usage",
ApiCallSubType::PostError => "/error",
ApiCallSubType::PostLaboratoriesExecutions => "/laboratories/executions",
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
#[serde(tag = "type", rename_all = "snake_case")]
#[schemars(rename = "viewer.ApiCallEnvelope")]
pub enum ApiCallEnvelope {
#[schemars(title = "Begin")]
Begin,
#[schemars(title = "Chunk")]
Chunk { chunk: serde_json::Value },
#[schemars(title = "Error")]
Error { error: serde_json::Value },
#[schemars(title = "End")]
End,
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
#[test]
fn sub_type_roundtrip_with_underscore_separator() {
let s = ApiCallSubType::PostAgentCompletions;
let json = serde_json::to_value(&s).unwrap();
assert_eq!(json, json!("POST_/agent/completions"));
let back: ApiCallSubType = serde_json::from_value(json).unwrap();
assert_eq!(back, ApiCallSubType::PostAgentCompletions);
}
#[test]
fn auth_keys_disambiguated_by_method() {
let post = ApiCallSubType::PostAuthKeys;
let del = ApiCallSubType::DeleteAuthKeys;
let get = ApiCallSubType::GetAuthKeys;
assert_eq!(post.path(), "/auth/keys");
assert_eq!(del.path(), "/auth/keys");
assert_eq!(get.path(), "/auth/keys");
assert_eq!(post.method(), HttpMethod::Post);
assert_eq!(del.method(), HttpMethod::Delete);
assert_eq!(get.method(), HttpMethod::Get);
assert_eq!(
serde_json::to_value(&post).unwrap(),
json!("POST_/auth/keys")
);
assert_eq!(
serde_json::to_value(&del).unwrap(),
json!("DELETE_/auth/keys")
);
assert_eq!(serde_json::to_value(&get).unwrap(), json!("GET_/auth/keys"));
}
#[test]
fn envelope_serializes_as_tagged_enum() {
let begin = serde_json::to_value(ApiCallEnvelope::Begin).unwrap();
assert_eq!(begin, json!({"type": "begin"}));
let chunk = serde_json::to_value(ApiCallEnvelope::Chunk {
chunk: json!({"x": 1}),
})
.unwrap();
assert_eq!(chunk, json!({"type": "chunk", "chunk": {"x": 1}}));
let end = serde_json::to_value(ApiCallEnvelope::End).unwrap();
assert_eq!(end, json!({"type": "end"}));
let err = serde_json::to_value(ApiCallEnvelope::Error {
error: json!({"message": "boom"}),
})
.unwrap();
assert_eq!(
err,
json!({"type": "error", "error": {"message": "boom"}})
);
}
#[test]
fn method_str_matches_serde_rename_prefix() {
assert_eq!(HttpMethod::Get.as_str(), "GET");
assert_eq!(HttpMethod::Post.as_str(), "POST");
assert_eq!(HttpMethod::Delete.as_str(), "DELETE");
for variant in [
ApiCallSubType::PostAgentCompletions,
ApiCallSubType::GetAuthKeys,
ApiCallSubType::DeleteAuthKeysOpenrouter,
] {
let rename = serde_json::to_string(&variant).unwrap();
let prefix = rename.trim_matches('"').split('_').next().unwrap();
assert_eq!(prefix, variant.method().as_str());
}
}
}