Gemini Export#59
Merged
Merged
Conversation
…h Path
derive_path and extract_conversation were an incomplete pair: several
Turn fields either never got serialized into conversation.append extras
(stop_reason, environment, Turn.extra, tool-use results, delegations) or
were serialized but never read back (tool_uses, delegations, token_usage
in its nested form). Any ConversationView written to a Path and read
back lost those fields silently.
derive now writes them; extract reads them with fall-throughs so Claude's
bespoke top-level-key schema still decodes. build_environment,
build_inline_tool_uses, build_delegations, and build_turn_extra factor
out the readers; build_token_usage prefers the nested shape and falls
back to the top-level Claude keys.
Model attribution consolidates on the actor URI. derive_path stopped
writing a redundant "model" key into the append extras; extract reads
the model out of the step's agent:{model} actor via a new
model_from_actor helper that handles the agent:claude-code/tool:... sub-
actor form and the agent:unknown sentinel. A fallback to extras["model"]
keeps earlier Paths decoding.
Provider + session now recover from the {provider}://{session} artifact
key on the first conversation.append step, since shared derivation does
not emit conversation.init.
Adds a Gemini-side reverse of the existing forward path: any ConversationView can be projected into a Gemini-native Conversation that loads cleanly into `gemini --resume`. End-to-end this enables moving a conversation from another harness (Claude in particular) into a resumable Gemini session. toolpath-gemini changes: - New `project` module with `GeminiProjector: ConversationProjector< Output = Conversation>`. Sets `kind: "main"`, full UUID `sessionId`, populates `directories`. Synthesizes per-tool-call `description`, `displayName`, `renderOutputAsMarkdown`, `resultDisplay` from args and result text — real Gemini sessions carry these on every call. - `provider::native_name(ToolCategory, &Value)` — reverse of `tool_category`. Picks Gemini's preferred native name for a generic category, using the call's args to disambiguate FileWrite (replace vs write_file) and FileRead (read_file vs read_many_files vs list_directory). The projector remaps foreign tool names through this; native ones pass through unchanged. - `provider::build_gemini_extra` now preserves thought `description` alongside subject/timestamp so `Thought[]` round-trips losslessly. - `paths::resolve_main_file(project, session_id)` — locates a main chat by either filename stem OR inner `sessionId` UUID, mirroring how Gemini CLI's `--resume <uuid>` resolves. `read_session`, `read_session_metadata`, and `session_exists` use it. - `Tokens` fields gain `skip_serializing_if = "Option::is_none"` so partial usage (from foreign sources) omits absent fields instead of writing nulls. - Foreign-namespace extras (e.g. `Turn.extra["claude"]`) are dropped during projection rather than flattening as top-level message fields, eliminating per-message JSON pollution. toolpath-cli changes: - `cmd_export::ExportTarget::Gemini` — `path export gemini --input <cache-id-or-file> [--project <dir>]`. Writes the resume-ready layout to `~/.gemini/tmp/<slot>/chats/`: flat `session-<ts>-<short>.json` main file (the `session-` prefix is mandatory for `--list-sessions` to find it) plus `chats/<session-uuid>/<sub>.json` for any sub-agents. Drops a `.project_root` marker. Bakes `projectHash` to match what Gemini computes from the same cwd. toolpath-claude changes: - `tool_category` and `tool_category_str` learn `MultiEdit` (FileWrite) and `Agent` (Delegation, alias for Task). Without these, Claude- derived path docs left those tools uncategorized and the projector couldn't remap them. Format docs: - `docs/agents/formats/gemini.md` documents two empirical constraints discovered while building this: the mandatory `session-*.json` filename prefix for CLI session enumeration, and the two-step `--resume <id>` resolution (stem match → inner sessionId scan). Tests: - 17 unit tests in `project.rs` covering content shape, role mapping, thoughts (meta + flattened-string fallback), tokens (gemini extras + common-token-usage fallback), tool calls (success/error/meta preservation), delegation unfolding, foreign-namespace dropping, Gemini-native message extras preservation, serde round-trip. - 11 integration tests in `tests/projection_roundtrip.rs` exercising the full chain ChatFile -> ConversationView -> Path (serialized) -> ConversationView -> ChatFile, including a write-to-disk + GeminiConvo::read_conversation round-trip that uses the same code path Gemini CLI uses for --resume. - 4 unit tests in `paths.rs` for the new `resolve_main_file` (stem match, inner-sessionId match, stem-preferred-over-id, no-match). - 2 integration tests in `cmd_export.rs` for the new gemini variant (writes resume-ready layout + readable via library, rejects non-Path docs).
|
🔍 Preview deployed: https://da47bb17.toolpath.pages.dev |
benbaarber
commented
Apr 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.