fix(wizard): prepare default Local Agent and refine Runner setup

This commit is contained in:
RockChinQ
2026-09-18 19:27:56 +08:00
parent bece2aa554
commit da4b0d6ca2
18 changed files with 1424 additions and 359 deletions
@@ -8,6 +8,7 @@ import {
type PluginV4,
type RunnerUsage,
} from '@/app/infra/entities/plugin';
import type { AsyncTask } from '@/app/infra/entities/api';
import type { I18nObject } from '@/app/infra/entities/common';
export const RUNNER_COMPONENT_FILTER = 'Runner';
@@ -54,6 +55,7 @@ export interface PendingRunnerInstall {
interface InstallRunnerOptions {
scope: string;
onTaskCreated?: (taskId: number) => void;
onProgress?: (task: AsyncTask) => void;
}
function wait(ms: number) {
@@ -250,7 +252,7 @@ export async function installMarketplaceRunner(
};
writePendingRunnerInstall(pending);
options.onTaskCreated?.(taskId);
return finishRunnerInstall(pending);
return finishRunnerInstall(pending, options.onProgress);
}
function extractPluginLabel(plugin: PluginV4) {
@@ -267,6 +269,7 @@ function extractPluginLabel(plugin: PluginV4) {
async function finishRunnerInstall(
pending: PendingRunnerInstall,
onProgress?: (task: AsyncTask) => void,
): Promise<InstalledRunner> {
// A refreshed page receives a fresh observation window. The backend task is
// authoritative; `startedAt` is display metadata, not a reason to abandon a
@@ -275,6 +278,7 @@ async function finishRunnerInstall(
let installCompleted = false;
while (true) {
const task = await httpClient.getAsyncTask(pending.taskId);
onProgress?.(task);
if (task.runtime.done) {
if (task.runtime.exception) {
clearPendingRunnerInstall(pending.scope, pending.taskId);
@@ -323,8 +327,9 @@ async function finishRunnerInstall(
export async function resumePendingRunnerInstall(
scope: string,
onProgress?: (task: AsyncTask) => void,
): Promise<InstalledRunner | null> {
const pending = readPendingRunnerInstall(scope);
if (!pending) return null;
return finishRunnerInstall(pending);
return finishRunnerInstall(pending, onProgress);
}
@@ -185,7 +185,9 @@ function isPluginInstallTask(name: string): boolean {
/**
* Convert a backend AsyncTask to our PluginInstallTask.
*/
function asyncTaskToPluginInstallTask(task: AsyncTask): PluginInstallTask {
export function asyncTaskToPluginInstallTask(
task: AsyncTask,
): PluginInstallTask {
const source = extractSourceFromName(task.name);
const md = (task.task_context?.metadata ?? {}) as Record<string, unknown>;
const action = task.task_context?.current_action || '';
File diff suppressed because it is too large Load Diff
+16 -10
View File
@@ -105,13 +105,16 @@ export function isRequiredRunnerConfigComplete(
});
}
export const LOCAL_AGENT_RUNNER_ID = 'plugin:langbot-team/LocalAgent/default';
export function configureLocalAgentPrimaryModel(
config: Record<string, unknown>,
modelUuid: string,
): Record<string, unknown> {
const aiConfig = (config.ai ?? {}) as Record<string, unknown>;
const runnerConfig = (aiConfig.runner ?? {}) as Record<string, unknown>;
const localAgentConfig = (aiConfig['local-agent'] ?? {}) as Record<
const configs = (aiConfig.runner_config ?? {}) as Record<string, unknown>;
const localAgentConfig = (configs[LOCAL_AGENT_RUNNER_ID] ?? {}) as Record<
string,
unknown
>;
@@ -121,15 +124,18 @@ export function configureLocalAgentPrimaryModel(
...config,
ai: {
...aiConfig,
runner: { ...runnerConfig, runner: 'local-agent' },
'local-agent': {
...localAgentConfig,
model: {
...modelConfig,
primary: modelUuid,
fallbacks: Array.isArray(modelConfig.fallbacks)
? modelConfig.fallbacks
: [],
runner: { ...runnerConfig, id: LOCAL_AGENT_RUNNER_ID },
runner_config: {
...configs,
[LOCAL_AGENT_RUNNER_ID]: {
...localAgentConfig,
model: {
...modelConfig,
primary: modelUuid,
fallbacks: Array.isArray(modelConfig.fallbacks)
? modelConfig.fallbacks
: [],
},
},
},
},
+10 -5
View File
@@ -2580,14 +2580,18 @@ const enUS = {
'Monitor bot activity to verify the platform connection is working.',
},
aiEngine: {
defaultModelUnavailable:
'No default chat model is available. Please retry.',
defaultRunnerUnavailable: 'Local Agent is not ready. Please retry.',
preparingDefault: 'Preparing default AI…',
title: 'Select an AI Engine',
description:
"Choose the AI engine that will power your bot's intelligence.",
optionalDescription:
'This step is optional. Choose how you want to continue with the current agent.',
'The default AI is ready. Keep it or choose another way to connect.',
externalTitle: 'Connect an External Agent',
externalDescription:
'Connect Dify, n8n, Coze, or another platform and replace the bot pipeline.',
'Connect Dify, n8n, Coze, or another external Agent through a Runner plugin.',
ownModelTitle: 'Use My Own Model',
ownModelDescription:
'Add a provider, then scan or manually enter a model to finish setup.',
@@ -2600,7 +2604,7 @@ const enUS = {
selectModelTitle: 'Choose a Model',
selectScannedModelTitle: 'Choose a Model',
selectScannedModelDescription:
'The selected model will be the primary model of a new pipeline, and the bot will switch to it.',
'The selected model will replace the primary model in this bot’s pipeline.',
scanModelMode: 'Scan Models',
manualModelMode: 'Add Manually',
scanningModels: 'Scanning available models…',
@@ -2619,12 +2623,13 @@ const enUS = {
manualModelOptions: 'Optional Model Capabilities',
editProvider: 'Edit provider',
rescanModels: 'Scan models again',
moreFeaturesTitle: 'Add More Agent Features',
moreFeaturesTitle: 'Use the default setup',
moreFeaturesDescription:
'Open the workbench to add tools, knowledge bases, and other capabilities to the Agent that was just generated automatically.',
'Keep Local Agent and the recommended model. You can add tools and knowledge bases later.',
runnerDescription:
'Select a runner for the external agent and configure its connection.',
backToChoices: 'Back to options',
backToList: 'Back to list',
createExternal: 'Create and Bind',
finishWithModel: 'Use Selected Model & Finish',
openWorkbench: 'Open Workbench',
+11 -5
View File
@@ -2012,14 +2012,19 @@ const esES = {
'Monitorea la actividad del Bot para verificar que la conexión con la plataforma funcione.',
},
aiEngine: {
defaultModelUnavailable:
'No hay un modelo predeterminado disponible. Inténtalo de nuevo.',
defaultRunnerUnavailable:
'Local Agent aún no está listo. Inténtalo de nuevo.',
preparingDefault: 'Preparando la IA predeterminada…',
title: 'Configura el motor de IA',
description:
'Elige el motor de IA que impulsará la inteligencia de tu Bot.',
optionalDescription:
'Este paso es opcional. Elige cómo quieres continuar con el Agent actual.',
'La IA ya está configurada. Puedes usarla o cambiar la conexión.',
externalTitle: 'Conectar un Agent de una plataforma externa',
externalDescription:
'Conecta Dify, n8n, Coze u otra plataforma y sustituye el Pipeline del Bot.',
'Conecta Dify, n8n, Coze u otro Agent externo mediante un plugin Runner.',
ownModelTitle: 'Usar mi propio modelo',
ownModelDescription:
'Añade un proveedor y luego escanea o introduce manualmente un modelo para completar la configuración.',
@@ -2032,7 +2037,7 @@ const esES = {
selectModelTitle: 'Elige un modelo',
selectScannedModelTitle: 'Elige un modelo',
selectScannedModelDescription:
'El modelo seleccionado será el modelo principal de un nuevo Pipeline y el Bot cambiará a él.',
'El modelo seleccionado sustituirá al modelo principal del pipeline de este bot.',
scanModelMode: 'Detectar modelos',
manualModelMode: 'Añadir manualmente',
scanningModels: 'Detectando modelos disponibles…',
@@ -2051,12 +2056,13 @@ const esES = {
manualModelOptions: 'Capacidades opcionales del modelo',
editProvider: 'Editar proveedor',
rescanModels: 'Volver a detectar modelos',
moreFeaturesTitle: 'Añadir más funciones al Agent',
moreFeaturesTitle: 'Usar la configuración predeterminada',
moreFeaturesDescription:
'Abre el área de trabajo para añadir herramientas, bases de conocimiento y otras capacidades al Agent que se acaba de generar automáticamente.',
'Usa Local Agent y el modelo recomendado. Podrás añadir herramientas y bases de conocimiento después.',
runnerDescription:
'Selecciona un Runner para el Agent externo y configura su conexión.',
backToChoices: 'Volver a las opciones',
backToList: 'Volver a la lista',
createExternal: 'Crear y vincular',
finishWithModel: 'Usar el modelo seleccionado y finalizar',
openWorkbench: 'Abrir área de trabajo',
+11 -5
View File
@@ -2361,14 +2361,19 @@ const jaJP = {
'ボットの活動を監視して、プラットフォーム接続が正常に動作していることを確認します。',
},
aiEngine: {
defaultModelUnavailable:
'既定の会話モデルがありません。再試行してください。',
defaultRunnerUnavailable:
'ローカル Agent が準備できていません。再試行してください。',
preparingDefault: '既定の AI を準備中…',
title: 'AIエンジンを選択',
description:
'ボットのインテリジェンスを駆動するAIエンジンを選択してください。',
optionalDescription:
'このステップは任意です。現在の Agent をどのように設定するか選択してください。',
'既定の AI は設定済みです。そのまま使うか、接続方法を変更できます。',
externalTitle: '外部プラットフォームの Agent を接続',
externalDescription:
'Dify、n8n、Coze などを接続し、ボットのパイプラインを置き換えます。',
'ランナープラグインで Dify、n8n、Coze などの外部 Agent に接続します。',
ownModelTitle: '自分のモデルを使用',
ownModelDescription:
'プロバイダーを追加し、モデルをスキャンまたは手動入力して設定を完了します。',
@@ -2381,7 +2386,7 @@ const jaJP = {
selectModelTitle: 'モデルを選択',
selectScannedModelTitle: 'モデルを選択',
selectScannedModelDescription:
'選択したモデルを新しいパイプラインのメインモデルに設定し、ボットをそのパイプラインへ切り替えます。',
'選択したモデルを現在のパイプラインのメインモデルに設定します。',
scanModelMode: 'モデルをスキャン',
manualModelMode: '手動で追加',
scanningModels: '利用可能なモデルをスキャン中…',
@@ -2400,11 +2405,12 @@ const jaJP = {
manualModelOptions: '任意のモデル機能',
editProvider: 'プロバイダーを編集',
rescanModels: 'モデルを再スキャン',
moreFeaturesTitle: 'Agent に機能を追加',
moreFeaturesTitle: '既定の設定を使う',
moreFeaturesDescription:
'ワークベンチを開き、自動生成されたばかりの Agent にツール、ナレッジベースなどの機能を追加します。',
'ローカル Agent と推奨モデルを使います。ツールやナレッジベースは後から追加できます。',
runnerDescription: '外部 Agent の Runner を選択し、接続を設定します。',
backToChoices: '選択肢に戻る',
backToList: '一覧に戻る',
createExternal: '作成して関連付ける',
finishWithModel: '選択したモデルを使用して完了',
openWorkbench: 'ワークベンチを開く',
+10 -5
View File
@@ -1977,14 +1977,18 @@ const ruRU = {
'Отслеживайте активность бота для проверки подключения к платформе.',
},
aiEngine: {
defaultModelUnavailable:
'Модель по умолчанию недоступна. Повторите попытку.',
defaultRunnerUnavailable: 'Local Agent ещё не готов. Повторите попытку.',
preparingDefault: 'Подготовка ИИ по умолчанию…',
title: 'Настройте ИИ-движок',
description:
'Выберите ИИ-движок, который будет управлять интеллектом вашего бота.',
optionalDescription:
'Этот шаг необязателен. Выберите, как продолжить настройку текущего Agent.',
'ИИ уже настроен. Используйте его или измените способ подключения.',
externalTitle: 'Подключить Agent внешней платформы',
externalDescription:
'Подключите Dify, n8n, Coze или другую платформу и замените Pipeline бота.',
'Подключите Dify, n8n, Coze или другой внешний Agent через плагин Runner.',
ownModelTitle: 'Использовать собственную модель',
ownModelDescription:
'Добавьте провайдера, затем найдите модель автоматически или укажите её вручную, чтобы завершить настройку.',
@@ -1997,7 +2001,7 @@ const ruRU = {
selectModelTitle: 'Выберите модель',
selectScannedModelTitle: 'Выберите модель',
selectScannedModelDescription:
'Выбранная модель станет основной моделью нового Pipeline, и бот переключится на неё.',
'Выбранная модель заменит основную модель в пайплайне этого бота.',
scanModelMode: 'Найти модели',
manualModelMode: 'Добавить вручную',
scanningModels: 'Поиск доступных моделей…',
@@ -2016,12 +2020,13 @@ const ruRU = {
manualModelOptions: 'Дополнительные возможности модели',
editProvider: 'Изменить провайдера',
rescanModels: 'Повторить поиск моделей',
moreFeaturesTitle: 'Добавить возможности Agent',
moreFeaturesTitle: 'Использовать настройки по умолчанию',
moreFeaturesDescription:
'Откройте рабочую панель, чтобы добавить инструменты, базы знаний и другие возможности только что автоматически созданному Agent.',
'Продолжить с Local Agent и рекомендованной моделью. Инструменты и базы знаний можно добавить позже.',
runnerDescription:
'Выберите Runner для внешнего Agent и настройте подключение.',
backToChoices: 'Вернуться к вариантам',
backToList: 'Вернуться к списку',
createExternal: 'Создать и привязать',
finishWithModel: 'Использовать выбранную модель и завершить',
openWorkbench: 'Открыть рабочую панель',
+10 -5
View File
@@ -1938,13 +1938,17 @@ const thTH = {
'ตรวจสอบกิจกรรม Bot เพื่อยืนยันว่าการเชื่อมต่อแพลตฟอร์มทำงานอยู่',
},
aiEngine: {
defaultModelUnavailable:
'ไม่มีโมเดลเริ่มต้นที่พร้อมใช้งาน โปรดลองอีกครั้ง',
defaultRunnerUnavailable: 'Local Agent ยังไม่พร้อม โปรดลองอีกครั้ง',
preparingDefault: 'กำลังเตรียม AI เริ่มต้น…',
title: 'กำหนดค่าเครื่องมือ AI',
description: 'เลือกเครื่องมือ AI ที่จะขับเคลื่อนความฉลาดของ Bot',
optionalDescription:
'ขั้นตอนนี้ไม่บังคับ เลือกวิธีที่คุณต้องการดำเนินการต่อกับ Agent ปัจจุบัน',
'AI เริ่มต้นพร้อมแล้ว ใช้งานได้ทันทีหรือเลือกวิธีเชื่อมต่ออื่น',
externalTitle: 'เชื่อมต่อ Agent จากแพลตฟอร์มภายนอก',
externalDescription:
'เชื่อมต่อ Dify, n8n, Coze หรือแพลตฟอร์มอื่น และแทนที่ Pipeline ของ Bot',
'เชื่อมต่อ Dify, n8n, Coze หรือ Agent ภายนอกผ่านปลั๊กอิน Runner',
ownModelTitle: 'ใช้โมเดลของฉันเอง',
ownModelDescription:
'เพิ่มผู้ให้บริการ แล้วสแกนหรือกรอกโมเดลด้วยตนเองเพื่อเสร็จสิ้นการตั้งค่า',
@@ -1957,7 +1961,7 @@ const thTH = {
selectModelTitle: 'เลือกโมเดล',
selectScannedModelTitle: 'เลือกโมเดล',
selectScannedModelDescription:
'โมเดลที่เลือกจะเป็นโมเดลหลักของ Pipeline ใหม่ และ Bot จะเปลี่ยนไปใช้โมเดลนี้',
'โมเดลที่เลือกจะแทนที่โมเดลหลักในไปป์ไลน์ของบอทนี้',
scanModelMode: 'สแกนโมเดล',
manualModelMode: 'เพิ่มด้วยตนเอง',
scanningModels: 'กำลังสแกนโมเดลที่พร้อมใช้งาน…',
@@ -1974,12 +1978,13 @@ const thTH = {
manualModelOptions: 'ความสามารถเพิ่มเติมของโมเดล',
editProvider: 'แก้ไขผู้ให้บริการ',
rescanModels: 'สแกนโมเดลอีกครั้ง',
moreFeaturesTitle: 'เพิ่มความสามารถให้ Agent',
moreFeaturesTitle: 'ใช้การตั้งค่าเริ่มต้น',
moreFeaturesDescription:
'เปิดหน้าทำงานเพื่อเพิ่มเครื่องมือ ฐานความรู้ และความสามารถอื่น ๆ ให้ Agent ที่เพิ่งสร้างขึ้นโดยอัตโนมัติ',
'ใช้ Local Agent และโมเดลที่แนะนำต่อไป เพิ่มเครื่องมือและฐานความรู้ได้ภายหลัง',
runnerDescription:
'เลือก Runner สำหรับ Agent ภายนอกและกำหนดค่าการเชื่อมต่อ',
backToChoices: 'กลับไปยังตัวเลือก',
backToList: 'กลับไปยังรายการ',
createExternal: 'สร้างและผูก',
finishWithModel: 'ใช้โมเดลที่เลือกและเสร็จสิ้น',
openWorkbench: 'เปิดหน้าทำงาน',
+9 -5
View File
@@ -1966,13 +1966,16 @@ const viVN = {
'Giám sát hoạt động Bot để xác minh kết nối nền tảng đang hoạt động.',
},
aiEngine: {
defaultModelUnavailable: 'Chưa có mô hình mặc định. Vui lòng thử lại.',
defaultRunnerUnavailable: 'Local Agent chưa sẵn sàng. Vui lòng thử lại.',
preparingDefault: 'Đang chuẩn bị AI mặc định…',
title: 'Cấu hình công cụ AI',
description: 'Chọn công cụ AI sẽ cung cấp trí tuệ cho Bot của bạn.',
optionalDescription:
'Bước này không bắt buộc. Hãy chọn cách bạn muốn tiếp tục với Agent hiện tại.',
'AI mặc định đã sẵn sàng. Bạn có thể dùng ngay hoặc đổi cách kết nối.',
externalTitle: 'Kết nối Agent từ nền tảng bên ngoài',
externalDescription:
'Kết nối Dify, n8n, Coze hoặc nền tảng khác và thay thế Pipeline của Bot.',
'Kết nối Dify, n8n, Coze hoặc Agent bên ngoài qua plugin Runner.',
ownModelTitle: 'Sử dụng mô hình của riêng tôi',
ownModelDescription:
'Thêm nhà cung cấp, sau đó quét hoặc nhập mô hình thủ công để hoàn tất thiết lập.',
@@ -1985,7 +1988,7 @@ const viVN = {
selectModelTitle: 'Chọn mô hình',
selectScannedModelTitle: 'Chọn mô hình',
selectScannedModelDescription:
'Mô hình đã chọn sẽ là mô hình chính của Pipeline mới và Bot sẽ chuyển sang sử dụng mô hình đó.',
'Mô hình đã chọn sẽ thay thế mô hình chính trong pipeline của bot này.',
scanModelMode: 'Quét mô hình',
manualModelMode: 'Thêm thủ công',
scanningModels: 'Đang quét các mô hình khả dụng…',
@@ -2004,11 +2007,12 @@ const viVN = {
manualModelOptions: 'Khả năng mô hình tùy chọn',
editProvider: 'Chỉnh sửa nhà cung cấp',
rescanModels: 'Quét lại mô hình',
moreFeaturesTitle: 'Thêm khả năng cho Agent',
moreFeaturesTitle: 'Dùng cấu hình mặc định',
moreFeaturesDescription:
'Mở bàn làm việc để thêm công cụ, cơ sở tri thức và các khả năng khác cho Agent vừa được tạo tự động.',
'Tiếp tục dùng Local Agent và mô hình đề xuất. Có thể thêm công cụ và cơ sở tri thức sau.',
runnerDescription: 'Chọn Runner cho Agent bên ngoài và cấu hình kết nối.',
backToChoices: 'Quay lại các tùy chọn',
backToList: 'Quay lại danh sách',
createExternal: 'Tạo và liên kết',
finishWithModel: 'Sử dụng mô hình đã chọn và hoàn tất',
openWorkbench: 'Mở bàn làm việc',
+10 -5
View File
@@ -2446,12 +2446,16 @@ const zhHans = {
logsDescription: '监控机器人活动,确认平台连接是否正常工作。',
},
aiEngine: {
defaultModelUnavailable: '暂无可用的默认对话模型,请重试。',
defaultRunnerUnavailable: '本地 Agent 尚未就绪,请重试。',
preparingDefault: '正在准备默认 AI…',
title: '选择 AI 引擎',
description: '选择驱动机器人智能的 AI 引擎。',
optionalDescription: '这一步可选。选择接下来要如何完善当前 Agent。',
optionalDescription:
'默认 AI 已配置好,你可以直接使用,也可以选择其他接入方式。',
externalTitle: '接入外部平台 Agent',
externalDescription:
'接入 Dify、n8n、Coze 等平台,并替换当前机器人的流水线。',
'通过运行器插件接入 Dify、n8n、Coze 等外部 Agent 平台。',
ownModelTitle: '改成使用自己的模型',
ownModelDescription:
'添加模型供应商,自动扫描或手动填写模型以快速完成引导。',
@@ -2463,7 +2467,7 @@ const zhHans = {
selectModelTitle: '选择模型',
selectScannedModelTitle: '选择一个模型',
selectScannedModelDescription:
'选中的模型将作为新流水线的主模型,机器人会切换到这条流水线。',
'选中的模型将替换当前机器人流水线的主模型。',
scanModelMode: '扫描模型',
manualModelMode: '手动添加',
scanningModels: '正在扫描可用模型…',
@@ -2478,11 +2482,12 @@ const zhHans = {
manualModelOptions: '可选模型能力',
editProvider: '修改供应商',
rescanModels: '重新扫描模型',
moreFeaturesTitle: '给现在的 Agent 配置更多功能',
moreFeaturesTitle: '使用默认配置',
moreFeaturesDescription:
'进入工作台,为刚刚自动生成的 Agent 添加工具、知识库等能力',
'继续使用本地 Agent 和推荐模型,之后可在流水线中添加工具、知识库等功能。',
runnerDescription: '选择外部 Agent 的运行器并完成连接配置。',
backToChoices: '返回选项',
backToList: '返回列表',
createExternal: '创建并绑定',
finishWithModel: '使用所选模型并完成',
openWorkbench: '进入工作台',
+10 -5
View File
@@ -1875,12 +1875,16 @@ const zhHant = {
logsDescription: '監控機器人活動,確認平台連接是否正常運作。',
},
aiEngine: {
defaultModelUnavailable: '暫無可用的預設對話模型,請重試。',
defaultRunnerUnavailable: '本地 Agent 尚未就緒,請重試。',
preparingDefault: '正在準備預設 AI…',
title: '配置 AI 引擎',
description: '選擇驅動機器人智慧的 AI 引擎。',
optionalDescription: '這一步可選。選擇接下來要如何完善目前的 Agent。',
optionalDescription:
'預設 AI 已設定好,你可以直接使用,也可以選擇其他接入方式。',
externalTitle: '接入外部平台 Agent',
externalDescription:
'接入 Dify、n8n、Coze 等平台,並替換目前機器人的流水線。',
'透過執行器外掛接入 Dify、n8n、Coze 等外部 Agent 平台。',
ownModelTitle: '改成使用自己的模型',
ownModelDescription:
'新增模型供應商,自動掃描或手動填寫模型以快速完成引導。',
@@ -1892,7 +1896,7 @@ const zhHant = {
selectModelTitle: '選擇模型',
selectScannedModelTitle: '選擇模型',
selectScannedModelDescription:
'所選模型將成為新流水線的主要模型,機器人也會切換到該流水線。',
'選取的模型將取代目前機器人流水線的主模型。',
scanModelMode: '自動掃描',
manualModelMode: '手動新增',
scanningModels: '正在掃描可用模型…',
@@ -1906,11 +1910,12 @@ const zhHant = {
manualModelOptions: '模型能力(可選)',
editProvider: '編輯供應商',
rescanModels: '重新掃描模型',
moreFeaturesTitle: '給目前的 Agent 配置更多功能',
moreFeaturesTitle: '使用預設設定',
moreFeaturesDescription:
'進入工作台,為剛剛自動產生的 Agent 新增工具、知識庫等能力',
'繼續使用本地 Agent 和推薦模型,之後可在流水線中新增工具、知識庫等功能。',
runnerDescription: '選擇外部 Agent 的運行器並完成連接配置。',
backToChoices: '返回選項',
backToList: '返回列表',
createExternal: '建立並關聯',
finishWithModel: '使用所選模型並完成',
openWorkbench: '進入工作台',