feat(llm): 新增 IR 类型层 + 切换 LlmProvider trait 签名
引入跨 Provider 统一的新类型系统: - Message 扁平大枚举(System/User/UserImage/Assistant/ToolResult) - MessageRequest + MessageResponse + StreamEvent(高精度 IR) - PartialMessageResponse 含 apply_to/finalize 汇聚算法 - ProviderType enum 扩展 + ProviderCapabilities 切换 LlmProvider trait 签名为 chat(MessageRequest) → MessageResponse, chat_stream 返回 Stream<Item = Result<StreamEvent, LlmError>>,新增 capabilities()。 StreamEvent 命名冲突处理:旧变体迁移至 old_stream::LegacyStreamEvent, stream.rs 通过 pub use 重新导出新高精度事件。 OpenaiProvider 添加 Phase 0 临时桥接(MessageRequest ↔ OpenaiChatRequest 转换), 标注 ponytail: Phase 0 临时桥接 标记,Phase 1 重写时移除。 测试 147 passed / 0 failed(新增 31 个新类型测试)。
This commit is contained in:
+23
-12
@@ -4,23 +4,34 @@ use agcore::init_tracing;
|
||||
use agcore::llm::{
|
||||
cycle::{CycleConfig, LlmCycle},
|
||||
provider::{create_provider, ProviderConfig, ProviderType},
|
||||
types::{ChatResponse, OpenaiContentPart},
|
||||
types::{
|
||||
message::ContentBlock, response_v2::MessageResponse,
|
||||
},
|
||||
};
|
||||
|
||||
fn extract_response_text(response: &ChatResponse) -> &str {
|
||||
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::OpenaiChatMessage::Assistant { content, .. } => match content {
|
||||
agcore::llm::types::ContentField::String(s) => s,
|
||||
agcore::llm::types::ContentField::Array(parts) => {
|
||||
for part in parts {
|
||||
if let OpenaiContentPart::Text { text } = part {
|
||||
return text;
|
||||
}
|
||||
agcore::llm::types::message::Message::Assistant { content } => {
|
||||
for block in content {
|
||||
if let ContentBlock::Text { text } = block {
|
||||
return text.as_str();
|
||||
}
|
||||
"[无文本内容]"
|
||||
}
|
||||
},
|
||||
_ => "[非 assistant 消息]",
|
||||
""
|
||||
}
|
||||
_ => "",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user