@matimo/core 0.1.0-alpha.12 → 0.1.0-alpha.13
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/README.md +169 -8
- package/dist/approval/approval-handler.d.ts +5 -1
- package/dist/approval/approval-handler.d.ts.map +1 -1
- package/dist/approval/approval-handler.js +6 -0
- package/dist/approval/approval-handler.js.map +1 -1
- package/dist/core/schema.d.ts +29 -8
- package/dist/core/schema.d.ts.map +1 -1
- package/dist/core/schema.js +10 -3
- package/dist/core/schema.js.map +1 -1
- package/dist/core/skill-content-parser.d.ts +91 -0
- package/dist/core/skill-content-parser.d.ts.map +1 -0
- package/dist/core/skill-content-parser.js +248 -0
- package/dist/core/skill-content-parser.js.map +1 -0
- package/dist/core/skill-loader.d.ts +46 -0
- package/dist/core/skill-loader.d.ts.map +1 -0
- package/dist/core/skill-loader.js +310 -0
- package/dist/core/skill-loader.js.map +1 -0
- package/dist/core/skill-registry.d.ts +131 -0
- package/dist/core/skill-registry.d.ts.map +1 -0
- package/dist/core/skill-registry.js +316 -0
- package/dist/core/skill-registry.js.map +1 -0
- package/dist/core/tfidf-embedding.d.ts +45 -0
- package/dist/core/tfidf-embedding.d.ts.map +1 -0
- package/dist/core/tfidf-embedding.js +199 -0
- package/dist/core/tfidf-embedding.js.map +1 -0
- package/dist/core/types.d.ts +192 -6
- package/dist/core/types.d.ts.map +1 -1
- package/dist/encodings/parameter-encoding.d.ts.map +1 -1
- package/dist/encodings/parameter-encoding.js +6 -2
- package/dist/encodings/parameter-encoding.js.map +1 -1
- package/dist/errors/matimo-error.d.ts +3 -1
- package/dist/errors/matimo-error.d.ts.map +1 -1
- package/dist/errors/matimo-error.js +2 -0
- package/dist/errors/matimo-error.js.map +1 -1
- package/dist/executors/command-executor.d.ts +9 -2
- package/dist/executors/command-executor.d.ts.map +1 -1
- package/dist/executors/command-executor.js +14 -2
- package/dist/executors/command-executor.js.map +1 -1
- package/dist/executors/function-executor.d.ts +10 -3
- package/dist/executors/function-executor.d.ts.map +1 -1
- package/dist/executors/function-executor.js +11 -4
- package/dist/executors/function-executor.js.map +1 -1
- package/dist/executors/http-executor.d.ts +16 -2
- package/dist/executors/http-executor.d.ts.map +1 -1
- package/dist/executors/http-executor.js +22 -6
- package/dist/executors/http-executor.js.map +1 -1
- package/dist/index.d.ts +20 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -1
- package/dist/index.js.map +1 -1
- package/dist/integrations/langchain.d.ts +55 -0
- package/dist/integrations/langchain.d.ts.map +1 -1
- package/dist/integrations/langchain.js +66 -0
- package/dist/integrations/langchain.js.map +1 -1
- package/dist/logging/winston-logger.d.ts.map +1 -1
- package/dist/logging/winston-logger.js +9 -1
- package/dist/logging/winston-logger.js.map +1 -1
- package/dist/matimo-instance.d.ts +210 -18
- package/dist/matimo-instance.d.ts.map +1 -1
- package/dist/matimo-instance.js +704 -40
- package/dist/matimo-instance.js.map +1 -1
- package/dist/mcp/mcp-server.d.ts +23 -0
- package/dist/mcp/mcp-server.d.ts.map +1 -1
- package/dist/mcp/mcp-server.js +119 -8
- package/dist/mcp/mcp-server.js.map +1 -1
- package/dist/mcp/tool-converter.d.ts.map +1 -1
- package/dist/mcp/tool-converter.js +10 -1
- package/dist/mcp/tool-converter.js.map +1 -1
- package/dist/policy/approval-manifest.d.ts +74 -0
- package/dist/policy/approval-manifest.d.ts.map +1 -0
- package/dist/policy/approval-manifest.js +178 -0
- package/dist/policy/approval-manifest.js.map +1 -0
- package/dist/policy/content-validator.d.ts +19 -0
- package/dist/policy/content-validator.d.ts.map +1 -0
- package/dist/policy/content-validator.js +196 -0
- package/dist/policy/content-validator.js.map +1 -0
- package/dist/policy/default-policy.d.ts +46 -0
- package/dist/policy/default-policy.d.ts.map +1 -0
- package/dist/policy/default-policy.js +241 -0
- package/dist/policy/default-policy.js.map +1 -0
- package/dist/policy/events.d.ts +71 -0
- package/dist/policy/events.d.ts.map +1 -0
- package/dist/policy/events.js +8 -0
- package/dist/policy/events.js.map +1 -0
- package/dist/policy/index.d.ts +13 -0
- package/dist/policy/index.d.ts.map +1 -0
- package/dist/policy/index.js +9 -0
- package/dist/policy/index.js.map +1 -0
- package/dist/policy/integrity-tracker.d.ts +62 -0
- package/dist/policy/integrity-tracker.d.ts.map +1 -0
- package/dist/policy/integrity-tracker.js +79 -0
- package/dist/policy/integrity-tracker.js.map +1 -0
- package/dist/policy/policy-loader.d.ts +58 -0
- package/dist/policy/policy-loader.d.ts.map +1 -0
- package/dist/policy/policy-loader.js +153 -0
- package/dist/policy/policy-loader.js.map +1 -0
- package/dist/policy/risk-classifier.d.ts +18 -0
- package/dist/policy/risk-classifier.d.ts.map +1 -0
- package/dist/policy/risk-classifier.js +43 -0
- package/dist/policy/risk-classifier.js.map +1 -0
- package/dist/policy/types.d.ts +126 -0
- package/dist/policy/types.d.ts.map +1 -0
- package/dist/policy/types.js +8 -0
- package/dist/policy/types.js.map +1 -0
- package/package.json +2 -2
- package/tools/matimo_approve_tool/definition.yaml +36 -0
- package/tools/matimo_approve_tool/matimo_approve_tool.ts +90 -0
- package/tools/matimo_create_skill/definition.yaml +46 -0
- package/tools/matimo_create_skill/matimo_create_skill.ts +75 -0
- package/tools/matimo_create_tool/definition.yaml +48 -0
- package/tools/matimo_create_tool/matimo_create_tool.ts +137 -0
- package/tools/matimo_get_skill/definition.yaml +60 -0
- package/tools/matimo_get_skill/matimo_get_skill.ts +182 -0
- package/tools/matimo_get_tool_status/definition.yaml +42 -0
- package/tools/matimo_get_tool_status/matimo_get_tool_status.ts +101 -0
- package/tools/matimo_list_skills/definition.yaml +52 -0
- package/tools/matimo_list_skills/matimo_list_skills.ts +138 -0
- package/tools/matimo_list_user_tools/definition.yaml +32 -0
- package/tools/matimo_list_user_tools/matimo_list_user_tools.ts +74 -0
- package/tools/matimo_reload_tools/definition.yaml +35 -0
- package/tools/matimo_reload_tools/matimo_reload_tools.ts +29 -0
- package/tools/matimo_validate_skill/definition.yaml +43 -0
- package/tools/matimo_validate_skill/matimo_validate_skill.ts +137 -0
- package/tools/matimo_validate_tool/definition.yaml +34 -0
- package/tools/matimo_validate_tool/matimo_validate_tool.ts +168 -0
- package/tools/shared/skill-validation.ts +335 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill Registry — in-memory store and search for skills
|
|
3
|
+
*
|
|
4
|
+
* Mirrors ToolRegistry but for skills. Provides discovery, search, and filtering.
|
|
5
|
+
* Supports both substring matching (default) and semantic search via pluggable embeddings.
|
|
6
|
+
*/
|
|
7
|
+
import { SkillDefinition, SkillSummary, SearchSkillsOptions, EmbeddingProvider, SkillContentOptions } from './types';
|
|
8
|
+
/**
|
|
9
|
+
* Semantic search result with relevance score.
|
|
10
|
+
*/
|
|
11
|
+
export interface SemanticSearchResult {
|
|
12
|
+
skill: SkillSummary;
|
|
13
|
+
/** Cosine similarity score (0–1, higher = more relevant) */
|
|
14
|
+
score: number;
|
|
15
|
+
}
|
|
16
|
+
export declare class SkillRegistry {
|
|
17
|
+
private logger;
|
|
18
|
+
private skills;
|
|
19
|
+
/** Pluggable embedding provider for semantic search */
|
|
20
|
+
private embeddingProvider;
|
|
21
|
+
/** Cached embeddings: skill name → vector */
|
|
22
|
+
private embeddings;
|
|
23
|
+
/** Whether embeddings need rebuilding */
|
|
24
|
+
private embeddingsDirty;
|
|
25
|
+
/** Cached parsed content for selective loading */
|
|
26
|
+
private parsedContent;
|
|
27
|
+
/**
|
|
28
|
+
* Set a custom embedding provider (OpenAI, Cohere, etc.).
|
|
29
|
+
* If not set, a built-in TF-IDF provider is used as fallback.
|
|
30
|
+
*/
|
|
31
|
+
setEmbeddingProvider(provider: EmbeddingProvider): void;
|
|
32
|
+
/**
|
|
33
|
+
* Register a single skill
|
|
34
|
+
*/
|
|
35
|
+
register(skill: SkillDefinition): void;
|
|
36
|
+
/**
|
|
37
|
+
* Register multiple skills
|
|
38
|
+
*/
|
|
39
|
+
registerAll(skills: SkillDefinition[]): void;
|
|
40
|
+
/**
|
|
41
|
+
* Get a single skill by name
|
|
42
|
+
*/
|
|
43
|
+
get(name: string): SkillDefinition | undefined;
|
|
44
|
+
/**
|
|
45
|
+
* Get a single skill by name (throws if not found)
|
|
46
|
+
*/
|
|
47
|
+
getRequired(name: string): SkillDefinition;
|
|
48
|
+
/**
|
|
49
|
+
* Get selective skill content — only the sections an agent needs.
|
|
50
|
+
* This prevents dumping entire SKILL.md files into the LLM context.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* // Get only the error handling section, max 500 tokens
|
|
54
|
+
* registry.getSkillContent('postgres-query-operations', {
|
|
55
|
+
* sections: ['Error Handling'],
|
|
56
|
+
* maxTokens: 500,
|
|
57
|
+
* })
|
|
58
|
+
*/
|
|
59
|
+
getSkillContent(name: string, options?: SkillContentOptions): string | null;
|
|
60
|
+
/**
|
|
61
|
+
* List all sections of a skill with their token costs.
|
|
62
|
+
* Agents use this to decide which sections to load.
|
|
63
|
+
*/
|
|
64
|
+
getSkillSections(name: string): Array<{
|
|
65
|
+
path: string;
|
|
66
|
+
level: number;
|
|
67
|
+
tokenEstimate: number;
|
|
68
|
+
}> | null;
|
|
69
|
+
/**
|
|
70
|
+
* List all skills (Level 1 discovery — minimal context)
|
|
71
|
+
*/
|
|
72
|
+
list(): SkillSummary[];
|
|
73
|
+
/**
|
|
74
|
+
* Search skills by keyword, category, difficulty, etc.
|
|
75
|
+
*
|
|
76
|
+
* When `options.semantic` is true, uses embedding-based similarity ranking
|
|
77
|
+
* instead of substring matching. Falls back to built-in TF-IDF if no
|
|
78
|
+
* external embedding provider is configured.
|
|
79
|
+
*/
|
|
80
|
+
search(options?: SearchSkillsOptions): SkillSummary[];
|
|
81
|
+
/**
|
|
82
|
+
* Semantic search with relevance scores.
|
|
83
|
+
* Returns ranked results with cosine similarity scores.
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* const results = await registry.semanticSearch('How do I handle Postgres connection pooling?');
|
|
87
|
+
* // → [{ skill: { name: 'postgres-query-operations', ... }, score: 0.82 }]
|
|
88
|
+
*/
|
|
89
|
+
semanticSearch(query: string, options?: {
|
|
90
|
+
limit?: number;
|
|
91
|
+
minScore?: number;
|
|
92
|
+
}): Promise<SemanticSearchResult[]>;
|
|
93
|
+
/**
|
|
94
|
+
* Get all skills (full definitions)
|
|
95
|
+
*/
|
|
96
|
+
getAll(): SkillDefinition[];
|
|
97
|
+
/**
|
|
98
|
+
* Check if a skill exists
|
|
99
|
+
*/
|
|
100
|
+
has(name: string): boolean;
|
|
101
|
+
/**
|
|
102
|
+
* Get the count of registered skills
|
|
103
|
+
*/
|
|
104
|
+
count(): number;
|
|
105
|
+
/**
|
|
106
|
+
* Clear all skills
|
|
107
|
+
*/
|
|
108
|
+
clear(): void;
|
|
109
|
+
/**
|
|
110
|
+
* Remove a skill
|
|
111
|
+
*/
|
|
112
|
+
remove(name: string): boolean;
|
|
113
|
+
/**
|
|
114
|
+
* Ensure embeddings are computed and up-to-date.
|
|
115
|
+
*/
|
|
116
|
+
private ensureEmbeddings;
|
|
117
|
+
/**
|
|
118
|
+
* Synchronous ranking using TF-IDF (for the non-async search() method).
|
|
119
|
+
*/
|
|
120
|
+
private rankBySimilarity;
|
|
121
|
+
/**
|
|
122
|
+
* Get or create the default TF-IDF provider.
|
|
123
|
+
*/
|
|
124
|
+
private defaultProvider;
|
|
125
|
+
private getDefaultProvider;
|
|
126
|
+
/**
|
|
127
|
+
* Convert a skill into a searchable text string for embedding.
|
|
128
|
+
*/
|
|
129
|
+
private skillToText;
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=skill-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-registry.d.ts","sourceRoot":"","sources":["../../src/core/skill-registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,SAAS,CAAC;AAOjB;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,YAAY,CAAC;IACpB,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,MAAM,CAAsC;IAEpD,uDAAuD;IACvD,OAAO,CAAC,iBAAiB,CAAkC;IAC3D,6CAA6C;IAC7C,OAAO,CAAC,UAAU,CAA+B;IACjD,yCAAyC;IACzC,OAAO,CAAC,eAAe,CAAQ;IAC/B,kDAAkD;IAClD,OAAO,CAAC,aAAa,CAAyC;IAE9D;;;OAGG;IACH,oBAAoB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI;IAMvD;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAetC;;OAEG;IACH,WAAW,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,IAAI;IAM5C;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAI9C;;OAEG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe;IAQ1C;;;;;;;;;;OAUG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,MAAM,GAAG,IAAI;IAM3E;;;OAGG;IACH,gBAAgB,CACd,IAAI,EAAE,MAAM,GACX,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,IAAI;IAMvE;;OAEG;IACH,IAAI,IAAI,YAAY,EAAE;IAWtB;;;;;;OAMG;IACH,MAAM,CAAC,OAAO,GAAE,mBAAwB,GAAG,YAAY,EAAE;IAmEzD;;;;;;;OAOG;IACG,cAAc,CAClB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAO,GAClD,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAgClC;;OAEG;IACH,MAAM,IAAI,eAAe,EAAE;IAI3B;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B;;OAEG;IACH,KAAK,IAAI,MAAM;IAIf;;OAEG;IACH,KAAK,IAAI,IAAI;IAOb;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAS7B;;OAEG;YACW,gBAAgB;IAwB9B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAyBxB;;OAEG;IACH,OAAO,CAAC,eAAe,CAAuC;IAC9D,OAAO,CAAC,kBAAkB;IAO1B;;OAEG;IACH,OAAO,CAAC,WAAW;CAOpB"}
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill Registry — in-memory store and search for skills
|
|
3
|
+
*
|
|
4
|
+
* Mirrors ToolRegistry but for skills. Provides discovery, search, and filtering.
|
|
5
|
+
* Supports both substring matching (default) and semantic search via pluggable embeddings.
|
|
6
|
+
*/
|
|
7
|
+
import { MatimoError, ErrorCode } from '../errors/matimo-error';
|
|
8
|
+
import { getGlobalMatimoLogger } from '../logging';
|
|
9
|
+
import { TfIdfEmbeddingProvider, cosineSimilarity } from './tfidf-embedding';
|
|
10
|
+
import { parseSkillSections, extractSkillContent, listSkillSections } from './skill-content-parser';
|
|
11
|
+
export class SkillRegistry {
|
|
12
|
+
constructor() {
|
|
13
|
+
this.logger = getGlobalMatimoLogger();
|
|
14
|
+
this.skills = new Map();
|
|
15
|
+
/** Pluggable embedding provider for semantic search */
|
|
16
|
+
this.embeddingProvider = null;
|
|
17
|
+
/** Cached embeddings: skill name → vector */
|
|
18
|
+
this.embeddings = new Map();
|
|
19
|
+
/** Whether embeddings need rebuilding */
|
|
20
|
+
this.embeddingsDirty = true;
|
|
21
|
+
/** Cached parsed content for selective loading */
|
|
22
|
+
this.parsedContent = new Map();
|
|
23
|
+
/**
|
|
24
|
+
* Get or create the default TF-IDF provider.
|
|
25
|
+
*/
|
|
26
|
+
this.defaultProvider = null;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Set a custom embedding provider (OpenAI, Cohere, etc.).
|
|
30
|
+
* If not set, a built-in TF-IDF provider is used as fallback.
|
|
31
|
+
*/
|
|
32
|
+
setEmbeddingProvider(provider) {
|
|
33
|
+
this.embeddingProvider = provider;
|
|
34
|
+
this.embeddingsDirty = true;
|
|
35
|
+
this.logger.debug('SkillRegistry: custom embedding provider set');
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Register a single skill
|
|
39
|
+
*/
|
|
40
|
+
register(skill) {
|
|
41
|
+
if (!skill.name) {
|
|
42
|
+
throw new MatimoError('Skill must have a name', ErrorCode.INVALID_SCHEMA);
|
|
43
|
+
}
|
|
44
|
+
this.skills.set(skill.name, skill);
|
|
45
|
+
this.embeddingsDirty = true;
|
|
46
|
+
// Cache parsed sections for selective loading
|
|
47
|
+
if (skill.body) {
|
|
48
|
+
this.parsedContent.set(skill.name, parseSkillSections(skill.body));
|
|
49
|
+
}
|
|
50
|
+
this.logger.debug('SkillRegistry: skill registered', { name: skill.name });
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Register multiple skills
|
|
54
|
+
*/
|
|
55
|
+
registerAll(skills) {
|
|
56
|
+
for (const skill of skills) {
|
|
57
|
+
this.register(skill);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Get a single skill by name
|
|
62
|
+
*/
|
|
63
|
+
get(name) {
|
|
64
|
+
return this.skills.get(name);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Get a single skill by name (throws if not found)
|
|
68
|
+
*/
|
|
69
|
+
getRequired(name) {
|
|
70
|
+
const skill = this.skills.get(name);
|
|
71
|
+
if (!skill) {
|
|
72
|
+
throw new MatimoError(`Skill not found: ${name}`, ErrorCode.TOOL_NOT_FOUND);
|
|
73
|
+
}
|
|
74
|
+
return skill;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Get selective skill content — only the sections an agent needs.
|
|
78
|
+
* This prevents dumping entire SKILL.md files into the LLM context.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* // Get only the error handling section, max 500 tokens
|
|
82
|
+
* registry.getSkillContent('postgres-query-operations', {
|
|
83
|
+
* sections: ['Error Handling'],
|
|
84
|
+
* maxTokens: 500,
|
|
85
|
+
* })
|
|
86
|
+
*/
|
|
87
|
+
getSkillContent(name, options) {
|
|
88
|
+
const parsed = this.parsedContent.get(name);
|
|
89
|
+
if (!parsed)
|
|
90
|
+
return null;
|
|
91
|
+
return extractSkillContent(parsed, options);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* List all sections of a skill with their token costs.
|
|
95
|
+
* Agents use this to decide which sections to load.
|
|
96
|
+
*/
|
|
97
|
+
getSkillSections(name) {
|
|
98
|
+
const parsed = this.parsedContent.get(name);
|
|
99
|
+
if (!parsed)
|
|
100
|
+
return null;
|
|
101
|
+
return listSkillSections(parsed);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* List all skills (Level 1 discovery — minimal context)
|
|
105
|
+
*/
|
|
106
|
+
list() {
|
|
107
|
+
return Array.from(this.skills.values()).map((skill) => ({
|
|
108
|
+
name: skill.name,
|
|
109
|
+
description: skill.description,
|
|
110
|
+
version: skill.version,
|
|
111
|
+
license: skill.license,
|
|
112
|
+
metadata: skill.metadata,
|
|
113
|
+
source: skill.source,
|
|
114
|
+
}));
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Search skills by keyword, category, difficulty, etc.
|
|
118
|
+
*
|
|
119
|
+
* When `options.semantic` is true, uses embedding-based similarity ranking
|
|
120
|
+
* instead of substring matching. Falls back to built-in TF-IDF if no
|
|
121
|
+
* external embedding provider is configured.
|
|
122
|
+
*/
|
|
123
|
+
search(options = {}) {
|
|
124
|
+
const { query = '', category, difficulty, tags, author, limit = 50, offset = 0 } = options;
|
|
125
|
+
let results = Array.from(this.skills.values());
|
|
126
|
+
// Apply filters first (these are always exact/substring)
|
|
127
|
+
if (category) {
|
|
128
|
+
results = results.filter((skill) => skill.metadata?.category?.toLowerCase() === category.toLowerCase());
|
|
129
|
+
}
|
|
130
|
+
if (difficulty) {
|
|
131
|
+
results = results.filter((skill) => skill.metadata?.difficulty?.toLowerCase() === difficulty.toLowerCase());
|
|
132
|
+
}
|
|
133
|
+
if (tags && tags.length > 0) {
|
|
134
|
+
const metadataTags = tags.map((t) => t.toLowerCase());
|
|
135
|
+
results = results.filter((skill) => {
|
|
136
|
+
const skillTags = (skill.metadata?.tags || '')
|
|
137
|
+
.split(',')
|
|
138
|
+
.map((t) => t.trim().toLowerCase());
|
|
139
|
+
return metadataTags.some((tag) => skillTags.includes(tag));
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
if (author) {
|
|
143
|
+
results = results.filter((skill) => skill.metadata?.author?.toLowerCase() === author.toLowerCase());
|
|
144
|
+
}
|
|
145
|
+
// Apply query filter (substring or semantic)
|
|
146
|
+
if (query) {
|
|
147
|
+
if (options.semantic) {
|
|
148
|
+
// Semantic search: rank by embedding similarity
|
|
149
|
+
const scored = this.rankBySimilarity(query, results);
|
|
150
|
+
// Precompute a map for O(1) lookup by skill name
|
|
151
|
+
const skillByName = new Map(results.map((skill) => [skill.name, skill]));
|
|
152
|
+
results = scored
|
|
153
|
+
.filter((r) => r.score > 0.1) // Minimum relevance threshold
|
|
154
|
+
.sort((a, b) => b.score - a.score)
|
|
155
|
+
.map((r) => skillByName.get(r.skill.name))
|
|
156
|
+
.filter((skill) => skill !== undefined);
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
// Substring search (original behavior)
|
|
160
|
+
const lowerQuery = query.toLowerCase();
|
|
161
|
+
results = results.filter((skill) => {
|
|
162
|
+
const nameMatch = skill.name.toLowerCase().includes(lowerQuery);
|
|
163
|
+
const descMatch = skill.description.toLowerCase().includes(lowerQuery);
|
|
164
|
+
return nameMatch || descMatch;
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
// Pagination
|
|
169
|
+
const paged = results.slice(offset, offset + limit);
|
|
170
|
+
return paged.map((skill) => ({
|
|
171
|
+
name: skill.name,
|
|
172
|
+
description: skill.description,
|
|
173
|
+
version: skill.version,
|
|
174
|
+
license: skill.license,
|
|
175
|
+
metadata: skill.metadata,
|
|
176
|
+
source: skill.source,
|
|
177
|
+
}));
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Semantic search with relevance scores.
|
|
181
|
+
* Returns ranked results with cosine similarity scores.
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* const results = await registry.semanticSearch('How do I handle Postgres connection pooling?');
|
|
185
|
+
* // → [{ skill: { name: 'postgres-query-operations', ... }, score: 0.82 }]
|
|
186
|
+
*/
|
|
187
|
+
async semanticSearch(query, options = {}) {
|
|
188
|
+
const { limit = 10, minScore = 0.1 } = options;
|
|
189
|
+
await this.ensureEmbeddings();
|
|
190
|
+
const provider = this.embeddingProvider || this.getDefaultProvider();
|
|
191
|
+
const queryEmbedding = await provider.embed(query);
|
|
192
|
+
const results = [];
|
|
193
|
+
for (const [name, embedding] of this.embeddings) {
|
|
194
|
+
const skill = this.skills.get(name);
|
|
195
|
+
if (!skill)
|
|
196
|
+
continue;
|
|
197
|
+
const score = cosineSimilarity(queryEmbedding, embedding);
|
|
198
|
+
if (score >= minScore) {
|
|
199
|
+
results.push({
|
|
200
|
+
skill: {
|
|
201
|
+
name: skill.name,
|
|
202
|
+
description: skill.description,
|
|
203
|
+
version: skill.version,
|
|
204
|
+
license: skill.license,
|
|
205
|
+
metadata: skill.metadata,
|
|
206
|
+
source: skill.source,
|
|
207
|
+
},
|
|
208
|
+
score,
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return results.sort((a, b) => b.score - a.score).slice(0, limit);
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Get all skills (full definitions)
|
|
216
|
+
*/
|
|
217
|
+
getAll() {
|
|
218
|
+
return Array.from(this.skills.values());
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Check if a skill exists
|
|
222
|
+
*/
|
|
223
|
+
has(name) {
|
|
224
|
+
return this.skills.has(name);
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Get the count of registered skills
|
|
228
|
+
*/
|
|
229
|
+
count() {
|
|
230
|
+
return this.skills.size;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Clear all skills
|
|
234
|
+
*/
|
|
235
|
+
clear() {
|
|
236
|
+
this.skills.clear();
|
|
237
|
+
this.embeddings.clear();
|
|
238
|
+
this.parsedContent.clear();
|
|
239
|
+
this.embeddingsDirty = true;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Remove a skill
|
|
243
|
+
*/
|
|
244
|
+
remove(name) {
|
|
245
|
+
this.embeddings.delete(name);
|
|
246
|
+
this.parsedContent.delete(name);
|
|
247
|
+
this.embeddingsDirty = true;
|
|
248
|
+
return this.skills.delete(name);
|
|
249
|
+
}
|
|
250
|
+
// ─── Private: Embedding Management ──────────────────────────────────────
|
|
251
|
+
/**
|
|
252
|
+
* Ensure embeddings are computed and up-to-date.
|
|
253
|
+
*/
|
|
254
|
+
async ensureEmbeddings() {
|
|
255
|
+
if (!this.embeddingsDirty)
|
|
256
|
+
return;
|
|
257
|
+
const provider = this.embeddingProvider || this.getDefaultProvider();
|
|
258
|
+
const skills = Array.from(this.skills.values());
|
|
259
|
+
// Build text corpus: name + description + metadata tags
|
|
260
|
+
const texts = skills.map((s) => this.skillToText(s));
|
|
261
|
+
// If using TF-IDF, refit the vocabulary
|
|
262
|
+
if (provider instanceof TfIdfEmbeddingProvider) {
|
|
263
|
+
provider.fit(texts);
|
|
264
|
+
}
|
|
265
|
+
const vectors = await provider.embedBatch(texts);
|
|
266
|
+
this.embeddings.clear();
|
|
267
|
+
for (let i = 0; i < skills.length; i++) {
|
|
268
|
+
this.embeddings.set(skills[i].name, vectors[i]);
|
|
269
|
+
}
|
|
270
|
+
this.embeddingsDirty = false;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Synchronous ranking using TF-IDF (for the non-async search() method).
|
|
274
|
+
*/
|
|
275
|
+
rankBySimilarity(query, candidates) {
|
|
276
|
+
const provider = this.getDefaultProvider();
|
|
277
|
+
// Build corpus from candidates
|
|
278
|
+
const texts = candidates.map((s) => this.skillToText(s));
|
|
279
|
+
provider.fit([...texts, query]); // Include query in vocab
|
|
280
|
+
const queryVec = provider.embedSync(query);
|
|
281
|
+
return candidates.map((skill) => {
|
|
282
|
+
const skillVec = provider.embedSync(this.skillToText(skill));
|
|
283
|
+
return {
|
|
284
|
+
skill: {
|
|
285
|
+
name: skill.name,
|
|
286
|
+
description: skill.description,
|
|
287
|
+
version: skill.version,
|
|
288
|
+
license: skill.license,
|
|
289
|
+
metadata: skill.metadata,
|
|
290
|
+
source: skill.source,
|
|
291
|
+
},
|
|
292
|
+
score: cosineSimilarity(queryVec, skillVec),
|
|
293
|
+
};
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
getDefaultProvider() {
|
|
297
|
+
if (!this.defaultProvider) {
|
|
298
|
+
this.defaultProvider = new TfIdfEmbeddingProvider();
|
|
299
|
+
}
|
|
300
|
+
return this.defaultProvider;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Convert a skill into a searchable text string for embedding.
|
|
304
|
+
*/
|
|
305
|
+
skillToText(skill) {
|
|
306
|
+
const parts = [skill.name.replace(/-/g, ' '), skill.description];
|
|
307
|
+
if (skill.metadata?.tags)
|
|
308
|
+
parts.push(skill.metadata.tags);
|
|
309
|
+
if (skill.metadata?.category)
|
|
310
|
+
parts.push(skill.metadata.category);
|
|
311
|
+
if (skill.allowedTools)
|
|
312
|
+
parts.push(skill.allowedTools.join(' '));
|
|
313
|
+
return parts.join(' ');
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
//# sourceMappingURL=skill-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-registry.js","sourceRoot":"","sources":["../../src/core/skill-registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAYpG,MAAM,OAAO,aAAa;IAA1B;QACU,WAAM,GAAG,qBAAqB,EAAE,CAAC;QACjC,WAAM,GAAG,IAAI,GAAG,EAA2B,CAAC;QAEpD,uDAAuD;QAC/C,sBAAiB,GAA6B,IAAI,CAAC;QAC3D,6CAA6C;QACrC,eAAU,GAAG,IAAI,GAAG,EAAoB,CAAC;QACjD,yCAAyC;QACjC,oBAAe,GAAG,IAAI,CAAC;QAC/B,kDAAkD;QAC1C,kBAAa,GAAG,IAAI,GAAG,EAA8B,CAAC;QA2T9D;;WAEG;QACK,oBAAe,GAAkC,IAAI,CAAC;IAkBhE,CAAC;IA9UC;;;OAGG;IACH,oBAAoB,CAAC,QAA2B;QAC9C,IAAI,CAAC,iBAAiB,GAAG,QAAQ,CAAC;QAClC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAC5B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;IACpE,CAAC;IAED;;OAEG;IACH,QAAQ,CAAC,KAAsB;QAC7B,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YAChB,MAAM,IAAI,WAAW,CAAC,wBAAwB,EAAE,SAAS,CAAC,cAAc,CAAC,CAAC;QAC5E,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACnC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAE5B,8CAA8C;QAC9C,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACf,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;QACrE,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,iCAAiC,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IAC7E,CAAC;IAED;;OAEG;IACH,WAAW,CAAC,MAAyB;QACnC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,WAAW,CAAC,IAAY;QACtB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,WAAW,CAAC,oBAAoB,IAAI,EAAE,EAAE,SAAS,CAAC,cAAc,CAAC,CAAC;QAC9E,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;;;;;OAUG;IACH,eAAe,CAAC,IAAY,EAAE,OAA6B;QACzD,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QACzB,OAAO,mBAAmB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;IAED;;;OAGG;IACH,gBAAgB,CACd,IAAY;QAEZ,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QACzB,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,IAAI;QACF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACtD,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,MAAM,EAAE,KAAK,CAAC,MAAM;SACrB,CAAC,CAAC,CAAC;IACN,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,UAA+B,EAAE;QACtC,MAAM,EAAE,KAAK,GAAG,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,GAAG,EAAE,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,OAAO,CAAC;QAE3F,IAAI,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QAE/C,yDAAyD;QACzD,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,GAAG,OAAO,CAAC,MAAM,CACtB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,QAAQ,CAAC,WAAW,EAAE,CAC9E,CAAC;QACJ,CAAC;QACD,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,GAAG,OAAO,CAAC,MAAM,CACtB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,KAAK,UAAU,CAAC,WAAW,EAAE,CAClF,CAAC;QACJ,CAAC;QACD,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;YACtD,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;gBACjC,MAAM,SAAS,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC;qBAC3C,KAAK,CAAC,GAAG,CAAC;qBACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;gBACtC,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;YAC7D,CAAC,CAAC,CAAC;QACL,CAAC;QACD,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,GAAG,OAAO,CAAC,MAAM,CACtB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,MAAM,CAAC,WAAW,EAAE,CAC1E,CAAC;QACJ,CAAC;QAED,6CAA6C;QAC7C,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;gBACrB,gDAAgD;gBAChD,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;gBACrD,iDAAiD;gBACjD,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAU,CAAC,CAAC,CAAC;gBAClF,OAAO,GAAG,MAAM;qBACb,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,8BAA8B;qBAC3D,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;qBACjC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;qBACzC,MAAM,CAAC,CAAC,KAAK,EAAsC,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;YAChF,CAAC;iBAAM,CAAC;gBACN,uCAAuC;gBACvC,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;gBACvC,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;oBACjC,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;oBAChE,MAAM,SAAS,GAAG,KAAK,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;oBACvE,OAAO,SAAS,IAAI,SAAS,CAAC;gBAChC,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,aAAa;QACb,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC;QAEpD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAC3B,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,MAAM,EAAE,KAAK,CAAC,MAAM;SACrB,CAAC,CAAC,CAAC;IACN,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,cAAc,CAClB,KAAa,EACb,UAAiD,EAAE;QAEnD,MAAM,EAAE,KAAK,GAAG,EAAE,EAAE,QAAQ,GAAG,GAAG,EAAE,GAAG,OAAO,CAAC;QAE/C,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAE9B,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACrE,MAAM,cAAc,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAEnD,MAAM,OAAO,GAA2B,EAAE,CAAC;QAC3C,KAAK,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAChD,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACpC,IAAI,CAAC,KAAK;gBAAE,SAAS;YAErB,MAAM,KAAK,GAAG,gBAAgB,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;YAC1D,IAAI,KAAK,IAAI,QAAQ,EAAE,CAAC;gBACtB,OAAO,CAAC,IAAI,CAAC;oBACX,KAAK,EAAE;wBACL,IAAI,EAAE,KAAK,CAAC,IAAI;wBAChB,WAAW,EAAE,KAAK,CAAC,WAAW;wBAC9B,OAAO,EAAE,KAAK,CAAC,OAAO;wBACtB,OAAO,EAAE,KAAK,CAAC,OAAO;wBACtB,QAAQ,EAAE,KAAK,CAAC,QAAQ;wBACxB,MAAM,EAAE,KAAK,CAAC,MAAM;qBACrB;oBACD,KAAK;iBACN,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACnE,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,KAAK;QACH,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACpB,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACxB,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;QAC3B,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;IAC9B,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,IAAY;QACjB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAChC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAC5B,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAED,2EAA2E;IAE3E;;OAEG;IACK,KAAK,CAAC,gBAAgB;QAC5B,IAAI,CAAC,IAAI,CAAC,eAAe;YAAE,OAAO;QAElC,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACrE,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QAEhD,wDAAwD;QACxD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;QAErD,wCAAwC;QACxC,IAAI,QAAQ,YAAY,sBAAsB,EAAE,CAAC;YAC/C,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAEjD,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACvC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QAClD,CAAC;QAED,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;IAC/B,CAAC;IAED;;OAEG;IACK,gBAAgB,CAAC,KAAa,EAAE,UAA6B;QACnE,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAE3C,+BAA+B;QAC/B,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;QACzD,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,yBAAyB;QAE1D,MAAM,QAAQ,GAAG,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAE3C,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YAC9B,MAAM,QAAQ,GAAG,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;YAC7D,OAAO;gBACL,KAAK,EAAE;oBACL,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,WAAW,EAAE,KAAK,CAAC,WAAW;oBAC9B,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,QAAQ,EAAE,KAAK,CAAC,QAAQ;oBACxB,MAAM,EAAE,KAAK,CAAC,MAAM;iBACrB;gBACD,KAAK,EAAE,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,CAAC;aAC5C,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAMO,kBAAkB;QACxB,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;YAC1B,IAAI,CAAC,eAAe,GAAG,IAAI,sBAAsB,EAAE,CAAC;QACtD,CAAC;QACD,OAAO,IAAI,CAAC,eAAe,CAAC;IAC9B,CAAC;IAED;;OAEG;IACK,WAAW,CAAC,KAAsB;QACxC,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;QACjE,IAAI,KAAK,CAAC,QAAQ,EAAE,IAAI;YAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC1D,IAAI,KAAK,CAAC,QAAQ,EAAE,QAAQ;YAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAClE,IAAI,KAAK,CAAC,YAAY;YAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACjE,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;CACF"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TF-IDF Embedding Provider — zero-dependency semantic search
|
|
3
|
+
* (Term Frequency–Inverse Document Frequency)
|
|
4
|
+
* Provides a lightweight text-to-vector implementation using TF-IDF (Term
|
|
5
|
+
* Frequency–Inverse Document Frequency) for cosine-similarity ranking. This
|
|
6
|
+
* is good enough for 10–200 skills. For production enterprise deployments,
|
|
7
|
+
* plug in an OpenAI/Cohere `EmbeddingProvider` instead.
|
|
8
|
+
*
|
|
9
|
+
* No external dependencies — works out of the box.
|
|
10
|
+
*/
|
|
11
|
+
import { EmbeddingProvider } from './types';
|
|
12
|
+
/**
|
|
13
|
+
* Simple TF-IDF based embedding provider.
|
|
14
|
+
* Builds a vocabulary from the registered corpus and represents each text as
|
|
15
|
+
* a TF-IDF weighted vector.
|
|
16
|
+
*/
|
|
17
|
+
export declare class TfIdfEmbeddingProvider implements EmbeddingProvider {
|
|
18
|
+
private vocabulary;
|
|
19
|
+
private idf;
|
|
20
|
+
private corpusSize;
|
|
21
|
+
private _dimensions;
|
|
22
|
+
get dimensions(): number;
|
|
23
|
+
/**
|
|
24
|
+
* Build the vocabulary and IDF weights from a corpus of documents.
|
|
25
|
+
* Must be called before `embed()` or `embedBatch()`.
|
|
26
|
+
*/
|
|
27
|
+
fit(documents: string[]): void;
|
|
28
|
+
embed(text: string): Promise<number[]>;
|
|
29
|
+
embedBatch(texts: string[]): Promise<number[][]>;
|
|
30
|
+
/**
|
|
31
|
+
* Synchronous embed for internal use (no async overhead).
|
|
32
|
+
*/
|
|
33
|
+
embedSync(text: string): number[];
|
|
34
|
+
/**
|
|
35
|
+
* Tokenize text into lowercase terms.
|
|
36
|
+
* Splits on non-alphanumeric characters and filters stopwords.
|
|
37
|
+
*/
|
|
38
|
+
private tokenize;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Cosine similarity between two vectors.
|
|
42
|
+
* Returns a value between -1 and 1 (1 = identical, 0 = orthogonal).
|
|
43
|
+
*/
|
|
44
|
+
export declare function cosineSimilarity(a: number[], b: number[]): number;
|
|
45
|
+
//# sourceMappingURL=tfidf-embedding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tfidf-embedding.d.ts","sourceRoot":"","sources":["../../src/core/tfidf-embedding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAE5C;;;;GAIG;AACH,qBAAa,sBAAuB,YAAW,iBAAiB;IAC9D,OAAO,CAAC,UAAU,CAAkC;IACpD,OAAO,CAAC,GAAG,CAAqC;IAChD,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,WAAW,CAAK;IAExB,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED;;;OAGG;IACH,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI;IA2BxB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAItC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;IAItD;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE;IAsCjC;;;OAGG;IACH,OAAO,CAAC,QAAQ;CAMjB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAejE"}
|