Repository navigation
feat(adapters): add Warp agent conversation adapter - #306
Conversation
Decode persisted task protobufs instead of synthesizing assistant messages and tool calls from query history or aggregate statistics. Verified with make check and isolated CLI sync, export, search, and event backfill against synthetic fixtures encoded with the official Warp protocol. Real Warp conversation acceptance remains pending because the installed app did not initialize. Signed-off-by: samzong <samzong.lu@gmail.com>
|
@codex review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2ca1be958e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| fn scan_for_sync_output( | ||
| &self, | ||
| context: &AdapterSyncContext, | ||
| _since_ts: Option<i64>, |
There was a problem hiding this comment.
Apply the sync cutoff before decoding Warp task blobs
When the user selects the Today, 7d, or 30d sync window, since_ts is supplied specifically to bound adapter work, but this implementation discards it and queries and protobuf-decodes every task in every conversation. The generic sync cutoff runs only after each RawSession has been constructed, so large Warp databases still incur a complete database read and protobuf decode on every sync; pass the cutoff into the query, while disabling it for forced scans.
Useful? React with 👍 / 👎.
| })(); | ||
| match parsed { | ||
| Ok(Some(mut raw)) => { | ||
| let data: String = row.get(2)?; |
There was a problem hiding this comment.
Keep metadata reads within the per-session failure boundary
If one conversation_data value cannot be converted to UTF-8 text—for example, a damaged row or a BLOB stored in SQLite's dynamically typed column—this ? exits scan_db_with_seen rather than warning and skipping that conversation. scan_paths then moves to the next database, so every readable conversation ordered after the bad row in this same database is silently omitted; handle this read in the per-row parsed result just like the ID, timestamp, and task decoding.
AGENTS.md reference: src/adapters/AGENTS.md:L17-L18
Useful? React with 👍 / 👎.
| let name = tool_names.get(&result.tool_call_id).cloned().flatten(); | ||
| let command = shell_commands.get(&result.tool_call_id).map(String::as_str); | ||
| session_events.push(result_event(&result, context, name, command, active_cwd)); |
There was a problem hiding this comment.
Resolve result tool names independently of traversal order
When a non-shell tool result sorts before its corresponding call because its timestamp is earlier or the records come from interleaved tasks, tool_names has not yet been populated and the result event is emitted without a name even though the result itself identifies read_files or apply_file_diffs. The shell-command map is already precomputed for this ordering case; precompute tool names similarly or derive the known result variant directly.
Useful? React with 👍 / 👎.
Signed-off-by: samzong <samzong.lu@gmail.com>
Signed-off-by: samzong <samzong.lu@gmail.com>
Signed-off-by: samzong <samzong.lu@gmail.com>
Signed-off-by: samzong <samzong.lu@gmail.com>
Signed-off-by: samzong <samzong.lu@gmail.com>
Signed-off-by: samzong <samzong.lu@gmail.com>
Signed-off-by: samzong <samzong.lu@gmail.com> # Conflicts: # src/usage.rs
What's changed?
warpsource (labelWP). Discover Stable and Preview databases in the standard macOS, Linux, and Windows directories, including macOS group-container and Application Support fallback locations,tui/warp.sqlite, LinuxXDG_STATE_HOME, and WindowsLOCALAPPDATA. Index duplicate native conversation IDs once, preferring the earlier canonical path.agent_conversationsand protobufagent_tasks.taskthrough a read-only SQLite snapshot with a busy timeout. Keep user/assistant text, source timestamps in milliseconds, task descriptions, and working directories. Deduplicate message IDs and keep tool directories separate across interleaved tasks.RequestMetadata.chargestoken counts. Keep model/category/origin and separate input, output, cache-read, and cache-write counts. Deduplicate message-based usage keys across forks in the shared report accumulator while preserving per-session records. Do not infer usage from conversation totals or billing values; provider remains unknown when absent from the source.conversation_data.parent_conversation_idto a subagent thread with a spawn parent link through the existing metadata backfill path.agent_conversationsandagent_tasks; the native migration creates them together. Skip taskless conversations so a handoff that transfers task ownership cannot replace already indexed assistant messages, events, or usage with user-only input.prostwith a partial local protocol definition containing only fields needed for indexing. Other native fields and accepted query-origin payloads are skipped as unknown fields; they do not suppress user text. No migrations, source mutations, or additional persistent adapter state. Retain the Junie and Zed adapters from main alongside Warp, including their event-backfill registrations.warp://conversation/...handler requires a server conversation token, and no verified local CLI accepts a native conversation ID or an initial local-agent prompt.Why
Warp conversations were not searchable in Recall. Query history alone loses real assistant text and detailed tool records. Warp persists the complete task protobuf, providing the requested messages, events, and explicit token counts without synthesizing them from aggregates. Treating absent task rows as missing source data preserves Recall history when Warp transfers task ownership during handoff. Native timestamps are parsed before cutoff comparisons, preserving timezone offsets and conservative handling of unknown timestamps without decoding old payloads. Collecting call metadata once preserves chronological event order while making result names independent of traversal order.
Verification
make check: CI-pinned cargo-audit 0.22.2, format, workspace Clippy with--all-targets --features bench -D warnings, and all workspace tests (921 core tests plus extension tests).00cdd6726f28fb6b32a6712f0ca3264dbd0956a1. The SQL fixture is a minimal schema derived from Warp's upstream migration, not an installed database dump.file_historyendpoint also verifies shell evidence after event-version backfill. Sanitized real-fixture CLI replay verifies Stable/Preview accumulation, duplicate native IDs, corrupt primary-database isolation, and repeat sync.Test evidence
make checkpasses audit, format, workspace Clippy, and all workspace tests (921 core tests plus extension tests).grok-4-7-low, display namegrok 4.7 (low)). The user used their own logged-in account to ask the agent to readsample.txt, runwc -l sample.txt, and appendgammain/tmp/recall-warp-probe. The verifier did not log in, configure a gateway, or operate Warp. The final file was independently checked asalpha,beta, andgamma, each on its own line..backupinside Warp's terminal to produce a consistent snapshot. The snapshot was placed at~/Library/Application Support/dev.warp.Warp-Stable/warp.sqlitein a private sandbox HOME, exercising the macOS Stable Application Support fallback. A probe-only sync returnedstatus: created,message_count: 2; repeat sync returnedstatus: unchanged. Export was compared against only the probe's official-protocol-decoded task before any other sessions were indexed./tmp/recall-warp-probe; file evidence resolves the read target to/private/tmp/recall-warp-probe/sample.txt. Message timestamps are1791387715621and1791387728192; source modification time maps to1791387729000. The title isCount Lines And Append Text In File. The source has no parent conversation, so Recall leaves the thread role unspecified and emits no parent link.2 sample.txt, then3 sample.txtfollowed byalpha/beta/gamma. Event timestamps and call associations matched the native task. The append is represented by its actual shell command, rather than a fabricated edit-tool event.wcand the command containing ordinary append redirection asunsupported, so these shell events retain their commands/output but have no inferred file records. Matching results add no duplicate file evidence. Supporting these shell forms is separate from decoding the Warp task.RequestMetadatamessages; Recall emits zero usage events. Conversation-level billing/usage metadata is not converted into inferred token counts. Real per-request classified token counts were not present in this session.Sync: 1 new, 0 updated, 1 unchanged, 2 messages. The other conversation with a task indexed successfully; the one without a task was skipped. Only indexing status was inspected for these conversations; their contents were not exported or included in fixtures.unable to open database file.recall sync --source warp --backfill-events --dry-run --project all -vreturned exit code 0,Found 0 sessions, and a WARN containingopening Warp database read-only: unable to open database file/ SQLite error 14. No sync-wide failure occurred. This command uses a read-only Recall store;--dry-runrequires--backfill-events. No privacy/security settings were changed or access controls bypassed.probe.textprotoandprobe.binretain allowlisted probe content and actual timestamps/variants, using invented stable IDs. Account/user identifiers, server/conversation tokens, credentials, project context, attachments, reasoning text, and other conversation data were removed. The fixture README records provenance and sanitization; the payload was reserialized with the official protocol, not copied unchanged. A new adapter test covers the observed messages, metadata, read success, commands/results, and absent usage/topology.file_historyverification confirms duplicate-free supported command evidence. These synthetic checks are not real-session acceptance for those variants./tmp/recall-warp-*; only verified sandbox worker PIDs were stopped. The real Recall database's identity, size, and modification time were unchanged./tmp/recall-warp-copyand all sandbox copies/private indexes from this verification were deleted. The probe directory was not modified by the verifier.Closes #291