Files
paseo/public-docs/sdk/provider-options.zh-CN.md
T
Mohamed Boudra bd15e40e94 Serve paseo.sh in Simplified Chinese (#7373)
* feat(website): serve paseo.sh in Simplified Chinese

Every page of the website now has a Simplified Chinese version under
/zh-CN: the interface, docs, blog posts, comparison pages, legal pages,
all changelog releases and the homepage mockup. English URLs are unchanged.

The URL alone decides the language. There is no browser-language redirect
and no stored preference, because either would have to redirect the
unprefixed English URLs that people share and search engines index.
Internal links carry the page's language instead, and hreflang alternates
point Chinese search results at /zh-CN.

Translated headings pin the English anchor with {#id}, so section links
work in both languages. content-translations.test.ts fails when a page
has no translation or a translation's headings drift from the English.
Changelog releases and plugin listings without a translation render
whole in English under a notice, so a release never waits on one.

Plugin manifests and the registry gain optional translations and
OVERVIEW.zh-CN.md fields; older clients and registries ignore them.

* feat(website): replace the native language select with an EN/ZH menu

The header showed an OS-native select whose popup did not match the site.
The trigger now shows the language abbreviated (EN, ZH) and opens a menu in
the app's dropdown style that names each language in itself, with its name
in the page language underneath. Rows are real links to the same page in
that language; arrows, Escape, outside presses and taps behave as a menu
button, and the menu keeps itself on screen when a narrow header pushes the
trigger toward an edge.

Also drops the stray space after the full-width comma in the Chinese
homepage subtitle.

* docs(website): translate main's new docs and 0.12.0 release notes

Main added Keep run workspaces to the schedules docs, rewrote plugin icons
around inline SVG, and promoted 0.12.0 with new entries. Bring the Chinese
pages and changelog in line so no section falls back to English.

* fix(server): leave plugin listing translations to the registry

The daemon rejected manifests whose translations the registry would refuse,
so a plugin main installs could fail to load here. Paseo never reads
translations; the registry validates them at publish. Docs now say which
checks are automated at publish and which are human review.

* docs(plugins): describe the registry's final overview translation discovery

* style(server): format manifest test

* test(app): measure sidebar rows one at a time

After a reload the developer error toast appears while expectVerticalOrder
measures every row at once. Each concurrent boundingBox runs the toast
locator handler, and only one of them resumes, so the poll timed out on
every attempt since #7424. Measuring sequentially keeps one action in flight.

* test(app): return sidebar row measuring to main

#7480 hides the developer toast instead of running a locator handler, so
measuring the rows concurrently no longer races it. Reverts 41ac23016.

* test(app): wait for the compact shell before opening compact Changes

The shell survives the breakpoint, so right after the resize the wide
Explorer could still be visible: the test skipped the Explorer toggle and
the tab then disappeared, or toggled at the wrong time. Wait for the
compact-shell marker, as the composer helpers do since #7424.

* docs(website): translate main's plugin file panel docs

* test(app): edit the code font size after the font family remount

A committed appearance change remounts the settings screen through
AppearanceStyleBoundary, and the new form starts from the stored size.
Filling the size before that remount lost the edit in CI.

* docs(website): translate main's client/ui import docs

Follows #7474: one /client/ui entry, StreamedText instead of useRevealedText,
SettingsGroup dropped from the settings table, and the new
'UI imports in v0.13' migration section.

* test(app): wait for the previous layout's file panel picker to leave

After a resize the old layout's picker animates out while the new one is
already mounted, so the Use button matched two elements and the strict
locator failed. Wait for the shell's layout and a single picker first.
2026-10-21 13:13:03 +07:00

8.4 KiB
Raw Blame History

title, description, nav
title description nav
Provider 选项 从 SDK 创建的 Codex、Claude 和 OpenCode Agent 的沙箱、权限和网络规则。 Provider 选项

Provider 选项

Provider 选项是传给 Provider 的一个不透明的 Record<string, unknown>。如何校验和应用它由 Provider 决定。Claude、Codex 和 OpenCode 使用严格的 schema:未知或拼错的键会使 Agent 创建失败,并在错误信息中指出该键。不处理选项的 Provider 会忽略这个记录。Pi、OMP、ACP 和插件 Provider 会解释它们自己的键。

你可以在两个地方设置选项:

  • Provider 默认值:config.json → agents.providers.<id>.options。
  • 单个 Agent:client.agents.create() 中的 config.options。它在协议中的名称是 providerOptions。

在会话启动或恢复时,daemon 会把 Agent 的选项深度合并到 Provider 默认值之上。普通对象递归合并;数组、标量和 null 会替换基础值。只有 Agent 自己的选项会被保存。修改 config.json 中的默认值会在下次启动或恢复时生效。

例如,先设置一次 Codex 默认值:

{
  "agents": {
    "providers": {
      "codex": {
        "options": {
          "sandbox_mode": "read-only",
          "approval_policy": "never",
          "sandbox_workspace_write": { "network_access": false }
        }
      }
    }
  }
}

然后用 config.options: { sandbox_mode: "workspace-write" } 创建一个 Agent。它会得到 workspace-write,同时保留 approval_policy: "never" 和 sandbox_workspace_write.network_access: false。没有单独选项的 Agent 会得到上面的默认值。键是 Provider 原生的;各 Provider 接受的选项见下面各节。

Provider 选项不是主机边界。它们约束的是 Agent CLI,而 Agent CLI 以你的用户身份运行在你的机器上。对于不受信任的工作,请在容器或单独的机器上运行 daemon。参见安全。

Codex

把写入限制在一个目录内,切断网络访问,并停止审批提示,让运行可以无人值守:

import { createPaseoClient } from "@getpaseo/client";

const client = createPaseoClient({ url: "ws://127.0.0.1:6767/ws" });
await client.connect();

const agent = await client.agents.create({
  config: {
    provider: "codex/gpt-5.5",
    options: {
      approval_policy: "never",
      sandbox_mode: "workspace-write",
      sandbox_workspace_write: {
        writable_roots: ["/Users/me/dev/storefront"],
        network_access: false,
        exclude_slash_tmp: true,
      },
      web_search: "disabled",
    },
  },
  cwd: "/Users/me/dev/storefront",
  prompt: "Fix the failing checkout test.",
});

const result = await agent.waitForFinish();
console.log(result.status, result.lastMessage);

await client.close();
选项 取值
approval_policy untrusted、on-request、never 或 { granular: { … } }
sandbox_mode read-only、workspace-write、danger-full-access
sandbox_workspace_write writable_roots、network_access、exclude_slash_tmp、exclude_tmpdir_env_var
web_search disabled、cached、indexed、live
features multi_agent_v2、network_proxy(布尔值,或代理/域名策略对象)

approval_policy: "never" 只是去掉了提示。Agent 被允许接触什么由 sandbox_mode 决定。设置 never 而不设置沙箱模式,会让无人值守的 Agent 拥有完全访问权限。

Claude

开启 Claude 自己的沙箱,把写入限制在项目内,禁止读取凭据目录,并只允许两个域名:

import { createPaseoClient } from "@getpaseo/client";

const client = createPaseoClient({ url: "ws://127.0.0.1:6767/ws" });
await client.connect();

const agent = await client.agents.create({
  config: {
    provider: "claude/claude-sonnet-5",
    options: {
      disallowedTools: ["WebFetch"],
      sandbox: {
        enabled: true,
        failIfUnavailable: true,
        allowUnsandboxedCommands: false,
        filesystem: {
          allowWrite: ["/Users/me/dev/storefront"],
          denyRead: ["/Users/me/.ssh", "/Users/me/.aws"],
        },
        network: {
          allowedDomains: ["registry.npmjs.org", "github.com"],
          strictAllowlist: true,
        },
      },
    },
  },
  cwd: "/Users/me/dev/storefront",
  prompt: "Install dependencies and run the focused test.",
});

const result = await agent.waitForFinish();
console.log(result.status, result.lastMessage);

await client.close();
选项 取值
allowedTools Agent 可以不经询问就使用的工具名称
disallowedTools Agent 永远不能使用的工具名称
additionalDirectories Agent 可以访问的额外目录
sandbox enabled、failIfUnavailable、allowUnsandboxedCommands、excludedCommands、filesystem、network
settings permissions(allow/ask/deny 规则列表)以及嵌套的 sandbox

failIfUnavailable: true 会在无法建立沙箱时让 Agent 启动失败。不设置时,Claude 会在没有沙箱的情况下运行。

sandbox.filesystem 接受 allowWrite、denyWrite、allowRead 和 denyRead。sandbox.network 接受 allowedDomains、deniedDomains、strictAllowlist 以及代理设置。

OpenCode

允许读取和编辑,禁止任何超出项目范围的访问,并按模式控制 shell 命令:

import { createPaseoClient } from "@getpaseo/client";

const client = createPaseoClient({ url: "ws://127.0.0.1:6767/ws" });
await client.connect();

const agent = await client.agents.create({
  config: {
    provider: "opencode/opencode/gpt-5.5",
    options: {
      permission: {
        read: "allow",
        edit: "allow",
        webfetch: "deny",
        external_directory: "deny",
        bash: {
          "git status": "allow",
          "git diff*": "allow",
          "git push*": "deny",
          "*": "ask",
        },
      },
    },
  },
  cwd: "/Users/me/dev/storefront",
  prompt: "Implement the requested change and show me the diff.",
});

const result = await agent.waitForFinish();
console.log(result.status, result.lastMessage);

await client.close();

每项权限的取值是 ask、allow 或 deny。带有目标的工具(read、edit、glob、grep、list、bash、task、external_directory、repo_clone、repo_overview、lsp、skill)还接受一个模式映射,其中后面的键作为兜底。没有目标的工具(todowrite、question、webfetch、websearch、codesearch、doom_loop)只接受单个操作值。

把 permission: "deny" 写成单个字符串,会一次性应用到所有工具。

ask 会在 Paseo 中变成一个权限请求,请求待处理期间 waitForFinish() 返回 permission。无人值守的运行请使用 allow 和 deny。如何响应待处理的请求,请参见事件。

模式与选项

modeId 从 Provider 公布的列表中选择一个 Paseo 模式,daemon 会在应用中显示这个列表,并通过 Provider 发现报告它。options 是 Provider 自己的配置。两者是独立的控制项,可以同时设置:

config: {
  provider: "codex/gpt-5.5",
  modeId: "full-access",
  options: {
    approval_policy: "never",
    sandbox_mode: "read-only",
  },
}

两者重叠时,以 options 为准。上例中,即使 full-access 本来会授予更多权限,Codex 仍以只读方式运行。