feat(ai): add Pi Coding Agent provider
This commit is contained in:
1 parent
4a5eb3f04a
commit
de44fddf29
32 files changed
+1592
-31
No files matched your search
@@ -2195,7 +2195,7 @@ async function saveMaxAgentTurnsSetting() {
|
||||
const aiDeleteConfirmOpen = ref(false);
|
||||
const aiDeleteConfigId = ref<string | null>(null);
|
||||
|
||||
const CLI_AI_PROVIDERS = new Set<AiProvider>(["claude-code-cli", "codex-cli"]);
|
||||
const CLI_AI_PROVIDERS = new Set<AiProvider>(["claude-code-cli", "pi-agent-cli", "codex-cli"]);
|
||||
const aiProviderOptions = computed(() => Object.values(AI_PROVIDER_PRESETS).filter((provider) => !isWeb || !CLI_AI_PROVIDERS.has(provider.provider)));
|
||||
const selectedAiProviderPreset = computed(() => AI_PROVIDER_PRESETS[aiEditProvider.value]);
|
||||
|
||||
@@ -2215,6 +2215,8 @@ const aiEditCodexCliPath = ref("");
|
||||
const aiEditCodexCliEnvRows = ref<AiEnvRow[]>([]);
|
||||
const aiEditClaudeCodeCliPath = ref("");
|
||||
const aiEditClaudeCodeCliEnvRows = ref<AiEnvRow[]>([]);
|
||||
const aiEditPiAgentCliPath = ref("");
|
||||
const aiEditPiAgentCliEnvRows = ref<AiEnvRow[]>([]);
|
||||
|
||||
const aiAnthropicMessagesMode = computed(() => aiEditApiStyle.value === "anthropic-messages");
|
||||
|
||||
@@ -2243,21 +2245,40 @@ const aiTestErrorPresentation = computed(() => {
|
||||
const aiTestErrorDisplay = computed(() => [aiTestErrorPresentation.value.summary, aiTestErrorPresentation.value.detail].filter(Boolean).join(" "));
|
||||
const aiIsCodexCli = computed(() => aiEditProvider.value === "codex-cli");
|
||||
const aiIsClaudeCodeCli = computed(() => aiEditProvider.value === "claude-code-cli");
|
||||
const aiIsPiAgentCli = computed(() => aiEditProvider.value === "pi-agent-cli");
|
||||
const aiIsCliProvider = computed(() => CLI_AI_PROVIDERS.has(aiEditProvider.value));
|
||||
const aiCliProviderLabel = computed(() => selectedAiProviderPreset.value.label);
|
||||
const aiCliCommandName = computed(() => (aiIsClaudeCodeCli.value ? "claude" : "codex"));
|
||||
const aiCliLoginCommand = computed(() => (aiIsClaudeCodeCli.value ? "claude auth login" : "codex login"));
|
||||
const aiCliCommandName = computed(() => {
|
||||
if (aiIsClaudeCodeCli.value) return "claude";
|
||||
if (aiIsPiAgentCli.value) return "pi";
|
||||
return "codex";
|
||||
});
|
||||
const aiCliLoginCommand = computed(() => {
|
||||
if (aiIsClaudeCodeCli.value) return "claude auth login";
|
||||
if (aiIsPiAgentCli.value) return "pi";
|
||||
return "codex login";
|
||||
});
|
||||
const aiEditCliPath = computed({
|
||||
get: () => (aiIsClaudeCodeCli.value ? aiEditClaudeCodeCliPath.value : aiEditCodexCliPath.value),
|
||||
get: () => {
|
||||
if (aiIsClaudeCodeCli.value) return aiEditClaudeCodeCliPath.value;
|
||||
if (aiIsPiAgentCli.value) return aiEditPiAgentCliPath.value;
|
||||
return aiEditCodexCliPath.value;
|
||||
},
|
||||
set: (value: string) => {
|
||||
if (aiIsClaudeCodeCli.value) {
|
||||
aiEditClaudeCodeCliPath.value = value;
|
||||
} else if (aiIsPiAgentCli.value) {
|
||||
aiEditPiAgentCliPath.value = value;
|
||||
} else {
|
||||
aiEditCodexCliPath.value = value;
|
||||
}
|
||||
},
|
||||
});
|
||||
const aiEditCliEnvRows = computed(() => (aiIsClaudeCodeCli.value ? aiEditClaudeCodeCliEnvRows.value : aiEditCodexCliEnvRows.value));
|
||||
const aiEditCliEnvRows = computed(() => {
|
||||
if (aiIsClaudeCodeCli.value) return aiEditClaudeCodeCliEnvRows.value;
|
||||
if (aiIsPiAgentCli.value) return aiEditPiAgentCliEnvRows.value;
|
||||
return aiEditCodexCliEnvRows.value;
|
||||
});
|
||||
watch(aiIsCliProvider, (isCliProvider) => {
|
||||
if (isCliProvider) void ensureCliMcpStatus();
|
||||
});
|
||||
@@ -2325,7 +2346,10 @@ function cliEnvValidationError(): string {
|
||||
for (const row of aiEditCliEnvRows.value) {
|
||||
const key = row.key.trim();
|
||||
if (key && !/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) return t("ai.cliEnvInvalidName", { name: key });
|
||||
if (key.toUpperCase().startsWith("DBX_MCP_")) return t("ai.cliEnvReservedName", { name: key });
|
||||
const upper = key.toUpperCase();
|
||||
if (upper.startsWith("DBX_MCP_") || (aiIsPiAgentCli.value && upper.startsWith("DBX_PI_"))) {
|
||||
return t("ai.cliEnvReservedName", { name: key });
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
@@ -2337,6 +2361,8 @@ function addCliEnvRow() {
|
||||
function removeCliEnvRow(id: string) {
|
||||
if (aiIsClaudeCodeCli.value) {
|
||||
aiEditClaudeCodeCliEnvRows.value = aiEditClaudeCodeCliEnvRows.value.filter((row) => row.id !== id);
|
||||
} else if (aiIsPiAgentCli.value) {
|
||||
aiEditPiAgentCliEnvRows.value = aiEditPiAgentCliEnvRows.value.filter((row) => row.id !== id);
|
||||
} else {
|
||||
aiEditCodexCliEnvRows.value = aiEditCodexCliEnvRows.value.filter((row) => row.id !== id);
|
||||
}
|
||||
@@ -2363,6 +2389,8 @@ function currentAiEditConfig() {
|
||||
codexCliEnv: aiIsCodexCli.value ? cliEnvFromRows(aiEditCodexCliEnvRows.value) : {},
|
||||
claudeCodeCliPath: aiEditClaudeCodeCliPath.value.trim() || undefined,
|
||||
claudeCodeCliEnv: aiIsClaudeCodeCli.value ? cliEnvFromRows(aiEditClaudeCodeCliEnvRows.value) : {},
|
||||
piAgentCliPath: aiEditPiAgentCliPath.value.trim() || undefined,
|
||||
piAgentCliEnv: aiIsPiAgentCli.value ? cliEnvFromRows(aiEditPiAgentCliEnvRows.value) : {},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2430,6 +2458,8 @@ function aiEnterEditMode(configId?: string) {
|
||||
aiEditCodexCliEnvRows.value = aiEnvRowsFromConfig(config.codexCliEnv);
|
||||
aiEditClaudeCodeCliPath.value = config.claudeCodeCliPath ?? "";
|
||||
aiEditClaudeCodeCliEnvRows.value = aiEnvRowsFromConfig(config.claudeCodeCliEnv);
|
||||
aiEditPiAgentCliPath.value = config.piAgentCliPath ?? "";
|
||||
aiEditPiAgentCliEnvRows.value = aiEnvRowsFromConfig(config.piAgentCliEnv);
|
||||
}
|
||||
} else {
|
||||
aiEditConfigName.value = "";
|
||||
@@ -2449,6 +2479,8 @@ function aiEnterEditMode(configId?: string) {
|
||||
aiEditCodexCliEnvRows.value = [];
|
||||
aiEditClaudeCodeCliPath.value = "";
|
||||
aiEditClaudeCodeCliEnvRows.value = [];
|
||||
aiEditPiAgentCliPath.value = "";
|
||||
aiEditPiAgentCliEnvRows.value = [];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ function configSignature(config: AiConfigItem): string {
|
||||
contextWindow: config.contextWindow ?? null,
|
||||
codexCliPath: config.codexCliPath ?? null,
|
||||
claudeCodeCliPath: config.claudeCodeCliPath ?? null,
|
||||
piAgentCliPath: config.piAgentCliPath ?? null,
|
||||
connectionFingerprint: fingerprint(
|
||||
JSON.stringify({
|
||||
apiKey: config.apiKey,
|
||||
@@ -63,6 +64,7 @@ function configSignature(config: AiConfigItem): string {
|
||||
proxyUrl: config.proxyUrl ?? "",
|
||||
codexCliEnv: sortedRecord(config.codexCliEnv),
|
||||
claudeCodeCliEnv: sortedRecord(config.claudeCodeCliEnv),
|
||||
piAgentCliEnv: sortedRecord(config.piAgentCliEnv),
|
||||
}),
|
||||
),
|
||||
});
|
||||
|
||||
@@ -11,6 +11,16 @@ const taggedAiCliErrorKeys: Record<string, string> = {
|
||||
claudeCodeMcpStartupFailed: "ai.cliErrors.claudeCodeMcpStartupFailed",
|
||||
claudeCodeCommandLineTooLong: "ai.cliErrors.claudeCodeCommandLineTooLong",
|
||||
claudeCodeRunFailed: "ai.cliErrors.claudeCodeRunFailed",
|
||||
piAgentNotInstalled: "ai.cliErrors.piAgentNotInstalled",
|
||||
piAgentCliPathInvalid: "ai.cliErrors.piAgentCliPathInvalid",
|
||||
piAgentEnvInvalid: "ai.cliErrors.piAgentEnvInvalid",
|
||||
piAgentEnvReserved: "ai.cliErrors.piAgentEnvReserved",
|
||||
piAgentNotAuthenticated: "ai.cliErrors.piAgentNotAuthenticated",
|
||||
piAgentMcpStartupFailed: "ai.cliErrors.piAgentMcpStartupFailed",
|
||||
piAgentTimeout: "ai.cliErrors.piAgentTimeout",
|
||||
piAgentProtocolError: "ai.cliErrors.piAgentProtocolError",
|
||||
piAgentModelInvalid: "ai.cliErrors.piAgentModelInvalid",
|
||||
piAgentRunFailed: "ai.cliErrors.piAgentRunFailed",
|
||||
};
|
||||
|
||||
const patterns: [RegExp, string][] = [
|
||||
|
||||
@@ -1786,6 +1786,16 @@ export default {
|
||||
claudeCodeMcpStartupFailed: "Claude Code loaded the MCP configuration but could not start DBX MCP Server. Check Settings > MCP and the diagnostics below.",
|
||||
claudeCodeCommandLineTooLong: "Windows rejected the Claude Code command because it was too long. Update DBX and retry using the generated MCP configuration file.",
|
||||
claudeCodeRunFailed: "Claude Code CLI exited unexpectedly. Use the error code and diagnostics below to identify the failing executable or CLI output.",
|
||||
piAgentNotInstalled: "Pi Coding Agent was not found. Install Pi or set its executable path in Settings > AI.",
|
||||
piAgentCliPathInvalid: "The Pi Coding Agent path is invalid. Select only the Pi executable and configure environment variables separately.",
|
||||
piAgentEnvInvalid: "A Pi Coding Agent environment variable name is invalid. Use names such as HTTPS_PROXY.",
|
||||
piAgentEnvReserved: "A DBX-managed Pi or MCP environment variable was overridden. Remove DBX_PI_* and DBX_MCP_* variables from the provider configuration.",
|
||||
piAgentNotAuthenticated: "Pi Coding Agent has no authenticated model provider. Configure or sign in to a provider with Pi and try again.",
|
||||
piAgentMcpStartupFailed: "Pi could not start the scoped DBX MCP bridge. Check Settings > MCP and the diagnostics below.",
|
||||
piAgentTimeout: "Pi Coding Agent did not respond before the operation timed out.",
|
||||
piAgentProtocolError: "Pi Coding Agent returned an invalid RPC response. Check the Pi version and diagnostics below.",
|
||||
piAgentModelInvalid: "The selected Pi model identifier is invalid. Refresh the model list and select a provider/model entry.",
|
||||
piAgentRunFailed: "Pi Coding Agent exited unexpectedly. Use the error code and diagnostics below to identify the failing executable or CLI output.",
|
||||
},
|
||||
actions: {
|
||||
general: "General",
|
||||
|
||||
@@ -1634,6 +1634,16 @@ export default withEnglishFallback({
|
||||
claudeCodeMcpStartupFailed: "Claude Code cargó la configuración MCP, pero no pudo iniciar DBX MCP Server. Comprueba Configuración > MCP y los detalles siguientes.",
|
||||
claudeCodeCommandLineTooLong: "Windows rechazó el comando de Claude Code porque era demasiado largo. Actualiza DBX y vuelve a intentarlo con el archivo MCP generado.",
|
||||
claudeCodeRunFailed: "Claude Code CLI terminó de forma inesperada. Usa el código de error y los detalles siguientes para identificar el ejecutable o la salida que falló.",
|
||||
piAgentNotInstalled: "No se encontró Pi Coding Agent. Instala Pi o configura la ruta del ejecutable en Configuración > AI.",
|
||||
piAgentCliPathInvalid: "La ruta de Pi Coding Agent no es válida. Selecciona solo el ejecutable de Pi y configura las variables de entorno por separado.",
|
||||
piAgentEnvInvalid: "El nombre de una variable de entorno de Pi Coding Agent no es válido. Usa nombres como HTTPS_PROXY.",
|
||||
piAgentEnvReserved: "Se sobrescribió una variable de Pi o MCP administrada por DBX. Elimina DBX_PI_* y DBX_MCP_* de la configuración.",
|
||||
piAgentNotAuthenticated: "Pi Coding Agent no tiene un proveedor de modelos autenticado. Configura o inicia sesión en un proveedor con Pi.",
|
||||
piAgentMcpStartupFailed: "Pi no pudo iniciar el puente MCP de DBX. Comprueba Configuración > MCP y los detalles siguientes.",
|
||||
piAgentTimeout: "Pi Coding Agent no respondió antes de que la operación agotara el tiempo.",
|
||||
piAgentProtocolError: "Pi Coding Agent devolvió una respuesta RPC no válida. Comprueba la versión de Pi y los detalles siguientes.",
|
||||
piAgentModelInvalid: "El identificador del modelo Pi no es válido. Actualiza la lista y selecciona una entrada provider/model.",
|
||||
piAgentRunFailed: "Pi Coding Agent terminó de forma inesperada. Usa el código de error y los detalles siguientes para identificar el fallo.",
|
||||
},
|
||||
run: "Ejecutar",
|
||||
readingSchema: "Leyendo esquema",
|
||||
|
||||
@@ -1765,6 +1765,16 @@ export default withEnglishFallback({
|
||||
claudeCodeMcpStartupFailed: "Claude Code ha caricato la configurazione MCP ma non ha potuto avviare DBX MCP Server. Controlla Impostazioni > MCP e i dettagli seguenti.",
|
||||
claudeCodeCommandLineTooLong: "Windows ha rifiutato il comando Claude Code perché troppo lungo. Aggiorna DBX e riprova usando il file MCP generato.",
|
||||
claudeCodeRunFailed: "Claude Code CLI è terminato in modo imprevisto. Usa il codice errore e i dettagli seguenti per identificare l'eseguibile o l'output non riuscito.",
|
||||
piAgentNotInstalled: "Pi Coding Agent non è stato trovato. Installa Pi o imposta il percorso dell'eseguibile in Impostazioni > AI.",
|
||||
piAgentCliPathInvalid: "Il percorso di Pi Coding Agent non è valido. Seleziona solo l'eseguibile Pi e configura separatamente le variabili d'ambiente.",
|
||||
piAgentEnvInvalid: "Il nome di una variabile d'ambiente di Pi Coding Agent non è valido. Usa nomi come HTTPS_PROXY.",
|
||||
piAgentEnvReserved: "È stata sovrascritta una variabile Pi o MCP gestita da DBX. Rimuovi DBX_PI_* e DBX_MCP_* dalla configurazione.",
|
||||
piAgentNotAuthenticated: "Pi Coding Agent non dispone di un provider di modelli autenticato. Configura o accedi a un provider con Pi.",
|
||||
piAgentMcpStartupFailed: "Pi non ha potuto avviare il bridge MCP DBX. Controlla Impostazioni > MCP e i dettagli seguenti.",
|
||||
piAgentTimeout: "Pi Coding Agent non ha risposto prima del timeout dell'operazione.",
|
||||
piAgentProtocolError: "Pi Coding Agent ha restituito una risposta RPC non valida. Controlla la versione di Pi e i dettagli seguenti.",
|
||||
piAgentModelInvalid: "L'identificatore del modello Pi non è valido. Aggiorna l'elenco e seleziona una voce provider/model.",
|
||||
piAgentRunFailed: "Pi Coding Agent è terminato in modo imprevisto. Usa il codice errore e i dettagli seguenti per identificare il problema.",
|
||||
},
|
||||
actions: {
|
||||
general: "Generale",
|
||||
|
||||
@@ -1638,6 +1638,16 @@ export default withEnglishFallback({
|
||||
claudeCodeMcpStartupFailed: "Claude CodeはMCP設定を読み込みましたが、DBX MCP Serverを起動できません。設定 > MCPと以下の診断詳細を確認してください。",
|
||||
claudeCodeCommandLineTooLong: "Windowsが長すぎるClaude Codeコマンドを拒否しました。DBXを更新し、生成されたMCP設定ファイルで再試行してください。",
|
||||
claudeCodeRunFailed: "Claude Code CLIが予期せず終了しました。エラーコードと以下の診断詳細から、失敗した実行ファイルまたはCLI出力を確認してください。",
|
||||
piAgentNotInstalled: "Pi Coding Agentが見つかりません。Piをインストールするか、設定 > AIで実行ファイルのパスを指定してください。",
|
||||
piAgentCliPathInvalid: "Pi Coding Agentのパスが無効です。Piの実行ファイルのみを選択し、環境変数は別に設定してください。",
|
||||
piAgentEnvInvalid: "Pi Coding Agentの環境変数名が無効です。HTTPS_PROXYなどの有効な名前を使用してください。",
|
||||
piAgentEnvReserved: "DBXが管理するPiまたはMCP環境変数が上書きされています。DBX_PI_*とDBX_MCP_*を削除してください。",
|
||||
piAgentNotAuthenticated: "Pi Coding Agentに認証済みのモデルプロバイダーがありません。Piでプロバイダーを設定またはログインしてください。",
|
||||
piAgentMcpStartupFailed: "PiはDBX MCPブリッジを起動できませんでした。設定 > MCPと以下の診断詳細を確認してください。",
|
||||
piAgentTimeout: "Pi Coding Agentは操作のタイムアウトまでに応答しませんでした。",
|
||||
piAgentProtocolError: "Pi Coding Agentが無効なRPC応答を返しました。Piのバージョンと以下の診断詳細を確認してください。",
|
||||
piAgentModelInvalid: "選択したPiモデルIDが無効です。モデル一覧を更新してprovider/model項目を選択してください。",
|
||||
piAgentRunFailed: "Pi Coding Agentが予期せず終了しました。エラーコードと以下の診断詳細から問題を確認してください。",
|
||||
},
|
||||
run: "実行",
|
||||
readingSchema: "スキーマを読み取り中",
|
||||
|
||||
@@ -1636,6 +1636,16 @@ export default withEnglishFallback({
|
||||
claudeCodeMcpStartupFailed: "O Claude Code carregou a configuração MCP, mas não conseguiu iniciar o DBX MCP Server. Verifique Configurações > MCP e os detalhes abaixo.",
|
||||
claudeCodeCommandLineTooLong: "O Windows rejeitou o comando do Claude Code porque era muito longo. Atualize o DBX e tente novamente com o arquivo MCP gerado.",
|
||||
claudeCodeRunFailed: "Claude Code CLI foi encerrado inesperadamente. Use o código do erro e os detalhes abaixo para identificar o executável ou a saída com falha.",
|
||||
piAgentNotInstalled: "Pi Coding Agent não foi encontrado. Instale o Pi ou defina o caminho do executável em Configurações > AI.",
|
||||
piAgentCliPathInvalid: "O caminho do Pi Coding Agent é inválido. Selecione apenas o executável do Pi e configure as variáveis de ambiente separadamente.",
|
||||
piAgentEnvInvalid: "O nome de uma variável de ambiente do Pi Coding Agent é inválido. Use nomes como HTTPS_PROXY.",
|
||||
piAgentEnvReserved: "Uma variável Pi ou MCP gerenciada pelo DBX foi sobrescrita. Remova DBX_PI_* e DBX_MCP_* da configuração.",
|
||||
piAgentNotAuthenticated: "O Pi Coding Agent não possui um provedor de modelos autenticado. Configure ou entre em um provedor com o Pi.",
|
||||
piAgentMcpStartupFailed: "O Pi não conseguiu iniciar a ponte MCP do DBX. Verifique Configurações > MCP e os detalhes abaixo.",
|
||||
piAgentTimeout: "O Pi Coding Agent não respondeu antes do tempo limite da operação.",
|
||||
piAgentProtocolError: "O Pi Coding Agent retornou uma resposta RPC inválida. Verifique a versão do Pi e os detalhes abaixo.",
|
||||
piAgentModelInvalid: "O identificador do modelo Pi é inválido. Atualize a lista e selecione uma entrada provider/model.",
|
||||
piAgentRunFailed: "O Pi Coding Agent foi encerrado inesperadamente. Use o código do erro e os detalhes abaixo para identificar a falha.",
|
||||
},
|
||||
run: "Executar",
|
||||
readingSchema: "Lendo schema",
|
||||
|
||||
@@ -1787,6 +1787,16 @@ export default withEnglishFallback({
|
||||
claudeCodeMcpStartupFailed: "Claude Code 已加载 MCP 配置,但无法启动 DBX MCP Server。请检查 设置 > MCP 和下方诊断详情。",
|
||||
claudeCodeCommandLineTooLong: "Windows 拒绝了过长的 Claude Code 命令。请更新 DBX,并使用生成的 MCP 配置文件重试。",
|
||||
claudeCodeRunFailed: "Claude Code CLI 异常退出。请根据错误代码和下方诊断详情确认失败的可执行文件或 CLI 输出。",
|
||||
piAgentNotInstalled: "未找到 Pi Coding Agent。请安装 Pi,或在 设置 > AI 中填写其可执行文件路径。",
|
||||
piAgentCliPathInvalid: "Pi Coding Agent 路径无效。请只选择 Pi 可执行文件,环境变量需单独配置。",
|
||||
piAgentEnvInvalid: "Pi Coding Agent 环境变量名称无效。请使用 HTTPS_PROXY 这类合法名称。",
|
||||
piAgentEnvReserved: "配置覆盖了由 DBX 管理的 Pi 或 MCP 环境变量。请移除 DBX_PI_* 和 DBX_MCP_* 变量。",
|
||||
piAgentNotAuthenticated: "Pi Coding Agent 没有可用的已认证模型供应商。请先在 Pi 中配置或登录供应商。",
|
||||
piAgentMcpStartupFailed: "Pi 无法启动 DBX 的作用域 MCP 桥接。请检查 设置 > MCP 和下方诊断详情。",
|
||||
piAgentTimeout: "Pi Coding Agent 未在操作超时前响应。",
|
||||
piAgentProtocolError: "Pi Coding Agent 返回了无效的 RPC 响应。请检查 Pi 版本和下方诊断详情。",
|
||||
piAgentModelInvalid: "所选 Pi 模型标识无效。请刷新模型列表并选择 provider/model 条目。",
|
||||
piAgentRunFailed: "Pi Coding Agent 异常退出。请根据错误代码和下方诊断详情确认失败的可执行文件或 CLI 输出。",
|
||||
},
|
||||
actions: {
|
||||
general: "通用问答",
|
||||
|
||||
@@ -1766,6 +1766,16 @@ export default withEnglishFallback({
|
||||
claudeCodeMcpStartupFailed: "Claude Code 已載入 MCP 設定,但無法啟動 DBX MCP Server。請檢查 設定 > MCP 和下方診斷詳情。",
|
||||
claudeCodeCommandLineTooLong: "Windows 拒絕了過長的 Claude Code 命令。請更新 DBX,並使用產生的 MCP 設定檔重試。",
|
||||
claudeCodeRunFailed: "Claude Code CLI 異常結束。請依據錯誤代碼和下方診斷詳情確認失敗的可執行檔或 CLI 輸出。",
|
||||
piAgentNotInstalled: "找不到 Pi Coding Agent。請安裝 Pi,或在 設定 > AI 中填寫其可執行檔路徑。",
|
||||
piAgentCliPathInvalid: "Pi Coding Agent 路徑無效。請只選擇 Pi 可執行檔,環境變數需另外設定。",
|
||||
piAgentEnvInvalid: "Pi Coding Agent 環境變數名稱無效。請使用 HTTPS_PROXY 這類合法名稱。",
|
||||
piAgentEnvReserved: "設定覆寫了由 DBX 管理的 Pi 或 MCP 環境變數。請移除 DBX_PI_* 與 DBX_MCP_* 變數。",
|
||||
piAgentNotAuthenticated: "Pi Coding Agent 沒有可用的已驗證模型供應商。請先在 Pi 中設定或登入供應商。",
|
||||
piAgentMcpStartupFailed: "Pi 無法啟動 DBX 的作用域 MCP 橋接。請檢查 設定 > MCP 和下方診斷詳情。",
|
||||
piAgentTimeout: "Pi Coding Agent 未在操作逾時前回應。",
|
||||
piAgentProtocolError: "Pi Coding Agent 傳回無效的 RPC 回應。請檢查 Pi 版本和下方診斷詳情。",
|
||||
piAgentModelInvalid: "所選 Pi 模型識別碼無效。請重新整理模型清單並選擇 provider/model 項目。",
|
||||
piAgentRunFailed: "Pi Coding Agent 異常結束。請依據錯誤代碼和下方診斷詳情確認失敗的可執行檔或 CLI 輸出。",
|
||||
},
|
||||
actions: {
|
||||
general: "通用問答",
|
||||
|
||||
@@ -24,7 +24,7 @@ describe("isAiConfigModelCandidate", () => {
|
||||
expect(isAiConfigModelCandidate(config({ apiKey: "" }), true)).toBe(false);
|
||||
});
|
||||
|
||||
it.each(["codex-cli", "claude-code-cli"] as const)("keeps %s configs eligible without endpoint, API key, or model metadata", (provider) => {
|
||||
it.each(["codex-cli", "claude-code-cli", "pi-agent-cli"] as const)("keeps %s configs eligible without endpoint, API key, or model metadata", (provider) => {
|
||||
expect(
|
||||
isAiConfigModelCandidate(
|
||||
config({
|
||||
|
||||
@@ -14,10 +14,11 @@ describe("orderAiConfigsForDisplay", () => {
|
||||
{ id: "claude", provider: "claude" },
|
||||
{ id: "openai", provider: "openai" },
|
||||
{ id: "codex", provider: "codex-cli" },
|
||||
{ id: "pi", provider: "pi-agent-cli" },
|
||||
{ id: "custom", provider: "custom" },
|
||||
];
|
||||
|
||||
expect(orderAiConfigsForDisplay(configs).map((config) => config.id)).toEqual(["claude", "openai", "claude-code-1", "codex", "custom"]);
|
||||
expect(orderAiConfigsForDisplay(configs).map((config) => config.id)).toEqual(["claude", "openai", "claude-code-1", "codex", "pi", "custom"]);
|
||||
});
|
||||
|
||||
it("preserves creation order for configs from the same provider", () => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { AiConfig } from "@/types/ai";
|
||||
|
||||
const CLI_PROVIDERS = new Set<AiConfig["provider"]>(["codex-cli", "claude-code-cli"]);
|
||||
const CLI_PROVIDERS = new Set<AiConfig["provider"]>(["codex-cli", "claude-code-cli", "pi-agent-cli"]);
|
||||
|
||||
export function isAiConfigModelCandidate(config: AiConfig, requiresApiKey: boolean): boolean {
|
||||
// CLI providers resolve their model and credentials externally, so keep the existing eligibility bypass.
|
||||
|
||||
@@ -210,6 +210,16 @@ export const AI_PROVIDER_PRESETS: Record<AiProvider, AiProviderPreset> = {
|
||||
authMethod: "bearer",
|
||||
requiresApiKey: false,
|
||||
},
|
||||
"pi-agent-cli": {
|
||||
label: "Pi Coding Agent",
|
||||
iconSlug: "pi",
|
||||
provider: "pi-agent-cli",
|
||||
endpoint: "",
|
||||
model: "default",
|
||||
apiStyle: "completions",
|
||||
authMethod: "bearer",
|
||||
requiresApiKey: false,
|
||||
},
|
||||
custom: {
|
||||
label: "Custom",
|
||||
provider: "custom",
|
||||
@@ -264,6 +274,8 @@ export function normalizeAiConfig(config: Partial<AiConfig> | null | undefined):
|
||||
codexCliEnv: normalizeAiEnv(config?.codexCliEnv),
|
||||
claudeCodeCliPath: config?.claudeCodeCliPath?.trim() || undefined,
|
||||
claudeCodeCliEnv: normalizeAiEnv(config?.claudeCodeCliEnv),
|
||||
piAgentCliPath: config?.piAgentCliPath?.trim() || undefined,
|
||||
piAgentCliEnv: normalizeAiEnv(config?.piAgentCliEnv),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1257,7 +1269,7 @@ export const useSettingsStore = defineStore("settings", () => {
|
||||
const config = aiConfigs.value.find((c) => c.id === activeModel.value!.configId);
|
||||
if (!config) return false;
|
||||
const preset = AI_PROVIDER_PRESETS[config.provider];
|
||||
if (config.provider === "codex-cli" || config.provider === "claude-code-cli") return true;
|
||||
if (config.provider === "codex-cli" || config.provider === "claude-code-cli" || config.provider === "pi-agent-cli") return true;
|
||||
return !!config.endpoint && !!activeModel.value!.modelId && (!preset.requiresApiKey || !!config.apiKey);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export type AiProvider = "claude" | "openai" | "gemini" | "deepseek" | "qwen" | "ollama" | "openai-compatible" | "claude-code-cli" | "codex-cli" | "custom";
|
||||
export type AiProvider = "claude" | "openai" | "gemini" | "deepseek" | "qwen" | "ollama" | "openai-compatible" | "claude-code-cli" | "pi-agent-cli" | "codex-cli" | "custom";
|
||||
export type AiApiStyle = "completions" | "responses" | "anthropic-messages";
|
||||
export type AiAuthMethod = "api-key" | "bearer";
|
||||
export type AiEffortLevel = "low" | "medium" | "high" | "xhigh" | "max";
|
||||
@@ -44,6 +44,8 @@ export interface AiConfig {
|
||||
codexCliEnv?: Record<string, string>;
|
||||
claudeCodeCliPath?: string | null;
|
||||
claudeCodeCliEnv?: Record<string, string>;
|
||||
piAgentCliPath?: string | null;
|
||||
piAgentCliEnv?: Record<string, string>;
|
||||
runtimeEffort?: AiEffortSelection | null;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user