@frontmcp/plugin-skilled-openapi 1.2.1 → 1.4.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/esm/index.mjs
CHANGED
|
@@ -372,9 +372,10 @@ var BundleSyncService = class {
|
|
|
372
372
|
if (this.options.exposeOperationsAsInternalTools && this.operationToolFactory) {
|
|
373
373
|
try {
|
|
374
374
|
this.operationToolFactory.unregisterAll();
|
|
375
|
+
const pathsWithGet = collectPathsWithGet(this.hiddenOps.values());
|
|
375
376
|
for (const entry of this.hiddenOps.values()) {
|
|
376
377
|
try {
|
|
377
|
-
this.operationToolFactory.register(entry);
|
|
378
|
+
this.operationToolFactory.register(entry, { pathsWithGet });
|
|
378
379
|
} catch (regErr) {
|
|
379
380
|
this.logger.warn(
|
|
380
381
|
`[bundle-sync] internal-tool register failed for ${entry.bundleId}.${entry.op.operationId}: ${regErr.message}`
|
|
@@ -401,9 +402,10 @@ var BundleSyncService = class {
|
|
|
401
402
|
if (this.options.exposeOperationsAsInternalTools && this.operationToolFactory) {
|
|
402
403
|
try {
|
|
403
404
|
this.operationToolFactory.unregisterAll();
|
|
405
|
+
const pathsWithGet = collectPathsWithGet(snapshotEntries);
|
|
404
406
|
for (const entry of snapshotEntries) {
|
|
405
407
|
try {
|
|
406
|
-
this.operationToolFactory.register(entry);
|
|
408
|
+
this.operationToolFactory.register(entry, { pathsWithGet });
|
|
407
409
|
} catch {
|
|
408
410
|
}
|
|
409
411
|
}
|
|
@@ -500,6 +502,15 @@ var BundleSyncService = class {
|
|
|
500
502
|
}
|
|
501
503
|
}
|
|
502
504
|
};
|
|
505
|
+
function collectPathsWithGet(entries) {
|
|
506
|
+
const set = /* @__PURE__ */ new Set();
|
|
507
|
+
for (const entry of entries) {
|
|
508
|
+
if (typeof entry.op.httpMethod === "string" && entry.op.httpMethod.toUpperCase() === "GET") {
|
|
509
|
+
set.add(entry.op.pathTemplate);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
return set;
|
|
513
|
+
}
|
|
503
514
|
|
|
504
515
|
// plugins/plugin-skilled-openapi/src/tools/execute-action.tool.ts
|
|
505
516
|
import { BundleStore, SkillAuditWriterToken } from "@frontmcp/adapters/skills";
|
|
@@ -1137,6 +1148,7 @@ LoadSkillTool = __decorateClass([
|
|
|
1137
1148
|
], LoadSkillTool);
|
|
1138
1149
|
|
|
1139
1150
|
// plugins/plugin-skilled-openapi/src/tools/operation-tool.factory.ts
|
|
1151
|
+
import { classifyOne } from "@frontmcp/adapters/skills";
|
|
1140
1152
|
import {
|
|
1141
1153
|
ToolInstance,
|
|
1142
1154
|
ToolKind
|
|
@@ -1179,12 +1191,21 @@ var OperationToolFactory = class {
|
|
|
1179
1191
|
}
|
|
1180
1192
|
/** Map (bundleId|opId) → the executor function that doubles as registry token. */
|
|
1181
1193
|
registered = /* @__PURE__ */ new Map();
|
|
1194
|
+
/** Tool names this factory has pushed into the classification registry. */
|
|
1195
|
+
classificationKeys = /* @__PURE__ */ new Set();
|
|
1182
1196
|
/**
|
|
1183
1197
|
* Register one operation as an internal tool. Idempotent — calling twice
|
|
1184
1198
|
* with the same `(bundleId, operationId)` is a no-op (the existing
|
|
1185
1199
|
* registration is left in place).
|
|
1200
|
+
*
|
|
1201
|
+
* When the factory was constructed with a `classificationRegistry` AND
|
|
1202
|
+
* the caller supplies `ctx.pathsWithGet`, the factory also classifies the
|
|
1203
|
+
* operation (per HTTP semantics) and pushes the result into the
|
|
1204
|
+
* classification registry. A downstream `tools/call` hook can then look
|
|
1205
|
+
* up the classification by tool name and auto-emit
|
|
1206
|
+
* `notifications/resources/*` on success.
|
|
1186
1207
|
*/
|
|
1187
|
-
register(entry) {
|
|
1208
|
+
register(entry, ctx) {
|
|
1188
1209
|
const key2 = `${entry.bundleId}|${entry.op.operationId}`;
|
|
1189
1210
|
if (this.registered.has(key2)) return;
|
|
1190
1211
|
const executor = this.makeExecutor(entry);
|
|
@@ -1197,10 +1218,31 @@ var OperationToolFactory = class {
|
|
|
1197
1218
|
const instance = new ToolInstance(record, this.deps.providers, OPERATION_TOOL_OWNER);
|
|
1198
1219
|
this.deps.toolRegistry.registerToolInstance(instance);
|
|
1199
1220
|
this.registered.set(key2, executor);
|
|
1221
|
+
if (this.deps.classificationRegistry && ctx?.pathsWithGet) {
|
|
1222
|
+
try {
|
|
1223
|
+
const classification = classifyOne(
|
|
1224
|
+
entry.bundleId,
|
|
1225
|
+
{
|
|
1226
|
+
operationId: entry.op.operationId,
|
|
1227
|
+
method: entry.op.httpMethod,
|
|
1228
|
+
path: entry.op.pathTemplate
|
|
1229
|
+
},
|
|
1230
|
+
ctx.pathsWithGet
|
|
1231
|
+
);
|
|
1232
|
+
const toolName = metadata.name;
|
|
1233
|
+
this.deps.classificationRegistry.register(toolName, classification);
|
|
1234
|
+
this.classificationKeys.add(toolName);
|
|
1235
|
+
} catch (e) {
|
|
1236
|
+
this.deps.logger.warn(
|
|
1237
|
+
`[operation-tool-factory] classification failed for ${entry.bundleId}.${entry.op.operationId}: ${e.message}`
|
|
1238
|
+
);
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1200
1241
|
}
|
|
1201
1242
|
/**
|
|
1202
1243
|
* Unregister every tool this factory has registered. Used on bundle swap
|
|
1203
|
-
* before re-registering the new bundle's operations.
|
|
1244
|
+
* before re-registering the new bundle's operations. Also clears the
|
|
1245
|
+
* classification entries this factory pushed.
|
|
1204
1246
|
*/
|
|
1205
1247
|
unregisterAll() {
|
|
1206
1248
|
for (const executor of this.registered.values()) {
|
|
@@ -1211,6 +1253,12 @@ var OperationToolFactory = class {
|
|
|
1211
1253
|
}
|
|
1212
1254
|
}
|
|
1213
1255
|
this.registered.clear();
|
|
1256
|
+
if (this.deps.classificationRegistry && this.classificationKeys.size > 0) {
|
|
1257
|
+
for (const toolName of this.classificationKeys) {
|
|
1258
|
+
this.deps.classificationRegistry.unregister(toolName);
|
|
1259
|
+
}
|
|
1260
|
+
this.classificationKeys.clear();
|
|
1261
|
+
}
|
|
1214
1262
|
}
|
|
1215
1263
|
/** Number of currently-registered internal operation tools (test/audit hook). */
|
|
1216
1264
|
get size() {
|
package/esm/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frontmcp/plugin-skilled-openapi",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "FrontMCP plugin: serve a customer's OpenAPI spec as skill bundles (signed, OpenAPI-Overlay-based) with hidden per-operation tools mediated by three meta-tools (search_skill / load_skill / execute_action).",
|
|
5
5
|
"author": "AgentFront <info@agentfront.dev>",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -45,14 +45,14 @@
|
|
|
45
45
|
}
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@frontmcp/adapters": "1.
|
|
49
|
-
"@frontmcp/auth": "1.
|
|
50
|
-
"@frontmcp/protocol": "1.
|
|
51
|
-
"@frontmcp/sdk": "1.
|
|
52
|
-
"@frontmcp/utils": "1.
|
|
48
|
+
"@frontmcp/adapters": "1.4.0",
|
|
49
|
+
"@frontmcp/auth": "1.4.0",
|
|
50
|
+
"@frontmcp/protocol": "1.4.0",
|
|
51
|
+
"@frontmcp/sdk": "1.4.0",
|
|
52
|
+
"@frontmcp/utils": "1.4.0"
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
|
55
|
-
"@frontmcp/lazy-zod": "1.
|
|
55
|
+
"@frontmcp/lazy-zod": "1.4.0"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"reflect-metadata": "^0.2.2"
|
package/index.js
CHANGED
|
@@ -37,7 +37,7 @@ __export(index_exports, {
|
|
|
37
37
|
module.exports = __toCommonJS(index_exports);
|
|
38
38
|
|
|
39
39
|
// plugins/plugin-skilled-openapi/src/skilled-openapi.plugin.ts
|
|
40
|
-
var
|
|
40
|
+
var import_skills6 = require("@frontmcp/adapters/skills");
|
|
41
41
|
var import_sdk5 = require("@frontmcp/sdk");
|
|
42
42
|
|
|
43
43
|
// plugins/plugin-skilled-openapi/src/executor/credential-resolver.ts
|
|
@@ -366,9 +366,10 @@ var BundleSyncService = class {
|
|
|
366
366
|
if (this.options.exposeOperationsAsInternalTools && this.operationToolFactory) {
|
|
367
367
|
try {
|
|
368
368
|
this.operationToolFactory.unregisterAll();
|
|
369
|
+
const pathsWithGet = collectPathsWithGet(this.hiddenOps.values());
|
|
369
370
|
for (const entry of this.hiddenOps.values()) {
|
|
370
371
|
try {
|
|
371
|
-
this.operationToolFactory.register(entry);
|
|
372
|
+
this.operationToolFactory.register(entry, { pathsWithGet });
|
|
372
373
|
} catch (regErr) {
|
|
373
374
|
this.logger.warn(
|
|
374
375
|
`[bundle-sync] internal-tool register failed for ${entry.bundleId}.${entry.op.operationId}: ${regErr.message}`
|
|
@@ -395,9 +396,10 @@ var BundleSyncService = class {
|
|
|
395
396
|
if (this.options.exposeOperationsAsInternalTools && this.operationToolFactory) {
|
|
396
397
|
try {
|
|
397
398
|
this.operationToolFactory.unregisterAll();
|
|
399
|
+
const pathsWithGet = collectPathsWithGet(snapshotEntries);
|
|
398
400
|
for (const entry of snapshotEntries) {
|
|
399
401
|
try {
|
|
400
|
-
this.operationToolFactory.register(entry);
|
|
402
|
+
this.operationToolFactory.register(entry, { pathsWithGet });
|
|
401
403
|
} catch {
|
|
402
404
|
}
|
|
403
405
|
}
|
|
@@ -494,6 +496,15 @@ var BundleSyncService = class {
|
|
|
494
496
|
}
|
|
495
497
|
}
|
|
496
498
|
};
|
|
499
|
+
function collectPathsWithGet(entries) {
|
|
500
|
+
const set = /* @__PURE__ */ new Set();
|
|
501
|
+
for (const entry of entries) {
|
|
502
|
+
if (typeof entry.op.httpMethod === "string" && entry.op.httpMethod.toUpperCase() === "GET") {
|
|
503
|
+
set.add(entry.op.pathTemplate);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
return set;
|
|
507
|
+
}
|
|
497
508
|
|
|
498
509
|
// plugins/plugin-skilled-openapi/src/tools/execute-action.tool.ts
|
|
499
510
|
var import_skills4 = require("@frontmcp/adapters/skills");
|
|
@@ -1128,6 +1139,7 @@ LoadSkillTool = __decorateClass([
|
|
|
1128
1139
|
], LoadSkillTool);
|
|
1129
1140
|
|
|
1130
1141
|
// plugins/plugin-skilled-openapi/src/tools/operation-tool.factory.ts
|
|
1142
|
+
var import_skills5 = require("@frontmcp/adapters/skills");
|
|
1131
1143
|
var import_sdk3 = require("@frontmcp/sdk");
|
|
1132
1144
|
var OPERATION_TOOL_OWNER_TOKEN = /* @__PURE__ */ Symbol.for("skilled-openapi:operation-tool-owner");
|
|
1133
1145
|
var OPERATION_TOOL_OWNER = {
|
|
@@ -1167,12 +1179,21 @@ var OperationToolFactory = class {
|
|
|
1167
1179
|
}
|
|
1168
1180
|
/** Map (bundleId|opId) → the executor function that doubles as registry token. */
|
|
1169
1181
|
registered = /* @__PURE__ */ new Map();
|
|
1182
|
+
/** Tool names this factory has pushed into the classification registry. */
|
|
1183
|
+
classificationKeys = /* @__PURE__ */ new Set();
|
|
1170
1184
|
/**
|
|
1171
1185
|
* Register one operation as an internal tool. Idempotent — calling twice
|
|
1172
1186
|
* with the same `(bundleId, operationId)` is a no-op (the existing
|
|
1173
1187
|
* registration is left in place).
|
|
1188
|
+
*
|
|
1189
|
+
* When the factory was constructed with a `classificationRegistry` AND
|
|
1190
|
+
* the caller supplies `ctx.pathsWithGet`, the factory also classifies the
|
|
1191
|
+
* operation (per HTTP semantics) and pushes the result into the
|
|
1192
|
+
* classification registry. A downstream `tools/call` hook can then look
|
|
1193
|
+
* up the classification by tool name and auto-emit
|
|
1194
|
+
* `notifications/resources/*` on success.
|
|
1174
1195
|
*/
|
|
1175
|
-
register(entry) {
|
|
1196
|
+
register(entry, ctx) {
|
|
1176
1197
|
const key2 = `${entry.bundleId}|${entry.op.operationId}`;
|
|
1177
1198
|
if (this.registered.has(key2)) return;
|
|
1178
1199
|
const executor = this.makeExecutor(entry);
|
|
@@ -1185,10 +1206,31 @@ var OperationToolFactory = class {
|
|
|
1185
1206
|
const instance = new import_sdk3.ToolInstance(record, this.deps.providers, OPERATION_TOOL_OWNER);
|
|
1186
1207
|
this.deps.toolRegistry.registerToolInstance(instance);
|
|
1187
1208
|
this.registered.set(key2, executor);
|
|
1209
|
+
if (this.deps.classificationRegistry && ctx?.pathsWithGet) {
|
|
1210
|
+
try {
|
|
1211
|
+
const classification = (0, import_skills5.classifyOne)(
|
|
1212
|
+
entry.bundleId,
|
|
1213
|
+
{
|
|
1214
|
+
operationId: entry.op.operationId,
|
|
1215
|
+
method: entry.op.httpMethod,
|
|
1216
|
+
path: entry.op.pathTemplate
|
|
1217
|
+
},
|
|
1218
|
+
ctx.pathsWithGet
|
|
1219
|
+
);
|
|
1220
|
+
const toolName = metadata.name;
|
|
1221
|
+
this.deps.classificationRegistry.register(toolName, classification);
|
|
1222
|
+
this.classificationKeys.add(toolName);
|
|
1223
|
+
} catch (e) {
|
|
1224
|
+
this.deps.logger.warn(
|
|
1225
|
+
`[operation-tool-factory] classification failed for ${entry.bundleId}.${entry.op.operationId}: ${e.message}`
|
|
1226
|
+
);
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1188
1229
|
}
|
|
1189
1230
|
/**
|
|
1190
1231
|
* Unregister every tool this factory has registered. Used on bundle swap
|
|
1191
|
-
* before re-registering the new bundle's operations.
|
|
1232
|
+
* before re-registering the new bundle's operations. Also clears the
|
|
1233
|
+
* classification entries this factory pushed.
|
|
1192
1234
|
*/
|
|
1193
1235
|
unregisterAll() {
|
|
1194
1236
|
for (const executor of this.registered.values()) {
|
|
@@ -1199,6 +1241,12 @@ var OperationToolFactory = class {
|
|
|
1199
1241
|
}
|
|
1200
1242
|
}
|
|
1201
1243
|
this.registered.clear();
|
|
1244
|
+
if (this.deps.classificationRegistry && this.classificationKeys.size > 0) {
|
|
1245
|
+
for (const toolName of this.classificationKeys) {
|
|
1246
|
+
this.deps.classificationRegistry.unregister(toolName);
|
|
1247
|
+
}
|
|
1248
|
+
this.classificationKeys.clear();
|
|
1249
|
+
}
|
|
1202
1250
|
}
|
|
1203
1251
|
/** Number of currently-registered internal operation tools (test/audit hook). */
|
|
1204
1252
|
get size() {
|
|
@@ -1397,7 +1445,7 @@ var SkilledOpenApiPlugin = class extends import_sdk5.DynamicPlugin {
|
|
|
1397
1445
|
{ name: "skilled-openapi:hidden-ops", provide: HiddenOpRegistry, useValue: new HiddenOpRegistry() },
|
|
1398
1446
|
{
|
|
1399
1447
|
name: "skilled-openapi:bundle-store",
|
|
1400
|
-
provide:
|
|
1448
|
+
provide: import_skills6.BundleStore,
|
|
1401
1449
|
// Resolve TelemetryAccessor from the scope's provider registry so the
|
|
1402
1450
|
// bundle-pulls counter and `skill.bundle.swap` span actually export.
|
|
1403
1451
|
// The accessor is structurally compatible with `BundleStoreTelemetry`.
|
|
@@ -1405,7 +1453,7 @@ var SkilledOpenApiPlugin = class extends import_sdk5.DynamicPlugin {
|
|
|
1405
1453
|
// we resolve `undefined` and the BundleStore falls through its zero-cost
|
|
1406
1454
|
// no-telemetry path.
|
|
1407
1455
|
inject: () => [import_sdk5.ScopeEntry],
|
|
1408
|
-
useFactory: (scope) => new
|
|
1456
|
+
useFactory: (scope) => new import_skills6.BundleStore({ telemetry: resolveBundleTelemetry(scope) })
|
|
1409
1457
|
},
|
|
1410
1458
|
{
|
|
1411
1459
|
name: "skilled-openapi:credential-resolver",
|
|
@@ -1421,7 +1469,7 @@ var SkilledOpenApiPlugin = class extends import_sdk5.DynamicPlugin {
|
|
|
1421
1469
|
{
|
|
1422
1470
|
name: "skilled-openapi:bundle-sync",
|
|
1423
1471
|
provide: BundleSyncService,
|
|
1424
|
-
inject: () => [import_sdk5.ScopeEntry, HiddenOpRegistry,
|
|
1472
|
+
inject: () => [import_sdk5.ScopeEntry, HiddenOpRegistry, import_skills6.BundleStore],
|
|
1425
1473
|
useFactory: async (scope, hiddenOps, bundleStore) => {
|
|
1426
1474
|
const logger = scope.logger.child("skilled-openapi:sync");
|
|
1427
1475
|
const lazySkillRegistry = new Proxy({}, {
|
|
@@ -1478,7 +1526,7 @@ var SkilledOpenApiPlugin = class extends import_sdk5.DynamicPlugin {
|
|
|
1478
1526
|
);
|
|
1479
1527
|
let source;
|
|
1480
1528
|
try {
|
|
1481
|
-
source = (0,
|
|
1529
|
+
source = (0, import_skills6.createBundleSource)(parsed.source, parsed.bundleCacheDir, logger);
|
|
1482
1530
|
} catch (e) {
|
|
1483
1531
|
logger.error(`failed to construct bundle source: ${e.message}`);
|
|
1484
1532
|
return sync;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frontmcp/plugin-skilled-openapi",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "FrontMCP plugin: serve a customer's OpenAPI spec as skill bundles (signed, OpenAPI-Overlay-based) with hidden per-operation tools mediated by three meta-tools (search_skill / load_skill / execute_action).",
|
|
5
5
|
"author": "AgentFront <info@agentfront.dev>",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -45,14 +45,14 @@
|
|
|
45
45
|
}
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@frontmcp/adapters": "1.
|
|
49
|
-
"@frontmcp/auth": "1.
|
|
50
|
-
"@frontmcp/protocol": "1.
|
|
51
|
-
"@frontmcp/sdk": "1.
|
|
52
|
-
"@frontmcp/utils": "1.
|
|
48
|
+
"@frontmcp/adapters": "1.4.0",
|
|
49
|
+
"@frontmcp/auth": "1.4.0",
|
|
50
|
+
"@frontmcp/protocol": "1.4.0",
|
|
51
|
+
"@frontmcp/sdk": "1.4.0",
|
|
52
|
+
"@frontmcp/utils": "1.4.0"
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
|
55
|
-
"@frontmcp/lazy-zod": "1.
|
|
55
|
+
"@frontmcp/lazy-zod": "1.4.0"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"reflect-metadata": "^0.2.2"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bundle-sync.service.d.ts","sourceRoot":"","sources":["../../src/sync/bundle-sync.service.ts"],"names":[],"mappings":"AAEA,OAAO,EASL,KAAK,UAAU,EACf,KAAK,WAAW,EAEhB,KAAK,cAAc,EAEnB,KAAK,wBAAwB,EAC9B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,KAAK,cAAc,EAAqB,KAAK,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAEpG,OAAO,EAAsB,KAAK,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAC3F,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,KAAK,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAE5E,MAAM,WAAW,iBAAiB;IAChC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,WAAW,EAAE,YAAY,EAAE,CAAC;IAC5B;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,wBAAwB,CAAC;IACrC;;;;;;;;OAQG;IACH,+BAA+B,EAAE,OAAO,CAAC;CAC1C;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,iBAAiB;IAI1B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC;IAfxC,OAAO,CAAC,yBAAyB,CAA0C;gBAGxD,aAAa,EAAE,sBAAsB,EACrC,SAAS,EAAE,gBAAgB,EAC3B,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,iBAAiB,EAC1B,MAAM,EAAE,cAAc;IACvC;;;;;;OAMG;IACc,oBAAoB,CAAC,EAAE,oBAAoB,YAAA;IAG9D;;;;OAIG;IACG,KAAK,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"bundle-sync.service.d.ts","sourceRoot":"","sources":["../../src/sync/bundle-sync.service.ts"],"names":[],"mappings":"AAEA,OAAO,EASL,KAAK,UAAU,EACf,KAAK,WAAW,EAEhB,KAAK,cAAc,EAEnB,KAAK,wBAAwB,EAC9B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,KAAK,cAAc,EAAqB,KAAK,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAEpG,OAAO,EAAsB,KAAK,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAC3F,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,KAAK,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAE5E,MAAM,WAAW,iBAAiB;IAChC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,WAAW,EAAE,YAAY,EAAE,CAAC;IAC5B;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,wBAAwB,CAAC;IACrC;;;;;;;;OAQG;IACH,+BAA+B,EAAE,OAAO,CAAC;CAC1C;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,iBAAiB;IAI1B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC;IAfxC,OAAO,CAAC,yBAAyB,CAA0C;gBAGxD,aAAa,EAAE,sBAAsB,EACrC,SAAS,EAAE,gBAAgB,EAC3B,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,iBAAiB,EAC1B,MAAM,EAAE,cAAc;IACvC;;;;;;OAMG;IACc,oBAAoB,CAAC,EAAE,oBAAoB,YAAA;IAG9D;;;;OAIG;IACG,KAAK,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,iBAAiB,CAAC;IA0O/D;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAatB,OAAO,CAAC,gBAAgB;CAmCzB"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ClassificationRegistry } from '@frontmcp/adapters/skills';
|
|
1
2
|
import { type FrontMcpLogger, type ProviderRegistry, type ToolRegistry } from '@frontmcp/sdk';
|
|
2
3
|
import { type HiddenOpEntry } from '../registry/hidden-op.registry';
|
|
3
4
|
/**
|
|
@@ -13,6 +14,25 @@ export interface OperationToolFactoryDeps {
|
|
|
13
14
|
providers: ProviderRegistry;
|
|
14
15
|
/** Logger for diagnostics. */
|
|
15
16
|
logger: FrontMcpLogger;
|
|
17
|
+
/**
|
|
18
|
+
* Optional classification registry. When set together with `pathsWithGet`
|
|
19
|
+
* on each `register()` call, the factory also records the OpenAPI -> MCP
|
|
20
|
+
* classification for the operation so a runtime dispatcher hook can
|
|
21
|
+
* auto-emit `notifications/resources/updated` / `…/list_changed` on
|
|
22
|
+
* successful tool calls. Unregistering via `unregisterAll()` clears the
|
|
23
|
+
* matching classification entries.
|
|
24
|
+
*/
|
|
25
|
+
classificationRegistry?: ClassificationRegistry;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Optional context passed per `register()` call so the factory can classify
|
|
29
|
+
* the operation against the rest of the bundle. Callers (typically the
|
|
30
|
+
* bundle-sync service) precompute `pathsWithGet` once over the bundle's
|
|
31
|
+
* full operation list before iterating.
|
|
32
|
+
*/
|
|
33
|
+
export interface OperationRegisterContext {
|
|
34
|
+
/** Set of path templates that have a GET op in the same bundle. */
|
|
35
|
+
pathsWithGet: ReadonlySet<string>;
|
|
16
36
|
}
|
|
17
37
|
/**
|
|
18
38
|
* Stable result envelope produced by every operation executor. Mirrors the
|
|
@@ -35,16 +55,26 @@ export declare class OperationToolFactory {
|
|
|
35
55
|
private readonly deps;
|
|
36
56
|
/** Map (bundleId|opId) → the executor function that doubles as registry token. */
|
|
37
57
|
private registered;
|
|
58
|
+
/** Tool names this factory has pushed into the classification registry. */
|
|
59
|
+
private classificationKeys;
|
|
38
60
|
constructor(deps: OperationToolFactoryDeps);
|
|
39
61
|
/**
|
|
40
62
|
* Register one operation as an internal tool. Idempotent — calling twice
|
|
41
63
|
* with the same `(bundleId, operationId)` is a no-op (the existing
|
|
42
64
|
* registration is left in place).
|
|
65
|
+
*
|
|
66
|
+
* When the factory was constructed with a `classificationRegistry` AND
|
|
67
|
+
* the caller supplies `ctx.pathsWithGet`, the factory also classifies the
|
|
68
|
+
* operation (per HTTP semantics) and pushes the result into the
|
|
69
|
+
* classification registry. A downstream `tools/call` hook can then look
|
|
70
|
+
* up the classification by tool name and auto-emit
|
|
71
|
+
* `notifications/resources/*` on success.
|
|
43
72
|
*/
|
|
44
|
-
register(entry: HiddenOpEntry): void;
|
|
73
|
+
register(entry: HiddenOpEntry, ctx?: OperationRegisterContext): void;
|
|
45
74
|
/**
|
|
46
75
|
* Unregister every tool this factory has registered. Used on bundle swap
|
|
47
|
-
* before re-registering the new bundle's operations.
|
|
76
|
+
* before re-registering the new bundle's operations. Also clears the
|
|
77
|
+
* classification entries this factory pushed.
|
|
48
78
|
*/
|
|
49
79
|
unregisterAll(): void;
|
|
50
80
|
/** Number of currently-registered internal operation tools (test/audit hook). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"operation-tool.factory.d.ts","sourceRoot":"","sources":["../../src/tools/operation-tool.factory.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"operation-tool.factory.d.ts","sourceRoot":"","sources":["../../src/tools/operation-tool.factory.ts"],"names":[],"mappings":"AAaA,OAAO,EAAe,KAAK,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAErF,OAAO,EAIL,KAAK,cAAc,EACnB,KAAK,gBAAgB,EAGrB,KAAK,YAAY,EAClB,MAAM,eAAe,CAAC;AAIvB,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAWpE;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAS/E;AA2BD,MAAM,WAAW,wBAAwB;IACvC,sEAAsE;IACtE,YAAY,EAAE,YAAY,CAAC;IAC3B,8DAA8D;IAC9D,SAAS,EAAE,gBAAgB,CAAC;IAC5B,8BAA8B;IAC9B,MAAM,EAAE,cAAc,CAAC;IACvB;;;;;;;OAOG;IACH,sBAAsB,CAAC,EAAE,sBAAsB,CAAC;CACjD;AAED;;;;;GAKG;AACH,MAAM,WAAW,wBAAwB;IACvC,mEAAmE;IACnE,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACnC;AAED;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAUD;;;GAGG;AACH,qBAAa,oBAAoB;IAMnB,OAAO,CAAC,QAAQ,CAAC,IAAI;IALjC,kFAAkF;IAClF,OAAO,CAAC,UAAU,CAAwC;IAC1D,2EAA2E;IAC3E,OAAO,CAAC,kBAAkB,CAAqB;gBAElB,IAAI,EAAE,wBAAwB;IAE3D;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,CAAC,EAAE,wBAAwB,GAAG,IAAI;IA2CpE;;;;OAIG;IACH,aAAa,IAAI,IAAI;IAqBrB,iFAAiF;IACjF,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;;;;OAKG;IACH,OAAO,CAAC,YAAY;CA4ErB"}
|