@byted-las/contextlake-openclaw 1.0.0 → 1.0.3
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.d.ts +2 -1
- package/dist/index.js +5 -5
- package/dist/src/client/lancedb.js +13 -4
- package/dist/src/commands/cli.d.ts +5 -2
- package/dist/src/commands/cli.js +94 -10
- package/dist/src/commands/index.d.ts +2 -1
- package/dist/src/commands/index.js +31 -35
- package/dist/src/commands/slashcmd.d.ts +8 -1
- package/dist/src/commands/slashcmd.js +90 -6
- package/dist/src/commands/tools.d.ts +10 -218
- package/dist/src/commands/tools.js +109 -104
- package/dist/src/lib/actions/ingest-source.d.ts +15 -0
- package/dist/src/lib/actions/ingest-source.js +193 -0
- package/dist/src/lib/actions/ingest.d.ts +14 -7
- package/dist/src/lib/actions/ingest.js +133 -63
- package/dist/src/lib/actions/las-api.d.ts +13 -0
- package/dist/src/lib/actions/las-api.js +105 -0
- package/dist/src/lib/actions/las-tools.d.ts +3 -0
- package/dist/src/lib/actions/las-tools.js +194 -0
- package/dist/src/lib/actions/las.d.ts +64 -0
- package/dist/src/lib/actions/las.js +72 -0
- package/dist/src/lib/actions/manage.d.ts +3 -2
- package/dist/src/{skills/las-data-profiler/index.d.ts → lib/actions/profiler.d.ts} +4 -2
- package/dist/src/{skills/las-data-profiler/index.js → lib/actions/profiler.js} +19 -3
- package/dist/src/lib/actions/retrieve.d.ts +2 -1
- package/dist/src/lib/actions/retrieve.js +2 -18
- package/{src/skills/las-data-profiler → dist/src/lib/scripts}/s3_catalog.py +10 -1
- package/dist/src/processor/loader.js +9 -2
- package/dist/src/service/embedding/factory.js +1 -10
- package/dist/src/service/embedding/interface.d.ts +8 -1
- package/dist/src/service/embedding/local.js +16 -13
- package/dist/src/service/embedding/remote.d.ts +7 -0
- package/dist/src/service/embedding/remote.js +108 -7
- package/dist/src/service/metadata/interface.d.ts +1 -0
- package/dist/src/service/metadata/local.d.ts +1 -0
- package/dist/src/service/metadata/local.js +6 -0
- package/dist/src/skills/SKILL.md +174 -0
- package/dist/src/skills/contextlake-delete/SKILL.md +36 -0
- package/dist/src/skills/contextlake-ingest/SKILL.md +40 -0
- package/dist/src/skills/contextlake-list/SKILL.md +22 -0
- package/dist/src/skills/contextlake-retrieve/SKILL.md +37 -0
- package/dist/src/skills/las-data-profiler/SKILL.md +174 -0
- package/dist/src/utils/config.d.ts +34 -1
- package/dist/src/utils/config.js +16 -3
- package/dist/src/utils/credentials.d.ts +8 -0
- package/dist/src/utils/credentials.js +77 -0
- package/index.ts +8 -8
- package/openclaw.plugin.json +1 -1
- package/package.json +8 -7
- package/src/client/lancedb.ts +32 -21
- package/src/commands/cli.ts +105 -13
- package/src/commands/index.ts +45 -42
- package/src/commands/slashcmd.ts +69 -10
- package/src/commands/tools.ts +142 -117
- package/src/lib/actions/ingest.ts +151 -75
- package/src/lib/actions/las-api.ts +119 -0
- package/src/lib/actions/las-tools.ts +196 -0
- package/src/lib/actions/manage.ts +6 -5
- package/src/{skills/las-data-profiler/index.ts → lib/actions/profiler.ts} +21 -4
- package/src/lib/actions/retrieve.ts +16 -34
- package/src/lib/scripts/s3_catalog.py +617 -0
- package/src/processor/loader.ts +12 -4
- package/src/service/embedding/factory.ts +1 -8
- package/src/service/embedding/interface.ts +9 -1
- package/src/service/embedding/remote.ts +133 -13
- package/src/service/metadata/interface.ts +1 -0
- package/src/service/metadata/local.ts +7 -0
- package/src/service/storage/factory.ts +2 -2
- package/src/utils/config.ts +61 -8
- package/src/utils/credentials.ts +50 -0
- package/bin/contextlake-openclaw.js +0 -5
- package/dist/src/skills/las-data-profiler/register.d.ts +0 -1
- package/dist/src/skills/las-data-profiler/register.js +0 -19
- package/src/service/embedding/local.ts +0 -118
- package/src/skills/las-data-profiler/register.ts +0 -19
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { OpenClawPluginApi } from 'openclaw/plugin-sdk';
|
|
1
2
|
declare const plugin: {
|
|
2
3
|
id: string;
|
|
3
4
|
name: string;
|
|
@@ -108,6 +109,6 @@ declare const plugin: {
|
|
|
108
109
|
};
|
|
109
110
|
};
|
|
110
111
|
};
|
|
111
|
-
register(ctx:
|
|
112
|
+
register(ctx: OpenClawPluginApi): void;
|
|
112
113
|
};
|
|
113
114
|
export default plugin;
|
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.
|
|
7
|
+
version: '1.0.2',
|
|
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',
|
|
@@ -58,10 +58,10 @@ const plugin = {
|
|
|
58
58
|
},
|
|
59
59
|
register(ctx) {
|
|
60
60
|
const logger = ctx.logger || {
|
|
61
|
-
info: (msg
|
|
62
|
-
warn: (msg
|
|
63
|
-
error: (msg
|
|
64
|
-
debug: (msg
|
|
61
|
+
info: (msg) => console.log(msg),
|
|
62
|
+
warn: (msg) => console.warn(msg),
|
|
63
|
+
error: (msg) => console.error(msg),
|
|
64
|
+
debug: (msg) => console.debug(msg),
|
|
65
65
|
};
|
|
66
66
|
// Add logging
|
|
67
67
|
logger.info(`[${new Date().toISOString()}] [ContextLake] Plugin register started`);
|
|
@@ -60,7 +60,7 @@ class ContextLakeLanceDBClient {
|
|
|
60
60
|
else {
|
|
61
61
|
if (dim <= 0) {
|
|
62
62
|
// Fallback: use embedding provider to infer dimension only if needed
|
|
63
|
-
const dummyVec = await this.embeddingProvider.generateEmbedding(
|
|
63
|
+
const dummyVec = await this.embeddingProvider.generateEmbedding('init');
|
|
64
64
|
dim = dummyVec.length;
|
|
65
65
|
}
|
|
66
66
|
// @ts-ignore
|
|
@@ -88,10 +88,18 @@ class ContextLakeLanceDBClient {
|
|
|
88
88
|
await table.add(docs);
|
|
89
89
|
}
|
|
90
90
|
async search(query, limit = 5, filter) {
|
|
91
|
-
const
|
|
91
|
+
const normalizedLimit = Number.isFinite(limit) ? Math.max(1, Math.floor(limit)) : 5;
|
|
92
92
|
const table = await this.getTable();
|
|
93
|
+
if (!query || !query.trim()) {
|
|
94
|
+
let fallbackQuery = table.query().limit(normalizedLimit);
|
|
95
|
+
if (filter) {
|
|
96
|
+
fallbackQuery = fallbackQuery.where(filter);
|
|
97
|
+
}
|
|
98
|
+
return await fallbackQuery.toArray();
|
|
99
|
+
}
|
|
100
|
+
const vector = await this.embeddingProvider.generateMultimodalEmbedding([{ type: 'text', text: query }]);
|
|
93
101
|
// @ts-ignore
|
|
94
|
-
let search = table.vectorSearch(vector).limit(
|
|
102
|
+
let search = table.vectorSearch(vector).limit(normalizedLimit);
|
|
95
103
|
if (filter) {
|
|
96
104
|
search = search.where(filter);
|
|
97
105
|
}
|
|
@@ -102,8 +110,9 @@ class ContextLakeLanceDBClient {
|
|
|
102
110
|
await table.delete(filter);
|
|
103
111
|
}
|
|
104
112
|
async list(limit = 100, filter) {
|
|
113
|
+
const normalizedLimit = Number.isFinite(limit) ? Math.max(1, Math.floor(limit)) : 100;
|
|
105
114
|
const table = await this.getTable();
|
|
106
|
-
let query = table.query().limit(
|
|
115
|
+
let query = table.query().limit(normalizedLimit);
|
|
107
116
|
if (filter) {
|
|
108
117
|
query = query.where(filter);
|
|
109
118
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { ContextLakeConfig } from '../utils/config';
|
|
2
|
+
export declare function getCliCommands(pluginConfig: ContextLakeConfig, logger: any): {
|
|
3
|
+
connectAction: (datasource_name: string, options: any) => Promise<void>;
|
|
4
|
+
ingestAction: (datasource_name: string) => Promise<void>;
|
|
3
5
|
searchAction: (query: any, options: any) => Promise<void>;
|
|
4
6
|
listAction: (options: any) => Promise<void>;
|
|
5
7
|
deleteAction: (options: any) => Promise<void>;
|
|
8
|
+
onboardAction: () => Promise<void>;
|
|
6
9
|
};
|
package/dist/src/commands/cli.js
CHANGED
|
@@ -1,20 +1,78 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getCliCommands = getCliCommands;
|
|
4
|
+
// @ts-ignore
|
|
4
5
|
const ingest_1 = require("../lib/actions/ingest");
|
|
5
6
|
const retrieve_1 = require("../lib/actions/retrieve");
|
|
6
7
|
const manage_1 = require("../lib/actions/manage");
|
|
8
|
+
const profiler_1 = require("../lib/actions/profiler");
|
|
9
|
+
const credentials_1 = require("../utils/credentials");
|
|
10
|
+
function parseOptionalInt(value, fallback) {
|
|
11
|
+
const parsed = Number.parseInt(String(value), 10);
|
|
12
|
+
return Number.isFinite(parsed) ? parsed : fallback;
|
|
13
|
+
}
|
|
14
|
+
function parseMetadata(metadata) {
|
|
15
|
+
if (!metadata) {
|
|
16
|
+
return {};
|
|
17
|
+
}
|
|
18
|
+
if (typeof metadata === 'object') {
|
|
19
|
+
return metadata;
|
|
20
|
+
}
|
|
21
|
+
if (typeof metadata !== 'string') {
|
|
22
|
+
throw new Error('metadata must be a JSON object or JSON string');
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
const parsed = JSON.parse(metadata);
|
|
26
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
27
|
+
throw new Error('metadata must be a JSON object');
|
|
28
|
+
}
|
|
29
|
+
return parsed;
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
throw new Error(`Invalid metadata JSON: ${error.message}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
7
35
|
function getCliCommands(pluginConfig, logger) {
|
|
8
36
|
return {
|
|
9
|
-
|
|
10
|
-
logger.info(`[${new Date().toISOString()}] [ContextLake] CLI
|
|
37
|
+
connectAction: async (datasource_name, options) => {
|
|
38
|
+
logger.info(`[${new Date().toISOString()}] [ContextLake] CLI connect started`, { datasource_name, options });
|
|
39
|
+
try {
|
|
40
|
+
const params = {
|
|
41
|
+
datasource_name,
|
|
42
|
+
vendor: options.vendor,
|
|
43
|
+
endpoint: options.endpoint,
|
|
44
|
+
access_key: options.ak,
|
|
45
|
+
secret_key: options.sk,
|
|
46
|
+
region: options.region,
|
|
47
|
+
bucket: options.bucket,
|
|
48
|
+
prefix: options.prefix,
|
|
49
|
+
sample_rows: parseInt(options.sampleRows),
|
|
50
|
+
};
|
|
51
|
+
// eslint-disable-next-line no-console
|
|
52
|
+
console.log(`[contextlake connect] Connecting to datasource "${datasource_name}"...`);
|
|
53
|
+
// eslint-disable-next-line no-console
|
|
54
|
+
console.log(` vendor: ${params.vendor}`);
|
|
55
|
+
// eslint-disable-next-line no-console
|
|
56
|
+
console.log(` bucket: ${params.bucket}`);
|
|
57
|
+
// eslint-disable-next-line no-console
|
|
58
|
+
console.log(` prefix: ${params.prefix}`);
|
|
59
|
+
const result = await (0, profiler_1.connectDataSource)(params);
|
|
60
|
+
// eslint-disable-next-line no-console
|
|
61
|
+
console.log(JSON.stringify(result, null, 2));
|
|
62
|
+
logger.info(`[${new Date().toISOString()}] [ContextLake] CLI connect success`);
|
|
63
|
+
}
|
|
64
|
+
catch (e) {
|
|
65
|
+
// eslint-disable-next-line no-console
|
|
66
|
+
console.error('Error:', e.message);
|
|
67
|
+
logger.error(`[${new Date().toISOString()}] [ContextLake] CLI connect failed`, { error: e.message, stack: e.stack });
|
|
68
|
+
process.exitCode = 1;
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
ingestAction: async (datasource_name) => {
|
|
72
|
+
logger.info(`[${new Date().toISOString()}] [ContextLake] CLI ingest started`, { datasource_name });
|
|
11
73
|
try {
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
files,
|
|
15
|
-
metadata,
|
|
16
|
-
chunkSize: parseInt(options.chunkSize),
|
|
17
|
-
overlap: parseInt(options.overlap)
|
|
74
|
+
const result = await (0, ingest_1.ingestSource)({
|
|
75
|
+
datasource_name
|
|
18
76
|
}, pluginConfig, logger);
|
|
19
77
|
// eslint-disable-next-line no-console
|
|
20
78
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -30,7 +88,7 @@ function getCliCommands(pluginConfig, logger) {
|
|
|
30
88
|
try {
|
|
31
89
|
const result = await (0, retrieve_1.retrieveAssets)({
|
|
32
90
|
query,
|
|
33
|
-
top_k:
|
|
91
|
+
top_k: parseOptionalInt(options.topK, 5),
|
|
34
92
|
filter: options.filter,
|
|
35
93
|
include_binary: options.binary
|
|
36
94
|
}, pluginConfig, logger);
|
|
@@ -47,7 +105,7 @@ function getCliCommands(pluginConfig, logger) {
|
|
|
47
105
|
logger.info(`[${new Date().toISOString()}] [ContextLake] CLI list started`, { options });
|
|
48
106
|
try {
|
|
49
107
|
const result = await (0, manage_1.listAssets)({
|
|
50
|
-
limit:
|
|
108
|
+
limit: parseOptionalInt(options.limit, 100)
|
|
51
109
|
}, pluginConfig, logger);
|
|
52
110
|
// eslint-disable-next-line no-console
|
|
53
111
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -73,6 +131,32 @@ function getCliCommands(pluginConfig, logger) {
|
|
|
73
131
|
console.error('Error:', e.message);
|
|
74
132
|
logger.error(`[${new Date().toISOString()}] [ContextLake] CLI delete failed`, { error: e.message, stack: e.stack });
|
|
75
133
|
}
|
|
134
|
+
},
|
|
135
|
+
onboardAction: async () => {
|
|
136
|
+
logger.info(`[${new Date().toISOString()}] [ContextLake] CLI onboard started`);
|
|
137
|
+
try {
|
|
138
|
+
const currentCreds = (0, credentials_1.loadCredentials)();
|
|
139
|
+
// eslint-disable-next-line no-console
|
|
140
|
+
console.log('Welcome to ContextLake Onboarding!');
|
|
141
|
+
// eslint-disable-next-line no-console
|
|
142
|
+
console.log('Please provide your credentials below. Press enter to keep the current value.');
|
|
143
|
+
const lasApiKey = await (0, credentials_1.promptForInput)('LAS_API_KEY', currentCreds.LAS_API_KEY);
|
|
144
|
+
const volcengineAccessKey = await (0, credentials_1.promptForInput)('VOLCENGINE_ACCESS_KEY', currentCreds.VOLCENGINE_ACCESS_KEY);
|
|
145
|
+
const volcengineSecretKey = await (0, credentials_1.promptForInput)('VOLCENGINE_SECRET_KEY', currentCreds.VOLCENGINE_SECRET_KEY);
|
|
146
|
+
const newCreds = {
|
|
147
|
+
LAS_API_KEY: lasApiKey,
|
|
148
|
+
VOLCENGINE_ACCESS_KEY: volcengineAccessKey,
|
|
149
|
+
VOLCENGINE_SECRET_KEY: volcengineSecretKey
|
|
150
|
+
};
|
|
151
|
+
(0, credentials_1.saveCredentials)(newCreds);
|
|
152
|
+
// eslint-disable-next-line no-console
|
|
153
|
+
console.log('Credentials saved successfully!');
|
|
154
|
+
logger.info(`[${new Date().toISOString()}] [ContextLake] CLI onboard success`);
|
|
155
|
+
}
|
|
156
|
+
catch (e) {
|
|
157
|
+
console.error('Error during onboarding:', e.message);
|
|
158
|
+
logger.error(`[${new Date().toISOString()}] [ContextLake] CLI onboard failed`, { error: e.message, stack: e.stack });
|
|
159
|
+
}
|
|
76
160
|
}
|
|
77
161
|
};
|
|
78
162
|
}
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import type { OpenClawPluginApi, PluginLogger } from 'openclaw/plugin-sdk';
|
|
2
|
+
export declare function registerAll(ctx: OpenClawPluginApi, logger: PluginLogger): void;
|
|
@@ -5,7 +5,6 @@ const tools_1 = require("./tools");
|
|
|
5
5
|
const cli_1 = require("./cli");
|
|
6
6
|
const slashcmd_1 = require("./slashcmd");
|
|
7
7
|
const config_1 = require("../utils/config");
|
|
8
|
-
const las_data_profiler_1 = require("../skills/las-data-profiler");
|
|
9
8
|
function registerAll(ctx, logger) {
|
|
10
9
|
const pluginConfig = (0, config_1.getPluginConfig)(ctx);
|
|
11
10
|
// Register Agent Tools
|
|
@@ -19,9 +18,17 @@ function registerAll(ctx, logger) {
|
|
|
19
18
|
logger.info(`[${new Date().toISOString()}] [ContextLake] Tool registered: ${tools.listTool.name}`);
|
|
20
19
|
ctx.registerTool(tools.deleteTool);
|
|
21
20
|
logger.info(`[${new Date().toISOString()}] [ContextLake] Tool registered: ${tools.deleteTool.name}`);
|
|
21
|
+
ctx.registerTool(tools.lasDataProfilerTool);
|
|
22
|
+
logger.info(`[${new Date().toISOString()}] [ContextLake] Tool registered: ${tools.lasDataProfilerTool.name}`);
|
|
23
|
+
ctx.registerTool(tools.listDatasourceTool);
|
|
24
|
+
logger.info(`[${new Date().toISOString()}] [ContextLake] Tool registered: ${tools.listDatasourceTool.name}`);
|
|
25
|
+
for (const lasTool of tools.lasTools) {
|
|
26
|
+
ctx.registerTool(lasTool);
|
|
27
|
+
logger.info(`[${new Date().toISOString()}] [ContextLake] Tool registered: ${lasTool.name}`);
|
|
28
|
+
}
|
|
22
29
|
}
|
|
23
30
|
catch (error) {
|
|
24
|
-
logger.error(`[${new Date().toISOString()}] [ContextLake] Error registering agent tools: ${error.message}
|
|
31
|
+
logger.error(`[${new Date().toISOString()}] [ContextLake] Error registering agent tools: ${error.message}${error.stack ? '\\n' + error.stack : ''}`);
|
|
25
32
|
throw error;
|
|
26
33
|
}
|
|
27
34
|
// Register CLI
|
|
@@ -43,37 +50,10 @@ function registerAll(ctx, logger) {
|
|
|
43
50
|
.requiredOption('--bucket <bucket>', 'Bucket name (or local root directory for local vendor)')
|
|
44
51
|
.requiredOption('--prefix <prefix>', 'Path prefix to limit scan scope')
|
|
45
52
|
.option('--sample-rows <number>', 'Number of rows to sample per structured file', '100')
|
|
46
|
-
.action(
|
|
47
|
-
try {
|
|
48
|
-
const params = {
|
|
49
|
-
datasource_name,
|
|
50
|
-
vendor: options.vendor,
|
|
51
|
-
endpoint: options.endpoint,
|
|
52
|
-
access_key: options.ak,
|
|
53
|
-
secret_key: options.sk,
|
|
54
|
-
region: options.region,
|
|
55
|
-
bucket: options.bucket,
|
|
56
|
-
prefix: options.prefix,
|
|
57
|
-
sample_rows: parseInt(options.sampleRows),
|
|
58
|
-
};
|
|
59
|
-
console.log(`[contextlake connect] Connecting to datasource "${datasource_name}"...`);
|
|
60
|
-
console.log(` vendor: ${params.vendor}`);
|
|
61
|
-
console.log(` bucket: ${params.bucket}`);
|
|
62
|
-
console.log(` prefix: ${params.prefix}`);
|
|
63
|
-
const result = await (0, las_data_profiler_1.connectDataSource)(params);
|
|
64
|
-
console.log(JSON.stringify(result, null, 2));
|
|
65
|
-
}
|
|
66
|
-
catch (e) {
|
|
67
|
-
console.error('Error:', e.message);
|
|
68
|
-
process.exitCode = 1;
|
|
69
|
-
}
|
|
70
|
-
});
|
|
53
|
+
.action(commands.connectAction);
|
|
71
54
|
// Ingest
|
|
72
|
-
contextlake.command('ingest <
|
|
73
|
-
.description('
|
|
74
|
-
.option('-c, --chunk-size <number>', 'Chunk size for text splitting', '500')
|
|
75
|
-
.option('-o, --overlap <number>', 'Chunk overlap size', '50')
|
|
76
|
-
.option('-m, --metadata <json>', 'JSON metadata to attach to the documents')
|
|
55
|
+
contextlake.command('ingest <datasource_name>')
|
|
56
|
+
.description('Process and ingest all files from a connected data source into the knowledge base')
|
|
77
57
|
.action(commands.ingestAction);
|
|
78
58
|
// Search
|
|
79
59
|
contextlake.command('search <query>')
|
|
@@ -93,11 +73,15 @@ function registerAll(ctx, logger) {
|
|
|
93
73
|
.option('--ids <ids...>', 'List of specific file IDs to delete')
|
|
94
74
|
.option('-f, --filter <string>', 'Filter string to match documents for deletion')
|
|
95
75
|
.action(commands.deleteAction);
|
|
76
|
+
// Onboard
|
|
77
|
+
contextlake.command('onboard')
|
|
78
|
+
.description('Configure credentials for ContextLake')
|
|
79
|
+
.action(commands.onboardAction);
|
|
96
80
|
}, { commands: ['contextlake'] });
|
|
97
81
|
logger.info(`[${new Date().toISOString()}] [ContextLake] CLI commands registered`);
|
|
98
82
|
}
|
|
99
83
|
catch (error) {
|
|
100
|
-
logger.error(`[${new Date().toISOString()}] [ContextLake] Error registering CLI commands: ${error.message}
|
|
84
|
+
logger.error(`[${new Date().toISOString()}] [ContextLake] Error registering CLI commands: ${error.message}${error.stack ? '\\n' + error.stack : ''}`);
|
|
101
85
|
throw error;
|
|
102
86
|
}
|
|
103
87
|
// Register Slash Commands
|
|
@@ -109,7 +93,7 @@ function registerAll(ctx, logger) {
|
|
|
109
93
|
const slashCommands = (0, slashcmd_1.getSlashCommands)(pluginConfig, logger);
|
|
110
94
|
ctx.registerCommand({
|
|
111
95
|
name: 'contextlake-ingest',
|
|
112
|
-
description: '
|
|
96
|
+
description: 'Process and ingest all files from a connected data source (usage: /contextlake-ingest <datasource_name>)',
|
|
113
97
|
acceptsArgs: true,
|
|
114
98
|
handler: slashCommands.ingestHandler
|
|
115
99
|
});
|
|
@@ -131,9 +115,21 @@ function registerAll(ctx, logger) {
|
|
|
131
115
|
acceptsArgs: true,
|
|
132
116
|
handler: slashCommands.deleteHandler
|
|
133
117
|
});
|
|
118
|
+
ctx.registerCommand({
|
|
119
|
+
name: 'contextlake-profiler',
|
|
120
|
+
description: 'Connect to a data source and profile its structure (usage: /contextlake-profiler <datasource_name> <vendor> <bucket> <prefix>)',
|
|
121
|
+
acceptsArgs: true,
|
|
122
|
+
handler: slashCommands.profilerHandler
|
|
123
|
+
});
|
|
124
|
+
ctx.registerCommand({
|
|
125
|
+
name: 'contextlake-list-datasource',
|
|
126
|
+
description: 'List all connected and profiled data sources (usage: /contextlake-list-datasource)',
|
|
127
|
+
acceptsArgs: false,
|
|
128
|
+
handler: slashCommands.listDatasourceHandler
|
|
129
|
+
});
|
|
134
130
|
logger.info(`[${new Date().toISOString()}] [ContextLake] Slash commands registered`);
|
|
135
131
|
}
|
|
136
132
|
catch (error) {
|
|
137
|
-
logger.error(`[${new Date().toISOString()}] [ContextLake] Error registering Slash commands: ${error.message}
|
|
133
|
+
logger.error(`[${new Date().toISOString()}] [ContextLake] Error registering Slash commands: ${error.message}${error.stack ? '\\n' + error.stack : ''}`);
|
|
138
134
|
}
|
|
139
135
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import { ContextLakeConfig } from '../utils/config';
|
|
2
|
+
export declare function getSlashCommands(pluginConfig: ContextLakeConfig, logger: any): {
|
|
2
3
|
ingestHandler: (commandCtx: any) => Promise<{
|
|
3
4
|
text: string;
|
|
4
5
|
}>;
|
|
@@ -11,4 +12,10 @@ export declare function getSlashCommands(pluginConfig: any, logger: any): {
|
|
|
11
12
|
deleteHandler: (commandCtx: any) => Promise<{
|
|
12
13
|
text: string;
|
|
13
14
|
}>;
|
|
15
|
+
profilerHandler: (commandCtx: any) => Promise<{
|
|
16
|
+
text: string;
|
|
17
|
+
}>;
|
|
18
|
+
listDatasourceHandler: (commandCtx: any) => Promise<{
|
|
19
|
+
text: string;
|
|
20
|
+
}>;
|
|
14
21
|
};
|
|
@@ -1,9 +1,46 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
36
|
exports.getSlashCommands = getSlashCommands;
|
|
4
37
|
const ingest_1 = require("../lib/actions/ingest");
|
|
5
38
|
const retrieve_1 = require("../lib/actions/retrieve");
|
|
6
39
|
const manage_1 = require("../lib/actions/manage");
|
|
40
|
+
const profiler_1 = require("../lib/actions/profiler");
|
|
41
|
+
const fs = __importStar(require("fs"));
|
|
42
|
+
const path = __importStar(require("path"));
|
|
43
|
+
const os = __importStar(require("os"));
|
|
7
44
|
function getSlashCommands(pluginConfig, logger) {
|
|
8
45
|
return {
|
|
9
46
|
ingestHandler: async (commandCtx) => {
|
|
@@ -12,12 +49,16 @@ function getSlashCommands(pluginConfig, logger) {
|
|
|
12
49
|
logger.info(`[${new Date().toISOString()}] [ContextLake] Slash command ingest started`, { args });
|
|
13
50
|
try {
|
|
14
51
|
if (args.length === 0) {
|
|
15
|
-
return { text: `**Error:** Missing
|
|
52
|
+
return { text: `**Error:** Missing datasource_name. Usage: /contextlake-ingest <datasource_name>` };
|
|
16
53
|
}
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
54
|
+
const datasource_name = args[0];
|
|
55
|
+
const BASE_DIR = path.join(os.homedir(), '.openclaw', 'contextlake', 'profiler');
|
|
56
|
+
const dsDir = path.join(BASE_DIR, datasource_name);
|
|
57
|
+
const dbPath = path.join(dsDir, 'catalog_db');
|
|
58
|
+
if (!fs.existsSync(dbPath)) {
|
|
59
|
+
return { text: `**Error:** Data source "${datasource_name}" has not been profiled yet.\n\nPlease run the profiler first using:\n\`/contextlake-profiler <datasource_name> <vendor> <bucket> <prefix> [endpoint] [ak] [sk] [region]\`` };
|
|
60
|
+
}
|
|
61
|
+
const result = await (0, ingest_1.ingestSource)({ datasource_name }, pluginConfig, logger);
|
|
21
62
|
logger.info(`[${new Date().toISOString()}] [ContextLake] Slash command ingest completed`, { resultCount: result.length });
|
|
22
63
|
return { text: `**Ingest Results (${result.length} files processed):**\n\`\`\`json\n${JSON.stringify(result, null, 2)}\n\`\`\`` };
|
|
23
64
|
}
|
|
@@ -86,6 +127,49 @@ function getSlashCommands(pluginConfig, logger) {
|
|
|
86
127
|
logger.error(`[ContextLake] Slash delete failed`, { error: e.message });
|
|
87
128
|
return { text: `**Error executing delete:** ${e.message}` };
|
|
88
129
|
}
|
|
89
|
-
}
|
|
130
|
+
},
|
|
131
|
+
profilerHandler: async (commandCtx) => {
|
|
132
|
+
const rawArgs = commandCtx.args || "";
|
|
133
|
+
const args = rawArgs.split(' ').filter((arg) => arg.trim() !== '');
|
|
134
|
+
logger.info(`[${new Date().toISOString()}] [ContextLake] Slash command profiler started`, { args });
|
|
135
|
+
try {
|
|
136
|
+
if (args.length < 4) {
|
|
137
|
+
return { text: `**Error:** Missing arguments. Usage: /contextlake-profiler <datasource_name> <vendor> <bucket> <prefix> [endpoint] [ak] [sk] [region]` };
|
|
138
|
+
}
|
|
139
|
+
const [datasource_name, vendor, bucket, prefix, endpoint, access_key, secret_key, region] = args;
|
|
140
|
+
if (!['volcengine', 'alibaba', 'tencent', 'aws', 'local'].includes(vendor)) {
|
|
141
|
+
return { text: `**Error:** Invalid vendor. Must be one of: volcengine, alibaba, tencent, aws, local` };
|
|
142
|
+
}
|
|
143
|
+
const params = {
|
|
144
|
+
datasource_name,
|
|
145
|
+
vendor: vendor,
|
|
146
|
+
bucket,
|
|
147
|
+
prefix,
|
|
148
|
+
endpoint,
|
|
149
|
+
access_key,
|
|
150
|
+
secret_key,
|
|
151
|
+
region,
|
|
152
|
+
};
|
|
153
|
+
const result = await (0, profiler_1.connectDataSource)(params);
|
|
154
|
+
logger.info(`[${new Date().toISOString()}] [ContextLake] Slash command profiler completed`, { result });
|
|
155
|
+
return { text: `**Profiler Results:**\n\`\`\`json\n${JSON.stringify(result, null, 2)}\n\`\`\`` };
|
|
156
|
+
}
|
|
157
|
+
catch (e) {
|
|
158
|
+
logger.error(`[ContextLake] Slash profiler failed`, { error: e.message });
|
|
159
|
+
return { text: `**Error executing profiler:** ${e.message}` };
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
listDatasourceHandler: async (commandCtx) => {
|
|
163
|
+
logger.info(`[${new Date().toISOString()}] [ContextLake] Slash command list-datasource started`);
|
|
164
|
+
try {
|
|
165
|
+
const result = await (0, profiler_1.listDataSources)();
|
|
166
|
+
logger.info(`[${new Date().toISOString()}] [ContextLake] Slash command list-datasource completed`, { result });
|
|
167
|
+
return { text: `**Data Sources:**\n\`\`\`json\n${JSON.stringify(result, null, 2)}\n\`\`\`` };
|
|
168
|
+
}
|
|
169
|
+
catch (e) {
|
|
170
|
+
logger.error(`[ContextLake] Slash list-datasource failed`, { error: e.message });
|
|
171
|
+
return { text: `**Error executing list-datasource:** ${e.message}` };
|
|
172
|
+
}
|
|
173
|
+
},
|
|
90
174
|
};
|
|
91
175
|
}
|