Step Search (:search)
Quick Answer
Use :search to query workspace resources and entities without external HTTP calls.
{:type :search :query "..." :targets [:resources :flows :runs :connections] :limit 12}
For :resources, Breyta can use semantic retrieval when it is enabled for the workspace. Flow authors do not need a different step shape. The same :search step keeps lexical matching, exact path/URI pinning, and hydration behavior.
When :targets includes :resources, the step hydrates the top resource hits by default so flows can send full file or blob content to downstream steps without an extra fetch path.
Use :persist {:search-index ...} on the producing step when you need persisted artifacts to be easier to find later by text, tags, or source label.
Canonical Shape
| Field | Type | Required | Notes |
|---|---|---|---|
:type | keyword | Yes | Must be :search |
:query | string | Yes | Non-blank search query |
:targets | vector | No | Any of :resources, :flows, :runs, :connections (default: all) |
:storage-backend | keyword/string | No | Resource-target filter such as :gcs. |
:storage-root | string | No | Resource-target filter such as "reports/acme". |
:path-prefix | string | No | Relative resource path filter under the effective storage root, such as "exports/2026". |
:limit | int | No | Per-target max results, 1 to 20 (default: 12) |
:hydrate | map | No | Resource hydration config. Defaults to enabled when :resources is targeted. |
Hydrate Config
| Field | Type | Required | Notes |
|---|---|---|---|
:enabled | boolean | No | Default true when :resources is targeted, otherwise false |
:top-k | int | No | Max resource hits to hydrate, 1 to 10 (default: 5) |
:max-chars | int | No | Max inline text chars per hydrated resource, 1 to 100000 (default: 20000) |
Runtime Behavior
- Search scope is always the current workflow runtime workspace.
workspace-idis taken from runtime context, not step input.- Search clients are injected by runtime wiring:
- resources search client
- workspace search client (flows/runs/connections)
- If a requested target has no configured search client, step execution fails with a validation error.
- Semantic retrieval applies only to
:resourceshits, and only when the Elastic resource-search backend has semantic reads enabled. :flows,:runs, and:connectionsstill use workspace search.- Local memory search and emulator fallback stay lexical.
- Explicit sorting disables hybrid semantic ranking. Sorted resource searches keep deterministic lexical/index ordering.
- Resource hydration uses the runtime workspace resource store and preserves workspace isolation.
- Hydration only applies to
:resourceshits. :storage-backend,:storage-root, and:path-prefixapply only to:resourceshits.- The resource index keeps both the full physical
pathand normalized storage fields (storage_backend,storage_root,path_under_root). :path-prefixis interpreted againstpath_under_root, so it stays relative to the effective storage root instead of the absolute workspace storage path.- Text-like resources return inline
:content. - Non-text resources return
:content-urlwith:hydration-status :linked-binary. - Oversized or failed reads keep the hit and mark
:hydration-statusinstead of failing the whole search step.
Public Docs Retrieval
:search does not search Breyta public docs directly. It only searches the current workflow runtime workspace.
When a flow needs Breyta docs at runtime, use an explicit :http step against the public docs API:
- search docs pages with
GET /api/docs/pages - fetch page content with
GET /api/docs/pages/:slug?format=md
Use a :http-api connection slot with :base-url "https://flows.breyta.ai" so the flow body only contains API paths. See Step HTTP for a complete copy-pasteable example.
Searchable Resource Lifecycle
Resource search is workspace-scoped and runs over indexed resource metadata plus indexed text when available.
The most common searchable resource sources are:
- workspace files
- persisted step artifacts (
res://...) - HTTP page responses auto-indexed by
:http - retained artifacts whose indexed text/metadata were customized with
:persist {:search-index ...}
Use :search-index inside the :persist map when the stored payload bytes are not the best search text on their own, or when the resource should show a more useful label in search results.
Successful :http GET responses for page-like content can be auto-persisted and indexed. This covers HTML, markdown, and article-like plain text pages. See Step HTTP for defaults and opt-out.
When semantic resource search is enabled, indexed article/page text is available to semantic ranking. When it is disabled, the same resources are still found through lexical keyword and metadata matching.
For fast operator proof outside the flow runtime, start with:
breyta resources search "refund support bundle"
Result Shape
{:query "refund policy"
:targets [:resources :flows]
:limit 12
:grouped {:resources [{:target :resources
:title "Refund policy"
:uri "res://..."
:content "Full file content..."
:content-type "text/markdown"
:size-bytes 1842
:content-truncated? false
:hydration-status :inline-text}]
:flows [...]
:runs []
:connections []}
:results [...]} ; flattened in requested target order
Hydrated resource hits may include:
:content:content-url:content-type:size-bytes:content-truncated?:hydration-statusas one of:inline-text,:linked-binary,:too-large,:read-error,:skipped:hydration-error
Canonical Example
'(let [hits (flow/step :search :knowledge
{:query (:question (flow/input))
:targets [:resources :flows :runs]
:storage-backend :gcs
:storage-root "reports/acme"
:path-prefix "exports/2026"
:limit 10
:hydrate {:top-k 5
:max-chars 20000}})]
hits)
Persist, index, and retrieve later:
'(let [bundle (flow/step :function :persist-support-bundle
{:input {:rows (:rows (flow/input))}
:code '(fn [{:keys [rows]}] rows)
:persist {:type :blob
:path "support/bundles"
:filename "refund-bundle.json"
:content-type "application/json"
:search-index {:text "refund support bundle refunds chargebacks returns"
:tags ["refund" "support" "bundle"]
:source-label "Refund support bundle"
:include-raw-content? true}}})
hits (flow/step :search :find-support-bundle
{:query "refund support bundle"
:targets [:resources]
:limit 5
:hydrate {:enabled true
:top-k 1
:max-chars 20000}})]
{:bundle bundle
:hits hits})