skill-tree 0.1.2 → 0.1.3
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/cli/index.js +68 -1171
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/index.mjs +10664 -74
- package/dist/cli/index.mjs.map +1 -0
- package/dist/index.d.mts +23 -1090
- package/dist/index.d.ts +23 -1090
- package/dist/index.js +171 -1855
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +14091 -127
- package/dist/index.mjs.map +1 -0
- package/package.json +2 -3
- package/dist/chunk-3SRB47JW.mjs +0 -8344
- package/dist/chunk-43YOKLZP.mjs +0 -6081
- package/dist/chunk-4AGZU52D.mjs +0 -7918
- package/dist/chunk-4OC5QFIF.mjs +0 -11267
- package/dist/chunk-55SMGVTP.mjs +0 -7126
- package/dist/chunk-6FX4IK4Z.mjs +0 -5368
- package/dist/chunk-7EGDKOHV.mjs +0 -9439
- package/dist/chunk-7LMOQW5H.mjs +0 -4893
- package/dist/chunk-7VB4ZRZO.mjs +0 -7127
- package/dist/chunk-BPVRW25O.mjs +0 -6089
- package/dist/chunk-CI4476KM.mjs +0 -6607
- package/dist/chunk-DDXYQ74I.mjs +0 -13969
- package/dist/chunk-DQOFJXBX.mjs +0 -6595
- package/dist/chunk-E2CVK23F.mjs +0 -8751
- package/dist/chunk-II7DECZQ.mjs +0 -9111
- package/dist/chunk-INKVOZXK.mjs +0 -15898
- package/dist/chunk-K6NRCSAZ.mjs +0 -4355
- package/dist/chunk-ZQVS7MQK.mjs +0 -6081
package/dist/index.js
CHANGED
|
@@ -42,7 +42,6 @@ __export(index_exports, {
|
|
|
42
42
|
BaseStorageAdapter: () => BaseStorageAdapter,
|
|
43
43
|
BatchProcessor: () => BatchProcessor,
|
|
44
44
|
ClaudeCodeAdapter: () => ClaudeCodeAdapter,
|
|
45
|
-
CognitiveCoreProvider: () => CognitiveCoreProvider,
|
|
46
45
|
ConflictStore: () => ConflictStore,
|
|
47
46
|
DEFAULT_ACTIVATION_CONFIG: () => DEFAULT_ACTIVATION_CONFIG,
|
|
48
47
|
DEFAULT_AGENTS_CONFIG: () => DEFAULT_AGENTS_CONFIG,
|
|
@@ -61,7 +60,6 @@ __export(index_exports, {
|
|
|
61
60
|
MemoryMetricsStorage: () => MemoryMetricsStorage,
|
|
62
61
|
MemoryStorageAdapter: () => MemoryStorageAdapter,
|
|
63
62
|
MetricsTracker: () => MetricsTracker,
|
|
64
|
-
NaiveLearningProvider: () => NaiveLearningProvider,
|
|
65
63
|
OpenAIAdapter: () => OpenAIAdapter,
|
|
66
64
|
OpenAIEmbedding: () => OpenAIEmbedding,
|
|
67
65
|
ProjectDetector: () => ProjectDetector,
|
|
@@ -94,9 +92,7 @@ __export(index_exports, {
|
|
|
94
92
|
createAgentsParser: () => createAgentsParser,
|
|
95
93
|
createAgentsSync: () => createAgentsSync,
|
|
96
94
|
createBackupHook: () => createBackupHook,
|
|
97
|
-
createCognitiveCoreProvider: () => createCognitiveCoreProvider,
|
|
98
95
|
createConflictStore: () => createConflictStore,
|
|
99
|
-
createDefaultCognitiveCoreFactory: () => createDefaultCognitiveCoreFactory,
|
|
100
96
|
createDefaultSyncConfig: () => createDefaultSyncConfig,
|
|
101
97
|
createExtractionEnrichmentHook: () => createExtractionEnrichmentHook,
|
|
102
98
|
createExtractionValidationHook: () => createExtractionValidationHook,
|
|
@@ -106,7 +102,6 @@ __export(index_exports, {
|
|
|
106
102
|
createMcpServer: () => createMcpServer,
|
|
107
103
|
createMetricsHook: () => createMetricsHook,
|
|
108
104
|
createMetricsTracker: () => createMetricsTracker,
|
|
109
|
-
createNaiveProvider: () => createNaiveProvider,
|
|
110
105
|
createQualityBypassHook: () => createQualityBypassHook,
|
|
111
106
|
createQualityLoggingHook: () => createQualityLoggingHook,
|
|
112
107
|
createSaveValidationHook: () => createSaveValidationHook,
|
|
@@ -116,6 +111,7 @@ __export(index_exports, {
|
|
|
116
111
|
createToolHandlers: () => createToolHandlers,
|
|
117
112
|
debuggingProfile: () => debuggingProfile,
|
|
118
113
|
devopsProfile: () => devopsProfile,
|
|
114
|
+
discoverSkills: () => discoverSkills,
|
|
119
115
|
documentationProfile: () => documentationProfile,
|
|
120
116
|
euclideanDistance: () => euclideanDistance,
|
|
121
117
|
executeToolCall: () => executeToolCall,
|
|
@@ -126,6 +122,7 @@ __export(index_exports, {
|
|
|
126
122
|
getLatestVersion: () => getLatestVersion,
|
|
127
123
|
getToolDefinition: () => getToolDefinition,
|
|
128
124
|
getToolNames: () => getToolNames,
|
|
125
|
+
hasSkilltreeDir: () => hasSkilltreeDir,
|
|
129
126
|
hookRegistry: () => hookRegistry,
|
|
130
127
|
implementationProfile: () => implementationProfile,
|
|
131
128
|
importFromAgentsMd: () => importFromAgentsMd,
|
|
@@ -846,11 +843,76 @@ var LoadoutCompiler = class {
|
|
|
846
843
|
// src/serving/project-detector.ts
|
|
847
844
|
var import_fs = require("fs");
|
|
848
845
|
var import_path = require("path");
|
|
849
|
-
var
|
|
846
|
+
var ProjectDetector = class _ProjectDetector {
|
|
850
847
|
constructor() {
|
|
851
848
|
/** Cache for project context */
|
|
852
849
|
this.cache = /* @__PURE__ */ new Map();
|
|
853
850
|
}
|
|
851
|
+
static {
|
|
852
|
+
/** Project type patterns */
|
|
853
|
+
this.PROJECT_TYPES = [
|
|
854
|
+
{ manifestFile: "package.json", type: "nodejs", tags: ["nodejs", "javascript"], packageManager: "npm" },
|
|
855
|
+
{ manifestFile: "pyproject.toml", type: "python", tags: ["python"], packageManager: "pip" },
|
|
856
|
+
{ manifestFile: "requirements.txt", type: "python", tags: ["python"], packageManager: "pip" },
|
|
857
|
+
{ manifestFile: "Cargo.toml", type: "rust", tags: ["rust"], packageManager: "cargo" },
|
|
858
|
+
{ manifestFile: "go.mod", type: "go", tags: ["go", "golang"] },
|
|
859
|
+
{ manifestFile: "pom.xml", type: "java", tags: ["java", "maven"], packageManager: "maven" },
|
|
860
|
+
{ manifestFile: "build.gradle", type: "java", tags: ["java", "gradle"], packageManager: "gradle" },
|
|
861
|
+
{ manifestFile: "build.gradle.kts", type: "kotlin", tags: ["kotlin", "gradle"], packageManager: "gradle" }
|
|
862
|
+
];
|
|
863
|
+
}
|
|
864
|
+
static {
|
|
865
|
+
/** TypeScript detection */
|
|
866
|
+
this.TYPESCRIPT_FILES = ["tsconfig.json", "tsconfig.base.json"];
|
|
867
|
+
}
|
|
868
|
+
static {
|
|
869
|
+
/** Node.js framework patterns */
|
|
870
|
+
this.NODE_FRAMEWORKS = [
|
|
871
|
+
{ name: "react", packageName: "react", tags: ["react", "frontend"] },
|
|
872
|
+
{ name: "next", packageName: "next", tags: ["nextjs", "react", "fullstack"] },
|
|
873
|
+
{ name: "vue", packageName: "vue", tags: ["vue", "frontend"] },
|
|
874
|
+
{ name: "nuxt", packageName: "nuxt", tags: ["nuxt", "vue", "fullstack"] },
|
|
875
|
+
{ name: "angular", packageName: "@angular/core", tags: ["angular", "frontend"] },
|
|
876
|
+
{ name: "svelte", packageName: "svelte", tags: ["svelte", "frontend"] },
|
|
877
|
+
{ name: "express", packageName: "express", tags: ["express", "backend", "api"] },
|
|
878
|
+
{ name: "fastify", packageName: "fastify", tags: ["fastify", "backend", "api"] },
|
|
879
|
+
{ name: "nestjs", packageName: "@nestjs/core", tags: ["nestjs", "backend", "api"] },
|
|
880
|
+
{ name: "hono", packageName: "hono", tags: ["hono", "backend", "api"] },
|
|
881
|
+
{ name: "prisma", packageName: "@prisma/client", tags: ["prisma", "database", "orm"] },
|
|
882
|
+
{ name: "drizzle", packageName: "drizzle-orm", tags: ["drizzle", "database", "orm"] },
|
|
883
|
+
{ name: "typeorm", packageName: "typeorm", tags: ["typeorm", "database", "orm"] },
|
|
884
|
+
{ name: "jest", packageName: "jest", tags: ["testing", "jest"] },
|
|
885
|
+
{ name: "vitest", packageName: "vitest", tags: ["testing", "vitest"] },
|
|
886
|
+
{ name: "playwright", packageName: "@playwright/test", tags: ["testing", "e2e", "playwright"] },
|
|
887
|
+
{ name: "cypress", packageName: "cypress", tags: ["testing", "e2e", "cypress"] }
|
|
888
|
+
];
|
|
889
|
+
}
|
|
890
|
+
static {
|
|
891
|
+
/** Python framework patterns (from pyproject.toml or requirements.txt) */
|
|
892
|
+
this.PYTHON_FRAMEWORKS = [
|
|
893
|
+
{ name: "fastapi", packageName: "fastapi", tags: ["fastapi", "backend", "api"] },
|
|
894
|
+
{ name: "django", packageName: "django", tags: ["django", "backend", "fullstack"] },
|
|
895
|
+
{ name: "flask", packageName: "flask", tags: ["flask", "backend", "api"] },
|
|
896
|
+
{ name: "sqlalchemy", packageName: "sqlalchemy", tags: ["sqlalchemy", "database", "orm"] },
|
|
897
|
+
{ name: "pytest", packageName: "pytest", tags: ["testing", "pytest"] },
|
|
898
|
+
{ name: "pydantic", packageName: "pydantic", tags: ["pydantic", "validation"] }
|
|
899
|
+
];
|
|
900
|
+
}
|
|
901
|
+
static {
|
|
902
|
+
/** Directory patterns */
|
|
903
|
+
this.DIRECTORY_PATTERNS = [
|
|
904
|
+
{ pattern: ".github/workflows", feature: "github-actions", tags: ["ci", "github-actions"] },
|
|
905
|
+
{ pattern: ".gitlab-ci.yml", feature: "gitlab-ci", tags: ["ci", "gitlab"] },
|
|
906
|
+
{ pattern: "Dockerfile", feature: "docker", tags: ["docker", "containers"] },
|
|
907
|
+
{ pattern: "docker-compose.yml", feature: "docker-compose", tags: ["docker", "containers"] },
|
|
908
|
+
{ pattern: "docker-compose.yaml", feature: "docker-compose", tags: ["docker", "containers"] },
|
|
909
|
+
{ pattern: "terraform", feature: "terraform", tags: ["terraform", "infrastructure"] },
|
|
910
|
+
{ pattern: "kubernetes", feature: "kubernetes", tags: ["kubernetes", "infrastructure"] },
|
|
911
|
+
{ pattern: "k8s", feature: "kubernetes", tags: ["kubernetes", "infrastructure"] },
|
|
912
|
+
{ pattern: ".env.example", feature: "env-config", tags: ["configuration"] },
|
|
913
|
+
{ pattern: "prisma/schema.prisma", feature: "prisma", tags: ["prisma", "database"] }
|
|
914
|
+
];
|
|
915
|
+
}
|
|
854
916
|
/**
|
|
855
917
|
* Detect project context from a directory
|
|
856
918
|
*/
|
|
@@ -1012,62 +1074,6 @@ var _ProjectDetector = class _ProjectDetector {
|
|
|
1012
1074
|
}
|
|
1013
1075
|
}
|
|
1014
1076
|
};
|
|
1015
|
-
/** Project type patterns */
|
|
1016
|
-
_ProjectDetector.PROJECT_TYPES = [
|
|
1017
|
-
{ manifestFile: "package.json", type: "nodejs", tags: ["nodejs", "javascript"], packageManager: "npm" },
|
|
1018
|
-
{ manifestFile: "pyproject.toml", type: "python", tags: ["python"], packageManager: "pip" },
|
|
1019
|
-
{ manifestFile: "requirements.txt", type: "python", tags: ["python"], packageManager: "pip" },
|
|
1020
|
-
{ manifestFile: "Cargo.toml", type: "rust", tags: ["rust"], packageManager: "cargo" },
|
|
1021
|
-
{ manifestFile: "go.mod", type: "go", tags: ["go", "golang"] },
|
|
1022
|
-
{ manifestFile: "pom.xml", type: "java", tags: ["java", "maven"], packageManager: "maven" },
|
|
1023
|
-
{ manifestFile: "build.gradle", type: "java", tags: ["java", "gradle"], packageManager: "gradle" },
|
|
1024
|
-
{ manifestFile: "build.gradle.kts", type: "kotlin", tags: ["kotlin", "gradle"], packageManager: "gradle" }
|
|
1025
|
-
];
|
|
1026
|
-
/** TypeScript detection */
|
|
1027
|
-
_ProjectDetector.TYPESCRIPT_FILES = ["tsconfig.json", "tsconfig.base.json"];
|
|
1028
|
-
/** Node.js framework patterns */
|
|
1029
|
-
_ProjectDetector.NODE_FRAMEWORKS = [
|
|
1030
|
-
{ name: "react", packageName: "react", tags: ["react", "frontend"] },
|
|
1031
|
-
{ name: "next", packageName: "next", tags: ["nextjs", "react", "fullstack"] },
|
|
1032
|
-
{ name: "vue", packageName: "vue", tags: ["vue", "frontend"] },
|
|
1033
|
-
{ name: "nuxt", packageName: "nuxt", tags: ["nuxt", "vue", "fullstack"] },
|
|
1034
|
-
{ name: "angular", packageName: "@angular/core", tags: ["angular", "frontend"] },
|
|
1035
|
-
{ name: "svelte", packageName: "svelte", tags: ["svelte", "frontend"] },
|
|
1036
|
-
{ name: "express", packageName: "express", tags: ["express", "backend", "api"] },
|
|
1037
|
-
{ name: "fastify", packageName: "fastify", tags: ["fastify", "backend", "api"] },
|
|
1038
|
-
{ name: "nestjs", packageName: "@nestjs/core", tags: ["nestjs", "backend", "api"] },
|
|
1039
|
-
{ name: "hono", packageName: "hono", tags: ["hono", "backend", "api"] },
|
|
1040
|
-
{ name: "prisma", packageName: "@prisma/client", tags: ["prisma", "database", "orm"] },
|
|
1041
|
-
{ name: "drizzle", packageName: "drizzle-orm", tags: ["drizzle", "database", "orm"] },
|
|
1042
|
-
{ name: "typeorm", packageName: "typeorm", tags: ["typeorm", "database", "orm"] },
|
|
1043
|
-
{ name: "jest", packageName: "jest", tags: ["testing", "jest"] },
|
|
1044
|
-
{ name: "vitest", packageName: "vitest", tags: ["testing", "vitest"] },
|
|
1045
|
-
{ name: "playwright", packageName: "@playwright/test", tags: ["testing", "e2e", "playwright"] },
|
|
1046
|
-
{ name: "cypress", packageName: "cypress", tags: ["testing", "e2e", "cypress"] }
|
|
1047
|
-
];
|
|
1048
|
-
/** Python framework patterns (from pyproject.toml or requirements.txt) */
|
|
1049
|
-
_ProjectDetector.PYTHON_FRAMEWORKS = [
|
|
1050
|
-
{ name: "fastapi", packageName: "fastapi", tags: ["fastapi", "backend", "api"] },
|
|
1051
|
-
{ name: "django", packageName: "django", tags: ["django", "backend", "fullstack"] },
|
|
1052
|
-
{ name: "flask", packageName: "flask", tags: ["flask", "backend", "api"] },
|
|
1053
|
-
{ name: "sqlalchemy", packageName: "sqlalchemy", tags: ["sqlalchemy", "database", "orm"] },
|
|
1054
|
-
{ name: "pytest", packageName: "pytest", tags: ["testing", "pytest"] },
|
|
1055
|
-
{ name: "pydantic", packageName: "pydantic", tags: ["pydantic", "validation"] }
|
|
1056
|
-
];
|
|
1057
|
-
/** Directory patterns */
|
|
1058
|
-
_ProjectDetector.DIRECTORY_PATTERNS = [
|
|
1059
|
-
{ pattern: ".github/workflows", feature: "github-actions", tags: ["ci", "github-actions"] },
|
|
1060
|
-
{ pattern: ".gitlab-ci.yml", feature: "gitlab-ci", tags: ["ci", "gitlab"] },
|
|
1061
|
-
{ pattern: "Dockerfile", feature: "docker", tags: ["docker", "containers"] },
|
|
1062
|
-
{ pattern: "docker-compose.yml", feature: "docker-compose", tags: ["docker", "containers"] },
|
|
1063
|
-
{ pattern: "docker-compose.yaml", feature: "docker-compose", tags: ["docker", "containers"] },
|
|
1064
|
-
{ pattern: "terraform", feature: "terraform", tags: ["terraform", "infrastructure"] },
|
|
1065
|
-
{ pattern: "kubernetes", feature: "kubernetes", tags: ["kubernetes", "infrastructure"] },
|
|
1066
|
-
{ pattern: "k8s", feature: "kubernetes", tags: ["kubernetes", "infrastructure"] },
|
|
1067
|
-
{ pattern: ".env.example", feature: "env-config", tags: ["configuration"] },
|
|
1068
|
-
{ pattern: "prisma/schema.prisma", feature: "prisma", tags: ["prisma", "database"] }
|
|
1069
|
-
];
|
|
1070
|
-
var ProjectDetector = _ProjectDetector;
|
|
1071
1077
|
|
|
1072
1078
|
// src/serving/view-renderer.ts
|
|
1073
1079
|
var DEFAULT_CONFIG2 = {
|
|
@@ -6522,10 +6528,7 @@ var MemoryStorageAdapter = class extends BaseStorageAdapter {
|
|
|
6522
6528
|
this.skills = /* @__PURE__ */ new Map();
|
|
6523
6529
|
// skillId -> version -> skill
|
|
6524
6530
|
this.lineages = /* @__PURE__ */ new Map();
|
|
6525
|
-
this.candidates = /* @__PURE__ */ new Map();
|
|
6526
|
-
this.antiPatterns = /* @__PURE__ */ new Map();
|
|
6527
6531
|
}
|
|
6528
|
-
// skillId -> patterns
|
|
6529
6532
|
async initialize() {
|
|
6530
6533
|
this.initialized = true;
|
|
6531
6534
|
}
|
|
@@ -6656,78 +6659,6 @@ var MemoryStorageAdapter = class extends BaseStorageAdapter {
|
|
|
6656
6659
|
clear() {
|
|
6657
6660
|
this.skills.clear();
|
|
6658
6661
|
this.lineages.clear();
|
|
6659
|
-
this.candidates.clear();
|
|
6660
|
-
this.antiPatterns.clear();
|
|
6661
|
-
}
|
|
6662
|
-
// ==========================================================================
|
|
6663
|
-
// Learning Candidate Operations
|
|
6664
|
-
// ==========================================================================
|
|
6665
|
-
async saveCandidate(candidate) {
|
|
6666
|
-
this.ensureInitialized();
|
|
6667
|
-
this.candidates.set(candidate.id, { ...candidate });
|
|
6668
|
-
}
|
|
6669
|
-
async getCandidate(id) {
|
|
6670
|
-
this.ensureInitialized();
|
|
6671
|
-
return this.candidates.get(id) || null;
|
|
6672
|
-
}
|
|
6673
|
-
async listCandidates(filter) {
|
|
6674
|
-
this.ensureInitialized();
|
|
6675
|
-
let results = Array.from(this.candidates.values());
|
|
6676
|
-
if (filter) {
|
|
6677
|
-
if (filter.kind && filter.kind.length > 0) {
|
|
6678
|
-
results = results.filter((c) => filter.kind.includes(c.kind));
|
|
6679
|
-
}
|
|
6680
|
-
if (filter.status && filter.status.length > 0) {
|
|
6681
|
-
results = results.filter((c) => filter.status.includes(c.status));
|
|
6682
|
-
}
|
|
6683
|
-
if (filter.minConfidence !== void 0) {
|
|
6684
|
-
results = results.filter((c) => c.confidence >= filter.minConfidence);
|
|
6685
|
-
}
|
|
6686
|
-
if (filter.createdAfter) {
|
|
6687
|
-
results = results.filter((c) => c.createdAt >= filter.createdAfter);
|
|
6688
|
-
}
|
|
6689
|
-
if (filter.createdBefore) {
|
|
6690
|
-
results = results.filter((c) => c.createdAt <= filter.createdBefore);
|
|
6691
|
-
}
|
|
6692
|
-
}
|
|
6693
|
-
return results;
|
|
6694
|
-
}
|
|
6695
|
-
async updateCandidateStatus(id, status, details) {
|
|
6696
|
-
this.ensureInitialized();
|
|
6697
|
-
const candidate = this.candidates.get(id);
|
|
6698
|
-
if (!candidate) return false;
|
|
6699
|
-
candidate.status = status;
|
|
6700
|
-
candidate.updatedAt = /* @__PURE__ */ new Date();
|
|
6701
|
-
if (details?.promotedToSkillId) {
|
|
6702
|
-
candidate.promotedToSkillId = details.promotedToSkillId;
|
|
6703
|
-
}
|
|
6704
|
-
if (details?.rejectionReason) {
|
|
6705
|
-
candidate.rejectionReason = details.rejectionReason;
|
|
6706
|
-
}
|
|
6707
|
-
return true;
|
|
6708
|
-
}
|
|
6709
|
-
async deleteCandidate(id) {
|
|
6710
|
-
this.ensureInitialized();
|
|
6711
|
-
return this.candidates.delete(id);
|
|
6712
|
-
}
|
|
6713
|
-
// ==========================================================================
|
|
6714
|
-
// Anti-Pattern Operations
|
|
6715
|
-
// ==========================================================================
|
|
6716
|
-
async saveAntiPatterns(skillId, patterns) {
|
|
6717
|
-
this.ensureInitialized();
|
|
6718
|
-
this.antiPatterns.set(skillId, [...patterns]);
|
|
6719
|
-
}
|
|
6720
|
-
async getAntiPatterns(skillId) {
|
|
6721
|
-
this.ensureInitialized();
|
|
6722
|
-
return this.antiPatterns.get(skillId) || [];
|
|
6723
|
-
}
|
|
6724
|
-
async listAntiPatterns() {
|
|
6725
|
-
this.ensureInitialized();
|
|
6726
|
-
const results = [];
|
|
6727
|
-
for (const [skillId, patterns] of this.antiPatterns) {
|
|
6728
|
-
results.push({ skillId, patterns });
|
|
6729
|
-
}
|
|
6730
|
-
return results;
|
|
6731
6662
|
}
|
|
6732
6663
|
// ==========================================================================
|
|
6733
6664
|
// Fork Tracking
|
|
@@ -7278,152 +7209,6 @@ ${body}`;
|
|
|
7278
7209
|
return Math.abs(hash).toString(16);
|
|
7279
7210
|
}
|
|
7280
7211
|
// ==========================================================================
|
|
7281
|
-
// Learning Candidate Operations
|
|
7282
|
-
// ==========================================================================
|
|
7283
|
-
get candidatesDir() {
|
|
7284
|
-
return path4.join(this.skilltreeDir, "candidates");
|
|
7285
|
-
}
|
|
7286
|
-
get antiPatternsDir() {
|
|
7287
|
-
return path4.join(this.skilltreeDir, "anti-patterns");
|
|
7288
|
-
}
|
|
7289
|
-
async saveCandidate(candidate) {
|
|
7290
|
-
this.ensureInitialized();
|
|
7291
|
-
await fs4.mkdir(this.candidatesDir, { recursive: true });
|
|
7292
|
-
const candidatePath = path4.join(this.candidatesDir, `${candidate.id}.json`);
|
|
7293
|
-
await fs4.writeFile(candidatePath, JSON.stringify(candidate, null, 2), "utf-8");
|
|
7294
|
-
}
|
|
7295
|
-
async getCandidate(id) {
|
|
7296
|
-
this.ensureInitialized();
|
|
7297
|
-
const candidatePath = path4.join(this.candidatesDir, `${id}.json`);
|
|
7298
|
-
try {
|
|
7299
|
-
const content = await fs4.readFile(candidatePath, "utf-8");
|
|
7300
|
-
const candidate = JSON.parse(content);
|
|
7301
|
-
candidate.createdAt = new Date(candidate.createdAt);
|
|
7302
|
-
candidate.updatedAt = new Date(candidate.updatedAt);
|
|
7303
|
-
candidate.source.extractedAt = new Date(candidate.source.extractedAt);
|
|
7304
|
-
return candidate;
|
|
7305
|
-
} catch (error) {
|
|
7306
|
-
if (error.code === "ENOENT") {
|
|
7307
|
-
return null;
|
|
7308
|
-
}
|
|
7309
|
-
throw error;
|
|
7310
|
-
}
|
|
7311
|
-
}
|
|
7312
|
-
async listCandidates(filter) {
|
|
7313
|
-
this.ensureInitialized();
|
|
7314
|
-
try {
|
|
7315
|
-
const files = await fs4.readdir(this.candidatesDir);
|
|
7316
|
-
const candidates = [];
|
|
7317
|
-
for (const file of files) {
|
|
7318
|
-
if (!file.endsWith(".json")) continue;
|
|
7319
|
-
const id = file.replace(".json", "");
|
|
7320
|
-
const candidate = await this.getCandidate(id);
|
|
7321
|
-
if (candidate) {
|
|
7322
|
-
candidates.push(candidate);
|
|
7323
|
-
}
|
|
7324
|
-
}
|
|
7325
|
-
let results = candidates;
|
|
7326
|
-
if (filter) {
|
|
7327
|
-
if (filter.kind && filter.kind.length > 0) {
|
|
7328
|
-
results = results.filter((c) => filter.kind.includes(c.kind));
|
|
7329
|
-
}
|
|
7330
|
-
if (filter.status && filter.status.length > 0) {
|
|
7331
|
-
results = results.filter((c) => filter.status.includes(c.status));
|
|
7332
|
-
}
|
|
7333
|
-
if (filter.minConfidence !== void 0) {
|
|
7334
|
-
results = results.filter((c) => c.confidence >= filter.minConfidence);
|
|
7335
|
-
}
|
|
7336
|
-
if (filter.createdAfter) {
|
|
7337
|
-
results = results.filter((c) => c.createdAt >= filter.createdAfter);
|
|
7338
|
-
}
|
|
7339
|
-
if (filter.createdBefore) {
|
|
7340
|
-
results = results.filter((c) => c.createdAt <= filter.createdBefore);
|
|
7341
|
-
}
|
|
7342
|
-
}
|
|
7343
|
-
return results;
|
|
7344
|
-
} catch (error) {
|
|
7345
|
-
if (error.code === "ENOENT") {
|
|
7346
|
-
return [];
|
|
7347
|
-
}
|
|
7348
|
-
throw error;
|
|
7349
|
-
}
|
|
7350
|
-
}
|
|
7351
|
-
async updateCandidateStatus(id, status, details) {
|
|
7352
|
-
this.ensureInitialized();
|
|
7353
|
-
const candidate = await this.getCandidate(id);
|
|
7354
|
-
if (!candidate) return false;
|
|
7355
|
-
candidate.status = status;
|
|
7356
|
-
candidate.updatedAt = /* @__PURE__ */ new Date();
|
|
7357
|
-
if (details?.promotedToSkillId) {
|
|
7358
|
-
candidate.promotedToSkillId = details.promotedToSkillId;
|
|
7359
|
-
}
|
|
7360
|
-
if (details?.rejectionReason) {
|
|
7361
|
-
candidate.rejectionReason = details.rejectionReason;
|
|
7362
|
-
}
|
|
7363
|
-
await this.saveCandidate(candidate);
|
|
7364
|
-
return true;
|
|
7365
|
-
}
|
|
7366
|
-
async deleteCandidate(id) {
|
|
7367
|
-
this.ensureInitialized();
|
|
7368
|
-
const candidatePath = path4.join(this.candidatesDir, `${id}.json`);
|
|
7369
|
-
try {
|
|
7370
|
-
await fs4.unlink(candidatePath);
|
|
7371
|
-
return true;
|
|
7372
|
-
} catch (error) {
|
|
7373
|
-
if (error.code === "ENOENT") {
|
|
7374
|
-
return false;
|
|
7375
|
-
}
|
|
7376
|
-
throw error;
|
|
7377
|
-
}
|
|
7378
|
-
}
|
|
7379
|
-
// ==========================================================================
|
|
7380
|
-
// Anti-Pattern Operations
|
|
7381
|
-
// ==========================================================================
|
|
7382
|
-
async saveAntiPatterns(skillId, patterns) {
|
|
7383
|
-
this.ensureInitialized();
|
|
7384
|
-
await fs4.mkdir(this.antiPatternsDir, { recursive: true });
|
|
7385
|
-
const patternPath = path4.join(this.antiPatternsDir, `${skillId}.json`);
|
|
7386
|
-
await fs4.writeFile(patternPath, JSON.stringify(patterns, null, 2), "utf-8");
|
|
7387
|
-
}
|
|
7388
|
-
async getAntiPatterns(skillId) {
|
|
7389
|
-
this.ensureInitialized();
|
|
7390
|
-
const patternPath = path4.join(this.antiPatternsDir, `${skillId}.json`);
|
|
7391
|
-
try {
|
|
7392
|
-
const content = await fs4.readFile(patternPath, "utf-8");
|
|
7393
|
-
const patterns = JSON.parse(content);
|
|
7394
|
-
for (const pattern of patterns) {
|
|
7395
|
-
pattern.learnedAt = new Date(pattern.learnedAt);
|
|
7396
|
-
}
|
|
7397
|
-
return patterns;
|
|
7398
|
-
} catch (error) {
|
|
7399
|
-
if (error.code === "ENOENT") {
|
|
7400
|
-
return [];
|
|
7401
|
-
}
|
|
7402
|
-
throw error;
|
|
7403
|
-
}
|
|
7404
|
-
}
|
|
7405
|
-
async listAntiPatterns() {
|
|
7406
|
-
this.ensureInitialized();
|
|
7407
|
-
try {
|
|
7408
|
-
const files = await fs4.readdir(this.antiPatternsDir);
|
|
7409
|
-
const results = [];
|
|
7410
|
-
for (const file of files) {
|
|
7411
|
-
if (!file.endsWith(".json")) continue;
|
|
7412
|
-
const skillId = file.replace(".json", "");
|
|
7413
|
-
const patterns = await this.getAntiPatterns(skillId);
|
|
7414
|
-
if (patterns.length > 0) {
|
|
7415
|
-
results.push({ skillId, patterns });
|
|
7416
|
-
}
|
|
7417
|
-
}
|
|
7418
|
-
return results;
|
|
7419
|
-
} catch (error) {
|
|
7420
|
-
if (error.code === "ENOENT") {
|
|
7421
|
-
return [];
|
|
7422
|
-
}
|
|
7423
|
-
throw error;
|
|
7424
|
-
}
|
|
7425
|
-
}
|
|
7426
|
-
// ==========================================================================
|
|
7427
7212
|
// Fork Tracking
|
|
7428
7213
|
// ==========================================================================
|
|
7429
7214
|
async recordFork(sourceSkillId, fork) {
|
|
@@ -8226,8 +8011,6 @@ async function migrateStorage(source, target, options = {}) {
|
|
|
8226
8011
|
const opts = {
|
|
8227
8012
|
skills: options.skills ?? true,
|
|
8228
8013
|
lineage: options.lineage ?? true,
|
|
8229
|
-
candidates: options.candidates ?? true,
|
|
8230
|
-
antiPatterns: options.antiPatterns ?? true,
|
|
8231
8014
|
onProgress: options.onProgress ?? (() => {
|
|
8232
8015
|
}),
|
|
8233
8016
|
overwrite: options.overwrite ?? false
|
|
@@ -8239,9 +8022,7 @@ async function migrateStorage(source, target, options = {}) {
|
|
|
8239
8022
|
errors: 0,
|
|
8240
8023
|
details: {
|
|
8241
8024
|
skills: { migrated: 0, skipped: 0, errors: 0 },
|
|
8242
|
-
lineages: { migrated: 0, skipped: 0, errors: 0 }
|
|
8243
|
-
candidates: { migrated: 0, skipped: 0, errors: 0 },
|
|
8244
|
-
antiPatterns: { migrated: 0, skipped: 0, errors: 0 }
|
|
8025
|
+
lineages: { migrated: 0, skipped: 0, errors: 0 }
|
|
8245
8026
|
}
|
|
8246
8027
|
};
|
|
8247
8028
|
if (opts.skills) {
|
|
@@ -8250,12 +8031,6 @@ async function migrateStorage(source, target, options = {}) {
|
|
|
8250
8031
|
if (opts.lineage) {
|
|
8251
8032
|
await migrateLineages(source, target, opts, result);
|
|
8252
8033
|
}
|
|
8253
|
-
if (opts.candidates) {
|
|
8254
|
-
await migrateCandidates(source, target, opts, result);
|
|
8255
|
-
}
|
|
8256
|
-
if (opts.antiPatterns) {
|
|
8257
|
-
await migrateAntiPatterns(source, target, opts, result);
|
|
8258
|
-
}
|
|
8259
8034
|
return result;
|
|
8260
8035
|
}
|
|
8261
8036
|
async function migrateSkills(source, target, opts, result) {
|
|
@@ -8321,65 +8096,6 @@ async function migrateLineages(source, target, opts, result) {
|
|
|
8321
8096
|
}
|
|
8322
8097
|
}
|
|
8323
8098
|
}
|
|
8324
|
-
async function migrateCandidates(source, target, opts, result) {
|
|
8325
|
-
if (!source.listCandidates || !target.saveCandidate) {
|
|
8326
|
-
return;
|
|
8327
|
-
}
|
|
8328
|
-
const candidates = await source.listCandidates();
|
|
8329
|
-
for (const candidate of candidates) {
|
|
8330
|
-
result.totalProcessed++;
|
|
8331
|
-
try {
|
|
8332
|
-
if (!opts.overwrite && target.getCandidate) {
|
|
8333
|
-
const existing = await target.getCandidate(candidate.id);
|
|
8334
|
-
if (existing) {
|
|
8335
|
-
result.skipped++;
|
|
8336
|
-
result.details.candidates.skipped++;
|
|
8337
|
-
opts.onProgress({ type: "candidate", id: candidate.id, status: "skipped" });
|
|
8338
|
-
continue;
|
|
8339
|
-
}
|
|
8340
|
-
}
|
|
8341
|
-
await target.saveCandidate(candidate);
|
|
8342
|
-
result.migrated++;
|
|
8343
|
-
result.details.candidates.migrated++;
|
|
8344
|
-
opts.onProgress({ type: "candidate", id: candidate.id, status: "migrated" });
|
|
8345
|
-
} catch (error) {
|
|
8346
|
-
result.errors++;
|
|
8347
|
-
result.details.candidates.errors++;
|
|
8348
|
-
opts.onProgress({
|
|
8349
|
-
type: "candidate",
|
|
8350
|
-
id: candidate.id,
|
|
8351
|
-
status: "error",
|
|
8352
|
-
error: error instanceof Error ? error.message : String(error)
|
|
8353
|
-
});
|
|
8354
|
-
}
|
|
8355
|
-
}
|
|
8356
|
-
}
|
|
8357
|
-
async function migrateAntiPatterns(source, target, opts, result) {
|
|
8358
|
-
if (!source.getAntiPatterns || !target.saveAntiPatterns) {
|
|
8359
|
-
return;
|
|
8360
|
-
}
|
|
8361
|
-
const skills = await source.listSkills();
|
|
8362
|
-
for (const skill of skills) {
|
|
8363
|
-
try {
|
|
8364
|
-
const patterns = await source.getAntiPatterns(skill.id);
|
|
8365
|
-
if (!patterns || patterns.length === 0) continue;
|
|
8366
|
-
result.totalProcessed++;
|
|
8367
|
-
await target.saveAntiPatterns(skill.id, patterns);
|
|
8368
|
-
result.migrated++;
|
|
8369
|
-
result.details.antiPatterns.migrated++;
|
|
8370
|
-
opts.onProgress({ type: "anti-pattern", id: skill.id, status: "migrated" });
|
|
8371
|
-
} catch (error) {
|
|
8372
|
-
result.errors++;
|
|
8373
|
-
result.details.antiPatterns.errors++;
|
|
8374
|
-
opts.onProgress({
|
|
8375
|
-
type: "anti-pattern",
|
|
8376
|
-
id: skill.id,
|
|
8377
|
-
status: "error",
|
|
8378
|
-
error: error instanceof Error ? error.message : String(error)
|
|
8379
|
-
});
|
|
8380
|
-
}
|
|
8381
|
-
}
|
|
8382
|
-
}
|
|
8383
8099
|
|
|
8384
8100
|
// src/versioning/lineage.ts
|
|
8385
8101
|
var LineageTracker = class {
|
|
@@ -9152,387 +8868,80 @@ function createSkillMerger(storage, config) {
|
|
|
9152
8868
|
return new SkillMerger(storage, config);
|
|
9153
8869
|
}
|
|
9154
8870
|
|
|
9155
|
-
// src/
|
|
9156
|
-
var
|
|
9157
|
-
|
|
9158
|
-
|
|
9159
|
-
|
|
9160
|
-
|
|
9161
|
-
|
|
9162
|
-
|
|
9163
|
-
|
|
9164
|
-
|
|
9165
|
-
|
|
9166
|
-
this.config = {
|
|
9167
|
-
llmProvider: config?.llmProvider ?? null,
|
|
9168
|
-
minConfidence: config?.minConfidence ?? 0.6,
|
|
9169
|
-
runQualityGates: config?.runQualityGates ?? true,
|
|
9170
|
-
creditStrategy: config?.creditStrategy ?? "simple"
|
|
9171
|
-
};
|
|
9172
|
-
this.manualExtractor = new ManualExtractor();
|
|
9173
|
-
this.automaticExtractor = new AutomaticExtractor({
|
|
9174
|
-
llmProvider: this.config.llmProvider || void 0,
|
|
9175
|
-
minConfidence: this.config.minConfidence
|
|
9176
|
-
});
|
|
8871
|
+
// src/hooks/registry.ts
|
|
8872
|
+
var import_crypto = require("crypto");
|
|
8873
|
+
var PRIORITY_ORDER = {
|
|
8874
|
+
high: 0,
|
|
8875
|
+
normal: 1,
|
|
8876
|
+
low: 2
|
|
8877
|
+
};
|
|
8878
|
+
var HookRegistry = class {
|
|
8879
|
+
constructor() {
|
|
8880
|
+
this.hooks = /* @__PURE__ */ new Map();
|
|
8881
|
+
this.eventIndex = /* @__PURE__ */ new Map();
|
|
9177
8882
|
}
|
|
9178
8883
|
/**
|
|
9179
|
-
*
|
|
8884
|
+
* Register a new hook
|
|
9180
8885
|
*/
|
|
9181
|
-
|
|
9182
|
-
|
|
9183
|
-
|
|
8886
|
+
register(options) {
|
|
8887
|
+
const id = (0, import_crypto.randomUUID)();
|
|
8888
|
+
const events = Array.isArray(options.events) ? options.events : [options.events];
|
|
8889
|
+
const hook = {
|
|
8890
|
+
id,
|
|
8891
|
+
name: options.name,
|
|
8892
|
+
events,
|
|
8893
|
+
handler: options.handler,
|
|
8894
|
+
priority: options.priority || "normal",
|
|
8895
|
+
enabled: options.enabled !== false,
|
|
8896
|
+
filter: options.filter
|
|
8897
|
+
};
|
|
8898
|
+
this.hooks.set(id, hook);
|
|
8899
|
+
for (const event of events) {
|
|
8900
|
+
if (!this.eventIndex.has(event)) {
|
|
8901
|
+
this.eventIndex.set(event, /* @__PURE__ */ new Set());
|
|
8902
|
+
}
|
|
8903
|
+
this.eventIndex.get(event).add(id);
|
|
8904
|
+
}
|
|
8905
|
+
return id;
|
|
9184
8906
|
}
|
|
9185
8907
|
/**
|
|
9186
|
-
*
|
|
8908
|
+
* Unregister a hook
|
|
9187
8909
|
*/
|
|
9188
|
-
|
|
9189
|
-
const
|
|
9190
|
-
|
|
9191
|
-
const
|
|
9192
|
-
|
|
9193
|
-
let results;
|
|
9194
|
-
if (useAutomatic) {
|
|
9195
|
-
results = await this.automaticExtractor.extract(trajectory, {
|
|
9196
|
-
turnRange: options?.turnRange,
|
|
9197
|
-
minConfidence: options?.minConfidence ?? this.config.minConfidence,
|
|
9198
|
-
skipValidation: options?.skipValidation ?? !this.config.runQualityGates,
|
|
9199
|
-
context: options?.context
|
|
9200
|
-
});
|
|
9201
|
-
} else {
|
|
9202
|
-
results = await this.manualExtractor.extract(trajectory, {
|
|
9203
|
-
turnRange: options?.turnRange,
|
|
9204
|
-
skipValidation: options?.skipValidation ?? !this.config.runQualityGates,
|
|
9205
|
-
context: options?.context
|
|
9206
|
-
});
|
|
9207
|
-
}
|
|
9208
|
-
for (const result of results) {
|
|
9209
|
-
if (!result.success || !result.skill) continue;
|
|
9210
|
-
const kind = this.inferKind(result.skill);
|
|
9211
|
-
if (!kinds.includes(kind)) continue;
|
|
9212
|
-
const candidate = this.extractionResultToCandidate(result, trajectory);
|
|
9213
|
-
candidates.push(candidate);
|
|
8910
|
+
unregister(hookId) {
|
|
8911
|
+
const hook = this.hooks.get(hookId);
|
|
8912
|
+
if (!hook) return false;
|
|
8913
|
+
for (const event of hook.events) {
|
|
8914
|
+
this.eventIndex.get(event)?.delete(hookId);
|
|
9214
8915
|
}
|
|
9215
|
-
|
|
9216
|
-
|
|
9217
|
-
// Naive provider doesn't produce updates, demotions, or anti-patterns
|
|
9218
|
-
metadata: {
|
|
9219
|
-
trajectoriesAnalyzed: 1,
|
|
9220
|
-
durationMs: Date.now() - startTime
|
|
9221
|
-
}
|
|
9222
|
-
};
|
|
8916
|
+
this.hooks.delete(hookId);
|
|
8917
|
+
return true;
|
|
9223
8918
|
}
|
|
9224
8919
|
/**
|
|
9225
|
-
*
|
|
9226
|
-
* A more sophisticated provider could do cross-trajectory pattern detection.
|
|
8920
|
+
* Enable a hook
|
|
9227
8921
|
*/
|
|
9228
|
-
|
|
9229
|
-
const
|
|
9230
|
-
|
|
9231
|
-
|
|
9232
|
-
|
|
9233
|
-
allCandidates.push(...result.candidates);
|
|
9234
|
-
}
|
|
9235
|
-
const deduplicated = this.deduplicateCandidates(allCandidates);
|
|
9236
|
-
return {
|
|
9237
|
-
candidates: deduplicated,
|
|
9238
|
-
metadata: {
|
|
9239
|
-
trajectoriesAnalyzed: trajectories.length,
|
|
9240
|
-
durationMs: Date.now() - startTime
|
|
9241
|
-
}
|
|
9242
|
-
};
|
|
8922
|
+
enable(hookId) {
|
|
8923
|
+
const hook = this.hooks.get(hookId);
|
|
8924
|
+
if (!hook) return false;
|
|
8925
|
+
hook.enabled = true;
|
|
8926
|
+
return true;
|
|
9243
8927
|
}
|
|
9244
8928
|
/**
|
|
9245
|
-
*
|
|
8929
|
+
* Disable a hook
|
|
9246
8930
|
*/
|
|
9247
|
-
|
|
9248
|
-
|
|
9249
|
-
|
|
9250
|
-
|
|
9251
|
-
|
|
9252
|
-
for (const e of existing) {
|
|
9253
|
-
if (this.normalizeName(e.name) === normalizedName) {
|
|
9254
|
-
return true;
|
|
9255
|
-
}
|
|
9256
|
-
}
|
|
9257
|
-
return false;
|
|
8931
|
+
disable(hookId) {
|
|
8932
|
+
const hook = this.hooks.get(hookId);
|
|
8933
|
+
if (!hook) return false;
|
|
8934
|
+
hook.enabled = false;
|
|
8935
|
+
return true;
|
|
9258
8936
|
}
|
|
9259
8937
|
/**
|
|
9260
|
-
*
|
|
8938
|
+
* Get a hook by ID
|
|
9261
8939
|
*/
|
|
9262
|
-
|
|
9263
|
-
|
|
9264
|
-
const nameA = this.normalizeName(a.name);
|
|
9265
|
-
const nameB = this.normalizeName(b.name);
|
|
9266
|
-
const nameSimilarity = this.jaccardSimilarity(
|
|
9267
|
-
nameA.split("-"),
|
|
9268
|
-
nameB.split("-")
|
|
9269
|
-
);
|
|
9270
|
-
let contentSimilarity = 0;
|
|
9271
|
-
if (a.content.kind === "skill" && b.content.kind === "skill") {
|
|
9272
|
-
const aWords = this.tokenize(a.content.problem + " " + a.content.solution);
|
|
9273
|
-
const bWords = this.tokenize(b.content.problem + " " + b.content.solution);
|
|
9274
|
-
contentSimilarity = this.jaccardSimilarity(aWords, bWords);
|
|
9275
|
-
}
|
|
9276
|
-
return nameSimilarity * 0.3 + contentSimilarity * 0.7;
|
|
8940
|
+
get(hookId) {
|
|
8941
|
+
return this.hooks.get(hookId);
|
|
9277
8942
|
}
|
|
9278
|
-
// ==========================================================================
|
|
9279
|
-
// Private Methods
|
|
9280
|
-
// ==========================================================================
|
|
9281
8943
|
/**
|
|
9282
|
-
*
|
|
9283
|
-
*/
|
|
9284
|
-
extractionResultToCandidate(result, trajectory) {
|
|
9285
|
-
const skill = result.skill;
|
|
9286
|
-
const turnRange = result.sourceTrajectory.turnRange;
|
|
9287
|
-
return {
|
|
9288
|
-
kind: this.inferKind(skill),
|
|
9289
|
-
id: skill.id,
|
|
9290
|
-
name: skill.name,
|
|
9291
|
-
content: this.skillToContent(skill),
|
|
9292
|
-
confidence: result.confidence,
|
|
9293
|
-
attribution: this.computeAttribution(trajectory, turnRange),
|
|
9294
|
-
source: {
|
|
9295
|
-
provider: this.name,
|
|
9296
|
-
trajectoryId: trajectory.sessionId,
|
|
9297
|
-
turnRange,
|
|
9298
|
-
extractedAt: /* @__PURE__ */ new Date(),
|
|
9299
|
-
metadata: {
|
|
9300
|
-
gateResults: result.gateResults,
|
|
9301
|
-
extractionMode: this.config.llmProvider ? "automatic" : "manual"
|
|
9302
|
-
}
|
|
9303
|
-
},
|
|
9304
|
-
tags: skill.tags,
|
|
9305
|
-
reasoning: result.failureReason
|
|
9306
|
-
};
|
|
9307
|
-
}
|
|
9308
|
-
/**
|
|
9309
|
-
* Convert a Skill to LearningContent
|
|
9310
|
-
*/
|
|
9311
|
-
skillToContent(skill) {
|
|
9312
|
-
return {
|
|
9313
|
-
kind: "skill",
|
|
9314
|
-
problem: skill.problem,
|
|
9315
|
-
solution: skill.solution,
|
|
9316
|
-
verification: skill.verification,
|
|
9317
|
-
triggers: skill.triggerConditions.map(
|
|
9318
|
-
(t) => ({
|
|
9319
|
-
type: t.type,
|
|
9320
|
-
value: t.value,
|
|
9321
|
-
description: t.description
|
|
9322
|
-
})
|
|
9323
|
-
),
|
|
9324
|
-
examples: skill.examples.map(
|
|
9325
|
-
(e) => ({
|
|
9326
|
-
scenario: e.scenario,
|
|
9327
|
-
before: e.before,
|
|
9328
|
-
after: e.after
|
|
9329
|
-
})
|
|
9330
|
-
)
|
|
9331
|
-
};
|
|
9332
|
-
}
|
|
9333
|
-
/**
|
|
9334
|
-
* Infer the kind of learning from a skill
|
|
9335
|
-
*/
|
|
9336
|
-
inferKind(skill) {
|
|
9337
|
-
const hasErrorTriggers = skill.triggerConditions.some(
|
|
9338
|
-
(t) => t.type === "error"
|
|
9339
|
-
);
|
|
9340
|
-
if (hasErrorTriggers && skill.problem.toLowerCase().includes("error")) {
|
|
9341
|
-
return "error-fix";
|
|
9342
|
-
}
|
|
9343
|
-
if (skill.solution.toLowerCase().includes("approach") || skill.solution.toLowerCase().includes("strategy") || skill.solution.toLowerCase().includes("when you see")) {
|
|
9344
|
-
return "strategy";
|
|
9345
|
-
}
|
|
9346
|
-
return "skill";
|
|
9347
|
-
}
|
|
9348
|
-
/**
|
|
9349
|
-
* Compute step attribution using the configured strategy
|
|
9350
|
-
*/
|
|
9351
|
-
computeAttribution(trajectory, turnRange) {
|
|
9352
|
-
const [start, end] = turnRange;
|
|
9353
|
-
const turns = trajectory.turns.slice(start, end + 1);
|
|
9354
|
-
switch (this.config.creditStrategy) {
|
|
9355
|
-
case "simple":
|
|
9356
|
-
return this.simpleCredit(turns, start);
|
|
9357
|
-
case "uniform":
|
|
9358
|
-
return this.uniformCredit(turns, start);
|
|
9359
|
-
case "llm":
|
|
9360
|
-
return this.simpleCredit(turns, start);
|
|
9361
|
-
default:
|
|
9362
|
-
return this.simpleCredit(turns, start);
|
|
9363
|
-
}
|
|
9364
|
-
}
|
|
9365
|
-
/**
|
|
9366
|
-
* Simple credit assignment: exponential decay from end.
|
|
9367
|
-
* Last step gets most credit, earlier steps get less.
|
|
9368
|
-
*/
|
|
9369
|
-
simpleCredit(turns, startOffset) {
|
|
9370
|
-
const attributions = [];
|
|
9371
|
-
const n = turns.length;
|
|
9372
|
-
for (let i = 0; i < n; i++) {
|
|
9373
|
-
const turn = turns[i];
|
|
9374
|
-
if (turn.role === "system") continue;
|
|
9375
|
-
const distanceFromEnd = n - 1 - i;
|
|
9376
|
-
const score = Math.pow(0.7, distanceFromEnd);
|
|
9377
|
-
const hasToolCalls = turn.toolCalls && turn.toolCalls.length > 0;
|
|
9378
|
-
const boostedScore = hasToolCalls ? Math.min(1, score * 1.3) : score;
|
|
9379
|
-
attributions.push({
|
|
9380
|
-
turnIndex: startOffset + i,
|
|
9381
|
-
score: Math.round(boostedScore * 100) / 100,
|
|
9382
|
-
reasoning: this.getAttributionReasoning(turn, boostedScore)
|
|
9383
|
-
});
|
|
9384
|
-
}
|
|
9385
|
-
return attributions;
|
|
9386
|
-
}
|
|
9387
|
-
/**
|
|
9388
|
-
* Uniform credit assignment: all steps get equal credit.
|
|
9389
|
-
*/
|
|
9390
|
-
uniformCredit(turns, startOffset) {
|
|
9391
|
-
const nonSystemTurns = turns.filter((t) => t.role !== "system");
|
|
9392
|
-
const score = 1 / nonSystemTurns.length;
|
|
9393
|
-
return turns.map((turn, i) => {
|
|
9394
|
-
if (turn.role === "system") return null;
|
|
9395
|
-
return {
|
|
9396
|
-
turnIndex: startOffset + i,
|
|
9397
|
-
score: Math.round(score * 100) / 100
|
|
9398
|
-
};
|
|
9399
|
-
}).filter((a) => a !== null);
|
|
9400
|
-
}
|
|
9401
|
-
/**
|
|
9402
|
-
* Generate reasoning for attribution
|
|
9403
|
-
*/
|
|
9404
|
-
getAttributionReasoning(turn, score) {
|
|
9405
|
-
const reasons = [];
|
|
9406
|
-
if (score >= 0.8) {
|
|
9407
|
-
reasons.push("High impact (near end of solution)");
|
|
9408
|
-
} else if (score >= 0.5) {
|
|
9409
|
-
reasons.push("Medium impact");
|
|
9410
|
-
} else {
|
|
9411
|
-
reasons.push("Lower impact (early in trajectory)");
|
|
9412
|
-
}
|
|
9413
|
-
if (turn.toolCalls && turn.toolCalls.length > 0) {
|
|
9414
|
-
const toolNames = turn.toolCalls.map((t) => t.name).join(", ");
|
|
9415
|
-
reasons.push(`Used tools: ${toolNames}`);
|
|
9416
|
-
}
|
|
9417
|
-
if (turn.toolResults?.some((r) => !r.success)) {
|
|
9418
|
-
reasons.push("Encountered and handled errors");
|
|
9419
|
-
}
|
|
9420
|
-
return reasons.join(". ");
|
|
9421
|
-
}
|
|
9422
|
-
/**
|
|
9423
|
-
* Deduplicate candidates by ID
|
|
9424
|
-
*/
|
|
9425
|
-
deduplicateCandidates(candidates) {
|
|
9426
|
-
const seen = /* @__PURE__ */ new Map();
|
|
9427
|
-
for (const candidate of candidates) {
|
|
9428
|
-
const existing = seen.get(candidate.id);
|
|
9429
|
-
if (!existing || candidate.confidence > existing.confidence) {
|
|
9430
|
-
seen.set(candidate.id, candidate);
|
|
9431
|
-
}
|
|
9432
|
-
}
|
|
9433
|
-
return Array.from(seen.values());
|
|
9434
|
-
}
|
|
9435
|
-
/**
|
|
9436
|
-
* Normalize a name for comparison
|
|
9437
|
-
*/
|
|
9438
|
-
normalizeName(name) {
|
|
9439
|
-
return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
9440
|
-
}
|
|
9441
|
-
/**
|
|
9442
|
-
* Tokenize text into words
|
|
9443
|
-
*/
|
|
9444
|
-
tokenize(text) {
|
|
9445
|
-
return text.toLowerCase().split(/\W+/).filter((w) => w.length > 2);
|
|
9446
|
-
}
|
|
9447
|
-
/**
|
|
9448
|
-
* Compute Jaccard similarity between two arrays
|
|
9449
|
-
*/
|
|
9450
|
-
jaccardSimilarity(a, b) {
|
|
9451
|
-
const setA = new Set(a);
|
|
9452
|
-
const setB = new Set(b);
|
|
9453
|
-
const intersection = new Set([...setA].filter((x) => setB.has(x)));
|
|
9454
|
-
const union = /* @__PURE__ */ new Set([...setA, ...setB]);
|
|
9455
|
-
return union.size === 0 ? 0 : intersection.size / union.size;
|
|
9456
|
-
}
|
|
9457
|
-
};
|
|
9458
|
-
function createNaiveProvider(config) {
|
|
9459
|
-
return new NaiveLearningProvider(config);
|
|
9460
|
-
}
|
|
9461
|
-
|
|
9462
|
-
// src/hooks/registry.ts
|
|
9463
|
-
var import_crypto = require("crypto");
|
|
9464
|
-
var PRIORITY_ORDER = {
|
|
9465
|
-
high: 0,
|
|
9466
|
-
normal: 1,
|
|
9467
|
-
low: 2
|
|
9468
|
-
};
|
|
9469
|
-
var HookRegistry = class {
|
|
9470
|
-
constructor() {
|
|
9471
|
-
this.hooks = /* @__PURE__ */ new Map();
|
|
9472
|
-
this.eventIndex = /* @__PURE__ */ new Map();
|
|
9473
|
-
}
|
|
9474
|
-
/**
|
|
9475
|
-
* Register a new hook
|
|
9476
|
-
*/
|
|
9477
|
-
register(options) {
|
|
9478
|
-
const id = (0, import_crypto.randomUUID)();
|
|
9479
|
-
const events = Array.isArray(options.events) ? options.events : [options.events];
|
|
9480
|
-
const hook = {
|
|
9481
|
-
id,
|
|
9482
|
-
name: options.name,
|
|
9483
|
-
events,
|
|
9484
|
-
handler: options.handler,
|
|
9485
|
-
priority: options.priority || "normal",
|
|
9486
|
-
enabled: options.enabled !== false,
|
|
9487
|
-
filter: options.filter
|
|
9488
|
-
};
|
|
9489
|
-
this.hooks.set(id, hook);
|
|
9490
|
-
for (const event of events) {
|
|
9491
|
-
if (!this.eventIndex.has(event)) {
|
|
9492
|
-
this.eventIndex.set(event, /* @__PURE__ */ new Set());
|
|
9493
|
-
}
|
|
9494
|
-
this.eventIndex.get(event).add(id);
|
|
9495
|
-
}
|
|
9496
|
-
return id;
|
|
9497
|
-
}
|
|
9498
|
-
/**
|
|
9499
|
-
* Unregister a hook
|
|
9500
|
-
*/
|
|
9501
|
-
unregister(hookId) {
|
|
9502
|
-
const hook = this.hooks.get(hookId);
|
|
9503
|
-
if (!hook) return false;
|
|
9504
|
-
for (const event of hook.events) {
|
|
9505
|
-
this.eventIndex.get(event)?.delete(hookId);
|
|
9506
|
-
}
|
|
9507
|
-
this.hooks.delete(hookId);
|
|
9508
|
-
return true;
|
|
9509
|
-
}
|
|
9510
|
-
/**
|
|
9511
|
-
* Enable a hook
|
|
9512
|
-
*/
|
|
9513
|
-
enable(hookId) {
|
|
9514
|
-
const hook = this.hooks.get(hookId);
|
|
9515
|
-
if (!hook) return false;
|
|
9516
|
-
hook.enabled = true;
|
|
9517
|
-
return true;
|
|
9518
|
-
}
|
|
9519
|
-
/**
|
|
9520
|
-
* Disable a hook
|
|
9521
|
-
*/
|
|
9522
|
-
disable(hookId) {
|
|
9523
|
-
const hook = this.hooks.get(hookId);
|
|
9524
|
-
if (!hook) return false;
|
|
9525
|
-
hook.enabled = false;
|
|
9526
|
-
return true;
|
|
9527
|
-
}
|
|
9528
|
-
/**
|
|
9529
|
-
* Get a hook by ID
|
|
9530
|
-
*/
|
|
9531
|
-
get(hookId) {
|
|
9532
|
-
return this.hooks.get(hookId);
|
|
9533
|
-
}
|
|
9534
|
-
/**
|
|
9535
|
-
* List all registered hooks
|
|
8944
|
+
* List all registered hooks
|
|
9536
8945
|
*/
|
|
9537
8946
|
list() {
|
|
9538
8947
|
return Array.from(this.hooks.values());
|
|
@@ -9931,10 +9340,6 @@ var SkillBank = class {
|
|
|
9931
9340
|
this.eventHandlers = [];
|
|
9932
9341
|
this.initialized = false;
|
|
9933
9342
|
this.autoIndexOnInit = false;
|
|
9934
|
-
/** Learning providers for meta-learning integration */
|
|
9935
|
-
this.learningProviders = /* @__PURE__ */ new Map();
|
|
9936
|
-
/** Anti-patterns stored separately as metadata */
|
|
9937
|
-
this.antiPatterns = /* @__PURE__ */ new Map();
|
|
9938
9343
|
/** Validation mode: advisory (non-blocking) or blocking */
|
|
9939
9344
|
this.validationMode = "advisory";
|
|
9940
9345
|
/** Whether validation is enabled */
|
|
@@ -9972,11 +9377,6 @@ var SkillBank = class {
|
|
|
9972
9377
|
similarityThreshold: config.matching?.similarityThreshold
|
|
9973
9378
|
});
|
|
9974
9379
|
this.autoIndexOnInit = config.matching?.autoIndex ?? false;
|
|
9975
|
-
const naiveProvider = new NaiveLearningProvider({
|
|
9976
|
-
llmProvider: config.llmProvider,
|
|
9977
|
-
minConfidence: config.minExtractionConfidence
|
|
9978
|
-
});
|
|
9979
|
-
this.learningProviders.set(naiveProvider.name, naiveProvider);
|
|
9980
9380
|
if (config.namespace) {
|
|
9981
9381
|
this.namespaceConfig = {
|
|
9982
9382
|
agentId: config.namespace.agentId,
|
|
@@ -10004,11 +9404,6 @@ var SkillBank = class {
|
|
|
10004
9404
|
*/
|
|
10005
9405
|
async initialize() {
|
|
10006
9406
|
await this.storage.initialize();
|
|
10007
|
-
for (const provider of this.learningProviders.values()) {
|
|
10008
|
-
if (provider.initialize) {
|
|
10009
|
-
await provider.initialize();
|
|
10010
|
-
}
|
|
10011
|
-
}
|
|
10012
9407
|
if (this.validator) {
|
|
10013
9408
|
this.validator.setStorage(this.storage);
|
|
10014
9409
|
}
|
|
@@ -10021,11 +9416,6 @@ var SkillBank = class {
|
|
|
10021
9416
|
* Shutdown the skill bank cleanly
|
|
10022
9417
|
*/
|
|
10023
9418
|
async shutdown() {
|
|
10024
|
-
for (const provider of this.learningProviders.values()) {
|
|
10025
|
-
if (provider.shutdown) {
|
|
10026
|
-
await provider.shutdown();
|
|
10027
|
-
}
|
|
10028
|
-
}
|
|
10029
9419
|
}
|
|
10030
9420
|
/**
|
|
10031
9421
|
* Ensure initialized before operations
|
|
@@ -10127,625 +9517,62 @@ var SkillBank = class {
|
|
|
10127
9517
|
this.emit({ type: "extraction:started", sessionId: trajectory.sessionId });
|
|
10128
9518
|
const results = await this.automaticExtractor.extract(trajectory, options);
|
|
10129
9519
|
for (const result of results) {
|
|
10130
|
-
if (result.success && result.skill) {
|
|
10131
|
-
const duplicate = await this.findSemanticDuplicate(result.skill);
|
|
10132
|
-
if (duplicate) {
|
|
10133
|
-
result.success = false;
|
|
10134
|
-
result.failureReason = `Duplicate of existing skill: ${duplicate.skill.id} (similarity: ${duplicate.similarity.toFixed(2)})`;
|
|
10135
|
-
} else {
|
|
10136
|
-
await this.storage.saveSkill(result.skill);
|
|
10137
|
-
this.emit({ type: "skill:created", skill: result.skill });
|
|
10138
|
-
}
|
|
10139
|
-
}
|
|
10140
|
-
this.emit({ type: "extraction:completed", result });
|
|
10141
|
-
}
|
|
10142
|
-
return results;
|
|
10143
|
-
}
|
|
10144
|
-
/**
|
|
10145
|
-
* Unified extraction entry point.
|
|
10146
|
-
*
|
|
10147
|
-
* Supports both manual (targeted) and automatic (LLM-driven) extraction
|
|
10148
|
-
* from a Trajectory. Use this instead of calling extractManual/extractAutomatic
|
|
10149
|
-
* directly.
|
|
10150
|
-
*
|
|
10151
|
-
* @example
|
|
10152
|
-
* ```typescript
|
|
10153
|
-
* // Manual extraction with defaults
|
|
10154
|
-
* const results = await bank.extract(trajectory);
|
|
10155
|
-
*
|
|
10156
|
-
* // Automatic extraction
|
|
10157
|
-
* const results = await bank.extract(trajectory, { mode: 'automatic' });
|
|
10158
|
-
*
|
|
10159
|
-
* // Manual with specific turn range
|
|
10160
|
-
* const results = await bank.extract(trajectory, {
|
|
10161
|
-
* mode: 'manual',
|
|
10162
|
-
* turnRange: [0, 5],
|
|
10163
|
-
* suggestedName: 'fix-auth-error',
|
|
10164
|
-
* });
|
|
10165
|
-
* ```
|
|
10166
|
-
*/
|
|
10167
|
-
async extract(trajectory, options) {
|
|
10168
|
-
if (options?.mode === "automatic") {
|
|
10169
|
-
return this.extractAutomatic(trajectory, options);
|
|
10170
|
-
}
|
|
10171
|
-
const result = await this.extractManual(trajectory, options);
|
|
10172
|
-
return [result];
|
|
10173
|
-
}
|
|
10174
|
-
/**
|
|
10175
|
-
* Extract from raw session content (convenience method)
|
|
10176
|
-
*/
|
|
10177
|
-
async extractFromSession(content, options) {
|
|
10178
|
-
const trajectory = await this.parseSession(content, options?.adapterName);
|
|
10179
|
-
return this.extract(trajectory, options);
|
|
10180
|
-
}
|
|
10181
|
-
/**
|
|
10182
|
-
* Set LLM provider for automatic extraction
|
|
10183
|
-
*/
|
|
10184
|
-
setLLMProvider(provider) {
|
|
10185
|
-
this.automaticExtractor.setLLMProvider(provider);
|
|
10186
|
-
const naiveProvider = this.learningProviders.get("naive");
|
|
10187
|
-
if (naiveProvider && "setLLMProvider" in naiveProvider) {
|
|
10188
|
-
naiveProvider.setLLMProvider(provider);
|
|
10189
|
-
}
|
|
10190
|
-
}
|
|
10191
|
-
// ==========================================================================
|
|
10192
|
-
// Learning Providers (Meta-learning Integration)
|
|
10193
|
-
// ==========================================================================
|
|
10194
|
-
/**
|
|
10195
|
-
* Register a learning provider.
|
|
10196
|
-
* Learning providers analyze trajectories and produce learning candidates.
|
|
10197
|
-
* Use this to integrate external learning engines like cognitive-core.
|
|
10198
|
-
*/
|
|
10199
|
-
async registerLearningProvider(provider) {
|
|
10200
|
-
if (provider.initialize) {
|
|
10201
|
-
await provider.initialize();
|
|
10202
|
-
}
|
|
10203
|
-
this.learningProviders.set(provider.name, provider);
|
|
10204
|
-
}
|
|
10205
|
-
/**
|
|
10206
|
-
* Get a registered learning provider by name
|
|
10207
|
-
*/
|
|
10208
|
-
getLearningProvider(name) {
|
|
10209
|
-
return this.learningProviders.get(name);
|
|
10210
|
-
}
|
|
10211
|
-
/**
|
|
10212
|
-
* List all registered learning providers
|
|
10213
|
-
*/
|
|
10214
|
-
listLearningProviders() {
|
|
10215
|
-
return Array.from(this.learningProviders.values());
|
|
10216
|
-
}
|
|
10217
|
-
/**
|
|
10218
|
-
* Learn from a trajectory using a learning provider.
|
|
10219
|
-
* This is the primary integration point for meta-learning engines.
|
|
10220
|
-
*
|
|
10221
|
-
* For accumulating providers, this may not return immediate results.
|
|
10222
|
-
* Use flushProviders() to force extraction from accumulated trajectories.
|
|
10223
|
-
*/
|
|
10224
|
-
async learnFrom(trajectory, options) {
|
|
10225
|
-
this.ensureInitialized();
|
|
10226
|
-
const providerName = options?.provider ?? "naive";
|
|
10227
|
-
const provider = this.learningProviders.get(providerName);
|
|
10228
|
-
if (!provider) {
|
|
10229
|
-
throw new Error(
|
|
10230
|
-
`Learning provider not found: ${providerName}. Available: ${Array.from(this.learningProviders.keys()).join(", ")}`
|
|
10231
|
-
);
|
|
10232
|
-
}
|
|
10233
|
-
const result = await provider.analyze(trajectory, options);
|
|
10234
|
-
return this.processAnalyzeResult(result);
|
|
10235
|
-
}
|
|
10236
|
-
/**
|
|
10237
|
-
* Learn from multiple trajectories.
|
|
10238
|
-
* Providers that support batch analysis can find cross-trajectory patterns.
|
|
10239
|
-
*/
|
|
10240
|
-
async learnFromBatch(trajectories, options) {
|
|
10241
|
-
this.ensureInitialized();
|
|
10242
|
-
const providerName = options?.provider ?? "naive";
|
|
10243
|
-
const provider = this.learningProviders.get(providerName);
|
|
10244
|
-
if (!provider) {
|
|
10245
|
-
throw new Error(`Learning provider not found: ${providerName}`);
|
|
10246
|
-
}
|
|
10247
|
-
let result;
|
|
10248
|
-
if (provider.analyzeBatch) {
|
|
10249
|
-
result = await provider.analyzeBatch(trajectories, options);
|
|
10250
|
-
} else {
|
|
10251
|
-
const candidates = [];
|
|
10252
|
-
const updates = [];
|
|
10253
|
-
const demotions = [];
|
|
10254
|
-
const antiPatterns = [];
|
|
10255
|
-
let totalDuration = 0;
|
|
10256
|
-
for (const trajectory of trajectories) {
|
|
10257
|
-
const r = await provider.analyze(trajectory, options);
|
|
10258
|
-
candidates.push(...r.candidates);
|
|
10259
|
-
if (r.updates) updates.push(...r.updates);
|
|
10260
|
-
if (r.demotions) demotions.push(...r.demotions);
|
|
10261
|
-
if (r.antiPatterns) antiPatterns.push(...r.antiPatterns);
|
|
10262
|
-
totalDuration += r.metadata.durationMs;
|
|
10263
|
-
}
|
|
10264
|
-
result = {
|
|
10265
|
-
candidates,
|
|
10266
|
-
updates: updates.length > 0 ? updates : void 0,
|
|
10267
|
-
demotions: demotions.length > 0 ? demotions : void 0,
|
|
10268
|
-
antiPatterns: antiPatterns.length > 0 ? antiPatterns : void 0,
|
|
10269
|
-
metadata: {
|
|
10270
|
-
trajectoriesAnalyzed: trajectories.length,
|
|
10271
|
-
durationMs: totalDuration
|
|
10272
|
-
}
|
|
10273
|
-
};
|
|
10274
|
-
}
|
|
10275
|
-
return this.processAnalyzeResult(result);
|
|
10276
|
-
}
|
|
10277
|
-
/**
|
|
10278
|
-
* Force extraction from all accumulating providers.
|
|
10279
|
-
*/
|
|
10280
|
-
async flushProviders() {
|
|
10281
|
-
this.ensureInitialized();
|
|
10282
|
-
const mergedResult = {
|
|
10283
|
-
skillsCreated: 0,
|
|
10284
|
-
skillsUpdated: 0,
|
|
10285
|
-
skillsDemoted: 0,
|
|
10286
|
-
antiPatternsAdded: 0,
|
|
10287
|
-
createdSkillIds: [],
|
|
10288
|
-
updatedSkillIds: []
|
|
10289
|
-
};
|
|
10290
|
-
for (const provider of this.learningProviders.values()) {
|
|
10291
|
-
if (provider.capabilities.accumulating && provider.flush) {
|
|
10292
|
-
const result = await provider.flush();
|
|
10293
|
-
const processed = await this.processAnalyzeResult(result);
|
|
10294
|
-
mergedResult.skillsCreated += processed.skillsCreated;
|
|
10295
|
-
mergedResult.skillsUpdated += processed.skillsUpdated;
|
|
10296
|
-
mergedResult.skillsDemoted += processed.skillsDemoted;
|
|
10297
|
-
mergedResult.antiPatternsAdded += processed.antiPatternsAdded;
|
|
10298
|
-
mergedResult.createdSkillIds.push(...processed.createdSkillIds);
|
|
10299
|
-
mergedResult.updatedSkillIds.push(...processed.updatedSkillIds);
|
|
10300
|
-
}
|
|
10301
|
-
}
|
|
10302
|
-
return mergedResult;
|
|
10303
|
-
}
|
|
10304
|
-
/**
|
|
10305
|
-
* Record outcome when a skill is applied.
|
|
10306
|
-
* Provider updates internal state and returns updates for SkillBank.
|
|
10307
|
-
*/
|
|
10308
|
-
async recordOutcome(feedback, providerName) {
|
|
10309
|
-
this.ensureInitialized();
|
|
10310
|
-
const skill = await this.storage.getSkill(feedback.candidateId);
|
|
10311
|
-
if (skill) {
|
|
10312
|
-
skill.metrics.usageCount++;
|
|
10313
|
-
if (feedback.success) {
|
|
10314
|
-
const totalUses = skill.metrics.usageCount;
|
|
10315
|
-
const currentSuccesses = skill.metrics.successRate * (totalUses - 1);
|
|
10316
|
-
skill.metrics.successRate = (currentSuccesses + 1) / totalUses;
|
|
10317
|
-
} else {
|
|
10318
|
-
const totalUses = skill.metrics.usageCount;
|
|
10319
|
-
const currentSuccesses = skill.metrics.successRate * (totalUses - 1);
|
|
10320
|
-
skill.metrics.successRate = currentSuccesses / totalUses;
|
|
10321
|
-
}
|
|
10322
|
-
skill.metrics.lastUsed = /* @__PURE__ */ new Date();
|
|
10323
|
-
await this.storage.saveSkill(skill);
|
|
10324
|
-
}
|
|
10325
|
-
const providersToNotify = providerName ? [this.learningProviders.get(providerName)].filter(Boolean) : Array.from(this.learningProviders.values());
|
|
10326
|
-
for (const provider of providersToNotify) {
|
|
10327
|
-
if (provider.capabilities.feedbackEnabled && provider.recordOutcome) {
|
|
10328
|
-
const result = await provider.recordOutcome(feedback);
|
|
10329
|
-
if (result.updates) {
|
|
10330
|
-
for (const update of result.updates) {
|
|
10331
|
-
await this.applyUpdate(update);
|
|
10332
|
-
}
|
|
10333
|
-
}
|
|
10334
|
-
if (result.antiPatterns) {
|
|
10335
|
-
for (const ap of result.antiPatterns) {
|
|
10336
|
-
await this.addAntiPattern(ap);
|
|
10337
|
-
}
|
|
10338
|
-
}
|
|
10339
|
-
}
|
|
10340
|
-
}
|
|
10341
|
-
}
|
|
10342
|
-
/**
|
|
10343
|
-
* Process an AnalyzeResult: store candidates, apply updates, etc.
|
|
10344
|
-
*/
|
|
10345
|
-
async processAnalyzeResult(result) {
|
|
10346
|
-
const learnResult = {
|
|
10347
|
-
skillsCreated: 0,
|
|
10348
|
-
skillsUpdated: 0,
|
|
10349
|
-
skillsDemoted: 0,
|
|
10350
|
-
antiPatternsAdded: 0,
|
|
10351
|
-
providerState: result.providerState,
|
|
10352
|
-
createdSkillIds: [],
|
|
10353
|
-
updatedSkillIds: []
|
|
10354
|
-
};
|
|
10355
|
-
for (const candidate of result.candidates) {
|
|
10356
|
-
if (candidate.content.kind === "skill") {
|
|
10357
|
-
const skill = await this.promoteToSkill(candidate);
|
|
10358
|
-
learnResult.skillsCreated++;
|
|
10359
|
-
learnResult.createdSkillIds.push(skill.id);
|
|
10360
|
-
} else {
|
|
10361
|
-
await this.storeCandidateForReview(candidate);
|
|
10362
|
-
}
|
|
10363
|
-
}
|
|
10364
|
-
if (result.updates) {
|
|
10365
|
-
for (const update of result.updates) {
|
|
10366
|
-
const updated = await this.applyUpdate(update);
|
|
10367
|
-
if (updated) {
|
|
10368
|
-
learnResult.skillsUpdated++;
|
|
10369
|
-
learnResult.updatedSkillIds.push(update.candidateId);
|
|
10370
|
-
}
|
|
10371
|
-
}
|
|
10372
|
-
}
|
|
10373
|
-
if (result.demotions) {
|
|
10374
|
-
for (const demotion of result.demotions) {
|
|
10375
|
-
await this.applyDemotion(demotion);
|
|
10376
|
-
learnResult.skillsDemoted++;
|
|
10377
|
-
}
|
|
10378
|
-
}
|
|
10379
|
-
if (result.antiPatterns) {
|
|
10380
|
-
for (const ap of result.antiPatterns) {
|
|
10381
|
-
await this.addAntiPattern(ap);
|
|
10382
|
-
learnResult.antiPatternsAdded++;
|
|
10383
|
-
}
|
|
10384
|
-
}
|
|
10385
|
-
return learnResult;
|
|
10386
|
-
}
|
|
10387
|
-
/**
|
|
10388
|
-
* Store a non-skill candidate for later review
|
|
10389
|
-
*/
|
|
10390
|
-
async storeCandidateForReview(candidate) {
|
|
10391
|
-
if (!this.storage.saveCandidate) {
|
|
10392
|
-
return;
|
|
10393
|
-
}
|
|
10394
|
-
const record = {
|
|
10395
|
-
id: candidate.id,
|
|
10396
|
-
kind: candidate.kind,
|
|
10397
|
-
name: candidate.name,
|
|
10398
|
-
content: candidate.content,
|
|
10399
|
-
confidence: candidate.confidence,
|
|
10400
|
-
source: {
|
|
10401
|
-
trajectoryId: candidate.source.trajectoryId,
|
|
10402
|
-
provider: candidate.source.provider,
|
|
10403
|
-
extractedAt: candidate.source.extractedAt,
|
|
10404
|
-
turnRange: candidate.source.turnRange
|
|
10405
|
-
},
|
|
10406
|
-
tags: candidate.tags,
|
|
10407
|
-
reasoning: candidate.reasoning,
|
|
10408
|
-
createdAt: /* @__PURE__ */ new Date(),
|
|
10409
|
-
updatedAt: /* @__PURE__ */ new Date(),
|
|
10410
|
-
status: "pending"
|
|
10411
|
-
};
|
|
10412
|
-
await this.storage.saveCandidate(record);
|
|
10413
|
-
}
|
|
10414
|
-
/**
|
|
10415
|
-
* Apply an update to an existing skill
|
|
10416
|
-
*/
|
|
10417
|
-
async applyUpdate(update) {
|
|
10418
|
-
const skill = await this.storage.getSkill(update.candidateId);
|
|
10419
|
-
if (!skill) return false;
|
|
10420
|
-
let modified = false;
|
|
10421
|
-
if (update.addTrigger) {
|
|
10422
|
-
const exists = skill.triggerConditions.some(
|
|
10423
|
-
(t) => t.type === update.addTrigger.type && t.value === update.addTrigger.value
|
|
10424
|
-
);
|
|
10425
|
-
if (!exists) {
|
|
10426
|
-
skill.triggerConditions.push({
|
|
10427
|
-
type: update.addTrigger.type,
|
|
10428
|
-
value: update.addTrigger.value,
|
|
10429
|
-
description: update.addTrigger.description
|
|
10430
|
-
});
|
|
10431
|
-
modified = true;
|
|
10432
|
-
}
|
|
10433
|
-
}
|
|
10434
|
-
if (update.refinement) {
|
|
10435
|
-
const refinementNote = `[${update.refinement.source}] ${update.refinement.context}: ${update.refinement.addition}`;
|
|
10436
|
-
skill.notes = skill.notes ? `${skill.notes}
|
|
10437
|
-
${refinementNote}` : refinementNote;
|
|
10438
|
-
modified = true;
|
|
10439
|
-
}
|
|
10440
|
-
if (update.confidenceAdjustment) {
|
|
10441
|
-
skill.metrics.successRate = Math.max(
|
|
10442
|
-
0,
|
|
10443
|
-
Math.min(1, skill.metrics.successRate + update.confidenceAdjustment)
|
|
10444
|
-
);
|
|
10445
|
-
modified = true;
|
|
10446
|
-
}
|
|
10447
|
-
if (update.incrementSuccess || update.incrementFailure) {
|
|
10448
|
-
skill.metrics.usageCount++;
|
|
10449
|
-
if (update.incrementSuccess) {
|
|
10450
|
-
const total = skill.metrics.usageCount;
|
|
10451
|
-
const currentSuccesses = skill.metrics.successRate * (total - 1);
|
|
10452
|
-
skill.metrics.successRate = (currentSuccesses + 1) / total;
|
|
10453
|
-
}
|
|
10454
|
-
modified = true;
|
|
10455
|
-
}
|
|
10456
|
-
if (modified) {
|
|
10457
|
-
skill.updatedAt = /* @__PURE__ */ new Date();
|
|
10458
|
-
await this.storage.saveSkill(skill);
|
|
10459
|
-
this.emit({ type: "skill:updated", skill, previousVersion: skill.version });
|
|
10460
|
-
}
|
|
10461
|
-
return modified;
|
|
10462
|
-
}
|
|
10463
|
-
/**
|
|
10464
|
-
* Apply a demotion to an existing skill
|
|
10465
|
-
*/
|
|
10466
|
-
async applyDemotion(demotion) {
|
|
10467
|
-
const skill = await this.storage.getSkill(demotion.candidateId);
|
|
10468
|
-
if (!skill) return;
|
|
10469
|
-
skill.metrics.successRate = demotion.newConfidence;
|
|
10470
|
-
if (demotion.deprecate) {
|
|
10471
|
-
skill.status = "deprecated";
|
|
10472
|
-
this.emit({ type: "skill:deprecated", skillId: skill.id });
|
|
10473
|
-
}
|
|
10474
|
-
skill.notes = skill.notes ? `${skill.notes}
|
|
10475
|
-
[demotion] ${demotion.reason}` : `[demotion] ${demotion.reason}`;
|
|
10476
|
-
skill.updatedAt = /* @__PURE__ */ new Date();
|
|
10477
|
-
await this.storage.saveSkill(skill);
|
|
10478
|
-
}
|
|
10479
|
-
// ==========================================================================
|
|
10480
|
-
// Anti-Pattern Management
|
|
10481
|
-
// ==========================================================================
|
|
10482
|
-
/**
|
|
10483
|
-
* Get anti-patterns for a skill
|
|
10484
|
-
*/
|
|
10485
|
-
async getAntiPatterns(skillId) {
|
|
10486
|
-
return this.antiPatterns.get(skillId) ?? [];
|
|
10487
|
-
}
|
|
10488
|
-
/**
|
|
10489
|
-
* Add an anti-pattern
|
|
10490
|
-
*/
|
|
10491
|
-
async addAntiPattern(antiPattern) {
|
|
10492
|
-
const existing = this.antiPatterns.get(antiPattern.candidateId) ?? [];
|
|
10493
|
-
existing.push(antiPattern);
|
|
10494
|
-
this.antiPatterns.set(antiPattern.candidateId, existing);
|
|
10495
|
-
if (this.storage.saveAntiPatterns) {
|
|
10496
|
-
const records = existing.map((ap) => ({
|
|
10497
|
-
id: ap.id,
|
|
10498
|
-
pattern: ap.pattern,
|
|
10499
|
-
description: ap.reason,
|
|
10500
|
-
context: ap.discoveredFrom,
|
|
10501
|
-
severity: "warning",
|
|
10502
|
-
learnedAt: ap.createdAt,
|
|
10503
|
-
occurrences: 1
|
|
10504
|
-
}));
|
|
10505
|
-
await this.storage.saveAntiPatterns(antiPattern.candidateId, records);
|
|
10506
|
-
}
|
|
10507
|
-
}
|
|
10508
|
-
/**
|
|
10509
|
-
* Remove an anti-pattern by ID
|
|
10510
|
-
*/
|
|
10511
|
-
async removeAntiPattern(antiPatternId) {
|
|
10512
|
-
for (const [skillId, patterns] of this.antiPatterns.entries()) {
|
|
10513
|
-
const index = patterns.findIndex((p) => p.id === antiPatternId);
|
|
10514
|
-
if (index >= 0) {
|
|
10515
|
-
patterns.splice(index, 1);
|
|
10516
|
-
if (patterns.length === 0) {
|
|
10517
|
-
this.antiPatterns.delete(skillId);
|
|
10518
|
-
}
|
|
10519
|
-
return true;
|
|
10520
|
-
}
|
|
10521
|
-
}
|
|
10522
|
-
return false;
|
|
10523
|
-
}
|
|
10524
|
-
// ==========================================================================
|
|
10525
|
-
// Candidate Lifecycle Management
|
|
10526
|
-
// ==========================================================================
|
|
10527
|
-
/**
|
|
10528
|
-
* List pending learning candidates for review
|
|
10529
|
-
*/
|
|
10530
|
-
async listCandidates(filter) {
|
|
10531
|
-
this.ensureInitialized();
|
|
10532
|
-
if (!this.storage.listCandidates) {
|
|
10533
|
-
return [];
|
|
10534
|
-
}
|
|
10535
|
-
return this.storage.listCandidates(filter);
|
|
10536
|
-
}
|
|
10537
|
-
/**
|
|
10538
|
-
* Get a specific candidate by ID
|
|
10539
|
-
*/
|
|
10540
|
-
async getCandidate(id) {
|
|
10541
|
-
this.ensureInitialized();
|
|
10542
|
-
if (!this.storage.getCandidate) {
|
|
10543
|
-
return null;
|
|
10544
|
-
}
|
|
10545
|
-
return this.storage.getCandidate(id);
|
|
10546
|
-
}
|
|
10547
|
-
/**
|
|
10548
|
-
* Promote a candidate to a skill
|
|
10549
|
-
* Works for strategy, pattern, and error-fix candidates that were stored for review
|
|
10550
|
-
*/
|
|
10551
|
-
async promoteCandidate(candidateId) {
|
|
10552
|
-
this.ensureInitialized();
|
|
10553
|
-
if (!this.storage.getCandidate || !this.storage.updateCandidateStatus) {
|
|
10554
|
-
throw new Error("Storage does not support candidate operations");
|
|
10555
|
-
}
|
|
10556
|
-
const record = await this.storage.getCandidate(candidateId);
|
|
10557
|
-
if (!record) return null;
|
|
10558
|
-
if (record.status !== "pending") {
|
|
10559
|
-
throw new Error(`Cannot promote candidate with status: ${record.status}`);
|
|
10560
|
-
}
|
|
10561
|
-
const candidate = {
|
|
10562
|
-
id: record.id,
|
|
10563
|
-
kind: record.kind,
|
|
10564
|
-
name: record.name,
|
|
10565
|
-
content: record.content,
|
|
10566
|
-
confidence: record.confidence,
|
|
10567
|
-
source: {
|
|
10568
|
-
provider: record.source.provider,
|
|
10569
|
-
trajectoryId: record.source.trajectoryId,
|
|
10570
|
-
extractedAt: record.source.extractedAt,
|
|
10571
|
-
turnRange: record.source.turnRange ?? [0, 0]
|
|
10572
|
-
},
|
|
10573
|
-
tags: record.tags,
|
|
10574
|
-
reasoning: record.reasoning
|
|
10575
|
-
};
|
|
10576
|
-
const skill = await this.promoteToSkill(candidate);
|
|
10577
|
-
await this.storage.updateCandidateStatus(candidateId, "promoted", {
|
|
10578
|
-
promotedToSkillId: skill.id
|
|
10579
|
-
});
|
|
10580
|
-
return skill;
|
|
10581
|
-
}
|
|
10582
|
-
/**
|
|
10583
|
-
* Reject a candidate with a reason
|
|
10584
|
-
*/
|
|
10585
|
-
async rejectCandidate(candidateId, reason) {
|
|
10586
|
-
this.ensureInitialized();
|
|
10587
|
-
if (!this.storage.updateCandidateStatus) {
|
|
10588
|
-
throw new Error("Storage does not support candidate operations");
|
|
10589
|
-
}
|
|
10590
|
-
return this.storage.updateCandidateStatus(candidateId, "rejected", {
|
|
10591
|
-
rejectionReason: reason
|
|
10592
|
-
});
|
|
10593
|
-
}
|
|
10594
|
-
/**
|
|
10595
|
-
* Delete a candidate
|
|
10596
|
-
*/
|
|
10597
|
-
async deleteCandidate(candidateId) {
|
|
10598
|
-
this.ensureInitialized();
|
|
10599
|
-
if (!this.storage.deleteCandidate) {
|
|
10600
|
-
return false;
|
|
10601
|
-
}
|
|
10602
|
-
return this.storage.deleteCandidate(candidateId);
|
|
10603
|
-
}
|
|
10604
|
-
/**
|
|
10605
|
-
* Find skills with anti-pattern awareness
|
|
10606
|
-
*/
|
|
10607
|
-
async findSkillsWithAntiPatterns(query, options) {
|
|
10608
|
-
this.ensureInitialized();
|
|
10609
|
-
const skills = await this.storage.listSkills({ status: ["active"] });
|
|
10610
|
-
const matches = await this.semanticMatcher.findMatches(query, skills, {
|
|
10611
|
-
threshold: options?.minSimilarity,
|
|
10612
|
-
maxResults: options?.maxResults
|
|
10613
|
-
});
|
|
10614
|
-
const results = [];
|
|
10615
|
-
for (const match of matches) {
|
|
10616
|
-
const skillAntiPatterns = await this.getAntiPatterns(match.skill.id);
|
|
10617
|
-
const warnings = [];
|
|
10618
|
-
let relevantAntiPatterns;
|
|
10619
|
-
if (options?.context && skillAntiPatterns.length > 0) {
|
|
10620
|
-
relevantAntiPatterns = skillAntiPatterns.filter(
|
|
10621
|
-
(ap) => options.context.toLowerCase().includes(ap.pattern.toLowerCase())
|
|
10622
|
-
);
|
|
10623
|
-
if (relevantAntiPatterns.length > 0) {
|
|
10624
|
-
warnings.push(
|
|
10625
|
-
`This skill has failed in similar contexts: ${relevantAntiPatterns.map((ap) => ap.reason).join("; ")}`
|
|
10626
|
-
);
|
|
9520
|
+
if (result.success && result.skill) {
|
|
9521
|
+
const duplicate = await this.findSemanticDuplicate(result.skill);
|
|
9522
|
+
if (duplicate) {
|
|
9523
|
+
result.success = false;
|
|
9524
|
+
result.failureReason = `Duplicate of existing skill: ${duplicate.skill.id} (similarity: ${duplicate.similarity.toFixed(2)})`;
|
|
9525
|
+
} else {
|
|
9526
|
+
await this.storage.saveSkill(result.skill);
|
|
9527
|
+
this.emit({ type: "skill:created", skill: result.skill });
|
|
10627
9528
|
}
|
|
10628
9529
|
}
|
|
10629
|
-
|
|
10630
|
-
continue;
|
|
10631
|
-
}
|
|
10632
|
-
if (match.skill.metrics.successRate < 0.5 && match.skill.metrics.usageCount > 2) {
|
|
10633
|
-
warnings.push(`Low success rate: ${Math.round(match.skill.metrics.successRate * 100)}%`);
|
|
10634
|
-
}
|
|
10635
|
-
results.push({
|
|
10636
|
-
...match,
|
|
10637
|
-
relevantAntiPatterns: relevantAntiPatterns && relevantAntiPatterns.length > 0 ? relevantAntiPatterns : void 0,
|
|
10638
|
-
warnings: warnings.length > 0 ? warnings : void 0
|
|
10639
|
-
});
|
|
9530
|
+
this.emit({ type: "extraction:completed", result });
|
|
10640
9531
|
}
|
|
10641
9532
|
return results;
|
|
10642
9533
|
}
|
|
10643
|
-
// ==========================================================================
|
|
10644
|
-
// Legacy Learning Methods (backwards compatibility)
|
|
10645
|
-
// ==========================================================================
|
|
10646
9534
|
/**
|
|
10647
|
-
*
|
|
10648
|
-
*
|
|
9535
|
+
* Unified extraction entry point.
|
|
9536
|
+
*
|
|
9537
|
+
* Supports both manual (targeted) and automatic (LLM-driven) extraction
|
|
9538
|
+
* from a Trajectory. Use this instead of calling extractManual/extractAutomatic
|
|
9539
|
+
* directly.
|
|
9540
|
+
*
|
|
9541
|
+
* @example
|
|
9542
|
+
* ```typescript
|
|
9543
|
+
* // Manual extraction with defaults
|
|
9544
|
+
* const results = await bank.extract(trajectory);
|
|
9545
|
+
*
|
|
9546
|
+
* // Automatic extraction
|
|
9547
|
+
* const results = await bank.extract(trajectory, { mode: 'automatic' });
|
|
9548
|
+
*
|
|
9549
|
+
* // Manual with specific turn range
|
|
9550
|
+
* const results = await bank.extract(trajectory, {
|
|
9551
|
+
* mode: 'manual',
|
|
9552
|
+
* turnRange: [0, 5],
|
|
9553
|
+
* suggestedName: 'fix-auth-error',
|
|
9554
|
+
* });
|
|
9555
|
+
* ```
|
|
10649
9556
|
*/
|
|
10650
|
-
async
|
|
10651
|
-
|
|
10652
|
-
|
|
10653
|
-
const provider = this.learningProviders.get(providerName);
|
|
10654
|
-
if (!provider) {
|
|
10655
|
-
throw new Error(
|
|
10656
|
-
`Learning provider not found: ${providerName}. Available: ${Array.from(this.learningProviders.keys()).join(", ")}`
|
|
10657
|
-
);
|
|
9557
|
+
async extract(trajectory, options) {
|
|
9558
|
+
if (options?.mode === "automatic") {
|
|
9559
|
+
return this.extractAutomatic(trajectory, options);
|
|
10658
9560
|
}
|
|
10659
|
-
const result = await
|
|
10660
|
-
return result
|
|
9561
|
+
const result = await this.extractManual(trajectory, options);
|
|
9562
|
+
return [result];
|
|
10661
9563
|
}
|
|
10662
9564
|
/**
|
|
10663
|
-
* Extract
|
|
10664
|
-
* @deprecated Use learnFromBatch() instead
|
|
9565
|
+
* Extract from raw session content (convenience method)
|
|
10665
9566
|
*/
|
|
10666
|
-
async
|
|
10667
|
-
this.
|
|
10668
|
-
|
|
10669
|
-
const provider = this.learningProviders.get(providerName);
|
|
10670
|
-
if (!provider) {
|
|
10671
|
-
throw new Error(`Learning provider not found: ${providerName}`);
|
|
10672
|
-
}
|
|
10673
|
-
if (provider.analyzeBatch) {
|
|
10674
|
-
const result = await provider.analyzeBatch(trajectories, options);
|
|
10675
|
-
return result.candidates;
|
|
10676
|
-
}
|
|
10677
|
-
const allCandidates = [];
|
|
10678
|
-
for (const trajectory of trajectories) {
|
|
10679
|
-
const result = await provider.analyze(trajectory, options);
|
|
10680
|
-
allCandidates.push(...result.candidates);
|
|
10681
|
-
}
|
|
10682
|
-
return allCandidates;
|
|
9567
|
+
async extractFromSession(content, options) {
|
|
9568
|
+
const trajectory = await this.parseSession(content, options?.adapterName);
|
|
9569
|
+
return this.extract(trajectory, options);
|
|
10683
9570
|
}
|
|
10684
9571
|
/**
|
|
10685
|
-
*
|
|
10686
|
-
* This converts the raw learning into a curated, versioned skill.
|
|
9572
|
+
* Set LLM provider for automatic extraction
|
|
10687
9573
|
*/
|
|
10688
|
-
|
|
10689
|
-
this.
|
|
10690
|
-
if (candidate.content.kind !== "skill") {
|
|
10691
|
-
throw new Error(
|
|
10692
|
-
`Cannot promote ${candidate.content.kind} to skill directly. Only 'skill' kind is supported.`
|
|
10693
|
-
);
|
|
10694
|
-
}
|
|
10695
|
-
const agentId = this.activationManager.getCurrentAgentId();
|
|
10696
|
-
const agentMetadata = this.activationManager.getAgentMetadata();
|
|
10697
|
-
const agentName = agentMetadata?.agentName;
|
|
10698
|
-
const content = candidate.content;
|
|
10699
|
-
const skill = {
|
|
10700
|
-
id: candidate.id,
|
|
10701
|
-
name: candidate.name,
|
|
10702
|
-
version: "1.0.0",
|
|
10703
|
-
description: content.problem.substring(0, 150),
|
|
10704
|
-
problem: content.problem,
|
|
10705
|
-
triggerConditions: (content.triggers ?? []).map((t) => ({
|
|
10706
|
-
type: t.type,
|
|
10707
|
-
value: t.value,
|
|
10708
|
-
description: t.description
|
|
10709
|
-
})),
|
|
10710
|
-
solution: content.solution,
|
|
10711
|
-
verification: content.verification,
|
|
10712
|
-
examples: (content.examples ?? []).map((e) => ({
|
|
10713
|
-
scenario: e.scenario,
|
|
10714
|
-
before: e.before,
|
|
10715
|
-
after: e.after
|
|
10716
|
-
})),
|
|
10717
|
-
author: options?.author ?? agentName ?? candidate.source.provider,
|
|
10718
|
-
tags: options?.tags ?? candidate.tags ?? [],
|
|
10719
|
-
createdAt: /* @__PURE__ */ new Date(),
|
|
10720
|
-
updatedAt: /* @__PURE__ */ new Date(),
|
|
10721
|
-
status: options?.status ?? "draft",
|
|
10722
|
-
metrics: {
|
|
10723
|
-
usageCount: 0,
|
|
10724
|
-
successRate: candidate.confidence,
|
|
10725
|
-
feedbackScores: []
|
|
10726
|
-
},
|
|
10727
|
-
source: {
|
|
10728
|
-
type: "extracted",
|
|
10729
|
-
sessionId: candidate.source.trajectoryId,
|
|
10730
|
-
importedAt: candidate.source.extractedAt,
|
|
10731
|
-
agentId,
|
|
10732
|
-
agentName
|
|
10733
|
-
}
|
|
10734
|
-
};
|
|
10735
|
-
skill.serving = computeServingMetadata(skill);
|
|
10736
|
-
await this.storage.saveSkill(skill);
|
|
10737
|
-
this.emit({ type: "skill:created", skill });
|
|
10738
|
-
if (this.validationEnabled && this.validator) {
|
|
10739
|
-
this.runValidationAsync(skill).catch((err) => {
|
|
10740
|
-
console.error("Validation error:", err);
|
|
10741
|
-
});
|
|
10742
|
-
}
|
|
10743
|
-
if (this.compositionEnabled && this.composer) {
|
|
10744
|
-
this.runCompositionSuggestionsAsync(skill).catch((err) => {
|
|
10745
|
-
console.error("Composition suggestion error:", err);
|
|
10746
|
-
});
|
|
10747
|
-
}
|
|
10748
|
-
return skill;
|
|
9574
|
+
setLLMProvider(provider) {
|
|
9575
|
+
this.automaticExtractor.setLLMProvider(provider);
|
|
10749
9576
|
}
|
|
10750
9577
|
/**
|
|
10751
9578
|
* Validate a skill and store the result
|
|
@@ -11204,7 +10031,6 @@ ${refinementNote}` : refinementNote;
|
|
|
11204
10031
|
const deleted = await this.storage.deleteSkill(id, version);
|
|
11205
10032
|
if (deleted) {
|
|
11206
10033
|
this.emit({ type: "skill:deleted", skillId: id });
|
|
11207
|
-
this.antiPatterns.delete(id);
|
|
11208
10034
|
}
|
|
11209
10035
|
return deleted;
|
|
11210
10036
|
}
|
|
@@ -11678,8 +10504,7 @@ ${refinementNote}` : refinementNote;
|
|
|
11678
10504
|
},
|
|
11679
10505
|
byTag: {},
|
|
11680
10506
|
avgSuccessRate: 0,
|
|
11681
|
-
totalUsage: 0
|
|
11682
|
-
totalAntiPatterns: 0
|
|
10507
|
+
totalUsage: 0
|
|
11683
10508
|
};
|
|
11684
10509
|
if (this.namespaceConfig) {
|
|
11685
10510
|
stats.byScope = { personal: 0, team: 0, global: 0 };
|
|
@@ -11697,10 +10522,6 @@ ${refinementNote}` : refinementNote;
|
|
|
11697
10522
|
successRateSum += skill.metrics.successRate;
|
|
11698
10523
|
successRateCount++;
|
|
11699
10524
|
}
|
|
11700
|
-
const ap = this.antiPatterns.get(skill.id);
|
|
11701
|
-
if (ap) {
|
|
11702
|
-
stats.totalAntiPatterns += ap.length;
|
|
11703
|
-
}
|
|
11704
10525
|
if (stats.byScope && stats.byVisibility) {
|
|
11705
10526
|
const scope = skill.namespace?.scope || "personal";
|
|
11706
10527
|
const visibility = skill.namespace?.visibility || "private";
|
|
@@ -13910,509 +12731,6 @@ function conditionalHook(filter, handler) {
|
|
|
13910
12731
|
};
|
|
13911
12732
|
}
|
|
13912
12733
|
|
|
13913
|
-
// src/learning/providers/cognitive-core.ts
|
|
13914
|
-
var CognitiveCoreProvider = class {
|
|
13915
|
-
constructor(options) {
|
|
13916
|
-
this.name = "cognitive-core";
|
|
13917
|
-
this.description = "Advanced learning using cognitive-core with batch extraction and feedback";
|
|
13918
|
-
this.capabilities = {
|
|
13919
|
-
accumulating: true,
|
|
13920
|
-
feedbackEnabled: true,
|
|
13921
|
-
persistent: true,
|
|
13922
|
-
minTrajectories: 5,
|
|
13923
|
-
supportedKinds: ["skill", "strategy", "pattern", "error-fix"]
|
|
13924
|
-
};
|
|
13925
|
-
this.initialized = false;
|
|
13926
|
-
// ID mapping: playbook.id <-> candidate.id
|
|
13927
|
-
// For cognitive-core, we use playbook.id as the candidate.id directly
|
|
13928
|
-
this.playbookIdCache = /* @__PURE__ */ new Map();
|
|
13929
|
-
this.factory = options.factory;
|
|
13930
|
-
this.config = {
|
|
13931
|
-
storagePath: options.storagePath ?? "./.cognitive-core",
|
|
13932
|
-
minTrajectories: options.minTrajectories ?? 5,
|
|
13933
|
-
deduplicationThreshold: options.deduplicationThreshold ?? 0.85,
|
|
13934
|
-
creditStrategy: options.creditStrategy ?? "simple",
|
|
13935
|
-
convertToReAct: options.convertToReAct ?? true
|
|
13936
|
-
};
|
|
13937
|
-
this.memory = this.factory.createMemorySystem(this.config.storagePath);
|
|
13938
|
-
this.pipeline = this.factory.createLearningPipeline(this.memory, {
|
|
13939
|
-
creditStrategy: this.config.creditStrategy,
|
|
13940
|
-
minTrajectories: this.config.minTrajectories,
|
|
13941
|
-
deduplicationThreshold: this.config.deduplicationThreshold
|
|
13942
|
-
});
|
|
13943
|
-
}
|
|
13944
|
-
/**
|
|
13945
|
-
* Initialize the provider (load persisted state)
|
|
13946
|
-
*/
|
|
13947
|
-
async initialize() {
|
|
13948
|
-
if (this.initialized) return;
|
|
13949
|
-
await this.memory.init();
|
|
13950
|
-
this.initialized = true;
|
|
13951
|
-
}
|
|
13952
|
-
/**
|
|
13953
|
-
* Shutdown cleanly (persist state, release resources)
|
|
13954
|
-
*/
|
|
13955
|
-
async shutdown() {
|
|
13956
|
-
await this.memory.close();
|
|
13957
|
-
this.initialized = false;
|
|
13958
|
-
}
|
|
13959
|
-
/**
|
|
13960
|
-
* Analyze a trajectory and accumulate for batch learning.
|
|
13961
|
-
* Returns empty candidates until flush() or batch threshold.
|
|
13962
|
-
*/
|
|
13963
|
-
async analyze(trajectory, options) {
|
|
13964
|
-
await this.initialize();
|
|
13965
|
-
const startTime = Date.now();
|
|
13966
|
-
const ccTrajectory = this.convertTrajectory(trajectory, options);
|
|
13967
|
-
await this.pipeline.processTrajectory(ccTrajectory);
|
|
13968
|
-
let candidates = [];
|
|
13969
|
-
let updates = [];
|
|
13970
|
-
let demotions = [];
|
|
13971
|
-
let antiPatterns = [];
|
|
13972
|
-
if (options?.forceImmediate || this.pipeline.shouldRunBatch()) {
|
|
13973
|
-
const batchResult = await this.runBatchExtraction(options);
|
|
13974
|
-
candidates = batchResult.candidates;
|
|
13975
|
-
updates = batchResult.updates ?? [];
|
|
13976
|
-
demotions = batchResult.demotions ?? [];
|
|
13977
|
-
antiPatterns = batchResult.antiPatterns ?? [];
|
|
13978
|
-
}
|
|
13979
|
-
return {
|
|
13980
|
-
candidates,
|
|
13981
|
-
updates: updates.length > 0 ? updates : void 0,
|
|
13982
|
-
demotions: demotions.length > 0 ? demotions : void 0,
|
|
13983
|
-
antiPatterns: antiPatterns.length > 0 ? antiPatterns : void 0,
|
|
13984
|
-
providerState: {
|
|
13985
|
-
pendingCount: this.pipeline.getAccumulatedCount(),
|
|
13986
|
-
readyForFlush: this.pipeline.shouldRunBatch()
|
|
13987
|
-
},
|
|
13988
|
-
metadata: {
|
|
13989
|
-
trajectoriesAnalyzed: 1,
|
|
13990
|
-
durationMs: Date.now() - startTime
|
|
13991
|
-
}
|
|
13992
|
-
};
|
|
13993
|
-
}
|
|
13994
|
-
/**
|
|
13995
|
-
* Analyze multiple trajectories together.
|
|
13996
|
-
* Enables better cross-trajectory pattern detection.
|
|
13997
|
-
*/
|
|
13998
|
-
async analyzeBatch(trajectories, options) {
|
|
13999
|
-
await this.initialize();
|
|
14000
|
-
const startTime = Date.now();
|
|
14001
|
-
for (const trajectory of trajectories) {
|
|
14002
|
-
const ccTrajectory = this.convertTrajectory(trajectory, options);
|
|
14003
|
-
await this.pipeline.processTrajectory(ccTrajectory);
|
|
14004
|
-
}
|
|
14005
|
-
const batchResult = await this.runBatchExtraction(options);
|
|
14006
|
-
return {
|
|
14007
|
-
candidates: batchResult.candidates,
|
|
14008
|
-
updates: batchResult.updates,
|
|
14009
|
-
demotions: batchResult.demotions,
|
|
14010
|
-
antiPatterns: batchResult.antiPatterns,
|
|
14011
|
-
providerState: {
|
|
14012
|
-
pendingCount: this.pipeline.getAccumulatedCount(),
|
|
14013
|
-
readyForFlush: this.pipeline.shouldRunBatch()
|
|
14014
|
-
},
|
|
14015
|
-
metadata: {
|
|
14016
|
-
trajectoriesAnalyzed: trajectories.length,
|
|
14017
|
-
durationMs: Date.now() - startTime
|
|
14018
|
-
}
|
|
14019
|
-
};
|
|
14020
|
-
}
|
|
14021
|
-
/**
|
|
14022
|
-
* Force extraction from accumulated trajectories.
|
|
14023
|
-
*/
|
|
14024
|
-
async flush(options) {
|
|
14025
|
-
await this.initialize();
|
|
14026
|
-
const startTime = Date.now();
|
|
14027
|
-
const pendingCount = this.pipeline.getAccumulatedCount();
|
|
14028
|
-
const batchResult = await this.runBatchExtraction(options);
|
|
14029
|
-
return {
|
|
14030
|
-
...batchResult,
|
|
14031
|
-
metadata: {
|
|
14032
|
-
trajectoriesAnalyzed: pendingCount,
|
|
14033
|
-
durationMs: Date.now() - startTime
|
|
14034
|
-
}
|
|
14035
|
-
};
|
|
14036
|
-
}
|
|
14037
|
-
/**
|
|
14038
|
-
* Record outcome when a candidate/playbook is applied.
|
|
14039
|
-
* Updates playbook confidence and may generate refinements.
|
|
14040
|
-
*/
|
|
14041
|
-
async recordOutcome(feedback) {
|
|
14042
|
-
await this.initialize();
|
|
14043
|
-
const playbookId = feedback.candidateId;
|
|
14044
|
-
const playbook = await this.memory.playbooks.get(playbookId);
|
|
14045
|
-
if (!playbook) {
|
|
14046
|
-
return { recorded: false };
|
|
14047
|
-
}
|
|
14048
|
-
await this.memory.recordPlaybookUsage(
|
|
14049
|
-
playbookId,
|
|
14050
|
-
feedback.trajectoryId,
|
|
14051
|
-
feedback.success,
|
|
14052
|
-
feedback.context,
|
|
14053
|
-
feedback.failureMode
|
|
14054
|
-
);
|
|
14055
|
-
const updates = [];
|
|
14056
|
-
const antiPatterns = [];
|
|
14057
|
-
if (feedback.success) {
|
|
14058
|
-
updates.push({
|
|
14059
|
-
candidateId: playbookId,
|
|
14060
|
-
incrementSuccess: true,
|
|
14061
|
-
confidenceAdjustment: 0.05
|
|
14062
|
-
// Slight boost on success
|
|
14063
|
-
});
|
|
14064
|
-
} else {
|
|
14065
|
-
updates.push({
|
|
14066
|
-
candidateId: playbookId,
|
|
14067
|
-
incrementFailure: true,
|
|
14068
|
-
confidenceAdjustment: -0.1
|
|
14069
|
-
// Decrease confidence on failure
|
|
14070
|
-
});
|
|
14071
|
-
if (feedback.context || feedback.failureMode) {
|
|
14072
|
-
antiPatterns.push({
|
|
14073
|
-
id: `anti-${playbookId}-${Date.now()}`,
|
|
14074
|
-
candidateId: playbookId,
|
|
14075
|
-
pattern: feedback.context ?? "Unknown context",
|
|
14076
|
-
reason: feedback.failureMode ?? "Unknown failure mode",
|
|
14077
|
-
discoveredFrom: feedback.trajectoryId,
|
|
14078
|
-
createdAt: /* @__PURE__ */ new Date()
|
|
14079
|
-
});
|
|
14080
|
-
}
|
|
14081
|
-
}
|
|
14082
|
-
return {
|
|
14083
|
-
recorded: true,
|
|
14084
|
-
updates: updates.length > 0 ? updates : void 0,
|
|
14085
|
-
antiPatterns: antiPatterns.length > 0 ? antiPatterns : void 0
|
|
14086
|
-
};
|
|
14087
|
-
}
|
|
14088
|
-
/**
|
|
14089
|
-
* Check if a candidate is a duplicate based on playbook similarity
|
|
14090
|
-
*/
|
|
14091
|
-
isDuplicate(candidate, existing) {
|
|
14092
|
-
if (existing.some((e) => e.id === candidate.id)) {
|
|
14093
|
-
return true;
|
|
14094
|
-
}
|
|
14095
|
-
for (const e of existing) {
|
|
14096
|
-
const similarity = this.computeSimilarity(candidate, e);
|
|
14097
|
-
if (similarity > this.config.deduplicationThreshold) {
|
|
14098
|
-
return true;
|
|
14099
|
-
}
|
|
14100
|
-
}
|
|
14101
|
-
return false;
|
|
14102
|
-
}
|
|
14103
|
-
/**
|
|
14104
|
-
* Compute similarity between two candidates
|
|
14105
|
-
*/
|
|
14106
|
-
computeSimilarity(a, b) {
|
|
14107
|
-
if (a.kind !== b.kind) return 0.1;
|
|
14108
|
-
const nameA = this.tokenize(a.name);
|
|
14109
|
-
const nameB = this.tokenize(b.name);
|
|
14110
|
-
const nameSimilarity = this.jaccardSimilarity(nameA, nameB);
|
|
14111
|
-
let contentSimilarity = 0;
|
|
14112
|
-
if (a.content.kind === "skill" && b.content.kind === "skill") {
|
|
14113
|
-
const aWords = this.tokenize(a.content.problem + " " + a.content.solution);
|
|
14114
|
-
const bWords = this.tokenize(b.content.problem + " " + b.content.solution);
|
|
14115
|
-
contentSimilarity = this.jaccardSimilarity(aWords, bWords);
|
|
14116
|
-
}
|
|
14117
|
-
return nameSimilarity * 0.3 + contentSimilarity * 0.7;
|
|
14118
|
-
}
|
|
14119
|
-
// ==========================================================================
|
|
14120
|
-
// Private Methods
|
|
14121
|
-
// ==========================================================================
|
|
14122
|
-
/**
|
|
14123
|
-
* Run batch extraction and convert results to LearningCandidates
|
|
14124
|
-
*/
|
|
14125
|
-
async runBatchExtraction(options) {
|
|
14126
|
-
await this.pipeline.runBatchLearning();
|
|
14127
|
-
const allPlaybooks = await this.memory.playbooks.getAll();
|
|
14128
|
-
const candidates = [];
|
|
14129
|
-
const updates = [];
|
|
14130
|
-
const demotions = [];
|
|
14131
|
-
const antiPatterns = [];
|
|
14132
|
-
const minConfidence = options?.minConfidence ?? 0;
|
|
14133
|
-
const requestedKinds = options?.kinds;
|
|
14134
|
-
for (const playbook of allPlaybooks) {
|
|
14135
|
-
if (!this.playbookIdCache.has(playbook.id)) {
|
|
14136
|
-
const candidate = this.playbookToCandidate(playbook);
|
|
14137
|
-
if (candidate.confidence < minConfidence) {
|
|
14138
|
-
continue;
|
|
14139
|
-
}
|
|
14140
|
-
if (requestedKinds && !requestedKinds.includes(candidate.kind)) {
|
|
14141
|
-
continue;
|
|
14142
|
-
}
|
|
14143
|
-
candidates.push(candidate);
|
|
14144
|
-
this.playbookIdCache.set(playbook.id, true);
|
|
14145
|
-
}
|
|
14146
|
-
const successRate = playbook.evolution.successCount + playbook.evolution.failureCount > 0 ? playbook.evolution.successCount / (playbook.evolution.successCount + playbook.evolution.failureCount) : 1;
|
|
14147
|
-
if (successRate < 0.3 && playbook.evolution.successCount + playbook.evolution.failureCount >= 3) {
|
|
14148
|
-
demotions.push({
|
|
14149
|
-
candidateId: playbook.id,
|
|
14150
|
-
reason: `Low success rate: ${Math.round(successRate * 100)}%`,
|
|
14151
|
-
newConfidence: successRate,
|
|
14152
|
-
deprecate: successRate < 0.1
|
|
14153
|
-
});
|
|
14154
|
-
}
|
|
14155
|
-
for (const antiPattern of playbook.applicability.antiPatterns) {
|
|
14156
|
-
antiPatterns.push({
|
|
14157
|
-
id: `anti-${playbook.id}-${antiPattern.slice(0, 10)}`,
|
|
14158
|
-
candidateId: playbook.id,
|
|
14159
|
-
pattern: antiPattern,
|
|
14160
|
-
reason: "Learned from playbook applicability",
|
|
14161
|
-
discoveredFrom: playbook.evolution.createdFrom[0] ?? "unknown",
|
|
14162
|
-
createdAt: playbook.createdAt
|
|
14163
|
-
});
|
|
14164
|
-
}
|
|
14165
|
-
}
|
|
14166
|
-
return {
|
|
14167
|
-
candidates,
|
|
14168
|
-
updates: updates.length > 0 ? updates : void 0,
|
|
14169
|
-
demotions: demotions.length > 0 ? demotions : void 0,
|
|
14170
|
-
antiPatterns: antiPatterns.length > 0 ? antiPatterns : void 0,
|
|
14171
|
-
providerState: {
|
|
14172
|
-
pendingCount: this.pipeline.getAccumulatedCount(),
|
|
14173
|
-
readyForFlush: this.pipeline.shouldRunBatch()
|
|
14174
|
-
}
|
|
14175
|
-
};
|
|
14176
|
-
}
|
|
14177
|
-
/**
|
|
14178
|
-
* Convert a skill-tree Trajectory to cognitive-core Trajectory format
|
|
14179
|
-
*/
|
|
14180
|
-
convertTrajectory(trajectory, options) {
|
|
14181
|
-
const firstUserTurn = trajectory.turns.find((t) => t.role === "user");
|
|
14182
|
-
let taskDescription = firstUserTurn?.content ?? "Unknown task";
|
|
14183
|
-
if (options?.context) {
|
|
14184
|
-
taskDescription = `${taskDescription}
|
|
14185
|
-
|
|
14186
|
-
Context: ${options.context}`;
|
|
14187
|
-
}
|
|
14188
|
-
const task = this.factory.createTask({
|
|
14189
|
-
id: trajectory.sessionId,
|
|
14190
|
-
domain: trajectory.metadata.projectName ?? "general",
|
|
14191
|
-
description: taskDescription,
|
|
14192
|
-
context: trajectory.metadata.custom ?? {}
|
|
14193
|
-
});
|
|
14194
|
-
const [startTurn, endTurn] = options?.turnRange ?? [0, trajectory.turns.length - 1];
|
|
14195
|
-
const turnsToProcess = trajectory.turns.slice(startTurn, endTurn + 1);
|
|
14196
|
-
const steps = [];
|
|
14197
|
-
if (this.config.convertToReAct) {
|
|
14198
|
-
for (let i = 0; i < turnsToProcess.length; i++) {
|
|
14199
|
-
const turn = turnsToProcess[i];
|
|
14200
|
-
if (turn.role === "assistant") {
|
|
14201
|
-
const step = this.turnToStep(turn, turnsToProcess, i);
|
|
14202
|
-
if (step) {
|
|
14203
|
-
steps.push(step);
|
|
14204
|
-
}
|
|
14205
|
-
}
|
|
14206
|
-
}
|
|
14207
|
-
}
|
|
14208
|
-
const outcome = {
|
|
14209
|
-
success: trajectory.outcome?.success ?? false,
|
|
14210
|
-
partialScore: trajectory.outcome?.success ? 1 : 0,
|
|
14211
|
-
solution: trajectory.outcome?.summary ?? "",
|
|
14212
|
-
errorInfo: trajectory.outcome?.errors?.join("; ")
|
|
14213
|
-
};
|
|
14214
|
-
return this.factory.createTrajectory({
|
|
14215
|
-
id: trajectory.sessionId,
|
|
14216
|
-
task,
|
|
14217
|
-
steps,
|
|
14218
|
-
outcome,
|
|
14219
|
-
agentId: trajectory.metadata.agentType ?? "skill-tree",
|
|
14220
|
-
metadata: trajectory.metadata.custom ?? {}
|
|
14221
|
-
});
|
|
14222
|
-
}
|
|
14223
|
-
/**
|
|
14224
|
-
* Convert an assistant turn to a cognitive-core Step
|
|
14225
|
-
*/
|
|
14226
|
-
turnToStep(turn, allTurns, turnIndex) {
|
|
14227
|
-
let observation = "";
|
|
14228
|
-
const nextTurn = allTurns[turnIndex + 1];
|
|
14229
|
-
if (nextTurn?.role === "tool" && nextTurn.toolResults?.length) {
|
|
14230
|
-
observation = nextTurn.toolResults.map((r) => r.output).join("\n");
|
|
14231
|
-
} else if (nextTurn?.role === "user") {
|
|
14232
|
-
observation = nextTurn.content.slice(0, 500);
|
|
14233
|
-
}
|
|
14234
|
-
let action = "";
|
|
14235
|
-
if (turn.toolCalls?.length) {
|
|
14236
|
-
action = turn.toolCalls.map((tc) => `${tc.name}(${JSON.stringify(tc.input).slice(0, 200)})`).join("; ");
|
|
14237
|
-
} else {
|
|
14238
|
-
action = turn.content.slice(0, 300);
|
|
14239
|
-
}
|
|
14240
|
-
const thought = turn.toolCalls?.length ? turn.content.slice(0, 500) : void 0;
|
|
14241
|
-
return this.factory.createStep({
|
|
14242
|
-
thought,
|
|
14243
|
-
action,
|
|
14244
|
-
observation
|
|
14245
|
-
});
|
|
14246
|
-
}
|
|
14247
|
-
/**
|
|
14248
|
-
* Convert a cognitive-core Playbook to a LearningCandidate
|
|
14249
|
-
*/
|
|
14250
|
-
playbookToCandidate(playbook) {
|
|
14251
|
-
const kind = this.inferKind(playbook);
|
|
14252
|
-
const content = this.createContentForKind(kind, playbook);
|
|
14253
|
-
const attribution = playbook.evolution.createdFrom.map(
|
|
14254
|
-
(trajectoryId, i) => ({
|
|
14255
|
-
turnIndex: i,
|
|
14256
|
-
score: 1 / Math.max(1, playbook.evolution.createdFrom.length),
|
|
14257
|
-
reasoning: `Derived from trajectory ${trajectoryId}`
|
|
14258
|
-
})
|
|
14259
|
-
);
|
|
14260
|
-
return {
|
|
14261
|
-
kind,
|
|
14262
|
-
id: playbook.id,
|
|
14263
|
-
name: playbook.name,
|
|
14264
|
-
content,
|
|
14265
|
-
confidence: playbook.confidence,
|
|
14266
|
-
attribution,
|
|
14267
|
-
source: {
|
|
14268
|
-
provider: this.name,
|
|
14269
|
-
trajectoryId: playbook.evolution.createdFrom[0] ?? "unknown",
|
|
14270
|
-
turnRange: [0, 0],
|
|
14271
|
-
// Playbooks don't track specific turn ranges
|
|
14272
|
-
extractedAt: playbook.createdAt,
|
|
14273
|
-
metadata: {
|
|
14274
|
-
version: playbook.evolution.version,
|
|
14275
|
-
successCount: playbook.evolution.successCount,
|
|
14276
|
-
failureCount: playbook.evolution.failureCount,
|
|
14277
|
-
complexity: playbook.complexity
|
|
14278
|
-
}
|
|
14279
|
-
},
|
|
14280
|
-
embedding: playbook.embedding,
|
|
14281
|
-
// Pass through embedding if present
|
|
14282
|
-
tags: playbook.applicability.domains,
|
|
14283
|
-
reasoning: playbook.guidance.strategy
|
|
14284
|
-
};
|
|
14285
|
-
}
|
|
14286
|
-
/**
|
|
14287
|
-
* Create appropriate content type for the inferred kind
|
|
14288
|
-
*/
|
|
14289
|
-
createContentForKind(kind, playbook) {
|
|
14290
|
-
switch (kind) {
|
|
14291
|
-
case "strategy":
|
|
14292
|
-
return {
|
|
14293
|
-
kind: "strategy",
|
|
14294
|
-
situation: playbook.applicability.situations.join(". "),
|
|
14295
|
-
suggestion: playbook.guidance.strategy,
|
|
14296
|
-
parameters: playbook.guidance.codeExample ? { example: playbook.guidance.codeExample } : void 0
|
|
14297
|
-
};
|
|
14298
|
-
case "pattern":
|
|
14299
|
-
return {
|
|
14300
|
-
kind: "pattern",
|
|
14301
|
-
pattern: playbook.applicability.triggers[0] ?? playbook.name,
|
|
14302
|
-
description: playbook.guidance.strategy,
|
|
14303
|
-
examples: playbook.applicability.situations
|
|
14304
|
-
};
|
|
14305
|
-
case "error-fix":
|
|
14306
|
-
return {
|
|
14307
|
-
kind: "error-fix",
|
|
14308
|
-
errorPattern: playbook.applicability.triggers.join(" | "),
|
|
14309
|
-
fix: playbook.guidance.strategy + (playbook.guidance.steps?.length ? "\n\nSteps:\n" + playbook.guidance.steps.map((s, i) => `${i + 1}. ${s}`).join("\n") : ""),
|
|
14310
|
-
frequency: playbook.evolution.successCount + playbook.evolution.failureCount,
|
|
14311
|
-
errorExamples: playbook.applicability.triggers
|
|
14312
|
-
};
|
|
14313
|
-
case "skill":
|
|
14314
|
-
default:
|
|
14315
|
-
return {
|
|
14316
|
-
kind: "skill",
|
|
14317
|
-
problem: playbook.applicability.situations.join(". "),
|
|
14318
|
-
solution: playbook.guidance.strategy + (playbook.guidance.steps?.length ? "\n\nSteps:\n" + playbook.guidance.steps.map((s, i) => `${i + 1}. ${s}`).join("\n") : ""),
|
|
14319
|
-
verification: playbook.verification.successIndicators.join(". "),
|
|
14320
|
-
triggers: this.extractTriggers(playbook),
|
|
14321
|
-
examples: []
|
|
14322
|
-
// Playbooks don't have direct examples
|
|
14323
|
-
};
|
|
14324
|
-
}
|
|
14325
|
-
}
|
|
14326
|
-
/**
|
|
14327
|
-
* Infer the kind of learning from a playbook
|
|
14328
|
-
*/
|
|
14329
|
-
inferKind(playbook) {
|
|
14330
|
-
const hasErrorTriggers = playbook.applicability.triggers.some(
|
|
14331
|
-
(t) => t.toLowerCase().includes("error") || /^[A-Z]{2,}\d+/.test(t)
|
|
14332
|
-
);
|
|
14333
|
-
if (hasErrorTriggers) {
|
|
14334
|
-
return "error-fix";
|
|
14335
|
-
}
|
|
14336
|
-
const strategy = playbook.guidance.strategy.toLowerCase();
|
|
14337
|
-
if (strategy.includes("approach") || strategy.includes("strategy") || strategy.includes("when you see")) {
|
|
14338
|
-
return "strategy";
|
|
14339
|
-
}
|
|
14340
|
-
if (playbook.applicability.situations.some((s) => s.includes("pattern"))) {
|
|
14341
|
-
return "pattern";
|
|
14342
|
-
}
|
|
14343
|
-
return "skill";
|
|
14344
|
-
}
|
|
14345
|
-
/**
|
|
14346
|
-
* Extract triggers from playbook applicability
|
|
14347
|
-
*/
|
|
14348
|
-
extractTriggers(playbook) {
|
|
14349
|
-
const triggers = [];
|
|
14350
|
-
for (const situation of playbook.applicability.situations) {
|
|
14351
|
-
triggers.push({
|
|
14352
|
-
type: "context",
|
|
14353
|
-
value: situation,
|
|
14354
|
-
description: "Situation trigger"
|
|
14355
|
-
});
|
|
14356
|
-
}
|
|
14357
|
-
for (const trigger of playbook.applicability.triggers) {
|
|
14358
|
-
let type = "keyword";
|
|
14359
|
-
if (trigger.toLowerCase().includes("error") || /^[A-Z]{2,}\d+/.test(trigger)) {
|
|
14360
|
-
type = "error";
|
|
14361
|
-
} else if (trigger.startsWith("/") || trigger.includes("*")) {
|
|
14362
|
-
type = "pattern";
|
|
14363
|
-
}
|
|
14364
|
-
triggers.push({
|
|
14365
|
-
type,
|
|
14366
|
-
value: trigger,
|
|
14367
|
-
description: "Explicit trigger"
|
|
14368
|
-
});
|
|
14369
|
-
}
|
|
14370
|
-
return triggers;
|
|
14371
|
-
}
|
|
14372
|
-
/**
|
|
14373
|
-
* Tokenize text into words
|
|
14374
|
-
*/
|
|
14375
|
-
tokenize(text) {
|
|
14376
|
-
return text.toLowerCase().split(/\W+/).filter((w) => w.length > 2);
|
|
14377
|
-
}
|
|
14378
|
-
/**
|
|
14379
|
-
* Compute Jaccard similarity between two arrays
|
|
14380
|
-
*/
|
|
14381
|
-
jaccardSimilarity(a, b) {
|
|
14382
|
-
const setA = new Set(a);
|
|
14383
|
-
const setB = new Set(b);
|
|
14384
|
-
const intersection = new Set([...setA].filter((x) => setB.has(x)));
|
|
14385
|
-
const union = /* @__PURE__ */ new Set([...setA, ...setB]);
|
|
14386
|
-
return union.size === 0 ? 0 : intersection.size / union.size;
|
|
14387
|
-
}
|
|
14388
|
-
};
|
|
14389
|
-
function createCognitiveCoreProvider(options) {
|
|
14390
|
-
return new CognitiveCoreProvider(options);
|
|
14391
|
-
}
|
|
14392
|
-
async function createDefaultCognitiveCoreFactory() {
|
|
14393
|
-
const cc = await import("cognitive-core");
|
|
14394
|
-
return {
|
|
14395
|
-
createMemorySystem(storagePath) {
|
|
14396
|
-
return cc.createMemorySystem(storagePath);
|
|
14397
|
-
},
|
|
14398
|
-
createLearningPipeline(memory, config) {
|
|
14399
|
-
return cc.createLearningPipeline(
|
|
14400
|
-
memory,
|
|
14401
|
-
config
|
|
14402
|
-
);
|
|
14403
|
-
},
|
|
14404
|
-
createTrajectory(params) {
|
|
14405
|
-
return cc.createTrajectory(params);
|
|
14406
|
-
},
|
|
14407
|
-
createTask(params) {
|
|
14408
|
-
return cc.createTask(params);
|
|
14409
|
-
},
|
|
14410
|
-
createStep(params) {
|
|
14411
|
-
return cc.createStep(params);
|
|
14412
|
-
}
|
|
14413
|
-
};
|
|
14414
|
-
}
|
|
14415
|
-
|
|
14416
12734
|
// src/sync/git-sync-adapter.ts
|
|
14417
12735
|
var fs8 = __toESM(require("fs"));
|
|
14418
12736
|
var path8 = __toESM(require("path"));
|
|
@@ -15942,7 +14260,6 @@ var VERSION = "0.1.0";
|
|
|
15942
14260
|
BaseStorageAdapter,
|
|
15943
14261
|
BatchProcessor,
|
|
15944
14262
|
ClaudeCodeAdapter,
|
|
15945
|
-
CognitiveCoreProvider,
|
|
15946
14263
|
ConflictStore,
|
|
15947
14264
|
DEFAULT_ACTIVATION_CONFIG,
|
|
15948
14265
|
DEFAULT_AGENTS_CONFIG,
|
|
@@ -15961,7 +14278,6 @@ var VERSION = "0.1.0";
|
|
|
15961
14278
|
MemoryMetricsStorage,
|
|
15962
14279
|
MemoryStorageAdapter,
|
|
15963
14280
|
MetricsTracker,
|
|
15964
|
-
NaiveLearningProvider,
|
|
15965
14281
|
OpenAIAdapter,
|
|
15966
14282
|
OpenAIEmbedding,
|
|
15967
14283
|
ProjectDetector,
|
|
@@ -15994,9 +14310,7 @@ var VERSION = "0.1.0";
|
|
|
15994
14310
|
createAgentsParser,
|
|
15995
14311
|
createAgentsSync,
|
|
15996
14312
|
createBackupHook,
|
|
15997
|
-
createCognitiveCoreProvider,
|
|
15998
14313
|
createConflictStore,
|
|
15999
|
-
createDefaultCognitiveCoreFactory,
|
|
16000
14314
|
createDefaultSyncConfig,
|
|
16001
14315
|
createExtractionEnrichmentHook,
|
|
16002
14316
|
createExtractionValidationHook,
|
|
@@ -16006,7 +14320,6 @@ var VERSION = "0.1.0";
|
|
|
16006
14320
|
createMcpServer,
|
|
16007
14321
|
createMetricsHook,
|
|
16008
14322
|
createMetricsTracker,
|
|
16009
|
-
createNaiveProvider,
|
|
16010
14323
|
createQualityBypassHook,
|
|
16011
14324
|
createQualityLoggingHook,
|
|
16012
14325
|
createSaveValidationHook,
|
|
@@ -16016,6 +14329,7 @@ var VERSION = "0.1.0";
|
|
|
16016
14329
|
createToolHandlers,
|
|
16017
14330
|
debuggingProfile,
|
|
16018
14331
|
devopsProfile,
|
|
14332
|
+
discoverSkills,
|
|
16019
14333
|
documentationProfile,
|
|
16020
14334
|
euclideanDistance,
|
|
16021
14335
|
executeToolCall,
|
|
@@ -16026,6 +14340,7 @@ var VERSION = "0.1.0";
|
|
|
16026
14340
|
getLatestVersion,
|
|
16027
14341
|
getToolDefinition,
|
|
16028
14342
|
getToolNames,
|
|
14343
|
+
hasSkilltreeDir,
|
|
16029
14344
|
hookRegistry,
|
|
16030
14345
|
implementationProfile,
|
|
16031
14346
|
importFromAgentsMd,
|
|
@@ -16055,3 +14370,4 @@ var VERSION = "0.1.0";
|
|
|
16055
14370
|
testingProfile,
|
|
16056
14371
|
writeAgentsMd
|
|
16057
14372
|
});
|
|
14373
|
+
//# sourceMappingURL=index.js.map
|