feat(ui): reimagine Spinner as brutalist grid-based loader

- Replace orbital spinner with 3x3 grid of blocks
- Diagonal wave animation matches dithering aesthetic
- Sharp squares, no rounded corners (brutalist)
- Inline horizontal layout with monospace text
- Consistent styling across all loading states

The new loader evokes "tools being constructed" - fitting
for a tool registry. Uses staggered opacity/scale animation
creating a wave pattern across the grid.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Ajax Davis 2025-12-11 08:19:44 +10:00
parent 1e58537a65
commit 150d48d0ba
11 changed files with 6003 additions and 76 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,739 @@
# Hierarchical Cascading Tree: Tool & Context Loading
A pattern for any agent chat interface where tool plans are generated speculatively,
skills/context are inferred backwards from those plans, and execution proceeds with
minimal context at each step.
---
## The Core Insight
Traditional agent flow:
```
User Query → Load ALL tools → Model picks tools → Execute
(huge context)
```
Hierarchical cascading flow:
```
User Query → Generate Y Plans → Infer Skills from Plans → Load minimal context per step
(context derived from likely tools)
```
**Key idea**: The tool plans themselves tell you what context/skills the agent needs.
You don't load everything—you load what the plan reveals is relevant.
---
## Real World Example: Website Audit
**User Query**:
> "Perform a complete audit of my website including SEO, performance, accessibility,
> and security, then generate a prioritized action plan"
### Step 1: Generate Y Plans (speculatively, in parallel)
The system generates 3 alternative plans before any execution:
```
┌─────────────────────────────────────────────────────────────────────────────────┐
│ PLAN GENERATION │
│ │
│ User Query: "audit my website..." │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ PLAN A │ │ PLAN B │ │ PLAN C │ │
│ │ (thorough) │ │ (quick) │ │ (balanced) │ │
│ │ 22 steps │ │ 8 steps │ │ 14 steps │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
```
### Step 2: Analyze Plans → Infer Required Domains
Look at ALL tools across ALL plans to identify skill domains:
```
┌─────────────────────────────────────────────────────────────────────────────────┐
│ DOMAIN INFERENCE FROM PLANS │
│ │
│ Plan A Tools: Plan B Tools: Plan C Tools: │
│ ───────────── ───────────── ───────────── │
│ sitemap-discoverer lighthouse-runner sitemap-discoverer │
│ page-fetcher security-scanner lighthouse-runner │
│ meta-tag-analyzer report-generator wcag-checker │
│ heading-structure-analyzer ssl-checker │
│ internal-link-analyzer action-plan-generator │
│ keyword-density-analyzer report-generator │
│ schema-markup-checker │
│ page-speed-analyzer │
│ asset-analyzer │
│ core-web-vitals-checker │
│ wcag-checker │
│ color-contrast-checker │
│ alt-text-checker │
│ keyboard-nav-checker │
│ ssl-checker │
│ header-security-checker │
│ vulnerability-scanner │
│ ... │
│ │
│ ↓ CLUSTER BY DOMAIN ↓ │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ SEO │ │ PERFORMANCE │ │ACCESSIBILITY│ │ SECURITY │ │
│ │ domain │ │ domain │ │ domain │ │ domain │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
```
### Step 3: Load Domain-Specific Context (Skills)
Each domain has associated contextual knowledge:
```
┌─────────────────────────────────────────────────────────────────────────────────┐
│ SKILL/CONTEXT LOADING │
│ │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ SEO SKILL CONTEXT │ │
│ │ ─────────────────── │ │
│ │ • Meta tag best practices (title 50-60 chars, desc 150-160) │ │
│ │ • Heading hierarchy rules (single H1, logical nesting) │ │
│ │ • Internal linking patterns (hub & spoke, silo structure) │ │
│ │ • Schema.org markup types and validation │ │
│ │ • Core Web Vitals thresholds (LCP < 2.5s, FID < 100ms, CLS < 0.1)
│ └─────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ ACCESSIBILITY SKILL CONTEXT │ │
│ │ ─────────────────────────── │ │
│ │ • WCAG 2.1 AA requirements checklist │ │
│ │ • Color contrast ratios (4.5:1 normal, 3:1 large text) │ │
│ │ • ARIA roles and proper usage patterns │ │
│ │ • Keyboard navigation requirements │ │
│ │ • Screen reader compatibility guidelines │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ SECURITY SKILL CONTEXT │ │
│ │ ────────────────────── │ │
│ │ • Security header requirements (CSP, HSTS, X-Frame-Options) │ │
│ │ • SSL/TLS configuration best practices │ │
│ │ • OWASP Top 10 vulnerability patterns │ │
│ │ • Cookie security attributes (Secure, HttpOnly, SameSite) │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
```
### Step 4: The Cascading Tree During Execution
Now execution proceeds. At each step, only load:
1. The current tool
2. Context relevant to that tool's domain
3. The likely next 1-2 tools
```
┌─────────────────────────────────────────────────────────────────────────────────┐
│ HIERARCHICAL CASCADING EXECUTION │
│ │
│ Time ─────────────────────────────────────────────────────────────────────► │
│ │
│ STEP 1: Discovery │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ LOADED IN CONTEXT: │ │
│ │ ┌─────────────────┐ │ │
│ │ │ sitemap- │ ← Current tool │ │
│ │ │ discoverer │ │ │
│ │ └────────┬────────┘ │ │
│ │ │ │ │
│ │ │ likely next │ │
│ │ ▼ │ │
│ │ ┌─────────────────┐ │ │
│ │ │ page-fetcher │ ← Preloaded (90% likely) │ │
│ │ └─────────────────┘ │ │
│ │ │ │
│ │ Context: [web-crawling basics, robots.txt rules] │ │
│ │ Tokens: ~800 │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ↓ output: sitemap with 47 pages │
│ │
│ STEP 2: Fetch Pages │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ LOADED IN CONTEXT: │ │
│ │ ┌─────────────────┐ │ │
│ │ │ page-fetcher │ ← Current tool │ │
│ │ └────────┬────────┘ │ │
│ │ │ │ │
│ │ ┌──────┴──────┐ likely next (fan out to parallel) │ │
│ │ ▼ ▼ │ │
│ │ ┌─────┐ ┌─────────────┐ │ │
│ │ │ SEO │ │ PERFORMANCE │ ← Domain branches preloaded │ │
│ │ │tools│ │ tools │ │ │
│ │ └─────┘ └─────────────┘ │ │
│ │ │ │
│ │ Context: [HTTP fetching, rate limiting, caching headers] │ │
│ │ Tokens: ~600 │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ↓ output: 47 page objects │
│ │
│ STEP 3-7: SEO Analysis (parallel group) │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ LOADED IN CONTEXT: │ │
│ │ │ │
│ │ ┌─────────────┬─────────────┬─────────────┬─────────────┐ │ │
│ │ │ meta-tag │ heading │ internal │ schema │ │ │
│ │ │ analyzer │ analyzer │ link │ checker │ │ │
│ │ │ │ │ analyzer │ │ │ │
│ │ └─────────────┴─────────────┴─────────────┴─────────────┘ │ │
│ │ │ │ │ │ │ │
│ │ └─────────────┴──────┬──────┴─────────────┘ │ │
│ │ ▼ │ │
│ │ ┌─────────────────┐ │ │
│ │ │ seo-score-calc │ ← Convergence point │ │
│ │ └─────────────────┘ │ │
│ │ │ │
│ │ Context: [SEO SKILL - full domain context loaded] │ │
│ │ Tokens: ~2,400 │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ... similar parallel groups for PERFORMANCE, ACCESSIBILITY, SECURITY ... │
│ │
│ FINAL STEP: Report Generation │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ LOADED IN CONTEXT: │ │
│ │ │ │
│ │ ┌───────────────────────┐ │ │
│ │ │ action-plan-generator │ ← Current tool │ │
│ │ └───────────┬───────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌───────────────────────┐ │ │
│ │ │ audit-report-generator│ ← Final tool │ │
│ │ └───────────────────────┘ │ │
│ │ │ │
│ │ Context: [report writing, prioritization frameworks, all scores] │ │
│ │ Tokens: ~1,800 │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
```
---
## The Full Tree Visualization
Here's the complete hierarchical tree for the website audit:
```
USER QUERY
│ "audit my website..."
┌───────────────────┼───────────────────┐
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ PLAN A │ │ PLAN B │ │ PLAN C │
│thorough │ │ quick │ │balanced │
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
│ │ │
┌─────────┴─────────┐ │ ┌────────┴────────┐
│ │ │ │ │
▼ ▼ ▼ ▼ ▼
┌─────────┐ ┌─────────┐ (...) ┌─────────┐ ┌─────────┐
│ SKILL │ │ SKILL │ │ SKILL │ │ SKILL │
│ SEO │ │SECURITY │ │ PERF │ │ A11Y │
└────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘
│ │ │ │
│ context │ context │ context │ context
│ docs │ docs │ docs │ docs
▼ ▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│meta-tag │ │ssl-check│ │lighthouse│ │wcag- │
│heading │ │headers │ │webvitals│ │contrast │
│links │ │vulns │ │assets │ │alt-text │
│schema │ │... │ │... │ │keyboard │
└─────────┘ └─────────┘ └─────────┘ └─────────┘
DETAIL: Cascading through SEO branch
═══════════════════════════════════════════════════════════════════════════════
Step 1 Step 2 Step 3 (parallel)
─────────────────────────────────────────────────────────────────────────────
┌──────────────┐
│ sitemap- │
│ discoverer │◄─── ACTIVE
└──────┬───────┘
│ preload likely next
┌──────────────┐ ┌──────────────┐
│ page- │ │ page- │
│ fetcher │───────►│ fetcher │◄─── ACTIVE
└──────────────┘ └──────┬───────┘
(shadowed) │
│ preload domain tools
┌──────────────┐
│ SEO tools │
│ (grouped) │───────────────┐
└──────────────┘ │
(shadowed) │
┌─────────────────────────┐
│ │
│ ┌──────────────┐ │
│ │ meta-tag │◄── │
│ │ analyzer │ │ │
│ └──────────────┘ │ │
│ │ │
│ ┌──────────────┐ │ │
│ │ heading │◄─┤ │
│ │ analyzer │ │ │
│ └──────────────┘ ├───┼── ALL ACTIVE
│ │ │ (parallel)
│ ┌──────────────┐ │ │
│ │ link │◄─┤ │
│ │ analyzer │ │ │
│ └──────────────┘ │ │
│ │ │
│ ┌──────────────┐ │ │
│ │ schema │◄── │
│ │ checker │ │
│ └──────────────┘ │
│ │
│ + SEO SKILL CONTEXT │
│ loaded for all │
│ │
└─────────────────────────┘
CONTEXT SIZE AT EACH STEP
═══════════════════════════════════════════════════════════════════════════════
Traditional approach (load everything):
┌─────────────────────────────────────────────────────────────────────────────┐
│ █████████████████████████████████████████████████████████████████████████ │
│ ALL 22 tools + ALL skill docs = ~45,000 tokens │
└─────────────────────────────────────────────────────────────────────────────┘
Hierarchical cascading approach:
┌─────────────────────────────────────────────────────────────────────────────┐
│ │
│ Step 1: ██░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ~800 tokens │
│ Step 2: ██░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ~600 tokens │
│ Step 3: █████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ~2,400 tokens │
│ Step 4: ████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ~2,100 tokens │
│ Step 5: ███████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ~1,900 tokens │
│ Step 6: ██████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ~1,600 tokens │
│ Final: ██████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ~1,800 tokens │
│ │
│ Average per step: ~1,600 tokens (96% reduction from loading everything) │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
```
---
## The Algorithm
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ │
│ 1. PLAN GENERATION PHASE │
│ ───────────────────── │
│ │
│ Input: User query │
│ Output: Y candidate plans │
│ │
│ ┌─────────────┐ │
│ │ Query │ │
│ │ Analyzer │──────► Extract intent, entities, constraints │
│ └──────┬──────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ Tool │ │
│ │ Searcher │──────► Find candidate tools (semantic + keyword) │
│ └──────┬──────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ Plan │ │
│ │ Generator │──────► Generate Y distinct plans │
│ └─────────────┘ │
│ │
│ │
│ 2. SKILL INFERENCE PHASE │
│ ────────────────────── │
│ │
│ Input: Y plans │
│ Output: Skill domains + contextual docs │
│ │
│ ┌─────────────┐ │
│ │ Tool │ │
│ │ Clusterer │──────► Group tools by domain/category │
│ └──────┬──────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ Skill │ │
│ │ Mapper │──────► Map domains → skill documents │
│ └──────┬──────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ Context │ │
│ │ Loader │──────► Fetch relevant docs, examples, constraints │
│ └─────────────┘ │
│ │
│ │
│ 3. EXECUTION PHASE (cascading) │
│ ─────────────────────────── │
│ │
│ For each step: │
│ │
│ ┌─────────────┐ │
│ │ Probability │ │
│ │ Calculator │──────► Calculate P(next_tool) for all candidates │
│ └──────┬──────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ Context │ │
│ │ Assembler │──────► current_tool + top_k likely + domain_context │
│ └──────┬──────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ Executor │──────► Run tool, capture output │
│ └──────┬──────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ State │ │
│ │ Updater │──────► Update context, prune unlikely branches │
│ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
```
---
## Probability-Based Preloading
At each step, calculate which tools are most likely needed next:
```
CURRENT STATE
│ completed: [step_1, step_2]
│ current: step_3
┌────────────────────────────────────┐
│ NEXT TOOL PROBABILITIES │
│ │
│ Based on: │
│ • Plan structure (what's next) │
│ • Current output type │
│ • Historical patterns │
│ • User's stated goals │
│ │
│ ┌──────────────────────────────┐ │
│ │ seo-score-calc P=0.92 │──┼──► PRELOAD
│ │ accessibility-check P=0.85 │──┼──► PRELOAD
│ │ perf-score-calc P=0.78 │──┼──► PRELOAD
│ │ security-scanner P=0.45 │ │
│ │ other-tool P=0.12 │ │
│ │ ... │ │
│ └──────────────────────────────┘ │
│ │
│ Threshold: P > 0.70 → preload │
│ │
└────────────────────────────────────┘
```
---
## The User Choice Interface
When Y plans are generated, present them to the user:
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ │
│ Your request: "Audit my website for SEO, performance, and security" │
│ │
│ I've generated 3 approaches: │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ ◉ PLAN A: Comprehensive Audit [SELECT] │ │
│ │ │ │
│ │ 22 steps • ~15 min • $2.00 estimated │ │
│ │ │ │
│ │ Covers: SEO (7), Performance (3), Accessibility (4), Security (3)│ │
│ │ Plus: Scoring, prioritization, PDF report │ │
│ │ │ │
│ │ Skills loaded: SEO best practices, WCAG 2.1, Security headers, │ │
│ │ Core Web Vitals, Schema.org markup │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ ○ PLAN B: Quick Scan [SELECT] │ │
│ │ │ │
│ │ 8 steps • ~3 min • $0.40 estimated │ │
│ │ │ │
│ │ Covers: Lighthouse audit, basic security scan │ │
│ │ Output: Summary scores only │ │
│ │ │ │
│ │ Skills loaded: Lighthouse interpretation, SSL basics │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ ○ PLAN C: Balanced Review [SELECT] │ │
│ │ │ │
│ │ 14 steps • ~8 min • $1.20 estimated │ │
│ │ │ │
│ │ Covers: Key checks from each domain │ │
│ │ Output: Prioritized action items │ │
│ │ │ │
│ │ Skills loaded: SEO essentials, A11y critical, Security must-haves│ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ ───────────────────────────────────────────────────────────────────────── │
│ │
│ Or: [Let AI decide based on your site] [Customize plan] [Cancel] │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
```
---
## Adaptive Execution: Plan as Guide, Not Law
Once skills are loaded from the plan, execution can be:
### Mode 1: Strict Plan Following
```
Plan Step 1 → Execute Tool A → Plan Step 2 → Execute Tool B → ...
The plan is the law. Execute exactly as specified.
```
### Mode 2: Plan-Guided Free Execution
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ │
│ Plan provides: │
│ • Which tools are available (pre-approved set) │
│ • What context/skills are loaded │
│ • Rough ordering guidance │
│ │
│ Model decides: │
│ • Exact tool call order │
│ • Whether to skip steps │
│ • Whether to repeat steps │
│ • Parameter values │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Agent has access to: │ │
│ │ │ │
│ │ TOOLS (from plan): SKILLS (from plan): │ │
│ │ ├── sitemap-discoverer ├── SEO best practices │ │
│ │ ├── page-fetcher ├── WCAG 2.1 guidelines │ │
│ │ ├── meta-analyzer ├── Security header docs │ │
│ │ ├── wcag-checker └── Core Web Vitals guide │ │
│ │ ├── ssl-checker │ │
│ │ └── report-generator │ │
│ │ │ │
│ │ Agent can call these tools in any order, with the skills │ │
│ │ providing domain expertise for intelligent decisions. │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
```
### Mode 3: Hybrid (Checkpoints)
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ │
│ Phase 1: Discovery Phase 2: Analysis Phase 3: Report │
│ ───────────────── ────────────────── ──────────────── │
│ │
│ [sitemap-discoverer] [CHECKPOINT: got pages] [CHECKPOINT: got │
│ │ │ all scores] │
│ ▼ ▼ │ │
│ [page-fetcher] Agent freely uses: ▼ │
│ │ • seo tools [action-plan-gen] │
│ ▼ • perf tools │ │
│ [CHECKPOINT] • a11y tools ▼ │
│ • security tools [report-generator] │
│ in whatever order │
│ makes sense │
│ │
│ Strict Flexible Strict │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
```
---
## Dynamic Tool Installation (Registry Integration)
In a registry-backed system (like TPMJS), if the agent needs a tool that isn't loaded:
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ │
│ During execution, agent realizes it needs a tool not in the plan: │
│ │
│ Agent: "The SSL certificate uses ECDSA which my ssl-checker doesn't │
│ fully support. I need a more specialized tool." │
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 🔍 Searching registry for: "ECDSA certificate" │ │
│ │ │ │
│ │ Found: │ │
│ │ ┌──────────────────────────────────────────────┐ │ │
│ │ │ ecdsa-cert-analyzer │ │ │
│ │ │ "Analyzes ECDSA and EdDSA certificates" │ │ │
│ │ │ Health: ✓ Healthy │ │ │
│ │ │ Quality: 0.87 │ │ │
│ │ └──────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ [Install and use] [Skip this check] [Ask user] │ │
│ │ │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ On install: │
│ 1. Fetch tool metadata from registry │
│ 2. Load tool's associated skill/context docs │
│ 3. Add to current execution context │
│ 4. Continue execution │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
```
---
## Summary: The Complete Flow
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ │
│ USER QUERY ARRIVES │
│ │ │
│ ▼ │
│ ┌───────────────────────┐ │
│ │ 1. GENERATE Y PLANS │ │
│ │ (speculative) │ │
│ └───────────┬───────────┘ │
│ │ │
│ ┌─────────────────┼─────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │ Plan A │ │ Plan B │ │ Plan C │ │
│ └────┬───┘ └────┬───┘ └────┬───┘ │
│ │ │ │ │
│ └─────────────────┼─────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────┐ │
│ │ 2. CLUSTER TOOLS BY │ │
│ │ DOMAIN/SKILL │ │
│ └───────────┬───────────┘ │
│ │ │
│ ┌─────────┬───────┼───────┬─────────┐ │
│ ▼ ▼ ▼ ▼ ▼ │
│ ┌────────┐ ┌──────┐ ┌─────┐ ┌──────┐ ┌───────┐ │
│ │SEO │ │Perf │ │A11y │ │Sec │ │Report │ │
│ │domain │ │domain│ │domain│ │domain│ │domain │ │
│ └────┬───┘ └──┬───┘ └──┬──┘ └──┬───┘ └───┬───┘ │
│ │ │ │ │ │ │
│ └────────┴────────┼───────┴─────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────┐ │
│ │ 3. LOAD SKILL DOCS │ │
│ │ FOR EACH DOMAIN │ │
│ └───────────┬───────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────┐ │
│ │ 4. PRESENT PLANS TO USER (optional) │ │
│ │ or AUTO-SELECT │ │
│ └───────────────────┬──────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────┐ │
│ │ 5. EXECUTE WITH │ │
│ │ CASCADING CONTEXT │ │
│ └───────────┬───────────┘ │
│ │ │
│ ┌─────────────────┴─────────────────┐ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ Strict: Follow plan │ │ Flexible: Use plan │ │
│ │ exactly │ │ as context guide │ │
│ └─────────────────────┘ └─────────────────────┘ │
│ │
│ At each step: │
│ • Load only current tool + likely next tools │
│ • Load only relevant domain context │
│ • Keep context window small (~1-3k tokens) │
│ • Prune unlikely branches as execution proceeds │
│ │
│ │ │
│ ▼ │
│ ┌───────────────────────┐ │
│ │ FINAL OUTPUT │ │
│ └───────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
```
---
## Key Takeaways
1. **Plans reveal skills**: Instead of loading all context upfront, generate plans first
and let them tell you what context is actually needed.
2. **Small context, right context**: At each step, load only what's needed for that step
plus likely next steps. 96% reduction in context size.
3. **User choice as a feature**: Multiple plans aren't a bug—they're a feature. Users
can pick their preferred approach.
4. **Adaptive execution**: Plans can be strict guides or loose frameworks. The skill
context enables intelligent tool use either way.
5. **Registry as escape hatch**: If the agent needs something not in the plan, it can
query the registry, install on-demand, and continue.
The hierarchical cascading tree pattern makes agents both more capable (access to any
tool in the registry) and more efficient (minimal context at each step).

View file

@ -0,0 +1,980 @@
/**
* ============================================================================
* PLANNER TYPE DEFINITIONS
* ============================================================================
*
* Complete TypeScript types for the hierarchical cascading tool planner system.
* Based on research into:
* - Dynamic tool orchestration
* - Y×X plan generation (Y alternatives, X steps each)
* - Skill/context inference from tool plans
* - Pathway learning algorithms
* - Fragility management
*
* ============================================================================
*/
// ============================================================================
// CORE PRIMITIVES
// ============================================================================
/**
* A tool from the registry
*
*
* TOOL
*
* packageName: "tpmjs-web-scraper"
* exportName: "scrapeUrl"
* description: "Fetches webpage..."
* parameters: [...]
* returns: { type: "string" }
* category: "web-scraping"
* qualityScore: 0.87
* healthStatus: "HEALTHY"
*
*/
export interface Tool {
id: string;
packageName: string;
exportName: string;
description: string;
parameters: ToolParameter[];
returns: ToolReturn;
category: ToolCategory;
qualityScore: number;
healthStatus: ToolHealthStatus;
aiAgent?: ToolAIAgent;
tier: 'minimal' | 'rich';
}
export interface ToolParameter {
name: string;
type: ParameterType;
required: boolean;
description: string;
default?: unknown;
enum?: string[];
}
export type ParameterType =
| 'string'
| 'number'
| 'boolean'
| 'object'
| 'array'
| 'string[]'
| 'number[]';
export interface ToolReturn {
type: string;
description: string;
schema?: JSONSchema;
}
export interface ToolAIAgent {
useCase: string;
limitations?: string;
examples?: string[];
}
export type ToolCategory =
| 'web-scraping'
| 'data-analysis'
| 'file-generation'
| 'image-processing'
| 'text-processing'
| 'communication'
| 'ai-ml'
| 'database'
| 'api-integration'
| 'general';
export type ToolHealthStatus = 'HEALTHY' | 'BROKEN' | 'UNKNOWN';
export interface JSONSchema {
type: string;
properties?: Record<string, JSONSchema>;
items?: JSONSchema;
required?: string[];
[key: string]: unknown;
}
// ============================================================================
// QUERY ANALYSIS
// ============================================================================
/**
* Result of analyzing a user query
*
* Query: "Scrape competitor prices from example.com and make a report"
*
*
* QUERY ANALYSIS
*
* intent: "price-comparison-report"
* entities: [{ type: "url", value: "example.com" }]
* capabilities: ["fetch-webpage", "extract-prices",
* "analyze-data", "generate-report"]
* outputFormat: "pdf"
* complexity: 7
*
*/
export interface QueryAnalysis {
intent: string;
entities: QueryEntity[];
requiredCapabilities: string[];
outputFormat?: OutputFormat;
constraints: QueryConstraints;
ambiguities: string[];
complexity: number; // 1-10
}
export interface QueryEntity {
type: EntityType;
value: string;
confidence: number;
}
export type EntityType = 'url' | 'file_path' | 'email' | 'date' | 'number' | 'name' | 'keyword';
export type OutputFormat = 'json' | 'csv' | 'pdf' | 'xlsx' | 'markdown' | 'html' | 'image' | 'text';
export interface QueryConstraints {
format?: string;
style?: string;
maxTime?: number;
maxCost?: number;
quality?: 'draft' | 'standard' | 'high';
}
// ============================================================================
// EXECUTION PLANS
// ============================================================================
/**
* A complete execution plan (one of Y alternatives)
*
*
* EXECUTION PLAN
*
*
* metadata:
* query: "Scrape competitor prices..."
* complexity: 7
* estimatedDuration: 45000ms
* estimatedCost: $0.45
* confidence: 0.87
*
* classification:
* approach: "thorough"
* riskLevel: "low"
*
* steps: [step1, step2, step3, ...]
* skills: [seo, scraping, analysis]
*
*
*/
export interface ExecutionPlan {
id: string;
version: '1.0';
metadata: PlanMetadata;
classification: PlanClassification;
steps: PlanStep[];
skills: Skill[];
expectedOutput: ExpectedOutput;
}
export interface PlanMetadata {
generatedAt: string;
query: string;
complexity: number;
estimatedDuration: number; // milliseconds
estimatedCost: number; // USD
confidence: number; // 0-1
}
export interface PlanClassification {
approach: 'thorough' | 'quick' | 'balanced';
riskLevel: 'low' | 'medium' | 'high';
parallelizable: boolean;
}
export interface ExpectedOutput {
type: string;
schema?: JSONSchema;
description: string;
}
// ============================================================================
// PLAN STEPS
// ============================================================================
/**
* A single step in an execution plan
*
*
* PLAN STEP
*
*
* id: "step_3"
* order: 3
* tool: { packageName: "tpmjs-price-extractor", ... }
* purpose: "Extract and normalize price values"
*
* input:
* fromStep: { stepId: "step_2", path: "$.elements" }
* static: { currency: "USD" }
*
* output:
* type: "array"
* storeAs: "prices"
*
* execution:
* timeout: 5000
* retries: 2
* fallbackTools: ["alt-price-extractor"]
*
* dependsOn: ["step_2"]
* parallelGroup: "extraction"
*
*
*/
export interface PlanStep {
id: string;
order: number;
tool: ToolReference;
purpose: string;
input: StepInput;
output: StepOutput;
execution: StepExecution;
dependsOn: string[];
parallelGroup?: string;
}
export interface ToolReference {
packageName: string;
exportName: string;
version?: string;
}
export interface StepInput {
static?: Record<string, unknown>;
fromStep?: StepReference | StepReference[];
fromQuery?: QueryReference;
computed?: ComputedInput;
}
export interface StepReference {
stepId: string;
path: string; // JSONPath
as?: string; // alias
}
export interface QueryReference {
entityType: EntityType;
index?: number;
}
export interface ComputedInput {
expression: string;
dependencies: string[];
}
export interface StepOutput {
type: string;
storeAs: string;
validate?: ValidationRule[];
}
export interface ValidationRule {
rule: 'minLength' | 'maxLength' | 'regex' | 'type' | 'required';
value: unknown;
message?: string;
}
export interface StepExecution {
timeout: number;
retries: number;
canSkipOnError: boolean;
fallbackTools?: string[];
}
// ============================================================================
// SKILLS (CONTEXTUAL KNOWLEDGE)
// ============================================================================
/**
* A skill is domain knowledge inferred from tools in a plan
*
* Tools in Plan Inferred Skill
*
*
* web-scraper SKILL: web-scraping
* html-parser
* url-validator context:
* Rate limiting rules
* Robots.txt guidelines
* CSS selector best practices
*
*/
export interface Skill {
domain: ToolCategory;
context: string;
tools: Tool[];
priority: number; // For ordering in context
}
export interface SkillContext {
domain: ToolCategory;
content: string;
tokenEstimate: number;
}
// ============================================================================
// EXECUTION CONTEXT
// ============================================================================
/**
* Runtime state during plan execution
*
*
* EXECUTION CONTEXT
*
*
* query: "Scrape competitor prices..."
*
* variables:
* step_1 { html: "<html>..." }
* step_2 { elements: [...] }
* step_3 { prices: [19.99, 24.99] }
*
* completed: { step_1, step_2, step_3 }
* currentStep: "step_4"
*
* errors: []
* retryCount: { step_2: 1 }
*
* timing:
* startTime: 1702234567890
* stepTimings: { step_1: 823, step_2: 234, step_3: 567 }
*
* tokens:
* input: 4521
* output: 1234
*
*
*/
export interface ExecutionContext {
query: string;
entities: QueryEntity[];
variables: Map<string, unknown>;
completed: Set<string>;
currentStep: string | null;
errors: ExecutionError[];
retryCount: Map<string, number>;
timing: ExecutionTiming;
tokens: TokenUsage;
}
export interface ExecutionError {
stepId: string;
tool: string;
error: string;
timestamp: number;
recoverable: boolean;
}
export interface ExecutionTiming {
startTime: number;
stepTimings: Map<string, number>;
}
export interface TokenUsage {
input: number;
output: number;
perStep: Map<string, { input: number; output: number }>;
}
// ============================================================================
// EXECUTION EVENTS (FOR STREAMING)
// ============================================================================
/**
* Events emitted during plan execution
*
* Time
*
*
* plan_startstep_startstep_done step_startplan_end
*
*/
export type ExecutionEvent =
| PlanStartEvent
| StepStartEvent
| ContextLoadedEvent
| StepProgressEvent
| StepCompleteEvent
| StepErrorEvent
| StepSkippedEvent
| PlanCompleteEvent
| PlanErrorEvent;
export interface PlanStartEvent {
type: 'plan_start';
planId: string;
totalSteps: number;
skills: string[];
}
export interface StepStartEvent {
type: 'step_start';
stepId: string;
tool: string;
purpose: string;
}
export interface ContextLoadedEvent {
type: 'context_loaded';
stepId: string;
tokens: number;
skills: string[];
}
export interface StepProgressEvent {
type: 'step_progress';
stepId: string;
progress: number; // 0-100
message?: string;
}
export interface StepCompleteEvent {
type: 'step_complete';
stepId: string;
duration: number;
resultPreview: string;
}
export interface StepErrorEvent {
type: 'step_error';
stepId: string;
error: string;
willRetry: boolean;
fallbackTool?: string;
}
export interface StepSkippedEvent {
type: 'step_skipped';
stepId: string;
reason: string;
}
export interface PlanCompleteEvent {
type: 'plan_complete';
success: boolean;
totalDuration: number;
totalTokens: number;
output: unknown;
}
export interface PlanErrorEvent {
type: 'plan_error';
error: string;
failedStep: string;
completedSteps: string[];
}
// ============================================================================
// PATHWAY LEARNING
// ============================================================================
/**
* Record of a pathway execution for learning
*
*
* PATHWAY RECORD
*
*
* queryPattern: "scrape.*price.*report"
* steps: ["scraper", "parser", "analyzer", "reporter"]
*
* stats:
* successes: 847
* failures: 45
* avgDuration: 34500ms
*
* lastUsed: 2024-01-15T10:30:00Z
* firstUsed: 2024-01-01T08:00:00Z
*
*
*/
export interface PathwayRecord {
id: string;
queryPattern: string;
steps: string[]; // Tool IDs in order
stats: PathwayStats;
lastUsed: Date;
firstUsed: Date;
metadata: PathwayMetadata;
}
export interface PathwayStats {
successes: number;
failures: number;
totalRuns: number;
avgDuration: number;
avgTokens: number;
avgCost: number;
}
export interface PathwayMetadata {
createdBy: 'user' | 'auto';
tags: string[];
notes?: string;
}
/**
* K-factor represents convergence toward determinism
*
* K = 0.00 No pattern, explore freely
* K = 0.50 Weak pattern, prefer but explore
* K = 0.85 Strong pattern, mostly deterministic
* K = 0.99 Near-locked, rare deviation
*/
export interface KFactorResult {
value: number; // 0-1
confidence: number;
dominantPath: string[] | null;
totalObservations: number;
}
// ============================================================================
// LEARNING ALGORITHMS
// ============================================================================
/**
* Configuration for pathway selection algorithms
*/
export interface LearningConfig {
algorithm: LearningAlgorithm;
params: AlgorithmParams;
}
export type LearningAlgorithm =
| 'epsilon_greedy'
| 'ucb'
| 'thompson_sampling'
| 'contextual_bandit'
| 'q_learning'
| 'mcts';
export type AlgorithmParams =
| EpsilonGreedyParams
| UCBParams
| ThompsonParams
| ContextualBanditParams
| QLearningParams
| MCTSParams;
export interface EpsilonGreedyParams {
type: 'epsilon_greedy';
epsilon: number; // Exploration rate (0-1)
decayRate: number; // How fast epsilon decays
minEpsilon: number; // Floor for epsilon
}
export interface UCBParams {
type: 'ucb';
explorationConstant: number; // C in UCB formula
}
export interface ThompsonParams {
type: 'thompson_sampling';
priorAlpha: number; // Beta distribution prior
priorBeta: number;
}
export interface ContextualBanditParams {
type: 'contextual_bandit';
features: ContextFeature[];
learningRate: number;
}
export type ContextFeature =
| 'user_type'
| 'query_complexity'
| 'time_of_day'
| 'previous_success_rate';
export interface QLearningParams {
type: 'q_learning';
learningRate: number; // Alpha
discountFactor: number; // Gamma
explorationRate: number; // Epsilon
}
export interface MCTSParams {
type: 'mcts';
simulations: number;
explorationConstant: number;
maxDepth: number;
}
// ============================================================================
// FRAGILITY MANAGEMENT
// ============================================================================
/**
* Fragility budget for a plan
*
*
* FRAGILITY BUDGET
*
*
* Target success rate: 90%
*
* If each step has P(success) = 0.98:
* Max steps = floor(log(0.90) / log(0.98)) = 5
*
* If each step has P(success) = 0.95:
* Max steps = floor(log(0.90) / log(0.95)) = 2
*
*
*/
export interface FragilityBudget {
targetSuccessRate: number; // e.g., 0.90 for 90%
avgStepSuccessRate: number; // e.g., 0.98
maxSteps: number; // Calculated limit
currentSteps: number;
withinBudget: boolean;
}
export interface FragilityAnalysis {
plan: ExecutionPlan;
budget: FragilityBudget;
sequentialFragility: number; // P(all sequential steps succeed)
parallelBenefit: number; // Improvement from parallel execution
fallbackBenefit: number; // Improvement from fallbacks
effectiveSuccessRate: number; // Final calculated rate
recommendations: FragilityRecommendation[];
}
export interface FragilityRecommendation {
type: 'reduce_steps' | 'add_fallbacks' | 'parallelize' | 'add_checkpoints';
description: string;
impact: number; // Estimated improvement
}
// ============================================================================
// PLAN GENERATION OPTIONS
// ============================================================================
/**
* Options for generating plans
*/
export interface PlanGenerationOptions {
numPlans: number; // Y in Y×X
maxStepsPerPlan: number; // Max X
strategies: PlanStrategy[];
fragilityBudget?: FragilityBudget;
preferredCategories?: ToolCategory[];
excludeTools?: string[];
}
export interface PlanStrategy {
name: string;
maxSteps: number;
preferQuality: boolean;
preferSpeed: boolean;
allowParallel: boolean;
requireFallbacks: boolean;
}
// ============================================================================
// CASCADING CONTEXT
// ============================================================================
/**
* Context assembled for a single step (minimal footprint)
*
* Traditional: Load ALL tools + ALL docs = ~45,000 tokens
*
* Cascading:
*
* STEP CONTEXT (~1,500 tokens)
*
*
*
* CURRENT TOOL (~400 tokens)
* web-scraper: description, parameters, examples
*
*
*
* DOMAIN CONTEXT (~600 tokens)
* Web scraping best practices, rate limits, selectors
*
*
*
* UPCOMING TOOLS (~200 tokens)
* Next: html-parser, price-extractor
*
*
*
* PRIOR RESULTS (~300 tokens)
* Summarized output from dependencies
*
*
*
*/
export interface CascadingContext {
currentTool: ToolContext;
domainContext: SkillContext | null;
upcomingTools: ToolPreview[];
priorResults: PriorResult[];
totalTokens: number;
}
export interface ToolContext {
tool: Tool;
formattedDescription: string;
formattedParameters: string;
examples: string[];
tokenEstimate: number;
}
export interface ToolPreview {
exportName: string;
purpose: string;
tokenEstimate: number;
}
export interface PriorResult {
stepId: string;
summary: string;
tokenEstimate: number;
}
// ============================================================================
// PRELOADING / PROBABILITY
// ============================================================================
/**
* Probability calculation for preloading next tools
*
* Current: step_2 (html-parser)
*
*
* NEXT TOOL PROBABILITIES
*
* price-extractor P = 0.92 LOAD
* text-cleaner P = 0.78 LOAD
* image-extractor P = 0.34
* link-extractor P = 0.21
*
* Threshold: 0.70
*
*/
export interface ToolProbability {
tool: Tool;
probability: number;
reason: ProbabilityReason;
}
export type ProbabilityReason =
| 'plan_next' // Next in plan
| 'plan_soon' // Coming up in plan
| 'learned_pattern' // Historical data
| 'output_type_match' // Output type matches input
| 'same_domain'; // Same category
export interface PreloadDecision {
toLoad: Tool[];
threshold: number;
reasoning: Map<string, ProbabilityReason>;
}
// ============================================================================
// USER INTERFACE TYPES
// ============================================================================
/**
* Plan summary for UI display
*/
export interface PlanSummary {
id: string;
name: string;
approach: 'thorough' | 'quick' | 'balanced';
stepCount: number;
estimatedDuration: string; // "~2 min"
estimatedCost: string; // "$0.45"
confidence: number;
skills: string[];
riskLevel: 'low' | 'medium' | 'high';
}
/**
* Execution progress for UI display
*/
export interface ExecutionProgress {
status: 'idle' | 'planning' | 'running' | 'complete' | 'error';
currentStep: number;
totalSteps: number;
completedSteps: StepProgress[];
currentStepProgress?: {
stepId: string;
tool: string;
progress: number;
message?: string;
};
contextTokens: number;
elapsedTime: number;
}
export interface StepProgress {
stepId: string;
tool: string;
status: 'complete' | 'skipped' | 'error';
duration: number;
resultPreview?: string;
error?: string;
}
// ============================================================================
// API TYPES
// ============================================================================
/**
* Request/Response types for API routes
*/
export interface GeneratePlansRequest {
query: string;
numPlans?: number;
options?: Partial<PlanGenerationOptions>;
}
export interface GeneratePlansResponse {
success: boolean;
data: {
plans: PlanSummary[];
kFactor: KFactorResult;
learnedPathAvailable: boolean;
};
error?: string;
}
export interface ExecutePlanRequest {
planId: string;
query: string;
options?: {
useFallbacks?: boolean;
maxRetries?: number;
};
}
// Response is SSE stream of ExecutionEvent
export interface GetToolsRequest {
capability: string;
category?: ToolCategory;
limit?: number;
healthyOnly?: boolean;
}
export interface GetToolsResponse {
success: boolean;
data: {
tools: Tool[];
total: number;
};
error?: string;
}
// ============================================================================
// DATABASE MODELS (for Prisma schema reference)
// ============================================================================
/**
* Database models for persistence
*
* Add to packages/db/prisma/schema.prisma:
*
* model PathwayRecord {
* id String @id @default(cuid())
* queryPattern String
* steps String[] // Tool IDs
* successes Int @default(0)
* failures Int @default(0)
* avgDuration Float @default(0)
* avgTokens Float @default(0)
* avgCost Float @default(0)
* lastUsed DateTime @default(now())
* firstUsed DateTime @default(now())
* createdBy String @default("auto")
* tags String[]
* notes String?
*
* @@index([queryPattern])
* @@index([lastUsed])
* }
*
* model PlanExecution {
* id String @id @default(cuid())
* planId String
* query String
* steps Json // PlanStep[]
* status String // 'running' | 'complete' | 'error'
* output Json?
* totalTokens Int @default(0)
* totalCost Float @default(0)
* duration Int @default(0)
* createdAt DateTime @default(now())
* completedAt DateTime?
*
* @@index([planId])
* @@index([createdAt])
* }
*/
export interface PathwayRecordDB {
id: string;
queryPattern: string;
steps: string[];
successes: number;
failures: number;
avgDuration: number;
avgTokens: number;
avgCost: number;
lastUsed: Date;
firstUsed: Date;
createdBy: string;
tags: string[];
notes: string | null;
}
export interface PlanExecutionDB {
id: string;
planId: string;
query: string;
steps: PlanStep[];
status: 'running' | 'complete' | 'error';
output: unknown | null;
totalTokens: number;
totalCost: number;
duration: number;
createdAt: Date;
completedAt: Date | null;
}
// ============================================================================
// UTILITY TYPES
// ============================================================================
export type DeepPartial<T> = {
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};
export type AsyncGenerator<T> = {
next(): Promise<{ value: T; done: boolean }>;
[Symbol.asyncIterator](): AsyncGenerator<T>;
};
export type Result<T, E = Error> = { success: true; data: T } | { success: false; error: E };

File diff suppressed because it is too large Load diff