Open Source Engines (OpenCode, Qwen)
Relevant source files
The following files were used as context for generating this wiki page:
The Morty ecosystem integrates various AI engines to perform autonomous coding tasks. Among these, open-source oriented engines like OpenCode and Qwen-Code provide developers with flexible, high-performance alternatives to proprietary solutions. These engines are integrated into Morty's core loop, allowing the system to leverage their specific CLI capabilities for implementing features, writing tests, and resolving bugs.
In the Morty architecture, these engines are abstracted through a consistent interface, enabling them to be triggered via simple CLI flags such as --opencode or --qwen. They support standard features like model overrides and automated tool approval modes, ensuring they can operate within Morty's fully autonomous execution loop.
Sources: README.md:94-110, morty.sh:10-15, cli/src/cli/args.ts:40-50
Engine Architecture and Integration
Both OpenCode and Qwen-Code are treated as external CLI tools that Morty orchestrates. They follow a specific execution pattern where Morty builds a prompt, executes the engine's CLI command, and parses the resulting output (typically in a streamed JSON format) to determine the next steps in the coding loop.
Core Engine Interface
Engines in the TypeScript CLI implementation extend a BaseAIEngine class. This class defines the contract for availability checks and prompt execution.
The diagram shows the class hierarchy for the Qwen engine integration within the CLI.
Sources: cli/src/engines/base.ts:219-236, cli/src/engines/qwen.ts:11-15
Qwen-Code Engine
The Qwen-Code engine utilizes the qwen CLI tool. It is configured to operate in a high-autonomy mode, specifically using the --approval-mode yolo flag to allow the AI to perform operations without manual intervention.
Execution Flow
The QwenEngine implements both standard and streaming execution. It captures output from stdout and stderr, then parses the cumulative text for results and token usage.
- Command Construction: The engine builds a command string:
qwen --output-format stream-json --approval-mode yolo -p <prompt>. - Streaming & Parsing: As the CLI outputs JSON lines, Morty uses
parseStreamJsonResultto extract the final response and token metrics. - Step Detection: During streaming, Morty analyzes the JSON output to detect what the engine is doing (e.g., "Implementing", "Testing", "Reading code").
Sources: cli/src/engines/qwen.ts:17-45, cli/src/engines/base.ts:182-217
Qwen Configuration Options
| Option | CLI Flag | Description |
|---|---|---|
| Format | --output-format stream-json | Required for Morty to parse structured usage and results. |
| Approval | --approval-mode yolo | Enables autonomous tool usage without user prompts. |
| Model | --model <name> | Allows overriding the default Qwen model (e.g., qwen-max). |
Sources: cli/src/engines/qwen.ts:18-21, README.md:108
OpenCode Engine
OpenCode is a high-performance engine supported in both the Bash (morty.sh) and TypeScript CLI implementations. It is notable for providing actual cost data in its output, which Morty tracks to provide a cost summary at the end of a session.
Integration Logic in Bash
In morty.sh, OpenCode is invoked with specific permission settings to ensure it can modify files autonomously.
This flowchart illustrates the execution and data extraction logic for OpenCode in the bash script.
Sources: morty.sh:783-790, morty.sh:815-827
Data Extraction (OpenCode)
Unlike other engines that only provide token counts, OpenCode provides a specific step_finish event in its JSON stream containing detailed metrics:
- Input Tokens: Found in
part.tokens.input. - Output Tokens: Found in
part.tokens.output. - Actual Cost: Extracted from
part.cost.
Sources: morty.sh:819-823
Comparison of Capabilities
Both engines share common infrastructure for error handling and iteration, but they differ in the metadata they provide to the Morty runtime.
| Feature | OpenCode | Qwen-Code |
|---|---|---|
| CLI Command | opencode | qwen |
| Approval Mode | full-auto | yolo |
| Primary Output | stream-json | stream-json |
| Cost Tracking | Actual cost provided | Estimated via tokens |
| Permission Env | OPENCODE_PERMISSION | N/A |
Sources: morty.sh:783-802, README.md:144-153, cli/src/engines/qwen.ts:18-20
Common Base Logic
Both engines rely on the BaseAIEngine and utility functions in cli/src/engines/base.ts for consistent behavior across the Morty CLI.
Step Detection Logic
Morty identifies the current action of the open-source engines by inspecting the tool or command fields in the JSON output stream.
- Reading code: Detected when
toolisread,glob, orgrep. - Implementing: Detected when
tooliswriteorediton non-test files. - Testing: Detected when
commandincludesvitest,jest,pytest, etc. - Writing tests: Detected when
tooliswrite/editon files matching*.test.*or*.spec.*.
Sources: cli/src/engines/base.ts:250-310
Error Handling
If an engine encounters an issue, Morty searches the JSON stream for objects where type === "error". It specifically looks for error messages in:
error.data.message(Common in OpenCode)error.message(Common in Qwen/Claude)message(Generic fallback)
Sources: morty.sh:883-895, cli/src/engines/base.ts:133-149
Conclusion
The integration of OpenCode and Qwen-Code provides Morty with robust, open-source-compatible autonomous capabilities. By abstracting these engines behind a unified CLI and internal class structure, Morty ensures that developers can switch between proprietary and open-source models with minimal configuration changes while maintaining full visibility into task progress, token usage, and operational costs.