CL-6492: report real connector status to agents - #225
Merged
Merged
Conversation
…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.
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.
Root cause
list_connections— the tool an agent calls to check what it can use — resolved every connector's status throughlistConnectedProviders(packages/chat/src/inference-preferences.ts:42), wired into the workflow route atapps/hub/src/index.ts(createWorkflowConnectionRoutes({ listConnectedProviders: (tenantId) => listConnectedProviders(db, tenantId) })).listConnectedProvidersanswers fromlistVisibleProviders(vendor/intx/db/src/catalog-resolution.ts:74), which reads the model catalog'smodelProvidertable — a tablepersistConnectorCredential(packages/connections/src/persist-credential.ts:154) only seeds viaseedCatalogwhenisInferenceProvider(descriptor.id)is true. A GitHub/Linear/Notion/Sentry/Exa credential is written to the genericprovider+credentialtables (ensureProvider+ensureCredential) but never reachesmodelProvider. SocreateWorkflowConnectionRoutes's/connectionsroute (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 /connectionsnow resolves eachCONNECTOR_REGISTRYentry throughresolveCredentialRequirement(@intx/db,vendor/intx/db/src/credential-resolution.ts:153) keyed on the connector's registryidas its provider name — the same resolutionbuildCredentialDeliveryuses at agent-launch time to decide whether a tool actually gets a credential delivered. This is one uniform check for both connector kinds:persistConnectorCredential'sdisplayName-named row or an onboarding seed's<id>-defaultrow —resolveCredentialRequirementdoesn't key on credential name at all, onlyproviderId+ tenant ancestry +status: "active".persistConnectorCredentialalways creates aproviderrow nameddescriptor.idbefore the credential row, for every connector kind.No special-casing at the call site —
packages/connections/src/workflow-connection-routes.ts's newisConnectorConnected(tenantId, connectorId)port is the only thing the route calls per descriptor.apps/hub/src/index.tsnow wires that port toresolveCredentialRequirement(db, tenantId, { providerName: connectorId, source: "tenant" }, null, null), replacing thelistConnectedProvidersdependency for this route only —listConnectedProvidersitself 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:connected: trueonce its port says soconnected: falseVerified these fail against the pre-fix code (interface mismatch — old code called the removed
listConnectedProvidersdep) and pass against the fix.bun test packages/connections/(218 pass) andbun test workflows/assistant/(26 pass, checked for the response-shape ripple below) are green.bun run lintis clean (0 errors). A repo-rootbun run checkwas still running when this PR was opened — CI will cover it.Ripple check (fixture shapes)
Grepped for anything hand-mocking the
/api/workflow-connections/connectionsresponse shape orlist_connections' tool contract, since neither changed (ConnectionSummaryis still{id, displayName, docsUrl, connected}; the tool's text format is unchanged) — only howconnectedgets computed server-side:workflows/assistant/test/manager-tools-scenario.test.tsfakes the HTTP fetch layer directly against the unchanged wire shape; doesn't exercisecreateWorkflowConnectionRoutesat all. Ran green.packages/evals/src/scorers/*,packages/evals/src/targets/trace.test.tsoperate 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'slistPluginsForTenant, correct), while the agent's ownlist_connectionscall 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.persistConnectorCredential's write (see the comment atapps/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.list_connections/credential resolution) based onpackages/plugins-ui/src/mcp-preset-cards.tsxand 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_connectionsis fixed, rather than closing either off this PR's evidence alone.Not verified
bun run checkto completion before opening (per instruction to open the PR promptly; CI will run it).resolveCredentialRequirementend-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