Skip to content

feat(agentic,web-ui): task tool UI, explore region, and session event wiring#672

Merged
GCWing merged 2 commits into
mainfrom
gcwing/dev
May 12, 2026
Merged

feat(agentic,web-ui): task tool UI, explore region, and session event wiring#672
GCWing merged 2 commits into
mainfrom
gcwing/dev

Conversation

@GCWing
Copy link
Copy Markdown
Owner

@GCWing GCWing commented May 12, 2026

Summary

  • 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.

Verification

  • cargo check (bitfun-core, bitfun-desktop, bitfun-transport, bitfun-events, bitfun-services-core)
  • pnpm run type-check:web

GCWing 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.
@GCWing GCWing merged commit c6103ea into main May 12, 2026
4 checks passed
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant