Skip to content

Agent sandbox#6532

Open
c121914yu wants to merge 12 commits intolabring:v4.14.9-devfrom
c121914yu:terminal-box
Open

Agent sandbox#6532
c121914yu wants to merge 12 commits intolabring:v4.14.9-devfrom
c121914yu:terminal-box

Conversation

@c121914yu
Copy link
Collaborator

No description provided.

c121914yu added 12 commits March 9, 2026 21:06
* cloud doc

* doc refactor

* doc move

* seo

* remove doc

* yml

* doc

* fix: tsconfig

* fix: tsconfig
* sandbox version

* add sandbox log

* update lock

* fix

* fix: sandbox

* doc

* add console

* i18n
Copilot AI review requested due to automatic review settings March 9, 2026 13:08
@github-actions
Copy link

github-actions bot commented Mar 9, 2026

Preview sandbox Image:

registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-pr:fatsgpt_sandbox_d3a487cca42511d7493f02d5d3a7b85c3e2289e4

@github-actions
Copy link

github-actions bot commented Mar 9, 2026

Preview mcp_server Image:

registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-pr:fatsgpt_mcp_server_d3a487cca42511d7493f02d5d3a7b85c3e2289e4

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces an “Agent sandbox” (per-chat Linux sandbox) integration across service, API, and web UI, enabling sandbox-backed tool execution (sandbox_shell) and user-facing sandbox file management (list/read/write/download), plus lifecycle cleanup and cron-based suspension.

Changes:

  • Add service-side sandbox persistence + lifecycle management (Mongo schema, controller, cron suspend, deletion hooks on chat/app delete).
  • Inject sandbox tool + prompts into ToolCall/Agent dispatch paths and propagate useComputer through workflow/app forms.
  • Add web UI entry points + APIs for sandbox file browsing/editing/downloading, plus new icons and i18n strings.

Reviewed changes

Copilot reviewed 79 out of 102 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
test/setup.ts Adjusts test DB cleanup behavior for Mongo connections.
test/cases/service/core/ai/sandbox/sandbox.integration.test.ts Adds env-gated integration tests for sandbox exec/FS/state/concurrency.
test/cases/service/core/ai/sandbox/controller.test.ts Adds unit tests for sandbox deletion helpers and inactivity query logic (mocked adapter).
test/cases/service/core/ai/sandbox/constants.test.ts Adds tests for deterministic sandbox ID generation.
test/cases/global/core/chat/utils.test.ts Updates expectations to match new chat statistical fields behavior.
projects/app/src/web/core/workflow/utils.ts Updates workflow validation to account for useComputer when tools aren’t connected.
projects/app/src/service/common/system/index.ts Exposes show_agent_sandbox flag in system config based on env.
projects/app/src/service/common/system/cron.ts Registers sandbox cron job in app cron startup.
projects/app/src/pages/api/core/chat/history/batchDelete.ts Deletes sandboxes when chats are batch-deleted.
projects/app/src/pages/api/core/ai/sandbox/file.ts Adds sandbox file list/read/write API endpoint.
projects/app/src/pages/api/core/ai/sandbox/download.ts Adds sandbox file/directory download endpoint (zip for directories).
projects/app/src/pages/api/core/ai/sandbox/checkExist.ts Adds API to check if a sandbox exists for a chat.
projects/app/src/pageComponents/chat/ToolMenu.tsx Adds sandbox entry icon/menu integration for chat UI.
projects/app/src/pageComponents/chat/SandboxEditor/utils.tsx Adds helpers for file icons + language detection by extension.
projects/app/src/pageComponents/chat/SandboxEditor/modal.tsx Adds modal wrapper for sandbox editor UI.
projects/app/src/pageComponents/chat/SandboxEditor/hook.tsx Adds hook handling sandbox existence polling + modal state.
projects/app/src/pageComponents/chat/SandboxEditor/api.ts Adds client API helpers for sandbox file ops/download/checkExist.
projects/app/src/pageComponents/chat/ChatHeader.tsx Removes unused usePathname import.
projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/ChatTest.tsx Adds sandbox entry + modal in workflow test chat UI.
projects/app/src/pageComponents/app/detail/Logs/DetailLogsModal.tsx Adds sandbox entry + modal in logs detail modal UI, updates close button.
projects/app/src/pageComponents/app/detail/Edit/SimpleApp/utils.ts Persists useComputer into workflow and uses tool template when enabled.
projects/app/src/pageComponents/app/detail/Edit/SimpleApp/EditForm.tsx Adds “Use Computer” (sandbox) switch to SimpleApp edit form.
projects/app/src/pageComponents/app/detail/Edit/SimpleApp/ChatTest.tsx Adds sandbox entry + modal to SimpleApp test chat.
projects/app/src/pageComponents/app/detail/Edit/ChatAgent/utils.ts Persists useComputer into agent workflow inputs.
projects/app/src/pageComponents/app/detail/Edit/ChatAgent/EditForm.tsx Adds “Use Computer” (sandbox) switch to ChatAgent edit form.
projects/app/src/pageComponents/app/detail/Edit/ChatAgent/ChatTest.tsx Adds sandbox entry + modal to ChatAgent test chat.
projects/app/src/global/core/chat/utils.ts Adds useComputer response tagging derived from sandbox tool usage; deprecates old fields.
projects/app/src/components/core/chat/ChatContainer/ChatBox/components/ResponseTags.tsx Replaces contextual preview tags with sandbox files tag + modal integration.
projects/app/src/components/core/chat/ChatContainer/ChatBox/components/ContextModal.tsx Removes contextual preview modal implementation.
projects/app/package.json Increases dev memory limit; adds archiver and Monaco dependency.
projects/app/.env.template Adds sandbox-related env vars.
packages/web/package.json Bumps @monaco-editor/react version.
packages/web/i18n/zh-Hant/chat.json Updates/extends chat translations for sandbox UI.
packages/web/i18n/zh-Hant/app.json Adds app translations for sandbox UI and use_computer.
packages/web/i18n/zh-CN/chat.json Updates/extends chat translations for sandbox UI.
packages/web/i18n/zh-CN/app.json Adds app translations for sandbox UI and editor strings.
packages/web/i18n/en/chat.json Updates/extends chat translations for sandbox UI.
packages/web/i18n/en/app.json Adds app translations for sandbox UI and use_computer.
packages/web/components/v2/common/MyModal/index.tsx Adds a v2 modal implementation used by sandbox editor modal.
packages/web/components/common/Icon/icons/core/app/sandbox/zip.svg Adds sandbox file-type icon.
packages/web/components/common/Icon/icons/core/app/sandbox/yml.svg Adds sandbox file-type icon.
packages/web/components/common/Icon/icons/core/app/sandbox/xlsx.svg Adds sandbox file-type icon.
packages/web/components/common/Icon/icons/core/app/sandbox/video.svg Adds sandbox file-type icon.
packages/web/components/common/Icon/icons/core/app/sandbox/txt.svg Adds sandbox file-type icon.
packages/web/components/common/Icon/icons/core/app/sandbox/svg.svg Adds sandbox file-type icon.
packages/web/components/common/Icon/icons/core/app/sandbox/scss.svg Adds sandbox file-type icon.
packages/web/components/common/Icon/icons/core/app/sandbox/sandbox.svg Adds sandbox main icon.
packages/web/components/common/Icon/icons/core/app/sandbox/py.svg Adds sandbox file-type icon.
packages/web/components/common/Icon/icons/core/app/sandbox/pptx.svg Adds sandbox file-type icon.
packages/web/components/common/Icon/icons/core/app/sandbox/pdf.svg Adds sandbox file-type icon.
packages/web/components/common/Icon/icons/core/app/sandbox/md.svg Adds sandbox file-type icon.
packages/web/components/common/Icon/icons/core/app/sandbox/js.svg Adds sandbox file-type icon.
packages/web/components/common/Icon/icons/core/app/sandbox/java.svg Adds sandbox file-type icon.
packages/web/components/common/Icon/icons/core/app/sandbox/image.svg Adds sandbox file-type icon.
packages/web/components/common/Icon/icons/core/app/sandbox/html.svg Adds sandbox file-type icon.
packages/web/components/common/Icon/icons/core/app/sandbox/go.svg Adds sandbox file-type icon.
packages/web/components/common/Icon/icons/core/app/sandbox/file.svg Adds sandbox file icon.
packages/web/components/common/Icon/icons/core/app/sandbox/docx.svg Adds sandbox file-type icon.
packages/web/components/common/Icon/icons/core/app/sandbox/default.svg Adds sandbox default file icon.
packages/web/components/common/Icon/icons/core/app/sandbox/css.svg Adds sandbox file-type icon.
packages/web/components/common/Icon/icons/common/downloadLine.svg Updates download icon asset.
packages/web/components/common/Icon/constants.ts Registers new sandbox icon paths.
packages/service/package.json Adds sandbox adapter dependency; reorganizes json-schema-ref-parser entry.
packages/service/env.ts Adds sandbox env schema fields.
packages/service/core/workflow/dispatch/ai/tool/type.ts Adds useComputer to tool dispatch props and introduces ChildResponseItemType.
packages/service/core/workflow/dispatch/ai/tool/toolCall.ts Injects sandbox tool/prompt and handles sandbox tool calls in ToolCall flow.
packages/service/core/workflow/dispatch/ai/tool/index.ts Plumbs useComputer into tool-call execution path.
packages/service/core/workflow/dispatch/ai/tool/constants.ts Adds helper to format sandbox tool workflow responses.
packages/service/core/workflow/dispatch/ai/agent/utils.ts Injects sandbox tools for agent mode when useComputer is enabled.
packages/service/core/workflow/dispatch/ai/agent/sub/sandbox/index.ts Adds agent sub-dispatcher for sandbox shell execution.
packages/service/core/workflow/dispatch/ai/agent/master/prompt.ts Adds sandbox environment prompt injection for master agent.
packages/service/core/workflow/dispatch/ai/agent/master/call.ts Handles sandbox tool calls in master agent dispatch flow.
packages/service/core/workflow/dispatch/ai/agent/index.ts Plumbs useComputer into agent dispatch and tool injection.
packages/service/core/app/controller.ts Deletes sandboxes when an app is deleted.
packages/service/core/ai/sandbox/type.ts Adds Zod schema/type for sandbox instance records.
packages/service/core/ai/sandbox/schema.ts Adds Mongo model + indexes for sandbox instances.
packages/service/core/ai/sandbox/index.ts Re-exports sandbox adapter interface type.
packages/service/core/ai/sandbox/controller.ts Implements sandbox instance wrapper + deletion helpers + cron job.
packages/service/core/ai/llm/compress/index.ts Downgrades tool-response compression log to debug level.
packages/service/common/logger/categories.ts Adds sandbox logging category.
packages/global/openapi/tag.ts Adds OpenAPI tag for sandbox.
packages/global/openapi/index.ts Adds sandbox tag into AI group.
packages/global/openapi/core/ai/sandbox/index.ts Adds OpenAPI paths for sandbox file/check/download.
packages/global/openapi/core/ai/sandbox/api.ts Adds request/response schemas for sandbox APIs.
packages/global/openapi/core/ai/index.ts Includes sandbox paths under AI OpenAPI.
packages/global/core/workflow/template/system/toolCall.ts Adds useComputer switch input to ToolCall node template.
packages/global/core/workflow/runtime/type.ts Adds toolId field to dispatch node response type.
packages/global/core/workflow/node/agent/constants.ts Registers sandbox as a system sub-app/tool.
packages/global/core/workflow/constants.ts Adds useComputer to workflow node input keys.
packages/global/core/chat/type.ts Adds useComputer to response tag type; marks old fields deprecated.
packages/global/core/app/formEdit/type.ts Adds useComputer to AI settings schema.
packages/global/core/ai/type.ts Adjusts OpenAI re-exports ordering/types.
packages/global/core/ai/sandbox/constants.ts Adds sandbox constants, tool schema, and prompt text.
packages/global/common/system/types/index.ts Adds show_agent_sandbox to FE config type.
document/data/doc-last-modified.json Updates doc modification map (currently contains conflict markers).
document/content/docs/openapi/chat.mdx Updates docs to match response tag field changes.
document/content/docs/openapi/chat.en.mdx Updates docs to match response tag field changes.
.claude/skills/design/core/ai/sandbox/technical-design.md Adds internal technical design doc for sandbox integration.
.claude/skills/design/core/ai/sandbox/prd.md Adds internal PRD doc for sandbox integration.
.claude/plan/phase5-agent-computer-use-todo.md Adds internal TODO plan for agent computer-use support.
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (2)

projects/app/src/pages/api/core/chat/history/batchDelete.ts:67

  • deleteSandboxesByChatIds is awaited inside the mongoSessionRun transaction. This holds the Mongo transaction open while performing external sandbox deletion (network I/O) and S3 deletions, increasing the risk of transaction timeouts/locks. Additionally, deleteSandboxesByChatIds can throw synchronously (e.g., sandbox env not configured, constructor throws), which would abort the chat deletion transaction. Move sandbox cleanup (and ideally S3 cleanup) outside the transaction and make it best-effort (catch/log) so history deletion isn't blocked.
    test/setup.ts:61
  • Test Mongo connections are no longer closed: afterAll drops the DB but does not close() the connections, which can leave open handles and cause Vitest to hang. Also, dropping the DB in both afterAll and onTestFinished duplicates work and increases test runtime. Consider restoring connection close in afterAll (and pick a single cleanup strategy: drop DB per-test or once per-suite).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +111 to +133
await Promise.allSettled(
instances.map((doc) =>
new SandboxInstance({
appId: doc.appId,
userId: doc.userId,
chatId: doc.chatId
}).delete()
)
);
};
export const deleteSandboxesByAppId = async (appId: string) => {
const instances = await MongoSandboxInstance.find({ appId }).lean();
if (!instances.length) return;

await Promise.allSettled(
instances.map((doc) =>
new SandboxInstance({
appId: doc.appId,
userId: doc.userId,
chatId: doc.chatId
}).delete()
)
);
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

deleteSandboxesByChatIds/deleteSandboxesByAppId constructs SandboxInstance for each record. If sandbox env vars are not configured, the SandboxInstance constructor throws synchronously, which will cause these cleanup functions to reject before reaching Promise.allSettled. Wrap per-instance construction in a try/catch (or early-return when sandbox is disabled) so cleanup is always best-effort and doesn't break chat/app deletion flows.

Copilot uses AI. Check for mistakes.
Comment on lines +81 to +97
async delete() {
await mongoSessionRun(async (session) => {
await MongoSandboxInstance.deleteOne({ sandboxId: this.sandboxId }, { session });
await super.delete();
});
}

async stop() {
await mongoSessionRun(async (session) => {
await MongoSandboxInstance.updateOne(
{ sandboxId: this.sandboxId },
{ $set: { status: SandboxStatusEnum.stoped } },
{ session }
);
await super.stop();
});
}
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

delete()/stop() wrap external adapter calls (super.delete()/super.stop()) inside mongoSessionRun. Mongo transactions can't include the external sandbox service call, so this keeps the DB transaction open across network I/O and can hit maxCommitTimeMS / increase lock time. Prefer updating the DB in a short transaction (or without one), and run the external call outside; if you need consistency, handle partial failures explicitly (e.g., retry queue).

Copilot uses AI. Check for mistakes.
};
}, [historyItem, isShowCite]);

console.log(useComputer, historyItem);
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

console.log(useComputer, historyItem) was left in the component, which will spam logs in production and may leak chat content to the browser console. Please remove this debug statement.

Copilot uses AI. Check for mistakes.
Comment on lines +85 to +87
icon: 'core/app/sandbox/file' as const,
label: t('chat:sandox.files'),
onClick: () => onOpenSandboxModal()
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The i18n key chat:sandox.files appears to have a typo (sandox) and is inconsistent with other new keys like chat:sandbox_files. This makes translations harder to maintain and increases the chance of missing translations. Please rename to a consistently spelled key (and update the locale JSON accordingly).

Copilot uses AI. Check for mistakes.
Comment on lines +54 to +56
archive.on('error', (err) => {
throw err;
});
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Throwing inside archive.on('error', ...) won't be caught by the surrounding try/catch/await flow and can crash the Next.js server process. Handle the error by rejecting the request (set an HTTP error status, res.end()), and make sure the archive/response stream is properly terminated/aborted.

Copilot uses AI. Check for mistakes.
Comment on lines +55 to +88
if (result.error) {
return Promise.reject('Failed to read file');
}

// 尝试将 Uint8Array 转换为 UTF-8 字符串
try {
const decoder = new TextDecoder('utf-8', { fatal: true });
const content = decoder.decode(result.content);
return { action: 'read', content };
} catch (error) {
// 非 UTF-8 内容,返回特殊标记
return { action: 'read', content: '[Binary File - Cannot Display]' };
}
}

case 'write': {
const results = await sandbox.writeFiles([
{
path: body.path,
data: body.content
}
]);
const result = results[0];

if (result.error) {
return Promise.reject('Failed to write file');
}

return { action: 'write', success: true };
}

default:
return Promise.reject('Invalid action');
}
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These branches use Promise.reject('...') with a string. The API layer will return a 500 with an unstructured error payload, and callers lose useful context. Prefer throwing an Error (or returning a typed error response) so error handling/logging is consistent and includes a message/stack.

Copilot uses AI. Check for mistakes.
Comment on lines +156 to 160

// 2. 删除聊天记录和S3文件
// 删除沙盒实例
await deleteSandboxesByAppId(appId);
await getS3ChatSource().deleteChatFilesByPrefix({ appId });
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

deleteAppDataProcessor now awaits deleteSandboxesByAppId(appId). If sandbox is not configured or the downstream delete fails, this will throw and can prevent the rest of the app deletion cleanup from running. Sandbox cleanup should generally be best-effort here (catch/log and continue) so core deletion isn’t blocked by an optional integration.

Copilot uses AI. Check for mistakes.
Comment on lines +234 to +246
<<<<<<< HEAD
"document/content/docs/self-host/upgrading/4-14/4148.en.mdx": "2026-03-06T19:32:23+08:00",
"document/content/docs/self-host/upgrading/4-14/4148.mdx": "2026-03-09T12:04:22+08:00",
"document/content/docs/self-host/upgrading/4-14/41481.en.mdx": "2026-03-09T12:02:02+08:00",
"document/content/docs/self-host/upgrading/4-14/41481.mdx": "2026-03-09T14:24:27+08:00",
=======
"document/content/docs/self-host/upgrading/4-14/4148.en.mdx": "2026-03-03T17:39:47+08:00",
<<<<<<< HEAD
"document/content/docs/self-host/upgrading/4-14/4148.mdx": "2026-03-04T18:18:14+08:00",
>>>>>>> b7d57cb9d (sandbox in chat window)
=======
"document/content/docs/self-host/upgrading/4-14/4148.mdx": "2026-03-05T13:59:50+08:00",
>>>>>>> b9d4f061f (sandbox entry)
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doc-last-modified.json still contains unresolved Git merge conflict markers (<<<<<<<, =======, >>>>>>>), which makes the JSON invalid and will break any tooling that reads this file. Resolve the conflict and ensure the final file is valid JSON.

Copilot uses AI. Check for mistakes.
Comment on lines +85 to +89
const { onOpenSandboxModal, SandboxEditorModal } = useSandboxEditor({
appId,
chatId,
outLinkAuthData
});
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useSandboxEditor sets up a 10s polling interval (useInterval) to call /core/ai/sandbox/checkExist. ResponseTags is rendered per message, so this will create one interval per history item and can cause a large number of repeated network calls and timers. Consider only instantiating the hook when useComputer is true (and ideally at a higher level so it runs once per chat), or add an option to disable polling for this usage.

Copilot uses AI. Check for mistakes.
@github-actions
Copy link

github-actions bot commented Mar 9, 2026

Preview fastgpt Image:

registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-pr:fatsgpt_d3a487cca42511d7493f02d5d3a7b85c3e2289e4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants