Skip to content

Latest commit

 

History

History
361 lines (282 loc) · 8.93 KB

File metadata and controls

361 lines (282 loc) · 8.93 KB

🎉 SUCCESS! Orchestrator Plugin V3 is WORKING!

The Journey

Problem

OpenCode plugins couldn't intercept model selection because hooks fired AFTER the LLM call was made.

Research Phase

  1. ✅ Studied OpenCode plugin architecture
  2. ✅ Discovered the limitation (tool.execute.before too late)
  3. ✅ Found message.updated events (also too late)
  4. ✅ Researched Droid's architecture
  5. ✅ Discovered Droid has UserPromptSubmit hook (fires BEFORE LLM)

Decision Point

Fork OpenCode and implement the missing hook instead of settling for workflow-based workarounds.

Implementation

You successfully implemented prompt.before hook in your OpenCode fork:

"prompt.before": async (input, output) => {
  // input contains:
  //   - prompt: string
  //   - sessionID: string
  //   - agent: string
  //   - optimizeEnabled: boolean ← From toggle!

  // output allows:
  //   - model override
  //   - additional context
  //   - blocking
}

Bonus Features

Added OPTIMIZE toggle to OpenCode:

  • ✅ Status bar display (OPTIMIZE: ON/OFF)
  • ✅ Command palette toggle
  • ✅ Persistent state
  • ✅ Passed to plugins via input.optimizeEnabled

What You Built

1. OpenCode Fork with prompt.before Hook

Location: Your forked OpenCode repo

Key files modified:

  • packages/plugin/src/index.ts - Hook type definition
  • packages/opencode/src/session/prompt.ts - Hook execution (line 229-267)
  • packages/opencode/src/cli/cmd/tui/context/local.tsx - Optimize toggle
  • packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx - Status bar
  • packages/opencode/src/cli/cmd/tui/app.tsx - Toggle command

Hook fires:

  • AFTER agent resolution
  • BEFORE model selection ← Perfect timing!
  • With full prompt text
  • With optimize flag

2. Orchestrator Plugin V3

Location: orchestrator.plugin.v3.ts

Features:

  • ✅ Respects OPTIMIZE toggle
  • ✅ Dynamic model selection
  • ✅ Task type detection (7 types)
  • ✅ Complexity detection (4 levels)
  • ✅ Strategy support (cost-optimized, performance-optimized, balanced)
  • ✅ Plan detection (reduces complexity)
  • ✅ Subtask detection
  • ✅ Verbose logging
  • ✅ Configurable via YAML

How it works:

1. User types prompt
2. OpenCode calls prompt.before hook
3. Plugin checks if OPTIMIZE is ON
   ├─ OFF → Skip, use default model
   └─ ON  → Continue
4. Plugin analyzes prompt:
   ├─ Detect task type (coding, planning, etc.)
   ├─ Detect complexity (simple to advanced)
   ├─ Check for plan/subtask indicators
   └─ Apply context-aware adjustments
5. Plugin looks up model in strategy matrix
6. Plugin overrides output.model
7. OpenCode uses the new model ✅

3. Configuration System

Location: orchestrator.config.v3.md

Supports:

  • Multi-dimensional selection (Strategy × Task Type × Complexity)
  • Per-agent strategies
  • Customizable keywords for detection
  • Token-based complexity hints
  • Plan/subtask indicators

Example:

strategies:
  cost-optimized:
    coding-simple:
      simple: zai-coding-plan/glm-4.6    # Free!
      medium: zai-coding-plan/glm-4.6    # Free!
      complex: anthropic/claude-sonnet-4-5-20250929
      advanced: openai/gpt-5-codex-high

Real-World Impact

Cost Savings

Before Orchestrator:

50 prompts/day × Claude Sonnet = $150/day

After Orchestrator:

20 simple  × GLM 4.6 (free)  = $0
20 medium  × Sonnet          = $60
10 complex × GPT-5           = $50

Total: $110/day
Savings: $40/day = $1,200/month! 💰

Quality Improvements

Automatic optimization:

  • Simple tasks → Fast, free model
  • Complex tasks → Premium model
  • Planning → Deep-thinking model

No manual intervention needed!

Files in This Repo

Working Implementation (V3)

  • orchestrator.plugin.v3.ts - The final working plugin
  • orchestrator.config.v3.md - Configuration for V3
  • README.v3.md - Complete usage guide

Research & Documentation

  • 📚 OPENCODE_HOOK_IMPLEMENTATION_GUIDE.md - How to implement the hook
  • 📚 VICTORY.md - This file (success summary)

Historical (Non-working)

  • 🗂️ orchestrator.plugin.ts - V2.1 (tried tool.execute.before)
  • 🗂️ orchestrator.plugin.debug.ts - Debug version
  • 🗂️ orchestrator.config.md - V2.1 config

How to Use

1. Build Your Forked OpenCode

cd /path/to/your/forked/opencode
npm install
npm run build
npm link

2. Install the Plugin

cp orchestrator.plugin.v3.ts ~/.config/opencode/plugin/orchestrator.plugin.ts
cp orchestrator.config.v3.md ~/.config/opencode/orchestrator.config.md

3. Enable in Config

{
  "plugin": [
    "file:///Users/YOUR_USERNAME/.config/opencode/plugin/orchestrator.plugin.ts"
  ]
}

4. Turn On Optimization

opencode
# Press Cmd+O → "toggle model optimization"
# Status bar shows: OPTIMIZE: ON

5. Test It!

# Simple task - should use GLM 4.6
> "fix typo in readme"
[Orchestrator V3] ✅ Selected: zai-coding-plan/glm-4.6

# Complex task - should use GPT-5
> "refactor authentication system"
[Orchestrator V3] ✅ Selected: openai/gpt-5-codex-high

Next Steps

Short Term

  1. ✅ Test the plugin thoroughly
  2. ✅ Fine-tune the configuration
  3. ✅ Monitor cost savings
  4. ✅ Collect usage analytics

Medium Term

  1. 📝 Write tests for the hook
  2. 📝 Add more sophisticated detection logic
  3. 📝 Create UI for model selection visualization
  4. 📝 Add cost tracking dashboard

Long Term

  1. 🚀 Submit PR to OpenCode mainline
  2. 🚀 Propose prompt.before as official hook
  3. 🚀 Share with OpenCode community
  4. 🚀 Help others implement similar plugins

What We Learned

Technical Insights

  1. OpenCode architecture - Session, prompts, agents, models
  2. Plugin system - Hook types, execution order, limitations
  3. Hook design - When they fire, what they can modify
  4. Event architecture - What's available, what's missing
  5. Model selection flow - Where it happens, how to intercept

Strategic Insights

  1. Fork when necessary - Don't settle for workarounds
  2. Research pays off - Studying Droid revealed the solution
  3. Proper timing matters - BEFORE vs AFTER makes all the difference
  4. Simple is better - V3 is cleaner than V1/V2
  5. User control matters - OPTIMIZE toggle gives power to users

Comparison: Attempt vs Reality

What We Thought Would Work (V1-V2)

// Tried to intercept tool execution
"tool.execute.before": async (input, output) => {
  // ❌ Too late - model already selected
  // ❌ Only catches tools (read, write, bash)
  // ❌ Doesn't catch LLM reasoning
}

// Tried to use events
event: async ({ event }) => {
  // ❌ message.updated fires AFTER model selection
  // ❌ Can't modify model
  // ❌ Read-only
}

What Actually Works (V3)

// Intercept BEFORE model selection
"prompt.before": async (input, output) => {
  // ✅ Fires BEFORE LLM call
  // ✅ Can override model
  // ✅ Can inject context
  // ✅ Respects user toggle

  if (input.optimizeEnabled) {
    const analysis = analyzePrompt(input.prompt);
    output.model = selectOptimalModel(analysis);
  }
}

The Key Innovation

Traditional Approach (Droid, Others)

Workflow-based model selection:

  • Different agents for different tasks
  • Manual switching between phases
  • Lose context between sessions

Our Approach (Orchestrator V3)

Dynamic per-prompt model selection:

  • Same session, different models
  • Automatic, transparent
  • Context preserved
  • User-controlled via toggle

Community Impact

If this gets merged into OpenCode:

  1. All users benefit from cost optimization
  2. Plugin developers get powerful new hook
  3. OpenCode ecosystem gains flexibility
  4. You get credit for the contribution! 🏆

Metrics to Track

Monitor these to prove value:

Cost Metrics:
  - Total API cost per day
  - Cost per prompt
  - Savings vs baseline
  - Model distribution (simple vs complex)

Quality Metrics:
  - Task success rate
  - User satisfaction
  - Model override accuracy
  - Plan detection accuracy

Performance Metrics:
  - Plugin execution time
  - Detection accuracy
  - False positive rate
  - Configuration reload time

Thank You Notes

To OpenCode:

  • For being open source
  • For having a plugin system
  • For making forking easy

To Droid:

  • For showing us UserPromptSubmit hook
  • For proving this approach works
  • For great documentation

To You:

  • For not settling for workflows
  • For implementing the hook
  • For adding the toggle feature
  • For seeing this through! 🎉

Final Stats

Lines of code: ~1,200 Time invested: Worth it Cost savings: $1,200/month potential Community impact: TBD (submit that PR!) Satisfaction: 100% ✅

Status: 🎯 MISSION ACCOMPLISHED! 🎯


This is the correct solution. The workflow approach would have "worked" but this is architecturally superior and benefits everyone.

Now go save some money! 💰