feat: more

This commit is contained in:
2026-09-26 01:44:56 -04:00
parent 83a01de915
commit cf35271341
4 changed files with 442 additions and 2 deletions

View File

@@ -1,3 +1,59 @@
fn main() {
println!("Hello, world!");
use clap::Parser;
use secrecy::SecretString;
use tracing_subscriber::{EnvFilter, fmt::format::FmtSpan};
mod openai;
#[derive(Parser, Debug)]
struct AppArgs {
#[arg(long)]
cloudflare_workers_api_key: Vec<SecretString>,
#[arg(long)]
google_ai_studio_api_key: Vec<SecretString>,
#[arg(long)]
groq_api_key: Vec<SecretString>,
#[arg(long)]
hugging_face_api_key: Vec<SecretString>,
#[arg(long)]
mistral_api_key: Vec<SecretString>,
#[arg(long)]
openrouter_api_key: Vec<SecretString>,
}
#[derive(Parser)]
struct Args {
#[arg(long = "tracing-directives", env = "RUST_LOG", default_value_t = Default::default())]
env_filter: EnvFilter,
#[command(flatten)]
app_args: AppArgs,
}
#[tokio::main]
async fn main() {
let args = Parser::parse();
let Args {
env_filter,
app_args,
} = args;
tracing_subscriber::fmt()
.pretty()
.with_span_events(FmtSpan::NEW | FmtSpan::CLOSE)
.with_env_filter(env_filter)
.init();
tracing::debug!(?app_args, "using");
let AppArgs {
cloudflare_workers_api_key,
google_ai_studio_api_key,
groq_api_key,
hugging_face_api_key,
mistral_api_key,
openrouter_api_key,
} = app_args;
}

81
src/openai.rs Normal file
View File

@@ -0,0 +1,81 @@
use std::marker::PhantomData;
use schemars::{JsonSchema, Schema, SchemaGenerator};
use serde::{Deserialize, Serialize, ser::SerializeMap as _};
use typed_builder::TypedBuilder;
use url::Url;
#[derive(Debug, TypedBuilder, Serialize, Deserialize)]
struct Message {
role: String,
content: String,
}
struct StructuredOutputJson<S>(PhantomData<S>);
impl<S> Serialize for StructuredOutputJson<S>
where
S: JsonSchema,
{
fn serialize<Serializer>(
&self,
serializer: Serializer,
) -> Result<Serializer::Ok, Serializer::Error>
where
Serializer: serde::Serializer,
{
let mut map = serializer.serialize_map(Some(3))?;
map.serialize_entry("strict", &true)?;
map.serialize_entry("name", &S::schema_name())?;
map.serialize_entry(
"schema",
&SchemaGenerator::default().into_root_schema_for::<S>(),
)?;
map.end()
}
}
#[derive(Debug)]
enum ResponseFormat<OutputFormat> {
Json { schema: PhantomData<OutputFormat> },
}
impl<OutputFormat> Serialize for ResponseFormat<OutputFormat>
where
OutputFormat: JsonSchema,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut map = serializer.serialize_map(Some(2))?;
map.serialize_entry("type", "json_schema")?;
map.serialize_entry(
"json_schema",
&StructuredOutputJson::<OutputFormat>(Default::default()),
)?;
map.end()
}
}
#[derive(Debug, TypedBuilder, Serialize)]
#[serde(bound(serialize = "ResponseFormat<OutputSchema>: Serialize"))]
struct ChatCompletionsRequest<OutputSchema> {
model: String,
messages: Vec<Message>,
response_format: ResponseFormat<OutputSchema>,
}
#[derive(Debug, Deserialize)]
struct Choice {
finish_reason: String, // I don't care
message: Message,
}
#[derive(Debug, Deserialize)]
struct ChatCompletionsResponse {
choices: Vec<Choice>,
}