Skip to content

Docs/pi agent integration#701

Merged
kinwin-ustc merged 9 commits into
TencentCloud:masterfrom
chaojixinren:docs/pi-agent-integration
Jul 3, 2026
Merged

Docs/pi agent integration#701
kinwin-ustc merged 9 commits into
TencentCloud:masterfrom
chaojixinren:docs/pi-agent-integration

Conversation

@chaojixinren

@chaojixinren chaojixinren commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds an end-to-end Pi Agent integration for #698: a bilingual guide plus a
runnable example project, following the layout and quality bar of the existing
integration examples.

What Changed

  • Runnable example at examples/pi-agent-integration/:
    • Dockerfile — Node.js 24 + @earendil-works/pi-coding-agent on top of
      ghcr.io/tencentcloud/cubesandbox-base:2026.16; envd already listens on :49983.
    • run_pi_agent.py — headless one-shot run (pi --version preflight → seed
      project → pi --print --mode json → stream stdout, key injected per-command via envs=).
    • resume_pi_agent.py — pause/resume across two turns; verifies /workspace
      and Pi's state dir (/root/.pi/agent) survive the snapshot. Manual
      try/finally lifecycle (no context manager) so the pause is not undone.
    • network_policy.py — default-deny egress + CubeEgress inject so the
      provider key rides the wire and never enters the VM.
    • env_utils.py, bilingual README.md / README_zh.md, .env.example,
      .gitignore, requirements.txt.
  • Integration guide in both languages, on the _template.md frontmatter,
    linked from both index tables:
    • docs/guide/integrations/pi-agent.md
    • docs/zh/guide/integrations/pi-agent.md

Acceptance Criteria (#698)

  1. End-to-end guide — template build, deps, API key injection, network/egress
    policy, snapshot-based session persistence. ✅
  2. Runnable example under examples/ with template definition + reproducible
    flow + bilingual README. ✅
  3. Use cases & best practices (isolated dev, run agent-generated code, snapshot
    checkpoint/resume). ✅
  4. FAQ / troubleshooting aligned with existing egress / auth / template mechanics. ✅
  5. Docs placed under docs/guide/integrations following the existing template. ✅

Test Plan

  • python3 -m py_compile examples/pi-agent-integration/*.py
  • env_utils helper checks (LLM host resolution, credential inject shape, vault env excludes secrets)
  • run/resume/network_policy --help parse cleanly
  • cd docs && npm run docs:build
  • git diff --check clean
  • docker build --platform linux/amd64 succeeds (~76s; image 551 MB)
  • envd /health returns 204 (probe passes); envd 0.5.13; pi 0.80.3; node 24.18; git/python3/rg/jq present

Live CubeSandbox cluster run

Ran against a live single-node CubeSandbox cluster (a registered pi-agent-cube
template, pi 0.80.3). The LLM provider was an Anthropic-compatible gateway
registered as a custom Pi provider (model glm-5.2), because no native
Anthropic key was available in the test environment.

  • run_pi_agent.py — sandbox created, pi --version preflight, seeded
    project, one-shot task drove bash/write tool calls and wrote
    /workspace/result.md; exit 0. The runner's parsed transcript (assistant
    text + tool calls) renders cleanly; --raw still dumps the JSONL stream.
  • resume_pi_agent.py — turn 1 wrote /workspace/plan.md; sandbox.pause()
    then Sandbox.connect() resumed; /workspace/plan.md and Pi's state dir
    (/root/.pi/agent) survived the snapshot; turn 2 read the plan and continued
    (wrote current_time.py + progress.md, plan.md left intact); exit 0.
  • network_policy.py — default-deny egress verified on-cluster: a non-LLM
    host (example.com) is blocked, and printenv inside the sandbox shows the
    provider key unset/placeholder (the real key never enters the VM).
  • network_policy.py full LLM call via CubeEgress inject — verified end-to-end
    on-cluster. A bare request (no auth header) is authenticated by the injected
    key and the LLM returns HTTP 200, while the VM only ever holds a placeholder.
    Pi (Node) additionally needs NODE_EXTRA_CA_CERTS to trust the CubeEgress
    interception CA (now set by the script).
截屏2026-07-02 16 43 10 截屏2026-07-02 16 43 33 截屏2026-07-02 16 43 51

Closes #698

Adds an end-to-end Pi Agent integration for TencentCloud#698: bilingual docs plus a
runnable example project, following the layout and quality bar of the
existing integration examples.

- examples/pi-agent-integration/: Dockerfile (Node.js + Pi CLI on the
  cubesandbox-base image), run_pi_agent.py (headless one-shot run),
  resume_pi_agent.py (pause/resume session persistence via manual
  lifecycle), network_policy.py (default-deny egress + on-the-wire key
  injection), env_utils.py, bilingual README, .env.example, .gitignore,
  requirements.txt
- docs/guide/integrations/pi-agent.md and docs/zh/guide/integrations/pi-agent.md
- Register the guide in both integrations index tables

Validation (no live cluster; dev machine is Apple Silicon macOS):
- python3 -m py_compile examples/pi-agent-integration/*.py
- env_utils helper checks (LLM host resolution, credential inject, vault
  env excludes secrets)
- run/resume/network_policy --help parse cleanly
- docs build (vitepress) succeeds
- git diff --check clean

Closes TencentCloud#698

Signed-off-by: chaojixinren <chaoji_xinren@163.com>
Replaces references to the outdated model version "claude-sonnet-4-20250514" with the updated version "claude-sonnet-4-6" in both English and Chinese documentation, as well as in example environment configurations and utility scripts. This ensures consistency across the integration guides and examples for the Pi Agent.

- Updated model version in docs/guide/integrations/pi-agent.md
- Updated model version in docs/zh/guide/integrations/pi-agent.md
- Updated model version in examples/pi-agent-integration/.env.example
- Updated model version in examples/pi-agent-integration/env_utils.py

Signed-off-by: chaojixinren <chaoji_xinren@163.com>
pi_command() built the Pi command without --print, so Pi launched its
interactive TUI and hung over the E2B exec channel instead of running
headless. Verified against pi 0.80.3 that --print is the non-interactive
flag and that --approve is a boolean (trust project-local files) with the
prompt passed as the trailing positional argument.

- env_utils.py: emit `pi --print --mode json ...`
- docs/guide/integrations/pi-agent.md and zh: update command snippets and
  clarify --print / --approve semantics

Signed-off-by: chaojixinren <chaoji_xinren@163.com>
@chaojixinren chaojixinren force-pushed the docs/pi-agent-integration branch from b650faf to 46127c4 Compare July 1, 2026 17:07
Comment thread examples/pi-agent-integration/network_policy.py Outdated
Comment thread docs/guide/integrations/pi-agent.md
Comment thread examples/pi-agent-integration/run_pi_agent.py Outdated
Comment thread examples/pi-agent-integration/network_policy.py Outdated
Comment thread examples/pi-agent-integration/env_utils.py Outdated
Addresses cubesandbox-bot review on TencentCloud#701:

- network_policy.py + both integration guides: create the sandbox with
  allow_internet_access=False. With =True, unmatched traffic is forwarded at
  L3/L4 and bypasses CubeEgress, so the "default-deny" never held. With =False,
  CubeVS drops everything except the LLM host, which is auto-allowed from the
  L7 rules.
- network_policy.py: remove the TypeError fallback that silently dropped
  allow_internet_access (it would re-enable full internet egress).
- run_pi_agent.py: narrow the commands.run TypeError retry to the envs/env
  signature mismatch so unrelated TypeErrors are not masked.
- env_utils.py: add explicit "format": "${SECRET}" on the anthropic-version
  inject entry instead of relying on the server default.

Signed-off-by: chaojixinren <chaoji_xinren@163.com>
Verified end-to-end on a live CubeSandbox cluster. Fixes from the live run:

- run_pi_agent.py: run commands as user="root" — /workspace and Pi's state
  dir (/root/.pi/agent) are root-owned; the default e2b exec user cannot write.
- resume_pi_agent.py: sandbox.pause() can return a bool (success), not the
  resume handle; keep the original sandbox_id for connect().
- network_policy.py: use the native cubesandbox SDK with Rule/Match/Action/
  Inject. The e2b SDK serialises network.rules as a map, which CubeAPI rejects
  (it expects the CubeEgress rule list); cubesandbox is the canonical path per
  docs/guide/security-proxy.md.
- env_utils.py: provider_inject() returns CubeEgress Inject specs.
- requirements.txt: add cubesandbox (used by network_policy.py).
- docs: update egress snippet to the cubesandbox Rule/Inject form; fix
  anthropic-version to 2023-06-01.

Signed-off-by: chaojixinren <chaoji_xinren@163.com>
Comment thread examples/pi-agent-integration/env_utils.py
Comment thread examples/pi-agent-integration/env_utils.py Outdated
Comment thread examples/pi-agent-integration/Dockerfile
Comment thread examples/pi-agent-integration/run_pi_agent.py Outdated
Comment thread examples/pi-agent-integration/run_pi_agent.py Outdated
@cubesandboxbot

cubesandboxbot Bot commented Jul 2, 2026

Copy link
Copy Markdown

Pi Agent Integration — Code Review Summary

Overall, this is a well-structured, thoroughly tested PR. The code is clean, the security model is thoughtfully documented, the docs are accurate and bilingual, and the example scripts are practical. Below are the findings worth flagging before merge.

Security (1 issue, moderate)

Self-modifying-instruction risk in resume_pi_agent.py
pi_command() defaults to approve=True, trusting CLAUDE.md/AGENTS.md in the workspace. Turn 1's Pi agent can write a malicious CLAUDE.md to /workspace, which Turn 2 then blindly trusts via --approve after the pause/resume. The resume script has no files that need trusting pre-turn-2, so passing approve=False closes this gap. (Inline comment on line 199)

Code quality / maintainability (1 issue)

Fragile exception-message matching in _pi_common.py
The TypeError retry guard checks "envs" not in str(exc) — exception messages are implementation-defined and not part of Python's spec. This may silently mask bugs across Python versions or SDK changes. (Inline comment on line 133)

Dockerfile (1 issue)

Redundant packagesbash, ca-certificates, and curl are already present in the base image. Removing them trims a few seconds from every build. (Inline comment on line 29)

Documentation (1 issue)

Missing ANTHROPIC_BASE_URL in README env table — The env table in examples/pi-agent-integration/README.md omits ANTHROPIC_BASE_URL, which both the integration guide and .env.example document as a key variable for custom endpoints. (Inline comment on line 84)

Performance (minor)

Extra sandbox round-trip for pi --version — Both run_pi_agent.py and resume_pi_agent.py issue a separate sandbox.commands.run() call purely for a version check, adding ~200-500ms of gRPC overhead. This can be inlined into the main command chain. (Inline comments on line 161 of both scripts)

Positive highlights

  • Clear, explicit security commentary in every script that handles credentials, directing users to the vault pattern for production.
  • Duck-typed SDK abstraction (_pi_common.py) works with both e2b and cubesandbox SDKs — well designed.
  • Excellent Docker layer separation (Pi version bumps don't invalidate the OS layer).
  • Bilingual docs are consistent and cross-linked correctly; all code snippets match the implementation.
  • --ignore-scripts on npm install and allow_internet_access=False in the vault pattern show solid security hygiene.

chaojixinren added a commit to chaojixinren/CubeSandbox that referenced this pull request Jul 2, 2026
…e, deps)

Addresses cubesandbox-bot review on TencentCloud#701:

- Extract run_command / ensure_success / sandbox_identifier / stream_writer
  into a shared _pi_common.py so run_pi_agent / resume_pi_agent /
  network_policy no longer import from one another (env_utils.py stays
  focused on .env/config).
- env_utils.py: pi_command() gains an `approve` flag (default True) so callers
  can disable --approve (which trusts project-local AGENTS.md/CLAUDE.md) in
  high-security workflows.
- requirements.txt: drop unused `rich`; README file trees add _pi_common.py.
- docs: caveat that the direct (`envs=`) key may be cached by Pi under
  /root/.pi/agent and survive pause/resume; prefer the vault flavor.

Co-authored-by: Cursor <cursoragent@cursor.com>
Signed-off-by: chaojixinren <chaoji_xinren@163.com>
…e, deps)

Addresses cubesandbox-bot review on TencentCloud#701:

- Extract run_command / ensure_success / sandbox_identifier / stream_writer
  into a shared _pi_common.py so run_pi_agent / resume_pi_agent /
  network_policy no longer import from one another (env_utils.py stays
  focused on .env/config).
- env_utils.py: pi_command() gains an `approve` flag (default True) so callers
  can disable --approve (which trusts project-local AGENTS.md/CLAUDE.md) in
  high-security workflows.
- requirements.txt: drop unused `rich`; README file trees add _pi_common.py.
- docs: caveat that the direct (`envs=`) key may be cached by Pi under
  /root/.pi/agent and survive pause/resume; prefer the vault flavor.

Signed-off-by: chaojixinren <chaoji_xinren@163.com>
@chaojixinren chaojixinren force-pushed the docs/pi-agent-integration branch from a5c1dff to 939dedc Compare July 2, 2026 07:49
Parse the pi --mode json event stream and print assistant text, tool calls, and failures instead of raw JSONL. Add --raw / PI_STREAM_RAW to keep the raw stream, and document the behavior in the READMEs and integration guides.

Signed-off-by: chaojixinren <chaoji_xinren@163.com>
@chaojixinren chaojixinren force-pushed the docs/pi-agent-integration branch from 004e50d to 1a4889b Compare July 2, 2026 08:54
Comment thread examples/pi-agent-integration/Dockerfile
Comment thread examples/pi-agent-integration/run_pi_agent.py
Comment thread examples/pi-agent-integration/resume_pi_agent.py
Comment thread examples/pi-agent-integration/env_utils.py Outdated
Comment thread examples/pi-agent-integration/env_utils.py Outdated
network_policy.py failed end-to-end because Pi runs on Node.js, which ignores the system CA store and rejected CubeEgress's TLS-interception cert with a Connection error. Set NODE_EXTRA_CA_CERTS (override via PI_NODE_EXTRA_CA_CERTS) so Pi trusts the CubeEgress root CA; document it in the READMEs and guides. Verified on a live cluster: CubeEgress injects the real key on the wire (bare request -> HTTP 200) while the VM only holds a placeholder.

Signed-off-by: chaojixinren <chaoji_xinren@163.com>
…fault, key scoping)

env_utils.py: normalize PI_PROVIDER case so lookups/inject are case-insensitive; add PROVIDER_DEFAULT_MODEL and fail loudly for non-Anthropic providers without PI_MODEL instead of sending a Claude model name; build_pi_env forwards only the active provider's key(s), not every known secret. Dockerfile: install Pi in its own layer so PI_VERSION bumps don't rebuild the OS/Node layer. run_pi_agent.py / resume_pi_agent.py: document the open-egress key-exfiltration risk of the direct flavor and point to network_policy.py.

Signed-off-by: chaojixinren <chaoji_xinren@163.com>
@chaojixinren chaojixinren marked this pull request as ready for review July 2, 2026 09:39
@chaojixinren chaojixinren requested a review from tinklone as a code owner July 2, 2026 09:39
Comment thread examples/pi-agent-integration/resume_pi_agent.py
Comment thread examples/pi-agent-integration/_pi_common.py
Comment thread examples/pi-agent-integration/Dockerfile
Comment thread examples/pi-agent-integration/run_pi_agent.py
Comment thread examples/pi-agent-integration/README.md
@kinwin-ustc

Copy link
Copy Markdown
Collaborator

Thanks for your contribution

@kinwin-ustc kinwin-ustc merged commit cea6cca into TencentCloud:master Jul 3, 2026
1 check passed
@chaojixinren chaojixinren deleted the docs/pi-agent-integration branch July 4, 2026 14:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature Request] Integrate CubeSandbox with Pi Agent

3 participants