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:
parent
1e58537a65
commit
150d48d0ba
11 changed files with 6003 additions and 76 deletions
|
|
@ -3,7 +3,7 @@
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "npx @react-grab/claude-code@latest && next dev",
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
|
|
|
||||||
|
|
@ -119,9 +119,11 @@ export default function ToolDetailPage({
|
||||||
<div className="min-h-screen bg-background">
|
<div className="min-h-screen bg-background">
|
||||||
<AppHeader />
|
<AppHeader />
|
||||||
<Container size="xl" padding="md" className="py-12">
|
<Container size="xl" padding="md" className="py-12">
|
||||||
<div className="flex flex-col items-center justify-center py-24 gap-6">
|
<div className="flex items-center justify-center py-24 gap-4">
|
||||||
<Spinner size="xl" />
|
<Spinner size="lg" />
|
||||||
<span className="text-foreground-secondary text-lg">Loading tool...</span>
|
<span className="text-foreground-secondary font-mono text-sm tracking-wide">
|
||||||
|
Loading tool...
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -88,9 +88,11 @@ export default function BrokenToolsPage(): React.ReactElement {
|
||||||
|
|
||||||
{/* Loading state */}
|
{/* Loading state */}
|
||||||
{loading && (
|
{loading && (
|
||||||
<div className="flex flex-col items-center justify-center py-24 gap-6">
|
<div className="flex items-center justify-center py-24 gap-4">
|
||||||
<Spinner size="xl" />
|
<Spinner size="lg" />
|
||||||
<span className="text-foreground-secondary text-lg">Loading broken tools...</span>
|
<span className="text-foreground-secondary font-mono text-sm tracking-wide">
|
||||||
|
Loading broken tools...
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -184,9 +184,11 @@ export default function ToolSearchPage(): React.ReactElement {
|
||||||
|
|
||||||
{/* Loading state */}
|
{/* Loading state */}
|
||||||
{loading && (
|
{loading && (
|
||||||
<div className="flex flex-col items-center justify-center py-24 gap-6">
|
<div className="flex items-center justify-center py-24 gap-4">
|
||||||
<Spinner size="xl" />
|
<Spinner size="lg" />
|
||||||
<span className="text-foreground-secondary text-lg">Loading tools...</span>
|
<span className="text-foreground-secondary font-mono text-sm tracking-wide">
|
||||||
|
Loading tools...
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -323,9 +323,11 @@ export function ToolPlayground({ tool }: ToolPlaygroundProps): React.ReactElemen
|
||||||
})()}
|
})()}
|
||||||
</div>
|
</div>
|
||||||
) : isExecuting ? (
|
) : isExecuting ? (
|
||||||
<div className="flex flex-col items-center justify-center py-12 gap-6">
|
<div className="flex items-center justify-center py-12 gap-4">
|
||||||
<Spinner size="xl" />
|
<Spinner size="lg" />
|
||||||
<p className="text-foreground-secondary">Executing...</p>
|
<p className="text-foreground-secondary font-mono text-sm tracking-wide">
|
||||||
|
Executing...
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="text-center py-12">
|
<div className="text-center py-12">
|
||||||
|
|
|
||||||
1112
docs/CASCADING_COMPLEXITY_AND_FRAGILITY.md
Normal file
1112
docs/CASCADING_COMPLEXITY_AND_FRAGILITY.md
Normal file
File diff suppressed because it is too large
Load diff
1950
docs/DYNAMIC_TOOL_ORCHESTRATION.md
Normal file
1950
docs/DYNAMIC_TOOL_ORCHESTRATION.md
Normal file
File diff suppressed because it is too large
Load diff
739
docs/HIERARCHICAL_CONTEXT_LOADING.md
Normal file
739
docs/HIERARCHICAL_CONTEXT_LOADING.md
Normal 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).
|
||||||
980
docs/PLANNER_TYPE_DEFINITIONS.ts
Normal file
980
docs/PLANNER_TYPE_DEFINITIONS.ts
Normal 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_start│►│step_start│►│step_done │►│step_start│►│plan_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 };
|
||||||
1140
docs/TPMJS_PLANNER_TUTORIAL.md
Normal file
1140
docs/TPMJS_PLANNER_TUTORIAL.md
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -2,25 +2,17 @@
|
||||||
|
|
||||||
import { cn } from '@tpmjs/utils/cn';
|
import { cn } from '@tpmjs/utils/cn';
|
||||||
|
|
||||||
const sizeClasses = {
|
const sizeConfig = {
|
||||||
xs: 'w-5 h-5',
|
xs: { container: 'w-4 h-4', block: 3, gap: 1 },
|
||||||
sm: 'w-8 h-8',
|
sm: { container: 'w-6 h-6', block: 4, gap: 2 },
|
||||||
md: 'w-12 h-12',
|
md: { container: 'w-8 h-8', block: 6, gap: 2 },
|
||||||
lg: 'w-16 h-16',
|
lg: { container: 'w-12 h-12', block: 8, gap: 3 },
|
||||||
xl: 'w-24 h-24',
|
xl: { container: 'w-16 h-16', block: 12, gap: 4 },
|
||||||
} as const;
|
|
||||||
|
|
||||||
const dotSizeClasses = {
|
|
||||||
xs: 'w-1 h-1',
|
|
||||||
sm: 'w-1.5 h-1.5',
|
|
||||||
md: 'w-2 h-2',
|
|
||||||
lg: 'w-3 h-3',
|
|
||||||
xl: 'w-4 h-4',
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export interface SpinnerProps extends React.HTMLAttributes<HTMLDivElement> {
|
export interface SpinnerProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||||
/** Size variant */
|
/** Size variant */
|
||||||
size?: keyof typeof sizeClasses;
|
size?: keyof typeof sizeConfig;
|
||||||
/** Optional label for accessibility */
|
/** Optional label for accessibility */
|
||||||
label?: string;
|
label?: string;
|
||||||
}
|
}
|
||||||
|
|
@ -28,8 +20,9 @@ export interface SpinnerProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||||
/**
|
/**
|
||||||
* Spinner component
|
* Spinner component
|
||||||
*
|
*
|
||||||
* An elegant orbital loading spinner with three dots rotating
|
* A brutalist grid-based loader that evokes the feeling of
|
||||||
* in a synchronized dance pattern.
|
* tools being constructed, block by block. Matches the TPMJS
|
||||||
|
* dithering aesthetic with sharp squares and wave animations.
|
||||||
*/
|
*/
|
||||||
export function Spinner({
|
export function Spinner({
|
||||||
className,
|
className,
|
||||||
|
|
@ -37,68 +30,73 @@ export function Spinner({
|
||||||
label = 'Loading...',
|
label = 'Loading...',
|
||||||
...props
|
...props
|
||||||
}: SpinnerProps): React.ReactElement {
|
}: SpinnerProps): React.ReactElement {
|
||||||
const sizeClass = sizeClasses[size];
|
const config = sizeConfig[size];
|
||||||
const dotSize = dotSizeClasses[size];
|
const blockSize = config.block;
|
||||||
|
const gap = config.gap;
|
||||||
|
|
||||||
|
// 3x3 grid positions with staggered delays (diagonal wave)
|
||||||
|
const blocks = [
|
||||||
|
{ id: 'b00', row: 0, col: 0, delay: 0 },
|
||||||
|
{ id: 'b01', row: 0, col: 1, delay: 0.1 },
|
||||||
|
{ id: 'b02', row: 0, col: 2, delay: 0.2 },
|
||||||
|
{ id: 'b10', row: 1, col: 0, delay: 0.1 },
|
||||||
|
{ id: 'b11', row: 1, col: 1, delay: 0.2 },
|
||||||
|
{ id: 'b12', row: 1, col: 2, delay: 0.3 },
|
||||||
|
{ id: 'b20', row: 2, col: 0, delay: 0.2 },
|
||||||
|
{ id: 'b21', row: 2, col: 1, delay: 0.3 },
|
||||||
|
{ id: 'b22', row: 2, col: 2, delay: 0.4 },
|
||||||
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
// biome-ignore lint/a11y/useSemanticElements: Spinner requires role="status" for screen reader announcements, <output> is not semantically appropriate
|
// biome-ignore lint/a11y/useSemanticElements: Spinner requires role="status" for screen reader announcements
|
||||||
<div
|
<div
|
||||||
role="status"
|
role="status"
|
||||||
aria-label={label}
|
aria-label={label}
|
||||||
className={cn('relative', sizeClass, className)}
|
className={cn(
|
||||||
|
'relative inline-flex items-center justify-center',
|
||||||
|
config.container,
|
||||||
|
className
|
||||||
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
<style>
|
<style>
|
||||||
{`
|
{`
|
||||||
@keyframes spinnerOrbit {
|
@keyframes blockPulse {
|
||||||
0% {
|
0%, 100% {
|
||||||
transform: rotate(0deg) translateX(140%) rotate(0deg);
|
opacity: 0.15;
|
||||||
|
transform: scale(0.85);
|
||||||
}
|
}
|
||||||
100% {
|
50% {
|
||||||
transform: rotate(360deg) translateX(140%) rotate(-360deg);
|
opacity: 1;
|
||||||
|
transform: scale(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`}
|
`}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
{/* Orbital ring hint */}
|
<div
|
||||||
<div className="absolute inset-[15%] rounded-full border border-foreground/10" />
|
className="relative"
|
||||||
|
style={{
|
||||||
|
width: blockSize * 3 + gap * 2,
|
||||||
|
height: blockSize * 3 + gap * 2,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{blocks.map((block) => (
|
||||||
|
<div
|
||||||
|
key={block.id}
|
||||||
|
className="absolute bg-foreground"
|
||||||
|
style={{
|
||||||
|
width: blockSize,
|
||||||
|
height: blockSize,
|
||||||
|
left: block.col * (blockSize + gap),
|
||||||
|
top: block.row * (blockSize + gap),
|
||||||
|
animation: 'blockPulse 1.2s ease-in-out infinite',
|
||||||
|
animationDelay: `${block.delay}s`,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Three orbiting dots with staggered animations */}
|
|
||||||
<div
|
|
||||||
className={cn('absolute rounded-full bg-foreground', dotSize)}
|
|
||||||
style={{
|
|
||||||
top: '50%',
|
|
||||||
left: '50%',
|
|
||||||
marginTop: '-0.25rem',
|
|
||||||
marginLeft: '-0.25rem',
|
|
||||||
animation: 'spinnerOrbit 1.4s cubic-bezier(0.5, 0, 0.5, 1) infinite',
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
className={cn('absolute rounded-full bg-foreground/50', dotSize)}
|
|
||||||
style={{
|
|
||||||
top: '50%',
|
|
||||||
left: '50%',
|
|
||||||
marginTop: '-0.25rem',
|
|
||||||
marginLeft: '-0.25rem',
|
|
||||||
animation: 'spinnerOrbit 1.4s cubic-bezier(0.5, 0, 0.5, 1) infinite',
|
|
||||||
animationDelay: '-0.45s',
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
className={cn('absolute rounded-full bg-foreground/25', dotSize)}
|
|
||||||
style={{
|
|
||||||
top: '50%',
|
|
||||||
left: '50%',
|
|
||||||
marginTop: '-0.25rem',
|
|
||||||
marginLeft: '-0.25rem',
|
|
||||||
animation: 'spinnerOrbit 1.4s cubic-bezier(0.5, 0, 0.5, 1) infinite',
|
|
||||||
animationDelay: '-0.9s',
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{/* Screen reader text */}
|
|
||||||
<span className="sr-only">{label}</span>
|
<span className="sr-only">{label}</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue