From e1144aafe8b0aa4bb041fe829d375d5d94bf8c6a Mon Sep 17 00:00:00 2001 From: Anycodes <21079031+anycodes@users.noreply.github.com> Date: Sun, 18 Oct 2026 02:20:19 +0000 Subject: [PATCH] fix: align Node schema and source installation guidance --- .agents/README.md | 23 +++++++ ...2026-10-18-config-provider-reservations.md | 60 +++++++++++++++++++ ...2026-10-18-config-provider-reservations.md | 59 ++++++++++++++++++ .github/workflows/ci.yml | 53 ++++++++++++++++ CHANGELOG.md | 15 +++++ README.md | 28 ++++++--- README.zh-CN.md | 27 ++++++--- src/config-keys.json | 3 +- test/config-keys.test.mjs | 15 +++++ 9 files changed, 263 insertions(+), 20 deletions(-) create mode 100644 .agents/README.md create mode 100644 .agents/evidence/verify/2026-10-18-config-provider-reservations.md create mode 100644 .agents/notes/proposed/process/2026-10-18-config-provider-reservations.md create mode 100644 .github/workflows/ci.yml create mode 100644 CHANGELOG.md diff --git a/.agents/README.md b/.agents/README.md new file mode 100644 index 0000000..a24651b --- /dev/null +++ b/.agents/README.md @@ -0,0 +1,23 @@ +# Node SDK engineering records + +This repository owns decisions and verification for its HTTP client, public +configuration schema, ESM/TypeScript exports and examples. New records use English; +source contracts in other repositories are linked through absolute GitHub URLs. + +Notes live in `notes/proposed//YYYY-MM-DD-.md`. +Acceptance moves them to `notes/implemented/` with the same category and an updated +`Status:`. Rejected and superseded notes use flat state directories. A note has +Problem, Decision, API Design, Alternatives considered, Dependencies, Test Strategy +and Acceptance criteria sections. + +Evidence lives in `evidence/verify/YYYY-MM-DD-.md` and records revision, +environment, actual commands/results, behavior, cleanup and unrun gates. Use PASS, +PARTIAL, BLOCKED or FAIL honestly. Merged evidence is immutable; add a new file for +a later run. Keep credentials, private data and raw sensitive logs out of records. + +Include scoped records in the owning PR. Run applicable tests/build, inspect exact +latest-head required CI and independent review, and verify actual remote merge +state. A local/runtime result is not cloud acceptance or package publication. + +- [Configuration reservations and installation](notes/proposed/process/2026-10-18-config-provider-reservations.md) +- [Verification](evidence/verify/2026-10-18-config-provider-reservations.md) diff --git a/.agents/evidence/verify/2026-10-18-config-provider-reservations.md b/.agents/evidence/verify/2026-10-18-config-provider-reservations.md new file mode 100644 index 0000000..dbc860b --- /dev/null +++ b/.agents/evidence/verify/2026-10-18-config-provider-reservations.md @@ -0,0 +1,60 @@ +# Verification: Node configuration reservations and source installation + +- Date: 2026-10-18 +- Base: `90335324461b6d01e361908211b7d69a4c57305b`. +- Authority: Python SDK `145341d462df2f4753c03a62365114f1872acd1a`. +- Result: PARTIAL (local acceptance complete; new exact-head CI/review pending). +- Environment: Linux; Node 22.22.2; npm 12.0.2; matching server 0.3.0 with Python 3.12.15. + +## Reproduction and authority + +The actual `config_keys.py --json` export from the pinned Python source and the +unchanged Node JSON differ only at `reserved_provider_ids`: Node additionally +reserves `e2b`. All 23 key entries and other metadata agree. After the one-id fix, +the complete parsed JSON structures match. CI repeats the full-structure comparison +against a pinned source checkout rather than fetching mutable main or only checking +one field. + +The new public-export test was executed after `npm run build` against the unchanged +schema: **1 FAIL**, with `true !== false`. This is a real negative control through +`dist/index.js`, not an assertion about source prose. + +An anonymous GET to `https://registry.npmjs.org/@agent-sandbox%2Fsdk` returned +HTTP 404 and `{ "error": "Not found" }`. No authentication header was sent. +The publication statement is a dated observation, not a future availability claim. + +## Commands and results + +- `npm ci`: PASS, committed lockfile unchanged. +- `npm run typecheck`: PASS. +- `npm test` with matching `python3` server environment: **9 PASS / zero SKIP**, + 821.36 milliseconds; includes the public export and actual local server loop. +- `node examples/agent-loop.mjs` with the same Python environment: PASS; health, + command stdout `4` plus newline, file round trip, SIGTERM and reaped process. +- Complete JSON comparison with actual pinned Python `--json` output: PASS. +- `npm pack --json`: PASS, 22 package files. Fresh temporary consumer installs + from both the built local checkout and the packed tarball: PASS. Each imports + `@agent-sandbox/sdk`, verifies `e2b` is unreserved, keeps the builtin reservation, + resolves the existing env name and exports `ServerClient`. +- The first verification harness assumed array-shaped npm JSON and stopped before + consumer installation. Local npm returned an object keyed by package name; + correcting only the harness enabled the two actual successful installations. +- Workflow YAML parses; the whole-schema comparison step uses the pinned source's + real `--json` export and compares complete JSON structures. +- Scoped diff and relative engineering-record links: PASS. + +## CI and review scope + +The repository had no tracked workflow and its remote workflow count was zero. +This change introduces normal Node 20/22 checks with fixed Python 3.12.15, the pinned +server source, lockfile installation, whole-schema comparison, typecheck and existing +real local tests. No package publishing step, cloud credential or cloud operation +is added. Local Node 22 success does not replace the pending Node 20/22 hosted run. + +## Cleanup and limits + +Temporary consumer projects/artifacts are task-owned and removed after validation. +The local server process is terminated and reaped by the existing loop; no cloud +resource was created. Public npm publication, Node cloud-provider execution and +real native-provider acceptance are outside this change. Existing unrelated original +checkout engineering proposals remain untouched. diff --git a/.agents/notes/proposed/process/2026-10-18-config-provider-reservations.md b/.agents/notes/proposed/process/2026-10-18-config-provider-reservations.md new file mode 100644 index 0000000..5b1868f --- /dev/null +++ b/.agents/notes/proposed/process/2026-10-18-config-provider-reservations.md @@ -0,0 +1,59 @@ +# Decision: Synchronize the public configuration contract + +Status: proposed + +## Problem + +The Node schema still reserves `e2b`, unlike the authoritative Python export where +it is an installable catalog id. Both README languages also give an immediate +public npm install command although current package metadata returns 404. + +## Decision + +Remove the stale id while preserving all built-in/core reservations, existing 23 +keys, ESM types, env aliases and HTTP behavior. Document independent lockfile-based +source build and local-dependency installation in both languages. Add the missing +normal PR CI for Node 20/22, using Python 3.12.15 and a matching pinned server source. +No workflow existed before this change; the new checks are not historical gates. + +## API Design + +`configSchema.reserved_provider_ids` no longer includes `e2b`. No exported symbol, +configuration key or provider execution API is added. The public npm installation +command is described as applicable after publication; this change does not publish. + +## Alternatives considered + +- Keep the old id: preserves a contradictory public metadata contract. +- Change Python to match stale Node metadata: rejects an intentional catalog id. +- Claim source builds prove npm publication: contradicted by the registry result. +- Test only the source JSON: misses the built public export and real package use. + +## Dependencies + +- Schema: https://github.com/Alibaba-Agent-Sandbox/nodejs-sdk/issues/1 +- Installation: https://github.com/Alibaba-Agent-Sandbox/nodejs-sdk/issues/2 +- Authority: https://github.com/Alibaba-Agent-Sandbox/python-sdk/blob/145341d462df2f4753c03a62365114f1872acd1a/client-sdk/src/agent_sandbox/utils/config_keys.py +- CI source/server revision: `145341d462df2f4753c03a62365114f1872acd1a`. + +## Test Strategy + +Demonstrate the public-export regression against a built unchanged schema before +fixing it. Compare the complete JSON structure with the actual pinned Python +export. Execute lockfile install, typecheck, the full existing tests and actual +local server loop. Verify fresh consumer installation/import from the built local +checkout and packed artifact. Require exact-head Node 20/22 CI and independent +review before any authorized merge; no cloud or release is involved. + +## Acceptance criteria + +- Built public metadata matches the Python contract, leaving `e2b` unreserved. +- Existing built-in/core ids and all 23 keys remain unchanged. +- Regression fails before the fix; current unit/runtime/package checks pass. +- Both README languages disclose verified publication status and usable source setup. +- CI compares the complete source schema and runs existing real local behavior. +- Changelog and owner records are included; publication/merge evidence is not invented. + +## Evidence + +- [Verification](../../../evidence/verify/2026-10-18-config-provider-reservations.md) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..1710fcd --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,53 @@ +name: CI + +on: + pull_request: + push: + branches: [main] + +permissions: + contents: read + +jobs: + test: + name: Node.js ${{ matrix.node }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + node: [20, 22] + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node }} + cache: npm + - uses: actions/setup-python@v5 + with: + python-version: "3.12.15" + - name: Check out the matching Python server source + uses: actions/checkout@v4 + with: + repository: Alibaba-Agent-Sandbox/python-sdk + ref: 145341d462df2f4753c03a62365114f1872acd1a + path: python-sdk + - name: Install the local server prerequisite + run: python -m pip install ./python-sdk/server-sdk + - name: Compare the complete Python and Node configuration schema + run: | + python - <<'PY' + import json + import subprocess + import sys + from pathlib import Path + + exported = subprocess.check_output( + [sys.executable, "python-sdk/client-sdk/src/agent_sandbox/utils/config_keys.py", "--json"], + text=True, + ) + assert json.loads(exported) == json.loads(Path("src/config-keys.json").read_text()) + print("Complete Python/Node configuration schema matches") + PY + - run: npm ci + - run: npm run typecheck + - run: npm test diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..aacb6a0 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,15 @@ +# Changelog + +## [Unreleased] + +### Fixed + +- Match the Python configuration schema by leaving the installable `e2b` catalog + provider id unreserved while preserving all built-in/core reservations. +- Explain the current source-checkout installation path in English and Chinese; + public npm package metadata returns 404 until publication. + +### Added + +- A PR CI matrix for Node.js 20/22, including the existing real local server loop + against a pinned Python server source. No publication workflow is added. diff --git a/README.md b/README.md index df9c20c..2b27721 100644 --- a/README.md +++ b/README.md @@ -13,19 +13,24 @@ It is **not** a port of `Sandbox.create`, cloud providers, or the server SDK. Cr ## Install -```bash -npm install @agent-sandbox/sdk -``` - -The published entry is `dist/`. From a checkout: +`@agent-sandbox/sdk` is not published to public npm yet (package metadata returned +HTTP 404 on 2026-10-18). Build the `dist/` entry from a checkout: ```bash -npm install -npm test -node examples/agent-loop.mjs +git clone https://github.com/Alibaba-Agent-Sandbox/nodejs-sdk.git +cd nodejs-sdk +npm ci +npm run build ``` -`npm test` builds first, then runs `node:test`. +To use the package-name imports below from another project, install that built +checkout as a local dependency with `npm install ../nodejs-sdk` (adjust the path). +The public command `npm install @agent-sandbox/sdk` applies after publication. + +For validation, run `npm run typecheck` and `npm test`. The latter builds first, +then runs `node:test`, including a real local server loop. That loop requires +`agent-sandbox-server` in the `python3` environment; it needs no cloud credentials. +The PR workflow checks Node.js 20 and 22 with a pinned Python server source. ## ServerClient @@ -59,6 +64,11 @@ await server.close(); `src/config-keys.json` is the canonical list, exported from `python -m agent_sandbox.utils.config_keys --json`. Each key has exactly one environment variable. There are no aliases. `readEnv` reads only that name. +`configSchema.reserved_provider_ids` follows the +[Python registry](https://github.com/Alibaba-Agent-Sandbox/python-sdk/blob/145341d462df2f4753c03a62365114f1872acd1a/client-sdk/src/agent_sandbox/utils/config_keys.py): +built-in/core identifiers stay reserved, while the installable catalog id `e2b` +is available. Provider execution belongs to the Python SDK and `abx`. + Product keys use the `ABX_` prefix: `ABX_SANDBOX_API_KEY`, `ABX_SANDBOX_BASE_URL`, `ABX_SANDBOX_DOMAIN`, `ABX_PROVIDER`. Where the vendor already publishes a name, that name is the environment variable: `ALICLOUD_ACCESS_KEY_ID`, `ALICLOUD_ACCESS_KEY_SECRET`, `ALIBABA_CLOUD_REGION_ID`, and `GITHUB_TOKEN`. diff --git a/README.zh-CN.md b/README.zh-CN.md index 105d970..4e2f6c7 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -13,19 +13,23 @@ ## 安装 -```bash -npm install @agent-sandbox/sdk -``` - -发布入口是 `dist/`。在检出的仓库里: +`@agent-sandbox/sdk` 尚未发布到公共 npm(2026-10-18 查询包元数据返回 HTTP 404)。 +请从独立检出的源码构建 `dist/` 入口: ```bash -npm install -npm test -node examples/agent-loop.mjs +git clone https://github.com/Alibaba-Agent-Sandbox/nodejs-sdk.git +cd nodejs-sdk +npm ci +npm run build ``` -`npm test` 会先构建,再跑 `node:test`。 +在其他项目中使用下方的包名导入示例时,先用 `npm install ../nodejs-sdk` +把构建好的检出目录作为本地依赖安装(请调整路径)。 +公共安装命令 `npm install @agent-sandbox/sdk` 适用于正式发布之后。 + +验证时运行 `npm run typecheck` 和 `npm test`。后者先构建,再执行 `node:test`, +其中包含真实本地服务循环,需要 `python3` 环境已安装 `agent-sandbox-server`,不需要云凭据。 +新增 PR 工作流使用固定的 Python server 源码,检查 Node.js 20 和 22。 ## ServerClient @@ -59,6 +63,11 @@ await server.close(); `src/config-keys.json` 是规范列表,来自 `python -m agent_sandbox.utils.config_keys --json`。每个 key 只有一个环境变量,没有别名。`readEnv` 只读这个名字。 +`configSchema.reserved_provider_ids` 遵循 +[Python 注册表](https://github.com/Alibaba-Agent-Sandbox/python-sdk/blob/145341d462df2f4753c03a62365114f1872acd1a/client-sdk/src/agent_sandbox/utils/config_keys.py): +内置及核心标识仍保留,可安装的目录提供方标识 `e2b` 不再保留。 +提供方执行由 Python SDK 和 `abx` 负责。 + 产品 key 使用 `ABX_` 前缀:`ABX_SANDBOX_API_KEY`、`ABX_SANDBOX_BASE_URL`、`ABX_SANDBOX_DOMAIN`、`ABX_PROVIDER`。 厂商已经公布名字时,环境变量就用那个名字:`ALICLOUD_ACCESS_KEY_ID`、`ALICLOUD_ACCESS_KEY_SECRET`、`ALIBABA_CLOUD_REGION_ID`,以及 `GITHUB_TOKEN`。 diff --git a/src/config-keys.json b/src/config-keys.json index 5fd9431..22b9236 100644 --- a/src/config-keys.json +++ b/src/config-keys.json @@ -14,8 +14,7 @@ "shortcuts", "core", "transport", - "providers", - "e2b" + "providers" ], "reserved_provider_prefixes": [ "abx-", diff --git a/test/config-keys.test.mjs b/test/config-keys.test.mjs index a35e9a2..e1c2dd4 100644 --- a/test/config-keys.test.mjs +++ b/test/config-keys.test.mjs @@ -14,6 +14,21 @@ const source = JSON.parse( readFileSync(new URL("../src/config-keys.json", import.meta.url), "utf8"), ); +test("reserved provider ids keep the E2B catalog id available", () => { + assert.equal(configSchema.reserved_provider_ids.includes("e2b"), false); + assert.deepEqual(configSchema.reserved_provider_ids, [ + "alicloud-express", + "default", + "all", + "none", + "builtin", + "shortcuts", + "core", + "transport", + "providers", + ]); +}); + test("fixture is copied through with one env name per key", () => { assert.equal(configSchema.schema_version, 1); assert.equal(CONFIG_KEYS.length, source.keys.length);