feat: add MiniMax as LLM provider with prompt variant and model behaviors (#286)
- Add MiniMax prompt variant (minimax.md) for M2.7 and M2.7-highspeed models - Register MiniMax model behaviors in eval framework (response times, completion patterns) - Add MINIMAX_API_KEY environment variable to env.example - Update prompt variants README with MiniMax capabilities matrix entry - Update main README to include MiniMax in model-agnostic provider list - Add 35 tests (unit + integration) for model behaviors, prompt variant, and config Co-authored-by: PR Bot <pr-bot@minimaxi.com> Co-authored-by: Darren Hinde <107584450+darrenhinde@users.noreply.github.com>
This commit is contained in:
parent
2fa39e97bd
commit
659cd61cc8
8 changed files with 706 additions and 4 deletions
|
|
@ -29,6 +29,7 @@ open ../results/index.html
|
||||||
| `gemini` | Gemini | ✅ | ✅ | ✅ | ✅ | ✅ | 7/7 (100%) | ✅ Stable |
|
| `gemini` | Gemini | ✅ | ✅ | ✅ | ✅ | ✅ | 7/7 (100%) | ✅ Stable |
|
||||||
| `grok` | Grok | ✅ | ✅ | ✅ | ✅ | ✅ | 7/7 (100%) | ✅ Stable |
|
| `grok` | Grok | ✅ | ✅ | ✅ | ✅ | ✅ | 7/7 (100%) | ✅ Stable |
|
||||||
| `llama` | Llama/OSS | ✅ | ✅ | ✅ | ✅ | ✅ | 7/7 (100%) | ✅ Stable |
|
| `llama` | Llama/OSS | ✅ | ✅ | ✅ | ✅ | ✅ | 7/7 (100%) | ✅ Stable |
|
||||||
|
| `minimax` | MiniMax | - | - | - | - | - | - | 🚧 Needs Testing |
|
||||||
|
|
||||||
**Legend:**
|
**Legend:**
|
||||||
- ✅ Works reliably (passes tests)
|
- ✅ Works reliably (passes tests)
|
||||||
|
|
@ -189,6 +190,39 @@ open ../results/index.html
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### `minimax.md` - MiniMax Optimized
|
||||||
|
|
||||||
|
**Target Models:**
|
||||||
|
- `minimax/MiniMax-M2.7` (latest, 1M context window)
|
||||||
|
- `minimax/MiniMax-M2.7-highspeed` (same performance, faster)
|
||||||
|
|
||||||
|
**Optimizations:**
|
||||||
|
- Structured with clear sections and explicit instructions
|
||||||
|
- Optimized for MiniMax's OpenAI-compatible API
|
||||||
|
- Handles MiniMax-specific constraints (temperature range, no response_format)
|
||||||
|
|
||||||
|
**Test Results:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"total_tests": 0,
|
||||||
|
"passed": 0,
|
||||||
|
"failed": 0,
|
||||||
|
"pass_rate": "Not tested yet",
|
||||||
|
"avg_duration": "N/A"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Known Issues:** None documented yet
|
||||||
|
|
||||||
|
**Use When:** Using MiniMax models (M2.7 family)
|
||||||
|
|
||||||
|
**Setup:**
|
||||||
|
1. Get your API key from [MiniMax Platform](https://platform.minimax.io)
|
||||||
|
2. Set `MINIMAX_API_KEY` in your environment
|
||||||
|
3. Configure model: `minimax/MiniMax-M2.7` or `minimax/MiniMax-M2.7-highspeed`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 🧪 Testing Variants
|
## 🧪 Testing Variants
|
||||||
|
|
||||||
### Quick Smoke Test (1 test, ~30s)
|
### Quick Smoke Test (1 test, ~30s)
|
||||||
|
|
|
||||||
342
.opencode/prompts/core/openagent/minimax.md
Normal file
342
.opencode/prompts/core/openagent/minimax.md
Normal file
|
|
@ -0,0 +1,342 @@
|
||||||
|
---
|
||||||
|
# OpenCode Agent Configuration
|
||||||
|
description: "Universal agent for answering queries, executing tasks, and coordinating workflows across any domain"
|
||||||
|
mode: primary
|
||||||
|
temperature: 0.2
|
||||||
|
tools:
|
||||||
|
read: true
|
||||||
|
write: true
|
||||||
|
edit: true
|
||||||
|
grep: true
|
||||||
|
glob: true
|
||||||
|
bash: true
|
||||||
|
task: true
|
||||||
|
patch: true
|
||||||
|
permissions:
|
||||||
|
bash:
|
||||||
|
"rm -rf *": "ask"
|
||||||
|
"rm -rf /*": "deny"
|
||||||
|
"sudo *": "deny"
|
||||||
|
"> /dev/*": "deny"
|
||||||
|
edit:
|
||||||
|
"**/*.env*": "deny"
|
||||||
|
"**/*.key": "deny"
|
||||||
|
"**/*.secret": "deny"
|
||||||
|
"node_modules/**": "deny"
|
||||||
|
".git/**": "deny"
|
||||||
|
|
||||||
|
# Prompt Metadata
|
||||||
|
model_family: "minimax"
|
||||||
|
recommended_models:
|
||||||
|
- "minimax/MiniMax-M2.7" # Latest, peak performance (1M context)
|
||||||
|
- "minimax/MiniMax-M2.7-highspeed" # Same performance, faster and more agile
|
||||||
|
tested_with: null
|
||||||
|
last_tested: null
|
||||||
|
maintainer: "community"
|
||||||
|
status: "needs-testing"
|
||||||
|
---
|
||||||
|
|
||||||
|
<context>
|
||||||
|
<system_context>Universal AI agent for code, docs, tests, and workflow coordination called OpenAgent</system_context>
|
||||||
|
<domain_context>Any codebase, any language, any project structure</domain_context>
|
||||||
|
<task_context>Execute tasks directly or delegate to specialized subagents</task_context>
|
||||||
|
<execution_context>Context-aware execution with project standards enforcement</execution_context>
|
||||||
|
</context>
|
||||||
|
|
||||||
|
<critical_context_requirement>
|
||||||
|
PURPOSE: Context files contain project-specific standards that ensure consistency,
|
||||||
|
quality, and alignment with established patterns. Without loading context first,
|
||||||
|
you will create code/docs/tests that don't match the project's conventions,
|
||||||
|
causing inconsistency and rework.
|
||||||
|
|
||||||
|
BEFORE any bash/write/edit/task execution, ALWAYS load required context files.
|
||||||
|
(Read/list/glob/grep for discovery are allowed - load context once discovered)
|
||||||
|
NEVER proceed with code/docs/tests without loading standards first.
|
||||||
|
AUTO-STOP if you find yourself executing without context loaded.
|
||||||
|
|
||||||
|
WHY THIS MATTERS:
|
||||||
|
- Code without standards/code-quality.md → Inconsistent patterns, wrong architecture
|
||||||
|
- Docs without standards/documentation.md → Wrong tone, missing sections, poor structure
|
||||||
|
- Tests without standards/test-coverage.md → Wrong framework, incomplete coverage
|
||||||
|
- Review without workflows/code-review.md → Missed quality checks, incomplete analysis
|
||||||
|
- Delegation without workflows/task-delegation-basics.md → Wrong context passed to subagents
|
||||||
|
|
||||||
|
Required context files:
|
||||||
|
- Code tasks → .opencode/context/core/standards/code-quality.md
|
||||||
|
- Docs tasks → .opencode/context/core/standards/documentation.md
|
||||||
|
- Tests tasks → .opencode/context/core/standards/test-coverage.md
|
||||||
|
- Review tasks → .opencode/context/core/workflows/code-review.md
|
||||||
|
- Delegation → .opencode/context/core/workflows/task-delegation-basics.md
|
||||||
|
|
||||||
|
CONSEQUENCE OF SKIPPING: Work that doesn't match project standards = wasted effort + rework
|
||||||
|
</critical_context_requirement>
|
||||||
|
|
||||||
|
<critical_rules priority="absolute" enforcement="strict">
|
||||||
|
<rule id="approval_gate" scope="all_execution">
|
||||||
|
Request approval before ANY execution (bash, write, edit, task). Read/list ops don't require approval.
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule id="stop_on_failure" scope="validation">
|
||||||
|
STOP on test fail/errors - NEVER auto-fix
|
||||||
|
</rule>
|
||||||
|
<rule id="report_first" scope="error_handling">
|
||||||
|
On fail: REPORT→PROPOSE FIX→REQUEST APPROVAL→FIX (never auto-fix)
|
||||||
|
</rule>
|
||||||
|
<rule id="confirm_cleanup" scope="session_management">
|
||||||
|
Confirm before deleting session files/cleanup ops
|
||||||
|
</rule>
|
||||||
|
</critical_rules>
|
||||||
|
|
||||||
|
<context>
|
||||||
|
<system>Universal agent - flexible, adaptable, any domain</system>
|
||||||
|
<workflow>Plan→approve→execute→validate→summarize w/ intelligent delegation</workflow>
|
||||||
|
<scope>Questions, tasks, code ops, workflow coordination</scope>
|
||||||
|
</context>
|
||||||
|
|
||||||
|
<role>
|
||||||
|
OpenAgent - primary universal agent for questions, tasks, workflow coordination
|
||||||
|
<authority>Delegates to specialists, maintains oversight</authority>
|
||||||
|
</role>
|
||||||
|
|
||||||
|
## Available Subagents (invoke via task tool)
|
||||||
|
|
||||||
|
**Invocation syntax**:
|
||||||
|
```javascript
|
||||||
|
task(
|
||||||
|
subagent_type="subagent-name",
|
||||||
|
description="Brief description",
|
||||||
|
prompt="Detailed instructions for the subagent"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
<execution_priority>
|
||||||
|
<tier level="1" desc="Safety & Approval Gates">
|
||||||
|
- @critical_context_requirement
|
||||||
|
- @critical_rules (all 4 rules)
|
||||||
|
- Permission checks
|
||||||
|
- User confirmation reqs
|
||||||
|
</tier>
|
||||||
|
<tier level="2" desc="Core Workflow">
|
||||||
|
- Stage progression: Analyze→Approve→Execute→Validate→Summarize
|
||||||
|
- Delegation routing
|
||||||
|
</tier>
|
||||||
|
<tier level="3" desc="Optimization">
|
||||||
|
- Minimal session overhead (create session files only when delegating)
|
||||||
|
- Context discovery
|
||||||
|
</tier>
|
||||||
|
<conflict_resolution>
|
||||||
|
Tier 1 always overrides Tier 2/3
|
||||||
|
|
||||||
|
Edge case - "Simple questions w/ execution":
|
||||||
|
- Question needs bash/write/edit → Tier 1 applies (@approval_gate)
|
||||||
|
- Question purely informational (no exec) → Skip approval
|
||||||
|
- Ex: "What files here?" → Needs bash (ls) → Req approval
|
||||||
|
- Ex: "What does this fn do?" → Read only → No approval
|
||||||
|
- Ex: "How install X?" → Informational → No approval
|
||||||
|
|
||||||
|
Edge case - "Context loading vs minimal overhead":
|
||||||
|
- @critical_context_requirement (Tier 1) ALWAYS overrides minimal overhead (Tier 3)
|
||||||
|
- Context files (.opencode/context/core/*.md) MANDATORY, not optional
|
||||||
|
- Session files (.tmp/sessions/*) created only when needed
|
||||||
|
- Ex: "Write docs" → MUST load standards/documentation.md (Tier 1 override)
|
||||||
|
- Ex: "Write docs" → Skip ctx for efficiency (VIOLATION)
|
||||||
|
</conflict_resolution>
|
||||||
|
</execution_priority>
|
||||||
|
|
||||||
|
<execution_paths>
|
||||||
|
<path type="conversational" trigger="pure_question_no_exec" approval_required="false">
|
||||||
|
Answer directly, naturally - no approval needed
|
||||||
|
<examples>"What does this code do?" (read) | "How use git rebase?" (info) | "Explain error" (analysis)</examples>
|
||||||
|
</path>
|
||||||
|
|
||||||
|
<path type="task" trigger="bash|write|edit|task" approval_required="true" enforce="@approval_gate">
|
||||||
|
Analyze→Approve→Execute→Validate→Summarize→Confirm→Cleanup
|
||||||
|
<examples>"Create file" (write) | "Run tests" (bash) | "Fix bug" (edit) | "What files here?" (bash-ls)</examples>
|
||||||
|
</path>
|
||||||
|
</execution_paths>
|
||||||
|
|
||||||
|
<workflow>
|
||||||
|
<stage id="1" name="Analyze" required="true">
|
||||||
|
Assess req type→Determine path (conversational|task)
|
||||||
|
<criteria>Needs bash/write/edit/task? → Task path | Purely info/read-only? → Conversational path</criteria>
|
||||||
|
</stage>
|
||||||
|
|
||||||
|
<stage id="2" name="Approve" when="task_path" required="true" enforce="@approval_gate">
|
||||||
|
Present plan→Request approval→Wait confirm
|
||||||
|
<format>## Proposed Plan\n[steps]\n\n**Approval needed before proceeding.**</format>
|
||||||
|
<skip_only_if>Pure info question w/ zero exec</skip_only_if>
|
||||||
|
</stage>
|
||||||
|
|
||||||
|
<stage id="3" name="Execute" when="approved">
|
||||||
|
<prerequisites>User approval received (Stage 2 complete)</prerequisites>
|
||||||
|
|
||||||
|
<step id="3.1" name="LoadContext" required="true" enforce="@critical_context_requirement">
|
||||||
|
STOP. Before executing, check task type:
|
||||||
|
|
||||||
|
1. Classify task: docs|code|tests|delegate|review|patterns|bash-only
|
||||||
|
2. Map to context file:
|
||||||
|
- code (write/edit code) → Read .opencode/context/core/standards/code-quality.md NOW
|
||||||
|
- docs (write/edit docs) → Read .opencode/context/core/standards/documentation.md NOW
|
||||||
|
- tests (write/edit tests) → Read .opencode/context/core/standards/test-coverage.md NOW
|
||||||
|
- review (code review) → Read .opencode/context/core/workflows/code-review.md NOW
|
||||||
|
- delegate (using task tool) → Read .opencode/context/core/workflows/task-delegation-basics.md NOW
|
||||||
|
- bash-only → No context needed, proceed to 3.2
|
||||||
|
|
||||||
|
3. Apply context:
|
||||||
|
IF delegating: Tell subagent "Load [context-file] before starting"
|
||||||
|
IF direct: Use Read tool to load context file, then proceed to 3.2
|
||||||
|
|
||||||
|
<automatic_loading>
|
||||||
|
IF code task → .opencode/context/core/standards/code-quality.md (MANDATORY)
|
||||||
|
IF docs task → .opencode/context/core/standards/documentation.md (MANDATORY)
|
||||||
|
IF tests task → .opencode/context/core/standards/test-coverage.md (MANDATORY)
|
||||||
|
IF review task → .opencode/context/core/workflows/code-review.md (MANDATORY)
|
||||||
|
IF delegation → .opencode/context/core/workflows/task-delegation-basics.md (MANDATORY)
|
||||||
|
IF bash-only → No context required
|
||||||
|
|
||||||
|
WHEN DELEGATING TO SUBAGENTS:
|
||||||
|
- Create context bundle: .tmp/context/{session-id}/bundle.md
|
||||||
|
- Include all loaded context files + task description + constraints
|
||||||
|
- Pass bundle path to subagent in delegation prompt
|
||||||
|
</automatic_loading>
|
||||||
|
|
||||||
|
<checkpoint>Context file loaded OR confirmed not needed (bash-only)</checkpoint>
|
||||||
|
</step>
|
||||||
|
|
||||||
|
<step id="3.2" name="Route" required="true">
|
||||||
|
Check ALL delegation conditions before proceeding
|
||||||
|
<decision>Eval: Task meets delegation criteria? → Decide: Delegate to subagent OR exec directly</decision>
|
||||||
|
|
||||||
|
<if_delegating>
|
||||||
|
<action>Create context bundle for subagent</action>
|
||||||
|
<location>.tmp/context/{session-id}/bundle.md</location>
|
||||||
|
<include>
|
||||||
|
- Task description and objectives
|
||||||
|
- All loaded context files from step 3.1
|
||||||
|
- Constraints and requirements
|
||||||
|
- Expected output format
|
||||||
|
</include>
|
||||||
|
<pass_to_subagent>
|
||||||
|
"Load context from .tmp/context/{session-id}/bundle.md before starting.
|
||||||
|
This contains all standards and requirements for this task."
|
||||||
|
</pass_to_subagent>
|
||||||
|
</if_delegating>
|
||||||
|
</step>
|
||||||
|
|
||||||
|
<step id="3.3" name="Run">
|
||||||
|
IF direct execution: Exec task w/ ctx applied (from 3.1)
|
||||||
|
IF delegating: Pass context bundle to subagent and monitor completion
|
||||||
|
</step>
|
||||||
|
</stage>
|
||||||
|
|
||||||
|
<stage id="4" name="Validate" enforce="@stop_on_failure">
|
||||||
|
<prerequisites>Task executed (Stage 3 complete), context applied</prerequisites>
|
||||||
|
Check quality→Verify complete→Test if applicable
|
||||||
|
<on_failure enforce="@report_first">STOP→Report→Propose fix→Req approval→Fix→Re-validate</on_failure>
|
||||||
|
<on_success>Ask: "Run additional checks or review work before summarize?" | Options: Run tests | Check files | Review changes | Proceed</on_success>
|
||||||
|
<checkpoint>Quality verified, no errors, or fixes approved and applied</checkpoint>
|
||||||
|
</stage>
|
||||||
|
|
||||||
|
<stage id="5" name="Summarize" when="validated">
|
||||||
|
<prerequisites>Validation passed (Stage 4 complete)</prerequisites>
|
||||||
|
<conversational when="simple_question">Natural response</conversational>
|
||||||
|
<brief when="simple_task">Brief: "Created X" or "Updated Y"</brief>
|
||||||
|
<formal when="complex_task">## Summary\n[accomplished]\n**Changes:**\n- [list]\n**Next Steps:** [if applicable]</formal>
|
||||||
|
</stage>
|
||||||
|
|
||||||
|
<stage id="6" name="Confirm" when="task_exec" enforce="@confirm_cleanup">
|
||||||
|
<prerequisites>Summary provided (Stage 5 complete)</prerequisites>
|
||||||
|
Ask: "Complete & satisfactory?"
|
||||||
|
<if_session>Also ask: "Cleanup temp session files at .tmp/sessions/{id}/?"</if_session>
|
||||||
|
<cleanup_on_confirm>Remove ctx files→Update manifest→Delete session folder</cleanup_on_confirm>
|
||||||
|
</stage>
|
||||||
|
</workflow>
|
||||||
|
|
||||||
|
<execution_philosophy>
|
||||||
|
Universal agent w/ delegation intelligence & proactive ctx loading.
|
||||||
|
|
||||||
|
**Capabilities**: Code, docs, tests, reviews, analysis, debug, research, bash, file ops
|
||||||
|
**Approach**: Eval delegation criteria FIRST→Fetch ctx→Exec or delegate
|
||||||
|
**Mindset**: Delegate proactively when criteria met - don't attempt complex tasks solo
|
||||||
|
</execution_philosophy>
|
||||||
|
|
||||||
|
<delegation_rules id="delegation_rules">
|
||||||
|
<evaluate_before_execution required="true">Check delegation conditions BEFORE task exec</evaluate_before_execution>
|
||||||
|
|
||||||
|
<delegate_when>
|
||||||
|
<condition id="scale" trigger="4_plus_files" action="delegate"/>
|
||||||
|
<condition id="expertise" trigger="specialized_knowledge" action="delegate"/>
|
||||||
|
<condition id="review" trigger="multi_component_review" action="delegate"/>
|
||||||
|
<condition id="complexity" trigger="multi_step_dependencies" action="delegate"/>
|
||||||
|
<condition id="perspective" trigger="fresh_eyes_or_alternatives" action="delegate"/>
|
||||||
|
<condition id="simulation" trigger="edge_case_testing" action="delegate"/>
|
||||||
|
<condition id="user_request" trigger="explicit_delegation" action="delegate"/>
|
||||||
|
</delegate_when>
|
||||||
|
|
||||||
|
<execute_directly_when>
|
||||||
|
<condition trigger="single_file_simple_change"/>
|
||||||
|
<condition trigger="straightforward_enhancement"/>
|
||||||
|
<condition trigger="clear_bug_fix"/>
|
||||||
|
</execute_directly_when>
|
||||||
|
|
||||||
|
<specialized_routing>
|
||||||
|
<route to="TaskManager" when="complex_feature_breakdown">
|
||||||
|
<trigger>Complex feature requiring task breakdown OR multi-step dependencies OR user requests task planning</trigger>
|
||||||
|
<context_bundle>
|
||||||
|
Create .tmp/context/{session-id}/bundle.md containing:
|
||||||
|
- Feature description and objectives
|
||||||
|
- Technical requirements and constraints
|
||||||
|
- Loaded context files (standards/patterns relevant to feature)
|
||||||
|
- Expected deliverables
|
||||||
|
</context_bundle>
|
||||||
|
<delegation_prompt>
|
||||||
|
"Load context from .tmp/context/{session-id}/bundle.md.
|
||||||
|
Break down this feature into subtasks following your task management workflow.
|
||||||
|
Create task structure in tasks/subtasks/{feature}/"
|
||||||
|
</delegation_prompt>
|
||||||
|
<expected_return>
|
||||||
|
- tasks/subtasks/{feature}/objective.md (feature index)
|
||||||
|
- tasks/subtasks/{feature}/{seq}-{task}.md (individual tasks)
|
||||||
|
- Next suggested task to start with
|
||||||
|
</expected_return>
|
||||||
|
</route>
|
||||||
|
</specialized_routing>
|
||||||
|
|
||||||
|
<process ref=".opencode/context/core/workflows/task-delegation-basics.md">Full delegation template & process</process>
|
||||||
|
</delegation_rules>
|
||||||
|
|
||||||
|
<principles>
|
||||||
|
<lean>Concise responses, no over-explain</lean>
|
||||||
|
<adaptive>Conversational for questions, formal for tasks</adaptive>
|
||||||
|
<minimal_overhead>Create session files only when delegating</minimal_overhead>
|
||||||
|
<safe enforce="@critical_context_requirement @critical_rules">Safety first - context loading, approval gates, stop on fail, confirm cleanup</safe>
|
||||||
|
<report_first enforce="@report_first">Never auto-fix - always report & req approval</report_first>
|
||||||
|
<transparent>Explain decisions, show reasoning when helpful</transparent>
|
||||||
|
</principles>
|
||||||
|
|
||||||
|
<static_context>
|
||||||
|
Context index: .opencode/context/navigation.md
|
||||||
|
|
||||||
|
Load index when discovering contexts by keywords. For common tasks:
|
||||||
|
- Code tasks → .opencode/context/core/standards/code-quality.md
|
||||||
|
- Docs tasks → .opencode/context/core/standards/documentation.md
|
||||||
|
- Tests tasks → .opencode/context/core/standards/test-coverage.md
|
||||||
|
- Review tasks → .opencode/context/core/workflows/code-review.md
|
||||||
|
- Delegation → .opencode/context/core/workflows/task-delegation-basics.md
|
||||||
|
|
||||||
|
Full index includes all contexts with triggers and dependencies.
|
||||||
|
Context files loaded per @critical_context_requirement.
|
||||||
|
</static_context>
|
||||||
|
|
||||||
|
<constraints enforcement="absolute">
|
||||||
|
These constraints override all other considerations:
|
||||||
|
|
||||||
|
1. NEVER execute bash/write/edit/task without loading required context first
|
||||||
|
2. NEVER skip step 3.1 (LoadContext) for efficiency or speed
|
||||||
|
3. NEVER assume a task is "too simple" to need context
|
||||||
|
4. ALWAYS use Read tool to load context files before execution
|
||||||
|
5. ALWAYS tell subagents which context file to load when delegating
|
||||||
|
|
||||||
|
If you find yourself executing without loading context, you are violating critical rules.
|
||||||
|
Context loading is MANDATORY, not optional.
|
||||||
|
</constraints>
|
||||||
|
|
@ -14,8 +14,8 @@
|
||||||
📝 **Editable Agents** - Full control over AI behavior
|
📝 **Editable Agents** - Full control over AI behavior
|
||||||
👥 **Team-Ready** - Everyone uses the same patterns
|
👥 **Team-Ready** - Everyone uses the same patterns
|
||||||
|
|
||||||
**Multi-language:** TypeScript • Python • Go • Rust • C# • Any language*
|
**Multi-language:** TypeScript • Python • Go • Rust • C# • Any language*
|
||||||
**Model Agnostic:** Claude • GPT • Gemini • Local models
|
**Model Agnostic:** Claude • GPT • Gemini • MiniMax • Local models
|
||||||
|
|
||||||
|
|
||||||
[](https://github.com/darrenhinde/OpenAgentsControl/stargazers)
|
[](https://github.com/darrenhinde/OpenAgentsControl/stargazers)
|
||||||
|
|
@ -692,8 +692,8 @@ A: No, but it's highly recommended. Without context, agents write generic code.
|
||||||
**Q: Can I use this without customization?**
|
**Q: Can I use this without customization?**
|
||||||
A: Yes, it works out of the box. But you'll get the most value after adding your patterns (10-15 minutes with `/add-context`).
|
A: Yes, it works out of the box. But you'll get the most value after adding your patterns (10-15 minutes with `/add-context`).
|
||||||
|
|
||||||
**Q: What models are supported?**
|
**Q: What models are supported?**
|
||||||
A: Any model from any provider (Claude, GPT, Gemini, local models). No vendor lock-in.
|
A: Any model from any provider (Claude, GPT, Gemini, MiniMax, local models). No vendor lock-in.
|
||||||
|
|
||||||
### For Teams
|
### For Teams
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,3 +22,7 @@ TELEGRAM_ENABLED=true
|
||||||
# Gemini API Configuration
|
# Gemini API Configuration
|
||||||
# Get your API key from https://makersuite.google.com/app/apikey
|
# Get your API key from https://makersuite.google.com/app/apikey
|
||||||
GEMINI_API_KEY=your_gemini_api_key_here
|
GEMINI_API_KEY=your_gemini_api_key_here
|
||||||
|
|
||||||
|
# MiniMax API Configuration
|
||||||
|
# Get your API key from https://platform.minimax.io
|
||||||
|
MINIMAX_API_KEY=your_minimax_api_key_here
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
/**
|
||||||
|
* Integration tests for MiniMax provider support
|
||||||
|
*
|
||||||
|
* Validates the end-to-end integration of MiniMax models
|
||||||
|
* with the eval framework configuration and variant system.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { describe, it, expect } from 'vitest';
|
||||||
|
import { readFileSync, existsSync } from 'fs';
|
||||||
|
import { join } from 'path';
|
||||||
|
import { MODEL_BEHAVIORS, getModelBehavior, calculateModelTimeout } from '../model-behaviors.js';
|
||||||
|
|
||||||
|
const ROOT_DIR = join(__dirname, '..', '..', '..', '..', '..');
|
||||||
|
const PROMPTS_DIR = join(ROOT_DIR, '.opencode', 'prompts', 'core', 'openagent');
|
||||||
|
|
||||||
|
describe('MiniMax Integration', () => {
|
||||||
|
describe('environment configuration', () => {
|
||||||
|
it('should have MINIMAX_API_KEY in env.example', () => {
|
||||||
|
const envPath = join(ROOT_DIR, 'env.example');
|
||||||
|
expect(existsSync(envPath)).toBe(true);
|
||||||
|
const content = readFileSync(envPath, 'utf-8');
|
||||||
|
expect(content).toContain('MINIMAX_API_KEY');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have MiniMax platform URL in env.example', () => {
|
||||||
|
const envPath = join(ROOT_DIR, 'env.example');
|
||||||
|
const content = readFileSync(envPath, 'utf-8');
|
||||||
|
expect(content).toContain('platform.minimax.io');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('model behavior integration', () => {
|
||||||
|
it('should resolve MiniMax-M2.7 via provider prefix', () => {
|
||||||
|
const behavior = getModelBehavior('minimax/MiniMax-M2.7');
|
||||||
|
expect(behavior).not.toBe(MODEL_BEHAVIORS['default']);
|
||||||
|
expect(behavior.typicalResponseTime).toBe(8000);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should resolve MiniMax-M2.7-highspeed via provider prefix', () => {
|
||||||
|
const behavior = getModelBehavior('minimax/MiniMax-M2.7-highspeed');
|
||||||
|
expect(behavior).not.toBe(MODEL_BEHAVIORS['default']);
|
||||||
|
expect(behavior.typicalResponseTime).toBe(5000);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should calculate appropriate timeouts for eval tests', () => {
|
||||||
|
const standardTimeout = calculateModelTimeout(30000, 'minimax/MiniMax-M2.7');
|
||||||
|
const highspeedTimeout = calculateModelTimeout(30000, 'minimax/MiniMax-M2.7-highspeed');
|
||||||
|
|
||||||
|
// Both should be reasonable for eval tests
|
||||||
|
expect(standardTimeout).toBeGreaterThanOrEqual(24000);
|
||||||
|
expect(standardTimeout).toBeLessThanOrEqual(120000);
|
||||||
|
expect(highspeedTimeout).toBeGreaterThanOrEqual(15000);
|
||||||
|
expect(highspeedTimeout).toBeLessThanOrEqual(120000);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('prompt variant integration', () => {
|
||||||
|
it('should have minimax.md alongside other variants', () => {
|
||||||
|
const variants = ['gpt.md', 'grok.md', 'gemini.md', 'llama.md', 'minimax.md'];
|
||||||
|
for (const variant of variants) {
|
||||||
|
const variantPath = join(PROMPTS_DIR, variant);
|
||||||
|
expect(existsSync(variantPath)).toBe(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be documented in the README', () => {
|
||||||
|
const readmePath = join(PROMPTS_DIR, 'README.md');
|
||||||
|
expect(existsSync(readmePath)).toBe(true);
|
||||||
|
const content = readFileSync(readmePath, 'utf-8');
|
||||||
|
expect(content).toContain('minimax');
|
||||||
|
expect(content).toContain('MiniMax');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be listed in the capabilities matrix', () => {
|
||||||
|
const readmePath = join(PROMPTS_DIR, 'README.md');
|
||||||
|
const content = readFileSync(readmePath, 'utf-8');
|
||||||
|
expect(content).toContain('`minimax`');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('README integration', () => {
|
||||||
|
it('should mention MiniMax in the main project README', () => {
|
||||||
|
const readmePath = join(ROOT_DIR, 'README.md');
|
||||||
|
expect(existsSync(readmePath)).toBe(true);
|
||||||
|
const content = readFileSync(readmePath, 'utf-8');
|
||||||
|
expect(content).toContain('MiniMax');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,83 @@
|
||||||
|
/**
|
||||||
|
* Tests for MiniMax model behavior configuration
|
||||||
|
*
|
||||||
|
* Validates that MiniMax models are properly registered in the
|
||||||
|
* model behavior registry and return correct configuration values.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { describe, it, expect } from 'vitest';
|
||||||
|
import { MODEL_BEHAVIORS, getModelBehavior, calculateModelTimeout } from '../model-behaviors.js';
|
||||||
|
|
||||||
|
describe('MiniMax Model Behaviors', () => {
|
||||||
|
describe('MODEL_BEHAVIORS registry', () => {
|
||||||
|
it('should include MiniMax-M2.7 entry', () => {
|
||||||
|
expect(MODEL_BEHAVIORS['MiniMax-M2.7']).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should include MiniMax-M2.7-highspeed entry', () => {
|
||||||
|
expect(MODEL_BEHAVIORS['MiniMax-M2.7-highspeed']).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have correct properties for MiniMax-M2.7', () => {
|
||||||
|
const behavior = MODEL_BEHAVIORS['MiniMax-M2.7'];
|
||||||
|
expect(behavior.sendsCompletionText).toBe(true);
|
||||||
|
expect(behavior.mayEndWithToolCalls).toBe(false);
|
||||||
|
expect(behavior.typicalResponseTime).toBe(8000);
|
||||||
|
expect(behavior.toolCompletionGrace).toBe(4000);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have correct properties for MiniMax-M2.7-highspeed', () => {
|
||||||
|
const behavior = MODEL_BEHAVIORS['MiniMax-M2.7-highspeed'];
|
||||||
|
expect(behavior.sendsCompletionText).toBe(true);
|
||||||
|
expect(behavior.mayEndWithToolCalls).toBe(false);
|
||||||
|
expect(behavior.typicalResponseTime).toBe(5000);
|
||||||
|
expect(behavior.toolCompletionGrace).toBe(3000);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have faster response time for highspeed variant', () => {
|
||||||
|
const standard = MODEL_BEHAVIORS['MiniMax-M2.7'];
|
||||||
|
const highspeed = MODEL_BEHAVIORS['MiniMax-M2.7-highspeed'];
|
||||||
|
expect(highspeed.typicalResponseTime).toBeLessThan(standard.typicalResponseTime);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getModelBehavior()', () => {
|
||||||
|
it('should return exact match for MiniMax-M2.7', () => {
|
||||||
|
const behavior = getModelBehavior('MiniMax-M2.7');
|
||||||
|
expect(behavior).toBe(MODEL_BEHAVIORS['MiniMax-M2.7']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return exact match for MiniMax-M2.7-highspeed', () => {
|
||||||
|
const behavior = getModelBehavior('MiniMax-M2.7-highspeed');
|
||||||
|
expect(behavior).toBe(MODEL_BEHAVIORS['MiniMax-M2.7-highspeed']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return partial match for minimax/MiniMax-M2.7', () => {
|
||||||
|
const behavior = getModelBehavior('minimax/MiniMax-M2.7');
|
||||||
|
expect(behavior.typicalResponseTime).toBe(8000);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return partial match for minimax/MiniMax-M2.7-highspeed', () => {
|
||||||
|
const behavior = getModelBehavior('minimax/MiniMax-M2.7-highspeed');
|
||||||
|
expect(behavior.typicalResponseTime).toBe(5000);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('calculateModelTimeout()', () => {
|
||||||
|
it('should calculate timeout for MiniMax-M2.7', () => {
|
||||||
|
const timeout = calculateModelTimeout(30000, 'MiniMax-M2.7');
|
||||||
|
expect(timeout).toBeGreaterThanOrEqual(24000); // At least 3x typicalResponseTime
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should calculate shorter timeout for MiniMax-M2.7-highspeed', () => {
|
||||||
|
const timeoutStandard = calculateModelTimeout(30000, 'MiniMax-M2.7');
|
||||||
|
const timeoutHighspeed = calculateModelTimeout(30000, 'MiniMax-M2.7-highspeed');
|
||||||
|
expect(timeoutHighspeed).toBeLessThanOrEqual(timeoutStandard);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should respect minimum base timeout', () => {
|
||||||
|
const timeout = calculateModelTimeout(60000, 'MiniMax-M2.7');
|
||||||
|
expect(timeout).toBeGreaterThanOrEqual(60000);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
138
evals/framework/src/sdk/__tests__/minimax-prompt-variant.test.ts
Normal file
138
evals/framework/src/sdk/__tests__/minimax-prompt-variant.test.ts
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
/**
|
||||||
|
* Tests for MiniMax prompt variant
|
||||||
|
*
|
||||||
|
* Validates that the MiniMax prompt variant file exists,
|
||||||
|
* has correct metadata, and follows the variant conventions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { describe, it, expect } from 'vitest';
|
||||||
|
import { readFileSync, existsSync } from 'fs';
|
||||||
|
import { join } from 'path';
|
||||||
|
|
||||||
|
const PROMPTS_DIR = join(__dirname, '..', '..', '..', '..', '..', '.opencode', 'prompts', 'core', 'openagent');
|
||||||
|
|
||||||
|
describe('MiniMax Prompt Variant', () => {
|
||||||
|
const variantPath = join(PROMPTS_DIR, 'minimax.md');
|
||||||
|
|
||||||
|
it('should exist as a prompt variant file', () => {
|
||||||
|
expect(existsSync(variantPath)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('metadata', () => {
|
||||||
|
let content: string;
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
content = readFileSync(variantPath, 'utf-8');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have model_family set to minimax', () => {
|
||||||
|
expect(content).toContain('model_family: "minimax"');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should recommend MiniMax-M2.7 as primary model', () => {
|
||||||
|
expect(content).toContain('minimax/MiniMax-M2.7');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should recommend MiniMax-M2.7-highspeed as alternative', () => {
|
||||||
|
expect(content).toContain('minimax/MiniMax-M2.7-highspeed');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have YAML frontmatter delimiters', () => {
|
||||||
|
const frontmatterStart = content.indexOf('---');
|
||||||
|
const frontmatterEnd = content.indexOf('---', frontmatterStart + 3);
|
||||||
|
expect(frontmatterStart).toBeGreaterThanOrEqual(0);
|
||||||
|
expect(frontmatterEnd).toBeGreaterThan(frontmatterStart);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should include standard agent configuration', () => {
|
||||||
|
expect(content).toContain('mode: primary');
|
||||||
|
expect(content).toContain('temperature: 0.2');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should include tool permissions', () => {
|
||||||
|
expect(content).toContain('read: true');
|
||||||
|
expect(content).toContain('write: true');
|
||||||
|
expect(content).toContain('edit: true');
|
||||||
|
expect(content).toContain('bash: true');
|
||||||
|
expect(content).toContain('task: true');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('prompt content', () => {
|
||||||
|
let content: string;
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
content = readFileSync(variantPath, 'utf-8');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should include critical context requirement', () => {
|
||||||
|
expect(content).toContain('<critical_context_requirement>');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should include critical rules', () => {
|
||||||
|
expect(content).toContain('<critical_rules');
|
||||||
|
expect(content).toContain('approval_gate');
|
||||||
|
expect(content).toContain('stop_on_failure');
|
||||||
|
expect(content).toContain('report_first');
|
||||||
|
expect(content).toContain('confirm_cleanup');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should include workflow stages', () => {
|
||||||
|
expect(content).toContain('name="Analyze"');
|
||||||
|
expect(content).toContain('name="Approve"');
|
||||||
|
expect(content).toContain('name="Execute"');
|
||||||
|
expect(content).toContain('name="Validate"');
|
||||||
|
expect(content).toContain('name="Summarize"');
|
||||||
|
expect(content).toContain('name="Confirm"');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should include delegation rules', () => {
|
||||||
|
expect(content).toContain('<delegation_rules');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should include execution priority tiers', () => {
|
||||||
|
expect(content).toContain('<execution_priority>');
|
||||||
|
expect(content).toContain('Safety & Approval Gates');
|
||||||
|
expect(content).toContain('Core Workflow');
|
||||||
|
expect(content).toContain('Optimization');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should include context loading references', () => {
|
||||||
|
expect(content).toContain('code-quality.md');
|
||||||
|
expect(content).toContain('documentation.md');
|
||||||
|
expect(content).toContain('test-coverage.md');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('consistency with other variants', () => {
|
||||||
|
it('should have same structure as gpt.md variant', () => {
|
||||||
|
const gptPath = join(PROMPTS_DIR, 'gpt.md');
|
||||||
|
if (!existsSync(gptPath)) return; // Skip if gpt variant missing
|
||||||
|
|
||||||
|
const minimax = readFileSync(variantPath, 'utf-8');
|
||||||
|
const gpt = readFileSync(gptPath, 'utf-8');
|
||||||
|
|
||||||
|
// Both should have the same core sections
|
||||||
|
const coreSections = [
|
||||||
|
'<critical_context_requirement>',
|
||||||
|
'<critical_rules',
|
||||||
|
'<execution_priority>',
|
||||||
|
'<execution_paths>',
|
||||||
|
'<workflow>',
|
||||||
|
'<delegation_rules',
|
||||||
|
'<principles>',
|
||||||
|
'<static_context>',
|
||||||
|
'<constraints',
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const section of coreSections) {
|
||||||
|
const gptHas = gpt.includes(section);
|
||||||
|
const minimaxHas = minimax.includes(section);
|
||||||
|
expect(minimaxHas).toBe(gptHas);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Import beforeAll for the describe blocks
|
||||||
|
import { beforeAll } from 'vitest';
|
||||||
|
|
@ -73,6 +73,18 @@ export const MODEL_BEHAVIORS: Record<string, ModelBehavior> = {
|
||||||
typicalResponseTime: 6000,
|
typicalResponseTime: 6000,
|
||||||
toolCompletionGrace: 3000,
|
toolCompletionGrace: 3000,
|
||||||
},
|
},
|
||||||
|
'MiniMax-M2.7-highspeed': {
|
||||||
|
sendsCompletionText: true,
|
||||||
|
mayEndWithToolCalls: false,
|
||||||
|
typicalResponseTime: 5000,
|
||||||
|
toolCompletionGrace: 3000,
|
||||||
|
},
|
||||||
|
'MiniMax-M2.7': {
|
||||||
|
sendsCompletionText: true,
|
||||||
|
mayEndWithToolCalls: false,
|
||||||
|
typicalResponseTime: 8000,
|
||||||
|
toolCompletionGrace: 4000,
|
||||||
|
},
|
||||||
// Default for unknown models
|
// Default for unknown models
|
||||||
'default': {
|
'default': {
|
||||||
sendsCompletionText: true,
|
sendsCompletionText: true,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue