Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
2b8c936
perf: instrument mapnav episode timings
suguanYang Aug 28, 2026
9b355e5
Merge pull request #350 from Ontos-AI/perf/wangbinqi/mapnav-timing-in…
suguanYang Aug 28, 2026
259065f
perf: eliminate lazy mapnav tree n-plus-one loads
suguanYang Aug 29, 2026
0d859b9
perf: defer lazy reference metadata and tune token lookup
suguanYang Aug 29, 2026
00fc7e2
perf: trust transactional map index marker
suguanYang Aug 29, 2026
1f33531
perf: add revision-pinned retrieval serving index
suguanYang Aug 30, 2026
dabb25d
test: patch active database module in revision race contract
suguanYang Aug 30, 2026
464ae7b
Merge pull request #352 from Ontos-AI/perf/wangbinqi/mapnav-timing-in…
suguanYang Aug 30, 2026
2e8e4c0
perf: avoid eager job chunk hydration
suguanYang Aug 30, 2026
e1b8c88
Merge pull request #354 from Ontos-AI/perf/wangbinqi/retrieval-hydrat…
suguanYang Aug 30, 2026
cc67a90
perf: bound retrieval snapshot payload reads
suguanYang Aug 31, 2026
b683ded
test: lock large snapshot manifest bypass
suguanYang Aug 31, 2026
5162d0a
Merge pull request #355 from Ontos-AI/perf/wangbinqi/retrieval-hydrat…
suguanYang Aug 31, 2026
93d9eee
fix(worker): cap internal parser filenames
suguanYang Aug 31, 2026
19b0e28
Merge pull request #357 from Ontos-AI/fix/wangbinqi/internal-filename…
suguanYang Aug 31, 2026
0409925
feat: add conversation_id to retrieval queries and enhance namespace …
EricNGOntos Aug 31, 2026
6ab4f8e
feat: enhance map unit index backfill process and remove obsolete tests
EricNGOntos Aug 31, 2026
194204f
feat: enhance retrieval tests and refactor scoring logic
EricNGOntos Aug 31, 2026
47bc458
feat: add average IDF fields and optimize retrieval logic
EricNGOntos Aug 31, 2026
496501b
chore: drop unused serving_manifest import in nav_knowhere
EricNGOntos Aug 31, 2026
5fee166
feat: add read-only --check for serving-index fallback readiness
EricNGOntos Aug 31, 2026
10d61eb
Merge pull request #359 from Ontos-AI/feat/wuchengke/2026-08-31
EricNGOntos Aug 31, 2026
d044c58
fix: resolve PR 358 codeql comments
suguanYang Aug 31, 2026
0e9ed9a
fix: tighten retrieval fallback handling
suguanYang Aug 31, 2026
7f05cba
Merge pull request #360 from Ontos-AI/fix/wangbinqi/pr358-codeql-comm…
suguanYang Aug 31, 2026
eeff527
fix: make CodeQL migration exports explicit
suguanYang Aug 31, 2026
dceaffa
Merge pull request #362 from Ontos-AI/fix/wangbinqi/codeql-alembic-su…
suguanYang Aug 31, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions CONTEXT.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,76 @@ The query workflow that returns cited evidence from published documents.
The typed retrieval request that owns cache-shaping fields and route policy:
scope, filters, data type, channels, ranking options, and agentic toggle.

### Retrieval Run

One execution of a Retrieval Query, recorded across classic, map-nav,
small-corpus, cache-hit, failed, and cancelled outcomes with route, timing,
and terminal-status metadata.

### Retrieval Progress Event

A safe, user-facing update about the current phase of a Retrieval run. It uses
the fixed phases `started`, `planning`, `searching`, `reviewing_sources`, and
`finalizing`; it never contains chain-of-thought or raw planner output.

### Retrieval Stream

The server-to-client event stream for a Retrieval Query. It carries
Retrieval Progress Events during execution and one authoritative final result
or terminal failure, while leaving answer generation to downstream clients.

### Retrieval Duration

The end-to-end server time for a Retrieval Query, measured from retrieval
execution start through final public-result assembly. It includes cache lookup
and excludes authentication, network transfer, SSE delivery time, and
downstream answer generation.

### Retrieval Non-LLM Work

The database and retrieval-engine work for a Retrieval Query: snapshot or
serving-index loading, lexical scoring, ranking, result hydration, citation
assembly, and asset-reference resolution. It excludes planner, harvest,
control, and answer-generation model time, which are measured separately.

### Retrieval Serving Index

The publication-derived read model used to load retrieval structure and
scoring inputs without rebuilding them from the full document corpus for each
query. It is revision-pinned and complete before its document revision becomes
active.

### Retrieval Serving Fallback

The exact legacy retrieval path used when a serving index is missing,
incomplete, or inconsistent. It preserves retrieval quality while sacrificing
the serving-index latency target until the derived data is repaired.

### Retrieval Serving Generation

The namespace-scoped version that identifies one coherent set of active
document revisions and their serving-index statistics. Retrieval captures one
generation and retries or falls back if publication changes it during capture.

### Retrieval Semantic Parity

The compatibility requirement that a serving-index retrieval returns the same
selected chunk IDs, ordering, rounded scores, citations, and asset references
as the legacy retrieval path for the same request.

### Retrieval Revision Pin

The set of document revision IDs captured at retrieval start and used for the
entire retrieval run, including lazy content and asset resolution. A later
publication affects subsequent runs, not the run already in progress.

### Online Retrieval Serving Rollout

The additive rollout of retrieval-serving schema and derived data while
retrieval and document publication remain available. Incomplete or
inconsistent revisions use the exact legacy retrieval path until backfill and
validation finish.

### Workflow Run Request

The agentic Retrieval request passed through planning and step execution. It
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""Add a covering index for persisted map-nav token lookups."""

from __future__ import annotations

from alembic import op


revision = "2e3f4a5b6c7d"
down_revision = "1d2e3f4a5b6c"
branch_labels = None
depends_on = None

_INDEX_NAME = "idx_document_map_unit_tokens_unit_lookup"


def upgrade() -> None:
external_transaction = bool(
op.get_context().opts.get("knowhere_external_transaction", False)
)
statement = (
f"CREATE INDEX {{concurrently}}IF NOT EXISTS {_INDEX_NAME} "
"ON document_map_unit_tokens (map_unit_id, channel, token_hash) "
"INCLUDE (token, frequency)"
)
if external_transaction:
op.execute(statement.format(concurrently=""))
return
with op.get_context().autocommit_block():
op.execute(statement.format(concurrently="CONCURRENTLY "))


def downgrade() -> None:
external_transaction = bool(
op.get_context().opts.get("knowhere_external_transaction", False)
)
if external_transaction:
op.execute(f"DROP INDEX IF EXISTS {_INDEX_NAME}")
return
with op.get_context().autocommit_block():
op.execute(f"DROP INDEX CONCURRENTLY IF EXISTS {_INDEX_NAME}")
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""Add the index used by lazy map-nav section pagination."""

from __future__ import annotations

from alembic import op


revision = "3f4a5b6c7d8e"
down_revision = "2e3f4a5b6c7d"
branch_labels = None
depends_on = None

_INDEX_NAME = "idx_document_sections_revision_snapshot_order"


def upgrade() -> None:
external_transaction = bool(
op.get_context().opts.get("knowhere_external_transaction", False)
)
statement = (
f"CREATE INDEX {{concurrently}}IF NOT EXISTS {_INDEX_NAME} "
"ON document_sections "
"(document_id, job_result_id, sort_order, section_id)"
)
if external_transaction:
op.execute(statement.format(concurrently=""))
return
with op.get_context().autocommit_block():
op.execute(statement.format(concurrently="CONCURRENTLY "))


def downgrade() -> None:
external_transaction = bool(
op.get_context().opts.get("knowhere_external_transaction", False)
)
statement = f"DROP INDEX {{concurrently}}IF EXISTS {_INDEX_NAME}"
if external_transaction:
op.execute(statement.format(concurrently=""))
return
with op.get_context().autocommit_block():
op.execute(statement.format(concurrently="CONCURRENTLY "))
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
"""Add revision-pinned serving manifests and namespace statistics."""

from __future__ import annotations

from collections.abc import Sequence

from alembic import op
import sqlalchemy as sa


revision: str = "4a5b6c7d8e9f"
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
down_revision: str | None = "3f4a5b6c7d8e"
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
branch_labels: Sequence[str] | None = None
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
depends_on: Sequence[str] | None = None
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed

__all__ = [
"revision",
"down_revision",
"branch_labels",
"depends_on",
"upgrade",
"downgrade",
]


def upgrade() -> None:
if not sa.inspect(op.get_bind()).has_table("retrieval_namespace_generations"):
op.create_table(
"retrieval_namespace_generations",
sa.Column("id", sa.String(length=100), nullable=False),
sa.Column("user_id", sa.Text(), nullable=False),
sa.Column("namespace", sa.String(length=255), nullable=False),
sa.Column(
"generation", sa.BigInteger(), nullable=False, server_default="0"
),
sa.Column("updated_at", sa.DateTime(), nullable=False),
sa.PrimaryKeyConstraint("id"),
sa.UniqueConstraint(
"user_id",
"namespace",
name="uq_retrieval_namespace_generations_scope",
),
)
if not sa.inspect(op.get_bind()).has_table("retrieval_serving_revision_manifests"):
op.create_table(
"retrieval_serving_revision_manifests",
sa.Column("id", sa.String(length=100), nullable=False),
sa.Column("user_id", sa.Text(), nullable=False),
sa.Column("namespace", sa.String(length=255), nullable=False),
sa.Column("document_id", sa.String(length=36), nullable=False),
sa.Column("job_result_id", sa.String(length=36), nullable=False),
sa.Column("format_version", sa.Integer(), nullable=False),
sa.Column("payload_zlib", sa.LargeBinary(), nullable=False),
sa.Column("checksum", sa.String(length=64), nullable=False),
sa.Column("created_at", sa.DateTime(), nullable=False),
sa.ForeignKeyConstraint(
["document_id"], ["documents.document_id"], ondelete="CASCADE"
),
sa.ForeignKeyConstraint(
["job_result_id"], ["job_results.id"], ondelete="CASCADE"
),
sa.PrimaryKeyConstraint("id"),
sa.UniqueConstraint(
"document_id",
"job_result_id",
name="uq_retrieval_serving_revision_manifests_revision",
),
)
if not _index_exists("idx_retrieval_serving_revision_manifests_scope"):
op.create_index(
"idx_retrieval_serving_revision_manifests_scope",
"retrieval_serving_revision_manifests",
["user_id", "namespace", "document_id", "job_result_id"],
)
if not sa.inspect(op.get_bind()).has_table("retrieval_serving_revision_stats"):
op.create_table(
"retrieval_serving_revision_stats",
sa.Column("id", sa.String(length=100), nullable=False),
sa.Column("user_id", sa.Text(), nullable=False),
sa.Column("namespace", sa.String(length=255), nullable=False),
sa.Column("document_id", sa.String(length=36), nullable=False),
sa.Column("job_result_id", sa.String(length=36), nullable=False),
sa.Column("format_version", sa.Integer(), nullable=False),
sa.Column("payload_zlib", sa.LargeBinary(), nullable=False),
sa.Column("checksum", sa.String(length=64), nullable=False),
sa.Column("created_at", sa.DateTime(), nullable=False),
sa.ForeignKeyConstraint(
["document_id"], ["documents.document_id"], ondelete="CASCADE"
),
sa.ForeignKeyConstraint(
["job_result_id"], ["job_results.id"], ondelete="CASCADE"
),
sa.PrimaryKeyConstraint("id"),
sa.UniqueConstraint(
"document_id",
"job_result_id",
name="uq_retrieval_serving_revision_stats_revision",
),
)
if not _index_exists("idx_retrieval_serving_revision_stats_scope"):
op.create_index(
"idx_retrieval_serving_revision_stats_scope",
"retrieval_serving_revision_stats",
["user_id", "namespace", "document_id", "job_result_id"],
)
if not sa.inspect(op.get_bind()).has_table("retrieval_namespace_stats"):
op.create_table(
"retrieval_namespace_stats",
sa.Column("id", sa.String(length=100), nullable=False),
sa.Column("user_id", sa.Text(), nullable=False),
sa.Column("namespace", sa.String(length=255), nullable=False),
sa.Column("generation", sa.BigInteger(), nullable=False),
sa.Column("payload_zlib", sa.LargeBinary(), nullable=False),
sa.Column("checksum", sa.String(length=64), nullable=False),
sa.Column("updated_at", sa.DateTime(), nullable=False),
sa.PrimaryKeyConstraint("id"),
sa.UniqueConstraint(
"user_id", "namespace", name="uq_retrieval_namespace_stats_scope"
),
)
if not sa.inspect(op.get_bind()).has_table("retrieval_namespace_token_stats"):
op.create_table(
"retrieval_namespace_token_stats",
sa.Column("id", sa.String(length=100), nullable=False),
sa.Column("user_id", sa.Text(), nullable=False),
sa.Column("namespace", sa.String(length=255), nullable=False),
sa.Column("generation", sa.BigInteger(), nullable=False),
sa.Column("channel", sa.String(length=32), nullable=False),
sa.Column("token_hash", sa.String(length=64), nullable=False),
sa.Column("document_frequency", sa.Integer(), nullable=False),
sa.PrimaryKeyConstraint("id"),
sa.UniqueConstraint(
"user_id",
"namespace",
"channel",
"token_hash",
name="uq_retrieval_namespace_token_stats_key",
),
)
if not _index_exists("idx_retrieval_namespace_token_stats_lookup"):
op.create_index(
"idx_retrieval_namespace_token_stats_lookup",
"retrieval_namespace_token_stats",
["user_id", "namespace", "generation", "channel", "token_hash"],
)


def _index_exists(index_name: str) -> bool:
bind = op.get_bind()
inspector = sa.inspect(bind)
for table_name in inspector.get_table_names():
if any(
index.get("name") == index_name
for index in inspector.get_indexes(table_name)
):
return True
return False


def downgrade() -> None:
op.drop_index(
"idx_retrieval_namespace_token_stats_lookup",
table_name="retrieval_namespace_token_stats",
if_exists=True,
)
op.drop_table("retrieval_namespace_token_stats", if_exists=True)
op.drop_table("retrieval_namespace_stats", if_exists=True)
op.drop_index(
"idx_retrieval_serving_revision_stats_scope",
table_name="retrieval_serving_revision_stats",
if_exists=True,
)
op.drop_table("retrieval_serving_revision_stats", if_exists=True)
op.drop_index(
"idx_retrieval_serving_revision_manifests_scope",
table_name="retrieval_serving_revision_manifests",
if_exists=True,
)
op.drop_table("retrieval_serving_revision_manifests", if_exists=True)
op.drop_table("retrieval_namespace_generations", if_exists=True)
44 changes: 44 additions & 0 deletions apps/api/alembic/versions/5b6c7d8e9f0a_add_term_trigram_indexes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""Add trigram acceleration for exact term-channel candidate discovery."""

from __future__ import annotations

from collections.abc import Sequence

from alembic import op


revision: str = "5b6c7d8e9f0a"
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
down_revision: str | None = "4a5b6c7d8e9f"
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
branch_labels: Sequence[str] | None = None
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
depends_on: Sequence[str] | None = None
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed

__all__ = [
"revision",
"down_revision",
"branch_labels",
"depends_on",
"upgrade",
"downgrade",
]

_MAP_UNIT_INDEX = "idx_document_map_units_term_trgm"
_CHUNK_INDEX = "idx_document_chunks_term_trgm"


def upgrade() -> None:
op.execute("CREATE EXTENSION IF NOT EXISTS pg_trgm")
op.execute(
f"CREATE INDEX IF NOT EXISTS {_MAP_UNIT_INDEX} "
"ON document_map_units USING gin "
"(term_search_text_lower gin_trgm_ops)"
)
op.execute(
f"CREATE INDEX IF NOT EXISTS {_CHUNK_INDEX} "
"ON document_chunks USING gin "
"(lower(COALESCE(term_search_text, '')) gin_trgm_ops)"
)


def downgrade() -> None:
op.execute(f"DROP INDEX IF EXISTS {_CHUNK_INDEX}")
op.execute(f"DROP INDEX IF EXISTS {_MAP_UNIT_INDEX}")
Loading
Loading