Commit History
-
updates
ritvikv031e4837a
-
feat: deduplicate knowledge graph nodes by source URL
ritvikv031f2e87a
-
merge: resolve conflicts with origin/main β keep improved colours and layoutβ
ritvikv03 +1: Claude Sonnet 4.6Conflict resolution strategy: - Colour values: kept HEAD improvements (#a8bcd0 font_color, #6a8099 axis ticks) - Layout: kept HEAD's richer tab content (urgency matrix, feed+stats, ring guide) - _load_graph_elements: merged both β connected-only filter (HEAD) + try/except (remote) - Trivial docstring diffs: took remote's phrasing Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>9cb08f7 -
fix: switch LLM provider cerebras->novita, harden empty-response, fix PDF encodingβ
ritvikv03 +1: Claude Sonnet 4.6- pipeline.py / agents.py / graph_engine.py: _HF_PROVIDER = 'novita' (cerebras was returning StopIteration on backend failures) - Add defensive check after every chat_completion call: if not response.choices: raise RuntimeError / log + default prevents IndexError on empty generator responses - app.py: add _sanitize_for_pdf() β translates non-Latin-1 chars (β¬ β EUR, β β --, ' β ', etc.) before fpdf render so PDF export never raises UnicodeEncodeError on reports containing currency symbols Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>1d4d5aa
-
Fix: UI unreadable text, Knowledge Graph errors, and PDF auto-downloadβ
ritvikv03- Fix: Low-contrast Plotly chart colors (radar, axes, annotations) - Fix: Infinite loop in Knowledge Graph BFS pathfinding - Fix: Automatic PDF download when switching report tab/dropdown - Fix: Duplicate report rendering on tab loadf7b0720 -
test: add test_graph_engine, test_agents, test_summary_engine, test_integration_pipelineβ
ritvikv03 +1: Claude Sonnet 4.6Full offline test suite for all core modules: - test_graph_engine: pure-function tests for _compute_causal_chain and _build_triple; file-reading tests for get_causal_chains and infer_hidden_relationships; mocked integration tests for run_graph_update - test_agents: dict_to_string, all calculator tools, router routing logic, run_agent_query end-to-end with mocked InferenceClient - test_summary_engine: generate() LLM/fallback/quota paths, get_latest(), generate_brief_markdown() rule-based and LLM paths - test_integration_pipeline: end-to-end score_text -> insert -> graph update Also fixes BFS bug in infer_hidden_relationships: [start] + suffix[1:] was stripping intermediate nodes, collapsing A->B->C into [A,C] and preventing any path of length >= 3 from being detected. 81 tests pass, 6 Astra DB integration tests skip without token. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>83a2bb8 -
feat: production-grade Knowledge Graph refactorβ
ritvikv03 +1: Claude Sonnet 4.6- graph.json reset to empty; stale orphaned nodes purged - graph_engine: add rebuild_graph_from_db() β reconstructs graph from live Astra DB on demand, called automatically post-Scout cycle - graph_engine: add infer_hidden_relationships() β BFS traversal to surface non-obvious cross-PESTEL cascade paths (e.g. ENVβECO), stored as INFERRED_CASCADE triples with hop_path metadata - scheduler: wire rebuild_graph_from_db() after every successful cycle - app.py: Knowledge Graph tab β Rebuild Graph + Run Inference buttons, inferred-cascades panel in sidebar, accurate empty state messaging Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>77879e2
-
feat: multi-agent relational brain, triples ontology, dict_to_stringβ
ritvikv03 +1: Claude Sonnet 4.6core/agents.py (new) Multi-Agent LangGraph system β zero Anthropic dependency, all inference via meta-llama/Llama-3.2-3B-Instruct on HuggingFace Inference API: AgentState TypedDict: question, signals, route, tool_result, final_answer, agent_trace, confidence router_node LLM-based conditional classifier; classifies question into QUANTITATIVE (counts/scores/aggregations) or SYNTHESIS (strategy/ analysis/recommendations); safe fallback to synthesis on HF error Route A β calculator_node (Tool-Calling Agent) Tool registry: average_score, count_by_dimension, top_signals, score_distribution; LLM selects tool via JSON response; Python executes against live signal metadata; LLM narrates result Route B β analyst_node (RAG-hydrated Analyst Agent) Injects Astra DB context serialised through dict_to_string() to eliminate context poisoning from raw Python dicts in LLM prompts dict_to_string(data, indent) Recursive unpacker: dicts β indented β¦296d877 -
feat: migrate vector store from ChromaDB to Astra DB + Astra Vectorizeβ
ritvikv03 +1: Claude Sonnet 4.6core/database.py β complete rewrite - Remove all chromadb / sentence-transformers / ONNX runtime dependencies - Integrate DataStax Astra DB via astrapy DataAPIClient - Collection "pestel_signals" created with Astra Vectorize: provider=nvidia, model=NV-Embed-QA (1024-dim, cosine) No local model or external embedding API call β Astra embeds server-side - Signal._to_astra_doc(): maps Signal β Astra document (_id, $vectorize, fields) - Signal._from_astra_doc(): reconstructs Signal from Astra document (accepts both native lists and legacy JSON strings for entities/themes) - SignalDB._get_or_create_collection(): idempotent bootstrap on first init - SignalDB.insert(): find_one_and_replace(..., upsert=True) β safe re-ingestion - SignalDB.search(): find(..., sort={"$vectorize": query}, include_similarity=True) converts Astra similarity [0,1] β distance convention (1.0 β similarity) to preserve all existing threshold logic in pipeline.py and graph_engine.py - SignalDB.get_all(): limiβ¦b65c098 -
feat: model unification, node truncation, generate brief buttonβ
ritvikv03 +1: Claude Sonnet 4.6- Step 1: Replace all HF model strings with meta-llama/Llama-3.2-3B-Instruct across pipeline.py, graph_engine.py, summary_engine.py, and app.py chat - Step 1 (continued): Replace HuggingFaceEndpoint (LangChain, broken novita text-generation task) with InferenceClient.chat_completion() in summary_engine._call_llm() and app.py _llm_chat() - Step 2: Node label truncation in graph_engine.update_graph() β both new signal nodes and historical match nodes now use 35-char + "..." truncation - Step 3: Add "Generate New Intelligence Brief" button to Strategic Reports tab; new generate_intelligence_brief() callback fetches top-10 signals, calls generate_brief_markdown(), writes outputs/reports/Strategic_Brief_<ts>.md, refreshes dropdown and renders new report inline - Add generate_brief_markdown() + _rule_based_brief() module functions to summary_engine.py with full LLM + deterministic fallback implementation Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>81a544d
-
refactor: replace Gemini with HuggingFace/LangGraph stackβ
ritvikv03 +1: Claude Sonnet 4.6- Swap core/pipeline.py to HuggingFaceEndpoint (Mistral-7B-Instruct-v0.3) with module-level singleton, [INST] format, and severity_score removed - Swap core/summary_engine.py to HuggingFace, fix dead q2_solution db path - Add semantic deduplication (cosine threshold 0.08) before LLM scoring - Create core/graph_engine.py: 4-node LangGraph RAG knowledge-graph workflow with aborted sentinel, correct short-circuit logic, and edge deduplication - Hook run_graph_update() into scheduler after each successful signal insert - Add Export Report button + dcc.Download HTML export in app.py - Rename tabs: Field Intelligence, Disruption Horizon, Signal Feed, Strategic Advisor - Update sidebar brand to AGRO-MARKET INTELLIGENCE, remove Gemini branding - Reset data/graph.json to empty template (no synthetic data) - Add langchain/langgraph/huggingface_hub deps with upper-bound caps Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>c9dcf7a