Checkpoint Odysseus local update

This commit is contained in:
pewdiepie-archdaemon
2026-07-07 00:50:07 +00:00
parent 5f6e6a2c4a
commit 017903de61
66 changed files with 22349 additions and 982 deletions
+215
View File
@@ -186,6 +186,12 @@ _FUNCTION_MODEL_NAME_RE = re.compile(
)
_FUNCTION_MODEL_PARAMS_OPEN_RE = re.compile(r"<parameters>\s*", re.IGNORECASE)
_FUNCTION_MODEL_PARAMS_CLOSE_RE = re.compile(r"</parameters>", re.IGNORECASE)
_QWEN_ROLE_MARKER_RE = re.compile(r"</?\|(?:assistant|assistan|user|system|tool)\|>?|</\|end\|>?", re.IGNORECASE)
_QWEN_BARE_MARKER_RE = re.compile(
r"(?:^|[\t\r\n ])(?:\|?end\|?|/?\|end\|)(?=[\t\r\n ]|$)|"
r"(?:^|[\t\r\n ])assistan(?:t)?(?=[\t\r\n ]|$)",
re.IGNORECASE,
)
# Pattern 5: DeepSeek DSML markup leaking into content. When deepseek
@@ -581,6 +587,205 @@ def _parse_raw_web_json_lookup(text: str) -> Optional[tuple[ToolBlock, tuple[int
return block, (start, start + end)
return None
def _looks_like_openai_tool_call_blob(value) -> bool:
"""Return True for raw OpenAI-style tool-call JSON leaked as text."""
if isinstance(value, list):
return bool(value) and all(_looks_like_openai_tool_call_blob(item) for item in value)
if not isinstance(value, dict):
return False
fn = value.get("function")
if isinstance(fn, dict) and isinstance(fn.get("name"), str):
return True
return False
def _raw_openai_tool_call_to_block(value) -> Optional[ToolBlock]:
if isinstance(value, list):
for item in value:
block = _raw_openai_tool_call_to_block(item)
if block:
return block
return None
if not isinstance(value, dict):
return None
fn = value.get("function")
if not isinstance(fn, dict):
return None
name = str(fn.get("name") or "").strip()
if not name:
return None
tool_type = _TOOL_NAME_MAP.get(name, name)
raw_args = fn.get("arguments") or {}
try:
args = json.loads(raw_args) if isinstance(raw_args, str) else raw_args
except (json.JSONDecodeError, TypeError):
args = {}
if not isinstance(args, dict):
args = {}
# Common local-model typo seen in raw OpenAI JSON leaks.
if "text" not in args and "tex" in args:
args["text"] = args.get("tex")
if tool_type.startswith("mcp__"):
return ToolBlock(tool_type, json.dumps(args) if args else "{}")
if name in BUILTIN_EMAIL_TOOLS:
return ToolBlock(f"mcp__email__{name}", json.dumps(args) if args else "{}")
if tool_type not in TOOL_TAGS:
return None
if tool_type == "bash":
content = args.get("command", "")
elif tool_type == "python":
content = args.get("code", "")
elif tool_type == "web_search":
content = args.get("query", "")
queries = args.get("queries")
if not content and isinstance(queries, list) and queries:
content = str(queries[0])
elif not content and queries:
content = str(queries)
tf = args.get("time_filter")
if content and isinstance(tf, str) and tf in ("day", "week", "month", "year"):
content = json.dumps({"query": content, "time_filter": tf})
elif tool_type == "web_fetch":
content = args.get("url") or args.get("domain") or ""
elif tool_type == "read_file":
content = json.dumps(args) if (args.get("offset") or args.get("limit")) else args.get("path", "")
elif tool_type in ("grep", "glob", "ls", "edit_file"):
content = json.dumps(args) if args else "{}"
elif tool_type == "write_file":
content = args.get("path", "") + "\n" + args.get("content", "")
elif tool_type == "create_document":
parts = [args.get("title", "Untitled")]
if args.get("language"):
parts.append(args["language"])
parts.append(args.get("content", ""))
content = "\n".join(parts)
elif tool_type == "update_document":
content = args.get("content", "")
elif tool_type in ("edit_document", "suggest_document"):
marker = "SUGGEST" if tool_type == "suggest_document" else "REPLACE"
blocks = []
for edit in args.get("suggestions" if tool_type == "suggest_document" else "edits", []) or []:
if not isinstance(edit, dict):
continue
block = f'<<<FIND>>>\n{edit.get("find", "")}\n<<<{marker}>>>\n{edit.get("replace", "")}'
if tool_type == "suggest_document":
block += f'\n<<<REASON>>>\n{edit.get("reason", "")}'
blocks.append(block + "\n<<<END>>>")
content = "\n".join(blocks)
elif tool_type == "search_chats":
content = args.get("query", "")
elif tool_type == "chat_with_model":
content = args.get("model", "") + "\n" + args.get("message", "")
elif tool_type == "create_session":
content = args.get("name", "Untitled") + "\n" + args.get("model", "")
elif tool_type == "list_sessions":
content = args.get("filter", "")
elif tool_type == "send_to_session":
content = args.get("session_id", "") + "\n" + args.get("message", "")
elif tool_type == "pipeline":
content = json.dumps({"steps": args.get("steps", [])})
elif tool_type == "manage_session":
action = args.get("action", "")
if action == "list":
keyword = args.get("keyword", "") or args.get("value", "")
content = "list" + (("\n" + keyword) if keyword and keyword.lower() != "current" else "")
else:
content = action + "\n" + args.get("session_id", "current")
if args.get("value"):
content += "\n" + args["value"]
elif tool_type == "manage_memory":
action = args.get("action", "")
if action == "add":
content = "add\n" + str(args.get("text", ""))
if args.get("category"):
content += "\n" + str(args["category"])
elif action == "edit":
content = "edit\n" + str(args.get("memory_id", "")) + "\n" + str(args.get("text", ""))
elif action == "delete":
content = "delete\n" + str(args.get("memory_id", ""))
elif action == "search":
content = "search\n" + str(args.get("text", ""))
elif action == "list":
content = "list" + (("\n" + str(args["category"])) if args.get("category") else "")
else:
content = action
elif tool_type == "ui_control":
action = args.get("action", "")
name_arg = args.get("name", "")
value = args.get("value", "")
if action == "open_panel":
content = f"open_panel {name_arg or value}"
elif action == "toggle":
content = f"toggle {name_arg} {value}"
else:
content = action
elif tool_type in ("manage_tasks", "manage_skills", "api_call", "manage_endpoints",
"manage_mcp", "manage_webhooks", "manage_tokens",
"manage_documents", "manage_settings", "manage_notes",
"manage_research", "manage_bg_jobs"):
content = json.dumps(args)
elif tool_type in ("get_workspace", "list_models"):
content = args.get("filter", "") if tool_type == "list_models" else ""
else:
content = json.dumps(args) if args else ""
return ToolBlock(tool_type, str(content or ""))
def _parse_raw_openai_tool_call_json(text: str) -> Optional[ToolBlock]:
if not isinstance(text, str) or '"function"' not in text:
return None
decoder = json.JSONDecoder()
for match in re.finditer(r"[\[{]", text):
try:
parsed, _end = decoder.raw_decode(text[match.start():])
except json.JSONDecodeError:
continue
block = _raw_openai_tool_call_to_block(parsed)
if block:
return block
return None
def _strip_raw_openai_tool_call_json(text: str) -> str:
"""Strip raw JSON tool calls such as {"function": {...}, "type": "function"}.
Some local models emit native tool-call JSON into assistant text. The agent
can still parse/execute it through the native path, but the raw payload must
not render or persist as prose.
"""
if not isinstance(text, str) or '"function"' not in text:
return text
decoder = json.JSONDecoder()
pieces = []
pos = 0
changed = False
for match in re.finditer(r"[\[{]", text):
start = match.start()
if start < pos:
continue
try:
parsed, rel_end = decoder.raw_decode(text[start:])
except json.JSONDecodeError:
continue
end = start + rel_end
if not _looks_like_openai_tool_call_blob(parsed):
continue
pieces.append(text[pos:start])
pos = end
changed = True
# Common broken local-model suffix: a standalone ] before a role marker.
while pos < len(text) and text[pos] in " \t\r\n":
pos += 1
if pos < len(text) and text[pos] == "]":
pos += 1
if not changed:
return text
pieces.append(text[pos:])
return "".join(pieces)
def _parse_tool_call_block(raw: str) -> Optional[ToolBlock]:
"""Parse a [TOOL_CALL] block into a ToolBlock.
@@ -1178,6 +1383,13 @@ def parse_tool_blocks(text: str, skip_fenced: bool = False) -> List[ToolBlock]:
if block:
blocks.append(block)
# Pattern 4d: raw OpenAI-style tool-call JSON leaked as assistant text.
# Example: {"function":{"arguments":"{\"action\":\"add\"}","name":"manage_memory"},"type":"function"}
if not blocks:
block = _parse_raw_openai_tool_call_json(text)
if block:
blocks.append(block)
# Pattern 6: local text-model web_search call leaked as prose + bare JSON.
if not blocks and not skip_fenced:
raw_web_json = _parse_raw_web_json_lookup(text)
@@ -1225,6 +1437,9 @@ def strip_tool_blocks(text: str, skip_fenced: bool = False) -> str:
cleaned = _strip_delimited(cleaned, _TOOL_CODE_OPEN_RE, _TOOL_CODE_CLOSE_RE)
cleaned = _GEMMA_TOOL_CALL_RE.sub('', cleaned)
cleaned = _strip_delimited(cleaned, _FUNCTION_MODEL_OPEN_RE, _FUNCTION_MODEL_CLOSE_RE)
cleaned = _strip_raw_openai_tool_call_json(cleaned)
cleaned = _QWEN_ROLE_MARKER_RE.sub('', cleaned)
cleaned = _QWEN_BARE_MARKER_RE.sub(' ', cleaned)
if not skip_fenced:
raw_web_json = _parse_raw_web_json_lookup(cleaned)
if raw_web_json: