@goondocks/myco 0.20.2 → 0.21.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/dist/agent-eval-RJSQI5S2.js +355 -0
- package/dist/agent-eval-RJSQI5S2.js.map +1 -0
- package/dist/{agent-run-X25Q2A6T.js → agent-run-2JSYFOKU.js} +10 -8
- package/dist/{agent-run-X25Q2A6T.js.map → agent-run-2JSYFOKU.js.map} +1 -1
- package/dist/{agent-tasks-7B6OFERB.js → agent-tasks-APFJIM2T.js} +10 -8
- package/dist/{agent-tasks-7B6OFERB.js.map → agent-tasks-APFJIM2T.js.map} +1 -1
- package/dist/{chunk-OD4AA7PV.js → chunk-53RPGOEN.js} +56 -8
- package/dist/chunk-53RPGOEN.js.map +1 -0
- package/dist/chunk-54SXG5HF.js +26 -0
- package/dist/chunk-54SXG5HF.js.map +1 -0
- package/dist/{chunk-DCSGJ7W4.js → chunk-5ZG4RMUH.js} +2 -2
- package/dist/{chunk-FLLBJLHM.js → chunk-6C6QZ4PM.js} +9 -5
- package/dist/chunk-6C6QZ4PM.js.map +1 -0
- package/dist/chunk-6LB7XELY.js +406 -0
- package/dist/chunk-6LB7XELY.js.map +1 -0
- package/dist/{chunk-JZGN33AY.js → chunk-75Z7UKDY.js} +4 -4
- package/dist/{chunk-XG5RRUYF.js → chunk-BUTL6IFS.js} +2 -2
- package/dist/chunk-CESKJD44.js +586 -0
- package/dist/chunk-CESKJD44.js.map +1 -0
- package/dist/chunk-CISWUP5W.js +101 -0
- package/dist/chunk-CISWUP5W.js.map +1 -0
- package/dist/chunk-DJ3IHNYO.js +50 -0
- package/dist/chunk-DJ3IHNYO.js.map +1 -0
- package/dist/chunk-F3OEQYLS.js +847 -0
- package/dist/chunk-F3OEQYLS.js.map +1 -0
- package/dist/{chunk-6RFZWV4R.js → chunk-FCJ5JV54.js} +1 -1
- package/dist/{chunk-6RFZWV4R.js.map → chunk-FCJ5JV54.js.map} +1 -1
- package/dist/{chunk-2PDWCDKY.js → chunk-G6QIBNZM.js} +9 -6
- package/dist/{chunk-2PDWCDKY.js.map → chunk-G6QIBNZM.js.map} +1 -1
- package/dist/{chunk-6X2ERTQV.js → chunk-ILJPRYES.js} +6 -4
- package/dist/{chunk-6X2ERTQV.js.map → chunk-ILJPRYES.js.map} +1 -1
- package/dist/{chunk-US4LNCAT.js → chunk-IPPMYQ2Y.js} +5 -1
- package/dist/chunk-IPPMYQ2Y.js.map +1 -0
- package/dist/{chunk-KESLPBKV.js → chunk-JR54LTPP.js} +4 -4
- package/dist/{chunk-CCRGY3QW.js → chunk-JZS6GZ6T.js} +16 -94
- package/dist/chunk-JZS6GZ6T.js.map +1 -0
- package/dist/{chunk-5XIVBO25.js → chunk-LVIY7P35.js} +2 -2
- package/dist/chunk-NGH7U6A3.js +13844 -0
- package/dist/chunk-NGH7U6A3.js.map +1 -0
- package/dist/chunk-OUJSQSKE.js +113 -0
- package/dist/chunk-OUJSQSKE.js.map +1 -0
- package/dist/{chunk-VVNL26WX.js → chunk-P66DLD6G.js} +22 -10
- package/dist/chunk-P66DLD6G.js.map +1 -0
- package/dist/{chunk-XATDZX7U.js → chunk-R2JIJBCL.js} +18 -4
- package/dist/{chunk-XATDZX7U.js.map → chunk-R2JIJBCL.js.map} +1 -1
- package/dist/{chunk-MYOZLMB2.js → chunk-RL5R4CQU.js} +538 -19
- package/dist/chunk-RL5R4CQU.js.map +1 -0
- package/dist/{chunk-EVDQKYCG.js → chunk-RQSJLWP4.js} +13 -2
- package/dist/chunk-RQSJLWP4.js.map +1 -0
- package/dist/{chunk-BPRIYNLE.js → chunk-TKAJ3JVF.js} +3 -3
- package/dist/{chunk-Q36VMZST.js → chunk-VHNRMM4O.js} +3 -2
- package/dist/{chunk-FMRZ26U5.js → chunk-X3IGT5RV.js} +5 -2
- package/dist/{chunk-FMRZ26U5.js.map → chunk-X3IGT5RV.js.map} +1 -1
- package/dist/{chunk-KHT24OWC.js → chunk-YDUOSRGD.js} +8 -94
- package/dist/{chunk-KHT24OWC.js.map → chunk-YDUOSRGD.js.map} +1 -1
- package/dist/{cli-GGPWH4UO.js → cli-LNYSTDQM.js} +49 -42
- package/dist/cli-LNYSTDQM.js.map +1 -0
- package/dist/{client-YXQUTXVZ.js → client-NWE4TCNO.js} +4 -4
- package/dist/{config-OMCYHG2S.js → config-VC4ACP42.js} +6 -4
- package/dist/{config-OMCYHG2S.js.map → config-VC4ACP42.js.map} +1 -1
- package/dist/{detect-providers-5KOPZ7J2.js → detect-providers-ILLQZROY.js} +4 -4
- package/dist/{doctor-5JXJ36KA.js → doctor-TI7EZ3RW.js} +48 -15
- package/dist/doctor-TI7EZ3RW.js.map +1 -0
- package/dist/executor-F2YU7HXJ.js +44 -0
- package/dist/{init-LMYOVZAV.js → init-KG3TYVGE.js} +14 -12
- package/dist/{init-LMYOVZAV.js.map → init-KG3TYVGE.js.map} +1 -1
- package/dist/{installer-FS257JRZ.js → installer-UMH7OJ5A.js} +6 -4
- package/dist/{llm-TH4NLIRM.js → llm-AGVEF5XD.js} +5 -4
- package/dist/{loader-CQYTFHEW.js → loader-LX7TFRM6.js} +5 -3
- package/dist/{loader-NOMBJUPW.js → loader-NAVVZK63.js} +4 -3
- package/dist/{main-YTBVRTBI.js → main-5PRQNEEE.js} +2453 -650
- package/dist/main-5PRQNEEE.js.map +1 -0
- package/dist/{open-HG2DX6RN.js → open-5A27BCSB.js} +10 -8
- package/dist/{open-HG2DX6RN.js.map → open-5A27BCSB.js.map} +1 -1
- package/dist/{post-compact-JSECI44W.js → post-compact-USAODKPQ.js} +6 -6
- package/dist/{post-tool-use-POGPTJBA.js → post-tool-use-GMMSYBII.js} +9 -7
- package/dist/post-tool-use-GMMSYBII.js.map +1 -0
- package/dist/{post-tool-use-failure-OT7BFWQW.js → post-tool-use-failure-NZVSL2PO.js} +6 -6
- package/dist/{pre-compact-OXVODKH4.js → pre-compact-LZ57DLUS.js} +6 -6
- package/dist/{provider-check-43LAMSMH.js → provider-check-ZEV5P4KM.js} +4 -4
- package/dist/{registry-U4CHXK6R.js → registry-M2Z5QBWH.js} +5 -4
- package/dist/{remove-N7ZPELFU.js → remove-T3KE6C5N.js} +10 -8
- package/dist/{remove-N7ZPELFU.js.map → remove-T3KE6C5N.js.map} +1 -1
- package/dist/{restart-ADG5GBTB.js → restart-YWDEVZUJ.js} +11 -9
- package/dist/{restart-ADG5GBTB.js.map → restart-YWDEVZUJ.js.map} +1 -1
- package/dist/{search-AHZEUNRR.js → search-GKFDGELR.js} +11 -9
- package/dist/{search-AHZEUNRR.js.map → search-GKFDGELR.js.map} +1 -1
- package/dist/{server-AGVYZVP5.js → server-AHUR6CWF.js} +368 -269
- package/dist/server-AHUR6CWF.js.map +1 -0
- package/dist/{session-6IU4AXYP.js → session-2ZEPLWW6.js} +11 -9
- package/dist/{session-6IU4AXYP.js.map → session-2ZEPLWW6.js.map} +1 -1
- package/dist/{session-end-FT27DWYZ.js → session-end-LWJYQAXX.js} +5 -5
- package/dist/session-start-WTA6GCOQ.js +134 -0
- package/dist/session-start-WTA6GCOQ.js.map +1 -0
- package/dist/{setup-llm-77MP4I2G.js → setup-llm-E7UU5IO7.js} +11 -9
- package/dist/{setup-llm-77MP4I2G.js.map → setup-llm-E7UU5IO7.js.map} +1 -1
- package/dist/src/agent/definitions/agent.yaml +9 -5
- package/dist/src/agent/definitions/tasks/cortex-instructions.yaml +93 -0
- package/dist/src/agent/definitions/tasks/cortex-prompt-builder.yaml +67 -0
- package/dist/src/agent/definitions/tasks/digest-only.yaml +1 -1
- package/dist/src/agent/definitions/tasks/extract-only.yaml +1 -1
- package/dist/src/agent/definitions/tasks/review-session.yaml +10 -39
- package/dist/src/agent/definitions/tasks/skill-evolve.yaml +4 -4
- package/dist/src/agent/definitions/tasks/skill-generate.yaml +1 -1
- package/dist/src/agent/definitions/tasks/skill-survey.yaml +2 -6
- package/dist/src/agent/definitions/tasks/supersession-sweep.yaml +1 -1
- package/dist/src/agent/definitions/tasks/title-summary.yaml +12 -19
- package/dist/src/agent/definitions/tasks/{full-intelligence.yaml → vault-evolve.yaml} +17 -82
- package/dist/src/agent/definitions/tasks/vault-seed.yaml +370 -0
- package/dist/src/agent/prompts/agent.md +12 -38
- package/dist/src/cli.js +1 -1
- package/dist/src/daemon/main.js +1 -1
- package/dist/src/hooks/post-tool-use.js +1 -1
- package/dist/src/hooks/session-end.js +1 -1
- package/dist/src/hooks/session-start.js +1 -1
- package/dist/src/hooks/stop.js +1 -1
- package/dist/src/hooks/user-prompt-submit.js +1 -1
- package/dist/src/mcp/server.js +1 -1
- package/dist/src/symbionts/manifests/claude-code.yaml +4 -0
- package/dist/src/symbionts/manifests/pi.yaml +22 -0
- package/dist/src/symbionts/templates/pi/package.json +6 -0
- package/dist/src/symbionts/templates/pi/plugin.ts +559 -0
- package/dist/{stats-NVPWOYTE.js → stats-DFG6S23S.js} +11 -9
- package/dist/{stats-NVPWOYTE.js.map → stats-DFG6S23S.js.map} +1 -1
- package/dist/{stop-ZPIKVLH4.js → stop-WRBTXEVT.js} +5 -5
- package/dist/{stop-failure-2PX67YJC.js → stop-failure-32MGIG2Q.js} +6 -6
- package/dist/{subagent-start-UUE6EHQD.js → subagent-start-VFGHQFVL.js} +6 -6
- package/dist/{subagent-stop-KQWWWPE6.js → subagent-stop-663FXG3P.js} +6 -6
- package/dist/{task-completed-WMHOFQ7B.js → task-completed-ZCQYEFMZ.js} +6 -6
- package/dist/{team-LRZ6GTQK.js → team-JTI5CDUO.js} +7 -5
- package/dist/{turns-YFNI5CQC.js → turns-HU2CTZAP.js} +2 -2
- package/dist/ui/assets/index-DGf1h-Ha.js +842 -0
- package/dist/ui/assets/index-_OP4ifzH.css +1 -0
- package/dist/ui/index.html +2 -2
- package/dist/{update-O6V4RC4W.js → update-3NBQTG32.js} +10 -8
- package/dist/{update-O6V4RC4W.js.map → update-3NBQTG32.js.map} +1 -1
- package/dist/{user-prompt-submit-N36KUPHI.js → user-prompt-submit-ME2TBKOS.js} +8 -7
- package/dist/{user-prompt-submit-N36KUPHI.js.map → user-prompt-submit-ME2TBKOS.js.map} +1 -1
- package/dist/{verify-LXPV7NYG.js → verify-R76ZFJSZ.js} +8 -5
- package/dist/{verify-LXPV7NYG.js.map → verify-R76ZFJSZ.js.map} +1 -1
- package/dist/{version-XMPPJQHR.js → version-GQAFBBPX.js} +2 -2
- package/dist/version-GQAFBBPX.js.map +1 -0
- package/package.json +3 -1
- package/skills/myco/SKILL.md +16 -1
- package/skills/myco/references/cli-usage.md +1 -1
- package/skills/myco-curate/SKILL.md +1 -1
- package/dist/chunk-4YFKBL3F.js +0 -195
- package/dist/chunk-4YFKBL3F.js.map +0 -1
- package/dist/chunk-CCRGY3QW.js.map +0 -1
- package/dist/chunk-EVDQKYCG.js.map +0 -1
- package/dist/chunk-FLLBJLHM.js.map +0 -1
- package/dist/chunk-MYOZLMB2.js.map +0 -1
- package/dist/chunk-OD4AA7PV.js.map +0 -1
- package/dist/chunk-US4LNCAT.js.map +0 -1
- package/dist/chunk-UYMFCYBF.js +0 -2326
- package/dist/chunk-UYMFCYBF.js.map +0 -1
- package/dist/chunk-VVNL26WX.js.map +0 -1
- package/dist/cli-GGPWH4UO.js.map +0 -1
- package/dist/doctor-5JXJ36KA.js.map +0 -1
- package/dist/executor-HWW2QNZQ.js +0 -2472
- package/dist/executor-HWW2QNZQ.js.map +0 -1
- package/dist/main-YTBVRTBI.js.map +0 -1
- package/dist/post-tool-use-POGPTJBA.js.map +0 -1
- package/dist/server-AGVYZVP5.js.map +0 -1
- package/dist/session-start-LAFICHII.js +0 -189
- package/dist/session-start-LAFICHII.js.map +0 -1
- package/dist/src/agent/definitions/tasks/graph-maintenance.yaml +0 -93
- package/dist/ui/assets/index-C2JuNtRB.css +0 -1
- package/dist/ui/assets/index-JLVaQKV2.js +0 -832
- /package/dist/{chunk-DCSGJ7W4.js.map → chunk-5ZG4RMUH.js.map} +0 -0
- /package/dist/{chunk-JZGN33AY.js.map → chunk-75Z7UKDY.js.map} +0 -0
- /package/dist/{chunk-XG5RRUYF.js.map → chunk-BUTL6IFS.js.map} +0 -0
- /package/dist/{chunk-KESLPBKV.js.map → chunk-JR54LTPP.js.map} +0 -0
- /package/dist/{chunk-5XIVBO25.js.map → chunk-LVIY7P35.js.map} +0 -0
- /package/dist/{chunk-BPRIYNLE.js.map → chunk-TKAJ3JVF.js.map} +0 -0
- /package/dist/{chunk-Q36VMZST.js.map → chunk-VHNRMM4O.js.map} +0 -0
- /package/dist/{client-YXQUTXVZ.js.map → client-NWE4TCNO.js.map} +0 -0
- /package/dist/{detect-providers-5KOPZ7J2.js.map → detect-providers-ILLQZROY.js.map} +0 -0
- /package/dist/{installer-FS257JRZ.js.map → executor-F2YU7HXJ.js.map} +0 -0
- /package/dist/{llm-TH4NLIRM.js.map → installer-UMH7OJ5A.js.map} +0 -0
- /package/dist/{loader-CQYTFHEW.js.map → llm-AGVEF5XD.js.map} +0 -0
- /package/dist/{loader-NOMBJUPW.js.map → loader-LX7TFRM6.js.map} +0 -0
- /package/dist/{provider-check-43LAMSMH.js.map → loader-NAVVZK63.js.map} +0 -0
- /package/dist/{post-compact-JSECI44W.js.map → post-compact-USAODKPQ.js.map} +0 -0
- /package/dist/{post-tool-use-failure-OT7BFWQW.js.map → post-tool-use-failure-NZVSL2PO.js.map} +0 -0
- /package/dist/{pre-compact-OXVODKH4.js.map → pre-compact-LZ57DLUS.js.map} +0 -0
- /package/dist/{registry-U4CHXK6R.js.map → provider-check-ZEV5P4KM.js.map} +0 -0
- /package/dist/{team-LRZ6GTQK.js.map → registry-M2Z5QBWH.js.map} +0 -0
- /package/dist/{session-end-FT27DWYZ.js.map → session-end-LWJYQAXX.js.map} +0 -0
- /package/dist/{stop-ZPIKVLH4.js.map → stop-WRBTXEVT.js.map} +0 -0
- /package/dist/{stop-failure-2PX67YJC.js.map → stop-failure-32MGIG2Q.js.map} +0 -0
- /package/dist/{subagent-start-UUE6EHQD.js.map → subagent-start-VFGHQFVL.js.map} +0 -0
- /package/dist/{subagent-stop-KQWWWPE6.js.map → subagent-stop-663FXG3P.js.map} +0 -0
- /package/dist/{task-completed-WMHOFQ7B.js.map → task-completed-ZCQYEFMZ.js.map} +0 -0
- /package/dist/{turns-YFNI5CQC.js.map → team-JTI5CDUO.js.map} +0 -0
- /package/dist/{version-XMPPJQHR.js.map → turns-HU2CTZAP.js.map} +0 -0
package/dist/chunk-UYMFCYBF.js
DELETED
|
@@ -1,2326 +0,0 @@
|
|
|
1
|
-
import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
|
|
2
|
-
import {
|
|
3
|
-
loadAllTasks
|
|
4
|
-
} from "./chunk-6X2ERTQV.js";
|
|
5
|
-
import {
|
|
6
|
-
getAgent,
|
|
7
|
-
getDefaultTask,
|
|
8
|
-
getTask,
|
|
9
|
-
loadAgentDefinition,
|
|
10
|
-
resolveDefinitionsDir,
|
|
11
|
-
resolveEffectiveConfig
|
|
12
|
-
} from "./chunk-CCRGY3QW.js";
|
|
13
|
-
import {
|
|
14
|
-
countSpores,
|
|
15
|
-
getSpore,
|
|
16
|
-
listSporeIdsSince,
|
|
17
|
-
listSpores
|
|
18
|
-
} from "./chunk-4YFKBL3F.js";
|
|
19
|
-
import {
|
|
20
|
-
countSessions,
|
|
21
|
-
getSession,
|
|
22
|
-
getTeamMachineId,
|
|
23
|
-
listSessions,
|
|
24
|
-
syncRow
|
|
25
|
-
} from "./chunk-EVDQKYCG.js";
|
|
26
|
-
import {
|
|
27
|
-
loadMergedConfig
|
|
28
|
-
} from "./chunk-OD4AA7PV.js";
|
|
29
|
-
import {
|
|
30
|
-
getDatabase
|
|
31
|
-
} from "./chunk-MYX5NCRH.js";
|
|
32
|
-
import {
|
|
33
|
-
DEFAULT_LIST_LIMIT,
|
|
34
|
-
DIGEST_TIERS,
|
|
35
|
-
EDGE_TYPE_DERIVED_FROM,
|
|
36
|
-
EDGE_TYPE_EXTRACTED_FROM,
|
|
37
|
-
EDGE_TYPE_FROM_SESSION,
|
|
38
|
-
EDGE_TYPE_HAS_BATCH,
|
|
39
|
-
GRAPH_EDGE_DEFAULT_CONFIDENCE,
|
|
40
|
-
QUERY_DEFAULT_LIST_LIMIT,
|
|
41
|
-
epochSeconds
|
|
42
|
-
} from "./chunk-FLLBJLHM.js";
|
|
43
|
-
import {
|
|
44
|
-
require_dist
|
|
45
|
-
} from "./chunk-6LQIMRTC.js";
|
|
46
|
-
import {
|
|
47
|
-
__toESM
|
|
48
|
-
} from "./chunk-PZUWP5VK.js";
|
|
49
|
-
|
|
50
|
-
// src/notifications/notify.ts
|
|
51
|
-
import crypto from "crypto";
|
|
52
|
-
|
|
53
|
-
// src/db/queries/notifications.ts
|
|
54
|
-
var DEFAULT_LIMIT = 50;
|
|
55
|
-
var NOTIFICATION_PRUNE_AGE_SECONDS = 30 * 24 * 60 * 60;
|
|
56
|
-
function insertNotification(n) {
|
|
57
|
-
const db = getDatabase();
|
|
58
|
-
db.prepare(
|
|
59
|
-
`INSERT INTO notifications (id, domain, type, level, title, message, mode, status, link, metadata, created_at)
|
|
60
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, 'unread', ?, ?, ?)`
|
|
61
|
-
).run(n.id, n.domain, n.type, n.level, n.title, n.message, n.mode, n.link, n.metadata, epochSeconds());
|
|
62
|
-
}
|
|
63
|
-
function listNotifications(opts = {}) {
|
|
64
|
-
const db = getDatabase();
|
|
65
|
-
const conditions = [];
|
|
66
|
-
const params = [];
|
|
67
|
-
if (opts.status) {
|
|
68
|
-
conditions.push("status = ?");
|
|
69
|
-
params.push(opts.status);
|
|
70
|
-
}
|
|
71
|
-
if (opts.domain) {
|
|
72
|
-
conditions.push("domain = ?");
|
|
73
|
-
params.push(opts.domain);
|
|
74
|
-
}
|
|
75
|
-
if (opts.mode) {
|
|
76
|
-
conditions.push("mode = ?");
|
|
77
|
-
params.push(opts.mode);
|
|
78
|
-
}
|
|
79
|
-
const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
80
|
-
const limit = opts.limit ?? DEFAULT_LIMIT;
|
|
81
|
-
const offset = opts.offset ?? 0;
|
|
82
|
-
return db.prepare(
|
|
83
|
-
`SELECT * FROM notifications ${where} ORDER BY created_at DESC LIMIT ? OFFSET ?`
|
|
84
|
-
).all(...params, limit, offset);
|
|
85
|
-
}
|
|
86
|
-
function countNotifications(status) {
|
|
87
|
-
const db = getDatabase();
|
|
88
|
-
if (status) {
|
|
89
|
-
const row2 = db.prepare("SELECT COUNT(*) as count FROM notifications WHERE status = ?").get(status);
|
|
90
|
-
return row2.count;
|
|
91
|
-
}
|
|
92
|
-
const row = db.prepare("SELECT COUNT(*) as count FROM notifications").get();
|
|
93
|
-
return row.count;
|
|
94
|
-
}
|
|
95
|
-
function getNotification(id) {
|
|
96
|
-
const db = getDatabase();
|
|
97
|
-
return db.prepare("SELECT * FROM notifications WHERE id = ?").get(id);
|
|
98
|
-
}
|
|
99
|
-
function updateNotificationStatus(id, status) {
|
|
100
|
-
const db = getDatabase();
|
|
101
|
-
const result = db.prepare("UPDATE notifications SET status = ? WHERE id = ?").run(status, id);
|
|
102
|
-
return result.changes > 0;
|
|
103
|
-
}
|
|
104
|
-
function dismissAllNotifications(domain) {
|
|
105
|
-
const db = getDatabase();
|
|
106
|
-
if (domain) {
|
|
107
|
-
const result2 = db.prepare("UPDATE notifications SET status = 'dismissed' WHERE domain = ? AND status != 'dismissed'").run(domain);
|
|
108
|
-
return result2.changes;
|
|
109
|
-
}
|
|
110
|
-
const result = db.prepare("UPDATE notifications SET status = 'dismissed' WHERE status != 'dismissed'").run();
|
|
111
|
-
return result.changes;
|
|
112
|
-
}
|
|
113
|
-
function markAllRead(domain) {
|
|
114
|
-
const db = getDatabase();
|
|
115
|
-
if (domain) {
|
|
116
|
-
const result2 = db.prepare("UPDATE notifications SET status = 'read' WHERE domain = ? AND status = 'unread'").run(domain);
|
|
117
|
-
return result2.changes;
|
|
118
|
-
}
|
|
119
|
-
const result = db.prepare("UPDATE notifications SET status = 'read' WHERE status = 'unread'").run();
|
|
120
|
-
return result.changes;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// src/notifications/registry.ts
|
|
124
|
-
var domains = /* @__PURE__ */ new Map();
|
|
125
|
-
function register(descriptor) {
|
|
126
|
-
domains.set(descriptor.domain, descriptor);
|
|
127
|
-
}
|
|
128
|
-
function getAllDomains() {
|
|
129
|
-
return [...domains.values()].sort((a, b) => a.domain.localeCompare(b.domain));
|
|
130
|
-
}
|
|
131
|
-
function getType(typeId) {
|
|
132
|
-
for (const descriptor of domains.values()) {
|
|
133
|
-
const match = descriptor.types.find((t) => t.id === typeId);
|
|
134
|
-
if (match) return { domain: descriptor, type: match };
|
|
135
|
-
}
|
|
136
|
-
return void 0;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// src/notifications/notify.ts
|
|
140
|
-
function notify(vaultDir, payload, config) {
|
|
141
|
-
if (!vaultDir) return null;
|
|
142
|
-
try {
|
|
143
|
-
const cfg = config ?? loadMergedConfig(vaultDir);
|
|
144
|
-
if (!cfg.notifications.enabled) return null;
|
|
145
|
-
const domainConfig = cfg.notifications.domains[payload.domain];
|
|
146
|
-
if (domainConfig && !domainConfig.enabled) return null;
|
|
147
|
-
const registeredType = getType(payload.type);
|
|
148
|
-
const mode = payload.mode ?? domainConfig?.mode ?? cfg.notifications.default_mode ?? registeredType?.type.defaultMode;
|
|
149
|
-
const level = payload.level ?? registeredType?.type.defaultLevel ?? "info";
|
|
150
|
-
const id = crypto.randomUUID();
|
|
151
|
-
insertNotification({
|
|
152
|
-
id,
|
|
153
|
-
domain: payload.domain,
|
|
154
|
-
type: payload.type,
|
|
155
|
-
level,
|
|
156
|
-
title: payload.title,
|
|
157
|
-
message: payload.message ?? null,
|
|
158
|
-
mode,
|
|
159
|
-
link: payload.link ?? null,
|
|
160
|
-
metadata: payload.metadata ? JSON.stringify(payload.metadata) : null
|
|
161
|
-
});
|
|
162
|
-
return id;
|
|
163
|
-
} catch (err) {
|
|
164
|
-
console.warn("[notify] Failed to emit notification:", err instanceof Error ? err.message : err);
|
|
165
|
-
return null;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// src/utils/error-message.ts
|
|
170
|
-
function errorMessage(err) {
|
|
171
|
-
if (err instanceof Error) return err.message || err.constructor.name || "Error";
|
|
172
|
-
if (typeof err === "string") return err || "Empty string error";
|
|
173
|
-
try {
|
|
174
|
-
return JSON.stringify(err);
|
|
175
|
-
} catch {
|
|
176
|
-
return "Unserializable error";
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// src/db/queries/runs.ts
|
|
181
|
-
var DEFAULT_LIST_LIMIT2 = 100;
|
|
182
|
-
var DEFAULT_STATUS = "pending";
|
|
183
|
-
var STATUS_RUNNING = "running";
|
|
184
|
-
var STATUS_COMPLETED = "completed";
|
|
185
|
-
var STATUS_FAILED = "failed";
|
|
186
|
-
var RUN_COLUMNS = [
|
|
187
|
-
"id",
|
|
188
|
-
"agent_id",
|
|
189
|
-
"task",
|
|
190
|
-
"instruction",
|
|
191
|
-
"status",
|
|
192
|
-
"started_at",
|
|
193
|
-
"completed_at",
|
|
194
|
-
"tokens_used",
|
|
195
|
-
"cost_usd",
|
|
196
|
-
"actions_taken",
|
|
197
|
-
"error"
|
|
198
|
-
];
|
|
199
|
-
var SELECT_COLUMNS = RUN_COLUMNS.join(", ");
|
|
200
|
-
function toRunRow(row) {
|
|
201
|
-
return {
|
|
202
|
-
id: row.id,
|
|
203
|
-
agent_id: row.agent_id,
|
|
204
|
-
task: row.task ?? null,
|
|
205
|
-
instruction: row.instruction ?? null,
|
|
206
|
-
status: row.status,
|
|
207
|
-
started_at: row.started_at ?? null,
|
|
208
|
-
completed_at: row.completed_at ?? null,
|
|
209
|
-
tokens_used: row.tokens_used ?? null,
|
|
210
|
-
cost_usd: row.cost_usd ?? null,
|
|
211
|
-
actions_taken: row.actions_taken ?? null,
|
|
212
|
-
error: row.error ?? null
|
|
213
|
-
};
|
|
214
|
-
}
|
|
215
|
-
function insertRun(data) {
|
|
216
|
-
const db = getDatabase();
|
|
217
|
-
db.prepare(
|
|
218
|
-
`INSERT INTO agent_runs (
|
|
219
|
-
id, agent_id, task, instruction, status,
|
|
220
|
-
started_at, completed_at, tokens_used, cost_usd,
|
|
221
|
-
actions_taken, error
|
|
222
|
-
) VALUES (
|
|
223
|
-
?, ?, ?, ?, ?,
|
|
224
|
-
?, ?, ?, ?,
|
|
225
|
-
?, ?
|
|
226
|
-
)`
|
|
227
|
-
).run(
|
|
228
|
-
data.id,
|
|
229
|
-
data.agent_id,
|
|
230
|
-
data.task ?? null,
|
|
231
|
-
data.instruction ?? null,
|
|
232
|
-
data.status ?? DEFAULT_STATUS,
|
|
233
|
-
data.started_at ?? null,
|
|
234
|
-
data.completed_at ?? null,
|
|
235
|
-
data.tokens_used ?? null,
|
|
236
|
-
data.cost_usd ?? null,
|
|
237
|
-
data.actions_taken ?? null,
|
|
238
|
-
data.error ?? null
|
|
239
|
-
);
|
|
240
|
-
return toRunRow(
|
|
241
|
-
db.prepare(`SELECT ${SELECT_COLUMNS} FROM agent_runs WHERE id = ?`).get(data.id)
|
|
242
|
-
);
|
|
243
|
-
}
|
|
244
|
-
function getRun(id) {
|
|
245
|
-
const db = getDatabase();
|
|
246
|
-
const row = db.prepare(
|
|
247
|
-
`SELECT ${SELECT_COLUMNS} FROM agent_runs WHERE id = ?`
|
|
248
|
-
).get(id);
|
|
249
|
-
if (!row) return null;
|
|
250
|
-
return toRunRow(row);
|
|
251
|
-
}
|
|
252
|
-
function buildRunsWhere(options) {
|
|
253
|
-
const conditions = [];
|
|
254
|
-
const params = [];
|
|
255
|
-
if (options.agent_id !== void 0) {
|
|
256
|
-
conditions.push(`agent_id = ?`);
|
|
257
|
-
params.push(options.agent_id);
|
|
258
|
-
}
|
|
259
|
-
if (options.status !== void 0) {
|
|
260
|
-
conditions.push(`status = ?`);
|
|
261
|
-
params.push(options.status);
|
|
262
|
-
}
|
|
263
|
-
if (options.task !== void 0) {
|
|
264
|
-
conditions.push(`task = ?`);
|
|
265
|
-
params.push(options.task);
|
|
266
|
-
}
|
|
267
|
-
if (options.search !== void 0 && options.search.length > 0) {
|
|
268
|
-
conditions.push(`task LIKE ?`);
|
|
269
|
-
params.push(`%${options.search}%`);
|
|
270
|
-
}
|
|
271
|
-
return {
|
|
272
|
-
where: conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "",
|
|
273
|
-
params
|
|
274
|
-
};
|
|
275
|
-
}
|
|
276
|
-
function listRuns(options = {}) {
|
|
277
|
-
const db = getDatabase();
|
|
278
|
-
const { where, params } = buildRunsWhere(options);
|
|
279
|
-
const limit = options.limit ?? DEFAULT_LIST_LIMIT2;
|
|
280
|
-
const offset = options.offset ?? 0;
|
|
281
|
-
const rows = db.prepare(
|
|
282
|
-
`SELECT ${SELECT_COLUMNS}
|
|
283
|
-
FROM agent_runs
|
|
284
|
-
${where}
|
|
285
|
-
ORDER BY started_at DESC NULLS LAST
|
|
286
|
-
LIMIT ?
|
|
287
|
-
OFFSET ?`
|
|
288
|
-
).all(...params, limit, offset);
|
|
289
|
-
return rows.map(toRunRow);
|
|
290
|
-
}
|
|
291
|
-
function countRuns(options = {}) {
|
|
292
|
-
const db = getDatabase();
|
|
293
|
-
const { where, params } = buildRunsWhere(options);
|
|
294
|
-
const row = db.prepare(
|
|
295
|
-
`SELECT COUNT(*) as count FROM agent_runs ${where}`
|
|
296
|
-
).get(...params);
|
|
297
|
-
return row.count;
|
|
298
|
-
}
|
|
299
|
-
function updateRunStatus(id, status, completion) {
|
|
300
|
-
const db = getDatabase();
|
|
301
|
-
const setClauses = ["status = ?"];
|
|
302
|
-
const params = [status];
|
|
303
|
-
if (completion?.completed_at !== void 0) {
|
|
304
|
-
setClauses.push(`completed_at = ?`);
|
|
305
|
-
params.push(completion.completed_at);
|
|
306
|
-
}
|
|
307
|
-
if (completion?.tokens_used !== void 0) {
|
|
308
|
-
setClauses.push(`tokens_used = ?`);
|
|
309
|
-
params.push(completion.tokens_used);
|
|
310
|
-
}
|
|
311
|
-
if (completion?.cost_usd !== void 0) {
|
|
312
|
-
setClauses.push(`cost_usd = ?`);
|
|
313
|
-
params.push(completion.cost_usd);
|
|
314
|
-
}
|
|
315
|
-
if (completion?.actions_taken !== void 0) {
|
|
316
|
-
setClauses.push(`actions_taken = ?`);
|
|
317
|
-
params.push(completion.actions_taken);
|
|
318
|
-
}
|
|
319
|
-
if (completion?.error !== void 0) {
|
|
320
|
-
setClauses.push(`error = ?`);
|
|
321
|
-
params.push(completion.error);
|
|
322
|
-
}
|
|
323
|
-
params.push(id);
|
|
324
|
-
const info = db.prepare(
|
|
325
|
-
`UPDATE agent_runs
|
|
326
|
-
SET ${setClauses.join(", ")}
|
|
327
|
-
WHERE id = ?`
|
|
328
|
-
).run(...params);
|
|
329
|
-
if (info.changes === 0) return null;
|
|
330
|
-
return toRunRow(
|
|
331
|
-
db.prepare(`SELECT ${SELECT_COLUMNS} FROM agent_runs WHERE id = ?`).get(id)
|
|
332
|
-
);
|
|
333
|
-
}
|
|
334
|
-
function getRunningRunForTask(agentId, taskName) {
|
|
335
|
-
const db = getDatabase();
|
|
336
|
-
const row = db.prepare(
|
|
337
|
-
`SELECT id FROM agent_runs
|
|
338
|
-
WHERE agent_id = ? AND task = ? AND status = ?
|
|
339
|
-
LIMIT 1`
|
|
340
|
-
).get(agentId, taskName, STATUS_RUNNING);
|
|
341
|
-
return row?.id ?? null;
|
|
342
|
-
}
|
|
343
|
-
function getLatestRunId(agentId, taskName) {
|
|
344
|
-
const db = getDatabase();
|
|
345
|
-
if (taskName) {
|
|
346
|
-
const row2 = db.prepare(
|
|
347
|
-
`SELECT id FROM agent_runs
|
|
348
|
-
WHERE agent_id = ? AND task = ?
|
|
349
|
-
ORDER BY started_at DESC
|
|
350
|
-
LIMIT 1`
|
|
351
|
-
).get(agentId, taskName);
|
|
352
|
-
return row2?.id ?? null;
|
|
353
|
-
}
|
|
354
|
-
const row = db.prepare(
|
|
355
|
-
`SELECT id FROM agent_runs
|
|
356
|
-
WHERE agent_id = ?
|
|
357
|
-
ORDER BY started_at DESC
|
|
358
|
-
LIMIT 1`
|
|
359
|
-
).get(agentId);
|
|
360
|
-
return row?.id ?? null;
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
// src/agent/config-resolver.ts
|
|
364
|
-
function hasConfiguredProvider(mycoConfig, taskName) {
|
|
365
|
-
const taskProvider = taskName ? mycoConfig.agent.tasks?.[taskName]?.provider : void 0;
|
|
366
|
-
return !!(taskProvider ?? mycoConfig.agent.provider);
|
|
367
|
-
}
|
|
368
|
-
function toProviderConfig(p) {
|
|
369
|
-
return {
|
|
370
|
-
type: p.type,
|
|
371
|
-
baseUrl: p.base_url,
|
|
372
|
-
model: p.model,
|
|
373
|
-
contextLength: p.context_length
|
|
374
|
-
};
|
|
375
|
-
}
|
|
376
|
-
function resolveRunConfig(agentId, requestedTask, vaultDir) {
|
|
377
|
-
const definitionsDir = resolveDefinitionsDir();
|
|
378
|
-
const definition = loadAgentDefinition(definitionsDir);
|
|
379
|
-
const agentRow = getAgent(agentId);
|
|
380
|
-
const taskRow = requestedTask ? getTask(requestedTask) : getDefaultTask(agentId);
|
|
381
|
-
const allTasks = loadAllTasks(definitionsDir, vaultDir);
|
|
382
|
-
const taskName = taskRow?.id ?? requestedTask;
|
|
383
|
-
const yamlTask = taskName ? allTasks.get(taskName) : void 0;
|
|
384
|
-
const taskOverrides = taskRow ? {
|
|
385
|
-
name: taskRow.id,
|
|
386
|
-
displayName: taskRow.display_name ?? taskRow.id,
|
|
387
|
-
description: taskRow.description ?? "",
|
|
388
|
-
agent: taskRow.agent_id,
|
|
389
|
-
prompt: taskRow.prompt,
|
|
390
|
-
isDefault: taskRow.is_default === 1,
|
|
391
|
-
...taskRow.tool_overrides ? { toolOverrides: JSON.parse(taskRow.tool_overrides) } : {},
|
|
392
|
-
// Scalar config from YAML (model, turns, timeout) — DB doesn't store these
|
|
393
|
-
...yamlTask?.model ? { model: yamlTask.model } : {},
|
|
394
|
-
...yamlTask?.maxTurns ? { maxTurns: yamlTask.maxTurns } : {},
|
|
395
|
-
...yamlTask?.timeoutSeconds ? { timeoutSeconds: yamlTask.timeoutSeconds } : {},
|
|
396
|
-
// Structural config from YAML
|
|
397
|
-
...yamlTask?.phases ? { phases: yamlTask.phases } : {},
|
|
398
|
-
...yamlTask?.execution ? { execution: yamlTask.execution } : {},
|
|
399
|
-
...yamlTask?.contextQueries ? { contextQueries: yamlTask.contextQueries } : {},
|
|
400
|
-
...yamlTask?.orchestrator ? { orchestrator: yamlTask.orchestrator } : {}
|
|
401
|
-
} : void 0;
|
|
402
|
-
const config = resolveEffectiveConfig(definition, agentRow, taskOverrides);
|
|
403
|
-
let taskProviderOverride;
|
|
404
|
-
let phaseProviderOverrides = {};
|
|
405
|
-
let taskParams;
|
|
406
|
-
try {
|
|
407
|
-
const mycoConfig = loadMergedConfig(vaultDir);
|
|
408
|
-
const taskConfig = taskName ? mycoConfig.agent.tasks?.[taskName] : void 0;
|
|
409
|
-
const globalProvider = mycoConfig.agent.provider;
|
|
410
|
-
if (taskConfig?.provider) {
|
|
411
|
-
taskProviderOverride = toProviderConfig(taskConfig.provider);
|
|
412
|
-
} else if (globalProvider) {
|
|
413
|
-
taskProviderOverride = toProviderConfig(globalProvider);
|
|
414
|
-
}
|
|
415
|
-
if (taskConfig?.phases) {
|
|
416
|
-
for (const [phaseName, phaseConfig] of Object.entries(taskConfig.phases)) {
|
|
417
|
-
phaseProviderOverrides[phaseName] = {
|
|
418
|
-
...phaseConfig.provider ? { provider: toProviderConfig(phaseConfig.provider) } : {},
|
|
419
|
-
...phaseConfig.maxTurns != null ? { maxTurns: phaseConfig.maxTurns } : {}
|
|
420
|
-
};
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
const yamlParams = yamlTask?.params;
|
|
424
|
-
const configParams = taskConfig?.params;
|
|
425
|
-
if (yamlParams || configParams) {
|
|
426
|
-
taskParams = { ...yamlParams, ...configParams };
|
|
427
|
-
}
|
|
428
|
-
} catch {
|
|
429
|
-
}
|
|
430
|
-
return {
|
|
431
|
-
config,
|
|
432
|
-
definitionsDir,
|
|
433
|
-
taskProviderOverride,
|
|
434
|
-
phaseProviderOverrides,
|
|
435
|
-
taskName,
|
|
436
|
-
taskParams
|
|
437
|
-
};
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
// src/agent/instruction-builders.ts
|
|
441
|
-
import { readFileSync } from "fs";
|
|
442
|
-
import { resolve } from "path";
|
|
443
|
-
|
|
444
|
-
// src/db/queries/skill-candidates.ts
|
|
445
|
-
var DEFAULT_CONFIDENCE = 0;
|
|
446
|
-
var DEFAULT_STATUS2 = "identified";
|
|
447
|
-
var CANDIDATE_COLUMNS = [
|
|
448
|
-
"id",
|
|
449
|
-
"agent_id",
|
|
450
|
-
"machine_id",
|
|
451
|
-
"topic",
|
|
452
|
-
"rationale",
|
|
453
|
-
"confidence",
|
|
454
|
-
"status",
|
|
455
|
-
"source_ids",
|
|
456
|
-
"skill_id",
|
|
457
|
-
"supersedes",
|
|
458
|
-
"approved_at",
|
|
459
|
-
"created_at",
|
|
460
|
-
"updated_at",
|
|
461
|
-
"synced_at"
|
|
462
|
-
];
|
|
463
|
-
var SELECT_COLUMNS2 = CANDIDATE_COLUMNS.join(", ");
|
|
464
|
-
function toCandidateRow(row) {
|
|
465
|
-
return {
|
|
466
|
-
id: row.id,
|
|
467
|
-
agent_id: row.agent_id,
|
|
468
|
-
machine_id: row.machine_id ?? getTeamMachineId(),
|
|
469
|
-
topic: row.topic,
|
|
470
|
-
rationale: row.rationale,
|
|
471
|
-
confidence: row.confidence,
|
|
472
|
-
status: row.status,
|
|
473
|
-
source_ids: row.source_ids ?? "[]",
|
|
474
|
-
skill_id: row.skill_id ?? null,
|
|
475
|
-
supersedes: row.supersedes ?? null,
|
|
476
|
-
approved_at: row.approved_at ?? null,
|
|
477
|
-
created_at: row.created_at,
|
|
478
|
-
updated_at: row.updated_at,
|
|
479
|
-
synced_at: row.synced_at ?? null
|
|
480
|
-
};
|
|
481
|
-
}
|
|
482
|
-
function buildWhere(options) {
|
|
483
|
-
const conditions = [];
|
|
484
|
-
const params = [];
|
|
485
|
-
if (options.agent_id !== void 0) {
|
|
486
|
-
conditions.push(`agent_id = ?`);
|
|
487
|
-
params.push(options.agent_id);
|
|
488
|
-
}
|
|
489
|
-
if (options.statuses !== void 0 && options.statuses.length > 0) {
|
|
490
|
-
const placeholders = options.statuses.map(() => "?").join(", ");
|
|
491
|
-
conditions.push(`status IN (${placeholders})`);
|
|
492
|
-
params.push(...options.statuses);
|
|
493
|
-
} else if (options.status !== void 0) {
|
|
494
|
-
conditions.push(`status = ?`);
|
|
495
|
-
params.push(options.status);
|
|
496
|
-
}
|
|
497
|
-
return {
|
|
498
|
-
where: conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "",
|
|
499
|
-
params
|
|
500
|
-
};
|
|
501
|
-
}
|
|
502
|
-
function insertCandidate(data) {
|
|
503
|
-
const db = getDatabase();
|
|
504
|
-
db.prepare(
|
|
505
|
-
`INSERT INTO skill_candidates (
|
|
506
|
-
id, agent_id, machine_id, topic, rationale,
|
|
507
|
-
confidence, status, source_ids, skill_id, supersedes, approved_at,
|
|
508
|
-
created_at, updated_at
|
|
509
|
-
) VALUES (
|
|
510
|
-
?, ?, ?, ?, ?,
|
|
511
|
-
?, ?, ?, ?, ?, ?,
|
|
512
|
-
?, ?
|
|
513
|
-
)`
|
|
514
|
-
).run(
|
|
515
|
-
data.id,
|
|
516
|
-
data.agent_id,
|
|
517
|
-
data.machine_id ?? getTeamMachineId(),
|
|
518
|
-
data.topic,
|
|
519
|
-
data.rationale,
|
|
520
|
-
data.confidence ?? DEFAULT_CONFIDENCE,
|
|
521
|
-
data.status ?? DEFAULT_STATUS2,
|
|
522
|
-
data.source_ids ?? "[]",
|
|
523
|
-
data.skill_id ?? null,
|
|
524
|
-
data.supersedes ?? null,
|
|
525
|
-
data.approved_at ?? null,
|
|
526
|
-
data.created_at,
|
|
527
|
-
data.updated_at
|
|
528
|
-
);
|
|
529
|
-
const raw = db.prepare(`SELECT ${SELECT_COLUMNS2} FROM skill_candidates WHERE id = ?`).get(data.id);
|
|
530
|
-
if (!raw) throw new Error(`Failed to insert skill candidate: ${data.id}`);
|
|
531
|
-
const row = toCandidateRow(raw);
|
|
532
|
-
syncRow("skill_candidates", row);
|
|
533
|
-
return row;
|
|
534
|
-
}
|
|
535
|
-
function getCandidate(id) {
|
|
536
|
-
const db = getDatabase();
|
|
537
|
-
const row = db.prepare(
|
|
538
|
-
`SELECT ${SELECT_COLUMNS2} FROM skill_candidates WHERE id = ?`
|
|
539
|
-
).get(id);
|
|
540
|
-
if (!row) return null;
|
|
541
|
-
return toCandidateRow(row);
|
|
542
|
-
}
|
|
543
|
-
function listCandidates(options = {}) {
|
|
544
|
-
const db = getDatabase();
|
|
545
|
-
const { where, params } = buildWhere(options);
|
|
546
|
-
const limit = options.limit ?? DEFAULT_LIST_LIMIT;
|
|
547
|
-
const offset = options.offset ?? 0;
|
|
548
|
-
const rows = db.prepare(
|
|
549
|
-
`SELECT ${SELECT_COLUMNS2}
|
|
550
|
-
FROM skill_candidates
|
|
551
|
-
${where}
|
|
552
|
-
ORDER BY confidence DESC, created_at DESC
|
|
553
|
-
LIMIT ?
|
|
554
|
-
OFFSET ?`
|
|
555
|
-
).all(...params, limit, offset);
|
|
556
|
-
return rows.map(toCandidateRow);
|
|
557
|
-
}
|
|
558
|
-
function updateCandidate(id, updates) {
|
|
559
|
-
const db = getDatabase();
|
|
560
|
-
let autoApprovedAt;
|
|
561
|
-
if (updates.status === "approved" && updates.approved_at === void 0) {
|
|
562
|
-
const existing = getCandidate(id);
|
|
563
|
-
if (existing && existing.approved_at === null) {
|
|
564
|
-
autoApprovedAt = updates.updated_at;
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
const fieldMap = {
|
|
568
|
-
topic: "topic",
|
|
569
|
-
rationale: "rationale",
|
|
570
|
-
confidence: "confidence",
|
|
571
|
-
status: "status",
|
|
572
|
-
source_ids: "source_ids",
|
|
573
|
-
skill_id: "skill_id",
|
|
574
|
-
supersedes: "supersedes",
|
|
575
|
-
approved_at: "approved_at",
|
|
576
|
-
updated_at: "updated_at"
|
|
577
|
-
};
|
|
578
|
-
const setClauses = [];
|
|
579
|
-
const params = [];
|
|
580
|
-
const updateValues = updates;
|
|
581
|
-
for (const [key, column] of Object.entries(fieldMap)) {
|
|
582
|
-
if (key in updates) {
|
|
583
|
-
setClauses.push(`${column} = ?`);
|
|
584
|
-
params.push(updateValues[key] ?? null);
|
|
585
|
-
} else if (key === "approved_at" && autoApprovedAt !== void 0) {
|
|
586
|
-
setClauses.push(`${column} = ?`);
|
|
587
|
-
params.push(autoApprovedAt);
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
if (setClauses.length === 0) return getCandidate(id);
|
|
591
|
-
params.push(id);
|
|
592
|
-
db.prepare(
|
|
593
|
-
`UPDATE skill_candidates
|
|
594
|
-
SET ${setClauses.join(", ")}
|
|
595
|
-
WHERE id = ?`
|
|
596
|
-
).run(...params);
|
|
597
|
-
const updated = getCandidate(id);
|
|
598
|
-
if (updated) syncRow("skill_candidates", updated);
|
|
599
|
-
return updated;
|
|
600
|
-
}
|
|
601
|
-
function listCandidatesWithCount(options = {}) {
|
|
602
|
-
const db = getDatabase();
|
|
603
|
-
const { where, params } = buildWhere(options);
|
|
604
|
-
const limit = options.limit ?? DEFAULT_LIST_LIMIT;
|
|
605
|
-
const offset = options.offset ?? 0;
|
|
606
|
-
const rows = db.prepare(
|
|
607
|
-
`SELECT ${SELECT_COLUMNS2}, COUNT(*) OVER () AS __total
|
|
608
|
-
FROM skill_candidates
|
|
609
|
-
${where}
|
|
610
|
-
ORDER BY confidence DESC, created_at DESC
|
|
611
|
-
LIMIT ?
|
|
612
|
-
OFFSET ?`
|
|
613
|
-
).all(...params, limit, offset);
|
|
614
|
-
if (rows.length === 0) {
|
|
615
|
-
return { items: [], total: countCandidates(options) };
|
|
616
|
-
}
|
|
617
|
-
const total = Number(rows[0].__total);
|
|
618
|
-
const items = rows.map((row) => {
|
|
619
|
-
const { __total: _drop, ...rest } = row;
|
|
620
|
-
return toCandidateRow(rest);
|
|
621
|
-
});
|
|
622
|
-
return { items, total };
|
|
623
|
-
}
|
|
624
|
-
function countCandidates(options = {}) {
|
|
625
|
-
const db = getDatabase();
|
|
626
|
-
const { where, params } = buildWhere(options);
|
|
627
|
-
const row = db.prepare(
|
|
628
|
-
`SELECT COUNT(*) as count FROM skill_candidates ${where}`
|
|
629
|
-
).get(...params);
|
|
630
|
-
return row.count;
|
|
631
|
-
}
|
|
632
|
-
function deleteCandidate(id) {
|
|
633
|
-
const db = getDatabase();
|
|
634
|
-
const info = db.prepare("DELETE FROM skill_candidates WHERE id = ?").run(id);
|
|
635
|
-
return info.changes > 0;
|
|
636
|
-
}
|
|
637
|
-
|
|
638
|
-
// src/db/queries/skill-records.ts
|
|
639
|
-
var DEFAULT_STATUS3 = "active";
|
|
640
|
-
var DEFAULT_GENERATION = 1;
|
|
641
|
-
var RECORD_COLUMNS = [
|
|
642
|
-
"id",
|
|
643
|
-
"agent_id",
|
|
644
|
-
"machine_id",
|
|
645
|
-
"name",
|
|
646
|
-
"display_name",
|
|
647
|
-
"description",
|
|
648
|
-
"status",
|
|
649
|
-
"generation",
|
|
650
|
-
"candidate_id",
|
|
651
|
-
"source_ids",
|
|
652
|
-
"path",
|
|
653
|
-
"usage_count",
|
|
654
|
-
"last_used_at",
|
|
655
|
-
"created_at",
|
|
656
|
-
"updated_at",
|
|
657
|
-
"properties",
|
|
658
|
-
"synced_at"
|
|
659
|
-
];
|
|
660
|
-
var SELECT_COLUMNS3 = RECORD_COLUMNS.join(", ");
|
|
661
|
-
function toSkillRecordRow(row) {
|
|
662
|
-
return {
|
|
663
|
-
id: row.id,
|
|
664
|
-
agent_id: row.agent_id,
|
|
665
|
-
machine_id: row.machine_id ?? getTeamMachineId(),
|
|
666
|
-
name: row.name,
|
|
667
|
-
display_name: row.display_name,
|
|
668
|
-
description: row.description,
|
|
669
|
-
status: row.status,
|
|
670
|
-
generation: row.generation,
|
|
671
|
-
candidate_id: row.candidate_id ?? null,
|
|
672
|
-
source_ids: row.source_ids ?? "[]",
|
|
673
|
-
path: row.path,
|
|
674
|
-
usage_count: row.usage_count,
|
|
675
|
-
last_used_at: row.last_used_at ?? null,
|
|
676
|
-
created_at: row.created_at,
|
|
677
|
-
updated_at: row.updated_at,
|
|
678
|
-
properties: row.properties ?? "{}",
|
|
679
|
-
synced_at: row.synced_at ?? null
|
|
680
|
-
};
|
|
681
|
-
}
|
|
682
|
-
function buildWhere2(options) {
|
|
683
|
-
const conditions = [];
|
|
684
|
-
const params = [];
|
|
685
|
-
if (options.agent_id !== void 0) {
|
|
686
|
-
conditions.push(`agent_id = ?`);
|
|
687
|
-
params.push(options.agent_id);
|
|
688
|
-
}
|
|
689
|
-
if (options.status !== void 0) {
|
|
690
|
-
conditions.push(`status = ?`);
|
|
691
|
-
params.push(options.status);
|
|
692
|
-
}
|
|
693
|
-
return {
|
|
694
|
-
where: conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "",
|
|
695
|
-
params
|
|
696
|
-
};
|
|
697
|
-
}
|
|
698
|
-
function insertSkillRecord(data) {
|
|
699
|
-
const db = getDatabase();
|
|
700
|
-
db.prepare(
|
|
701
|
-
`INSERT INTO skill_records (
|
|
702
|
-
id, agent_id, machine_id, name, display_name,
|
|
703
|
-
description, status, generation, candidate_id,
|
|
704
|
-
source_ids, path, created_at, updated_at, properties
|
|
705
|
-
) VALUES (
|
|
706
|
-
?, ?, ?, ?, ?,
|
|
707
|
-
?, ?, ?, ?,
|
|
708
|
-
?, ?, ?, ?, ?
|
|
709
|
-
)`
|
|
710
|
-
).run(
|
|
711
|
-
data.id,
|
|
712
|
-
data.agent_id,
|
|
713
|
-
data.machine_id ?? getTeamMachineId(),
|
|
714
|
-
data.name,
|
|
715
|
-
data.display_name,
|
|
716
|
-
data.description,
|
|
717
|
-
data.status ?? DEFAULT_STATUS3,
|
|
718
|
-
data.generation ?? DEFAULT_GENERATION,
|
|
719
|
-
data.candidate_id ?? null,
|
|
720
|
-
data.source_ids ?? "[]",
|
|
721
|
-
data.path,
|
|
722
|
-
data.created_at,
|
|
723
|
-
data.updated_at,
|
|
724
|
-
data.properties ?? "{}"
|
|
725
|
-
);
|
|
726
|
-
const raw = db.prepare(`SELECT ${SELECT_COLUMNS3} FROM skill_records WHERE id = ?`).get(data.id);
|
|
727
|
-
if (!raw) throw new Error(`Failed to insert skill record: ${data.id}`);
|
|
728
|
-
const row = toSkillRecordRow(raw);
|
|
729
|
-
syncRow("skill_records", row);
|
|
730
|
-
return row;
|
|
731
|
-
}
|
|
732
|
-
function getSkillRecord(id) {
|
|
733
|
-
const db = getDatabase();
|
|
734
|
-
const row = db.prepare(
|
|
735
|
-
`SELECT ${SELECT_COLUMNS3} FROM skill_records WHERE id = ?`
|
|
736
|
-
).get(id);
|
|
737
|
-
if (!row) return null;
|
|
738
|
-
return toSkillRecordRow(row);
|
|
739
|
-
}
|
|
740
|
-
function getSkillRecordByName(name) {
|
|
741
|
-
const db = getDatabase();
|
|
742
|
-
const row = db.prepare(
|
|
743
|
-
`SELECT ${SELECT_COLUMNS3} FROM skill_records WHERE name = ?`
|
|
744
|
-
).get(name);
|
|
745
|
-
if (!row) return null;
|
|
746
|
-
return toSkillRecordRow(row);
|
|
747
|
-
}
|
|
748
|
-
function listSkillRecords(options = {}) {
|
|
749
|
-
const db = getDatabase();
|
|
750
|
-
const { where, params } = buildWhere2(options);
|
|
751
|
-
const limit = options.limit ?? DEFAULT_LIST_LIMIT;
|
|
752
|
-
const offset = options.offset ?? 0;
|
|
753
|
-
const rows = db.prepare(
|
|
754
|
-
`SELECT ${SELECT_COLUMNS3}
|
|
755
|
-
FROM skill_records
|
|
756
|
-
${where}
|
|
757
|
-
ORDER BY updated_at DESC
|
|
758
|
-
LIMIT ?
|
|
759
|
-
OFFSET ?`
|
|
760
|
-
).all(...params, limit, offset);
|
|
761
|
-
return rows.map(toSkillRecordRow);
|
|
762
|
-
}
|
|
763
|
-
function updateSkillRecord(id, updates) {
|
|
764
|
-
const db = getDatabase();
|
|
765
|
-
const setClauses = [];
|
|
766
|
-
const params = [];
|
|
767
|
-
const fieldMap = {
|
|
768
|
-
display_name: "display_name",
|
|
769
|
-
description: "description",
|
|
770
|
-
status: "status",
|
|
771
|
-
generation: "generation",
|
|
772
|
-
source_ids: "source_ids",
|
|
773
|
-
path: "path",
|
|
774
|
-
usage_count: "usage_count",
|
|
775
|
-
last_used_at: "last_used_at",
|
|
776
|
-
updated_at: "updated_at",
|
|
777
|
-
properties: "properties"
|
|
778
|
-
};
|
|
779
|
-
for (const [key, column] of Object.entries(fieldMap)) {
|
|
780
|
-
if (key in updates) {
|
|
781
|
-
setClauses.push(`${column} = ?`);
|
|
782
|
-
params.push(updates[key] ?? null);
|
|
783
|
-
}
|
|
784
|
-
}
|
|
785
|
-
if (setClauses.length === 0) return getSkillRecord(id);
|
|
786
|
-
params.push(id);
|
|
787
|
-
db.prepare(
|
|
788
|
-
`UPDATE skill_records
|
|
789
|
-
SET ${setClauses.join(", ")}
|
|
790
|
-
WHERE id = ?`
|
|
791
|
-
).run(...params);
|
|
792
|
-
const updated = getSkillRecord(id);
|
|
793
|
-
if (updated) syncRow("skill_records", updated);
|
|
794
|
-
return updated;
|
|
795
|
-
}
|
|
796
|
-
function incrementSkillUsageCount(id, now) {
|
|
797
|
-
const db = getDatabase();
|
|
798
|
-
db.prepare(
|
|
799
|
-
`UPDATE skill_records SET usage_count = usage_count + 1, last_used_at = ?, updated_at = ? WHERE id = ?`
|
|
800
|
-
).run(now, now, id);
|
|
801
|
-
}
|
|
802
|
-
function listSkillRecordsWithCount(options = {}) {
|
|
803
|
-
const items = listSkillRecords(options);
|
|
804
|
-
const total = countSkillRecords(options);
|
|
805
|
-
return { items, total };
|
|
806
|
-
}
|
|
807
|
-
function countSkillRecords(options = {}) {
|
|
808
|
-
const db = getDatabase();
|
|
809
|
-
const { where, params } = buildWhere2(options);
|
|
810
|
-
const row = db.prepare(
|
|
811
|
-
`SELECT COUNT(*) as count FROM skill_records ${where}`
|
|
812
|
-
).get(...params);
|
|
813
|
-
return row.count;
|
|
814
|
-
}
|
|
815
|
-
function deleteSkillRecordCascade(idOrName) {
|
|
816
|
-
const db = getDatabase();
|
|
817
|
-
const record = getSkillRecord(idOrName) ?? getSkillRecordByName(idOrName);
|
|
818
|
-
if (!record) return null;
|
|
819
|
-
db.transaction(() => {
|
|
820
|
-
db.prepare("DELETE FROM skill_lineage WHERE skill_id = ?").run(record.id);
|
|
821
|
-
db.prepare("DELETE FROM skill_usage WHERE skill_id = ?").run(record.id);
|
|
822
|
-
if (record.candidate_id) {
|
|
823
|
-
db.prepare(
|
|
824
|
-
`UPDATE skill_candidates SET status = 'dismissed', skill_id = NULL, updated_at = ? WHERE id = ?`
|
|
825
|
-
).run(Math.floor(Date.now() / 1e3), record.candidate_id);
|
|
826
|
-
}
|
|
827
|
-
db.prepare(
|
|
828
|
-
`UPDATE skill_candidates SET status = 'dismissed', skill_id = NULL, updated_at = ? WHERE skill_id = ?`
|
|
829
|
-
).run(Math.floor(Date.now() / 1e3), record.id);
|
|
830
|
-
db.prepare("DELETE FROM skill_records WHERE id = ?").run(record.id);
|
|
831
|
-
})();
|
|
832
|
-
return { id: record.id, name: record.name };
|
|
833
|
-
}
|
|
834
|
-
|
|
835
|
-
// src/db/queries/digest-extracts.ts
|
|
836
|
-
var EXTRACT_COLUMNS = [
|
|
837
|
-
"id",
|
|
838
|
-
"agent_id",
|
|
839
|
-
"tier",
|
|
840
|
-
"content",
|
|
841
|
-
"substrate_hash",
|
|
842
|
-
"generated_at",
|
|
843
|
-
"machine_id",
|
|
844
|
-
"synced_at"
|
|
845
|
-
];
|
|
846
|
-
var SELECT_COLUMNS4 = EXTRACT_COLUMNS.join(", ");
|
|
847
|
-
function toDigestExtractRow(row) {
|
|
848
|
-
return {
|
|
849
|
-
id: row.id,
|
|
850
|
-
agent_id: row.agent_id,
|
|
851
|
-
tier: row.tier,
|
|
852
|
-
content: row.content,
|
|
853
|
-
substrate_hash: row.substrate_hash ?? null,
|
|
854
|
-
generated_at: row.generated_at,
|
|
855
|
-
machine_id: row.machine_id ?? "local",
|
|
856
|
-
synced_at: row.synced_at ?? null
|
|
857
|
-
};
|
|
858
|
-
}
|
|
859
|
-
function upsertDigestExtract(data) {
|
|
860
|
-
const db = getDatabase();
|
|
861
|
-
db.prepare(
|
|
862
|
-
`INSERT INTO digest_extracts (agent_id, tier, content, generated_at)
|
|
863
|
-
VALUES (?, ?, ?, ?)
|
|
864
|
-
ON CONFLICT (agent_id, tier) DO UPDATE SET
|
|
865
|
-
content = EXCLUDED.content,
|
|
866
|
-
generated_at = EXCLUDED.generated_at`
|
|
867
|
-
).run(data.agent_id, data.tier, data.content, data.generated_at);
|
|
868
|
-
const row = db.prepare(
|
|
869
|
-
`SELECT ${SELECT_COLUMNS4} FROM digest_extracts WHERE agent_id = ? AND tier = ?`
|
|
870
|
-
).get(data.agent_id, data.tier);
|
|
871
|
-
return toDigestExtractRow(row);
|
|
872
|
-
}
|
|
873
|
-
function getDigestExtract(agentId, tier) {
|
|
874
|
-
const db = getDatabase();
|
|
875
|
-
const row = db.prepare(
|
|
876
|
-
`SELECT ${SELECT_COLUMNS4} FROM digest_extracts
|
|
877
|
-
WHERE agent_id = ? AND tier = ?`
|
|
878
|
-
).get(agentId, tier);
|
|
879
|
-
if (!row) return null;
|
|
880
|
-
return toDigestExtractRow(row);
|
|
881
|
-
}
|
|
882
|
-
function listDigestExtracts(agentId) {
|
|
883
|
-
const db = getDatabase();
|
|
884
|
-
const tierPlaceholders = DIGEST_TIERS.map(() => "?").join(", ");
|
|
885
|
-
const rows = db.prepare(
|
|
886
|
-
`SELECT ${SELECT_COLUMNS4}
|
|
887
|
-
FROM digest_extracts
|
|
888
|
-
WHERE agent_id = ? AND tier IN (${tierPlaceholders})
|
|
889
|
-
ORDER BY tier ASC`
|
|
890
|
-
).all(agentId, ...DIGEST_TIERS);
|
|
891
|
-
return rows.map(toDigestExtractRow);
|
|
892
|
-
}
|
|
893
|
-
|
|
894
|
-
// src/db/queries/agent-state.ts
|
|
895
|
-
var STATE_COLUMNS = [
|
|
896
|
-
"agent_id",
|
|
897
|
-
"key",
|
|
898
|
-
"value",
|
|
899
|
-
"updated_at"
|
|
900
|
-
];
|
|
901
|
-
var SELECT_COLUMNS5 = STATE_COLUMNS.join(", ");
|
|
902
|
-
function toAgentStateRow(row) {
|
|
903
|
-
return {
|
|
904
|
-
agent_id: row.agent_id,
|
|
905
|
-
key: row.key,
|
|
906
|
-
value: row.value,
|
|
907
|
-
updated_at: row.updated_at
|
|
908
|
-
};
|
|
909
|
-
}
|
|
910
|
-
function getState(agentId, key) {
|
|
911
|
-
const db = getDatabase();
|
|
912
|
-
const row = db.prepare(
|
|
913
|
-
`SELECT ${SELECT_COLUMNS5} FROM agent_state WHERE agent_id = ? AND key = ?`
|
|
914
|
-
).get(agentId, key);
|
|
915
|
-
if (!row) return null;
|
|
916
|
-
return toAgentStateRow(row);
|
|
917
|
-
}
|
|
918
|
-
function setState(agentId, key, value, updatedAt) {
|
|
919
|
-
const db = getDatabase();
|
|
920
|
-
db.prepare(
|
|
921
|
-
`INSERT INTO agent_state (agent_id, key, value, updated_at)
|
|
922
|
-
VALUES (?, ?, ?, ?)
|
|
923
|
-
ON CONFLICT (agent_id, key) DO UPDATE SET
|
|
924
|
-
value = EXCLUDED.value,
|
|
925
|
-
updated_at = EXCLUDED.updated_at`
|
|
926
|
-
).run(agentId, key, value, updatedAt);
|
|
927
|
-
return toAgentStateRow(
|
|
928
|
-
db.prepare(`SELECT ${SELECT_COLUMNS5} FROM agent_state WHERE agent_id = ? AND key = ?`).get(agentId, key)
|
|
929
|
-
);
|
|
930
|
-
}
|
|
931
|
-
function getStatesForAgent(agentId) {
|
|
932
|
-
const db = getDatabase();
|
|
933
|
-
const rows = db.prepare(
|
|
934
|
-
`SELECT ${SELECT_COLUMNS5}
|
|
935
|
-
FROM agent_state
|
|
936
|
-
WHERE agent_id = ?
|
|
937
|
-
ORDER BY key ASC`
|
|
938
|
-
).all(agentId);
|
|
939
|
-
return rows.map(toAgentStateRow);
|
|
940
|
-
}
|
|
941
|
-
|
|
942
|
-
// src/agent/tools/skill-validator.ts
|
|
943
|
-
var import_yaml = __toESM(require_dist(), 1);
|
|
944
|
-
var MAX_SKILL_LINES = 800;
|
|
945
|
-
var MAX_SKILL_DESCRIPTION_CHARS = 1024;
|
|
946
|
-
var FRONTMATTER_PATTERN = /^---\n([\s\S]*?)\n---/;
|
|
947
|
-
var REQUIRED_FRONTMATTER_FIELDS = ["name", "description", "managed_by", "user-invocable", "allowed-tools"];
|
|
948
|
-
var PROTECTED_FRONTMATTER_FIELDS = ["user-invocable", "allowed-tools"];
|
|
949
|
-
var ALLOWED_CLAUDE_CODE_TOOLS = /* @__PURE__ */ new Set([
|
|
950
|
-
"Read",
|
|
951
|
-
"Edit",
|
|
952
|
-
"Write",
|
|
953
|
-
"MultiEdit",
|
|
954
|
-
"Bash",
|
|
955
|
-
"Grep",
|
|
956
|
-
"Glob",
|
|
957
|
-
"NotebookRead",
|
|
958
|
-
"NotebookEdit",
|
|
959
|
-
"WebFetch",
|
|
960
|
-
"WebSearch",
|
|
961
|
-
"Task",
|
|
962
|
-
"TodoWrite"
|
|
963
|
-
]);
|
|
964
|
-
function extractFrontmatterBlock(content) {
|
|
965
|
-
return content.match(FRONTMATTER_PATTERN)?.[1];
|
|
966
|
-
}
|
|
967
|
-
function parseFrontmatter(content) {
|
|
968
|
-
const block = extractFrontmatterBlock(content);
|
|
969
|
-
if (!block) return null;
|
|
970
|
-
const parsed = (0, import_yaml.parse)(block);
|
|
971
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
972
|
-
return null;
|
|
973
|
-
}
|
|
974
|
-
return parsed;
|
|
975
|
-
}
|
|
976
|
-
function normalizeFrontmatterValue(value) {
|
|
977
|
-
if (typeof value === "string") return value;
|
|
978
|
-
if (typeof value === "boolean" || typeof value === "number") return String(value);
|
|
979
|
-
if (Array.isArray(value)) {
|
|
980
|
-
const items = value.map((item) => typeof item === "string" ? item : null).filter((item) => item !== null);
|
|
981
|
-
return items.length > 0 ? items.join(", ") : void 0;
|
|
982
|
-
}
|
|
983
|
-
return void 0;
|
|
984
|
-
}
|
|
985
|
-
function extractFrontmatterField(content, field) {
|
|
986
|
-
try {
|
|
987
|
-
const parsed = parseFrontmatter(content);
|
|
988
|
-
const normalized = normalizeFrontmatterValue(parsed?.[field]);
|
|
989
|
-
if (normalized !== void 0) return normalized;
|
|
990
|
-
} catch {
|
|
991
|
-
}
|
|
992
|
-
const fm = extractFrontmatterBlock(content);
|
|
993
|
-
if (!fm) return void 0;
|
|
994
|
-
const match = fm.match(new RegExp(`^${field}:\\s*(.+)$`, "m"));
|
|
995
|
-
if (match) return match[1].trim();
|
|
996
|
-
const blockMatch = fm.match(new RegExp(`^${field}:\\s*$`, "m"));
|
|
997
|
-
if (blockMatch) {
|
|
998
|
-
const startIdx = fm.indexOf(blockMatch[0]) + blockMatch[0].length;
|
|
999
|
-
const remaining = fm.slice(startIdx);
|
|
1000
|
-
const items = [];
|
|
1001
|
-
for (const line of remaining.split("\n")) {
|
|
1002
|
-
const itemMatch = line.match(/^\s+-\s+(.+)$/);
|
|
1003
|
-
if (!itemMatch) break;
|
|
1004
|
-
items.push(itemMatch[1].trim());
|
|
1005
|
-
}
|
|
1006
|
-
if (items.length > 0) return items.join(", ");
|
|
1007
|
-
}
|
|
1008
|
-
return void 0;
|
|
1009
|
-
}
|
|
1010
|
-
function parseAllowedTools(rawValue) {
|
|
1011
|
-
if (!rawValue) return null;
|
|
1012
|
-
let stripped = rawValue.trim();
|
|
1013
|
-
if (stripped.length === 0) return null;
|
|
1014
|
-
if (stripped.startsWith("[") && stripped.endsWith("]")) {
|
|
1015
|
-
stripped = stripped.slice(1, -1).trim();
|
|
1016
|
-
}
|
|
1017
|
-
if (stripped.length === 0) return null;
|
|
1018
|
-
const parts = stripped.split(",").map((s) => s.trim().replace(/^['"]|['"]$/g, "")).filter((s) => s.length > 0);
|
|
1019
|
-
if (parts.length === 0) return null;
|
|
1020
|
-
const sentinels = /* @__PURE__ */ new Set(["None", "none", "null", "Null", "~"]);
|
|
1021
|
-
if (parts.some((p) => sentinels.has(p))) return null;
|
|
1022
|
-
return parts;
|
|
1023
|
-
}
|
|
1024
|
-
function stemToken(word) {
|
|
1025
|
-
let w = word;
|
|
1026
|
-
if (w.length > 5 && w.endsWith("ing")) w = w.slice(0, -3);
|
|
1027
|
-
else if (w.length > 5 && w.endsWith("ed")) w = w.slice(0, -2);
|
|
1028
|
-
if (w.length > 4 && w.endsWith("s")) w = w.slice(0, -1);
|
|
1029
|
-
if (w.length > 4 && w.endsWith("e")) w = w.slice(0, -1);
|
|
1030
|
-
return w;
|
|
1031
|
-
}
|
|
1032
|
-
var STOPWORDS = /* @__PURE__ */ new Set([
|
|
1033
|
-
"the",
|
|
1034
|
-
"a",
|
|
1035
|
-
"an",
|
|
1036
|
-
"and",
|
|
1037
|
-
"or",
|
|
1038
|
-
"but",
|
|
1039
|
-
"is",
|
|
1040
|
-
"are",
|
|
1041
|
-
"was",
|
|
1042
|
-
"were",
|
|
1043
|
-
"be",
|
|
1044
|
-
"been",
|
|
1045
|
-
"being",
|
|
1046
|
-
"have",
|
|
1047
|
-
"has",
|
|
1048
|
-
"had",
|
|
1049
|
-
"do",
|
|
1050
|
-
"does",
|
|
1051
|
-
"did",
|
|
1052
|
-
"will",
|
|
1053
|
-
"would",
|
|
1054
|
-
"should",
|
|
1055
|
-
"could",
|
|
1056
|
-
"may",
|
|
1057
|
-
"might",
|
|
1058
|
-
"must",
|
|
1059
|
-
"can",
|
|
1060
|
-
"this",
|
|
1061
|
-
"that",
|
|
1062
|
-
"these",
|
|
1063
|
-
"those",
|
|
1064
|
-
"with",
|
|
1065
|
-
"from",
|
|
1066
|
-
"into",
|
|
1067
|
-
"onto",
|
|
1068
|
-
"for",
|
|
1069
|
-
"when",
|
|
1070
|
-
"where",
|
|
1071
|
-
"which",
|
|
1072
|
-
"what",
|
|
1073
|
-
"who",
|
|
1074
|
-
"how",
|
|
1075
|
-
"why",
|
|
1076
|
-
"use",
|
|
1077
|
-
"uses",
|
|
1078
|
-
"used",
|
|
1079
|
-
"using",
|
|
1080
|
-
"not",
|
|
1081
|
-
"also",
|
|
1082
|
-
"than",
|
|
1083
|
-
"then",
|
|
1084
|
-
"ensure",
|
|
1085
|
-
"ensures",
|
|
1086
|
-
"make",
|
|
1087
|
-
"makes"
|
|
1088
|
-
]);
|
|
1089
|
-
function tokenSet(text) {
|
|
1090
|
-
return new Set(
|
|
1091
|
-
text.toLowerCase().replace(/[^a-z0-9_\s]/g, " ").split(/\s+/).filter((w) => w.length >= 4 && !STOPWORDS.has(w)).map(stemToken)
|
|
1092
|
-
);
|
|
1093
|
-
}
|
|
1094
|
-
function intersectionSize(a, b) {
|
|
1095
|
-
let count = 0;
|
|
1096
|
-
for (const token of a) {
|
|
1097
|
-
if (b.has(token)) count++;
|
|
1098
|
-
}
|
|
1099
|
-
return count;
|
|
1100
|
-
}
|
|
1101
|
-
function descriptionSimilarity(a, b) {
|
|
1102
|
-
const aTokens = tokenSet(a);
|
|
1103
|
-
const bTokens = tokenSet(b);
|
|
1104
|
-
if (aTokens.size === 0 || bTokens.size === 0) return 0;
|
|
1105
|
-
const intersection = intersectionSize(aTokens, bTokens);
|
|
1106
|
-
const union = aTokens.size + bTokens.size - intersection;
|
|
1107
|
-
return union === 0 ? 0 : intersection / union;
|
|
1108
|
-
}
|
|
1109
|
-
function topicOverlapSimilarity(a, b, minTokens = 3) {
|
|
1110
|
-
const aTokens = tokenSet(a);
|
|
1111
|
-
const bTokens = tokenSet(b);
|
|
1112
|
-
if (aTokens.size < minTokens || bTokens.size < minTokens) return 0;
|
|
1113
|
-
const intersection = intersectionSize(aTokens, bTokens);
|
|
1114
|
-
const smaller = Math.min(aTokens.size, bTokens.size);
|
|
1115
|
-
return smaller === 0 ? 0 : intersection / smaller;
|
|
1116
|
-
}
|
|
1117
|
-
var DESCRIPTION_DUPLICATE_THRESHOLD = 0.4;
|
|
1118
|
-
var TOPIC_OVERLAP_THRESHOLD = 0.6;
|
|
1119
|
-
function checkFrontmatterPreservation(existing, incoming) {
|
|
1120
|
-
const violations = [];
|
|
1121
|
-
for (const field of PROTECTED_FRONTMATTER_FIELDS) {
|
|
1122
|
-
const oldValue = extractFrontmatterField(existing, field);
|
|
1123
|
-
const newValue = extractFrontmatterField(incoming, field);
|
|
1124
|
-
if (oldValue === void 0 || newValue === void 0) continue;
|
|
1125
|
-
if (field === "allowed-tools") {
|
|
1126
|
-
const oldParsed = parseAllowedTools(oldValue);
|
|
1127
|
-
const newParsed = parseAllowedTools(newValue);
|
|
1128
|
-
if (oldParsed && newParsed) {
|
|
1129
|
-
const oldSet = new Set(oldParsed);
|
|
1130
|
-
const newSet = new Set(newParsed);
|
|
1131
|
-
const changed = oldSet.size !== newSet.size || [...oldSet].some((t) => !newSet.has(t));
|
|
1132
|
-
if (changed) {
|
|
1133
|
-
violations.push(`${field}: was [${oldParsed.join(", ")}], changed to [${newParsed.join(", ")}]`);
|
|
1134
|
-
}
|
|
1135
|
-
continue;
|
|
1136
|
-
}
|
|
1137
|
-
}
|
|
1138
|
-
if (oldValue !== newValue) {
|
|
1139
|
-
violations.push(`${field}: was "${oldValue}", changed to "${newValue}"`);
|
|
1140
|
-
}
|
|
1141
|
-
}
|
|
1142
|
-
const oldDesc = extractFrontmatterField(existing, "description");
|
|
1143
|
-
const newDesc = extractFrontmatterField(incoming, "description");
|
|
1144
|
-
if (oldDesc && newDesc && newDesc.length < oldDesc.length * 0.9) {
|
|
1145
|
-
violations.push(
|
|
1146
|
-
`description shortened from ${oldDesc.length} to ${newDesc.length} chars (${Math.round((1 - newDesc.length / oldDesc.length) * 100)}% reduction). Descriptions are the primary triggering mechanism \u2014 do not shorten them.`
|
|
1147
|
-
);
|
|
1148
|
-
}
|
|
1149
|
-
return violations;
|
|
1150
|
-
}
|
|
1151
|
-
function validateSkillContent(content, dirName) {
|
|
1152
|
-
const issues = [];
|
|
1153
|
-
const frontmatter = extractFrontmatterBlock(content);
|
|
1154
|
-
if (!frontmatter) {
|
|
1155
|
-
issues.push("Missing YAML frontmatter (must start with --- and end with ---)");
|
|
1156
|
-
return issues;
|
|
1157
|
-
}
|
|
1158
|
-
let parsedFrontmatter = null;
|
|
1159
|
-
try {
|
|
1160
|
-
parsedFrontmatter = parseFrontmatter(content);
|
|
1161
|
-
} catch (error) {
|
|
1162
|
-
const message = error instanceof Error ? error.message.split("\n")[0] : String(error);
|
|
1163
|
-
issues.push(`Invalid YAML frontmatter: ${message}`);
|
|
1164
|
-
return issues;
|
|
1165
|
-
}
|
|
1166
|
-
if (!parsedFrontmatter) {
|
|
1167
|
-
issues.push("Invalid YAML frontmatter: top-level frontmatter must be a mapping/object");
|
|
1168
|
-
return issues;
|
|
1169
|
-
}
|
|
1170
|
-
for (const field of REQUIRED_FRONTMATTER_FIELDS) {
|
|
1171
|
-
if (!(field in parsedFrontmatter)) {
|
|
1172
|
-
issues.push(`Missing required frontmatter field: ${field}`);
|
|
1173
|
-
}
|
|
1174
|
-
}
|
|
1175
|
-
const nameValue = normalizeFrontmatterValue(parsedFrontmatter.name);
|
|
1176
|
-
if (nameValue && !nameValue.startsWith("myco:")) {
|
|
1177
|
-
issues.push(`Skill name must start with "myco:" prefix. Got: "${nameValue}"`);
|
|
1178
|
-
}
|
|
1179
|
-
if (nameValue && nameValue !== `myco:${dirName}`) {
|
|
1180
|
-
issues.push(`Skill name must match directory name. Expected "myco:${dirName}", got "${nameValue}"`);
|
|
1181
|
-
}
|
|
1182
|
-
const managedByValue = normalizeFrontmatterValue(parsedFrontmatter.managed_by);
|
|
1183
|
-
if (managedByValue && managedByValue !== "myco") {
|
|
1184
|
-
issues.push(`managed_by must be "myco". Got: "${managedByValue}"`);
|
|
1185
|
-
}
|
|
1186
|
-
const descriptionValue = normalizeFrontmatterValue(parsedFrontmatter.description);
|
|
1187
|
-
if (descriptionValue && descriptionValue.length > MAX_SKILL_DESCRIPTION_CHARS) {
|
|
1188
|
-
issues.push(
|
|
1189
|
-
`description exceeds maximum length of ${MAX_SKILL_DESCRIPTION_CHARS} characters (got ${descriptionValue.length})`
|
|
1190
|
-
);
|
|
1191
|
-
}
|
|
1192
|
-
const rawAllowedTools = normalizeFrontmatterValue(parsedFrontmatter["allowed-tools"]);
|
|
1193
|
-
if (rawAllowedTools) {
|
|
1194
|
-
const rawValue = rawAllowedTools;
|
|
1195
|
-
if (rawValue.includes("vault_")) {
|
|
1196
|
-
issues.push(
|
|
1197
|
-
"allowed-tools contains vault agent tool names (vault_*). Skills run in Claude Code sessions -- use Claude Code tool names instead: Read, Edit, Write, Bash, Grep, Glob"
|
|
1198
|
-
);
|
|
1199
|
-
} else {
|
|
1200
|
-
const parsed = parseAllowedTools(rawValue);
|
|
1201
|
-
if (parsed === null) {
|
|
1202
|
-
issues.push(
|
|
1203
|
-
`allowed-tools value is malformed or empty: "${rawValue}". Provide a comma-separated list of Claude Code tools, e.g. "Read, Edit, Write, Bash, Grep, Glob". Use the narrowest set the skill actually needs.`
|
|
1204
|
-
);
|
|
1205
|
-
} else {
|
|
1206
|
-
const unknown = parsed.filter((t) => !ALLOWED_CLAUDE_CODE_TOOLS.has(t));
|
|
1207
|
-
if (unknown.length > 0) {
|
|
1208
|
-
issues.push(
|
|
1209
|
-
`allowed-tools contains unknown tool name(s): ${unknown.join(", ")}. Valid Claude Code tools: ${[...ALLOWED_CLAUDE_CODE_TOOLS].join(", ")}.`
|
|
1210
|
-
);
|
|
1211
|
-
}
|
|
1212
|
-
}
|
|
1213
|
-
}
|
|
1214
|
-
}
|
|
1215
|
-
const listToolLines = frontmatter.match(/^\s+-\s+vault_\w+/gm);
|
|
1216
|
-
if (listToolLines) {
|
|
1217
|
-
issues.push(
|
|
1218
|
-
"allowed-tools contains vault agent tool names (vault_*). Skills run in Claude Code sessions -- use Claude Code tool names instead: Read, Edit, Write, Bash, Grep, Glob"
|
|
1219
|
-
);
|
|
1220
|
-
}
|
|
1221
|
-
const lineCount = content.split("\n").length;
|
|
1222
|
-
if (lineCount > MAX_SKILL_LINES) {
|
|
1223
|
-
issues.push(`Skill is ${lineCount} lines (max ${MAX_SKILL_LINES})`);
|
|
1224
|
-
}
|
|
1225
|
-
return issues;
|
|
1226
|
-
}
|
|
1227
|
-
|
|
1228
|
-
// src/agent/instruction-builders.ts
|
|
1229
|
-
var SKILL_GENERATE_TASK = "skill-generate";
|
|
1230
|
-
var SKILL_EVOLVE_TASK = "skill-evolve";
|
|
1231
|
-
var SKILL_SURVEY_TASK = "skill-survey";
|
|
1232
|
-
var SURVEY_MAX_WISDOM_SPORES = 30;
|
|
1233
|
-
var SURVEY_MAX_SESSIONS = 15;
|
|
1234
|
-
var SURVEY_MIN_SETTLED_SESSIONS = 2;
|
|
1235
|
-
var SURVEY_MIN_SETTLED_ACTIVE_SPORES = 3;
|
|
1236
|
-
var SURVEY_WATERMARK_KEY = "skill-survey-watermark";
|
|
1237
|
-
function getSkillSurveyEligibility(agentId) {
|
|
1238
|
-
const settledSessionCount = countSessions({ includeActive: false });
|
|
1239
|
-
if (settledSessionCount < SURVEY_MIN_SETTLED_SESSIONS) {
|
|
1240
|
-
return { eligible: false, reason: "insufficient-settled-sessions" };
|
|
1241
|
-
}
|
|
1242
|
-
const settledSporeCount = countSpores({ includeActive: false, status: "active" });
|
|
1243
|
-
if (settledSporeCount < SURVEY_MIN_SETTLED_ACTIVE_SPORES) {
|
|
1244
|
-
return { eligible: false, reason: "insufficient-settled-spores" };
|
|
1245
|
-
}
|
|
1246
|
-
if (!agentId) {
|
|
1247
|
-
return { eligible: true, reason: null };
|
|
1248
|
-
}
|
|
1249
|
-
const watermarkState = getState(agentId, SURVEY_WATERMARK_KEY);
|
|
1250
|
-
const watermarkEpoch = watermarkState ? Number(watermarkState.value) : 0;
|
|
1251
|
-
if (watermarkEpoch <= 0) {
|
|
1252
|
-
return { eligible: true, reason: null };
|
|
1253
|
-
}
|
|
1254
|
-
const hasNewSettledSessions = countSessions({
|
|
1255
|
-
includeActive: false,
|
|
1256
|
-
since: watermarkEpoch
|
|
1257
|
-
}) > 0;
|
|
1258
|
-
if (hasNewSettledSessions) {
|
|
1259
|
-
return { eligible: true, reason: null };
|
|
1260
|
-
}
|
|
1261
|
-
const hasNewSettledSpores = countSpores({
|
|
1262
|
-
includeActive: false,
|
|
1263
|
-
status: "active",
|
|
1264
|
-
since: watermarkEpoch
|
|
1265
|
-
}) > 0;
|
|
1266
|
-
if (hasNewSettledSpores) {
|
|
1267
|
-
return { eligible: true, reason: null };
|
|
1268
|
-
}
|
|
1269
|
-
return { eligible: false, reason: "no-new-settled-knowledge" };
|
|
1270
|
-
}
|
|
1271
|
-
function buildSkillGenerateInstruction() {
|
|
1272
|
-
const candidates = listCandidates({ status: "approved", limit: 1 });
|
|
1273
|
-
if (candidates.length === 0) return void 0;
|
|
1274
|
-
const c = candidates[0];
|
|
1275
|
-
const parts = [
|
|
1276
|
-
`candidate_id: ${c.id}`,
|
|
1277
|
-
`topic: ${c.topic}`,
|
|
1278
|
-
`confidence: ${c.confidence}`,
|
|
1279
|
-
`rationale: ${c.rationale}`,
|
|
1280
|
-
"",
|
|
1281
|
-
"## Source Material"
|
|
1282
|
-
];
|
|
1283
|
-
let sourceIds = [];
|
|
1284
|
-
try {
|
|
1285
|
-
sourceIds = JSON.parse(c.source_ids || "[]");
|
|
1286
|
-
} catch {
|
|
1287
|
-
}
|
|
1288
|
-
for (const src of sourceIds) {
|
|
1289
|
-
if (src.type === "spore") {
|
|
1290
|
-
const spore = getSpore(src.id);
|
|
1291
|
-
if (spore) {
|
|
1292
|
-
parts.push(`
|
|
1293
|
-
### Spore: ${src.id} (${spore.observation_type}, importance ${spore.importance})`);
|
|
1294
|
-
parts.push(spore.content);
|
|
1295
|
-
if (spore.context) parts.push(`Context: ${spore.context}`);
|
|
1296
|
-
if (spore.tags) parts.push(`Tags: ${spore.tags}`);
|
|
1297
|
-
}
|
|
1298
|
-
} else if (src.type === "session") {
|
|
1299
|
-
const session = getSession(src.id);
|
|
1300
|
-
if (session) {
|
|
1301
|
-
parts.push(`
|
|
1302
|
-
### Session: ${src.id}`);
|
|
1303
|
-
if (session.title) parts.push(`Title: ${session.title}`);
|
|
1304
|
-
if (session.summary) parts.push(session.summary);
|
|
1305
|
-
}
|
|
1306
|
-
}
|
|
1307
|
-
}
|
|
1308
|
-
return {
|
|
1309
|
-
instruction: parts.join("\n"),
|
|
1310
|
-
context: { candidate_id: c.id }
|
|
1311
|
-
};
|
|
1312
|
-
}
|
|
1313
|
-
function buildSkillSurveyInstruction(agentId) {
|
|
1314
|
-
const eligibility = getSkillSurveyEligibility(agentId);
|
|
1315
|
-
if (!eligibility.eligible) {
|
|
1316
|
-
return void 0;
|
|
1317
|
-
}
|
|
1318
|
-
const now = epochSeconds();
|
|
1319
|
-
const watermarkState = getState(agentId, SURVEY_WATERMARK_KEY);
|
|
1320
|
-
const watermarkEpoch = watermarkState ? Number(watermarkState.value) : 0;
|
|
1321
|
-
const sinceFilter = watermarkEpoch > 0 ? { since: watermarkEpoch } : {};
|
|
1322
|
-
const parts = [
|
|
1323
|
-
"## Pre-assembled Vault Context",
|
|
1324
|
-
"",
|
|
1325
|
-
`Survey watermark: ${watermarkEpoch === 0 ? "first run (full scan)" : new Date(watermarkEpoch * 1e3).toISOString()}`,
|
|
1326
|
-
`Eligibility gate: requires ${SURVEY_MIN_SETTLED_SESSIONS}+ settled sessions and ${SURVEY_MIN_SETTLED_ACTIVE_SPORES}+ active spores from settled work.`,
|
|
1327
|
-
"",
|
|
1328
|
-
"CRITICAL: only propose project-specific procedural domains.",
|
|
1329
|
-
"- A valid domain must be anchored to this repository's components, files, commands, or conventions.",
|
|
1330
|
-
"- Generic engineering topics that could apply to any Node/TypeScript/React repo are not candidates.",
|
|
1331
|
-
"- If a domain fails repo-specificity or cross-session evidence, reject it instead of creating or updating a candidate.",
|
|
1332
|
-
""
|
|
1333
|
-
];
|
|
1334
|
-
const digests = listDigestExtracts(agentId);
|
|
1335
|
-
if (digests.length > 0) {
|
|
1336
|
-
const smallest = digests.reduce((a, b) => a.tier < b.tier ? a : b);
|
|
1337
|
-
parts.push("### Digest");
|
|
1338
|
-
parts.push(`**Tier ${smallest.tier}** (${smallest.content.length} chars):`);
|
|
1339
|
-
parts.push(smallest.content);
|
|
1340
|
-
parts.push("");
|
|
1341
|
-
}
|
|
1342
|
-
const wisdomSpores = listSpores({
|
|
1343
|
-
observation_type: "wisdom",
|
|
1344
|
-
limit: SURVEY_MAX_WISDOM_SPORES,
|
|
1345
|
-
includeActive: false,
|
|
1346
|
-
...sinceFilter
|
|
1347
|
-
});
|
|
1348
|
-
if (wisdomSpores.length > 0) {
|
|
1349
|
-
parts.push(`### Wisdom Spores (${wisdomSpores.length})`);
|
|
1350
|
-
for (const s of wisdomSpores) {
|
|
1351
|
-
parts.push(`- **${s.id}** (importance ${s.importance}): ${s.content.slice(0, 300)}`);
|
|
1352
|
-
}
|
|
1353
|
-
parts.push("");
|
|
1354
|
-
}
|
|
1355
|
-
const decisions = listSpores({
|
|
1356
|
-
observation_type: "decision",
|
|
1357
|
-
limit: 20,
|
|
1358
|
-
includeActive: false,
|
|
1359
|
-
...sinceFilter
|
|
1360
|
-
});
|
|
1361
|
-
const gotchas = listSpores({
|
|
1362
|
-
observation_type: "gotcha",
|
|
1363
|
-
limit: 10,
|
|
1364
|
-
includeActive: false,
|
|
1365
|
-
...sinceFilter
|
|
1366
|
-
});
|
|
1367
|
-
if (decisions.length > 0 || gotchas.length > 0) {
|
|
1368
|
-
parts.push(`### Decisions (${decisions.length}) & Gotchas (${gotchas.length})`);
|
|
1369
|
-
for (const s of [...decisions, ...gotchas]) {
|
|
1370
|
-
parts.push(`- **${s.observation_type}** ${s.id}: ${s.content.slice(0, 200)}`);
|
|
1371
|
-
}
|
|
1372
|
-
parts.push("");
|
|
1373
|
-
}
|
|
1374
|
-
const sessions = listSessions({
|
|
1375
|
-
limit: SURVEY_MAX_SESSIONS,
|
|
1376
|
-
includeActive: false,
|
|
1377
|
-
...sinceFilter
|
|
1378
|
-
});
|
|
1379
|
-
if (sessions.length > 0) {
|
|
1380
|
-
parts.push(`### Recent Sessions (${sessions.length})`);
|
|
1381
|
-
for (const s of sessions) {
|
|
1382
|
-
parts.push(`- **${s.id}**: ${s.title ?? "(untitled)"} \u2014 ${(s.summary ?? "").slice(0, 200)}`);
|
|
1383
|
-
}
|
|
1384
|
-
parts.push("");
|
|
1385
|
-
}
|
|
1386
|
-
const activeSkills = listSkillRecords({ status: "active", limit: 100 });
|
|
1387
|
-
parts.push(`### Active Skills (${activeSkills.length})`);
|
|
1388
|
-
for (const s of activeSkills) {
|
|
1389
|
-
parts.push(`- **${s.name}**: ${s.description.slice(0, 150)}`);
|
|
1390
|
-
}
|
|
1391
|
-
parts.push("");
|
|
1392
|
-
setState(agentId, SURVEY_WATERMARK_KEY, String(now), now);
|
|
1393
|
-
return { instruction: parts.join("\n") };
|
|
1394
|
-
}
|
|
1395
|
-
var SKILL_EVOLVE_DEFAULT_ASSESS_INTERVAL_HOURS = 24;
|
|
1396
|
-
var SKILL_EVOLVE_DEFAULT_MAX_SKILLS_PER_RUN = 8;
|
|
1397
|
-
var MIN_SECTIONS_FOR_STANDALONE = 2;
|
|
1398
|
-
function extractHeadings(content) {
|
|
1399
|
-
const bodyMatch = content.match(/^---[\s\S]*?---\n([\s\S]*)$/);
|
|
1400
|
-
const body = bodyMatch ? bodyMatch[1] : content;
|
|
1401
|
-
return body.split("\n").filter((line) => line.startsWith("## ")).map((line) => line.slice(3).trim());
|
|
1402
|
-
}
|
|
1403
|
-
function headingOverlap(headingsA, headingsB) {
|
|
1404
|
-
if (headingsA.length === 0 || headingsB.length === 0) return { score: 0, shared: [] };
|
|
1405
|
-
const tokenize = (h) => new Set(
|
|
1406
|
-
h.toLowerCase().replace(/[^a-z0-9\s]/g, " ").split(/\s+/).filter((w) => w.length >= 4)
|
|
1407
|
-
);
|
|
1408
|
-
const shared = [];
|
|
1409
|
-
for (const a of headingsA) {
|
|
1410
|
-
const aTokens = tokenize(a);
|
|
1411
|
-
for (const b of headingsB) {
|
|
1412
|
-
const bTokens = tokenize(b);
|
|
1413
|
-
const intersection = [...aTokens].filter((t) => bTokens.has(t)).length;
|
|
1414
|
-
const union = (/* @__PURE__ */ new Set([...aTokens, ...bTokens])).size;
|
|
1415
|
-
if (union > 0 && intersection / union >= 0.5) {
|
|
1416
|
-
shared.push(`"${a}" ~ "${b}"`);
|
|
1417
|
-
}
|
|
1418
|
-
}
|
|
1419
|
-
}
|
|
1420
|
-
const smaller = Math.min(headingsA.length, headingsB.length);
|
|
1421
|
-
return { score: smaller > 0 ? shared.length / smaller : 0, shared };
|
|
1422
|
-
}
|
|
1423
|
-
function buildSkillEvolveInstruction(params, projectRoot, similarityProvider) {
|
|
1424
|
-
const assessIntervalHours = Number(params?.assess_interval_hours ?? SKILL_EVOLVE_DEFAULT_ASSESS_INTERVAL_HOURS);
|
|
1425
|
-
const maxSkillsPerRun = Number(params?.max_skills_per_run ?? SKILL_EVOLVE_DEFAULT_MAX_SKILLS_PER_RUN);
|
|
1426
|
-
const now = epochSeconds();
|
|
1427
|
-
const intervalSeconds = assessIntervalHours * 3600;
|
|
1428
|
-
const allSkills = listSkillRecords({ status: "active", limit: 100 });
|
|
1429
|
-
const needsAssessment = [];
|
|
1430
|
-
for (const skill of allSkills) {
|
|
1431
|
-
let props = {};
|
|
1432
|
-
try {
|
|
1433
|
-
props = JSON.parse(skill.properties || "{}");
|
|
1434
|
-
} catch {
|
|
1435
|
-
props = {};
|
|
1436
|
-
}
|
|
1437
|
-
const lastAssessedAt = typeof props.last_assessed_at === "number" ? props.last_assessed_at : 0;
|
|
1438
|
-
const knowledgeWatermark = typeof props.knowledge_watermark === "number" ? props.knowledge_watermark : 0;
|
|
1439
|
-
if (lastAssessedAt > 0 && now - lastAssessedAt < intervalSeconds) continue;
|
|
1440
|
-
const newSporeIds = listSporeIdsSince(knowledgeWatermark, 10);
|
|
1441
|
-
if (newSporeIds.length === 0) continue;
|
|
1442
|
-
needsAssessment.push({
|
|
1443
|
-
id: skill.id,
|
|
1444
|
-
name: skill.name,
|
|
1445
|
-
generation: skill.generation,
|
|
1446
|
-
description: skill.description,
|
|
1447
|
-
newSporeIds
|
|
1448
|
-
});
|
|
1449
|
-
if (needsAssessment.length >= maxSkillsPerRun) {
|
|
1450
|
-
break;
|
|
1451
|
-
}
|
|
1452
|
-
}
|
|
1453
|
-
if (needsAssessment.length === 0) {
|
|
1454
|
-
return "No skills need assessment. All active skills are current or were recently assessed. Report skip via vault_report and finish.";
|
|
1455
|
-
}
|
|
1456
|
-
const structures = [];
|
|
1457
|
-
const skillHeadings = /* @__PURE__ */ new Map();
|
|
1458
|
-
for (const skill of allSkills) {
|
|
1459
|
-
let content = "";
|
|
1460
|
-
if (projectRoot && skill.path) {
|
|
1461
|
-
try {
|
|
1462
|
-
content = readFileSync(resolve(projectRoot, skill.path), "utf-8");
|
|
1463
|
-
} catch {
|
|
1464
|
-
}
|
|
1465
|
-
}
|
|
1466
|
-
const headings = extractHeadings(content);
|
|
1467
|
-
skillHeadings.set(skill.name, headings);
|
|
1468
|
-
structures.push({
|
|
1469
|
-
name: skill.name,
|
|
1470
|
-
sectionCount: headings.length,
|
|
1471
|
-
headings,
|
|
1472
|
-
narrow: headings.length < MIN_SECTIONS_FOR_STANDALONE
|
|
1473
|
-
});
|
|
1474
|
-
}
|
|
1475
|
-
const overlaps = [];
|
|
1476
|
-
for (let i = 0; i < allSkills.length; i++) {
|
|
1477
|
-
for (let j = i + 1; j < allSkills.length; j++) {
|
|
1478
|
-
const a = allSkills[i];
|
|
1479
|
-
const b = allSkills[j];
|
|
1480
|
-
const descJaccard = descriptionSimilarity(a.description, b.description);
|
|
1481
|
-
const aHeadings = skillHeadings.get(a.name) ?? [];
|
|
1482
|
-
const bHeadings = skillHeadings.get(b.name) ?? [];
|
|
1483
|
-
const ho = headingOverlap(aHeadings, bHeadings);
|
|
1484
|
-
const descFlag = descJaccard >= DESCRIPTION_DUPLICATE_THRESHOLD * 0.75;
|
|
1485
|
-
const headingFlag = ho.score >= 0.4;
|
|
1486
|
-
if (!descFlag && !headingFlag) continue;
|
|
1487
|
-
const verdict = descJaccard >= DESCRIPTION_DUPLICATE_THRESHOLD || ho.score >= 0.5 ? "potential-merge" : "potential-narrow";
|
|
1488
|
-
overlaps.push({
|
|
1489
|
-
skillA: a.name,
|
|
1490
|
-
skillB: b.name,
|
|
1491
|
-
descriptionJaccard: Math.round(descJaccard * 100) / 100,
|
|
1492
|
-
headingOverlap: Math.round(ho.score * 100) / 100,
|
|
1493
|
-
sharedHeadings: ho.shared,
|
|
1494
|
-
verdict
|
|
1495
|
-
});
|
|
1496
|
-
}
|
|
1497
|
-
}
|
|
1498
|
-
const parts = [
|
|
1499
|
-
`${needsAssessment.length} skill(s) need assessment.`,
|
|
1500
|
-
`assess_interval_hours: ${assessIntervalHours}`,
|
|
1501
|
-
`max_skills_per_run: ${maxSkillsPerRun}`
|
|
1502
|
-
];
|
|
1503
|
-
for (const skill of needsAssessment) {
|
|
1504
|
-
parts.push("");
|
|
1505
|
-
parts.push("---");
|
|
1506
|
-
parts.push(`## Skill: ${skill.name} (gen ${skill.generation})`);
|
|
1507
|
-
parts.push(`id: ${skill.id}`);
|
|
1508
|
-
parts.push(`description: ${skill.description}`);
|
|
1509
|
-
parts.push(`new_spore_ids: ${JSON.stringify(skill.newSporeIds)}`);
|
|
1510
|
-
}
|
|
1511
|
-
parts.push("");
|
|
1512
|
-
parts.push("## All Active Skills (for inventory analysis)");
|
|
1513
|
-
for (const s of structures) {
|
|
1514
|
-
const skill = allSkills.find((sk) => sk.name === s.name);
|
|
1515
|
-
const narrowTag = s.narrow ? " **[NARROW \u2014 <2 sections]**" : "";
|
|
1516
|
-
parts.push(`- **${skill.name}** (gen ${skill.generation}, ${s.sectionCount} sections${narrowTag}): ${skill.description.slice(0, 200)}`);
|
|
1517
|
-
if (s.headings.length > 0) {
|
|
1518
|
-
parts.push(` Headings: ${s.headings.join(" | ")}`);
|
|
1519
|
-
}
|
|
1520
|
-
}
|
|
1521
|
-
const narrowSkills = structures.filter((s) => s.narrow);
|
|
1522
|
-
if (narrowSkills.length > 0) {
|
|
1523
|
-
parts.push("");
|
|
1524
|
-
parts.push("## Mechanically Narrow Skills (<2 H2 sections)");
|
|
1525
|
-
parts.push("These skills have insufficient section breadth for domain-level standalone status.");
|
|
1526
|
-
parts.push("Determine which broader skill each should be absorbed into.");
|
|
1527
|
-
for (const s of narrowSkills) {
|
|
1528
|
-
parts.push(`- **${s.name}**: ${s.sectionCount} section(s). Headings: ${s.headings.length > 0 ? s.headings.join(" | ") : "(none)"}`);
|
|
1529
|
-
}
|
|
1530
|
-
}
|
|
1531
|
-
if (overlaps.length > 0) {
|
|
1532
|
-
parts.push("");
|
|
1533
|
-
parts.push("## Pre-computed Token Overlap");
|
|
1534
|
-
parts.push("Pairs flagged by description token similarity AND/OR heading overlap:");
|
|
1535
|
-
for (const o of overlaps) {
|
|
1536
|
-
parts.push(`- **${o.skillA}** <-> **${o.skillB}**: desc=${o.descriptionJaccard}, headings=${o.headingOverlap} (${o.verdict})`);
|
|
1537
|
-
if (o.sharedHeadings.length > 0) {
|
|
1538
|
-
parts.push(` Shared headings: ${o.sharedHeadings.join("; ")}`);
|
|
1539
|
-
}
|
|
1540
|
-
}
|
|
1541
|
-
}
|
|
1542
|
-
if (similarityProvider) {
|
|
1543
|
-
const idToName = new Map(allSkills.map((s) => [s.id, s.name]));
|
|
1544
|
-
try {
|
|
1545
|
-
const semanticPairs = similarityProvider.pairwiseSimilarity("skill_records", 0.65);
|
|
1546
|
-
if (semanticPairs.length > 0) {
|
|
1547
|
-
parts.push("");
|
|
1548
|
-
parts.push("## Semantic Similarity (embedding cosine distance)");
|
|
1549
|
-
parts.push("Pairs with cosine similarity >= 0.65. This is the STRONGEST overlap signal.");
|
|
1550
|
-
parts.push("High similarity (>0.8) means the skills describe nearly identical procedures.");
|
|
1551
|
-
for (const p of semanticPairs) {
|
|
1552
|
-
const nameA = idToName.get(p.idA) ?? p.idA;
|
|
1553
|
-
const nameB = idToName.get(p.idB) ?? p.idB;
|
|
1554
|
-
parts.push(`- **${nameA}** <-> **${nameB}**: cosine=${p.similarity}`);
|
|
1555
|
-
}
|
|
1556
|
-
}
|
|
1557
|
-
} catch {
|
|
1558
|
-
}
|
|
1559
|
-
}
|
|
1560
|
-
return parts.join("\n");
|
|
1561
|
-
}
|
|
1562
|
-
function buildTaskInstruction(taskName, taskParams, agentId, projectRoot, similarityProvider) {
|
|
1563
|
-
switch (taskName) {
|
|
1564
|
-
case SKILL_GENERATE_TASK:
|
|
1565
|
-
return buildSkillGenerateInstruction();
|
|
1566
|
-
case SKILL_SURVEY_TASK:
|
|
1567
|
-
return agentId ? buildSkillSurveyInstruction(agentId) : void 0;
|
|
1568
|
-
case SKILL_EVOLVE_TASK: {
|
|
1569
|
-
const instruction = buildSkillEvolveInstruction(taskParams, projectRoot, similarityProvider);
|
|
1570
|
-
return instruction ? { instruction } : void 0;
|
|
1571
|
-
}
|
|
1572
|
-
default:
|
|
1573
|
-
return void 0;
|
|
1574
|
-
}
|
|
1575
|
-
}
|
|
1576
|
-
function isInstructionRequiredTask(taskName) {
|
|
1577
|
-
return taskName === SKILL_GENERATE_TASK || taskName === SKILL_EVOLVE_TASK || taskName === SKILL_SURVEY_TASK;
|
|
1578
|
-
}
|
|
1579
|
-
|
|
1580
|
-
// src/db/queries/skill-lineage.ts
|
|
1581
|
-
var LINEAGE_COLUMNS = [
|
|
1582
|
-
"id",
|
|
1583
|
-
"skill_id",
|
|
1584
|
-
"generation",
|
|
1585
|
-
"action",
|
|
1586
|
-
"rationale",
|
|
1587
|
-
"source_ids_added",
|
|
1588
|
-
"content_snapshot",
|
|
1589
|
-
"created_at"
|
|
1590
|
-
];
|
|
1591
|
-
var SELECT_COLUMNS6 = LINEAGE_COLUMNS.join(", ");
|
|
1592
|
-
function toLineageRow(row) {
|
|
1593
|
-
return {
|
|
1594
|
-
id: row.id,
|
|
1595
|
-
skill_id: row.skill_id,
|
|
1596
|
-
generation: row.generation,
|
|
1597
|
-
action: row.action,
|
|
1598
|
-
rationale: row.rationale,
|
|
1599
|
-
source_ids_added: row.source_ids_added ?? "[]",
|
|
1600
|
-
content_snapshot: row.content_snapshot,
|
|
1601
|
-
created_at: row.created_at
|
|
1602
|
-
};
|
|
1603
|
-
}
|
|
1604
|
-
function insertLineage(data) {
|
|
1605
|
-
const db = getDatabase();
|
|
1606
|
-
db.prepare(
|
|
1607
|
-
`INSERT INTO skill_lineage (
|
|
1608
|
-
id, skill_id, generation, action, rationale,
|
|
1609
|
-
source_ids_added, content_snapshot, created_at
|
|
1610
|
-
) VALUES (
|
|
1611
|
-
?, ?, ?, ?, ?,
|
|
1612
|
-
?, ?, ?
|
|
1613
|
-
)`
|
|
1614
|
-
).run(
|
|
1615
|
-
data.id,
|
|
1616
|
-
data.skill_id,
|
|
1617
|
-
data.generation,
|
|
1618
|
-
data.action,
|
|
1619
|
-
data.rationale,
|
|
1620
|
-
data.source_ids_added ?? "[]",
|
|
1621
|
-
data.content_snapshot,
|
|
1622
|
-
data.created_at
|
|
1623
|
-
);
|
|
1624
|
-
return toLineageRow(
|
|
1625
|
-
db.prepare(`SELECT ${SELECT_COLUMNS6} FROM skill_lineage WHERE id = ?`).get(data.id)
|
|
1626
|
-
);
|
|
1627
|
-
}
|
|
1628
|
-
function listLineageForSkill(skillId, limit = 50) {
|
|
1629
|
-
const db = getDatabase();
|
|
1630
|
-
const rows = db.prepare(
|
|
1631
|
-
`SELECT ${SELECT_COLUMNS6}
|
|
1632
|
-
FROM skill_lineage
|
|
1633
|
-
WHERE skill_id = ?
|
|
1634
|
-
ORDER BY generation DESC
|
|
1635
|
-
LIMIT ?`
|
|
1636
|
-
).all(skillId, limit);
|
|
1637
|
-
return rows.map(toLineageRow);
|
|
1638
|
-
}
|
|
1639
|
-
|
|
1640
|
-
// src/db/queries/batches.ts
|
|
1641
|
-
var DEFAULT_UNPROCESSED_LIMIT = 100;
|
|
1642
|
-
var BATCHES_DEFAULT_LIMIT = 200;
|
|
1643
|
-
var STATUS_COMPLETED2 = "completed";
|
|
1644
|
-
var DEFAULT_STATUS4 = "active";
|
|
1645
|
-
var DEFAULT_ACTIVITY_COUNT = 0;
|
|
1646
|
-
var DEFAULT_PROCESSED = 0;
|
|
1647
|
-
var PROCESSED_FLAG = 1;
|
|
1648
|
-
var PROMPT_PREFIX_MATCH_CHARS = 60;
|
|
1649
|
-
var BATCH_COLUMNS = [
|
|
1650
|
-
"id",
|
|
1651
|
-
"session_id",
|
|
1652
|
-
"prompt_number",
|
|
1653
|
-
"user_prompt",
|
|
1654
|
-
"response_summary",
|
|
1655
|
-
"classification",
|
|
1656
|
-
"started_at",
|
|
1657
|
-
"ended_at",
|
|
1658
|
-
"status",
|
|
1659
|
-
"activity_count",
|
|
1660
|
-
"processed",
|
|
1661
|
-
"content_hash",
|
|
1662
|
-
"created_at",
|
|
1663
|
-
"machine_id",
|
|
1664
|
-
"synced_at"
|
|
1665
|
-
];
|
|
1666
|
-
var SELECT_COLUMNS7 = BATCH_COLUMNS.join(", ");
|
|
1667
|
-
function toBatchRow(row) {
|
|
1668
|
-
return {
|
|
1669
|
-
id: row.id,
|
|
1670
|
-
session_id: row.session_id,
|
|
1671
|
-
prompt_number: row.prompt_number ?? null,
|
|
1672
|
-
user_prompt: row.user_prompt ?? null,
|
|
1673
|
-
response_summary: row.response_summary ?? null,
|
|
1674
|
-
classification: row.classification ?? null,
|
|
1675
|
-
started_at: row.started_at ?? null,
|
|
1676
|
-
ended_at: row.ended_at ?? null,
|
|
1677
|
-
status: row.status,
|
|
1678
|
-
activity_count: row.activity_count,
|
|
1679
|
-
processed: row.processed,
|
|
1680
|
-
content_hash: row.content_hash ?? null,
|
|
1681
|
-
created_at: row.created_at,
|
|
1682
|
-
machine_id: row.machine_id ?? "local",
|
|
1683
|
-
synced_at: row.synced_at ?? null
|
|
1684
|
-
};
|
|
1685
|
-
}
|
|
1686
|
-
function populateBatchResponses(sessionId, responses) {
|
|
1687
|
-
const db = getDatabase();
|
|
1688
|
-
const batches = db.prepare(
|
|
1689
|
-
`SELECT id FROM prompt_batches WHERE session_id = ? ORDER BY id ASC`
|
|
1690
|
-
).all(sessionId);
|
|
1691
|
-
for (const { turnIndex, response } of responses) {
|
|
1692
|
-
const batchIndex = turnIndex - 1;
|
|
1693
|
-
if (batchIndex >= 0 && batchIndex < batches.length) {
|
|
1694
|
-
const batchId = batches[batchIndex].id;
|
|
1695
|
-
db.prepare(
|
|
1696
|
-
`UPDATE prompt_batches SET response_summary = ? WHERE id = ? AND response_summary IS NULL`
|
|
1697
|
-
).run(response, batchId);
|
|
1698
|
-
}
|
|
1699
|
-
}
|
|
1700
|
-
}
|
|
1701
|
-
function getUnprocessedBatches(options = {}) {
|
|
1702
|
-
const db = getDatabase();
|
|
1703
|
-
const conditions = [`processed = ?`];
|
|
1704
|
-
const params = [DEFAULT_PROCESSED];
|
|
1705
|
-
if (options.after_id !== void 0) {
|
|
1706
|
-
conditions.push(`id > ?`);
|
|
1707
|
-
params.push(options.after_id);
|
|
1708
|
-
}
|
|
1709
|
-
if (options.includeActive === false) {
|
|
1710
|
-
conditions.push(
|
|
1711
|
-
`EXISTS (SELECT 1 FROM sessions s WHERE s.id = prompt_batches.session_id AND s.status != 'active')`
|
|
1712
|
-
);
|
|
1713
|
-
}
|
|
1714
|
-
const limit = options.limit ?? DEFAULT_UNPROCESSED_LIMIT;
|
|
1715
|
-
params.push(limit);
|
|
1716
|
-
const where = conditions.join(" AND ");
|
|
1717
|
-
const rows = db.prepare(
|
|
1718
|
-
`SELECT ${SELECT_COLUMNS7}
|
|
1719
|
-
FROM prompt_batches
|
|
1720
|
-
WHERE ${where}
|
|
1721
|
-
ORDER BY id ASC
|
|
1722
|
-
LIMIT ?`
|
|
1723
|
-
).all(...params);
|
|
1724
|
-
return rows.map(toBatchRow);
|
|
1725
|
-
}
|
|
1726
|
-
function incrementActivityCount(id) {
|
|
1727
|
-
const db = getDatabase();
|
|
1728
|
-
const info = db.prepare(
|
|
1729
|
-
`UPDATE prompt_batches
|
|
1730
|
-
SET activity_count = activity_count + 1
|
|
1731
|
-
WHERE id = ?`
|
|
1732
|
-
).run(id);
|
|
1733
|
-
if (info.changes === 0) return null;
|
|
1734
|
-
return toBatchRow(
|
|
1735
|
-
db.prepare(`SELECT ${SELECT_COLUMNS7} FROM prompt_batches WHERE id = ?`).get(id)
|
|
1736
|
-
);
|
|
1737
|
-
}
|
|
1738
|
-
function markBatchProcessed(id) {
|
|
1739
|
-
const db = getDatabase();
|
|
1740
|
-
const info = db.prepare(
|
|
1741
|
-
`UPDATE prompt_batches
|
|
1742
|
-
SET processed = ?
|
|
1743
|
-
WHERE id = ?`
|
|
1744
|
-
).run(PROCESSED_FLAG, id);
|
|
1745
|
-
if (info.changes === 0) return null;
|
|
1746
|
-
return toBatchRow(
|
|
1747
|
-
db.prepare(`SELECT ${SELECT_COLUMNS7} FROM prompt_batches WHERE id = ?`).get(id)
|
|
1748
|
-
);
|
|
1749
|
-
}
|
|
1750
|
-
function findBatchByPromptPrefix(sessionId, promptPrefix) {
|
|
1751
|
-
const db = getDatabase();
|
|
1752
|
-
const prefix = promptPrefix.slice(0, PROMPT_PREFIX_MATCH_CHARS);
|
|
1753
|
-
const row = db.prepare(
|
|
1754
|
-
`SELECT id, prompt_number FROM prompt_batches
|
|
1755
|
-
WHERE session_id = ? AND user_prompt LIKE ? || '%'
|
|
1756
|
-
LIMIT 1`
|
|
1757
|
-
).get(sessionId, prefix);
|
|
1758
|
-
return row ?? null;
|
|
1759
|
-
}
|
|
1760
|
-
function insertBatchStateless(data) {
|
|
1761
|
-
const db = getDatabase();
|
|
1762
|
-
const info = db.prepare(
|
|
1763
|
-
`INSERT INTO prompt_batches (
|
|
1764
|
-
session_id, prompt_number, user_prompt, response_summary,
|
|
1765
|
-
classification, started_at, ended_at, status,
|
|
1766
|
-
activity_count, processed, content_hash, created_at, machine_id
|
|
1767
|
-
) VALUES (
|
|
1768
|
-
?,
|
|
1769
|
-
(SELECT COALESCE(MAX(prompt_number), 0) + 1 FROM prompt_batches WHERE session_id = ?),
|
|
1770
|
-
?, NULL,
|
|
1771
|
-
NULL, ?, NULL, ?,
|
|
1772
|
-
?, ?, NULL, ?, ?
|
|
1773
|
-
)`
|
|
1774
|
-
).run(
|
|
1775
|
-
data.session_id,
|
|
1776
|
-
data.session_id,
|
|
1777
|
-
data.user_prompt ?? null,
|
|
1778
|
-
data.started_at ?? null,
|
|
1779
|
-
data.status ?? DEFAULT_STATUS4,
|
|
1780
|
-
DEFAULT_ACTIVITY_COUNT,
|
|
1781
|
-
DEFAULT_PROCESSED,
|
|
1782
|
-
data.created_at,
|
|
1783
|
-
data.machine_id ?? getTeamMachineId()
|
|
1784
|
-
);
|
|
1785
|
-
const batchId = Number(info.lastInsertRowid);
|
|
1786
|
-
return toBatchRow(
|
|
1787
|
-
db.prepare(`SELECT ${SELECT_COLUMNS7} FROM prompt_batches WHERE id = ?`).get(batchId)
|
|
1788
|
-
);
|
|
1789
|
-
}
|
|
1790
|
-
function closeOpenBatches(sessionId, endedAt) {
|
|
1791
|
-
const db = getDatabase();
|
|
1792
|
-
const info = db.prepare(
|
|
1793
|
-
`UPDATE prompt_batches
|
|
1794
|
-
SET status = ?, ended_at = ?
|
|
1795
|
-
WHERE session_id = ? AND ended_at IS NULL`
|
|
1796
|
-
).run(STATUS_COMPLETED2, endedAt, sessionId);
|
|
1797
|
-
return info.changes;
|
|
1798
|
-
}
|
|
1799
|
-
function setResponseSummary(batchId, summary) {
|
|
1800
|
-
const db = getDatabase();
|
|
1801
|
-
db.prepare(
|
|
1802
|
-
`UPDATE prompt_batches SET response_summary = ? WHERE id = ? AND response_summary IS NULL`
|
|
1803
|
-
).run(summary, batchId);
|
|
1804
|
-
}
|
|
1805
|
-
function getLatestBatch(sessionId) {
|
|
1806
|
-
const db = getDatabase();
|
|
1807
|
-
const row = db.prepare(
|
|
1808
|
-
`SELECT ${SELECT_COLUMNS7} FROM prompt_batches
|
|
1809
|
-
WHERE session_id = ?
|
|
1810
|
-
ORDER BY id DESC LIMIT 1`
|
|
1811
|
-
).get(sessionId);
|
|
1812
|
-
if (!row) return null;
|
|
1813
|
-
return toBatchRow(row);
|
|
1814
|
-
}
|
|
1815
|
-
function listBatchesBySession(sessionId, options = {}) {
|
|
1816
|
-
const db = getDatabase();
|
|
1817
|
-
const limit = options.limit ?? BATCHES_DEFAULT_LIMIT;
|
|
1818
|
-
const offset = options.offset ?? 0;
|
|
1819
|
-
const rows = db.prepare(
|
|
1820
|
-
`SELECT ${SELECT_COLUMNS7}
|
|
1821
|
-
FROM prompt_batches
|
|
1822
|
-
WHERE session_id = ?
|
|
1823
|
-
ORDER BY prompt_number ASC
|
|
1824
|
-
LIMIT ?
|
|
1825
|
-
OFFSET ?`
|
|
1826
|
-
).all(sessionId, limit, offset);
|
|
1827
|
-
return rows.map(toBatchRow);
|
|
1828
|
-
}
|
|
1829
|
-
function countBatchesBySession(sessionId) {
|
|
1830
|
-
const db = getDatabase();
|
|
1831
|
-
const row = db.prepare(
|
|
1832
|
-
`SELECT COUNT(*) as count FROM prompt_batches WHERE session_id = ?`
|
|
1833
|
-
).get(sessionId);
|
|
1834
|
-
return row.count;
|
|
1835
|
-
}
|
|
1836
|
-
|
|
1837
|
-
// src/db/queries/graph-edges.ts
|
|
1838
|
-
import crypto2 from "crypto";
|
|
1839
|
-
var DEFAULT_BFS_DEPTH = 2;
|
|
1840
|
-
var MAX_BFS_DEPTH = 5;
|
|
1841
|
-
var GRAPH_EDGE_COLUMNS = [
|
|
1842
|
-
"id",
|
|
1843
|
-
"agent_id",
|
|
1844
|
-
"source_id",
|
|
1845
|
-
"source_type",
|
|
1846
|
-
"target_id",
|
|
1847
|
-
"target_type",
|
|
1848
|
-
"type",
|
|
1849
|
-
"session_id",
|
|
1850
|
-
"confidence",
|
|
1851
|
-
"properties",
|
|
1852
|
-
"created_at",
|
|
1853
|
-
"machine_id",
|
|
1854
|
-
"synced_at"
|
|
1855
|
-
];
|
|
1856
|
-
var SELECT_COLUMNS8 = GRAPH_EDGE_COLUMNS.join(", ");
|
|
1857
|
-
function toGraphEdgeRow(row) {
|
|
1858
|
-
return {
|
|
1859
|
-
id: row.id,
|
|
1860
|
-
agent_id: row.agent_id,
|
|
1861
|
-
source_id: row.source_id,
|
|
1862
|
-
source_type: row.source_type,
|
|
1863
|
-
target_id: row.target_id,
|
|
1864
|
-
target_type: row.target_type,
|
|
1865
|
-
type: row.type,
|
|
1866
|
-
session_id: row.session_id ?? null,
|
|
1867
|
-
confidence: row.confidence,
|
|
1868
|
-
properties: row.properties ?? null,
|
|
1869
|
-
created_at: row.created_at,
|
|
1870
|
-
machine_id: row.machine_id ?? getTeamMachineId(),
|
|
1871
|
-
synced_at: row.synced_at ?? null
|
|
1872
|
-
};
|
|
1873
|
-
}
|
|
1874
|
-
function insertGraphEdge(data) {
|
|
1875
|
-
const db = getDatabase();
|
|
1876
|
-
const id = crypto2.randomUUID();
|
|
1877
|
-
db.prepare(
|
|
1878
|
-
`INSERT INTO graph_edges (
|
|
1879
|
-
id, agent_id, source_id, source_type, target_id, target_type,
|
|
1880
|
-
type, session_id, confidence, properties, created_at, machine_id
|
|
1881
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
|
|
1882
|
-
).run(
|
|
1883
|
-
id,
|
|
1884
|
-
data.agent_id,
|
|
1885
|
-
data.source_id,
|
|
1886
|
-
data.source_type,
|
|
1887
|
-
data.target_id,
|
|
1888
|
-
data.target_type,
|
|
1889
|
-
data.type,
|
|
1890
|
-
data.session_id ?? null,
|
|
1891
|
-
data.confidence ?? GRAPH_EDGE_DEFAULT_CONFIDENCE,
|
|
1892
|
-
data.properties ?? null,
|
|
1893
|
-
data.created_at,
|
|
1894
|
-
data.machine_id ?? getTeamMachineId()
|
|
1895
|
-
);
|
|
1896
|
-
const row = toGraphEdgeRow(
|
|
1897
|
-
db.prepare(`SELECT ${SELECT_COLUMNS8} FROM graph_edges WHERE id = ?`).get(id)
|
|
1898
|
-
);
|
|
1899
|
-
syncRow("graph_edges", row);
|
|
1900
|
-
return row;
|
|
1901
|
-
}
|
|
1902
|
-
function listGraphEdges(options = {}) {
|
|
1903
|
-
const db = getDatabase();
|
|
1904
|
-
const conditions = [];
|
|
1905
|
-
const params = [];
|
|
1906
|
-
if (options.sourceId !== void 0) {
|
|
1907
|
-
conditions.push(`source_id = ?`);
|
|
1908
|
-
params.push(options.sourceId);
|
|
1909
|
-
}
|
|
1910
|
-
if (options.targetId !== void 0) {
|
|
1911
|
-
conditions.push(`target_id = ?`);
|
|
1912
|
-
params.push(options.targetId);
|
|
1913
|
-
}
|
|
1914
|
-
if (options.type !== void 0) {
|
|
1915
|
-
conditions.push(`type = ?`);
|
|
1916
|
-
params.push(options.type);
|
|
1917
|
-
}
|
|
1918
|
-
if (options.agentId !== void 0) {
|
|
1919
|
-
conditions.push(`agent_id = ?`);
|
|
1920
|
-
params.push(options.agentId);
|
|
1921
|
-
}
|
|
1922
|
-
const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
1923
|
-
const limit = options.limit ?? QUERY_DEFAULT_LIST_LIMIT;
|
|
1924
|
-
params.push(limit);
|
|
1925
|
-
const rows = db.prepare(
|
|
1926
|
-
`SELECT ${SELECT_COLUMNS8}
|
|
1927
|
-
FROM graph_edges
|
|
1928
|
-
${where}
|
|
1929
|
-
ORDER BY created_at DESC
|
|
1930
|
-
LIMIT ?`
|
|
1931
|
-
).all(...params);
|
|
1932
|
-
return rows.map(toGraphEdgeRow);
|
|
1933
|
-
}
|
|
1934
|
-
function getGraphForNode(nodeId, nodeType, options) {
|
|
1935
|
-
const db = getDatabase();
|
|
1936
|
-
const depth = Math.min(Math.max(options?.depth ?? DEFAULT_BFS_DEPTH, 1), MAX_BFS_DEPTH);
|
|
1937
|
-
const seenEdgeIds = /* @__PURE__ */ new Set();
|
|
1938
|
-
const collectedEdges = [];
|
|
1939
|
-
const visited = /* @__PURE__ */ new Set([`${nodeType}:${nodeId}`]);
|
|
1940
|
-
let frontier = /* @__PURE__ */ new Set([nodeId]);
|
|
1941
|
-
for (let hop = 0; hop < depth; hop++) {
|
|
1942
|
-
if (frontier.size === 0) break;
|
|
1943
|
-
const frontierArray = Array.from(frontier);
|
|
1944
|
-
const placeholders = frontierArray.map(() => `?`).join(", ");
|
|
1945
|
-
const rows = db.prepare(
|
|
1946
|
-
`SELECT ${SELECT_COLUMNS8}
|
|
1947
|
-
FROM graph_edges
|
|
1948
|
-
WHERE source_id IN (${placeholders}) OR target_id IN (${placeholders})`
|
|
1949
|
-
).all(...frontierArray, ...frontierArray);
|
|
1950
|
-
const nextFrontier = /* @__PURE__ */ new Set();
|
|
1951
|
-
for (const row of rows) {
|
|
1952
|
-
const edge = toGraphEdgeRow(row);
|
|
1953
|
-
if (!seenEdgeIds.has(edge.id)) {
|
|
1954
|
-
seenEdgeIds.add(edge.id);
|
|
1955
|
-
collectedEdges.push(edge);
|
|
1956
|
-
}
|
|
1957
|
-
const sourceKey = `${edge.source_type}:${edge.source_id}`;
|
|
1958
|
-
const targetKey = `${edge.target_type}:${edge.target_id}`;
|
|
1959
|
-
if (!visited.has(sourceKey)) {
|
|
1960
|
-
visited.add(sourceKey);
|
|
1961
|
-
nextFrontier.add(edge.source_id);
|
|
1962
|
-
}
|
|
1963
|
-
if (!visited.has(targetKey)) {
|
|
1964
|
-
visited.add(targetKey);
|
|
1965
|
-
nextFrontier.add(edge.target_id);
|
|
1966
|
-
}
|
|
1967
|
-
}
|
|
1968
|
-
frontier = nextFrontier;
|
|
1969
|
-
}
|
|
1970
|
-
return { edges: collectedEdges };
|
|
1971
|
-
}
|
|
1972
|
-
|
|
1973
|
-
// src/db/queries/entities.ts
|
|
1974
|
-
var DEFAULT_LIST_LIMIT3 = 100;
|
|
1975
|
-
var ENTITY_COLUMNS = [
|
|
1976
|
-
"id",
|
|
1977
|
-
"agent_id",
|
|
1978
|
-
"type",
|
|
1979
|
-
"name",
|
|
1980
|
-
"properties",
|
|
1981
|
-
"first_seen",
|
|
1982
|
-
"last_seen",
|
|
1983
|
-
"status",
|
|
1984
|
-
"machine_id",
|
|
1985
|
-
"synced_at"
|
|
1986
|
-
];
|
|
1987
|
-
var SELECT_COLUMNS9 = ENTITY_COLUMNS.join(", ");
|
|
1988
|
-
function toEntityRow(row) {
|
|
1989
|
-
return {
|
|
1990
|
-
id: row.id,
|
|
1991
|
-
agent_id: row.agent_id,
|
|
1992
|
-
type: row.type,
|
|
1993
|
-
name: row.name,
|
|
1994
|
-
properties: row.properties ?? null,
|
|
1995
|
-
first_seen: row.first_seen,
|
|
1996
|
-
last_seen: row.last_seen,
|
|
1997
|
-
status: row.status ?? "active",
|
|
1998
|
-
machine_id: row.machine_id ?? "local",
|
|
1999
|
-
synced_at: row.synced_at ?? null
|
|
2000
|
-
};
|
|
2001
|
-
}
|
|
2002
|
-
function insertEntity(data) {
|
|
2003
|
-
const db = getDatabase();
|
|
2004
|
-
db.prepare(
|
|
2005
|
-
`INSERT INTO entities (id, agent_id, type, name, properties, first_seen, last_seen, machine_id)
|
|
2006
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
2007
|
-
ON CONFLICT (agent_id, type, name) DO UPDATE SET
|
|
2008
|
-
properties = COALESCE(EXCLUDED.properties, entities.properties),
|
|
2009
|
-
last_seen = EXCLUDED.last_seen`
|
|
2010
|
-
).run(
|
|
2011
|
-
data.id,
|
|
2012
|
-
data.agent_id,
|
|
2013
|
-
data.type,
|
|
2014
|
-
data.name,
|
|
2015
|
-
data.properties ?? null,
|
|
2016
|
-
data.first_seen,
|
|
2017
|
-
data.last_seen,
|
|
2018
|
-
data.machine_id ?? getTeamMachineId()
|
|
2019
|
-
);
|
|
2020
|
-
const row = toEntityRow(
|
|
2021
|
-
db.prepare(`SELECT ${SELECT_COLUMNS9} FROM entities WHERE agent_id = ? AND type = ? AND name = ?`).get(
|
|
2022
|
-
data.agent_id,
|
|
2023
|
-
data.type,
|
|
2024
|
-
data.name
|
|
2025
|
-
)
|
|
2026
|
-
);
|
|
2027
|
-
syncRow("entities", row);
|
|
2028
|
-
return row;
|
|
2029
|
-
}
|
|
2030
|
-
function getEntity(id) {
|
|
2031
|
-
const db = getDatabase();
|
|
2032
|
-
const row = db.prepare(
|
|
2033
|
-
`SELECT ${SELECT_COLUMNS9} FROM entities WHERE id = ?`
|
|
2034
|
-
).get(id);
|
|
2035
|
-
if (!row) return null;
|
|
2036
|
-
return toEntityRow(row);
|
|
2037
|
-
}
|
|
2038
|
-
function listEntities(options = {}) {
|
|
2039
|
-
const db = getDatabase();
|
|
2040
|
-
const conditions = [];
|
|
2041
|
-
const params = [];
|
|
2042
|
-
if (options.agent_id !== void 0) {
|
|
2043
|
-
conditions.push(`agent_id = ?`);
|
|
2044
|
-
params.push(options.agent_id);
|
|
2045
|
-
}
|
|
2046
|
-
if (options.type !== void 0) {
|
|
2047
|
-
conditions.push(`type = ?`);
|
|
2048
|
-
params.push(options.type);
|
|
2049
|
-
}
|
|
2050
|
-
if (options.name !== void 0) {
|
|
2051
|
-
conditions.push(`name = ?`);
|
|
2052
|
-
params.push(options.name);
|
|
2053
|
-
}
|
|
2054
|
-
if (options.status !== void 0) {
|
|
2055
|
-
conditions.push(`status = ?`);
|
|
2056
|
-
params.push(options.status);
|
|
2057
|
-
} else {
|
|
2058
|
-
conditions.push(`status = ?`);
|
|
2059
|
-
params.push("active");
|
|
2060
|
-
}
|
|
2061
|
-
if (options.mentioned_in !== void 0 && options.note_type !== void 0) {
|
|
2062
|
-
conditions.push(
|
|
2063
|
-
`id IN (SELECT entity_id FROM entity_mentions WHERE note_id = ? AND note_type = ?)`
|
|
2064
|
-
);
|
|
2065
|
-
params.push(options.mentioned_in);
|
|
2066
|
-
params.push(options.note_type);
|
|
2067
|
-
}
|
|
2068
|
-
const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
2069
|
-
const limit = options.limit ?? DEFAULT_LIST_LIMIT3;
|
|
2070
|
-
const offset = options.offset ?? 0;
|
|
2071
|
-
params.push(limit);
|
|
2072
|
-
params.push(offset);
|
|
2073
|
-
const rows = db.prepare(
|
|
2074
|
-
`SELECT ${SELECT_COLUMNS9}
|
|
2075
|
-
FROM entities
|
|
2076
|
-
${where}
|
|
2077
|
-
ORDER BY last_seen DESC
|
|
2078
|
-
LIMIT ?
|
|
2079
|
-
OFFSET ?`
|
|
2080
|
-
).all(...params);
|
|
2081
|
-
return rows.map(toEntityRow);
|
|
2082
|
-
}
|
|
2083
|
-
|
|
2084
|
-
// src/db/queries/lineage.ts
|
|
2085
|
-
function createSporeLineage(spore) {
|
|
2086
|
-
if (spore.session_id) {
|
|
2087
|
-
insertGraphEdge({
|
|
2088
|
-
agent_id: spore.agent_id,
|
|
2089
|
-
source_id: spore.id,
|
|
2090
|
-
source_type: "spore",
|
|
2091
|
-
target_id: spore.session_id,
|
|
2092
|
-
target_type: "session",
|
|
2093
|
-
type: EDGE_TYPE_FROM_SESSION,
|
|
2094
|
-
created_at: spore.created_at
|
|
2095
|
-
});
|
|
2096
|
-
}
|
|
2097
|
-
if (spore.prompt_batch_id != null) {
|
|
2098
|
-
insertGraphEdge({
|
|
2099
|
-
agent_id: spore.agent_id,
|
|
2100
|
-
source_id: spore.id,
|
|
2101
|
-
source_type: "spore",
|
|
2102
|
-
target_id: String(spore.prompt_batch_id),
|
|
2103
|
-
target_type: "batch",
|
|
2104
|
-
type: EDGE_TYPE_EXTRACTED_FROM,
|
|
2105
|
-
created_at: spore.created_at
|
|
2106
|
-
});
|
|
2107
|
-
}
|
|
2108
|
-
if (spore.observation_type === "wisdom" && spore.properties) {
|
|
2109
|
-
try {
|
|
2110
|
-
const props = JSON.parse(spore.properties);
|
|
2111
|
-
if (Array.isArray(props.consolidated_from)) {
|
|
2112
|
-
for (const sourceId of props.consolidated_from) {
|
|
2113
|
-
insertGraphEdge({
|
|
2114
|
-
agent_id: spore.agent_id,
|
|
2115
|
-
source_id: spore.id,
|
|
2116
|
-
source_type: "spore",
|
|
2117
|
-
target_id: sourceId,
|
|
2118
|
-
target_type: "spore",
|
|
2119
|
-
type: EDGE_TYPE_DERIVED_FROM,
|
|
2120
|
-
created_at: spore.created_at
|
|
2121
|
-
});
|
|
2122
|
-
}
|
|
2123
|
-
}
|
|
2124
|
-
} catch {
|
|
2125
|
-
}
|
|
2126
|
-
}
|
|
2127
|
-
}
|
|
2128
|
-
function createBatchLineage(agentId, sessionId, batchId, createdAt) {
|
|
2129
|
-
insertGraphEdge({
|
|
2130
|
-
agent_id: agentId,
|
|
2131
|
-
source_id: sessionId,
|
|
2132
|
-
source_type: "session",
|
|
2133
|
-
target_id: String(batchId),
|
|
2134
|
-
target_type: "batch",
|
|
2135
|
-
type: EDGE_TYPE_HAS_BATCH,
|
|
2136
|
-
created_at: createdAt
|
|
2137
|
-
});
|
|
2138
|
-
}
|
|
2139
|
-
|
|
2140
|
-
// src/db/queries/resolution-events.ts
|
|
2141
|
-
var EVENT_COLUMNS = [
|
|
2142
|
-
"id",
|
|
2143
|
-
"agent_id",
|
|
2144
|
-
"spore_id",
|
|
2145
|
-
"action",
|
|
2146
|
-
"new_spore_id",
|
|
2147
|
-
"reason",
|
|
2148
|
-
"session_id",
|
|
2149
|
-
"created_at",
|
|
2150
|
-
"machine_id",
|
|
2151
|
-
"synced_at"
|
|
2152
|
-
];
|
|
2153
|
-
var SELECT_COLUMNS10 = EVENT_COLUMNS.join(", ");
|
|
2154
|
-
function toResolutionEventRow(row) {
|
|
2155
|
-
return {
|
|
2156
|
-
id: row.id,
|
|
2157
|
-
agent_id: row.agent_id,
|
|
2158
|
-
spore_id: row.spore_id,
|
|
2159
|
-
action: row.action,
|
|
2160
|
-
new_spore_id: row.new_spore_id ?? null,
|
|
2161
|
-
reason: row.reason ?? null,
|
|
2162
|
-
session_id: row.session_id ?? null,
|
|
2163
|
-
created_at: row.created_at,
|
|
2164
|
-
machine_id: row.machine_id ?? "local",
|
|
2165
|
-
synced_at: row.synced_at ?? null
|
|
2166
|
-
};
|
|
2167
|
-
}
|
|
2168
|
-
function insertResolutionEvent(data) {
|
|
2169
|
-
const db = getDatabase();
|
|
2170
|
-
db.prepare(
|
|
2171
|
-
`INSERT INTO resolution_events (
|
|
2172
|
-
id, agent_id, spore_id, action, new_spore_id, reason, session_id, created_at, machine_id
|
|
2173
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`
|
|
2174
|
-
).run(
|
|
2175
|
-
data.id,
|
|
2176
|
-
data.agent_id,
|
|
2177
|
-
data.spore_id,
|
|
2178
|
-
data.action,
|
|
2179
|
-
data.new_spore_id ?? null,
|
|
2180
|
-
data.reason ?? null,
|
|
2181
|
-
data.session_id ?? null,
|
|
2182
|
-
data.created_at,
|
|
2183
|
-
data.machine_id ?? getTeamMachineId()
|
|
2184
|
-
);
|
|
2185
|
-
const row = toResolutionEventRow(
|
|
2186
|
-
db.prepare(`SELECT ${SELECT_COLUMNS10} FROM resolution_events WHERE id = ?`).get(data.id)
|
|
2187
|
-
);
|
|
2188
|
-
syncRow("resolution_events", row);
|
|
2189
|
-
return row;
|
|
2190
|
-
}
|
|
2191
|
-
|
|
2192
|
-
// src/db/queries/reports.ts
|
|
2193
|
-
var REPORT_COLUMNS = [
|
|
2194
|
-
"id",
|
|
2195
|
-
"run_id",
|
|
2196
|
-
"agent_id",
|
|
2197
|
-
"action",
|
|
2198
|
-
"summary",
|
|
2199
|
-
"details",
|
|
2200
|
-
"created_at"
|
|
2201
|
-
];
|
|
2202
|
-
var SELECT_COLUMNS11 = REPORT_COLUMNS.join(", ");
|
|
2203
|
-
function toReportRow(row) {
|
|
2204
|
-
return {
|
|
2205
|
-
id: row.id,
|
|
2206
|
-
run_id: row.run_id,
|
|
2207
|
-
agent_id: row.agent_id,
|
|
2208
|
-
action: row.action,
|
|
2209
|
-
summary: row.summary,
|
|
2210
|
-
details: row.details ?? null,
|
|
2211
|
-
created_at: row.created_at
|
|
2212
|
-
};
|
|
2213
|
-
}
|
|
2214
|
-
function insertReport(data) {
|
|
2215
|
-
const db = getDatabase();
|
|
2216
|
-
const info = db.prepare(
|
|
2217
|
-
`INSERT INTO agent_reports (
|
|
2218
|
-
run_id, agent_id, action, summary, details, created_at
|
|
2219
|
-
) VALUES (
|
|
2220
|
-
?, ?, ?, ?, ?, ?
|
|
2221
|
-
)`
|
|
2222
|
-
).run(
|
|
2223
|
-
data.run_id,
|
|
2224
|
-
data.agent_id,
|
|
2225
|
-
data.action,
|
|
2226
|
-
data.summary,
|
|
2227
|
-
data.details ?? null,
|
|
2228
|
-
data.created_at
|
|
2229
|
-
);
|
|
2230
|
-
const reportId = Number(info.lastInsertRowid);
|
|
2231
|
-
return toReportRow(
|
|
2232
|
-
db.prepare(`SELECT ${SELECT_COLUMNS11} FROM agent_reports WHERE id = ?`).get(reportId)
|
|
2233
|
-
);
|
|
2234
|
-
}
|
|
2235
|
-
function listReports(runId) {
|
|
2236
|
-
const db = getDatabase();
|
|
2237
|
-
const rows = db.prepare(
|
|
2238
|
-
`SELECT ${SELECT_COLUMNS11}
|
|
2239
|
-
FROM agent_reports
|
|
2240
|
-
WHERE run_id = ?
|
|
2241
|
-
ORDER BY created_at ASC`
|
|
2242
|
-
).all(runId);
|
|
2243
|
-
return rows.map(toReportRow);
|
|
2244
|
-
}
|
|
2245
|
-
|
|
2246
|
-
export {
|
|
2247
|
-
listNotifications,
|
|
2248
|
-
countNotifications,
|
|
2249
|
-
getNotification,
|
|
2250
|
-
updateNotificationStatus,
|
|
2251
|
-
dismissAllNotifications,
|
|
2252
|
-
markAllRead,
|
|
2253
|
-
register,
|
|
2254
|
-
getAllDomains,
|
|
2255
|
-
notify,
|
|
2256
|
-
insertCandidate,
|
|
2257
|
-
getCandidate,
|
|
2258
|
-
listCandidates,
|
|
2259
|
-
updateCandidate,
|
|
2260
|
-
listCandidatesWithCount,
|
|
2261
|
-
countCandidates,
|
|
2262
|
-
deleteCandidate,
|
|
2263
|
-
insertSkillRecord,
|
|
2264
|
-
getSkillRecord,
|
|
2265
|
-
getSkillRecordByName,
|
|
2266
|
-
listSkillRecords,
|
|
2267
|
-
updateSkillRecord,
|
|
2268
|
-
incrementSkillUsageCount,
|
|
2269
|
-
listSkillRecordsWithCount,
|
|
2270
|
-
countSkillRecords,
|
|
2271
|
-
deleteSkillRecordCascade,
|
|
2272
|
-
insertLineage,
|
|
2273
|
-
listLineageForSkill,
|
|
2274
|
-
populateBatchResponses,
|
|
2275
|
-
getUnprocessedBatches,
|
|
2276
|
-
incrementActivityCount,
|
|
2277
|
-
markBatchProcessed,
|
|
2278
|
-
findBatchByPromptPrefix,
|
|
2279
|
-
insertBatchStateless,
|
|
2280
|
-
closeOpenBatches,
|
|
2281
|
-
setResponseSummary,
|
|
2282
|
-
getLatestBatch,
|
|
2283
|
-
listBatchesBySession,
|
|
2284
|
-
countBatchesBySession,
|
|
2285
|
-
errorMessage,
|
|
2286
|
-
STATUS_RUNNING,
|
|
2287
|
-
STATUS_COMPLETED,
|
|
2288
|
-
STATUS_FAILED,
|
|
2289
|
-
insertRun,
|
|
2290
|
-
getRun,
|
|
2291
|
-
listRuns,
|
|
2292
|
-
countRuns,
|
|
2293
|
-
updateRunStatus,
|
|
2294
|
-
getRunningRunForTask,
|
|
2295
|
-
getLatestRunId,
|
|
2296
|
-
setState,
|
|
2297
|
-
getStatesForAgent,
|
|
2298
|
-
insertGraphEdge,
|
|
2299
|
-
listGraphEdges,
|
|
2300
|
-
getGraphForNode,
|
|
2301
|
-
insertEntity,
|
|
2302
|
-
getEntity,
|
|
2303
|
-
listEntities,
|
|
2304
|
-
createSporeLineage,
|
|
2305
|
-
createBatchLineage,
|
|
2306
|
-
insertResolutionEvent,
|
|
2307
|
-
upsertDigestExtract,
|
|
2308
|
-
getDigestExtract,
|
|
2309
|
-
listDigestExtracts,
|
|
2310
|
-
insertReport,
|
|
2311
|
-
listReports,
|
|
2312
|
-
descriptionSimilarity,
|
|
2313
|
-
topicOverlapSimilarity,
|
|
2314
|
-
DESCRIPTION_DUPLICATE_THRESHOLD,
|
|
2315
|
-
TOPIC_OVERLAP_THRESHOLD,
|
|
2316
|
-
checkFrontmatterPreservation,
|
|
2317
|
-
validateSkillContent,
|
|
2318
|
-
hasConfiguredProvider,
|
|
2319
|
-
resolveRunConfig,
|
|
2320
|
-
SKILL_GENERATE_TASK,
|
|
2321
|
-
SKILL_SURVEY_TASK,
|
|
2322
|
-
getSkillSurveyEligibility,
|
|
2323
|
-
buildTaskInstruction,
|
|
2324
|
-
isInstructionRequiredTask
|
|
2325
|
-
};
|
|
2326
|
-
//# sourceMappingURL=chunk-UYMFCYBF.js.map
|