diff --git a/app/api/documents/route.ts b/app/api/documents/route.ts index aff5ea0..7470ee9 100644 --- a/app/api/documents/route.ts +++ b/app/api/documents/route.ts @@ -1,35 +1,81 @@ import { createClient } from '@supabase/supabase-js'; import { NextResponse } from 'next/server'; +function getSupabaseServerClient() { + const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL; + const supabaseServiceKey = process.env.SUPABASE_SERVICE_ROLE_KEY; + + if (!supabaseUrl) { + throw new Error('Server configuration error: Missing Supabase URL'); + } + + if (!supabaseServiceKey) { + throw new Error('Server configuration error: Missing Supabase service key'); + } + + return createClient(supabaseUrl, supabaseServiceKey, { + auth: { + autoRefreshToken: false, + persistSession: false, + }, + }); +} + +export async function POST(request: Request) { + try { + const supabase = getSupabaseServerClient(); + const body = await request.json(); + + const { + title, + content, + type = 'markdown', + folder = 'Research/', + tags = ['saved', 'article'], + description, + size, + } = body; + + // Validate required fields + if (!title || !content) { + return NextResponse.json( + { error: 'Missing required fields: title and content' }, + { status: 400 } + ); + } + + const { data, error } = await supabase + .from('mission_control_documents') + .insert({ + title, + content, + type, + folder, + tags, + description, + size, + }) + .select() + .single(); + + if (error) { + console.error('Supabase error:', error); + return NextResponse.json({ error: error.message }, { status: 500 }); + } + + return NextResponse.json({ document: data }, { status: 201 }); + } catch (err: any) { + console.error('POST /api/documents error:', err); + return NextResponse.json( + { error: err.message || 'Unknown error occurred' }, + { status: 500 } + ); + } +} + export async function GET() { try { - // Get environment variables inside the handler (important for Vercel) - const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL; - const supabaseServiceKey = process.env.SUPABASE_SERVICE_ROLE_KEY; - - // Validate environment variables - if (!supabaseUrl) { - console.error('Missing NEXT_PUBLIC_SUPABASE_URL environment variable'); - return NextResponse.json( - { error: 'Server configuration error: Missing Supabase URL' }, - { status: 500 } - ); - } - - if (!supabaseServiceKey) { - console.error('Missing SUPABASE_SERVICE_ROLE_KEY environment variable'); - return NextResponse.json( - { error: 'Server configuration error: Missing Supabase service key' }, - { status: 500 } - ); - } - - const supabase = createClient(supabaseUrl, supabaseServiceKey, { - auth: { - autoRefreshToken: false, - persistSession: false, - }, - }); + const supabase = getSupabaseServerClient(); const { data, error } = await supabase .from('mission_control_documents') @@ -50,3 +96,53 @@ export async function GET() { ); } } + +export async function DELETE(request: Request) { + try { + const supabase = getSupabaseServerClient(); + const { searchParams } = new URL(request.url); + + let id = searchParams.get('id')?.trim(); + + if (!id) { + try { + const body = await request.json(); + id = body?.id?.trim(); + } catch { + // Ignore JSON parse errors; query param is preferred. + } + } + + if (!id) { + return NextResponse.json( + { error: 'Missing required document id' }, + { status: 400 } + ); + } + + const { error, count } = await supabase + .from('mission_control_documents') + .delete({ count: 'exact' }) + .eq('id', id); + + if (error) { + console.error('Supabase delete error:', error); + return NextResponse.json({ error: error.message }, { status: 500 }); + } + + if (!count) { + return NextResponse.json( + { error: 'Document not found' }, + { status: 404 } + ); + } + + return NextResponse.json({ success: true, id }); + } catch (err: any) { + console.error('DELETE /api/documents error:', err); + return NextResponse.json( + { error: err.message || 'Unknown error occurred' }, + { status: 500 } + ); + } +} diff --git a/app/api/search/route.ts b/app/api/search/route.ts index 7de852f..f71189f 100644 --- a/app/api/search/route.ts +++ b/app/api/search/route.ts @@ -73,6 +73,26 @@ interface SearchableEntityConfig { getSnippet?: (item: any) => string | undefined; } +function buildSearchCondition( + entity: SearchableEntityConfig, + field: string, + query: string +): string { + // mission_control_documents.tags is text[]; ilike fails with Postgres 42883. + // Use array-contains for exact tag matching while preserving ilike for text fields. + if (entity.table === "mission_control_documents" && field === "tags") { + const normalizedTag = query + .trim() + .toLowerCase() + .replace(/\\/g, "\\\\") + .replace(/"/g, '\\"'); + + return `${field}.cs.{"${normalizedTag}"}`; + } + + return `${field}.ilike.%${query}%`; +} + const searchableEntities: SearchableEntityConfig[] = [ { table: "tasks", @@ -311,7 +331,7 @@ export async function GET(request: Request) { try { // Build OR filter for search fields const orConditions = entity.searchFields - .map(field => `${field}.ilike.%${query}%`) + .map((field) => buildSearchCondition(entity, field, query)) .join(","); // Only select fields we need for search results diff --git a/documents/ai-adoption-meta-learning-loops-plan.md b/documents/ai-adoption-meta-learning-loops-plan.md new file mode 100644 index 0000000..d7526d3 --- /dev/null +++ b/documents/ai-adoption-meta-learning-loops-plan.md @@ -0,0 +1,164 @@ +# Implementation Plan: Nine Meta-Learning Loops Integration + +## Overview +Integrate Vox's 9 meta-learning loops framework into Mission Control's autonomous agent system to enable closed-loop operations and progression toward full agent autonomy. + +## Current State Analysis +**Strengths:** +- Alice/Bob/Charlie workflow established +- API-centric CLI pattern prevents duplication +- Gantt Board provides task orchestration +- Research → Document → Task pipeline works + +**Gaps:** +- No cap gates for agent overreach prevention +- No reaction matrix for standardized responses +- No proposal service for agent coordination +- No self-healing/stale task detection +- Missing autonomy progression tracking + +## Proposed Implementation + +### Phase 1: Safety Mechanisms (Week 1-2) + +**1.1 Cap Gates System** +``` +Location: /lib/agents/cap-gates.ts +- Max review cycles: 3 before human escalation +- Max token spend per task: 100k tokens +- Max execution time: 2 hours per agent session +- Forbidden operations: Require explicit approval +``` + +**1.2 Reaction Matrix** +``` +Location: /lib/agents/reaction-matrix.ts +Standardized responses for: +- API failures → Retry with backoff +- Syntax errors → Check SKILL.md first +- Test failures → Run debug skill +- Research complete → Handoff to Bob +- Implementation stuck → Escalate to human +``` + +### Phase 2: Coordination Layer (Week 3-4) + +**2.1 Proposal Service** +``` +Location: /lib/agents/proposals/ +- Agent submits proposal: "I want to do X" +- Check against cap gates +- Validation against current sprint +- Auto-approve if within bounds +- Human approval if exceeds limits +``` + +**2.2 Proposal Protocol** +```json +{ + "proposalId": "uuid", + "agentId": "alice-researcher", + "type": "research|implement|test", + "estimatedCost": "tokens", + "estimatedTime": "minutes", + "requiresApproval": true|false, + "rationale": "string", + "expectedOutput": "string" +} +``` + +### Phase 3: Self-Healing (Week 5-6) + +**3.1 Stale Task Detection** +``` +Location: /lib/agents/health-check.ts +- Cron every 30 minutes +- Check tasks with status "in-progress" > 30 min +- Query agent status via sessions_list +- If agent stalled: Respawn or escalate +- Update task with diagnostic comment +``` + +**3.2 Recovery Actions** +``` +- Agent crashed → Respawn with context +- Agent stuck → Spawn debugger agent +- Task unclear → Add clarification request +- Resource exhausted → Queue for off-peak +``` + +### Phase 4: Observability (Week 7-8) + +**4.1 Agent Dashboard (Mission Control Phase 8)** +- Real-time agent status +- Token usage per agent +- Success/failure rates +- Time-to-completion metrics +- Autonomy level progression + +**4.2 Learning Metrics** +- Which patterns succeed most +- Common failure modes +- Optimal task sizes +- Best agent combinations + +## Integration Points + +### With Existing Systems +| System | Integration Point | Change Required | +|--------|-------------------|-----------------| +| Gantt Board | Task status API | Add stale detection trigger | +| Mission Control | Documents API | Link research → plans | +| Agent Workflow | Spawn protocol | Add cap gate checks | +| Session Logs | Query API | Health check queries | + +### File Changes +``` +NEW: /lib/agents/cap-gates.ts +NEW: /lib/agents/reaction-matrix.ts +NEW: /lib/agents/proposal-service.ts +NEW: /lib/agents/health-check.ts +NEW: /lib/agents/dashboard.ts +MODIFY: /agents/TEAM-REGISTRY.md +MODIFY: Skill files for Alice/Bob/Charlie (add cap checks) +``` + +## Risks and Mitigation + +| Risk | Impact | Mitigation | +|------|--------|------------| +| Cap gates too restrictive | Agents can't work | Start permissive, tighten based on data | +| Proposal overhead | Slower execution | Auto-approve 90% of cases | +| False stale detection | Interrupted work | Require 3 checks before action | +| Dashboard complexity | Delayed Phase 8 | Build incrementally | + +## Success Criteria +- [ ] Zero runaway agent incidents +- [ ] 95% auto-approval rate for proposals +- [ ] <5 min stale detection latency +- [ ] 50% reduction in human intervention needs +- [ ] Complete audit trail of agent decisions + +## Timeline +- **Week 1-2:** Cap gates + reactions +- **Week 3-4:** Proposal service +- **Week 5-6:** Self-healing +- **Week 7-8:** Dashboard + +## Dependencies +- Requires current agent workflow to be stable +- Gantt Board API token access +- Session log query capability +- Session list/monitoring tools + +## Rollout Strategy +1. Deploy cap gates (observation mode) +2. Enable reaction matrix +3. Launch proposal service (with manual approval) +4. Enable auto-approval after 1 week +5. Add stale detection +6. Build dashboard incrementally + +## Verdict: ADOPT + +This plan directly addresses Mission Control's Phase 6-9 roadmap using a proven pattern from Vox. Start with Phase 1 safety mechanisms before enabling more autonomy. diff --git a/documents/ai-adoption-meta-learning-loops.md b/documents/ai-adoption-meta-learning-loops.md new file mode 100644 index 0000000..92183f8 --- /dev/null +++ b/documents/ai-adoption-meta-learning-loops.md @@ -0,0 +1,120 @@ +# Nine Meta-Learning Loops: A Guide to AI Adoption in Business + +**Source:** X Thread by [@Voxyz_ai](https://x.com/Voxyz_ai) +**Date Researched:** Feb 25, 2026 +**Recommended Verdict:** **ADOPT** - High relevance for Mission Control's autonomous agent vision + +--- + +## Executive Summary + +Vox shares a framework of 9 meta-learning loops that enabled "AI Co-Pilot" adoption across their entire company. After 1 year, they're still learning, but their structured approach to AI integration provides a replicable pattern for businesses looking to accelerate AI adoption. + +--- + +## The 9 Meta-Learning Loops + +### 1. **Learning Loop** +- Continuous improvement through feedback +- Teams learn what works and iterates +- *Relevance: Core mechanism for any AI implementation* + +### 2. **Scale Loop** +- Expanding AI use cases across departments +- Moving from pilot to production +- *Relevance: Critical for going beyond small experiments* + +### 3. **Trust Loop** +- Building confidence in AI outputs +- QA and validation processes +- *Relevance: Required for adoption at scale* + +### 4. **Cost Loop** +- Balancing AI expenses with value +- Optimizing token usage and efficiency +- *Relevance: Essential for sustainable operations* + +### 5. **Speed Loop** +- Improving latency and response times +- Performance optimization +- *Relevance: Affects user acceptance* + +### 6. **Quality Loop** +- Maintaining high standards of output +- Consistency across use cases +- *Relevance: Determines long-term value* + +### 7. **Customization Loop** +- Adapting AI to specific business needs +- Fine-tuning for domain-specific tasks +- *Relevance: Maximizes utility* + +### 8. **Integration Loop** +- Embedding AI into existing workflows +- API connections and automation +- *Relevance: Determines adoption friction* + +### 9. **Autonomy Loop** +- Moving from copilot to autonomous agent +- Self-directed task completion +- *Relevance: Ultimate goal for productivity gains* + +--- + +## Key Insights for Mission Control + +| Pattern | Application to Our System | +|---------|---------------------------| +| Closed-loop operations | Alice/Bob/Charlie workflow already implements this | +| Cap gates | Need to add to prevent runaway agents | +| Reaction matrix | Required for autonomous decision-making | +| Self-healing (30-min detection) | Critical addition for 24/7 operation | + +### Direct Relevance to Current Projects + +1. **Gantt Board Task Worker**: Implementing Loop 9 (Autonomy) - agents working continuously +2. **Subagent Orchestration**: Implements Loop 1 (Learning) and Loop 2 (Scale) +3. **Research → Implementation Pipeline**: Maps to Loops 3-8 + +### Vox's Architecture +- **Agent stack**: 6 autonomous agents with closed-loop operations +- **Proposal service**: Single coordination point +- **Human oversight**: Cap gates prevent overreach +- **Reaction matrix**: Standardized response patterns + +--- + +## Implementation Plan + +**Phase 1: Current State** +- Alice/Bob/Charlie workflow exists +- API-centric CLI pattern working +- Task management through Gantt Board + +**Phase 2: Add Loop Mechanisms** +1. Implement cap gates (risk management) +2. Add reaction matrix for common scenarios +3. Build proposal service for agent coordination +4. Enable 30-minute stale task detection + +**Phase 3: Dashboard Vision** +Following Vox's blueprint for Phases 6-9 of Mission Control: +- Agent observability +- Performance metrics +- Autonomy progression tracking + +--- + +## Verdict + +**ADOPT** - This framework directly addresses Mission Control's Phase 6-9 roadmap and provides a battle-tested pattern for our autonomous agent system. + +**Next Steps:** +- [ ] Review implementation plan details +- [ ] Prioritize cap gates and reaction matrix +- [ ] Design proposal service architecture +- [ ] Plan 30-min stale detection mechanism + +--- + +**Tags:** #ai-adoption #automation #voxyz #mission-control #agents #meta-learning diff --git a/hooks/useDocuments.ts b/hooks/useDocuments.ts index fc09198..680a52f 100644 --- a/hooks/useDocuments.ts +++ b/hooks/useDocuments.ts @@ -155,9 +155,30 @@ export function useDocuments() { ); const deleteDocument = useCallback(async (id: string): Promise => { - // TODO: Implement via API - console.log('Delete document not yet implemented'); - return false; + try { + const response = await fetchWithTimeout(`/api/documents?id=${encodeURIComponent(id)}`, { + method: 'DELETE', + }, 10000); + + let result: any = null; + try { + result = await response.json(); + } catch { + // Best effort parse; fall back to status text below. + } + + if (!response.ok) { + throw new Error(result?.error || `HTTP error! status: ${response.status}`); + } + + setDocuments((prev) => prev.filter((doc) => doc.id !== id)); + setError(null); + return true; + } catch (err: any) { + console.error('[useDocuments] Delete failed:', err); + setError(err?.message || 'Failed to delete document'); + return false; + } }, []); const createFolder = useCallback((name: string): Folder => { diff --git a/scripts/lib/api_client.sh b/scripts/lib/api_client.sh index 887e803..4577cc0 100755 --- a/scripts/lib/api_client.sh +++ b/scripts/lib/api_client.sh @@ -6,19 +6,53 @@ set -euo pipefail # Configuration -MC_API_URL="${MC_API_URL:-http://localhost:3001/api}" +MC_API_URL="${MC_API_URL:-https://mission-control-rho-pink.vercel.app/api}" MC_COOKIE_FILE="${MC_COOKIE_FILE:-$HOME/.config/mission-control/cookies.txt}" # Ensure cookie directory exists mkdir -p "$(dirname "$MC_COOKIE_FILE")" +# Machine-to-machine API call (for cron/automation) +# Uses MC_MACHINE_TOKEN env var instead of cookie auth +# Usage: mc_api_call_machine [data] +mc_api_call_machine() { + local method="$1" + local endpoint="$2" + local data="${3:-}" + + local token="${MC_MACHINE_TOKEN:-}" + if [[ -z "$token" ]]; then + echo "Error: MC_MACHINE_TOKEN not set" >&2 + return 1 + fi + + local url="${MC_API_URL}${endpoint}" + local curl_opts=( + -s + -H "Content-Type: application/json" + -H "Authorization: Bearer ${token}" + ) + + if [[ -n "$data" ]]; then + curl_opts+=(-d "$data") + fi + + curl "${curl_opts[@]}" -X "$method" "$url" +} + # Make authenticated API call to Mission Control # Usage: mc_api_call [data] mc_api_call() { local method="$1" local endpoint="$2" local data="${3:-}" - + + # Machine token path for automation/cron (no cookie auth needed) + if [[ -n "${MC_MACHINE_TOKEN:-}" ]]; then + mc_api_call_machine "$method" "$endpoint" "$data" + return $? + fi + local url="${MC_API_URL}${endpoint}" local curl_opts=( -s @@ -26,11 +60,11 @@ mc_api_call() { -c "$MC_COOKIE_FILE" -H "Content-Type: application/json" ) - + if [[ -n "$data" ]]; then curl_opts+=(-d "$data") fi - + curl "${curl_opts[@]}" -X "$method" "$url" } @@ -101,6 +135,7 @@ mc_logout() { } # Export functions for use in other scripts +export -f mc_api_call_machine export -f mc_api_call export -f mc_get export -f mc_post diff --git a/scripts/mc.sh b/scripts/mc.sh index d8bbd95..8d44dac 100755 --- a/scripts/mc.sh +++ b/scripts/mc.sh @@ -147,9 +147,87 @@ handle_documents() { fi mc_get "/documents?id=$id" | jq . ;; + create) + shift # Remove 'create' from args + local title="" + local content="" + local folder="Research/" + local tags='["saved", "article"]' + local description="" + + # Parse arguments + while [[ $# -gt 0 ]]; do + case "$1" in + --title) + title="$2" + shift 2 + ;; + --content) + content="$2" + shift 2 + ;; + --folder) + folder="$2" + shift 2 + ;; + --tags) + tags="$2" + shift 2 + ;; + --description) + description="$2" + shift 2 + ;; + *) + echo "Unknown option: $1" >&2 + shift + ;; + esac + done + + # Validate required fields + if [[ -z "$title" ]]; then + echo "Usage: ./mc.sh documents create --title --content <content> [--folder <folder>] [--tags <tags>] [--description <description>]" >&2 + exit 1 + fi + + if [[ -z "$content" ]]; then + echo "Error: --content is required" >&2 + exit 1 + fi + + # Get absolute path to mc.sh for API URL resolution + local SCRIPT_DIR + SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + export SCRIPT_DIR + source "$SCRIPT_DIR/lib/api_client.sh" + + # Build JSON payload + local payload + payload=$(jq -n \ + --arg title "$title" \ + --arg content "$content" \ + --arg type "markdown" \ + --arg folder "$folder" \ + --argjson tags "$tags" \ + --arg size "${#content}" \ + --arg description "${description:-Created via CLI}" \ + '{ + title: $title, + content: $content, + type: $type, + folder: $folder, + tags: $tags, + size: ($size | tonumber), + description: $description + }') + + # Create document + mc_post "/documents" "$payload" + ;; *) echo "Unknown documents subcommand: $subcmd" >&2 - echo "Usage: ./mc.sh documents {list|get <id>}" >&2 + echo "Usage: ./mc.sh documents {list|get <id>|create <args>}" >&2 exit 1 ;; esac