mirror of
https://github.com/shishantbiswas/bknd.git
synced 2026-03-15 20:17:22 +00:00
added mcp tests for media
This commit is contained in:
@@ -1,19 +1,23 @@
|
||||
import { describe, it, expect, beforeAll } from "bun:test";
|
||||
import { type App, createApp } from "core/test/utils";
|
||||
import { describe, test, expect, beforeAll, beforeEach, afterAll } from "bun:test";
|
||||
import { type App, createApp, createMcpToolCaller } from "core/test/utils";
|
||||
import { getSystemMcp } from "modules/mcp/system-mcp";
|
||||
import { registries } from "index";
|
||||
import { StorageLocalAdapter } from "adapter/node/storage/StorageLocalAdapter";
|
||||
import { disableConsoleLog, enableConsoleLog } from "core/utils";
|
||||
|
||||
beforeAll(disableConsoleLog);
|
||||
afterAll(enableConsoleLog);
|
||||
|
||||
/**
|
||||
* - [ ] config_media_get
|
||||
* - [ ] config_media_update
|
||||
* - [ ] config_media_adapter_get
|
||||
* - [ ] config_media_adapter_update
|
||||
* - [x] config_media_get
|
||||
* - [x] config_media_update
|
||||
* - [x] config_media_adapter_get
|
||||
* - [x] config_media_adapter_update
|
||||
*/
|
||||
describe("mcp media", async () => {
|
||||
let app: App;
|
||||
let server: ReturnType<typeof getSystemMcp>;
|
||||
beforeAll(async () => {
|
||||
beforeEach(async () => {
|
||||
registries.media.register("local", StorageLocalAdapter);
|
||||
app = createApp({
|
||||
initialConfig: {
|
||||
@@ -35,5 +39,79 @@ describe("mcp media", async () => {
|
||||
});
|
||||
await app.build();
|
||||
server = getSystemMcp(app);
|
||||
server.setLogLevel("error");
|
||||
server.onNotification((message) => {
|
||||
console.dir(message, { depth: null });
|
||||
});
|
||||
});
|
||||
|
||||
const tool = createMcpToolCaller();
|
||||
|
||||
test("config_media_{get,update}", async () => {
|
||||
const result = await tool(server, "config_media_get", {});
|
||||
expect(result).toEqual({
|
||||
path: "",
|
||||
secrets: false,
|
||||
partial: false,
|
||||
value: app.toJSON().media,
|
||||
});
|
||||
|
||||
// partial
|
||||
expect((await tool(server, "config_media_get", { path: "adapter" })).value).toEqual({
|
||||
type: "local",
|
||||
config: {
|
||||
path: "./",
|
||||
},
|
||||
});
|
||||
|
||||
// update
|
||||
await tool(server, "config_media_update", {
|
||||
value: {
|
||||
storage: {
|
||||
body_max_size: 1024 * 1024 * 10,
|
||||
},
|
||||
},
|
||||
return_config: true,
|
||||
});
|
||||
expect(app.toJSON().media.storage.body_max_size).toBe(1024 * 1024 * 10);
|
||||
});
|
||||
|
||||
test("config_media_adapter_{get,update}", async () => {
|
||||
const result = await tool(server, "config_media_adapter_get", {});
|
||||
expect(result).toEqual({
|
||||
secrets: false,
|
||||
value: app.toJSON().media.adapter,
|
||||
});
|
||||
|
||||
// update
|
||||
await tool(server, "config_media_adapter_update", {
|
||||
value: {
|
||||
type: "local",
|
||||
config: {
|
||||
path: "./subdir",
|
||||
},
|
||||
},
|
||||
});
|
||||
const adapter = app.toJSON().media.adapter as any;
|
||||
expect(adapter.config.path).toBe("./subdir");
|
||||
expect(adapter.type).toBe("local");
|
||||
|
||||
// set to s3
|
||||
{
|
||||
await tool(server, "config_media_adapter_update", {
|
||||
value: {
|
||||
type: "s3",
|
||||
config: {
|
||||
access_key: "123",
|
||||
secret_access_key: "456",
|
||||
url: "https://example.com/what",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const adapter = app.toJSON(true).media.adapter as any;
|
||||
expect(adapter.type).toBe("s3");
|
||||
expect(adapter.config.url).toBe("https://example.com/what");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -177,7 +177,6 @@ export class SchemaObject<Schema extends TSchema = TSchema> {
|
||||
|
||||
this.throwIfRestricted(partial);
|
||||
|
||||
// overwrite arrays and primitives, only deep merge objects
|
||||
// @ts-ignore
|
||||
const config = set(current, path, value);
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ export function buildMediaSchema() {
|
||||
},
|
||||
{ default: {} },
|
||||
),
|
||||
// @todo: currently cannot be updated partially using mcp
|
||||
adapter: $schema(
|
||||
"config_media_adapter",
|
||||
s.anyOf(Object.values(adapterSchemaObject)),
|
||||
|
||||
@@ -50,12 +50,28 @@ export const $schema = <
|
||||
{
|
||||
...mcp.getToolOptions("update"),
|
||||
inputSchema: s.strictObject({
|
||||
full: s.boolean({ default: false }).optional(),
|
||||
value: schema as any,
|
||||
return_config: s.boolean({ default: false }).optional(),
|
||||
secrets: s.boolean({ default: false }).optional(),
|
||||
}),
|
||||
},
|
||||
async (params, ctx: AppToolHandlerCtx) => {
|
||||
return ctx.json(params);
|
||||
const { value, return_config, secrets } = params;
|
||||
const [module_name, ...rest] = node.instancePath;
|
||||
|
||||
await ctx.context.app.mutateConfig(module_name as any).overwrite(rest, value);
|
||||
|
||||
let config: any = undefined;
|
||||
if (return_config) {
|
||||
const configs = ctx.context.app.toJSON(secrets);
|
||||
config = getPath(configs, node.instancePath);
|
||||
}
|
||||
|
||||
return ctx.json({
|
||||
success: true,
|
||||
module: module_name,
|
||||
config,
|
||||
});
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
@@ -2910,10 +2910,6 @@
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"full": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"value": {
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -3028,6 +3024,14 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"return_config": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"secrets": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user