@goondocks/myco 0.14.4 → 0.15.1
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-run-GZ5UVLDV.js → agent-run-T433ENJS.js} +6 -6
- package/dist/{agent-tasks-KKQ2GBBB.js → agent-tasks-TAIU3V5I.js} +6 -6
- package/dist/{chunk-X34OFKYU.js → chunk-23FJUKCN.js} +2 -2
- package/dist/{chunk-LD6U3L6O.js → chunk-2QMDRZPJ.js} +21 -17
- package/dist/chunk-2QMDRZPJ.js.map +1 -0
- package/dist/{chunk-KNTJOMWY.js → chunk-3MEOYXOW.js} +2 -2
- package/dist/{chunk-PSYLKCWQ.js → chunk-4BQ5QE76.js} +24 -5
- package/dist/chunk-4BQ5QE76.js.map +1 -0
- package/dist/{chunk-UZ5Y6XMP.js → chunk-4O3QNM5I.js} +2 -2
- package/dist/{chunk-JTYZRPX5.js → chunk-5ZT2Q6P5.js} +1 -1
- package/dist/{chunk-BCKYVLUZ.js → chunk-6GG2IVNV.js} +3 -3
- package/dist/{chunk-JJXVDCEX.js → chunk-75J2BR4P.js} +486 -488
- package/dist/chunk-75J2BR4P.js.map +1 -0
- package/dist/{chunk-TFBAV3PV.js → chunk-BFM6AM6R.js} +2 -2
- package/dist/{chunk-S6I62FAH.js → chunk-CUADDHHU.js} +4 -2
- package/dist/{chunk-S6I62FAH.js.map → chunk-CUADDHHU.js.map} +1 -1
- package/dist/{chunk-4VF6KQ2Z.js → chunk-DJQOYEK3.js} +87 -84
- package/dist/chunk-DJQOYEK3.js.map +1 -0
- package/dist/{chunk-OQVKLTQY.js → chunk-EYMKBNRP.js} +2 -2
- package/dist/{chunk-STBNNKL5.js → chunk-GCCBXCHF.js} +6 -6
- package/dist/{chunk-KH64DHOY.js → chunk-GDY63YAW.js} +279 -277
- package/dist/chunk-GDY63YAW.js.map +1 -0
- package/dist/{chunk-ZESTWGJT.js → chunk-GYIA6XLB.js} +2 -2
- package/dist/{chunk-S66YG6QK.js → chunk-LF5Z62X6.js} +46 -7
- package/dist/chunk-LF5Z62X6.js.map +1 -0
- package/dist/{chunk-PX5KIOKY.js → chunk-SPJGJEFV.js} +10 -2
- package/dist/{chunk-PX5KIOKY.js.map → chunk-SPJGJEFV.js.map} +1 -1
- package/dist/{chunk-QFMBZ72S.js → chunk-SV6UCB2Z.js} +2 -2
- package/dist/{chunk-GMTWRMLP.js → chunk-TQO4PF5K.js} +3 -3
- package/dist/{chunk-NVCGF2DS.js → chunk-X4XFJG6I.js} +10 -6
- package/dist/chunk-X4XFJG6I.js.map +1 -0
- package/dist/{chunk-TNCBMGWB.js → chunk-X5IXK5KO.js} +262 -226
- package/dist/chunk-X5IXK5KO.js.map +1 -0
- package/dist/{chunk-TVV6PZOC.js → chunk-Z7TZJ2SP.js} +2 -2
- package/dist/{cli-JLDCZ77U.js → cli-W37MRZHD.js} +45 -44
- package/dist/cli-W37MRZHD.js.map +1 -0
- package/dist/{client-LRQMMKLP.js → client-YNTTC75R.js} +4 -4
- package/dist/{config-H657SF6B.js → config-MOWCOJJ4.js} +4 -4
- package/dist/{detect-27DN6UTL.js → detect-GFYKKHLJ.js} +3 -3
- package/dist/{detect-providers-PAVE2X6O.js → detect-providers-EU35RUL3.js} +2 -2
- package/dist/{doctor-IG3CXMI7.js → doctor-PAAQU5AS.js} +38 -19
- package/dist/doctor-PAAQU5AS.js.map +1 -0
- package/dist/{executor-HKNINUWO.js → executor-4OXDK4ZA.js} +790 -312
- package/dist/executor-4OXDK4ZA.js.map +1 -0
- package/dist/{init-RHQUINC2.js → init-PHQAQANR.js} +41 -23
- package/dist/init-PHQAQANR.js.map +1 -0
- package/dist/{init-wizard-ZB3JRDLE.js → init-wizard-RFD46XAJ.js} +7 -7
- package/dist/{installer-25TSX4SR.js → installer-BTUNKWOU.js} +2 -2
- package/dist/{llm-T3QVHC3Y.js → llm-D4VWYUK7.js} +4 -4
- package/dist/{loader-WQKVWL5D.js → loader-WC4U5NM5.js} +4 -4
- package/dist/{loader-JQLO6K44.js → loader-WGDVRGLM.js} +6 -4
- package/dist/{logs-LXHPDKUA.js → logs-WFBX2I7C.js} +3 -3
- package/dist/{main-MVXPBP5Z.js → main-ADLCOYKM.js} +2351 -1914
- package/dist/main-ADLCOYKM.js.map +1 -0
- package/dist/{open-CVEMRH3Z.js → open-3VPUP3HD.js} +6 -6
- package/dist/{openai-embeddings-5T5ZP7LO.js → openai-embeddings-SEIV7AM3.js} +2 -2
- package/dist/{openrouter-RD2COFC7.js → openrouter-ELODIZRP.js} +2 -2
- package/dist/{post-compact-ALQ2UGZ7.js → post-compact-5NYLOC46.js} +9 -9
- package/dist/{post-tool-use-SPL7HIYU.js → post-tool-use-SNNXSZ5Y.js} +10 -10
- package/dist/{post-tool-use-failure-B3CUYBTR.js → post-tool-use-failure-POKVXQHY.js} +9 -9
- package/dist/{pre-compact-KPWC4V64.js → pre-compact-ZUICBJEX.js} +9 -9
- package/dist/{provider-check-QN7OGXZA.js → provider-check-B66E5PWS.js} +2 -2
- package/dist/{registry-2XQMCPA6.js → registry-DHWVHXWY.js} +5 -5
- package/dist/{remove-O2WCN6RC.js → remove-SVU2V4Q7.js} +52 -20
- package/dist/remove-SVU2V4Q7.js.map +1 -0
- package/dist/{resolution-events-5EVUEWHS.js → resolution-events-DBCRVZGU.js} +4 -4
- package/dist/{restart-S52VV3SP.js → restart-NBB5CXJ4.js} +7 -7
- package/dist/{search-IOJ5O37S.js → search-YUQZFRZX.js} +6 -6
- package/dist/{server-T4VPK6FU.js → server-NBRX56VL.js} +8 -8
- package/dist/{session-ID6BX72K.js → session-2QP4HMZ5.js} +8 -8
- package/dist/{session-end-I7ZABXRI.js → session-end-NNFBW7CQ.js} +10 -10
- package/dist/{session-start-VPOUY42U.js → session-start-NPNP4IXX.js} +15 -15
- package/dist/{setup-llm-G5UG5N3T.js → setup-llm-C3IGFLRN.js} +8 -8
- package/dist/src/agent/definitions/tasks/full-intelligence.yaml +8 -7
- package/dist/src/agent/definitions/tasks/skill-evolve.yaml +71 -144
- package/dist/src/agent/definitions/tasks/skill-generate.yaml +10 -62
- package/dist/src/agent/definitions/tasks/skill-survey.yaml +87 -53
- package/dist/src/agent/prompts/agent.md +1 -0
- 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/worker/src/schema.ts +14 -0
- package/dist/{stats-GRI4MTS2.js → stats-FEEXIRMS.js} +9 -9
- package/dist/{stop-UTZ2CXI2.js → stop-FGDGWXTK.js} +10 -10
- package/dist/{stop-failure-CECM5NB7.js → stop-failure-5YAGH2TQ.js} +9 -9
- package/dist/{subagent-start-SYZGJYUN.js → subagent-start-UCKVJDR4.js} +9 -9
- package/dist/{subagent-stop-7WWW7TGQ.js → subagent-stop-H25B3QEC.js} +9 -9
- package/dist/{task-completed-N7SIY6T6.js → task-completed-2JGZN2CF.js} +9 -9
- package/dist/{team-SJPDXELY.js → team-TG5WZXWO.js} +34 -26
- package/dist/team-TG5WZXWO.js.map +1 -0
- package/dist/ui/assets/index-7Vimyg7g.js +837 -0
- package/dist/ui/assets/{index-BmsHIwjl.css → index-DlEQ8A8Y.css} +1 -1
- package/dist/ui/index.html +2 -2
- package/dist/{update-DZZYQ4NJ.js → update-EG3N2EXI.js} +30 -14
- package/dist/update-EG3N2EXI.js.map +1 -0
- package/dist/{user-prompt-submit-UUNRRS5P.js → user-prompt-submit-7FFQ3ORA.js} +10 -10
- package/dist/{verify-JHIMXTY5.js → verify-2M3DYHEY.js} +6 -6
- package/dist/{version-VKNCAPZW.js → version-JUQU5W22.js} +2 -2
- package/package.json +3 -3
- package/dist/chunk-4VF6KQ2Z.js.map +0 -1
- package/dist/chunk-JJXVDCEX.js.map +0 -1
- package/dist/chunk-KH64DHOY.js.map +0 -1
- package/dist/chunk-LD6U3L6O.js.map +0 -1
- package/dist/chunk-NVCGF2DS.js.map +0 -1
- package/dist/chunk-PSYLKCWQ.js.map +0 -1
- package/dist/chunk-S66YG6QK.js.map +0 -1
- package/dist/chunk-TNCBMGWB.js.map +0 -1
- package/dist/cli-JLDCZ77U.js.map +0 -1
- package/dist/doctor-IG3CXMI7.js.map +0 -1
- package/dist/executor-HKNINUWO.js.map +0 -1
- package/dist/init-RHQUINC2.js.map +0 -1
- package/dist/main-MVXPBP5Z.js.map +0 -1
- package/dist/remove-O2WCN6RC.js.map +0 -1
- package/dist/resolve-3FEUV462.js +0 -9
- package/dist/team-SJPDXELY.js.map +0 -1
- package/dist/ui/assets/index-Cn6cQwJy.js +0 -842
- package/dist/update-DZZYQ4NJ.js.map +0 -1
- package/dist/version-VKNCAPZW.js.map +0 -1
- /package/dist/{agent-run-GZ5UVLDV.js.map → agent-run-T433ENJS.js.map} +0 -0
- /package/dist/{agent-tasks-KKQ2GBBB.js.map → agent-tasks-TAIU3V5I.js.map} +0 -0
- /package/dist/{chunk-X34OFKYU.js.map → chunk-23FJUKCN.js.map} +0 -0
- /package/dist/{chunk-KNTJOMWY.js.map → chunk-3MEOYXOW.js.map} +0 -0
- /package/dist/{chunk-UZ5Y6XMP.js.map → chunk-4O3QNM5I.js.map} +0 -0
- /package/dist/{chunk-JTYZRPX5.js.map → chunk-5ZT2Q6P5.js.map} +0 -0
- /package/dist/{chunk-BCKYVLUZ.js.map → chunk-6GG2IVNV.js.map} +0 -0
- /package/dist/{chunk-TFBAV3PV.js.map → chunk-BFM6AM6R.js.map} +0 -0
- /package/dist/{chunk-OQVKLTQY.js.map → chunk-EYMKBNRP.js.map} +0 -0
- /package/dist/{chunk-STBNNKL5.js.map → chunk-GCCBXCHF.js.map} +0 -0
- /package/dist/{chunk-ZESTWGJT.js.map → chunk-GYIA6XLB.js.map} +0 -0
- /package/dist/{chunk-QFMBZ72S.js.map → chunk-SV6UCB2Z.js.map} +0 -0
- /package/dist/{chunk-GMTWRMLP.js.map → chunk-TQO4PF5K.js.map} +0 -0
- /package/dist/{chunk-TVV6PZOC.js.map → chunk-Z7TZJ2SP.js.map} +0 -0
- /package/dist/{client-LRQMMKLP.js.map → client-YNTTC75R.js.map} +0 -0
- /package/dist/{config-H657SF6B.js.map → config-MOWCOJJ4.js.map} +0 -0
- /package/dist/{detect-27DN6UTL.js.map → detect-GFYKKHLJ.js.map} +0 -0
- /package/dist/{detect-providers-PAVE2X6O.js.map → detect-providers-EU35RUL3.js.map} +0 -0
- /package/dist/{init-wizard-ZB3JRDLE.js.map → init-wizard-RFD46XAJ.js.map} +0 -0
- /package/dist/{installer-25TSX4SR.js.map → installer-BTUNKWOU.js.map} +0 -0
- /package/dist/{llm-T3QVHC3Y.js.map → llm-D4VWYUK7.js.map} +0 -0
- /package/dist/{loader-JQLO6K44.js.map → loader-WC4U5NM5.js.map} +0 -0
- /package/dist/{loader-WQKVWL5D.js.map → loader-WGDVRGLM.js.map} +0 -0
- /package/dist/{logs-LXHPDKUA.js.map → logs-WFBX2I7C.js.map} +0 -0
- /package/dist/{open-CVEMRH3Z.js.map → open-3VPUP3HD.js.map} +0 -0
- /package/dist/{openai-embeddings-5T5ZP7LO.js.map → openai-embeddings-SEIV7AM3.js.map} +0 -0
- /package/dist/{openrouter-RD2COFC7.js.map → openrouter-ELODIZRP.js.map} +0 -0
- /package/dist/{post-compact-ALQ2UGZ7.js.map → post-compact-5NYLOC46.js.map} +0 -0
- /package/dist/{post-tool-use-SPL7HIYU.js.map → post-tool-use-SNNXSZ5Y.js.map} +0 -0
- /package/dist/{post-tool-use-failure-B3CUYBTR.js.map → post-tool-use-failure-POKVXQHY.js.map} +0 -0
- /package/dist/{pre-compact-KPWC4V64.js.map → pre-compact-ZUICBJEX.js.map} +0 -0
- /package/dist/{provider-check-QN7OGXZA.js.map → provider-check-B66E5PWS.js.map} +0 -0
- /package/dist/{registry-2XQMCPA6.js.map → registry-DHWVHXWY.js.map} +0 -0
- /package/dist/{resolution-events-5EVUEWHS.js.map → resolution-events-DBCRVZGU.js.map} +0 -0
- /package/dist/{restart-S52VV3SP.js.map → restart-NBB5CXJ4.js.map} +0 -0
- /package/dist/{search-IOJ5O37S.js.map → search-YUQZFRZX.js.map} +0 -0
- /package/dist/{server-T4VPK6FU.js.map → server-NBRX56VL.js.map} +0 -0
- /package/dist/{session-ID6BX72K.js.map → session-2QP4HMZ5.js.map} +0 -0
- /package/dist/{session-end-I7ZABXRI.js.map → session-end-NNFBW7CQ.js.map} +0 -0
- /package/dist/{session-start-VPOUY42U.js.map → session-start-NPNP4IXX.js.map} +0 -0
- /package/dist/{setup-llm-G5UG5N3T.js.map → setup-llm-C3IGFLRN.js.map} +0 -0
- /package/dist/{stats-GRI4MTS2.js.map → stats-FEEXIRMS.js.map} +0 -0
- /package/dist/{stop-UTZ2CXI2.js.map → stop-FGDGWXTK.js.map} +0 -0
- /package/dist/{stop-failure-CECM5NB7.js.map → stop-failure-5YAGH2TQ.js.map} +0 -0
- /package/dist/{subagent-start-SYZGJYUN.js.map → subagent-start-UCKVJDR4.js.map} +0 -0
- /package/dist/{subagent-stop-7WWW7TGQ.js.map → subagent-stop-H25B3QEC.js.map} +0 -0
- /package/dist/{task-completed-N7SIY6T6.js.map → task-completed-2JGZN2CF.js.map} +0 -0
- /package/dist/{user-prompt-submit-UUNRRS5P.js.map → user-prompt-submit-7FFQ3ORA.js.map} +0 -0
- /package/dist/{verify-JHIMXTY5.js.map → verify-2M3DYHEY.js.map} +0 -0
- /package/dist/{resolve-3FEUV462.js.map → version-JUQU5W22.js.map} +0 -0
|
@@ -30,13 +30,13 @@ import {
|
|
|
30
30
|
updateRunStatus,
|
|
31
31
|
updateSkillRecord,
|
|
32
32
|
upsertDigestExtract
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-75J2BR4P.js";
|
|
34
34
|
import {
|
|
35
35
|
fullTextSearch
|
|
36
36
|
} from "./chunk-DTE3SHYK.js";
|
|
37
37
|
import {
|
|
38
38
|
loadAllTasks
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-3MEOYXOW.js";
|
|
40
40
|
import {
|
|
41
41
|
getAgent,
|
|
42
42
|
getDefaultTask,
|
|
@@ -45,31 +45,31 @@ import {
|
|
|
45
45
|
loadSystemPrompt,
|
|
46
46
|
resolveDefinitionsDir,
|
|
47
47
|
resolveEffectiveConfig
|
|
48
|
-
} from "./chunk-
|
|
48
|
+
} from "./chunk-X4XFJG6I.js";
|
|
49
49
|
import {
|
|
50
50
|
insertTurn
|
|
51
51
|
} from "./chunk-QLCD77AN.js";
|
|
52
52
|
import {
|
|
53
53
|
insertResolutionEvent
|
|
54
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-Z7TZJ2SP.js";
|
|
55
55
|
import "./chunk-IB76KGBY.js";
|
|
56
56
|
import {
|
|
57
57
|
DEFAULT_IMPORTANCE,
|
|
58
58
|
insertSpore,
|
|
59
59
|
listSpores,
|
|
60
60
|
updateSporeStatus
|
|
61
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-SPJGJEFV.js";
|
|
62
62
|
import {
|
|
63
63
|
listSessions,
|
|
64
64
|
updateSession
|
|
65
|
-
} from "./chunk-
|
|
66
|
-
import "./chunk-
|
|
65
|
+
} from "./chunk-23FJUKCN.js";
|
|
66
|
+
import "./chunk-LF5Z62X6.js";
|
|
67
67
|
import {
|
|
68
68
|
createSchema
|
|
69
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-DJQOYEK3.js";
|
|
70
70
|
import {
|
|
71
71
|
loadConfig
|
|
72
|
-
} from "./chunk-
|
|
72
|
+
} from "./chunk-4BQ5QE76.js";
|
|
73
73
|
import {
|
|
74
74
|
getDatabase,
|
|
75
75
|
initDatabase,
|
|
@@ -77,7 +77,7 @@ import {
|
|
|
77
77
|
} from "./chunk-MYX5NCRH.js";
|
|
78
78
|
import {
|
|
79
79
|
getPluginVersion
|
|
80
|
-
} from "./chunk-
|
|
80
|
+
} from "./chunk-BFM6AM6R.js";
|
|
81
81
|
import {
|
|
82
82
|
findPackageRoot
|
|
83
83
|
} from "./chunk-LPUQPDC2.js";
|
|
@@ -90,23 +90,23 @@ import {
|
|
|
90
90
|
TEAM_SOURCE_PREFIX,
|
|
91
91
|
epochSeconds
|
|
92
92
|
} from "./chunk-TRA3R4EC.js";
|
|
93
|
-
import "./chunk-
|
|
93
|
+
import "./chunk-CUADDHHU.js";
|
|
94
94
|
import "./chunk-D7TYRPRM.js";
|
|
95
95
|
import "./chunk-E4VLWIJC.js";
|
|
96
96
|
import {
|
|
97
97
|
external_exports
|
|
98
|
-
} from "./chunk-
|
|
98
|
+
} from "./chunk-GDY63YAW.js";
|
|
99
99
|
import "./chunk-PZUWP5VK.js";
|
|
100
100
|
|
|
101
101
|
// src/agent/executor.ts
|
|
102
|
-
import
|
|
102
|
+
import crypto4 from "crypto";
|
|
103
103
|
import { resolve as resolve2 } from "path";
|
|
104
104
|
|
|
105
105
|
// src/agent/tools.ts
|
|
106
|
-
import
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
import { tool
|
|
106
|
+
import { createSdkMcpServer } from "@anthropic-ai/claude-agent-sdk";
|
|
107
|
+
|
|
108
|
+
// src/agent/tools/read-tools.ts
|
|
109
|
+
import { tool } from "@anthropic-ai/claude-agent-sdk";
|
|
110
110
|
|
|
111
111
|
// src/db/queries/agent-state.ts
|
|
112
112
|
var STATE_COLUMNS = [
|
|
@@ -148,77 +148,20 @@ function getStatesForAgent(agentId) {
|
|
|
148
148
|
return rows.map(toAgentStateRow);
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
-
// src/agent/tools.ts
|
|
151
|
+
// src/agent/tools/types.ts
|
|
152
|
+
function textResult(data) {
|
|
153
|
+
return { content: [{ type: "text", text: JSON.stringify(data) }] };
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// src/agent/tools/read-tools.ts
|
|
152
157
|
var DEFAULT_UNPROCESSED_LIMIT = 50;
|
|
153
158
|
var DEFAULT_SPORES_LIMIT = 50;
|
|
154
159
|
var DEFAULT_SESSIONS_LIMIT = 20;
|
|
155
160
|
var DEFAULT_SEARCH_LIMIT = 10;
|
|
156
161
|
var DEFAULT_ENTITIES_LIMIT = 50;
|
|
157
162
|
var DEFAULT_EDGES_LIMIT = 50;
|
|
158
|
-
function
|
|
159
|
-
|
|
160
|
-
}
|
|
161
|
-
var MAX_SKILL_LINES = 500;
|
|
162
|
-
var REQUIRED_FRONTMATTER_FIELDS = ["name", "description", "managed_by", "user-invocable", "allowed-tools"];
|
|
163
|
-
function validateSkillContent(content, dirName) {
|
|
164
|
-
const issues = [];
|
|
165
|
-
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
166
|
-
if (!fmMatch) {
|
|
167
|
-
issues.push("Missing YAML frontmatter (must start with --- and end with ---)");
|
|
168
|
-
return issues;
|
|
169
|
-
}
|
|
170
|
-
const frontmatter = fmMatch[1];
|
|
171
|
-
for (const field of REQUIRED_FRONTMATTER_FIELDS) {
|
|
172
|
-
if (!frontmatter.includes(`${field}:`)) {
|
|
173
|
-
issues.push(`Missing required frontmatter field: ${field}`);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
const nameMatch = frontmatter.match(/^name:\s*(.+)$/m);
|
|
177
|
-
if (nameMatch && !nameMatch[1].trim().startsWith("myco:")) {
|
|
178
|
-
issues.push(`Skill name must start with "myco:" prefix. Got: "${nameMatch[1].trim()}"`);
|
|
179
|
-
}
|
|
180
|
-
const managedMatch = frontmatter.match(/^managed_by:\s*(.+)$/m);
|
|
181
|
-
if (managedMatch && managedMatch[1].trim() !== "myco") {
|
|
182
|
-
issues.push(`managed_by must be "myco". Got: "${managedMatch[1].trim()}"`);
|
|
183
|
-
}
|
|
184
|
-
const allowedToolsMatch = frontmatter.match(/^allowed-tools:\s*(.+)$/m);
|
|
185
|
-
if (allowedToolsMatch) {
|
|
186
|
-
const toolsValue = allowedToolsMatch[1].trim();
|
|
187
|
-
if (toolsValue.includes("vault_")) {
|
|
188
|
-
issues.push(
|
|
189
|
-
"allowed-tools contains vault agent tool names (vault_*). Skills run in Claude Code sessions \u2014 use Claude Code tool names instead: Read, Edit, Write, Bash, Grep, Glob"
|
|
190
|
-
);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
const listToolLines = frontmatter.match(/^\s+-\s+vault_\w+/gm);
|
|
194
|
-
if (listToolLines) {
|
|
195
|
-
issues.push(
|
|
196
|
-
"allowed-tools contains vault agent tool names (vault_*). Skills run in Claude Code sessions \u2014 use Claude Code tool names instead: Read, Edit, Write, Bash, Grep, Glob"
|
|
197
|
-
);
|
|
198
|
-
}
|
|
199
|
-
const lineCount = content.split("\n").length;
|
|
200
|
-
if (lineCount > MAX_SKILL_LINES) {
|
|
201
|
-
issues.push(`Skill is ${lineCount} lines (max ${MAX_SKILL_LINES})`);
|
|
202
|
-
}
|
|
203
|
-
return issues;
|
|
204
|
-
}
|
|
205
|
-
function createVaultTools(agentId, runId, options) {
|
|
206
|
-
const { turnOffset = 0, embeddingManager, teamClient, machineId, projectRoot, vaultDir } = options ?? {};
|
|
207
|
-
let turnCounter = turnOffset;
|
|
208
|
-
function recordTurn(toolName, toolInput) {
|
|
209
|
-
turnCounter++;
|
|
210
|
-
try {
|
|
211
|
-
insertTurn({
|
|
212
|
-
run_id: runId,
|
|
213
|
-
agent_id: agentId,
|
|
214
|
-
turn_number: turnCounter,
|
|
215
|
-
tool_name: toolName,
|
|
216
|
-
tool_input: JSON.stringify(toolInput),
|
|
217
|
-
started_at: epochSeconds()
|
|
218
|
-
});
|
|
219
|
-
} catch {
|
|
220
|
-
}
|
|
221
|
-
}
|
|
163
|
+
function createReadTools(deps) {
|
|
164
|
+
const { agentId, embeddingManager, teamClient, machineId, recordTurn } = deps;
|
|
222
165
|
const vaultUnprocessed = tool(
|
|
223
166
|
"vault_unprocessed",
|
|
224
167
|
"Get unprocessed prompt batches, ordered by id ASC. Supports cursor-based pagination.",
|
|
@@ -337,7 +280,7 @@ function createVaultTools(agentId, runId, options) {
|
|
|
337
280
|
return textResult({ results: [], message: "Semantic search unavailable" });
|
|
338
281
|
}
|
|
339
282
|
},
|
|
340
|
-
{ annotations: { readOnlyHint: true } }
|
|
283
|
+
{ annotations: { readOnlyHint: true, openWorldHint: true } }
|
|
341
284
|
);
|
|
342
285
|
const vaultState = tool(
|
|
343
286
|
"vault_state",
|
|
@@ -392,7 +335,24 @@ function createVaultTools(agentId, runId, options) {
|
|
|
392
335
|
},
|
|
393
336
|
{ annotations: { readOnlyHint: true } }
|
|
394
337
|
);
|
|
395
|
-
|
|
338
|
+
return [
|
|
339
|
+
vaultUnprocessed,
|
|
340
|
+
vaultSpores,
|
|
341
|
+
vaultSessions,
|
|
342
|
+
vaultSearchFts,
|
|
343
|
+
vaultSearchSemantic,
|
|
344
|
+
vaultState,
|
|
345
|
+
vaultEntities,
|
|
346
|
+
vaultEdges
|
|
347
|
+
];
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// src/agent/tools/write-tools.ts
|
|
351
|
+
import crypto from "crypto";
|
|
352
|
+
import { tool as tool2 } from "@anthropic-ai/claude-agent-sdk";
|
|
353
|
+
function createWriteTools(deps) {
|
|
354
|
+
const { agentId, embeddingManager, machineId, recordTurn } = deps;
|
|
355
|
+
const vaultCreateSpore = tool2(
|
|
396
356
|
"vault_create_spore",
|
|
397
357
|
"Create a new spore (observation) in the vault. The agent_id is set automatically.",
|
|
398
358
|
{
|
|
@@ -436,9 +396,10 @@ function createVaultTools(agentId, runId, options) {
|
|
|
436
396
|
});
|
|
437
397
|
recordTurn("vault_create_spore", args);
|
|
438
398
|
return textResult(spore);
|
|
439
|
-
}
|
|
399
|
+
},
|
|
400
|
+
{ annotations: { openWorldHint: true } }
|
|
440
401
|
);
|
|
441
|
-
const vaultCreateEntity =
|
|
402
|
+
const vaultCreateEntity = tool2(
|
|
442
403
|
"vault_create_entity",
|
|
443
404
|
"Create or update an entity in the knowledge graph. Uses UPSERT on (agent_id, type, name).",
|
|
444
405
|
{
|
|
@@ -462,9 +423,10 @@ function createVaultTools(agentId, runId, options) {
|
|
|
462
423
|
});
|
|
463
424
|
recordTurn("vault_create_entity", args);
|
|
464
425
|
return textResult(entity);
|
|
465
|
-
}
|
|
426
|
+
},
|
|
427
|
+
{ annotations: { idempotentHint: true } }
|
|
466
428
|
);
|
|
467
|
-
const vaultCreateEdge =
|
|
429
|
+
const vaultCreateEdge = tool2(
|
|
468
430
|
"vault_create_edge",
|
|
469
431
|
"Create a semantic edge in the knowledge graph. Lineage edges (FROM_SESSION, EXTRACTED_FROM, HAS_BATCH, DERIVED_FROM) are created automatically \u2014 do NOT create those.",
|
|
470
432
|
{
|
|
@@ -495,9 +457,10 @@ function createVaultTools(agentId, runId, options) {
|
|
|
495
457
|
});
|
|
496
458
|
recordTurn("vault_create_edge", args);
|
|
497
459
|
return textResult(edge);
|
|
498
|
-
}
|
|
460
|
+
},
|
|
461
|
+
{ annotations: { idempotentHint: true } }
|
|
499
462
|
);
|
|
500
|
-
const vaultResolveSpore =
|
|
463
|
+
const vaultResolveSpore = tool2(
|
|
501
464
|
"vault_resolve_spore",
|
|
502
465
|
"Resolve a spore by updating its status and recording a resolution event.",
|
|
503
466
|
{
|
|
@@ -538,9 +501,10 @@ function createVaultTools(agentId, runId, options) {
|
|
|
538
501
|
}
|
|
539
502
|
recordTurn("vault_resolve_spore", args);
|
|
540
503
|
return textResult({ spore: updatedSpore, resolution_event_id: eventId });
|
|
541
|
-
}
|
|
504
|
+
},
|
|
505
|
+
{ annotations: { destructiveHint: true } }
|
|
542
506
|
);
|
|
543
|
-
const vaultUpdateSession =
|
|
507
|
+
const vaultUpdateSession = tool2(
|
|
544
508
|
"vault_update_session",
|
|
545
509
|
"Update a session title and/or summary. When generating for the first time, provide BOTH title and summary. Title should be under 80 characters and reflect the full session scope.",
|
|
546
510
|
{
|
|
@@ -559,9 +523,10 @@ function createVaultTools(agentId, runId, options) {
|
|
|
559
523
|
}
|
|
560
524
|
recordTurn("vault_update_session", args);
|
|
561
525
|
return textResult(session);
|
|
562
|
-
}
|
|
526
|
+
},
|
|
527
|
+
{ annotations: { idempotentHint: true } }
|
|
563
528
|
);
|
|
564
|
-
const vaultSetState =
|
|
529
|
+
const vaultSetState = tool2(
|
|
565
530
|
"vault_set_state",
|
|
566
531
|
"Set a key-value state pair for the current agent. Used for bookmarks, cursors, and preferences.",
|
|
567
532
|
{
|
|
@@ -573,9 +538,10 @@ function createVaultTools(agentId, runId, options) {
|
|
|
573
538
|
const state = setState(agentId, args.key, args.value, now);
|
|
574
539
|
recordTurn("vault_set_state", args);
|
|
575
540
|
return textResult(state);
|
|
576
|
-
}
|
|
541
|
+
},
|
|
542
|
+
{ annotations: { idempotentHint: true } }
|
|
577
543
|
);
|
|
578
|
-
const vaultReadDigest =
|
|
544
|
+
const vaultReadDigest = tool2(
|
|
579
545
|
"vault_read_digest",
|
|
580
546
|
"Read current digest extracts. Without a tier parameter, returns a summary of all tiers (content length, generation time). With a tier parameter, returns the full content for that specific tier.",
|
|
581
547
|
{
|
|
@@ -597,7 +563,7 @@ function createVaultTools(agentId, runId, options) {
|
|
|
597
563
|
},
|
|
598
564
|
{ annotations: { readOnlyHint: true } }
|
|
599
565
|
);
|
|
600
|
-
const vaultWriteDigest =
|
|
566
|
+
const vaultWriteDigest = tool2(
|
|
601
567
|
"vault_write_digest",
|
|
602
568
|
"Write or update a digest extract at a specific token tier. Uses UPSERT on (agent_id, tier).",
|
|
603
569
|
{
|
|
@@ -614,9 +580,10 @@ function createVaultTools(agentId, runId, options) {
|
|
|
614
580
|
});
|
|
615
581
|
recordTurn("vault_write_digest", args);
|
|
616
582
|
return textResult(extract);
|
|
617
|
-
}
|
|
583
|
+
},
|
|
584
|
+
{ annotations: { idempotentHint: true } }
|
|
618
585
|
);
|
|
619
|
-
const vaultMarkProcessed =
|
|
586
|
+
const vaultMarkProcessed = tool2(
|
|
620
587
|
"vault_mark_processed",
|
|
621
588
|
"Mark a prompt batch as processed so it is not returned by vault_unprocessed.",
|
|
622
589
|
{
|
|
@@ -626,9 +593,27 @@ function createVaultTools(agentId, runId, options) {
|
|
|
626
593
|
const batch = markBatchProcessed(args.batch_id);
|
|
627
594
|
recordTurn("vault_mark_processed", args);
|
|
628
595
|
return textResult(batch);
|
|
629
|
-
}
|
|
596
|
+
},
|
|
597
|
+
{ annotations: { destructiveHint: true } }
|
|
630
598
|
);
|
|
631
|
-
|
|
599
|
+
return [
|
|
600
|
+
vaultCreateSpore,
|
|
601
|
+
vaultCreateEntity,
|
|
602
|
+
vaultCreateEdge,
|
|
603
|
+
vaultResolveSpore,
|
|
604
|
+
vaultUpdateSession,
|
|
605
|
+
vaultSetState,
|
|
606
|
+
vaultReadDigest,
|
|
607
|
+
vaultWriteDigest,
|
|
608
|
+
vaultMarkProcessed
|
|
609
|
+
];
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
// src/agent/tools/observability-tools.ts
|
|
613
|
+
import { tool as tool3 } from "@anthropic-ai/claude-agent-sdk";
|
|
614
|
+
function createObservabilityTools(deps) {
|
|
615
|
+
const { runId, agentId, recordTurn } = deps;
|
|
616
|
+
const vaultReport = tool3(
|
|
632
617
|
"vault_report",
|
|
633
618
|
'Record an observability report for the current run. Use action "skip" when skipping expected operations (e.g., not updating a session summary) with reasoning in the summary field.',
|
|
634
619
|
{
|
|
@@ -648,9 +633,210 @@ function createVaultTools(agentId, runId, options) {
|
|
|
648
633
|
created_at: now
|
|
649
634
|
});
|
|
650
635
|
return textResult(report);
|
|
651
|
-
}
|
|
636
|
+
},
|
|
637
|
+
{ annotations: {} }
|
|
638
|
+
);
|
|
639
|
+
return [vaultReport];
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
// src/agent/tools/skill-tools.ts
|
|
643
|
+
import crypto2 from "crypto";
|
|
644
|
+
import { readFileSync, writeFileSync, mkdirSync, rmSync, existsSync } from "fs";
|
|
645
|
+
import { resolve } from "path";
|
|
646
|
+
import { tool as tool4 } from "@anthropic-ai/claude-agent-sdk";
|
|
647
|
+
|
|
648
|
+
// src/agent/tools/skill-validator.ts
|
|
649
|
+
var MAX_SKILL_LINES = 500;
|
|
650
|
+
var REQUIRED_FRONTMATTER_FIELDS = ["name", "description", "managed_by", "user-invocable", "allowed-tools"];
|
|
651
|
+
var PROTECTED_FRONTMATTER_FIELDS = ["user-invocable", "allowed-tools"];
|
|
652
|
+
var ALLOWED_CLAUDE_CODE_TOOLS = /* @__PURE__ */ new Set([
|
|
653
|
+
"Read",
|
|
654
|
+
"Edit",
|
|
655
|
+
"Write",
|
|
656
|
+
"MultiEdit",
|
|
657
|
+
"Bash",
|
|
658
|
+
"Grep",
|
|
659
|
+
"Glob",
|
|
660
|
+
"NotebookRead",
|
|
661
|
+
"NotebookEdit",
|
|
662
|
+
"WebFetch",
|
|
663
|
+
"WebSearch",
|
|
664
|
+
"Task",
|
|
665
|
+
"TodoWrite"
|
|
666
|
+
]);
|
|
667
|
+
function extractFrontmatterField(content, field) {
|
|
668
|
+
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
669
|
+
if (!fmMatch) return void 0;
|
|
670
|
+
const match = fmMatch[1].match(new RegExp(`^${field}:\\s*(.+)$`, "m"));
|
|
671
|
+
return match?.[1].trim();
|
|
672
|
+
}
|
|
673
|
+
function parseAllowedTools(rawValue) {
|
|
674
|
+
if (!rawValue) return null;
|
|
675
|
+
let stripped = rawValue.trim();
|
|
676
|
+
if (stripped.length === 0) return null;
|
|
677
|
+
if (stripped.startsWith("[") && stripped.endsWith("]")) {
|
|
678
|
+
stripped = stripped.slice(1, -1).trim();
|
|
679
|
+
}
|
|
680
|
+
if (stripped.length === 0) return null;
|
|
681
|
+
const parts = stripped.split(",").map((s) => s.trim().replace(/^['"]|['"]$/g, "")).filter((s) => s.length > 0);
|
|
682
|
+
if (parts.length === 0) return null;
|
|
683
|
+
const sentinels = /* @__PURE__ */ new Set(["None", "none", "null", "Null", "~"]);
|
|
684
|
+
if (parts.some((p) => sentinels.has(p))) return null;
|
|
685
|
+
return parts;
|
|
686
|
+
}
|
|
687
|
+
function tokenSet(text) {
|
|
688
|
+
const stopwords = /* @__PURE__ */ new Set([
|
|
689
|
+
"the",
|
|
690
|
+
"a",
|
|
691
|
+
"an",
|
|
692
|
+
"and",
|
|
693
|
+
"or",
|
|
694
|
+
"but",
|
|
695
|
+
"is",
|
|
696
|
+
"are",
|
|
697
|
+
"was",
|
|
698
|
+
"were",
|
|
699
|
+
"be",
|
|
700
|
+
"been",
|
|
701
|
+
"being",
|
|
702
|
+
"have",
|
|
703
|
+
"has",
|
|
704
|
+
"had",
|
|
705
|
+
"do",
|
|
706
|
+
"does",
|
|
707
|
+
"did",
|
|
708
|
+
"will",
|
|
709
|
+
"would",
|
|
710
|
+
"should",
|
|
711
|
+
"could",
|
|
712
|
+
"may",
|
|
713
|
+
"might",
|
|
714
|
+
"must",
|
|
715
|
+
"can",
|
|
716
|
+
"this",
|
|
717
|
+
"that",
|
|
718
|
+
"these",
|
|
719
|
+
"those",
|
|
720
|
+
"with",
|
|
721
|
+
"from",
|
|
722
|
+
"into",
|
|
723
|
+
"onto",
|
|
724
|
+
"for",
|
|
725
|
+
"when",
|
|
726
|
+
"where",
|
|
727
|
+
"which",
|
|
728
|
+
"what",
|
|
729
|
+
"who",
|
|
730
|
+
"how",
|
|
731
|
+
"why",
|
|
732
|
+
"use",
|
|
733
|
+
"uses",
|
|
734
|
+
"used",
|
|
735
|
+
"using",
|
|
736
|
+
"not",
|
|
737
|
+
"also",
|
|
738
|
+
"than",
|
|
739
|
+
"then",
|
|
740
|
+
"ensure",
|
|
741
|
+
"ensures",
|
|
742
|
+
"make",
|
|
743
|
+
"makes"
|
|
744
|
+
]);
|
|
745
|
+
return new Set(
|
|
746
|
+
text.toLowerCase().replace(/[^a-z0-9_\s]/g, " ").split(/\s+/).filter((w) => w.length >= 4 && !stopwords.has(w))
|
|
652
747
|
);
|
|
653
|
-
|
|
748
|
+
}
|
|
749
|
+
function descriptionSimilarity(a, b) {
|
|
750
|
+
const aTokens = tokenSet(a);
|
|
751
|
+
const bTokens = tokenSet(b);
|
|
752
|
+
if (aTokens.size === 0 || bTokens.size === 0) return 0;
|
|
753
|
+
let intersection = 0;
|
|
754
|
+
for (const token of aTokens) {
|
|
755
|
+
if (bTokens.has(token)) intersection++;
|
|
756
|
+
}
|
|
757
|
+
const union = aTokens.size + bTokens.size - intersection;
|
|
758
|
+
return union === 0 ? 0 : intersection / union;
|
|
759
|
+
}
|
|
760
|
+
var DESCRIPTION_DUPLICATE_THRESHOLD = 0.4;
|
|
761
|
+
function checkFrontmatterPreservation(existing, incoming) {
|
|
762
|
+
const violations = [];
|
|
763
|
+
for (const field of PROTECTED_FRONTMATTER_FIELDS) {
|
|
764
|
+
const oldValue = extractFrontmatterField(existing, field);
|
|
765
|
+
const newValue = extractFrontmatterField(incoming, field);
|
|
766
|
+
if (oldValue !== void 0 && newValue !== void 0 && oldValue !== newValue) {
|
|
767
|
+
violations.push(`${field}: was "${oldValue}", changed to "${newValue}"`);
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
const oldDesc = extractFrontmatterField(existing, "description");
|
|
771
|
+
const newDesc = extractFrontmatterField(incoming, "description");
|
|
772
|
+
if (oldDesc && newDesc && newDesc.length < oldDesc.length * 0.9) {
|
|
773
|
+
violations.push(
|
|
774
|
+
`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.`
|
|
775
|
+
);
|
|
776
|
+
}
|
|
777
|
+
return violations;
|
|
778
|
+
}
|
|
779
|
+
function validateSkillContent(content, dirName) {
|
|
780
|
+
const issues = [];
|
|
781
|
+
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
782
|
+
if (!fmMatch) {
|
|
783
|
+
issues.push("Missing YAML frontmatter (must start with --- and end with ---)");
|
|
784
|
+
return issues;
|
|
785
|
+
}
|
|
786
|
+
const frontmatter = fmMatch[1];
|
|
787
|
+
for (const field of REQUIRED_FRONTMATTER_FIELDS) {
|
|
788
|
+
if (!frontmatter.includes(`${field}:`)) {
|
|
789
|
+
issues.push(`Missing required frontmatter field: ${field}`);
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
const nameMatch = frontmatter.match(/^name:\s*(.+)$/m);
|
|
793
|
+
if (nameMatch && !nameMatch[1].trim().startsWith("myco:")) {
|
|
794
|
+
issues.push(`Skill name must start with "myco:" prefix. Got: "${nameMatch[1].trim()}"`);
|
|
795
|
+
}
|
|
796
|
+
const managedMatch = frontmatter.match(/^managed_by:\s*(.+)$/m);
|
|
797
|
+
if (managedMatch && managedMatch[1].trim() !== "myco") {
|
|
798
|
+
issues.push(`managed_by must be "myco". Got: "${managedMatch[1].trim()}"`);
|
|
799
|
+
}
|
|
800
|
+
const allowedToolsMatch = frontmatter.match(/^allowed-tools:\s*(.+)$/m);
|
|
801
|
+
if (allowedToolsMatch) {
|
|
802
|
+
const rawValue = allowedToolsMatch[1].trim();
|
|
803
|
+
if (rawValue.includes("vault_")) {
|
|
804
|
+
issues.push(
|
|
805
|
+
"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"
|
|
806
|
+
);
|
|
807
|
+
} else {
|
|
808
|
+
const parsed = parseAllowedTools(rawValue);
|
|
809
|
+
if (parsed === null) {
|
|
810
|
+
issues.push(
|
|
811
|
+
`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.`
|
|
812
|
+
);
|
|
813
|
+
} else {
|
|
814
|
+
const unknown = parsed.filter((t) => !ALLOWED_CLAUDE_CODE_TOOLS.has(t));
|
|
815
|
+
if (unknown.length > 0) {
|
|
816
|
+
issues.push(
|
|
817
|
+
`allowed-tools contains unknown tool name(s): ${unknown.join(", ")}. Valid Claude Code tools: ${[...ALLOWED_CLAUDE_CODE_TOOLS].join(", ")}.`
|
|
818
|
+
);
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
const listToolLines = frontmatter.match(/^\s+-\s+vault_\w+/gm);
|
|
824
|
+
if (listToolLines) {
|
|
825
|
+
issues.push(
|
|
826
|
+
"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"
|
|
827
|
+
);
|
|
828
|
+
}
|
|
829
|
+
const lineCount = content.split("\n").length;
|
|
830
|
+
if (lineCount > MAX_SKILL_LINES) {
|
|
831
|
+
issues.push(`Skill is ${lineCount} lines (max ${MAX_SKILL_LINES})`);
|
|
832
|
+
}
|
|
833
|
+
return issues;
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
// src/agent/tools/skill-tools.ts
|
|
837
|
+
function createSkillTools(deps) {
|
|
838
|
+
const { agentId, machineId, projectRoot, vaultDir, recordTurn } = deps;
|
|
839
|
+
const vaultSkillCandidates = tool4(
|
|
654
840
|
"vault_skill_candidates",
|
|
655
841
|
"Manage skill candidates (identified topics that may become skills). Supports list, get, create, and update actions.",
|
|
656
842
|
{
|
|
@@ -685,9 +871,22 @@ function createVaultTools(agentId, runId, options) {
|
|
|
685
871
|
if (!args.topic || !args.rationale) {
|
|
686
872
|
return textResult({ error: "topic and rationale are required for create action" });
|
|
687
873
|
}
|
|
874
|
+
const activeSkills = listSkillRecords({ agent_id: agentId, status: "active", limit: 100 });
|
|
875
|
+
const topicLower = args.topic.toLowerCase();
|
|
876
|
+
const overlapping = activeSkills.filter((s) => {
|
|
877
|
+
const nameWords = s.name.split("-").filter((w) => w.length > 2);
|
|
878
|
+
if (nameWords.length < 2) return false;
|
|
879
|
+
return nameWords.every((w) => topicLower.includes(w));
|
|
880
|
+
});
|
|
881
|
+
if (overlapping.length > 0) {
|
|
882
|
+
return textResult({
|
|
883
|
+
error: "Candidate rejected: active skill(s) already cover this topic. Update the existing skill via vault_skill_records instead.",
|
|
884
|
+
overlapping_skills: overlapping.map((s) => ({ name: s.name, display_name: s.display_name, description: s.description }))
|
|
885
|
+
});
|
|
886
|
+
}
|
|
688
887
|
const now = epochSeconds();
|
|
689
888
|
const candidate = insertCandidate({
|
|
690
|
-
id:
|
|
889
|
+
id: crypto2.randomUUID(),
|
|
691
890
|
agent_id: agentId,
|
|
692
891
|
machine_id: machineId,
|
|
693
892
|
topic: args.topic,
|
|
@@ -732,9 +931,10 @@ function createVaultTools(agentId, runId, options) {
|
|
|
732
931
|
default:
|
|
733
932
|
return textResult({ error: `Unknown action: ${args.action}` });
|
|
734
933
|
}
|
|
735
|
-
}
|
|
934
|
+
},
|
|
935
|
+
{ annotations: {} }
|
|
736
936
|
);
|
|
737
|
-
const vaultSkillRecords =
|
|
937
|
+
const vaultSkillRecords = tool4(
|
|
738
938
|
"vault_skill_records",
|
|
739
939
|
"Read, update, and delete skill records (materialized skills on disk). Supports list, get, update, and delete actions.",
|
|
740
940
|
{
|
|
@@ -791,7 +991,7 @@ function createVaultTools(agentId, runId, options) {
|
|
|
791
991
|
console.warn("[vault_skill_records] Failed to remove skill directory:", err instanceof Error ? err.message : err);
|
|
792
992
|
}
|
|
793
993
|
try {
|
|
794
|
-
const { syncSkillSymlinks } = await import("./installer-
|
|
994
|
+
const { syncSkillSymlinks } = await import("./installer-BTUNKWOU.js");
|
|
795
995
|
syncSkillSymlinks(root, result.name, { remove: true });
|
|
796
996
|
} catch (err) {
|
|
797
997
|
console.warn("[vault_skill_records] Failed to remove symlinks:", err instanceof Error ? err.message : err);
|
|
@@ -802,9 +1002,10 @@ function createVaultTools(agentId, runId, options) {
|
|
|
802
1002
|
default:
|
|
803
1003
|
return textResult({ error: `Unknown action: ${args.action}` });
|
|
804
1004
|
}
|
|
805
|
-
}
|
|
1005
|
+
},
|
|
1006
|
+
{ annotations: {} }
|
|
806
1007
|
);
|
|
807
|
-
const vaultWriteSkill =
|
|
1008
|
+
const vaultWriteSkill = tool4(
|
|
808
1009
|
"vault_write_skill",
|
|
809
1010
|
"Write a SKILL.md file to disk and create or update the corresponding skill record and lineage entry.",
|
|
810
1011
|
{
|
|
@@ -831,9 +1032,71 @@ function createVaultTools(agentId, runId, options) {
|
|
|
831
1032
|
error: 'Invalid skill name: must be a simple directory name without path separators or ".."'
|
|
832
1033
|
});
|
|
833
1034
|
}
|
|
1035
|
+
const existingSameName = getSkillRecordByName(args.name);
|
|
1036
|
+
if (!existingSameName) {
|
|
1037
|
+
if (args.candidate_id) {
|
|
1038
|
+
const candidate = getCandidate(args.candidate_id);
|
|
1039
|
+
if (candidate?.skill_id) {
|
|
1040
|
+
const linkedSkill = getSkillRecord(candidate.skill_id);
|
|
1041
|
+
if (linkedSkill && linkedSkill.name !== args.name) {
|
|
1042
|
+
recordTurn("vault_write_skill", args);
|
|
1043
|
+
return textResult({
|
|
1044
|
+
error: `Candidate ${args.candidate_id} is already fulfilled by skill "${linkedSkill.name}". Do not create a sibling skill. If the existing skill needs changes, write to the same name to evolve it (this bumps its generation), or mark it stale via vault_skill_records before replacing.`,
|
|
1045
|
+
existing_skill: {
|
|
1046
|
+
id: linkedSkill.id,
|
|
1047
|
+
name: linkedSkill.name,
|
|
1048
|
+
description: linkedSkill.description,
|
|
1049
|
+
path: linkedSkill.path
|
|
1050
|
+
}
|
|
1051
|
+
});
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
const activeSkills = listSkillRecords({ agent_id: agentId, status: "active", limit: 200 });
|
|
1056
|
+
let bestMatch = null;
|
|
1057
|
+
for (const skill of activeSkills) {
|
|
1058
|
+
const score = descriptionSimilarity(args.description, skill.description);
|
|
1059
|
+
if (score >= DESCRIPTION_DUPLICATE_THRESHOLD && (!bestMatch || score > bestMatch.score)) {
|
|
1060
|
+
bestMatch = { skill, score };
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
if (bestMatch) {
|
|
1064
|
+
recordTurn("vault_write_skill", args);
|
|
1065
|
+
return textResult({
|
|
1066
|
+
error: `Description overlaps with existing active skill "${bestMatch.skill.name}" (Jaccard ${bestMatch.score.toFixed(2)}, threshold ${DESCRIPTION_DUPLICATE_THRESHOLD}). Do not create a duplicate. Either evolve the existing skill by writing to its name ("${bestMatch.skill.name}"), or reframe this skill so its description describes a distinct procedure.`,
|
|
1067
|
+
overlapping_skill: {
|
|
1068
|
+
id: bestMatch.skill.id,
|
|
1069
|
+
name: bestMatch.skill.name,
|
|
1070
|
+
description: bestMatch.skill.description,
|
|
1071
|
+
path: bestMatch.skill.path
|
|
1072
|
+
},
|
|
1073
|
+
similarity: bestMatch.score
|
|
1074
|
+
});
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
834
1077
|
const root = projectRoot ?? process.cwd();
|
|
835
1078
|
const skillDir = resolve(root, ".agents", "skills", args.name);
|
|
836
1079
|
const skillPath = resolve(skillDir, "SKILL.md");
|
|
1080
|
+
if (existsSync(skillPath)) {
|
|
1081
|
+
const existingContent = readFileSync(skillPath, "utf-8");
|
|
1082
|
+
const violations = checkFrontmatterPreservation(existingContent, args.content);
|
|
1083
|
+
if (violations.length > 0) {
|
|
1084
|
+
recordTurn("vault_write_skill", args);
|
|
1085
|
+
return textResult({
|
|
1086
|
+
error: "Skill update rejected: protected frontmatter fields were changed. Read the existing skill and preserve these values exactly.",
|
|
1087
|
+
violations
|
|
1088
|
+
});
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
const skillDirPreexisted = existsSync(skillDir);
|
|
1092
|
+
let priorSkillContent = null;
|
|
1093
|
+
if (existsSync(skillPath)) {
|
|
1094
|
+
try {
|
|
1095
|
+
priorSkillContent = readFileSync(skillPath, "utf-8");
|
|
1096
|
+
} catch {
|
|
1097
|
+
priorSkillContent = null;
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
837
1100
|
try {
|
|
838
1101
|
mkdirSync(skillDir, { recursive: true });
|
|
839
1102
|
writeFileSync(skillPath, args.content, "utf-8");
|
|
@@ -841,7 +1104,7 @@ function createVaultTools(agentId, runId, options) {
|
|
|
841
1104
|
return textResult({ error: `Failed to write skill file: ${err instanceof Error ? err.message : String(err)}` });
|
|
842
1105
|
}
|
|
843
1106
|
try {
|
|
844
|
-
const { syncSkillSymlinks } = await import("./installer-
|
|
1107
|
+
const { syncSkillSymlinks } = await import("./installer-BTUNKWOU.js");
|
|
845
1108
|
syncSkillSymlinks(root, args.name);
|
|
846
1109
|
} catch (err) {
|
|
847
1110
|
console.warn("[vault_write_skill] syncSkillSymlinks failed:", err instanceof Error ? err.message : err);
|
|
@@ -852,77 +1115,98 @@ function createVaultTools(agentId, runId, options) {
|
|
|
852
1115
|
let recordId = "";
|
|
853
1116
|
let generation = 0;
|
|
854
1117
|
const txDb = getDatabase();
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
});
|
|
867
|
-
insertLineage({
|
|
868
|
-
id: crypto.randomUUID(),
|
|
869
|
-
skill_id: existing.id,
|
|
870
|
-
generation,
|
|
871
|
-
action: "updated",
|
|
872
|
-
rationale: args.rationale ?? "Skill content updated",
|
|
873
|
-
source_ids_added: args.source_ids,
|
|
874
|
-
content_snapshot: args.content,
|
|
875
|
-
created_at: now
|
|
876
|
-
});
|
|
877
|
-
} else {
|
|
878
|
-
recordId = crypto.randomUUID();
|
|
879
|
-
generation = 1;
|
|
880
|
-
insertSkillRecord({
|
|
881
|
-
id: recordId,
|
|
882
|
-
agent_id: agentId,
|
|
883
|
-
machine_id: machineId,
|
|
884
|
-
name: args.name,
|
|
885
|
-
display_name: args.display_name,
|
|
886
|
-
description: args.description,
|
|
887
|
-
candidate_id: args.candidate_id ?? null,
|
|
888
|
-
source_ids: args.source_ids,
|
|
889
|
-
path: relativePath,
|
|
890
|
-
created_at: now,
|
|
891
|
-
updated_at: now
|
|
892
|
-
});
|
|
893
|
-
insertLineage({
|
|
894
|
-
id: crypto.randomUUID(),
|
|
895
|
-
skill_id: recordId,
|
|
896
|
-
generation,
|
|
897
|
-
action: "created",
|
|
898
|
-
rationale: args.rationale ?? "Initial skill creation",
|
|
899
|
-
source_ids_added: args.source_ids,
|
|
900
|
-
content_snapshot: args.content,
|
|
901
|
-
created_at: now
|
|
902
|
-
});
|
|
903
|
-
const approvedCandidates = listCandidates({ status: "approved", limit: 10 });
|
|
904
|
-
let linkedCandidate = false;
|
|
905
|
-
if (args.candidate_id && !linkedCandidate) {
|
|
906
|
-
const exact = updateCandidate(args.candidate_id, {
|
|
907
|
-
status: "generated",
|
|
908
|
-
skill_id: recordId,
|
|
1118
|
+
try {
|
|
1119
|
+
txDb.transaction(() => {
|
|
1120
|
+
if (existing) {
|
|
1121
|
+
generation = existing.generation + 1;
|
|
1122
|
+
recordId = existing.id;
|
|
1123
|
+
updateSkillRecord(existing.id, {
|
|
1124
|
+
display_name: args.display_name,
|
|
1125
|
+
description: args.description,
|
|
1126
|
+
generation,
|
|
1127
|
+
...args.source_ids !== void 0 ? { source_ids: args.source_ids } : {},
|
|
1128
|
+
path: relativePath,
|
|
909
1129
|
updated_at: now
|
|
910
1130
|
});
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
1131
|
+
insertLineage({
|
|
1132
|
+
id: crypto2.randomUUID(),
|
|
1133
|
+
skill_id: existing.id,
|
|
1134
|
+
generation,
|
|
1135
|
+
action: "updated",
|
|
1136
|
+
rationale: args.rationale ?? "Skill content updated",
|
|
1137
|
+
source_ids_added: args.source_ids,
|
|
1138
|
+
content_snapshot: args.content,
|
|
1139
|
+
created_at: now
|
|
1140
|
+
});
|
|
1141
|
+
} else {
|
|
1142
|
+
recordId = crypto2.randomUUID();
|
|
1143
|
+
generation = 1;
|
|
1144
|
+
insertSkillRecord({
|
|
1145
|
+
id: recordId,
|
|
1146
|
+
agent_id: agentId,
|
|
1147
|
+
machine_id: machineId,
|
|
1148
|
+
name: args.name,
|
|
1149
|
+
display_name: args.display_name,
|
|
1150
|
+
description: args.description,
|
|
1151
|
+
candidate_id: args.candidate_id ?? null,
|
|
1152
|
+
source_ids: args.source_ids,
|
|
1153
|
+
path: relativePath,
|
|
1154
|
+
created_at: now,
|
|
1155
|
+
updated_at: now
|
|
1156
|
+
});
|
|
1157
|
+
insertLineage({
|
|
1158
|
+
id: crypto2.randomUUID(),
|
|
1159
|
+
skill_id: recordId,
|
|
1160
|
+
generation,
|
|
1161
|
+
action: "created",
|
|
1162
|
+
rationale: args.rationale ?? "Initial skill creation",
|
|
1163
|
+
source_ids_added: args.source_ids,
|
|
1164
|
+
content_snapshot: args.content,
|
|
1165
|
+
created_at: now
|
|
1166
|
+
});
|
|
1167
|
+
const approvedCandidates = listCandidates({ status: "approved", limit: 10 });
|
|
1168
|
+
let linkedCandidate = false;
|
|
1169
|
+
if (args.candidate_id && !linkedCandidate) {
|
|
1170
|
+
const exact = updateCandidate(args.candidate_id, {
|
|
917
1171
|
status: "generated",
|
|
918
1172
|
skill_id: recordId,
|
|
919
1173
|
updated_at: now
|
|
920
1174
|
});
|
|
921
|
-
linkedCandidate = true;
|
|
1175
|
+
if (exact) linkedCandidate = true;
|
|
922
1176
|
}
|
|
1177
|
+
if (args.candidate_id && !linkedCandidate) {
|
|
1178
|
+
const prefixMatch = approvedCandidates.find((c) => c.id.startsWith(args.candidate_id));
|
|
1179
|
+
if (prefixMatch) {
|
|
1180
|
+
updateCandidate(prefixMatch.id, {
|
|
1181
|
+
status: "generated",
|
|
1182
|
+
skill_id: recordId,
|
|
1183
|
+
updated_at: now
|
|
1184
|
+
});
|
|
1185
|
+
linkedCandidate = true;
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
})();
|
|
1190
|
+
} catch (err) {
|
|
1191
|
+
try {
|
|
1192
|
+
if (priorSkillContent !== null) {
|
|
1193
|
+
writeFileSync(skillPath, priorSkillContent, "utf-8");
|
|
1194
|
+
} else if (!skillDirPreexisted) {
|
|
1195
|
+
rmSync(skillDir, { recursive: true, force: true });
|
|
1196
|
+
} else {
|
|
1197
|
+
rmSync(skillPath, { force: true });
|
|
923
1198
|
}
|
|
1199
|
+
} catch (rollbackErr) {
|
|
1200
|
+
console.warn(
|
|
1201
|
+
"[vault_write_skill] file rollback after DB failure also failed:",
|
|
1202
|
+
rollbackErr instanceof Error ? rollbackErr.message : rollbackErr
|
|
1203
|
+
);
|
|
924
1204
|
}
|
|
925
|
-
|
|
1205
|
+
recordTurn("vault_write_skill", args);
|
|
1206
|
+
return textResult({
|
|
1207
|
+
error: `Skill write aborted: database transaction failed and on-disk state was rolled back. ${err instanceof Error ? err.message : String(err)}`
|
|
1208
|
+
});
|
|
1209
|
+
}
|
|
926
1210
|
const isNew = generation === 1;
|
|
927
1211
|
notify(vaultDir, {
|
|
928
1212
|
domain: "skills",
|
|
@@ -939,32 +1223,85 @@ function createVaultTools(agentId, runId, options) {
|
|
|
939
1223
|
path: relativePath,
|
|
940
1224
|
generation
|
|
941
1225
|
});
|
|
942
|
-
}
|
|
1226
|
+
},
|
|
1227
|
+
{ annotations: { openWorldHint: true } }
|
|
943
1228
|
);
|
|
944
1229
|
return [
|
|
945
|
-
vaultUnprocessed,
|
|
946
|
-
vaultSpores,
|
|
947
|
-
vaultSessions,
|
|
948
|
-
vaultSearchFts,
|
|
949
|
-
vaultSearchSemantic,
|
|
950
|
-
vaultState,
|
|
951
|
-
vaultEntities,
|
|
952
|
-
vaultEdges,
|
|
953
|
-
vaultCreateSpore,
|
|
954
|
-
vaultCreateEntity,
|
|
955
|
-
vaultCreateEdge,
|
|
956
|
-
vaultResolveSpore,
|
|
957
|
-
vaultUpdateSession,
|
|
958
|
-
vaultSetState,
|
|
959
|
-
vaultReadDigest,
|
|
960
|
-
vaultWriteDigest,
|
|
961
|
-
vaultMarkProcessed,
|
|
962
|
-
vaultReport,
|
|
963
1230
|
vaultSkillCandidates,
|
|
964
1231
|
vaultSkillRecords,
|
|
965
1232
|
vaultWriteSkill
|
|
966
1233
|
];
|
|
967
1234
|
}
|
|
1235
|
+
|
|
1236
|
+
// src/agent/tools.ts
|
|
1237
|
+
var READ_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
1238
|
+
"vault_unprocessed",
|
|
1239
|
+
"vault_spores",
|
|
1240
|
+
"vault_sessions",
|
|
1241
|
+
"vault_search_fts",
|
|
1242
|
+
"vault_search_semantic",
|
|
1243
|
+
"vault_state",
|
|
1244
|
+
"vault_entities",
|
|
1245
|
+
"vault_edges"
|
|
1246
|
+
]);
|
|
1247
|
+
var WRITE_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
1248
|
+
"vault_create_spore",
|
|
1249
|
+
"vault_create_entity",
|
|
1250
|
+
"vault_create_edge",
|
|
1251
|
+
"vault_resolve_spore",
|
|
1252
|
+
"vault_update_session",
|
|
1253
|
+
"vault_set_state",
|
|
1254
|
+
"vault_read_digest",
|
|
1255
|
+
"vault_write_digest",
|
|
1256
|
+
"vault_mark_processed"
|
|
1257
|
+
]);
|
|
1258
|
+
var OBSERVABILITY_TOOL_NAMES = /* @__PURE__ */ new Set(["vault_report"]);
|
|
1259
|
+
var SKILL_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
1260
|
+
"vault_skill_candidates",
|
|
1261
|
+
"vault_skill_records",
|
|
1262
|
+
"vault_write_skill"
|
|
1263
|
+
]);
|
|
1264
|
+
function setsOverlap(a, b) {
|
|
1265
|
+
for (const item of a) {
|
|
1266
|
+
if (b.has(item)) return true;
|
|
1267
|
+
}
|
|
1268
|
+
return false;
|
|
1269
|
+
}
|
|
1270
|
+
function createVaultTools(agentId, runId, options) {
|
|
1271
|
+
const { turnOffset = 0, embeddingManager, teamClient, machineId, projectRoot, vaultDir, onlyNames } = options ?? {};
|
|
1272
|
+
let turnCounter = turnOffset;
|
|
1273
|
+
function recordTurn(toolName, toolInput) {
|
|
1274
|
+
turnCounter++;
|
|
1275
|
+
try {
|
|
1276
|
+
insertTurn({
|
|
1277
|
+
run_id: runId,
|
|
1278
|
+
agent_id: agentId,
|
|
1279
|
+
turn_number: turnCounter,
|
|
1280
|
+
tool_name: toolName,
|
|
1281
|
+
tool_input: JSON.stringify(toolInput),
|
|
1282
|
+
started_at: epochSeconds()
|
|
1283
|
+
});
|
|
1284
|
+
} catch {
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
const deps = {
|
|
1288
|
+
agentId,
|
|
1289
|
+
runId,
|
|
1290
|
+
embeddingManager,
|
|
1291
|
+
teamClient,
|
|
1292
|
+
machineId,
|
|
1293
|
+
projectRoot,
|
|
1294
|
+
vaultDir,
|
|
1295
|
+
recordTurn
|
|
1296
|
+
};
|
|
1297
|
+
const needsAll = !onlyNames;
|
|
1298
|
+
return [
|
|
1299
|
+
...needsAll || setsOverlap(onlyNames, READ_TOOL_NAMES) ? createReadTools(deps) : [],
|
|
1300
|
+
...needsAll || setsOverlap(onlyNames, WRITE_TOOL_NAMES) ? createWriteTools(deps) : [],
|
|
1301
|
+
...needsAll || setsOverlap(onlyNames, OBSERVABILITY_TOOL_NAMES) ? createObservabilityTools(deps) : [],
|
|
1302
|
+
...needsAll || setsOverlap(onlyNames, SKILL_TOOL_NAMES) ? createSkillTools(deps) : []
|
|
1303
|
+
];
|
|
1304
|
+
}
|
|
968
1305
|
function createVaultToolServer(agentId, runId, options) {
|
|
969
1306
|
const tools = createVaultTools(agentId, runId, options);
|
|
970
1307
|
return createSdkMcpServer({
|
|
@@ -974,9 +1311,10 @@ function createVaultToolServer(agentId, runId, options) {
|
|
|
974
1311
|
});
|
|
975
1312
|
}
|
|
976
1313
|
function createScopedVaultToolServer(agentId, runId, toolNames, options) {
|
|
977
|
-
const allTools = createVaultTools(agentId, runId, options);
|
|
978
1314
|
const nameSet = new Set(toolNames);
|
|
979
|
-
const
|
|
1315
|
+
const allTools = createVaultTools(agentId, runId, { ...options, onlyNames: nameSet });
|
|
1316
|
+
const eligible = options?.readOnly ? allTools.filter((t) => t.annotations?.readOnlyHint === true) : allTools;
|
|
1317
|
+
const scopedTools = eligible.filter((t) => nameSet.has(t.name));
|
|
980
1318
|
return createSdkMcpServer({
|
|
981
1319
|
name: "myco-vault",
|
|
982
1320
|
version: getPluginVersion(),
|
|
@@ -1251,13 +1589,13 @@ var KNOWN_CONTEXT_QUERY_TOOLS = /* @__PURE__ */ new Set([
|
|
|
1251
1589
|
"vault_sessions",
|
|
1252
1590
|
"vault_state"
|
|
1253
1591
|
]);
|
|
1254
|
-
function validateTool(
|
|
1255
|
-
if (!KNOWN_CONTEXT_QUERY_TOOLS.has(
|
|
1256
|
-
throw new Error(`Unknown context query tool: "${
|
|
1592
|
+
function validateTool(tool5) {
|
|
1593
|
+
if (!KNOWN_CONTEXT_QUERY_TOOLS.has(tool5)) {
|
|
1594
|
+
throw new Error(`Unknown context query tool: "${tool5}"`);
|
|
1257
1595
|
}
|
|
1258
1596
|
}
|
|
1259
|
-
async function executeQuery(agentId,
|
|
1260
|
-
switch (
|
|
1597
|
+
async function executeQuery(agentId, tool5, limit) {
|
|
1598
|
+
switch (tool5) {
|
|
1261
1599
|
case "vault_unprocessed":
|
|
1262
1600
|
return getUnprocessedBatches({ limit });
|
|
1263
1601
|
case "vault_spores":
|
|
@@ -1267,7 +1605,7 @@ async function executeQuery(agentId, tool2, limit) {
|
|
|
1267
1605
|
case "vault_state":
|
|
1268
1606
|
return getStatesForAgent(agentId);
|
|
1269
1607
|
default:
|
|
1270
|
-
throw new Error(`Unknown context query tool: "${
|
|
1608
|
+
throw new Error(`Unknown context query tool: "${tool5}"`);
|
|
1271
1609
|
}
|
|
1272
1610
|
}
|
|
1273
1611
|
|
|
@@ -1306,62 +1644,87 @@ function getProviderEnvVars(provider) {
|
|
|
1306
1644
|
}
|
|
1307
1645
|
}
|
|
1308
1646
|
|
|
1309
|
-
// src/agent/
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
var PROMPT_SECTION_PRIOR_PHASES = "## Prior Phase Results";
|
|
1318
|
-
var PROMPT_SECTION_CURRENT_PHASE = "## Current Phase: ";
|
|
1319
|
-
function composeTaskPrompt(vaultContext, taskDisplayName, taskPrompt, instruction) {
|
|
1320
|
-
const sessionIdMatch = instruction?.match(/\b([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\b/i);
|
|
1321
|
-
const sessionId = sessionIdMatch?.[1] ?? "";
|
|
1322
|
-
let resolvedPrompt = taskPrompt;
|
|
1323
|
-
resolvedPrompt = resolvedPrompt.replace(/\{\{session_id\}\}/g, sessionId);
|
|
1324
|
-
resolvedPrompt = resolvedPrompt.replace(/\{\{instruction\}\}/g, instruction ?? "");
|
|
1325
|
-
const parts = [
|
|
1326
|
-
vaultContext,
|
|
1327
|
-
`${PROMPT_SECTION_TASK}${taskDisplayName}
|
|
1328
|
-
${resolvedPrompt}`
|
|
1329
|
-
];
|
|
1330
|
-
if (instruction) {
|
|
1331
|
-
parts.push(`${PROMPT_SECTION_INSTRUCTION}
|
|
1332
|
-
${instruction}`);
|
|
1333
|
-
}
|
|
1334
|
-
return parts.join(PROMPT_SECTION_SEPARATOR);
|
|
1647
|
+
// src/agent/config-resolver.ts
|
|
1648
|
+
function toProviderConfig(p) {
|
|
1649
|
+
return {
|
|
1650
|
+
type: p.type,
|
|
1651
|
+
baseUrl: p.base_url,
|
|
1652
|
+
model: p.model,
|
|
1653
|
+
contextLength: p.context_length
|
|
1654
|
+
};
|
|
1335
1655
|
}
|
|
1336
|
-
function
|
|
1337
|
-
const
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
}
|
|
1352
|
-
|
|
1353
|
-
|
|
1656
|
+
function resolveRunConfig(agentId, requestedTask, vaultDir) {
|
|
1657
|
+
const definitionsDir = resolveDefinitionsDir();
|
|
1658
|
+
const definition = loadAgentDefinition(definitionsDir);
|
|
1659
|
+
const agentRow = getAgent(agentId);
|
|
1660
|
+
const taskRow = requestedTask ? getTask(requestedTask) : getDefaultTask(agentId);
|
|
1661
|
+
const allTasks = loadAllTasks(definitionsDir, vaultDir);
|
|
1662
|
+
const taskName = taskRow?.id ?? requestedTask;
|
|
1663
|
+
const yamlTask = taskName ? allTasks.get(taskName) : void 0;
|
|
1664
|
+
const taskOverrides = taskRow ? {
|
|
1665
|
+
name: taskRow.id,
|
|
1666
|
+
displayName: taskRow.display_name ?? taskRow.id,
|
|
1667
|
+
description: taskRow.description ?? "",
|
|
1668
|
+
agent: taskRow.agent_id,
|
|
1669
|
+
prompt: taskRow.prompt,
|
|
1670
|
+
isDefault: taskRow.is_default === 1,
|
|
1671
|
+
...taskRow.tool_overrides ? { toolOverrides: JSON.parse(taskRow.tool_overrides) } : {},
|
|
1672
|
+
// Scalar config from YAML (model, turns, timeout) — DB doesn't store these
|
|
1673
|
+
...yamlTask?.model ? { model: yamlTask.model } : {},
|
|
1674
|
+
...yamlTask?.maxTurns ? { maxTurns: yamlTask.maxTurns } : {},
|
|
1675
|
+
...yamlTask?.timeoutSeconds ? { timeoutSeconds: yamlTask.timeoutSeconds } : {},
|
|
1676
|
+
// Structural config from YAML
|
|
1677
|
+
...yamlTask?.phases ? { phases: yamlTask.phases } : {},
|
|
1678
|
+
...yamlTask?.execution ? { execution: yamlTask.execution } : {},
|
|
1679
|
+
...yamlTask?.contextQueries ? { contextQueries: yamlTask.contextQueries } : {},
|
|
1680
|
+
...yamlTask?.orchestrator ? { orchestrator: yamlTask.orchestrator } : {}
|
|
1681
|
+
} : void 0;
|
|
1682
|
+
const config = resolveEffectiveConfig(definition, agentRow, taskOverrides);
|
|
1683
|
+
let taskProviderOverride;
|
|
1684
|
+
let phaseProviderOverrides = {};
|
|
1685
|
+
let taskParams;
|
|
1686
|
+
try {
|
|
1687
|
+
const mycoConfig = loadConfig(vaultDir);
|
|
1688
|
+
const taskConfig = taskName ? mycoConfig.agent.tasks?.[taskName] : void 0;
|
|
1689
|
+
const globalProvider = mycoConfig.agent.provider;
|
|
1690
|
+
if (taskConfig?.provider) {
|
|
1691
|
+
taskProviderOverride = toProviderConfig(taskConfig.provider);
|
|
1692
|
+
} else if (globalProvider) {
|
|
1693
|
+
taskProviderOverride = toProviderConfig(globalProvider);
|
|
1694
|
+
}
|
|
1695
|
+
if (taskConfig?.phases) {
|
|
1696
|
+
for (const [phaseName, phaseConfig] of Object.entries(taskConfig.phases)) {
|
|
1697
|
+
phaseProviderOverrides[phaseName] = {
|
|
1698
|
+
...phaseConfig.provider ? { provider: toProviderConfig(phaseConfig.provider) } : {},
|
|
1699
|
+
...phaseConfig.maxTurns != null ? { maxTurns: phaseConfig.maxTurns } : {}
|
|
1700
|
+
};
|
|
1701
|
+
}
|
|
1702
|
+
}
|
|
1703
|
+
const yamlParams = yamlTask?.params;
|
|
1704
|
+
const configParams = taskConfig?.params;
|
|
1705
|
+
if (yamlParams || configParams) {
|
|
1706
|
+
taskParams = { ...yamlParams, ...configParams };
|
|
1707
|
+
}
|
|
1708
|
+
} catch {
|
|
1354
1709
|
}
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1710
|
+
return {
|
|
1711
|
+
config,
|
|
1712
|
+
definitionsDir,
|
|
1713
|
+
taskProviderOverride,
|
|
1714
|
+
phaseProviderOverrides,
|
|
1715
|
+
taskName,
|
|
1716
|
+
taskParams
|
|
1717
|
+
};
|
|
1358
1718
|
}
|
|
1719
|
+
|
|
1720
|
+
// src/agent/ollama-context.ts
|
|
1721
|
+
import { execFileSync } from "child_process";
|
|
1722
|
+
import { writeFileSync as writeFileSync2, unlinkSync } from "fs";
|
|
1723
|
+
import { tmpdir } from "os";
|
|
1724
|
+
import { join } from "path";
|
|
1359
1725
|
var OLLAMA_PRELOAD_TIMEOUT_MS = 3e4;
|
|
1726
|
+
var DEFAULT_OLLAMA_CONTEXT_LENGTH = 32768;
|
|
1360
1727
|
async function ensureOllamaContextVariant(model, contextLength) {
|
|
1361
|
-
const { execFileSync } = await import("child_process");
|
|
1362
|
-
const { writeFileSync: writeFileSync2, unlinkSync } = await import("fs");
|
|
1363
|
-
const { tmpdir } = await import("os");
|
|
1364
|
-
const { join } = await import("path");
|
|
1365
1728
|
const baseName = model.replace(/:latest$/, "");
|
|
1366
1729
|
const variantName = `${baseName}-ctx${contextLength}`;
|
|
1367
1730
|
try {
|
|
@@ -1387,6 +1750,63 @@ PARAMETER num_ctx ${contextLength}
|
|
|
1387
1750
|
return model;
|
|
1388
1751
|
}
|
|
1389
1752
|
}
|
|
1753
|
+
async function resolveOllamaContextVariants(taskProvider, phaseOverrides, createVariant = ensureOllamaContextVariant) {
|
|
1754
|
+
const seen = /* @__PURE__ */ new Map();
|
|
1755
|
+
const recordOllama = (p) => {
|
|
1756
|
+
if (p?.type !== "ollama" || !p.model) return;
|
|
1757
|
+
const ctx = p.contextLength ?? DEFAULT_OLLAMA_CONTEXT_LENGTH;
|
|
1758
|
+
const set = seen.get(p.model) ?? /* @__PURE__ */ new Set();
|
|
1759
|
+
set.add(ctx);
|
|
1760
|
+
seen.set(p.model, set);
|
|
1761
|
+
};
|
|
1762
|
+
recordOllama(taskProvider);
|
|
1763
|
+
for (const override of Object.values(phaseOverrides)) {
|
|
1764
|
+
recordOllama(override.provider);
|
|
1765
|
+
}
|
|
1766
|
+
if (seen.size === 0) {
|
|
1767
|
+
return { taskProvider, phaseOverrides, conflicts: [] };
|
|
1768
|
+
}
|
|
1769
|
+
const resolvedContext = /* @__PURE__ */ new Map();
|
|
1770
|
+
const conflicts = [];
|
|
1771
|
+
for (const [model, values] of seen) {
|
|
1772
|
+
const sorted = [...values].sort((a, b) => a - b);
|
|
1773
|
+
const max = sorted[sorted.length - 1];
|
|
1774
|
+
resolvedContext.set(model, max);
|
|
1775
|
+
if (sorted.length > 1) {
|
|
1776
|
+
conflicts.push({ model, values: sorted, resolved: max });
|
|
1777
|
+
}
|
|
1778
|
+
}
|
|
1779
|
+
const variantEntries = await Promise.all(
|
|
1780
|
+
[...resolvedContext.entries()].map(async ([model, ctx]) => {
|
|
1781
|
+
const variant = await createVariant(model, ctx);
|
|
1782
|
+
return [model, variant];
|
|
1783
|
+
})
|
|
1784
|
+
);
|
|
1785
|
+
const variantByModel = new Map(variantEntries);
|
|
1786
|
+
const rewriteProvider = (p) => {
|
|
1787
|
+
if (!p) return p;
|
|
1788
|
+
if (p.type !== "ollama" || !p.model) return p;
|
|
1789
|
+
const variant = variantByModel.get(p.model);
|
|
1790
|
+
const resolvedCtx = resolvedContext.get(p.model);
|
|
1791
|
+
if (!variant) return p;
|
|
1792
|
+
return { ...p, model: variant, contextLength: resolvedCtx };
|
|
1793
|
+
};
|
|
1794
|
+
const rewrittenPhaseOverrides = {};
|
|
1795
|
+
for (const [name, override] of Object.entries(phaseOverrides)) {
|
|
1796
|
+
rewrittenPhaseOverrides[name] = {
|
|
1797
|
+
...override,
|
|
1798
|
+
...override.provider ? { provider: rewriteProvider(override.provider) } : {}
|
|
1799
|
+
};
|
|
1800
|
+
}
|
|
1801
|
+
return {
|
|
1802
|
+
taskProvider: rewriteProvider(taskProvider),
|
|
1803
|
+
phaseOverrides: rewrittenPhaseOverrides,
|
|
1804
|
+
conflicts
|
|
1805
|
+
};
|
|
1806
|
+
}
|
|
1807
|
+
|
|
1808
|
+
// src/agent/wave-computation.ts
|
|
1809
|
+
import crypto3 from "crypto";
|
|
1390
1810
|
function computeWaves(phases) {
|
|
1391
1811
|
const nameToPhase = new Map(phases.map((p) => [p.name, p]));
|
|
1392
1812
|
const inDegree = /* @__PURE__ */ new Map();
|
|
@@ -1428,7 +1848,7 @@ function computeWaves(phases) {
|
|
|
1428
1848
|
return waves;
|
|
1429
1849
|
}
|
|
1430
1850
|
function phaseSessionId(runId, phaseName) {
|
|
1431
|
-
const hash =
|
|
1851
|
+
const hash = crypto3.createHash("sha256").update(`${runId}-${phaseName}`).digest("hex");
|
|
1432
1852
|
return [
|
|
1433
1853
|
hash.slice(0, 8),
|
|
1434
1854
|
hash.slice(8, 12),
|
|
@@ -1437,10 +1857,94 @@ function phaseSessionId(runId, phaseName) {
|
|
|
1437
1857
|
hash.slice(20, 32)
|
|
1438
1858
|
].join("-");
|
|
1439
1859
|
}
|
|
1860
|
+
|
|
1861
|
+
// src/agent/executor.ts
|
|
1862
|
+
var STATUS_SKIPPED = "skipped";
|
|
1863
|
+
var SKIP_REASON_ALREADY_RUNNING = "already_running";
|
|
1864
|
+
var PROMPT_SECTION_TASK = "## Task: ";
|
|
1865
|
+
var PROMPT_SECTION_INSTRUCTION = "## User Instruction";
|
|
1866
|
+
var PROMPT_SECTION_SEPARATOR = "\n\n";
|
|
1867
|
+
var MCP_SERVER_NAME = "myco-vault";
|
|
1868
|
+
var PERSIST_SESSION = true;
|
|
1869
|
+
var PROMPT_SECTION_PRIOR_PHASES = "## Prior Phase Results";
|
|
1870
|
+
var PROMPT_SECTION_CURRENT_PHASE = "## Current Phase: ";
|
|
1871
|
+
var DEBUG_TOOL_CALLS = process.env.MYCO_AGENT_DEBUG === "1";
|
|
1872
|
+
var TOOL_DEBUG_PREVIEW_CHARS = 240;
|
|
1873
|
+
function previewPayload(value) {
|
|
1874
|
+
const str = typeof value === "string" ? value : JSON.stringify(value);
|
|
1875
|
+
if (str === void 0) return "";
|
|
1876
|
+
return str.length > TOOL_DEBUG_PREVIEW_CHARS ? `${str.slice(0, TOOL_DEBUG_PREVIEW_CHARS)}\u2026(${str.length - TOOL_DEBUG_PREVIEW_CHARS} more chars)` : str;
|
|
1877
|
+
}
|
|
1878
|
+
function logToolUseBlocks(phaseName, message) {
|
|
1879
|
+
if (!DEBUG_TOOL_CALLS) return;
|
|
1880
|
+
const blocks = message.message?.content;
|
|
1881
|
+
if (!Array.isArray(blocks)) return;
|
|
1882
|
+
for (const block of blocks) {
|
|
1883
|
+
if (block.type === "tool_use") {
|
|
1884
|
+
console.log(
|
|
1885
|
+
`[agent:debug] ${phaseName} tool_use: ${block.name ?? "unknown"} input=${previewPayload(block.input)}`
|
|
1886
|
+
);
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
}
|
|
1890
|
+
function logToolResultBlocks(phaseName, message) {
|
|
1891
|
+
if (!DEBUG_TOOL_CALLS) return;
|
|
1892
|
+
const blocks = message.message?.content;
|
|
1893
|
+
if (!Array.isArray(blocks)) return;
|
|
1894
|
+
for (const block of blocks) {
|
|
1895
|
+
if (block.type === "tool_result") {
|
|
1896
|
+
const flag = block.is_error ? " [ERROR]" : "";
|
|
1897
|
+
console.log(
|
|
1898
|
+
`[agent:debug] ${phaseName} tool_result${flag}: ${previewPayload(block.content)}`
|
|
1899
|
+
);
|
|
1900
|
+
}
|
|
1901
|
+
}
|
|
1902
|
+
}
|
|
1903
|
+
function composeTaskPrompt(vaultContext, taskDisplayName, taskPrompt, instruction) {
|
|
1904
|
+
const sessionIdMatch = instruction?.match(/\b([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\b/i);
|
|
1905
|
+
const sessionId = sessionIdMatch?.[1] ?? "";
|
|
1906
|
+
let resolvedPrompt = taskPrompt;
|
|
1907
|
+
resolvedPrompt = resolvedPrompt.replace(/\{\{session_id\}\}/g, sessionId);
|
|
1908
|
+
resolvedPrompt = resolvedPrompt.replace(/\{\{instruction\}\}/g, instruction ?? "");
|
|
1909
|
+
const parts = [
|
|
1910
|
+
vaultContext,
|
|
1911
|
+
`${PROMPT_SECTION_TASK}${taskDisplayName}
|
|
1912
|
+
${resolvedPrompt}`
|
|
1913
|
+
];
|
|
1914
|
+
if (instruction) {
|
|
1915
|
+
parts.push(`${PROMPT_SECTION_INSTRUCTION}
|
|
1916
|
+
${instruction}`);
|
|
1917
|
+
}
|
|
1918
|
+
return parts.join(PROMPT_SECTION_SEPARATOR);
|
|
1919
|
+
}
|
|
1920
|
+
function composePhasePrompt(vaultContext, taskDisplayName, taskOverview, phase, priorPhaseResults, instruction) {
|
|
1921
|
+
const parts = [
|
|
1922
|
+
vaultContext,
|
|
1923
|
+
`${PROMPT_SECTION_TASK}${taskDisplayName}
|
|
1924
|
+
${taskOverview}`
|
|
1925
|
+
];
|
|
1926
|
+
if (instruction) {
|
|
1927
|
+
parts.push(`${PROMPT_SECTION_INSTRUCTION}
|
|
1928
|
+
${instruction}`);
|
|
1929
|
+
}
|
|
1930
|
+
if (priorPhaseResults.length > 0 && !phase.skipPriorContext) {
|
|
1931
|
+
const summaries = priorPhaseResults.map((pr) => {
|
|
1932
|
+
const truncated = pr.summary.length > PHASE_SUMMARY_MAX_CHARS ? pr.summary.slice(0, PHASE_SUMMARY_MAX_CHARS) + "..." : pr.summary;
|
|
1933
|
+
return `### ${pr.name} (${pr.status})
|
|
1934
|
+
${truncated}`;
|
|
1935
|
+
});
|
|
1936
|
+
parts.push(`${PROMPT_SECTION_PRIOR_PHASES}
|
|
1937
|
+
${summaries.join("\n\n")}`);
|
|
1938
|
+
}
|
|
1939
|
+
parts.push(`${PROMPT_SECTION_CURRENT_PHASE}${phase.name}
|
|
1940
|
+
${phase.prompt}`);
|
|
1941
|
+
return parts.join(PROMPT_SECTION_SEPARATOR);
|
|
1942
|
+
}
|
|
1440
1943
|
async function executePhase(query, phasePrompt, phaseModel, systemPrompt, toolServer, phase, env, sessionId, abortController) {
|
|
1441
1944
|
let phaseCost = 0;
|
|
1442
1945
|
let phaseTokens = 0;
|
|
1443
1946
|
let phaseTurns = 0;
|
|
1947
|
+
let agenticTurns = 0;
|
|
1444
1948
|
let phaseSummary = "";
|
|
1445
1949
|
try {
|
|
1446
1950
|
for await (const message of query({
|
|
@@ -1460,6 +1964,13 @@ async function executePhase(query, phasePrompt, phaseModel, systemPrompt, toolSe
|
|
|
1460
1964
|
...abortController ? { abortController } : {}
|
|
1461
1965
|
}
|
|
1462
1966
|
})) {
|
|
1967
|
+
if (message.type === "assistant") {
|
|
1968
|
+
agenticTurns++;
|
|
1969
|
+
logToolUseBlocks(phase.name, message);
|
|
1970
|
+
}
|
|
1971
|
+
if (message.type === "user") {
|
|
1972
|
+
logToolResultBlocks(phase.name, message);
|
|
1973
|
+
}
|
|
1463
1974
|
if (message.type === "result") {
|
|
1464
1975
|
phaseCost = message.total_cost_usd ?? 0;
|
|
1465
1976
|
phaseTokens = (message.usage.input_tokens ?? 0) + (message.usage.output_tokens ?? 0);
|
|
@@ -1469,6 +1980,11 @@ async function executePhase(query, phasePrompt, phaseModel, systemPrompt, toolSe
|
|
|
1469
1980
|
}
|
|
1470
1981
|
}
|
|
1471
1982
|
}
|
|
1983
|
+
if (phase.maxTurns) {
|
|
1984
|
+
console.log(
|
|
1985
|
+
`[agent] Phase "${phase.name}": num_turns=${phaseTurns}, assistant_msgs=${agenticTurns}, budget=${phase.maxTurns}`
|
|
1986
|
+
);
|
|
1987
|
+
}
|
|
1472
1988
|
if (phase.required && phaseTurns === 0) {
|
|
1473
1989
|
console.warn(`[agent] Required phase "${phase.name}" produced 0 turns`);
|
|
1474
1990
|
}
|
|
@@ -1581,7 +2097,8 @@ async function executePhasedQuery(config, systemPrompt, vaultContext, agentId, r
|
|
|
1581
2097
|
turnOffset: runningTurnCount + indexInWave * effectiveMaxTurns,
|
|
1582
2098
|
embeddingManager,
|
|
1583
2099
|
projectRoot,
|
|
1584
|
-
vaultDir
|
|
2100
|
+
vaultDir,
|
|
2101
|
+
readOnly: phase.readOnly
|
|
1585
2102
|
}
|
|
1586
2103
|
);
|
|
1587
2104
|
const phaseProvider = phase.provider ?? phaseOverride?.provider ?? taskProviderOverride ?? config.execution?.provider;
|
|
@@ -1644,60 +2161,15 @@ async function runAgent(vaultDir, options) {
|
|
|
1644
2161
|
}
|
|
1645
2162
|
}
|
|
1646
2163
|
}
|
|
1647
|
-
const
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
displayName: taskRow.display_name ?? taskRow.id,
|
|
1657
|
-
description: taskRow.description ?? "",
|
|
1658
|
-
agent: taskRow.agent_id,
|
|
1659
|
-
prompt: taskRow.prompt,
|
|
1660
|
-
isDefault: taskRow.is_default === 1,
|
|
1661
|
-
...taskRow.tool_overrides ? { toolOverrides: JSON.parse(taskRow.tool_overrides) } : {},
|
|
1662
|
-
// Scalar config from YAML (model, turns, timeout) — DB doesn't store these
|
|
1663
|
-
...yamlTask?.model ? { model: yamlTask.model } : {},
|
|
1664
|
-
...yamlTask?.maxTurns ? { maxTurns: yamlTask.maxTurns } : {},
|
|
1665
|
-
...yamlTask?.timeoutSeconds ? { timeoutSeconds: yamlTask.timeoutSeconds } : {},
|
|
1666
|
-
// Structural config from YAML
|
|
1667
|
-
...yamlTask?.phases ? { phases: yamlTask.phases } : {},
|
|
1668
|
-
...yamlTask?.execution ? { execution: yamlTask.execution } : {},
|
|
1669
|
-
...yamlTask?.contextQueries ? { contextQueries: yamlTask.contextQueries } : {},
|
|
1670
|
-
...yamlTask?.orchestrator ? { orchestrator: yamlTask.orchestrator } : {}
|
|
1671
|
-
} : void 0;
|
|
1672
|
-
const config = resolveEffectiveConfig(definition, agentRow, taskOverrides);
|
|
1673
|
-
let taskProviderOverride;
|
|
1674
|
-
let phaseProviderOverrides = {};
|
|
1675
|
-
try {
|
|
1676
|
-
const mycoConfig = loadConfig(vaultDir);
|
|
1677
|
-
const toProviderConfig = (p) => ({
|
|
1678
|
-
type: p.type,
|
|
1679
|
-
baseUrl: p.base_url,
|
|
1680
|
-
model: p.model,
|
|
1681
|
-
contextLength: p.context_length
|
|
1682
|
-
});
|
|
1683
|
-
const taskConfig = taskName ? mycoConfig.agent.tasks?.[taskName] : void 0;
|
|
1684
|
-
const globalProvider = mycoConfig.agent.provider;
|
|
1685
|
-
if (taskConfig?.provider) {
|
|
1686
|
-
taskProviderOverride = toProviderConfig(taskConfig.provider);
|
|
1687
|
-
} else if (globalProvider) {
|
|
1688
|
-
taskProviderOverride = toProviderConfig(globalProvider);
|
|
1689
|
-
}
|
|
1690
|
-
if (taskConfig?.phases) {
|
|
1691
|
-
for (const [phaseName, phaseConfig] of Object.entries(taskConfig.phases)) {
|
|
1692
|
-
phaseProviderOverrides[phaseName] = {
|
|
1693
|
-
...phaseConfig.provider ? { provider: toProviderConfig(phaseConfig.provider) } : {},
|
|
1694
|
-
...phaseConfig.maxTurns != null ? { maxTurns: phaseConfig.maxTurns } : {}
|
|
1695
|
-
};
|
|
1696
|
-
}
|
|
1697
|
-
}
|
|
1698
|
-
} catch {
|
|
1699
|
-
}
|
|
1700
|
-
const runId = options?.resumeRunId ?? crypto2.randomUUID();
|
|
2164
|
+
const {
|
|
2165
|
+
config,
|
|
2166
|
+
definitionsDir,
|
|
2167
|
+
taskProviderOverride: resolvedTaskProvider,
|
|
2168
|
+
phaseProviderOverrides: resolvedPhaseOverrides
|
|
2169
|
+
} = resolveRunConfig(agentId, requestedTask, vaultDir);
|
|
2170
|
+
let taskProviderOverride = resolvedTaskProvider;
|
|
2171
|
+
let phaseProviderOverrides = resolvedPhaseOverrides;
|
|
2172
|
+
const runId = options?.resumeRunId ?? crypto4.randomUUID();
|
|
1701
2173
|
const now = epochSeconds();
|
|
1702
2174
|
if (!options?.resumeRunId) {
|
|
1703
2175
|
insertRun({
|
|
@@ -1718,12 +2190,18 @@ async function runAgent(vaultDir, options) {
|
|
|
1718
2190
|
provider: effectiveProvider?.type ?? "cloud",
|
|
1719
2191
|
...effectiveProvider?.baseUrl ? { baseUrl: effectiveProvider.baseUrl } : {}
|
|
1720
2192
|
};
|
|
1721
|
-
|
|
1722
|
-
const
|
|
1723
|
-
|
|
1724
|
-
|
|
2193
|
+
{
|
|
2194
|
+
const resolved = await resolveOllamaContextVariants(
|
|
2195
|
+
taskProviderOverride,
|
|
2196
|
+
phaseProviderOverrides
|
|
1725
2197
|
);
|
|
1726
|
-
taskProviderOverride =
|
|
2198
|
+
taskProviderOverride = resolved.taskProvider;
|
|
2199
|
+
phaseProviderOverrides = resolved.phaseOverrides;
|
|
2200
|
+
for (const conflict of resolved.conflicts) {
|
|
2201
|
+
console.warn(
|
|
2202
|
+
`[agent] Ollama model "${conflict.model}" referenced with conflicting context_length values [${conflict.values.join(", ")}] \u2014 reconciled to ${conflict.resolved} to avoid loading multiple variants. Configure one value per model to silence this warning.`
|
|
2203
|
+
);
|
|
2204
|
+
}
|
|
1727
2205
|
}
|
|
1728
2206
|
const taskAbortController = new AbortController();
|
|
1729
2207
|
const timeoutMs = config.timeoutSeconds * MS_PER_SECOND;
|
|
@@ -1834,4 +2312,4 @@ export {
|
|
|
1834
2312
|
computeWaves,
|
|
1835
2313
|
runAgent
|
|
1836
2314
|
};
|
|
1837
|
-
//# sourceMappingURL=executor-
|
|
2315
|
+
//# sourceMappingURL=executor-4OXDK4ZA.js.map
|