Unified · Split
| @@ -0,0 +1,10 @@ | ||
| 1 | +--- | |
| 2 | +"@executor-js/sdk": patch | |
| 3 | +"@executor-js/execution": patch | |
| 4 | +--- | |
| 5 | + | |
| 6 | +**Fix: a filtered tools read no longer waits on unrelated integrations' catalog refreshes** | |
| 7 | + | |
| 8 | +`tools.list` refreshes stale tool catalogs before it answers, and each refresh is a live upstream handshake. That scan ignored the read's own filter, so `GET /api/tools?integration=railway` re-listed every stale connection in the workspace — thirteen sequential handshakes for integrations the caller had not asked for, none of them railway. The scan also applied the remote-catalog freshness TTL globally, so any connection older than the TTL was fetched in full and then discarded by a per-row check. | |
| 9 | + | |
| 10 | +The refresh now scopes to the same `integration`/`owner`/`connection` filter the read uses, narrows the TTL and config-revision triggers to the integrations they can actually fire for, projects only the four columns it reads, and runs the remaining refreshes concurrently instead of one at a time. A plugin defect raised during a refresh can no longer fail the read. Tool search's empty-query enumeration pushes its namespace into the read for the same reason. | |
| @@ -37,6 +37,18 @@ join the same traces via traceparent). · 36 unmodified lines | ||
| 37 | 37 | `mcp.tool.integration`, same outcome attrs. |
| 38 | 38 | - `plugin.openapi.invoke` — `plugin.openapi.method` / `path_template` / |
| 39 | 39 | `base_url`, and since PR #992 `http.status_code`. |
| 40 | +- `executor.tools.list` — `executor.tools.filter.integration` / `.owner` / | |
| 41 | + `.connection` (present only when the read was filtered), | |
| 42 | + `executor.tools.result_count`, and the catalog-refresh counters | |
| 43 | + `executor.tools.sync.candidates` (rows the stale scan returned) / | |
| 44 | + `executor.tools.sync.synced`. A slow tools read is almost always | |
| 45 | + `candidates` > 0: subtract the child span durations to confirm. | |
| 46 | +- `executor.tools.sync` (child of the above, one per refreshed connection; | |
| 47 | + older spans carry the previous name `executor.tools.sync_stale` and no | |
| 48 | + trigger/outcome attrs) — `executor.integration`, | |
| 49 | + `executor.connection`, `executor.tools.sync.trigger` | |
| 50 | + (`stale_marked`/`config_revised`/`expired`) and | |
| 51 | + `executor.tools.sync.outcome` (`ok`/`fail`). | |
| 40 | 52 | - `mcp.request` (outer) — `mcp.auth.organization_id`, |
| 41 | 53 | `mcp.auth.account_id`, `mcp.tool.name`, CF edge fields (`cf.country`…), |
| 42 | 54 | MCP client fingerprint (`mcp.client.name`…). |