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
10 changes: 5 additions & 5 deletions docs-site/docs/api/rest.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ curl http://localhost:9200/health
- 普通 `utok_` / `ntok_` 只看到其有权访问网络的 session;无网络成员关系时返回空对象。

::: tip `license` 字段是 v0.6 legacy
`license: "trial"` 是 v0.6 时代 14 天试用机制的残留字段,Apache 2.0 OSS 后**不再作为商业功能门控**(自部署没有"过期"概念)。`send_task` 路径仍跑 trial 检查仅为后向兼容(verify [`server/src/tools.ts:521`](https://github.com/sleep2agi/agent-network/blob/main/server/src/tools.ts#L521) `license_expired` 仍 emit),若命中见 [troubleshooting](/troubleshooting)。**v0.9.x / v0.10.x scope 都未动**(Recovery & Observability 主题为先),整段移除排到 v0.11+ / 未排期。
`license: "trial"` 是 v0.6 时代 14 天试用机制的残留字段,Apache 2.0 OSS 后**不再作为商业功能门控**(自部署没有"过期"概念)。`send_task` 路径仍跑 trial 检查仅为后向兼容(verify [`server/src/tools.ts:521`](https://github.com/sleep2agi/agent-network/blob/main/server/src/tools.ts) `license_expired` 仍 emit),若命中见 [troubleshooting](/troubleshooting)。**v0.9.x / v0.10.x scope 都未动**(Recovery & Observability 主题为先),整段移除排到 v0.11+ / 未排期。
:::

---
Expand Down Expand Up @@ -432,7 +432,7 @@ curl -X POST http://localhost:9200/api/networks \
| 状态 | `error` 值 | 触发条件 |
|------|------------|---------|
| 400 | `network name already exists` | 同一 owner 名下已有同名 network(`UNIQUE(owner_id, network_name)` 约束) |
| 400 | `quota exceeded: max N networks for free plan` | 触发 plan quota 配额限制(v0.8 起 admin 用户豁免;free plan 默认 max_networks_owned=2,**当前 quota 仍在 `auth.ts:184-189` enforced**,跟 networks 表的 `max_members` 不同:那个 dormant、这个 active) |
| 400 | `quota exceeded: max N networks for free plan` | 触发 plan quota 配额限制(v0.8 起 admin 用户豁免;free plan 默认 max_networks_owned=2,**真正会拒绝建网的是 plan 配额** —— `auth.ts` 的 `createNetwork()` 按 `max_networks_owned` 校验(free=2,admin 豁免)。注意它与 `/api/license` 的 `limits` 不是一回事:后者(trial 默认 `max_agents=5` / `max_networks=3` / `max_tasks_day=500`)**是软限额**,服务端只存储和返回、不做任何拦截(CLI 里直接标作 `Soft limits`),而且两者的 networks 数字不同(3 vs 2)—— 以实际生效的 plan 配额为准(原文钉的 `184-189` 已漂到发 token 的代码上,所以这里改钉函数名),跟 networks 表的 `max_members` 不同:那个 dormant、这个 active) |
| 401 | `token required` / `invalid token` | 未提供 / 提供了无效 utok_ |

---
Expand Down Expand Up @@ -1578,10 +1578,10 @@ curl -N "http://localhost:9200/events/代码1号?token=ntok_xxx"
| `new_message` | 收到新消息(`send_message`) | `{from, message_id}` |
| `new_reply` | 收到 reply(`send_reply`) | `{from, message_id, in_reply_to, status}` |
| `broadcast` | 收到广播(`broadcast` 工具) | `{inbox_count}` |
| `chained_reply` | 子任务完成自动串回上游父任务发起者 ([`tools.ts:286/646`](https://github.com/sleep2agi/agent-network/blob/main/server/src/tools.ts#L286)) | `{parent_task_id, child_task_id, child_alias}` |
| `chained_reply` | 子任务完成自动串回上游父任务发起者 ([`tools.ts:286/646`](https://github.com/sleep2agi/agent-network/blob/main/server/src/tools.ts)) | `{parent_task_id, child_task_id, child_alias}` |
| `node.renamed` | RFC-010 节点改名 COMMIT 时广播([`rename.ts:100-123`](https://github.com/sleep2agi/agent-network/blob/main/server/src/rename.ts#L100)),推给 old + new 两个 alias 流 **+ 每个网络成员的 user channel**(dashboard 订阅的是 `/events/<username>` user channel、不是 per-alias 流,#84 SSE channel fix) | `{txn_id, alias(=new_alias), network_id, data:{old_alias, new_alias, surfaces_updated[], history_policy:"preserve"}}` |

> 旧 doc 在 `new_message` 上写过 `message` 字段、`broadcast` 上写过 `{content, from}` —— 都不对。verify [`tools.ts:571 + 911`](https://github.com/sleep2agi/agent-network/blob/main/server/src/tools.ts#L571) 实际 payload 以上表为准。另注:`new_task` / `new_message` 在目标 alias **刚被改名**时会额外带一个 `renamed_from` 字段(指向旧 alias,`tools.ts` 的 `canonical.renamed` 分支)。
> 旧 doc 在 `new_message` 上写过 `message` 字段、`broadcast` 上写过 `{content, from}` —— 都不对。verify [`tools.ts:571 + 911`](https://github.com/sleep2agi/agent-network/blob/main/server/src/tools.ts) 实际 payload 以上表为准。另注:`new_task` / `new_message` 在目标 alias **刚被改名**时会额外带一个 `renamed_from` 字段(指向旧 alias,`tools.ts` 的 `canonical.renamed` 分支)。
>
> **校正**:原表列过 `heartbeat` event with `{time}` payload,源码不发这个事件。[`push.ts:38-44`](https://github.com/sleep2agi/agent-network/blob/main/server/src/push.ts#L38) 实际发 SSE **comment 行** `: keepalive\n\n`(每 30s 一次,纯粹是给 proxy / LB 防 idle timeout 用),不会被 EventSource `onmessage` / `addEventListener` 触发,也不带 JSON payload。`connected` event 才是真正每次连接发一次的初始事件(agent-node 在 [`agent-node/src/cli.ts`](https://github.com/sleep2agi/agent-network/blob/main/agent-node/src/cli.ts) 显式处理它)。

Expand Down Expand Up @@ -2220,7 +2220,7 @@ curl http://localhost:9200/api/license
{
"ok": true,
"license": { "type": "trial", "expires_at": "2026-04-25 12:00:00", "days_left": 12, "expired": false },
"limits": { "max_agents": 5, "max_networks": 1, "max_tasks_day": 100 }
"limits": { "max_agents": 5, "max_networks": 3, "max_tasks_day": 500 }
}
```

Expand Down
11 changes: 6 additions & 5 deletions docs-site/docs/en/api/rest.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ sessions from networks they may access (or an empty object when they belong to
none).

::: tip The `license` field is a v0.6 legacy
`license: "trial"` is a leftover from the v0.6 era 14-day trial mechanism. After the Apache 2.0 OSS transition it is **no longer a commercial feature gate** (self-hosted has no notion of "expired"). The `send_task` path still runs the trial check only for backward compatibility (verify [`server/src/tools.ts:521`](https://github.com/sleep2agi/agent-network/blob/main/server/src/tools.ts#L521) where `license_expired` is still emitted); if you hit it, see [troubleshooting](/en/troubleshooting). **The v0.9.x and v0.10.x scopes did not touch this** (Recovery & Observability took priority); full removal is queued for v0.11+ / unscheduled.
`license: "trial"` is a leftover from the v0.6 era 14-day trial mechanism. After the Apache 2.0 OSS transition it is **no longer a commercial feature gate** (self-hosted has no notion of "expired"). The `send_task` path still runs the trial check only for backward compatibility (verify [`server/src/tools.ts:521`](https://github.com/sleep2agi/agent-network/blob/main/server/src/tools.ts) where `license_expired` is still emitted); if you hit it, see [troubleshooting](/en/troubleshooting). **The v0.9.x and v0.10.x scopes did not touch this** (Recovery & Observability took priority); full removal is queued for v0.11+ / unscheduled.
:::

---
Expand Down Expand Up @@ -442,7 +442,8 @@ curl -X POST http://localhost:9200/api/networks \
| Status | `error` value | Trigger |
|------|------------|---------|
| 400 | `network name already exists` | Same owner already has a network with this name (`UNIQUE(owner_id, network_name)` constraint) |
| 400 | `quota exceeded: max N networks for free plan` | Plan quota gate ([`auth.ts:184-189`](https://github.com/sleep2agi/agent-network/blob/main/server/src/auth.ts#L184); admins are exempt; free plan default `max_networks_owned = 2`). Note this gate **is** enforced, unlike the `max_members` column, which is dormant |
| 400 | `quota exceeded: max N networks for free plan` | **What actually rejects a network creation is the plan quota** — enforced in [`auth.ts`](https://github.com/sleep2agi/agent-network/blob/main/server/src/auth.ts) `createNetwork()` (the old `L184-189` pin has drifted onto token-issuing code, so this now pins the function name; admins are exempt; free plan default `max_networks_owned = 2`). Note this gate **is** enforced, unlike the `max_members` column, which is dormant.
⚠️ Do not confuse it with the `limits` block from `/api/license` (trial defaults `max_agents=5` / `max_networks=3` / `max_tasks_day=500`): those are **soft limits** — the server only stores and returns them and enforces nothing (the CLI prints them as `Soft limits`). The two `networks` numbers even differ (3 vs 2); the plan quota is the one that applies |
| 401 | `token required` / `invalid token` | Missing / invalid utok_ |

---
Expand Down Expand Up @@ -1532,10 +1533,10 @@ curl -N "http://localhost:9200/events/coder-1?token=ntok_xxx"
| `new_message` | New chat message (`send_message`) | `{from, message_id}` |
| `new_reply` | Reply to a task (`send_reply`) | `{from, message_id, in_reply_to, status}` |
| `broadcast` | Broadcast received (`broadcast` tool) | `{inbox_count}` |
| `chained_reply` | Sub-task completion routed back to the parent task's originator ([`tools.ts:286/646`](https://github.com/sleep2agi/agent-network/blob/main/server/src/tools.ts#L286)) | `{parent_task_id, child_task_id, child_alias}` |
| `chained_reply` | Sub-task completion routed back to the parent task's originator ([`tools.ts:286/646`](https://github.com/sleep2agi/agent-network/blob/main/server/src/tools.ts)) | `{parent_task_id, child_task_id, child_alias}` |
| `node.renamed` | Broadcast on RFC-010 node-rename COMMIT ([`rename.ts:100-123`](https://github.com/sleep2agi/agent-network/blob/main/server/src/rename.ts#L100)); pushed to the old + new alias streams **plus every network member's user channel** (the dashboard subscribes to `/events/<username>`, not per-alias streams — #84 SSE channel fix) | `{txn_id, alias(=new_alias), network_id, data:{old_alias, new_alias, surfaces_updated[], history_policy:"preserve"}}` |

> Earlier docs claimed `new_message` carried a `message` field and `broadcast` carried `{content, from}` — neither is correct. Verify [`tools.ts:571 + 911`](https://github.com/sleep2agi/agent-network/blob/main/server/src/tools.ts#L571) for the actual payloads. Note: `new_task` / `new_message` additionally carry a `renamed_from` field (the old alias) when the target alias was just renamed — the `canonical.renamed` branch in `tools.ts`.
> Earlier docs claimed `new_message` carried a `message` field and `broadcast` carried `{content, from}` — neither is correct. Verify [`tools.ts:571 + 911`](https://github.com/sleep2agi/agent-network/blob/main/server/src/tools.ts) for the actual payloads. Note: `new_task` / `new_message` additionally carry a `renamed_from` field (the old alias) when the target alias was just renamed — the `canonical.renamed` branch in `tools.ts`.
>
> **Correction**: the table previously listed a `heartbeat` event with `{time}` payload. No such JSON event is emitted. [`push.ts:38-44`](https://github.com/sleep2agi/agent-network/blob/main/server/src/push.ts#L38) sends an SSE **comment line** `: keepalive\n\n` every 30s purely to defeat proxy/LB idle timeouts — comments are NOT delivered to `EventSource.onmessage` / `addEventListener` and carry no payload. The real once-per-connection initial event is `connected` (agent-node handles it explicitly at [`agent-node/src/cli.ts`](https://github.com/sleep2agi/agent-network/blob/main/agent-node/src/cli.ts)).

Expand Down Expand Up @@ -2130,7 +2131,7 @@ curl http://localhost:9200/api/license
{
"ok": true,
"license": { "type": "trial", "expires_at": "2026-04-25 12:00:00", "days_left": 12, "expired": false },
"limits": { "max_agents": 5, "max_networks": 1, "max_tasks_day": 100 }
"limits": { "max_agents": 5, "max_networks": 3, "max_tasks_day": 500 }
}
```

Expand Down
3 changes: 0 additions & 3 deletions docs/doc-source-pins-baseline.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,4 @@
# 修一条就把它从这里删掉 —— 门会检查这一点,不删会红。
# 修法见 #831:优先把行号锚点换成符号锚点(读者用 git grep 定位,重构改不坏)。

server/src/auth.ts#L184
server/src/push.ts#L38
server/src/tools.ts#L521
server/src/tools.ts#L571
6 changes: 3 additions & 3 deletions docs/tests/report-test831.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@ python=Python 3.12.13
[L0] denominator
listing_mode=walk
scanned_doc_files=106
pin_occurrences=35
pin_occurrences=28
pins_on_immutable_ref=0
pin_doc_pairs=35
unique_pins=15
unique_pins=11
broken_pins=5
baseline_entries=5

OK: 失效 pin 5 个,基线 5 条 —— 没有新增,也没有该清的残留。
注意:这只说明已知失效的那批没变多。它抓不到「锚点指着一行正常代码、
只是不是声称的那一行」—— 实测召回率 5/10,详见本文件头部。
OK walk 路径与 git 路径给出同一份清单(106 文件 / 15 唯一 pin / 35 处)
OK walk 路径与 git 路径给出同一份清单(106 文件 / 11 唯一 pin / 28 处)
[L1] clean tree passes
OK rc=0 broken_pins=5(全部在基线里)
[L2] witnessed-red: a NEW broken pin must turn it red
Expand Down
26 changes: 21 additions & 5 deletions tests/test831-doc-source-pins/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,23 @@ broken=$(printf '%s' "$out" | sed -nE 's/^broken_pins=([0-9]+)$/\1/p')
# 正好 3 条,18 - 3 = 15。`occ` 仍是 35(钉提交不减少"出现次数",只改变引用形式),
# `files` 仍是 106 —— **只有一个数变了,而且变的原因能逐条指出来**。这正是这道
# 断言想逼出来的动作:数字变了要有人说清是进展还是扫漏,而不是把它改宽。
#
# 2026-08-18(第二次):15 → 11,35 → 28。#810 把 docs-site 中英两版 api/rest.md 里
# 4 个唯一 pin 的 `#L` 锚点去掉了(链接保留,只是不再钉行号),逐条数得出来:
#
# server/src/tools.ts#L521 ×2(中/英)
# server/src/tools.ts#L571 ×2
# server/src/tools.ts#L286 ×2
# server/src/auth.ts#L184 ×1
# ─────────────────────────────
# 唯一 4 个,出现 7 处
#
# 15 − 4 = 11,35 − 7 = 28,`files` 仍 106。**加回来的锚点数是 0**(diff 的 `+` 侧
# 一个 `#L` 都没有),所以这是净减少,不是"挪了个位置"。
[[ "$files" -eq 106 ]] || fail "预期扫 106 个文档文件(= git ls-files 的结果),实际 $files"
[[ "$uniq" -eq 15 ]] || fail "预期 15 个唯一 pin,实际 $uniq"
[[ "$occ" -eq 35 ]] || fail "预期 35 处原始出现,实际 $occ"
echo " OK walk 路径与 git 路径给出同一份清单(106 文件 / 15 唯一 pin / 35 处)"
[[ "$uniq" -eq 11 ]] || fail "预期 11 个唯一 pin,实际 $uniq"
[[ "$occ" -eq 28 ]] || fail "预期 28 处原始出现,实际 $occ"
echo " OK walk 路径与 git 路径给出同一份清单(106 文件 / 11 唯一 pin / 28 处)"

# ---------------------------------------------------------------------------
# L1 — 干净树上必须绿
Expand Down Expand Up @@ -304,7 +317,10 @@ cmp -s "$BASELINE" /tmp/bl7.bak || fail "② 它拒绝了,却还是把基线写
echo " MUTATION_RED write-baseline-refuses-new-failure rc=$rc12"

# ③ 引用消失时要删对,并保留表头注释
BL_BEFORE=$(grep -cv '^\s*#\|^\s*$' "$BASELINE")
# 🔴 `grep -c` 在计数为 0 时退出码是 1,而这一段 set -e 是开着的
# ⇒ `VAR=$(grep -c …)` 会**静默**终止整个脚本(没有任何 FAIL 输出)。
# 而计数为 0 恰恰是这道门**清干净了**才会出现的状态 —— 又一次「门赢了自己就坏」。
BL_BEFORE=$(grep -cv '^\s*#\|^\s*$' "$BASELINE" || true)
# 🔴 造场景用的 SHA 必须是**仓里不可能出现的**合成值,不能借用一个真实提交。
# 原来这里用 22ed1886 —— 而 #834 之后 changelog 里**真的**有
# `blob/22ed1886/server/src/index.ts#L253`,于是下面的复原(全局把
Expand Down Expand Up @@ -333,7 +349,7 @@ print(f" (造场景:把 {target} 的 {n} 处引用改钉合成 SHA,涉及 {le
PYX
out13=$(python3 "$CHECK" "$ROOT" --write-baseline) || fail "③ 有该删的条目时 --write-baseline 却非零"
printf '%s' "$out13" | grep -qF "已改写基线" || fail "③ 没报告改写"
BL_AFTER=$(grep -cv '^\s*#\|^\s*$' "$BASELINE")
BL_AFTER=$(grep -cv '^\s*#\|^\s*$' "$BASELINE" || true)
[[ "$BL_AFTER" -lt "$BL_BEFORE" ]] || fail "③ 基线没有变小($BL_BEFORE → $BL_AFTER)"
head -1 "$BASELINE" | grep -q '^#' || fail "③ 改写把表头注释弄丢了"
python3 "$CHECK" "$ROOT" >/dev/null || fail "③ 改写之后门没有转绿"
Expand Down
Loading