fix(v8.0): openai 引擎改纯官方格式 + 讯飞 500 兼容 + <input> 向导
- openai_engine: 请求体严格纯官方 OpenAI /chat/completions 格式(tool 消息去 name、 tool_calls 重建、tools 统一 type=function);500(含 xunfei/Invalid Params)自动去掉 tools 降级重试;_friendly_error 友好提示;MODEL_CONTEXT_WINDOWS 补讯飞星火。 - ollama_engine/fc_tools/cli_core: tool 消息去 name。 - config.py resolve_input_value(<input> 语法);ollama max_token_k(默认 <input:...>); launcher 向导加 max_token_k 步骤。
This commit is contained in:
1 parent
539c21be72
commit
dfc42d8583
7 files changed
+203
-23
No files matched your search
@@ -795,11 +795,10 @@ multi 操作支持一次修改多处:
|
||||
# 通过插件管理器执行
|
||||
result = self._execute_tool_by_name(tool_name, tool_args)
|
||||
|
||||
# 记录工具结果到历史
|
||||
# 记录工具结果到历史(官方 OpenAI tool 消息不含 name 字段)
|
||||
tool_result_msg = {
|
||||
"role": "tool",
|
||||
"tool_call_id": call_id,
|
||||
"name": tool_name,
|
||||
"content": result[:5000] if result else "执行完成"
|
||||
}
|
||||
self.shared_conversation_history.append(tool_result_msg)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import os
|
||||
import re
|
||||
import json
|
||||
import logging
|
||||
from colorama import Fore, Style
|
||||
@@ -6,6 +7,39 @@ from colorama import Fore, Style
|
||||
# 配置文件路径
|
||||
CONFIG_FILE = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "config.json")
|
||||
|
||||
# <input> 特殊语法:配置模型时可用它交互式询问用户并获取输入
|
||||
# <input> → 用默认提示询问
|
||||
# <input:提示语> → 用自定义提示语询问
|
||||
_INPUT_PATTERN = re.compile(r"<input(?::([^>]*))?>")
|
||||
|
||||
|
||||
def resolve_input_value(value, field_name="", default_prompt=None):
|
||||
"""解析配置值中的 <input> 特殊语法,交互式询问用户并返回其输入。
|
||||
|
||||
用法(写在 config.json 的字段值里):
|
||||
"model": "<input>" → 启动时提示"请输入model: "
|
||||
"model": "<input:请输入模型名>" → 启动时提示自定义文案
|
||||
也可以夹在字符串中间: "prefix<input>suffix"
|
||||
|
||||
不含 <input> 的值原样返回;用户直接回车/中断时返回空串,由调用方兜底。
|
||||
"""
|
||||
if not isinstance(value, str) or "<input" not in value:
|
||||
return value
|
||||
|
||||
def _ask(match):
|
||||
label = (match.group(1) or "").strip()
|
||||
prompt = label or default_prompt or (f"请输入{field_name}" if field_name else "请输入")
|
||||
prompt = prompt.rstrip()
|
||||
if prompt and not prompt.endswith((":", ":", "?", "?", "!", "!", " ")):
|
||||
prompt += ": "
|
||||
try:
|
||||
answer = input(f"{Fore.CYAN}{prompt}{Style.RESET_ALL}").strip()
|
||||
return answer
|
||||
except (EOFError, KeyboardInterrupt):
|
||||
return ""
|
||||
|
||||
return _INPUT_PATTERN.sub(_ask, value)
|
||||
|
||||
|
||||
def load_config():
|
||||
"""加载配置文件"""
|
||||
|
||||
@@ -120,11 +120,11 @@ def fc_result_to_message(tool_call_id: str, tool_name: str, result: str) -> Dict
|
||||
|
||||
Returns:
|
||||
{"role": "tool", "tool_call_id": ..., "content": ...}
|
||||
注意: 官方 OpenAI 的 tool 消息不含 name 字段(严格服务端如讯飞会拒),故不写入。
|
||||
"""
|
||||
return {
|
||||
"role": "tool",
|
||||
"tool_call_id": tool_call_id,
|
||||
"name": tool_name,
|
||||
"content": result[:10000] if result else "" # 截断过长结果
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user