When using Credify in async contexts (like web servers, AI agents, or async applications), it's crucial to use the async versions of functions to avoid runtime panics.
Using synchronous functions in async contexts can cause this error:
thread 'main' panicked at .../tokio-.../runtime/blocking/shutdown.rs:51:21:
Cannot drop a runtime in a context where blocking is not allowed.
This happens because synchronous functions create blocking HTTP clients that conflict with async runtimes like Tokio.
Always use the *_async versions of functions in async contexts:
impl Tool for LinkedInValidator {
async fn call(&self, args: Args) -> Result<String, Error> {
// This will panic in async context!
Ok(credify::ai_validate_json(&args.url))
}
}impl Tool for LinkedInValidator {
async fn call(&self, args: Args) -> Result<String, Error> {
// Use async version
Ok(credify::ai_validate_json_async(&args.url).await)
}
}Credify provides async versions for all validation functions:
| Synchronous | Asynchronous |
|---|---|
validate_for_llm() |
validate_for_llm_async() |
ai_validate() |
ai_validate_async() |
ai_validate_json() |
ai_validate_json_async() |
validate_linkedin_url() |
validate_linkedin_url_async() |
use credify::ai_validate_json_async;
use rig::tool::Tool;
use serde::{Deserialize, Serialize};
use serde_json::json;
#[derive(Deserialize)]
struct ValidateArgs {
url: String,
}
#[derive(Debug, thiserror::Error)]
#[error("Validation error: {0}")]
struct ValidationError(String);
#[derive(Deserialize, Serialize)]
struct LinkedInValidator;
impl Tool for LinkedInValidator {
const NAME: &'static str = "LinkedInValidator";
type Error = ValidationError;
type Args = ValidateArgs;
type Output = String;
async fn definition(&self, _prompt: String) -> rig::completion::ToolDefinition {
rig::completion::ToolDefinition {
name: Self::NAME.to_string(),
description: "Validates LinkedIn profile URLs".to_string(),
parameters: json!({
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "LinkedIn URL to validate"
}
},
"required": ["url"]
}),
}
}
async fn call(&self, args: Self::Args) -> Result<Self::Output, Self::Error> {
// Always use async version in async contexts
Ok(ai_validate_json_async(&args.url).await)
}
}- Always use async in async contexts: If your function is
async, use Credify's async functions - Use sync for CLI tools: For command-line tools, the sync versions are fine
- Web servers need async: FastAPI, Actix, Axum, etc. all need async versions
- AI frameworks need async: Rig, LangChain-rust, etc. need async versions
The async versions use Tokio-compatible async HTTP clients and are optimized for concurrent operations. They're just as fast as sync versions but play nicely with async runtimes.