Agentic RAG-based report writing (handcrafted multi-agent pipeline + QMIX baseline).
Project description
Agent Q-Mix: QMIX for Multi-Agent Communication Topology Optimization
REQUIRES: Python >= 3.10
QMIX-based multi-agent reinforcement learning that learns optimal communication topologies for LLM agent collaboration. Maximizes task accuracy while minimizing token usage.
Architecture
Networked MMDP with centralized training, decentralized execution:
- GNN Message Passing — Agents communicate through a learned graph topology
- Per-Agent Q-Network — GNN -> GRU (temporal) -> MLP (Q-values)
- QMIX Mixing Network — Monotonic: $\frac{\delta Q_{tot}}{\delta Q_i} >= 0$
- Reward = $\Delta_{report , score} \times w_{report , score} + \Delta_{token , goal} \times w_{token , goal}$, where $\Delta_{report , score}$ is the variation of the report score compared to its last state and $\Delta_{token , goal}$ is the variation of the token goal score compared to its last state. The token goal score is calculated using a Gaussian curve centered around the token goal.
QMIX Actions
| Action | Name | Communication Pattern |
|---|---|---|
| 0 | solo_process |
No communication |
| 1 | broadcast_all |
Send to all neighbors |
| 2 - 5 | selective_query |
Query one neighbor (one for each agent) |
| 6 | aggregate_refine |
Receive from all, refine |
| 7 | append |
Send to a collector node |
| 8 | terminate |
Output the content of collector node |
Quick Start
On Gemini 3.1 Flash Lite Model:
cp .env.example .env # Add your API key
pip install -r requirements.txt
# To Train and Test (LCB, HE, MMLU, AIME, B-AIME, HMMT)
bash scripts/run_all_gemini.sh
# To Test For HLE
bash scripts/run_hle_gemini.sh
On GPT-oss 120B Model:
cp .env.example .env # Add your API key
pip install -r requirements.txt
# To Train and Test (LCB, HE, MMLU, AIME, B-AIME, HMMT)
bash scripts/run_all_gpt.sh
# To Test For HLE
bash scripts/run_hle_gpt.sh
Reproducibility
Pre-trained QMIX checkpoints and evaluation results from our runs are included in the repository.
Checkpoints
| Model | Path |
|---|---|
| GPT-OSS:120B | checkpoints/qmix_unified.pt |
| Gemini Flash Lite | checkpoints_gemini/qmix_unified.pt |
Project Structure
The library code is an installable Python package, qmix_report_writer/, so it
can be embedded in a host project (pip install + from qmix_report_writer import
run_handcrafted). Development entry points, tests and runtime data live at the
repo root, outside the package.
Q-Mix_report_writer/ # repo root
├── qmix_report_writer/ # ── installable package ──────────────────
│ ├── __init__.py # public API (re-exports run_handcrafted)
│ ├── handcrafted_graph/ # deterministic phase-based pipeline (+ runner)
│ ├── qmix/ # QMIX core (GNN, Q-networks, mixing, replay, trainer)
│ ├── graph/ # multi-agent graph execution engine
│ ├── agents/ # agent roster (LeadArchitect, Researcher, ...)
│ ├── llm/ # LLM API layer (Ollama)
│ ├── prompt/ # prompt sets
│ ├── tools/rag/ # RAG manager (ChromaDB + hybrid retrieval)
│ ├── utils/ # config/paths, report export, PDF, visualization
│ ├── configs/ # bundled default.yaml (defaults; host-overridable)
│ └── assets/ # images used by the PDF/LaTeX template
├── experiments/ # training and evaluation entry points
├── scripts/ # ingestion / query utilities
├── datasets/ # benchmark dataset loaders
├── tests/ # test suite
├── checkpoints/ # saved QMIX models
├── pyproject.toml # package definition + dependencies
├── requirements.txt
└── (git-ignored runtime data: chroma_data/, output/, .tools/, *_trace.json)
Configuration & data paths
configs/default.yaml ships inside the package as the built-in defaults. A host
overrides it without editing package files via configure(), a YAML override
file (QMIX_REPORT_CONFIG), or in-code overrides:
from qmix_report_writer.utils.config import configure
configure(overrides={"paths": {"output_root": "qmix_report_writer_data"}})
Runtime locations resolve against two independent, configurable roots (both default to the current working directory, so standalone use is unchanged):
- data root (
paths.data_root/QMIX_REPORT_DATA_ROOT) — used resources: the Chroma DB (chroma_path) and the Tectonic cache (tools_dir). - output root (
paths.output_root/QMIX_REPORT_OUTPUT_ROOT) — files the pipeline produces: report runs (output_dir) and execution traces (trace_file). A host typically sets only this to group generated artifacts in one folder, leaving the DB in place.
Using the package in a host project
A short end-to-end walkthrough for embedding the report writer in another
project. The public entry point is the async run_handcrafted.
1. Install — pin to a released version tag for reproducibility:
pip install git+https://github.com/leobeaumont/Q-Mix_report_writer.git@v0.1.0
Use
@mainfor the latest stable code, or@<commit-sha>to pin an exact commit. Pinning a tag is recommended so a given host build always resolves the same code.
Runtime prerequisite: a running Ollama serving both the generation model (see
llm.default_modelindefault.yaml) and the embedding modelnomic-embed-text. PDF export additionally needs Tectonic onPATH(otherwise it is auto-downloaded; see tectonic cache above), or passexport_pdf=False.
2. Wire it up (optional) — point produced files at a dedicated folder and/or
load your own config. Call configure() once, before the first run:
from qmix_report_writer.utils.config import configure
configure(overrides={"paths": {"output_root": "qmix_report_writer_data"}})
# or load a whole override file: configure(config_path="host_qmix.yaml")
# or set env vars instead of calling configure():
# QMIX_REPORT_CONFIG=host_qmix.yaml QMIX_REPORT_OUTPUT_ROOT=qmix_report_writer_data
3. Ingest documents into the RAG store (once, or whenever the corpus changes):
from qmix_report_writer.tools.rag import RAGManager
rag = RAGManager() # uses paths.chroma_path under the data root
rag.add_document_from_path("docs/paper.pdf") # also supports .txt/.md/.docx
4. Generate a report:
import asyncio
from qmix_report_writer import run_handcrafted
answers, total_tokens = asyncio.run(run_handcrafted(
task="Write a technical report on graphene synthesis.",
export_pdf=True, # set False to skip LaTeX/PDF and keep only markdown
))
report_markdown = answers[0]
Artifacts are written under <output_root>/output/<timestamp>_<slug>/ (raw
markdown, .tex, .pdf); the vector DB stays at <data_root>/chroma_data. From
inside an existing async context, await run_handcrafted(...) directly instead of
asyncio.run.
Adaptation for report writing
This repository is a specification of ericjiang18/Agent-Q-Mix for scientific report writing. This part describes the modifications applied to the code to solve the report writing task.
New team of agents
The team of agents used for report writing is the following:
- Lead architect: responsible for the outline, highest messaging and appending priority.
- Researcher: can use RAG tools to look for information in the database.
- Data analyst: turns raw data into ideas.
- Reviewer: review and grades writings, used to calculate the reward function, lowest messaging and appending priority.
From final answer to append loop system
Agent-Q-Mix uses a final answer system, where all the agents interact during their communication rounds. After a fixed set of rounds, all of their output is passed to a decision agent to generate the final answer given to the user. This approach is good for problem solving and especially token efficiency, but in our case generating a full report in one pass of the decision agent would create poor results.
To solve this problem, an append loop approach is used without breaking the structure of the original code. To do that, 2 new actions have been added: append and terminate. When the append action is used by an agent, its output is sent to a collector agent. The collector is only used to store the current state of the report as it is written and does nothing else. When the terminate action is selected by the majority of the agents, the round loop ends and the report stored inside of the collector agent is returned. This approach keeps the graph design of the original code. This means that the information flows from the user query to the final report with no interruption.
Technical changes:
- Creation of
appendandterminateactions. - Removed
debateandexecute_verifyactions. - Created a copy of
selective_queryaction for each agent. This way Q-Mix can choose the interlocutor by using the corresponding version of the action. This means Q-Mix has a pool of $5 + N$ actions where $N$ is the number of agents. - Multiple agents may choose the
appendaction in the same round; all of them get a spatial edge to theCollector, which processes every incoming message. - Creation of the
collectornode that receives the output of the agents choosing theappendaction. - The
collectoris a normal node like other agents, but it can't use any action. - The
terminateaction ends the round loop only when a majority of the acting agents vote for it (threshold:>= n_acting / 2votes). A single agent votingterminateis not enough. - The
Collectormakes two sequential LLM calls per append: the first generates the polished prose to add to the report, the second (using a dedicated "Summarizer" role prompt) rewrites the progress summary so all agents have an up-to-date picture of what has been written. - The
Collectorsilently skips execution when itsspatial_infois empty (no agent sent it a message that round) or when theDataAnalyst's entire message consists only of absence markers (State Deficiency,absent,not found, etc.). This prevents meta-commentary about missing evidence from ever reaching the report. - When an agent choose the
appendaction, its prompt informs it that its output will be added to the report. - The verification to avoid graph cycles is still present and gives messaging priority to lower indices agents.
- When an agent action is denied because of a cycle, its action is defaulted to
solo_process. - Changed Kahn's algorithm in
graph/graph.py: _execute_roundmethod to accept self edge and mutual edge. - Modified Q-Mix to only train and select actions for the 5 acting agents, while ignoring the
collectornode. - Added a dynamic
ReportStatesingleton to track the report text, sources and a progress summary. Internally, the report is stored as a structured list of sections, each with a uniquesection_id, atitle(inferred from the first Markdown heading), and itscontent. This allows targeted in-place replacement viareplace_section(section_id, new_content)and a formatted section index vialist_sections(), both used during the review and revision flow. The report state is updated by theCollectoragent and the summary of progress is given as context to other agents. - The report state summary is embedded inside of the observation features as context for the Q-Mixer.
Lead Architectnow define aCurrent Team Objectiveto help the team separate the goal of the round from the global report subject. This aims to help the agents decompose the task into small trivial parts.- Added a deterministic post-processing filter (
utils/report_filter.py) applied to the final report before it is returned to the caller. The filter works at sentence level and removes any sentence containing pipeline-internal jargon (State Deficiency,data atoms,evidence atoms,RAG Tool,RAG results, internal variable names, etc.) as well as section-transition sentences that reference "the next/following/subsequent section". No LLM call is made; only unambiguous pipeline-internal patterns are removed so that legitimate scientific prose is left untouched.
From a post-process to in real time reward system
Agent-Q-Mix is trained on a set of problem solving database. To train the Q-Mixer they use the score based on the answers given by the model to each problem of the datasets. And a penalty is applied for token usage. This forces the model to be precise with few tokens.
In the report writer implementation, since the Q-Mixer is not used for problem solving, it can't be scored using answer accuracy anymore. On top of that, report generation is a longer process than problem solving. It means that it is possible and preferable to score the model while it is constructing the report, to help the model understand the quality of each of its decisions. This change is highly compatible with the new append loop architecture: every time content is added to the report with the append action, it is possible to score the quality of the addition and the token usage. The Q-Mixer reward can be computed mid-process using these scores. More precisely, the variation of the scores between the previous and the current state of the report gives a very good insight on how good the last addition was to the overall report. And the better the addition is, the better the reward will be.
Technical changes:
- Changed reward to $\Delta_{report , score} \times w_{report , score} + \Delta_{token , goal} \times w_{token , goal}$.
- Added an optional
JSONschema format to the LLM handlers, that forces the LLM's output to a specific format. - Added a
Micro ScoringandMacro ScoringLLM judges used during training to help improve the quality of the production. TheMicro Scoringjudge scores each chunk of the document. TheMacro Scoringjudge scores the whole document. Micro Scoringjudge is responsible for: logic, verifiability, technical precision, information density and hallucination flagging.Macro Scoringjudge is responsible for: subject coverage, flow, structure, tone and avoiding repetition.- The reward is now computed after every
appendaction, because the changes in the report cause changes in the reportscoreandtoken goalcompletion. - All rounds between the previous
appendround and the currentappendround receive an even fraction of the reward. This is done to reward all the rounds that lead to a goodappendto the the report and not only the round where theappendaction occurs. The reward is shared between rounds to motivate the model to be efficient (i.e.: get to a high qualityappendaction in as few rounds as possible). - Added a
ScoreandLengthGoalsingletons to track their current respective value, but also the previous one. This way aget_delta()method can be called on them to get the difference between their current and their last value. - Changed the training pipeline to compute the reward after each
appendaction. - Added a
step bufferto propagate the reward to all the rounds that lead to theappendaction. The reward is evenly spread between all actions to reward the whole process of creation. Any steps remaining in the buffer at the end of an episode (i.e. after the lastappend) are flushed to the episode withteam_reward = 0. - Added a
length scorerbased on a Gausian curve centered at $\mu = 25000$ and $\sigma = 8500$ with a peak of height 1. The goal of 25000 character correspond to ~4500 words which is the average length of scientific documents. The value of $\sigma$ is set to 8500 to start giving a good reward signal at around 5000 characters. - Added a
report scorerbased on the 2LLM judgesdescribed earlier.- The
Macrojudge is prompted to analyze the whole report with only a prompt and the report as context. - The
Microjudge is prompted to analyze each chunk of the report individually. When the judge process a chunk he has access to: its prompt, global notes generated by theMacrojudge, a summary of the report, notes from theMicroanalysis of all previous chunks and the text of the current chunk. - Each judge produces scores for each categories they are asked evaluate, with scores ranging from 0 to 5.
- The final score of the report is the average of all the
Macroscores and all theMicroscores from each individual chunks. - The final score is normalized between 0 and 1. To ensure it has the same scale as the
length score.
- The
- To compute the
reward, the evolution of thelengthandreportscores is used. This ensure that an addition that increases significantly the global score is greatly rewarded. However is mediocre addition is not rewarded much and a bad addition can even be penalized.
Adding tool usage
The first tool implemented is a RAG tool (Retrieval Augmented Generation). It is exclusive to the Researcher agent. When used, it lets the agent search for sources documents from a database. The sources used during report generation are tracked, to ensure proper citation and verifiability of the final result.
Technical changes:
- The selected
actionis passed from the graph's main loop (arunmethod) to the agent's execution (async_executemethod). - When an agent
execute, it can trigger tools and modify its prompt depending on theactionreceived. - Implemented
RAGdatabase inside oftools/rag. TheRAGalso usesoLLamato ensure the privacy of all the documents. The whole production loop (embedding / storing / querying / generation) is fully local, and doesn't require any network connection. - The current implementation of the
RAGuses theChromaDBlibrary. - Added a
SourceBuffersingleton to track the sources used to generate each part of the report. The buffer stores the sources given by theRAGtool to generate the current report part and it is flushed when the part is added to theReportState. Once flushed, the sources are stored in theReportStatewith their respective part. - The
Collectoragent is responsible for flushing the sources from theSourceBufferand storing them inside of theReportStatewhen processing anappendaction. - When a
Researcheragent execute, it start by generating a query to theRAGtool, using its current context. The query is then used on theRAGdatabase to find relevent chunks of information. These chunks are then added to theResearcher's context before generating its notes for the next round of communication. - To respect the graph architecture of the project, the
RAG's selected documents are passed to theResearcheragent via aspatialedge. With this representation, the tool can be represented by a node just like any other agent. - Wrote prompt for preparing the query given to the
RAGtool. The query is prepared with the communication context of theResearcheragent and aims to formulate a precise and effective query. - Added
ChromaDBandollamalibraries to the requirements.ChromaDBis used to handle the vectorial database andollamais used to embed the query locally using oLLama (to avoid data leaks). - Added cosine distance threshold filtering (ceiling: 0.7). Chunks below the relevance bar are discarded before reranking; if all candidates fail the filter, the method returns an empty list, triggering
[RESEARCH_EXHAUSTED]rather than injecting noise. - Added cross-encoder reranking with
BAAI/bge-reranker-baseloaded viatransformers(bypasses thesentence_transformersimport chain, which conflicts with the localdatasets/module). The cross-encoder scores each(query, chunk)pair jointly, far more accurately than cosine similarity. Retrieves 15 candidates, returns top 3 after reranking. Model is lazy-loaded on first query. - Multi-query expansion: the RAG Tool prompt now requests 3 semantically distinct queries per retrieval — one targeting implementation details, one targeting system-level context, one targeting behavioral/process aspects. Candidates from all 3 queries are deduplicated by chunk ID before reranking. The RAG Tool constraint prompt enforces a hard 8-term limit per query line and introduces a
NO_QUERYfallback sentinel so the LLM never echoes pipeline signals as queries. - Page number metadata:
add_document_from_path()tracks a runningcurrent_pagecounter across chunks by detecting[PAGE N]markers already present in PDF text. Page number is stored in each chunk's ChromaDB metadata; query results now carry real page references instead of"N/A". - Contextual chunk prefixing: each chunk is embedded with a one-line prefix
[Source: filename | Page: N]prepended to the text. The stored document text remains the original (no prefix). This anchors semantically vague chunks to their document and page context at embedding time. Because the prefix is embedded together with the chunk, the chunk budget reserves prefix headroom (effective_chunk_size = min(chunk_size, 512 - 24)) so prefix + chunk stays within nomic-embed-text's 512-token encoder limit. The server tokenizes with nomic's WordPiece tokenizer (which splits dense math/LaTeX text into more tokens than tiktoken's cl100k), so a chunk under the cl100k budget can still exceed the server's 512-tokenn_ubatchand crash the runner (Post .../embedding: EOF→ HTTP 500). Rather than pre-shrinking every chunk on a guess,_embed_batchself-heals: if a batch is rejected it re-embeds that batch one chunk at a time and progressively truncates only the specific chunk(s) that keep failing, so good chunks keep their full text and an oversized chunk fails neither its batch-mates nor the document. - Replaced
OllamaEmbeddingFunction.__call__()(which routes through ChromaDB's internal server causing random-port connection failures) with a direct HTTP call to Ollama's/api/embedendpoint viaurllib, matching the approach inllm/ollama_chat.py. - Added an in-memory BM25 index (
BM25Okapifromrank_bm25) built from all ChromaDB documents at initialisation time and rebuilt after every mutation. BM25 handles exact-term matching that dense vector embeddings dilute — critical for project-specific acronyms, component names, and internal identifiers the embedding model has not seen. - Added Reciprocal Rank Fusion (
_rrf_merge, k=60): merges the vector search and BM25 ranked lists into a single ranking by summing1 / (k + rank + 1)scores per document. Chunks appearing in both lists accumulate higher scores and surface ahead of chunks found by only one path.
Adding animated graph visualization
The advantage of preserving the graph structure of the original code of Agent-Q-Mix is that representing the evolution of the graph creates a very visual and accessible debug tool. The tool is programmed to track the full execution trace of the redaction process. And then plot the communication graph of the agents and its evolution round after round.
Technical changes:
- Implemented a full
ExecutionTracesingleton. Every action is tracked with intra-round order and context. This includes for every round:- execution order of the agents
- for each agent:
- selected action
- list of the agents that will receive its message
- prompt
- response
- the current state of the report
- When the graph is initiated with
execution_trace = True, the whole process trace is stored inside theExecutionTraceobject. At the end of the execution, theExecutionTraceis stored inside of ajsonfile (default name:execution_trace.json). - Creation of a visualizer tool inside of
utils/visualization.py. The visualizer creates a full interactive animation from theExecutionTracejsonfile. The animation is a simplehtmlfile (default name:agent_trace.html) that can be openned on any browser and contains all the data/logic of the visualization. - The animation shows the evolution of communications during every step of every round of the process. Displaying the informations of the
ExecutionTracein a human friendly interface. The goal of the interface is to debug the redaction process and find the errors in a timely manner. - On the graph each agent is represented by a
Node. The communication are represented byEdges. - The
timelineof the exectuion is represented by aslide bar, and the active agent and communications at a specific execution step are highlighted for clarity. The information on the active agent is displayed to the right of the graph, alongside the state of the report at that current step. - The
playbutton lets the user observ the graph evolution by going through steps automatically at a rapid pace.
Handcrafted graph baseline
The handcrafted_graph/ module implements a deterministic, phase-ordered pipeline as a structural baseline for the QMIX-trained approach. It reuses the existing Node, AgentRegistry, and Collector infrastructure entirely unchanged, replacing only the action-selection mechanism: instead of the QMIX mixer choosing actions each round, the communication topology is hand-designed and executed in a fixed sequence of phases. This makes it possible to run and evaluate the report-writing pipeline without any RL training.
Pipeline overview:
The pipeline is divided into 5 ordered phases. Each phase defines one or more round patterns that cycle until the phase's maximum round count is reached.
| Phase | Max rounds | Purpose |
|---|---|---|
| PLANNING | 2 | Evidence-first outline. Researcher scans corpus coverage before LeadArchitect commits to any section titles. |
| RESEARCH | 6 | Iterative evidence gathering. LeadArchitect directs Researcher with specific queries; DataAnalyst synthesises raw evidence atoms into structured writing blueprints. |
| DRAFTING | 10 | Section-by-section writing. LeadArchitect designates the section; DataAnalyst structures content; Collector writes and appends polished prose to the report. |
| REVIEW | 2 | Reviewer audits the full draft for factual accuracy, logical coherence, and scientific rigour, then forwards structured critique to LeadArchitect. |
| REVISION | 4 | LeadArchitect applies reviewer feedback. DataAnalyst prepares corrected content; Collector replaces flagged sections in-place (not append). |
Technical changes:
- Created
handcrafted_graph/module with the following components:graph.py—HandcraftedGraphclass. Orchestrates phase-based execution: iterates over phases, builds the spatial edge topology for each round from the phase definition, runs Kahn's topological sort (identical tie-breaking logic asQMIXGraph), and returns the finished report fromReportState.phases.py—PhaseTypeenum,RoundTopologydataclass (required agents, optional agents, directed edge list) andPhaseConfigdataclass (name, description, round patterns, max rounds, next phase). Defines the completePHASE_SEQUENCEandPHASE_MAPconstants.scheduler.py—RoundSchedulerclass with threeSkipStrategymodes for optional agents:ALWAYS_INCLUDE(safest, highest token cost),TEMPORAL_HEURISTIC(include agent only if it has produced output in a prior round), andLLM_GATECHECK(single lightweight LLM call ~50 tokens asking the agent "EXECUTE or SKIP?" before its full execution).LLM_GATECHECKfalls back toTEMPORAL_HEURISTICautomatically when no LLM instance is provided.state.py—PhaseStatesingleton tracking the currentPhaseTypeand the round index within the active phase. Agents and the prompt set read from it to tailor their behaviour without requiring it to be threaded through every call.prompts/handcrafted_prompt_set.py—HandcraftedPromptSetregistered under the key"handcrafted_redacting". Wraps the existingredacting_prompt_setrole descriptions and constraints, and dynamically injects: (1) a phase context block into the system prompt, and (2) a per-(phase, role)objective and current round number into the user-prompt context block. REVIEW and REVISION phases additionally inject the live section ID list fromReportState.list_sections()so agents can target corrections precisely.runner.py—run_handcrafted()async function mirroring the QMIX runner interface. Resets all singletons before each run, constructsHandcraftedGraph, appliesfilter_meta_commentary()to the final output, and optionally saves the execution trace tohandcrafted_trace.json.
- Added
experiments/run_handcrafted.pyas a standalone CLI entry point. Accepts--task,--task-index,--llm,--skip-strategy,--trace,--max-tries, and--max-timearguments. - Spatial edges are cleared and rebuilt from scratch every round according to the current phase topology. Temporal self-edges are re-wired each round: a node that has prior-round output receives its own last output as a temporal predecessor (giving agents memory without an explicit state store).
- Round patterns within a phase cycle: if a phase has N patterns and
max_rounds > N, patternround_idx % Nis selected, so the alternating topology repeats until the phase ends. - The execution trace format exactly mirrors
QMIXGraph, withaction=Nonefor all agents (no QMIX action is selected). This means the existingStandaloneVisualizerinutils/visualization.pyworks without any modification on handcrafted traces. - REVISION Collector performs an in-place section replacement instead of an append. DataAnalyst prefixes its output with a
[SECTION_ID: section_X]tag so the Collector knows exactly which section to overwrite. - Strong anti-hallucination guardrails are embedded directly in the phase-role prompts: Researcher signals
"State Deficiency"when the knowledge base lacks requested data; DataAnalyst propagates the signal and emitsREMOVE:directives for unverifiable claims; Collector omits those claims entirely — an empty section is preferred over speculative prose. PhaseStateis fully reset between runs viarunner._reset_singletons().- Phase early-exit signals allow the pipeline to terminate a phase before its round budget is exhausted. The LeadArchitect emits
[DRAFTING_COMPLETE]when all planned sections have been written or exhausted. The Researcher emits[RESEARCH_EXHAUSTED](code-level, before the synthesis LLM call) when the RAG database returns no documents, or as an LLM output when all retrieved documents are irrelevant to the current directive. The LeadArchitect emits[REVISION_COMPLETE]once all Reviewer-flagged corrections have been applied. The graph detects each signal after the round it appears in and breaks the phase loop immediately, avoiding idle rounds consuming the remaining budget. - Task-sentinel coordination advances section assignments across DRAFTING and REVISION without relying on LLM memory. After writing a section the Collector sets
ReportState.taskto[SECTION_COMPLETE — ASSIGN NEXT SECTION]; after a failed attempt where the DataAnalyst returned only State Deficiency or absence markers it sets[SECTION_SKIPPED — ASSIGN NEXT SECTION]; after a successful in-place correction in REVISION it sets[CORRECTION_APPLIED — ASSIGN NEXT CORRECTION]. The LeadArchitect reads the active sentinel as itsCurrent Team Objectiveat the start of each Round A and advances to the next topic accordingly. - Phase-boundary memory reset: all agent temporal memory (
last_memory) is wiped at the start of every phase. This prevents stale outputs from a finished phase (e.g. DRAFTING-style<task>tags) from pattern-biasing agent behaviour in the next phase. All durable cross-phase context — report content, section list, and current directive — is carried byReportState, which is the intended persistent state store. - Researcher hold mechanism in REVISION: before calling the RAG tool the Researcher performs a code-level gap check. In REVISION Round A (where the
DataAnalyst→Researcherspatial edge is active) it inspects DataAnalyst's output: if noState Deficiencyentry is present it returns[HOLD]immediately without querying RAG. In REVISION Round B (no incoming edge from DataAnalyst) it re-emits its Round A evidence directly to DataAnalyst rather than issuing a redundant second RAG call. TheTEMPORAL_HEURISTICscheduler recognises[HOLD]and[RESEARCH_EXHAUSTED]as non-productive outputs and excludes the Researcher from the following round. - PLANNING deficiency persistence: the Researcher parses
State Deficiencyentries from its PLANNING coverage response and stores them inReportState.deficient_topicsviaadd_deficiency(). The LeadArchitect's_process_inputsinjects this list as a dedicatedTopics absent from knowledge baseblock in itsCurrent report statecontext during PLANNING, making unavailable topics an explicit named constraint rather than free text buried in received messages.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file qmix_report_writer-0.1.1.tar.gz.
File metadata
- Download URL: qmix_report_writer-0.1.1.tar.gz
- Upload date:
- Size: 1.6 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
19944afba35a48681e75fd22d7794011a1f0e5103e7f54e1b90ebdc13d52950e
|
|
| MD5 |
65243f2d7e0bc9481810eba818b5f1b4
|
|
| BLAKE2b-256 |
4a01559b30374b75246e374ad137c84507d4ea638138806e8163413b0dfd0e41
|
File details
Details for the file qmix_report_writer-0.1.1-py3-none-any.whl.
File metadata
- Download URL: qmix_report_writer-0.1.1-py3-none-any.whl
- Upload date:
- Size: 1.6 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5a247c9a5dffc88180c18aaed85b3343084592065b707b2abbff66d0708d2f13
|
|
| MD5 |
14e8830073459484f1e09954ce19062f
|
|
| BLAKE2b-256 |
6d530b794d99cd5ddbe40f67a83c8a7898a42e20766946274b87070fe137a5c3
|