Fix Groq API compatibility in parallel simulation

- Patch camel tool schema to add empty properties when required is
  present but properties is missing (fixes do_nothing tool rejection)
- Fix LLM-generated concatenated hour arrays in config loading
  (e.g. [19202122] -> [19,20,21,22])
This commit is contained in:
_Yusaki 2026-03-13 17:21:30 +07:00
parent 42ab084edd
commit 8024cb130a

View file

@ -168,6 +168,23 @@ try:
generate_twitter_agent_graph,
generate_reddit_agent_graph
)
# Patch camel tool schema for Groq compatibility.
# Groq rejects tool schemas where 'required' is present but 'properties'
# is missing (e.g. zero-parameter tools like do_nothing).
import camel.toolkits.function_tool as _ft
_original_get_openai_tool_schema = _ft.get_openai_tool_schema
def _patched_get_openai_tool_schema(func):
schema = _original_get_openai_tool_schema(func)
params = schema.get("function", {}).get("parameters", {})
if "required" in params and "properties" not in params:
params["properties"] = {}
if not params.get("properties") and "required" in params:
del params["required"]
return schema
_ft.get_openai_tool_schema = _patched_get_openai_tool_schema
except ImportError as e:
print(f"错误: 缺少依赖 {e}")
print("请先安装: pip install oasis-ai camel-ai")
@ -601,10 +618,51 @@ class ParallelIPCHandler:
return True
def _fix_hour_array(val):
"""Fix LLM-generated concatenated hour arrays.
Some models produce [19202122] instead of [19,20,21,22] or
["012345"] instead of [0,1,2,3,4,5]. Parse these back into
individual hour integers (0-23).
"""
if not isinstance(val, list) or len(val) != 1:
return val
item = val[0]
if isinstance(item, str):
return [int(ch) for ch in item if ch.isdigit()]
if isinstance(item, int) and item > 23:
s = str(item)
hours = []
i = 0
while i < len(s):
if i + 1 < len(s):
two_digit = int(s[i:i + 2])
if 10 <= two_digit <= 23:
hours.append(two_digit)
i += 2
continue
hours.append(int(s[i]))
i += 1
return hours
return val
def load_config(config_path: str) -> Dict[str, Any]:
"""加载配置文件"""
with open(config_path, 'r', encoding='utf-8') as f:
return json.load(f)
config = json.load(f)
# Fix malformed hour arrays from LLM config generation
time_config = config.get("time_config", {})
for key in ("peak_hours", "off_peak_hours"):
if key in time_config:
time_config[key] = _fix_hour_array(time_config[key])
for agent_cfg in config.get("agent_configs", []):
if "active_hours" in agent_cfg:
agent_cfg["active_hours"] = _fix_hour_array(agent_cfg["active_hours"])
return config
# 需要过滤掉的非核心动作类型(这些动作对分析价值较低)