@agfpd/iapeer 0.4.104 → 0.4.105
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/docs/09-runtimes.md +2 -0
- package/docs/10-messaging.md +1 -1
- package/docs/ru/09-/321/200/320/260/320/275/321/202/320/260/320/271/320/274/321/213.md +2 -0
- package/docs/ru/10-/320/276/320/261/320/274/320/265/320/275-/321/201/320/276/320/276/320/261/321/211/320/265/320/275/320/270/321/217/320/274/320/270.md +1 -1
- package/package.json +1 -1
- package/src/transport/index.ts +17 -13
package/docs/09-runtimes.md
CHANGED
|
@@ -67,6 +67,8 @@ iapeer default-runtime codex --all # all peers
|
|
|
67
67
|
|
|
68
68
|
Switches the primary runtime — where routing goes and which runtime comes up first. A bulk `--all` switch is exactly the "transplant" of the whole team from one agent runtime to another; it's symmetric back (`default-runtime claude --all`). The command refuses if the peer doesn't declare that runtime (run `add-runtime` first), and skips infrastructure peers. The registry is fixed in the same command, so routing switches at once.
|
|
69
69
|
|
|
70
|
+
The routing choice is strict: a send without an explicit `runtime` always targets `default_runtime`. A live session on another declared runtime does not capture that send; if the default session is asleep, the daemon wakes it. Passing `runtime` explicitly remains the way to target a non-default surface.
|
|
71
|
+
|
|
70
72
|
## Connecting Telegram: connect
|
|
71
73
|
|
|
72
74
|
```bash
|
package/docs/10-messaging.md
CHANGED
|
@@ -25,7 +25,7 @@ The `--from` flag sets the sender (`<runtime>-<name>`); by default it's the iden
|
|
|
25
25
|
|
|
26
26
|
## The delivery path
|
|
27
27
|
|
|
28
|
-
The daemon finds the recipient in the registry and looks at
|
|
28
|
+
The daemon finds the recipient in the registry and selects its endpoint first. With no explicit `runtime`, the endpoint is always the recipient's `default_runtime`; liveness of other declared runtimes does not change that choice. An explicit `runtime` selects that exact surface. The daemon then looks at the selected endpoint's state:
|
|
29
29
|
|
|
30
30
|
- **alive** — the daemon writes the message into the peer's session through the supervisor socket onto the session's input. The daemon waits for confirmation that the input was accepted (the input field cleared); the answer is `delivered`.
|
|
31
31
|
- **busy** (the agent is mid-turn, the input field isn't empty) — the message goes into the composer queue and is delivered as soon as the agent is free; the answer to the sender is `queued`. The queue waits up to 120 seconds, then force-delivers.
|
|
@@ -67,6 +67,8 @@ iapeer default-runtime codex --all # все пиры
|
|
|
67
67
|
|
|
68
68
|
Переключает основной рантайм — куда идёт маршрутизация и какой рантайм поднимается первым. Массовое переключение `--all` — это и есть «пересадка» всей команды с одного агентского рантайма на другой; обратно симметрично (`default-runtime claude --all`). Команда откажет, если пир не объявляет этот рантайм (сначала `add-runtime`), и пропустит инфраструктурных. Реестр чинится в той же команде, поэтому маршрутизация переключается сразу.
|
|
69
69
|
|
|
70
|
+
Выбор для маршрутизации строгий: отправка без явного `runtime` всегда целится в `default_runtime`. Живая сессия на другом объявленном рантайме не перехватывает такую отправку; если дефолтная сессия спит, демон будит её. Явный `runtime` по-прежнему выбирает конкретную недефолтную поверхность.
|
|
71
|
+
|
|
70
72
|
## Подключение Telegram: connect
|
|
71
73
|
|
|
72
74
|
```bash
|
|
@@ -25,7 +25,7 @@ iapeer send assistant --message "..." --topic "релиз" --from claude-reviewe
|
|
|
25
25
|
|
|
26
26
|
## Путь доставки
|
|
27
27
|
|
|
28
|
-
Демон находит получателя в реестре и смотрит на
|
|
28
|
+
Демон находит получателя в реестре и сначала выбирает поверхность доставки. Без явного `runtime` это всегда `default_runtime` адресата; живость других объявленных рантаймов выбор не меняет. Явный `runtime` выбирает ровно указанную поверхность. Затем демон смотрит на состояние выбранной поверхности:
|
|
29
29
|
|
|
30
30
|
- **живой** — демон пишет сообщение в сессию пира через сокет супервизора на ввод сессии. Демон ждёт подтверждения, что ввод принят (поле ввода очистилось); ответ — `доставлено`.
|
|
31
31
|
- **занят** (агент в середине хода, поле ввода не пустое) — сообщение встаёт в очередь композера и доставляется, как только агент освободится; ответ отправителю — `в очереди`. Очередь ждёт до 120 секунд, потом досылает принудительно.
|
package/package.json
CHANGED
package/src/transport/index.ts
CHANGED
|
@@ -162,12 +162,18 @@ export function resolvePeerDeliveryTarget(
|
|
|
162
162
|
peer: PeerRecord,
|
|
163
163
|
env: NodeJS.ProcessEnv = process.env,
|
|
164
164
|
): Result<DeliveryTarget> {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
165
|
+
// Routing is CONFIG-ANCHORED, not liveness-selected. An omitted runtime means
|
|
166
|
+
// exactly the peer's default_runtime (`PeerRecord.runtime` is the normalized
|
|
167
|
+
// in-memory name), even when another declared runtime already has a live
|
|
168
|
+
// session. If that default endpoint is asleep, returning its exact offline
|
|
169
|
+
// miss is load-bearing: routeSend will wake THE DEFAULT instead of falling
|
|
170
|
+
// through to whichever non-default session happens to be alive.
|
|
171
|
+
//
|
|
172
|
+
// An explicit runtime remains an exact override. `resolveDeliveryTarget`
|
|
173
|
+
// without a runtime is deliberately NOT used here: its sole-live discovery is
|
|
174
|
+
// useful for observation/control callers, but would silently defeat the
|
|
175
|
+
// operator's `default-runtime` routing lever.
|
|
176
|
+
return resolveDeliveryTarget({ personality, runtime: runtime ?? peer.runtime, env })
|
|
171
177
|
}
|
|
172
178
|
|
|
173
179
|
// Confirm poll interval — how often deliverViaHost re-reads the transcript for a NEW record carrying
|
|
@@ -1407,8 +1413,7 @@ export function hasTelegramPresence(record: PeerRecord): boolean {
|
|
|
1407
1413
|
* ok:true — a false-OK + silent loss, the class this contract forbids. Applied to
|
|
1408
1414
|
* the INTENDED channel (override / target default — before any wake side-effect,
|
|
1409
1415
|
* since a wake delivers the envelope as the boot first-message) AND to the RESOLVED
|
|
1410
|
-
* channel at both delivery points (
|
|
1411
|
-
* telegram without either). */
|
|
1416
|
+
* channel at both delivery points (defence in depth against registry/wake drift). */
|
|
1412
1417
|
function telegramSenderGuard(
|
|
1413
1418
|
caller: ResolvedCaller,
|
|
1414
1419
|
targetRuntime: string,
|
|
@@ -1500,9 +1505,8 @@ async function routeSendInner(
|
|
|
1500
1505
|
// a mismatch is HELD (persisted verbatim + instructive error), not delivered — the
|
|
1501
1506
|
// agent then confirms cross-channel or redirects to the origin, zero regeneration.
|
|
1502
1507
|
// Intended runtime = the explicit override or the human's default; exact for the
|
|
1503
|
-
// natural-peer class (
|
|
1504
|
-
//
|
|
1505
|
-
// window). Initiative (answered / no inbound / ARM_TTL-stale) passes untouched.
|
|
1508
|
+
// natural-peer class (implicit routing is strictly default_runtime-anchored).
|
|
1509
|
+
// Initiative (answered / no inbound / ARM_TTL-stale) passes untouched.
|
|
1506
1510
|
if (
|
|
1507
1511
|
!deps.originGuardBypass &&
|
|
1508
1512
|
originGuardEnabled(env) &&
|
|
@@ -1561,8 +1565,8 @@ async function routeSendInner(
|
|
|
1561
1565
|
const target = resolvePeerDeliveryTarget(personality, runtime, peer, env)
|
|
1562
1566
|
if (target.ok) {
|
|
1563
1567
|
if (target.value.address === caller.address) return err('cannot send to self')
|
|
1564
|
-
// Telegram sender policy — RESOLVED channel (
|
|
1565
|
-
//
|
|
1568
|
+
// Telegram sender policy — RESOLVED channel (defence in depth: the resolved
|
|
1569
|
+
// target must still obey the domain guard even though selection is exact).
|
|
1566
1570
|
const liveGuard = telegramSenderGuard(caller, target.value.runtime, personality)
|
|
1567
1571
|
if (!liveGuard.ok) return liveGuard
|
|
1568
1572
|
const queued = await deps.composerQueue?.tryEnqueue({ caller, peer, target: target.value, envelope, topic, sentAt })
|