Repository navigation
Releases: resolveworks/pathfinder
Release list
v0.8.0
This release is a fidelity pass over the ported runtime: provider adapters, auth flows, session persistence, and agent contracts are realigned with pi as the source of truth.
Tool-call arguments become a parsed JsonObject end to end, pi's upstream contract, instead of a raw JSON string. The ai module ports pi's json-parse (repair, partial-json 0.1.7, re-parse at every streaming delta), every adapter accumulates fragments and finalizes at stop or replay, and the agent fold, JSONL codec, compaction utils, and app UI move to the object shape with it. The adapters are aligned throughout: Anthropic keeps the requested model id, repairs SSE payloads, fails terminally on missing schema-required fields, and throws synchronously on missing auth; OpenAI-completions preserves interleaved text/image order, wires grammar-constrained custom tools, and computes X-Initiator from the transcript; Responses carries supportsStrictMode nullable with per-API defaults (codex/azure true, openai-responses false), while Codex's retry loop, Azure URL rewriting, and header handling follow pi; Google expands systemInstruction, derives x-goog-api-key only when absent, and fails mid-stream on unknown finish reasons; Mistral drops the invented completions bridge and sanitizes streamed text. Models.stream restores pi's lazy-stream contract, where unknown providers, failing auth resolution, and synchronous setup failures surface as a single terminal error event, and the ModelsError taxonomy is back.
The agent and session layers gain pi's steering and follow-up message queues with their drain semantics, poll points, and post-run continuation tail; the composer stays usable while streaming and queued messages render as transient pending rows. AgentSession's event contract is restored — agent_settled, thinking_level_changed, retry-aware AgentEnd.willRetry, and pi's re-emit-before-persist ordering — with run-active state spanning retry backoff and inter-run compaction. Abort semantics follow the abort audit: post-abort threshold compaction really compacts, pre-prompt compaction runs under a tracked child job, a tool-execution abort runs pi's extra turn with the ABORTED finalization, and auth aborts surface as pi's login failures rather than silent cancellation.
Persistence and settings converge on pi's shapes: JSONL uses pi's camelCase stopReason wire values, lenient ECMA-262 timestamps, \n-only splitting, and RawEntry retention for unported entry types; SettingsManager validates compaction budgets lazily at read, persists only modified keys, and models branchSummary; compaction gains pi's compaction-local estimator, where system messages estimate zero and are never cut candidates. Schema-driven validateToolArguments replaces the per-tool hand-rolled checks, and bash timeout validation and enforcement move into the Operations seam like pi's local shell.
Underneath, shared implementations replace the per-site forks: JSON reads and jsonEquals onto one JsonDom surface, WHATWG query parsing and href normalization onto OkHttp's HttpUrl, form encoding onto URLEncoder, Number()/parseFloat semantics onto shared JS-number helpers, retry-after dates onto one lenient parser, and Flow collect-breaks onto truncation operators with both sentinel exceptions deleted. OAuth moves to an OkHttp client with a single whole-exchange deadline, loopback handlers return per-flow error shapes, and the SSE transport takes pi's 300 s idle cap plus full error-body capture so retry classification and error parsing see what pi's adapters see.
On the app side, the transcript becomes an eager Column in a verticalScroll: follow is one snapshotFlow over maxValue, so content growing below the reader can no longer move them, and the LazyList anchoring machinery — TranscriptScrollState, the nested-scroll connection, the sentinel row — is gone.
v0.7.0
This release ports pi's mid-conversation system messages end to end: the TranscriptContext model in the AI package, system-message handling in the agent loop, the system-prompt sections model in reduced form, and AgentSession's mid-conversation prompt and tool loadout, so the system prompt and tool availability can change while a conversation runs.
Session and settings management sync to pi's shapes. SessionManager gains pi-shaped session discovery — most-recent-session lookup ordered by mtime, bounded-concurrency listing — and replaces the SessionSource seam, with ChatViewModel calling it directly. Compaction entries stamp a system-message baseline and lead the compacted context with it, findCutPoint falls back to the latest valid cut point when trailing tool results exceed the budget, and split-turn history summaries default to the previous summary.
The bash tool treats a signal-killed process as failure while preserving partial output, with the SSH seam mapping exit signals to 128+signal like pi's local shell, and the built-in tools declare prefer-strict JSON-schema sampling. Upstream ai-utils fixes land as well: overflow scoping and a retry delay cap.
Streaming is reworked around deltas: stream deltas are the truth, snapshots exist only at boundaries, per-chunk streaming state is split out of the chat UI state, and agent events are collected on Main.immediate with message-update noise filtered out. Session summary decode moves off the startup and per-run critical paths.
v0.6.0
This release ports pi's built-in coding tools — read, bash, edit, write — and runs them over SSH. The SSH layer covers a host store with per-host keys, TOFU host-key verification, a process-wide lazy connection provider with main-thread confinement at the connection seam, and required per-host working directories. Hosts are managed in-app through a host form with a connection test and TOFU prompt, and the composer bar carries a machine selection chip backed by a persisted preference.
Sessions pick up the remote context: the system prompt and JSONL header record the machine's working directory, and the bash tool gets a file-exploration guideline. Tool-call display follows pi's renderCall grammar, and every SSH connection failure maps to a distinct, actionable message in the UI.
Custom markdown rendering is replaced by multiplatform-markdown-renderer, parsed once in the ViewModel instead of per composition, and conversation text is selectable. User-facing strings and errors resolve from resources, ChatViewModel is decomposed into SSH session, provider credentials, and model settings controllers, the provider page gains model search, and the screen stays awake while a response streams.
Logging moves to slf4j with an in-repo logcat binding and per-class tags, gated by build type, plus lifecycle logging across the SSH seam. Diff rendering now uses java-diff-utils instead of a hand-rolled Myers implementation, and the project is licensed under GPL-3.0-or-later.
v0.5.0
Ports pi's SettingsManager stack into the coding-agent core, with DataStore-backed settings storage in the app. AgentSession now runs on a single repository-backed SettingsManager, including scoped models and thinking-level switching, and the app's own ModelSettings persistence and SessionSeeding are gone in favor of pi's createAgentSession factory.
Session behavior moves closer to pi: preflight and compaction checkpoints, manual compaction, the abort contract and next-turn refresh, summarization guards and cut-point math, and pi's session test suite ported to Kotlin. The session tree is consolidated into SessionManager behind a read-only view, tree rows project from the ported getTree, and web_search is reworked as Pathfinder-owned tool code.
Performance: streaming delivery is decoupled from the Main thread, transcript recomposition and parsing hot paths are eliminated, session listing and appends are cheaper, session summary refreshes are coalesced to once per agent run, and snapshot content is cached per block to avoid quadratic per-delta cost.
v0.4.0
Replaces the app's custom session store with a port of pi's SessionManager: JSONL persistence, recovery, conversation trees, and compaction now follow pi's semantics, with pi's session-manager test suite ported to Kotlin.
The transcript is now rendered directly from runtime messages instead of mirrored DTOs: tool executions render as one row per call, like pi, and the streaming row survives the persistence write.
Smaller changes: OAuth login for sole-OAuth providers starts straight from the provider row, session search filters refreshed summaries, and search results drop provenance narration.
v0.3.0
Adds session search: the session selector drawer now searches across session content, using pi's session-selector matcher ported as pure Kotlin.
The transcript now follows streaming output only while pinned to the bottom, so reading earlier messages during a response no longer jumps the view.
Smaller changes: the send button is hidden for empty drafts, and the composer and tree search show placeholders.
v0.2.0
v0.1.0
Full Changelog: https://github.com/resolveworks/pathfinder/commits/v0.1.0