Repository navigation
Deliberate reasoning loop + Memory v2 + prompts registry - #2
Merged
Merged
Conversation
Take the transferable idea from arXiv 2603.16021 (interpretable, version- controlled context as files) without its multi-agent-replacement thesis, which does not fit dexta's rigor design. agents/prompts/ holds prompts as markdown loaded by name; a user can override any of them via [prompts] dir. The dosing/observation rail is a code constant re-applied by with_safety, so an override can never remove the safety floor. Proof slice migrates the chat system prompt verbatim (byte-identical, asserted); the other ~10 agents follow the same pattern next.
Every agent prompt now loads from agents/prompts/*.md instead of an inline constant: chat, discovery, insulin, coordinator (plan/replan), brief (system/user), orchestrator (doctrine/system), investigator (reflect/write), router (safety/route + the five family systems), seeker (reflect/goal), and advisory (refine). System prompts that carry the dosing rail load through with_safety so an override cannot strip it; the rest load verbatim. Migration is byte-identical: each file was dumped from the original constant and test_prompts_rollout.py asserts every constant equals its intended file (no cross-wiring). Removed the now-dead orchestrator._HARD_RULES (folded into orchestrator_system.md). ruff/mypy clean, full suite 1288 passed.
- README: add CI/license/python badges; repoint the deleted DEXTA_OSS_TECHNICAL_SPEC.md link to TECHNICAL_REPORT.md. - Add CITATION.cff. - CHANGELOG: note the prompt registry, Dockerfile, and CITATION.
Curated, committed docs (TECHNICAL_REPORT, EXTENDING, PRODUCT-OVERVIEW) now live in guide/, separate from the gitignored docs/ dev notes. README, LICENSE, the community-health files, and the legal/safety docs stay at root where GitHub and readers expect them. Updated the README links and the test_extensibility docstring.
- #8: rename the two _text_of variants by behavior (_content_text extractor vs _strip_code_fence) so one name no longer means two things. - #10a: add the dexta-mcp console_scripts entry point. - #10b: verified pattern.py:647 is live (not a dead branch); closed. - #10c: monitor._severe_high now breaks a sustained-high run on a sensor gap so a gap is not counted as sustained (regression test added). - #7 unblocker: CI now runs the Postgres parity suite against a postgres:16 service, so the backend is tested and the dedup becomes verifiable. ruff/mypy clean, full suite 1289 passed.
- #7: hoist the two byte-identical store helpers (_opt_json, _prediction_horizon_min) into store/_common.py, shared by both backends. The _row_to_* mappers genuinely differ (TEXT-JSON vs JSONB) and stay per-backend. - #9: one _relative_time (server/_format.py, None-safe superset) replaces the 4 server copies; one parse_json (agents/_json.py, optional logging context) backs the 3 former _parse_json copies. ruff/mypy clean, full suite 1289 passed.
guide/DEMO.md (4-5 min walkthrough script for an AI/AI-health audience), guide/UI-ROADMAP.md (the hero-visualization plan), guide/RELEASE.md (PyPI, supply-chain CI, one-command Docker demo). PRODUCT-OVERVIEW gains a dedicated "novel piece: agentic AI + LLM" section (LLM navigates, determinism computes, rails enforced in code) and links the companion docs.
… user The one net-new from the feature review. Determinism detects a context gap (a spike >= 200 mg/dL with no logged meal or note within +/- 90 min); dexta asks the user to log what happened. It asks, it never fabricates the value. - models.ContextRequest: the observation-only question + the gap's evidence. - agents/context_acquisition.py: ContextAcquisitionAgent.build(ctx) detects gaps deterministically, templates a safe question (passed through the dosing-advice gate), caps at 5, and optionally rephrases via a model that falls back to the template on any unsafe or failed output. - server: /context page (views_context + template) listing the questions with a "Log it" link to the existing manual-logging page; dashboard link added. Comprehensive tests (detector suppression by meal/note, cap, safety gate, model fallback, minimal-store degrade, page render + empty state). ruff/mypy clean, full suite 1302 passed.
The demo-facing UI pass (per guide/UI-FIX-PLAN.md): - Hero glucose-trace chart on the dashboard (server-rendered SVG: target band, spike highlight, carb/bolus markers, attribution annotation) via server/charts.py + views_hero.py + _hero_chart.html. - Trace timeline component (views_trace.py + _trace_timeline.html) and a goals sidebar view. - Nav consolidated to primary tabs + a "More" group; cached header status pill. - Reconciliation/findings view-model updates and template/CSS/JS polish. Cleaned to the project bar: ruff clean, mypy strict clean (120 files), full suite 1310 passed. (lint/type fixes: charts min/max + TYPE_CHECKING import, hero-view helper extraction for complexity, nav-globals typing, status-pill cast.)
The highest-impact run-quality fix from the parity audit (guide/MEMORY-V2-AUDIT.md). - recall() now returns only ACTIVE findings. Previously it excluded only STALE, so rejected / superseded / dismissed / contradicted findings could still be pulled into an agent's context and reasoned from. It now also emits an `excluded` list labeling each withheld memory by reason (not_used_rejected / superseded / contradicted / stale). - New FindingStatus.CONTRADICTED. The skeptic already detected contradictions (downgraded confidence, logged notes) but left the finding ACTIVE; it now marks it CONTRADICTED, with rejection taking precedence. Wired into the embeddings status-weight, the findings graveyard, and the wiki graveyard. Tests: recall excludes non-active and labels them; the skeptic sets CONTRADICTED on a contradicting finding. ruff/mypy clean, full suite 1311 passed.
Finishes the run-affecting + demo-facing Memory v2 work: - Recall now also withholds any active finding that reads as dosing advice (_ADVICE_RE over headline/body), labeled not_used_safety_blocked, so no dosing memory is retrievable. - Memory guard evals (tests/test_memory_guard.py): stale/rejected/contradicted/ superseded/dosing all excluded with the right reason; active used; used and excluded both reported. - Memory Inspector page at /memory (views_memory.py + memory.html + nav): memory in use vs withheld, with the exclusion reason for each. Deferred (tracked): the provenance-column migration (source_run_id, coverage_limited, profile_version_id, etc.) is gated on the live-Postgres CI parity check and is a follow-up. ruff/mypy clean, full suite 1321 passed.
Score the investigation path, not just the final answer: cross-modal evidence coverage (did it consult the tool-classes the planted cause needs), probe efficiency (tool calls vs a budget), gap-handling (flag missing context instead of fabricating), and path soundness. Reuses the E6 InvestigationOutcome and a shared attribution predicate so E6 and E7 cannot drift. Runner stays injectable, so the metric is fully tested key-free. Adds the eval reasoning subcommand and a gap scenario whose cause is unlogged.
Give the agent's understanding a place to live across steps: a structured BeliefState (competing hypotheses with status, evidence, open gaps, running confidence, summary) the model revises through an update_belief tool. The loop offers the tool, streams a belief event after each tool round, and returns the final state; the orchestrator threads one per ask. Fully additive: belief defaults to None, so the existing run_reasoning_loop contract is unchanged. The belief tool emits no evidence numbers, so it cannot leak past the faithfulness guard. Foundation for hypothesis-driven probing and adaptive re-planning.
Wire the hypotheses store into the live belief: seed_belief_from_store pulls the
open hypotheses prior analysis banked and re-enters them as competing hypotheses
the orchestrator injects into the first-turn prompt with stable stored-{id}
keys, so the model probes to discriminate or refute them and can update their
status in place instead of minting duplicates. Read-only on the interactive path
(no surprise writes), deduped, capped, and defensive over an optional backend.
Seeding records prior hypotheses; it never decides for the model.
The belief state now suggests the most discriminating evidence not yet gathered for its open hypotheses: a light heuristic that maps hypothesis keywords to evidence modalities and recommends an unexamined one, folded into the snapshot the model reads each step. The loop feeds it the tools actually called. Advisory only: nothing branches on the suggestion to choose, skip, or stop probes, and it stays out of the faithfulness evidence pool. Improves the probe-efficiency and coverage that Phase 0 measures.
Turn the loop into probe -> update -> decide with explicit stop conditions: when belief confidence is high or consecutive rounds add no new information, inject a one-shot nudge to conclude and emit a stop_signal, rather than probing in circles to the step budget. A per-round belief signature (evidence, confidence, hypothesis status/statement/note) detects stagnation; refining a hypothesis counts as progress, not a stall. Advisory only: nothing terminates the loop on belief, max_steps stays the sole hard stop, and with no belief the loop is unchanged.
When a gap blocks discrimination, the model can call request_context for the moment it cannot explain. The tool reuses the batch detector's proximity rule and dosing gate to return either the context already logged near that time (so the model probes it) or a precise, observation-only logging request to surface in the answer instead of guessing. It returns no evidence numbers, so it stays clear of the faithfulness guard, and never fabricates the missing value. Additive: an advisory tool on the belt, unchanged when the model ignores it.
At the end of an investigation, synthesize() fuses the belief and tool trace into one explanation plus its evidence graph: the leading hypothesis, the alternatives ruled out, the supporting evidence, the cross-modal probes, and the open gaps. Every text field that can carry a number is re-audited against the tool evidence pool and dropped if a figure does not trace, so the synthesis cannot surface a number the tools never produced. The orchestrator attaches it only to a clean, faithful conclusion (not a fallback or a treatment-gate fade). Grounds in material already available; the deferred Memory v2 provenance schema is not a dependency.
Phases 1-6 added update_belief and request_context to the trace; they are bookkeeping, not probes, and would otherwise inflate the probe count and make a post-synthesis E7 run incomparable to the pre-belief baseline. Promote META_TOOLS to the public source of truth in investigation.py and have E7 count real probes only, so synthesis and the reasoning eval agree on what is not a probe.
guide/ is for reader-facing docs; the intelligence-flow plan and the Memory v2 audit are internal implementation/working docs and belong under docs/.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Turns dexta's improvised investigations into a deliberate, measured progressive-reasoning loop, alongside Memory v2, active context acquisition, a prompts registry, and OSS hardening. The thesis holds throughout: the agents are the intelligence; determinism scaffolds and verifies. The two rails (faithfulness guard, treatment gate) are untouched.
Intelligence flow (Phases 0-6)
eval reasoninggrades the investigation path, not just the answer: cross-modal coverage, probe efficiency, gap-handling, path soundness. Built first so the rest is provable.BeliefState(hypotheses/evidence/gaps/confidence) the model revises via anupdate_belieftool, threaded through the loop. Additive; stays out of the faithfulness evidence pool.max_stepsstays the only hard stop.request_contexttool: when a gap blocks it, surface a precise, dosing-gated logging request instead of guessing. Reuses the unexplained-spike detector.Each phase was reviewed against Google's eng-practices bar and ships green.
Also in this branch
CONTRADICTEDstatus,/memoryinspector./context).uv lockfix,/reportsno longer blocks on PubMed, redacted stream/storage errors, Dockerfile, CODE_OF_CONDUCT, CITATION.cff.Validation
ruffandmypyclean acrosssrc,eval,tests(138 source files).