llm-model-configの実装
This commit is contained in:
@@ -20,9 +20,35 @@ mod recorder;
|
||||
mod scenarios;
|
||||
|
||||
use clap::{Parser, ValueEnum};
|
||||
use llm_worker::llm_client::providers::anthropic::AnthropicClient;
|
||||
use llm_worker::llm_client::providers::gemini::GeminiClient;
|
||||
use llm_worker::llm_client::providers::openai::OpenAIClient;
|
||||
use llm_worker::llm_client::capability::{
|
||||
CacheStrategy, ModelCapability, StructuredOutput, ToolCallingSupport,
|
||||
};
|
||||
use llm_worker::llm_client::scheme::{
|
||||
Scheme, anthropic::AnthropicScheme, gemini::GeminiScheme, openai_chat::OpenAIScheme,
|
||||
};
|
||||
use llm_worker::llm_client::transport::{HttpTransport, ResolvedAuth};
|
||||
|
||||
/// 既定の capability: fixture 記録には cache_control を付けない
|
||||
/// (既知モデルの静的テーブルを経由すると scheme 毎に自動設定される)。
|
||||
fn fallback_capability() -> ModelCapability {
|
||||
ModelCapability {
|
||||
tool_calling: ToolCallingSupport::Parallel,
|
||||
structured_output: StructuredOutput::JsonSchema,
|
||||
reasoning: None,
|
||||
vision: false,
|
||||
prompt_caching: CacheStrategy::Auto,
|
||||
}
|
||||
}
|
||||
|
||||
fn make_transport<S: Scheme>(
|
||||
scheme: S,
|
||||
model: &str,
|
||||
auth: ResolvedAuth,
|
||||
) -> HttpTransport<S> {
|
||||
let cap = scheme.capability_for(model).unwrap_or_else(fallback_capability);
|
||||
let base_url = scheme.default_base_url().to_string();
|
||||
HttpTransport::new(scheme, model.to_string(), base_url, auth, cap)
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
@@ -60,7 +86,11 @@ async fn run_scenario_with_anthropic(
|
||||
let api_key = std::env::var("ANTHROPIC_API_KEY")
|
||||
.expect("ANTHROPIC_API_KEY environment variable must be set");
|
||||
let model = model.as_deref().unwrap_or("claude-sonnet-4-20250514");
|
||||
let client = AnthropicClient::new(&api_key, model);
|
||||
let client = make_transport(
|
||||
AnthropicScheme::new(),
|
||||
model,
|
||||
ResolvedAuth::ApiKey(api_key),
|
||||
);
|
||||
|
||||
recorder::record_request(
|
||||
&client,
|
||||
@@ -82,7 +112,7 @@ async fn run_scenario_with_openai(
|
||||
let api_key =
|
||||
std::env::var("OPENAI_API_KEY").expect("OPENAI_API_KEY environment variable must be set");
|
||||
let model = model.as_deref().unwrap_or("gpt-4o");
|
||||
let client = OpenAIClient::new(&api_key, model);
|
||||
let client = make_transport(OpenAIScheme::new(), model, ResolvedAuth::ApiKey(api_key));
|
||||
|
||||
recorder::record_request(
|
||||
&client,
|
||||
@@ -101,10 +131,15 @@ async fn run_scenario_with_ollama(
|
||||
subdir: &str,
|
||||
model: Option<String>,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
use llm_worker::llm_client::providers::ollama::OllamaClient;
|
||||
// Ollama typically runs local, no key needed or placeholder
|
||||
let model = model.as_deref().unwrap_or("llama3"); // default example
|
||||
let client = OllamaClient::new(model); // base_url placeholder, handled by client default
|
||||
// Ollama = Anthropic scheme + base_url 差し替え + 認証なし
|
||||
let model = model.as_deref().unwrap_or("llama3");
|
||||
let client = HttpTransport::new(
|
||||
AnthropicScheme::new(),
|
||||
model.to_string(),
|
||||
"http://localhost:11434".to_string(),
|
||||
ResolvedAuth::None,
|
||||
fallback_capability(),
|
||||
);
|
||||
|
||||
recorder::record_request(
|
||||
&client,
|
||||
@@ -126,7 +161,7 @@ async fn run_scenario_with_gemini(
|
||||
let api_key =
|
||||
std::env::var("GEMINI_API_KEY").expect("GEMINI_API_KEY environment variable must be set");
|
||||
let model = model.as_deref().unwrap_or("gemini-2.0-flash");
|
||||
let client = GeminiClient::new(&api_key, model);
|
||||
let client = make_transport(GeminiScheme::new(), model, ResolvedAuth::ApiKey(api_key));
|
||||
|
||||
recorder::record_request(
|
||||
&client,
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
//!
|
||||
//! Example of cancelling from another thread during streaming
|
||||
|
||||
use llm_worker::llm_client::providers::anthropic::AnthropicClient;
|
||||
use llm_worker::llm_client::capability::{
|
||||
CacheStrategy, ModelCapability, StructuredOutput, ToolCallingSupport,
|
||||
};
|
||||
use llm_worker::llm_client::scheme::{Scheme, anthropic::AnthropicScheme};
|
||||
use llm_worker::llm_client::transport::{HttpTransport, ResolvedAuth};
|
||||
use llm_worker::{Worker, WorkerResult};
|
||||
use std::time::Duration;
|
||||
|
||||
@@ -22,7 +26,17 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let api_key =
|
||||
std::env::var("ANTHROPIC_API_KEY").expect("ANTHROPIC_API_KEY environment variable not set");
|
||||
|
||||
let client = AnthropicClient::new(&api_key, "claude-sonnet-4-20250514");
|
||||
let scheme = AnthropicScheme::new();
|
||||
let model = "claude-sonnet-4-20250514".to_string();
|
||||
let cap = scheme.capability_for(&model).unwrap_or(ModelCapability {
|
||||
tool_calling: ToolCallingSupport::Parallel,
|
||||
structured_output: StructuredOutput::JsonSchema,
|
||||
reasoning: None,
|
||||
vision: false,
|
||||
prompt_caching: CacheStrategy::Auto,
|
||||
});
|
||||
let base_url = scheme.default_base_url().to_string();
|
||||
let client = HttpTransport::new(scheme, model, base_url, ResolvedAuth::ApiKey(api_key), cap);
|
||||
let worker = Worker::new(client);
|
||||
|
||||
println!("🚀 Starting Worker...");
|
||||
|
||||
@@ -44,10 +44,11 @@ use llm_worker::{
|
||||
interceptor::{Interceptor, PostToolAction, ToolResultInfo},
|
||||
llm_client::{
|
||||
LlmClient,
|
||||
providers::{
|
||||
anthropic::AnthropicClient, gemini::GeminiClient, ollama::OllamaClient,
|
||||
openai::OpenAIClient,
|
||||
capability::{CacheStrategy, ModelCapability, StructuredOutput, ToolCallingSupport},
|
||||
scheme::{
|
||||
Scheme, anthropic::AnthropicScheme, gemini::GeminiScheme, openai_chat::OpenAIScheme,
|
||||
},
|
||||
transport::{HttpTransport, ResolvedAuth},
|
||||
},
|
||||
timeline::{Handler, TextBlockEvent, TextBlockKind, ToolUseBlockEvent, ToolUseBlockKind},
|
||||
};
|
||||
@@ -327,6 +328,28 @@ fn get_api_key(args: &Args) -> Result<String, String> {
|
||||
}
|
||||
|
||||
/// Create client based on provider
|
||||
fn default_capability() -> ModelCapability {
|
||||
ModelCapability {
|
||||
tool_calling: ToolCallingSupport::Parallel,
|
||||
structured_output: StructuredOutput::JsonSchema,
|
||||
reasoning: None,
|
||||
vision: false,
|
||||
prompt_caching: CacheStrategy::Auto,
|
||||
}
|
||||
}
|
||||
|
||||
fn build_transport<S: Scheme>(
|
||||
scheme: S,
|
||||
model: String,
|
||||
auth: ResolvedAuth,
|
||||
) -> Box<dyn LlmClient> {
|
||||
let cap = scheme
|
||||
.capability_for(&model)
|
||||
.unwrap_or_else(default_capability);
|
||||
let base_url = scheme.default_base_url().to_string();
|
||||
Box::new(HttpTransport::new(scheme, model, base_url, auth, cap))
|
||||
}
|
||||
|
||||
fn create_client(args: &Args) -> Result<Box<dyn LlmClient>, String> {
|
||||
let model = args
|
||||
.model
|
||||
@@ -336,21 +359,32 @@ fn create_client(args: &Args) -> Result<Box<dyn LlmClient>, String> {
|
||||
let api_key = get_api_key(args)?;
|
||||
|
||||
match args.provider {
|
||||
Provider::Anthropic => {
|
||||
let client = AnthropicClient::new(&api_key, &model);
|
||||
Ok(Box::new(client))
|
||||
}
|
||||
Provider::Gemini => {
|
||||
let client = GeminiClient::new(&api_key, &model);
|
||||
Ok(Box::new(client))
|
||||
}
|
||||
Provider::Openai => {
|
||||
let client = OpenAIClient::new(&api_key, &model);
|
||||
Ok(Box::new(client))
|
||||
}
|
||||
Provider::Anthropic => Ok(build_transport(
|
||||
AnthropicScheme::new(),
|
||||
model,
|
||||
ResolvedAuth::ApiKey(api_key),
|
||||
)),
|
||||
Provider::Gemini => Ok(build_transport(
|
||||
GeminiScheme::new(),
|
||||
model,
|
||||
ResolvedAuth::ApiKey(api_key),
|
||||
)),
|
||||
Provider::Openai => Ok(build_transport(
|
||||
OpenAIScheme::new(),
|
||||
model,
|
||||
ResolvedAuth::ApiKey(api_key),
|
||||
)),
|
||||
Provider::Ollama => {
|
||||
let client = OllamaClient::new(&model);
|
||||
Ok(Box::new(client))
|
||||
// Ollama = Anthropic scheme + base_url 差し替え + 認証なし
|
||||
let scheme = AnthropicScheme::new();
|
||||
let cap = default_capability();
|
||||
Ok(Box::new(HttpTransport::new(
|
||||
scheme,
|
||||
model,
|
||||
"http://localhost:11434".to_string(),
|
||||
ResolvedAuth::None,
|
||||
cap,
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user