9e4f50c955
核心改动: - LlmCycle.messages 从 Vec<OpenaiChatMessage> 切换为 Vec<Message>, 移除 Phase 0 引入的 chat_message_to_message / message_to_chat_message 转换函数 - 移除 LlmCycle.system_prompt 字段(FIX-D),调用方通过 Message::system_text() + with_messages() 管理系统提示; with_system_prompt() 标记 #[deprecated] 保留为过渡期 shim - submit_stream 简化(FIX-E):Item = StreamEvent 不再带 Result 包装, 错误用 StreamEvent::Error 传出;self.messages 不再自动 push_message, 调用方在收到 MessageComplete 后手动调用 cycle.push_message() - compact.rs 适配 Message 类型 + ContentBlock 估算;microcompact 跳过 is_error:true 的 ToolResult(FIX-F),保留 LLM 错误诊断 - ConversationMemory 持久化从 OpenaiChatMessage 切换为 Message - ToolInvocation 增加 tool_call_id 字段(FIX-A), invoke/invoke_all 签名增加 tool_call_id 参数 调用方迁移: - AgentSession::submit_turn 用 Message::system_text() + with_messages() - simple_visit example 同步迁移 测试 177 passed / 0 failed(compact 新增 5 个单元测试覆盖 FIX-F + 估计全变体)。
86 lines
2.8 KiB
Rust
86 lines
2.8 KiB
Rust
use std::env;
|
||
|
||
use agcore::init_tracing;
|
||
use agcore::llm::{
|
||
cycle::{CycleConfig, LlmCycle},
|
||
provider::{create_provider, ProviderConfig, ProviderType},
|
||
types::{message::ContentBlock, message::Message, response_v2::MessageResponse},
|
||
};
|
||
|
||
fn extract_response_text(response: &MessageResponse) -> &str {
|
||
// Phase 0:MessageResponse.text() 直接给出拼接好的 Assistant 文本。
|
||
if !response.text().is_empty() {
|
||
// ⚠️ 返回的是 owned String 的引用,调用方需在 response 生命周期内使用。
|
||
// 此 example 短命,足以演示。
|
||
return response_text_ref(response);
|
||
}
|
||
"[无文本内容]"
|
||
}
|
||
|
||
fn response_text_ref(response: &MessageResponse) -> &str {
|
||
// ponytail: example 助手 —— 不在正式 crate API 中,单纯绕开 borrow 限制。
|
||
// 真实调用请直接使用 `response.text()` 拿到 owned String。
|
||
match &response.message {
|
||
agcore::llm::types::message::Message::Assistant { content } => {
|
||
for block in content {
|
||
if let ContentBlock::Text { text } = block {
|
||
return text.as_str();
|
||
}
|
||
}
|
||
""
|
||
}
|
||
_ => "",
|
||
}
|
||
}
|
||
|
||
#[tokio::main]
|
||
async fn main() {
|
||
dotenvy::dotenv().ok();
|
||
init_tracing();
|
||
|
||
let api_key = env::var("OPENAI_API_KEY").expect("未设置 OPENAI_API_KEY 环境变量");
|
||
let base_url = env::var("OPENAI_BASE_URL").expect("未设置 OPENAI_BASE_URL 环境变量");
|
||
let model = env::var("OPENAI_MODEL").expect("未设置 OPENAI_MODEL 环境变量");
|
||
|
||
let provider_type = env::var("PROVIDER")
|
||
.unwrap_or_else(|_| "openai".into())
|
||
.parse::<ProviderType>()
|
||
.expect("无效的 PROVIDER 值");
|
||
|
||
let config = ProviderConfig {
|
||
base_url,
|
||
api_key,
|
||
model: model.clone(),
|
||
};
|
||
|
||
let provider = create_provider(provider_type, config)
|
||
.expect("创建 Provider 失败");
|
||
|
||
let cycle_config = CycleConfig {
|
||
model,
|
||
max_tokens: Some(65536),
|
||
temperature: Some(1.3),
|
||
..CycleConfig::default()
|
||
};
|
||
|
||
let mut cycle = LlmCycle::new(provider, cycle_config).with_messages(vec![
|
||
Message::system("你是一个简洁的助手,对于任何问题都是用一句话回答。"),
|
||
]);
|
||
|
||
println!("发送请求...");
|
||
|
||
match cycle.submit("介绍一下你自己吧。".to_string(), vec![]).await {
|
||
Ok(response) => {
|
||
println!("LLM 回复:{}", extract_response_text(&response));
|
||
println!(
|
||
"Token 用量:{} 输入, {} 输出",
|
||
response.usage.prompt_tokens, response.usage.completion_tokens
|
||
);
|
||
}
|
||
Err(e) => {
|
||
eprintln!("请求失败:{e}");
|
||
std::process::exit(1);
|
||
}
|
||
}
|
||
}
|