Files
ppsspp/Tools/langtool/src/chatgpt.rs
T
Henrik RydgårdandClaude Opus 5 77e356961d langtool: Add Claude as an alternative to OpenAI for AI translation
New claude.rs talks to the Anthropic Messages API, and ai.rs picks between the
two providers. The provider is chosen with --provider, or guessed from the model
name, or from whichever of ANTHROPIC_API_KEY/OPENAI_API_KEY is set.

Also update the dependencies (and bump the clap requirement to 4.6).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0164UKoXpz9r155TRfQsoc3H
2026-08-23 16:18:07 +02:00

73 lines
1.5 KiB
Rust

use anyhow::Context;
use serde::{Deserialize, Serialize};
use std::{error::Error, time::Duration};
#[derive(Serialize)]
pub struct ChatRequest<'a> {
pub model: &'a str,
pub messages: Vec<Message<'a>>,
}
#[derive(Serialize)]
pub struct Message<'a> {
pub role: &'a str,
pub content: &'a str,
}
#[derive(Deserialize)]
pub struct ChatResponse {
pub choices: Vec<Choice>,
}
#[derive(Deserialize)]
pub struct Choice {
pub message: MessageResponse,
}
#[allow(dead_code)]
#[derive(Deserialize)]
pub struct MessageResponse {
pub content: String,
pub role: String, // unused
}
pub struct ChatGPT {
api_key: String,
model: String,
}
impl ChatGPT {
pub fn new(api_key: String, model: String) -> Self {
ChatGPT { api_key, model }
}
pub fn model(&self) -> &str {
&self.model
}
pub fn chat(&self, request: &str) -> Result<String, Box<dyn Error>> {
let client = reqwest::blocking::Client::builder()
.timeout(Duration::from_secs(300))
.build()?;
let req_body = ChatRequest {
model: &self.model,
messages: vec![Message {
role: "user",
content: request,
}],
};
let res: ChatResponse = client
.post("https://api.openai.com/v1/chat/completions")
.bearer_auth(&self.api_key)
.json(&req_body)
.send()
.context("response")?
.json()
.context("json")?;
Ok(res.choices[0].message.content.clone())
}
}