@happyvertical/smrt-core 0.40.61 → 0.40.62
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 +21 -0
- package/dist/generators/mcp-runtime-template.d.ts +5 -0
- package/dist/generators/mcp-runtime-template.d.ts.map +1 -1
- package/dist/generators/mcp-runtime-template.js +230 -3
- package/dist/generators/mcp-runtime-template.js.map +1 -1
- package/dist/generators/mcp.d.ts +46 -0
- package/dist/generators/mcp.d.ts.map +1 -1
- package/dist/generators/mcp.js +102 -0
- package/dist/generators/mcp.js.map +1 -1
- package/dist/manifest/static-manifest.js +1 -1
- package/dist/manifest/static-manifest.js.map +1 -1
- package/dist/manifest/store.js +1 -1
- package/dist/manifest.json +1 -1
- package/dist/registry/types.d.ts +8 -0
- package/dist/registry/types.d.ts.map +1 -1
- package/dist/smrt-knowledge.json +3 -3
- package/dist/system/compatibility.d.ts.map +1 -1
- package/dist/system/compatibility.js +6 -0
- package/dist/system/compatibility.js.map +1 -1
- package/package.json +4 -4
package/dist/generators/mcp.js
CHANGED
|
@@ -53,6 +53,29 @@ function resolveCustomActionMethod(methods, toolAction) {
|
|
|
53
53
|
for (const [methodName, method] of methods) if (methodName.toLowerCase() === toolAction.toLowerCase()) return [methodName, method];
|
|
54
54
|
return [toolAction, void 0];
|
|
55
55
|
}
|
|
56
|
+
/** Preserve a declared method's case when a runtime-only class has no manifest. */
|
|
57
|
+
function resolveRuntimeMethodName(classConstructor, action) {
|
|
58
|
+
let prototype = classConstructor?.prototype;
|
|
59
|
+
while (prototype && prototype !== Object.prototype) {
|
|
60
|
+
const match = Object.getOwnPropertyNames(prototype).find((name) => name.toLowerCase() === action.toLowerCase());
|
|
61
|
+
if (match) return match;
|
|
62
|
+
prototype = Object.getPrototypeOf(prototype);
|
|
63
|
+
}
|
|
64
|
+
return action;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Background task methods receive `JobExecutionContext` from TaskRunner, not
|
|
68
|
+
* from untrusted MCP arguments. Keep that conventional trailing parameter out
|
|
69
|
+
* of the persisted positional call so the runner can append its live context.
|
|
70
|
+
*/
|
|
71
|
+
function buildTaskActionInvocationArgs(metadata, args) {
|
|
72
|
+
const parameters = metadata.parameters;
|
|
73
|
+
if (parameters?.at(-1)?.name === "context") return buildCustomActionInvocationArgs({
|
|
74
|
+
...metadata,
|
|
75
|
+
parameters: parameters.slice(0, -1)
|
|
76
|
+
}, args);
|
|
77
|
+
return buildCustomActionInvocationArgs(metadata, args);
|
|
78
|
+
}
|
|
56
79
|
/**
|
|
57
80
|
* Generate MCP server from smrt objects
|
|
58
81
|
*/
|
|
@@ -459,6 +482,63 @@ var MCPGenerator = class {
|
|
|
459
482
|
};
|
|
460
483
|
}
|
|
461
484
|
}
|
|
485
|
+
/** Whether a visible tool has explicitly opted into durable task execution. */
|
|
486
|
+
async supportsTaskTool(name) {
|
|
487
|
+
return await this.resolveTaskAction(name, { id: "__mcp_task_probe__" }) !== null;
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Create a durable MCP task for an explicitly enabled item custom action.
|
|
491
|
+
* The caller is responsible for checking the client's extension capability
|
|
492
|
+
* before exposing this result on the wire.
|
|
493
|
+
*/
|
|
494
|
+
async createTask(request) {
|
|
495
|
+
if (!this.context.taskStore) throw new Error("MCP Tasks is enabled but no durable task store is configured");
|
|
496
|
+
const resolved = await this.resolveTaskAction(request.params.name, request.params.arguments);
|
|
497
|
+
if (!resolved) throw new Error(`MCP task execution is not enabled for tool: ${request.params.name}`);
|
|
498
|
+
return {
|
|
499
|
+
content: [],
|
|
500
|
+
structuredContent: {},
|
|
501
|
+
resultType: "task",
|
|
502
|
+
...await this.context.taskStore.createTask({
|
|
503
|
+
objectType: resolved.objectType,
|
|
504
|
+
objectId: resolved.objectId,
|
|
505
|
+
method: resolved.methodName,
|
|
506
|
+
invocationArgs: resolved.invocationArgs,
|
|
507
|
+
tenantId: this.context.tenantId ?? null
|
|
508
|
+
})
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
async resolveTaskAction(toolName, args) {
|
|
512
|
+
const separator = toolName.indexOf("_");
|
|
513
|
+
if (separator <= 0) return null;
|
|
514
|
+
const objectPrefix = toolName.slice(0, separator);
|
|
515
|
+
const action = toolName.slice(separator + 1);
|
|
516
|
+
if ([
|
|
517
|
+
"list",
|
|
518
|
+
"get",
|
|
519
|
+
"create",
|
|
520
|
+
"update",
|
|
521
|
+
"delete"
|
|
522
|
+
].includes(action)) return null;
|
|
523
|
+
const classEntry = Array.from(ObjectRegistry.getAllClasses().entries()).find(([key, info]) => (info.name || key).toLowerCase() === objectPrefix.toLowerCase());
|
|
524
|
+
if (!classEntry) return null;
|
|
525
|
+
const [key, classInfo] = classEntry;
|
|
526
|
+
const objectName = classInfo.name || key;
|
|
527
|
+
const mcpConfig = ObjectRegistry.getConfig(objectName).mcp;
|
|
528
|
+
const configuredTasks = typeof mcpConfig === "object" ? mcpConfig.tasks : void 0;
|
|
529
|
+
if (configuredTasks !== true && (!Array.isArray(configuredTasks) || !configuredTasks.some((method) => method.toLowerCase() === action.toLowerCase()))) return null;
|
|
530
|
+
if (!(await this.generateTools()).some((tool) => tool.name === toolName)) return null;
|
|
531
|
+
const [resolvedMethodName, method] = resolveCustomActionMethod(await ObjectRegistry.getAllMethods(objectName), action);
|
|
532
|
+
const methodName = method ? resolvedMethodName : resolveRuntimeMethodName(classInfo.constructor, action);
|
|
533
|
+
const metadata = this.resolveCustomActionMetadata(objectName, methodName, method, this.hasCollectionReceiver(classInfo));
|
|
534
|
+
if (!metadata.idRequired || metadata.isStatic || typeof args.id !== "string") return null;
|
|
535
|
+
return {
|
|
536
|
+
objectType: classInfo.qualifiedName || objectName,
|
|
537
|
+
objectId: args.id,
|
|
538
|
+
methodName,
|
|
539
|
+
invocationArgs: buildTaskActionInvocationArgs(metadata, args)
|
|
540
|
+
};
|
|
541
|
+
}
|
|
462
542
|
/** Convert runtime values to the JSON values MCP structuredContent permits. */
|
|
463
543
|
toJsonValue(value) {
|
|
464
544
|
const serialized = JSON.stringify(value);
|
|
@@ -820,6 +900,7 @@ var MCPGenerator = class {
|
|
|
820
900
|
debug,
|
|
821
901
|
tools,
|
|
822
902
|
customActions: await this.runtimeCustomActions(tools),
|
|
903
|
+
taskActions: await this.runtimeTaskActions(tools),
|
|
823
904
|
tenantScopedObjects,
|
|
824
905
|
stiTargets: this.runtimeStiTargets(tools),
|
|
825
906
|
toolListCacheHint: resolveMCPToolListCacheHint(this.config.cache?.toolsList, hasTenantScopedTools)
|
|
@@ -877,6 +958,26 @@ var MCPGenerator = class {
|
|
|
877
958
|
}
|
|
878
959
|
return metadata;
|
|
879
960
|
}
|
|
961
|
+
/** Emit only task-enabled item custom actions for the generated runtime. */
|
|
962
|
+
async runtimeTaskActions(tools) {
|
|
963
|
+
const actions = {};
|
|
964
|
+
const classes = ObjectRegistry.getAllClasses();
|
|
965
|
+
for (const tool of tools) {
|
|
966
|
+
if (!await this.supportsTaskTool(tool.name)) continue;
|
|
967
|
+
const separator = tool.name.indexOf("_");
|
|
968
|
+
if (separator <= 0) continue;
|
|
969
|
+
const objectPrefix = tool.name.slice(0, separator).toLowerCase();
|
|
970
|
+
const matched = Array.from(classes.entries()).find(([key, info]) => (info.name || key).toLowerCase() === objectPrefix);
|
|
971
|
+
if (!matched) continue;
|
|
972
|
+
const [key, classInfo] = matched;
|
|
973
|
+
const objectName = classInfo.name || key;
|
|
974
|
+
actions[tool.name] = {
|
|
975
|
+
objectName,
|
|
976
|
+
objectType: classInfo.qualifiedName || objectName
|
|
977
|
+
};
|
|
978
|
+
}
|
|
979
|
+
return actions;
|
|
980
|
+
}
|
|
880
981
|
/**
|
|
881
982
|
* Emit only the STI discriminator targets advertised by create-tool schemas.
|
|
882
983
|
* Generated processes start with an empty registry, so resolving the
|
|
@@ -1147,6 +1248,7 @@ const TENANT_SCOPED = new Set(${JSON.stringify(tenantScopedSet)});
|
|
|
1147
1248
|
const MCP_TENANT_ID = process.env.SMRT_MCP_TENANT_ID || undefined;
|
|
1148
1249
|
const MCP_ALLOW_CROSS_TENANT = process.env.SMRT_MCP_ALLOW_CROSS_TENANT === 'true';
|
|
1149
1250
|
` : ""}
|
|
1251
|
+
|
|
1150
1252
|
const PUBLIC_JSON_OPTIONS = {
|
|
1151
1253
|
permissions: (process.env.SMRT_MCP_PERMISSIONS || '')
|
|
1152
1254
|
.split(',')
|