@baize-ai/core 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.dockerignore +8 -18
- package/CHANGELOG.md +24 -1
- package/Dockerfile +66 -12
- package/README.md +85 -6
- package/README.zh-CN.md +63 -3
- package/assets/logo.png +0 -0
- package/cli/baize.js +6 -0
- package/cli/commands/a2a.js +124 -0
- package/cli/commands/add.js +126 -86
- package/cli/commands/component.js +27 -4
- package/cli/commands/doctor.js +2 -2
- package/cli/commands/init.js +28 -0
- package/cli/commands/self-uninstall.js +1 -1
- package/cli/lib/__tests__/instruction-split.test.js +1 -1
- package/cli/lib/a2a.js +235 -0
- package/cli/lib/lock.js +3 -3
- package/cli/lib/self-upgrade.js +1 -1
- package/docker-compose.yml +1 -1
- package/docs/docker.md +18 -4
- package/docs/release.md +150 -0
- package/package.json +1 -1
- package/scripts/docker-publish.sh +70 -0
- package/scripts/install.sh +4 -4
- package/scripts/pack-release.sh +361 -0
- package/skills/comm-bridge/package.json +7 -3
- package/skills/comm-bridge/scripts/c4-receive.js +23 -2
- package/skills/scheduler/package.json +2 -2
- package/skills/web-console/SKILL.md +34 -0
- package/skills/web-console/package.json +2 -2
- package/skills/web-console/public/app.js +967 -4
- package/skills/web-console/public/index.html +141 -0
- package/skills/web-console/public/styles.css +136 -0
- package/skills/web-console/scripts/a2a-admin.js +533 -0
- package/skills/web-console/scripts/channel-admin.js +99 -16
- package/skills/web-console/scripts/server.js +395 -1
- package/skills/web-console/scripts/skill-catalog.js +179 -0
- package/templates/claude-system.md +22 -0
- package/templates/pm2/ecosystem.config.cjs +4 -1
- package/test/a2a-cli.test.js +180 -0
- package/test/agent-card-api.test.js +261 -0
- package/test/channel-admin.test.js +87 -0
- package/test/component-lock.test.js +216 -0
- package/test/skill-catalog.test.js +118 -0
- package/test/web-console-routes.test.js +512 -1
package/.dockerignore
CHANGED
|
@@ -1,18 +1,8 @@
|
|
|
1
|
-
#
|
|
2
|
-
#
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
.
|
|
9
|
-
.github
|
|
10
|
-
*.log
|
|
11
|
-
*.env
|
|
12
|
-
.env.*
|
|
13
|
-
!.env.example
|
|
14
|
-
test
|
|
15
|
-
docs
|
|
16
|
-
assets
|
|
17
|
-
README*.md
|
|
18
|
-
CHANGELOG.md
|
|
1
|
+
# Publish-mode build context: source code is NOT copied into the image.
|
|
2
|
+
# Only entrypoint + PM2 ecosystem + pre-bundled Claude binary are needed.
|
|
3
|
+
*
|
|
4
|
+
!Dockerfile
|
|
5
|
+
!docker/entrypoint.sh
|
|
6
|
+
!templates/pm2/ecosystem.config.cjs
|
|
7
|
+
!.claude-local/claude
|
|
8
|
+
!.claude-local/claude.version
|
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,29 @@ All notable changes to baize-core will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.3.1] - 2026-08-25
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- web-console「定时任务」只读列表视图(`/api/admin/scheduler/tasks`:tasks 表列表,无管理操作;scheduler 未启动容错)
|
|
12
|
+
|
|
13
|
+
## [0.3.0] - 2026-08-25
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
- A2A 运行模式(单机/集群):`baize a2a enable/disable/status` 完整事务(daemon 启动 → 身份就绪轮询 → 注册,失败回滚);web 控制台 A2A 页模式卡 + tar.gz 上传安装(D25)
|
|
17
|
+
- 证书自动生成(自签 CA + CA 签发服务器证书,共享 CA 模型)
|
|
18
|
+
- `baize add` 孤儿残留自动清理(中断安装重试不再死循环,KI-024)
|
|
19
|
+
- web-console `/api/admin/a2a/install`(manifest/大小/防路径穿越校验 + `--ignore-scripts`)
|
|
20
|
+
- 打包脚本 `scripts/pack-release.sh`(A2A 套件私有交付)
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
- A2A CLI 集成(`baize a2a` 子命令,D21-D24:card 编辑/发现重构/能力认知/凭证轮换)
|
|
24
|
+
- 渠道组件 upgrade 走 npm(D18,KI-006)
|
|
25
|
+
- add/uninstall 持组件锁(D20,KI-007)
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
- web-console 上传安装校验(D25 Review:身份就绪验证/凭证 issuer/CA 互信/审批抖动)
|
|
29
|
+
- 组件安装残留死循环(KI-024)
|
|
30
|
+
|
|
8
31
|
## [0.2.0] - 2026-08-23
|
|
9
32
|
|
|
10
33
|
### Added
|
|
@@ -52,7 +75,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
52
75
|
|
|
53
76
|
### Added
|
|
54
77
|
|
|
55
|
-
- **Baize (白泽) inception**: forked from zylos-core v0.7.1 as an independent project. All identifiers renamed (`zylos` → `baize`): CLI (`baize`), npm package (`@baize-ai/core`), runtime root (`~/baize/`), config dir (`~/.baize/`), env vars (`BAIZE_*`), instruction file (`BAIZE.md`), skills (`baize-memory`), PM2 service names, Docker image (`ghcr.io/
|
|
78
|
+
- **Baize (白泽) inception**: forked from zylos-core v0.7.1 as an independent project. All identifiers renamed (`zylos` → `baize`): CLI (`baize`), npm package (`@baize-ai/core`), runtime root (`~/baize/`), config dir (`~/.baize/`), env vars (`BAIZE_*`), instruction file (`BAIZE.md`), skills (`baize-memory`), PM2 service names, Docker image (`ghcr.io/baize01-ai/baize-core`), and the agent persona in system templates.
|
|
56
79
|
|
|
57
80
|
### Removed
|
|
58
81
|
|
package/Dockerfile
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
FROM node:22-slim
|
|
14
14
|
|
|
15
|
-
LABEL org.opencontainers.image.source="https://github.com/
|
|
15
|
+
LABEL org.opencontainers.image.source="https://github.com/baize01-ai/baize-core"
|
|
16
16
|
LABEL org.opencontainers.image.description="Baize — autonomous AI agent infrastructure"
|
|
17
17
|
|
|
18
18
|
# ── System packages ───────────────────────────────────────────────────────────
|
|
@@ -26,20 +26,31 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
|
26
26
|
procps \
|
|
27
27
|
# For `baize doctor` network checks
|
|
28
28
|
dnsutils \
|
|
29
|
+
# Native-module build toolchain (better-sqlite3 etc.): prebuild download
|
|
30
|
+
# can fail at build/runtime (GitHub Releases is a flaky source); with the
|
|
31
|
+
# toolchain present npm falls back to source compile instead of leaving a
|
|
32
|
+
# broken binary in the image (D19 container crash root cause).
|
|
33
|
+
python3 \
|
|
34
|
+
make \
|
|
35
|
+
g++ \
|
|
29
36
|
&& rm -rf /var/lib/apt/lists/*
|
|
30
37
|
|
|
31
38
|
# ── Global npm tools ──────────────────────────────────────────────────────────
|
|
32
39
|
RUN npm install -g pm2@latest
|
|
33
40
|
|
|
34
|
-
# ── Claude Code CLI (pre-bundled)
|
|
41
|
+
# ── Claude Code CLI (pre-bundled, pinned version) ─────────────────────────────
|
|
35
42
|
# The official install.sh downloads a ~340MB binary at container runtime, which
|
|
36
43
|
# is unreliable inside container networks (fails ~90% through on Docker
|
|
37
|
-
# Desktop). Bundle
|
|
38
|
-
# .claude-local/claude in the build context (gitignored). Fetch with:
|
|
44
|
+
# Desktop). Bundle a PINNED, verified binary in the image instead:
|
|
39
45
|
# curl -fsSL https://downloads.claude.ai/claude-code-releases/<ver>/linux-arm64/claude
|
|
40
|
-
#
|
|
46
|
+
# (verify against .../manifest.json platforms.linux-arm64 checksum)
|
|
47
|
+
# echo <ver> > .claude-local/claude.version
|
|
48
|
+
# Upgrade = replace the binary + bump claude.version, then rebuild the image
|
|
49
|
+
# (explicit release decision — never auto-fetch latest at build time).
|
|
41
50
|
COPY .claude-local/claude /usr/local/bin/claude
|
|
42
51
|
RUN chmod +x /usr/local/bin/claude
|
|
52
|
+
COPY .claude-local/claude.version /usr/local/bin/claude.version
|
|
53
|
+
LABEL org.opencontainers.image.claude-version="$(cat .claude-local/claude.version 2>/dev/null || echo unknown)"
|
|
43
54
|
|
|
44
55
|
# ── Create baize user (non-root) ──────────────────────────────────────────────
|
|
45
56
|
RUN useradd -m -s /bin/bash baize \
|
|
@@ -49,15 +60,58 @@ USER baize
|
|
|
49
60
|
ENV HOME=/home/baize
|
|
50
61
|
ENV NPM_CONFIG_PREFIX=/home/baize/.npm-global
|
|
51
62
|
ENV PATH="/home/baize/.npm-global/bin:/home/baize/.local/bin:/usr/local/bin:${PATH}"
|
|
63
|
+
# Web console must listen on all interfaces for Docker port mapping to work
|
|
64
|
+
# (default is 127.0.0.1, which Docker Desktop cannot reach). PM2 fork mode
|
|
65
|
+
# inherits process env, so this reaches the web-console service even when the
|
|
66
|
+
# bundled ecosystem.config.cjs predates the WEB_CONSOLE_BIND field.
|
|
67
|
+
ENV WEB_CONSOLE_BIND=0.0.0.0
|
|
52
68
|
|
|
53
|
-
# ── Install baize-core from
|
|
54
|
-
#
|
|
55
|
-
#
|
|
69
|
+
# ── Install baize-core from the npm package ─────────────────────────────────
|
|
70
|
+
# The image pulls the published @baize-ai/core package (no source code in the
|
|
71
|
+
# build context) — source stays private, the image matches the npm version
|
|
72
|
+
# exactly. Build with: docker build --build-arg BAZE_CORE_VERSION=0.2.0 .
|
|
73
|
+
ARG BAZE_CORE_VERSION=latest
|
|
56
74
|
WORKDIR /home/baize
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
75
|
+
RUN npm install -g @baize-ai/core@${BAZE_CORE_VERSION} \
|
|
76
|
+
&& baize --version \
|
|
77
|
+
# ── Build-time skill dependency preinstall (reproducibility) ─────────
|
|
78
|
+
# `baize init` reinstalls skill deps at runtime; doing it here bakes the
|
|
79
|
+
# native modules (better-sqlite3 etc.) into the image with a known-good
|
|
80
|
+
# result and the toolchain above as fallback. Same selection logic as
|
|
81
|
+
# init.js installSkillDependencies (skills with a package.json that has
|
|
82
|
+
# dependencies).
|
|
83
|
+
&& for skill_dir in /home/baize/.npm-global/lib/node_modules/@baize-ai/core/skills/*/; do \
|
|
84
|
+
if [ -f "${skill_dir}package.json" ]; then \
|
|
85
|
+
deps=$(node -e "const p=require('${skill_dir}package.json');console.log(p.dependencies?1:0)" 2>/dev/null || echo 0); \
|
|
86
|
+
if [ "$deps" = "1" ]; then \
|
|
87
|
+
(cd "$skill_dir" && npm install --production --no-audit --no-fund) || exit 1; \
|
|
88
|
+
fi; \
|
|
89
|
+
fi; \
|
|
90
|
+
done \
|
|
91
|
+
# ── Force local native-module compilation ──────────────────────────
|
|
92
|
+
# better-sqlite3 12.x prebuild download can return the WRONG platform
|
|
93
|
+
# binary (observed: macOS Mach-O inside linux build → ERR_DLOPEN_FAILED
|
|
94
|
+
# at runtime). Rebuild forces node-gyp compile with the toolchain above,
|
|
95
|
+
# guaranteeing a correct linux ELF regardless of prebuild availability.
|
|
96
|
+
&& for skill_dir in /home/baize/.npm-global/lib/node_modules/@baize-ai/core/skills/*/; do \
|
|
97
|
+
if [ -d "${skill_dir}node_modules/better-sqlite3" ]; then \
|
|
98
|
+
(cd "${skill_dir}node_modules/better-sqlite3" && npm rebuild better-sqlite3) || exit 1; \
|
|
99
|
+
fi; \
|
|
100
|
+
done \
|
|
101
|
+
# ── Bake deps into the runtime skills dir ──────────────────────────
|
|
102
|
+
# init's skill sync preserves existing node_modules and (since the
|
|
103
|
+
# idempotent-dep check) skips reinstall when deps are loadable — so
|
|
104
|
+
# pre-baking here makes runtime init never touch the compiled binaries.
|
|
105
|
+
&& mkdir -p /home/baize/baize/.claude/skills \
|
|
106
|
+
&& for skill_dir in /home/baize/.npm-global/lib/node_modules/@baize-ai/core/skills/*/; do \
|
|
107
|
+
name=$(basename "$skill_dir"); \
|
|
108
|
+
if [ -d "$skill_dir" ] && [ -f "$skill_dir/package.json" ]; then \
|
|
109
|
+
mkdir -p "/home/baize/baize/.claude/skills/$name"; \
|
|
110
|
+
cp -r "$skill_dir"/. "/home/baize/baize/.claude/skills/$name/"; \
|
|
111
|
+
fi; \
|
|
112
|
+
done \
|
|
113
|
+
&& node -e "const D=require('/home/baize/baize/.claude/skills/web-console/node_modules/better-sqlite3'); new D(':memory:')" \
|
|
114
|
+
&& echo "native modules OK (locally compiled, baked into runtime skills)"
|
|
61
115
|
|
|
62
116
|
# ── Workspace directories ─────────────────────────────────────────────────────
|
|
63
117
|
# ~/baize is mounted as a single volume in docker-compose.yml.
|
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ subscription (or an OpenAI Codex setup — Codex CLI v0.129.0+ required,
|
|
|
20
20
|
0.146+ recommended).
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
|
-
curl -fsSL https://raw.githubusercontent.com/
|
|
23
|
+
curl -fsSL https://raw.githubusercontent.com/baize01-ai/baize-core/main/scripts/install.sh | bash
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
This installs dependencies (git, tmux, Node.js, PM2, the `baize` CLI) and runs
|
|
@@ -36,17 +36,26 @@ baize init
|
|
|
36
36
|
**Docker deployment:**
|
|
37
37
|
|
|
38
38
|
```bash
|
|
39
|
+
# Global (GitHub Container Registry)
|
|
39
40
|
docker run -d --name baize \
|
|
40
41
|
-p 3456:3456 \
|
|
41
42
|
-v baize-data:/home/baize/baize \
|
|
42
43
|
-v claude-config:/home/baize/.claude \
|
|
43
|
-
ghcr.io/
|
|
44
|
+
ghcr.io/baize01-ai/baize-core:latest
|
|
45
|
+
|
|
46
|
+
# China (Aliyun ACR — fast, no mirror needed)
|
|
47
|
+
docker run -d --name baize \
|
|
48
|
+
-p 3456:3456 \
|
|
49
|
+
-v baize-data:/home/baize/baize \
|
|
50
|
+
-v claude-config:/home/baize/.claude \
|
|
51
|
+
crpi-8bg62qbrjs3cr3as.cn-hangzhou.personal.cr.aliyuncs.com/baize01/baize-core:latest
|
|
44
52
|
```
|
|
45
53
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
54
|
+
The image is built from the published `@baize-ai/core` npm package — no source
|
|
55
|
+
code in the build. Open `http://localhost:3456` for the web console (see
|
|
56
|
+
below); configure authentication in 模型设置 (Claude API key / setup token /
|
|
57
|
+
custom endpoint / Codex / ChatGPT login). See `docs/docker.md` for Compose
|
|
58
|
+
setup, optional auth environment variables, and volume details.
|
|
50
59
|
|
|
51
60
|
`baize init` is idempotent and supports interactive and non-interactive modes.
|
|
52
61
|
It will:
|
|
@@ -181,6 +190,72 @@ session, audit trail, and memory.
|
|
|
181
190
|
|
|
182
191
|
---
|
|
183
192
|
|
|
193
|
+
## A2A (Agent-to-Agent Collaboration)
|
|
194
|
+
|
|
195
|
+
A2A connects multiple Baize instances for direct, **HTTPS P2P** collaboration —
|
|
196
|
+
no central message server. Messages and task delegations travel straight from
|
|
197
|
+
one agent to another, and every instance stays fully independent.
|
|
198
|
+
|
|
199
|
+
**Components:**
|
|
200
|
+
|
|
201
|
+
| Component | Role |
|
|
202
|
+
|-----------|------|
|
|
203
|
+
| `@baize-ai/baize-a2a` | npm channel package installed on each enabled instance: HTTPS server, registration/heartbeat client, task worker, and the `baize a2a` CLI |
|
|
204
|
+
| `@baize-ai/baize-admin-workspace` | Standalone control plane (npm package + Docker image + Ant Design Pro console): admission approval, online status, audit, and Card-based discovery — never in the message path |
|
|
205
|
+
|
|
206
|
+
**Core concepts:**
|
|
207
|
+
|
|
208
|
+
- **Agent Card is the single source of business truth** — each agent
|
|
209
|
+
self-reports its `name`, `description`, and `skills` at
|
|
210
|
+
`GET /.well-known/baize-agent.json`. The admin does not maintain business
|
|
211
|
+
descriptions; it only governs admission, presence, audit, and discovery.
|
|
212
|
+
- **Receiver-side authorization** — every agent decides for itself who may
|
|
213
|
+
call it (`authz` in `config.json`: `open` by default, or an `allowlist`).
|
|
214
|
+
- **Card-based discovery** — peers are found through the admin directory by
|
|
215
|
+
text-matching the Card's name/description/skills, or by exact skill id.
|
|
216
|
+
|
|
217
|
+
**Quick start:**
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
baize add @baize-ai/baize-a2a # install the channel
|
|
221
|
+
baize a2a enable --admin <url> --advertise <https://your-agent.example.com>
|
|
222
|
+
# → self-register → admin approves → JWT issued → heartbeat (30s) → discoverable
|
|
223
|
+
baize a2a search <query> # discover agents via the admin directory
|
|
224
|
+
baize a2a task <peer> <skill> "<instruction>" # delegate a task (sync wait)
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
**CLI (`baize a2a`):**
|
|
228
|
+
|
|
229
|
+
| Command | Purpose |
|
|
230
|
+
|---------|---------|
|
|
231
|
+
| `status` | Local state: enabled / agent_id / registration / advertise_url |
|
|
232
|
+
| `enable --admin <url> --advertise <url>` | Enable A2A and register with the admin |
|
|
233
|
+
| `disable` | Disable (already-accepted tasks keep running) |
|
|
234
|
+
| `peer list` | Cached peers |
|
|
235
|
+
| `search <query>` | Discover agents via the admin directory |
|
|
236
|
+
| `card <id>` | Agent Card details |
|
|
237
|
+
| `session-summary` | Summary of the currently available peers |
|
|
238
|
+
| `send <peer> <text>` | Plain message (no reply wait) |
|
|
239
|
+
| `task <peer> <skill> "<instruction>"` | Delegate a task; sync wait by default (`--async` returns the task_id only) |
|
|
240
|
+
| `task status <id>` / `task cancel <id>` | Query / cancel a delegated task |
|
|
241
|
+
|
|
242
|
+
**Card editing and call authorization (web console):** the A2A page edits
|
|
243
|
+
your Agent Card — name, description, and Skills picked from the installed
|
|
244
|
+
SKILL.md list (frontmatter auto-extracted). Saving hot-refreshes the Card
|
|
245
|
+
within seconds and the admin probe syncs the snapshot; the Card can be
|
|
246
|
+
pre-filled even before A2A is enabled. The same page configures 调用授权
|
|
247
|
+
(call authorization): `open` with a block list (default) or `allowlist` —
|
|
248
|
+
rejected calls return 403 and are audited.
|
|
249
|
+
|
|
250
|
+
**Credential rotation:** each agent holds its own admin-issued JWT (RS256,
|
|
251
|
+
12h validity, per-agent credentials). Agents auto-refresh before expiry and
|
|
252
|
+
re-fetch credentials within 60s after an admin rotation (revocation
|
|
253
|
+
detection + forced recovery). Rotation revokes only the target agent's
|
|
254
|
+
credential and re-signs it with the current key — the global signing key
|
|
255
|
+
stays unchanged, so rotating one agent never affects the others.
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
184
259
|
## Configuration
|
|
185
260
|
|
|
186
261
|
Persistent configuration lives in `~/baize/.baize/config.json`:
|
|
@@ -243,6 +318,10 @@ baize uninstall --self # Uninstall Baize entirely
|
|
|
243
318
|
|
|
244
319
|
---
|
|
245
320
|
|
|
321
|
+
## Release
|
|
322
|
+
|
|
323
|
+
npm + Docker 发布的完整操作手册(认证 / 四包发布 / ghcr + 阿里云 ACR 镜像)见 [`docs/release.md`](docs/release.md)。
|
|
324
|
+
|
|
246
325
|
## License
|
|
247
326
|
|
|
248
327
|
[MIT](./LICENSE)
|
package/README.zh-CN.md
CHANGED
|
@@ -14,7 +14,7 @@ Baize(白泽)是一个本地软件研发 Agent 工作台:一个自托管
|
|
|
14
14
|
**前置条件:** Linux 服务器(或 macOS)、[Claude](https://claude.ai) 订阅(或 OpenAI Codex 环境——Codex CLI v0.129.0+,推荐 0.146+)。
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
|
-
curl -fsSL https://raw.githubusercontent.com/
|
|
17
|
+
curl -fsSL https://raw.githubusercontent.com/baize01-ai/baize-core/main/scripts/install.sh | bash
|
|
18
18
|
```
|
|
19
19
|
|
|
20
20
|
安装依赖(git、tmux、Node.js、PM2、`baize` CLI)并运行 `baize init` 初始化 Agent。
|
|
@@ -29,14 +29,22 @@ baize init
|
|
|
29
29
|
**Docker 部署:**
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
|
+
# 海外(GitHub Container Registry)
|
|
32
33
|
docker run -d --name baize \
|
|
33
34
|
-p 3456:3456 \
|
|
34
35
|
-v baize-data:/home/baize/baize \
|
|
35
36
|
-v claude-config:/home/baize/.claude \
|
|
36
|
-
ghcr.io/
|
|
37
|
+
ghcr.io/baize01-ai/baize-core:latest
|
|
38
|
+
|
|
39
|
+
# 国内(阿里云 ACR,免镜像加速)
|
|
40
|
+
docker run -d --name baize \
|
|
41
|
+
-p 3456:3456 \
|
|
42
|
+
-v baize-data:/home/baize/baize \
|
|
43
|
+
-v claude-config:/home/baize/.claude \
|
|
44
|
+
crpi-8bg62qbrjs3cr3as.cn-hangzhou.personal.cr.aliyuncs.com/baize01/baize-core:latest
|
|
37
45
|
```
|
|
38
46
|
|
|
39
|
-
|
|
47
|
+
镜像由已发布的 `@baize-ai/core` npm 包构建(构建上下文不含源码)。打开 `http://localhost:3456` 进入网页控制台(见下文);认证在「模型设置」中配置(Claude API key / setup token / 自定义端点 / Codex / ChatGPT 登录)。Compose 配置、可选认证环境变量与卷说明见 `docs/docker.md`。
|
|
40
48
|
|
|
41
49
|
`baize init` 幂等,支持交互与非交互模式,它会:
|
|
42
50
|
|
|
@@ -147,6 +155,54 @@ baize search # 从当前源动态发现渠道目录
|
|
|
147
155
|
|
|
148
156
|
---
|
|
149
157
|
|
|
158
|
+
## A2A(Agent-to-Agent 协作)
|
|
159
|
+
|
|
160
|
+
A2A 让多个 Baize 实例经 **HTTPS P2P** 直接协作——没有中心消息服务器,消息与任务委托直达对端 Agent,每个实例保持完全独立。
|
|
161
|
+
|
|
162
|
+
**组件:**
|
|
163
|
+
|
|
164
|
+
| 组件 | 职责 |
|
|
165
|
+
|------|------|
|
|
166
|
+
| `@baize-ai/baize-a2a` | npm 渠道包,装在每个启用实例:HTTPS server、注册/心跳客户端、任务 worker、`baize a2a` CLI |
|
|
167
|
+
| `@baize-ai/baize-admin-workspace` | 独立控制面(npm 包 + Docker 镜像 + Ant Design Pro 控制台):准入审批、在线状态、审计、基于 Card 的发现——不进消息路径 |
|
|
168
|
+
|
|
169
|
+
**核心概念:**
|
|
170
|
+
|
|
171
|
+
- **Agent Card 是唯一业务事实源** —— 每个 agent 在 `GET /.well-known/baize-agent.json` 自报 `name` / `description` / `skills`;admin 不维护业务描述,只管准入、在线、审计与发现。
|
|
172
|
+
- **接收方授权自治** —— 每个 agent 自己决定接受谁的调用(`config.json` 的 `authz`:默认 `open`,或 `allowlist`)。
|
|
173
|
+
- **基于 Card 的发现** —— 经 admin 目录按 Card 的 name/description/skills 文本匹配,或按 skill id 精确匹配发现 peer。
|
|
174
|
+
|
|
175
|
+
**快速上手:**
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
baize add @baize-ai/baize-a2a # 安装渠道
|
|
179
|
+
baize a2a enable --admin <url> --advertise <https://your-agent.example.com>
|
|
180
|
+
# → 自注册 → 管理员审批 → 签发 JWT → 心跳(30s)→ 可发现
|
|
181
|
+
baize a2a search <query> # 经 admin 目录发现 agent
|
|
182
|
+
baize a2a task <peer> <skill> "<instruction>" # 委托任务(默认同步等待)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
**CLI(`baize a2a`):**
|
|
186
|
+
|
|
187
|
+
| 命令 | 用途 |
|
|
188
|
+
|------|------|
|
|
189
|
+
| `status` | 本实例状态:enabled / agent_id / 注册状态 / advertise_url |
|
|
190
|
+
| `enable --admin <url> --advertise <url>` | 启用 A2A 并向 admin 注册 |
|
|
191
|
+
| `disable` | 关闭(已接受任务继续执行) |
|
|
192
|
+
| `peer list` | 本地缓存 peer |
|
|
193
|
+
| `search <query>` | 经 admin 目录发现 agent |
|
|
194
|
+
| `card <id>` | Agent Card 详情 |
|
|
195
|
+
| `session-summary` | 当前可用 peer 摘要 |
|
|
196
|
+
| `send <peer> <text>` | 普通消息(不等待回复) |
|
|
197
|
+
| `task <peer> <skill> "<instruction>"` | 委托任务;默认同步等待终态(`--async` 只拿 task_id) |
|
|
198
|
+
| `task status <id>` / `task cancel <id>` | 查询 / 取消委托任务 |
|
|
199
|
+
|
|
200
|
+
**名片编辑与调用授权(网页控制台):** A2A 页可编辑本实例 Agent Card——名称、描述,以及从已安装 SKILL.md 列表勾选 Skills(frontmatter 自动提取)。保存后 Card 秒级热更新,admin 探测同步快照;A2A 未启用也可先编辑预填名片。同页配置「调用授权」:默认 `open` + 黑名单,或 `allowlist`——被拒调用返回 403 并记审计。
|
|
201
|
+
|
|
202
|
+
**凭证轮换:** 每个 agent 持有 admin 签发的独立 JWT(RS256,12h 有效,凭证独立)。agent 在过期前自动刷新;admin 轮换后 agent 60s 内自动重取凭证(吊销检测 + 强制恢复)。轮换只吊销目标 agent 的凭证并以当前 key 重签——全局签名 key 不变,单 agent 轮换不影响其他 agent。
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
150
206
|
## 配置
|
|
151
207
|
|
|
152
208
|
持久化配置在 `~/baize/.baize/config.json`:
|
|
@@ -203,6 +259,10 @@ baize uninstall --self # 完全卸载 Baize
|
|
|
203
259
|
|
|
204
260
|
---
|
|
205
261
|
|
|
262
|
+
## Release
|
|
263
|
+
|
|
264
|
+
npm + Docker 发布的完整操作手册(认证 / 四包发布 / ghcr + 阿里云 ACR 镜像)见 [`docs/release.md`](docs/release.md)。
|
|
265
|
+
|
|
206
266
|
## License
|
|
207
267
|
|
|
208
268
|
[MIT](./LICENSE)
|
package/assets/logo.png
CHANGED
|
Binary file
|
package/cli/baize.js
CHANGED
|
@@ -22,6 +22,7 @@ import { attachCommand } from './commands/attach.js';
|
|
|
22
22
|
import { doctorCommand } from './commands/doctor.js';
|
|
23
23
|
import { shellCommand } from './commands/shell.js';
|
|
24
24
|
import { runtimeCommand } from './commands/runtime.js';
|
|
25
|
+
import { a2aCommand } from './commands/a2a.js';
|
|
25
26
|
|
|
26
27
|
const commands = {
|
|
27
28
|
// Environment setup
|
|
@@ -45,6 +46,8 @@ const commands = {
|
|
|
45
46
|
remove: uninstallComponent,
|
|
46
47
|
list: listComponents,
|
|
47
48
|
search: searchComponents,
|
|
49
|
+
// A2A (Agent-to-Agent)
|
|
50
|
+
a2a: a2aCommand,
|
|
48
51
|
// Help
|
|
49
52
|
help: showHelp,
|
|
50
53
|
};
|
|
@@ -120,6 +123,9 @@ Component Management:
|
|
|
120
123
|
list List installed components
|
|
121
124
|
search [keyword] Search available components
|
|
122
125
|
|
|
126
|
+
A2A:
|
|
127
|
+
a2a A2A 智能体互联管理(baize a2a --help 查看子命令)
|
|
128
|
+
|
|
123
129
|
Other:
|
|
124
130
|
help Show this help
|
|
125
131
|
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* baize a2a — A2A(Agent-to-Agent)互联管理。
|
|
3
|
+
*
|
|
4
|
+
* 全部子命令委托 @baize-ai/baize-a2a 的 scripts/cli.js(D19 契约 §6):
|
|
5
|
+
* 参数透传 + --json,成功 exit 0,失败 stderr + exit 1。
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* baize a2a status
|
|
9
|
+
* baize a2a enable --admin <url> --advertise <url>
|
|
10
|
+
* baize a2a disable
|
|
11
|
+
* baize a2a peer list
|
|
12
|
+
* baize a2a search <query>
|
|
13
|
+
* baize a2a send <peer> <text>
|
|
14
|
+
* baize a2a task <peer> <skill?> <instruction> [--async]
|
|
15
|
+
* baize a2a task status <taskId>
|
|
16
|
+
* baize a2a task cancel <taskId>
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { a2aCliPath, runA2aCli, formatA2aOutput } from '../lib/a2a.js';
|
|
20
|
+
import { bold, dim, cyan, error } from '../lib/colors.js';
|
|
21
|
+
|
|
22
|
+
export const A2A_SUBCOMMANDS = ['status', 'enable', 'disable', 'peer', 'search', 'send', 'task'];
|
|
23
|
+
|
|
24
|
+
// Contract: sync task waits for a terminal state (timeout 10 min).
|
|
25
|
+
const TASK_TIMEOUT_MS = 660000;
|
|
26
|
+
const DEFAULT_TIMEOUT_MS = 120000;
|
|
27
|
+
|
|
28
|
+
export function a2aHelp() {
|
|
29
|
+
return `${bold('baize a2a')} — A2A(Agent-to-Agent)互联管理
|
|
30
|
+
|
|
31
|
+
委托 @baize-ai/baize-a2a 通道 CLI(定位:BAIZE_A2A_PATH → 全局 npm 包 → ../baize-a2a 开发目录)。
|
|
32
|
+
|
|
33
|
+
Usage: ${bold('baize a2a <subcommand> [options]')}
|
|
34
|
+
|
|
35
|
+
Subcommands:
|
|
36
|
+
${cyan('status')} A2A 身份与注册状态
|
|
37
|
+
${cyan('enable')} --admin <url> --advertise <url>
|
|
38
|
+
启用并注册:生成 agentId + 向 admin-workspace 提交注册
|
|
39
|
+
${cyan('disable')} 停用(停止心跳/消息接收)
|
|
40
|
+
${cyan('peer list')} peer 目录(已缓存)
|
|
41
|
+
${cyan('search')} <query> 在 admin Directory 中搜索 agent
|
|
42
|
+
${cyan('send')} <peer> <text> 发送一条消息给 peer
|
|
43
|
+
${cyan('task')} <peer> <skill?> <instruction> [--async]
|
|
44
|
+
派发任务;默认同步等待终态(超时 10 分钟),
|
|
45
|
+
${dim('--async')} 立即返回 taskId
|
|
46
|
+
${cyan('task status')} <taskId> 查询任务状态
|
|
47
|
+
${cyan('task cancel')} <taskId> 取消任务(queued → canceled;running → cancel_requested)
|
|
48
|
+
|
|
49
|
+
Options:
|
|
50
|
+
--help, -h 显示帮助
|
|
51
|
+
--json 原始 JSON 输出(透传给 baize-a2a CLI)
|
|
52
|
+
|
|
53
|
+
Examples:
|
|
54
|
+
baize a2a status
|
|
55
|
+
baize a2a enable --admin https://admin.example.com --advertise https://a2a.example.com
|
|
56
|
+
baize a2a peer list
|
|
57
|
+
baize a2a search doccraft
|
|
58
|
+
baize a2a send agent_doccraft "帮我生成一份周报"
|
|
59
|
+
baize a2a task agent_doccraft "生成周报" --async
|
|
60
|
+
baize a2a task status <taskId>`;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function commandKind(args) {
|
|
64
|
+
const [sub, sub2] = args;
|
|
65
|
+
if (sub === 'task') {
|
|
66
|
+
if (sub2 === 'status') return 'task-status';
|
|
67
|
+
if (sub2 === 'cancel') return 'task-cancel';
|
|
68
|
+
return 'task';
|
|
69
|
+
}
|
|
70
|
+
if (sub === 'peer') return 'peer-list';
|
|
71
|
+
return sub;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Entry point for `baize a2a ...`.
|
|
76
|
+
*
|
|
77
|
+
* @param {string[]} args CLI args after "a2a"
|
|
78
|
+
* @param {object} [deps] injectable seams for tests
|
|
79
|
+
* @param {Function} [deps.runA2aCli] delegated runner (defaults to runA2aCli)
|
|
80
|
+
* @param {string|Function} [deps.cliPath] cli.js path override (defaults to a2aCliPath())
|
|
81
|
+
* @param {Function} [deps.exit] process.exit stand-in
|
|
82
|
+
* @param {Function} [deps.log] stdout writer
|
|
83
|
+
* @param {Function} [deps.logError] stderr writer
|
|
84
|
+
*/
|
|
85
|
+
export async function a2aCommand(args = [], deps = {}) {
|
|
86
|
+
const run = deps.runA2aCli || runA2aCli;
|
|
87
|
+
const exit = deps.exit || ((code) => { process.exit(code); });
|
|
88
|
+
const log = deps.log || ((s) => console.log(s));
|
|
89
|
+
const logError = deps.logError || ((s) => console.error(s));
|
|
90
|
+
|
|
91
|
+
const first = args[0] || '';
|
|
92
|
+
if (!first || first === '--help' || first === '-h') {
|
|
93
|
+
log(a2aHelp());
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (!A2A_SUBCOMMANDS.includes(first)) {
|
|
97
|
+
logError(error(`Unknown a2a subcommand: ${first}`));
|
|
98
|
+
logError('Usage: baize a2a <subcommand> [options] (baize a2a --help 查看全部子命令)');
|
|
99
|
+
return exit(1);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const cli = typeof deps.cliPath === 'function' ? deps.cliPath() : (deps.cliPath !== undefined ? deps.cliPath : a2aCliPath());
|
|
103
|
+
if (!cli) {
|
|
104
|
+
logError(error('未找到 baize-a2a CLI。请设置 BAIZE_A2A_PATH,安装 @baize-ai/baize-a2a(npm i -g),或确认 ../baize-a2a 开发目录存在。'));
|
|
105
|
+
return exit(1);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Sync task dispatch waits for a terminal state (contract §6, 10 min).
|
|
109
|
+
const isTaskSync = first === 'task'
|
|
110
|
+
&& args[1] !== 'status'
|
|
111
|
+
&& args[1] !== 'cancel'
|
|
112
|
+
&& !args.includes('--async');
|
|
113
|
+
const timeout = isTaskSync ? TASK_TIMEOUT_MS : DEFAULT_TIMEOUT_MS;
|
|
114
|
+
|
|
115
|
+
const result = await run(args, { cliPath: cli, timeout });
|
|
116
|
+
if (!result.success) {
|
|
117
|
+
logError(error(result.error || 'a2a 命令失败'));
|
|
118
|
+
if (result.output && result.output !== result.error) logError(result.output.slice(-800));
|
|
119
|
+
return exit(1);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const json = result.json || {};
|
|
123
|
+
log(formatA2aOutput(commandKind(args), json));
|
|
124
|
+
}
|