Short list of changes - - Automations quickstart - Slack mentions router - Live turns keep narration inside. Add commentary for tasks. - Approvals card UI enhancements - Newer models - Fable, Sol, Terra, etc added to list
8.0 KiB
UI Refresh — Verification & Test Plan
Companion to UI-REFRESH-SPEC.md. Defines the test cases, the manual checks,
and the acceptance bar for each phase. The implementing agent must land these (green) alongside the
code. Several integration tests depend on the FakeSlack harness (FAKE-SLACK-SPEC.md) —
build that first.
How to run
- Python:
./.runtests.sh platform/tests/<file> -q(uses the agent-platform venv). Whole suite:./.runtests.sh platform/tests/ -q. Baseline is green except 3 pre-existing SDK-import failures (test_anthropic_provider,test_gemini_provider,test_provider_router) — unrelated; don't "fix" by mocking the SDK. - Frontend:
cd platform/surfaces/gui && npx tsc --noEmit(must be clean) andnpm run build. - Server under the aisuite venv:
PYTHONPATH=platform /Users/rohit/fleet/ro4d/aisuite/platform/.venv/bin/python -m coworker.server.run --port 8765. Dev GUI on :1420 defaults to backend 8765.
Conventions
- Backend unit tests use
ScriptedProvider+SessionManager(workspace=tmp_path, provider=…)andTestClient(create_app(mgr))(seetest_session_events.py,test_subscriptions.py). - Messaging integration tests use FakeSlack instead of the network: point the Slack adapter at the
fake, drive inbound/button events through the fake's control API, assert on outbound calls it
recorded. No
COWORKER_DEBUG_INJECT, no real tokens.
Phase 1 — connector registry + contract
Unit
test_descriptor_brand_logo: every descriptor exposesbrand_color(hex) +logo;/v1/connectorssurfaces them; an unknown/placeholder connector still returns a color (fallback gray) +logo.test_placeholder_connectors_listed: github/datadog/salesforce/hubspot/pagerduty appear asavailable:falseso personas can recommend them; they have noconnect.test_slack_resolve_channel_name:_channel_name(id)returns the resolved name, caches (oneconversations.infocall for repeats), returnsNoneon failure. (Pattern mirrors the existingtest_slack_resolves_and_caches_display_name.)
Frontend
ConnectorIcon/ConnectorBadgerenders the registry SVG for a known id and the fallback for an unknown id; brand color applied from prop. (Component test or a Storybook-style render assertion.)
Manual: Integrations → Connectors shows correct logos/colors incl. a placeholder (e.g. Datadog) with the fallback-or-brand badge.
Phase 2 — structured connector messages
Unit
test_inbound_builds_message_source:_dispatch_inboundof a channelMessageEvent(withuser_name,chat_nameset) delivers to the subscribed session with aMessageSource(connector/kind/channel_id/channel_name/sender_id/sender_name/ts/text).test_message_source_persisted_and_stripped: after the turn,GET /v1/sessions/{id}/messagesreturns the user message withsource; the provider received the framed text and nosource/unknown keys (assert against theScriptedProvider's capturedmessages).test_turn_start_carries_source: the WSturn_startevent for a delivered connector message includessource(register a fake session client, liketest_session_events.py).test_dm_message_source_kind_dm: a DM yieldskind="dm".
Frontend
itemsFromMessagesmaps a message withsource.connectorto aconnectoritem;turn_startwithsourcerendersConnectorMessageCard(not a plain bubble). Hover swaps names→ids.
Manual (FakeSlack): post a channel message via FakeSlack → the session's open view shows the
connector card live (names, hover→ids, ts); reselect the session → the card persists (re-rendered
from /messages).
Phase 3 — connection hierarchy
Unit (test_connections.py, new)
test_persona_defaults_seeded_from_manifest:PersonaConnectionStore.defaults_for(ops, manifest)→ core+connected recommends on, others off; persisted after first read.test_effective_resolution: withconnected={slack,github}, persona-default{slack:on, github:on, datadog:off}, session override{slack:off}→ effective{github:on}(slack muted, datadog not connected).test_session_override_clear_inherits: clearing a session override returns to persona default.test_remove_session_clears_overrides: deleting a session drops its overrides.
Runtime gating
test_muted_connector_not_delivered: a session subscribed to a Slack channel but with Slack muted (session override off) does not receive_dispatch_inboundfor that channel (still buffered).test_muted_connector_tools_absent: building that session's engine omits the connector's tools.test_dm_muted_session_not_delivered: DM routed to a session with the connector muted is parked/ skipped, not delivered.
Manual: in a session's Sources drawer, toggle Slack off → posting in the subscribed channel no longer wakes the session; toggle on → it resumes. Confirm the persona-level default is unchanged.
Phase 4 — persona + session connection surfaces
Unit (TestClient)
test_persona_detail_endpoint:GET /v1/personas/opsreturns identity, tools,recommendswithconnectedannotated, anddefault_connections.test_persona_set_default_connection:POST /v1/personas/ops/connections {github,false}flips the persona default; reflected in the next GET and in new sessions' effective set.test_persona_enable_toggle:POST /v1/personas/ops/enable {false}removes it from the/v1/personaspicker list.test_session_connections_endpoint:GET /v1/sessions/{id}/connectionsreturns connected + recommended +attention= count of not-yet-connected recommends.test_session_set_override:POST /v1/sessions/{id}/connections {slack,false}sets the override; effective resolution +GETreflect it.
Frontend
- PersonaView renders detail from the endpoint; toggling a default connection POSTs and re-reads.
- SourcesBar shows
⚠ N= attention; opening the drawer lists connected (with working toggles) + recommended (Connect/Add).
Manual: open a persona's gear → detail page shows recommends with reasons + connect state + the "new sessions get by default" toggles; flip one and start a new session of that persona → the default is reflected in its Sources drawer.
Phase 5 — frontend polish
Frontend / manual
- Integrations sub-nav (Connectors/Messaging/Activity/MCP); the three messaging controls live under "Messaging routing"; Unrouted under "Activity".
- Sidebar layout toggle persists across reload (prefs
nav_layout); grouped view shows bounded per-persona cards with a working gear. - New-session split button: primary starts last/default persona; ▾ lists enabled personas + opens PersonaView via "Manage personas…".
- StepGroup: tool/approval items render collapsed ("N actions · M approvals ✓"), expandable.
npx tsc --noEmitclean;npm run buildsucceeds.
Cross-cutting acceptance (end-to-end, via FakeSlack)
A single scripted scenario the FakeSlack harness can drive, asserting the whole refresh:
- Connect Slack (against FakeSlack); allow a user; subscribe the Ops "incident" session to a channel.
- Post a channel message → session shows the connector card live (resolved names).
- Agent proposes a tool needing approval; session is Unattended with approvals routed to a channel → FakeSlack receives a Block Kit card; inject the Approve click → turn resumes, reply posts back to the origin channel (FakeSlack records the outbound).
- Mute Slack for the session in the drawer → a further channel post does not wake it.
GET /v1/sessions/{id}/connectionsattentionmatches the persona's unconnected recommends.
This scenario lives as test_ui_refresh_e2e.py against FakeSlack and is the merge gate.
Regression bar
- Whole suite green (minus the 3 known SDK-import failures).
- No real-network calls in tests (grep the diff for
slack.com, real tokens — there should be none outside FakeSlack config). tsc --noEmitclean;npm run buildpasses.