Commit History
-
[KM-652] fix(report,chat): align report gate with readiness + cleanup
Rifqi Hafizuddin +1: Claude Opus 4.8- T-D: generate_report only 409'd on zero records — it ignored problem_validated and whether any analysis actually succeeded, so the button could 201 a findings-empty report while Help said "not ready". Extract report_floor() (validated goal + >=1 substantive analyze_* success) as the single source of truth; is_report_ready composes it (+ its delta-check), and the report API gates on it (no delta — a new version is always allowed, decision 4A). - T-E: document that reports require ENABLE_SLOW_PATH=on (only the slow path persists AnalysisRecords; no records => 409 by design), and return a clear "still needs ..." 409 instead of a bare "no analyses recorded". - T-F: drop the dead source_hint derivation + _intent_to_source_hint — the intent event is consumed by the endpoint's cache gate and never forwarded to the frontend; fix the misleading comment. - T-G: document the history-blind chat cache key (message-only) limitation; history-aware key deferred to the endpoint…9c06bea -
[KM-652] fix(orchestrator): un-brick sessions + enforce data-source binding
Rifqi Hafizuddin +1: Claude Opus 4.8Three critical fixes found tracing the request lifecycle: - T-A: rooms from /room/create have no analysis_states row, so with the gate on the turn redirect-looped (gate fail-closed + a silent no-op on the problem_validated write) and gate-off it spammed duplicate report versions (report_id write-back no-op'd). AnalysisStateStore.update now warns instead of silently no-op'ing; new idempotent ensure() (INSERT ON CONFLICT DO NOTHING) get-or-creates the row; ChatHandler ensures it once per turn and the gate reuses that state (also drops the gate/help double-read). - T-B: #10 binding only scoped the Planner's catalog; the data-access tools re-read the full catalog themselves, so binding was a hint, not a boundary. Scope at the reader (_ScopedCatalogReader) so the Planner AND the tools share one scoped view. Fast path was already correct. - T-C: _scope_to_binding failed CLOSED on a disjoint binding (empty catalog -> hard fail). The scoped reader fails open (scoped or w…236d991
-
[KM-652] feat(analysis): #10 data-source binding (analysis-owned join table)
Rifqi Hafizuddin +1: Claude Opus 4.8Persist which catalog sources an analysis is scoped to, and consume it: - New analysis_data_sources(analysis_id, source_id) join table (Option A: analysis-owned, leaves the 8-field state contract untouched). Written atomically with state + room in /analysis/create. - AnalysisDataSourceStore read seam. structured_flow scopes its catalog to the bound sources (chat_handler._scope_to_binding); the report's data appendix scopes _build_data_sources to them. Both fail-open: no binding / legacy room / read error -> whole catalog, so nothing breaks until the FE sends ids. - /analysis/create dedupes + returns data_source_ids. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>4c143c4 -
[KM-652] fix(report): connect record->report->state loop + readiness refinement
Rifqi Hafizuddin +1: Claude Opus 4.8Three subsystems were built in parallel and never wired together: - Stamp analysis_id (+ user_id) onto the persisted AnalysisRecord in the slow path. Without it records were orphaned (analysis_id NULL) so list_for_analysis found nothing — the report API and is_report_ready were both silently blind. - Report API now loads the validated problem statement from analysis_states (was an empty stub) and writes report_id back onto the state after persist (feeds Help's has_report + the readiness delta-check). Both never-throw. - is_report_ready: count *substantive* records (>=1 finding, not raw turns) and add delta-since-report (a prior report + no newer analysis -> not ready). Also fix stale docstrings made false by this change: get_analysis_state (no longer a stub — reads the real store), the slow-path AnalysisStore seam (no longer a no-op), and SlowPathCoordinator (now wired behind ENABLE_SLOW_PATH). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>53d197f
-
[KM-652] feat(report): is_report_ready signal + wire into help dispatch
Rifqi Hafizuddin +1: Claude Opus 4.8Deterministic report-readiness (seam #5): validated problem statement + >=1 persisted AnalysisRecord, mirroring the report API's own 409 gate. Never-throws (fails closed to not-ready). Wired into the help dispatch so HelpAgent's consistency guard only offers generate_report when actually ready. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>ec1e341 -
[KM-667] feat(help): wire help dispatch in chat_handler
Replace the help placeholder with the real handler. _load_analysis_state fail-closes to a not-validated stub (legacy room / read error); help_agent injectable; streams chunk/done with masked callbacks. Remove dead _stub_message (help was the last unwired intent). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>66fbce0 -
[KM-652] feat(orchestrator): analysis state + gate wiring + problem_statement skill
Rifqi Hafizuddin +1: Claude Opus 4.8Wire the gated analysis flow end-to-end. The gate is OFF by default (ENABLE_GATE) so live structured_flow is unchanged until the frontend creates analyses. - Analysis State: `analysis_states` table (shared id with `rooms` — analysis_id == room_id), `AnalysisStateStore` (get/create/update), `get_analysis_state` seam (fails closed to not-validated). 8-field contract: id, analysis_title, problem_statement, problem_validated, owner_id, report_id, created_at, updated_at. - POST /api/v1/analysis/create — creates Room + analysis_states atomically with a shared id; data-first check. - gate.py: rule keys on `problem_validated`; stub fixtures for build/test. - problem_statement skill: LLM drafts/refines, deterministic validator decides the pass, writes problem_statement + problem_validated to the store. - chat_handler: thread `analysis_id` (= room_id); apply gate before dispatch behind `enable_gate` (redirect structured_flow -> problem_statement until validated). - settings: ENABL…adcc635
-
[NOTICKET] fix context description
Rifqi Hafizuddin47f10d6
-
[NOTICKET] feat(orchestrator): flat 6-intent router + gate + check skill
Rifqi Hafizuddin +1: Claude Opus 4.8Rework the intent router from the 3-way source_hint classifier to a flat 6-intent handler router (chat, help, problem_statement, check, unstructured_flow, structured_flow). Structured/unstructured data modality on the slow path stays the Planner's job, not the router's. - orchestration.py: RouterDecision { intent, rewritten_query, confidence }; kept GPT-4o + the classify() seam. - intent_router.md: v2 prompt (labels, disambiguation, per-intent few-shots). - chat_handler.py: dispatch on intent; chat/unstructured_flow/structured_flow/ check wired; problem_statement/help stubbed; back-compat source_hint on the SSE intent event. - gate.py: deterministic gate (structured_flow requires interview pass) + AnalysisState stub contract (pending the lead's table). - handlers/check.py: check_data/check_knowledge tool-pick + table render. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>c1e4608
-
[NOTICKET] feat(slow-path): persist AnalysisRecord via PostgresAnalysisStore
Rifqi Hafizuddin +1: Claude Opus 4.8Groundwork for generate_report - the slow path now persists a real, citable record that the report (next) renders from. Contract gaps (schemas.py): - stage: CrispStage added to TaskResult + TaskSummary, populated at all 3 TaskResult build sites (task_runner) + copied in assembler._build_record, so the report can group its method appendix by CRISP-DM phase. - AnalysisRecord gained identity: record_id (auto uuid), analysis_id/user_id (optional; stamped at persist time). Persistence: - PostgresAnalysisStore (store.py): save() never-throw idempotent upsert + list_for_analysis() oldest-first (the report render order). NullAnalysisStore kept for tests. AnalysisStore Protocol gained list_for_analysis. - analysis_records jsonb table (models.py), indexed by analysis_id + user_id; registered in init_db, created by create_all on startup (no migration). - chat_handler default store -> PostgresAnalysisStore; user_id stamped at save. Open: analysis_id is NULL until the Analysis State …09f8451
-
feat/Planner Agent (#2)
- [KM-567][AI] Planner agent: contracts, schemas, inputs, registry (be96601ad46c00e8e789768dd6e89c2db827bde4) - [KM-567][AI] Planner agent: prompt + few-shot examples (83ba6b1743370145454d9315224eeb7b2d12ac18) - [KM-567][AI] Planner agent: validator + service (72306d0ce92c76d60117a20c701c7f8185bcfeef) - [KM-567] docs: record Phase 3 Planner agent in PROGRESS.md (ba2fa8892392028c8d13646c09d1155bbf34e703) - [KM-567][AI] Planner agent: fix PII leak + placeholder/retry robustness (6b3637dda097f16cd98d4b9ad6094fdaed6d1346) - [KM-624] Implement Compute Functions Tools (78c598c22d2f2a14229a83c3f43fa98c5d520ae7) - [KM-624][AI] Planner: realign stub registry + examples to composite analyze_* tools (93a24dabf48d8121e981cc470c835cb10badb62a) - [KM-624] docs: record tool taxonomy + ownership revision in PROGRESS (f3461142542f6216aff23b30a1321dfb4654afdc) - [KM-626][AI] Slow-path agent: seam contracts + TaskRunner (ac310de551d0888ccfef31e981e22d88f54c6a38) - [KM-626][AI] Slow-path agent: Assembler…81e5fe7
-
[KM-582][DED][AI] Fix Retrieval in Agentic Service
ticket: https://bukittechnology.atlassian.net/browse/KM-582 fix: replace LangChain ORM retrieval with raw SQL and fix pgvector collection name - Rewrite DocumentRetriever.retrieve() using raw SQL cosine/manhattan queries instead of LangChain PGVector ORM, bypassing asyncpg type-mapping issues (id String vs UUID column, jsonb_path_match binding quirks) - Fix _COLLECTION_NAME from "document_embeddings" to "documents" to match the collection name set by the Golang ingestion service - Fix collection_name in vector_store.py to match consistently - Fix Redis chat cache to store {response, sources} dict so cached replies also populate message_sources table - Add cache management endpoints: DELETE /chat/cache, /chat/cache/room/{id}, /retrieval/cache/{user_id} - Invalidate retrieval cache automatically after document processing - Update intent_router prompt: route topical/knowledge questions to unstructured even without explicit document mention; prefer unstructured when ambiguous…61c746f
-
feat/Catalog Retrieval System (#1)
- initial commit (8557a2045ca2c0873e07efdf6227064b83e4a1e5) - initial structure (efc0c0a8b2444014cbe74f04617c3c974d9915be) - [KM-553] initialize shared contract (f31f6731692b0199d8cb5c5d29dffa466d6d4ca0) - [KM-553] migrate retrieval layer and remove obsolete rag/tools modules (df220ea47c96eb8a1efa07c6eebef4604fc308d6) - [NOTICKET] catalog enricher + structured pipeline + on_db_registered (77ea82d29d86400c5ed30ac154be8df6a7e897eb) - Merge commit 'refs/pr/1' of https://huggingface.co/spaces/DataEyond/Agentic-Service-Data-Eyond-Catalog into pr/1 (0ae8717c7efce2cda14fe4b8caecd774459b1f6e) - [NOTICKET] SqlCompiler (Postgres) + DbExecutor (212dad360714508c1aa607995039e6818fa40f78) - Merge commit 'refs/pr/1' of https://huggingface.co/spaces/DataEyond/Agentic-Service-Data-Eyond-Catalog into pr/1 (faf8a4f6d7e06ccf1ce84c2e7f4990c79f27f843) - TabularIntrospector + on_tabular_uploaded trigger + 31 tests (ca425208969b72a20ed76f86ef0faa1a0e912339) - [KM 556] add columns field to QueryResult + update…6bff5d9