@frontmcp/plugins 0.5.1 → 0.6.1
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/package.json +15 -4
- package/src/cache/cache.plugin.js +33 -1
- package/src/cache/cache.plugin.js.map +1 -1
- package/src/cache/cache.types.d.ts +26 -3
- package/src/cache/cache.types.js.map +1 -1
- package/src/cache/providers/cache-memory.provider.d.ts +3 -3
- package/src/cache/providers/cache-memory.provider.js +2 -2
- package/src/cache/providers/cache-memory.provider.js.map +1 -1
- package/src/cache/providers/cache-redis.provider.d.ts +3 -3
- package/src/cache/providers/cache-redis.provider.js +1 -1
- package/src/cache/providers/cache-redis.provider.js.map +1 -1
- package/src/cache/providers/cache-vercel-kv.provider.d.ts +24 -0
- package/src/cache/providers/cache-vercel-kv.provider.js +85 -0
- package/src/cache/providers/cache-vercel-kv.provider.js.map +1 -0
- package/src/codecall/codecall.types.d.ts +90 -27
- package/src/codecall/codecall.types.js +13 -9
- package/src/codecall/codecall.types.js.map +1 -1
- package/src/codecall/tools/invoke.schema.d.ts +6 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frontmcp/plugins",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "FrontMCP plugins to extend the SDK",
|
|
5
5
|
"author": "AgentFront <info@agentfront.dev>",
|
|
6
6
|
"homepage": "https://docs.agentfront.dev",
|
|
@@ -33,11 +33,22 @@
|
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"ioredis": "^5.8.0",
|
|
36
|
-
"@frontmcp/sdk": "0.
|
|
37
|
-
"ast-guard": "^1.1.1",
|
|
36
|
+
"@frontmcp/sdk": "0.6.1",
|
|
38
37
|
"enclave-vm": "^1.0.3",
|
|
39
38
|
"vectoriadb": "^2.0.1",
|
|
40
|
-
"
|
|
39
|
+
"zod": "^4.0.0",
|
|
40
|
+
"@modelcontextprotocol/sdk": "1.25.1"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"reflect-metadata": "^0.2.2"
|
|
44
|
+
},
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"@vercel/kv": "^2.0.0 || ^3.0.0"
|
|
47
|
+
},
|
|
48
|
+
"peerDependenciesMeta": {
|
|
49
|
+
"@vercel/kv": {
|
|
50
|
+
"optional": true
|
|
51
|
+
}
|
|
41
52
|
},
|
|
42
53
|
"type": "commonjs"
|
|
43
54
|
}
|
|
@@ -5,12 +5,44 @@ const tslib_1 = require("tslib");
|
|
|
5
5
|
const sdk_1 = require("@frontmcp/sdk");
|
|
6
6
|
const cache_redis_provider_1 = tslib_1.__importDefault(require("./providers/cache-redis.provider"));
|
|
7
7
|
const cache_memory_provider_1 = tslib_1.__importDefault(require("./providers/cache-memory.provider"));
|
|
8
|
+
const cache_vercel_kv_provider_1 = tslib_1.__importDefault(require("./providers/cache-vercel-kv.provider"));
|
|
8
9
|
const cache_symbol_1 = require("./cache.symbol");
|
|
9
10
|
let CachePlugin = class CachePlugin extends sdk_1.DynamicPlugin {
|
|
10
11
|
static { CachePlugin_1 = this; }
|
|
11
12
|
static dynamicProviders = (options) => {
|
|
12
13
|
const providers = [];
|
|
13
14
|
switch (options.type) {
|
|
15
|
+
case 'global-store':
|
|
16
|
+
// Use inject/useFactory to access FrontMcpConfig at runtime
|
|
17
|
+
providers.push({
|
|
18
|
+
name: 'cache:global-store',
|
|
19
|
+
provide: cache_symbol_1.CacheStoreToken,
|
|
20
|
+
inject: () => [sdk_1.FrontMcpConfig],
|
|
21
|
+
useFactory: (config) => {
|
|
22
|
+
const storeConfig = (0, sdk_1.getGlobalStoreConfig)('CachePlugin', config);
|
|
23
|
+
const globalOptions = options;
|
|
24
|
+
if ((0, sdk_1.isVercelKvProvider)(storeConfig)) {
|
|
25
|
+
return new cache_vercel_kv_provider_1.default({
|
|
26
|
+
url: storeConfig.url,
|
|
27
|
+
token: storeConfig.token,
|
|
28
|
+
keyPrefix: storeConfig.keyPrefix,
|
|
29
|
+
defaultTTL: globalOptions.defaultTTL,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
// Redis provider (including legacy format without provider field)
|
|
33
|
+
return new cache_redis_provider_1.default({
|
|
34
|
+
type: 'redis',
|
|
35
|
+
config: {
|
|
36
|
+
host: storeConfig.host ?? 'localhost',
|
|
37
|
+
port: storeConfig.port ?? 6379,
|
|
38
|
+
password: storeConfig.password,
|
|
39
|
+
db: storeConfig.db,
|
|
40
|
+
},
|
|
41
|
+
defaultTTL: globalOptions.defaultTTL,
|
|
42
|
+
});
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
break;
|
|
14
46
|
case 'redis':
|
|
15
47
|
case 'redis-client':
|
|
16
48
|
providers.push({
|
|
@@ -126,7 +158,7 @@ function hashObject(obj) {
|
|
|
126
158
|
acc += hashObject(val);
|
|
127
159
|
}
|
|
128
160
|
else {
|
|
129
|
-
acc += val;
|
|
161
|
+
acc += String(val);
|
|
130
162
|
}
|
|
131
163
|
acc += ';';
|
|
132
164
|
return acc;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.plugin.js","sourceRoot":"","sources":["../../../src/cache/cache.plugin.ts"],"names":[],"mappings":";;;;AAAA,uCAAyF;AACzF,oGAAkE;AAClE,sGAAoE;AAEpE,iDAAiD;AAelC,IAAM,WAAW,GAAjB,MAAM,WAAY,SAAQ,mBAAiC;;IACxE,MAAM,CAAU,gBAAgB,GAAG,CAAC,OAA2B,EAAE,EAAE;QACjE,MAAM,SAAS,GAAmB,EAAE,CAAC;QACrC,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;YACrB,KAAK,OAAO,CAAC;YACb,KAAK,cAAc;gBACjB,SAAS,CAAC,IAAI,CAAC;oBACb,IAAI,EAAE,aAAa;oBACnB,OAAO,EAAE,8BAAe;oBACxB,QAAQ,EAAE,IAAI,8BAAkB,CAAC,OAAO,CAAC;iBAC1C,CAAC,CAAC;gBACH,MAAM;YACR,KAAK,QAAQ;gBACX,SAAS,CAAC,IAAI,CAAC;oBACb,IAAI,EAAE,cAAc;oBACpB,OAAO,EAAE,8BAAe;oBACxB,QAAQ,EAAE,IAAI,+BAAmB,CAAC,OAAO,CAAC,UAAU,CAAC;iBACtD,CAAC,CAAC;gBACH,MAAM;QACV,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;IAEF,MAAM,CAAC,cAAc,GAAuB;QAC1C,IAAI,EAAE,QAAQ;KACf,CAAC;IACF,OAAO,CAAqB;IAE5B,YAAY,UAA8B,aAAW,CAAC,cAAc;QAClE,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,OAAO,GAAG;YACb,UAAU,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE;YACxB,GAAG,OAAO;SACX,CAAC;IACJ,CAAC;IAGK,AAAN,KAAK,CAAC,aAAa,CAAC,OAAqC;QACvD,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC;QAC5C,IAAI,CAAC,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO;QAElC,MAAM,EAAE,KAAK,EAAE,GAAG,WAAW,CAAC,QAAQ,CAAC;QACvC,IAAI,CAAC,KAAK,IAAI,OAAO,WAAW,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;YACvD,6BAA6B;YAC7B,OAAO;QACT,CAAC;QACD,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,8BAAe,CAAC,CAAC;QAC7C,MAAM,IAAI,GAAG,UAAU,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC;QAC3E,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAE/C,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YAC5C,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;gBACvD,MAAM,GAAG,GAAG,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;gBAC5F,MAAM,UAAU,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;YAC/C,CAAC;YAED;;eAEG;YACH,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC;gBAC1C,MAAM,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAC9B,OAAO;YACT,CAAC;YACD;;eAEG;YACH,OAAO,CAAC,KAAK,CAAC,SAAS,GAAG,MAAM,CAAC;YAEjC;;eAEG;YACH,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAGK,AAAN,KAAK,CAAC,cAAc,CAAC,OAAqC;QACxD,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC;QAC5C,IAAI,CAAC,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO;QAClC,MAAM,EAAE,KAAK,EAAE,GAAG,WAAW,CAAC,QAAQ,CAAC;QACvC,IAAI,CAAC,KAAK,IAAI,OAAO,WAAW,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;YACvD,OAAO;QACT,CAAC;QACD,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,8BAAe,CAAC,CAAC;QAC7C,MAAM,GAAG,GAAG,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;QAE5F,MAAM,IAAI,GAAG,UAAU,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC;QAC3E,MAAM,UAAU,CAAC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3D,CAAC;;AAnDK;IADL,cAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;;;gDAqC5C;AAGK;IADL,cAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;;;iDAa3C;AAxFkB,WAAW;IAb/B,IAAA,YAAM,EAAC;QACN,IAAI,EAAE,OAAO;QACb,WAAW,EAAE,uCAAuC;QACpD,SAAS,EAAE;YACT,2EAA2E;YAC3E;gBACE,+FAA+F;gBAC/F,IAAI,EAAE,cAAc;gBACpB,OAAO,EAAE,8BAAe;gBACxB,QAAQ,EAAE,IAAI,+BAAmB,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;aAChD;SACF;KACF,CAAC;;GACmB,WAAW,CAyF/B;kBAzFoB,WAAW;AA2FhC,SAAS,UAAU,CAAC,GAAQ;IAC1B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACrC,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC9B,GAAG,IAAI,GAAG,GAAG,GAAG,CAAC;QACjB,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QACrB,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YAC5C,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,GAAG,IAAI,GAAG,CAAC;QACb,CAAC;QACD,GAAG,IAAI,GAAG,CAAC;QACX,OAAO,GAAG,CAAC;IACb,CAAC,EAAE,EAAE,CAAC,CAAC;AACT,CAAC","sourcesContent":["import { DynamicPlugin, FlowCtxOf, Plugin, ProviderType, ToolHook } from '@frontmcp/sdk';\nimport CacheRedisProvider from './providers/cache-redis.provider';\nimport CacheMemoryProvider from './providers/cache-memory.provider';\nimport { CachePluginOptions } from './cache.types';\nimport { CacheStoreToken } from './cache.symbol';\n\n@Plugin({\n name: 'cache',\n description: 'Cache plugin for caching tool results',\n providers: [\n /* add providers that always loaded with the plugin or default providers */\n {\n // this is a default provider for cache, will be overridden if dynamicProviders based on config\n name: 'cache:memory',\n provide: CacheStoreToken,\n useValue: new CacheMemoryProvider(60 * 60 * 24),\n },\n ],\n})\nexport default class CachePlugin extends DynamicPlugin<CachePluginOptions> {\n static override dynamicProviders = (options: CachePluginOptions) => {\n const providers: ProviderType[] = [];\n switch (options.type) {\n case 'redis':\n case 'redis-client':\n providers.push({\n name: 'cache:redis',\n provide: CacheStoreToken,\n useValue: new CacheRedisProvider(options),\n });\n break;\n case 'memory':\n providers.push({\n name: 'cache:memory',\n provide: CacheStoreToken,\n useValue: new CacheMemoryProvider(options.defaultTTL),\n });\n break;\n }\n return providers;\n };\n\n static defaultOptions: CachePluginOptions = {\n type: 'memory',\n };\n options: CachePluginOptions;\n\n constructor(options: CachePluginOptions = CachePlugin.defaultOptions) {\n super();\n this.options = {\n defaultTTL: 60 * 60 * 24,\n ...options,\n };\n }\n\n @ToolHook.Will('execute', { priority: 1000 })\n async willReadCache(flowCtx: FlowCtxOf<'tools:call-tool'>) {\n const { tool, toolContext } = flowCtx.state;\n if (!tool || !toolContext) return;\n\n const { cache } = toolContext.metadata;\n if (!cache || typeof toolContext.input === 'undefined') {\n // no cache or no input, skip\n return;\n }\n const cacheStore = this.get(CacheStoreToken);\n const hash = hashObject({ tool: tool.fullName, input: toolContext.input });\n const cached = await cacheStore.getValue(hash);\n\n if (cached !== undefined && cached !== null) {\n if (cache === true || (cache.ttl && cache.slideWindow)) {\n const ttl = cache === true ? this.options.defaultTTL : cache.ttl ?? this.options.defaultTTL;\n await cacheStore.setValue(hash, cached, ttl);\n }\n\n /**\n * double check if cache still valid based on tool output schema\n */\n if (!tool.safeParseOutput(cached).success) {\n await cacheStore.delete(hash);\n return;\n }\n /**\n * cache hit, set output to the main flow context\n */\n flowCtx.state.rawOutput = cached;\n\n /**\n * call respond to bypass tool execution\n */\n toolContext.respond(cached);\n }\n }\n\n @ToolHook.Did('execute', { priority: 1000 })\n async willWriteCache(flowCtx: FlowCtxOf<'tools:call-tool'>) {\n const { tool, toolContext } = flowCtx.state;\n if (!tool || !toolContext) return;\n const { cache } = toolContext.metadata;\n if (!cache || typeof toolContext.input === 'undefined') {\n return;\n }\n const cacheStore = this.get(CacheStoreToken);\n const ttl = cache === true ? this.options.defaultTTL : cache.ttl ?? this.options.defaultTTL;\n\n const hash = hashObject({ tool: tool.fullName, input: toolContext.input });\n await cacheStore.setValue(hash, toolContext.output, ttl);\n }\n}\n\nfunction hashObject(obj: any) {\n const keys = Object.keys(obj).sort();\n return keys.reduce((acc, key) => {\n acc += key + ':';\n const val = obj[key];\n if (typeof val === 'object' && val !== null) {\n acc += hashObject(val);\n } else {\n acc += val;\n }\n acc += ';';\n return acc;\n }, '');\n}\n"]}
|
|
1
|
+
{"version":3,"file":"cache.plugin.js","sourceRoot":"","sources":["../../../src/cache/cache.plugin.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n DynamicPlugin,\n FlowCtxOf,\n Plugin,\n ProviderType,\n ToolHook,\n FrontMcpConfig,\n FrontMcpConfigType,\n getGlobalStoreConfig,\n isVercelKvProvider,\n} from '@frontmcp/sdk';\nimport CacheRedisProvider from './providers/cache-redis.provider';\nimport CacheMemoryProvider from './providers/cache-memory.provider';\nimport CacheVercelKvProvider from './providers/cache-vercel-kv.provider';\nimport { CachePluginOptions, GlobalStoreCachePluginOptions } from './cache.types';\nimport { CacheStoreToken } from './cache.symbol';\n\n@Plugin({\n name: 'cache',\n description: 'Cache plugin for caching tool results',\n providers: [\n /* add providers that always loaded with the plugin or default providers */\n {\n // this is a default provider for cache, will be overridden if dynamicProviders based on config\n name: 'cache:memory',\n provide: CacheStoreToken,\n useValue: new CacheMemoryProvider(60 * 60 * 24),\n },\n ],\n})\nexport default class CachePlugin extends DynamicPlugin<CachePluginOptions> {\n static override dynamicProviders = (options: CachePluginOptions) => {\n const providers: ProviderType[] = [];\n switch (options.type) {\n case 'global-store':\n // Use inject/useFactory to access FrontMcpConfig at runtime\n providers.push({\n name: 'cache:global-store',\n provide: CacheStoreToken,\n inject: () => [FrontMcpConfig] as const,\n useFactory: (config: FrontMcpConfigType) => {\n const storeConfig = getGlobalStoreConfig('CachePlugin', config);\n const globalOptions = options as GlobalStoreCachePluginOptions;\n\n if (isVercelKvProvider(storeConfig)) {\n return new CacheVercelKvProvider({\n url: storeConfig.url,\n token: storeConfig.token,\n keyPrefix: storeConfig.keyPrefix,\n defaultTTL: globalOptions.defaultTTL,\n });\n }\n\n // Redis provider (including legacy format without provider field)\n return new CacheRedisProvider({\n type: 'redis',\n config: {\n host: storeConfig.host ?? 'localhost',\n port: storeConfig.port ?? 6379,\n password: storeConfig.password,\n db: storeConfig.db,\n },\n defaultTTL: globalOptions.defaultTTL,\n });\n },\n });\n break;\n case 'redis':\n case 'redis-client':\n providers.push({\n name: 'cache:redis',\n provide: CacheStoreToken,\n useValue: new CacheRedisProvider(options),\n });\n break;\n case 'memory':\n providers.push({\n name: 'cache:memory',\n provide: CacheStoreToken,\n useValue: new CacheMemoryProvider(options.defaultTTL),\n });\n break;\n }\n return providers;\n };\n\n static defaultOptions: CachePluginOptions = {\n type: 'memory',\n };\n options: CachePluginOptions;\n\n constructor(options: CachePluginOptions = CachePlugin.defaultOptions) {\n super();\n this.options = {\n defaultTTL: 60 * 60 * 24,\n ...options,\n };\n }\n\n @ToolHook.Will('execute', { priority: 1000 })\n async willReadCache(flowCtx: FlowCtxOf<'tools:call-tool'>) {\n const { tool, toolContext } = flowCtx.state;\n if (!tool || !toolContext) return;\n\n const { cache } = toolContext.metadata;\n if (!cache || typeof toolContext.input === 'undefined') {\n // no cache or no input, skip\n return;\n }\n const cacheStore = this.get(CacheStoreToken);\n const hash = hashObject({ tool: tool.fullName, input: toolContext.input });\n const cached = await cacheStore.getValue(hash);\n\n if (cached !== undefined && cached !== null) {\n if (cache === true || (cache.ttl && cache.slideWindow)) {\n const ttl = cache === true ? this.options.defaultTTL : cache.ttl ?? this.options.defaultTTL;\n await cacheStore.setValue(hash, cached, ttl);\n }\n\n /**\n * double check if cache still valid based on tool output schema\n */\n if (!tool.safeParseOutput(cached).success) {\n await cacheStore.delete(hash);\n return;\n }\n /**\n * cache hit, set output to the main flow context\n */\n flowCtx.state.rawOutput = cached;\n\n /**\n * call respond to bypass tool execution\n */\n toolContext.respond(cached);\n }\n }\n\n @ToolHook.Did('execute', { priority: 1000 })\n async willWriteCache(flowCtx: FlowCtxOf<'tools:call-tool'>) {\n const { tool, toolContext } = flowCtx.state;\n if (!tool || !toolContext) return;\n const { cache } = toolContext.metadata;\n if (!cache || typeof toolContext.input === 'undefined') {\n return;\n }\n const cacheStore = this.get(CacheStoreToken);\n const ttl = cache === true ? this.options.defaultTTL : cache.ttl ?? this.options.defaultTTL;\n\n const hash = hashObject({ tool: tool.fullName, input: toolContext.input });\n await cacheStore.setValue(hash, toolContext.output, ttl);\n }\n}\n\nfunction hashObject(obj: Record<string, unknown>): string {\n const keys = Object.keys(obj).sort();\n return keys.reduce((acc, key) => {\n acc += key + ':';\n const val = obj[key];\n if (typeof val === 'object' && val !== null) {\n acc += hashObject(val as Record<string, unknown>);\n } else {\n acc += String(val);\n }\n acc += ';';\n return acc;\n }, '');\n}\n"]}
|
|
@@ -34,11 +34,34 @@ export interface RedisCachePluginOptions extends BaseCachePluginOptions {
|
|
|
34
34
|
export type MemoryCachePluginOptions = BaseCachePluginOptions & {
|
|
35
35
|
type: 'memory';
|
|
36
36
|
};
|
|
37
|
+
/**
|
|
38
|
+
* Use global store configuration from @FrontMcp decorator.
|
|
39
|
+
* Requires `redis` to be configured in the main FrontMcp options.
|
|
40
|
+
* Supports both Redis and Vercel KV global configurations.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```typescript
|
|
44
|
+
* // In main.ts - configure global store
|
|
45
|
+
* @FrontMcp({
|
|
46
|
+
* redis: { host: 'localhost', port: 6379 },
|
|
47
|
+
* apps: [MyApp]
|
|
48
|
+
* })
|
|
49
|
+
*
|
|
50
|
+
* // In app - use global store
|
|
51
|
+
* @App({
|
|
52
|
+
* plugins: [CachePlugin.init({ type: 'global-store' })]
|
|
53
|
+
* })
|
|
54
|
+
* class MyApp {}
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export interface GlobalStoreCachePluginOptions extends BaseCachePluginOptions {
|
|
58
|
+
type: 'global-store';
|
|
59
|
+
}
|
|
37
60
|
export type RedisCacheOptions = RedisClientCachePluginOptions | RedisCachePluginOptions;
|
|
38
|
-
export type CachePluginOptions = MemoryCachePluginOptions | RedisCacheOptions;
|
|
61
|
+
export type CachePluginOptions = MemoryCachePluginOptions | RedisCacheOptions | GlobalStoreCachePluginOptions;
|
|
39
62
|
export interface CacheStoreInterface {
|
|
40
|
-
setValue(key: string, value:
|
|
41
|
-
getValue<T =
|
|
63
|
+
setValue(key: string, value: unknown, ttlSeconds?: number): Promise<void>;
|
|
64
|
+
getValue<T = unknown>(key: string, defaultValue?: T): Promise<T | undefined>;
|
|
42
65
|
delete(key: string): Promise<void>;
|
|
43
66
|
exists(key: string): Promise<boolean>;
|
|
44
67
|
close(): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.types.js","sourceRoot":"","sources":["../../../src/cache/cache.types.ts"],"names":[],"mappings":"","sourcesContent":["import { Redis as RedisClient } from 'ioredis';\n\ndeclare global {\n interface ExtendFrontMcpToolMetadata {\n cache?: CachePluginToolOptions | true;\n }\n}\n\nexport interface CachePluginToolOptions {\n /**\n * Time to live in seconds. Default is 1 day.\n */\n ttl?: number; // default 1 day\n\n /**\n * If true, the cache value will be updated with the new value after the TTL.\n * Default is false.\n */\n slideWindow?: boolean;\n}\n\nexport interface BaseCachePluginOptions {\n defaultTTL?: number; // default 1 day\n}\n\nexport interface RedisClientCachePluginOptions extends BaseCachePluginOptions {\n type: 'redis-client';\n client: RedisClient;\n}\n\nexport interface RedisCachePluginOptions extends BaseCachePluginOptions {\n type: 'redis';\n config: {\n host: string;\n port: number;\n password?: string;\n db?: number;\n };\n}\n\nexport type MemoryCachePluginOptions = BaseCachePluginOptions & {\n type: 'memory';\n};\n\nexport type RedisCacheOptions = RedisClientCachePluginOptions | RedisCachePluginOptions;\n\nexport type CachePluginOptions = MemoryCachePluginOptions | RedisCacheOptions;\n\nexport interface CacheStoreInterface {\n setValue(key: string, value:
|
|
1
|
+
{"version":3,"file":"cache.types.js","sourceRoot":"","sources":["../../../src/cache/cache.types.ts"],"names":[],"mappings":"","sourcesContent":["import { Redis as RedisClient } from 'ioredis';\n\ndeclare global {\n interface ExtendFrontMcpToolMetadata {\n cache?: CachePluginToolOptions | true;\n }\n}\n\nexport interface CachePluginToolOptions {\n /**\n * Time to live in seconds. Default is 1 day.\n */\n ttl?: number; // default 1 day\n\n /**\n * If true, the cache value will be updated with the new value after the TTL.\n * Default is false.\n */\n slideWindow?: boolean;\n}\n\nexport interface BaseCachePluginOptions {\n defaultTTL?: number; // default 1 day\n}\n\nexport interface RedisClientCachePluginOptions extends BaseCachePluginOptions {\n type: 'redis-client';\n client: RedisClient;\n}\n\nexport interface RedisCachePluginOptions extends BaseCachePluginOptions {\n type: 'redis';\n config: {\n host: string;\n port: number;\n password?: string;\n db?: number;\n };\n}\n\nexport type MemoryCachePluginOptions = BaseCachePluginOptions & {\n type: 'memory';\n};\n\n/**\n * Use global store configuration from @FrontMcp decorator.\n * Requires `redis` to be configured in the main FrontMcp options.\n * Supports both Redis and Vercel KV global configurations.\n *\n * @example\n * ```typescript\n * // In main.ts - configure global store\n * @FrontMcp({\n * redis: { host: 'localhost', port: 6379 },\n * apps: [MyApp]\n * })\n *\n * // In app - use global store\n * @App({\n * plugins: [CachePlugin.init({ type: 'global-store' })]\n * })\n * class MyApp {}\n * ```\n */\nexport interface GlobalStoreCachePluginOptions extends BaseCachePluginOptions {\n type: 'global-store';\n}\n\nexport type RedisCacheOptions = RedisClientCachePluginOptions | RedisCachePluginOptions;\n\nexport type CachePluginOptions = MemoryCachePluginOptions | RedisCacheOptions | GlobalStoreCachePluginOptions;\n\nexport interface CacheStoreInterface {\n setValue(key: string, value: unknown, ttlSeconds?: number): Promise<void>;\n\n getValue<T = unknown>(key: string, defaultValue?: T): Promise<T | undefined>;\n\n delete(key: string): Promise<void>;\n\n exists(key: string): Promise<boolean>;\n\n close(): Promise<void>;\n}\n"]}
|
|
@@ -3,10 +3,10 @@ export default class CacheMemoryProvider implements CacheStoreInterface {
|
|
|
3
3
|
private readonly memory;
|
|
4
4
|
private sweeper?;
|
|
5
5
|
constructor(sweepIntervalTTL?: number);
|
|
6
|
-
/** Set
|
|
7
|
-
setValue(key: string, value:
|
|
6
|
+
/** Set a value (auto-stringifies objects) */
|
|
7
|
+
setValue(key: string, value: unknown, ttlSeconds?: number): Promise<void>;
|
|
8
8
|
/** Get a value and automatically parse JSON if possible */
|
|
9
|
-
getValue<T =
|
|
9
|
+
getValue<T = unknown>(key: string, defaultValue?: T): Promise<T | undefined>;
|
|
10
10
|
/** Delete a key */
|
|
11
11
|
delete(key: string): Promise<void>;
|
|
12
12
|
/** Check if a key exists (and not expired) */
|
|
@@ -8,10 +8,10 @@ let CacheMemoryProvider = class CacheMemoryProvider {
|
|
|
8
8
|
sweeper;
|
|
9
9
|
constructor(sweepIntervalTTL = 60) {
|
|
10
10
|
this.sweeper = setInterval(() => this.sweep(), sweepIntervalTTL * 1000);
|
|
11
|
-
// don
|
|
11
|
+
// don't keep the process alive just for the sweeper (Node >=14)
|
|
12
12
|
this.sweeper.unref?.();
|
|
13
13
|
}
|
|
14
|
-
/** Set
|
|
14
|
+
/** Set a value (auto-stringifies objects) */
|
|
15
15
|
async setValue(key, value, ttlSeconds) {
|
|
16
16
|
const strValue = typeof value === 'string' ? value : JSON.stringify(value);
|
|
17
17
|
// clear any previous timeout on this key
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache-memory.provider.js","sourceRoot":"","sources":["../../../../src/cache/providers/cache-memory.provider.ts"],"names":[],"mappings":";;;AAAA,uCAAwD;AAWxD,MAAM,cAAc,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,qCAAqC;AAO1D,IAAM,mBAAmB,GAAzB,MAAM,mBAAmB;IACrB,MAAM,GAAG,IAAI,GAAG,EAAiB,CAAC;IAC3C,OAAO,CAAkB;IAEjC,YAAY,gBAAgB,GAAG,EAAE;QAC/B,IAAI,CAAC,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,gBAAgB,GAAG,IAAI,CAAC,CAAC;QACxE,gEAAgE;QAC/D,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"cache-memory.provider.js","sourceRoot":"","sources":["../../../../src/cache/providers/cache-memory.provider.ts"],"names":[],"mappings":"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","sourcesContent":["import { Provider, ProviderScope } from '@frontmcp/sdk';\nimport { CacheStoreInterface } from '../cache.types';\n\ntype Entry = {\n value: string;\n /** epoch millis when this entry expires (undefined = no TTL) */\n expiresAt?: number;\n /** per-key timeout when TTL is short enough to schedule */\n timeout?: NodeJS.Timeout;\n};\n\nconst MAX_TIMEOUT_MS = 2 ** 31 - 1; // ~24.8 days (Node setTimeout limit)\n\n@Provider({\n name: 'provider:cache:memory',\n description: 'Memory-based cache provider',\n scope: ProviderScope.GLOBAL,\n})\nexport default class CacheMemoryProvider implements CacheStoreInterface {\n private readonly memory = new Map<string, Entry>();\n private sweeper?: NodeJS.Timeout;\n\n constructor(sweepIntervalTTL = 60) {\n this.sweeper = setInterval(() => this.sweep(), sweepIntervalTTL * 1000);\n // don't keep the process alive just for the sweeper (Node >=14)\n (this.sweeper as { unref?: () => void }).unref?.();\n }\n\n /** Set a value (auto-stringifies objects) */\n async setValue(key: string, value: unknown, ttlSeconds?: number): Promise<void> {\n const strValue = typeof value === 'string' ? value : JSON.stringify(value);\n\n // clear any previous timeout on this key\n const existing = this.memory.get(key);\n if (existing?.timeout) clearTimeout(existing.timeout);\n\n const entry: Entry = { value: strValue };\n\n if (ttlSeconds && ttlSeconds > 0) {\n const ttlMs = ttlSeconds * 1000;\n entry.expiresAt = Date.now() + ttlMs;\n\n // Only schedule a timer if within Node's setTimeout limit; otherwise rely on sweeper/lazy purge\n if (ttlMs <= MAX_TIMEOUT_MS) {\n entry.timeout = setTimeout(() => {\n // final check guards against clock drift or updates\n const e = this.memory.get(key);\n if (e && e.expiresAt && e.expiresAt <= Date.now()) {\n this.memory.delete(key);\n }\n }, ttlMs);\n (entry.timeout as { unref?: () => void }).unref?.();\n }\n }\n\n this.memory.set(key, entry);\n }\n\n /** Get a value and automatically parse JSON if possible */\n async getValue<T = unknown>(key: string, defaultValue?: T): Promise<T | undefined> {\n const entry = this.memory.get(key);\n if (!entry) return defaultValue;\n\n if (this.isExpired(entry)) {\n await this.delete(key);\n return defaultValue;\n }\n\n const raw = entry.value;\n try {\n return JSON.parse(raw) as T;\n } catch {\n // fallback for plain string values\n return raw as unknown as T;\n }\n }\n\n /** Delete a key */\n async delete(key: string): Promise<void> {\n const entry = this.memory.get(key);\n if (entry?.timeout) clearTimeout(entry.timeout);\n this.memory.delete(key);\n }\n\n /** Check if a key exists (and not expired) */\n async exists(key: string): Promise<boolean> {\n const entry = this.memory.get(key);\n if (!entry) return false;\n if (this.isExpired(entry)) {\n await this.delete(key);\n return false;\n }\n return true;\n }\n\n /** Gracefully close the provider */\n async close(): Promise<void> {\n if (this.sweeper) clearInterval(this.sweeper);\n for (const [, entry] of this.memory) {\n if (entry.timeout) clearTimeout(entry.timeout);\n }\n this.memory.clear();\n }\n\n // ---- internals ----\n\n private isExpired(entry: Entry): boolean {\n return entry.expiresAt !== undefined && entry.expiresAt <= Date.now();\n }\n\n /** Periodically remove expired keys to keep memory tidy */\n private sweep(): void {\n const now = Date.now();\n for (const [key, entry] of this.memory) {\n if (entry.expiresAt !== undefined && entry.expiresAt <= now) {\n if (entry.timeout) clearTimeout(entry.timeout);\n this.memory.delete(key);\n }\n }\n }\n}\n"]}
|
|
@@ -2,10 +2,10 @@ import { CacheStoreInterface, RedisCacheOptions } from '../cache.types';
|
|
|
2
2
|
export default class CacheRedisProvider implements CacheStoreInterface {
|
|
3
3
|
private readonly client;
|
|
4
4
|
constructor(options: RedisCacheOptions);
|
|
5
|
-
/** Set
|
|
6
|
-
setValue(key: string, value:
|
|
5
|
+
/** Set a value (auto-stringifies objects) */
|
|
6
|
+
setValue(key: string, value: unknown, ttlSeconds?: number): Promise<void>;
|
|
7
7
|
/** Get a value and automatically parse JSON if possible */
|
|
8
|
-
getValue<T =
|
|
8
|
+
getValue<T = unknown>(key: string, defaultValue?: T): Promise<T | undefined>;
|
|
9
9
|
/** Delete a key */
|
|
10
10
|
delete(key: string): Promise<void>;
|
|
11
11
|
/** Check if a key exists */
|
|
@@ -21,7 +21,7 @@ let CacheRedisProvider = class CacheRedisProvider {
|
|
|
21
21
|
this.client.on('connect', () => console.log('[Redis] Connected'));
|
|
22
22
|
this.client.on('error', (err) => console.error('[Redis] Error:', err));
|
|
23
23
|
}
|
|
24
|
-
/** Set
|
|
24
|
+
/** Set a value (auto-stringifies objects) */
|
|
25
25
|
async setValue(key, value, ttlSeconds) {
|
|
26
26
|
const strValue = typeof value === 'string' ? value : JSON.stringify(value);
|
|
27
27
|
if (ttlSeconds && ttlSeconds > 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache-redis.provider.js","sourceRoot":"","sources":["../../../../src/cache/providers/cache-redis.provider.ts"],"names":[],"mappings":";;;AAAA,8DAAsD;AACtD,uCAAwD;AAQzC,IAAM,kBAAkB,GAAxB,MAAM,kBAAkB;IACpB,MAAM,CAAc;IAErC,YAAY,OAA0B;QACpC,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YAChE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACjD,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YACpC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAC7B,OAAO;QACT,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,IAAI,iBAAK,CAAC;YACtB,WAAW,EAAE,KAAK;YAClB,oBAAoB,EAAE,CAAC;YACvB,GAAG,OAAO,CAAC,MAAM;SAClB,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAC;QAClE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC,CAAC;IACzE,CAAC;IAED
|
|
1
|
+
{"version":3,"file":"cache-redis.provider.js","sourceRoot":"","sources":["../../../../src/cache/providers/cache-redis.provider.ts"],"names":[],"mappings":";;;AAAA,8DAAsD;AACtD,uCAAwD;AAQzC,IAAM,kBAAkB,GAAxB,MAAM,kBAAkB;IACpB,MAAM,CAAc;IAErC,YAAY,OAA0B;QACpC,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YAChE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACjD,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YACpC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAC7B,OAAO;QACT,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,IAAI,iBAAK,CAAC;YACtB,WAAW,EAAE,KAAK;YAClB,oBAAoB,EAAE,CAAC;YACvB,GAAG,OAAO,CAAC,MAAM;SAClB,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAC;QAClE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC,CAAC;IACzE,CAAC;IAED,6CAA6C;IAC7C,KAAK,CAAC,QAAQ,CAAC,GAAW,EAAE,KAAc,EAAE,UAAmB;QAC7D,MAAM,QAAQ,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC3E,IAAI,UAAU,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;QACzD,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAED,2DAA2D;IAC3D,KAAK,CAAC,QAAQ,CAAc,GAAW,EAAE,YAAgB;QACvD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACvC,IAAI,GAAG,KAAK,IAAI;YAAE,OAAO,YAAY,CAAC;QAEtC,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAM,CAAC;QAC9B,CAAC;QAAC,MAAM,CAAC;YACP,mCAAmC;YACnC,OAAO,GAAmB,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,mBAAmB;IACnB,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,4BAA4B;IAC5B,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,OAAO,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IAC/C,CAAC;IAED,4CAA4C;IAC5C,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAC3B,CAAC;CACF,CAAA;AA3DoB,kBAAkB;IALtC,IAAA,cAAQ,EAAC;QACR,IAAI,EAAE,sBAAsB;QAC5B,WAAW,EAAE,4BAA4B;QACzC,KAAK,EAAE,mBAAa,CAAC,MAAM;KAC5B,CAAC;;GACmB,kBAAkB,CA2DtC;kBA3DoB,kBAAkB","sourcesContent":["import Redis, { Redis as RedisClient } from 'ioredis';\nimport { Provider, ProviderScope } from '@frontmcp/sdk';\nimport { CacheStoreInterface, RedisCacheOptions } from '../cache.types';\n\n@Provider({\n name: 'provider:cache:redis',\n description: 'Redis-based cache provider',\n scope: ProviderScope.GLOBAL,\n})\nexport default class CacheRedisProvider implements CacheStoreInterface {\n private readonly client: RedisClient;\n\n constructor(options: RedisCacheOptions) {\n if (options.type !== 'redis' && options.type !== 'redis-client') {\n throw new Error('Invalid cache provider type');\n }\n\n if (options.type === 'redis-client') {\n this.client = options.client;\n return;\n }\n this.client = new Redis({\n lazyConnect: false,\n maxRetriesPerRequest: 3,\n ...options.config,\n });\n\n this.client.on('connect', () => console.log('[Redis] Connected'));\n this.client.on('error', (err) => console.error('[Redis] Error:', err));\n }\n\n /** Set a value (auto-stringifies objects) */\n async setValue(key: string, value: unknown, ttlSeconds?: number): Promise<void> {\n const strValue = typeof value === 'string' ? value : JSON.stringify(value);\n if (ttlSeconds && ttlSeconds > 0) {\n await this.client.set(key, strValue, 'EX', ttlSeconds);\n } else {\n await this.client.set(key, strValue);\n }\n }\n\n /** Get a value and automatically parse JSON if possible */\n async getValue<T = unknown>(key: string, defaultValue?: T): Promise<T | undefined> {\n const raw = await this.client.get(key);\n if (raw === null) return defaultValue;\n\n try {\n return JSON.parse(raw) as T;\n } catch {\n // fallback for plain string values\n return raw as unknown as T;\n }\n }\n\n /** Delete a key */\n async delete(key: string): Promise<void> {\n await this.client.del(key);\n }\n\n /** Check if a key exists */\n async exists(key: string): Promise<boolean> {\n return (await this.client.exists(key)) === 1;\n }\n\n /** Gracefully close the Redis connection */\n async close(): Promise<void> {\n await this.client.quit();\n }\n}\n"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { CacheStoreInterface } from '../cache.types';
|
|
2
|
+
export interface CacheVercelKvProviderOptions {
|
|
3
|
+
url?: string;
|
|
4
|
+
token?: string;
|
|
5
|
+
keyPrefix?: string;
|
|
6
|
+
defaultTTL?: number;
|
|
7
|
+
}
|
|
8
|
+
export default class CacheVercelKvProvider implements CacheStoreInterface {
|
|
9
|
+
private kv;
|
|
10
|
+
private readonly keyPrefix;
|
|
11
|
+
private readonly defaultTTL;
|
|
12
|
+
constructor(options?: CacheVercelKvProviderOptions);
|
|
13
|
+
private prefixKey;
|
|
14
|
+
/** Set a value (auto-stringifies objects) */
|
|
15
|
+
setValue(key: string, value: unknown, ttlSeconds?: number): Promise<void>;
|
|
16
|
+
/** Get a value and automatically parse JSON if possible */
|
|
17
|
+
getValue<T = unknown>(key: string, defaultValue?: T): Promise<T | undefined>;
|
|
18
|
+
/** Delete a key */
|
|
19
|
+
delete(key: string): Promise<void>;
|
|
20
|
+
/** Check if a key exists */
|
|
21
|
+
exists(key: string): Promise<boolean>;
|
|
22
|
+
/** Gracefully close the provider (no-op for Vercel KV - stateless REST API) */
|
|
23
|
+
close(): Promise<void>;
|
|
24
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const sdk_1 = require("@frontmcp/sdk");
|
|
5
|
+
let CacheVercelKvProvider = class CacheVercelKvProvider {
|
|
6
|
+
kv;
|
|
7
|
+
keyPrefix;
|
|
8
|
+
defaultTTL;
|
|
9
|
+
constructor(options = {}) {
|
|
10
|
+
// Lazy import @vercel/kv to avoid bundling when not used
|
|
11
|
+
const vercelKv = require('@vercel/kv');
|
|
12
|
+
// Validate partial configuration - both url and token must be provided together, or neither
|
|
13
|
+
const hasUrl = options.url !== undefined;
|
|
14
|
+
const hasToken = options.token !== undefined;
|
|
15
|
+
if (hasUrl !== hasToken) {
|
|
16
|
+
throw new Error(`CacheVercelKvProvider: Both 'url' and 'token' must be provided together, or neither. ` +
|
|
17
|
+
`Received: url=${hasUrl ? 'provided' : 'missing'}, token=${hasToken ? 'provided' : 'missing'}`);
|
|
18
|
+
}
|
|
19
|
+
// Use the kv instance with custom config if url/token provided
|
|
20
|
+
if (options.url && options.token) {
|
|
21
|
+
this.kv = vercelKv.createClient({
|
|
22
|
+
url: options.url,
|
|
23
|
+
token: options.token,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
// Use default kv instance (reads from KV_REST_API_URL and KV_REST_API_TOKEN env vars)
|
|
28
|
+
this.kv = vercelKv.kv;
|
|
29
|
+
}
|
|
30
|
+
this.keyPrefix = options.keyPrefix ?? 'cache:';
|
|
31
|
+
this.defaultTTL = options.defaultTTL ?? 60 * 60 * 24; // 1 day default
|
|
32
|
+
}
|
|
33
|
+
prefixKey(key) {
|
|
34
|
+
return `${this.keyPrefix}${key}`;
|
|
35
|
+
}
|
|
36
|
+
/** Set a value (auto-stringifies objects) */
|
|
37
|
+
async setValue(key, value, ttlSeconds) {
|
|
38
|
+
const strValue = typeof value === 'string' ? value : JSON.stringify(value);
|
|
39
|
+
const ttl = ttlSeconds ?? this.defaultTTL;
|
|
40
|
+
if (ttl > 0) {
|
|
41
|
+
await this.kv.set(this.prefixKey(key), strValue, { ex: ttl });
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
await this.kv.set(this.prefixKey(key), strValue);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/** Get a value and automatically parse JSON if possible */
|
|
48
|
+
async getValue(key, defaultValue) {
|
|
49
|
+
const raw = await this.kv.get(this.prefixKey(key));
|
|
50
|
+
if (raw === null || raw === undefined)
|
|
51
|
+
return defaultValue;
|
|
52
|
+
// Vercel KV auto-parses JSON, but we handle string fallback
|
|
53
|
+
if (typeof raw === 'string') {
|
|
54
|
+
try {
|
|
55
|
+
return JSON.parse(raw);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return raw;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return raw;
|
|
62
|
+
}
|
|
63
|
+
/** Delete a key */
|
|
64
|
+
async delete(key) {
|
|
65
|
+
await this.kv.del(this.prefixKey(key));
|
|
66
|
+
}
|
|
67
|
+
/** Check if a key exists */
|
|
68
|
+
async exists(key) {
|
|
69
|
+
return (await this.kv.exists(this.prefixKey(key))) === 1;
|
|
70
|
+
}
|
|
71
|
+
/** Gracefully close the provider (no-op for Vercel KV - stateless REST API) */
|
|
72
|
+
async close() {
|
|
73
|
+
// No-op: Vercel KV uses stateless REST API, no connection to close
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
CacheVercelKvProvider = tslib_1.__decorate([
|
|
77
|
+
(0, sdk_1.Provider)({
|
|
78
|
+
name: 'provider:cache:vercel-kv',
|
|
79
|
+
description: 'Vercel KV-based cache provider',
|
|
80
|
+
scope: sdk_1.ProviderScope.GLOBAL,
|
|
81
|
+
}),
|
|
82
|
+
tslib_1.__metadata("design:paramtypes", [Object])
|
|
83
|
+
], CacheVercelKvProvider);
|
|
84
|
+
exports.default = CacheVercelKvProvider;
|
|
85
|
+
//# sourceMappingURL=cache-vercel-kv.provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache-vercel-kv.provider.js","sourceRoot":"","sources":["../../../../src/cache/providers/cache-vercel-kv.provider.ts"],"names":[],"mappings":"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","sourcesContent":["import { Provider, ProviderScope } from '@frontmcp/sdk';\nimport { CacheStoreInterface } from '../cache.types';\n\nexport interface CacheVercelKvProviderOptions {\n url?: string;\n token?: string;\n keyPrefix?: string;\n defaultTTL?: number;\n}\n\n/** Minimal interface for Vercel KV client operations used by the cache provider */\ninterface VercelKvClient {\n set(key: string, value: string, options?: { ex?: number }): Promise<void>;\n get(key: string): Promise<unknown>;\n del(key: string): Promise<void>;\n exists(key: string): Promise<number>;\n}\n\n@Provider({\n name: 'provider:cache:vercel-kv',\n description: 'Vercel KV-based cache provider',\n scope: ProviderScope.GLOBAL,\n})\nexport default class CacheVercelKvProvider implements CacheStoreInterface {\n private kv: VercelKvClient;\n private readonly keyPrefix: string;\n private readonly defaultTTL: number;\n\n constructor(options: CacheVercelKvProviderOptions = {}) {\n // Lazy import @vercel/kv to avoid bundling when not used\n const vercelKv = require('@vercel/kv');\n\n // Validate partial configuration - both url and token must be provided together, or neither\n const hasUrl = options.url !== undefined;\n const hasToken = options.token !== undefined;\n if (hasUrl !== hasToken) {\n throw new Error(\n `CacheVercelKvProvider: Both 'url' and 'token' must be provided together, or neither. ` +\n `Received: url=${hasUrl ? 'provided' : 'missing'}, token=${hasToken ? 'provided' : 'missing'}`,\n );\n }\n\n // Use the kv instance with custom config if url/token provided\n if (options.url && options.token) {\n this.kv = vercelKv.createClient({\n url: options.url,\n token: options.token,\n });\n } else {\n // Use default kv instance (reads from KV_REST_API_URL and KV_REST_API_TOKEN env vars)\n this.kv = vercelKv.kv;\n }\n\n this.keyPrefix = options.keyPrefix ?? 'cache:';\n this.defaultTTL = options.defaultTTL ?? 60 * 60 * 24; // 1 day default\n }\n\n private prefixKey(key: string): string {\n return `${this.keyPrefix}${key}`;\n }\n\n /** Set a value (auto-stringifies objects) */\n async setValue(key: string, value: unknown, ttlSeconds?: number): Promise<void> {\n const strValue = typeof value === 'string' ? value : JSON.stringify(value);\n const ttl = ttlSeconds ?? this.defaultTTL;\n\n if (ttl > 0) {\n await this.kv.set(this.prefixKey(key), strValue, { ex: ttl });\n } else {\n await this.kv.set(this.prefixKey(key), strValue);\n }\n }\n\n /** Get a value and automatically parse JSON if possible */\n async getValue<T = unknown>(key: string, defaultValue?: T): Promise<T | undefined> {\n const raw = await this.kv.get(this.prefixKey(key));\n if (raw === null || raw === undefined) return defaultValue;\n\n // Vercel KV auto-parses JSON, but we handle string fallback\n if (typeof raw === 'string') {\n try {\n return JSON.parse(raw) as T;\n } catch {\n return raw as unknown as T;\n }\n }\n\n return raw as T;\n }\n\n /** Delete a key */\n async delete(key: string): Promise<void> {\n await this.kv.del(this.prefixKey(key));\n }\n\n /** Check if a key exists */\n async exists(key: string): Promise<boolean> {\n return (await this.kv.exists(this.prefixKey(key))) === 1;\n }\n\n /** Gracefully close the provider (no-op for Vercel KV - stateless REST API) */\n async close(): Promise<void> {\n // No-op: Vercel KV uses stateless REST API, no connection to close\n }\n}\n"]}
|
|
@@ -66,21 +66,42 @@ export declare const synonymExpansionConfigSchema: z.ZodDefault<z.ZodObject<{
|
|
|
66
66
|
replaceDefaults: z.ZodDefault<z.ZodBoolean>;
|
|
67
67
|
maxExpansionsPerTerm: z.ZodDefault<z.ZodNumber>;
|
|
68
68
|
}, z.core.$strip>>;
|
|
69
|
-
export declare const codeCallEmbeddingOptionsSchema: z.
|
|
70
|
-
strategy: z.ZodDefault<z.ZodEnum<{
|
|
69
|
+
export declare const codeCallEmbeddingOptionsSchema: z.ZodPipe<z.ZodOptional<z.ZodObject<{
|
|
70
|
+
strategy: z.ZodOptional<z.ZodDefault<z.ZodEnum<{
|
|
71
71
|
tfidf: "tfidf";
|
|
72
72
|
ml: "ml";
|
|
73
|
-
}
|
|
74
|
-
modelName: z.
|
|
75
|
-
cacheDir: z.
|
|
76
|
-
useHNSW: z.
|
|
77
|
-
synonymExpansion: z.
|
|
73
|
+
}>>>;
|
|
74
|
+
modelName: z.ZodOptional<z.ZodString>;
|
|
75
|
+
cacheDir: z.ZodOptional<z.ZodString>;
|
|
76
|
+
useHNSW: z.ZodOptional<z.ZodBoolean>;
|
|
77
|
+
synonymExpansion: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<false>, z.ZodDefault<z.ZodObject<{
|
|
78
78
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
79
79
|
additionalSynonyms: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodString>>>;
|
|
80
80
|
replaceDefaults: z.ZodDefault<z.ZodBoolean>;
|
|
81
81
|
maxExpansionsPerTerm: z.ZodDefault<z.ZodNumber>;
|
|
82
|
-
}, z.core.$strip>>]
|
|
83
|
-
}, z.core.$strip
|
|
82
|
+
}, z.core.$strip>>]>>;
|
|
83
|
+
}, z.core.$strip>>, z.ZodTransform<{
|
|
84
|
+
strategy: "tfidf" | "ml";
|
|
85
|
+
modelName: string;
|
|
86
|
+
cacheDir: string;
|
|
87
|
+
useHNSW: boolean;
|
|
88
|
+
synonymExpansion: false | {
|
|
89
|
+
enabled: boolean;
|
|
90
|
+
replaceDefaults: boolean;
|
|
91
|
+
maxExpansionsPerTerm: number;
|
|
92
|
+
};
|
|
93
|
+
}, {
|
|
94
|
+
strategy?: "tfidf" | "ml" | undefined;
|
|
95
|
+
modelName?: string | undefined;
|
|
96
|
+
cacheDir?: string | undefined;
|
|
97
|
+
useHNSW?: boolean | undefined;
|
|
98
|
+
synonymExpansion?: false | {
|
|
99
|
+
enabled: boolean;
|
|
100
|
+
replaceDefaults: boolean;
|
|
101
|
+
maxExpansionsPerTerm: number;
|
|
102
|
+
additionalSynonyms?: string[][] | undefined;
|
|
103
|
+
} | undefined;
|
|
104
|
+
} | undefined>>;
|
|
84
105
|
export declare const codeCallSidecarOptionsSchema: z.ZodDefault<z.ZodObject<{
|
|
85
106
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
86
107
|
maxTotalSize: z.ZodOptional<z.ZodNumber>;
|
|
@@ -118,21 +139,42 @@ declare const codeCallPluginOptionsObjectSchema: z.ZodObject<{
|
|
|
118
139
|
disabledGlobals: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
119
140
|
allowConsole: z.ZodOptional<z.ZodBoolean>;
|
|
120
141
|
}, z.core.$strip>>;
|
|
121
|
-
embedding: z.
|
|
122
|
-
strategy: z.ZodDefault<z.ZodEnum<{
|
|
142
|
+
embedding: z.ZodPipe<z.ZodOptional<z.ZodObject<{
|
|
143
|
+
strategy: z.ZodOptional<z.ZodDefault<z.ZodEnum<{
|
|
123
144
|
tfidf: "tfidf";
|
|
124
145
|
ml: "ml";
|
|
125
|
-
}
|
|
126
|
-
modelName: z.
|
|
127
|
-
cacheDir: z.
|
|
128
|
-
useHNSW: z.
|
|
129
|
-
synonymExpansion: z.
|
|
146
|
+
}>>>;
|
|
147
|
+
modelName: z.ZodOptional<z.ZodString>;
|
|
148
|
+
cacheDir: z.ZodOptional<z.ZodString>;
|
|
149
|
+
useHNSW: z.ZodOptional<z.ZodBoolean>;
|
|
150
|
+
synonymExpansion: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<false>, z.ZodDefault<z.ZodObject<{
|
|
130
151
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
131
152
|
additionalSynonyms: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodString>>>;
|
|
132
153
|
replaceDefaults: z.ZodDefault<z.ZodBoolean>;
|
|
133
154
|
maxExpansionsPerTerm: z.ZodDefault<z.ZodNumber>;
|
|
134
|
-
}, z.core.$strip>>]
|
|
135
|
-
}, z.core.$strip
|
|
155
|
+
}, z.core.$strip>>]>>;
|
|
156
|
+
}, z.core.$strip>>, z.ZodTransform<{
|
|
157
|
+
strategy: "tfidf" | "ml";
|
|
158
|
+
modelName: string;
|
|
159
|
+
cacheDir: string;
|
|
160
|
+
useHNSW: boolean;
|
|
161
|
+
synonymExpansion: false | {
|
|
162
|
+
enabled: boolean;
|
|
163
|
+
replaceDefaults: boolean;
|
|
164
|
+
maxExpansionsPerTerm: number;
|
|
165
|
+
};
|
|
166
|
+
}, {
|
|
167
|
+
strategy?: "tfidf" | "ml" | undefined;
|
|
168
|
+
modelName?: string | undefined;
|
|
169
|
+
cacheDir?: string | undefined;
|
|
170
|
+
useHNSW?: boolean | undefined;
|
|
171
|
+
synonymExpansion?: false | {
|
|
172
|
+
enabled: boolean;
|
|
173
|
+
replaceDefaults: boolean;
|
|
174
|
+
maxExpansionsPerTerm: number;
|
|
175
|
+
additionalSynonyms?: string[][] | undefined;
|
|
176
|
+
} | undefined;
|
|
177
|
+
} | undefined>>;
|
|
136
178
|
sidecar: z.ZodDefault<z.ZodObject<{
|
|
137
179
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
138
180
|
maxTotalSize: z.ZodOptional<z.ZodNumber>;
|
|
@@ -171,21 +213,42 @@ export declare const codeCallPluginOptionsSchema: z.ZodPrefault<z.ZodObject<{
|
|
|
171
213
|
disabledGlobals: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
172
214
|
allowConsole: z.ZodOptional<z.ZodBoolean>;
|
|
173
215
|
}, z.core.$strip>>;
|
|
174
|
-
embedding: z.
|
|
175
|
-
strategy: z.ZodDefault<z.ZodEnum<{
|
|
216
|
+
embedding: z.ZodPipe<z.ZodOptional<z.ZodObject<{
|
|
217
|
+
strategy: z.ZodOptional<z.ZodDefault<z.ZodEnum<{
|
|
176
218
|
tfidf: "tfidf";
|
|
177
219
|
ml: "ml";
|
|
178
|
-
}
|
|
179
|
-
modelName: z.
|
|
180
|
-
cacheDir: z.
|
|
181
|
-
useHNSW: z.
|
|
182
|
-
synonymExpansion: z.
|
|
220
|
+
}>>>;
|
|
221
|
+
modelName: z.ZodOptional<z.ZodString>;
|
|
222
|
+
cacheDir: z.ZodOptional<z.ZodString>;
|
|
223
|
+
useHNSW: z.ZodOptional<z.ZodBoolean>;
|
|
224
|
+
synonymExpansion: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<false>, z.ZodDefault<z.ZodObject<{
|
|
183
225
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
184
226
|
additionalSynonyms: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodString>>>;
|
|
185
227
|
replaceDefaults: z.ZodDefault<z.ZodBoolean>;
|
|
186
228
|
maxExpansionsPerTerm: z.ZodDefault<z.ZodNumber>;
|
|
187
|
-
}, z.core.$strip>>]
|
|
188
|
-
}, z.core.$strip
|
|
229
|
+
}, z.core.$strip>>]>>;
|
|
230
|
+
}, z.core.$strip>>, z.ZodTransform<{
|
|
231
|
+
strategy: "tfidf" | "ml";
|
|
232
|
+
modelName: string;
|
|
233
|
+
cacheDir: string;
|
|
234
|
+
useHNSW: boolean;
|
|
235
|
+
synonymExpansion: false | {
|
|
236
|
+
enabled: boolean;
|
|
237
|
+
replaceDefaults: boolean;
|
|
238
|
+
maxExpansionsPerTerm: number;
|
|
239
|
+
};
|
|
240
|
+
}, {
|
|
241
|
+
strategy?: "tfidf" | "ml" | undefined;
|
|
242
|
+
modelName?: string | undefined;
|
|
243
|
+
cacheDir?: string | undefined;
|
|
244
|
+
useHNSW?: boolean | undefined;
|
|
245
|
+
synonymExpansion?: false | {
|
|
246
|
+
enabled: boolean;
|
|
247
|
+
replaceDefaults: boolean;
|
|
248
|
+
maxExpansionsPerTerm: number;
|
|
249
|
+
additionalSynonyms?: string[][] | undefined;
|
|
250
|
+
} | undefined;
|
|
251
|
+
} | undefined>>;
|
|
189
252
|
sidecar: z.ZodDefault<z.ZodObject<{
|
|
190
253
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
191
254
|
maxTotalSize: z.ZodOptional<z.ZodNumber>;
|
|
@@ -119,23 +119,23 @@ exports.codeCallEmbeddingOptionsSchema = zod_1.z
|
|
|
119
119
|
* - 'ml': ML-based semantic search using transformers.js (better quality, requires model download)
|
|
120
120
|
* @default 'tfidf'
|
|
121
121
|
*/
|
|
122
|
-
strategy: exports.embeddingStrategySchema,
|
|
122
|
+
strategy: exports.embeddingStrategySchema.optional(),
|
|
123
123
|
/**
|
|
124
124
|
* Model name for ML-based embeddings (only used when strategy='ml')
|
|
125
125
|
* @default 'Xenova/all-MiniLM-L6-v2'
|
|
126
126
|
*/
|
|
127
|
-
modelName: zod_1.z.string().
|
|
127
|
+
modelName: zod_1.z.string().optional(),
|
|
128
128
|
/**
|
|
129
129
|
* Cache directory for ML models (only used when strategy='ml')
|
|
130
130
|
* @default './.cache/transformers'
|
|
131
131
|
*/
|
|
132
|
-
cacheDir: zod_1.z.string().
|
|
132
|
+
cacheDir: zod_1.z.string().optional(),
|
|
133
133
|
/**
|
|
134
134
|
* Enable HNSW index for faster search (only used when strategy='ml')
|
|
135
135
|
* When enabled, provides O(log n) search instead of O(n) brute-force
|
|
136
136
|
* @default false
|
|
137
137
|
*/
|
|
138
|
-
useHNSW: zod_1.z.boolean().
|
|
138
|
+
useHNSW: zod_1.z.boolean().optional(),
|
|
139
139
|
/**
|
|
140
140
|
* Synonym expansion configuration for TF-IDF search.
|
|
141
141
|
* When enabled, queries like "add user" will match tools for "create user".
|
|
@@ -143,12 +143,16 @@ exports.codeCallEmbeddingOptionsSchema = zod_1.z
|
|
|
143
143
|
* Set to false to disable, or provide a config object to customize.
|
|
144
144
|
* @default { enabled: true }
|
|
145
145
|
*/
|
|
146
|
-
synonymExpansion: zod_1.z
|
|
147
|
-
.union([zod_1.z.literal(false), exports.synonymExpansionConfigSchema])
|
|
148
|
-
.optional()
|
|
149
|
-
.default({ enabled: true, replaceDefaults: false, maxExpansionsPerTerm: 5 }),
|
|
146
|
+
synonymExpansion: zod_1.z.union([zod_1.z.literal(false), exports.synonymExpansionConfigSchema]).optional(),
|
|
150
147
|
})
|
|
151
|
-
.
|
|
148
|
+
.optional()
|
|
149
|
+
.transform((opts) => ({
|
|
150
|
+
strategy: opts?.strategy ?? DEFAULT_EMBEDDING_OPTIONS.strategy,
|
|
151
|
+
modelName: opts?.modelName ?? DEFAULT_EMBEDDING_OPTIONS.modelName,
|
|
152
|
+
cacheDir: opts?.cacheDir ?? DEFAULT_EMBEDDING_OPTIONS.cacheDir,
|
|
153
|
+
useHNSW: opts?.useHNSW ?? DEFAULT_EMBEDDING_OPTIONS.useHNSW,
|
|
154
|
+
synonymExpansion: opts?.synonymExpansion ?? DEFAULT_EMBEDDING_OPTIONS.synonymExpansion,
|
|
155
|
+
}));
|
|
152
156
|
exports.codeCallSidecarOptionsSchema = zod_1.z
|
|
153
157
|
.object({
|
|
154
158
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codecall.types.js","sourceRoot":"","sources":["../../../src/codecall/codecall.types.ts"],"names":[],"mappings":"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","sourcesContent":["// file: libs/plugins/src/codecall/codecall.types.ts\n\nimport { z } from 'zod';\n\n// ===== Filter Function Types =====\n\n/**\n * Tool info passed to the directCalls filter function\n */\nexport interface DirectCallsFilterToolInfo {\n name: string;\n appId?: string;\n source?: string;\n tags?: string[];\n}\n\n/**\n * Tool info passed to the includeTools filter function\n */\nexport interface IncludeToolsFilterToolInfo {\n name: string;\n appId?: string;\n source?: string;\n description?: string;\n tags?: string[];\n}\n\n/**\n * Function type for directCalls filter\n */\nexport type DirectCallsFilterFn = (tool: DirectCallsFilterToolInfo) => boolean;\n\n/**\n * Function type for includeTools filter\n */\nexport type IncludeToolsFilterFn = (tool: IncludeToolsFilterToolInfo) => boolean;\n\n// Helper schemas for filter functions with runtime validation\nconst directCallsFilterSchema = z.custom<DirectCallsFilterFn>((val) => typeof val === 'function', {\n message: 'filter must be a function with signature (tool: DirectCallsFilterToolInfo) => boolean',\n});\n\nconst includeToolsFilterSchema = z.custom<IncludeToolsFilterFn>((val) => typeof val === 'function', {\n message: 'includeTools must be a function with signature (tool: IncludeToolsFilterToolInfo) => boolean',\n});\n\n// ===== Zod Schemas with Defaults =====\n\nexport const codeCallModeSchema = z\n .enum(['codecall_only', 'codecall_opt_in', 'metadata_driven'])\n .default('codecall_only');\n\nexport const codeCallVmPresetSchema = z.enum(['locked_down', 'secure', 'balanced', 'experimental']).default('secure');\n\n// Default values for VM options\nconst DEFAULT_VM_OPTIONS = {\n preset: 'secure' as const,\n};\n\nexport const codeCallVmOptionsSchema = z\n .object({\n /**\n * CSP-like preset; see README.\n * @default 'secure'\n */\n preset: codeCallVmPresetSchema,\n\n /**\n * Timeout for script execution in milliseconds\n * Defaults vary by preset\n */\n timeoutMs: z.number().positive().optional(),\n\n /**\n * Allow loop constructs (for, while, do-while)\n * Defaults vary by preset\n */\n allowLoops: z.boolean().optional(),\n\n /**\n * Maximum number of steps (if applicable)\n * Defaults vary by preset\n */\n maxSteps: z.number().positive().optional(),\n\n /**\n * List of disabled builtin functions\n * Defaults vary by preset\n */\n disabledBuiltins: z.array(z.string()).optional(),\n\n /**\n * List of disabled global variables\n * Defaults vary by preset\n */\n disabledGlobals: z.array(z.string()).optional(),\n\n /**\n * Allow console.log/warn/error\n * Defaults vary by preset\n */\n allowConsole: z.boolean().optional(),\n })\n .default(() => DEFAULT_VM_OPTIONS);\n\nexport const codeCallDirectCallsOptionsSchema = z.object({\n /**\n * Enable/disable the `codecall.invoke` meta-tool.\n */\n enabled: z.boolean(),\n\n /**\n * Optional allowlist of tool names.\n */\n allowedTools: z.array(z.string()).optional(),\n\n /**\n * Optional advanced filter function.\n * Signature: (tool: DirectCallsFilterToolInfo) => boolean\n */\n filter: directCallsFilterSchema.optional(),\n});\n\nexport const embeddingStrategySchema = z.enum(['tfidf', 'ml']).default('tfidf');\n\n// Synonym expansion configuration schema\nexport const synonymExpansionConfigSchema = z\n .object({\n /**\n * Enable/disable synonym expansion for TF-IDF search.\n * When enabled, queries are expanded with synonyms to improve relevance.\n * For example, \"add user\" will also match tools containing \"create user\".\n * @default true\n */\n enabled: z.boolean().default(true),\n\n /**\n * Additional synonym groups beyond the defaults.\n * Each group is an array of related terms that should be treated as equivalent.\n * @example [['customer', 'client', 'buyer'], ['order', 'purchase', 'transaction']]\n */\n additionalSynonyms: z.array(z.array(z.string())).optional(),\n\n /**\n * Replace default synonyms entirely with additionalSynonyms.\n * @default false\n */\n replaceDefaults: z.boolean().default(false),\n\n /**\n * Maximum number of synonym expansions per term.\n * Prevents query explosion for terms with many synonyms.\n * @default 5\n */\n maxExpansionsPerTerm: z.number().positive().default(5),\n })\n .default({ enabled: true, replaceDefaults: false, maxExpansionsPerTerm: 5 });\n\n// Default values for embedding options\nconst DEFAULT_EMBEDDING_OPTIONS = {\n strategy: 'tfidf' as const,\n modelName: 'Xenova/all-MiniLM-L6-v2',\n cacheDir: './.cache/transformers',\n useHNSW: false,\n synonymExpansion: { enabled: true, replaceDefaults: false, maxExpansionsPerTerm: 5 },\n};\n\nexport const codeCallEmbeddingOptionsSchema = z\n .object({\n /**\n * Embedding strategy to use for tool search\n * - 'tfidf': Lightweight, synchronous TF-IDF based search (no ML models required)\n * - 'ml': ML-based semantic search using transformers.js (better quality, requires model download)\n * @default 'tfidf'\n */\n strategy: embeddingStrategySchema,\n\n /**\n * Model name for ML-based embeddings (only used when strategy='ml')\n * @default 'Xenova/all-MiniLM-L6-v2'\n */\n modelName: z.string().default('Xenova/all-MiniLM-L6-v2'),\n\n /**\n * Cache directory for ML models (only used when strategy='ml')\n * @default './.cache/transformers'\n */\n cacheDir: z.string().default('./.cache/transformers'),\n\n /**\n * Enable HNSW index for faster search (only used when strategy='ml')\n * When enabled, provides O(log n) search instead of O(n) brute-force\n * @default false\n */\n useHNSW: z.boolean().default(false),\n\n /**\n * Synonym expansion configuration for TF-IDF search.\n * When enabled, queries like \"add user\" will match tools for \"create user\".\n * Only applies when strategy is 'tfidf' (ML already handles semantic similarity).\n * Set to false to disable, or provide a config object to customize.\n * @default { enabled: true }\n */\n synonymExpansion: z\n .union([z.literal(false), synonymExpansionConfigSchema])\n .optional()\n .default({ enabled: true, replaceDefaults: false, maxExpansionsPerTerm: 5 }),\n })\n .default(DEFAULT_EMBEDDING_OPTIONS);\n\nexport const codeCallSidecarOptionsSchema = z\n .object({\n /**\n * Enable pass-by-reference support via sidecar\n * When enabled, large strings are automatically lifted to a sidecar\n * and resolved at the callTool boundary\n * @default false\n */\n enabled: z.boolean().default(false),\n\n /**\n * Maximum total size of all stored references in bytes\n * @default 16MB (from security level)\n */\n maxTotalSize: z.number().positive().optional(),\n\n /**\n * Maximum size of a single reference in bytes\n * @default 4MB (from security level)\n */\n maxReferenceSize: z.number().positive().optional(),\n\n /**\n * Threshold in bytes to trigger extraction from source code\n * Strings larger than this are lifted to the sidecar\n * @default 64KB (from security level)\n */\n extractionThreshold: z.number().positive().optional(),\n\n /**\n * Maximum expanded size when resolving references for tool calls\n * @default 8MB (from security level)\n */\n maxResolvedSize: z.number().positive().optional(),\n\n /**\n * Whether to allow composite handles from string concatenation\n * If false, concatenating references throws an error\n * @default false (strict mode)\n */\n allowComposites: z.boolean().optional(),\n\n /**\n * Maximum script length (in characters) when sidecar is disabled\n * Prevents large inline data from being embedded in script\n * If null, no limit is enforced\n * @default 64KB\n */\n maxScriptLengthWhenDisabled: z\n .number()\n .positive()\n .nullable()\n .default(64 * 1024),\n })\n .default(() => ({\n enabled: false,\n maxScriptLengthWhenDisabled: 64 * 1024,\n }));\n\n// Inner schema without the outer .default() - used for extracting input type\nconst codeCallPluginOptionsObjectSchema = z.object({\n /**\n * CodeCall mode\n * @default 'codecall_only'\n */\n mode: codeCallModeSchema,\n\n /**\n * Default number of tools to return in search results\n * @default 8\n */\n topK: z.number().positive().default(8),\n\n /**\n * Maximum number of tool definitions to include\n * @default 8\n */\n maxDefinitions: z.number().positive().default(8),\n\n /**\n * Optional filter function for including tools.\n * Signature: (tool: IncludeToolsFilterToolInfo) => boolean\n */\n includeTools: includeToolsFilterSchema.optional(),\n\n /**\n * Direct calls configuration\n */\n directCalls: codeCallDirectCallsOptionsSchema.optional(),\n\n /**\n * VM execution options\n */\n vm: codeCallVmOptionsSchema,\n\n /**\n * Embedding configuration for tool search\n */\n embedding: codeCallEmbeddingOptionsSchema,\n\n /**\n * Sidecar (pass-by-reference) configuration\n * When enabled, large data is stored outside the sandbox and resolved at callTool boundary\n */\n sidecar: codeCallSidecarOptionsSchema,\n});\n\n// Default values for plugin options\nconst DEFAULT_PLUGIN_OPTIONS = {\n mode: 'codecall_only' as const,\n topK: 8,\n maxDefinitions: 8,\n vm: DEFAULT_VM_OPTIONS,\n embedding: DEFAULT_EMBEDDING_OPTIONS,\n sidecar: {\n enabled: false,\n maxScriptLengthWhenDisabled: 64 * 1024,\n },\n};\n\n// Full schema with default - used for parsing\nexport const codeCallPluginOptionsSchema = codeCallPluginOptionsObjectSchema.prefault(DEFAULT_PLUGIN_OPTIONS);\n\n// ===== TypeScript Types =====\n\n// Output types (after parsing, with defaults applied) - use for internal plugin logic\nexport type CodeCallMode = z.infer<typeof codeCallModeSchema>;\nexport type CodeCallVmPreset = z.infer<typeof codeCallVmPresetSchema>;\nexport type CodeCallVmOptions = z.infer<typeof codeCallVmOptionsSchema>;\nexport type CodeCallDirectCallsOptions = z.infer<typeof codeCallDirectCallsOptionsSchema>;\nexport type EmbeddingStrategy = z.infer<typeof embeddingStrategySchema>;\nexport type SynonymExpansionConfig = z.infer<typeof synonymExpansionConfigSchema>;\nexport type CodeCallSidecarOptions = z.infer<typeof codeCallSidecarOptionsSchema>;\n\nexport type CodeCallEmbeddingOptions = z.infer<typeof codeCallEmbeddingOptionsSchema>;\nexport type CodeCallEmbeddingOptionsInput = z.input<typeof codeCallEmbeddingOptionsSchema>;\n\n/**\n * Resolved options type (after parsing with defaults applied).\n * Use this for internal plugin logic where all defaults are guaranteed.\n */\nexport type CodeCallPluginOptions = z.infer<typeof codeCallPluginOptionsSchema>;\n\n/**\n * Input options type (what users provide to init()).\n * All fields with defaults are optional.\n */\nexport type CodeCallPluginOptionsInput = z.input<typeof codeCallPluginOptionsObjectSchema>;\n\n/**\n * Per-tool metadata used by CodeCall.\n * This maps to `metadata.codecall` on tools.\n */\nexport interface CodeCallToolMetadata {\n /**\n * If true, this tool stays visible in `list_tools`\n * even when CodeCall is hiding most tools.\n */\n visibleInListTools?: boolean;\n\n /**\n * Whether this tool can be used via CodeCall.\n * Semantics depend on CodeCallMode (see README).\n */\n enabledInCodeCall?: boolean;\n\n /** Optional extra indexing hints */\n appId?: string;\n source?: string;\n tags?: string[];\n}\n\n// ----- meta-tool contracts -----\n\nexport type CodeCallSearchInput = {\n query: string;\n topK?: number;\n filter?: {\n appIds?: string[];\n tags?: string[];\n includeOpenApi?: boolean;\n includeInline?: boolean;\n };\n};\n\nexport type CodeCallSearchResult = {\n tools: {\n name: string;\n description: string;\n appId?: string;\n source?: string;\n score: number;\n }[];\n};\n\nexport type CodeCallDescribeInput = {\n tools: string[];\n max?: number;\n};\n\nexport type CodeCallDescribeResult = {\n tools: {\n name: string;\n description: string;\n inputSchema: unknown;\n outputSchema?: unknown | null;\n examples?: {\n input: unknown;\n output?: unknown;\n }[];\n }[];\n};\n\nexport type CodeCallExecuteInput = {\n script: string;\n /**\n * Arbitrary, readonly context exposed as `codecallContext`.\n */\n context?: Record<string, unknown>;\n};\n\n// ---- global FrontMCP metadata extension ----\n\ndeclare global {\n interface ExtendFrontMcpToolMetadata {\n /**\n * CodeCall-specific metadata, attached via `@Tool({ metadata: { codecall: ... } })`\n * or whatever your decorator mapping is.\n */\n codecall?: CodeCallToolMetadata;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"codecall.types.js","sourceRoot":"","sources":["../../../src/codecall/codecall.types.ts"],"names":[],"mappings":"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","sourcesContent":["// file: libs/plugins/src/codecall/codecall.types.ts\n\nimport { z } from 'zod';\n\n// ===== Filter Function Types =====\n\n/**\n * Tool info passed to the directCalls filter function\n */\nexport interface DirectCallsFilterToolInfo {\n name: string;\n appId?: string;\n source?: string;\n tags?: string[];\n}\n\n/**\n * Tool info passed to the includeTools filter function\n */\nexport interface IncludeToolsFilterToolInfo {\n name: string;\n appId?: string;\n source?: string;\n description?: string;\n tags?: string[];\n}\n\n/**\n * Function type for directCalls filter\n */\nexport type DirectCallsFilterFn = (tool: DirectCallsFilterToolInfo) => boolean;\n\n/**\n * Function type for includeTools filter\n */\nexport type IncludeToolsFilterFn = (tool: IncludeToolsFilterToolInfo) => boolean;\n\n// Helper schemas for filter functions with runtime validation\nconst directCallsFilterSchema = z.custom<DirectCallsFilterFn>((val) => typeof val === 'function', {\n message: 'filter must be a function with signature (tool: DirectCallsFilterToolInfo) => boolean',\n});\n\nconst includeToolsFilterSchema = z.custom<IncludeToolsFilterFn>((val) => typeof val === 'function', {\n message: 'includeTools must be a function with signature (tool: IncludeToolsFilterToolInfo) => boolean',\n});\n\n// ===== Zod Schemas with Defaults =====\n\nexport const codeCallModeSchema = z\n .enum(['codecall_only', 'codecall_opt_in', 'metadata_driven'])\n .default('codecall_only');\n\nexport const codeCallVmPresetSchema = z.enum(['locked_down', 'secure', 'balanced', 'experimental']).default('secure');\n\n// Default values for VM options\nconst DEFAULT_VM_OPTIONS = {\n preset: 'secure' as const,\n};\n\nexport const codeCallVmOptionsSchema = z\n .object({\n /**\n * CSP-like preset; see README.\n * @default 'secure'\n */\n preset: codeCallVmPresetSchema,\n\n /**\n * Timeout for script execution in milliseconds\n * Defaults vary by preset\n */\n timeoutMs: z.number().positive().optional(),\n\n /**\n * Allow loop constructs (for, while, do-while)\n * Defaults vary by preset\n */\n allowLoops: z.boolean().optional(),\n\n /**\n * Maximum number of steps (if applicable)\n * Defaults vary by preset\n */\n maxSteps: z.number().positive().optional(),\n\n /**\n * List of disabled builtin functions\n * Defaults vary by preset\n */\n disabledBuiltins: z.array(z.string()).optional(),\n\n /**\n * List of disabled global variables\n * Defaults vary by preset\n */\n disabledGlobals: z.array(z.string()).optional(),\n\n /**\n * Allow console.log/warn/error\n * Defaults vary by preset\n */\n allowConsole: z.boolean().optional(),\n })\n .default(() => DEFAULT_VM_OPTIONS);\n\nexport const codeCallDirectCallsOptionsSchema = z.object({\n /**\n * Enable/disable the `codecall.invoke` meta-tool.\n */\n enabled: z.boolean(),\n\n /**\n * Optional allowlist of tool names.\n */\n allowedTools: z.array(z.string()).optional(),\n\n /**\n * Optional advanced filter function.\n * Signature: (tool: DirectCallsFilterToolInfo) => boolean\n */\n filter: directCallsFilterSchema.optional(),\n});\n\nexport const embeddingStrategySchema = z.enum(['tfidf', 'ml']).default('tfidf');\n\n// Synonym expansion configuration schema\nexport const synonymExpansionConfigSchema = z\n .object({\n /**\n * Enable/disable synonym expansion for TF-IDF search.\n * When enabled, queries are expanded with synonyms to improve relevance.\n * For example, \"add user\" will also match tools containing \"create user\".\n * @default true\n */\n enabled: z.boolean().default(true),\n\n /**\n * Additional synonym groups beyond the defaults.\n * Each group is an array of related terms that should be treated as equivalent.\n * @example [['customer', 'client', 'buyer'], ['order', 'purchase', 'transaction']]\n */\n additionalSynonyms: z.array(z.array(z.string())).optional(),\n\n /**\n * Replace default synonyms entirely with additionalSynonyms.\n * @default false\n */\n replaceDefaults: z.boolean().default(false),\n\n /**\n * Maximum number of synonym expansions per term.\n * Prevents query explosion for terms with many synonyms.\n * @default 5\n */\n maxExpansionsPerTerm: z.number().positive().default(5),\n })\n .default({ enabled: true, replaceDefaults: false, maxExpansionsPerTerm: 5 });\n\n// Default values for embedding options\nconst DEFAULT_EMBEDDING_OPTIONS = {\n strategy: 'tfidf' as const,\n modelName: 'Xenova/all-MiniLM-L6-v2',\n cacheDir: './.cache/transformers',\n useHNSW: false,\n synonymExpansion: { enabled: true, replaceDefaults: false, maxExpansionsPerTerm: 5 },\n};\n\nexport const codeCallEmbeddingOptionsSchema = z\n .object({\n /**\n * Embedding strategy to use for tool search\n * - 'tfidf': Lightweight, synchronous TF-IDF based search (no ML models required)\n * - 'ml': ML-based semantic search using transformers.js (better quality, requires model download)\n * @default 'tfidf'\n */\n strategy: embeddingStrategySchema.optional(),\n\n /**\n * Model name for ML-based embeddings (only used when strategy='ml')\n * @default 'Xenova/all-MiniLM-L6-v2'\n */\n modelName: z.string().optional(),\n\n /**\n * Cache directory for ML models (only used when strategy='ml')\n * @default './.cache/transformers'\n */\n cacheDir: z.string().optional(),\n\n /**\n * Enable HNSW index for faster search (only used when strategy='ml')\n * When enabled, provides O(log n) search instead of O(n) brute-force\n * @default false\n */\n useHNSW: z.boolean().optional(),\n\n /**\n * Synonym expansion configuration for TF-IDF search.\n * When enabled, queries like \"add user\" will match tools for \"create user\".\n * Only applies when strategy is 'tfidf' (ML already handles semantic similarity).\n * Set to false to disable, or provide a config object to customize.\n * @default { enabled: true }\n */\n synonymExpansion: z.union([z.literal(false), synonymExpansionConfigSchema]).optional(),\n })\n .optional()\n .transform((opts) => ({\n strategy: opts?.strategy ?? DEFAULT_EMBEDDING_OPTIONS.strategy,\n modelName: opts?.modelName ?? DEFAULT_EMBEDDING_OPTIONS.modelName,\n cacheDir: opts?.cacheDir ?? DEFAULT_EMBEDDING_OPTIONS.cacheDir,\n useHNSW: opts?.useHNSW ?? DEFAULT_EMBEDDING_OPTIONS.useHNSW,\n synonymExpansion: opts?.synonymExpansion ?? DEFAULT_EMBEDDING_OPTIONS.synonymExpansion,\n }));\n\nexport const codeCallSidecarOptionsSchema = z\n .object({\n /**\n * Enable pass-by-reference support via sidecar\n * When enabled, large strings are automatically lifted to a sidecar\n * and resolved at the callTool boundary\n * @default false\n */\n enabled: z.boolean().default(false),\n\n /**\n * Maximum total size of all stored references in bytes\n * @default 16MB (from security level)\n */\n maxTotalSize: z.number().positive().optional(),\n\n /**\n * Maximum size of a single reference in bytes\n * @default 4MB (from security level)\n */\n maxReferenceSize: z.number().positive().optional(),\n\n /**\n * Threshold in bytes to trigger extraction from source code\n * Strings larger than this are lifted to the sidecar\n * @default 64KB (from security level)\n */\n extractionThreshold: z.number().positive().optional(),\n\n /**\n * Maximum expanded size when resolving references for tool calls\n * @default 8MB (from security level)\n */\n maxResolvedSize: z.number().positive().optional(),\n\n /**\n * Whether to allow composite handles from string concatenation\n * If false, concatenating references throws an error\n * @default false (strict mode)\n */\n allowComposites: z.boolean().optional(),\n\n /**\n * Maximum script length (in characters) when sidecar is disabled\n * Prevents large inline data from being embedded in script\n * If null, no limit is enforced\n * @default 64KB\n */\n maxScriptLengthWhenDisabled: z\n .number()\n .positive()\n .nullable()\n .default(64 * 1024),\n })\n .default(() => ({\n enabled: false,\n maxScriptLengthWhenDisabled: 64 * 1024,\n }));\n\n// Inner schema without the outer .default() - used for extracting input type\nconst codeCallPluginOptionsObjectSchema = z.object({\n /**\n * CodeCall mode\n * @default 'codecall_only'\n */\n mode: codeCallModeSchema,\n\n /**\n * Default number of tools to return in search results\n * @default 8\n */\n topK: z.number().positive().default(8),\n\n /**\n * Maximum number of tool definitions to include\n * @default 8\n */\n maxDefinitions: z.number().positive().default(8),\n\n /**\n * Optional filter function for including tools.\n * Signature: (tool: IncludeToolsFilterToolInfo) => boolean\n */\n includeTools: includeToolsFilterSchema.optional(),\n\n /**\n * Direct calls configuration\n */\n directCalls: codeCallDirectCallsOptionsSchema.optional(),\n\n /**\n * VM execution options\n */\n vm: codeCallVmOptionsSchema,\n\n /**\n * Embedding configuration for tool search\n */\n embedding: codeCallEmbeddingOptionsSchema,\n\n /**\n * Sidecar (pass-by-reference) configuration\n * When enabled, large data is stored outside the sandbox and resolved at callTool boundary\n */\n sidecar: codeCallSidecarOptionsSchema,\n});\n\n// Default values for plugin options\nconst DEFAULT_PLUGIN_OPTIONS = {\n mode: 'codecall_only' as const,\n topK: 8,\n maxDefinitions: 8,\n vm: DEFAULT_VM_OPTIONS,\n embedding: DEFAULT_EMBEDDING_OPTIONS,\n sidecar: {\n enabled: false,\n maxScriptLengthWhenDisabled: 64 * 1024,\n },\n};\n\n// Full schema with default - used for parsing\nexport const codeCallPluginOptionsSchema = codeCallPluginOptionsObjectSchema.prefault(DEFAULT_PLUGIN_OPTIONS);\n\n// ===== TypeScript Types =====\n\n// Output types (after parsing, with defaults applied) - use for internal plugin logic\nexport type CodeCallMode = z.infer<typeof codeCallModeSchema>;\nexport type CodeCallVmPreset = z.infer<typeof codeCallVmPresetSchema>;\nexport type CodeCallVmOptions = z.infer<typeof codeCallVmOptionsSchema>;\nexport type CodeCallDirectCallsOptions = z.infer<typeof codeCallDirectCallsOptionsSchema>;\nexport type EmbeddingStrategy = z.infer<typeof embeddingStrategySchema>;\nexport type SynonymExpansionConfig = z.infer<typeof synonymExpansionConfigSchema>;\nexport type CodeCallSidecarOptions = z.infer<typeof codeCallSidecarOptionsSchema>;\n\nexport type CodeCallEmbeddingOptions = z.infer<typeof codeCallEmbeddingOptionsSchema>;\nexport type CodeCallEmbeddingOptionsInput = z.input<typeof codeCallEmbeddingOptionsSchema>;\n\n/**\n * Resolved options type (after parsing with defaults applied).\n * Use this for internal plugin logic where all defaults are guaranteed.\n */\nexport type CodeCallPluginOptions = z.infer<typeof codeCallPluginOptionsSchema>;\n\n/**\n * Input options type (what users provide to init()).\n * All fields with defaults are optional.\n */\nexport type CodeCallPluginOptionsInput = z.input<typeof codeCallPluginOptionsObjectSchema>;\n\n/**\n * Per-tool metadata used by CodeCall.\n * This maps to `metadata.codecall` on tools.\n */\nexport interface CodeCallToolMetadata {\n /**\n * If true, this tool stays visible in `list_tools`\n * even when CodeCall is hiding most tools.\n */\n visibleInListTools?: boolean;\n\n /**\n * Whether this tool can be used via CodeCall.\n * Semantics depend on CodeCallMode (see README).\n */\n enabledInCodeCall?: boolean;\n\n /** Optional extra indexing hints */\n appId?: string;\n source?: string;\n tags?: string[];\n}\n\n// ----- meta-tool contracts -----\n\nexport type CodeCallSearchInput = {\n query: string;\n topK?: number;\n filter?: {\n appIds?: string[];\n tags?: string[];\n includeOpenApi?: boolean;\n includeInline?: boolean;\n };\n};\n\nexport type CodeCallSearchResult = {\n tools: {\n name: string;\n description: string;\n appId?: string;\n source?: string;\n score: number;\n }[];\n};\n\nexport type CodeCallDescribeInput = {\n tools: string[];\n max?: number;\n};\n\nexport type CodeCallDescribeResult = {\n tools: {\n name: string;\n description: string;\n inputSchema: unknown;\n outputSchema?: unknown | null;\n examples?: {\n input: unknown;\n output?: unknown;\n }[];\n }[];\n};\n\nexport type CodeCallExecuteInput = {\n script: string;\n /**\n * Arbitrary, readonly context exposed as `codecallContext`.\n */\n context?: Record<string, unknown>;\n};\n\n// ---- global FrontMCP metadata extension ----\n\ndeclare global {\n interface ExtendFrontMcpToolMetadata {\n /**\n * CodeCall-specific metadata, attached via `@Tool({ metadata: { codecall: ... } })`\n * or whatever your decorator mapping is.\n */\n codecall?: CodeCallToolMetadata;\n }\n}\n"]}
|
|
@@ -7,9 +7,10 @@ export declare const invokeToolInputSchema: z.ZodObject<{
|
|
|
7
7
|
export type InvokeToolInput = z.infer<typeof invokeToolInputSchema>;
|
|
8
8
|
export declare const invokeToolOutputSchema: z.ZodObject<{
|
|
9
9
|
_meta: z.ZodOptional<z.ZodObject<{
|
|
10
|
+
progressToken: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
|
|
10
11
|
"io.modelcontextprotocol/related-task": z.ZodOptional<z.ZodObject<{
|
|
11
12
|
taskId: z.ZodString;
|
|
12
|
-
}, z.core.$
|
|
13
|
+
}, z.core.$strip>>;
|
|
13
14
|
}, z.core.$loose>>;
|
|
14
15
|
content: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
15
16
|
type: z.ZodLiteral<"text">;
|
|
@@ -66,6 +67,10 @@ export declare const invokeToolOutputSchema: z.ZodObject<{
|
|
|
66
67
|
src: z.ZodString;
|
|
67
68
|
mimeType: z.ZodOptional<z.ZodString>;
|
|
68
69
|
sizes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
70
|
+
theme: z.ZodOptional<z.ZodEnum<{
|
|
71
|
+
light: "light";
|
|
72
|
+
dark: "dark";
|
|
73
|
+
}>>;
|
|
69
74
|
}, z.core.$strip>>>;
|
|
70
75
|
name: z.ZodString;
|
|
71
76
|
title: z.ZodOptional<z.ZodString>;
|