Skip to main content
Glama
qwenExecutor.ts4.16 kB
import { CLI, QWEN_MODELS, ERROR_MESSAGES, STATUS_MESSAGES } from "../constants.js"; import { executeCommand } from "./commandExecutor.js"; import { logger } from "./logger.js"; import type { QwenModel, ApprovalMode } from "../constants.js"; /** * Options for executing Qwen CLI */ export interface QwenExecutionOptions { prompt: string; model?: QwenModel; sandbox?: boolean; approvalMode?: ApprovalMode; yolo?: boolean; allFiles?: boolean; debug?: boolean; onProgress?: (output: string) => void; } /** * Execute Qwen CLI with the given options */ export async function executeQwenCLI( options: QwenExecutionOptions ): Promise<string> { const { prompt, model, sandbox = false, approvalMode, yolo = false, allFiles = false, debug = false, onProgress } = options; if (!prompt || !prompt.trim()) { throw new Error(ERROR_MESSAGES.NO_PROMPT_PROVIDED); } // Build command arguments const args: string[] = []; // Add model flag if specified if (model) { args.push(CLI.FLAGS.MODEL, model); } // Add sandbox flag if enabled if (sandbox) { args.push(CLI.FLAGS.SANDBOX); } // Add approval mode if specified if (approvalMode) { args.push(CLI.FLAGS.APPROVAL_MODE, approvalMode); } // Add yolo flag if enabled if (yolo) { args.push(CLI.FLAGS.YOLO); } // Add all-files flag if enabled if (allFiles) { args.push(CLI.FLAGS.ALL_FILES); } // Add debug flag if enabled if (debug) { args.push(CLI.FLAGS.DEBUG); } // Add prompt flag with the prompt // Wrap in quotes if it contains @ symbols for file references const shouldQuote = prompt.includes("@"); args.push(CLI.FLAGS.PROMPT); args.push(shouldQuote ? `"${prompt}"` : prompt); logger.info(`Executing Qwen CLI with model: ${model || "default"}`); if (onProgress) { onProgress(STATUS_MESSAGES.STARTING_ANALYSIS); } try { const result = await executeCommand(CLI.COMMANDS.QWEN, args, { onProgress, timeout: 600000 // 10 minutes }); if (onProgress) { onProgress(STATUS_MESSAGES.COMPLETED); } return result; } catch (error) { // Check if this is a quota/rate limit error and we used the primary model const errorMsg = error instanceof Error ? error.message : String(error); const isQuotaError = errorMsg.toLowerCase().includes("quota") || errorMsg.toLowerCase().includes("rate limit"); // If quota error with primary model, try fallback if (isQuotaError && model === QWEN_MODELS.PRIMARY) { logger.warn(STATUS_MESSAGES.SWITCHING_MODEL); if (onProgress) { onProgress(STATUS_MESSAGES.SWITCHING_MODEL); } // Retry with fallback model const fallbackArgs = [...args]; const modelIndex = fallbackArgs.indexOf(CLI.FLAGS.MODEL); if (modelIndex !== -1 && modelIndex + 1 < fallbackArgs.length) { fallbackArgs[modelIndex + 1] = QWEN_MODELS.FALLBACK; } else { // Model wasn't specified, add it fallbackArgs.unshift(CLI.FLAGS.MODEL, QWEN_MODELS.FALLBACK); } try { const fallbackResult = await executeCommand(CLI.COMMANDS.QWEN, fallbackArgs, { onProgress, timeout: 600000 }); if (onProgress) { onProgress(STATUS_MESSAGES.COMPLETED); } return fallbackResult; } catch (fallbackError) { const fallbackErrorMsg = fallbackError instanceof Error ? fallbackError.message : String(fallbackError); throw new Error( `Both primary and fallback models failed:\n` + `Primary: ${errorMsg}\n` + `Fallback: ${fallbackErrorMsg}` ); } } // Not a quota error or already tried fallback if (onProgress) { onProgress(STATUS_MESSAGES.FAILED); } throw error; } } /** * Execute a simple command (like echo or help) */ export async function executeSimpleCommand( command: string, args: string[] = [] ): Promise<string> { logger.debug(`Executing simple command: ${command} ${args.join(" ")}`); return executeCommand(command, args); }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Jaggerxtrm/qwen-mcp-tool'

If you have feedback or need assistance with the MCP directory API, please join our Discord server