#![allow(clippy::all, unused_imports, dead_code)]
use crate::{Actor, ActorBehavior, Message, Port};
use anyhow::{Error, Result};
use reflow_actor::{message::EncodableValue, ActorContext};
use reflow_actor_macro::actor;
use serde_json::{json, Value};
use std::collections::HashMap;
use std::time::Duration;
const BASE_URL: &str = "https://api-inference.huggingface.co";
const ENV_KEY: &str = "HUGGING_FACE_API_KEY";
fn apply_auth(
config: &reflow_actor::ActorConfig,
mut builder: reqwest::RequestBuilder,
) -> Result<reqwest::RequestBuilder> {
let credential = config
.get_config_or_env(ENV_KEY)
.ok_or_else(|| anyhow::anyhow!("Missing env var: {}", ENV_KEY))?;
builder = builder.header("Authorization", format!("Bearer {}", credential));
Ok(builder)
}
#[actor(
HuggingFaceGenerateTextActor,
inports::<100>(model_id, inputs),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_generate_text(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/models/{model_id}".to_string();
if let Some(val) = inputs.get("model_id") {
endpoint = endpoint.replace("{{model_id}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("inputs") {
body.insert("inputs".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("POST /models/{{model_id}} failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceClassifyTextActor,
inports::<100>(model_id, inputs),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_classify_text(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/models/{model_id}".to_string();
if let Some(val) = inputs.get("model_id") {
endpoint = endpoint.replace("{{model_id}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("inputs") {
body.insert("inputs".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("POST /models/{{model_id}} failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceReadUsersActor,
inports::<100>(namespace),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_read_users(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/avatars/{namespace}".to_string();
if let Some(val) = inputs.get("namespace") {
endpoint = endpoint.replace("{{namespace}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /api/avatars/{{namespace}} failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceCreateDiscussionsActor,
inports::<100>(namespace, slug, comment),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_create_discussions(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/blog/{namespace}/{slug}/comment".to_string();
if let Some(val) = inputs.get("namespace") {
endpoint = endpoint.replace("{{namespace}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("slug") {
endpoint = endpoint.replace("{{slug}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("comment") {
body.insert("comment".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!(
"POST /api/blog/{{namespace}}/{{slug}}/comment failed: {}",
e
)
.into(),
),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceSearchCollectionsActor,
inports::<100>(item, owner, q, sort, cursor, expand, limit),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_search_collections(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/api/collections".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("item") {
query_pairs.push(("item", super::message_to_str(val)));
}
if let Some(val) = inputs.get("owner") {
query_pairs.push(("owner", super::message_to_str(val)));
}
if let Some(val) = inputs.get("q") {
query_pairs.push(("q", super::message_to_str(val)));
}
if let Some(val) = inputs.get("sort") {
query_pairs.push(("sort", super::message_to_str(val)));
}
if let Some(val) = inputs.get("cursor") {
query_pairs.push(("cursor", super::message_to_str(val)));
}
if let Some(val) = inputs.get("expand") {
query_pairs.push(("expand", super::message_to_str(val)));
}
if let Some(val) = inputs.get("limit") {
query_pairs.push(("limit", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /api/collections failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceCreateCollectionsActor,
inports::<100>(title, namespace, item, private, description),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_create_collections(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/api/collections".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("title") {
body.insert("title".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("namespace") {
body.insert("namespace".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("item") {
body.insert("item".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("private") {
body.insert("private".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("description") {
body.insert("description".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("POST /api/collections failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceUpdateCollectionsActor,
inports::<100>(namespace, slug, theme, title, position, gating, private, description),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_update_collections(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/collections/{namespace}/{slug}".to_string();
if let Some(val) = inputs.get("namespace") {
endpoint = endpoint.replace("{{namespace}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("slug") {
endpoint = endpoint.replace("{{slug}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.patch(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("theme") {
body.insert("theme".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("title") {
body.insert("title".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("position") {
body.insert("position".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("gating") {
body.insert("gating".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("private") {
body.insert("private".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("description") {
body.insert("description".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!(
"PATCH /api/collections/{{namespace}}/{{slug}} failed: {}",
e
)
.into(),
),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceReadCollectionsActor,
inports::<100>(namespace, slug),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_read_collections(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/collections/{namespace}/{slug}".to_string();
if let Some(val) = inputs.get("namespace") {
endpoint = endpoint.replace("{{namespace}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("slug") {
endpoint = endpoint.replace("{{slug}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!("GET /api/collections/{{namespace}}/{{slug}} failed: {}", e).into(),
),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceDeleteCollectionsActor,
inports::<100>(namespace, slug),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_delete_collections(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/collections/{namespace}/{slug}".to_string();
if let Some(val) = inputs.get("namespace") {
endpoint = endpoint.replace("{{namespace}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("slug") {
endpoint = endpoint.replace("{{slug}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.delete(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!(
"DELETE /api/collections/{{namespace}}/{{slug}} failed: {}",
e
)
.into(),
),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceListPapersActor,
inports::<100>(p, limit, date, week, month, submitter, sort),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_list_papers(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/api/daily_papers".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("p") {
query_pairs.push(("p", super::message_to_str(val)));
}
if let Some(val) = inputs.get("limit") {
query_pairs.push(("limit", super::message_to_str(val)));
}
if let Some(val) = inputs.get("date") {
query_pairs.push(("date", super::message_to_str(val)));
}
if let Some(val) = inputs.get("week") {
query_pairs.push(("week", super::message_to_str(val)));
}
if let Some(val) = inputs.get("month") {
query_pairs.push(("month", super::message_to_str(val)));
}
if let Some(val) = inputs.get("submitter") {
query_pairs.push(("submitter", super::message_to_str(val)));
}
if let Some(val) = inputs.get("sort") {
query_pairs.push(("sort", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /api/daily_papers failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceListDatasetsActor,
inports::<100>(type_),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_list_datasets(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/api/datasets-tags-by-type".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("type_") {
query_pairs.push(("type", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /api/datasets-tags-by-type failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceReadDatasetsActor,
inports::<100>(namespace, repo, task_id),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_read_datasets(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/datasets/{namespace}/{repo}/leaderboard".to_string();
if let Some(val) = inputs.get("namespace") {
endpoint = endpoint.replace("{{namespace}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("repo") {
endpoint = endpoint.replace("{{repo}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("task_id") {
query_pairs.push(("task_id", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!(
"GET /api/datasets/{{namespace}}/{{repo}}/leaderboard failed: {}",
e
)
.into(),
),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceCreateDatasetsActor,
inports::<100>(namespace, repo, deletions),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_create_datasets(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/datasets/{namespace}/{repo}/lfs-files/batch".to_string();
if let Some(val) = inputs.get("namespace") {
endpoint = endpoint.replace("{{namespace}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("repo") {
endpoint = endpoint.replace("{{repo}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("deletions") {
body.insert("deletions".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!(
"POST /api/datasets/{{namespace}}/{{repo}}/lfs-files/batch failed: {}",
e
)
.into(),
),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceDeleteDatasetsActor,
inports::<100>(namespace, repo, sha, rewriteHistory),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_delete_datasets(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/datasets/{namespace}/{repo}/lfs-files/{sha}".to_string();
if let Some(val) = inputs.get("namespace") {
endpoint = endpoint.replace("{{namespace}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("repo") {
endpoint = endpoint.replace("{{repo}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("sha") {
endpoint = endpoint.replace("{{sha}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.delete(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("rewriteHistory") {
query_pairs.push(("rewriteHistory", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!(
"DELETE /api/datasets/{{namespace}}/{{repo}}/lfs-files/{{sha}} failed: {}",
e
)
.into(),
),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceCreateNotificationsActor,
inports::<100>(p, readStatus, repoType, repoName, postAuthor, paperId, articleId, mention, lastUpdate, applyToAll, read, discussionIds),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_create_notifications(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/api/discussions/mark-as-read".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("p") {
query_pairs.push(("p", super::message_to_str(val)));
}
if let Some(val) = inputs.get("readStatus") {
query_pairs.push(("readStatus", super::message_to_str(val)));
}
if let Some(val) = inputs.get("repoType") {
query_pairs.push(("repoType", super::message_to_str(val)));
}
if let Some(val) = inputs.get("repoName") {
query_pairs.push(("repoName", super::message_to_str(val)));
}
if let Some(val) = inputs.get("postAuthor") {
query_pairs.push(("postAuthor", super::message_to_str(val)));
}
if let Some(val) = inputs.get("paperId") {
query_pairs.push(("paperId", super::message_to_str(val)));
}
if let Some(val) = inputs.get("articleId") {
query_pairs.push(("articleId", super::message_to_str(val)));
}
if let Some(val) = inputs.get("mention") {
query_pairs.push(("mention", super::message_to_str(val)));
}
if let Some(val) = inputs.get("lastUpdate") {
query_pairs.push(("lastUpdate", super::message_to_str(val)));
}
if let Some(val) = inputs.get("applyToAll") {
query_pairs.push(("applyToAll", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("read") {
body.insert("read".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("discussionIds") {
body.insert("discussionIds".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("POST /api/discussions/mark-as-read failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceListDocsActor,
inports::<100>(trigger),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_list_docs(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/api/docs".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /api/docs failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceSearchDocsActor,
inports::<100>(q, product, limit),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_search_docs(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/api/docs/search".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("q") {
query_pairs.push(("q", super::message_to_str(val)));
}
if let Some(val) = inputs.get("product") {
query_pairs.push(("product", super::message_to_str(val)));
}
if let Some(val) = inputs.get("limit") {
query_pairs.push(("limit", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /api/docs/search failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceCreateInferenceEndpointsActor,
inports::<100>(namespace, perms, own, is_creator, creator_id, incur_cost, resource_group_id, repo_id),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_create_inference_endpoints(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/inference-endpoints/{namespace}/auth-check/{perms}".to_string();
if let Some(val) = inputs.get("namespace") {
endpoint = endpoint.replace("{{namespace}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("perms") {
endpoint = endpoint.replace("{{perms}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("own") {
query_pairs.push(("own", super::message_to_str(val)));
}
if let Some(val) = inputs.get("is_creator") {
query_pairs.push(("is_creator", super::message_to_str(val)));
}
if let Some(val) = inputs.get("creator_id") {
query_pairs.push(("creator_id", super::message_to_str(val)));
}
if let Some(val) = inputs.get("incur_cost") {
query_pairs.push(("incur_cost", super::message_to_str(val)));
}
if let Some(val) = inputs.get("resource_group_id") {
query_pairs.push(("resource_group_id", super::message_to_str(val)));
}
if let Some(val) = inputs.get("repo_id") {
query_pairs.push(("repo_id", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert("error".to_string(), Message::Error(format!("POST /api/inference-endpoints/{{namespace}}/auth-check/{{perms}} failed: {}", e).into()));
}
}
Ok(output)
}
#[actor(
HuggingFaceListJobsActor,
inports::<100>(trigger),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_list_jobs(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/api/jobs/hardware".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /api/jobs/hardware failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceReadJobsActor,
inports::<100>(namespace, label),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_read_jobs(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/jobs/{namespace}".to_string();
if let Some(val) = inputs.get("namespace") {
endpoint = endpoint.replace("{{namespace}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("label") {
query_pairs.push(("label", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /api/jobs/{{namespace}} failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceCreateJobsActor,
inports::<100>(namespace, arguments, flavor, command, attempts, labels, dockerImage, environment, arch, spaceId, timeoutSeconds, secrets),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_create_jobs(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/jobs/{namespace}".to_string();
if let Some(val) = inputs.get("namespace") {
endpoint = endpoint.replace("{{namespace}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("arguments") {
body.insert("arguments".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("flavor") {
body.insert("flavor".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("command") {
body.insert("command".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("attempts") {
body.insert("attempts".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("labels") {
body.insert("labels".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("dockerImage") {
body.insert("dockerImage".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("environment") {
body.insert("environment".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("arch") {
body.insert("arch".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("spaceId") {
body.insert("spaceId".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("timeoutSeconds") {
body.insert("timeoutSeconds".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("secrets") {
body.insert("secrets".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("POST /api/jobs/{{namespace}} failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceCancelJobsActor,
inports::<100>(namespace, jobId),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_cancel_jobs(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/jobs/{namespace}/{jobId}/cancel".to_string();
if let Some(val) = inputs.get("namespace") {
endpoint = endpoint.replace("{{namespace}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("jobId") {
endpoint = endpoint.replace("{{jobId}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!(
"POST /api/jobs/{{namespace}}/{{jobId}}/cancel failed: {}",
e
)
.into(),
),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceListModelsActor,
inports::<100>(type_),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_list_models(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/api/models-tags-by-type".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("type_") {
query_pairs.push(("type", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /api/models-tags-by-type failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceReadModelsActor,
inports::<100>(namespace, repo, cursor, limit, xet),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_read_models(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/models/{namespace}/{repo}/lfs-files".to_string();
if let Some(val) = inputs.get("namespace") {
endpoint = endpoint.replace("{{namespace}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("repo") {
endpoint = endpoint.replace("{{repo}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("cursor") {
query_pairs.push(("cursor", super::message_to_str(val)));
}
if let Some(val) = inputs.get("limit") {
query_pairs.push(("limit", super::message_to_str(val)));
}
if let Some(val) = inputs.get("xet") {
query_pairs.push(("xet", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!(
"GET /api/models/{{namespace}}/{{repo}}/lfs-files failed: {}",
e
)
.into(),
),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceCreateModelsActor,
inports::<100>(namespace, repo, deletions),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_create_models(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/models/{namespace}/{repo}/lfs-files/batch".to_string();
if let Some(val) = inputs.get("namespace") {
endpoint = endpoint.replace("{{namespace}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("repo") {
endpoint = endpoint.replace("{{repo}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("deletions") {
body.insert("deletions".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!(
"POST /api/models/{{namespace}}/{{repo}}/lfs-files/batch failed: {}",
e
)
.into(),
),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceDeleteModelsActor,
inports::<100>(namespace, repo, sha, rewriteHistory),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_delete_models(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/models/{namespace}/{repo}/lfs-files/{sha}".to_string();
if let Some(val) = inputs.get("namespace") {
endpoint = endpoint.replace("{{namespace}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("repo") {
endpoint = endpoint.replace("{{repo}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("sha") {
endpoint = endpoint.replace("{{sha}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.delete(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("rewriteHistory") {
query_pairs.push(("rewriteHistory", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!(
"DELETE /api/models/{{namespace}}/{{repo}}/lfs-files/{{sha}} failed: {}",
e
)
.into(),
),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceListNotificationsActor,
inports::<100>(p, readStatus, repoType, repoName, postAuthor, paperId, articleId, mention, lastUpdate),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_list_notifications(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/api/notifications".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("p") {
query_pairs.push(("p", super::message_to_str(val)));
}
if let Some(val) = inputs.get("readStatus") {
query_pairs.push(("readStatus", super::message_to_str(val)));
}
if let Some(val) = inputs.get("repoType") {
query_pairs.push(("repoType", super::message_to_str(val)));
}
if let Some(val) = inputs.get("repoName") {
query_pairs.push(("repoName", super::message_to_str(val)));
}
if let Some(val) = inputs.get("postAuthor") {
query_pairs.push(("postAuthor", super::message_to_str(val)));
}
if let Some(val) = inputs.get("paperId") {
query_pairs.push(("paperId", super::message_to_str(val)));
}
if let Some(val) = inputs.get("articleId") {
query_pairs.push(("articleId", super::message_to_str(val)));
}
if let Some(val) = inputs.get("mention") {
query_pairs.push(("mention", super::message_to_str(val)));
}
if let Some(val) = inputs.get("lastUpdate") {
query_pairs.push(("lastUpdate", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /api/notifications failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceDeleteNotificationsActor,
inports::<100>(p, readStatus, repoType, repoName, postAuthor, paperId, articleId, mention, lastUpdate, applyToAll, discussionIds),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_delete_notifications(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/api/notifications".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.delete(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("p") {
query_pairs.push(("p", super::message_to_str(val)));
}
if let Some(val) = inputs.get("readStatus") {
query_pairs.push(("readStatus", super::message_to_str(val)));
}
if let Some(val) = inputs.get("repoType") {
query_pairs.push(("repoType", super::message_to_str(val)));
}
if let Some(val) = inputs.get("repoName") {
query_pairs.push(("repoName", super::message_to_str(val)));
}
if let Some(val) = inputs.get("postAuthor") {
query_pairs.push(("postAuthor", super::message_to_str(val)));
}
if let Some(val) = inputs.get("paperId") {
query_pairs.push(("paperId", super::message_to_str(val)));
}
if let Some(val) = inputs.get("articleId") {
query_pairs.push(("articleId", super::message_to_str(val)));
}
if let Some(val) = inputs.get("mention") {
query_pairs.push(("mention", super::message_to_str(val)));
}
if let Some(val) = inputs.get("lastUpdate") {
query_pairs.push(("lastUpdate", super::message_to_str(val)));
}
if let Some(val) = inputs.get("applyToAll") {
query_pairs.push(("applyToAll", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("DELETE /api/notifications failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceExportOrgsActor,
inports::<100>(name, q),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_export_orgs(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/organizations/{name}/audit-log/export".to_string();
if let Some(val) = inputs.get("name") {
endpoint = endpoint.replace("{{name}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("q") {
query_pairs.push(("q", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!(
"GET /api/organizations/{{name}}/audit-log/export failed: {}",
e
)
.into(),
),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceReadOrgsActor,
inports::<100>(name, redirect),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_read_orgs(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/organizations/{name}/avatar".to_string();
if let Some(val) = inputs.get("name") {
endpoint = endpoint.replace("{{name}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("redirect") {
query_pairs.push(("redirect", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!("GET /api/organizations/{{name}}/avatar failed: {}", e).into(),
),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceUpdateOrgsActor,
inports::<100>(name, username, resourceGroups, role),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_update_orgs(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/organizations/{name}/members/{username}/role".to_string();
if let Some(val) = inputs.get("name") {
endpoint = endpoint.replace("{{name}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("username") {
endpoint = endpoint.replace("{{username}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.put(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("resourceGroups") {
body.insert("resourceGroups".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("role") {
body.insert("role".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!(
"PUT /api/organizations/{{name}}/members/{{username}}/role failed: {}",
e
)
.into(),
),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceReadResourceGroupsActor,
inports::<100>(name),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_read_resource_groups(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/organizations/{name}/resource-groups".to_string();
if let Some(val) = inputs.get("name") {
endpoint = endpoint.replace("{{name}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!(
"GET /api/organizations/{{name}}/resource-groups failed: {}",
e
)
.into(),
),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceCreateResourceGroupsActor,
inports::<100>(name, autoJoin, description, repos, users),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_create_resource_groups(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/organizations/{name}/resource-groups".to_string();
if let Some(val) = inputs.get("name") {
endpoint = endpoint.replace("{{name}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("autoJoin") {
body.insert("autoJoin".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("name") {
body.insert("name".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("description") {
body.insert("description".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("repos") {
body.insert("repos".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("users") {
body.insert("users".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!(
"POST /api/organizations/{{name}}/resource-groups failed: {}",
e
)
.into(),
),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceReadScimActor,
inports::<100>(name, startIndex, count, filter, excludedAttributes),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_read_scim(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/organizations/{name}/scim-provisioning/v2/Groups".to_string();
if let Some(val) = inputs.get("name") {
endpoint = endpoint.replace("{{name}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("startIndex") {
query_pairs.push(("startIndex", super::message_to_str(val)));
}
if let Some(val) = inputs.get("count") {
query_pairs.push(("count", super::message_to_str(val)));
}
if let Some(val) = inputs.get("filter") {
query_pairs.push(("filter", super::message_to_str(val)));
}
if let Some(val) = inputs.get("excludedAttributes") {
query_pairs.push(("excludedAttributes", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!(
"GET /api/organizations/{{name}}/scim-provisioning/v2/Groups failed: {}",
e
)
.into(),
),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceCreateScimActor,
inports::<100>(name, displayName, externalId, members),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_create_scim(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/organizations/{name}/scim-provisioning/v2/Groups".to_string();
if let Some(val) = inputs.get("name") {
endpoint = endpoint.replace("{{name}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("displayName") {
body.insert("displayName".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("externalId") {
body.insert("externalId".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("members") {
body.insert("members".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!(
"POST /api/organizations/{{name}}/scim-provisioning/v2/Groups failed: {}",
e
)
.into(),
),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceUpdateScimActor,
inports::<100>(name, groupId, schemas, displayName, members, externalId),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_update_scim(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint =
"/api/organizations/{name}/scim-provisioning/v2/Groups/{groupId}".to_string();
if let Some(val) = inputs.get("name") {
endpoint = endpoint.replace("{{name}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("groupId") {
endpoint = endpoint.replace("{{groupId}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.put(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("schemas") {
body.insert("schemas".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("displayName") {
body.insert("displayName".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("members") {
body.insert("members".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("externalId") {
body.insert("externalId".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert("error".to_string(), Message::Error(format!("PUT /api/organizations/{{name}}/scim-provisioning/v2/Groups/{{groupId}} failed: {}", e).into()));
}
}
Ok(output)
}
#[actor(
HuggingFaceDeleteScimActor,
inports::<100>(name, groupId),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_delete_scim(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint =
"/api/organizations/{name}/scim-provisioning/v2/Groups/{groupId}".to_string();
if let Some(val) = inputs.get("name") {
endpoint = endpoint.replace("{{name}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("groupId") {
endpoint = endpoint.replace("{{groupId}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.delete(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert("error".to_string(), Message::Error(format!("DELETE /api/organizations/{{name}}/scim-provisioning/v2/Groups/{{groupId}} failed: {}", e).into()));
}
}
Ok(output)
}
#[actor(
HuggingFaceCreatePapersActor,
inports::<100>(arxivId),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_create_papers(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/api/papers/index".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("arxivId") {
body.insert("arxivId".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("POST /api/papers/index failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceSearchPapersActor,
inports::<100>(q, limit),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_search_papers(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/api/papers/search".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("q") {
query_pairs.push(("q", super::message_to_str(val)));
}
if let Some(val) = inputs.get("limit") {
query_pairs.push(("limit", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /api/papers/search failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceDeleteDiscussionsActor,
inports::<100>(username, postSlug),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_delete_discussions(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/posts/{username}/{postSlug}".to_string();
if let Some(val) = inputs.get("username") {
endpoint = endpoint.replace("{{username}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("postSlug") {
endpoint = endpoint.replace("{{postSlug}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.delete(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!("DELETE /api/posts/{{username}}/{{postSlug}} failed: {}", e).into(),
),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceSearchRepoSearchActor,
inports::<100>(q, limit, lang, library, type_, orgsFilter, reposFilter, pipelines, exclude, namespace, includeInvitees, repoName, repoType, discussionId, discussionCollectionName, spacesTags),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_search_repo_search(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/api/quicksearch".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("q") {
query_pairs.push(("q", super::message_to_str(val)));
}
if let Some(val) = inputs.get("limit") {
query_pairs.push(("limit", super::message_to_str(val)));
}
if let Some(val) = inputs.get("lang") {
query_pairs.push(("lang", super::message_to_str(val)));
}
if let Some(val) = inputs.get("library") {
query_pairs.push(("library", super::message_to_str(val)));
}
if let Some(val) = inputs.get("type_") {
query_pairs.push(("type", super::message_to_str(val)));
}
if let Some(val) = inputs.get("orgsFilter") {
query_pairs.push(("orgsFilter", super::message_to_str(val)));
}
if let Some(val) = inputs.get("reposFilter") {
query_pairs.push(("reposFilter", super::message_to_str(val)));
}
if let Some(val) = inputs.get("pipelines") {
query_pairs.push(("pipelines", super::message_to_str(val)));
}
if let Some(val) = inputs.get("exclude") {
query_pairs.push(("exclude", super::message_to_str(val)));
}
if let Some(val) = inputs.get("namespace") {
query_pairs.push(("namespace", super::message_to_str(val)));
}
if let Some(val) = inputs.get("includeInvitees") {
query_pairs.push(("includeInvitees", super::message_to_str(val)));
}
if let Some(val) = inputs.get("repoName") {
query_pairs.push(("repoName", super::message_to_str(val)));
}
if let Some(val) = inputs.get("repoType") {
query_pairs.push(("repoType", super::message_to_str(val)));
}
if let Some(val) = inputs.get("discussionId") {
query_pairs.push(("discussionId", super::message_to_str(val)));
}
if let Some(val) = inputs.get("discussionCollectionName") {
query_pairs.push(("discussionCollectionName", super::message_to_str(val)));
}
if let Some(val) = inputs.get("spacesTags") {
query_pairs.push(("spacesTags", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /api/quicksearch failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceCreateRepoSearchActor,
inports::<100>(q, limit, lang, library, type_, orgsFilter, reposFilter, pipelines, exclude, namespace, includeInvitees, repoName, repoType, discussionId, discussionCollectionName, spacesTags),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_create_repo_search(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/api/quicksearch".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("q") {
query_pairs.push(("q", super::message_to_str(val)));
}
if let Some(val) = inputs.get("limit") {
query_pairs.push(("limit", super::message_to_str(val)));
}
if let Some(val) = inputs.get("lang") {
query_pairs.push(("lang", super::message_to_str(val)));
}
if let Some(val) = inputs.get("library") {
query_pairs.push(("library", super::message_to_str(val)));
}
if let Some(val) = inputs.get("type_") {
query_pairs.push(("type", super::message_to_str(val)));
}
if let Some(val) = inputs.get("orgsFilter") {
query_pairs.push(("orgsFilter", super::message_to_str(val)));
}
if let Some(val) = inputs.get("reposFilter") {
query_pairs.push(("reposFilter", super::message_to_str(val)));
}
if let Some(val) = inputs.get("pipelines") {
query_pairs.push(("pipelines", super::message_to_str(val)));
}
if let Some(val) = inputs.get("exclude") {
query_pairs.push(("exclude", super::message_to_str(val)));
}
if let Some(val) = inputs.get("namespace") {
query_pairs.push(("namespace", super::message_to_str(val)));
}
if let Some(val) = inputs.get("includeInvitees") {
query_pairs.push(("includeInvitees", super::message_to_str(val)));
}
if let Some(val) = inputs.get("repoName") {
query_pairs.push(("repoName", super::message_to_str(val)));
}
if let Some(val) = inputs.get("repoType") {
query_pairs.push(("repoType", super::message_to_str(val)));
}
if let Some(val) = inputs.get("discussionId") {
query_pairs.push(("discussionId", super::message_to_str(val)));
}
if let Some(val) = inputs.get("discussionCollectionName") {
query_pairs.push(("discussionCollectionName", super::message_to_str(val)));
}
if let Some(val) = inputs.get("spacesTags") {
query_pairs.push(("spacesTags", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("limit") {
body.insert("limit".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("pipelines") {
body.insert("pipelines".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("namespace") {
body.insert("namespace".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("spacesTags") {
body.insert("spacesTags".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("discussionCollectionName") {
body.insert("discussionCollectionName".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("includeInvitees") {
body.insert("includeInvitees".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("exclude") {
body.insert("exclude".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("library") {
body.insert("library".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("reposFilter") {
body.insert("reposFilter".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("type_") {
body.insert("type".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("lang") {
body.insert("lang".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("repoName") {
body.insert("repoName".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("repoType") {
body.insert("repoType".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("discussionId") {
body.insert("discussionId".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("q") {
body.insert("q".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("orgsFilter") {
body.insert("orgsFilter".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("POST /api/quicksearch failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceCreateReposActor,
inports::<100>(trigger),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_create_repos(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/api/repos/create".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("POST /api/repos/create failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceMoveReposActor,
inports::<100>(type_, fromRepo, toRepo),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_move_repos(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/api/repos/move".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("type_") {
body.insert("type".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("fromRepo") {
body.insert("fromRepo".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("toRepo") {
body.insert("toRepo".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("POST /api/repos/move failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceDeleteJobsActor,
inports::<100>(namespace, jobId),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_delete_jobs(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/scheduled-jobs/{namespace}/{jobId}".to_string();
if let Some(val) = inputs.get("namespace") {
endpoint = endpoint.replace("{{namespace}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("jobId") {
endpoint = endpoint.replace("{{jobId}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.delete(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!(
"DELETE /api/scheduled-jobs/{{namespace}}/{{jobId}} failed: {}",
e
)
.into(),
),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceResumeJobsActor,
inports::<100>(namespace, jobId),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_resume_jobs(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/scheduled-jobs/{namespace}/{jobId}/resume".to_string();
if let Some(val) = inputs.get("namespace") {
endpoint = endpoint.replace("{{namespace}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("jobId") {
endpoint = endpoint.replace("{{jobId}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!(
"POST /api/scheduled-jobs/{{namespace}}/{{jobId}}/resume failed: {}",
e
)
.into(),
),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceListUsersActor,
inports::<100>(periodId),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_list_users(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/api/settings/billing/usage".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("periodId") {
query_pairs.push(("periodId", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /api/settings/billing/usage failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceUpdateNotificationsActor,
inports::<100>(prepaidAmount, notifications),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_update_notifications(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/api/settings/notifications".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.patch(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("prepaidAmount") {
body.insert("prepaidAmount".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("notifications") {
body.insert("notifications".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("PATCH /api/settings/notifications failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceWatchNotificationsActor,
inports::<100>(add, delete),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_watch_notifications(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/api/settings/watch".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.patch(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("add") {
body.insert("add".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("delete") {
body.insert("delete".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("PATCH /api/settings/watch failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceListWebhooksActor,
inports::<100>(trigger),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_list_webhooks(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/api/settings/webhooks".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /api/settings/webhooks failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceCreateWebhooksActor,
inports::<100>(jobSourceId, url, secret, watched, domains, job),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_create_webhooks(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/api/settings/webhooks".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("jobSourceId") {
body.insert("jobSourceId".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("url") {
body.insert("url".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("secret") {
body.insert("secret".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("watched") {
body.insert("watched".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("domains") {
body.insert("domains".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("job") {
body.insert("job".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("POST /api/settings/webhooks failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceReadWebhooksActor,
inports::<100>(webhookId),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_read_webhooks(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/settings/webhooks/{webhookId}".to_string();
if let Some(val) = inputs.get("webhookId") {
endpoint = endpoint.replace("{{webhookId}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!("GET /api/settings/webhooks/{{webhookId}} failed: {}", e).into(),
),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceDeleteWebhooksActor,
inports::<100>(webhookId),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_delete_webhooks(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/settings/webhooks/{webhookId}".to_string();
if let Some(val) = inputs.get("webhookId") {
endpoint = endpoint.replace("{{webhookId}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.delete(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!("DELETE /api/settings/webhooks/{{webhookId}} failed: {}", e).into(),
),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceListSpacesActor,
inports::<100>(trigger),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_list_spaces(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/api/spaces/hardware".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /api/spaces/hardware failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceReadSpacesActor,
inports::<100>(namespace, repo, session_uuid),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_read_spaces(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/spaces/{namespace}/{repo}/events".to_string();
if let Some(val) = inputs.get("namespace") {
endpoint = endpoint.replace("{{namespace}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("repo") {
endpoint = endpoint.replace("{{repo}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("session_uuid") {
query_pairs.push(("session_uuid", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!(
"GET /api/spaces/{{namespace}}/{{repo}}/events failed: {}",
e
)
.into(),
),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceCreateSpacesActor,
inports::<100>(namespace, repo, deletions),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_create_spaces(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/spaces/{namespace}/{repo}/lfs-files/batch".to_string();
if let Some(val) = inputs.get("namespace") {
endpoint = endpoint.replace("{{namespace}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("repo") {
endpoint = endpoint.replace("{{repo}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("deletions") {
body.insert("deletions".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!(
"POST /api/spaces/{{namespace}}/{{repo}}/lfs-files/batch failed: {}",
e
)
.into(),
),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceDeleteSpacesActor,
inports::<100>(namespace, repo, sha, rewriteHistory),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_delete_spaces(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/spaces/{namespace}/{repo}/lfs-files/{sha}".to_string();
if let Some(val) = inputs.get("namespace") {
endpoint = endpoint.replace("{{namespace}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("repo") {
endpoint = endpoint.replace("{{repo}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("sha") {
endpoint = endpoint.replace("{{sha}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.delete(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("rewriteHistory") {
query_pairs.push(("rewriteHistory", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!(
"DELETE /api/spaces/{{namespace}}/{{repo}}/lfs-files/{{sha}} failed: {}",
e
)
.into(),
),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceListAuthActor,
inports::<100>(trigger),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_list_auth(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/api/whoami-v2".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /api/whoami-v2 failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceReadDiscussionsActor,
inports::<100>(repoType, namespace, repo, p, type_, status, author, search, sort),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_read_discussions(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/{repoType}/{namespace}/{repo}/discussions".to_string();
if let Some(val) = inputs.get("repoType") {
endpoint = endpoint.replace("{{repoType}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("namespace") {
endpoint = endpoint.replace("{{namespace}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("repo") {
endpoint = endpoint.replace("{{repo}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("p") {
query_pairs.push(("p", super::message_to_str(val)));
}
if let Some(val) = inputs.get("type_") {
query_pairs.push(("type", super::message_to_str(val)));
}
if let Some(val) = inputs.get("status") {
query_pairs.push(("status", super::message_to_str(val)));
}
if let Some(val) = inputs.get("author") {
query_pairs.push(("author", super::message_to_str(val)));
}
if let Some(val) = inputs.get("search") {
query_pairs.push(("search", super::message_to_str(val)));
}
if let Some(val) = inputs.get("sort") {
query_pairs.push(("sort", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!(
"GET /api/{{repoType}}/{{namespace}}/{{repo}}/discussions failed: {}",
e
)
.into(),
),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceMergeDiscussionsActor,
inports::<100>(repoType, namespace, repo, num, comment),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_merge_discussions(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/{repoType}/{namespace}/{repo}/discussions/{num}/merge".to_string();
if let Some(val) = inputs.get("repoType") {
endpoint = endpoint.replace("{{repoType}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("namespace") {
endpoint = endpoint.replace("{{namespace}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("repo") {
endpoint = endpoint.replace("{{repo}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("num") {
endpoint = endpoint.replace("{{num}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("comment") {
body.insert("comment".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert("error".to_string(), Message::Error(format!("POST /api/{{repoType}}/{{namespace}}/{{repo}}/discussions/{{num}}/merge failed: {}", e).into()));
}
}
Ok(output)
}
#[actor(
HuggingFaceUpdateModelsActor,
inports::<100>(repoType, namespace, repo, discussionsDisabled, gatedNotificationsMode, private, gated, gatedNotificationsEmail, discussionsSorting),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_update_models(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/{repoType}/{namespace}/{repo}/settings".to_string();
if let Some(val) = inputs.get("repoType") {
endpoint = endpoint.replace("{{repoType}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("namespace") {
endpoint = endpoint.replace("{{namespace}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("repo") {
endpoint = endpoint.replace("{{repo}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.put(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("discussionsDisabled") {
body.insert("discussionsDisabled".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("gatedNotificationsMode") {
body.insert("gatedNotificationsMode".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("private") {
body.insert("private".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("gated") {
body.insert("gated".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("gatedNotificationsEmail") {
body.insert("gatedNotificationsEmail".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("discussionsSorting") {
body.insert("discussionsSorting".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!(
"PUT /api/{{repoType}}/{{namespace}}/{{repo}}/settings failed: {}",
e
)
.into(),
),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceEmbedSqlConsoleActor,
inports::<100>(repoType, namespace, repo, views, private, sql, title),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_embed_sql_console(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/{repoType}/{namespace}/{repo}/sql-console/embed".to_string();
if let Some(val) = inputs.get("repoType") {
endpoint = endpoint.replace("{{repoType}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("namespace") {
endpoint = endpoint.replace("{{namespace}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("repo") {
endpoint = endpoint.replace("{{repo}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("views") {
body.insert("views".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("private") {
body.insert("private".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("sql") {
body.insert("sql".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("title") {
body.insert("title".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert("error".to_string(), Message::Error(format!("POST /api/{{repoType}}/{{namespace}}/{{repo}}/sql-console/embed failed: {}", e).into()));
}
}
Ok(output)
}
#[actor(
HuggingFaceCancelModelsActor,
inports::<100>(repoType, namespace, repo),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_cancel_models(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/{repoType}/{namespace}/{repo}/user-access-request/cancel".to_string();
if let Some(val) = inputs.get("repoType") {
endpoint = endpoint.replace("{{repoType}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("namespace") {
endpoint = endpoint.replace("{{namespace}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("repo") {
endpoint = endpoint.replace("{{repo}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert("error".to_string(), Message::Error(format!("POST /api/{{repoType}}/{{namespace}}/{{repo}}/user-access-request/cancel failed: {}", e).into()));
}
}
Ok(output)
}
#[actor(
HuggingFaceReadBucketsActor,
inports::<100>(repoType, namespace, repo),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_read_buckets(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/api/{repoType}/{namespace}/{repo}/xet-read-token".to_string();
if let Some(val) = inputs.get("repoType") {
endpoint = endpoint.replace("{{repoType}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("namespace") {
endpoint = endpoint.replace("{{namespace}}", &super::message_to_str(val));
}
if let Some(val) = inputs.get("repo") {
endpoint = endpoint.replace("{{repo}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!(
"GET /api/{{repoType}}/{{namespace}}/{{repo}}/xet-read-token failed: {}",
e
)
.into(),
),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceCreateOauthActor,
inports::<100>(client_id, scope),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_create_oauth(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/oauth/device".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("client_id") {
body.insert("client_id".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("scope") {
body.insert("scope".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("POST /oauth/device failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
HuggingFaceListOauthActor,
inports::<100>(trigger),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn hugging_face_list_oauth(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/oauth/userinfo".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /oauth/userinfo failed: {}", e).into()),
);
}
}
Ok(output)
}