Skip to content

Chat link_provider card shows 'Connect Google Calendar' on refresh when already connected #325

Description

@ljagiello

What

In a chat with a historical connect_service tool call, after the OAuth flow completes successfully and the page is refreshed, the embedded LinkProvider card re-renders as an active "Connect Google Calendar" CTA — even though the credential is connected and subsequent calendar tool calls in the same chat work fine.

Repro: chat chat_VjcXp8h3dx, see attached screenshot. Backend confirms /internal/v1/credentials/default/google-calendar returns 200 from 11:28:14 onward; the chat just keeps showing the old "isn't connected yet" copy + a live Connect button.

Why

Two reinforcing problems in tools/agent-playground/src/lib/components/chat/connect-service.svelte:

  1. Component never reconciles connection state at mount. connected is initialized to false and only flips to true when the OAuth callback message fires in the current page session ($effect at line 100). On a fresh page load the listener can't fire — the OAuth dance already completed — so the card re-renders the active "Connect" state.
  2. Persisted tool output is frozen. The assistant's tool-connect_service part in the chat stream stays { progress: { status: "active" } } forever. The successful OAuth arrives as a separate data-credential-linked user-message part rather than mutating the original tool call's output, so even an export/replay sees "still connecting."

tool-call-card.svelte:397-400 unconditionally mounts <ConnectService> whenever a connect_service tool call exists, regardless of whether the credential is now present.

Fix idea

Smallest safe fix: in connect-service.svelte's mount $effect, also query Link for current credential status (e.g. GET /v1/summary or a per-provider check) and set connected = true if the credential already exists — reusing the existing "✓ {provider} connected" success state.

Larger follow-up: update the persisted tool-call output when the credential-linked event arrives, so chat history/export is internally consistent.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions