Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
6676481
Expand OSS telemetry with ADR-0004 schema, heartbeats, and usage aggr…
suguanYang Jul 13, 2026
4361e45
Potential fix for pull request finding 'CodeQL / Unused import'
suguanYang Jul 13, 2026
b4a9403
Rename telemetry events from self_hosted_* to oss_*.
suguanYang Jul 13, 2026
d6e3f42
Fix telemetry contract test SCHEMA_VERSION import.
suguanYang Jul 13, 2026
26a82fc
Merge pull request #214 from Ontos-AI/feat/wangbinqi/oss-telemetry-em…
suguanYang Jul 13, 2026
896d786
Drop dashboard from OSS telemetry client allowlist.
suguanYang Jul 13, 2026
9c523f5
Merge pull request #215 from Ontos-AI/fix/wangbinqi/drop-dashboard-cl…
suguanYang Jul 13, 2026
af90aa5
fix: classify dashboard jwt telemetry
suguanYang Jul 14, 2026
abd83fb
test: address jwt telemetry code scanning comments
suguanYang Jul 14, 2026
8e55502
test: isolate dashboard jwt contract imports
suguanYang Jul 15, 2026
9645eb5
test: type dashboard jwt import isolation helper
suguanYang Jul 15, 2026
1cd8a01
fix: reject malformed jwt payloads before jwks lookup
suguanYang Jul 15, 2026
e7c2463
fix: keep dashboard jwt telemetry local
suguanYang Jul 15, 2026
fe6b880
refactor: simplify jwt structure decode options
suguanYang Jul 15, 2026
d26b637
refactor: clarify dashboard jwt auth pipeline
suguanYang Jul 15, 2026
7ac57e2
Merge pull request #216 from Ontos-AI/fix/wangbinqi/optimize-jwt-auth…
suguanYang Jul 15, 2026
df7acbc
feat: add v2 BYOK OpenAI-compatible LLM credentials
suguanYang Jul 15, 2026
e3316ee
fix: avoid empty except in llm_overrides greenlet walk
suguanYang Jul 15, 2026
9897f04
fix: use partial per-channel BYOK overrides
suguanYang Jul 15, 2026
f214091
feat: add llm_config.provider multimodal shorthand
suguanYang Jul 15, 2026
b72803e
refactor: flatten llm_config to OpenAI-style root fields
suguanYang Jul 15, 2026
c04925e
feat: support llm_config.models per-channel model map
suguanYang Jul 15, 2026
04f5adf
Merge pull request #217 from Ontos-AI/feat/suguanYang/byok-llm-creden…
suguanYang Jul 15, 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
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,24 @@ make check

- External dependency guide:
[docs/external-services.md](docs/external-services.md)
- Architecture decisions:
[docs/adr/README.md](docs/adr/README.md)

## Telemetry

Self-hosted Knowhere emits **anonymous** product telemetry to PostHog so Ontos
operators can understand OSS adoption (install liveness, usage aggregates,
client/document mix). Events never include filenames, prompts, emails, IPs, or
geo. Schema and allowlists are locked in
[ADR-0004](docs/adr/0004-anonymous-self-hosted-telemetry.md).

Telemetry is **default-on**. To opt out, set:

```bash
TELEMETRY_ENABLED=false
```

Related settings live in `apps/api/.env.example` under `TELEMETRY_*`.

## Citation

Expand Down
12 changes: 12 additions & 0 deletions apps/api/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ TMP_PATH=/tmp/knowhere
# Optional or development-only: observability and local dashboard wiring
LOGFIRE_TOKEN=

# Anonymous self-hosted product telemetry (PostHog). Default-on; opt out with false.
# See docs/adr/0004-anonymous-self-hosted-telemetry.md and the README Telemetry section.
TELEMETRY_ENABLED=true
# TELEMETRY_POSTHOG_HOST=https://us.i.posthog.com
# TELEMETRY_POSTHOG_PROJECT_KEY=
# TELEMETRY_INSTALLATION_ID=
# TELEMETRY_INSTALLATION_ID_PATH=/data/secrets/telemetry-installation-id
# TELEMETRY_BATCH_SIZE=20
# TELEMETRY_REQUEST_TIMEOUT_SECONDS=2.0
# TELEMETRY_DEPLOYMENT_MODE=self_hosted
# TELEMETRY_AGGREGATE_INTERVAL_SECONDS=300

# Required for local startup: database
DATABASE_URL=postgresql+asyncpg://root:root123@localhost:5432/Knowhere
DB_SSL_MODE=disable
Expand Down
30 changes: 24 additions & 6 deletions apps/api/app/api/v1/routes/retrieval.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from __future__ import annotations

from typing import Literal
from typing import Any, Literal

from app.api.dependencies.current_user import with_current_user
from app.services.rate_limit.data_structures import CurrentUser
Expand All @@ -11,6 +11,7 @@
from sqlalchemy.ext.asyncio import AsyncSession

from shared.core.database import get_db
from shared.models.schemas.llm_config import LLMConfig
from shared.models.schemas.retrieval_namespace import normalize_retrieval_namespace
from shared.services.retrieval.app_service import run_retrieval_query
from shared.services.retrieval.settings import DEFAULT_TOP_K, VALID_CHUNK_TYPES, normalize_chunk_types
Expand Down Expand Up @@ -129,12 +130,14 @@ class RetrievalQueryResponse(BaseModel):
)


@router.post("/query", response_model=RetrievalQueryResponse)
async def query_retrieval(
async def execute_retrieval_query(
payload: RetrievalQueryRequest,
current_user: CurrentUser = Depends(with_current_user),
db: AsyncSession = Depends(get_db),
):
current_user: CurrentUser,
db: AsyncSession,
*,
llm_config: LLMConfig | None = None,
) -> dict[str, Any]:
"""Shared retrieval execution used by v1 and v2 route handlers."""
# Resolve chunk_types: explicit field takes precedence over legacy data_type
if payload.chunk_types is not None:
resolved_chunk_types = normalize_chunk_types(payload.chunk_types)
Expand Down Expand Up @@ -166,4 +169,19 @@ async def query_retrieval(
threshold=payload.threshold,
internal_recall_k=payload.internal_recall_k,
use_agentic=payload.use_agentic,
llm_config=llm_config,
)


@router.post("/query", response_model=RetrievalQueryResponse)
async def query_retrieval(
payload: RetrievalQueryRequest,
current_user: CurrentUser = Depends(with_current_user),
db: AsyncSession = Depends(get_db),
):
return await execute_retrieval_query(
payload,
current_user,
db,
llm_config=None,
)
47 changes: 45 additions & 2 deletions apps/api/app/api/v2/routes/retrieval.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,48 @@
"""Retrieval API v2 routes."""

from app.api.v1.routes.retrieval import router
from __future__ import annotations

__all__ = ["router"]
from app.api.dependencies.current_user import with_current_user
from app.api.v1.routes.retrieval import (
RetrievalQueryRequest,
RetrievalQueryResponse,
execute_retrieval_query,
)
from app.services.rate_limit.data_structures import CurrentUser
from fastapi import APIRouter, Depends
from pydantic import Field
from sqlalchemy.ext.asyncio import AsyncSession

from shared.core.database import get_db
from shared.models.schemas.llm_config import LLMConfig

router = APIRouter(tags=["Retrieval"])


class RetrievalQueryRequestV2(RetrievalQueryRequest):
"""v2 retrieval query request with optional BYOK LLM credentials."""

llm_config: LLMConfig | None = Field(
None,
description=(
"Optional bring-your-own-key OpenAI-compatible LLM credentials. "
"Flat {api_key, model, base_url} applies to both channels. "
"Use models.{text,vision} for different model ids on the same "
"endpoint, or text/vision objects for different endpoints. "
"When omitted, server defaults are used."
),
)


@router.post("/query", response_model=RetrievalQueryResponse)
async def query_retrieval(
payload: RetrievalQueryRequestV2,
current_user: CurrentUser = Depends(with_current_user),
db: AsyncSession = Depends(get_db),
):
return await execute_retrieval_query(
payload,
current_user,
db,
llm_config=payload.llm_config,
)
Loading
Loading