feat(prompt): 添加提示词工程模块并扩展LLM周期接口
新增 `prompt` 模块,包含模板引擎、组合器和错误类型,同时在`LlmCycle`中增加直接操作消息历史的方法和`submit_messages`接口
This commit is contained in:
@@ -113,6 +113,94 @@ impl LlmCycle {
|
||||
self.usage.reset();
|
||||
}
|
||||
|
||||
/// 直接设置消息历史(覆盖已有消息),支持 Builder 链式调用。
|
||||
pub fn with_messages(mut self, messages: Vec<OpenaiChatMessage>) -> Self {
|
||||
self.messages = messages;
|
||||
self
|
||||
}
|
||||
|
||||
/// 追加消息到历史尾部。
|
||||
pub fn extend_messages(&mut self, messages: Vec<OpenaiChatMessage>) {
|
||||
self.messages.extend(messages);
|
||||
}
|
||||
|
||||
/// 使用预构建消息提交(跳过自动 push user prompt)。
|
||||
///
|
||||
/// 与 `submit()` 不同,不自动添加 `user_text(prompt)`,也不自动插入 system prompt。
|
||||
/// 调用方完全控制消息序列内容。
|
||||
pub async fn submit_messages(
|
||||
&mut self,
|
||||
messages: Vec<OpenaiChatMessage>,
|
||||
tools: Vec<ToolDefinition>,
|
||||
) -> Result<ChatResponse, LlmError> {
|
||||
let openai_tools: Option<Vec<OpenaiTool>> = if tools.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(
|
||||
tools
|
||||
.iter()
|
||||
.map(|t| OpenaiTool::Function {
|
||||
function: t.clone(),
|
||||
})
|
||||
.collect(),
|
||||
)
|
||||
};
|
||||
|
||||
let request = ChatRequest {
|
||||
model: self.config.model.clone(),
|
||||
messages,
|
||||
max_tokens: self.config.max_tokens,
|
||||
temperature: self.config.temperature,
|
||||
tools: openai_tools,
|
||||
tool_choice: Some(ToolChoice::Auto),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
if let Some(ref executor) = self.hook_executor {
|
||||
let ctx = HookContext::new(crate::llm::hooks::HookEvent::PreRequest)
|
||||
.with_request(&request);
|
||||
let results = executor
|
||||
.execute(crate::llm::hooks::HookEvent::PreRequest, &ctx)
|
||||
.await;
|
||||
if results.iter().any(|r| r.should_block) {
|
||||
let reason = results
|
||||
.iter()
|
||||
.find(|r| r.should_block)
|
||||
.and_then(|r| r.reason.clone())
|
||||
.unwrap_or_else(|| "Blocked by pre-request hook".to_string());
|
||||
return Err(LlmError::Other(reason));
|
||||
}
|
||||
}
|
||||
|
||||
match self.provider.chat(request).await {
|
||||
Ok(response) => {
|
||||
if let Some(ref executor) = self.hook_executor {
|
||||
let post_request = ChatRequest {
|
||||
model: self.config.model.clone(),
|
||||
messages: vec![],
|
||||
..Default::default()
|
||||
};
|
||||
let ctx = HookContext::new(crate::llm::hooks::HookEvent::PostRequest)
|
||||
.with_request(&post_request);
|
||||
executor
|
||||
.execute(crate::llm::hooks::HookEvent::PostRequest, &ctx)
|
||||
.await;
|
||||
}
|
||||
self.usage.add(&response.usage);
|
||||
Ok(response)
|
||||
}
|
||||
Err(e) => {
|
||||
if let Some(ref executor) = self.hook_executor {
|
||||
let ctx = HookContext::new(crate::llm::hooks::HookEvent::OnError).with_error(&e);
|
||||
executor
|
||||
.execute(crate::llm::hooks::HookEvent::OnError, &ctx)
|
||||
.await;
|
||||
}
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 提交用户消息并获取 LLM 响应。
|
||||
pub async fn submit(
|
||||
&mut self,
|
||||
|
||||
Reference in New Issue
Block a user