From 83d661af5585b220c58896bca702ff871fe4b8d4 Mon Sep 17 00:00:00 2001 From: wizardchen Date: Thu, 27 Aug 2026 16:33:49 +0800 Subject: [PATCH] ui(sandbox): redesign personal sandbox secrets settings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lead with skill credentials, hide empty inputs until edit, and rename the page to 沙箱密钥 so it is not mistaken for system env vars. --- client/env_var.go | 8 +- config/builtin_agents.yaml | 4 +- .../prompt_templates/agent_system_prompt.yaml | 2 +- docs/api/skill.md | 2 + docs/docs.go | 4 +- docs/swagger.json | 4 +- docs/swagger.yaml | 4 +- frontend/src/api/agent/index.ts | 4 +- frontend/src/api/env-vars.ts | 3 + frontend/src/api/skill/index.ts | 2 +- frontend/src/i18n/locales/en-US.ts | 36 +- frontend/src/i18n/locales/ko-KR.ts | 36 +- frontend/src/i18n/locales/ru-RU.ts | 36 +- frontend/src/i18n/locales/zh-CN.ts | 40 +- frontend/src/utils/sandboxArtifactRefs.ts | 8 +- frontend/src/views/agent/AgentEditorModal.vue | 2 +- .../src/views/settings/EnvVarSettings.vue | 941 ++++++++++++------ frontend/src/views/settings/Settings.vue | 4 +- .../src/views/settings/envVarState.test.ts | 40 + frontend/src/views/settings/envVarState.ts | 46 +- internal/agent/skills/env_resolver.go | 2 +- internal/agent/skills/env_resolver_test.go | 2 +- internal/agent/tools/shell_exec.go | 2 +- internal/application/service/user_env.go | 21 +- internal/application/service/user_env_test.go | 8 +- internal/handler/skill_handler.go | 4 +- 26 files changed, 876 insertions(+), 389 deletions(-) diff --git a/client/env_var.go b/client/env_var.go index 426168e92..df9eb3be3 100644 --- a/client/env_var.go +++ b/client/env_var.go @@ -32,9 +32,10 @@ type EnvVarView struct { // SkillEnvGroup is one skill's declared credentials. type SkillEnvGroup struct { - SkillID string `json:"skill_id"` - SkillName string `json:"skill_name"` - Vars []EnvVarView `json:"vars"` + SkillID string `json:"skill_id"` + SkillName string `json:"skill_name"` + Description string `json:"description,omitempty"` + Vars []EnvVarView `json:"vars"` } // ConfigEnvGroup is one sandbox config: the caller's own config-wide variables @@ -42,6 +43,7 @@ type SkillEnvGroup struct { type ConfigEnvGroup struct { SandboxConfigID string `json:"sandbox_config_id"` SandboxConfigName string `json:"sandbox_config_name"` + Description string `json:"description,omitempty"` Vars []EnvVarView `json:"vars"` Skills []SkillEnvGroup `json:"skills"` } diff --git a/config/builtin_agents.yaml b/config/builtin_agents.yaml index 98887162a..015087dec 100644 --- a/config/builtin_agents.yaml +++ b/config/builtin_agents.yaml @@ -242,10 +242,10 @@ builtin_agents: description: "Internal agent that installs an uploaded skill and its dependencies into the sandbox image" zh-CN: name: "技能安装器" - description: "把上传的技能及其依赖装进沙盒镜像的内部智能体" + description: "把上传的技能及其依赖装进沙箱镜像的内部智能体" zh-TW: name: "技能安裝器" - description: "把上傳的技能及其相依套件裝進沙盒鏡像的內部智能體" + description: "把上傳的技能及其相依套件裝進沙箱鏡像的內部智能體" ja-JP: name: "スキルインストーラー" description: "アップロードされたスキルとその依存関係をサンドボックスイメージにインストールする内部エージェント" diff --git a/config/prompt_templates/agent_system_prompt.yaml b/config/prompt_templates/agent_system_prompt.yaml index 68331c21c..dc7af4ad9 100644 --- a/config/prompt_templates/agent_system_prompt.yaml +++ b/config/prompt_templates/agent_system_prompt.yaml @@ -494,7 +494,7 @@ templates: i18n: zh-CN: name: "技能安装系统提示词" - description: "用于把上传的技能及其依赖装进沙盒镜像的系统提示词" + description: "用于把上传的技能及其依赖装进沙箱镜像的系统提示词" en-US: name: "Skill Installer System Prompt" description: "System prompt for installing an uploaded skill and its dependencies into the sandbox image" diff --git a/docs/api/skill.md b/docs/api/skill.md index 948c383e1..b02684535 100644 --- a/docs/api/skill.md +++ b/docs/api/skill.md @@ -224,6 +224,7 @@ curl --location 'http://localhost:8080/api/v1/me/env-vars' \ { "sandbox_config_id": "cfg-1", "sandbox_config_name": "默认沙箱", + "description": "日常对话用的沙箱", "vars": [ { "name": "HTTP_PROXY", "source": "user", "updated_at": "2026-08-27T10:00:00Z" } ], @@ -231,6 +232,7 @@ curl --location 'http://localhost:8080/api/v1/me/env-vars' \ { "skill_id": "sk-1", "skill_name": "web-search", + "description": "通过 Tavily 检索网页", "vars": [ { "name": "TAVILY_API_KEY", "description": "Tavily 搜索密钥", "required": true, "source": "workspace" }, { "name": "REGION", "source": "unset" } diff --git a/docs/docs.go b/docs/docs.go index 378dda235..799153fed 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -13333,7 +13333,7 @@ const docTemplate = `{ "ApiKeyAuth": [] } ], - "description": "返回指定沙盒配置镜像内、智能体实际能调用的已安装技能(ready 且启用)。不传 sandbox_config_id 时列表为空。", + "description": "返回指定沙箱配置镜像内、智能体实际能调用的已安装技能(ready 且启用)。不传 sandbox_config_id 时列表为空。", "consumes": [ "application/json" ], @@ -13343,7 +13343,7 @@ const docTemplate = `{ "tags": [ "Skills" ], - "summary": "获取当前沙盒配置上可执行的 Skills", + "summary": "获取当前沙箱配置上可执行的 Skills", "parameters": [ { "type": "string", diff --git a/docs/swagger.json b/docs/swagger.json index afe34a478..90c634165 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -13326,7 +13326,7 @@ "ApiKeyAuth": [] } ], - "description": "返回指定沙盒配置镜像内、智能体实际能调用的已安装技能(ready 且启用)。不传 sandbox_config_id 时列表为空。", + "description": "返回指定沙箱配置镜像内、智能体实际能调用的已安装技能(ready 且启用)。不传 sandbox_config_id 时列表为空。", "consumes": [ "application/json" ], @@ -13336,7 +13336,7 @@ "tags": [ "Skills" ], - "summary": "获取当前沙盒配置上可执行的 Skills", + "summary": "获取当前沙箱配置上可执行的 Skills", "parameters": [ { "type": "string", diff --git a/docs/swagger.yaml b/docs/swagger.yaml index c76997ec2..af472bbd2 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -14813,7 +14813,7 @@ paths: get: consumes: - application/json - description: 返回指定沙盒配置镜像内、智能体实际能调用的已安装技能(ready 且启用)。不传 sandbox_config_id 时列表为空。 + description: 返回指定沙箱配置镜像内、智能体实际能调用的已安装技能(ready 且启用)。不传 sandbox_config_id 时列表为空。 parameters: - description: Sandbox config ID in: query @@ -14830,7 +14830,7 @@ paths: security: - Bearer: [] - ApiKeyAuth: [] - summary: 获取当前沙盒配置上可执行的 Skills + summary: 获取当前沙箱配置上可执行的 Skills tags: - Skills /storage-backends: diff --git a/frontend/src/api/agent/index.ts b/frontend/src/api/agent/index.ts index 18f243c16..09cc126f6 100644 --- a/frontend/src/api/agent/index.ts +++ b/frontend/src/api/agent/index.ts @@ -65,8 +65,8 @@ export interface CustomAgentConfig { skills_selection_mode?: 'all' | 'selected' | 'none'; selected_skills?: string[]; // 选择的Skill名称列表 - // ===== 沙盒设置 ===== - // 该智能体的技能脚本运行在哪个沙盒配置上;为空表示不启用沙盒执行。 + // ===== 沙箱设置 ===== + // 该智能体的技能脚本运行在哪个沙箱配置上;为空表示不启用沙箱执行。 // 指向逻辑配置而非某个具体版本,凭据轮换时无需重新指派每个智能体。 sandbox_config_id?: string; diff --git a/frontend/src/api/env-vars.ts b/frontend/src/api/env-vars.ts index 5dc64c287..a46d8abe8 100644 --- a/frontend/src/api/env-vars.ts +++ b/frontend/src/api/env-vars.ts @@ -26,6 +26,8 @@ export interface EnvVarView { export interface SkillEnvGroup { skill_id: string skill_name: string + /** SKILL.md one-liner; not the instruction body. */ + description?: string vars: EnvVarView[] } @@ -36,6 +38,7 @@ export interface SkillEnvGroup { export interface ConfigEnvGroup { sandbox_config_id: string sandbox_config_name: string + description?: string vars: EnvVarView[] skills: SkillEnvGroup[] } diff --git a/frontend/src/api/skill/index.ts b/frontend/src/api/skill/index.ts index 80c8c2b54..e08421d93 100644 --- a/frontend/src/api/skill/index.ts +++ b/frontend/src/api/skill/index.ts @@ -6,7 +6,7 @@ export interface SkillInfo { description: string; } -// 获取当前沙盒配置上可执行的 Skills;未传 sandboxConfigId 或 +// 获取当前沙箱配置上可执行的 Skills;未传 sandboxConfigId 或 // skills_available 为 false 时,前端应隐藏/禁用 Skills 配置 export function listSkills(sandboxConfigId?: string) { return get<{ data: SkillInfo[]; skills_available?: boolean }>('/api/v1/skills', { diff --git a/frontend/src/i18n/locales/en-US.ts b/frontend/src/i18n/locales/en-US.ts index 72e893fb6..903aeae27 100755 --- a/frontend/src/i18n/locales/en-US.ts +++ b/frontend/src/i18n/locales/en-US.ts @@ -1366,7 +1366,7 @@ export default { toggleHide: 'Hide environment variables', none: 'This skill declared no environment variables.', workspaceTitle: 'Workspace-wide values', - workspaceHint: 'Every member who has not set their own value uses the value here. Members set their own under Settings, Environment variables.', + workspaceHint: 'Every member who has not set their own value uses the value here. Members set their own under Settings → Sandbox secrets.', required: 'Required', isSet: 'Set', notSet: 'Not set', @@ -1834,24 +1834,36 @@ export default { } }, envVarSettings: { - title: 'Environment variables', - description: 'Values you enter here belong to you alone. A sandbox variable is passed to every skill script and shell command you run on that sandbox; a skill credential is passed only when that skill runs. Nothing is displayed again once saved.', + title: 'Sandbox secrets', + description: 'Personal keys for skills and sandboxes, not WeKnora system or deployment settings.', + helpAria: 'About sandbox secrets', + introPersonalTitle: 'Yours only', + introPersonalBody: 'Injected into your own chats and runs. Other members cannot see them, and theirs will not replace yours.', + introRuntimeTitle: 'Passed in when something runs', + introRuntimeBody: 'Injected when a skill runs, or when a command runs in that sandbox. You can also supply them in the conversation. Saved values are never shown again.', loading: 'Loading…', - loadFailed: 'Could not load the environment variables.', + loadFailed: 'Could not load sandbox secrets.', retry: 'Try again', noConfigTitle: 'No sandbox configured', - noConfigDescription: 'This workspace has no sandbox backend yet, so there is nothing to set variables for.', - sandboxTitle: 'Sandbox variables', - sandboxHint: 'Passed to everything you run on this sandbox, whether or not a skill is involved.', - sandboxEmpty: 'You have no variables on this sandbox.', - skillTitle: 'Skill credentials', - skillHint: 'What each skill declared it needs. Passed only when that skill runs.', + noConfigDescription: 'This workspace has no sandbox backend yet, so there is nothing to set keys for.', + sandboxTitle: 'Always passed in a chosen sandbox', + sandboxHint: 'Passed only to commands you run in that sandbox. Most people never need this; you can also supply values in the conversation.', + sandboxEmpty: 'Nothing added yet.', + sandboxPick: 'Which sandbox', + skillTitle: 'Keys a skill needs', + skillHint: 'Each skill declares what it needs. Save them here ahead of time, or supply them in the conversation. Workspace admins can also fill in shared values on the skill card.', + skillEmptyTitle: 'No skill has asked for keys yet', + skillEmptyDesc: 'After you install a skill that declares credentials, the fields to fill in will show up here.', + skillOnSandbox: 'Sandbox: {name}', + skillNeedsCount: '{count} not saved here', + skillReady: 'Saved on this page', requiredTag: 'Required', statusUnset: 'Not set', statusWorkspace: 'Using the workspace value', statusUser: 'Set by you', - blocking: 'Required but not set, so this skill cannot run.', - addRow: 'Add a variable', + setValue: 'Set', + replaceValue: 'Replace', + addRow: 'Add', namePlaceholder: 'VARIABLE_NAME', nameRule: 'Upper-case letters, digits and underscores, starting with a letter or an underscore.', nameInvalid: 'That name cannot be used. Names the sandbox reserves, such as PATH or anything starting with WEKNORA_, are not accepted.', diff --git a/frontend/src/i18n/locales/ko-KR.ts b/frontend/src/i18n/locales/ko-KR.ts index 74ed2e526..f65773c0a 100755 --- a/frontend/src/i18n/locales/ko-KR.ts +++ b/frontend/src/i18n/locales/ko-KR.ts @@ -4782,24 +4782,36 @@ export default { } }, envVarSettings: { - title: '환경 변수', - description: '여기에 입력한 값은 나에게만 속합니다. 샌드박스 변수는 해당 샌드박스에서 실행하는 모든 스킬 스크립트와 명령에 전달되고, 스킬 자격 증명은 그 스킬이 실행될 때만 전달됩니다. 저장한 뒤에는 다시 표시되지 않습니다.', + title: '샌드박스 키', + description: '스킬과 샌드박스에 쓰는 개인 키이며, WeKnora 시스템이나 배포 설정이 아닙니다.', + helpAria: '샌드박스 키 설명', + introPersonalTitle: '나만의 값', + introPersonalBody: '내 대화와 실행에만 주입됩니다. 다른 구성원은 볼 수 없고, 그들의 값이 내 값을 대체하지도 않습니다.', + introRuntimeTitle: '실행할 때만 전달', + introRuntimeBody: '스킬이 실행되거나 해당 샌드박스에서 명령을 실행할 때 주입됩니다. 대화에서 바로 제공할 수도 있습니다. 저장한 뒤에는 다시 표시되지 않습니다.', loading: '불러오는 중…', - loadFailed: '환경 변수를 불러오지 못했습니다.', + loadFailed: '샌드박스 키를 불러오지 못했습니다.', retry: '다시 시도', noConfigTitle: '샌드박스가 없습니다', - noConfigDescription: '이 워크스페이스에는 아직 샌드박스 백엔드가 없어 설정할 변수가 없습니다.', - sandboxTitle: '샌드박스 변수', - sandboxHint: '스킬과 무관하게 이 샌드박스에서 실행하는 모든 것에 전달됩니다.', - sandboxEmpty: '이 샌드박스에 등록한 변수가 없습니다.', - skillTitle: '스킬 자격 증명', - skillHint: '각 스킬이 필요하다고 선언한 변수입니다. 그 스킬이 실행될 때만 전달됩니다.', + noConfigDescription: '이 워크스페이스에는 아직 샌드박스 백엔드가 없어 설정할 키가 없습니다.', + sandboxTitle: '선택한 샌드박스에서 항상 전달되는 값', + sandboxHint: '그 샌드박스에서 실행하는 명령에만 전달됩니다. 대부분은 필요 없고, 대화에서 바로 제공할 수도 있습니다.', + sandboxEmpty: '아직 추가한 값이 없습니다.', + sandboxPick: '어느 샌드박스에 쓸지', + skillTitle: '스킬이 필요한 키', + skillHint: '각 스킬이 필요하다고 선언한 값입니다. 여기에 미리 저장하거나 대화에서 바로 제공할 수 있습니다. 워크스페이스 관리자는 스킬 카드에서 공용 값을 넣을 수도 있습니다.', + skillEmptyTitle: '아직 키가 필요한 스킬이 없습니다', + skillEmptyDesc: '자격 증명을 선언하는 스킬을 설치하면 여기에 입력란이 나타납니다.', + skillOnSandbox: '샌드박스: {name}', + skillNeedsCount: '여기에 저장되지 않음 {count}개', + skillReady: '이 페이지에 저장됨', requiredTag: '필수', statusUnset: '설정되지 않음', statusWorkspace: '워크스페이스 공용 값 사용 중', statusUser: '내가 설정함', - blocking: '필수인데 설정되지 않아 이 스킬을 실행할 수 없습니다.', - addRow: '변수 추가', + setValue: '설정', + replaceValue: '변경', + addRow: '추가', namePlaceholder: 'VARIABLE_NAME', nameRule: '대문자, 숫자, 밑줄만 사용하며 문자 또는 밑줄로 시작해야 합니다.', nameInvalid: '이 이름은 사용할 수 없습니다. PATH처럼 샌드박스가 예약한 이름이나 WEKNORA_로 시작하는 이름은 허용되지 않습니다.', @@ -5261,7 +5273,7 @@ export default { toggleHide: '환경 변수 접기', none: '이 스킬은 환경 변수를 선언하지 않았습니다.', workspaceTitle: '워크스페이스 공용 값', - workspaceHint: '자기 값을 설정하지 않은 모든 구성원이 여기의 값을 사용합니다. 구성원은 설정의 환경 변수에서 자기 값을 설정할 수 있습니다.', + workspaceHint: '자기 값을 설정하지 않은 모든 구성원이 여기의 값을 사용합니다. 구성원은 설정의 「샌드박스 키」에서 자기 값을 설정할 수 있습니다.', required: '필수', isSet: '설정됨', notSet: '설정되지 않음', diff --git a/frontend/src/i18n/locales/ru-RU.ts b/frontend/src/i18n/locales/ru-RU.ts index 100d165b6..804c5e5b5 100755 --- a/frontend/src/i18n/locales/ru-RU.ts +++ b/frontend/src/i18n/locales/ru-RU.ts @@ -4782,24 +4782,36 @@ export default { } }, envVarSettings: { - title: 'Переменные окружения', - description: 'Введённые здесь значения принадлежат только вам. Переменная песочницы передаётся во все скрипты навыков и команды, которые вы запускаете в этой песочнице; учётные данные навыка — только при запуске этого навыка. После сохранения значение больше не отображается.', + title: 'Ключи песочницы', + description: 'Личные ключи для навыков и песочниц, а не системные или деплой-настройки WeKnora.', + helpAria: 'Справка по ключам песочницы', + introPersonalTitle: 'Только ваши', + introPersonalBody: 'Подставляются только в ваши диалоги и запуски. Другие участники их не видят, и их значения не заменяют ваши.', + introRuntimeTitle: 'Передаются в момент запуска', + introRuntimeBody: 'Подставляются, когда навык выполняется или когда команда идёт в этой песочнице. Их также можно передать прямо в разговоре. Сохранённые значения больше не показываются.', loading: 'Загрузка…', - loadFailed: 'Не удалось загрузить переменные окружения.', + loadFailed: 'Не удалось загрузить ключи песочницы.', retry: 'Повторить', noConfigTitle: 'Песочница не настроена', - noConfigDescription: 'В этом рабочем пространстве пока нет песочницы, поэтому задавать переменные не для чего.', - sandboxTitle: 'Переменные песочницы', - sandboxHint: 'Передаются во всё, что вы запускаете в этой песочнице, независимо от навыков.', - sandboxEmpty: 'У вас нет переменных в этой песочнице.', - skillTitle: 'Учётные данные навыков', - skillHint: 'То, что каждый навык объявил необходимым. Передаётся только при запуске этого навыка.', + noConfigDescription: 'В этом рабочем пространстве пока нет песочницы, поэтому задавать ключи не для чего.', + sandboxTitle: 'Всегда передаются в выбранной песочнице', + sandboxHint: 'Передаются только командам в этой песочнице. Обычно не нужны; значения можно также дать в разговоре.', + sandboxEmpty: 'Пока ничего не добавлено.', + sandboxPick: 'В какой песочнице', + skillTitle: 'Ключи, которые нужны навыку', + skillHint: 'Каждый навык объявляет, что ему нужно. Можно сохранить заранее здесь или передать в разговоре. Администратор рабочего пространства может также задать общие значения на карточке навыка.', + skillEmptyTitle: 'Пока ни один навык не запросил ключи', + skillEmptyDesc: 'После установки навыка, который объявляет учётные данные, поля для заполнения появятся здесь.', + skillOnSandbox: 'Песочница: {name}', + skillNeedsCount: 'Не сохранено здесь: {count}', + skillReady: 'Сохранено на этой странице', requiredTag: 'Обязательно', statusUnset: 'Не задано', statusWorkspace: 'Используется значение рабочего пространства', statusUser: 'Задано вами', - blocking: 'Обязательная переменная не задана, поэтому навык не может работать.', - addRow: 'Добавить переменную', + setValue: 'Задать', + replaceValue: 'Заменить', + addRow: 'Добавить', namePlaceholder: 'VARIABLE_NAME', nameRule: 'Только заглавные латинские буквы, цифры и подчёркивания; первым символом должна быть буква или подчёркивание.', nameInvalid: 'Это имя использовать нельзя. Имена, зарезервированные песочницей, например PATH или начинающиеся с WEKNORA_, не принимаются.', @@ -5261,7 +5273,7 @@ export default { toggleHide: 'Скрыть переменные окружения', none: 'Этот навык не объявил переменных окружения.', workspaceTitle: 'Значения для всего рабочего пространства', - workspaceHint: 'Каждый участник, не задавший своё значение, использует значение отсюда. Своё значение участник задаёт в настройках, раздел «Переменные окружения».', + workspaceHint: 'Каждый участник, не задавший своё значение, использует значение отсюда. Своё значение участник задаёт в настройках, раздел «Ключи песочницы».', required: 'Обязательно', isSet: 'Задано', notSet: 'Не задано', diff --git a/frontend/src/i18n/locales/zh-CN.ts b/frontend/src/i18n/locales/zh-CN.ts index 90d071e48..b6ae506f0 100755 --- a/frontend/src/i18n/locales/zh-CN.ts +++ b/frontend/src/i18n/locales/zh-CN.ts @@ -4784,24 +4784,36 @@ export default { } }, envVarSettings: { - title: '环境变量', - description: '这里填的值只属于你自己。沙盒变量会带给你在该沙盒上运行的所有技能脚本和命令;技能凭据只在该技能运行时带上。保存之后都不会再显示出来。', + title: '沙箱密钥', + description: '给技能和沙箱用的个人密钥,不是 WeKnora 的系统或部署配置。', + helpAria: '沙箱密钥说明', + introPersonalTitle: '只属于你', + introPersonalBody: '只注入到你自己的对话和执行里,空间里的其他人看不到,也不会改成他们的值。', + introRuntimeTitle: '用的时候才带上', + introRuntimeBody: '技能运行或在沙箱里执行命令时才会注入;对话里也可以当场提供。保存后不再显示明文。', loading: '加载中…', - loadFailed: '环境变量加载失败。', + loadFailed: '沙箱密钥加载失败。', retry: '重试', - noConfigTitle: '还没有沙盒', - noConfigDescription: '这个空间还没有配置沙盒后端,暂时没有可设置的变量。', - sandboxTitle: '沙盒变量', - sandboxHint: '你在这个沙盒上运行的任何东西都会带上,不限于技能。', - sandboxEmpty: '你在这个沙盒上还没有变量。', - skillTitle: '技能凭据', - skillHint: '各技能声明自己需要的变量,只在该技能运行时带上。', + noConfigTitle: '还没有沙箱', + noConfigDescription: '这个空间还没有配置沙箱后端,暂时没有可设置的密钥。', + sandboxTitle: '某个沙箱里始终带上的值', + sandboxHint: '只带给你在那个沙箱里跑的命令。多数情况用不到;需要时再加,对话里也可以当场提供。', + sandboxEmpty: '还没有添加过。', + sandboxPick: '用在哪个沙箱', + skillTitle: '技能要用的密钥', + skillHint: '技能声明需要的值。可以预先保存在这里,也可以在对话里当场提供。空间管理员还可以在技能卡上填空间共用值。', + skillEmptyTitle: '还没有技能需要密钥', + skillEmptyDesc: '安装会声明凭据的技能后,要填的项会出现在这里。', + skillOnSandbox: '用于沙箱「{name}」', + skillNeedsCount: '{count} 项未在此保存', + skillReady: '此页已保存', requiredTag: '必填', statusUnset: '未设置', statusWorkspace: '正在使用空间共用值', statusUser: '你已设置', - blocking: '必填但未设置,该技能无法运行。', - addRow: '添加变量', + setValue: '设置', + replaceValue: '更换', + addRow: '添加', namePlaceholder: 'VARIABLE_NAME', nameRule: '只能用大写字母、数字和下划线,且以字母或下划线开头。', nameInvalid: '这个名字不能用。沙箱保留的名字(例如 PATH,或以 WEKNORA_ 开头的名字)不接受。', @@ -4815,7 +4827,7 @@ export default { saveSuccess: '已保存。值已存好,之后不会再显示。', saveFailed: '保存失败。', delete: '删除', - deleteConfirm: '删除 {name}?之后在这个沙盒上运行的东西都不会再带上它。', + deleteConfirm: '删除 {name}?之后在这个沙箱上运行的东西都不会再带上它。', deleteSuccess: '变量已删除。', clear: '清除我的值', clearConfirm: '清除你为 {name} 设置的值?之后会重新使用空间共用值(如果有)。', @@ -5263,7 +5275,7 @@ export default { toggleHide: '收起环境变量', none: '这个技能没有声明环境变量。', workspaceTitle: '空间共用值', - workspaceHint: '所有没有填写自己值的成员都会用这里的值。成员可以在「设置 - 环境变量」里填自己的值。', + workspaceHint: '所有没有填写自己值的成员都会用这里的值。成员可以在「设置 → 沙箱密钥」里填自己的值。', required: '必填', isSet: '已设置', notSet: '未设置', diff --git a/frontend/src/utils/sandboxArtifactRefs.ts b/frontend/src/utils/sandboxArtifactRefs.ts index 62a2fb36b..62a0b5cb5 100644 --- a/frontend/src/utils/sandboxArtifactRefs.ts +++ b/frontend/src/utils/sandboxArtifactRefs.ts @@ -1,7 +1,7 @@ /** - * 把回答正文里对「沙盒生成文件」的引用,接到 artifact 下载链路上。 + * 把回答正文里对「沙箱生成文件」的引用,接到 artifact 下载链路上。 * - * 模型会用 Markdown 图片语法引用它在沙盒里生成的文件(提示词规定写成 + * 模型会用 Markdown 图片语法引用它在沙箱里生成的文件(提示词规定写成 * `![说明](sandbox:文件名)`),服务端在落库前把它改写成该文件的稳定句柄 * `resource://` —— 与知识库图片、聊天附件同一种引用形式。两种写法 * 都指向同一份 `Message.Artifacts`: @@ -77,7 +77,7 @@ function parseArtifactRef(href: string): ArtifactRef | null { } /** - * 该链接目标是否可能是沙盒产物引用。 + * 该链接目标是否可能是沙箱产物引用。 * * 句柄形式与知识库图片同形,因此这里为真只说明「值得交给产物解析试一次」, * 不代表本消息真有这个文件。 @@ -286,7 +286,7 @@ function renderImage( /** * 渲染一个 Markdown 图片/链接目标。 * - * 返回 null 表示这不是沙盒产物引用,调用方应回落到默认渲染(普通图片、 + * 返回 null 表示这不是沙箱产物引用,调用方应回落到默认渲染(普通图片、 * `resource://` 受保护图片、外链等一律不受影响)。 */ export function renderArtifactReference(args: { diff --git a/frontend/src/views/agent/AgentEditorModal.vue b/frontend/src/views/agent/AgentEditorModal.vue index cab8dd12d..52e1108a2 100644 --- a/frontend/src/views/agent/AgentEditorModal.vue +++ b/frontend/src/views/agent/AgentEditorModal.vue @@ -1940,7 +1940,7 @@ const showMcpServiceSelect = computed(() => ); const webSearchProviderList = ref([]); const skillOptions = ref<{ name: string; description: string }[]>([]); -// 是否允许启用 Skills(当前沙盒配置上有可执行技能时为 true;未选配置前为 false) +// 是否允许启用 Skills(当前沙箱配置上有可执行技能时为 true;未选配置前为 false) const skillsAvailable = ref(false); const hasSandboxSelected = computed(() => !!formData.value.config.sandbox_config_id); diff --git a/frontend/src/views/settings/EnvVarSettings.vue b/frontend/src/views/settings/EnvVarSettings.vue index ebdd6d4d7..c5ae02808 100644 --- a/frontend/src/views/settings/EnvVarSettings.vue +++ b/frontend/src/views/settings/EnvVarSettings.vue @@ -1,7 +1,26 @@