#!/bin/bash # Qwen Consult Hook - Integration with Qwen Code CLI # Allows Claude Code to consult with local Qwen installation for tasks # # Modes (via QWEN_CONSULT_MODE environment variable): # "always" - Consult Qwen for every request # "delegate" - Only when explicitly asked to delegate/consult # "off" - Disable Qwen consultation (default) # # Usage: # Set QWEN_CONSULT_MODE environment variable to control behavior # The hook runs Qwen in non-blocking mode and logs output set -euo pipefail # Configuration CLAUDE_DIR="$HOME/.claude" QWEN_STATE_FILE="$CLAUDE_DIR/qwen-consult.md" QWEN_OUTPUT_LOG="$CLAUDE_DIR/qwen-output.log" QWEN_LOCK_FILE="$CLAUDE_DIR/qwen.lock" # Read hook input from stdin HOOK_INPUT=$(cat) USER_PROMPT=$(echo "$HOOK_INPUT" | jq -r '.prompt // empty' 2>/dev/null || echo "") # Fallback: if no JSON input, use first argument if [[ -z "$USER_PROMPT" && $# -gt 0 ]]; then USER_PROMPT="$1" fi # Get Qwen mode (default: off - requires explicit opt-in) QWEN_CONSULT_MODE="${QWEN_CONSULT_MODE:-off}" QWEN_MODEL="${QWEN_MODEL:-}" QWEN_MAX_ITERATIONS="${QWEN_MAX_ITERATIONS:-30}" # Exit if consultation is disabled if [[ "$QWEN_CONSULT_MODE" == "off" ]]; then exit 0 fi # Check if Qwen is already running if [[ -f "$QWEN_LOCK_FILE" ]]; then LOCK_PID=$(cat "$QWEN_LOCK_FILE" 2>/dev/null || echo "") if [[ -n "$LOCK_PID" ]] && kill -0 "$LOCK_PID" 2>/dev/null; then exit 0 else rm -f "$QWEN_LOCK_FILE" fi fi # Keywords that trigger Qwen consultation (in delegate mode) DELEGATE_KEYWORDS="consult|qwen|delegate|second opinion|alternative|get.*advice|ask.*qwen" # Determine if we should consult Qwen should_consult=false case "$QWEN_CONSULT_MODE" in "always") should_consult=true ;; "delegate") if echo "$USER_PROMPT" | grep -iqE "$DELEGATE_KEYWORDS"; then should_consult=true fi ;; esac if [[ "$should_consult" == true ]]; then # Create state directory mkdir -p "$CLAUDE_DIR" # Build Qwen command arguments QWEN_ARGS=() if [[ -n "$QWEN_MODEL" ]]; then QWEN_ARGS+=(-m "$QWEN_MODEL") fi # Prepare prompt for Qwen with context QWEN_PROMPT="You are Qwen, consulted by Claude Code for assistance. The user asks: $USER_PROMPT Please provide your analysis, suggestions, or solution. Be concise and actionable." # Create state file cat > "$QWEN_STATE_FILE" << EOF # Qwen Consult State # Generated: $(date -u +"%Y-%m-%d %H:%M:%S UTC") **User Request:** $USER_PROMPT **Mode:** $QWEN_CONSULT_MODE **Model:** ${QWEN_MODEL:-default} **Timestamp:** $(date -Iseconds) ## Context This state file was generated by the Qwen consultation hook. Qwen Code CLI is being consulted to provide additional insights on this request. ## Configuration - Hook: UserPromptSubmit - Trigger mode: $QWEN_CONSULT_MODE - Log file: $QWEN_OUTPUT_LOG ## Usage Qwen is running autonomously in the background. Monitor progress: \`\`\`bash # View Qwen output in real-time tail -f ~/.claude/qwen-output.log # Check if Qwen is still running ps aux | grep qwen # Stop Qwen manually kill \$(cat ~/.claude/qwen.lock) \`\`\` EOF # Check if Qwen is available if command -v qwen &> /dev/null; then # Create log file touch "$QWEN_OUTPUT_LOG" # Start Qwen in background { echo "[$(date -u +"%Y-%m-%d %H:%M:%S UTC")] Qwen consultation started" echo "Mode: $QWEN_CONSULT_MODE" echo "Model: ${QWEN_MODEL:-default}" echo "---" } >> "$QWEN_OUTPUT_LOG" # Run Qwen in background if [[ ${#QWEN_ARGS[@]} -gt 0 ]]; then nohup qwen "${QWEN_ARGS[@]}" -p "$QWEN_PROMPT" >> "$QWEN_OUTPUT_LOG" 2>&1 & else nohup qwen -p "$QWEN_PROMPT" >> "$QWEN_OUTPUT_LOG" 2>&1 & fi QWEN_PID=$! echo "$QWEN_PID" > "$QWEN_LOCK_FILE" # Log the consultation { echo "[$(date -u +"%Y-%m-%d %H:%M:%S UTC")] Qwen consultation triggered" echo " Mode: $QWEN_CONSULT_MODE" echo " Model: ${QWEN_MODEL:-default}" echo " PID: $QWEN_PID" echo " Log: $QWEN_OUTPUT_LOG" } >> "$CLAUDE_DIR/qwen-consult.log" 2>/dev/null || true # Notify user echo "🤖 Qwen consultation started (PID: $QWEN_PID)" >&2 echo " Monitor: tail -f ~/.claude/qwen-output.log" >&2 else echo "⚠️ Qwen CLI not found at /usr/local/bin/qwen" >&2 fi fi # Exit immediately (non-blocking) exit 0