hive-am 1.3.0 → 1.5.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 +47 -1
- package/README.md +20 -5
- package/bin/hive-am.mjs +242 -31
- package/bin/run.mjs +135 -0
- package/package.json +1 -1
- package/server/dist/connections/manager.js +15 -3
- package/server/dist/connections/router.js +2 -2
- package/server/dist/connections/secrets.js +8 -0
- package/server/dist/db/migrations.js +68 -0
- package/server/dist/db.js +11 -10
- package/server/dist/efforts.js +105 -0
- package/server/dist/http/routes/agents.js +4 -3
- package/server/dist/http/routes/meta.js +12 -0
- package/server/dist/http/routes/notebook.js +10 -2
- package/server/dist/http/routes/resources.js +3 -0
- package/server/dist/http/routes/types.js +18 -1
- package/server/dist/http/validate.js +5 -2
- package/server/dist/index.js +4 -1
- package/server/dist/instructions.js +10 -2
- package/server/dist/objects/agent-db.js +258 -0
- package/server/dist/objects/database.js +496 -34
- package/server/dist/objects/index.js +20 -14
- package/server/dist/objects/runner.js +20 -0
- package/server/dist/objects/supervisor.js +2 -2
- package/server/dist/providers/kiro.js +7 -1
- package/server/dist/providers/opencode-server.js +11 -1
- package/server/dist/providers/opencode.js +4 -3
- package/server/dist/providers/spawn.js +38 -4
- package/server/dist/retention.js +50 -0
- package/server/dist/runtime.js +52 -21
- package/server/dist/services/agents.js +53 -1
- package/server/dist/services/notebook.js +7 -3
- package/server/dist/skills/defaults.js +35 -1
- package/server/dist/skills/notebook.js +57 -13
- package/server/mcp/dispatch.mjs +68 -0
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/app-build-manifest.json +79 -70
- package/web/.next/app-path-routes-manifest.json +9 -8
- package/web/.next/build-manifest.json +2 -2
- package/web/.next/prerender-manifest.json +71 -47
- package/web/.next/routes-manifest.json +6 -0
- package/web/.next/server/app/_not-found/page.js +1 -1
- package/web/.next/server/app/_not-found/page.js.nft.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 +4 -4
- package/web/.next/server/app/agents/[id]/page.js.nft.json +1 -1
- 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.js.nft.json +1 -1
- 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 +4 -4
- package/web/.next/server/app/chat/page.js +2 -0
- package/web/.next/server/app/chat/page.js.nft.json +1 -0
- package/web/.next/server/app/chat/page_client-reference-manifest.js +1 -0
- package/web/.next/server/app/chat.html +1 -0
- package/web/.next/server/app/chat.meta +15 -0
- package/web/.next/server/app/chat.rsc +25 -0
- package/web/.next/server/app/connections/page.js +1 -1
- package/web/.next/server/app/connections/page.js.nft.json +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 +1 -1
- package/web/.next/server/app/page.js.nft.json +1 -1
- package/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/relations/page.js +2 -2
- package/web/.next/server/app/relations/page.js.nft.json +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.js +2 -2
- package/web/.next/server/app/resources/[id]/page.js.nft.json +1 -1
- package/web/.next/server/app/resources/[id]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/resources/page.js +2 -2
- package/web/.next/server/app/resources/page.js.nft.json +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.js.nft.json +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 +2 -2
- package/web/.next/server/app/sessions/page.js.nft.json +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.js.nft.json +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.js.nft.json +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 +9 -8
- package/web/.next/server/chunks/143.js +1 -1
- package/web/.next/server/chunks/148.js +1 -0
- package/web/.next/server/chunks/213.js +6 -0
- package/web/.next/server/chunks/274.js +1 -1
- package/web/.next/server/chunks/368.js +1 -0
- package/web/.next/server/chunks/403.js +1 -0
- package/web/.next/server/chunks/{790.js → 435.js} +2 -2
- package/web/.next/server/chunks/505.js +1 -6
- package/web/.next/server/chunks/612.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/UDA414PFPu9ZROltNmjbX/_buildManifest.js +1 -0
- package/web/.next/static/chunks/{316-26da9cc233ba7557.js → 107-77dd87cc2ca4f941.js} +1 -1
- package/web/.next/static/chunks/281-30e32d932b8b5a75.js +1 -0
- package/web/.next/static/chunks/391-18768499e741112e.js +1 -0
- package/web/.next/static/chunks/517-b3b1c9044d2ef23c.js +1 -0
- package/web/.next/static/chunks/587-5b511f5f93910180.js +1 -0
- package/web/.next/static/chunks/606-14fb5aaa4d0ff22d.js +1 -0
- package/web/.next/static/chunks/656-f3cc78328603241a.js +1 -0
- package/web/.next/static/chunks/{705-780e48e55b0346bd.js → 705-ce86175dea00e6a9.js} +1 -1
- package/web/.next/static/chunks/757-03361e7a97a605a2.js +1 -0
- package/web/.next/static/chunks/app/agents/[id]/page-638e12ba3cb813c3.js +1 -0
- package/web/.next/static/chunks/app/agents/page-9da499db6d22731f.js +1 -0
- package/web/.next/static/chunks/app/chat/page-383bc24e72dab7fa.js +1 -0
- package/web/.next/static/chunks/app/connections/{page-eb11cfb1ffeab3ca.js → page-06bd2d7d9495126a.js} +1 -1
- package/web/.next/static/chunks/app/layout-fad968a635f9a4b3.js +1 -0
- package/web/.next/static/chunks/app/page-0062ebc30322b1ae.js +1 -0
- package/web/.next/static/chunks/app/relations/page-02710fe1f8a670a9.js +1 -0
- package/web/.next/static/chunks/app/resources/[id]/{page-bf05836f97248ca7.js → page-fc494e85b01e8cb7.js} +1 -1
- package/web/.next/static/chunks/app/resources/{page-800f774e5cacf4c9.js → page-61cccd8fdcc2f6c8.js} +1 -1
- package/web/.next/static/chunks/app/sessions/page-85638705fdc18174.js +1 -0
- package/web/.next/static/chunks/app/types/page-8e25f503bdcd72ad.js +1 -0
- package/web/.next/static/css/dfcaa19a8d46e60d.css +1 -0
- package/web/.next/trace +30 -29
- package/web/.next/types/app/chat/page.ts +84 -0
- package/web/.next/types/routes.d.ts +2 -1
- package/web/.next/types/validator.ts +9 -0
- package/web/.next/server/chunks/306.js +0 -1
- package/web/.next/server/chunks/451.js +0 -1
- package/web/.next/server/chunks/638.js +0 -1
- package/web/.next/server/chunks/802.js +0 -1
- package/web/.next/static/aSYzbHk1M5YeS_d3SQKTZ/_buildManifest.js +0 -1
- package/web/.next/static/chunks/281-d8a0dcfaa6d064e4.js +0 -1
- package/web/.next/static/chunks/291-23f314877fa39054.js +0 -1
- package/web/.next/static/chunks/304-681348099f874a30.js +0 -1
- package/web/.next/static/chunks/491-28f093772bd460ac.js +0 -1
- package/web/.next/static/chunks/517-373a80c8ba432bdc.js +0 -1
- package/web/.next/static/chunks/562-7c2e33d838e869bf.js +0 -1
- package/web/.next/static/chunks/581-3ad5c4343dad3f50.js +0 -1
- package/web/.next/static/chunks/844-519177e6198ca84f.js +0 -1
- package/web/.next/static/chunks/app/agents/[id]/page-c005161cec5527d8.js +0 -1
- package/web/.next/static/chunks/app/agents/page-9bb8cba69776c719.js +0 -1
- package/web/.next/static/chunks/app/layout-49b46c9b5aa512a8.js +0 -1
- package/web/.next/static/chunks/app/page-da042d146caeeab6.js +0 -1
- package/web/.next/static/chunks/app/relations/page-a44fd515a3b0525e.js +0 -1
- package/web/.next/static/chunks/app/sessions/page-a7534ebd90e982d6.js +0 -1
- package/web/.next/static/chunks/app/types/page-ebd37e220f77c1f3.js +0 -1
- package/web/.next/static/css/d42799b7e6a0e8a2.css +0 -1
- /package/web/.next/static/{aSYzbHk1M5YeS_d3SQKTZ → UDA414PFPu9ZROltNmjbX}/_ssgManifest.js +0 -0
|
@@ -5,6 +5,7 @@ export const CHANNELS_SKILL_ID = 'default-channels';
|
|
|
5
5
|
export const WAKEUPS_SKILL_ID = 'default-wakeups';
|
|
6
6
|
/** Running the servers and containers of the colony. Its tools (`object_list`, `object_action`, `object_logs`) exist only for agents that have this skill. */
|
|
7
7
|
export const OBJECTS_SKILL_ID = 'default-objects';
|
|
8
|
+
export const DATABASES_SKILL_ID = 'default-databases';
|
|
8
9
|
/**
|
|
9
10
|
* How to react to messages in a chat. It is part of the "Chat channels" skill; agents that already had that skill get it added once
|
|
10
11
|
* (see `migrateChannelSkill`). Telegram's list is the one in `connections/telegram.ts` (`TELEGRAM_REACTIONS`): keep them in step.
|
|
@@ -150,7 +151,40 @@ The resources of your own colony, or the ones that belong to no colony if you ar
|
|
|
150
151
|
## Care
|
|
151
152
|
- Stopping or restarting a server or a container interrupts whoever is using it. If the person did not ask for it and the resource is running fine, ask first.
|
|
152
153
|
- Logs can contain secrets (tokens, passwords, connection strings). Never repeat them in a chat; replace them with \`***\`.
|
|
153
|
-
- Do not run the resource's command yourself from a terminal as a way around \`object_action\`: use the tool, so hive-am knows what is running
|
|
154
|
+
- Do not run the resource's command yourself from a terminal as a way around \`object_action\`: use the tool, so hive-am knows what is running.
|
|
155
|
+
|
|
156
|
+
## Databases
|
|
157
|
+
A **database** resource is not started or stopped: it is used. \`object_list\` shows its state, but to look inside it or run SQL you need the "Database management" skill.`,
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
slug: 'databases',
|
|
161
|
+
load: 'always',
|
|
162
|
+
name: 'Database management',
|
|
163
|
+
description: 'Look inside the database resources of the colony and use them: structure, queries, writes, saved queries, history, and (with Full access) their connection.',
|
|
164
|
+
content: `The colony you belong to can have **database resources** (MySQL or MariaDB, PostgreSQL, SQL Server, SQLite). You can look at their structure, run SQL, keep saved queries and, with Full access, change how they connect. hive-am opens a connection when you ask something and closes it right after.
|
|
165
|
+
|
|
166
|
+
## Which databases are yours
|
|
167
|
+
The ones of your own colony, or the ones that belong to no colony if you are in none, unless a person chose one agent to look after a database (then only that agent). Another colony's databases are not visible to you. Use the exact name that \`object_db_list\` shows. \`object_db_list\` answers even when you do not have the Colony resources skill.
|
|
168
|
+
|
|
169
|
+
## How to work
|
|
170
|
+
1. **Look before you run.** \`object_db_list\`, then \`object_db_schema\` (databases, tables and views), \`object_db_columns\` and \`object_db_describe\` (keys, indexes, foreign keys, row count), \`object_db_search\` (find a table or column by name), \`object_db_ddl\` (the CREATE statement) and \`object_db_sample\` (the first rows without writing SQL). \`object_db_explain\` shows the plan of a statement without running it.
|
|
171
|
+
2. **Run SQL** with \`object_db_query\` (one statement: a read, a write or a DDL) or \`object_db_exec\` (several statements in ONE transaction: all are applied or none; MySQL commits by itself on a CREATE, ALTER or DROP, so those cannot be undone there). Another database of the same server: pass \`database\`.
|
|
172
|
+
3. **Keep what is useful**: \`object_db_saved\` (list, add, update, remove named queries) and \`object_db_history\` (the last 200 queries, including the ones people ran). \`object_db_export\` writes a result as CSV or JSON to a file inside your own working folder (it never overwrites unless you say so).
|
|
173
|
+
4. **A result is cut at the resource's row limit and a query at its time limit**: ask for fewer rows or columns instead of working around it. Never \`SELECT *\` from a big table without a \`LIMIT\` or a \`WHERE\`: it fills your context.
|
|
174
|
+
|
|
175
|
+
## What you may do
|
|
176
|
+
Your permission decides it (the \`readOnly\` setting of the resource is for people using its panel and does not apply to you):
|
|
177
|
+
- **Read-only (plan)**: everything that looks and reads. The connection is read-only and only SELECT, WITH, SHOW, DESCRIBE and EXPLAIN pass.
|
|
178
|
+
- **Edit files (acceptEdits)**: also INSERT, UPDATE, DELETE, CREATE and ALTER, scripts, saved queries, clearing the history, exports and \`object_db_sessions\`. **DROP and TRUNCATE are refused**, also inside a script (nothing of it runs).
|
|
179
|
+
- **Full access (bypassPermissions)**: also DROP and TRUNCATE, \`object_db_config_set\` (host, port, user, password, database, SSL, driver properties, limits, name, colony, manager), \`object_db_create\`, \`object_db_delete\` and \`object_db_kill\`.
|
|
180
|
+
|
|
181
|
+
## Care
|
|
182
|
+
- **Writes and DDL are real and irreversible.** Think first: say what you are going to change and on which database, prefer a transaction (\`object_db_exec\`), try a \`SELECT\` with the same \`WHERE\` before an UPDATE or DELETE, and suggest a backup before anything that cannot be undone. A DELETE or UPDATE without a WHERE is the commonest mistake.
|
|
183
|
+
- hive-am refuses DROP and TRUNCATE without Full access, but that is a guardrail, not a sandbox: it does not see a DELETE without a WHERE, a CALL, a PostgreSQL DO block or a stored procedure. The real boundary is what the database user is allowed to do: recommend a user with limited grants.
|
|
184
|
+
- **Results can contain secrets** (password hashes, tokens, personal data). Never repeat them in a chat; replace them with \`***\`.
|
|
185
|
+
- **Passwords are write-only.** You can set or replace one with \`object_db_create\` or \`object_db_config_set\`, but no tool will ever show you a stored one (\`object_db_config\` only says whether one is set). Never repeat a password, write it in a file, a note or a chat, or put it in a query that is not needed. If a person types one in a chat, use it once in the tool without echoing it, and prefer asking them to type it in the resource's panel. When you write SQL that sets a password (\`CREATE USER … IDENTIFIED BY\`), hive-am replaces the literal with \`***\` in the history and the logs.
|
|
186
|
+
- Changing a connection (\`object_db_config_set\`) points hive-am at that server with those credentials. Do it only when asked.
|
|
187
|
+
- \`object_db_kill\` cancels what another session is running: look at \`object_db_sessions\` first and do it only when asked.`,
|
|
154
188
|
},
|
|
155
189
|
{
|
|
156
190
|
slug: 'git-workflow',
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
1
2
|
import { db } from '../db.js';
|
|
2
3
|
import { DomainError } from '../errors.js';
|
|
3
4
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* A notebook: Markdown an agent keeps for itself across conversations (see the «Notebook» default skill). It is an object of its own with
|
|
6
|
+
* readers (`notebooks` and `notebook_readers`, created by db/migrations.ts): an agent and the clones made from it read and write the same one, and
|
|
7
|
+
* it goes away only with its last reader. It lives in its own table so it never travels with the agent list. Every change bumps `version`;
|
|
8
|
+
* `seen` belongs to the reader: it is the version that agent's live conversation already contains, so the runtime knows when the text must be
|
|
9
|
+
* re-sent to it (e.g. after the user, or another agent that shares the notebook, changed it).
|
|
7
10
|
*/
|
|
8
|
-
// The table (agent_notebooks) is created by db/migrations.ts.
|
|
9
11
|
/** It is prompt overhead on every turn, so it has a hard cap. */
|
|
10
12
|
export const NOTEBOOK_MAX = 8000;
|
|
11
13
|
const NOTE_MAX = 500;
|
|
@@ -37,19 +39,61 @@ const refuseSecret = (text) => {
|
|
|
37
39
|
throw new NotebookError(`That looks like ${what}. Credentials are never stored in the notebook: leave it out (or describe where it lives, not its value).`);
|
|
38
40
|
};
|
|
39
41
|
const empty = () => ({ content: '', version: 0, seen: 0, updated_at: 0, updated_by: '' });
|
|
42
|
+
/** The notebook an agent reads, with that agent's own `seen`. */
|
|
43
|
+
const readerRow = (agentId) => db.prepare(`SELECT n.id, n.content, n.version, r.seen, n.updated_at, n.updated_by FROM notebook_readers r JOIN notebooks n ON n.id = r.notebook_id WHERE r.agent_id = ?`).get(agentId);
|
|
44
|
+
/** The notebook the agent reads, created empty (version 0) when it has none yet. */
|
|
45
|
+
function ensure(agentId) {
|
|
46
|
+
let row = readerRow(agentId);
|
|
47
|
+
if (!row) {
|
|
48
|
+
const id = randomUUID();
|
|
49
|
+
db.prepare('INSERT INTO notebooks (id) VALUES (?)').run(id);
|
|
50
|
+
db.prepare('INSERT INTO notebook_readers (agent_id, notebook_id, seen) VALUES (?,?,0)').run(agentId, id);
|
|
51
|
+
row = readerRow(agentId);
|
|
52
|
+
}
|
|
53
|
+
return row;
|
|
54
|
+
}
|
|
40
55
|
export const notebooks = {
|
|
41
|
-
get: (agentId) =>
|
|
56
|
+
get: (agentId) => { const r = readerRow(agentId); return r ? { content: r.content, version: r.version, seen: r.seen, updated_at: r.updated_at, updated_by: r.updated_by } : empty(); },
|
|
57
|
+
/** The other agents that read the same notebook (empty for an ordinary notebook). */
|
|
58
|
+
sharedWith(agentId) {
|
|
59
|
+
const r = readerRow(agentId);
|
|
60
|
+
if (!r)
|
|
61
|
+
return [];
|
|
62
|
+
return db.prepare('SELECT a.id, a.name FROM notebook_readers x JOIN agents a ON a.id = x.agent_id WHERE x.notebook_id = ? AND x.agent_id <> ? ORDER BY a.name').all(r.id, agentId);
|
|
63
|
+
},
|
|
42
64
|
/** The agent (or the user) replaced the text. `live`: the change happened inside the conversation the agent is running now. */
|
|
43
|
-
save(agentId, content, by, live) {
|
|
44
|
-
const
|
|
45
|
-
const
|
|
46
|
-
db.prepare(
|
|
47
|
-
|
|
48
|
-
|
|
65
|
+
save: db.transaction((agentId, content, by, live) => {
|
|
66
|
+
const row = ensure(agentId); // an agent that never had one gets its own
|
|
67
|
+
const version = row.version + 1;
|
|
68
|
+
db.prepare('UPDATE notebooks SET content=?, version=?, updated_at=?, updated_by=? WHERE id=?').run(content, version, Date.now(), by, row.id);
|
|
69
|
+
// Only the writer's own conversation already contains what it just wrote; the other readers are sent it on their next turn.
|
|
70
|
+
if (live)
|
|
71
|
+
db.prepare('UPDATE notebook_readers SET seen=? WHERE agent_id=?').run(version, agentId);
|
|
49
72
|
return notebooks.get(agentId);
|
|
50
|
-
},
|
|
73
|
+
}),
|
|
51
74
|
/** The runtime sent version `v` to the agent's conversation. */
|
|
52
|
-
markSeen: (agentId, v) => { db.prepare('UPDATE
|
|
75
|
+
markSeen: (agentId, v) => { db.prepare('UPDATE notebook_readers SET seen=MAX(seen, ?) WHERE agent_id=?').run(v, agentId); },
|
|
76
|
+
/**
|
|
77
|
+
* `to` starts reading the notebook of `from` (a clone sharing its source's notes): `from` gets one if it had none, and what `to` read before
|
|
78
|
+
* is dropped with its last reader. Its `seen` starts at 0, so its first turn is sent the text.
|
|
79
|
+
*/
|
|
80
|
+
share: db.transaction((fromId, toId) => {
|
|
81
|
+
if (fromId === toId)
|
|
82
|
+
return;
|
|
83
|
+
const nb = ensure(fromId);
|
|
84
|
+
db.prepare('INSERT INTO notebook_readers (agent_id, notebook_id, seen) VALUES (?,?,0) ON CONFLICT(agent_id) DO UPDATE SET notebook_id=excluded.notebook_id, seen=0').run(toId, nb.id);
|
|
85
|
+
db.prepare('DELETE FROM notebooks WHERE id NOT IN (SELECT notebook_id FROM notebook_readers)').run(); // what `to` read before, if nobody else does
|
|
86
|
+
}),
|
|
87
|
+
/** Gives the agent its own copy of the notebook it shares, and leaves the shared one with the others. Does nothing for an agent that shares nothing. */
|
|
88
|
+
separate: db.transaction((agentId) => {
|
|
89
|
+
const row = readerRow(agentId);
|
|
90
|
+
if (!row || !notebooks.sharedWith(agentId).length)
|
|
91
|
+
return notebooks.get(agentId);
|
|
92
|
+
const id = randomUUID();
|
|
93
|
+
db.prepare('INSERT INTO notebooks (id, content, version, updated_at, updated_by) VALUES (?,?,?,?,?)').run(id, row.content, row.version, row.updated_at, row.updated_by);
|
|
94
|
+
db.prepare('UPDATE notebook_readers SET notebook_id=? WHERE agent_id=?').run(id, agentId); // `seen` stays: it still describes what this agent's conversation holds
|
|
95
|
+
return notebooks.get(agentId);
|
|
96
|
+
}),
|
|
53
97
|
/** Edit from the UI. `version` (when given) must be the one the user was looking at. */
|
|
54
98
|
edit(agentId, content, version) {
|
|
55
99
|
const text = content.replace(/\r\n/g, '\n').trimEnd();
|
package/server/mcp/dispatch.mjs
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
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)
|
|
7
|
+
// databases → object_db_* (agents with the Database management skill: the database resources of their colony)
|
|
7
8
|
// It only talks to the hive-am HTTP API; all rules (assignments, queueing) live there.
|
|
8
9
|
import { createInterface } from 'node:readline';
|
|
9
10
|
|
|
@@ -218,8 +219,68 @@ const allTools = [
|
|
|
218
219
|
inputSchema: { type: 'object', properties: { id: { type: 'string', description: 'The schedule id.' } }, required: ['id'], additionalProperties: false },
|
|
219
220
|
},
|
|
220
221
|
];
|
|
222
|
+
|
|
223
|
+
// ---- Database management (cap `databases`): one tool per operation, all answered by POST /api/agent-objects/db/<op> ----
|
|
224
|
+
const NAME = { type: 'string', description: 'The exact name of the database resource, as object_db_list shows it.' };
|
|
225
|
+
const DB = { type: 'string', description: 'Another database of the same server to use instead of the one the resource opens by default (see object_db_schema).' };
|
|
226
|
+
const SCHEMA = { type: 'string', description: 'The schema (PostgreSQL, SQL Server), the database (MySQL) or "main" (SQLite), as object_db_schema shows it.' };
|
|
227
|
+
const TABLE = { type: 'string', description: 'The table or view name.' };
|
|
228
|
+
const dbTool = (name, description, properties = {}, required = []) => ({ cap: 'databases', name: `object_db_${name}`, description, inputSchema: { type: 'object', properties, required, additionalProperties: false } });
|
|
229
|
+
const dbTools = [
|
|
230
|
+
dbTool('list', 'List the database resources you look after: name, engine, database and state. Use these exact names in the other object_db tools.'),
|
|
231
|
+
dbTool('schema', 'The structure of a database: the databases of the server, the current one and its tables and views (with a row estimate). Start here.', { name: NAME, database: DB }, ['name']),
|
|
232
|
+
dbTool('columns', 'The columns of a table or view: name, type, nullable, key and default.', { name: NAME, schema: SCHEMA, table: TABLE, database: DB }, ['name', 'schema', 'table']),
|
|
233
|
+
dbTool('describe', 'A table in full: columns, primary key, indexes, foreign keys and the number of rows.', { name: NAME, schema: SCHEMA, table: TABLE, database: DB }, ['name', 'schema', 'table']),
|
|
234
|
+
dbTool('search', 'Find tables, views and columns whose name contains some text, across everything the connection can see.', { name: NAME, query: { type: 'string', description: 'Part of a name.' }, database: DB }, ['name', 'query']),
|
|
235
|
+
dbTool('ddl', 'The CREATE statement of a table (with its indexes).', { name: NAME, schema: SCHEMA, table: TABLE, database: DB }, ['name', 'schema', 'table']),
|
|
236
|
+
dbTool('sample', 'The first rows of a table or view, without writing SQL.', { name: NAME, schema: SCHEMA, table: TABLE, limit: { type: 'number', description: 'How many rows (default 10).' }, database: DB }, ['name', 'schema', 'table']),
|
|
237
|
+
dbTool('query', 'Run ONE SQL statement: a read, or (not in read-only mode) a write or DDL. DROP and TRUNCATE need Full access. A result is cut at the resource\'s row limit and a query at its time limit. Writes are real and cannot be undone: say what you are about to change first. Results can contain secrets: never repeat them in a chat.', { name: NAME, sql: { type: 'string', description: 'One SQL statement.' }, database: DB }, ['name', 'sql']),
|
|
238
|
+
dbTool('exec', 'Run several SQL statements as ONE transaction: all are applied or none (a failure says which statement it was). Not in read-only mode; DROP and TRUNCATE need Full access and one of them refuses the whole script. MySQL commits by itself on CREATE, ALTER and DROP, so a DDL in the middle cannot be undone there.', { name: NAME, sql: { type: 'string', description: 'Statements separated by ;' }, database: DB }, ['name', 'sql']),
|
|
239
|
+
dbTool('explain', 'The execution plan of a statement, without running it.', { name: NAME, sql: { type: 'string', description: 'One SQL statement.' }, database: DB }, ['name', 'sql']),
|
|
240
|
+
dbTool('export', 'Write the result of a query to a CSV or JSON file inside your own working folder. It never writes outside it and never overwrites a file unless overwrite is true. Not in read-only mode.', { name: NAME, sql: { type: 'string', description: 'The query.' }, format: { type: 'string', enum: ['csv', 'json'] }, file: { type: 'string', description: 'The file, relative to your working folder.' }, overwrite: { type: 'boolean' }, database: DB }, ['name', 'sql', 'format', 'file']),
|
|
241
|
+
dbTool('saved', 'The named queries saved on a resource: list them, or add, update or remove one (not in read-only mode). A password in the text is replaced by ***.', { name: NAME, op: { type: 'string', enum: ['list', 'add', 'update', 'remove'] }, id: { type: 'string', description: 'The id of the saved query (update, remove).' }, query_name: { type: 'string', description: 'Its name (add, update).' }, sql: { type: 'string', description: 'Its text (add, update).' }, database: DB }, ['name', 'op']),
|
|
242
|
+
dbTool('history', 'The last 200 queries run on a resource (by people and by agents), or clear them (not in read-only mode).', { name: NAME, op: { type: 'string', enum: ['list', 'clear'] } }, ['name', 'op']),
|
|
243
|
+
dbTool('sessions', 'Who is connected to the server and what they are running (MySQL, PostgreSQL, SQL Server). Not in read-only mode.', { name: NAME }, ['name']),
|
|
244
|
+
dbTool('kill', 'Cancel what a session is running (MySQL, PostgreSQL) or end the session (SQL Server). Full access only. It can interrupt other people: look at object_db_sessions first and do it only when asked.', { name: NAME, id: { type: 'number', description: 'The session id from object_db_sessions.' } }, ['name', 'id']),
|
|
245
|
+
dbTool('config', 'How a resource connects: engine, host, port, user, database, SSL, driver properties and limits. The password is never shown: passwordSet says whether one exists.', { name: NAME }, ['name']),
|
|
246
|
+
dbTool('config_set', 'Change how a resource connects (Full access only). Give only the fields to change inside config; the engine cannot change. The new connection is tested first and nothing is saved if it fails. A password you give is stored and never shown again: do not repeat it anywhere. Can also rename it, move it to your colony or out of any, and choose the agent that looks after it.', { name: NAME, config: { type: 'object', description: 'Fields to change: host, port, user, password, database, file (SQLite), ssl, trustCert, props, readOnly, timeoutSec, maxRows.' }, new_name: { type: 'string' }, colony_id: { type: 'string', description: '"mine" (your colony) or "none".' }, manager_id: { type: 'string', description: 'An agent name or id, "me", or "none" to leave it to the colony.' } }, ['name']),
|
|
247
|
+
dbTool('test', 'Test a connection: a saved resource by name, or (Full access) a configuration that is not saved yet.', { name: { type: 'string', description: 'A saved resource to test.' }, config: { type: 'object', description: 'A draft configuration to test instead (Full access).' } }),
|
|
248
|
+
dbTool('create', 'Create a database resource (Full access only). The connection is tested first and nothing is created if it fails. It is created in your colony (or none) and you become the agent that looks after it. A password in config is stored and never shown again: do not repeat it anywhere.', { name: { type: 'string', description: 'The name of the new resource.' }, config: { type: 'object', description: 'engine (mysql, postgresql, sqlite, mssql) and host, port, user, password, database (or file for SQLite), ssl, trustCert, props, readOnly, timeoutSec, maxRows.' }, colony_id: { type: 'string', description: '"mine" (default) or "none".' } }, ['name', 'config']),
|
|
249
|
+
dbTool('delete', 'Delete a database resource (Full access only). The database itself is not touched: only hive-am forgets the connection, its saved queries and its history.', { name: NAME }, ['name']),
|
|
250
|
+
];
|
|
251
|
+
allTools.push(...dbTools);
|
|
221
252
|
const tools = allTools.filter((t) => CAPS.has(t.cap)).map(({ cap, ...t }) => t);
|
|
222
253
|
|
|
254
|
+
// ---- how a database answer is written for the model ----
|
|
255
|
+
const cellText = (v) => (v === null || v === undefined ? 'NULL' : String(v).replace(/\r?\n/g, '\\n'));
|
|
256
|
+
const table = (columns, rows) => [columns.map((c) => c.name ?? c).join('\t'), ...rows.map((r) => r.map(cellText).join('\t'))].join('\n');
|
|
257
|
+
const resultText = (r) => {
|
|
258
|
+
if (!r.columns?.length) return r.affected !== undefined ? `OK, ${r.affected} row${r.affected === 1 ? '' : 's'} affected (${r.ms ?? 0} ms).` : `OK (${r.ms ?? 0} ms).`;
|
|
259
|
+
return `${table(r.columns, r.rows)}\n${r.rows.length} row${r.rows.length === 1 ? '' : 's'}${r.truncated ? ' (cut at the resource\'s row limit: ask for fewer rows or columns)' : ''} in ${r.ms ?? 0} ms.`;
|
|
260
|
+
};
|
|
261
|
+
const dbAnswer = (op, j) => {
|
|
262
|
+
switch (op) {
|
|
263
|
+
case 'list': return j.databases.length ? j.databases.map((d) => `${d.name} · ${d.engine}${d.database ? ` · ${d.database}` : ''} · ${d.status}${d.detail ? ` (${d.detail})` : ''}`).join('\n') : 'You look after no database resources.';
|
|
264
|
+
case 'schema': return `${j.engine}, database ${j.database || '(none)'}${j.databases.length ? `. Databases on the server: ${j.databases.join(', ')}` : ''}.\n${j.tables.length ? j.tables.map((t) => `${t.schema}.${t.name} (${t.type}${t.rows !== undefined ? `, ~${t.rows} rows` : ''})`).join('\n') : 'No tables.'}`;
|
|
265
|
+
case 'columns': return j.columns.length ? j.columns.map((c) => `${c.name} ${c.type}${c.nullable ? '' : ' NOT NULL'}${c.key ? ` ${c.key}` : ''}${c.default !== undefined && c.default !== null ? ` DEFAULT ${c.default}` : ''}`).join('\n') : 'No columns: that table does not exist.';
|
|
266
|
+
case 'describe': return [`${j.schema}.${j.table}: ${j.rowCount ?? '?'} rows`, 'Columns:', ...j.columns.map((c) => ` ${c.name} ${c.type}${c.nullable ? '' : ' NOT NULL'}${c.key ? ` ${c.key}` : ''}`), `Primary key: ${j.primaryKey.join(', ') || '(none)'}`, 'Indexes:', ...(j.indexes.length ? j.indexes.map((i) => ` ${i.name}${i.unique ? ' UNIQUE' : ''} (${i.columns.join(', ')})`) : [' (none)']), 'Foreign keys:', ...(j.foreignKeys.length ? j.foreignKeys.map((f) => ` ${f.name}: (${f.columns.join(', ')}) -> ${f.refSchema ? `${f.refSchema}.` : ''}${f.refTable} (${f.refColumns.join(', ')})`) : [' (none)'])].join('\n');
|
|
267
|
+
case 'search': return j.matches.length ? j.matches.map((m) => (m.column ? `${m.schema}.${m.table}.${m.column} (column)` : `${m.schema}.${m.table} (${m.type})`)).join('\n') : 'Nothing matches.';
|
|
268
|
+
case 'ddl': return j.ddl;
|
|
269
|
+
case 'sample': case 'query': case 'explain': case 'sessions': return resultText(j);
|
|
270
|
+
case 'exec': return `${j.results.length} statement${j.results.length === 1 ? '' : 's'} applied in one transaction (${j.ms} ms).\n${j.results.map((r, n) => `${n + 1}. ${r.statement.replace(/\s+/g, ' ').slice(0, 80)}\n ${resultText(r).split('\n').join('\n ')}`).join('\n')}`;
|
|
271
|
+
case 'export': return `Wrote ${j.rows} row${j.rows === 1 ? '' : 's'} as ${j.format} to ${j.file} (${j.bytes} bytes)${j.truncated ? ', cut at the resource\'s row limit' : ''}.`;
|
|
272
|
+
case 'saved': return j.saved === undefined ? 'Done.' : Array.isArray(j.saved) ? (j.saved.length ? j.saved.map((q) => `${q.id} · ${q.name}${q.database ? ` (${q.database})` : ''}\n${q.sql}`).join('\n\n') : 'No saved queries.') : `Saved: ${j.saved.id} · ${j.saved.name}`;
|
|
273
|
+
case 'history': return j.cleared ? 'History cleared.' : j.history.length ? j.history.map((h) => `${new Date(h.at).toISOString().slice(0, 19)} ${h.ok ? 'ok' : 'FAILED'}${h.by ? ` (${h.by})` : ''} ${h.sql.replace(/\s+/g, ' ').slice(0, 160)}${h.error ? ` -> ${h.error}` : ''}`).join('\n') : 'No history.';
|
|
274
|
+
case 'kill': return j.text;
|
|
275
|
+
case 'config': return JSON.stringify({ name: j.name, ...j.config }, null, 2);
|
|
276
|
+
case 'test': return `Connection works: ${j.version} (${j.ms} ms).`;
|
|
277
|
+
case 'create': return `Created the database resource "${j.name}" (${j.engine}). You look after it now.`;
|
|
278
|
+
case 'config_set': return `Saved the connection of "${j.name}" after testing it.`;
|
|
279
|
+
case 'delete': return `Deleted the database resource "${j.deleted}".`;
|
|
280
|
+
default: return JSON.stringify(j);
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
|
|
223
284
|
async function call(name, args) {
|
|
224
285
|
if (!tools.some((t) => t.name === name)) throw new Error(`Unknown tool ${name}`);
|
|
225
286
|
if (name === 'list_agents') {
|
|
@@ -293,6 +354,13 @@ async function call(name, args) {
|
|
|
293
354
|
if (!r.ok) throw new Error(j.error ?? `channel_mute failed (${r.status})`);
|
|
294
355
|
return j.muted ? `Muted in this thread (${j.place}). You will only be woken when someone mentions you or replies to you.` : `Unmuted in this thread (${j.place}).`;
|
|
295
356
|
}
|
|
357
|
+
if (name.startsWith('object_db_')) {
|
|
358
|
+
const op = name.slice('object_db_'.length);
|
|
359
|
+
const r = await fetch(`${API}/api/agent-objects/db/${op}`, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ from: FROM, ...args }) });
|
|
360
|
+
const j = await r.json();
|
|
361
|
+
if (!r.ok) throw new Error(j.error ?? `${name} failed (${r.status})`);
|
|
362
|
+
return dbAnswer(op, j);
|
|
363
|
+
}
|
|
296
364
|
if (name === 'object_list' || name === 'object_logs' || name === 'object_action') {
|
|
297
365
|
const r = await fetch(`${API}/api/agent-objects/${name.slice('object_'.length)}`, {
|
|
298
366
|
method: 'POST', headers: { 'content-type': 'application/json' },
|
package/web/.next/BUILD_ID
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
UDA414PFPu9ZROltNmjbX
|
|
@@ -13,10 +13,21 @@
|
|
|
13
13
|
"static/chunks/89-b194fcffe5120c44.js",
|
|
14
14
|
"static/chunks/main-app-6086068e5fb5eacd.js",
|
|
15
15
|
"static/css/945795da867f5250.css",
|
|
16
|
-
"static/css/
|
|
16
|
+
"static/css/dfcaa19a8d46e60d.css",
|
|
17
17
|
"static/chunks/586-f7017d585a84738d.js",
|
|
18
|
-
"static/chunks/281-
|
|
19
|
-
"static/chunks/app/layout-
|
|
18
|
+
"static/chunks/281-30e32d932b8b5a75.js",
|
|
19
|
+
"static/chunks/app/layout-fad968a635f9a4b3.js"
|
|
20
|
+
],
|
|
21
|
+
"/chat/page": [
|
|
22
|
+
"static/chunks/webpack-ef515e41a83a16ac.js",
|
|
23
|
+
"static/chunks/0937d497-114a2a3de515565e.js",
|
|
24
|
+
"static/chunks/89-b194fcffe5120c44.js",
|
|
25
|
+
"static/chunks/main-app-6086068e5fb5eacd.js",
|
|
26
|
+
"static/chunks/586-f7017d585a84738d.js",
|
|
27
|
+
"static/chunks/706-fa2be0f10ffebe6a.js",
|
|
28
|
+
"static/chunks/281-30e32d932b8b5a75.js",
|
|
29
|
+
"static/chunks/517-b3b1c9044d2ef23c.js",
|
|
30
|
+
"static/chunks/app/chat/page-383bc24e72dab7fa.js"
|
|
20
31
|
],
|
|
21
32
|
"/connections/page": [
|
|
22
33
|
"static/chunks/webpack-ef515e41a83a16ac.js",
|
|
@@ -24,21 +35,22 @@
|
|
|
24
35
|
"static/chunks/89-b194fcffe5120c44.js",
|
|
25
36
|
"static/chunks/main-app-6086068e5fb5eacd.js",
|
|
26
37
|
"static/chunks/586-f7017d585a84738d.js",
|
|
27
|
-
"static/chunks/281-
|
|
28
|
-
"static/chunks/app/connections/page-
|
|
38
|
+
"static/chunks/281-30e32d932b8b5a75.js",
|
|
39
|
+
"static/chunks/app/connections/page-06bd2d7d9495126a.js"
|
|
29
40
|
],
|
|
30
|
-
"/
|
|
41
|
+
"/relations/page": [
|
|
31
42
|
"static/chunks/webpack-ef515e41a83a16ac.js",
|
|
32
43
|
"static/chunks/0937d497-114a2a3de515565e.js",
|
|
33
44
|
"static/chunks/89-b194fcffe5120c44.js",
|
|
34
45
|
"static/chunks/main-app-6086068e5fb5eacd.js",
|
|
46
|
+
"static/css/c4a545148b5320ec.css",
|
|
47
|
+
"static/chunks/2b9ff8ee-969e65cc354b2150.js",
|
|
35
48
|
"static/chunks/586-f7017d585a84738d.js",
|
|
36
|
-
"static/chunks/
|
|
37
|
-
"static/chunks/281-
|
|
38
|
-
"static/chunks/
|
|
39
|
-
"static/chunks/app/agents/page-9bb8cba69776c719.js"
|
|
49
|
+
"static/chunks/757-03361e7a97a605a2.js",
|
|
50
|
+
"static/chunks/281-30e32d932b8b5a75.js",
|
|
51
|
+
"static/chunks/app/relations/page-02710fe1f8a670a9.js"
|
|
40
52
|
],
|
|
41
|
-
"/resources/page": [
|
|
53
|
+
"/resources/[id]/page": [
|
|
42
54
|
"static/chunks/webpack-ef515e41a83a16ac.js",
|
|
43
55
|
"static/chunks/0937d497-114a2a3de515565e.js",
|
|
44
56
|
"static/chunks/89-b194fcffe5120c44.js",
|
|
@@ -46,18 +58,17 @@
|
|
|
46
58
|
"static/chunks/586-f7017d585a84738d.js",
|
|
47
59
|
"static/chunks/706-fa2be0f10ffebe6a.js",
|
|
48
60
|
"static/chunks/837-33c7480524f48577.js",
|
|
49
|
-
"static/chunks/
|
|
50
|
-
"static/chunks/
|
|
51
|
-
"static/chunks/
|
|
52
|
-
"static/chunks/517-373a80c8ba432bdc.js",
|
|
61
|
+
"static/chunks/391-18768499e741112e.js",
|
|
62
|
+
"static/chunks/281-30e32d932b8b5a75.js",
|
|
63
|
+
"static/chunks/517-b3b1c9044d2ef23c.js",
|
|
53
64
|
"static/chunks/350-0fe82e622e7a670f.js",
|
|
54
|
-
"static/chunks/
|
|
55
|
-
"static/chunks/
|
|
65
|
+
"static/chunks/606-14fb5aaa4d0ff22d.js",
|
|
66
|
+
"static/chunks/587-5b511f5f93910180.js",
|
|
56
67
|
"static/chunks/30-9adcbe92b15a6815.js",
|
|
57
|
-
"static/chunks/
|
|
58
|
-
"static/chunks/app/resources/page-
|
|
68
|
+
"static/chunks/656-f3cc78328603241a.js",
|
|
69
|
+
"static/chunks/app/resources/[id]/page-fc494e85b01e8cb7.js"
|
|
59
70
|
],
|
|
60
|
-
"/
|
|
71
|
+
"/agents/[id]/page": [
|
|
61
72
|
"static/chunks/webpack-ef515e41a83a16ac.js",
|
|
62
73
|
"static/chunks/0937d497-114a2a3de515565e.js",
|
|
63
74
|
"static/chunks/89-b194fcffe5120c44.js",
|
|
@@ -65,104 +76,102 @@
|
|
|
65
76
|
"static/chunks/586-f7017d585a84738d.js",
|
|
66
77
|
"static/chunks/706-fa2be0f10ffebe6a.js",
|
|
67
78
|
"static/chunks/837-33c7480524f48577.js",
|
|
68
|
-
"static/chunks/
|
|
69
|
-
"static/chunks/
|
|
70
|
-
"static/chunks/281-
|
|
71
|
-
"static/chunks/517-
|
|
79
|
+
"static/chunks/391-18768499e741112e.js",
|
|
80
|
+
"static/chunks/107-77dd87cc2ca4f941.js",
|
|
81
|
+
"static/chunks/281-30e32d932b8b5a75.js",
|
|
82
|
+
"static/chunks/517-b3b1c9044d2ef23c.js",
|
|
72
83
|
"static/chunks/350-0fe82e622e7a670f.js",
|
|
73
|
-
"static/chunks/
|
|
74
|
-
"static/chunks/844-519177e6198ca84f.js",
|
|
84
|
+
"static/chunks/606-14fb5aaa4d0ff22d.js",
|
|
75
85
|
"static/chunks/30-9adcbe92b15a6815.js",
|
|
76
|
-
"static/chunks/
|
|
77
|
-
"static/chunks/app/
|
|
86
|
+
"static/chunks/705-ce86175dea00e6a9.js",
|
|
87
|
+
"static/chunks/app/agents/[id]/page-638e12ba3cb813c3.js"
|
|
78
88
|
],
|
|
79
|
-
"/
|
|
89
|
+
"/resources/page": [
|
|
80
90
|
"static/chunks/webpack-ef515e41a83a16ac.js",
|
|
81
91
|
"static/chunks/0937d497-114a2a3de515565e.js",
|
|
82
92
|
"static/chunks/89-b194fcffe5120c44.js",
|
|
83
93
|
"static/chunks/main-app-6086068e5fb5eacd.js",
|
|
84
94
|
"static/chunks/586-f7017d585a84738d.js",
|
|
85
|
-
"static/chunks/
|
|
86
|
-
"static/chunks/
|
|
95
|
+
"static/chunks/706-fa2be0f10ffebe6a.js",
|
|
96
|
+
"static/chunks/837-33c7480524f48577.js",
|
|
97
|
+
"static/chunks/391-18768499e741112e.js",
|
|
98
|
+
"static/chunks/281-30e32d932b8b5a75.js",
|
|
99
|
+
"static/chunks/517-b3b1c9044d2ef23c.js",
|
|
100
|
+
"static/chunks/350-0fe82e622e7a670f.js",
|
|
101
|
+
"static/chunks/606-14fb5aaa4d0ff22d.js",
|
|
102
|
+
"static/chunks/587-5b511f5f93910180.js",
|
|
103
|
+
"static/chunks/30-9adcbe92b15a6815.js",
|
|
104
|
+
"static/chunks/656-f3cc78328603241a.js",
|
|
105
|
+
"static/chunks/app/resources/page-61cccd8fdcc2f6c8.js"
|
|
87
106
|
],
|
|
88
|
-
"/
|
|
107
|
+
"/page": [
|
|
89
108
|
"static/chunks/webpack-ef515e41a83a16ac.js",
|
|
90
109
|
"static/chunks/0937d497-114a2a3de515565e.js",
|
|
91
110
|
"static/chunks/89-b194fcffe5120c44.js",
|
|
92
111
|
"static/chunks/main-app-6086068e5fb5eacd.js",
|
|
93
112
|
"static/chunks/586-f7017d585a84738d.js",
|
|
94
113
|
"static/chunks/706-fa2be0f10ffebe6a.js",
|
|
95
|
-
"static/chunks/
|
|
96
|
-
"static/chunks/
|
|
114
|
+
"static/chunks/391-18768499e741112e.js",
|
|
115
|
+
"static/chunks/281-30e32d932b8b5a75.js",
|
|
116
|
+
"static/chunks/517-b3b1c9044d2ef23c.js",
|
|
117
|
+
"static/chunks/350-0fe82e622e7a670f.js",
|
|
118
|
+
"static/chunks/606-14fb5aaa4d0ff22d.js",
|
|
119
|
+
"static/chunks/587-5b511f5f93910180.js",
|
|
120
|
+
"static/chunks/app/page-0062ebc30322b1ae.js"
|
|
97
121
|
],
|
|
98
|
-
"/
|
|
122
|
+
"/agents/page": [
|
|
99
123
|
"static/chunks/webpack-ef515e41a83a16ac.js",
|
|
100
124
|
"static/chunks/0937d497-114a2a3de515565e.js",
|
|
101
125
|
"static/chunks/89-b194fcffe5120c44.js",
|
|
102
126
|
"static/chunks/main-app-6086068e5fb5eacd.js",
|
|
103
127
|
"static/chunks/586-f7017d585a84738d.js",
|
|
104
128
|
"static/chunks/706-fa2be0f10ffebe6a.js",
|
|
105
|
-
"static/chunks/
|
|
106
|
-
"static/chunks/
|
|
107
|
-
"static/chunks/
|
|
108
|
-
"static/chunks/705-780e48e55b0346bd.js",
|
|
109
|
-
"static/chunks/app/sessions/page-a7534ebd90e982d6.js"
|
|
129
|
+
"static/chunks/281-30e32d932b8b5a75.js",
|
|
130
|
+
"static/chunks/517-b3b1c9044d2ef23c.js",
|
|
131
|
+
"static/chunks/app/agents/page-9da499db6d22731f.js"
|
|
110
132
|
],
|
|
111
|
-
"/
|
|
133
|
+
"/sessions/page": [
|
|
112
134
|
"static/chunks/webpack-ef515e41a83a16ac.js",
|
|
113
135
|
"static/chunks/0937d497-114a2a3de515565e.js",
|
|
114
136
|
"static/chunks/89-b194fcffe5120c44.js",
|
|
115
137
|
"static/chunks/main-app-6086068e5fb5eacd.js",
|
|
116
138
|
"static/chunks/586-f7017d585a84738d.js",
|
|
117
139
|
"static/chunks/706-fa2be0f10ffebe6a.js",
|
|
118
|
-
"static/chunks/
|
|
119
|
-
"static/chunks/
|
|
120
|
-
"static/chunks/
|
|
140
|
+
"static/chunks/654-92a63b3c4b412666.js",
|
|
141
|
+
"static/chunks/281-30e32d932b8b5a75.js",
|
|
142
|
+
"static/chunks/350-0fe82e622e7a670f.js",
|
|
143
|
+
"static/chunks/705-ce86175dea00e6a9.js",
|
|
144
|
+
"static/chunks/app/sessions/page-85638705fdc18174.js"
|
|
121
145
|
],
|
|
122
|
-
"/
|
|
146
|
+
"/schedules/page": [
|
|
123
147
|
"static/chunks/webpack-ef515e41a83a16ac.js",
|
|
124
148
|
"static/chunks/0937d497-114a2a3de515565e.js",
|
|
125
149
|
"static/chunks/89-b194fcffe5120c44.js",
|
|
126
150
|
"static/chunks/main-app-6086068e5fb5eacd.js",
|
|
127
151
|
"static/chunks/586-f7017d585a84738d.js",
|
|
128
|
-
"static/chunks/
|
|
129
|
-
"static/chunks/
|
|
130
|
-
"static/chunks/304-681348099f874a30.js",
|
|
131
|
-
"static/chunks/316-26da9cc233ba7557.js",
|
|
132
|
-
"static/chunks/281-d8a0dcfaa6d064e4.js",
|
|
133
|
-
"static/chunks/517-373a80c8ba432bdc.js",
|
|
134
|
-
"static/chunks/350-0fe82e622e7a670f.js",
|
|
135
|
-
"static/chunks/291-23f314877fa39054.js",
|
|
136
|
-
"static/chunks/30-9adcbe92b15a6815.js",
|
|
137
|
-
"static/chunks/705-780e48e55b0346bd.js",
|
|
138
|
-
"static/chunks/app/agents/[id]/page-c005161cec5527d8.js"
|
|
152
|
+
"static/chunks/281-30e32d932b8b5a75.js",
|
|
153
|
+
"static/chunks/app/schedules/page-96976fff4ee23538.js"
|
|
139
154
|
],
|
|
140
|
-
"/
|
|
155
|
+
"/skills/page": [
|
|
141
156
|
"static/chunks/webpack-ef515e41a83a16ac.js",
|
|
142
157
|
"static/chunks/0937d497-114a2a3de515565e.js",
|
|
143
158
|
"static/chunks/89-b194fcffe5120c44.js",
|
|
144
159
|
"static/chunks/main-app-6086068e5fb5eacd.js",
|
|
145
|
-
"static/css/c4a545148b5320ec.css",
|
|
146
|
-
"static/chunks/2b9ff8ee-969e65cc354b2150.js",
|
|
147
160
|
"static/chunks/586-f7017d585a84738d.js",
|
|
148
|
-
"static/chunks/
|
|
149
|
-
"static/chunks/281-
|
|
150
|
-
"static/chunks/app/
|
|
161
|
+
"static/chunks/706-fa2be0f10ffebe6a.js",
|
|
162
|
+
"static/chunks/281-30e32d932b8b5a75.js",
|
|
163
|
+
"static/chunks/app/skills/page-bc1acd0663f36129.js"
|
|
151
164
|
],
|
|
152
|
-
"/page": [
|
|
165
|
+
"/types/page": [
|
|
153
166
|
"static/chunks/webpack-ef515e41a83a16ac.js",
|
|
154
167
|
"static/chunks/0937d497-114a2a3de515565e.js",
|
|
155
168
|
"static/chunks/89-b194fcffe5120c44.js",
|
|
156
169
|
"static/chunks/main-app-6086068e5fb5eacd.js",
|
|
157
170
|
"static/chunks/586-f7017d585a84738d.js",
|
|
158
171
|
"static/chunks/706-fa2be0f10ffebe6a.js",
|
|
159
|
-
"static/chunks/
|
|
160
|
-
"static/chunks/
|
|
161
|
-
"static/chunks/
|
|
162
|
-
"static/chunks/350-0fe82e622e7a670f.js",
|
|
163
|
-
"static/chunks/291-23f314877fa39054.js",
|
|
164
|
-
"static/chunks/844-519177e6198ca84f.js",
|
|
165
|
-
"static/chunks/app/page-da042d146caeeab6.js"
|
|
172
|
+
"static/chunks/281-30e32d932b8b5a75.js",
|
|
173
|
+
"static/chunks/517-b3b1c9044d2ef23c.js",
|
|
174
|
+
"static/chunks/app/types/page-8e25f503bdcd72ad.js"
|
|
166
175
|
]
|
|
167
176
|
}
|
|
168
177
|
}
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"/_not-found/page": "/_not-found",
|
|
3
|
+
"/favicon.ico/route": "/favicon.ico",
|
|
3
4
|
"/apple-icon.png/route": "/apple-icon.png",
|
|
4
5
|
"/icon.png/route": "/icon.png",
|
|
5
|
-
"/
|
|
6
|
+
"/chat/page": "/chat",
|
|
6
7
|
"/connections/page": "/connections",
|
|
7
|
-
"/
|
|
8
|
-
"/resources/page": "/resources",
|
|
8
|
+
"/relations/page": "/relations",
|
|
9
9
|
"/resources/[id]/page": "/resources/[id]",
|
|
10
|
+
"/agents/[id]/page": "/agents/[id]",
|
|
11
|
+
"/resources/page": "/resources",
|
|
12
|
+
"/page": "/",
|
|
13
|
+
"/agents/page": "/agents",
|
|
14
|
+
"/sessions/page": "/sessions",
|
|
10
15
|
"/schedules/page": "/schedules",
|
|
11
16
|
"/skills/page": "/skills",
|
|
12
|
-
"/
|
|
13
|
-
"/types/page": "/types",
|
|
14
|
-
"/agents/[id]/page": "/agents/[id]",
|
|
15
|
-
"/relations/page": "/relations",
|
|
16
|
-
"/page": "/"
|
|
17
|
+
"/types/page": "/types"
|
|
17
18
|
}
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
"devFiles": [],
|
|
6
6
|
"ampDevFiles": [],
|
|
7
7
|
"lowPriorityFiles": [
|
|
8
|
-
"static/
|
|
9
|
-
"static/
|
|
8
|
+
"static/UDA414PFPu9ZROltNmjbX/_buildManifest.js",
|
|
9
|
+
"static/UDA414PFPu9ZROltNmjbX/_ssgManifest.js"
|
|
10
10
|
],
|
|
11
11
|
"rootMainFiles": [
|
|
12
12
|
"static/chunks/webpack-ef515e41a83a16ac.js",
|