fix: parse tool_use/tool_result messages and add OpenCode SQLite backend (#1401)

* fix: parse tool_use/tool_result messages and add OpenCode SQLite backend

  - Claude: reclassify user messages containing tool_result as "tool" role
  - Codex: handle function_call and function_call_output payload types
  - Gemini: support array content and toolCalls extraction, filter info/error types
  - OpenCode: add SQLite session scan, load and delete alongside legacy JSON
  - utils: extend parse_timestamp_to_ms for integer timestamps, extract tool_use/tool_result in shared extract_text

* fix: address remaining issues from tool_use/tool_result parsing commit
  - Claude: fix role misclassification for mixed user+tool_result messages (any → all)
  - OpenCode: extract duplicate part text logic into extract_part_text()
  - OpenCode: add path validation for SQLite delete to prevent foreign DB access
  - OpenCode: wrap SQLite deletion in transaction for atomicity
  - openclaw_config: remove redundant as_deref() on Option<&str>
This commit is contained in:
BlueOcean
2026-03-22 22:02:35 +08:00
committed by GitHub
parent 117dbf1386
commit bd3cfb7741
7 changed files with 858 additions and 35 deletions
+10
View File
@@ -69,6 +69,11 @@ pub fn scan_sessions() -> Vec<SessionMeta> {
}
pub fn load_messages(provider_id: &str, source_path: &str) -> Result<Vec<SessionMessage>, String> {
// OpenCode SQLite sessions use a "sqlite:" prefixed source_path
if provider_id == "opencode" && source_path.starts_with("sqlite:") {
return opencode::load_messages_sqlite(source_path);
}
let path = Path::new(source_path);
match provider_id {
"codex" => codex::load_messages(path),
@@ -85,6 +90,11 @@ pub fn delete_session(
session_id: &str,
source_path: &str,
) -> Result<bool, String> {
// OpenCode SQLite sessions bypass the file-based deletion path
if provider_id == "opencode" && source_path.starts_with("sqlite:") {
return opencode::delete_session_sqlite(session_id, source_path);
}
let root = provider_root(provider_id)?;
delete_session_with_root(provider_id, session_id, Path::new(source_path), &root)
}