@byted-las/contextlake-openclaw 1.0.11 → 1.0.14

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/dist/index.js CHANGED
@@ -4,7 +4,7 @@ const commands_1 = require("./src/commands");
4
4
  const plugin = {
5
5
  id: 'contextlake-openclaw',
6
6
  name: 'ContextLake',
7
- version: '1.0.11',
7
+ version: '1.0.12',
8
8
  description: 'A lightweight knowledge base plugin for OpenClaw using LanceDB and TOS, with data profiling support',
9
9
  configSchema: {
10
10
  type: 'object',
@@ -66,7 +66,20 @@ function getCliCommands(pluginConfig, logger) {
66
66
  listS3ObjectsAction: async (url, options) => {
67
67
  logger.info(`[${new Date().toISOString()}] [ContextLake] CLI list-s3-objects started`, { url, options });
68
68
  try {
69
- const result = await (0, s3_tools_1.listS3Objects)({ url }, options.prefix || '', parseOptionalInt(options.maxKeys, 1000), options.continuationToken);
69
+ // Parse prefix from URL if present
70
+ let prefix = '';
71
+ if (url && !url.startsWith('file://')) {
72
+ try {
73
+ const parsedUrl = new URL(url);
74
+ prefix = parsedUrl.pathname.replace(/^\//, '');
75
+ // Reconstruct url without path to pass to listS3Objects as base url
76
+ url = `${parsedUrl.protocol}//${parsedUrl.host}`;
77
+ }
78
+ catch (e) {
79
+ // ignore, leave url as is
80
+ }
81
+ }
82
+ const result = await (0, s3_tools_1.listS3Objects)({ url }, prefix, parseOptionalInt(options.maxKeys, 1000), options.continuationToken);
70
83
  // eslint-disable-next-line no-console
71
84
  console.log(JSON.stringify(result, null, 2));
72
85
  logger.info(`[${new Date().toISOString()}] [ContextLake] CLI list-s3-objects success`);
@@ -70,7 +70,6 @@ function registerAll(ctx, logger) {
70
70
  // S3 Tools
71
71
  contextlake.command('list-s3-objects <url>')
72
72
  .description('List objects in an S3-compatible bucket or local directory')
73
- .option('--prefix <string>', 'Prefix to list')
74
73
  .option('--max-keys <number>', 'Maximum number of keys to return', '1000')
75
74
  .option('--continuation-token <string>', 'Continuation token for pagination')
76
75
  .action(commands.listS3ObjectsAction);
@@ -49,11 +49,22 @@ function getSlashCommands(pluginConfig, logger) {
49
49
  logger.info(`[${new Date().toISOString()}] [ContextLake] Slash command list-s3-objects started`, { args });
50
50
  try {
51
51
  if (args.length === 0) {
52
- return { text: `**Error:** Missing URL. Usage: /contextlake-list-s3-objects <url> [prefix] [maxKeys]` };
52
+ return { text: `**Error:** Missing URL. Usage: /contextlake-list-s3-objects <url> [maxKeys]` };
53
+ }
54
+ let url = args[0];
55
+ const maxKeys = args.length > 1 ? parseOptionalInt(args[1], 1000) : 1000;
56
+ let prefix = '';
57
+ if (url && !url.startsWith('file://')) {
58
+ try {
59
+ const parsedUrl = new URL(url);
60
+ prefix = parsedUrl.pathname.replace(/^\//, '');
61
+ // Reconstruct url without path to pass to listS3Objects as base url
62
+ url = `${parsedUrl.protocol}//${parsedUrl.host}`;
63
+ }
64
+ catch (e) {
65
+ // ignore, leave url as is
66
+ }
53
67
  }
54
- const url = args[0];
55
- const prefix = args.length > 1 ? args[1] : '';
56
- const maxKeys = args.length > 2 ? parseOptionalInt(args[2], 1000) : 1000;
57
68
  const result = await (0, s3_tools_1.listS3Objects)({ url }, prefix, maxKeys);
58
69
  return { text: `**List S3 Objects Results:**\n\`\`\`json\n${JSON.stringify(result, null, 2)}\n\`\`\`` };
59
70
  }
package/index.ts CHANGED
@@ -5,7 +5,7 @@ import { registerAll } from './src/commands';
5
5
  const plugin = {
6
6
  id: 'contextlake-openclaw',
7
7
  name: 'ContextLake',
8
- version: '1.0.11',
8
+ version: '1.0.12',
9
9
  description: 'A lightweight knowledge base plugin for OpenClaw using LanceDB and TOS, with data profiling support',
10
10
  configSchema: {
11
11
  type: 'object',
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "contextlake-openclaw",
3
3
  "name": "ContextLake",
4
- "version": "1.0.11",
4
+ "version": "1.0.12",
5
5
  "description": "A lightweight knowledge base plugin for OpenClaw using LanceDB and TOS, with data profiling support",
6
6
  "skills": ["./src/skills"],
7
7
  "configSchema": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@byted-las/contextlake-openclaw",
3
- "version": "1.0.11",
3
+ "version": "1.0.14",
4
4
  "description": "ContextLake OpenClaw Plugin for managing knowledge base",
5
5
  "main": "index.ts",
6
6
  "files": [
@@ -18,8 +18,6 @@
18
18
  "build": "tsc && npm run copy-assets",
19
19
  "copy-assets": "mkdir -p dist/src/skills && cp -r src/skills/* dist/src/skills/ 2>/dev/null || true && mkdir -p dist/src/lib/scripts && cp src/lib/scripts/*.py dist/src/lib/scripts/ 2>/dev/null || true",
20
20
  "test": "vitest --reporter verbose",
21
- "test:local": "npx ts-node scripts/local-test.ts",
22
- "test:profiler": "npx ts-node scripts/local-profiler-test.ts",
23
21
  "cli": "npx ts-node scripts/cli.ts"
24
22
  },
25
23
  "keywords": [
@@ -75,9 +75,22 @@ export function getCliCommands(pluginConfig: ContextLakeConfig, logger: any) {
75
75
  listS3ObjectsAction: async (url: string, options: any) => {
76
76
  logger.info(`[${new Date().toISOString()}] [ContextLake] CLI list-s3-objects started`, { url, options });
77
77
  try {
78
+ // Parse prefix from URL if present
79
+ let prefix = '';
80
+ if (url && !url.startsWith('file://')) {
81
+ try {
82
+ const parsedUrl = new URL(url);
83
+ prefix = parsedUrl.pathname.replace(/^\//, '');
84
+ // Reconstruct url without path to pass to listS3Objects as base url
85
+ url = `${parsedUrl.protocol}//${parsedUrl.host}`;
86
+ } catch (e) {
87
+ // ignore, leave url as is
88
+ }
89
+ }
90
+
78
91
  const result = await listS3Objects(
79
92
  { url },
80
- options.prefix || '',
93
+ prefix,
81
94
  parseOptionalInt(options.maxKeys, 1000),
82
95
  options.continuationToken
83
96
  );
@@ -12,35 +12,35 @@ export function registerAll(ctx: OpenClawPluginApi, logger: PluginLogger) {
12
12
  try {
13
13
  const tools = getAgentTools(pluginConfig, logger);
14
14
 
15
- ctx.registerTool(tools.retrieveTool );
15
+ ctx.registerTool(tools.retrieveTool, { name: tools.retrieveTool.name });
16
16
  logger.info(`[${new Date().toISOString()}] [ContextLake] Tool registered: ${tools.retrieveTool.name}`);
17
17
 
18
- ctx.registerTool(tools.listTool );
18
+ ctx.registerTool(tools.listTool, { name: tools.listTool.name });
19
19
  logger.info(`[${new Date().toISOString()}] [ContextLake] Tool registered: ${tools.listTool.name}`);
20
20
 
21
- ctx.registerTool(tools.deleteTool );
21
+ ctx.registerTool(tools.deleteTool, { name: tools.deleteTool.name });
22
22
  logger.info(`[${new Date().toISOString()}] [ContextLake] Tool registered: ${tools.deleteTool.name}`);
23
23
 
24
- ctx.registerTool(tools.listS3ObjectsTool );
24
+ ctx.registerTool(tools.listS3ObjectsTool, { name: tools.listS3ObjectsTool.name });
25
25
  logger.info(`[${new Date().toISOString()}] [ContextLake] Tool registered: ${tools.listS3ObjectsTool.name}`);
26
26
 
27
- ctx.registerTool(tools.readS3ObjectTool );
27
+ ctx.registerTool(tools.readS3ObjectTool, { name: tools.readS3ObjectTool.name });
28
28
  logger.info(`[${new Date().toISOString()}] [ContextLake] Tool registered: ${tools.readS3ObjectTool.name}`);
29
29
 
30
- ctx.registerTool(tools.writeLanceCatalogTool );
30
+ ctx.registerTool(tools.writeLanceCatalogTool, { name: tools.writeLanceCatalogTool.name });
31
31
  logger.info(`[${new Date().toISOString()}] [ContextLake] Tool registered: ${tools.writeLanceCatalogTool.name}`);
32
32
 
33
- ctx.registerTool(tools.readLanceCatalogTool );
33
+ ctx.registerTool(tools.readLanceCatalogTool, { name: tools.readLanceCatalogTool.name });
34
34
  logger.info(`[${new Date().toISOString()}] [ContextLake] Tool registered: ${tools.readLanceCatalogTool.name}`);
35
35
 
36
- ctx.registerTool(tools.generatePresignedUrlTool );
36
+ ctx.registerTool(tools.generatePresignedUrlTool, { name: tools.generatePresignedUrlTool.name });
37
37
  logger.info(`[${new Date().toISOString()}] [ContextLake] Tool registered: ${tools.generatePresignedUrlTool.name}`);
38
38
 
39
- ctx.registerTool(tools.listDatasourceTool );
39
+ ctx.registerTool(tools.listDatasourceTool, { name: tools.listDatasourceTool.name });
40
40
  logger.info(`[${new Date().toISOString()}] [ContextLake] Tool registered: ${tools.listDatasourceTool.name}`);
41
41
 
42
42
  for (const lasTool of tools.lasTools) {
43
- ctx.registerTool(lasTool);
43
+ ctx.registerTool(lasTool, { name: lasTool.name });
44
44
  logger.info(`[${new Date().toISOString()}] [ContextLake] Tool registered: ${lasTool.name}`);
45
45
  }
46
46
 
@@ -88,7 +88,6 @@ export function registerAll(ctx: OpenClawPluginApi, logger: PluginLogger) {
88
88
  // S3 Tools
89
89
  contextlake.command('list-s3-objects <url>')
90
90
  .description('List objects in an S3-compatible bucket or local directory')
91
- .option('--prefix <string>', 'Prefix to list')
92
91
  .option('--max-keys <number>', 'Maximum number of keys to return', '1000')
93
92
  .option('--continuation-token <string>', 'Continuation token for pagination')
94
93
  .action(commands.listS3ObjectsAction);
@@ -58,11 +58,22 @@ export function getSlashCommands(pluginConfig: ContextLakeConfig, logger: any) {
58
58
 
59
59
  try {
60
60
  if (args.length === 0) {
61
- return { text: `**Error:** Missing URL. Usage: /contextlake-list-s3-objects <url> [prefix] [maxKeys]` };
61
+ return { text: `**Error:** Missing URL. Usage: /contextlake-list-s3-objects <url> [maxKeys]` };
62
+ }
63
+ let url = args[0];
64
+ const maxKeys = args.length > 1 ? parseOptionalInt(args[1], 1000) : 1000;
65
+
66
+ let prefix = '';
67
+ if (url && !url.startsWith('file://')) {
68
+ try {
69
+ const parsedUrl = new URL(url);
70
+ prefix = parsedUrl.pathname.replace(/^\//, '');
71
+ // Reconstruct url without path to pass to listS3Objects as base url
72
+ url = `${parsedUrl.protocol}//${parsedUrl.host}`;
73
+ } catch (e) {
74
+ // ignore, leave url as is
75
+ }
62
76
  }
63
- const url = args[0];
64
- const prefix = args.length > 1 ? args[1] : '';
65
- const maxKeys = args.length > 2 ? parseOptionalInt(args[2], 1000) : 1000;
66
77
 
67
78
  const result = await listS3Objects({ url }, prefix, maxKeys);
68
79
  return { text: `**List S3 Objects Results:**\n\`\`\`json\n${JSON.stringify(result, null, 2)}\n\`\`\`` };
@@ -36,7 +36,7 @@ export function getAgentTools(pluginConfig: ContextLakeConfig, logger: any): {
36
36
  additionalProperties: false
37
37
  },
38
38
  async execute(toolCallId: string, params: any) {
39
- logger.info(`[${new Date().toISOString()}] [ContextLake] Executing list-datasource skill, toolCallId: ${toolCallId}`);
39
+ logger.info(`[${new Date().toISOString()}] [ContextLake] Executing list-datasource tool, toolCallId: ${toolCallId}`);
40
40
  try {
41
41
  const result = await listDataSources();
42
42
  return {
@@ -44,7 +44,7 @@ export function getAgentTools(pluginConfig: ContextLakeConfig, logger: any): {
44
44
  details: result
45
45
  } as any;
46
46
  } catch (error: any) {
47
- logger.error(`[${new Date().toISOString()}] [ContextLake] list-datasource skill failed`, { error: error.message });
47
+ logger.error(`[${new Date().toISOString()}] [ContextLake] list-datasource tool failed`, { error: error.message });
48
48
  return {
49
49
  content: [{ type: "text", text: String(error.message) }],
50
50
  details: { error: error.message }
@@ -77,7 +77,7 @@ Example User Queries:
77
77
  },
78
78
 
79
79
  async execute(toolCallId: string, params: any) {
80
- logger.info(`[${new Date().toISOString()}] [ContextLake] Executing retrieve skill, toolCallId: ${toolCallId}`, { params: JSON.stringify(params) });
80
+ logger.info(`[${new Date().toISOString()}] [ContextLake] Executing retrieve tool, toolCallId: ${toolCallId}`, { params: JSON.stringify(params) });
81
81
 
82
82
  try {
83
83
  let actualParams = params;
@@ -101,13 +101,13 @@ Example User Queries:
101
101
  }
102
102
 
103
103
  const result = await retrieveAssets(actualParams, pluginConfig, logger);
104
- logger.info(`[${new Date().toISOString()}] [ContextLake] Retrieve skill completed`, { resultCount: Array.isArray(result) ? result.length : 0 });
104
+ logger.info(`[${new Date().toISOString()}] [ContextLake] Retrieve tool completed`, { resultCount: Array.isArray(result) ? result.length : 0 });
105
105
  return {
106
106
  content: [{ type: "text", text: JSON.stringify(result) }],
107
107
  details: result
108
108
  } as any;
109
109
  } catch (error: any) {
110
- logger.error(`[${new Date().toISOString()}] [ContextLake] Retrieve skill failed`, { error: error.message, stack: error.stack });
110
+ logger.error(`[${new Date().toISOString()}] [ContextLake] Retrieve tool failed`, { error: error.message, stack: error.stack });
111
111
  return {
112
112
  content: [{ type: "text", text: String(error.message
113
113
  ) }],
@@ -137,7 +137,7 @@ Example User Queries:
137
137
  },
138
138
 
139
139
  async execute(toolCallId: string, params: any) {
140
- logger.info(`[${new Date().toISOString()}] [ContextLake] Executing list skill, toolCallId: ${toolCallId}`, { params: JSON.stringify(params) });
140
+ logger.info(`[${new Date().toISOString()}] [ContextLake] Executing list tool, toolCallId: ${toolCallId}`, { params: JSON.stringify(params) });
141
141
 
142
142
  try {
143
143
  let actualParams = params;
@@ -145,13 +145,13 @@ Example User Queries:
145
145
  actualParams = params.params;
146
146
  }
147
147
  const result = await listAssets(actualParams, pluginConfig, logger);
148
- logger.info(`[${new Date().toISOString()}] [ContextLake] List skill completed`, { count: Array.isArray(result) ? result.length : 0 });
148
+ logger.info(`[${new Date().toISOString()}] [ContextLake] List tool completed`, { count: Array.isArray(result) ? result.length : 0 });
149
149
  return {
150
150
  content: [{ type: "text", text: JSON.stringify(result) }],
151
151
  details: result
152
152
  } as any;
153
153
  } catch (error: any) {
154
- logger.error(`[${new Date().toISOString()}] [ContextLake] List skill failed`, { error: error.message, stack: error.stack });
154
+ logger.error(`[${new Date().toISOString()}] [ContextLake] List tool failed`, { error: error.message, stack: error.stack });
155
155
  return {
156
156
  content: [{ type: "text", text: String(error.message
157
157
  ) }],
@@ -183,7 +183,7 @@ Example User Queries:
183
183
  },
184
184
 
185
185
  async execute(toolCallId: string, params: any) {
186
- logger.info(`[${new Date().toISOString()}] [ContextLake] Executing delete skill, toolCallId: ${toolCallId}`, { params: JSON.stringify(params) });
186
+ logger.info(`[${new Date().toISOString()}] [ContextLake] Executing delete tool, toolCallId: ${toolCallId}`, { params: JSON.stringify(params) });
187
187
 
188
188
  try {
189
189
  let actualParams = params;
@@ -191,13 +191,13 @@ Example User Queries:
191
191
  actualParams = params.params;
192
192
  }
193
193
  const result = await deleteAssets(actualParams, pluginConfig, logger);
194
- logger.info(`[${new Date().toISOString()}] [ContextLake] Delete skill completed`, { result });
194
+ logger.info(`[${new Date().toISOString()}] [ContextLake] Delete tool completed`, { result });
195
195
  return {
196
196
  content: [{ type: "text", text: JSON.stringify(result) }],
197
197
  details: result
198
198
  } as any;
199
199
  } catch (error: any) {
200
- logger.error(`[${new Date().toISOString()}] [ContextLake] Delete skill failed`, { error: error.message, stack: error.stack });
200
+ logger.error(`[${new Date().toISOString()}] [ContextLake] Delete tool failed`, { error: error.message, stack: error.stack });
201
201
  return {
202
202
  content: [{ type: "text", text: String(error.message
203
203
  ) }],
@@ -226,6 +226,7 @@ Example User Queries:
226
226
  additionalProperties: false
227
227
  },
228
228
  async execute(toolCallId: string, params: any) {
229
+ logger.info(`[${new Date().toISOString()}] [ContextLake] Executing list-s3-objects tool, toolCallId: ${toolCallId}`, { params: JSON.stringify(params) });
229
230
  let actualParams = params.params || params;
230
231
  try {
231
232
  const result = await listS3Objects(actualParams, actualParams.prefix || '', actualParams.maxKeys, actualParams.continuationToken);
@@ -253,6 +254,7 @@ Example User Queries:
253
254
  additionalProperties: false
254
255
  },
255
256
  async execute(toolCallId: string, params: any) {
257
+ logger.info(`[${new Date().toISOString()}] [ContextLake] Executing read-s3-object tool, toolCallId: ${toolCallId}`, { params: JSON.stringify(params) });
256
258
  let actualParams = params.params || params;
257
259
  try {
258
260
  // Extract key from url if provided
@@ -299,6 +301,7 @@ Example User Queries:
299
301
  additionalProperties: false
300
302
  },
301
303
  async execute(toolCallId: string, params: any) {
304
+ logger.info(`[${new Date().toISOString()}] [ContextLake] Executing generate-presigned-url tool, toolCallId: ${toolCallId}`, { params: JSON.stringify(params) });
302
305
  let actualParams = params.params || params;
303
306
  try {
304
307
  let key = actualParams.key;
@@ -339,6 +342,7 @@ Example User Queries:
339
342
  additionalProperties: false
340
343
  },
341
344
  async execute(toolCallId: string, params: any) {
345
+ logger.info(`[${new Date().toISOString()}] [ContextLake] Executing write-lance-catalog tool, toolCallId: ${toolCallId}`, { params: JSON.stringify(params) });
342
346
  let actualParams = params.params || params;
343
347
  try {
344
348
  await writeLanceCatalog(actualParams);
@@ -364,6 +368,7 @@ Example User Queries:
364
368
  additionalProperties: false
365
369
  },
366
370
  async execute(toolCallId: string, params: any) {
371
+ logger.info(`[${new Date().toISOString()}] [ContextLake] Executing read-lance-catalog tool, toolCallId: ${toolCallId}`, { params: JSON.stringify(params) });
367
372
  let actualParams = params.params || params;
368
373
  try {
369
374
  const results = await readLanceCatalog(actualParams);
@@ -60,6 +60,7 @@ Parameters in data:
60
60
  required: ['data']
61
61
  },
62
62
  async execute(toolCallId: string, params: any) {
63
+ logger.info(`[${new Date().toISOString()}] [ContextLake] Executing las_image_resample tool, toolCallId: ${toolCallId}`, { params: JSON.stringify(params) });
63
64
  if (params.data?.image) {
64
65
  params.data.image = await processUrl(params.data.image);
65
66
  }
@@ -83,6 +84,7 @@ Parameters in data:
83
84
  required: ['data']
84
85
  },
85
86
  async execute(toolCallId: string, params: any) {
87
+ logger.info(`[${new Date().toISOString()}] [ContextLake] Executing las_audio_extract_and_split tool, toolCallId: ${toolCallId}`, { params: JSON.stringify(params) });
86
88
  if (params.data?.input_path) {
87
89
  params.data.input_path = await processUrl(params.data.input_path);
88
90
  }
@@ -104,6 +106,7 @@ Parameters in data:
104
106
  required: ['data']
105
107
  },
106
108
  async execute(toolCallId: string, params: any) {
109
+ logger.info(`[${new Date().toISOString()}] [ContextLake] Executing las_audio_convert tool, toolCallId: ${toolCallId}`, { params: JSON.stringify(params) });
107
110
  if (params.data?.input_path) {
108
111
  params.data.input_path = await processUrl(params.data.input_path);
109
112
  }
@@ -125,6 +128,7 @@ Parameters in data:
125
128
  required: ['data']
126
129
  },
127
130
  async execute(toolCallId: string, params: any) {
131
+ logger.info(`[${new Date().toISOString()}] [ContextLake] Executing las_asr_pro tool, toolCallId: ${toolCallId}`, { params: JSON.stringify(params) });
128
132
  if (params.data?.audio?.url) {
129
133
  params.data.audio.url = await processUrl(params.data.audio.url);
130
134
  }
@@ -144,6 +148,7 @@ Parameters in data:
144
148
  required: ['data']
145
149
  },
146
150
  async execute(toolCallId: string, params: any) {
151
+ logger.info(`[${new Date().toISOString()}] [ContextLake] Executing las_seed_2_0 tool, toolCallId: ${toolCallId}`, { params: JSON.stringify(params) });
147
152
  if (params.data?.audio?.url) {
148
153
  params.data.audio.url = await processUrl(params.data.audio.url);
149
154
  }
@@ -170,6 +175,7 @@ Parameters:
170
175
  required: ['model', 'input']
171
176
  },
172
177
  async execute(toolCallId: string, params: any) {
178
+ logger.info(`[${new Date().toISOString()}] [ContextLake] Executing las_bare_image_text_embedding tool, toolCallId: ${toolCallId}`, { params: JSON.stringify(params) });
173
179
  if (params.input && Array.isArray(params.input)) {
174
180
  for (const item of params.input) {
175
181
  if (item.type === 'image_url' && item.image_url?.url) {
@@ -200,6 +206,7 @@ Parameters in data:
200
206
  required: ['data']
201
207
  },
202
208
  async execute(toolCallId: string, params: any) {
209
+ logger.info(`[${new Date().toISOString()}] [ContextLake] Executing las_long_video_understand tool, toolCallId: ${toolCallId}`, { params: JSON.stringify(params) });
203
210
  if (params.data?.video_url) {
204
211
  params.data.video_url = await processUrl(params.data.video_url);
205
212
  }
@@ -221,6 +228,7 @@ Parameters in data:
221
228
  required: ['data']
222
229
  },
223
230
  async execute(toolCallId: string, params: any) {
231
+ logger.info(`[${new Date().toISOString()}] [ContextLake] Executing las_pdf_parse_doubao tool, toolCallId: ${toolCallId}`, { params: JSON.stringify(params) });
224
232
  if (params.data?.url) {
225
233
  params.data.url = await processUrl(params.data.url);
226
234
  }
@@ -242,6 +250,7 @@ Parameters in data:
242
250
  required: ['data']
243
251
  },
244
252
  async execute(toolCallId: string, params: any) {
253
+ logger.info(`[${new Date().toISOString()}] [ContextLake] Executing las_video_resize tool, toolCallId: ${toolCallId}`, { params: JSON.stringify(params) });
245
254
  if (params.data?.video_url) {
246
255
  params.data.video_url = await processUrl(params.data.video_url);
247
256
  }