@goondocks/myco 0.15.0 → 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-DUOJ3KDI.js → agent-run-T433ENJS.js} +4 -4
- package/dist/{agent-tasks-LUWBY5JD.js → agent-tasks-TAIU3V5I.js} +4 -4
- package/dist/{chunk-DK5VEBB5.js → chunk-2QMDRZPJ.js} +17 -13
- package/dist/chunk-2QMDRZPJ.js.map +1 -0
- package/dist/{chunk-R3YW7XVF.js → chunk-4O3QNM5I.js} +2 -2
- package/dist/{chunk-GZ7MXWYX.js → chunk-6GG2IVNV.js} +2 -2
- package/dist/{chunk-OMZCVRX6.js → chunk-BFM6AM6R.js} +2 -2
- package/dist/{chunk-DKGUCEWU.js → chunk-GCCBXCHF.js} +2 -2
- package/dist/{chunk-B3SF2CCW.js → chunk-TQO4PF5K.js} +2 -2
- package/dist/{cli-YBD2GPK4.js → cli-W37MRZHD.js} +35 -35
- package/dist/{client-CJ3X252K.js → client-YNTTC75R.js} +3 -3
- package/dist/{doctor-JR7NEL7K.js → doctor-PAAQU5AS.js} +5 -5
- package/dist/{executor-7XOKS6HS.js → executor-4OXDK4ZA.js} +359 -72
- package/dist/executor-4OXDK4ZA.js.map +1 -0
- package/dist/{init-PDLKYWQ4.js → init-PHQAQANR.js} +7 -7
- package/dist/{init-wizard-WH3SXNMB.js → init-wizard-RFD46XAJ.js} +2 -2
- package/dist/{llm-DK44LYO6.js → llm-D4VWYUK7.js} +2 -2
- package/dist/{main-JB3R3DQE.js → main-ADLCOYKM.js} +13 -10
- package/dist/{main-JB3R3DQE.js.map → main-ADLCOYKM.js.map} +1 -1
- package/dist/{open-AADZPSLW.js → open-3VPUP3HD.js} +4 -4
- package/dist/{post-compact-KNQ4DYLM.js → post-compact-5NYLOC46.js} +4 -4
- package/dist/{post-tool-use-OMWHFQLM.js → post-tool-use-SNNXSZ5Y.js} +3 -3
- package/dist/{post-tool-use-failure-KFP6MB7Z.js → post-tool-use-failure-POKVXQHY.js} +4 -4
- package/dist/{pre-compact-2ZYE2HRB.js → pre-compact-ZUICBJEX.js} +4 -4
- package/dist/{remove-QT7634L5.js → remove-SVU2V4Q7.js} +4 -4
- package/dist/{restart-YQNQEHOU.js → restart-NBB5CXJ4.js} +5 -5
- package/dist/{search-C6JTQDWY.js → search-YUQZFRZX.js} +4 -4
- package/dist/{server-QJ3RWZZZ.js → server-NBRX56VL.js} +3 -3
- package/dist/{session-JLVL5TYX.js → session-2QP4HMZ5.js} +4 -4
- package/dist/{session-end-XFZRRP5H.js → session-end-NNFBW7CQ.js} +3 -3
- package/dist/{session-start-XGINISXO.js → session-start-NPNP4IXX.js} +3 -3
- package/dist/{setup-llm-X2OCM6R7.js → setup-llm-C3IGFLRN.js} +4 -4
- 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/{stats-2EAETG2T.js → stats-FEEXIRMS.js} +5 -5
- package/dist/{stop-WOBDYTSA.js → stop-FGDGWXTK.js} +3 -3
- package/dist/{stop-failure-QEC7ZGBQ.js → stop-failure-5YAGH2TQ.js} +4 -4
- package/dist/{subagent-start-H6DVRVOE.js → subagent-start-UCKVJDR4.js} +4 -4
- package/dist/{subagent-stop-LKENKJ65.js → subagent-stop-H25B3QEC.js} +4 -4
- package/dist/{task-completed-ZZ47PRPD.js → task-completed-2JGZN2CF.js} +4 -4
- package/dist/{team-J62N7VMG.js → team-TG5WZXWO.js} +2 -2
- package/dist/ui/assets/{index-Bx9l8uxa.js → index-7Vimyg7g.js} +1 -1
- package/dist/ui/index.html +1 -1
- package/dist/{update-LX3CJ4TJ.js → update-EG3N2EXI.js} +4 -4
- package/dist/{user-prompt-submit-NNMLY3EW.js → user-prompt-submit-7FFQ3ORA.js} +3 -3
- package/dist/{verify-AMRQXQ3K.js → verify-2M3DYHEY.js} +2 -2
- package/dist/{version-6OJH5HLZ.js → version-JUQU5W22.js} +2 -2
- package/package.json +2 -2
- package/dist/chunk-DK5VEBB5.js.map +0 -1
- package/dist/executor-7XOKS6HS.js.map +0 -1
- /package/dist/{agent-run-DUOJ3KDI.js.map → agent-run-T433ENJS.js.map} +0 -0
- /package/dist/{agent-tasks-LUWBY5JD.js.map → agent-tasks-TAIU3V5I.js.map} +0 -0
- /package/dist/{chunk-R3YW7XVF.js.map → chunk-4O3QNM5I.js.map} +0 -0
- /package/dist/{chunk-GZ7MXWYX.js.map → chunk-6GG2IVNV.js.map} +0 -0
- /package/dist/{chunk-OMZCVRX6.js.map → chunk-BFM6AM6R.js.map} +0 -0
- /package/dist/{chunk-DKGUCEWU.js.map → chunk-GCCBXCHF.js.map} +0 -0
- /package/dist/{chunk-B3SF2CCW.js.map → chunk-TQO4PF5K.js.map} +0 -0
- /package/dist/{cli-YBD2GPK4.js.map → cli-W37MRZHD.js.map} +0 -0
- /package/dist/{client-CJ3X252K.js.map → client-YNTTC75R.js.map} +0 -0
- /package/dist/{doctor-JR7NEL7K.js.map → doctor-PAAQU5AS.js.map} +0 -0
- /package/dist/{init-PDLKYWQ4.js.map → init-PHQAQANR.js.map} +0 -0
- /package/dist/{init-wizard-WH3SXNMB.js.map → init-wizard-RFD46XAJ.js.map} +0 -0
- /package/dist/{llm-DK44LYO6.js.map → llm-D4VWYUK7.js.map} +0 -0
- /package/dist/{open-AADZPSLW.js.map → open-3VPUP3HD.js.map} +0 -0
- /package/dist/{post-compact-KNQ4DYLM.js.map → post-compact-5NYLOC46.js.map} +0 -0
- /package/dist/{post-tool-use-OMWHFQLM.js.map → post-tool-use-SNNXSZ5Y.js.map} +0 -0
- /package/dist/{post-tool-use-failure-KFP6MB7Z.js.map → post-tool-use-failure-POKVXQHY.js.map} +0 -0
- /package/dist/{pre-compact-2ZYE2HRB.js.map → pre-compact-ZUICBJEX.js.map} +0 -0
- /package/dist/{remove-QT7634L5.js.map → remove-SVU2V4Q7.js.map} +0 -0
- /package/dist/{restart-YQNQEHOU.js.map → restart-NBB5CXJ4.js.map} +0 -0
- /package/dist/{search-C6JTQDWY.js.map → search-YUQZFRZX.js.map} +0 -0
- /package/dist/{server-QJ3RWZZZ.js.map → server-NBRX56VL.js.map} +0 -0
- /package/dist/{session-JLVL5TYX.js.map → session-2QP4HMZ5.js.map} +0 -0
- /package/dist/{session-end-XFZRRP5H.js.map → session-end-NNFBW7CQ.js.map} +0 -0
- /package/dist/{session-start-XGINISXO.js.map → session-start-NPNP4IXX.js.map} +0 -0
- /package/dist/{setup-llm-X2OCM6R7.js.map → setup-llm-C3IGFLRN.js.map} +0 -0
- /package/dist/{stats-2EAETG2T.js.map → stats-FEEXIRMS.js.map} +0 -0
- /package/dist/{stop-WOBDYTSA.js.map → stop-FGDGWXTK.js.map} +0 -0
- /package/dist/{stop-failure-QEC7ZGBQ.js.map → stop-failure-5YAGH2TQ.js.map} +0 -0
- /package/dist/{subagent-start-H6DVRVOE.js.map → subagent-start-UCKVJDR4.js.map} +0 -0
- /package/dist/{subagent-stop-LKENKJ65.js.map → subagent-stop-H25B3QEC.js.map} +0 -0
- /package/dist/{task-completed-ZZ47PRPD.js.map → task-completed-2JGZN2CF.js.map} +0 -0
- /package/dist/{team-J62N7VMG.js.map → team-TG5WZXWO.js.map} +0 -0
- /package/dist/{update-LX3CJ4TJ.js.map → update-EG3N2EXI.js.map} +0 -0
- /package/dist/{user-prompt-submit-NNMLY3EW.js.map → user-prompt-submit-7FFQ3ORA.js.map} +0 -0
- /package/dist/{verify-AMRQXQ3K.js.map → verify-2M3DYHEY.js.map} +0 -0
- /package/dist/{version-6OJH5HLZ.js.map → version-JUQU5W22.js.map} +0 -0
|
@@ -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";
|
|
@@ -649,12 +649,115 @@ import { tool as tool4 } from "@anthropic-ai/claude-agent-sdk";
|
|
|
649
649
|
var MAX_SKILL_LINES = 500;
|
|
650
650
|
var REQUIRED_FRONTMATTER_FIELDS = ["name", "description", "managed_by", "user-invocable", "allowed-tools"];
|
|
651
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
|
+
]);
|
|
652
667
|
function extractFrontmatterField(content, field) {
|
|
653
668
|
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
654
669
|
if (!fmMatch) return void 0;
|
|
655
670
|
const match = fmMatch[1].match(new RegExp(`^${field}:\\s*(.+)$`, "m"));
|
|
656
671
|
return match?.[1].trim();
|
|
657
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))
|
|
747
|
+
);
|
|
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;
|
|
658
761
|
function checkFrontmatterPreservation(existing, incoming) {
|
|
659
762
|
const violations = [];
|
|
660
763
|
for (const field of PROTECTED_FRONTMATTER_FIELDS) {
|
|
@@ -696,11 +799,25 @@ function validateSkillContent(content, dirName) {
|
|
|
696
799
|
}
|
|
697
800
|
const allowedToolsMatch = frontmatter.match(/^allowed-tools:\s*(.+)$/m);
|
|
698
801
|
if (allowedToolsMatch) {
|
|
699
|
-
const
|
|
700
|
-
if (
|
|
802
|
+
const rawValue = allowedToolsMatch[1].trim();
|
|
803
|
+
if (rawValue.includes("vault_")) {
|
|
701
804
|
issues.push(
|
|
702
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"
|
|
703
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
|
+
}
|
|
704
821
|
}
|
|
705
822
|
}
|
|
706
823
|
const listToolLines = frontmatter.match(/^\s+-\s+vault_\w+/gm);
|
|
@@ -915,6 +1032,48 @@ function createSkillTools(deps) {
|
|
|
915
1032
|
error: 'Invalid skill name: must be a simple directory name without path separators or ".."'
|
|
916
1033
|
});
|
|
917
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
|
+
}
|
|
918
1077
|
const root = projectRoot ?? process.cwd();
|
|
919
1078
|
const skillDir = resolve(root, ".agents", "skills", args.name);
|
|
920
1079
|
const skillPath = resolve(skillDir, "SKILL.md");
|
|
@@ -929,6 +1088,15 @@ function createSkillTools(deps) {
|
|
|
929
1088
|
});
|
|
930
1089
|
}
|
|
931
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
|
+
}
|
|
932
1100
|
try {
|
|
933
1101
|
mkdirSync(skillDir, { recursive: true });
|
|
934
1102
|
writeFileSync(skillPath, args.content, "utf-8");
|
|
@@ -947,77 +1115,98 @@ function createSkillTools(deps) {
|
|
|
947
1115
|
let recordId = "";
|
|
948
1116
|
let generation = 0;
|
|
949
1117
|
const txDb = getDatabase();
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
});
|
|
962
|
-
insertLineage({
|
|
963
|
-
id: crypto2.randomUUID(),
|
|
964
|
-
skill_id: existing.id,
|
|
965
|
-
generation,
|
|
966
|
-
action: "updated",
|
|
967
|
-
rationale: args.rationale ?? "Skill content updated",
|
|
968
|
-
source_ids_added: args.source_ids,
|
|
969
|
-
content_snapshot: args.content,
|
|
970
|
-
created_at: now
|
|
971
|
-
});
|
|
972
|
-
} else {
|
|
973
|
-
recordId = crypto2.randomUUID();
|
|
974
|
-
generation = 1;
|
|
975
|
-
insertSkillRecord({
|
|
976
|
-
id: recordId,
|
|
977
|
-
agent_id: agentId,
|
|
978
|
-
machine_id: machineId,
|
|
979
|
-
name: args.name,
|
|
980
|
-
display_name: args.display_name,
|
|
981
|
-
description: args.description,
|
|
982
|
-
candidate_id: args.candidate_id ?? null,
|
|
983
|
-
source_ids: args.source_ids,
|
|
984
|
-
path: relativePath,
|
|
985
|
-
created_at: now,
|
|
986
|
-
updated_at: now
|
|
987
|
-
});
|
|
988
|
-
insertLineage({
|
|
989
|
-
id: crypto2.randomUUID(),
|
|
990
|
-
skill_id: recordId,
|
|
991
|
-
generation,
|
|
992
|
-
action: "created",
|
|
993
|
-
rationale: args.rationale ?? "Initial skill creation",
|
|
994
|
-
source_ids_added: args.source_ids,
|
|
995
|
-
content_snapshot: args.content,
|
|
996
|
-
created_at: now
|
|
997
|
-
});
|
|
998
|
-
const approvedCandidates = listCandidates({ status: "approved", limit: 10 });
|
|
999
|
-
let linkedCandidate = false;
|
|
1000
|
-
if (args.candidate_id && !linkedCandidate) {
|
|
1001
|
-
const exact = updateCandidate(args.candidate_id, {
|
|
1002
|
-
status: "generated",
|
|
1003
|
-
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,
|
|
1004
1129
|
updated_at: now
|
|
1005
1130
|
});
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
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, {
|
|
1012
1171
|
status: "generated",
|
|
1013
1172
|
skill_id: recordId,
|
|
1014
1173
|
updated_at: now
|
|
1015
1174
|
});
|
|
1016
|
-
linkedCandidate = true;
|
|
1175
|
+
if (exact) linkedCandidate = true;
|
|
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
|
+
}
|
|
1017
1187
|
}
|
|
1018
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 });
|
|
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
|
+
);
|
|
1019
1204
|
}
|
|
1020
|
-
|
|
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
|
+
}
|
|
1021
1210
|
const isNew = generation === 1;
|
|
1022
1211
|
notify(vaultDir, {
|
|
1023
1212
|
domain: "skills",
|
|
@@ -1534,6 +1723,7 @@ import { writeFileSync as writeFileSync2, unlinkSync } from "fs";
|
|
|
1534
1723
|
import { tmpdir } from "os";
|
|
1535
1724
|
import { join } from "path";
|
|
1536
1725
|
var OLLAMA_PRELOAD_TIMEOUT_MS = 3e4;
|
|
1726
|
+
var DEFAULT_OLLAMA_CONTEXT_LENGTH = 32768;
|
|
1537
1727
|
async function ensureOllamaContextVariant(model, contextLength) {
|
|
1538
1728
|
const baseName = model.replace(/:latest$/, "");
|
|
1539
1729
|
const variantName = `${baseName}-ctx${contextLength}`;
|
|
@@ -1560,6 +1750,60 @@ PARAMETER num_ctx ${contextLength}
|
|
|
1560
1750
|
return model;
|
|
1561
1751
|
}
|
|
1562
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
|
+
}
|
|
1563
1807
|
|
|
1564
1808
|
// src/agent/wave-computation.ts
|
|
1565
1809
|
import crypto3 from "crypto";
|
|
@@ -1624,6 +1868,38 @@ var MCP_SERVER_NAME = "myco-vault";
|
|
|
1624
1868
|
var PERSIST_SESSION = true;
|
|
1625
1869
|
var PROMPT_SECTION_PRIOR_PHASES = "## Prior Phase Results";
|
|
1626
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
|
+
}
|
|
1627
1903
|
function composeTaskPrompt(vaultContext, taskDisplayName, taskPrompt, instruction) {
|
|
1628
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);
|
|
1629
1905
|
const sessionId = sessionIdMatch?.[1] ?? "";
|
|
@@ -1690,6 +1966,10 @@ async function executePhase(query, phasePrompt, phaseModel, systemPrompt, toolSe
|
|
|
1690
1966
|
})) {
|
|
1691
1967
|
if (message.type === "assistant") {
|
|
1692
1968
|
agenticTurns++;
|
|
1969
|
+
logToolUseBlocks(phase.name, message);
|
|
1970
|
+
}
|
|
1971
|
+
if (message.type === "user") {
|
|
1972
|
+
logToolResultBlocks(phase.name, message);
|
|
1693
1973
|
}
|
|
1694
1974
|
if (message.type === "result") {
|
|
1695
1975
|
phaseCost = message.total_cost_usd ?? 0;
|
|
@@ -1885,9 +2165,10 @@ async function runAgent(vaultDir, options) {
|
|
|
1885
2165
|
config,
|
|
1886
2166
|
definitionsDir,
|
|
1887
2167
|
taskProviderOverride: resolvedTaskProvider,
|
|
1888
|
-
phaseProviderOverrides
|
|
2168
|
+
phaseProviderOverrides: resolvedPhaseOverrides
|
|
1889
2169
|
} = resolveRunConfig(agentId, requestedTask, vaultDir);
|
|
1890
2170
|
let taskProviderOverride = resolvedTaskProvider;
|
|
2171
|
+
let phaseProviderOverrides = resolvedPhaseOverrides;
|
|
1891
2172
|
const runId = options?.resumeRunId ?? crypto4.randomUUID();
|
|
1892
2173
|
const now = epochSeconds();
|
|
1893
2174
|
if (!options?.resumeRunId) {
|
|
@@ -1909,12 +2190,18 @@ async function runAgent(vaultDir, options) {
|
|
|
1909
2190
|
provider: effectiveProvider?.type ?? "cloud",
|
|
1910
2191
|
...effectiveProvider?.baseUrl ? { baseUrl: effectiveProvider.baseUrl } : {}
|
|
1911
2192
|
};
|
|
1912
|
-
|
|
1913
|
-
const
|
|
1914
|
-
|
|
1915
|
-
|
|
2193
|
+
{
|
|
2194
|
+
const resolved = await resolveOllamaContextVariants(
|
|
2195
|
+
taskProviderOverride,
|
|
2196
|
+
phaseProviderOverrides
|
|
1916
2197
|
);
|
|
1917
|
-
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
|
+
}
|
|
1918
2205
|
}
|
|
1919
2206
|
const taskAbortController = new AbortController();
|
|
1920
2207
|
const timeoutMs = config.timeoutSeconds * MS_PER_SECOND;
|
|
@@ -2025,4 +2312,4 @@ export {
|
|
|
2025
2312
|
computeWaves,
|
|
2026
2313
|
runAgent
|
|
2027
2314
|
};
|
|
2028
|
-
//# sourceMappingURL=executor-
|
|
2315
|
+
//# sourceMappingURL=executor-4OXDK4ZA.js.map
|