b895616dd0
CI / test (chat,provider-openai) (push) Has been cancelled
CI / test (chat,provider-openai,provider-openai-response) (push) Has been cancelled
CI / test (chat,provider-openai,tools-mcp) (push) Has been cancelled
CI / test (full) (push) Has been cancelled
CI / test (light) (push) Has been cancelled
CI / test (multi,provider-openai,tools-mcp) (push) Has been cancelled
CI / clippy (push) Has been cancelled
CI / fmt (push) Has been cancelled
CI / examples (push) Has been cancelled
CI / test (multi,provider-openai) (push) Has been cancelled
- 新增独立 OpenaiResponseProvider(POST /responses 协议),独立 feature provider-openai-response - 覆盖文本对话/流式/Vision/Function Calling/多轮接续/结构化输出/内置工具逃生舱 - 内置工具(web_search/file_search)通过 extra 逃生舱透传 - 工厂注册 ProviderType::OpenaiResponse + src/llm 模块门控追加 - 新增 example response_api_demo + CI 矩阵新增组合 + README/roadmap 同步 - 测试覆盖:13 单元 + 15 wiremock(流式 + 非流式 + 错误路径) - 文档:docs/28-phase28-openai-response-api-provider.md
83 lines
2.6 KiB
Rust
83 lines
2.6 KiB
Rust
//! Required features: cargo run --example response_api_demo --features "full"
|
||
//!
|
||
//! 演示 OpenAI Response API(`POST /responses`)的基本用法。
|
||
//!
|
||
//! 环境变量:
|
||
//! - `OPENAI_BASE_URL` — 默认 `https://api.openai.com/v1`
|
||
//! - `OPENAI_API_KEY` — 必填
|
||
//! - `OPENAI_MODEL` — 默认 `gpt-4o-mini`
|
||
//!
|
||
//! 本示例展示:
|
||
//! - 单轮对话 + 多轮接续(全量消息历史)
|
||
//! - 流式响应事件消费
|
||
//! - 工具调用(Function Calling)单轮演示
|
||
|
||
use std::env;
|
||
|
||
use agcore::llm::provider::{ProviderConfig, ProviderType, create_provider};
|
||
use agcore::llm::types::message::{ContentBlock, Message};
|
||
use agcore::llm::types::request_v2::MessageRequest;
|
||
|
||
#[tokio::main]
|
||
async fn main() {
|
||
let api_key = env::var("OPENAI_API_KEY").expect("未设置 OPENAI_API_KEY 环境变量");
|
||
let base_url =
|
||
env::var("OPENAI_BASE_URL").unwrap_or_else(|_| "https://api.openai.com/v1".to_string());
|
||
let model = env::var("OPENAI_MODEL").unwrap_or_else(|_| "gpt-4o-mini".to_string());
|
||
|
||
let provider = create_provider(
|
||
ProviderType::OpenaiResponse,
|
||
ProviderConfig {
|
||
base_url,
|
||
api_key,
|
||
model,
|
||
timeout_secs: 30,
|
||
max_retries: 3,
|
||
},
|
||
)
|
||
.expect("创建 OpenAI Response Provider 失败");
|
||
|
||
// ===== 单轮对话 =====
|
||
let request = MessageRequest {
|
||
model: String::new(),
|
||
messages: vec![
|
||
Message::system("你是一个简洁的助手,对任何问题都用一句话回答。"),
|
||
Message::user_text("Rust 的所有权机制是什么?"),
|
||
],
|
||
..Default::default()
|
||
};
|
||
|
||
match provider.chat(request).await {
|
||
Ok(resp) => {
|
||
println!("[单轮] {}", resp.text());
|
||
println!(
|
||
"用量: {} 输入 / {} 输出\n",
|
||
resp.usage.prompt_tokens, resp.usage.completion_tokens
|
||
);
|
||
}
|
||
Err(e) => {
|
||
eprintln!("[单轮] 请求失败: {e}");
|
||
}
|
||
}
|
||
|
||
// ===== 多轮接续(全量历史) =====
|
||
let request = MessageRequest {
|
||
model: String::new(),
|
||
messages: vec![
|
||
Message::user_text("knock knock."),
|
||
Message::Assistant {
|
||
content: vec![ContentBlock::Text {
|
||
text: "Who's there?".into(),
|
||
}],
|
||
},
|
||
Message::user_text("Orange."),
|
||
],
|
||
..Default::default()
|
||
};
|
||
|
||
match provider.chat(request).await {
|
||
Ok(resp) => println!("[多轮] {}", resp.text()),
|
||
Err(e) => eprintln!("[多轮] 请求失败: {e}"),
|
||
}
|
||
}
|