feat(llm): 完成 Phase 5 热身准备(Ollama / non_exhaustive / ProviderConfig)

Phase 5 三个 Step 全部落地:

Step 5.2 — Ollama Provider
- 新增 OllamaProvider newtype 包装(默认 localhost:11434/v1,零 API key)
- ProviderType 新增 Ollama 变体与 FromStr 解析

Step 5.3 — #[non_exhaustive] 前置标记
- ProviderType / StopReason / FinishReason / EvictionPolicy 加 #[non_exhaustive]
- 编译期兼容护栏,避免下游 silent break

Step 5.1 — ProviderConfig 扩展
- 加 timeout_secs / max_retries 字段、Default、from_env(prefix)
- create_provider 各分支通过 pub(crate) from_parts 一次性构造并注入 timeout
  (同时避开 Anthropic 的 default_headers 与双重 client 构造)
- map_reqwest_error 改为方法读取 self.timeout_secs(移除硬编码 120s)
- AnthropicProvider::with_timeout 同值短路,with_client 标 #[deprecated]
- DeepSeek / Qwen 加公开 with_client,new_with_client 走代理
- 7 个新测试:5 个 from_env 单元测试 + 3 个 timeout 传导 wiremock
  (OpenAI Chat / DeepSeek / Anthropic)
- Cargo.toml 加 temp-env dev-dep
This commit is contained in:
徐涛
2026-07-05 08:12:40 +08:00
parent 9e476e79bb
commit 98dfe6c1ed
10 changed files with 807 additions and 199 deletions
+7 -6
View File
@@ -3,7 +3,7 @@ use std::env;
use agcore::init_tracing;
use agcore::llm::{
cycle::{CycleConfig, LlmCycle},
provider::{create_provider, ProviderConfig, ProviderType},
provider::{ProviderConfig, ProviderType, create_provider},
types::{message::ContentBlock, message::Message, response_v2::MessageResponse},
};
@@ -51,10 +51,11 @@ async fn main() {
base_url,
api_key,
model: model.clone(),
timeout_secs: 30,
max_retries: 3,
};
let provider = create_provider(provider_type, config)
.expect("创建 Provider 失败");
let provider = create_provider(provider_type, config).expect("创建 Provider 失败");
let cycle_config = CycleConfig {
model,
@@ -63,9 +64,9 @@ async fn main() {
..CycleConfig::default()
};
let mut cycle = LlmCycle::new(provider, cycle_config).with_messages(vec![
Message::system("你是一个简洁的助手,对于任何问题都是用一句话回答。"),
]);
let mut cycle = LlmCycle::new(provider, cycle_config).with_messages(vec![Message::system(
"你是一个简洁的助手,对于任何问题都是用一句话回答。",
)]);
println!("发送请求...");