Lumoswitch 文档
Agent 接入

Qwen Code 接入

Qwen Code 是开源编码 Agent,可以在终端中理解项目、修改文件、运行命令并调用工具。它支持 OpenAI-compatible 提供方,因此可以把 Agent 请求交给 Lumoswitch。

配置 API 必须启用 OpenAI-compatible 输出,目标模型应支持流式输出与 Tool / Function Calling。以下 CLI 命令适用于 macOS、Linux 的 Bash / Zsh;开始前请确认 qwen --version 能返回版本号。

方式总览

方式适合什么情况会写入什么退出后是否保留
仅本次启动测试地址、Key 或模型Lumoswitch 临时设置文件
永久使用日常从终端启动原生设置、受管环境与可选维护启动器
IDE Companion把当前 Qwen Code CLI 连接到编辑器沿用当前 CLI 进程随 CLI 方式而定
VS Code 原生侧边栏直接在扩展界面使用用户级 Qwen Code 提供方配置

Qwen Code 没有独立的官方桌面端。官方提供 VS Code Extension Beta:既可连接当前 CLI,也可由扩展自己启动原生侧边栏 Agent。这两个入口的配置边界不同,具体见下文。

准备连接信息

占位符应填写的内容
{{api_base_url}}配置 API 显示的 OpenAI-compatible 请求地址,应以 /v1 结尾
{{access_key}}配置 API 的 Access Key
{{model}}配置 API 显示的下游模型名称
{{qwen_settings_json}}按有效推理能力生成的完整 Qwen Code 设置 JSON

从控制台复制的命令会自动填入真实值。每个模型的 generationConfig.reasoning 由有效能力单独生成:可调模型使用安全默认档位,明确不支持推理的模型关闭推理,未知或固定推理模型不注入控制字段。

仅本次启动

在要使用 Qwen Code 的项目目录运行。命令会为当前进程创建临时提供方目录,并通过环境传入 Key;退出后临时目录立即删除,不会修改用户级或项目级 Qwen Code 配置。

(
  set -e
  LUMOSWITCH_QWEN_SETTINGS="$(mktemp "${TMPDIR:-/tmp}/lumoswitch-qwen.XXXXXX")"
  trap 'rm -f "$LUMOSWITCH_QWEN_SETTINGS"' EXIT
  printf '%s\n' '{{qwen_settings_json}}' > "$LUMOSWITCH_QWEN_SETTINGS"
  chmod 600 "$LUMOSWITCH_QWEN_SETTINGS"
  env \
    LUMOSWITCH_QWEN_API_KEY="{{access_key}}" \
    QWEN_CODE_SYSTEM_SETTINGS_PATH="$LUMOSWITCH_QWEN_SETTINGS" \
    qwen --auth-type openai --model "{{model}}"
)

永久使用

首次设置,或 Lumoswitch 地址、Access Key、模型发生变化时,运行下面的完整命令。它会写入 Qwen Code 支持的系统设置路径和受管环境,并保存可选维护启动器;不会覆盖默认用户配置。

永久导入会把 Access Key 保存到仅当前用户可读的受管环境或 Agent 配置文件中。请只在可信的个人设备上使用。

set -e
LUMOSWITCH_ROOT="$HOME/.config/lumoswitch/agents/qwen-code"
LUMOSWITCH_ENV="$LUMOSWITCH_ROOT/env.sh"
LUMOSWITCH_LAUNCHER="$HOME/.local/bin/lumoswitch-qwen-code"
mkdir -p "$LUMOSWITCH_ROOT" "$(dirname "$LUMOSWITCH_LAUNCHER")"
umask 077

if [ -f "$LUMOSWITCH_LAUNCHER" ]; then
  LUMOSWITCH_BACKUP="$LUMOSWITCH_LAUNCHER.backup.$(date +%Y%m%d-%H%M%S)-$$"
  cp "$LUMOSWITCH_LAUNCHER" "$LUMOSWITCH_BACKUP"
  chmod 600 "$LUMOSWITCH_BACKUP"
fi

LUMOSWITCH_QWEN_SETTINGS="$LUMOSWITCH_ROOT/settings.json"
printf '%s\n' '{{qwen_settings_json}}' > "$LUMOSWITCH_QWEN_SETTINGS"

cat > "$LUMOSWITCH_ENV" <<'LUMOSWITCH_ENV_EOF'
export QWEN_CODE_SYSTEM_SETTINGS_PATH="$HOME/.config/lumoswitch/agents/qwen-code/settings.json"
export LUMOSWITCH_QWEN_API_KEY="{{access_key}}"
export LUMOSWITCH_QWEN_MODEL="{{model}}"
LUMOSWITCH_ENV_EOF

case "$SHELL" in
  */zsh) LUMOSWITCH_PROFILE="$HOME/.zshrc" ;;
  */bash) LUMOSWITCH_PROFILE="$HOME/.bashrc" ;;
  *) LUMOSWITCH_PROFILE="$HOME/.profile" ;;
esac
touch "$LUMOSWITCH_PROFILE"
LUMOSWITCH_PROFILE_MARKER='# Lumoswitch Agent: qwen-code'
LUMOSWITCH_SOURCE_LINE='[ -f "$HOME/.config/lumoswitch/agents/qwen-code/env.sh" ] && . "$HOME/.config/lumoswitch/agents/qwen-code/env.sh"'
if ! grep -Fqx "$LUMOSWITCH_SOURCE_LINE" "$LUMOSWITCH_PROFILE"; then
  printf '\n%s\n%s\n' "$LUMOSWITCH_PROFILE_MARKER" "$LUMOSWITCH_SOURCE_LINE" >> "$LUMOSWITCH_PROFILE"
fi
printf '%s\n' "$LUMOSWITCH_PROFILE" > "$LUMOSWITCH_ROOT/profile-path"

cat > "$LUMOSWITCH_LAUNCHER" <<'LUMOSWITCH_LAUNCHER_EOF'
#!/usr/bin/env bash
set -e
LUMOSWITCH_ROOT="$HOME/.config/lumoswitch/agents/qwen-code"
LUMOSWITCH_ENV="$LUMOSWITCH_ROOT/env.sh"
LUMOSWITCH_LAUNCHER="$HOME/.local/bin/lumoswitch-qwen-code"

if [ "$1" = "--lumoswitch-clean" ]; then
  if [ -f "$LUMOSWITCH_ROOT/profile-path" ]; then
    LUMOSWITCH_PROFILE="$(cat "$LUMOSWITCH_ROOT/profile-path")"
    if [ -f "$LUMOSWITCH_PROFILE" ]; then
      LUMOSWITCH_PROFILE_MARKER='# Lumoswitch Agent: qwen-code'
      LUMOSWITCH_SOURCE_LINE='[ -f "$HOME/.config/lumoswitch/agents/qwen-code/env.sh" ] && . "$HOME/.config/lumoswitch/agents/qwen-code/env.sh"'
      LUMOSWITCH_PROFILE_TMP="$LUMOSWITCH_PROFILE.lumoswitch.$$"
      awk -v marker="$LUMOSWITCH_PROFILE_MARKER" -v source="$LUMOSWITCH_SOURCE_LINE" '$0 != marker && $0 != source' "$LUMOSWITCH_PROFILE" > "$LUMOSWITCH_PROFILE_TMP"
      mv "$LUMOSWITCH_PROFILE_TMP" "$LUMOSWITCH_PROFILE"
    fi
  fi
  if [ -d "$LUMOSWITCH_ROOT" ]; then
    find "$LUMOSWITCH_ROOT" -depth \( -type f -o -type l \) -delete
    find "$LUMOSWITCH_ROOT" -depth -type d -exec rmdir {} \; 2>/dev/null || true
  fi
  find "$(dirname "$LUMOSWITCH_LAUNCHER")" -maxdepth 1 -type f -name 'lumoswitch-qwen-code.backup.*' -delete
  rm -f "$LUMOSWITCH_LAUNCHER"
  printf '%s\n' 'Lumoswitch native setup and optional launcher removed. Open a new terminal to refresh the environment.'
  exit 0
fi

if [ -f "$LUMOSWITCH_ENV" ]; then . "$LUMOSWITCH_ENV"; fi
exec qwen "$@"
LUMOSWITCH_LAUNCHER_EOF

chmod 600 "$LUMOSWITCH_ENV"
find "$LUMOSWITCH_ROOT" -type f -exec chmod 600 {} \;
chmod 700 "$LUMOSWITCH_LAUNCHER"
. "$LUMOSWITCH_ENV"
printf '%s\n' 'Native Lumoswitch setup saved. Future command: qwen'
printf '%s\n' 'Optional maintenance launcher: ~/.local/bin/lumoswitch-qwen-code'
qwen

以后在任意项目目录运行:

qwen

可以在命令末尾继续传入 Qwen Code 参数。更新启动器前会保留一个带时间戳、权限为 0600 的现有启动器备份。

Windows PowerShell 原生导入

以下命令在 Windows PowerShell 中原生运行,不需要 WSL。它们与本页的 macOS/Linux 模板使用同一组连接值。

仅本次使用(Windows)

& {
  $ErrorActionPreference = 'Stop'
  $lumoswitchConfig = Join-Path ([IO.Path]::GetTempPath()) ('lumoswitch-' + [Guid]::NewGuid().ToString('N') + '.json')
  $lumoswitchConfigContent = @'
{{qwen_settings_json}}
'@
  [IO.File]::WriteAllText($lumoswitchConfig, $lumoswitchConfigContent, [Text.UTF8Encoding]::new($false))
  $lumoswitchEnvironmentNames = @('LUMOSWITCH_QWEN_API_KEY', 'QWEN_CODE_SYSTEM_SETTINGS_PATH')
  $lumoswitchPreviousEnvironment = @{}
  foreach ($lumoswitchName in $lumoswitchEnvironmentNames) {
    $lumoswitchPreviousEnvironment[$lumoswitchName] = [Environment]::GetEnvironmentVariable($lumoswitchName, 'Process')
  }
  $lumoswitchExitCode = 0
  try {
    [Environment]::SetEnvironmentVariable('LUMOSWITCH_QWEN_API_KEY', '{{access_key}}', 'Process')
    [Environment]::SetEnvironmentVariable('QWEN_CODE_SYSTEM_SETTINGS_PATH', $lumoswitchConfig, 'Process')
    $lumoswitchArguments = @('--auth-type', 'openai', '--model', '{{model}}')
    $lumoswitchExecutable = Get-Command 'qwen.cmd' -CommandType Application -ErrorAction SilentlyContinue
    if ($null -eq $lumoswitchExecutable) { $lumoswitchExecutable = Get-Command 'qwen' -CommandType Application -ErrorAction Stop }
    & $lumoswitchExecutable.Path @lumoswitchArguments
    if ($null -ne $LASTEXITCODE) { $lumoswitchExitCode = $LASTEXITCODE }
  } finally {
    foreach ($lumoswitchName in $lumoswitchEnvironmentNames) {
      [Environment]::SetEnvironmentVariable($lumoswitchName, $lumoswitchPreviousEnvironment[$lumoswitchName], 'Process')
    }
    Remove-Item -LiteralPath $lumoswitchConfig -Force -ErrorAction SilentlyContinue
  }
  if ($lumoswitchExitCode -ne 0) { throw 'qwen exited with code ' + $lumoswitchExitCode }
}

永久使用(Windows)

该命令会备份已有的 Lumoswitch 专用文件,并为配置和启动器收紧当前用户的访问权限。

& {
  $ErrorActionPreference = 'Stop'
  $lumoswitchRoot = Join-Path $env:LOCALAPPDATA 'Lumoswitch\agents\qwen-code'
  $lumoswitchLauncher = Join-Path $env:LOCALAPPDATA 'Lumoswitch\bin\lumoswitch-qwen-code.ps1'
  $lumoswitchBackupSuffix = (Get-Date -Format 'yyyyMMdd-HHmmss') + '-' + $PID

  function Protect-LumoswitchFile([string] $Path) {
    $lumoswitchSid = [Security.Principal.WindowsIdentity]::GetCurrent().User.Value
    & icacls.exe $Path '/inheritance:r' '/grant:r' ('*' + $lumoswitchSid + ':(F)') '*S-1-5-18:(F)' '*S-1-5-32-544:(F)' | Out-Null
    if ($LASTEXITCODE -ne 0) { throw "Could not restrict access to $Path" }
  }

  function Install-LumoswitchFile([string] $Path, [string] $Content) {
    [IO.Directory]::CreateDirectory((Split-Path -Parent $Path)) | Out-Null
    if (Test-Path -LiteralPath $Path) {
      $lumoswitchItem = Get-Item -LiteralPath $Path -Force
      if ($lumoswitchItem.PSIsContainer -or ($lumoswitchItem.Attributes -band [IO.FileAttributes]::ReparsePoint)) {
        throw "Lumoswitch refused to replace a directory or link: $Path"
      }
      $lumoswitchBackup = $Path + '.backup.' + $lumoswitchBackupSuffix
      Copy-Item -LiteralPath $Path -Destination $lumoswitchBackup
      Protect-LumoswitchFile $lumoswitchBackup
    }
    $lumoswitchTemporary = $Path + '.' + [Guid]::NewGuid().ToString('N') + '.tmp'
    try {
      [IO.File]::WriteAllText($lumoswitchTemporary, $Content, [Text.UTF8Encoding]::new($false))
      Move-Item -LiteralPath $lumoswitchTemporary -Destination $Path -Force
      Protect-LumoswitchFile $Path
    } finally {
      Remove-Item -LiteralPath $lumoswitchTemporary -Force -ErrorAction SilentlyContinue
    }
  }

  [IO.Directory]::CreateDirectory($lumoswitchRoot) | Out-Null
  $lumoswitchQwenSettings = Join-Path $lumoswitchRoot 'settings.json'
  Install-LumoswitchFile $lumoswitchQwenSettings '{{qwen_settings_json}}'

  $lumoswitchEnvironment = [ordered]@{}
  $lumoswitchEnvironment['QWEN_CODE_SYSTEM_SETTINGS_PATH'] = (Join-Path $lumoswitchRoot 'settings.json')
  $lumoswitchEnvironment['LUMOSWITCH_QWEN_API_KEY'] = '{{access_key}}'
  $lumoswitchEnvironment['LUMOSWITCH_QWEN_MODEL'] = '{{model}}'
  foreach ($lumoswitchEntry in $lumoswitchEnvironment.GetEnumerator()) {
    [Environment]::SetEnvironmentVariable($lumoswitchEntry.Key, $lumoswitchEntry.Value, 'User')
    [Environment]::SetEnvironmentVariable($lumoswitchEntry.Key, $lumoswitchEntry.Value, 'Process')
  }

  $lumoswitchLauncherContent = @'
param([Parameter(ValueFromRemainingArguments = $true)][string[]] $AgentArgs)
$ErrorActionPreference = 'Stop'
$lumoswitchRoot = Join-Path $env:LOCALAPPDATA 'Lumoswitch\agents\qwen-code'
$lumoswitchLauncher = Join-Path $env:LOCALAPPDATA 'Lumoswitch\bin\lumoswitch-qwen-code.ps1'

function Remove-LumoswitchFile([string] $Path) {
  if (-not (Test-Path -LiteralPath $Path)) { return }
  $lumoswitchItem = Get-Item -LiteralPath $Path -Force
  if ($lumoswitchItem.PSIsContainer -or ($lumoswitchItem.Attributes -band [IO.FileAttributes]::ReparsePoint)) {
    throw "Lumoswitch refused to remove a directory or link: $Path"
  }
  Remove-Item -LiteralPath $Path -Force
}

if ($AgentArgs.Count -gt 0 -and $AgentArgs[0] -eq '--lumoswitch-clean') {
  foreach ($lumoswitchName in @('QWEN_CODE_SYSTEM_SETTINGS_PATH', 'LUMOSWITCH_QWEN_API_KEY', 'LUMOSWITCH_QWEN_MODEL')) {
    [Environment]::SetEnvironmentVariable($lumoswitchName, $null, 'User')
    [Environment]::SetEnvironmentVariable($lumoswitchName, $null, 'Process')
  }
  if (Test-Path -LiteralPath $lumoswitchRoot -PathType Container) {
    $lumoswitchRootItem = Get-Item -LiteralPath $lumoswitchRoot -Force
    if ($lumoswitchRootItem.Attributes -band [IO.FileAttributes]::ReparsePoint) { throw 'Lumoswitch refused to clean through a linked directory.' }
    foreach ($lumoswitchFile in @(Get-ChildItem -LiteralPath $lumoswitchRoot -File -Recurse -Force)) { Remove-LumoswitchFile $lumoswitchFile.FullName }
    foreach ($lumoswitchDirectory in @(Get-ChildItem -LiteralPath $lumoswitchRoot -Directory -Recurse -Force | Sort-Object FullName -Descending)) {
      if ($null -eq (Get-ChildItem -LiteralPath $lumoswitchDirectory.FullName -Force | Select-Object -First 1)) { Remove-Item -LiteralPath $lumoswitchDirectory.FullName -Force }
    }
    if ($null -eq (Get-ChildItem -LiteralPath $lumoswitchRoot -Force | Select-Object -First 1)) { Remove-Item -LiteralPath $lumoswitchRoot -Force }
  }
  $lumoswitchBin = Split-Path -Parent $lumoswitchLauncher
  if (Test-Path -LiteralPath $lumoswitchBin -PathType Container) {
    foreach ($lumoswitchBackup in @(Get-ChildItem -LiteralPath $lumoswitchBin -Filter 'lumoswitch-qwen-code.ps1.backup.*' -File -Force)) { Remove-LumoswitchFile $lumoswitchBackup.FullName }
  }
  Remove-LumoswitchFile $lumoswitchLauncher
  Write-Host 'Lumoswitch native setup and optional launcher removed. Open a new terminal to refresh the environment.'
  exit 0
}

$lumoswitchEnvironment = [ordered]@{}
$lumoswitchEnvironment['QWEN_CODE_SYSTEM_SETTINGS_PATH'] = (Join-Path $lumoswitchRoot 'settings.json')
$lumoswitchEnvironment['LUMOSWITCH_QWEN_API_KEY'] = '{{access_key}}'
$lumoswitchEnvironment['LUMOSWITCH_QWEN_MODEL'] = '{{model}}'
foreach ($lumoswitchEntry in $lumoswitchEnvironment.GetEnumerator()) {
  [Environment]::SetEnvironmentVariable($lumoswitchEntry.Key, $lumoswitchEntry.Value, 'Process')
}
$lumoswitchExecutable = Get-Command 'qwen.cmd' -CommandType Application -ErrorAction SilentlyContinue
if ($null -eq $lumoswitchExecutable) { $lumoswitchExecutable = Get-Command 'qwen.exe' -CommandType Application -ErrorAction SilentlyContinue }
if ($null -eq $lumoswitchExecutable) { $lumoswitchExecutable = Get-Command 'qwen' -CommandType Application -ErrorAction Stop }
$lumoswitchArguments = @()
& $lumoswitchExecutable.Path @lumoswitchArguments @AgentArgs
if ($null -ne $LASTEXITCODE) { exit $LASTEXITCODE }
'@
  Install-LumoswitchFile $lumoswitchLauncher $lumoswitchLauncherContent
  Write-Host 'Native Lumoswitch setup saved. Future command: qwen'
  Write-Host 'Optional maintenance launcher:' $lumoswitchLauncher
  $lumoswitchExecutable = Get-Command 'qwen.cmd' -CommandType Application -ErrorAction SilentlyContinue
  if ($null -eq $lumoswitchExecutable) { $lumoswitchExecutable = Get-Command 'qwen.exe' -CommandType Application -ErrorAction SilentlyContinue }
  if ($null -eq $lumoswitchExecutable) { $lumoswitchExecutable = Get-Command 'qwen' -CommandType Application -ErrorAction Stop }
  $lumoswitchArguments = @()
  & $lumoswitchExecutable.Path @lumoswitchArguments
  if ($null -ne $LASTEXITCODE -and $LASTEXITCODE -ne 0) { throw 'qwen exited with code ' + $LASTEXITCODE }
}

导入会写入 Agent 支持的持久化配置,并直接启动 qwen。保存的 Lumoswitch 维护脚本不是启动 Agent 的必需入口;需要恢复或移除此接入时,运行它并追加 --lumoswitch-clean

清除 CLI 接入

Windows PowerShell

先退出该 Agent 的所有 Lumoswitch 会话,再运行下面的命令。可选维护启动器会删除受管原生配置、恢复已保留的共享文件、清除 Lumoswitch 用户环境变量,并移除自身。

& {
  $lumoswitchLauncher = Join-Path $env:LOCALAPPDATA 'Lumoswitch\bin\lumoswitch-qwen-code.ps1'
  if (-not (Test-Path -LiteralPath $lumoswitchLauncher -PathType Leaf)) {
    throw 'The optional Lumoswitch maintenance launcher is missing. Run persistent import again before cleanup.'
  }
  & powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File $lumoswitchLauncher --lumoswitch-clean
}

macOS / Linux

下面的命令会删除受管 Qwen 设置、环境接入、可选维护启动器及其备份;它不会删除 ~/.qwen/settings.json、Qwen Code 登录信息、历史记录或其他用户配置。

"$HOME/.local/bin/lumoswitch-qwen-code" --lumoswitch-clean

临时命令会在退出时删除临时设置文件,也不会在当前终端留下变量。若曾手动导出过 LUMOSWITCH_QWEN_API_KEY,关闭对应终端窗口即可;不自动 unset 是为了避免影响同一终端中的其他 Lumoswitch 工具。

VS Code 与 IDE Companion

连接当前 CLI

先通过本页命令启动 Qwen Code,再按官方 IDE Integration 流程把 Companion 连接到当前 CLI 进程,即可继续使用当前 Lumoswitch 地址、Key 和模型,无需保存第二份凭证。退出临时 CLI 后,临时接入也随之失效。

VS Code 原生侧边栏

扩展原生侧边栏会自行启动 Qwen Code,不保证调用 ~/.local/bin/lumoswitch-qwen-code。如需从侧边栏直接使用 Lumoswitch,应把以下模型条目合并进用户级 ~/.qwen/settings.jsonopenai 数组,不要覆盖已有模型项或整个设置文件。

{
  "modelProviders": {
    "openai": [
      {
        "id": "{{model}}",
        "name": "Lumoswitch · {{model}}",
        "envKey": "LUMOSWITCH_QWEN_API_KEY",
        "baseUrl": "{{api_base_url}}"
      }
    ]
  },
  "security": {
    "auth": {
      "selectedType": "openai"
    }
  },
  "model": {
    "name": "{{model}}"
  }
}

再在 Qwen Code 可读取的用户环境或 ~/.qwen/.env 中提供 LUMOSWITCH_QWEN_API_KEY={{access_key}},并完全重启扩展。不要把真实 Key 写入会提交到 Git 的项目文件。

原生侧边栏只有持久接入,没有可靠的“仅本次启动”命令,因为扩展从持久设置和自己的启动环境读取提供方。清除 CLI 启动器也不会修改这份用户配置;需要清除侧边栏接入时,请只从 modelProviders.openai 删除自己添加的 Lumoswitch 条目、删除对应 LUMOSWITCH_QWEN_API_KEY 行,并切换模型。这里不提供自动清除命令,是为了避免脚本误删用户共享的 JSON、.env 或其他提供方。

参见 Qwen Code VS Code 集成IDE Integration模型提供方配置

验证与排查

  • 启动后先发送一个简单请求,再测试读取文件与工具调用,并在 Lumoswitch 请求日志中确认模型和 Access Key。
  • 返回 404:检查下游地址是否遗漏或重复 /v1
  • IDE 使用默认模型:确认 Companion 连接的是当前 CLI;原生侧边栏则需要单独合并用户级提供方配置。
  • 项目级 .qwen/settings.json 可能覆盖用户级设置,修改后请完全重启扩展。
维护者发布字段
  • 平台 ID:qwen-code
  • 展示名称:Qwen Code CLI
  • 下游协议:openai-compatible
  • commandTemplate:复制「仅本次启动」代码框的完整内容
  • 永久策略:native
  • persistentCommandTemplate:复制「永久使用」中的完整设置命令
  • futureCommandqwen
  • 展示顺序:60
  • 最近核验:2026-08-27

On this page