Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .github/actions/official-sdk/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Pinned official client
description: Install the official Python SDK that contracts/agents-api/upstream.json pins.
runs:
using: composite
steps:
- uses: actions/setup-python@v6
with:
python-version: '3.12'
- name: Install pinned official client
shell: bash
run: |
python - <<'PY'
import json, subprocess, sys
pin = json.load(open('contracts/agents-api/upstream.json'))
subprocess.run([sys.executable, '-m', 'pip', 'install', '-r', 'services/core/tests/requirements.txt',
'openai @ git+https://github.com/openai/openai-python@' + pin['commit']], check=True)
PY
13 changes: 1 addition & 12 deletions .github/workflows/api-acceptance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,7 @@ jobs:
OAC_DEV_CORE_BUILD_DIR="$RUNNER_TEMP/oac-core-build" make build-core
"$RUNNER_TEMP/oac-core-build/oac-core-device" --help
"$RUNNER_TEMP/oac-core-build/oac-core-environment-key" --help
- uses: actions/setup-python@v6
with:
python-version: '3.12'
- name: Install pinned official client
run: |
python - <<'PY'
import json, subprocess, sys
pin = json.load(open('contracts/agents-api/upstream.json'))
subprocess.run([sys.executable, '-m', 'pip', 'install', '-r', 'services/core/tests/requirements.txt',
'openai @ git+https://github.com/openai/openai-python@' + pin['commit']], check=True)
PY
- uses: ./.github/actions/official-sdk
- name: Verify official-client HTTP compatibility
env:
OAC_TEST_DATABASE_URL: postgres://oac:oac_test_only@127.0.0.1:${{ job.services.postgres.ports['5432'] }}/oac_ci_tests?sslmode=disable
Expand All @@ -64,7 +54,6 @@ jobs:
run: |
python services/core/tests/official_schema_test.py
python services/core/tests/official_client.py
go test ./services/core/tests/integration -run '^(TestFunctionStateOfficialClientReadsAndLiveEvents|TestSavedReferenceRetryOfficialClient|TestAgentUpdateOfficialClient|TestAgentDeletionOfficialClient|TestAutomationsOfficialClient|TestSessionAgentFilterOfficialClient|TestSessionDeletionOfficialClient|TestEnvironmentInitialFailureOfficialClient|TestSelfHostedInitialCreationOfficialClient|TestSelfHostedCancellationOfficialClient|TestStandaloneEnvironmentOfficialClientPostgres)$' -count=1
- uses: ./.github/actions/e2b-provider
if: inputs.container
- name: Verify the distribution's Core image
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,12 @@ jobs:
- name: Build standalone Core and test services and clients
if: matrix.part == 'core'
run: make build-core check-core-packages
- uses: ./.github/actions/official-sdk
if: matrix.part == 'integration'
- name: Test Core integration shard ${{ matrix.shard }}
if: matrix.part == 'integration'
env:
OAC_TEST_OFFICIAL_SDK_PYTHON: python
run: make check-core-integration OAC_CORE_INTEGRATION_SHARD=${{ matrix.shard }}

distribution:
Expand Down
2 changes: 1 addition & 1 deletion docs/maintainers.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ The planner compares the PR event's tested merge commit with its verified first
| `hygiene` | Repository links, bundled documentation integrity, and CI planner/gate tests; runs for every change |
| `distribution` | Harness catalog and installer schema, install/apply/recovery/cleanup tests, Compose parsing and initialization fixtures, release/download and bundle contracts, Go console tests and build; needs Docker Compose for template parsing, no pnpm install or browser |
| `compose` | Real startup from empty volumes using images built from the checkout, sign-in and API access, file upload and node installer download, then URL reconfiguration and container recreation with preserved credentials and data; needs Docker, Go and network access, no model credentials |
| `backend` | Parallel parts, each with a dedicated PostgreSQL guard: `runtime` (sqlc freshness, Runtime/shared Go tests, Linux microsandbox helper, daemon build), `core` (standalone Core build, Core service and client tests) and three `integration` shards of the serial Core integration test package |
| `backend` | Parallel parts, each with a dedicated PostgreSQL guard: `runtime` (sqlc freshness, Runtime/shared Go tests, Linux microsandbox helper, daemon build), `core` (standalone Core build, Core service and client tests) and three `integration` shards of the serial Core integration test package, run with the pinned official client |
| `harness` | Claude Code adapter tests and packaging, MiniMax companion scripts |
| `example` | Optional application typecheck, tests, build and isolated browser acceptance |
| `web` | TypeScript, Web/client tests and Web build |
Expand Down
4 changes: 2 additions & 2 deletions docs/zh/maintainers.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "构建并发布 OpenAgentCore"
source: docs/maintainers.md
source_hash: af77ec1c4a27d4742497068cee88195f07e9fb38e48bed89b9120e21e1a726b4
source_hash: f398cbc404cb012621eb6483715015114175d671c2dfbfd03b2ad52c773bd4d2
---

本指南面向负责构建和发布 OpenAgentCore 的维护者。要安装 Core 和 Web,请按 [安装 Core 和 Web](getting-started/install.md) 操作。安装程序代码遵循的规则见 [部署](https://github.com/MiniMax-AI/OpenAgentCore/blob/main/deploy/README.md) 和 [节点安装程序](https://github.com/MiniMax-AI/OpenAgentCore/blob/main/deploy/node/README.md);必需检查见 [CONTRIBUTING](https://github.com/MiniMax-AI/OpenAgentCore/blob/main/CONTRIBUTING.md#required-checks)。
Expand Down Expand Up @@ -183,7 +183,7 @@ gh workflow run core-release --repo MiniMax-AI/OpenAgentCore --ref main \
| `hygiene` | 仓库链接、随包文档完整性以及 CI 计划器/门禁测试;每次变更都会运行 |
| `distribution` | Harness 目录和安装程序模式、安装/应用/恢复/清理测试、Compose 解析和初始化固定数据、发布/下载和捆绑包契约、Go 控制台测试与构建;模板解析需要 Docker Compose,不需要 pnpm install 或浏览器 |
| `compose` | 使用从当前检出构建的镜像从空数据卷实际启动、登录和 API 访问、上传文件和下载节点安装程序,然后在保留凭据和数据的同时重新配置 URL 并重新创建容器;需要 Docker、Go 和网络访问,不需要模型凭据 |
| `backend` | 并行部分,每部分都有专用 PostgreSQL 保护检查:`runtime`(sqlc 新鲜度、Runtime/共享 Go 测试、Linux microsandbox 辅助程序、守护进程构建)、`core`(独立 Core 构建、Core 服务和客户端测试),以及串行 Core 集成测试包的三个 `integration` 分片 |
| `backend` | 并行部分,每部分都有专用 PostgreSQL 保护检查:`runtime`(sqlc 新鲜度、Runtime/共享 Go 测试、Linux microsandbox 辅助程序、守护进程构建)、`core`(独立 Core 构建、Core 服务和客户端测试),以及串行 Core 集成测试包的三个 `integration` 分片(使用固定版本的官方客户端运行) |
| `harness` | Claude Code adapter 测试和打包、MiniMax 配套脚本 |
| `example` | 可选的应用程序类型检查、测试、构建和隔离的浏览器验收 |
| `web` | TypeScript、Web/客户端测试和 Web 构建 |
Expand Down
1 change: 1 addition & 0 deletions scripts/ci_plan.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
".github/actions/node/action.yml": (*NODE_JOBS, "lint"),
".github/actions/mcode-companion/action.yml": ("native", "lint"),
".github/actions/e2b-provider/action.yml": ("api", "lint"),
".github/actions/official-sdk/action.yml": ("backend", "api", "lint"),
".github/workflows/cache-warm.yml": ("lint",),
"scripts/ci_plan.py": JOBS,
"scripts/ci_plan_test.py": ("hygiene",),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func TestTemplateNullSelectionOfficialClientPostgres(t *testing.T) {
}
}
})
if len(receipt.Sessions) != 9 || len(receipt.Expected) != 9 || len(receipt.RejectedKeys) != 10 {
if len(receipt.Sessions) != 10 || len(receipt.Expected) != 10 || len(receipt.RejectedKeys) != 7 {
t.Fatalf("incomplete acceptance receipt: sessions=%d expectations=%d rejections=%d", len(receipt.Sessions), len(receipt.Expected), len(receipt.RejectedKeys))
}
for label, id := range receipt.Sessions {
Expand Down Expand Up @@ -136,10 +136,10 @@ func TestTemplateNullSelectionOfficialClientPostgres(t *testing.T) {
query string
want int
}{
{"SELECT count(*) FROM sessions WHERE tenant_id=$1", 9},
{"SELECT count(*) FROM environments e JOIN sessions s ON s.environment_id=e.id WHERE s.tenant_id=$1", 9},
{"SELECT count(*) FROM environment_setups e JOIN sessions s ON s.environment_id=e.environment_id WHERE s.tenant_id=$1", 9},
{"SELECT count(*) FROM initial_environment_files f JOIN sessions s ON s.environment_id=f.environment_id WHERE s.tenant_id=$1", 9},
{"SELECT count(*) FROM sessions WHERE tenant_id=$1", 10},
{"SELECT count(*) FROM environments e JOIN sessions s ON s.environment_id=e.id WHERE s.tenant_id=$1", 10},
{"SELECT count(*) FROM environment_setups e JOIN sessions s ON s.environment_id=e.environment_id WHERE s.tenant_id=$1", 10},
{"SELECT count(*) FROM initial_environment_files f JOIN sessions s ON s.environment_id=f.environment_id WHERE s.tenant_id=$1", 10},
{"SELECT count(*) FROM turns t JOIN sessions s ON s.id=t.session_id WHERE s.tenant_id=$1", 0},
{"SELECT count(*) FROM environment_input_reservations e JOIN sessions s ON s.id=e.session_id WHERE s.tenant_id=$1", 0},
} {
Expand All @@ -154,5 +154,5 @@ func TestTemplateNullSelectionOfficialClientPostgres(t *testing.T) {
t.Fatalf("rejected creation persisted: %d %v", count, err)
}
}
t.Log("nine supported selection cases and rejected network restrictions passed SDK/raw HTTP, frozen encrypted bytes, tenant isolation, atomic rejection and reopened retries; no Runtime or model execution")
t.Log("ten supported selection cases and rejected widenings passed SDK/raw HTTP, frozen encrypted bytes, tenant isolation, atomic rejection and reopened retries; no Runtime or model execution")
}
4 changes: 1 addition & 3 deletions services/core/tests/official_template_null_selection.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,6 @@ def create(label, body, selection, sdk_create=False):
missing = copy.deepcopy(base)
missing["environment"]["environment_template_id"] = "00000000-0000-0000-0000-000000000001"
assert reject(missing, 404, settings["foreign"]) == denied
reject({**base, "environment": {**base["environment"], "network": {"access": "restricted", "allowed_domains": ["example.com"]}}}, 400)
reject({**base, "environment": {**base["environment"], "skills": [{"type": "skill_reference", "skill_id": foreign_skill.id}]}}, 404)
reject({**base, "environment": {**base["environment"], "capability_directories": ["/outside"]}}, 400)
malformed = copy.deepcopy(plugin)
Expand All @@ -194,8 +193,7 @@ def create(label, body, selection, sdk_create=False):
disabled = {"access": "disabled", "allowed_domains": []}
api.update(template_id, network={"access": "disabled"})
assert api.update(template_id, name="network omission preserves").network.to_dict() == disabled
reject(base, 400)
reject({**base, "environment": {**base["environment"], "network": None}}, 400)
create("inherit-disabled", {**base, "environment": {**base["environment"], "network": None}}, {**default, "network": disabled})
reject({**base, "environment": {**base["environment"], "network": {"access": "enabled"}}}, 400)
enabled = {"access": "enabled", "allowed_domains": []}
assert api.update(template_id, network=None).network.to_dict() == enabled
Expand Down
Loading