.agents/skills/full-text-search/SKILL.md
This skill covers search over LobeHub-owned product data such as agents, topics, messages, files,
knowledge bases, documents, chat groups, and memories. It does not cover the agent's external web
search providers under apps/server/src/services/search/ or builtin web-browsing tools.
Product reads follow one stable path:
router/service -> createFtsSearchRepo -> FtsSearchRepo -> selected backend -> existing result schema
apps/server/src/services/ftsSearch/ owns request-scoped provider selection, Elasticsearch
configuration, its HTTP client, and backend telemetry. Routers and domain services must call
createFtsSearchRepo; they must not construct providers themselves.packages/database/src/repositories/ftsSearch/ owns the provider-neutral contract and the concrete
PostgreSQL and Elasticsearch implementations. Keep public result shapes stable in FtsSearchRepo.packages/types/src/ftsSearch.ts owns the shared searchable-entity list and search domain types.packages/database/src/repositories/ftsSearchDocument/ owns Elasticsearch document schemas,
mappings, queryable fields, and source-to-document projection.packages/database/src/schemas/ftsSearchSyncOutbox.ts and
packages/database/src/repositories/ftsSearchSyncOutbox/ own durable change capture, claims,
retries, dead letters, leases, revision fences, and capture-definition validation.scripts/elasticsearchReindex/ owns the resumable full-backfill command and its operational
runtime. Shared database source queries and document construction remain in
packages/database/src/repositories/ftsSearchDocument/. apps/server/src/services/ftsSearchSync/ and
scripts/elasticsearchSync/ own continuous incremental draining.packages/env/src/ftsSearch.ts owns generic Elasticsearch environment variables.FTS_SEARCH_PROVIDER is a deployment-level provider selector with current values pg_search and
elasticsearch. It is not a feature flag or a user rollout. Add another enum value only when its
provider is implemented end to end.ilike fallback.userId, workspaceId, and caller-agent visibility throughout every provider. Candidate
retrieval must not broaden the caller's scope.Treat an entity addition or projection change as one cross-layer change. Inspect and update every applicable item:
FTS_SEARCH_DOCUMENT_ENTITIES and shared request/result types.FtsSearchDocumentBuilder, including soft deletion and fanout from related source rows.captureInfrastructure.ts.Schema fields, mappings, builders, and fixed fixtures must agree exactly. A field that is not in the document schema must not appear in the mapping or query field list.
Elasticsearch multi_match query length is bounded by a shared leaf-clause budget divided by the
selected query-field count. Adding a field reduces that entity's safe query length, and changing a
query analyzer to emit multiple terms per Unicode code point requires revisiting the budget and its
field-count regression tests.
installCaptureInfrastructure() is transactional, definition-checked,
idempotent for an exact installation, and fail-closed for partial or altered definitions.(entity, document_id). A newer capture resets retry/dead-letter state and
allocates a new revision only after locking the conflicting row, preserving same-document commit
order.last_value alone as proof that all earlier Outbox rows are visible.The supported operator entrypoints are:
bun run db:install-fts-search-capture
bun run fts-search:reindex -- --status
bun run fts-search:reindex -- --apply --yes
bun run fts-search:sync -- --max-steps=8 --yes
bun run scripts/pgSearchCleanup/index.ts --status
bun run scripts/pgSearchCleanup/index.ts --apply --yes
Read docs/self-hosting/advanced/elasticsearch-migration.mdx or its Chinese counterpart before
changing the operational sequence. When database rollout or index cost affects the design, also
use the db-migrations skill and measure the relevant operation on the actual Dev database before
adding manual or deferred release steps.
apps/server/src/services/ftsSearch/observability.ts.
Keep labels bounded: entity, provider, operation, outcome, and coarse error type are acceptable;
raw queries, user IDs, document IDs, and index contents are not.src/features/CommandMenu/analytics.ts. Product analytics may cover end-to-end duration, rendered
result counts, empty results, result clicks, and abandonment without a Cloud business slot.FtsSearchRepo, providers cannot leak raw result shapes,
and telemetry failures do not affect search behavior.bun run check <changed-files...> from the repository root. For migration or database-runtime
changes, follow the db-migrations and testing skills and verify against the actual Dev database.