feat(serve): distinguish search vs chat in query log via X-Source header (#127)
CI / Python lint (push) Has been cancelled
CI / Frontend build (push) Has been cancelled
CI / Tests (push) Has been cancelled
CI / Plugin validate (push) Has been cancelled
Deploy / deploy (push) Has been cancelled
CI / Python lint (push) Has been cancelled
CI / Frontend build (push) Has been cancelled
CI / Tests (push) Has been cancelled
CI / Plugin validate (push) Has been cancelled
Deploy / deploy (push) Has been cancelled
This commit is contained in:
@@ -102,12 +102,13 @@ def _init_query_log():
|
||||
_query_log_path = log_dir / "queries.jsonl"
|
||||
|
||||
|
||||
def _log_query(req: "SearchRequest", request_id: str):
|
||||
def _log_query(req: "SearchRequest", request_id: str, source: str | None = None):
|
||||
if _query_log_path is None:
|
||||
return
|
||||
record = {
|
||||
"ts": datetime.now(timezone.utc).isoformat(),
|
||||
"request_id": request_id,
|
||||
"source": source,
|
||||
"queries": [q.text for q in req.queries],
|
||||
"has_image": [q.image is not None for q in req.queries],
|
||||
"n_docs": req.n_docs,
|
||||
@@ -461,7 +462,7 @@ def _resolve_url(article_id: int) -> str:
|
||||
|
||||
|
||||
@app.post("/search", response_model=SearchResponse)
|
||||
async def search(req: SearchRequest):
|
||||
async def search(req: SearchRequest, request: Request):
|
||||
t0 = time.time()
|
||||
|
||||
# Encode queries
|
||||
@@ -570,7 +571,7 @@ async def search(req: SearchRequest):
|
||||
time.time() - t0,
|
||||
)
|
||||
|
||||
_log_query(req, _request_id_ctx.get())
|
||||
_log_query(req, _request_id_ctx.get(), request.headers.get("X-Source"))
|
||||
|
||||
return SearchResponse(results=results)
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ function createTools(onEvent, uploadedImage) {
|
||||
onEvent("searching", { query: label })
|
||||
const resp = await fetch(`${SEARCH_URL}/search`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
headers: { "Content-Type": "application/json", "X-Source": "chat" },
|
||||
body: JSON.stringify({ queries: [queryObj], n_docs: args.n_results ?? 5, articles_only: true }),
|
||||
signal: AbortSignal.timeout(30000),
|
||||
})
|
||||
|
||||
@@ -99,7 +99,7 @@ function createTools(
|
||||
|
||||
const resp = await fetch(`${SEARCH_URL}/search`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
headers: { "Content-Type": "application/json", "X-Source": "chat" },
|
||||
body: JSON.stringify({
|
||||
queries: [queryObj],
|
||||
n_docs: args.n_results ?? 5,
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ async function fetchApi<T>(path: string, init?: RequestInit): Promise<T> {
|
||||
export async function search(req: SearchRequest): Promise<SearchResponse> {
|
||||
return fetchApi<SearchResponse>("/search", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
headers: { "Content-Type": "application/json", "X-Source": "search" },
|
||||
// NOTE: the visual grid intentionally does NOT set articles_only — the
|
||||
// Portal/Featured-picture pages it would drop are often the most visually
|
||||
// striking tiles (panoramas, paintings), which is the point of this view.
|
||||
|
||||
Reference in New Issue
Block a user