Conversation
Add support for minimax and zai CLI agents from cc-mirror (https://github.com/numman-ali/cc-mirror). Both are wrappers for Claude Code (v2.1.1) and use --output-format stream-json --verbose for structured JSONL output parsing. Changes: - Add zai.ts agent plugin with stream-json parsing - Add minimax.ts agent plugin with stream-json parsing - Register both plugins in builtin/index.ts Both agents support: - Streaming output with proper event type parsing - Tool use and tool result event tracking - Subagent tracing via onJsonlMessage forwarding - File context via --add-dir flag - Configurable model and skip-permissions options
|
Someone is attempting to deploy a commit to the plgeek Team on Vercel. A member of the Team first needs to authorize it. |
WalkthroughAdds two built‑in agent plugins (MiniMax and Zai) with CLI detection/version checks, JSONL stream parsing to AgentDisplayEvents, sandbox and setup metadata, streaming execution that forwards JSONL and UI events, and factory exports; also re-exports ClaudeAgentPlugin and exposes new factory functions. Changes
Sequence Diagram(s)sequenceDiagram
participant Host as Host
participant Plugin as Agent Plugin
participant CLI as CLI Process
participant Parser as JSONL Parser
participant Callbacks as Callbacks
Host->>Plugin: execute(prompt, files, options)
Plugin->>Plugin: buildArgs & getStdinInput
Plugin->>CLI: spawn process (stdin)
CLI->>CLI: consume stdin, run model, emit JSONL
CLI-->>Plugin: stdout/stderr (line‑delimited JSON)
loop Stream processing
Plugin->>Parser: feed JSONL line
Parser-->>Plugin: AgentDisplayEvent[]
Plugin->>Callbacks: onJsonlMessage(raw)
Plugin->>Callbacks: onStdoutSegments / onStdout(events)
end
CLI-->>Plugin: exit
Plugin-->>Host: return AgentExecutionHandle
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Fix all issues with AI agents
In `@src/plugins/agents/builtin/minimax.ts`:
- Around line 54-65: In the case 'result' block inside
src/plugins/agents/builtin/minimax.ts, avoid emitting duplicate events when an
error result is represented as a string: if event.subtype === 'error' (or
event.is_error) has been detected and you pushed an error entry to allEvents, do
not also push a 'text' entry for the same event.result; update the logic in that
case 'result' branch to either use an else (skip adding the text when
subtype/error was handled) or add a conditional check before pushing the 'text'
event to ensure the previous error path didn't already consume event.result.
- Around line 401-407: In validateSetup replace the inline array check with the
shared VALID_MODELS constant (the same constant used by validateModel) so model
validation uses VALID_MODELS for allowed values; locate the conditional in
validateSetup that currently compares model against ['MiniMax-M2.1',
'MiniMax-M2', 'MiniMax-M1'] and update it to reference VALID_MODELS (convert
model to string as currently done) so both validateSetup and validateModel stay
consistent.
In `@src/plugins/agents/builtin/zai.ts`:
- Around line 53-64: The result-case handler in case 'result' (inside zai.ts)
can push both an error event and a text event for the same error result; update
the logic around event.subtype/event.is_error and event.result so that when you
detect an error (using event.subtype === 'error' || event.is_error ||
event.error), you push only the error into allEvents and skip adding the text
branch—e.g., make the text push conditional only when not an error (use else or
a negated check) so allEvents does not get duplicate error/text entries.
- Around line 186-193: getSandboxRequirements currently includes a hardcoded
user-specific path "/Users/roshan/.local/bin"; remove that entry and replace it
with a generic, cross-user alternative (e.g., expand "~/.local/bin" or rely on
PATH resolution) in the binaryPaths array inside the getSandboxRequirements
method so the function no longer references a developer-specific filesystem
location.
🧹 Nitpick comments (5)
src/plugins/agents/builtin/minimax.ts (2)
312-325: Consider cross-platform path handling.The directory extraction uses forward slash (
/) only. On Windows, paths may use backslashes. Consider usingpath.dirname()fromnode:pathfor robust cross-platform support.Also, root-level files (where
lastSlash <= 0) are silently skipped. This may be intentional but worth documenting.♻️ Suggested improvement
+import { dirname } from 'node:path'; // ... in buildArgs: if (files && files.length > 0) { const directories = new Set<string>(); for (const file of files) { - const lastSlash = file.path.lastIndexOf('/'); - if (lastSlash > 0) { - directories.add(file.path.substring(0, lastSlash)); + const dir = dirname(file.path); + if (dir && dir !== '.' && dir !== '/') { + directories.add(dir); } }
253-258: Potential double resolution after timeout.When the timeout fires,
proc.kill()is called and the promise resolves with a timeout error. However, thecloseevent will still fire afterwards, potentially causing the promise to resolve twice. While Node.js Promises ignore subsequent resolutions, this can be confusing and may mask issues.♻️ Suggested fix
private runVersion( command: string ): Promise<{ success: boolean; version?: string; error?: string }> { return new Promise((resolve) => { + let resolved = false; + const safeResolve = (result: { success: boolean; version?: string; error?: string }) => { + if (!resolved) { + resolved = true; + resolve(result); + } + }; const proc = spawn(command, ['--version'], { // ... rest of spawn options }); // ... event handlers using safeResolve instead of resolve setTimeout(() => { proc.kill(); - resolve({ success: false, error: 'Timeout waiting for --version' }); + safeResolve({ success: false, error: 'Timeout waiting for --version' }); }, 5000); }); }src/plugins/agents/builtin/zai.ts (3)
30-104: Significant code duplication withparseMiniMaxOutputToEvents.This function is nearly identical to
parseMiniMaxOutputToEventsinminimax.ts. Since both agents wrap Claude Code with the samestream-jsonoutput format, consider extracting a shared parser function.♻️ Suggested approach
Create a shared parser in a common location (e.g.,
output-formatting.tsor a newclaude-code-parser.ts):// In a shared module, e.g., ../claude-code-parser.ts export function parseClaudeCodeJsonlOutput(data: string): AgentDisplayEvent[] { // ... shared implementation }Then both agents can import and use the shared parser:
import { parseClaudeCodeJsonlOutput } from '../claude-code-parser.js'; // ... const events = parseClaudeCodeJsonlOutput(data);
240-244: Same timeout double-resolution issue asminimax.ts.This has the same potential for double promise resolution after timeout. Consider the same fix or extracting to a shared utility.
289-300: Same cross-platform path handling consideration asminimax.ts.The directory extraction logic has the same platform-specific path separator issue. Consider using
path.dirname()for consistency.
- Use else-if in result case to avoid duplicate error/text events - Reference VALID_MODELS constant in minimax validateSetup - Remove hardcoded user path from zai getSandboxRequirements
|
@txhno did you try using the builtin command option to run cc mirror using the claude agent? https://ralph-tui.com/docs/configuration/options#custom-command |
Add support for minimax and zai CLI agents from cc-mirror
(https://github.com/numman-ali/cc-mirror). Both are wrappers
for Claude Code (v2.1.1) and use --output-format stream-json
--verbose for structured JSONL output parsing.
Changes
Features
Both agents support:
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.