Skip to content

CL-6492: report real connector status to agents - #225

Merged
TheGreatAxios merged 1 commit into
mainfrom
cl-6492-connections-status
Aug 21, 2026
Merged

TheGreatAxios merged 1 commit into
mainfrom
cl-6492-connections-status

Conversation

@TheGreatAxios

Copy link
Copy Markdown
Contributor

Root cause

list_connections — the tool an agent calls to check what it can use — resolved every connector's status through listConnectedProviders (packages/chat/src/inference-preferences.ts:42), wired into the workflow route at apps/hub/src/index.ts (createWorkflowConnectionRoutes({ listConnectedProviders: (tenantId) => listConnectedProviders(db, tenantId) })).

listConnectedProviders answers from listVisibleProviders (vendor/intx/db/src/catalog-resolution.ts:74), which reads the model catalog's modelProvider table — a table persistConnectorCredential (packages/connections/src/persist-credential.ts:154) only seeds via seedCatalog when isInferenceProvider(descriptor.id) is true. A GitHub/Linear/Notion/Sentry/Exa credential is written to the generic provider + credential tables (ensureProvider + ensureCredential) but never reaches modelProvider. So createWorkflowConnectionRoutes's /connections route (packages/connections/src/workflow-connection-routes.ts:119-133, pre-fix) always reported every non-inference connector "not connected," regardless of a real, verified credential — and the agent correctly declined to use a tool it believed wasn't connected.

Fix

GET /connections now resolves each CONNECTOR_REGISTRY entry through resolveCredentialRequirement (@intx/db, vendor/intx/db/src/credential-resolution.ts:153) keyed on the connector's registry id as its provider name — the same resolution buildCredentialDelivery uses at agent-launch time to decide whether a tool actually gets a credential delivered. This is one uniform check for both connector kinds:

  • An inference provider's credential resolves the same way whether it was written under persistConnectorCredential's displayName-named row or an onboarding seed's <id>-default row — resolveCredentialRequirement doesn't key on credential name at all, only providerId + tenant ancestry + status: "active".
  • A tool connector (GitHub, Linear, ...) resolves through the exact same call, since persistConnectorCredential always creates a provider row named descriptor.id before the credential row, for every connector kind.

No special-casing at the call site — packages/connections/src/workflow-connection-routes.ts's new isConnectorConnected(tenantId, connectorId) port is the only thing the route calls per descriptor.

apps/hub/src/index.ts now wires that port to resolveCredentialRequirement(db, tenantId, { providerName: connectorId, source: "tenant" }, null, null), replacing the listConnectedProviders dependency for this route only — listConnectedProviders itself is untouched and still correctly backs inference preferences and the provider-health banner, which do want the catalog's view.

Tests

packages/connections/src/workflow-connection-routes.test.ts — new/updated cases:

  • a non-inference connector (GitHub) reports connected: true once its port says so
  • an unconnected connector still reports connected: false
  • an inference provider (Anthropic) still reports connected
  • auth-gate ordering preserved (dep never called before authentication)

Verified these fail against the pre-fix code (interface mismatch — old code called the removed listConnectedProviders dep) and pass against the fix. bun test packages/connections/ (218 pass) and bun test workflows/assistant/ (26 pass, checked for the response-shape ripple below) are green. bun run lint is clean (0 errors). A repo-root bun run check was still running when this PR was opened — CI will cover it.

Ripple check (fixture shapes)

Grepped for anything hand-mocking the /api/workflow-connections/connections response shape or list_connections' tool contract, since neither changed (ConnectionSummary is still {id, displayName, docsUrl, connected}; the tool's text format is unchanged) — only how connected gets computed server-side:

  • workflows/assistant/test/manager-tools-scenario.test.ts fakes the HTTP fetch layer directly against the unchanged wire shape; doesn't exercise createWorkflowConnectionRoutes at all. Ran green.
  • packages/evals/src/scorers/*, packages/evals/src/targets/trace.test.ts operate on tool-call transcripts (tool names), not route internals. Unaffected.

Ripple onto CL-6463 / CL-6472 (evidence only — not closing either)

The owner's original symptom — "Plugins says GitHub is connected but the chat UI didn't move forward" — is explained by exactly this bug: the Plugins page resolves status through the real credential/connector layer (packages/connections/src/plugins.ts's listPluginsForTenant, correct), while the agent's own list_connections call resolved through the wrong (inference-only) table. This fix makes that story coherent for any case where the block was the agent's own belief about connection state.

  • CL-6463 (the in-room GitHub connect card not flipping to connected after a PAT submit) already has its own, different, already-merged fix in this codebase — a credential-row-naming mismatch between the card's read and persistConnectorCredential's write (see the comment at apps/hub/src/index.ts:1979). That's a distinct bug from this one; this PR doesn't touch it. If the owner's repro was specifically about that in-room card, CL-6463's existing fix is likely what already covers it, not this PR.
  • CL-6472 (MCP presets not reaching a fresh bench's Plugins gallery) looks like a different mechanism entirely (preset-to-gallery rendering, not list_connections/credential resolution) based on packages/plugins-ui/src/mcp-preset-cards.tsx and its tests. This PR doesn't appear to bear on it.

Recommend the ticket owner re-check both against a live repro now that list_connections is fixed, rather than closing either off this PR's evidence alone.

Not verified

  • Did not run the full repo-root bun run check to completion before opening (per instruction to open the PR promptly; CI will run it).
  • Did not stand up a real Postgres-backed integration test exercising resolveCredentialRequirement end-to-end with a seeded GitHub credential row — the test coverage here is at the route's dependency-injection boundary (matching this file's existing test style), not a full DB integration test.

Fixes CL-6492

…he inference catalog

list_connections resolved every connector's status through
listConnectedProviders, which answers from the model catalog
(modelProvider) — a table persistConnectorCredential only seeds for
inference providers. A verified GitHub/Linear/Notion/Sentry/Exa
credential never reaches that table, so the tool always reported those
connectors "Not connected" even when a live credential existed, and the
agent correctly declined work it could actually do.

createWorkflowConnectionRoutes' /connections route now resolves each
CONNECTOR_REGISTRY entry through resolveCredentialRequirement (@intx/db)
keyed by the connector's registry id as its provider name — the same
resolution buildCredentialDelivery uses at agent-launch time to decide
whether a tool actually gets a credential. This covers an inference
provider and a tool connector the same way, with no per-kind branch at
the call site.
@TheGreatAxios
TheGreatAxios merged commit 169f4e0 into main Aug 21, 2026
2 checks passed
@TheGreatAxios
TheGreatAxios deleted the cl-6492-connections-status branch August 25, 2026 15:29
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