hive-am 1.10.1 → 1.11.0
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/CHANGELOG.md +14 -1
- package/package.json +1 -1
- package/server/dist/db.js +13 -4
- package/server/dist/dispatches.js +50 -2
- package/server/dist/http/routes/orchestration.js +16 -1
- package/server/dist/instructions.js +1 -1
- package/server/dist/runtime.js +25 -1
- package/server/mcp/dispatch.mjs +42 -2
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/app-build-manifest.json +79 -79
- package/web/.next/app-path-routes-manifest.json +7 -7
- package/web/.next/build-manifest.json +2 -2
- package/web/.next/prerender-manifest.json +35 -35
- package/web/.next/required-server-files.json +1 -1
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/_not-found.html +1 -1
- package/web/.next/server/app/_not-found.rsc +3 -3
- package/web/.next/server/app/agents/[id]/page.js +2 -2
- package/web/.next/server/app/agents/[id]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/agents/page.js +2 -2
- package/web/.next/server/app/agents/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/agents.html +1 -1
- package/web/.next/server/app/agents.rsc +5 -5
- package/web/.next/server/app/chat/page.js +1 -1
- package/web/.next/server/app/chat/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/chat.html +1 -1
- package/web/.next/server/app/chat.rsc +4 -4
- package/web/.next/server/app/colony/page.js +2 -2
- package/web/.next/server/app/colony/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/colony.html +1 -1
- package/web/.next/server/app/colony.rsc +4 -4
- package/web/.next/server/app/connections/page.js +1 -1
- package/web/.next/server/app/connections/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/connections.html +1 -1
- package/web/.next/server/app/connections.rsc +4 -4
- package/web/.next/server/app/index.html +1 -1
- package/web/.next/server/app/index.rsc +4 -4
- package/web/.next/server/app/page.js +2 -2
- package/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/relations/page.js +1 -1
- package/web/.next/server/app/relations/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/relations.html +1 -1
- package/web/.next/server/app/relations.rsc +4 -4
- package/web/.next/server/app/resources/[id]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/resources/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/resources.html +1 -1
- package/web/.next/server/app/resources.rsc +4 -4
- package/web/.next/server/app/schedules/page.js +1 -1
- package/web/.next/server/app/schedules/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/schedules.html +1 -1
- package/web/.next/server/app/schedules.rsc +4 -4
- package/web/.next/server/app/sessions/page.js +1 -1
- package/web/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/sessions.html +1 -1
- package/web/.next/server/app/sessions.rsc +4 -4
- package/web/.next/server/app/skills/page.js +1 -1
- package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/skills.html +1 -1
- package/web/.next/server/app/skills.rsc +4 -4
- package/web/.next/server/app/types/page.js +1 -1
- package/web/.next/server/app/types/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/types.html +1 -1
- package/web/.next/server/app/types.rsc +4 -4
- package/web/.next/server/app-paths-manifest.json +7 -7
- package/web/.next/server/chunks/143.js +1 -1
- package/web/.next/server/chunks/345.js +1 -1
- package/web/.next/server/chunks/368.js +1 -1
- package/web/.next/server/chunks/403.js +1 -1
- package/web/.next/server/chunks/505.js +3 -3
- package/web/.next/server/chunks/944.js +1 -1
- package/web/.next/server/chunks/953.js +1 -1
- package/web/.next/server/pages/404.html +1 -1
- package/web/.next/server/pages/500.html +1 -1
- package/web/.next/server/server-reference-manifest.json +1 -1
- package/web/.next/static/chunks/{1517-e96b538fa33001f5.js → 1517-9b82b61ee9921bb1.js} +1 -1
- package/web/.next/static/chunks/{1606-2aa8ee5a6751f920.js → 1606-6d25d725156f5127.js} +1 -1
- package/web/.next/static/chunks/{2547-821b5a01cff1915f.js → 2547-8b6bdae3c622a158.js} +1 -1
- package/web/.next/static/chunks/4491-886c18aee1e9c737.js +1 -0
- package/web/.next/static/chunks/4740-0581e5cb9334010b.js +1 -0
- package/web/.next/static/chunks/{5587-7e580517c4105e63.js → 5587-cdccc5cf4056b739.js} +1 -1
- package/web/.next/static/chunks/app/agents/[id]/page-eeb93069b69e7f7e.js +1 -0
- package/web/.next/static/chunks/app/agents/layout-db700c86124f32de.js +1 -0
- package/web/.next/static/chunks/app/agents/{page-0d8769f28c624f9c.js → page-bf40d654c5fe5c23.js} +1 -1
- package/web/.next/static/chunks/app/chat/{page-b1569cf72e958d8b.js → page-157685bdaad86c26.js} +1 -1
- package/web/.next/static/chunks/app/colony/{page-ffdc123dac47ad69.js → page-600b663a716d08c4.js} +1 -1
- package/web/.next/static/chunks/app/connections/{page-0e4f9f272da95c83.js → page-cbfcb1547d45c833.js} +1 -1
- package/web/.next/static/chunks/app/{layout-611dd72158f6f098.js → layout-b327408bcfb13a70.js} +1 -1
- package/web/.next/static/chunks/app/page-78c38105a034b0b3.js +1 -0
- package/web/.next/static/chunks/app/relations/{page-a9d991b174372f37.js → page-622a4c5723c7c5cc.js} +1 -1
- package/web/.next/static/chunks/app/resources/[id]/{page-48131f750e983a07.js → page-b9af9eecf693b695.js} +1 -1
- package/web/.next/static/chunks/app/resources/{page-706d012a4c0d57ce.js → page-a2e17f0dc205a2a4.js} +1 -1
- package/web/.next/static/chunks/app/schedules/{page-5821c0d26afde69f.js → page-d534462088c64b59.js} +1 -1
- package/web/.next/static/chunks/app/sessions/{page-6145eb19002dd390.js → page-6fef5b73bfbf262e.js} +1 -1
- package/web/.next/static/chunks/app/skills/{page-c080683abd0496ab.js → page-ab25a3a6d348a049.js} +1 -1
- package/web/.next/static/chunks/app/types/{page-a991fe9afa51bdb7.js → page-7e08ca1bcbee605f.js} +1 -1
- package/web/.next/static/css/f9099a8765eed6f0.css +1 -0
- package/web/.next/trace +31 -31
- package/web/.next/static/chunks/4491-49c700f509985c9e.js +0 -1
- package/web/.next/static/chunks/9977-78b955d85f795a21.js +0 -1
- package/web/.next/static/chunks/app/agents/[id]/page-da4050632f63874d.js +0 -1
- package/web/.next/static/chunks/app/agents/layout-2536c0c15d09ddcf.js +0 -1
- package/web/.next/static/chunks/app/page-68ae166b2f8dbf94.js +0 -1
- package/web/.next/static/css/10b50a352e0391ea.css +0 -1
- /package/web/.next/static/{4u5XzGwgVbDEHRyGvCzGf → HzL5-xIKbr0VsaWuLWHNl}/_buildManifest.js +0 -0
- /package/web/.next/static/{4u5XzGwgVbDEHRyGvCzGf → HzL5-xIKbr0VsaWuLWHNl}/_ssgManifest.js +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,18 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [1.11.0] - 2026-10-23
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- **Cancel a delegated task.** A task sent by mistake or no longer needed can be taken back, queued or running. In **Recent delegations** (Colony and Home) each unfinished task has a **×** button: a queued one is cancelled at once and never starts, a running one asks first and is stopped. The orchestrator is told once, in the place where it delegated. Orchestrators get two new tools, `dispatch_cancel` (only for their own tasks; they get no extra message for a task they cancel) and `dispatch_list` (their tasks that have not finished). A cancelled task shows as **cancelled** with a grey dot, frees its place in the limit of 10, and what the worker already changed stays in the folder. Unfinished tasks now come first in the list and are never hidden by its limit. Stop on a worker still stops only its current turn and marks that delegation failed.
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- **Lists follow the language at once.** Changing the language with the app open left some names in the old language until a reload: the **No colony** group in the chat's agent list and in **Resources**, and the colony hints in the agent form and the resource manager field. They now change right away.
|
|
18
|
+
- **Collapsing the agent list clears its search.** A search typed in the chat's agent list kept filtering the collapsed list, which has no search box, so agents and groups seemed to vanish and the group headings stayed disabled. Collapsing now clears the search, and expanding shows the full list with an empty box.
|
|
19
|
+
- **More of the interface follows the language.** The **Entrypoint**, **Gateway** and **Aliases** labels of a service's details, and the names screen readers hear for the method picker of a new HTTP request and for the sideways scroll bar of the diff view, were always in English; a request that failed in an HTTP file showed `error` in English too. They now come from the dictionaries. Empty cells and values show a plain hyphen instead of a long dash, and a service's empty lists (health log, variables, ports, mounts, networks) say **none**.
|
|
20
|
+
|
|
9
21
|
## [1.10.1] - 2026-10-23
|
|
10
22
|
|
|
11
23
|
### Fixed
|
|
@@ -290,7 +302,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
|
|
|
290
302
|
- Complete documentation in English and Spanish.
|
|
291
303
|
- npm package with the `hive-am` command.
|
|
292
304
|
|
|
293
|
-
[Unreleased]: https://github.com/hughcbscrt/hive-am/compare/v1.
|
|
305
|
+
[Unreleased]: https://github.com/hughcbscrt/hive-am/compare/v1.11.0...HEAD
|
|
306
|
+
[1.11.0]: https://github.com/hughcbscrt/hive-am/compare/v1.10.1...v1.11.0
|
|
294
307
|
[1.10.1]: https://github.com/hughcbscrt/hive-am/compare/v1.10.0...v1.10.1
|
|
295
308
|
[1.10.0]: https://github.com/hughcbscrt/hive-am/compare/v1.9.1...v1.10.0
|
|
296
309
|
[1.9.1]: https://github.com/hughcbscrt/hive-am/compare/v1.9.0...v1.9.1
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hive-am",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.11.0",
|
|
4
4
|
"description": "A colony of coding agents: orchestrators and subagents over Claude Code, OpenCode, Kiro and Cursor, with real session resume, a browser UI and Telegram.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai-agents",
|
package/server/dist/db.js
CHANGED
|
@@ -245,8 +245,9 @@ export const agents = {
|
|
|
245
245
|
allSessions: () => q(`SELECT s.*, a.name agent_name, a.role agent_role, f.name from_name FROM agent_sessions s JOIN agents a ON a.id=s.agent_id LEFT JOIN agents f ON f.id=s.from_id ORDER BY s.last_seen DESC`).all(),
|
|
246
246
|
};
|
|
247
247
|
// ---- dispatch log ----
|
|
248
|
-
// A delegation is `queued` until the worker's turn starts (it waits behind the worker's other turns), then `running`, then `done`, `failed
|
|
249
|
-
//
|
|
248
|
+
// A delegation is `queued` until the worker's turn starts (it waits behind the worker's other turns), then `running`, then `done`, `failed`,
|
|
249
|
+
// `interrupted` (the server stopped while it was queued or running) or `cancelled` (its orchestrator or the person took it back). Only a
|
|
250
|
+
// row still queued or running is closed, so the first of the end of the turn and a cancel sets the one final state.
|
|
250
251
|
export const dispatches = {
|
|
251
252
|
start(from, to, task, mode = 'sync', origin = null) {
|
|
252
253
|
const id = uid();
|
|
@@ -256,16 +257,24 @@ export const dispatches = {
|
|
|
256
257
|
get: (id) => q('SELECT * FROM dispatches WHERE id=?').get(id),
|
|
257
258
|
setRunning: (id) => q("UPDATE dispatches SET status='running' WHERE id=? AND status='queued'").run(id),
|
|
258
259
|
setSession: (id, sessionId) => q('UPDATE dispatches SET session_id=? WHERE id=?').run(sessionId, id),
|
|
259
|
-
finish: (id, status, result) => q(
|
|
260
|
+
finish: (id, status, result) => q("UPDATE dispatches SET status=?, result=?, finished_at=? WHERE id=? AND status IN ('queued','running')").run(status, result.slice(0, 20000), now(), id).changes > 0,
|
|
261
|
+
/** Cancels a task that has not finished; false if it already had. Cancelled by its orchestrator, it is never announced (the tool told it). */
|
|
262
|
+
cancel: (id, result, byOrchestrator) => {
|
|
263
|
+
const at = now();
|
|
264
|
+
return q("UPDATE dispatches SET status='cancelled', result=?, finished_at=?, notified_at=CASE WHEN ? THEN ? ELSE notified_at END WHERE id=? AND status IN ('queued','running')").run(result, at, byOrchestrator ? 1 : 0, at, id).changes > 0;
|
|
265
|
+
},
|
|
260
266
|
markNotified: (id) => q('UPDATE dispatches SET notified_at=? WHERE id=? AND notified_at IS NULL').run(now(), id),
|
|
261
267
|
markRead: (id) => q('UPDATE dispatches SET read_at=? WHERE id=? AND read_at IS NULL').run(now(), id),
|
|
262
268
|
/** Background tasks of an orchestrator that have not finished yet. */
|
|
263
269
|
unfinished: (from) => q("SELECT COUNT(*) AS n FROM dispatches WHERE from_id=? AND mode='background' AND status IN ('queued','running')").get(from).n,
|
|
270
|
+
/** Every task of an orchestrator that has not finished, oldest first. */
|
|
271
|
+
open: (from) => q("SELECT * FROM dispatches WHERE from_id=? AND status IN ('queued','running') ORDER BY created_at, id").all(from),
|
|
264
272
|
/** Finished background tasks whose result was not handed to the orchestrator yet. */
|
|
265
273
|
undelivered: () => q("SELECT * FROM dispatches WHERE mode='background' AND status NOT IN ('queued','running') AND notified_at IS NULL ORDER BY created_at").all(),
|
|
266
274
|
/** At startup nothing is running any more: what was queued or running is interrupted (a task is never resumed). */
|
|
267
275
|
interruptLeftovers: () => q("UPDATE dispatches SET status='interrupted', finished_at=? WHERE status IN ('queued','running')").run(now()).changes,
|
|
268
|
-
|
|
276
|
+
/** The newest rows, plus any older one that has not finished (so the interface can always show and cancel it). */
|
|
277
|
+
recent: (limit = 50) => q("SELECT * FROM (SELECT * FROM dispatches ORDER BY created_at DESC LIMIT ?) UNION SELECT * FROM dispatches WHERE status IN ('queued','running') ORDER BY created_at DESC").all(limit),
|
|
269
278
|
};
|
|
270
279
|
// Agents left 'running' by a crash/blackout are simply idle again: their session is intact on disk.
|
|
271
280
|
q("UPDATE agents SET status='idle' WHERE status='running'").run();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { agents, dispatches } from './db.js';
|
|
2
2
|
import { threads } from './connections/store.js';
|
|
3
|
-
import { liveOrigin, notifyAgentsChanged, startDispatch } from './runtime.js';
|
|
3
|
+
import { abortDispatch, cancelQueued, liveOrigin, notifyAgentsChanged, startDispatch } from './runtime.js';
|
|
4
4
|
import { deliverTo } from './wake.js';
|
|
5
5
|
import { DomainError } from './errors.js';
|
|
6
6
|
/**
|
|
@@ -15,7 +15,7 @@ export const MAX_BACKGROUND = 10; // unfinished background tasks per orchestrato
|
|
|
15
15
|
export const MAX_WAIT_S = 60; // the longest one `dispatch_status` call waits
|
|
16
16
|
const POLL_MS = 250;
|
|
17
17
|
const RETRY_MS = Number(process.env.HIVE_AM_WAKE_RETRY_MS) || 5000; // wait before trying a delivery again (as wake-ups do)
|
|
18
|
-
const FINISHED = new Set(['done', 'failed', 'interrupted']);
|
|
18
|
+
const FINISHED = new Set(['done', 'failed', 'interrupted', 'cancelled']);
|
|
19
19
|
const NO_TEXT = '(the subagent finished without a text answer)';
|
|
20
20
|
const nameOf = (id) => agents.get(id)?.name ?? 'a removed agent';
|
|
21
21
|
/** Starts a delegation without waiting for it. In the background, its end is announced to the orchestrator; a synchronous one is polled. */
|
|
@@ -74,6 +74,40 @@ export async function taskStatus(fromId, id, waitSeconds) {
|
|
|
74
74
|
out.note = `wait_seconds is capped at ${MAX_WAIT_S}: waited ${MAX_WAIT_S} s at most.`;
|
|
75
75
|
return out;
|
|
76
76
|
}
|
|
77
|
+
const CANCELLED_BY = { orchestrator: 'Cancelled by the orchestrator before it finished.', person: 'Cancelled by the person before it finished.' };
|
|
78
|
+
/**
|
|
79
|
+
* Takes a delegated task back. A queued one leaves the worker's queue and never starts; a running one has its turn aborted (only that turn).
|
|
80
|
+
* One already finished is left as it is and its state is answered, so cancelling twice is harmless. The row is closed by the same conditional
|
|
81
|
+
* update as the end of the turn, so whichever comes first sets the one final state. `by` is the orchestrator that started it, or null for the
|
|
82
|
+
* person (from the web), who may cancel any task; cancelled by the person, the orchestrator is told once.
|
|
83
|
+
*/
|
|
84
|
+
export function cancelTask(by, id) {
|
|
85
|
+
if (!id)
|
|
86
|
+
throw new DispatchError('id is required');
|
|
87
|
+
const row = dispatches.get(id);
|
|
88
|
+
if (!row)
|
|
89
|
+
throw new DispatchError(`There is no delegated task with id "${id}".`, 'not_found');
|
|
90
|
+
if (by !== null && row.from_id !== by)
|
|
91
|
+
throw new DispatchError(`Task "${id}" was not started by you.`, 'forbidden');
|
|
92
|
+
const was = row.status;
|
|
93
|
+
const cancelled = !FINISHED.has(was) && dispatches.cancel(id, by === null ? CANCELLED_BY.person : CANCELLED_BY.orchestrator, by !== null);
|
|
94
|
+
if (cancelled) {
|
|
95
|
+
if (was === 'queued')
|
|
96
|
+
cancelQueued(row.to_id, id);
|
|
97
|
+
else
|
|
98
|
+
abortDispatch(row.to_id, id);
|
|
99
|
+
notifyAgentsChanged();
|
|
100
|
+
// At once, not when the turn ends: a queued task only settles when the worker's queue reaches it.
|
|
101
|
+
if (by === null)
|
|
102
|
+
void announce(id);
|
|
103
|
+
}
|
|
104
|
+
const now = dispatches.get(id) ?? row;
|
|
105
|
+
return { id, agent: nameOf(now.to_id), status: now.status, mode: now.mode, was, cancelled, ...(FINISHED.has(now.status) ? { result: resultText(now) } : {}) };
|
|
106
|
+
}
|
|
107
|
+
/** The tasks of an orchestrator that have not finished, oldest first, so it can tell which one to cancel. */
|
|
108
|
+
export function openTasks(fromId) {
|
|
109
|
+
return dispatches.open(fromId).map((r) => ({ id: r.id, agent: nameOf(r.to_id), status: r.status, mode: r.mode, task: r.task.length > 200 ? `${r.task.slice(0, 200)}…` : r.task, age_s: Math.max(0, Math.round((Date.now() - r.created_at) / 1000)) }));
|
|
110
|
+
}
|
|
77
111
|
/** What a finished task says: its answer, its error, or why it stopped. */
|
|
78
112
|
function resultText(row) {
|
|
79
113
|
if (row.status === 'interrupted')
|
|
@@ -85,12 +119,26 @@ function resultText(row) {
|
|
|
85
119
|
const noticeText = (row) => `Delegated task ${row.id} to ${nameOf(row.to_id)} finished (${row.status}). Result:\n${resultText(row)}`;
|
|
86
120
|
const NEXT = 'Carry on with the work this task was part of and tell the person what came of it';
|
|
87
121
|
const timers = new Map();
|
|
122
|
+
const delivering = new Set();
|
|
88
123
|
/** Hands the result of a finished background task to the orchestrator, once. Tried again while the platform is not connected yet. */
|
|
89
124
|
async function announce(id, tries = 0) {
|
|
125
|
+
// A second call while the first is still delivering (a cancel, then the end of the aborted turn) or waiting to try again does nothing.
|
|
126
|
+
if (delivering.has(id) || (!tries && timers.has(id)))
|
|
127
|
+
return;
|
|
90
128
|
timers.delete(id);
|
|
91
129
|
const row = dispatches.get(id);
|
|
92
130
|
if (!row || row.mode !== 'background' || row.notified_at || !FINISHED.has(row.status))
|
|
93
131
|
return;
|
|
132
|
+
delivering.add(id);
|
|
133
|
+
try {
|
|
134
|
+
await deliver(row, tries);
|
|
135
|
+
}
|
|
136
|
+
finally {
|
|
137
|
+
delivering.delete(id);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
async function deliver(row, tries) {
|
|
141
|
+
const id = row.id;
|
|
94
142
|
const o = row.origin ? JSON.parse(row.origin) : null;
|
|
95
143
|
const to = { agent_id: row.from_id, connection_id: o?.connection_id ?? null, thread_id: o?.thread_id ?? null, req_id: o?.req_id ?? null, req_name: o?.req_name ?? null };
|
|
96
144
|
const again = () => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { agents, dispatches } from '../../db.js';
|
|
2
|
-
import { startTask, taskStatus } from '../../dispatches.js';
|
|
2
|
+
import { cancelTask, openTasks, startTask, taskStatus } from '../../dispatches.js';
|
|
3
3
|
import { dispatch, liveTurn, notifyAgentsChanged } from '../../runtime.js';
|
|
4
4
|
import { agentOrFail } from '../../services/agents.js';
|
|
5
5
|
import { body } from '../body.js';
|
|
@@ -40,4 +40,19 @@ route('POST', '/api/dispatch/status', async ({ req }) => {
|
|
|
40
40
|
throw bad('from is required');
|
|
41
41
|
return taskStatus(text(from), text(id), wait_seconds);
|
|
42
42
|
});
|
|
43
|
+
// Cancelling answers the final state: `cancelled`, or the one the task already had (it is not an error).
|
|
44
|
+
route('POST', '/api/dispatch/cancel', async ({ req }) => {
|
|
45
|
+
const { from, id } = await body(req);
|
|
46
|
+
if (!from)
|
|
47
|
+
throw bad('from is required');
|
|
48
|
+
return cancelTask(text(from), text(id));
|
|
49
|
+
});
|
|
50
|
+
route('POST', '/api/dispatch/list', async ({ req }) => {
|
|
51
|
+
const { from } = await body(req);
|
|
52
|
+
if (!from)
|
|
53
|
+
throw bad('from is required');
|
|
54
|
+
return openTasks(text(from));
|
|
55
|
+
});
|
|
43
56
|
route('GET', '/api/dispatches', () => dispatches.recent());
|
|
57
|
+
// From the web: the person can cancel any task, as they can stop any agent.
|
|
58
|
+
route('POST', '/api/dispatches/:id/cancel', ({ params }) => cancelTask(null, params[0]));
|
|
@@ -78,7 +78,7 @@ ${lazy.map((s) => `- **${s.name}**${s.description ? `: ${s.description}` : ''}`)
|
|
|
78
78
|
const team = a.worker_ids.map((wid) => agents.get(wid)).filter(Boolean);
|
|
79
79
|
if (team.length) {
|
|
80
80
|
const roster = team.map((w) => `- **${w.name}**${w.description ? `: ${w.description}` : ''}`).join('\n');
|
|
81
|
-
parts.push(`## Your team\nThese are your subagents — the ONLY agents you can delegate to:\n${roster}\n\nDelegate with the \`dispatch\` tool (${tn('dispatch')}) instead of doing their work yourself, then synthesize their answers. Always use it: never play a subagent's role yourself, and never use a generic built-in subagent in its place — a subagent is a separate real agent with its own session. Each delegation starts a fresh conversation for that subagent, so put all the context it needs in the task. \`dispatch\` returns at once with a task id, so you can answer the person or delegate more meanwhile, and the result reaches you as a message when the subagent finishes (you can also ask with the \`dispatch_status\` tool (${tn('dispatch_status')})). Use \`background: false\` only for a very short task whose answer you need right now: the call then waits for it. Your team can change at any time: when asked which agents you have or can delegate to, call the \`list_agents\` tool (${tn('list_agents')}) and report exactly what it returns, never an older list from memory. Never mention or try to use agents outside that list.`);
|
|
81
|
+
parts.push(`## Your team\nThese are your subagents — the ONLY agents you can delegate to:\n${roster}\n\nDelegate with the \`dispatch\` tool (${tn('dispatch')}) instead of doing their work yourself, then synthesize their answers. Always use it: never play a subagent's role yourself, and never use a generic built-in subagent in its place — a subagent is a separate real agent with its own session. Each delegation starts a fresh conversation for that subagent, so put all the context it needs in the task. \`dispatch\` returns at once with a task id, so you can answer the person or delegate more meanwhile, and the result reaches you as a message when the subagent finishes (you can also ask with the \`dispatch_status\` tool (${tn('dispatch_status')})). Use \`background: false\` only for a very short task whose answer you need right now: the call then waits for it. To take back a task that is no longer needed (sent by mistake, with the wrong context, or the plan changed), call the \`dispatch_cancel\` tool (${tn('dispatch_cancel')}) with its id; the \`dispatch_list\` tool (${tn('dispatch_list')}) lists your tasks that have not finished. What a cancelled subagent already changed stays in the folder, so check it before delegating again. Your team can change at any time: when asked which agents you have or can delegate to, call the \`list_agents\` tool (${tn('list_agents')}) and report exactly what it returns, never an older list from memory. Never mention or try to use agents outside that list.`);
|
|
82
82
|
}
|
|
83
83
|
else {
|
|
84
84
|
parts.push('## Your team\nYou currently have no subagents connected to you, so you cannot delegate. If asked, say so; do not claim to know other agents.');
|
package/server/dist/runtime.js
CHANGED
|
@@ -13,7 +13,7 @@ const states = new Map();
|
|
|
13
13
|
const st = (id) => {
|
|
14
14
|
let s = states.get(id);
|
|
15
15
|
if (!s)
|
|
16
|
-
states.set(id, (s = { chain: Promise.resolve(), controller: null, queued: 0, live: null }));
|
|
16
|
+
states.set(id, (s = { chain: Promise.resolve(), controller: null, dispatchId: null, queued: 0, live: null, cancelled: new Set() }));
|
|
17
17
|
return s;
|
|
18
18
|
};
|
|
19
19
|
export const liveTurn = (id) => states.get(id)?.live ?? null;
|
|
@@ -47,6 +47,9 @@ export function sendTurn(agentId, prompt, source = 'user', from, dispatchId, ori
|
|
|
47
47
|
}
|
|
48
48
|
async function execute(agentId, prompt, source, from, dispatchId, origin) {
|
|
49
49
|
const s = st(agentId);
|
|
50
|
+
// A delegation cancelled while it waited never reaches the provider; it already left the queue count when it was cancelled.
|
|
51
|
+
if (dispatchId && s.cancelled.delete(dispatchId))
|
|
52
|
+
return { ok: false, text: '', error: 'Cancelled' };
|
|
50
53
|
s.queued--;
|
|
51
54
|
let raw;
|
|
52
55
|
let agent;
|
|
@@ -84,6 +87,7 @@ async function execute(agentId, prompt, source, from, dispatchId, origin) {
|
|
|
84
87
|
const push = (event) => { s.live?.events.push(event); emit({ kind: 'event', agentId, turnId, event }); };
|
|
85
88
|
try {
|
|
86
89
|
s.controller = controller;
|
|
90
|
+
s.dispatchId = dispatchId ?? null;
|
|
87
91
|
s.live = { turnId, prompt, events: [], source, origin };
|
|
88
92
|
if (dispatchId)
|
|
89
93
|
dispatches.setRunning(dispatchId);
|
|
@@ -143,6 +147,7 @@ async function execute(agentId, prompt, source, from, dispatchId, origin) {
|
|
|
143
147
|
if (controller.signal.aborted && !error)
|
|
144
148
|
push({ t: 'done', ok: false, summary: 'Stopped' });
|
|
145
149
|
s.controller = null;
|
|
150
|
+
s.dispatchId = null;
|
|
146
151
|
s.live = null;
|
|
147
152
|
if (!error && !delegated && !controller.signal.aborted) {
|
|
148
153
|
agents.setInstrHash(agentId, hash);
|
|
@@ -159,6 +164,24 @@ export function stopAgent(agentId, clearQueue = true) {
|
|
|
159
164
|
s.controller.abort();
|
|
160
165
|
return true;
|
|
161
166
|
}
|
|
167
|
+
/** Takes a queued delegation out of the worker's queue: its turn is skipped when the chain reaches it, and the count drops now. */
|
|
168
|
+
export function cancelQueued(agentId, dispatchId) {
|
|
169
|
+
const s = states.get(agentId);
|
|
170
|
+
if (!s || s.queued <= 0 || s.cancelled.has(dispatchId))
|
|
171
|
+
return false;
|
|
172
|
+
s.cancelled.add(dispatchId);
|
|
173
|
+
s.queued--;
|
|
174
|
+
emit({ kind: 'status', agentId, status: s.live ? 'running' : s.queued ? 'queued' : agents.get(agentId)?.status === 'error' ? 'error' : 'idle', queued: s.queued });
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
/** Aborts the worker's turn only if it is serving this delegation, so cancelling one task never stops another. */
|
|
178
|
+
export function abortDispatch(agentId, dispatchId) {
|
|
179
|
+
const s = states.get(agentId);
|
|
180
|
+
if (!s?.controller || s.dispatchId !== dispatchId)
|
|
181
|
+
return false;
|
|
182
|
+
s.controller.abort();
|
|
183
|
+
return true;
|
|
184
|
+
}
|
|
162
185
|
/**
|
|
163
186
|
* Orchestrator → worker delegation. Enforces the explicit assignment rule. The task is stored and queued on the worker at once; `done`
|
|
164
187
|
* settles when the worker's turn ends, after the row holds the result, so nothing depends on the caller still waiting for it.
|
|
@@ -174,6 +197,7 @@ export function startDispatch(fromId, workerName, task, mode = 'sync', origin =
|
|
|
174
197
|
throw new Error(`"${worker.name}" is not assigned to ${from.name}`);
|
|
175
198
|
const id = dispatches.start(from.id, worker.id, task, mode, origin);
|
|
176
199
|
const done = sendTurn(worker.id, task, 'dispatch', from.id, id).then((res) => {
|
|
200
|
+
// A no-op when the task was cancelled meanwhile: the aborted or skipped turn does not turn `cancelled` into `failed`.
|
|
177
201
|
dispatches.finish(id, res.ok ? 'done' : 'failed', res.text || res.error || '');
|
|
178
202
|
return res;
|
|
179
203
|
});
|
package/server/mcp/dispatch.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// Minimal MCP stdio server for hive-am agents. Tool groups come from HIVE_CAPS:
|
|
3
|
-
// dispatch → list_agents, dispatch, dispatch_status (orchestrators with a team)
|
|
3
|
+
// dispatch → list_agents, dispatch, dispatch_status, dispatch_list, dispatch_cancel (orchestrators with a team)
|
|
4
4
|
// channel → channel_reply, channel_send_file, channel_react, channel_mute (agents linked to Telegram/Slack)
|
|
5
5
|
// wake → wake_me, wake_when_done, schedule_create, schedule_list, schedule_cancel (agents with the Wake-ups skill: to be woken later in the same place)
|
|
6
6
|
// objects → object_list, object_logs, object_action (agents with the Colony objects skill: the servers and containers of their colony)
|
|
@@ -39,7 +39,7 @@ const allTools = [
|
|
|
39
39
|
{
|
|
40
40
|
cap: 'dispatch',
|
|
41
41
|
name: 'dispatch_status',
|
|
42
|
-
description: 'State of a task you delegated: queued, running, done, failed or
|
|
42
|
+
description: 'State of a task you delegated: queued, running, done, failed, interrupted or cancelled, with the result once it has finished. With wait_seconds it waits up to that long for the end before answering.',
|
|
43
43
|
inputSchema: {
|
|
44
44
|
type: 'object',
|
|
45
45
|
properties: {
|
|
@@ -50,6 +50,23 @@ const allTools = [
|
|
|
50
50
|
additionalProperties: false,
|
|
51
51
|
},
|
|
52
52
|
},
|
|
53
|
+
{
|
|
54
|
+
cap: 'dispatch',
|
|
55
|
+
name: 'dispatch_list',
|
|
56
|
+
description: 'List the tasks you delegated that have not finished yet (queued or running), with their id, subagent, state and age, oldest first.',
|
|
57
|
+
inputSchema: { type: 'object', properties: {}, additionalProperties: false },
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
cap: 'dispatch',
|
|
61
|
+
name: 'dispatch_cancel',
|
|
62
|
+
description: 'Cancel a task you delegated that is no longer needed (sent by mistake, wrong context, or the plan changed). A queued task never starts; a running one is stopped at once, and what the subagent already changed stays in the folder, so check it before delegating again. A task that already finished is left as it is and its state is answered. You are not sent a message about a task you cancel.',
|
|
63
|
+
inputSchema: {
|
|
64
|
+
type: 'object',
|
|
65
|
+
properties: { id: { type: 'string', description: 'The task id that dispatch returned' } },
|
|
66
|
+
required: ['id'],
|
|
67
|
+
additionalProperties: false,
|
|
68
|
+
},
|
|
69
|
+
},
|
|
53
70
|
{
|
|
54
71
|
cap: 'channel',
|
|
55
72
|
name: 'channel_reply',
|
|
@@ -333,12 +350,35 @@ async function call(name, args) {
|
|
|
333
350
|
}
|
|
334
351
|
if (s.status === 'done') return s.result;
|
|
335
352
|
if (s.status === 'failed' || s.status === 'interrupted') throw new Error(`${j.agent} did not finish the task (${s.status}): ${s.result}`);
|
|
353
|
+
if (s.status === 'cancelled') throw new Error(`${j.agent} task was cancelled: ${s.result}`);
|
|
336
354
|
}
|
|
337
355
|
}
|
|
338
356
|
if (name === 'dispatch_status') {
|
|
339
357
|
const s = await taskStatus(args.id, args.wait_seconds);
|
|
340
358
|
return `Task ${s.id} for ${s.agent}: ${s.status}.${s.note ? ` ${s.note}` : ''}${s.result !== undefined ? ` Result:\n${s.result}` : ' Not finished yet.'}`;
|
|
341
359
|
}
|
|
360
|
+
if (name === 'dispatch_list') {
|
|
361
|
+
const r = await fetch(`${API}/api/dispatch/list`, {
|
|
362
|
+
method: 'POST', headers: { 'content-type': 'application/json' },
|
|
363
|
+
body: JSON.stringify({ from: FROM }),
|
|
364
|
+
});
|
|
365
|
+
const j = await r.json();
|
|
366
|
+
if (!r.ok) throw new Error(j.error ?? `dispatch_list failed (${r.status})`);
|
|
367
|
+
const age = (s) => (s < 60 ? `${s} s` : s < 3600 ? `${Math.round(s / 60)} min` : `${Math.round(s / 3600)} h`);
|
|
368
|
+
return j.length ? j.map((t) => `${t.id} · ${t.agent} · ${t.status} · ${t.mode} · ${age(t.age_s)} ago\n ${t.task.replace(/\s+/g, ' ')}`).join('\n') : 'You have no delegated tasks that have not finished.';
|
|
369
|
+
}
|
|
370
|
+
if (name === 'dispatch_cancel') {
|
|
371
|
+
const r = await fetch(`${API}/api/dispatch/cancel`, {
|
|
372
|
+
method: 'POST', headers: { 'content-type': 'application/json' },
|
|
373
|
+
body: JSON.stringify({ from: FROM, id: args.id }),
|
|
374
|
+
});
|
|
375
|
+
const j = await r.json();
|
|
376
|
+
if (!r.ok) throw new Error(j.error ?? `dispatch_cancel failed (${r.status})`);
|
|
377
|
+
if (!j.cancelled) return `Task ${j.id} for ${j.agent} had already finished (${j.status}); nothing changed.${j.result !== undefined ? ` Result:\n${j.result}` : ''}`;
|
|
378
|
+
return j.was === 'running'
|
|
379
|
+
? `Task ${j.id} for ${j.agent} cancelled: ${j.agent} was working on it and was stopped. What it already changed stays in the folder; check it before delegating again.`
|
|
380
|
+
: `Task ${j.id} for ${j.agent} cancelled before it started.`;
|
|
381
|
+
}
|
|
342
382
|
if (name === 'channel_reply') {
|
|
343
383
|
const r = await fetch(`${API}/api/channel/reply`, {
|
|
344
384
|
method: 'POST', headers: { 'content-type': 'application/json' },
|
package/web/.next/BUILD_ID
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
HzL5-xIKbr0VsaWuLWHNl
|
|
@@ -13,49 +13,49 @@
|
|
|
13
13
|
"static/chunks/89-b194fcffe5120c44.js",
|
|
14
14
|
"static/chunks/main-app-27cc7ffdb888b879.js",
|
|
15
15
|
"static/css/945795da867f5250.css",
|
|
16
|
-
"static/css/
|
|
16
|
+
"static/css/f9099a8765eed6f0.css",
|
|
17
17
|
"static/chunks/586-4f67b823df060b46.js",
|
|
18
18
|
"static/chunks/8523-82e1ee6239699d8a.js",
|
|
19
|
-
"static/chunks/
|
|
19
|
+
"static/chunks/4740-0581e5cb9334010b.js",
|
|
20
20
|
"static/chunks/969-07e498da015b149a.js",
|
|
21
21
|
"static/chunks/3790-3d3f11a264e8ede8.js",
|
|
22
|
-
"static/chunks/app/layout-
|
|
22
|
+
"static/chunks/app/layout-b327408bcfb13a70.js"
|
|
23
23
|
],
|
|
24
|
-
"/
|
|
24
|
+
"/colony/page": [
|
|
25
25
|
"static/chunks/webpack-ba68c1813987a630.js",
|
|
26
26
|
"static/chunks/0937d497-daa99a23a4431317.js",
|
|
27
27
|
"static/chunks/89-b194fcffe5120c44.js",
|
|
28
28
|
"static/chunks/main-app-27cc7ffdb888b879.js",
|
|
29
29
|
"static/chunks/586-4f67b823df060b46.js",
|
|
30
30
|
"static/chunks/7706-bd0d2bda0e0c8d1e.js",
|
|
31
|
-
"static/chunks/
|
|
32
|
-
"static/chunks/
|
|
33
|
-
"static/chunks/
|
|
31
|
+
"static/chunks/5642-09dd4161ddddaf94.js",
|
|
32
|
+
"static/chunks/4162-c2361cb017547c37.js",
|
|
33
|
+
"static/chunks/4740-0581e5cb9334010b.js",
|
|
34
|
+
"static/chunks/1517-9b82b61ee9921bb1.js",
|
|
35
|
+
"static/chunks/969-07e498da015b149a.js",
|
|
36
|
+
"static/chunks/1606-6d25d725156f5127.js",
|
|
37
|
+
"static/chunks/5587-cdccc5cf4056b739.js",
|
|
38
|
+
"static/chunks/app/colony/page-600b663a716d08c4.js"
|
|
34
39
|
],
|
|
35
|
-
"/
|
|
40
|
+
"/chat/page": [
|
|
36
41
|
"static/chunks/webpack-ba68c1813987a630.js",
|
|
37
42
|
"static/chunks/0937d497-daa99a23a4431317.js",
|
|
38
43
|
"static/chunks/89-b194fcffe5120c44.js",
|
|
39
44
|
"static/chunks/main-app-27cc7ffdb888b879.js",
|
|
40
45
|
"static/chunks/586-4f67b823df060b46.js",
|
|
41
|
-
"static/chunks/
|
|
42
|
-
"static/chunks/
|
|
46
|
+
"static/chunks/7706-bd0d2bda0e0c8d1e.js",
|
|
47
|
+
"static/chunks/4740-0581e5cb9334010b.js",
|
|
48
|
+
"static/chunks/1517-9b82b61ee9921bb1.js",
|
|
49
|
+
"static/chunks/app/chat/page-157685bdaad86c26.js"
|
|
43
50
|
],
|
|
44
|
-
"/
|
|
51
|
+
"/connections/page": [
|
|
45
52
|
"static/chunks/webpack-ba68c1813987a630.js",
|
|
46
53
|
"static/chunks/0937d497-daa99a23a4431317.js",
|
|
47
54
|
"static/chunks/89-b194fcffe5120c44.js",
|
|
48
55
|
"static/chunks/main-app-27cc7ffdb888b879.js",
|
|
49
56
|
"static/chunks/586-4f67b823df060b46.js",
|
|
50
|
-
"static/chunks/
|
|
51
|
-
"static/chunks/
|
|
52
|
-
"static/chunks/4162-c2361cb017547c37.js",
|
|
53
|
-
"static/chunks/9977-78b955d85f795a21.js",
|
|
54
|
-
"static/chunks/1517-e96b538fa33001f5.js",
|
|
55
|
-
"static/chunks/969-07e498da015b149a.js",
|
|
56
|
-
"static/chunks/1606-2aa8ee5a6751f920.js",
|
|
57
|
-
"static/chunks/5587-7e580517c4105e63.js",
|
|
58
|
-
"static/chunks/app/colony/page-ffdc123dac47ad69.js"
|
|
57
|
+
"static/chunks/4740-0581e5cb9334010b.js",
|
|
58
|
+
"static/chunks/app/connections/page-cbfcb1547d45c833.js"
|
|
59
59
|
],
|
|
60
60
|
"/page": [
|
|
61
61
|
"static/chunks/webpack-ba68c1813987a630.js",
|
|
@@ -64,43 +64,43 @@
|
|
|
64
64
|
"static/chunks/main-app-27cc7ffdb888b879.js",
|
|
65
65
|
"static/chunks/586-4f67b823df060b46.js",
|
|
66
66
|
"static/chunks/7706-bd0d2bda0e0c8d1e.js",
|
|
67
|
-
"static/chunks/
|
|
68
|
-
"static/chunks/1517-
|
|
67
|
+
"static/chunks/4740-0581e5cb9334010b.js",
|
|
68
|
+
"static/chunks/1517-9b82b61ee9921bb1.js",
|
|
69
69
|
"static/chunks/3790-3d3f11a264e8ede8.js",
|
|
70
|
-
"static/chunks/app/page-
|
|
70
|
+
"static/chunks/app/page-78c38105a034b0b3.js"
|
|
71
71
|
],
|
|
72
|
-
"/
|
|
72
|
+
"/relations/page": [
|
|
73
73
|
"static/chunks/webpack-ba68c1813987a630.js",
|
|
74
74
|
"static/chunks/0937d497-daa99a23a4431317.js",
|
|
75
75
|
"static/chunks/89-b194fcffe5120c44.js",
|
|
76
76
|
"static/chunks/main-app-27cc7ffdb888b879.js",
|
|
77
|
+
"static/css/c4a545148b5320ec.css",
|
|
78
|
+
"static/chunks/2b9ff8ee-0851c7e556e3a39b.js",
|
|
77
79
|
"static/chunks/586-4f67b823df060b46.js",
|
|
78
|
-
"static/chunks/
|
|
79
|
-
"static/chunks/
|
|
80
|
-
"static/chunks/
|
|
81
|
-
"static/chunks/1771-4688ad65e21bb512.js",
|
|
82
|
-
"static/chunks/9977-78b955d85f795a21.js",
|
|
83
|
-
"static/chunks/1517-e96b538fa33001f5.js",
|
|
84
|
-
"static/chunks/969-07e498da015b149a.js",
|
|
85
|
-
"static/chunks/1606-2aa8ee5a6751f920.js",
|
|
86
|
-
"static/chunks/5587-7e580517c4105e63.js",
|
|
87
|
-
"static/chunks/4030-bc2e0aa4da0d9ad8.js",
|
|
88
|
-
"static/chunks/4491-49c700f509985c9e.js",
|
|
89
|
-
"static/chunks/app/resources/[id]/page-48131f750e983a07.js"
|
|
80
|
+
"static/chunks/3757-45ea801718ec19e4.js",
|
|
81
|
+
"static/chunks/4740-0581e5cb9334010b.js",
|
|
82
|
+
"static/chunks/app/relations/page-622a4c5723c7c5cc.js"
|
|
90
83
|
],
|
|
91
|
-
"/
|
|
84
|
+
"/resources/page": [
|
|
92
85
|
"static/chunks/webpack-ba68c1813987a630.js",
|
|
93
86
|
"static/chunks/0937d497-daa99a23a4431317.js",
|
|
94
87
|
"static/chunks/89-b194fcffe5120c44.js",
|
|
95
88
|
"static/chunks/main-app-27cc7ffdb888b879.js",
|
|
96
|
-
"static/css/c4a545148b5320ec.css",
|
|
97
|
-
"static/chunks/2b9ff8ee-0851c7e556e3a39b.js",
|
|
98
89
|
"static/chunks/586-4f67b823df060b46.js",
|
|
99
|
-
"static/chunks/
|
|
100
|
-
"static/chunks/
|
|
101
|
-
"static/chunks/
|
|
90
|
+
"static/chunks/7706-bd0d2bda0e0c8d1e.js",
|
|
91
|
+
"static/chunks/5642-09dd4161ddddaf94.js",
|
|
92
|
+
"static/chunks/4837-8dc05d75f258f9e1.js",
|
|
93
|
+
"static/chunks/1771-4688ad65e21bb512.js",
|
|
94
|
+
"static/chunks/4740-0581e5cb9334010b.js",
|
|
95
|
+
"static/chunks/1517-9b82b61ee9921bb1.js",
|
|
96
|
+
"static/chunks/969-07e498da015b149a.js",
|
|
97
|
+
"static/chunks/1606-6d25d725156f5127.js",
|
|
98
|
+
"static/chunks/5587-cdccc5cf4056b739.js",
|
|
99
|
+
"static/chunks/4030-bc2e0aa4da0d9ad8.js",
|
|
100
|
+
"static/chunks/4491-886c18aee1e9c737.js",
|
|
101
|
+
"static/chunks/app/resources/page-a2e17f0dc205a2a4.js"
|
|
102
102
|
],
|
|
103
|
-
"/resources/page": [
|
|
103
|
+
"/resources/[id]/page": [
|
|
104
104
|
"static/chunks/webpack-ba68c1813987a630.js",
|
|
105
105
|
"static/chunks/0937d497-daa99a23a4431317.js",
|
|
106
106
|
"static/chunks/89-b194fcffe5120c44.js",
|
|
@@ -110,14 +110,14 @@
|
|
|
110
110
|
"static/chunks/5642-09dd4161ddddaf94.js",
|
|
111
111
|
"static/chunks/4837-8dc05d75f258f9e1.js",
|
|
112
112
|
"static/chunks/1771-4688ad65e21bb512.js",
|
|
113
|
-
"static/chunks/
|
|
114
|
-
"static/chunks/1517-
|
|
113
|
+
"static/chunks/4740-0581e5cb9334010b.js",
|
|
114
|
+
"static/chunks/1517-9b82b61ee9921bb1.js",
|
|
115
115
|
"static/chunks/969-07e498da015b149a.js",
|
|
116
|
-
"static/chunks/1606-
|
|
117
|
-
"static/chunks/5587-
|
|
116
|
+
"static/chunks/1606-6d25d725156f5127.js",
|
|
117
|
+
"static/chunks/5587-cdccc5cf4056b739.js",
|
|
118
118
|
"static/chunks/4030-bc2e0aa4da0d9ad8.js",
|
|
119
|
-
"static/chunks/4491-
|
|
120
|
-
"static/chunks/app/resources/page-
|
|
119
|
+
"static/chunks/4491-886c18aee1e9c737.js",
|
|
120
|
+
"static/chunks/app/resources/[id]/page-b9af9eecf693b695.js"
|
|
121
121
|
],
|
|
122
122
|
"/schedules/page": [
|
|
123
123
|
"static/chunks/webpack-ba68c1813987a630.js",
|
|
@@ -125,8 +125,8 @@
|
|
|
125
125
|
"static/chunks/89-b194fcffe5120c44.js",
|
|
126
126
|
"static/chunks/main-app-27cc7ffdb888b879.js",
|
|
127
127
|
"static/chunks/586-4f67b823df060b46.js",
|
|
128
|
-
"static/chunks/
|
|
129
|
-
"static/chunks/app/schedules/page-
|
|
128
|
+
"static/chunks/4740-0581e5cb9334010b.js",
|
|
129
|
+
"static/chunks/app/schedules/page-d534462088c64b59.js"
|
|
130
130
|
],
|
|
131
131
|
"/sessions/page": [
|
|
132
132
|
"static/chunks/webpack-ba68c1813987a630.js",
|
|
@@ -136,31 +136,31 @@
|
|
|
136
136
|
"static/chunks/586-4f67b823df060b46.js",
|
|
137
137
|
"static/chunks/7706-bd0d2bda0e0c8d1e.js",
|
|
138
138
|
"static/chunks/2654-4aeef09c0d6bf56a.js",
|
|
139
|
-
"static/chunks/
|
|
139
|
+
"static/chunks/4740-0581e5cb9334010b.js",
|
|
140
140
|
"static/chunks/969-07e498da015b149a.js",
|
|
141
|
-
"static/chunks/2547-
|
|
142
|
-
"static/chunks/app/sessions/page-
|
|
141
|
+
"static/chunks/2547-8b6bdae3c622a158.js",
|
|
142
|
+
"static/chunks/app/sessions/page-6fef5b73bfbf262e.js"
|
|
143
143
|
],
|
|
144
|
-
"/
|
|
144
|
+
"/skills/page": [
|
|
145
145
|
"static/chunks/webpack-ba68c1813987a630.js",
|
|
146
146
|
"static/chunks/0937d497-daa99a23a4431317.js",
|
|
147
147
|
"static/chunks/89-b194fcffe5120c44.js",
|
|
148
148
|
"static/chunks/main-app-27cc7ffdb888b879.js",
|
|
149
149
|
"static/chunks/586-4f67b823df060b46.js",
|
|
150
150
|
"static/chunks/7706-bd0d2bda0e0c8d1e.js",
|
|
151
|
-
"static/chunks/
|
|
152
|
-
"static/chunks/
|
|
153
|
-
"static/chunks/app/types/page-a991fe9afa51bdb7.js"
|
|
151
|
+
"static/chunks/4740-0581e5cb9334010b.js",
|
|
152
|
+
"static/chunks/app/skills/page-ab25a3a6d348a049.js"
|
|
154
153
|
],
|
|
155
|
-
"/
|
|
154
|
+
"/types/page": [
|
|
156
155
|
"static/chunks/webpack-ba68c1813987a630.js",
|
|
157
156
|
"static/chunks/0937d497-daa99a23a4431317.js",
|
|
158
157
|
"static/chunks/89-b194fcffe5120c44.js",
|
|
159
158
|
"static/chunks/main-app-27cc7ffdb888b879.js",
|
|
160
159
|
"static/chunks/586-4f67b823df060b46.js",
|
|
161
160
|
"static/chunks/7706-bd0d2bda0e0c8d1e.js",
|
|
162
|
-
"static/chunks/
|
|
163
|
-
"static/chunks/
|
|
161
|
+
"static/chunks/4740-0581e5cb9334010b.js",
|
|
162
|
+
"static/chunks/1517-9b82b61ee9921bb1.js",
|
|
163
|
+
"static/chunks/app/types/page-7e08ca1bcbee605f.js"
|
|
164
164
|
],
|
|
165
165
|
"/agents/layout": [
|
|
166
166
|
"static/chunks/webpack-ba68c1813987a630.js",
|
|
@@ -170,39 +170,39 @@
|
|
|
170
170
|
"static/chunks/586-4f67b823df060b46.js",
|
|
171
171
|
"static/chunks/7706-bd0d2bda0e0c8d1e.js",
|
|
172
172
|
"static/chunks/5642-09dd4161ddddaf94.js",
|
|
173
|
-
"static/chunks/
|
|
174
|
-
"static/chunks/1517-
|
|
173
|
+
"static/chunks/4740-0581e5cb9334010b.js",
|
|
174
|
+
"static/chunks/1517-9b82b61ee9921bb1.js",
|
|
175
175
|
"static/chunks/969-07e498da015b149a.js",
|
|
176
|
-
"static/chunks/app/agents/layout-
|
|
176
|
+
"static/chunks/app/agents/layout-db700c86124f32de.js"
|
|
177
177
|
],
|
|
178
|
-
"/agents/page": [
|
|
178
|
+
"/agents/[id]/page": [
|
|
179
179
|
"static/chunks/webpack-ba68c1813987a630.js",
|
|
180
180
|
"static/chunks/0937d497-daa99a23a4431317.js",
|
|
181
181
|
"static/chunks/89-b194fcffe5120c44.js",
|
|
182
182
|
"static/chunks/main-app-27cc7ffdb888b879.js",
|
|
183
183
|
"static/chunks/586-4f67b823df060b46.js",
|
|
184
184
|
"static/chunks/7706-bd0d2bda0e0c8d1e.js",
|
|
185
|
-
"static/chunks/
|
|
186
|
-
"static/chunks/
|
|
187
|
-
"static/chunks/
|
|
185
|
+
"static/chunks/5642-09dd4161ddddaf94.js",
|
|
186
|
+
"static/chunks/4837-8dc05d75f258f9e1.js",
|
|
187
|
+
"static/chunks/3214-c9d0c933db5b0f44.js",
|
|
188
|
+
"static/chunks/4740-0581e5cb9334010b.js",
|
|
189
|
+
"static/chunks/1517-9b82b61ee9921bb1.js",
|
|
190
|
+
"static/chunks/969-07e498da015b149a.js",
|
|
191
|
+
"static/chunks/1606-6d25d725156f5127.js",
|
|
192
|
+
"static/chunks/4030-bc2e0aa4da0d9ad8.js",
|
|
193
|
+
"static/chunks/2547-8b6bdae3c622a158.js",
|
|
194
|
+
"static/chunks/app/agents/[id]/page-eeb93069b69e7f7e.js"
|
|
188
195
|
],
|
|
189
|
-
"/agents/
|
|
196
|
+
"/agents/page": [
|
|
190
197
|
"static/chunks/webpack-ba68c1813987a630.js",
|
|
191
198
|
"static/chunks/0937d497-daa99a23a4431317.js",
|
|
192
199
|
"static/chunks/89-b194fcffe5120c44.js",
|
|
193
200
|
"static/chunks/main-app-27cc7ffdb888b879.js",
|
|
194
201
|
"static/chunks/586-4f67b823df060b46.js",
|
|
195
202
|
"static/chunks/7706-bd0d2bda0e0c8d1e.js",
|
|
196
|
-
"static/chunks/
|
|
197
|
-
"static/chunks/
|
|
198
|
-
"static/chunks/
|
|
199
|
-
"static/chunks/9977-78b955d85f795a21.js",
|
|
200
|
-
"static/chunks/1517-e96b538fa33001f5.js",
|
|
201
|
-
"static/chunks/969-07e498da015b149a.js",
|
|
202
|
-
"static/chunks/1606-2aa8ee5a6751f920.js",
|
|
203
|
-
"static/chunks/4030-bc2e0aa4da0d9ad8.js",
|
|
204
|
-
"static/chunks/2547-821b5a01cff1915f.js",
|
|
205
|
-
"static/chunks/app/agents/[id]/page-da4050632f63874d.js"
|
|
203
|
+
"static/chunks/4740-0581e5cb9334010b.js",
|
|
204
|
+
"static/chunks/1517-9b82b61ee9921bb1.js",
|
|
205
|
+
"static/chunks/app/agents/page-bf40d654c5fe5c23.js"
|
|
206
206
|
]
|
|
207
207
|
}
|
|
208
208
|
}
|