Skip to content

Latest commit

 

History

14 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TriLayer

A research pipeline exploring three-layer agentic orchestration — where declarative structure ends and imperative judgment begins.

Type: Application Skill Loadout: PAUL, AEGIS Stack: Python 3.11 · pydantic-ai · pydantic-graph · SQLModel · SQLite · Typer · Rich


Overview

TriLayer is a solo research tool built to answer one architectural question: at what point does a declarative graph specification require imperative runtime judgment to recover?

Three layers:

  • Planner — given a research topic, produces a typed GraphSpec (nodes, edges, typed data flows)
  • Executor — pydantic-graph's runtime, extended with mutation capabilities: detects weak node output, inserts nodes, rewires edges, logs every deviation
  • Node Agents — execute narrow research tasks (arXiv search, paper summarization) via pydantic-ai subagents

HumanInput is a first-class node type — execution blocks and prompts the user when the Executor can't resolve ambiguity autonomously. Runs persist to SQLite and are resumable across processes.

Test domain: academic paper research — given a query, find relevant arXiv papers, extract key contributions, produce a structured summary. The GraphMutation log is the primary research artifact.


Stack

Layer Choice
Agent framework pydantic-ai
Graph runtime pydantic-graph
Database SQLite + SQLModel
CLI Typer
Terminal UI Rich
Testing pytest + pytest-asyncio
Config python-dotenv
arXiv integration arxiv (Python library)

Data Model

Entity Purpose
GraphSpec Immutable Planner output — original declared intent
ExecutionGraph Mutable clone per run — what actually executes
Node AgentNode | HumanInputNode
Edge Typed payload between nodes (explicit wiring, declared by Planner or injected by Executor)
ExecutionRun Ties GraphSpec → ExecutionGraph, tracks status
NodeExecution Per-node state (status, input, output, retries)
HumanInputRequest Blocking clarification tied to a NodeExecution
GraphMutation Executor deviation log — primary research artifact

CLI Interface

trilayer run <topic>        Planner → GraphSpec → Executor loop
trilayer resume <run-id>    Resume a suspended HumanInput run
trilayer inspect <run-id>   Rich display: graph, node statuses, mutations
trilayer runs               List all ExecutionRuns with status

Architecture

GraphSpec is immutable after the Planner produces it. The Executor (pydantic-graph's runtime, extended) clones it into a mutable ExecutionGraph and works there.

Adaptation trigger: LLM judgment is the primary mechanism — the Executor asks the LLM whether the node output is sufficient to proceed. A fast-path threshold (e.g. < 3 results) fires before invoking LLM judgment to avoid unnecessary inference.

When the Executor adapts, it logs a GraphMutation with a structured enum reason (INSUFFICIENT_RESULTS, LOW_CONFIDENCE, AMBIGUOUS_QUERY, HUMAN_CLARIFICATION_REQUIRED) plus before/after graph snapshots. The delta between the original GraphSpec and the final ExecutionGraph is the answer to the research question.

Edge payloads are typed — the Planner declares all data flows upfront; the Executor must wire new edges explicitly when inserting nodes, making every deviation traceable.


Implementation Phases

Phase Name Outcome
1 Three-Layer Wiring All three layers connected, real arXiv data flows through typed edges
2 Executor Adaptation Executor detects weak output, inserts nodes, mutation log populated
3 HumanInput Blocking clarification works end-to-end
4 State Persistence Runs survive process restart, resume works
5 Rich Visualization inspect renders full run breakdown

Design Decisions

  1. GraphSpec is immutable: Executor works on a mutable ExecutionGraph clone — preserves original Planner intent for research comparison.
  2. Typed edge payloads: Planner declares all data flows; Executor wires edges explicitly when mutating. Deviation is traceable.
  3. HumanInput is blocking (terminal): Simpler to implement; valid for research purposes.
  4. No FastAPI: Typer + Rich sufficient for a local research tool.
  5. GraphMutation as primary artifact: Records what changed, where, and why — designed to be inspectable across runs.
  6. arXiv as primary integration: Free, no auth, stable Python library.
  7. Executor is pydantic-graph's runtime, extended: Not a separate orchestrator — pydantic-graph's runner augmented with mutation logic. pydantic-ai handles LLM inference within Node Agents.
  8. Adaptation trigger — LLM judgment primary, threshold fallback: Fast-path threshold fires first; LLM judgment invoked when threshold alone is insufficient.
  9. GraphMutation.reason is a structured enum: Enables programmatic analysis of mutation patterns across runs.

References


Last updated: 2026-04-06

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages