feat(agentic,web-ui): task tool UI, explore region, and session event wiring#672
Merged
Conversation
added 2 commits
May 12, 2026 11:46
… wiring - Surface task tool progress and state in Flow Chat (cards, stores, persistence, i18n). - Refine Explore region layout and grouping in modern flow chat. - Extend deep review manifest and coordinator/task tool paths; trim task adapter duplication. - Plumb session-related agentic fields through events, services-core, and transport adapters. - Update desktop tray and simplify AppLayout.
Keeps test helpers in sync with bitfun_services_core::session::ToolItemData after subagent_model_id / subagent_model_alias were added.
11 tasks
bobleer
added a commit
that referenced
this pull request
May 12, 2026
…ack persistence, companion typewriter (#674) * docs(agents): add remote compatibility and agent loop guidance Document two recurring engineering principles so new contributors do not silently regress them: - Remote compatibility: features must consider remote workspace and remote-control synchronization from the start; otherwise gate them or show an explicit unsupported message instead of failing with a generic error. - Agent loop behavior: do not respond to looping by hard-coding limits or pattern checks first; investigate root causes (tool behavior, model interaction, context packaging, prompt/tool schema, state synchronization) instead of letting the loop become a brittle workflow engine. * fix(stream): dedupe finalized tool calls and align finish_reason placement Three related stream-handling regressions surfaced when providers emit parallel tool calls or echo a finalized tool call in trailing chunks: - agent-stream: track finalized tool_call ids in a HashSet so a duplicated finalized call from the trailing chunk no longer produces a second ToolCall entry. Adds a regression test that feeds the same finalized tool call twice and asserts only one is emitted. - ai-adapters/openai: stop attaching finish_reason to the first response/text chunk and instead carry it to the last response in the batch (creating a synthetic empty response if needed). Existing tests are flipped to assert the new placement. - ai-adapters/gemini: index parallel functionCall parts via tool_call_index so the GeminiToolCallState assigns distinct ids to same-named calls that share a candidate. Mirror the OpenAI change so finish_reason rides on the last unified response. Tests cover the parallel-function-call payload and same-name-different-index id assignment. Together these prevent downstream tool pipelines from receiving a phantom duplicate tool invocation or losing the terminating finish_reason when the last chunk carries a tool call. * fix(round-executor): accept stream partial recovery without retrying the round Retrying after a partial-recovery stream forced the model to redo work it had already produced (the partial tokens were still cached in the session/context), which manifested as duplicated tool calls and wasted budget when a provider chunk dropped near the end of a round. Drop the retry branch and accept the recovered partial result instead, logging the reason for diagnostics. Pure formatting fix-ups elsewhere in the file are kept to keep `cargo fmt` clean. * fix(session): rollback also removes persisted dialog turn files `rollback_context_to_turn_start` was only deleting context snapshots, so runtime restore — which rebuilds history from persisted turn files — made the rolled-back prompts reappear on next session reload, undoing the rollback the user just performed. Persisted turn_count was also clamped by the previous metadata, leaving stale counters after a rollback. - PersistenceManager: add `delete_dialog_turns_from(workspace, session, turn_index)` that deletes `turn-N.json` files at or after the index and rewrites session metadata (turn_count / message_count / tool_call_count / last_active_at). Stop saturating turn_count with the previous metadata so rollbacks shrink it correctly. - SessionManager: invoke the new turn-deletion path before clearing context snapshots when persistence is enabled. Add an integration test that creates three persisted turns, rolls back to turn 1, verifies only turn 0 remains on disk and after restore, and confirms metadata.turn_count reflects the rollback. * feat(search): support remote filename search and content fallback chain Workspace search behavior was missing two capabilities that hurt remote users: filename search silently fell back to local-only execution for remote workspaces, and Content-mode searches surfaced "no results" when the bundled flashgrep daemon (v0.2.6) returned only summary statistics during ScanFallback (no indexed repository yet). - desktop/api/commands.rs: when the search root resolves to a remote desktop path target, walk the remote workspace via RemoteFileService with regex-based name matching, the standard ignore list (.git, node_modules, target, etc.), binary-extension skipping, cancellation, and optional progress sink. Both the synchronous `search_filenames` and the streaming `start_search_filenames_stream` commands now route to this remote path. - desktop/api/search_api.rs: reorder availability checks so remote workspace registration / connectivity is validated before the local workspace-search feature flag, otherwise remote users hit a misleading "feature disabled" error first. - core/service/search/{remote,service}.rs: add a Content-mode fallback chain. If hits are empty, try file_counts; if those are empty, try the new file_match_counts (mapped from the daemon's per-file occurrence totals); finally fall back to matched_paths. For remote, when the ScanFallback returns only summary statistics, re-issue the same query in `FilesWithMatches` mode so the user at least sees the matched file list while the index is being built. Surface the failure if the fallback request also fails instead of silently keeping summary-only results. Adds detailed structured logs around the remote re-issue and the post-conversion result counts to make future regressions easier to diagnose. * feat(web-ui): show typewriter latest output in single-task companion bubble The desktop companion pet bubble used to only show the task title and a short status label, so users could not tell what the agent was actually producing without opening the main window. Add a third line that streams the latest assistant output (text or thinking, with markdown stripped to plain text) using a small typewriter effect, but only when exactly one task is active so the multi-task layout is not perturbed. - agentCompanionActivity: derive `latestOutput` from the most recent non-runtime text or thinking item in the tracked dialog turn, truncated to the trailing 512 chars and routed through a markdown stripper. Populate it for both running tasks and completion-state tasks. Tests cover the streaming case (anchored to newest text) and the completed case (final assistant text remains visible). - AgentCompanionDesktopPet: fix bubble width to 146px, render a third `__bubble-output` span with a blinking caret while the visible text is still catching up to the target. Implement the typewriter via a per-session `{target, visible}` state map advanced on a 28ms interval; reuse the longest common suffix-prefix when the target changes mid-stream so unchanged trailing text does not flicker. The `--single` modifier sizes the bubble container to match the pet height so the layout stays compact. * fix(web-ui): keep Write param updates flowing during execution and tighten timeout tooltip Two unrelated UX regressions in the modern flow chat: - Write tool parameters were ignored once the card transitioned into `running`, so any late ParamsPartial events from the streamed body generation never reached the UI and the user saw a stuck snapshot. Allow ParamsPartial through for write-like tools while running, and switch the EventBatcher to a `replace` strategy so a new full-snapshot payload (which the Write tool now emits) overwrites instead of concatenating with the previous chunk. Also stop publishing the internal silent-update path for `processToolParamsPartialInternal` callers and only compute `_contentSize` for write tools so non-write cards keep their existing card-size heuristics. - ToolTimeoutIndicator: the popover was forced to a 160px minimum width, which cropped CJK localized labels in narrow side panels. Switch to `width: max-content; max-width: 150px` and allow soft breaks via `white-space: normal; overflow-wrap: anywhere`. Pass the live `remainingMs` into `useSubagentTimeoutControl` so the disable-action reflects the current remaining time instead of always re-reading the prop default. * chore: align explore-group tests with upstream and reformat touched modules - web-ui: rename the new explore-group regression assertions from the local `shouldAutoCollapse` to upstream's `wasCutByCritical` field so the tests run against the renderer landed in upstream PR #672. The boolean semantics are preserved (false = group is still the tail and stays expanded; true = a critical/non-explore round or turn completion has cut it and it should auto-collapse). - core: apply `cargo fmt` cleanups to deep_review/manifest, code_review_tool, and tool_pipeline so the workspace stays rustfmt-clean against the modules touched by surrounding fixes. No behavior change.
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.
Summary
Verification
cargo check(bitfun-core, bitfun-desktop, bitfun-transport, bitfun-events, bitfun-services-core)pnpm run type-check:web