@futdevpro/fdp-agent-memory 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +345 -0
- package/build/package.json +96 -0
- package/build/src/_assets/mcp-client-config/README.md +29 -0
- package/build/src/_assets/mcp-client-config/claude_desktop_config.json +15 -0
- package/build/src/_assets/mcp-client-config/mcp.json +15 -0
- package/build/src/_collections/config-catalog.const.js +180 -0
- package/build/src/_collections/config-error-codes.const.js +30 -0
- package/build/src/_collections/config-presets.const.js +25 -0
- package/build/src/_collections/error-banners.const.js +100 -0
- package/build/src/_collections/error-codes.const.js +150 -0
- package/build/src/_collections/fam-db-models.const.js +37 -0
- package/build/src/_collections/fam-entry-bootstrap.util.js +80 -0
- package/build/src/_collections/fam-error-context.util.js +90 -0
- package/build/src/_collections/fam-error-factory.util.js +64 -0
- package/build/src/_enums/fam-config-level.type-enum.js +15 -0
- package/build/src/_enums/fam-table.type-enum.js +20 -0
- package/build/src/_integration-tests/_helpers/fam-integration-test-setup.util.js +105 -0
- package/build/src/_models/data-models/fam-codebase.data-model.js +51 -0
- package/build/src/_models/data-models/fam-coding-patterns.data-model.js +58 -0
- package/build/src/_models/data-models/fam-config.data-model.js +68 -0
- package/build/src/_models/data-models/fam-documents.data-model.js +53 -0
- package/build/src/_models/data-models/fam-entry-base-properties.const.js +43 -0
- package/build/src/_models/data-models/fam-entry.data-model.js +81 -0
- package/build/src/_models/data-models/fam-error.data-model.js +88 -0
- package/build/src/_models/data-models/fam-ingest-run.data-model.js +74 -0
- package/build/src/_models/data-models/fam-knowledge.data-model.js +48 -0
- package/build/src/_models/data-models/fam-memory.data-model.js +55 -0
- package/build/src/_models/data-models/fam-reference.data-model.js +67 -0
- package/build/src/_models/data-models/fam-rules.data-model.js +51 -0
- package/build/src/_models/data-models/fam-scope.data-model.js +52 -0
- package/build/src/_models/interfaces/fam-common.interface.js +23 -0
- package/build/src/_models/interfaces/fam-config.interface.js +2 -0
- package/build/src/_models/interfaces/fam-error.interface.js +2 -0
- package/build/src/_modules/embedding/_collections/fam-embedding-pricing.const.js +22 -0
- package/build/src/_modules/embedding/_collections/fam-store-registry.const.js +63 -0
- package/build/src/_modules/embedding/_models/interfaces/fam-embedding-cost.interface.js +10 -0
- package/build/src/_modules/embedding/_models/interfaces/fam-embedding-provider.interface.js +2 -0
- package/build/src/_modules/embedding/_models/interfaces/fam-resolved-provider.interface.js +2 -0
- package/build/src/_modules/embedding/_services/fam-embedding-bootstrap.control-service.js +52 -0
- package/build/src/_modules/embedding/_services/fam-embedding-cost.control-service.js +175 -0
- package/build/src/_modules/embedding/_services/fam-embedding-pipeline.control-service.js +202 -0
- package/build/src/_modules/embedding/_services/fam-embedding-preset.control-service.js +66 -0
- package/build/src/_modules/embedding/_services/fam-embedding.control-service.js +253 -0
- package/build/src/_modules/embedding/_services/fam-entry.data-service.js +64 -0
- package/build/src/_modules/embedding/_services/fam-lmstudio-embedding.provider.js +112 -0
- package/build/src/_modules/embedding/_services/fam-mock-embedding.provider.js +64 -0
- package/build/src/_modules/embedding/_services/fam-openai-embedding.provider.js +64 -0
- package/build/src/_modules/embedding/_services/fam-vector-search.control-service.js +244 -0
- package/build/src/_modules/embedding/index.js +40 -0
- package/build/src/_modules/ingest/_collections/fam-content-hash.util.js +35 -0
- package/build/src/_modules/ingest/_collections/fam-file-routing.util.js +95 -0
- package/build/src/_modules/ingest/_collections/fam-glob-match.util.js +84 -0
- package/build/src/_modules/ingest/_collections/fam-md-chunker.util.js +164 -0
- package/build/src/_modules/ingest/_collections/fam-scan-path.util.js +91 -0
- package/build/src/_modules/ingest/_collections/fam-secret-exclude.util.js +54 -0
- package/build/src/_modules/ingest/_collections/fam-sliding-chunker.util.js +76 -0
- package/build/src/_modules/ingest/_collections/fam-ts-chunker.util.js +316 -0
- package/build/src/_modules/ingest/_models/interfaces/fam-ingest.interface.js +2 -0
- package/build/src/_modules/ingest/_services/fam-chunker.control-service.js +114 -0
- package/build/src/_modules/ingest/_services/fam-delta-compare.util.js +74 -0
- package/build/src/_modules/ingest/_services/fam-ingest-run.data-service.js +85 -0
- package/build/src/_modules/ingest/_services/fam-ingest.control-service.js +384 -0
- package/build/src/_modules/ingest/_services/fam-scan.control-service.js +211 -0
- package/build/src/_modules/ingest/index.js +46 -0
- package/build/src/_modules/mcp/_collections/fam-core-tools.const.js +186 -0
- package/build/src/_modules/mcp/_models/interfaces/fam-mcp.interface.js +31 -0
- package/build/src/_modules/mcp/_services/fam-capabilities-tool.service.js +111 -0
- package/build/src/_modules/mcp/_services/fam-capability-registry.service.js +1180 -0
- package/build/src/_modules/mcp/_services/fam-mcp-adapter.service.js +123 -0
- package/build/src/_modules/mcp/_services/fam-mcp-server.service.js +69 -0
- package/build/src/_modules/mcp/_services/fam-read-tool.service.js +99 -0
- package/build/src/_modules/mcp/_services/fam-write-tool.service.js +460 -0
- package/build/src/_modules/mcp/index.js +35 -0
- package/build/src/_modules/migration/_collections/fam-claude-mem-normalize.util.js +166 -0
- package/build/src/_modules/migration/_collections/fam-import-content-hash.util.js +38 -0
- package/build/src/_modules/migration/_collections/fam-target-mapping.util.js +90 -0
- package/build/src/_modules/migration/_enums/fam-claude-mem-source.type-enum.js +20 -0
- package/build/src/_modules/migration/_models/interfaces/fam-claude-mem.interface.js +26 -0
- package/build/src/_modules/migration/_services/fam-claude-mem-export-reader.service.js +134 -0
- package/build/src/_modules/migration/_services/fam-claude-mem-import.control-service.js +533 -0
- package/build/src/_modules/migration/_services/fam-claude-mem-sqlite-reader.service.js +144 -0
- package/build/src/_modules/migration/_services/fam-claude-mem-worker-reader.service.js +115 -0
- package/build/src/_modules/migration/_services/fam-import-dedup.data-service.js +102 -0
- package/build/src/_modules/migration/index.js +38 -0
- package/build/src/_modules/retrieval/_models/interfaces/fam-retrieval.interface.js +2 -0
- package/build/src/_modules/retrieval/_services/fam-retrieval-candidate.data-service.js +67 -0
- package/build/src/_modules/retrieval/_services/fam-retrieval-suggestions.util.js +182 -0
- package/build/src/_modules/retrieval/_services/fam-retrieval.control-service.js +282 -0
- package/build/src/_modules/retrieval/index.js +22 -0
- package/build/src/_modules/scope-reference/_collections/fam-fuzzy-match.util.js +86 -0
- package/build/src/_modules/scope-reference/_collections/fam-scope-normalize.util.js +47 -0
- package/build/src/_modules/scope-reference/_models/interfaces/fam-reference-resolution.interface.js +2 -0
- package/build/src/_modules/scope-reference/_models/interfaces/fam-resolution-trace.interface.js +2 -0
- package/build/src/_modules/scope-reference/_services/fam-reference.data-service.js +179 -0
- package/build/src/_modules/scope-reference/_services/fam-scope-resolver.control-service.js +473 -0
- package/build/src/_modules/scope-reference/_services/fam-scope.data-service.js +215 -0
- package/build/src/_modules/scope-reference/index.js +26 -0
- package/build/src/_routes/server/api/api.controller.js +400 -0
- package/build/src/_routes/server/client-app/client-app.control-service.js +132 -0
- package/build/src/_routes/server/client-app/client-app.controller.js +35 -0
- package/build/src/_routes/server/config/config.control-service.js +476 -0
- package/build/src/_routes/server/config/config.data-service.js +49 -0
- package/build/src/_routes/server/errors/errors.control-service.js +123 -0
- package/build/src/_routes/server/errors/errors.controller.js +65 -0
- package/build/src/_routes/server/errors/errors.data-service.js +80 -0
- package/build/src/_routes/server/server-status/server-status.control-service.js +19 -0
- package/build/src/_routes/server/server-status/server-status.controller.js +39 -0
- package/build/src/app.server.js +122 -0
- package/build/src/environments/environment.js +20 -0
- package/build/src/index.js +18 -0
- package/client-dist/chunk-GHKRM4SM.js +1 -0
- package/client-dist/chunk-LMTL7GA3.js +575 -0
- package/client-dist/index.html +17 -0
- package/client-dist/main-2KWB3QYK.js +2 -0
- package/client-dist/polyfills-HGDOEU5L.js +2 -0
- package/client-dist/styles-3J7JD5YE.css +1 -0
- package/package.json +96 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FAM_Scan_ControlService = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const fs = tslib_1.__importStar(require("fs"));
|
|
6
|
+
const path = tslib_1.__importStar(require("path"));
|
|
7
|
+
const config_catalog_const_1 = require("../../../_collections/config-catalog.const");
|
|
8
|
+
const config_control_service_1 = require("../../../_routes/server/config/config.control-service");
|
|
9
|
+
const fam_file_routing_util_1 = require("../_collections/fam-file-routing.util");
|
|
10
|
+
const fam_glob_match_util_1 = require("../_collections/fam-glob-match.util");
|
|
11
|
+
const fam_scan_path_util_1 = require("../_collections/fam-scan-path.util");
|
|
12
|
+
const fam_secret_exclude_util_1 = require("../_collections/fam-secret-exclude.util");
|
|
13
|
+
/**
|
|
14
|
+
* `FAM_Scan_ControlService` (SP-4.1, dsgn-004 §1/§2/§6) — a `write(scan-*)` fájl-felderítő + routing
|
|
15
|
+
* + biztonsági belépési pontja. A `scan.path` (file/folder/project) biztonságos bejárása
|
|
16
|
+
* (path-traversal guard + ignore-patterns + secret-exclude + méret-plafon), majd minden felderített
|
|
17
|
+
* fájl `documents` / `codebase` / `skip` route-olása (dsgn-004 §2), MIELŐTT a chunkerek (SP-4.2)
|
|
18
|
+
* futnának. Az orchestrátor (`FAM_Ingest_ControlService`) ezt hívja a scope-resolve UTÁN.
|
|
19
|
+
*
|
|
20
|
+
* Singleton (a felderítés állapot-mentes; a config-resolve a `FAM_Config_ControlService`-en).
|
|
21
|
+
*
|
|
22
|
+
* **BOUNDARY:** ez NEM hívja a chunkert/embeddinget — csak felderít + route-ol. A `scopePath` itt
|
|
23
|
+
* MÁR canonical (a MP-3 `resolveForWrite` feloldotta az orchestrátorban). A scope-resolve hibája a
|
|
24
|
+
* scan ELŐTT bukik (a run `failed`), ezért ide már csak feloldott scope érkezik.
|
|
25
|
+
*/
|
|
26
|
+
class FAM_Scan_ControlService {
|
|
27
|
+
static _instance;
|
|
28
|
+
/** Default issuer a scan-műveletekhez. */
|
|
29
|
+
issuer = 'FAM_Scan_ControlService';
|
|
30
|
+
static getInstance() {
|
|
31
|
+
if (!FAM_Scan_ControlService._instance) {
|
|
32
|
+
FAM_Scan_ControlService._instance = new FAM_Scan_ControlService();
|
|
33
|
+
}
|
|
34
|
+
return FAM_Scan_ControlService._instance;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Egy scan-művelet fájl-felderítése + routingja (dsgn-004 §1/§2/§6). A `scan-file` egyetlen
|
|
38
|
+
* fájl; a `scan-folder`/`scan-project` rekurzív bejárás (a könyvtárakat az ignore-patterns
|
|
39
|
+
* bejárás KÖZBEN kihagyja — ne lépjen `node_modules`-ba). A secret-exclude a routing ELŐTT fut;
|
|
40
|
+
* a méret-plafon feletti / olvashatatlan / skip-routed fájlok a `skippedFiles`-be (audit, nem néma).
|
|
41
|
+
*/
|
|
42
|
+
async discover(set) {
|
|
43
|
+
const resolvedRoot = fam_scan_path_util_1.FAM_ScanPath_Util.resolveRoot(set.path, this.issuer);
|
|
44
|
+
const ignorePatterns = await this.resolveIgnorePatterns(set.scopePath, set.exclude);
|
|
45
|
+
const maxFileSizeBytes = await this.resolveMaxFileSize(set.scopePath);
|
|
46
|
+
const followSymlinks = await this.resolveFollowSymlinks(set.scopePath);
|
|
47
|
+
const routedFiles = [];
|
|
48
|
+
const skippedFiles = [];
|
|
49
|
+
// A felderített abszolút fájlok (file = 1 db; folder/project = rekurzív bejárás).
|
|
50
|
+
const absoluteFiles = set.operation === 'scan-file'
|
|
51
|
+
? [resolvedRoot]
|
|
52
|
+
: this.walkDirectory(resolvedRoot, resolvedRoot, ignorePatterns, followSymlinks);
|
|
53
|
+
for (const absolutePath of absoluteFiles) {
|
|
54
|
+
const relativePath = set.operation === 'scan-file'
|
|
55
|
+
? path.basename(resolvedRoot)
|
|
56
|
+
: fam_scan_path_util_1.FAM_ScanPath_Util.toRelative(resolvedRoot, absolutePath);
|
|
57
|
+
const routed = this.classifyFile({
|
|
58
|
+
absolutePath: absolutePath,
|
|
59
|
+
relativePath: relativePath,
|
|
60
|
+
ignorePatterns: ignorePatterns,
|
|
61
|
+
includePatterns: set.include,
|
|
62
|
+
maxFileSizeBytes: maxFileSizeBytes,
|
|
63
|
+
tableOverride: set.tableOverride,
|
|
64
|
+
});
|
|
65
|
+
if (routed.route === 'skip') {
|
|
66
|
+
skippedFiles.push(routed);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
routedFiles.push(routed);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
resolvedRoot: resolvedRoot,
|
|
74
|
+
routedFiles: routedFiles,
|
|
75
|
+
skippedFiles: skippedFiles,
|
|
76
|
+
tables: this.collectTables(routedFiles),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Egy fájl osztályozása (dsgn-004 §2/§6): a secret-exclude + ignore-patterns + include-szűrés +
|
|
81
|
+
* méret-plafon, majd a file-típus-routing (vagy `tableOverride`). A skip-okot a `skipReason`
|
|
82
|
+
* hordozza (audit). A vizsgálati sorrend: secret → ignore → include → size → route.
|
|
83
|
+
*/
|
|
84
|
+
classifyFile(set) {
|
|
85
|
+
const base = {
|
|
86
|
+
absolutePath: set.absolutePath,
|
|
87
|
+
relativePath: set.relativePath,
|
|
88
|
+
};
|
|
89
|
+
// (1) Secret-exclude (a routing ELŐTT, dsgn-004 §6.3) — SOHA nem ingestálódik.
|
|
90
|
+
if (fam_secret_exclude_util_1.FAM_SecretExclude_Util.isSecret(set.relativePath)) {
|
|
91
|
+
return { ...base, route: 'skip', skipReason: 'secret-exclude (filename/path-based; content-PII scan = BACKLOG)' };
|
|
92
|
+
}
|
|
93
|
+
// (2) Ignore-patterns (dsgn-004 §6.2) — node_modules/.git/build/dist/lock/... + a config + input-exclude.
|
|
94
|
+
if (fam_glob_match_util_1.FAM_GlobMatch_Util.matchesAny(set.relativePath, set.ignorePatterns)) {
|
|
95
|
+
return { ...base, route: 'skip', skipReason: 'ignore-pattern' };
|
|
96
|
+
}
|
|
97
|
+
// (3) Include-szűrés (ha megadva: csak az illeszkedő fájl megy tovább, dsgn-003 §3.1).
|
|
98
|
+
if (set.includePatterns && set.includePatterns.length && !fam_glob_match_util_1.FAM_GlobMatch_Util.matchesAny(set.relativePath, set.includePatterns)) {
|
|
99
|
+
return { ...base, route: 'skip', skipReason: 'include-filter' };
|
|
100
|
+
}
|
|
101
|
+
// (4) Méret-plafon (dsgn-004 §6.4) — az óriás-fájl ne fújja fel a memóriát/költséget.
|
|
102
|
+
const sizeBytes = this.fileSizeSafe(set.absolutePath);
|
|
103
|
+
if (sizeBytes > set.maxFileSizeBytes) {
|
|
104
|
+
return { ...base, route: 'skip', skipReason: `file too large (${sizeBytes} > ${set.maxFileSizeBytes} bytes)` };
|
|
105
|
+
}
|
|
106
|
+
// (5) File-típus-routing (vagy explicit tableOverride, dsgn-004 §2).
|
|
107
|
+
const route = set.tableOverride ?? fam_file_routing_util_1.FAM_FileRouting_Util.route(set.relativePath);
|
|
108
|
+
if (route === 'skip') {
|
|
109
|
+
return { ...base, route: 'skip', skipReason: 'unrouted file-type' };
|
|
110
|
+
}
|
|
111
|
+
return { ...base, route: route };
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Rekurzív könyvtár-bejárás (a `scan-folder`/`scan-project` felderítője). Az ignore-patterns a
|
|
115
|
+
* KÖNYVTÁRAKAT bejárás KÖZBEN kihagyja (ne lépjen `node_modules`-ba — teljesítmény + biztonság).
|
|
116
|
+
* A symlinkeket alapból NEM követi (`followSymlinks` config); a path-traversal guardot minden
|
|
117
|
+
* fájlra futtatja (a feloldott valódi útvonal a gyökér alatt kell maradjon).
|
|
118
|
+
*/
|
|
119
|
+
walkDirectory(currentDir, resolvedRoot, ignorePatterns, followSymlinks) {
|
|
120
|
+
const result = [];
|
|
121
|
+
let entries;
|
|
122
|
+
try {
|
|
123
|
+
entries = fs.readdirSync(currentDir, { withFileTypes: true });
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
// Olvashatatlan könyvtár → kihagyjuk (a per-fájl olvasás-hiba a chunk-fázisban kezelt).
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
129
|
+
for (const entry of entries) {
|
|
130
|
+
const entryPath = path.join(currentDir, entry.name);
|
|
131
|
+
const relativePath = fam_scan_path_util_1.FAM_ScanPath_Util.toRelative(resolvedRoot, entryPath);
|
|
132
|
+
// Symlink-kezelés: alapból NEM követjük (path-traversal védelem, dsgn-004 §6.1).
|
|
133
|
+
if (entry.isSymbolicLink() && !followSymlinks) {
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
if (entry.isDirectory()) {
|
|
137
|
+
// Az ignore-patterns a könyvtárat bejárás közben kihagyja (ne lépjen be).
|
|
138
|
+
if (fam_glob_match_util_1.FAM_GlobMatch_Util.matchesAny(relativePath, ignorePatterns)
|
|
139
|
+
|| fam_glob_match_util_1.FAM_GlobMatch_Util.matchesAny(relativePath + '/', ignorePatterns)) {
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
// Path-traversal guard (a feloldott valódi útvonal a gyökér alatt kell maradjon).
|
|
143
|
+
if (!this.isInsideRootSafe(resolvedRoot, entryPath)) {
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
result.push(...this.walkDirectory(entryPath, resolvedRoot, ignorePatterns, followSymlinks));
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
if (entry.isFile()) {
|
|
150
|
+
if (this.isInsideRootSafe(resolvedRoot, entryPath)) {
|
|
151
|
+
result.push(entryPath);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return result;
|
|
156
|
+
}
|
|
157
|
+
/** Path-traversal guard egy bejárt útvonalra (a guard-hiba itt csendes-skip, nem run-bukás). */
|
|
158
|
+
isInsideRootSafe(resolvedRoot, candidatePath) {
|
|
159
|
+
try {
|
|
160
|
+
const real = fs.realpathSync(candidatePath);
|
|
161
|
+
return fam_scan_path_util_1.FAM_ScanPath_Util.isInside(resolvedRoot, real);
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/** Egy fájl mérete byte-ban (olvashatatlan → `Number.MAX_SAFE_INTEGER`, hogy a méret-plafon kiszűrje). */
|
|
168
|
+
fileSizeSafe(absolutePath) {
|
|
169
|
+
try {
|
|
170
|
+
return fs.statSync(absolutePath).size;
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
return Number.MAX_SAFE_INTEGER;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* A route-olt fájlok érintett tárai (a nem-`skip` route-ok uniója; scan-project többet is
|
|
178
|
+
* érinthet). Automata routingnál `documents`/`codebase`; `tableOverride`-nál bármely fő tár.
|
|
179
|
+
*/
|
|
180
|
+
collectTables(routedFiles) {
|
|
181
|
+
const tables = new Set();
|
|
182
|
+
for (const file of routedFiles) {
|
|
183
|
+
if (file.route !== 'skip') {
|
|
184
|
+
tables.add(file.route);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return Array.from(tables);
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Az effektív ignore-patterns: a config `scan.ignorePatterns` (default `SCAN_IGNORE_PATTERNS_DEFAULT`)
|
|
191
|
+
* + az input `exclude` HOZZÁADVA (dsgn-004 §6.2 — a `write.scan.exclude` HOZZÁADÓDIK, NEM felülír).
|
|
192
|
+
*/
|
|
193
|
+
async resolveIgnorePatterns(scopePath, exclude) {
|
|
194
|
+
const resolved = await config_control_service_1.FAM_Config_ControlService.getInstance().resolve('scan.ignorePatterns', { scopePath: scopePath });
|
|
195
|
+
const configPatterns = Array.isArray(resolved.value)
|
|
196
|
+
? resolved.value.filter((item) => typeof item === 'string')
|
|
197
|
+
: config_catalog_const_1.SCAN_IGNORE_PATTERNS_DEFAULT;
|
|
198
|
+
return [...configPatterns, ...(exclude ?? [])];
|
|
199
|
+
}
|
|
200
|
+
/** A méret-plafon a config-ból (`scan.maxFileSizeBytes`, default 1 MB). */
|
|
201
|
+
async resolveMaxFileSize(scopePath) {
|
|
202
|
+
const resolved = await config_control_service_1.FAM_Config_ControlService.getInstance().resolve('scan.maxFileSizeBytes', { scopePath: scopePath });
|
|
203
|
+
return typeof resolved.value === 'number' ? resolved.value : 1048576;
|
|
204
|
+
}
|
|
205
|
+
/** A symlink-követés a config-ból (`scan.followSymlinks`, default false — path-traversal védelem). */
|
|
206
|
+
async resolveFollowSymlinks(scopePath) {
|
|
207
|
+
const resolved = await config_control_service_1.FAM_Config_ControlService.getInstance().resolve('scan.followSymlinks', { scopePath: scopePath });
|
|
208
|
+
return typeof resolved.value === 'boolean' ? resolved.value : false;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
exports.FAM_Scan_ControlService = FAM_Scan_ControlService;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* `ingest` modul barrel (MP-4, dsgn-004) — a scan → chunk → delta → embed → persist ingest-engine
|
|
4
|
+
* publikus felülete. A fogyasztó-MP-k (MP-6 `write` MCP-eszköz / REST a `scanFile`/`scanFolder`/
|
|
5
|
+
* `scanProject`-hez + `list_scan_runs`/delete-run capability) innen importálnak.
|
|
6
|
+
*
|
|
7
|
+
* Boundary (dsgn-004 BOUNDARY): MP-4 az ingest-ENGINE — a scan-t TRIGGERELŐ MCP-tool / REST = MP-6;
|
|
8
|
+
* a retrieval = MP-5. A markdown-chunker NEM a Dynamo `DyNTS_DAI_DocChunking_Util`-t használja
|
|
9
|
+
* (az ClickUp-domain-kötött, nem plain string-API), hanem a CCAP header-aware algoritmus
|
|
10
|
+
* projekt-lokális portját (BFR-AM-005 mintára). PDF + dataflow/runflow code-intelligence + aktív
|
|
11
|
+
* file-watch = BACKLOG (dsgn-004 §2/§3 megjegyzés). A tartalmi PII/secret-detektálás = BACKLOG
|
|
12
|
+
* (MVP1 csak fájlnév-/útvonal-alapú secret-exclude).
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.FAM_IngestRun_DataService = exports.FAM_ContentHash_Util = exports.FAM_DeltaCompare_Util = exports.FAM_SlidingChunker_Util = exports.FAM_MdChunker_Util = exports.FAM_TsChunker_Util = exports.FAM_Chunker_ControlService = exports.FAM_GlobMatch_Util = exports.FAM_SecretExclude_Util = exports.FAM_ScanPath_Util = exports.FAM_FileRouting_Util = exports.FAM_Scan_ControlService = exports.FAM_Ingest_ControlService = void 0;
|
|
16
|
+
// SP-4.4 — ingest-orchestrátor (a `write(scan-*)` belépési pontja + group-by-run/delete-run)
|
|
17
|
+
var fam_ingest_control_service_1 = require("./_services/fam-ingest.control-service");
|
|
18
|
+
Object.defineProperty(exports, "FAM_Ingest_ControlService", { enumerable: true, get: function () { return fam_ingest_control_service_1.FAM_Ingest_ControlService; } });
|
|
19
|
+
// SP-4.1 — scan + felderítés + routing + security
|
|
20
|
+
var fam_scan_control_service_1 = require("./_services/fam-scan.control-service");
|
|
21
|
+
Object.defineProperty(exports, "FAM_Scan_ControlService", { enumerable: true, get: function () { return fam_scan_control_service_1.FAM_Scan_ControlService; } });
|
|
22
|
+
var fam_file_routing_util_1 = require("./_collections/fam-file-routing.util");
|
|
23
|
+
Object.defineProperty(exports, "FAM_FileRouting_Util", { enumerable: true, get: function () { return fam_file_routing_util_1.FAM_FileRouting_Util; } });
|
|
24
|
+
var fam_scan_path_util_1 = require("./_collections/fam-scan-path.util");
|
|
25
|
+
Object.defineProperty(exports, "FAM_ScanPath_Util", { enumerable: true, get: function () { return fam_scan_path_util_1.FAM_ScanPath_Util; } });
|
|
26
|
+
var fam_secret_exclude_util_1 = require("./_collections/fam-secret-exclude.util");
|
|
27
|
+
Object.defineProperty(exports, "FAM_SecretExclude_Util", { enumerable: true, get: function () { return fam_secret_exclude_util_1.FAM_SecretExclude_Util; } });
|
|
28
|
+
var fam_glob_match_util_1 = require("./_collections/fam-glob-match.util");
|
|
29
|
+
Object.defineProperty(exports, "FAM_GlobMatch_Util", { enumerable: true, get: function () { return fam_glob_match_util_1.FAM_GlobMatch_Util; } });
|
|
30
|
+
// SP-4.2 — chunkerek (dispatch + project-local utils)
|
|
31
|
+
var fam_chunker_control_service_1 = require("./_services/fam-chunker.control-service");
|
|
32
|
+
Object.defineProperty(exports, "FAM_Chunker_ControlService", { enumerable: true, get: function () { return fam_chunker_control_service_1.FAM_Chunker_ControlService; } });
|
|
33
|
+
var fam_ts_chunker_util_1 = require("./_collections/fam-ts-chunker.util");
|
|
34
|
+
Object.defineProperty(exports, "FAM_TsChunker_Util", { enumerable: true, get: function () { return fam_ts_chunker_util_1.FAM_TsChunker_Util; } });
|
|
35
|
+
var fam_md_chunker_util_1 = require("./_collections/fam-md-chunker.util");
|
|
36
|
+
Object.defineProperty(exports, "FAM_MdChunker_Util", { enumerable: true, get: function () { return fam_md_chunker_util_1.FAM_MdChunker_Util; } });
|
|
37
|
+
var fam_sliding_chunker_util_1 = require("./_collections/fam-sliding-chunker.util");
|
|
38
|
+
Object.defineProperty(exports, "FAM_SlidingChunker_Util", { enumerable: true, get: function () { return fam_sliding_chunker_util_1.FAM_SlidingChunker_Util; } });
|
|
39
|
+
// SP-4.3 — idempotens delta-detection
|
|
40
|
+
var fam_delta_compare_util_1 = require("./_services/fam-delta-compare.util");
|
|
41
|
+
Object.defineProperty(exports, "FAM_DeltaCompare_Util", { enumerable: true, get: function () { return fam_delta_compare_util_1.FAM_DeltaCompare_Util; } });
|
|
42
|
+
var fam_content_hash_util_1 = require("./_collections/fam-content-hash.util");
|
|
43
|
+
Object.defineProperty(exports, "FAM_ContentHash_Util", { enumerable: true, get: function () { return fam_content_hash_util_1.FAM_ContentHash_Util; } });
|
|
44
|
+
// SP-4.4 — ingest-run tracking
|
|
45
|
+
var fam_ingest_run_data_service_1 = require("./_services/fam-ingest-run.data-service");
|
|
46
|
+
Object.defineProperty(exports, "FAM_IngestRun_DataService", { enumerable: true, get: function () { return fam_ingest_run_data_service_1.FAM_IngestRun_DataService; } });
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FAM_CORE_TOOLS = void 0;
|
|
4
|
+
const fam_table_type_enum_1 = require("../../../_enums/fam-table.type-enum");
|
|
5
|
+
const fam_read_tool_service_1 = require("../_services/fam-read-tool.service");
|
|
6
|
+
const fam_write_tool_service_1 = require("../_services/fam-write-tool.service");
|
|
7
|
+
const fam_capabilities_tool_service_1 = require("../_services/fam-capabilities-tool.service");
|
|
8
|
+
/**
|
|
9
|
+
* A 3 ADVERTISED MCP core-tool definíciója (SP-6.1/6.2/6.3/6.4, dsgn-003 §2/§3/§4/§5). EZ a
|
|
10
|
+
* single-source a `read`/`write`/`capabilities` hirdetett tool-listához — a stdio `tools/list` PONTOSAN
|
|
11
|
+
* ezt a 3-at adja vissza (dsgn-003 §6.1), a speciális eszközök NEM kerülnek ide (csak a
|
|
12
|
+
* `FAM_CapabilityRegistry`-ben élnek — diszjunkció, dsgn-003 §6.6).
|
|
13
|
+
*
|
|
14
|
+
* Minden tool: agent-barát `description` (mely tár milyen tudást tárol, dsgn-003 §5) + JSON-schema
|
|
15
|
+
* input + handler (a transport-agnosztikus core-service-re delegál; a REST UGYANEZT hívja).
|
|
16
|
+
*/
|
|
17
|
+
/** A 6 fő RAG-tár leírása az LLM tár-választásához (dsgn-003 §5). */
|
|
18
|
+
const TABLE_GUIDE = 'Tárak: `rules` (kódolási/architektúra/viselkedési szabályok), `documents` (specifikációk, dev-jegyzetek, '
|
|
19
|
+
+ 'dokumentáció), `codebase` (forráskód-chunkok, szimbólumok), `knowledge` (tények, fogalmak, '
|
|
20
|
+
+ 'döntés-indoklás), `coding_patterns` (minták, anti-minták, receptek), `memory` (session-/fejlesztés-/'
|
|
21
|
+
+ 'incidens-történet, lessons-learned, user-preferenciák). A `reference` helper (alias/fogalom-feloldás) '
|
|
22
|
+
+ 'NEM kereshető/írható közvetlenül.';
|
|
23
|
+
/** A `read` query `tables` enum-értékei a fő tárak (a `reference` nem szerepel — helper). */
|
|
24
|
+
const MAIN_TABLE_ENUM = Object.values(fam_table_type_enum_1.FAM_Table).filter((table) => table !== fam_table_type_enum_1.FAM_Table.reference);
|
|
25
|
+
/** A nyers scope-lánc array-schema (`{ layer, rawName }[]`). */
|
|
26
|
+
const SCOPE_LAYER_ARRAY = {
|
|
27
|
+
type: 'array',
|
|
28
|
+
description: 'Nyers scope-lánc (root→leaf): [{ layer, rawName }] párok (pl. organization=FutDevPro, project=Adventor).',
|
|
29
|
+
items: {
|
|
30
|
+
type: 'object',
|
|
31
|
+
properties: {
|
|
32
|
+
layer: { type: 'string', description: 'A dinamikus layer-név (pl. organization/project/module).' },
|
|
33
|
+
rawName: { type: 'string', description: 'A nyers (feloldatlan) scope-név (typo/STT/fonetikus is).' },
|
|
34
|
+
},
|
|
35
|
+
required: ['layer', 'rawName'],
|
|
36
|
+
additionalProperties: false,
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
/** A `read` tool input JSON-schema-ja (dsgn-003 §2.1). */
|
|
40
|
+
const READ_INPUT_SCHEMA = {
|
|
41
|
+
type: 'object',
|
|
42
|
+
properties: {
|
|
43
|
+
queries: {
|
|
44
|
+
type: 'array',
|
|
45
|
+
description: 'Egy hívásban több, különböző táras + különböző kifejezésű query.',
|
|
46
|
+
items: {
|
|
47
|
+
type: 'object',
|
|
48
|
+
properties: {
|
|
49
|
+
tables: {
|
|
50
|
+
type: 'array',
|
|
51
|
+
description: '1+ fő tár (a `reference` TILOS — helper).',
|
|
52
|
+
items: { type: 'string', enum: MAIN_TABLE_ENUM },
|
|
53
|
+
},
|
|
54
|
+
query: { type: 'string', description: 'A keresési phrase.' },
|
|
55
|
+
topK: { type: 'number', description: 'Találat-limit query-nként (config-default 5).' },
|
|
56
|
+
minScore: { type: 'number', description: 'Minimum similarity-score küszöb.' },
|
|
57
|
+
scopeFilter: SCOPE_LAYER_ARRAY,
|
|
58
|
+
tagFilter: { type: 'array', items: { type: 'string' }, description: 'Tag-szűrő (OR).' },
|
|
59
|
+
kindFilter: { type: 'string', description: 'Egyetlen kind-szűrő.' },
|
|
60
|
+
},
|
|
61
|
+
required: ['tables', 'query'],
|
|
62
|
+
additionalProperties: false,
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
includeContent: {
|
|
66
|
+
type: 'boolean', default: true,
|
|
67
|
+
description: 'Default true: a hit-ek `content`-tel térnek vissza (single-pass). false → kompakt lista.',
|
|
68
|
+
},
|
|
69
|
+
globalScopeFilter: SCOPE_LAYER_ARRAY,
|
|
70
|
+
},
|
|
71
|
+
required: ['queries'],
|
|
72
|
+
additionalProperties: false,
|
|
73
|
+
};
|
|
74
|
+
/** A `write` tool input JSON-schema-ja (dsgn-003 §3.1). */
|
|
75
|
+
const WRITE_INPUT_SCHEMA = {
|
|
76
|
+
type: 'object',
|
|
77
|
+
properties: {
|
|
78
|
+
table: {
|
|
79
|
+
type: 'string', enum: Object.values(fam_table_type_enum_1.FAM_Table),
|
|
80
|
+
description: 'PONTOSAN egy fő tár (vagy `reference` a helper-CRUD-hoz).',
|
|
81
|
+
},
|
|
82
|
+
operation: {
|
|
83
|
+
type: 'string',
|
|
84
|
+
enum: ['create', 'update', 'delete', 'scan-file', 'scan-folder', 'scan-project', 're-embed', 'import'],
|
|
85
|
+
description: 'A művelet (create/update/delete/scan-*/re-embed/import).',
|
|
86
|
+
},
|
|
87
|
+
scopePath: SCOPE_LAYER_ARRAY,
|
|
88
|
+
kind: { type: 'string', description: 'Opcionális kind (per-tár default).' },
|
|
89
|
+
tags: { type: 'array', items: { type: 'string' }, description: 'Opcionális tagek.' },
|
|
90
|
+
content: { type: 'string', description: 'create/update tartalom (a vektorizálandó szöveg).' },
|
|
91
|
+
fields: { type: 'object', description: 'Per-tár specifikus mezők (dsgn-001 §4).', additionalProperties: true },
|
|
92
|
+
weight: { type: 'number', description: 'Opcionális retrieval-súly (default 1; coding_patterns 5).' },
|
|
93
|
+
importance: { type: 'number', description: 'Opcionális kvalitatív hangsúly (0..1).' },
|
|
94
|
+
target: {
|
|
95
|
+
type: 'object',
|
|
96
|
+
description: 'update/delete cél-azonosítás.',
|
|
97
|
+
properties: {
|
|
98
|
+
by: { type: 'string', enum: ['id', 'sourceFilePath', 'query'] },
|
|
99
|
+
value: { type: 'string' },
|
|
100
|
+
},
|
|
101
|
+
required: ['by', 'value'],
|
|
102
|
+
additionalProperties: false,
|
|
103
|
+
},
|
|
104
|
+
scan: {
|
|
105
|
+
type: 'object',
|
|
106
|
+
description: 'scan-* opciók (a scan-gyökér + glob-szűrők + dryRun).',
|
|
107
|
+
properties: {
|
|
108
|
+
path: { type: 'string', description: 'A scan-gyökér (file/folder/project).' },
|
|
109
|
+
include: { type: 'array', items: { type: 'string' } },
|
|
110
|
+
exclude: { type: 'array', items: { type: 'string' } },
|
|
111
|
+
dryRun: { type: 'boolean', description: 'Csak felderítés (NINCS embed+persist).' },
|
|
112
|
+
},
|
|
113
|
+
required: ['path'],
|
|
114
|
+
additionalProperties: false,
|
|
115
|
+
},
|
|
116
|
+
import: {
|
|
117
|
+
type: 'object',
|
|
118
|
+
description: 'import opciók (claude-mem migráció; a MP-11 engine thin-wrapper-én át — dsgn-009).',
|
|
119
|
+
properties: {
|
|
120
|
+
source: { type: 'string', description: 'Az import-forrás (claude-mem).' },
|
|
121
|
+
from: { type: 'string', enum: ['sqlite', 'export-json', 'worker-api'] },
|
|
122
|
+
path: { type: 'string' },
|
|
123
|
+
},
|
|
124
|
+
required: ['source'],
|
|
125
|
+
additionalProperties: false,
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
required: ['table', 'operation'],
|
|
129
|
+
additionalProperties: false,
|
|
130
|
+
};
|
|
131
|
+
/** A `capabilities` tool input JSON-schema-ja (dsgn-003 §4.1). */
|
|
132
|
+
const CAPABILITIES_INPUT_SCHEMA = {
|
|
133
|
+
type: 'object',
|
|
134
|
+
properties: {
|
|
135
|
+
action: {
|
|
136
|
+
type: 'string', enum: ['list', 'describe', 'invoke'],
|
|
137
|
+
description: 'list (katalógus) / describe(name) (schema) / invoke(name, arguments) (futtatás).',
|
|
138
|
+
},
|
|
139
|
+
category: { type: 'string', description: 'Opcionális kategória-szűrés (`list`).' },
|
|
140
|
+
name: { type: 'string', description: 'A cél-eszköz neve (`describe`/`invoke` kötelező).' },
|
|
141
|
+
arguments: { type: 'object', description: 'Az `invoke` argumentumai.', additionalProperties: true },
|
|
142
|
+
},
|
|
143
|
+
required: ['action'],
|
|
144
|
+
additionalProperties: false,
|
|
145
|
+
};
|
|
146
|
+
/**
|
|
147
|
+
* A 3 advertised core-tool. A handler-ek a transport-agnosztikus core-service-ekre delegálnak — a
|
|
148
|
+
* REST-réteg (SP-6.5) UGYANEZEKET a service-eket hívja (paritás-garancia). A `read`/`capabilities`
|
|
149
|
+
* handler a `data`-t adja vissza; a `write` szintén (a strukturált output a `data`).
|
|
150
|
+
*/
|
|
151
|
+
exports.FAM_CORE_TOOLS = [
|
|
152
|
+
{
|
|
153
|
+
name: 'read',
|
|
154
|
+
description: 'Tudás keresése / lekérése / context-fetch — egylépcsős, MINDIG tartalommal. Egy hívásban '
|
|
155
|
+
+ 'több tár + több query. ' + TABLE_GUIDE + ' A válasz dense-jelzést is ad (denseResults/totalRelevant/'
|
|
156
|
+
+ 'truncated + javasolt szűrők), ha a találat túl sűrű.',
|
|
157
|
+
inputSchema: READ_INPUT_SCHEMA,
|
|
158
|
+
handler: async (args) => {
|
|
159
|
+
const data = await fam_read_tool_service_1.FAM_ReadTool_Service.getInstance().handle(args);
|
|
160
|
+
return { data: data };
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
name: 'write',
|
|
165
|
+
description: 'Tudás mentése / módosítása / törlése / scan / re-embed / import — explicit, PONTOSAN 1 tár. '
|
|
166
|
+
+ 'A scope KÖTELEZŐ minden tartalom-műveletnél (create/scan-*/import). ' + TABLE_GUIDE
|
|
167
|
+
+ ' A `delete` soft-delete; a scan automatikusan chunkol + embeddel (idempotens delta).',
|
|
168
|
+
inputSchema: WRITE_INPUT_SCHEMA,
|
|
169
|
+
handler: async (args) => {
|
|
170
|
+
const data = await fam_write_tool_service_1.FAM_WriteTool_Service.getInstance().handle(args);
|
|
171
|
+
return { data: data };
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
name: 'capabilities',
|
|
176
|
+
description: 'A ritkán használt speciális eszközök (config/diagnosztika, statisztika, inspekció, '
|
|
177
|
+
+ 'karbantartás, import-migráció, debug) felderítése + meghívása EGYETLEN tool-on át. '
|
|
178
|
+
+ 'action=list (katalógus) | describe (egy eszköz schema-ja) | invoke (egy eszköz futtatása). '
|
|
179
|
+
+ 'Így az agent context tiszta marad (csak 3 advertised tool).',
|
|
180
|
+
inputSchema: CAPABILITIES_INPUT_SCHEMA,
|
|
181
|
+
handler: async (args) => {
|
|
182
|
+
const data = await fam_capabilities_tool_service_1.FAM_CapabilitiesTool_Service.getInstance().handle(args);
|
|
183
|
+
return { data: data };
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
];
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FAM_WriteOperation = exports.FAM_CapabilityCategory = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* A speciális (capability-only) eszköz-kategóriák (dsgn-003 §4.2). A `list` action ezekre csoportosít.
|
|
6
|
+
* Enum-konvenció (workspace base): key camelCase, value kebab-case.
|
|
7
|
+
*/
|
|
8
|
+
var FAM_CapabilityCategory;
|
|
9
|
+
(function (FAM_CapabilityCategory) {
|
|
10
|
+
FAM_CapabilityCategory["configDiagnostics"] = "config-diagnostics";
|
|
11
|
+
FAM_CapabilityCategory["highLevelStats"] = "high-level-stats";
|
|
12
|
+
FAM_CapabilityCategory["inspection"] = "inspection";
|
|
13
|
+
FAM_CapabilityCategory["maintenance"] = "maintenance";
|
|
14
|
+
FAM_CapabilityCategory["importMigration"] = "import-migration";
|
|
15
|
+
FAM_CapabilityCategory["debug"] = "debug";
|
|
16
|
+
})(FAM_CapabilityCategory || (exports.FAM_CapabilityCategory = FAM_CapabilityCategory = {}));
|
|
17
|
+
/**
|
|
18
|
+
* A `write` művelet-fajtái (dsgn-003 §3.1 operation enum). Enum-konvenció: key camelCase, value
|
|
19
|
+
* kebab-case (a wire-érték a dsgn-003 string-je).
|
|
20
|
+
*/
|
|
21
|
+
var FAM_WriteOperation;
|
|
22
|
+
(function (FAM_WriteOperation) {
|
|
23
|
+
FAM_WriteOperation["create"] = "create";
|
|
24
|
+
FAM_WriteOperation["update"] = "update";
|
|
25
|
+
FAM_WriteOperation["delete"] = "delete";
|
|
26
|
+
FAM_WriteOperation["scanFile"] = "scan-file";
|
|
27
|
+
FAM_WriteOperation["scanFolder"] = "scan-folder";
|
|
28
|
+
FAM_WriteOperation["scanProject"] = "scan-project";
|
|
29
|
+
FAM_WriteOperation["reEmbed"] = "re-embed";
|
|
30
|
+
FAM_WriteOperation["import"] = "import";
|
|
31
|
+
})(FAM_WriteOperation || (exports.FAM_WriteOperation = FAM_WriteOperation = {}));
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FAM_CapabilitiesTool_Service = void 0;
|
|
4
|
+
const error_codes_const_1 = require("../../../_collections/error-codes.const");
|
|
5
|
+
const fam_error_factory_util_1 = require("../../../_collections/fam-error-factory.util");
|
|
6
|
+
const fam_capability_registry_service_1 = require("./fam-capability-registry.service");
|
|
7
|
+
/**
|
|
8
|
+
* `FAM_CapabilitiesTool_Service` (SP-6.4, dsgn-003 §4) — a `capabilities` core-tool handler-je.
|
|
9
|
+
* Singleton. EGY belépési pont (`handle`), amit MIND az MCP-tool, MIND a REST `POST /capabilities` hív.
|
|
10
|
+
*
|
|
11
|
+
* Három action (dsgn-003 §4.1):
|
|
12
|
+
* - `list` → kategóriák + tool-nevek + egysoros leírás (a `FAM_CapabilityRegistry`-ből, single-source),
|
|
13
|
+
* - `describe(name)` → a tool teljes input-schema-ja + kategória + leírás,
|
|
14
|
+
* - `invoke(name, arguments)` → a capability handler futtatása + eredmény (vagy strukturált hiba).
|
|
15
|
+
*
|
|
16
|
+
* **Diszjunkció (dsgn-003 §6.6):** ez az EGYETLEN út a speciális eszközökhöz — azok SOHA nem
|
|
17
|
+
* advertised tool-ok. Ismeretlen `name` → `FAM-MCP-DISPATCH-002`; late-bind capability `invoke`-ja →
|
|
18
|
+
* clear "pending MP-X" hiba (a registry handler-éből). Néma hiba TILOS.
|
|
19
|
+
*/
|
|
20
|
+
class FAM_CapabilitiesTool_Service {
|
|
21
|
+
static _instance;
|
|
22
|
+
/** Default issuer (a dispatch-hibák issuer-éhez; dsgn-008). */
|
|
23
|
+
issuer = 'FAM_CapabilitiesTool_Service';
|
|
24
|
+
static getInstance() {
|
|
25
|
+
if (!FAM_CapabilitiesTool_Service._instance) {
|
|
26
|
+
FAM_CapabilitiesTool_Service._instance = new FAM_CapabilitiesTool_Service();
|
|
27
|
+
}
|
|
28
|
+
return FAM_CapabilitiesTool_Service._instance;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* A `capabilities` core-handler (dsgn-003 §4.1). A `action` választ a list/describe/invoke között;
|
|
32
|
+
* a `describe`/`invoke` `name`-et igényel. Az `invoke` a registry handler-ét futtatja (a dobott
|
|
33
|
+
* `DyFM_Error`-t az adaptor/REST egységesen strukturált hibává fordítja).
|
|
34
|
+
*/
|
|
35
|
+
async handle(input) {
|
|
36
|
+
const action = input?.action;
|
|
37
|
+
switch (action) {
|
|
38
|
+
case 'list':
|
|
39
|
+
return this.handleList(input.category);
|
|
40
|
+
case 'describe':
|
|
41
|
+
return this.handleDescribe(input.name);
|
|
42
|
+
case 'invoke':
|
|
43
|
+
return this.handleInvoke(input.name, input.arguments);
|
|
44
|
+
default:
|
|
45
|
+
throw fam_error_factory_util_1.FAM_Error_Util.create({
|
|
46
|
+
errorCode: error_codes_const_1.FAM_ERROR_CODES.mcpSchemaMismatch,
|
|
47
|
+
message: `Ismeretlen \`capabilities\` action: '${action}'. Megengedett: list | describe | invoke.`,
|
|
48
|
+
issuer: this.issuer,
|
|
49
|
+
context: { operation: 'capabilities-dispatch' },
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/** `list` → kategória → tool-nevek + egysoros leírás (a registry single-source-ból). */
|
|
54
|
+
handleList(category) {
|
|
55
|
+
const descriptors = fam_capability_registry_service_1.FAM_CapabilityRegistry.getInstance().list(category);
|
|
56
|
+
const byCategory = {};
|
|
57
|
+
for (const descriptor of descriptors) {
|
|
58
|
+
const bucket = byCategory[descriptor.category] ?? [];
|
|
59
|
+
bucket.push({
|
|
60
|
+
name: descriptor.name,
|
|
61
|
+
description: descriptor.description,
|
|
62
|
+
lateBound: descriptor.lateBound === true,
|
|
63
|
+
});
|
|
64
|
+
byCategory[descriptor.category] = bucket;
|
|
65
|
+
}
|
|
66
|
+
return { categories: byCategory, total: descriptors.length };
|
|
67
|
+
}
|
|
68
|
+
/** `describe(name)` → a cél-eszköz teljes input-schema-ja + meta. Ismeretlen → `FAM-MCP-DISPATCH-002`. */
|
|
69
|
+
handleDescribe(name) {
|
|
70
|
+
const descriptor = this.requireDescriptor(name, 'capabilities-describe');
|
|
71
|
+
return {
|
|
72
|
+
name: descriptor.name,
|
|
73
|
+
category: descriptor.category,
|
|
74
|
+
description: descriptor.description,
|
|
75
|
+
inputSchema: descriptor.inputSchema,
|
|
76
|
+
lateBound: descriptor.lateBound === true,
|
|
77
|
+
pendingMp: descriptor.pendingMp,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
/** `invoke(name, arguments)` → a capability handler futtatása. Ismeretlen → `FAM-MCP-DISPATCH-002`. */
|
|
81
|
+
async handleInvoke(name, args) {
|
|
82
|
+
const descriptor = this.requireDescriptor(name, 'capabilities-invoke');
|
|
83
|
+
const outcome = await descriptor.handler(args);
|
|
84
|
+
return outcome.data;
|
|
85
|
+
}
|
|
86
|
+
/** A cél-deszkriptor a nevéből; hiányzó/ismeretlen → `FAM-MCP-DISPATCH-002` (deskriptív). */
|
|
87
|
+
requireDescriptor(name, operation) {
|
|
88
|
+
if (!name) {
|
|
89
|
+
throw fam_error_factory_util_1.FAM_Error_Util.create({
|
|
90
|
+
errorCode: error_codes_const_1.FAM_ERROR_CODES.mcpDispatchUnknownCapability,
|
|
91
|
+
message: 'A `describe`/`invoke` action `name`-et igényel (a cél capability-eszköz neve). '
|
|
92
|
+
+ 'Használd a `list` action-t a katalógus felderítéséhez.',
|
|
93
|
+
issuer: this.issuer,
|
|
94
|
+
context: { operation: operation },
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
const descriptor = fam_capability_registry_service_1.FAM_CapabilityRegistry.getInstance().get(name);
|
|
98
|
+
if (!descriptor) {
|
|
99
|
+
const known = fam_capability_registry_service_1.FAM_CapabilityRegistry.getInstance().names();
|
|
100
|
+
throw fam_error_factory_util_1.FAM_Error_Util.create({
|
|
101
|
+
errorCode: error_codes_const_1.FAM_ERROR_CODES.mcpDispatchUnknownCapability,
|
|
102
|
+
message: `Ismeretlen capability: '${name}'. Elérhető (${known.length}): ${known.slice(0, 12).join(', ')}…. `
|
|
103
|
+
+ 'Használd a `capabilities { action: "list" }`-et a teljes katalógushoz.',
|
|
104
|
+
issuer: this.issuer,
|
|
105
|
+
context: { operation: operation },
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
return descriptor;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
exports.FAM_CapabilitiesTool_Service = FAM_CapabilitiesTool_Service;
|