Lumoswitch 文档
Agent 接入

Aider 接入

Aider 是运行在终端中的开源结对编程 Agent。它可以读取 Git 仓库、修改代码、生成提交,并通过 OpenAI-compatible 提供方把模型请求交给 Lumoswitch。

配置 API 必须启用 OpenAI-compatible 输出。目标模型应具备可靠的代码编辑能力;开始前请确认 aider --version 能返回版本号。

方式总览

方式适合什么情况会写入什么退出后是否保留
仅本次启动测试地址、Key 或模型临时模型设置文件
永久使用日常从终端启动Agent 原生配置、模型目录与可选维护启动器
浏览器界面在本机浏览器操作同一个 Aider 进程沿用启动方式随启动方式而定
IDE在集成终端或文件监听模式使用沿用启动方式随启动方式而定

Aider 没有官方独立桌面端,也没有官方 IDE 插件。浏览器界面、IDE 集成终端和文件监听仍然运行同一个 Aider 进程,因此无需维护另一份 Lumoswitch 提供方配置。

准备连接信息

占位符应填写的内容
{{api_base_url}}配置 API 显示的 OpenAI-compatible 请求地址,应以 /v1 结尾
{{access_key}}配置 API 的 Access Key
{{model}}配置 API 显示的下游模型名称
{{aider_model_settings_yaml}}按有效推理能力生成的 Aider 模型设置 YAML
{{aider_reasoning_effort}}默认模型可安全使用的推理档位;不应发送时为空

从控制台复制的命令会自动填入真实值。生成的模型设置只为有效能力支持的模型声明 accepts_settings: reasoning_effort;默认档位为空时,启动命令完全不发送该参数。

仅本次启动

在要让 Aider 编辑的项目目录运行。命令会创建临时模型设置文件,并只给新启动的 Aider 进程传入连接变量;退出后文件立即删除,变量不会污染当前终端,也不会修改 Aider 原有配置。

(
  set -e
  LUMOSWITCH_AIDER_MODELS="$(mktemp "${TMPDIR:-/tmp}/lumoswitch-aider-models.XXXXXX")"
  trap 'rm -f "$LUMOSWITCH_AIDER_MODELS"' EXIT
  cat > "$LUMOSWITCH_AIDER_MODELS" <<'LUMOSWITCH_AIDER_MODELS_EOF'
{{aider_model_settings_yaml}}LUMOSWITCH_AIDER_MODELS_EOF
  chmod 600 "$LUMOSWITCH_AIDER_MODELS"
  LUMOSWITCH_AIDER_REASONING_EFFORT="{{aider_reasoning_effort}}"
  set --
  if [ -n "$LUMOSWITCH_AIDER_REASONING_EFFORT" ]; then
    set -- --reasoning-effort "$LUMOSWITCH_AIDER_REASONING_EFFORT"
  fi
  env \
    OPENAI_API_KEY="{{access_key}}" \
    OPENAI_API_BASE="{{api_base_url}}" \
    aider --model-settings-file "$LUMOSWITCH_AIDER_MODELS" --model "openai/{{model}}" "$@"
)

openai/ 是 Aider 选择 OpenAI-compatible 提供方所需的前缀,不会作为下游模型名称的一部分发送给 Lumoswitch。

永久使用

首次设置,或 Lumoswitch 地址、Access Key、模型发生变化时,运行下面的完整命令。它会写入 Aider 支持的专属配置路径和模型设置,并同时保存可选维护启动器;不会覆盖默认 .aider.conf.yml

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

set -e
LUMOSWITCH_ROOT="$HOME/.config/lumoswitch/agents/aider"
LUMOSWITCH_ENV="$LUMOSWITCH_ROOT/env.sh"
LUMOSWITCH_LAUNCHER="$HOME/.local/bin/lumoswitch-aider"
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_AIDER_MODELS="$LUMOSWITCH_ROOT/models.yml"
LUMOSWITCH_AIDER_CONFIG="$LUMOSWITCH_ROOT/aider.conf.yml"
cat > "$LUMOSWITCH_AIDER_MODELS" <<'LUMOSWITCH_MODELS_EOF'
{{aider_model_settings_yaml}}LUMOSWITCH_MODELS_EOF
cat > "$LUMOSWITCH_AIDER_CONFIG" <<LUMOSWITCH_CONFIG_EOF
model: "openai/{{model}}"
model-settings-file: "$LUMOSWITCH_AIDER_MODELS"
reasoning-effort: "{{aider_reasoning_effort}}"
openai-api-base: "{{api_base_url}}"
openai-api-key: "{{access_key}}"
LUMOSWITCH_CONFIG_EOF

cat > "$LUMOSWITCH_ENV" <<'LUMOSWITCH_ENV_EOF'
export AIDER_CONFIG="$HOME/.config/lumoswitch/agents/aider/aider.conf.yml"
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: aider'
LUMOSWITCH_SOURCE_LINE='[ -f "$HOME/.config/lumoswitch/agents/aider/env.sh" ] && . "$HOME/.config/lumoswitch/agents/aider/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/aider"
LUMOSWITCH_ENV="$LUMOSWITCH_ROOT/env.sh"
LUMOSWITCH_LAUNCHER="$HOME/.local/bin/lumoswitch-aider"

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: aider'
      LUMOSWITCH_SOURCE_LINE='[ -f "$HOME/.config/lumoswitch/agents/aider/env.sh" ] && . "$HOME/.config/lumoswitch/agents/aider/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-aider.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 aider "$@"
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: aider'
printf '%s\n' 'Optional maintenance launcher: ~/.local/bin/lumoswitch-aider'
aider

以后在要编辑的项目目录运行:

aider

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

Windows PowerShell 原生导入

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

仅本次使用(Windows)

& {
  $ErrorActionPreference = 'Stop'
  $lumoswitchConfig = Join-Path ([IO.Path]::GetTempPath()) ('lumoswitch-' + [Guid]::NewGuid().ToString('N') + '.yml')
  $lumoswitchConfigContent = @'
{{aider_model_settings_yaml}}
'@
  [IO.File]::WriteAllText($lumoswitchConfig, $lumoswitchConfigContent, [Text.UTF8Encoding]::new($false))
  $lumoswitchEnvironmentNames = @('OPENAI_API_BASE', 'OPENAI_API_KEY')
  $lumoswitchPreviousEnvironment = @{}
  foreach ($lumoswitchName in $lumoswitchEnvironmentNames) {
    $lumoswitchPreviousEnvironment[$lumoswitchName] = [Environment]::GetEnvironmentVariable($lumoswitchName, 'Process')
  }
  $lumoswitchExitCode = 0
  try {
    [Environment]::SetEnvironmentVariable('OPENAI_API_BASE', '{{api_base_url}}', 'Process')
    [Environment]::SetEnvironmentVariable('OPENAI_API_KEY', '{{access_key}}', 'Process')
    $lumoswitchArguments = @('--model-settings-file', $lumoswitchConfig, '--model', 'openai/{{model}}')
    if ('{{aider_reasoning_effort}}') { $lumoswitchArguments += @('--reasoning-effort', '{{aider_reasoning_effort}}') }
    $lumoswitchExecutable = Get-Command 'aider.cmd' -CommandType Application -ErrorAction SilentlyContinue
    if ($null -eq $lumoswitchExecutable) { $lumoswitchExecutable = Get-Command 'aider' -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 'aider exited with code ' + $lumoswitchExitCode }
}

永久使用(Windows)

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

& {
  $ErrorActionPreference = 'Stop'
  $lumoswitchRoot = Join-Path $env:LOCALAPPDATA 'Lumoswitch\agents\aider'
  $lumoswitchLauncher = Join-Path $env:LOCALAPPDATA 'Lumoswitch\bin\lumoswitch-aider.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
  $lumoswitchAiderModels = Join-Path $lumoswitchRoot 'models.yml'
  $lumoswitchAiderConfig = Join-Path $lumoswitchRoot 'aider.conf.yml'
  $lumoswitchModelsContent = @'
{{aider_model_settings_yaml}}
'@
  Install-LumoswitchFile $lumoswitchAiderModels $lumoswitchModelsContent
  $lumoswitchAiderConfigPath = $lumoswitchAiderModels.Replace('\', '/')
  $lumoswitchConfigContent = @'
model: "openai/{{model}}"
model-settings-file: "__LUMOSWITCH_MODELS__"
reasoning-effort: "{{aider_reasoning_effort}}"
openai-api-base: "{{api_base_url}}"
openai-api-key: "{{access_key}}"
'@.Replace('__LUMOSWITCH_MODELS__', $lumoswitchAiderConfigPath)
  Install-LumoswitchFile $lumoswitchAiderConfig $lumoswitchConfigContent

  $lumoswitchEnvironment = [ordered]@{}
  $lumoswitchEnvironment['AIDER_CONFIG'] = (Join-Path $lumoswitchRoot 'aider.conf.yml')
  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\aider'
$lumoswitchLauncher = Join-Path $env:LOCALAPPDATA 'Lumoswitch\bin\lumoswitch-aider.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 @('AIDER_CONFIG')) {
    [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-aider.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['AIDER_CONFIG'] = (Join-Path $lumoswitchRoot 'aider.conf.yml')
foreach ($lumoswitchEntry in $lumoswitchEnvironment.GetEnumerator()) {
  [Environment]::SetEnvironmentVariable($lumoswitchEntry.Key, $lumoswitchEntry.Value, 'Process')
}
$lumoswitchExecutable = Get-Command 'aider.cmd' -CommandType Application -ErrorAction SilentlyContinue
if ($null -eq $lumoswitchExecutable) { $lumoswitchExecutable = Get-Command 'aider.exe' -CommandType Application -ErrorAction SilentlyContinue }
if ($null -eq $lumoswitchExecutable) { $lumoswitchExecutable = Get-Command 'aider' -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: aider'
  Write-Host 'Optional maintenance launcher:' $lumoswitchLauncher
  $lumoswitchExecutable = Get-Command 'aider.cmd' -CommandType Application -ErrorAction SilentlyContinue
  if ($null -eq $lumoswitchExecutable) { $lumoswitchExecutable = Get-Command 'aider.exe' -CommandType Application -ErrorAction SilentlyContinue }
  if ($null -eq $lumoswitchExecutable) { $lumoswitchExecutable = Get-Command 'aider' -CommandType Application -ErrorAction Stop }
  $lumoswitchArguments = @()
  & $lumoswitchExecutable.Path @lumoswitchArguments
  if ($null -ne $LASTEXITCODE -and $LASTEXITCODE -ne 0) { throw 'aider exited with code ' + $LASTEXITCODE }
}

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

清除接入

Windows PowerShell

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

& {
  $lumoswitchLauncher = Join-Path $env:LOCALAPPDATA 'Lumoswitch\bin\lumoswitch-aider.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

下面的命令会删除受管 Aider 配置、环境接入、可选维护启动器及其备份;它不会删除 Aider 的聊天记录、Git 记录或用户配置。

"$HOME/.local/bin/lumoswitch-aider" --lumoswitch-clean

临时命令的变量只属于 Aider 子进程,退出后无需清理。

浏览器与 IDE 使用

浏览器界面

Aider 的 --browser 是当前 Aider 进程的实验性本机 Web 界面,不是独立桌面客户端。仅本次使用时,在临时命令末尾加 --browser;永久接入后运行:

aider --browser

它沿用同一进程里的 Lumoswitch 地址、Key 和模型,所以没有单独的临时、永久或清除配置。关闭 Aider 进程即可结束浏览器会话;清理受管原生设置即可移除持久接入。

IDE

官方建议在 IDE 集成终端中运行 Aider,或使用 --watch-files 与编辑器协作。永久接入后可以直接运行 aider --watch-files。Aider 目前没有官方 IDE 插件,第三方插件的凭证保存与清除方式由插件作者决定,不在本页自动修改范围内。

参见 Aider 浏览器界面文件监听可选安装组件

验证与排查

  • 启动后先让 Aider 解释一个小文件,再测试修改,并在 Lumoswitch 请求日志中确认模型与 Access Key。
  • 返回 404:检查下游地址是否遗漏或重复 /v1
  • 模型未知:参数必须包含 Aider 使用的 openai/ 前缀,并使用配置 API 显示的下游模型名称。
  • 编辑能力异常:部分模型不适合仓库编辑,可先换成已确认具备代码能力的模型排查。

参考:Aider OpenAI-compatible APIs配置参考

维护者发布字段
  • 平台 ID:aider
  • 展示名称:Aider CLI
  • 下游协议:openai-compatible
  • commandTemplate:复制「仅本次启动」代码框的完整内容
  • 永久策略:native
  • persistentCommandTemplate:复制「永久使用」中的完整设置命令
  • futureCommandaider
  • 展示顺序:70
  • 最近核验:2026-08-27

On this page