{
  "track_id": "qwen_llama_grok_integration_20260606",
  "name": "Qwen, Llama & Grok Vendor Integration + Capability Matrix",
  "initialized": "2026-06-06",
  "owner": "tier2-tech-lead",
  "priority": "high",
  "status": "active",
  "type": "feature + refactor",
  "scope": {
    "new_files": [
      "src/vendor_capabilities.py",
      "src/openai_compatible.py",
      "tests/test_vendor_capabilities.py",
      "tests/test_openai_compatible.py",
      "tests/test_qwen_provider.py",
      "tests/test_llama_provider.py",
      "tests/test_grok_provider.py"
    ],
    "modified_files": [
      "src/ai_client.py",
      "src/cost_tracker.py",
      "src/models.py",
      "src/gui_2.py",
      "src/app_controller.py",
      "credentials_template.toml",
      "pyproject.toml",
      "tests/test_minimax_provider.py",
      "docs/guide_ai_client.md",
      "docs/guide_models.md"
    ]
  },
  "blocked_by": [],
  "blocks": ["anthropic_gemini_deepseek_capability_matrix_20260606" /* not yet created; conceptual follow-up */],
  "estimated_phases": 6,
  "spec": "spec.md",
  "plan": "plan.md",
  "priority_order": "A (capability matrix framework + 3 new vendors) > B (shared helper + MiniMax refactor) > C (UX adaptation + docs)",
  "capability_matrix_v1": ["vision", "tool_calling", "caching", "streaming", "model_discovery", "context_window", "cost_tracking"],
  "capability_matrix_deferred": ["audio_input", "pdf_input", "server_side_code_execution", "image_generation", "fine_tuning", "batch_api"],
  "data_oriented_design": {
    "shared_data_structure": "NormalizedResponse (text, tool_calls, usage_*) + OpenAICompatibleRequest (messages, tools, model, ...)",
    "shared_algorithm": "send_openai_compatible(client, request, capabilities) -> NormalizedResponse in src/openai_compatible.py",
    "per_vendor_boundary": "Each _send_<vendor>() is a thin adapter: init client, load history, call shared helper, update history, return text",
    "philosophy_references": ["Ryan Fleury (code/data separation)", "Mike Acton (data-oriented design)", "Timothy Lottes (cache-aware algorithms)"]
  },
  "vendors_added": {
    "qwen": {
      "api": "DashScope native SDK",
      "rationale": "Qwen-Audio, Qwen-Long (1M context), Qwen-VL-Max require native API; OpenAI-compatible mode loses them",
      "sdk": "dashscope>=1.14.0",
      "models_shipped": ["qwen-turbo", "qwen-plus", "qwen-max", "qwen-long", "qwen-vl-plus", "qwen-vl-max", "qwen-audio"]
    },
    "llama": {
      "api": "OpenAI-compatible (multi-backend)",
      "rationale": "Llama has no first-party API; backend is per-project config",
      "backends_v1": ["ollama (local)", "openrouter (cloud aggregator)", "custom_url (escape hatch)"],
      "models_shipped": ["llama-3.1-8b-instant", "llama-3.1-70b-versatile", "llama-3.1-405b-reasoning", "llama-3.2-1b-preview", "llama-3.2-3b-preview", "llama-3.2-11b-vision-preview", "llama-3.2-90b-vision-preview", "llama-3.3-70b-specdec"]
    },
    "grok": {
      "api": "xAI (OpenAI-compatible)",
      "rationale": "xAI's API is OpenAI-compatible; value is filling the matrix entry and exposing Grok-2-Vision",
      "sdk": "openai>=1.0.0 (already a dependency)",
      "models_shipped": ["grok-2", "grok-2-vision", "grok-beta"]
    }
  },
  "refactor_scope": {
    "minimax": "Refactor _send_minimax() (~250 lines) to use send_openai_compatible() helper (~50 lines)",
    "anthropic": "DEFERRED to follow-up track",
    "gemini": "DEFERRED to follow-up track",
    "deepseek": "DEFERRED to follow-up track"
  },
  "ux_adaptations": [
    "Screenshot button enabled iff vision=true",
    "Tools enabled toggle enabled iff tool_calling=true",
    "Cache panel visible iff caching=true",
    "Stream progress visible iff streaming=true",
    "Fetch Models button enabled iff model_discovery=true",
    "Token budget max = capabilities.context_window",
    "Cost panel shows estimate iff cost_tracking=true",
    "Cost panel shows 'Free (local)' for localhost + cost_tracking=false",
    "Cost panel shows '—' for other cost_tracking=false cases"
  ],
  "architectural_invariant": "Every _send_<vendor>() is a thin boundary adapter; the shared algorithm lives in send_openai_compatible(); the capability matrix is the authoritative source of per-(vendor, model) feature support; the GUI adapts to the matrix, not to vendor names.",
  "threading_constraint": "Same as existing pattern: _send_lock serializes all send() calls; per-vendor history locks (e.g. _minimax_history_lock) guard history mutations; the shared helper is stateless and thread-safe (the OpenAI SDK is thread-safe for distinct clients; the caller owns the client).",
  "verification_criteria": [
    "src/vendor_capabilities.py:get_capabilities(vendor, model) returns correct VendorCapabilities for all 4 OpenAI-compatible vendors + Qwen models",
    "src/vendor_capabilities.py:get_capabilities fallback to vendor default when model not registered",
    "src/openai_compatible.py:send_openai_compatible handles streaming, non-streaming, tool calls, vision, errors",
    "src/openai_compatible.py:send_openai_compatible classifies OpenAI errors to ProviderError kinds",
    "_send_qwen() uses DashScope SDK; tool format translated from OpenAI shape",
    "_send_qwen() handles Qwen-VL vision (image base64), Qwen-Audio stub",
    "_send_llama() supports Ollama, OpenRouter, custom URL backends",
    "_send_llama() unions Ollama /api/tags and OpenRouter /v1/models for model discovery",
    "_send_grok() uses xAI endpoint (base_url hardcoded to https://api.x.ai/v1)",
    "_send_grok() handles Grok-2-Vision vision",
    "_send_minimax() refactored: ~50 lines instead of ~250, all existing test_minimax_provider.py tests pass",
    "GUI: screenshot button enabled iff capabilities.vision is true for the active (vendor, model)",
    "GUI: cost panel shows correct value (estimate, 'Free (local)', or '—') based on capabilities.cost_tracking and base URL",
    "GUI: 9 UX adaptations from spec.md §6 all work end-to-end",
    "No regressions in 273+ existing tests (full test suite passes)",
    "No new threading.Thread calls in src/ (per project invariant)",
    "No top-level heavy imports in src/ai_client.py beyond what's already there (dashscope import is acceptable; flag if it pushes import time > 100ms)"
  ],
  "links": {
    "backlog_entry": "conductor/tracks.md (to be added)",
    "ai_client_guide": "docs/guide_ai_client.md",
    "models_guide": "docs/guide_models.md",
    "workflow_pitfalls": "conductor/workflow.md#known-pitfalls-2026-06-05",
    "related_tracks": [
      "conductor/tracks/openai_integration_20260308/",
      "conductor/tracks/zhipu_integration_20260308/",
      "conductor/tracks/startup_speedup_20260606/",
      "conductor/tracks/test_batching_refactor_20260606/"
    ],
    "external_docs": [
      "https://help.aliyun.com/zh/model-studio/ (DashScope)",
      "https://openrouter.ai/docs (OpenRouter)",
      "https://github.com/ollama/ollama/blob/main/docs/openai.md (Ollama OpenAI compat)",
      "https://docs.x.ai/ (xAI)"
    ]
  }
}
