@songsid/agend 2.3.4-beta.7 → 2.3.4-beta.9
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/THIRD_PARTY_NOTICES.md +37 -0
- package/dist/agent-cli-instructions.md +1 -1
- package/dist/agent-credentials.d.ts +24 -0
- package/dist/agent-credentials.js +66 -0
- package/dist/agent-credentials.js.map +1 -0
- package/dist/agent-endpoint.d.ts +3 -1
- package/dist/agent-endpoint.js +13 -0
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/authority/session-authorizations.d.ts +28 -4
- package/dist/authority/session-authorizations.js +63 -17
- package/dist/authority/session-authorizations.js.map +1 -1
- package/dist/backend/antigravity.js +3 -1
- package/dist/backend/antigravity.js.map +1 -1
- package/dist/backend/codex-footer-hints.d.ts +4 -0
- package/dist/backend/codex-footer-hints.js +27 -0
- package/dist/backend/codex-footer-hints.js.map +1 -0
- package/dist/backend/codex.js +8 -3
- package/dist/backend/codex.js.map +1 -1
- package/dist/backend/kiro.d.ts +3 -0
- package/dist/backend/kiro.js +39 -1
- package/dist/backend/kiro.js.map +1 -1
- package/dist/backend/muse.js +5 -3
- package/dist/backend/muse.js.map +1 -1
- package/dist/backend/types.d.ts +6 -1
- package/dist/backend/types.js +3 -0
- package/dist/backend/types.js.map +1 -1
- package/dist/cache-ledger.d.ts +85 -0
- package/dist/cache-ledger.js +236 -1
- package/dist/cache-ledger.js.map +1 -1
- package/dist/cache-service.d.ts +5 -0
- package/dist/cache-service.js +16 -4
- package/dist/cache-service.js.map +1 -1
- package/dist/channel/adapters/discord.js +11 -3
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/adapters/telegram.js +4 -3
- package/dist/channel/adapters/telegram.js.map +1 -1
- package/dist/channel/mcp-tools.js +1 -1
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/cross-instance-notice.d.ts +10 -0
- package/dist/cross-instance-notice.js +67 -5
- package/dist/cross-instance-notice.js.map +1 -1
- package/dist/daemon.d.ts +43 -0
- package/dist/daemon.js +361 -17
- package/dist/daemon.js.map +1 -1
- package/dist/delivery-consumed-watch.d.ts +23 -1
- package/dist/delivery-consumed-watch.js +30 -3
- package/dist/delivery-consumed-watch.js.map +1 -1
- package/dist/delivery-reconciliation.d.ts +7 -0
- package/dist/delivery-reconciliation.js +9 -1
- package/dist/delivery-reconciliation.js.map +1 -1
- package/dist/export-import.d.ts +7 -0
- package/dist/export-import.js +44 -10
- package/dist/export-import.js.map +1 -1
- package/dist/fleet-context.d.ts +2 -0
- package/dist/fleet-manager.d.ts +85 -4
- package/dist/fleet-manager.js +375 -30
- package/dist/fleet-manager.js.map +1 -1
- package/dist/general-knowledge/skills/concepts/SKILL.md +390 -0
- package/dist/general-knowledge/skills/cross-instance-messaging/SKILL.md +1 -0
- package/dist/general-knowledge/skills/instance-lifecycle/SKILL.md +3 -1
- package/dist/general-knowledge/skills/kiro-engine-migration/SKILL.md +41 -4
- package/dist/general-knowledge/skills/worker-collaboration/SKILL.md +1 -1
- package/dist/instance-lifecycle.d.ts +8 -2
- package/dist/instance-lifecycle.js +37 -6
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/instance-topic-delete.d.ts +77 -0
- package/dist/instance-topic-delete.js +123 -0
- package/dist/instance-topic-delete.js.map +1 -0
- package/dist/instructions.d.ts +1 -1
- package/dist/instructions.js +1 -1
- package/dist/instructions.js.map +1 -1
- package/dist/kiro-engine-status.d.ts +11 -0
- package/dist/kiro-engine-status.js +6 -0
- package/dist/kiro-engine-status.js.map +1 -1
- package/dist/locale.js +47 -1
- package/dist/locale.js.map +1 -1
- package/dist/log-steps.d.ts +4 -3
- package/dist/log-steps.js +32 -7
- package/dist/log-steps.js.map +1 -1
- package/dist/login-flows.d.ts +2 -0
- package/dist/login-flows.js +5 -2
- package/dist/login-flows.js.map +1 -1
- package/dist/needs-you-hub.js +1 -1
- package/dist/needs-you-hub.js.map +1 -1
- package/dist/needs-you.d.ts +6 -0
- package/dist/needs-you.js +8 -2
- package/dist/needs-you.js.map +1 -1
- package/dist/outbound-handlers.js +3 -3
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.js +5 -2
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/queued-handoffs.d.ts +33 -0
- package/dist/queued-handoffs.js +75 -0
- package/dist/queued-handoffs.js.map +1 -0
- package/dist/scheduler/db.d.ts +2 -1
- package/dist/scheduler/db.js +23 -9
- package/dist/scheduler/db.js.map +1 -1
- package/dist/settings-api.d.ts +13 -0
- package/dist/settings-api.js +12 -1
- package/dist/settings-api.js.map +1 -1
- package/dist/tool-permissions.d.ts +5 -2
- package/dist/tool-permissions.js +6 -5
- package/dist/tool-permissions.js.map +1 -1
- package/dist/tool-progress.d.ts +2 -0
- package/dist/tool-progress.js +19 -3
- package/dist/tool-progress.js.map +1 -1
- package/dist/topic-commands.js +4 -0
- package/dist/topic-commands.js.map +1 -1
- package/dist/ui/chat-strings.js +2 -2
- package/dist/ui/fleet-usage.js +90 -27
- package/dist/ui/panel-chat.js +2 -0
- package/dist/ui/panel-needs.js +4 -3
- package/dist/ui/settings-strings.js +2 -2
- package/dist/ui/shared/app-i18n.js +2 -2
- package/dist/ui/shared/app-needs.js +1 -1
- package/dist/ui/shared/app.css +15 -0
- package/dist/ui/shared/usage-dialog.js +18 -1
- package/dist/ui/shared/view-strings.js +16 -0
- package/dist/usage/capacity.d.ts +69 -0
- package/dist/usage/capacity.js +119 -0
- package/dist/usage/capacity.js.map +1 -0
- package/dist/usage/i18n-keys.d.ts +1 -1
- package/dist/usage/i18n-keys.js +3 -0
- package/dist/usage/i18n-keys.js.map +1 -1
- package/dist/usage/profile-timeline.d.ts +16 -0
- package/dist/usage/profile-timeline.js +58 -0
- package/dist/usage/profile-timeline.js.map +1 -0
- package/dist/usage/quota-history.d.ts +43 -0
- package/dist/usage/quota-history.js +168 -0
- package/dist/usage/quota-history.js.map +1 -0
- package/dist/usage/usage-api.d.ts +31 -0
- package/dist/usage/usage-api.js +80 -1
- package/dist/usage/usage-api.js.map +1 -1
- package/dist/usage-report.d.ts +25 -1
- package/dist/usage-report.js +55 -4
- package/dist/usage-report.js.map +1 -1
- package/dist/usage-rollup.d.ts +4 -1
- package/dist/usage-rollup.js +12 -3
- package/dist/usage-rollup.js.map +1 -1
- package/dist/web-api.d.ts +6 -0
- package/dist/web-api.js +8 -2
- package/dist/web-api.js.map +1 -1
- package/dist/web-session-authorization.d.ts +13 -2
- package/dist/web-session-authorization.js +10 -3
- package/dist/web-session-authorization.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: concepts
|
|
3
|
+
description: AgEnD product concepts and definitions — fleet, instances, General, tool sets, delivery, schedules, and the rest; the agents' built-in role reference
|
|
4
|
+
roles: [general, worker]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# AgEnD concepts and definitions
|
|
8
|
+
|
|
9
|
+
Draft. Each term states what the code on main does today, verified against the
|
|
10
|
+
listed files. Anything inferred is marked. These definitions were approved by the project
|
|
11
|
+
owner; behaviour that differs from them is a bug or needs a decision.
|
|
12
|
+
Where code and a decision disagree, see Mismatches at the end. Fleet decisions are scoped to the leader's project root and cannot be
|
|
13
|
+
opened by readers, so each citation carries its user-facing summary inline.
|
|
14
|
+
|
|
15
|
+
## fleet
|
|
16
|
+
|
|
17
|
+
The whole multi-agent system on one host: its instances, schedules, teams,
|
|
18
|
+
decisions and task board, driven by one daemon from one `fleet.yaml` in one
|
|
19
|
+
AgEnD home (`~/.agend`).
|
|
20
|
+
|
|
21
|
+
- Can: run agents reachable from chat connections, the web dashboard, or both.
|
|
22
|
+
- Can't: span hosts. There is one daemon, one fleet process, one home dir.
|
|
23
|
+
- Code: `src/fleet-manager.ts` (`FleetManager`), `src/config.ts` (`FleetConfig`).
|
|
24
|
+
- Refs: —
|
|
25
|
+
|
|
26
|
+
## instance / agent
|
|
27
|
+
|
|
28
|
+
One agent is one instance: a daemon driving one CLI in its own tmux pane, with
|
|
29
|
+
its own transcript, topic or room, and tool set. `instance` is the config and
|
|
30
|
+
runtime word (`fleet.yaml` `instances`); `agent` is the everyday word.
|
|
31
|
+
|
|
32
|
+
- Can: chat and call MCP tools within its tool set; message peers with
|
|
33
|
+
`send_to_instance`, `delegate_task`, `report_result`.
|
|
34
|
+
- Can't: exceed its tool set, or touch another instance's state except through
|
|
35
|
+
fleet tools (same-OS-user processes are not isolated from each other —
|
|
36
|
+
see `docs/design/coordinator-tool-perms.zh-TW.md`).
|
|
37
|
+
- Code: `src/daemon.ts`, `src/instance-lifecycle.ts`.
|
|
38
|
+
- Refs: #804.
|
|
39
|
+
|
|
40
|
+
## General
|
|
41
|
+
|
|
42
|
+
The user's definition (fleet decision 9e3bea6c, "General is the AgEnD
|
|
43
|
+
administrator", user 2026-11-04): as of beta.8 the `general` tool profile gets
|
|
44
|
+
the full ORCHESTRATION set — instance create, delete, replace, start, stop,
|
|
45
|
+
pause, wake and restart; templates; teams; `update_fleet_defaults`;
|
|
46
|
+
`update_instance_config`; the kiro migrate and reconcile tools;
|
|
47
|
+
`update_decision`; web settings — with no extra confirmation. The existing
|
|
48
|
+
confirmations stay: sensitive config (tokens and access) is confirmed by a
|
|
49
|
+
fleet admin, and #804 still refuses `tool_set` or `skipPermissions` escalation.
|
|
50
|
+
It supersedes the 2026-09-21 "dispatcher" rationale and lands in beta.8 (agy's
|
|
51
|
+
PR). General is the fleet's admin instance — the first agent on a new fleet —
|
|
52
|
+
and owns the General topic. An instance runs under the `general` tool set when
|
|
53
|
+
`general_topic: true` or its name is `general`.
|
|
54
|
+
|
|
55
|
+
- Can (as of beta.8): everything in the worker profile plus the full
|
|
56
|
+
ORCHESTRATION set, delegation, schedules, and the user's web-appearance
|
|
57
|
+
settings.
|
|
58
|
+
- Can't: exceed that set. Note the code on main is pre-beta.8 and still shows
|
|
59
|
+
the smaller subset (`src/tool-permissions.ts:107-136` holds only
|
|
60
|
+
`create/start/restart/wake_instance` plus the web settings
|
|
61
|
+
(`get/set_web_settings`) of the orchestration verbs) — expected
|
|
62
|
+
to change when beta.8 lands; see Mismatches.
|
|
63
|
+
- Code: `src/tool-permissions.ts:107-136`, `:201-208`;
|
|
64
|
+
`src/instance-lifecycle.ts:2741` (the General instance cannot be replaced).
|
|
65
|
+
- Refs: fleet decision 9e3bea6c.
|
|
66
|
+
|
|
67
|
+
## `coordinator` tool set
|
|
68
|
+
|
|
69
|
+
`TOOL_PROFILES.coordinator = WORKER + ORCHESTRATION`: every worker ability plus
|
|
70
|
+
every verb that runs the fleet rather than does the work — for an agent that
|
|
71
|
+
runs part of the fleet.
|
|
72
|
+
|
|
73
|
+
- Can: create/delete/replace/start/stop/pause/wake/restart instances, manage
|
|
74
|
+
teams and templates, edit fleet defaults and instance config, run kiro
|
|
75
|
+
migration/reconciliation, change others' decisions and web settings
|
|
76
|
+
(`src/tool-permissions.ts:80-93`).
|
|
77
|
+
- Can't: exceed the table — anything not listed is refused, with the reason
|
|
78
|
+
naming what the instance runs under.
|
|
79
|
+
- Code: `src/tool-permissions.ts:100-107`.
|
|
80
|
+
- Refs: `docs/design/coordinator-tool-perms.zh-TW.md` (zh-TW only).
|
|
81
|
+
|
|
82
|
+
## worker
|
|
83
|
+
|
|
84
|
+
An instance doing the work under the `worker` profile — the default when no
|
|
85
|
+
`tool_set` is written (`resolveToolSet`, `src/tool-permissions.ts:201-208`).
|
|
86
|
+
|
|
87
|
+
- Can: talk to people, report to peers (`send_to_instance`, `report_result`,
|
|
88
|
+
`request_information`, `broadcast`, `delegate_task`, `delivery_status`),
|
|
89
|
+
read fleet state, run its own task cards and schedules, keep its own theme
|
|
90
|
+
and Office character.
|
|
91
|
+
- Can't: any orchestration verb. A refused call names the coordinator and
|
|
92
|
+
suggests reporting back instead (`src/tool-permissions.ts:357-374`).
|
|
93
|
+
- Code: `src/tool-permissions.ts:33-72` (`WORKER`), `:185-208`.
|
|
94
|
+
- Refs: #804, #895 (own schedules only).
|
|
95
|
+
|
|
96
|
+
## team and team leader
|
|
97
|
+
|
|
98
|
+
A team is a named group of instances (`fleet.yaml` `teams`) for targeted
|
|
99
|
+
broadcasts and display grouping. A team leader is an instance that runs a
|
|
100
|
+
team, given the `coordinator` (or `full`) tool set — a convention, not a
|
|
101
|
+
separate role in code (approved by the user 2026-11-04).
|
|
102
|
+
|
|
103
|
+
- Can: address several instances at once; group the sidebar and Office.
|
|
104
|
+
- Can't: confer any authority — no leader election, no extra tools.
|
|
105
|
+
- Code: `create_team`, `list_teams`, `update_team`, `delete_team`
|
|
106
|
+
(`src/channel/mcp-tools.ts`).
|
|
107
|
+
- Refs: —
|
|
108
|
+
|
|
109
|
+
## topic / General topic
|
|
110
|
+
|
|
111
|
+
A topic is the chat home of one instance: a Telegram forum topic (or the
|
|
112
|
+
equivalent scope on another connection) bound to it. The General topic is the
|
|
113
|
+
General instance's topic. Commands that belong to General answer "works in the
|
|
114
|
+
General topic" anywhere else.
|
|
115
|
+
|
|
116
|
+
- Can: reach exactly that instance by talking there.
|
|
117
|
+
- Can't: run General-only commands from another topic.
|
|
118
|
+
- Code: `src/topic-commands.ts:836-839` (a General command typed in an
|
|
119
|
+
instance topic points to General, never to that agent);
|
|
120
|
+
`src/locale.ts:880` ("works in the General topic");
|
|
121
|
+
`src/tool-permissions.ts:207`.
|
|
122
|
+
- Refs: —
|
|
123
|
+
|
|
124
|
+
## Classic (ClassicBot) room
|
|
125
|
+
|
|
126
|
+
A private chat or group where ClassicBot runs a single agent, managed by
|
|
127
|
+
`classicBot.yaml` — separate from fleet topics, with its own admins
|
|
128
|
+
(`defaults.admin_users`) and chat allowlists.
|
|
129
|
+
|
|
130
|
+
- Can: `/start` an agent in the room and chat with it.
|
|
131
|
+
- Can't: use fleet-topic commands or see the fleet; an unregistered chat stays
|
|
132
|
+
silent unless `/start` is allowed.
|
|
133
|
+
- Code: `src/classic-channel-manager.ts`.
|
|
134
|
+
- Refs: `docs/permissions.md`.
|
|
135
|
+
|
|
136
|
+
## web-only fleet
|
|
137
|
+
|
|
138
|
+
A fleet with no Discord or Telegram connection at all, used from the web
|
|
139
|
+
dashboard (user decision, 2026-11-01/02). Its agents run in topic mode, so they
|
|
140
|
+
can still message each other from the dashboard.
|
|
141
|
+
|
|
142
|
+
- Can: everything chat fleets do, through `/ui` instead of chat.
|
|
143
|
+
- Can't: chat ingress; `/web revoke` (there is no `/web`) — its Notice names
|
|
144
|
+
the host's way, signing every browser out.
|
|
145
|
+
- Code: `src/web-only-fleet.ts:10-22`; `src/fleet-manager.ts:7807-7808`.
|
|
146
|
+
- Refs: 28c2d3a3.
|
|
147
|
+
|
|
148
|
+
## host owner / operator
|
|
149
|
+
|
|
150
|
+
The person on the AgEnD computer. On a web-only fleet, the `agend web --code`
|
|
151
|
+
session on this computer (`HOST_OPERATOR`): it confirms its own authority and
|
|
152
|
+
answers its own prompts.
|
|
153
|
+
|
|
154
|
+
- Can: confirm web authority, sign in, approve what asks for the host operator.
|
|
155
|
+
- Can't: act as operator from another machine, or after the session was
|
|
156
|
+
revoked or ran out.
|
|
157
|
+
- Code: `src/authority/web-authority.ts` (`HOST_OPERATOR`);
|
|
158
|
+
`src/fleet-manager.ts:2056-2060`; `src/locale.ts:1505-1506`.
|
|
159
|
+
- Refs: 28c2d3a3.
|
|
160
|
+
|
|
161
|
+
## fleet admin (`admin_users`)
|
|
162
|
+
|
|
163
|
+
A platform user id listed in a channel's `access.allowed_users` (fleet), or in
|
|
164
|
+
`defaults.admin_users` / `allowed_users` (ClassicBot). Admin is granted per
|
|
165
|
+
person, never per instance. Fleet admin = the people; General = the
|
|
166
|
+
administrator agent that carries out admin work for whoever may talk to it in
|
|
167
|
+
the General topic (approved by the user 2026-11-04).
|
|
168
|
+
|
|
169
|
+
- Can: admin-gated commands, confirming sensitive changes, managing access.
|
|
170
|
+
- Can't: anything while unlisted — an empty list grants nobody, and open
|
|
171
|
+
access or pairing approval alone does not grant the role
|
|
172
|
+
(`docs/SECURITY.md:13`).
|
|
173
|
+
- Code: `src/config-validator.ts:368-376`, `:677`.
|
|
174
|
+
- Refs: —
|
|
175
|
+
|
|
176
|
+
## guest (web)
|
|
177
|
+
|
|
178
|
+
A person who is not a fleet admin, signed in on the dashboard with a guest
|
|
179
|
+
code (`web.guests`, #1920). Guests see only the agents they are granted, in
|
|
180
|
+
chat they could already use.
|
|
181
|
+
|
|
182
|
+
- Can: chat with granted agents; sign out with `/web revoke` (own sessions).
|
|
183
|
+
- Can't: admin routes, Notices, the usage report, or anything over surfaces
|
|
184
|
+
the fleet closed to guests.
|
|
185
|
+
- Code: `src/config-validator.ts:738-740`.
|
|
186
|
+
- Refs: #1920.
|
|
187
|
+
|
|
188
|
+
## tool set / tool profile (`full`, `coordinator`, `general`, `worker`, `standard`, `minimal`)
|
|
189
|
+
|
|
190
|
+
The server-side table that decides which MCP tools an instance may call
|
|
191
|
+
(`TOOL_PROFILES`, `src/tool-permissions.ts:103-155`). `defaults.tool_set`
|
|
192
|
+
applies to every instance without its own value, including General; an
|
|
193
|
+
explicit `tool_set` always wins, otherwise the General instance gets `general`
|
|
194
|
+
and everything else defaults to `worker` (`resolveToolSet`, `:201-208`).
|
|
195
|
+
|
|
196
|
+
- `full`: every tool. Set explicitly only; nothing resolves to it by default
|
|
197
|
+
(the env-only fallback excepted, `:212-222`).
|
|
198
|
+
- `coordinator`: worker abilities plus all orchestration verbs — the profile
|
|
199
|
+
for running the fleet.
|
|
200
|
+
- `general`: General's administrator profile — as of beta.8, worker plus
|
|
201
|
+
every orchestration verb (fleet decision 9e3bea6c); before beta.8 only
|
|
202
|
+
`create/start/restart/wake_instance` — and the user's web settings.
|
|
203
|
+
- `worker`: the default. Doing the work, with reporting (`report_result`)
|
|
204
|
+
that `standard` lacks.
|
|
205
|
+
- `standard`: broad read access plus own schedules and themes, but no
|
|
206
|
+
`report_result`, `delegate_task` or `request_information` — so it cannot
|
|
207
|
+
complete the delegate → work → report protocol.
|
|
208
|
+
- `minimal`: a narrow sender — reply, forward, check delivery, read decisions,
|
|
209
|
+
download, and see emoji/sticker listings.
|
|
210
|
+
- Code: `src/tool-permissions.ts:30-155`.
|
|
211
|
+
- Refs: #804.
|
|
212
|
+
|
|
213
|
+
## Needs you
|
|
214
|
+
|
|
215
|
+
The dashboard's `/ui/needs` queue plus the `needs_you` config: items parked
|
|
216
|
+
for a person — permission prompts, usage-limit holds, dialogs the agent must
|
|
217
|
+
not answer, unconfirmed deliveries.
|
|
218
|
+
|
|
219
|
+
- Can: be acknowledged per item.
|
|
220
|
+
- Can't: be answered by an agent on the person's behalf.
|
|
221
|
+
- Code: `src/config.ts:284-293`; `src/web-api.ts` (`/ui/needs/ack`);
|
|
222
|
+
`src/daemon.ts:1564`, `:2071`, `:9888`.
|
|
223
|
+
- Refs: —
|
|
224
|
+
|
|
225
|
+
## Notices
|
|
226
|
+
|
|
227
|
+
On a web-only fleet, the Notices feed (`/ui/notices`) — what General would
|
|
228
|
+
have said in chat, kept, pushed and listed. Admins only, never a guest.
|
|
229
|
+
|
|
230
|
+
- Can: be listed and marked seen.
|
|
231
|
+
- Can't: be read by guests; on a chat fleet the feed is null because General
|
|
232
|
+
says them.
|
|
233
|
+
- Code: `src/web-api.ts:2346-2349`; `src/fleet-manager.ts:7807-7808`.
|
|
234
|
+
- Refs: #2910 D2.
|
|
235
|
+
|
|
236
|
+
## delivery: ✅ 👀 ❌, "uncertain", queued hand-off (#3030)
|
|
237
|
+
|
|
238
|
+
A channel message's status reactions, driven by the delivering daemon:
|
|
239
|
+
⏳ queued (CLI busy, waiting), 👀 delivered (pasted + Enter, the agent has it),
|
|
240
|
+
✅ confirmed (processing observed, or a native queue hand-off succeeded),
|
|
241
|
+
❌ failed (window gone, retries exhausted). Cross-instance rows add two
|
|
242
|
+
states: `uncertain` — the evidence was inconclusive, so never resend and never
|
|
243
|
+
forward it as consent; and the queued hand-off (#3030) — a message handed to a
|
|
244
|
+
backend-native queue, watched in the transcript and settled ✅ when a turn
|
|
245
|
+
takes it, ❌ when it never does.
|
|
246
|
+
|
|
247
|
+
- Can: tell the sender, at a glance, how far a message got.
|
|
248
|
+
- Can't: prove permission. A receipt proves the CLI accepted the bytes, not
|
|
249
|
+
that the person authorized the act — verify the human receipt before anything
|
|
250
|
+
irreversible.
|
|
251
|
+
- Code: `src/daemon.ts:7907-7913`; `:2450-2545`; `docs/delivery-verification.md`.
|
|
252
|
+
- Refs: #3030, 7244b130, 954e5e96.
|
|
253
|
+
|
|
254
|
+
## schedule
|
|
255
|
+
|
|
256
|
+
A fleet timer: a cron line or a one-shot datetime that injects a message into
|
|
257
|
+
an instance (`create_schedule`, `list_schedules`, `update_schedule`,
|
|
258
|
+
`delete_schedule`). A non-coordinator's schedules may only target itself and
|
|
259
|
+
must be created by itself; acting on other instances' schedules takes the
|
|
260
|
+
`full`, `coordinator` or `general` profile.
|
|
261
|
+
|
|
262
|
+
- Can: wake an instance with a message on a timetable.
|
|
263
|
+
- Can't: reach beyond its scope — the target, not the tool, is the control.
|
|
264
|
+
- Code: `src/channel/mcp-tools.ts` (schedule tools);
|
|
265
|
+
`src/tool-permissions.ts:67`, `:382`.
|
|
266
|
+
- Refs: #895.
|
|
267
|
+
|
|
268
|
+
## task board card
|
|
269
|
+
|
|
270
|
+
A unit of tracked work. Main tasks `M-n` are outcomes; sub tasks `S-n` are
|
|
271
|
+
steps under a main task. States: open, claimed, review, done, blocked,
|
|
272
|
+
cancelled. A main task that waits for someone's confirmation goes to review;
|
|
273
|
+
finishing it from review with done.
|
|
274
|
+
|
|
275
|
+
- Can: carry state, acceptance, comments and results across turns and
|
|
276
|
+
instances.
|
|
277
|
+
- Can't: substitute for chat consensus — a blocked card still needs the person
|
|
278
|
+
(or the dispatcher) to answer.
|
|
279
|
+
- Code: the `task` tool (`src/channel/mcp-tools.ts:79-80`).
|
|
280
|
+
- Refs: —
|
|
281
|
+
|
|
282
|
+
## decision
|
|
283
|
+
|
|
284
|
+
A recorded agreement (`post_decision`, `list_decisions`), scoped to a project
|
|
285
|
+
directory or to the whole fleet. Decisions are the fleet's memory of why,
|
|
286
|
+
readable with `list_decisions`.
|
|
287
|
+
|
|
288
|
+
- Can: record agreements agents and people consult later.
|
|
289
|
+
- Can't: enforce itself — code that never reads a decision is not bound by it
|
|
290
|
+
(see Mismatches).
|
|
291
|
+
- Code: `post_decision`, `list_decisions` tool definitions.
|
|
292
|
+
- Refs: —
|
|
293
|
+
|
|
294
|
+
## credential profile
|
|
295
|
+
|
|
296
|
+
A named credential set for one backend (`CREDENTIAL_HOMES`), so one fleet can
|
|
297
|
+
act under several accounts. `/login <backend> <profile>` signs a profile in;
|
|
298
|
+
chat sign-in from the fleet exists for some backends only.
|
|
299
|
+
|
|
300
|
+
- Can: separate accounts per instance or backend.
|
|
301
|
+
- Can't: share across backends — a profile belongs to its backend's home.
|
|
302
|
+
- Code: `src/backend/credential-profile.ts:5-13`, `:266-295`.
|
|
303
|
+
- Refs: —
|
|
304
|
+
|
|
305
|
+
## native Windows agent / paired PC / runtime
|
|
306
|
+
|
|
307
|
+
Today AgEnD runs on Linux and macOS (on Windows: under WSL, with desktop
|
|
308
|
+
shortcuts from `agend shortcuts`). The rest is alpha only
|
|
309
|
+
(`origin/release/2.3.5-alpha`, adapting the external #2934 — decision
|
|
310
|
+
72353fdf).
|
|
311
|
+
|
|
312
|
+
- A native Windows agent uses this PC's Windows-side CLI: AgEnD in WSL
|
|
313
|
+
discovers native Windows CLIs and runs Windows agents in the same fleet
|
|
314
|
+
registry as Linux agents (`runtimes.windows_cli`, off by default).
|
|
315
|
+
- A paired PC is another Windows computer connected over HTTPS: it runs the
|
|
316
|
+
small `agend-runtime` runner (a ZIP from Settings, never a fleet), connects
|
|
317
|
+
outbound with a one-time pairing code, and joins only after its pairing
|
|
318
|
+
fingerprint is approved in Settings (#2936). Agents pinned to it keep their
|
|
319
|
+
working directories on that PC.
|
|
320
|
+
- General can run on a Windows pane: "Run General on" moves General to an
|
|
321
|
+
approved, online paired PC while the coordinator — and chat and
|
|
322
|
+
administrator authority — stay on the host (#3007).
|
|
323
|
+
- Pairing of people (`agend access pair`) is the separate, older mechanism:
|
|
324
|
+
per-instance access codes, unrelated to paired PCs.
|
|
325
|
+
- Code (alpha branch): `docs/remote-runtime.md`, `docs/windows-cli-preview.md`,
|
|
326
|
+
`docs/windows-general.md`; `src/runtime-bundle.ts`.
|
|
327
|
+
- Refs: 72353fdf, #2936, #3007.
|
|
328
|
+
|
|
329
|
+
## public link (quick vs named)
|
|
330
|
+
|
|
331
|
+
Temporary dashboard access for someone off the host. Quick: an auto-made
|
|
332
|
+
`trycloudflare.com` tunnel URL with a short TTL. Named: the operator's own
|
|
333
|
+
hostname, with a longer TTL. Guests may ride an open public link, but never
|
|
334
|
+
with authority.
|
|
335
|
+
|
|
336
|
+
- Can: show the dashboard (and, if switched on, search, the usage report,
|
|
337
|
+
Office shares) without a chat account.
|
|
338
|
+
- Can't: admin surfaces that require the dashboard reached directly (guests,
|
|
339
|
+
web authority, the dashboard's own web settings).
|
|
340
|
+
- Code: `src/config-validator.ts:424-429`;
|
|
341
|
+
`src/office-share-service.ts:6` (quick-tunnel 429s);
|
|
342
|
+
`src/public-preview.ts:4-5`.
|
|
343
|
+
- Refs: `docs/named-tunnel.md`.
|
|
344
|
+
|
|
345
|
+
## connections from outside (alpha only)
|
|
346
|
+
|
|
347
|
+
`origin/release/2.3.5-alpha`: a web-only fleet may open itself to the
|
|
348
|
+
internet — "Allow connections from outside" — and sign the outside browser in
|
|
349
|
+
with an authenticator-app TOTP code (#3008; fleet decision 0471da59).
|
|
350
|
+
|
|
351
|
+
- Can (alpha): reach the dashboard from outside without a tunnel the operator
|
|
352
|
+
builds; sign in with the authenticator app's code.
|
|
353
|
+
- Can't: use it on main today — alpha only.
|
|
354
|
+
- Code (alpha branch): `src/auth-api.ts` (`/auth/totp`);
|
|
355
|
+
`src/authority/web-authority.ts`.
|
|
356
|
+
- Refs: #3008, fleet decision 0471da59.
|
|
357
|
+
|
|
358
|
+
## web session and the verified web go-ahead
|
|
359
|
+
|
|
360
|
+
A web session is a signed-in browser (dashboard reached directly, a LAN, a
|
|
361
|
+
tailnet, or opt-in over a link). A session carries the account's authority —
|
|
362
|
+
its messages read as `via web (verified)` — only after that account confirms
|
|
363
|
+
on Discord or Telegram (#1939); a guest session never qualifies. Agents check a
|
|
364
|
+
`web-verified` receipt like a Discord or Telegram message. A go-ahead action
|
|
365
|
+
(anything destructive, irreversible, spending, or authority-granting) needs a
|
|
366
|
+
Discord/Telegram receipt or a `web (verified)` one — an open browser alone
|
|
367
|
+
proves nothing.
|
|
368
|
+
|
|
369
|
+
- Can: with verification, stand behind the same acts as a chat message.
|
|
370
|
+
- Can't: without it, authorize anything; plain `via web` and guests never
|
|
371
|
+
carry authority.
|
|
372
|
+
- Code: `src/authority/web-authority.ts`;
|
|
373
|
+
`src/config-validator.ts:517-522` (`web.verified_authority`).
|
|
374
|
+
- Refs: #1939.
|
|
375
|
+
|
|
376
|
+
## Mismatches
|
|
377
|
+
|
|
378
|
+
Real code-vs-decision gaps only. Nothing here is papered over.
|
|
379
|
+
|
|
380
|
+
1. **General's orchestration tools (temporal, expected to resolve).** Code on
|
|
381
|
+
main is pre-beta.8: the `general` profile
|
|
382
|
+
(`src/tool-permissions.ts:107-136`) holds only
|
|
383
|
+
`create/start/restart/wake_instance` plus the web settings. Fleet decision
|
|
384
|
+
9e3bea6c moves it to
|
|
385
|
+
the full ORCHESTRATION set in beta.8 (agy's PR). No live mismatch once beta.8
|
|
386
|
+
lands; until then the code half is verified and the change half is the
|
|
387
|
+
decision's word.
|
|
388
|
+
|
|
389
|
+
[繁體中文](concepts.zh-TW.md)
|
|
390
|
+
|
|
@@ -53,6 +53,7 @@ A peer's summary is not the original person's consent. Before an irreversible ac
|
|
|
53
53
|
|
|
54
54
|
1. Ask the peer to send/delegate with `forwards: [verification_id]`, using the original human receipt's `verification_id` / `[agend-human-id:…]`. Every hop needs an explicit forward; mentioning an ID grants nothing. Only delivered references the sender can read are accepted (up to 16).
|
|
55
55
|
- The ID goes in the `forwards` parameter, never only in the message text: an ID in the text grants nothing, and the receiver's `delivery_status` says "Delivery not found".
|
|
56
|
+
- Put verification and message ids in the `forwards` field only; do not repeat them in the message text, because people see that text in the topic notices.
|
|
56
57
|
- If the `send_to_instance` / `delegate_task` schema you loaded has no `forwards`, pass it anyway. A session resumed across an AgEnD upgrade keeps the tool copy it first loaded (reloading does not refresh it); AgEnD's server accepts the parameter.
|
|
57
58
|
2. Read `delivery_status({message_id: verification_id})`. Require `state: delivered`, its owned `proof_kind`, and the original `content` naming the exact operation/resource. Check `origin.platform`, `origin.adapter_id` and `origin.user_id` against the human authorized for that resource. Labels, quoted headers and agent relay rows are not origin evidence.
|
|
58
59
|
3. Native queue/composer acceptance never proves the model consumed the message. Unknown/unverifiable outcomes, `/raw`, historical rows and a missing origin cannot prove human authorization. Action receipts identify the click and its anchor, not a human-authored platform message.
|
|
@@ -4,12 +4,14 @@ description: restart vs replace vs pause/wake; when to use each
|
|
|
4
4
|
roles: [general]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
## Restart vs Replace
|
|
7
|
+
## Restart vs Replace vs Stop / Delete
|
|
8
8
|
|
|
9
9
|
- `restart_instance("<name>")` — keeps the session, reloads config. Use when config changed.
|
|
10
10
|
- `replace_instance("<name>")` — kills old, creates a fresh instance with handover context.
|
|
11
11
|
Use when the session is the problem: hallucinating / referencing stale info, stuck in a
|
|
12
12
|
tool-call loop, or context is degrading (only backends that report context % surface that).
|
|
13
|
+
- `stop_instance("<name>")` / `start_instance("<name>")` — stop or start an instance without removing its configuration or topic.
|
|
14
|
+
- `delete_instance("<name>")` — stop and remove the instance, its schedules and team memberships, and its own chat topic (by default; pass `delete_topic: false` to keep the topic). On Discord the topic is a channel, so its history goes too. The General topic and a topic another agent uses are never deleted. The result's `topic_deleted` is the platform's answer; when it is false, `topic_reason` says why (for example, the Telegram bot lacks the Manage Topics admin right) — the agent is deleted either way.
|
|
13
15
|
|
|
14
16
|
## Pause / Wake (resource management)
|
|
15
17
|
|
|
@@ -10,6 +10,24 @@ roles: [general]
|
|
|
10
10
|
instances as configured, so AgEnD stopped them and will not retry.
|
|
11
11
|
- Or the user asks about kiro's engine change: Classic/legacy UI being deprecated, kiro-cli 3.0, or V3.
|
|
12
12
|
|
|
13
|
+
## Kiro CLI 3.0: current refusal and migration instructions
|
|
14
|
+
|
|
15
|
+
Kiro CLI 3.0 removed Classic. AgEnD refuses a Classic launch on major 3 or later before launching it or changing
|
|
16
|
+
its saved conversation. Needs you names the Agent and explains how to continue. If a retirement/V2-V3 choice appears
|
|
17
|
+
in an already running pane, AgEnD blocks messages and leaves the choice to the owner; never answer it for them.
|
|
18
|
+
An explicitly pinned TUI/V2 launch remains allowed: it is not a Classic launch.
|
|
19
|
+
|
|
20
|
+
For Classic today, ask the host owner to use a compatible Kiro CLI 2.x. The existing admin-confirmed Classic→TUI
|
|
21
|
+
migration below requires **2.34+ within 2.x**, not 3.x. Do not remove the migration version fence or edit `kiro_ui` to
|
|
22
|
+
bypass it. Keep the original pin, history and receipts; never resume a frozen Classic copy after work continued on V2.
|
|
23
|
+
|
|
24
|
+
The guided **admin-confirmed migration on 2.x followed by a safe upgrade to 3.0 (plan C, #3047)** is coming separately.
|
|
25
|
+
It is not implemented by this refusal/Needs-you change. Do not promise an automatic conversion or an upgrade date.
|
|
26
|
+
|
|
27
|
+
繁體中文:Kiro CLI 3.0 已移除 Classic。請由主機管理者改用相容的 2.x;這個拒絕啟動的保護不會更動已存對話。
|
|
28
|
+
既有管理員確認的 Classic→TUI 遷移只接受 2.34 以上的 **2.x**。先在 2.x 經管理員確認遷移、再安全升級到 3.0
|
|
29
|
+
的引導流程(計畫 C,#3047)會另外提供,並未包含在這次保護裡。不要直接改 `kiro_ui` 或刪除版本檢查來繞過。
|
|
30
|
+
|
|
13
31
|
## What is true
|
|
14
32
|
|
|
15
33
|
- **Each kiro instance's conversation lives in its engine's own store:**
|
|
@@ -56,11 +74,30 @@ The user has already been shown the plain notice in this topic. When they ask, e
|
|
|
56
74
|
- Never run `kiro-cli` yourself, and never delete or edit anything under `~/.kiro` or kiro's data directory.
|
|
57
75
|
- Never reply to the `[system:kiro-incompat]` notice itself. It is information, not a request.
|
|
58
76
|
|
|
77
|
+
## Preparing for Kiro CLI 3.x
|
|
78
|
+
|
|
79
|
+
1. Call `kiro_engine_status` with no name filter. Its `kiro3_readiness` summary counts **all** Kiro Agents and
|
|
80
|
+
Classic rooms, including General; filtering to one Agent still keeps that whole-fleet count. A Classic Agent
|
|
81
|
+
is not ready for Kiro 3.x. This readiness describes the removal of Classic, not a promise that every 3.x
|
|
82
|
+
release supports every session or tool.
|
|
83
|
+
2. Keep a compatible Kiro **2.x** installed. For each Classic fleet Agent, ask the owner to confirm the existing
|
|
84
|
+
`migrate_kiro_instance` move described below. Do not change `kiro_ui` by hand. Wait for the same conversation
|
|
85
|
+
and model to pass both verification starts; failure stops the Agent for inspection. The migration itself is
|
|
86
|
+
unchanged and is not available on 3.x.
|
|
87
|
+
3. A **ClassicBot room** cannot use `migrate_kiro_instance`: its owner must change the room to another backend
|
|
88
|
+
in Classic settings, or continue using Kiro 2.x. Such rooms count as still Classic until their effective Kiro
|
|
89
|
+
configuration no longer selects Classic. Do not present a fleet-Agent migration tool as room recovery.
|
|
90
|
+
4. Check `kiro_engine_status` again: every remaining Kiro Agent must use TUI (or already use V3), and the
|
|
91
|
+
`still_classic` count must be zero before recommending an upgrade. General is subject to the same check.
|
|
92
|
+
5. The owner then upgrades Kiro themselves. AgEnD neither installs the CLI nor answers a V2/V3 menu. If a menu
|
|
93
|
+
or an unverified resume blocks startup, inspect Needs-you; do not clear the pin or start a fresh conversation
|
|
94
|
+
to make the check pass. The version-specific exact-resume evidence is documented separately from readiness.
|
|
95
|
+
|
|
59
96
|
## Moving an instance from classic to the TUI engine (#2598)
|
|
60
97
|
|
|
61
98
|
kiro-cli 3.0 drops the classic engine (`kiro_ui: legacy`), so classic instances are being moved to the TUI engine,
|
|
62
|
-
**one batch at a time and only with the user's OK for that batch**. The move is `migrate_kiro_instance` (
|
|
63
|
-
|
|
99
|
+
**one batch at a time and only with the user's OK for that batch**. The move is `migrate_kiro_instance` (available
|
|
100
|
+
in the `general`, `coordinator` and `full` tool sets). It carries the conversation: the instance's classic conversation is
|
|
64
101
|
resumed once under the TUI and becomes its own. A fleet admin confirms each move in this General topic: a
|
|
65
102
|
"Move it / Cancel" prompt. Explain it if asked; never press it on the user's behalf.
|
|
66
103
|
|
|
@@ -92,8 +129,8 @@ session identity after `/chat` or `/clear`.
|
|
|
92
129
|
this instance's. When it can't be proven, or the check passes its 30 s / 2 GiB limit, the instance resumes the
|
|
93
130
|
conversation on record and the Log tab says why.
|
|
94
131
|
- **Two conversations after an interrupted carry (#2753).** When a stopped TUI instance has its original carried
|
|
95
|
-
conversation and a newer one with work, recovery holds instead of choosing. `reconcile_kiro_instance` (
|
|
96
|
-
coordinator tool sets) asks a fleet admin to confirm, in General, keeping the original and archiving the named
|
|
132
|
+
conversation and a newer one with work, recovery holds instead of choosing. `reconcile_kiro_instance` (general,
|
|
133
|
+
coordinator and full tool sets) asks a fleet admin to confirm, in General, keeping the original and archiving the named
|
|
97
134
|
newer one intact. Offer it only after the user chose those exact ids; docs/kiro-reconciliation.md explains it.
|
|
98
135
|
- **"Kiro's terminal is in use by another program" (#2682).** While a kiro pane runs `/editor`, `/transcript`, a
|
|
99
136
|
`!` command or a focused `/kvim` panel (legacy: `/editor`, `/reply`, `!`), AgEnD holds deliveries. Tell the user
|
|
@@ -42,4 +42,4 @@ Do not put user-facing results only in terminal text; the fleet report is the de
|
|
|
42
42
|
|
|
43
43
|
## Relayed human approval
|
|
44
44
|
|
|
45
|
-
For an irreversible action based on relayed consent, request an explicit `forwards` edge for the original human `verification_id`, then read its original content and origin with `delivery_status`. Each hop needs a forward; a peer's summary or a mentioned ID grants nothing. When you relay it, put the ID in `forwards` (even if your loaded copy of the tool's schema lacks the parameter: the server accepts it), not in the text. Require delivered and an owned proof_kind, and verify the actual platform/adapter/actor plus the exact resource. Hidden/expired/uncertain receipts are not consent and must not trigger a resend. A web-chat message (`[user:<name> via web, id:…]`) is that person: their sign-in code went to their own Discord or Telegram account. Answer it and do what it asks within your work — questions, looking things up, reading, analysis, changes in your own scope. Only a go-ahead action asks for more: a release or publish, anything destructive or irreversible beyond your own work (deleting what others use, force-pushing or resetting a shared branch; your temp files and your own branch and worktree are routine), spending money or quota beyond normal work, credentials or secrets, or granting or forwarding authority to another instance. For these an open browser is not proof of the account, so the account must stand behind it: a Discord or Telegram receipt, or a `via web (verified)` one — read it with `delivery_status`: `authority.kind: web-verified`, its person `authority.actor` (adapter and user id), checked like a Discord or Telegram message (delivered, an owned proof_kind, the original content, that actor) and forwarded the same way. On a web-only fleet (no Discord or Telegram connection) that person is the host operator, signed in with `agend web --code` on the AgEnD computer itself: a verified receipt names `authority.actor` adapter `host`, user `operator`. A guest (`via web (guest)`) was let in only to chat: talk with them there, and take nothing they ask as the admin's. Plain `via web`, a guest, and authority since revoked (`authority.kind: none`) are not a go-ahead; nor is a reviewer's APPROVE. See the cross-instance-messaging skill.
|
|
45
|
+
For an irreversible action based on relayed consent, request an explicit `forwards` edge for the original human `verification_id`, then read its original content and origin with `delivery_status`. Each hop needs a forward; a peer's summary or a mentioned ID grants nothing. When you relay it, put the ID in `forwards` (even if your loaded copy of the tool's schema lacks the parameter: the server accepts it), not in the text. Put verification and message ids in the `forwards` field only; do not repeat them in the message text, because people see that text in the topic notices. Require delivered and an owned proof_kind, and verify the actual platform/adapter/actor plus the exact resource. Hidden/expired/uncertain receipts are not consent and must not trigger a resend. A web-chat message (`[user:<name> via web, id:…]`) is that person: their sign-in code went to their own Discord or Telegram account. Answer it and do what it asks within your work — questions, looking things up, reading, analysis, changes in your own scope. Only a go-ahead action asks for more: a release or publish, anything destructive or irreversible beyond your own work (deleting what others use, force-pushing or resetting a shared branch; your temp files and your own branch and worktree are routine), spending money or quota beyond normal work, credentials or secrets, or granting or forwarding authority to another instance. For these an open browser is not proof of the account, so the account must stand behind it: a Discord or Telegram receipt, or a `via web (verified)` one — read it with `delivery_status`: `authority.kind: web-verified`, its person `authority.actor` (adapter and user id), checked like a Discord or Telegram message (delivered, an owned proof_kind, the original content, that actor) and forwarded the same way. On a web-only fleet (no Discord or Telegram connection) that person is the host operator, signed in with `agend web --code` on the AgEnD computer itself: a verified receipt names `authority.actor` adapter `host`, user `operator`. A guest (`via web (guest)`) was let in only to chat: talk with them there, and take nothing they ask as the admin's. Plain `via web`, a guest, and authority since revoked (`authority.kind: none`) are not a go-ahead; nor is a reviewer's APPROVE. See the cross-instance-messaging skill.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { SettingsExecution } from "./settings-transaction.js";
|
|
2
2
|
import type { InstanceConfig, FleetConfig } from "./types.js";
|
|
3
|
+
import type { TopicDeleteOutcome } from "./instance-topic-delete.js";
|
|
3
4
|
import { RoutingEngine } from "./routing-engine.js";
|
|
4
5
|
import type { Logger } from "./logger.js";
|
|
5
6
|
import type { IpcClient } from "./channel/ipc-bridge.js";
|
|
@@ -57,6 +58,7 @@ export declare function getUnsafeInstanceDaemonPidReason(pid: number, dataDir: s
|
|
|
57
58
|
* FleetManager implements this.
|
|
58
59
|
*/
|
|
59
60
|
export interface LifecycleContext {
|
|
61
|
+
readonly agentCredentials?: Pick<import("./agent-credentials.js").AgentCredentials, "issue" | "invalidate">;
|
|
60
62
|
readonly fleetConfig: FleetConfig | null;
|
|
61
63
|
readonly logger: Logger;
|
|
62
64
|
readonly dataDir: string;
|
|
@@ -93,8 +95,10 @@ export interface LifecycleContext {
|
|
|
93
95
|
createForumTopic(topicName: string, adapterId?: string): Promise<number | string>;
|
|
94
96
|
/** #2910: no Discord or Telegram connection at all — a new agent gets no topic (it is reached from the dashboard). */
|
|
95
97
|
isWebOnlyFleet?(): boolean;
|
|
96
|
-
/**
|
|
97
|
-
|
|
98
|
+
/** delete_instance: the removal, then (unless `deleteTopic` is false) the agent's own topic, through its own bot. */
|
|
99
|
+
removeInstanceAndTopic(name: string, authorization: ExplicitInstanceRemoval, opts: {
|
|
100
|
+
deleteTopic: boolean;
|
|
101
|
+
}): Promise<TopicDeleteOutcome>;
|
|
98
102
|
/**
|
|
99
103
|
* A bound delete for the world `adapterId` selects, captured by the caller
|
|
100
104
|
* BEFORE awaiting createForumTopic. Rollback must use exactly this — never
|
|
@@ -135,6 +139,8 @@ export interface LifecycleContext {
|
|
|
135
139
|
/** Notify a clean CLI exit and offer an admin-only restart action in General. */
|
|
136
140
|
notifyNormalExit(name: string): Promise<void>;
|
|
137
141
|
notifySessionOomStop?(name: string, unclear?: boolean): Promise<void>;
|
|
142
|
+
/** A pre-launch refusal is still a visible wait when no daemon was published. */
|
|
143
|
+
setKiroCompatibilityHold?(name: string, message: string | null): void;
|
|
138
144
|
/** Tell every General, as an agent, that kiro-cli can no longer run this instance as configured. */
|
|
139
145
|
queueKiroIncompatNotice?(name: string, reason: string): void;
|
|
140
146
|
/** True for a dynamic ClassicBot channel instance (not a fleet topic). */
|
|
@@ -681,6 +681,24 @@ export class InstanceLifecycle {
|
|
|
681
681
|
}
|
|
682
682
|
this.ctx.notifyInstanceTopic(name, t("delivery.cancelled_unsent", messages.length, name));
|
|
683
683
|
}, this.ctx.logger, `daemon.human_messages_cancelled[${name}]`));
|
|
684
|
+
// #3030: messages handed to the busy CLI's own queue that it never took (it went idle without them), or that a
|
|
685
|
+
// restart left unverifiable (its transcript could not be read, so they were not sent again). Each is marked ❌ and
|
|
686
|
+
// the person is told once — never a silent ✅.
|
|
687
|
+
daemon.on("human_handoffs_unsettled", safeHandler((data) => {
|
|
688
|
+
const messages = Array.isArray(data?.messages) ? data.messages : [];
|
|
689
|
+
if (!messages.length)
|
|
690
|
+
return;
|
|
691
|
+
const reason = data.reason === "unverifiable" ? "unverifiable" : "not-taken";
|
|
692
|
+
this.ctx.eventLog?.insert(name, "handoffs_unsettled", { reason, count: messages.length });
|
|
693
|
+
this.ctx.logger.warn({ name, reason, count: messages.length }, "Queued messages not taken by the CLI — telling the person");
|
|
694
|
+
for (const m of messages) {
|
|
695
|
+
if (this.ctx.finishDeliveryStatus)
|
|
696
|
+
this.ctx.finishDeliveryStatus(name, m.chatId, m.messageId, "failed", m.threadId);
|
|
697
|
+
else
|
|
698
|
+
this.ctx.reactMessageStatus(name, m.chatId, m.messageId, "failed", m.threadId);
|
|
699
|
+
}
|
|
700
|
+
this.ctx.notifyInstanceTopic(name, t(reason === "unverifiable" ? "delivery.handoff_unverified_after_restart" : "delivery.handoff_not_taken", messages.length, name));
|
|
701
|
+
}, this.ctx.logger, `daemon.human_handoffs_unsettled[${name}]`));
|
|
684
702
|
}
|
|
685
703
|
attachIncidentHandlers(name, daemon) {
|
|
686
704
|
daemon.on("capacity_nudge_cancelled", safeHandler((data) => {
|
|
@@ -1367,6 +1385,7 @@ export class InstanceLifecycle {
|
|
|
1367
1385
|
}
|
|
1368
1386
|
/** Invalidate every start/wake already running for `name` (they will not publish). */
|
|
1369
1387
|
invalidate(name) {
|
|
1388
|
+
this.ctx.agentCredentials?.invalidate(name);
|
|
1370
1389
|
this.lifecycleEpochs.set(name, this.epochOf(name) + 1);
|
|
1371
1390
|
}
|
|
1372
1391
|
/** Whether `transition` is `name`'s transition and is the one running now. */
|
|
@@ -1487,6 +1506,18 @@ export class InstanceLifecycle {
|
|
|
1487
1506
|
backend: backendName,
|
|
1488
1507
|
model: config.model ?? "default",
|
|
1489
1508
|
}, this.ctx.spawnGate, this.ctx.stormWindow, this.ctx.backendOutage);
|
|
1509
|
+
// Register before start: a pre-launch refusal has no published daemon or later incident handlers.
|
|
1510
|
+
daemon.on("kiro_compatibility_hold", (message) => {
|
|
1511
|
+
const owner = this.daemons.get(name);
|
|
1512
|
+
if (owner ? owner !== daemon : this.epochOf(name) !== epoch)
|
|
1513
|
+
return;
|
|
1514
|
+
this.ctx.setKiroCompatibilityHold?.(name, message);
|
|
1515
|
+
});
|
|
1516
|
+
daemon.setAgentCredentialIssuer?.(token => {
|
|
1517
|
+
if (this.epochOf(name) !== epoch)
|
|
1518
|
+
throw new SupersededStartError(name);
|
|
1519
|
+
this.ctx.agentCredentials?.issue(name, token);
|
|
1520
|
+
});
|
|
1490
1521
|
daemon.setDeliveryOutboxPort(this.ctx.deliveryOutbox ?? undefined);
|
|
1491
1522
|
daemon.setWorkLeaseCheck(() => this.hasWorkLease(name));
|
|
1492
1523
|
if (seedNow)
|
|
@@ -1580,6 +1611,7 @@ export class InstanceLifecycle {
|
|
|
1580
1611
|
this.ctx.setTopicIcon(name, "green");
|
|
1581
1612
|
this.ctx.touchActivity(name);
|
|
1582
1613
|
});
|
|
1614
|
+
this.ctx.setKiroCompatibilityHold?.(name, null);
|
|
1583
1615
|
this.attachIncidentHandlers(name, daemon);
|
|
1584
1616
|
// #2897: a new daemon starts with no dialog held; a notice the last one left (a crash, a respawn) is out of date.
|
|
1585
1617
|
this.ctx.resolveParkedNotice?.(name);
|
|
@@ -2341,7 +2373,8 @@ export class InstanceLifecycle {
|
|
|
2341
2373
|
/** Handle delete_instance tool call from a daemon. */
|
|
2342
2374
|
async handleDelete(args, respond) {
|
|
2343
2375
|
const instanceName = args.name;
|
|
2344
|
-
|
|
2376
|
+
// The user's decision (beta.9): deleting an agent deletes its topic, unless `delete_topic: false` keeps it.
|
|
2377
|
+
const deleteTopic = args.delete_topic ?? true;
|
|
2345
2378
|
const instanceConfig = this.ctx.fleetConfig?.instances[instanceName];
|
|
2346
2379
|
if (!instanceConfig) {
|
|
2347
2380
|
respond(null, `Instance not found: ${instanceName}`);
|
|
@@ -2351,11 +2384,9 @@ export class InstanceLifecycle {
|
|
|
2351
2384
|
respond(null, "Cannot delete the General instance");
|
|
2352
2385
|
return;
|
|
2353
2386
|
}
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
}
|
|
2357
|
-
await this.ctx.removeInstance(instanceName, authorizeExplicitInstanceRemoval("delete-instance-tool"));
|
|
2358
|
-
respond({ success: true, name: instanceName, topic_deleted: deleteTopic });
|
|
2387
|
+
// topic_deleted is the platform's answer, never the request; when the topic stays, topic_reason says why.
|
|
2388
|
+
const topic = await this.ctx.removeInstanceAndTopic(instanceName, authorizeExplicitInstanceRemoval("delete-instance-tool"), { deleteTopic });
|
|
2389
|
+
respond({ success: true, name: instanceName, topic_deleted: topic.deleted, ...(topic.deleted ? {} : { topic_reason: topic.reason }) });
|
|
2359
2390
|
}
|
|
2360
2391
|
has(name) {
|
|
2361
2392
|
return this.daemons.has(name);
|