Convert transport.request() to typed ES client methods#256456
Conversation
Replace transport.request() with typed esClient.search() in the Search Playground's ElasticsearchRetriever. Remove explicit project_routing (CPS handler injects it automatically for typed methods). Remove unused AggregationsAggregate and SearchResponse imports. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace transport.request() calls with typed elasticsearch-js client
methods in the Security Solution ES|QL request executor:
- POST /_query/async -> esClient.esql.asyncQuery()
- GET /_query/async/${id} -> esClient.esql.asyncQueryGet()
- DELETE /_query/async/${id} -> esClient.esql.asyncQueryDelete()
Remove explicit project_routing from submit body (CPS handler injects
it automatically for typed methods). Cast response to AsyncEsqlResponse
via unknown since the local type uses narrower column/value types than
the ES client's EsqlAsyncQueryResponse.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Pinging @elastic/obs-ai-team (Team:obs-ai) |
🤖 GitHub commentsExpand to view the GitHub comments
Just comment with:
|
| path: `/_query/async`, | ||
| body: params, | ||
| querystring: dropNullColumns ? 'drop_null_columns' : '', | ||
| ...params, |
There was a problem hiding this comment.
As noted in https://github.com/elastic/kibana-team/issues/2886 ES|QL search strategy often uses transport.request as a way to quickly adopt new ES features before the specs are available.
While I converted to the typed API method now, if we ever get blocked by specs we can safely convert it back to a transport.request using project_routing: '_alias:_origin' as the default for when project_routing isn't specified by the caller.
viduni94
left a comment
There was a problem hiding this comment.
Obs AI changes LGTM (CR only)
nreese
left a comment
There was a problem hiding this comment.
kibana-presentation changes LGTM
code review only
Use the ES client return types directly instead of double-casting through `unknown`. Adds a runtime guard for the optional `id` field and removes the redundant local `AsyncEsqlResponse` type. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
TattdCodeMonkey
left a comment
There was a problem hiding this comment.
search changes LGTM, but left some comments related to typescript
lukasolson
left a comment
There was a problem hiding this comment.
I opened a PR against this branch to clean up a few things: #256523
| { | ||
| method: 'GET', | ||
| path: `/_query/async/${id}`, | ||
| id: id!, |
rylnd
left a comment
There was a problem hiding this comment.
Detection Engine changes LGTM.
| body: requestBody, | ||
| querystring: requestQueryParams, | ||
| const asyncEsqlResponse = await esClient.esql.asyncQuery({ | ||
| ...requestBody, |
There was a problem hiding this comment.
For posterity: while requestQueryParams is only ever { drop_null_columns?: boolean }, which I see handled similarly elsewhere, requestBody contains both query and filter keys, both of which are top-level params to asyncQuery 👍
## Summary Fixing some type issues in #256456. This is PR against the branch from that PR (not main)
…_async_search/esql_async_search_strategy.test.ts Co-authored-by: Marco Vettorello <marco.vettorello@elastic.co>
Replace transport.request() calls with typed elasticsearch-js client
methods:
- POST /_query/async -> esClient.esql.asyncQuery()
- GET /_query/async/${id} -> esClient.esql.asyncQueryGet()
- POST /_query/async/${id}/stop -> esClient.esql.asyncQueryStop()
- DELETE /_query/async/${id} -> esClient.esql.asyncQueryDelete()
Typed methods include meta.acceptedParams so the CPS OnRequestHandler
automatically injects project_routing — no explicit injection needed.
Also fixes the incorrect SqlGetAsyncResponse type to EsqlAsyncEsqlResult.
Inspired by elastic#256456.
Made-with: Cursor
- Remove stray `);` syntax error in esql_async_search_strategy.test.ts - Set queryId before early return in esql_request.ts so completed queries are cleaned up - Update FTR test assertions for `drop_null_columns=true` query param serialization Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace transport.request() calls with typed elasticsearch-js client
methods:
- POST /_query/async -> esClient.esql.asyncQuery()
- GET /_query/async/${id} -> esClient.esql.asyncQueryGet()
- POST /_query/async/${id}/stop -> esClient.esql.asyncQueryStop()
- DELETE /_query/async/${id} -> esClient.esql.asyncQueryDelete()
Typed methods include meta.acceptedParams so the CPS OnRequestHandler
automatically injects project_routing — no explicit injection needed.
Also fixes the incorrect SqlGetAsyncResponse type to EsqlAsyncEsqlResult.
Inspired by elastic#256456.
Made-with: Cursor
Replace transport.request() calls with typed elasticsearch-js client
methods:
- POST /_query/async -> esClient.esql.asyncQuery()
- GET /_query/async/${id} -> esClient.esql.asyncQueryGet()
- POST /_query/async/${id}/stop -> esClient.esql.asyncQueryStop()
- DELETE /_query/async/${id} -> esClient.esql.asyncQueryDelete()
Typed methods include meta.acceptedParams so the CPS OnRequestHandler
automatically injects project_routing — no explicit injection needed.
Also fixes the incorrect SqlGetAsyncResponse type to EsqlAsyncEsqlResult.
Inspired by elastic#256456.
Made-with: Cursor
Replace transport.request() calls with typed elasticsearch-js client
methods:
- POST /_query/async -> esClient.esql.asyncQuery()
- GET /_query/async/${id} -> esClient.esql.asyncQueryGet()
- POST /_query/async/${id}/stop -> esClient.esql.asyncQueryStop()
- DELETE /_query/async/${id} -> esClient.esql.asyncQueryDelete()
Typed methods include meta.acceptedParams so the CPS OnRequestHandler
automatically injects project_routing — no explicit injection needed.
Also fixes the incorrect SqlGetAsyncResponse type to EsqlAsyncEsqlResult.
Inspired by elastic#256456.
Made-with: Cursor
## Summary 1. In this one: #256456 we accidentally patched Maps mvt routes with only supporting local project routing, but we shouldn't have, as CPS is supported on Maps (the setting should be taken from the project picker) 2. In this PR I also removed a setting from the cps picker, since it cannot be linked for tech preview <img width="932" height="263" alt="Screenshot 2026-03-13 at 16 41 35" src="https://github.com/user-attachments/assets/ec12dcf5-3a9d-4597-bda6-1573b4f9247d" />
## Summary Partially addresses elastic/kibana-team#2886 Further iteration on #256430 — converts `transport.request()` calls to typed elasticsearch-js client methods where feasible, improving type safety and ensuring CPS `project_routing` is automatically handled by the client library. **Converted (4 call sites):** - `elasticsearch_retriever.ts` → `esClient.search()` — Search Playground RAG retriever - `esql_request.ts` → `esql.asyncQuery()` / `asyncQueryGet()` / `asyncQueryDelete()` — Security detection engine ES|QL executor - `esql_search_strategy.ts` → `esql.query()` — Synchronous ES|QL search (Discover/Lens) - `esql_async_search_strategy.ts` → `esql.asyncQuery()` / `asyncQueryGet()` / `asyncQueryStop()` / `asyncQueryDelete()` — Async ES|QL search. Also fixed incorrect `SqlGetAsyncResponse` type → `EsqlAsyncQueryResponse` **Remaining as transport.request (2 call sites):** - `mvt_routes.ts` — Maps MVT tiles. Requires restructuring `getTile()` helper and tile request builders to pass `index`/`field`/`zoom`/`x`/`y` as separate params instead of a pre-built path string - `observability_ai_assistant elasticsearch.ts` — Dynamic caller by design, method/path determined at runtime by AI **Why typed methods are better for CPS:** Typed client methods already include `meta.acceptedParams` in their implementation, so the CPS handler automatically injects `project_routing` — no explicit injection or annotation needed. The two remaining `transport.request` callers use explicit `project_routing: '_alias:_origin'` injection (stripped automatically when CPS is disabled). ## Test plan - [x] `conversational_chain.test.ts` — 12/12 pass (updated mocks from `transport.request` to `search()`) - [x] `esql_request.test.ts` — all pass (updated mocks to typed esql methods) - [x] `esql.test.ts` — 5/5 pass (updated mocks) - [x] `esql_async_search_strategy.test.ts` — 15/15 pass (updated mocks + assertions) - [x] `async_utils.test.ts` — 16/16 pass - [x] `es_search_strategy.test.ts` + `ese_search_strategy.test.ts` — 35/35 pass (regression check) - [x] `cps_request_handler.test.ts` — 38/38 pass (CPS handler sanity check) - [x] `mvt_routes.test.ts` — pass - [x] Typecheck passes for all affected plugins 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Lukas Olson <lukas@elastic.co> Co-authored-by: Marco Vettorello <marco.vettorello@elastic.co>
## Summary 1. In this one: #256456 we accidentally patched Maps mvt routes with only supporting local project routing, but we shouldn't have, as CPS is supported on Maps (the setting should be taken from the project picker) 2. In this PR I also removed a setting from the cps picker, since it cannot be linked for tech preview <img width="932" height="263" alt="Screenshot 2026-03-13 at 16 41 35" src="https://github.com/user-attachments/assets/ec12dcf5-3a9d-4597-bda6-1573b4f9247d" />
## Summary Partially addresses elastic/kibana-team#2886 Further iteration on elastic#256430 — converts `transport.request()` calls to typed elasticsearch-js client methods where feasible, improving type safety and ensuring CPS `project_routing` is automatically handled by the client library. **Converted (4 call sites):** - `elasticsearch_retriever.ts` → `esClient.search()` — Search Playground RAG retriever - `esql_request.ts` → `esql.asyncQuery()` / `asyncQueryGet()` / `asyncQueryDelete()` — Security detection engine ES|QL executor - `esql_search_strategy.ts` → `esql.query()` — Synchronous ES|QL search (Discover/Lens) - `esql_async_search_strategy.ts` → `esql.asyncQuery()` / `asyncQueryGet()` / `asyncQueryStop()` / `asyncQueryDelete()` — Async ES|QL search. Also fixed incorrect `SqlGetAsyncResponse` type → `EsqlAsyncQueryResponse` **Remaining as transport.request (2 call sites):** - `mvt_routes.ts` — Maps MVT tiles. Requires restructuring `getTile()` helper and tile request builders to pass `index`/`field`/`zoom`/`x`/`y` as separate params instead of a pre-built path string - `observability_ai_assistant elasticsearch.ts` — Dynamic caller by design, method/path determined at runtime by AI **Why typed methods are better for CPS:** Typed client methods already include `meta.acceptedParams` in their implementation, so the CPS handler automatically injects `project_routing` — no explicit injection or annotation needed. The two remaining `transport.request` callers use explicit `project_routing: '_alias:_origin'` injection (stripped automatically when CPS is disabled). ## Test plan - [x] `conversational_chain.test.ts` — 12/12 pass (updated mocks from `transport.request` to `search()`) - [x] `esql_request.test.ts` — all pass (updated mocks to typed esql methods) - [x] `esql.test.ts` — 5/5 pass (updated mocks) - [x] `esql_async_search_strategy.test.ts` — 15/15 pass (updated mocks + assertions) - [x] `async_utils.test.ts` — 16/16 pass - [x] `es_search_strategy.test.ts` + `ese_search_strategy.test.ts` — 35/35 pass (regression check) - [x] `cps_request_handler.test.ts` — 38/38 pass (CPS handler sanity check) - [x] `mvt_routes.test.ts` — pass - [x] Typecheck passes for all affected plugins 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Lukas Olson <lukas@elastic.co> Co-authored-by: Marco Vettorello <marco.vettorello@elastic.co>
…7706) ## Summary 1. In this one: elastic#256456 we accidentally patched Maps mvt routes with only supporting local project routing, but we shouldn't have, as CPS is supported on Maps (the setting should be taken from the project picker) 2. In this PR I also removed a setting from the cps picker, since it cannot be linked for tech preview <img width="932" height="263" alt="Screenshot 2026-03-13 at 16 41 35" src="https://github.com/user-attachments/assets/ec12dcf5-3a9d-4597-bda6-1573b4f9247d" />
Summary
Partially addresses https://github.com/elastic/kibana-team/issues/2886
Further iteration on #256430 — converts
transport.request()calls to typed elasticsearch-js client methods where feasible, improving type safety and ensuring CPSproject_routingis automatically handled by the client library.Converted (4 call sites):
elasticsearch_retriever.ts→esClient.search()— Search Playground RAG retrieveresql_request.ts→esql.asyncQuery()/asyncQueryGet()/asyncQueryDelete()— Security detection engine ES|QL executoresql_search_strategy.ts→esql.query()— Synchronous ES|QL search (Discover/Lens)esql_async_search_strategy.ts→esql.asyncQuery()/asyncQueryGet()/asyncQueryStop()/asyncQueryDelete()— Async ES|QL search. Also fixed incorrectSqlGetAsyncResponsetype →EsqlAsyncQueryResponseRemaining as transport.request (2 call sites):
mvt_routes.ts— Maps MVT tiles. Requires restructuringgetTile()helper and tile request builders to passindex/field/zoom/x/yas separate params instead of a pre-built path stringobservability_ai_assistant elasticsearch.ts— Dynamic caller by design, method/path determined at runtime by AIWhy typed methods are better for CPS:
Typed client methods already include
meta.acceptedParamsin their implementation, so the CPS handler automatically injectsproject_routing— no explicit injection or annotation needed. The two remainingtransport.requestcallers use explicitproject_routing: '_alias:_origin'injection (stripped automatically when CPS is disabled).Test plan
conversational_chain.test.ts— 12/12 pass (updated mocks fromtransport.requesttosearch())esql_request.test.ts— all pass (updated mocks to typed esql methods)esql.test.ts— 5/5 pass (updated mocks)esql_async_search_strategy.test.ts— 15/15 pass (updated mocks + assertions)async_utils.test.ts— 16/16 passes_search_strategy.test.ts+ese_search_strategy.test.ts— 35/35 pass (regression check)cps_request_handler.test.ts— 38/38 pass (CPS handler sanity check)mvt_routes.test.ts— pass🤖 Generated with Claude Code
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com