@ontos-ai/knowhere-claw 0.2.0 → 0.2.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/dist/__tests__/channel-route.test.d.ts +1 -0
- package/dist/__tests__/ingest-tool.test.d.ts +1 -0
- package/dist/__tests__/kg-service-test-helper.d.ts +2 -0
- package/dist/__tests__/kg-service.test.d.ts +1 -0
- package/dist/__tests__/read-result-file-tool.test.d.ts +1 -0
- package/dist/__tests__/tracker-progress.test.d.ts +1 -0
- package/dist/channel-delivery.d.ts +21 -0
- package/dist/client.d.ts +33 -0
- package/dist/config.d.ts +13 -0
- package/dist/connect-builder.d.ts +48 -0
- package/dist/connect-builder.js +1 -2
- package/dist/error-message.d.ts +1 -0
- package/dist/graph-builder.d.ts +75 -0
- package/dist/graph-builder.js +1 -1
- package/dist/index.d.ts +9 -0
- package/dist/kg-service.d.ts +38 -0
- package/dist/kg-service.js +14 -5
- package/dist/parser.d.ts +16 -0
- package/dist/session.d.ts +11 -0
- package/dist/store.d.ts +79 -0
- package/dist/text.d.ts +10 -0
- package/dist/tools.d.ts +10 -0
- package/dist/tracker-progress.d.ts +10 -0
- package/dist/types.d.ts +320 -0
- package/openclaw.plugin.json +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/core";
|
|
2
|
+
import type { ChannelRouteRecord } from "./types";
|
|
3
|
+
type DeliverySurface = "discord" | "imessage" | "line" | "signal" | "slack" | "telegram" | "whatsapp";
|
|
4
|
+
type DeliveryResult = {
|
|
5
|
+
delivered: boolean;
|
|
6
|
+
surface?: DeliverySurface;
|
|
7
|
+
to?: string;
|
|
8
|
+
accountId?: string;
|
|
9
|
+
};
|
|
10
|
+
export declare function deliverChannelMessage(params: {
|
|
11
|
+
api: OpenClawPluginApi;
|
|
12
|
+
operationLabel: string;
|
|
13
|
+
context?: unknown;
|
|
14
|
+
sessionKey?: string;
|
|
15
|
+
messages?: unknown[];
|
|
16
|
+
channelRoute?: ChannelRouteRecord;
|
|
17
|
+
text: string;
|
|
18
|
+
mediaUrl?: string;
|
|
19
|
+
mediaLocalRoots?: readonly string[];
|
|
20
|
+
}): Promise<DeliveryResult>;
|
|
21
|
+
export {};
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { KnowhereIngestRequest, KnowhereIngestResult, KnowhereJobList, KnowhereJobListRequest, KnowhereJobResult } from "./types";
|
|
2
|
+
export declare class KnowhereClient {
|
|
3
|
+
private readonly apiKey;
|
|
4
|
+
private readonly baseUrl;
|
|
5
|
+
private readonly requestTimeoutMs;
|
|
6
|
+
private readonly uploadTimeoutMs;
|
|
7
|
+
private readonly pollIntervalMs;
|
|
8
|
+
private readonly pollTimeoutMs;
|
|
9
|
+
private readonly logger;
|
|
10
|
+
private readonly sdk;
|
|
11
|
+
constructor(params: {
|
|
12
|
+
apiKey: string;
|
|
13
|
+
baseUrl: string;
|
|
14
|
+
requestTimeoutMs: number;
|
|
15
|
+
uploadTimeoutMs: number;
|
|
16
|
+
pollIntervalMs: number;
|
|
17
|
+
pollTimeoutMs: number;
|
|
18
|
+
logger: {
|
|
19
|
+
debug?: (message: string) => void;
|
|
20
|
+
info: (message: string) => void;
|
|
21
|
+
};
|
|
22
|
+
});
|
|
23
|
+
ingestDocument(params: KnowhereIngestRequest): Promise<KnowhereIngestResult>;
|
|
24
|
+
private logPollProgress;
|
|
25
|
+
getJob(jobId: string): Promise<KnowhereJobResult>;
|
|
26
|
+
listJobs(options?: KnowhereJobListRequest): Promise<KnowhereJobList>;
|
|
27
|
+
getCompletedJobResult(jobId: string): Promise<KnowhereIngestResult>;
|
|
28
|
+
private downloadResultArchive;
|
|
29
|
+
private uploadFile;
|
|
30
|
+
private requestJson;
|
|
31
|
+
private requestBuffer;
|
|
32
|
+
private request;
|
|
33
|
+
}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/core";
|
|
2
|
+
import type { JsonSchemaObject, ResolvedKnowhereConfig, StringRecord, KnowledgeGraphConfig } from "./types";
|
|
3
|
+
export declare const DEFAULT_BASE_URL = "https://api.knowhereto.ai";
|
|
4
|
+
export declare const knowherePluginConfigSchema: JsonSchemaObject;
|
|
5
|
+
export declare function resolveKnowhereConfig(api: OpenClawPluginApi): ResolvedKnowhereConfig;
|
|
6
|
+
export declare const API_KEY_URL = "https://knowhereto.ai/api-keys";
|
|
7
|
+
export declare const PURCHASE_CREDITS_URL = "https://knowhereto.ai/usage?buy=true";
|
|
8
|
+
export declare function assertKnowhereApiKey(config: ResolvedKnowhereConfig): void;
|
|
9
|
+
export declare function isPaymentRequiredError(error: unknown): boolean;
|
|
10
|
+
export declare function formatPaymentRequiredMessage(): string;
|
|
11
|
+
export declare function readPersistedApiKey(storageDir: string): Promise<string | null>;
|
|
12
|
+
export declare function persistApiKey(storageDir: string, apiKey: string): Promise<void>;
|
|
13
|
+
export declare function resolveKnowledgeGraphConfig(raw: StringRecord): KnowledgeGraphConfig;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Connection Builder Module
|
|
3
|
+
*
|
|
4
|
+
* TypeScript implementation of knowhere-api/apps/worker/app/services/connect_builder/builder.py
|
|
5
|
+
* Builds connections between chunks based on keyword overlap and content similarity.
|
|
6
|
+
*/
|
|
7
|
+
import type { PluginLogger } from "./types";
|
|
8
|
+
/**
|
|
9
|
+
* Chunk data structure for building connections
|
|
10
|
+
*/
|
|
11
|
+
export interface ChunkData {
|
|
12
|
+
chunk_id: string;
|
|
13
|
+
path: string;
|
|
14
|
+
content: string;
|
|
15
|
+
metadata: {
|
|
16
|
+
keywords?: string[];
|
|
17
|
+
tokens?: string[];
|
|
18
|
+
summary?: string;
|
|
19
|
+
length?: number;
|
|
20
|
+
[key: string]: unknown;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Connection result between two chunks
|
|
25
|
+
*/
|
|
26
|
+
export interface Connection {
|
|
27
|
+
source: string;
|
|
28
|
+
target: string;
|
|
29
|
+
relation: string;
|
|
30
|
+
score: number;
|
|
31
|
+
sharedKeywords: string[];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Configuration for connection building
|
|
35
|
+
*/
|
|
36
|
+
export interface ConnectBuilderConfig {
|
|
37
|
+
minKeywordOverlap: number;
|
|
38
|
+
keywordScoreWeight: number;
|
|
39
|
+
maxConnectionsPerChunk: number;
|
|
40
|
+
minScoreThreshold: number;
|
|
41
|
+
crossFileOnly: boolean;
|
|
42
|
+
maxContentOverlap: number;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Main function to build connections between chunks
|
|
46
|
+
* Equivalent to Python: build_connections
|
|
47
|
+
*/
|
|
48
|
+
export declare function buildConnections(chunks: ChunkData[], config: ConnectBuilderConfig, logger?: PluginLogger): Connection[];
|
package/dist/connect-builder.js
CHANGED
|
@@ -120,7 +120,6 @@ function buildConnections(chunks, config, logger) {
|
|
|
120
120
|
const sourceChunk = chunkById.get(sourceId);
|
|
121
121
|
if (!sourceChunk) continue;
|
|
122
122
|
const sourceKeywords = getKeywords(sourceChunk);
|
|
123
|
-
sourceKeywords.map(normalizeKeyword);
|
|
124
123
|
const sourceFileKey = extractFileKey(sourceChunk.path);
|
|
125
124
|
for (const targetId of targetIds) {
|
|
126
125
|
const targetChunk = chunkById.get(targetId);
|
|
@@ -165,7 +164,7 @@ function buildConnections(chunks, config, logger) {
|
|
|
165
164
|
connectionsByChunk.get(conn.target).push(conn);
|
|
166
165
|
}
|
|
167
166
|
const kept = /* @__PURE__ */ new Set();
|
|
168
|
-
for (const [
|
|
167
|
+
for (const [, conns] of connectionsByChunk) {
|
|
169
168
|
const topN = conns.sort((a, b) => b.score - a.score).slice(0, config.maxConnectionsPerChunk);
|
|
170
169
|
for (const conn of topN) kept.add(conn);
|
|
171
170
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function formatErrorMessage(error: unknown): string;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graph Builder Module
|
|
3
|
+
*
|
|
4
|
+
* TypeScript implementation of knowhere-api/apps/worker/app/services/connect_builder/graph_builder.py
|
|
5
|
+
* Builds file-level knowledge graphs from chunk connections with TF-IDF and importance scoring.
|
|
6
|
+
*/
|
|
7
|
+
import type { ChunkData, Connection } from "./connect-builder";
|
|
8
|
+
import type { PluginLogger } from "./types";
|
|
9
|
+
/**
|
|
10
|
+
* File-level edge in the knowledge graph
|
|
11
|
+
*/
|
|
12
|
+
interface FileEdge {
|
|
13
|
+
source: string;
|
|
14
|
+
target: string;
|
|
15
|
+
connection_count: number;
|
|
16
|
+
avg_score: number;
|
|
17
|
+
top_connections: Array<{
|
|
18
|
+
source_chunk: string;
|
|
19
|
+
source_id: string;
|
|
20
|
+
target_chunk: string;
|
|
21
|
+
target_id: string;
|
|
22
|
+
relation: string;
|
|
23
|
+
score: number;
|
|
24
|
+
}>;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* File metadata in the knowledge graph
|
|
28
|
+
*/
|
|
29
|
+
interface FileMetadata {
|
|
30
|
+
chunks_count: number;
|
|
31
|
+
types: Record<string, number>;
|
|
32
|
+
top_keywords: string[];
|
|
33
|
+
top_summary: string;
|
|
34
|
+
importance: number;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Complete knowledge graph structure
|
|
38
|
+
*/
|
|
39
|
+
export interface KnowledgeGraph {
|
|
40
|
+
version: string;
|
|
41
|
+
stats: {
|
|
42
|
+
total_files: number;
|
|
43
|
+
total_chunks: number;
|
|
44
|
+
total_cross_file_edges: number;
|
|
45
|
+
};
|
|
46
|
+
files: Record<string, FileMetadata>;
|
|
47
|
+
edges: FileEdge[];
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Chunk statistics for usage tracking
|
|
51
|
+
*/
|
|
52
|
+
export interface ChunkStats {
|
|
53
|
+
[chunkId: string]: {
|
|
54
|
+
hit_count: number;
|
|
55
|
+
last_accessed?: string;
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Main function to build knowledge graph
|
|
60
|
+
* Equivalent to Python: build_knowledge_graph
|
|
61
|
+
*/
|
|
62
|
+
export declare function buildKnowledgeGraph(chunks: ChunkData[], connections: Connection[], chunkStats: ChunkStats, jiebaInitialized: boolean, logger?: PluginLogger): KnowledgeGraph;
|
|
63
|
+
/**
|
|
64
|
+
* Incremental update: match new chunks against existing chunks
|
|
65
|
+
* Equivalent to Python: _incremental_connections
|
|
66
|
+
*/
|
|
67
|
+
export declare function incrementalConnections(newChunks: ChunkData[], existingChunks: ChunkData[], config: {
|
|
68
|
+
minKeywordOverlap: number;
|
|
69
|
+
keywordScoreWeight: number;
|
|
70
|
+
maxConnectionsPerChunk: number;
|
|
71
|
+
minScoreThreshold: number;
|
|
72
|
+
crossFileOnly: boolean;
|
|
73
|
+
maxContentOverlap: number;
|
|
74
|
+
}, logger?: PluginLogger): Connection[];
|
|
75
|
+
export {};
|
package/dist/graph-builder.js
CHANGED
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/core";
|
|
2
|
+
declare const plugin: {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
description: string;
|
|
6
|
+
configSchema: import("./types").JsonSchemaObject;
|
|
7
|
+
register(api: OpenClawPluginApi): void;
|
|
8
|
+
};
|
|
9
|
+
export default plugin;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { KnowledgeGraphConfig, PluginLogger, ToolRuntimeContext, KbMetadata, KnowledgeGraph, FileEdge } from "./types";
|
|
2
|
+
export interface KnowledgeGraphServiceParams {
|
|
3
|
+
config: KnowledgeGraphConfig;
|
|
4
|
+
logger: PluginLogger;
|
|
5
|
+
}
|
|
6
|
+
type DegradationMode = "full" | "basic" | "disabled";
|
|
7
|
+
export declare class KnowledgeGraphService {
|
|
8
|
+
private readonly config;
|
|
9
|
+
private readonly logger;
|
|
10
|
+
private degradationMode;
|
|
11
|
+
private buildQueues;
|
|
12
|
+
private jiebaInitialized;
|
|
13
|
+
constructor(params: KnowledgeGraphServiceParams);
|
|
14
|
+
initialize(): Promise<void>;
|
|
15
|
+
private checkPythonEnvironment;
|
|
16
|
+
private initializeJieba;
|
|
17
|
+
extractKeywords(text: string, topK?: number): Promise<string[]>;
|
|
18
|
+
resolveKbId(context: ToolRuntimeContext): string | null;
|
|
19
|
+
getKbPath(kbId: string): string;
|
|
20
|
+
ensureKbDirectory(kbId: string): Promise<string>;
|
|
21
|
+
saveDocumentToKb(params: {
|
|
22
|
+
kbId: string;
|
|
23
|
+
docId: string;
|
|
24
|
+
sourcePath: string;
|
|
25
|
+
keywords: string[];
|
|
26
|
+
metadata: Record<string, unknown>;
|
|
27
|
+
}): Promise<void>;
|
|
28
|
+
scheduleBuild(kbId: string, task: () => Promise<void>): Promise<void>;
|
|
29
|
+
buildKnowledgeGraph(kbId: string): Promise<void>;
|
|
30
|
+
private updateKbMetadata;
|
|
31
|
+
queryGraph(kbId: string, fileKey?: string): Promise<FileEdge[]>;
|
|
32
|
+
getKnowledgeGraph(kbId: string): Promise<KnowledgeGraph | null>;
|
|
33
|
+
listKnowledgeBases(): Promise<string[]>;
|
|
34
|
+
getKbMetadata(kbId: string): Promise<KbMetadata | null>;
|
|
35
|
+
isEnabled(): boolean;
|
|
36
|
+
getDegradationMode(): DegradationMode;
|
|
37
|
+
}
|
|
38
|
+
export {};
|
package/dist/kg-service.js
CHANGED
|
@@ -25,6 +25,15 @@ const DEFAULT_KG_CONFIG = {
|
|
|
25
25
|
buildTimeout: 3e5,
|
|
26
26
|
notifyOnGraphFailure: false
|
|
27
27
|
};
|
|
28
|
+
function formatUnknownError(error) {
|
|
29
|
+
return error instanceof Error ? error.message : String(error);
|
|
30
|
+
}
|
|
31
|
+
function extractKeywordText(item) {
|
|
32
|
+
if (typeof item === "string") return item;
|
|
33
|
+
if (typeof item === "number" || typeof item === "boolean" || typeof item === "bigint") return String(item);
|
|
34
|
+
if (typeof item === "object" && item !== null && "word" in item && typeof item.word === "string") return item.word;
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
28
37
|
var KnowledgeGraphService = class {
|
|
29
38
|
config;
|
|
30
39
|
logger;
|
|
@@ -68,7 +77,7 @@ var KnowledgeGraphService = class {
|
|
|
68
77
|
async checkPythonEnvironment() {
|
|
69
78
|
return new Promise((resolve, reject) => {
|
|
70
79
|
const python = spawn("python3", ["--version"]);
|
|
71
|
-
python.on("error", (
|
|
80
|
+
python.on("error", () => {
|
|
72
81
|
const error = /* @__PURE__ */ new Error("Python3 not found in PATH");
|
|
73
82
|
error.code = "PYTHON_MISSING";
|
|
74
83
|
reject(error);
|
|
@@ -90,7 +99,7 @@ var KnowledgeGraphService = class {
|
|
|
90
99
|
import_nodejieba.load();
|
|
91
100
|
this.jiebaInitialized = true;
|
|
92
101
|
this.logger.info("Nodejieba initialized successfully");
|
|
93
|
-
} catch
|
|
102
|
+
} catch {
|
|
94
103
|
const err = /* @__PURE__ */ new Error("Failed to initialize nodejieba");
|
|
95
104
|
err.code = "NODEJIEBA_MISSING";
|
|
96
105
|
throw err;
|
|
@@ -100,13 +109,13 @@ var KnowledgeGraphService = class {
|
|
|
100
109
|
if (this.degradationMode === "disabled") return [];
|
|
101
110
|
if (this.degradationMode === "full" && this.jiebaInitialized) try {
|
|
102
111
|
const rawKeywords = import_nodejieba.extract(text, topK);
|
|
103
|
-
return (Array.isArray(rawKeywords) ? rawKeywords : []).map((item) =>
|
|
112
|
+
return (Array.isArray(rawKeywords) ? rawKeywords : []).map((item) => extractKeywordText(item)).filter((keyword) => keyword !== null).filter((kw) => {
|
|
104
113
|
if (kw.length <= 1) return false;
|
|
105
114
|
if (/^\d+$/.test(kw)) return false;
|
|
106
115
|
return true;
|
|
107
116
|
}).slice(0, topK);
|
|
108
117
|
} catch (error) {
|
|
109
|
-
this.logger.warn(`Jieba extraction failed, falling back to basic: ${error}`);
|
|
118
|
+
this.logger.warn(`Jieba extraction failed, falling back to basic: ${formatUnknownError(error)}`);
|
|
110
119
|
this.degradationMode = "basic";
|
|
111
120
|
}
|
|
112
121
|
return text.split(/\s+/).filter((w) => w.length > 1).slice(0, topK);
|
|
@@ -202,7 +211,7 @@ var KnowledgeGraphService = class {
|
|
|
202
211
|
});
|
|
203
212
|
this.logger.info(`Knowledge graph built successfully for kb=${kbId}`);
|
|
204
213
|
} catch (error) {
|
|
205
|
-
this.logger.error(`Failed to build knowledge graph: ${error}`);
|
|
214
|
+
this.logger.error(`Failed to build knowledge graph: ${formatUnknownError(error)}`);
|
|
206
215
|
throw error;
|
|
207
216
|
}
|
|
208
217
|
}
|
package/dist/parser.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { KnowhereDownloadedResult, KnowhereManifest, KnowhereParseResult, KnowhereStatistics, StoredBrowseIndex, StoredChunk } from "./types";
|
|
2
|
+
type KnowhereStoredResultSummary = {
|
|
3
|
+
manifest: KnowhereManifest;
|
|
4
|
+
chunkCount: number;
|
|
5
|
+
statistics: KnowhereStatistics;
|
|
6
|
+
};
|
|
7
|
+
export declare const STORED_BROWSE_INDEX_VERSION = 2;
|
|
8
|
+
export declare function resolveResultEntryPath(rootDir: string, entryPath: string): string;
|
|
9
|
+
export declare function buildStoredPathPrefixes(storedPath: string): string[];
|
|
10
|
+
export declare function isStoredBrowseIndex(value: unknown): value is StoredBrowseIndex;
|
|
11
|
+
export declare function buildStoredBrowseIndex(resultDir: string, manifest: KnowhereManifest, chunks: StoredChunk[]): Promise<StoredBrowseIndex>;
|
|
12
|
+
export declare function extractKnowhereResultArchive(downloadedResult: KnowhereDownloadedResult, targetDir: string): Promise<void>;
|
|
13
|
+
export declare function readStoredKnowhereResultSummary(resultDir: string): Promise<KnowhereStoredResultSummary>;
|
|
14
|
+
export declare function readStoredKnowhereResultContent(resultDir: string): Promise<Omit<KnowhereParseResult, "browseIndex">>;
|
|
15
|
+
export declare function readStoredKnowhereParseResult(resultDir: string): Promise<KnowhereParseResult>;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type ParsedConversationSessionKey = {
|
|
2
|
+
agentId: string;
|
|
3
|
+
surface: string;
|
|
4
|
+
remainder: string;
|
|
5
|
+
segments: string[];
|
|
6
|
+
};
|
|
7
|
+
export declare function parseConversationSessionKey(sessionKey: string | undefined): ParsedConversationSessionKey | undefined;
|
|
8
|
+
export declare function normalizeConversationScopeKey(sessionKey: string | undefined): string | undefined;
|
|
9
|
+
export declare function resolveSharedConversationScopeKey(sessionKey: string | undefined): string | undefined;
|
|
10
|
+
export declare function findConversationSegmentValue(session: ParsedConversationSessionKey | undefined, ...keys: string[]): string | undefined;
|
|
11
|
+
export declare function deriveMessageContextScopeKey(context: unknown): string | undefined;
|
package/dist/store.d.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { ChannelRouteRecord, KnowhereScope, PluginLogger, SaveStoredDocumentPayload, ScopeMode, StoredDocumentPayload, StoredDocumentRecord } from "./types";
|
|
2
|
+
export declare class KnowhereStore {
|
|
3
|
+
private readonly rootDir;
|
|
4
|
+
private readonly scopeMode;
|
|
5
|
+
private readonly logger;
|
|
6
|
+
private readonly indexCache;
|
|
7
|
+
private readonly documentPayloadCache;
|
|
8
|
+
private readonly scopeAccessChains;
|
|
9
|
+
private readonly scopeKeyAliases;
|
|
10
|
+
private readonly sessionScopeKeysBySessionId;
|
|
11
|
+
private readonly sessionScopeKeysBySessionKey;
|
|
12
|
+
private readonly channelRoutes;
|
|
13
|
+
private routesLoaded;
|
|
14
|
+
constructor(params: {
|
|
15
|
+
rootDir: string;
|
|
16
|
+
scopeMode: ScopeMode;
|
|
17
|
+
logger: PluginLogger;
|
|
18
|
+
});
|
|
19
|
+
registerScopeAlias(context: {
|
|
20
|
+
scopeKey: string;
|
|
21
|
+
sessionKey?: string;
|
|
22
|
+
sessionId?: string;
|
|
23
|
+
}): string;
|
|
24
|
+
registerMessageScope(context: {
|
|
25
|
+
sessionKey?: string;
|
|
26
|
+
sessionId?: string;
|
|
27
|
+
messageContext: unknown;
|
|
28
|
+
}): string | undefined;
|
|
29
|
+
registerChannelRoute(params: {
|
|
30
|
+
channelId: string;
|
|
31
|
+
accountId?: string;
|
|
32
|
+
conversationId?: string;
|
|
33
|
+
}): Promise<void>;
|
|
34
|
+
resolveChannelRoute(params: {
|
|
35
|
+
channelId?: string;
|
|
36
|
+
conversationId?: string;
|
|
37
|
+
sessionKey?: string;
|
|
38
|
+
}): Promise<ChannelRouteRecord | undefined>;
|
|
39
|
+
private lookupChannelRoute;
|
|
40
|
+
inheritScopeAlias(context: {
|
|
41
|
+
childSessionKey?: string;
|
|
42
|
+
childSessionId?: string;
|
|
43
|
+
requesterSessionKey?: string;
|
|
44
|
+
requesterSessionId?: string;
|
|
45
|
+
}): string | undefined;
|
|
46
|
+
resolveScope(context?: {
|
|
47
|
+
agentId?: string;
|
|
48
|
+
sessionKey?: string;
|
|
49
|
+
sessionId?: string;
|
|
50
|
+
}): KnowhereScope;
|
|
51
|
+
listDocuments(scope: KnowhereScope): Promise<StoredDocumentRecord[]>;
|
|
52
|
+
loadDocumentPayload(scope: KnowhereScope, docId: string): Promise<StoredDocumentPayload | null>;
|
|
53
|
+
getResultFileAbsolutePath(scope: KnowhereScope, docId: string, relativePath: string): string;
|
|
54
|
+
readResultFile(scope: KnowhereScope, docId: string, relativePath: string): Promise<{
|
|
55
|
+
document: StoredDocumentRecord;
|
|
56
|
+
relativePath: string;
|
|
57
|
+
text: string | null;
|
|
58
|
+
} | null>;
|
|
59
|
+
saveDownloadedDocument(scope: KnowhereScope, payload: SaveStoredDocumentPayload, options?: {
|
|
60
|
+
overwrite?: boolean;
|
|
61
|
+
}): Promise<StoredDocumentRecord>;
|
|
62
|
+
removeDocument(scope: KnowhereScope, docId: string): Promise<StoredDocumentRecord | null>;
|
|
63
|
+
clearScope(scope: KnowhereScope): Promise<StoredDocumentRecord[]>;
|
|
64
|
+
private getIndex;
|
|
65
|
+
private persistIndex;
|
|
66
|
+
private runWithScopeAccessLock;
|
|
67
|
+
private removeDocumentArtifacts;
|
|
68
|
+
private buildDocumentPayloadCacheKey;
|
|
69
|
+
private touchDocumentPayloadCache;
|
|
70
|
+
private deleteDocumentPayloadCache;
|
|
71
|
+
private deleteScopeDocumentPayloadCaches;
|
|
72
|
+
private loadOrBuildBrowseIndex;
|
|
73
|
+
private buildRouteKey;
|
|
74
|
+
private ensureRoutesLoaded;
|
|
75
|
+
private persistRoutes;
|
|
76
|
+
private resolveCanonicalScopeKey;
|
|
77
|
+
private resolveKnownScopeKey;
|
|
78
|
+
private rebuildIndex;
|
|
79
|
+
}
|
package/dist/text.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare function normalizeWhitespace(value: unknown): string;
|
|
2
|
+
export declare function truncateText(value: unknown, maxChars: number): string;
|
|
3
|
+
export declare function slugify(value: unknown, fallback?: string): string;
|
|
4
|
+
export declare function hashString(value: string): string;
|
|
5
|
+
export declare function sanitizeStringArray(value: unknown): string[];
|
|
6
|
+
export declare function toComparableText(value: unknown): string;
|
|
7
|
+
export declare function stripHtmlTags(text: string): string;
|
|
8
|
+
export declare function stripLatex(text: string): string;
|
|
9
|
+
export declare function normalizeUnicode(text: string): string;
|
|
10
|
+
export declare function normalizeForGrep(text: string): string;
|
package/dist/tools.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type AnyAgentTool, type OpenClawPluginApi } from "openclaw/plugin-sdk/core";
|
|
2
|
+
import { KnowhereStore } from "./store";
|
|
3
|
+
import type { KnowledgeGraphService } from "./kg-service";
|
|
4
|
+
import type { ResolvedKnowhereConfig, ToolRuntimeContext } from "./types";
|
|
5
|
+
export declare function createKnowhereToolFactory(params: {
|
|
6
|
+
api: OpenClawPluginApi;
|
|
7
|
+
config: ResolvedKnowhereConfig;
|
|
8
|
+
store: KnowhereStore;
|
|
9
|
+
kgService: KnowledgeGraphService;
|
|
10
|
+
}): (ctx: ToolRuntimeContext) => AnyAgentTool[];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/core";
|
|
2
|
+
import type { ChannelRouteRecord } from "./types";
|
|
3
|
+
export declare function sendTrackerProgress(params: {
|
|
4
|
+
api: OpenClawPluginApi;
|
|
5
|
+
context?: unknown;
|
|
6
|
+
sessionKey?: string;
|
|
7
|
+
messages?: unknown[];
|
|
8
|
+
channelRoute?: ChannelRouteRecord;
|
|
9
|
+
text: string;
|
|
10
|
+
}): Promise<boolean>;
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
export type ScopeMode = "session" | "agent" | "global";
|
|
2
|
+
export type StringRecord = Record<string, unknown>;
|
|
3
|
+
export interface PluginLogger {
|
|
4
|
+
debug?: (message: string) => void;
|
|
5
|
+
info: (message: string) => void;
|
|
6
|
+
warn: (message: string) => void;
|
|
7
|
+
error: (message: string) => void;
|
|
8
|
+
}
|
|
9
|
+
export interface ToolRuntimeContext {
|
|
10
|
+
workspaceDir?: string;
|
|
11
|
+
agentId?: string;
|
|
12
|
+
accountId?: string;
|
|
13
|
+
sessionKey?: string;
|
|
14
|
+
sessionId?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface ResolvedKnowhereConfig {
|
|
17
|
+
apiKey: string;
|
|
18
|
+
baseUrl: string;
|
|
19
|
+
storageDir: string;
|
|
20
|
+
scopeMode: ScopeMode;
|
|
21
|
+
pollIntervalMs: number;
|
|
22
|
+
pollTimeoutMs: number;
|
|
23
|
+
requestTimeoutMs: number;
|
|
24
|
+
uploadTimeoutMs: number;
|
|
25
|
+
}
|
|
26
|
+
export interface KnowhereStatistics {
|
|
27
|
+
total_chunks?: number;
|
|
28
|
+
text_chunks?: number;
|
|
29
|
+
image_chunks?: number;
|
|
30
|
+
table_chunks?: number;
|
|
31
|
+
total_pages?: number;
|
|
32
|
+
}
|
|
33
|
+
export interface KnowhereChecksum {
|
|
34
|
+
algorithm?: string;
|
|
35
|
+
value?: string;
|
|
36
|
+
}
|
|
37
|
+
export interface KnowhereManifest {
|
|
38
|
+
version?: string;
|
|
39
|
+
job_id?: string;
|
|
40
|
+
data_id?: string;
|
|
41
|
+
source_file_name?: string;
|
|
42
|
+
processing_date?: string;
|
|
43
|
+
checksum?: KnowhereChecksum;
|
|
44
|
+
statistics?: KnowhereStatistics;
|
|
45
|
+
files?: StringRecord;
|
|
46
|
+
}
|
|
47
|
+
export interface StoredChunk {
|
|
48
|
+
chunkId: string;
|
|
49
|
+
type: "text" | "image" | "table";
|
|
50
|
+
path: string | null;
|
|
51
|
+
summary: string;
|
|
52
|
+
content: string;
|
|
53
|
+
tokens: number | null;
|
|
54
|
+
keywords: string[];
|
|
55
|
+
relationships: unknown[];
|
|
56
|
+
metadata: StringRecord;
|
|
57
|
+
assetFilePath: string | null;
|
|
58
|
+
originalName: string | null;
|
|
59
|
+
tableType: string | null;
|
|
60
|
+
}
|
|
61
|
+
export interface StoredPathRecord {
|
|
62
|
+
path: string;
|
|
63
|
+
parentPath: string | null;
|
|
64
|
+
depth: number;
|
|
65
|
+
childPaths: string[];
|
|
66
|
+
chunkIds: string[];
|
|
67
|
+
directChunkCount: number;
|
|
68
|
+
chunkCount: number;
|
|
69
|
+
textChunkCount: number;
|
|
70
|
+
imageChunkCount: number;
|
|
71
|
+
tableChunkCount: number;
|
|
72
|
+
}
|
|
73
|
+
export type StoredResultFileKind = "manifest" | "chunks" | "fullMarkdown" | "kbCsv" | "hierarchy" | "hierarchyView" | "image" | "table" | "other";
|
|
74
|
+
export interface StoredResultFileRecord {
|
|
75
|
+
relativePath: string;
|
|
76
|
+
kind: StoredResultFileKind;
|
|
77
|
+
chunkId: string | null;
|
|
78
|
+
format: string | null;
|
|
79
|
+
sizeBytes: number | null;
|
|
80
|
+
}
|
|
81
|
+
export interface StoredBrowseIndex {
|
|
82
|
+
version: number;
|
|
83
|
+
paths: StoredPathRecord[];
|
|
84
|
+
chunkOrder: string[];
|
|
85
|
+
resultFiles: StoredResultFileRecord[];
|
|
86
|
+
}
|
|
87
|
+
export interface KnowhereParseResult {
|
|
88
|
+
manifest: KnowhereManifest;
|
|
89
|
+
chunks: StoredChunk[];
|
|
90
|
+
fullMarkdown: string;
|
|
91
|
+
hierarchy: unknown;
|
|
92
|
+
browseIndex: StoredBrowseIndex;
|
|
93
|
+
}
|
|
94
|
+
export interface KnowhereDownloadedResult {
|
|
95
|
+
zipBytes: Buffer;
|
|
96
|
+
rawZipSha1: string;
|
|
97
|
+
}
|
|
98
|
+
export interface KnowhereJob {
|
|
99
|
+
job_id: string;
|
|
100
|
+
status: string;
|
|
101
|
+
source_type: string;
|
|
102
|
+
data_id?: string | null;
|
|
103
|
+
created_at?: string | null;
|
|
104
|
+
upload_url?: string | null;
|
|
105
|
+
upload_headers?: Record<string, string> | null;
|
|
106
|
+
expires_in?: number | null;
|
|
107
|
+
}
|
|
108
|
+
export interface KnowhereJobError {
|
|
109
|
+
code?: string;
|
|
110
|
+
message?: string;
|
|
111
|
+
request_id?: string;
|
|
112
|
+
details?: unknown;
|
|
113
|
+
}
|
|
114
|
+
export interface KnowhereJobResult {
|
|
115
|
+
job_id: string;
|
|
116
|
+
status: string;
|
|
117
|
+
source_type: string;
|
|
118
|
+
data_id?: string | null;
|
|
119
|
+
created_at?: string | null;
|
|
120
|
+
progress?: unknown;
|
|
121
|
+
error?: KnowhereJobError | null;
|
|
122
|
+
result?: StringRecord | null;
|
|
123
|
+
result_url?: string | null;
|
|
124
|
+
result_url_expires_at?: string | null;
|
|
125
|
+
file_name?: string | null;
|
|
126
|
+
file_extension?: string | null;
|
|
127
|
+
model?: string | null;
|
|
128
|
+
ocr_enabled?: boolean | null;
|
|
129
|
+
duration_seconds?: number | null;
|
|
130
|
+
credits_spent?: number | null;
|
|
131
|
+
}
|
|
132
|
+
export interface KnowhereJobList {
|
|
133
|
+
jobs: KnowhereJobResult[];
|
|
134
|
+
total: number;
|
|
135
|
+
page: number;
|
|
136
|
+
pageSize: number;
|
|
137
|
+
totalPages: number;
|
|
138
|
+
}
|
|
139
|
+
export interface KnowhereJobListRequest {
|
|
140
|
+
page?: number;
|
|
141
|
+
pageSize?: number;
|
|
142
|
+
jobStatus?: string;
|
|
143
|
+
jobType?: string;
|
|
144
|
+
recentDays?: 1 | 7 | 30;
|
|
145
|
+
startTime?: string;
|
|
146
|
+
endTime?: string;
|
|
147
|
+
}
|
|
148
|
+
export interface KnowhereParsingParams {
|
|
149
|
+
model?: "base" | "advanced";
|
|
150
|
+
ocr_enabled?: boolean;
|
|
151
|
+
kb_dir?: string;
|
|
152
|
+
doc_type?: string;
|
|
153
|
+
smart_title_parse?: boolean;
|
|
154
|
+
summary_image?: boolean;
|
|
155
|
+
summary_table?: boolean;
|
|
156
|
+
summary_txt?: boolean;
|
|
157
|
+
add_frag_desc?: string;
|
|
158
|
+
}
|
|
159
|
+
export interface KnowhereIngestRequest {
|
|
160
|
+
filePath?: string;
|
|
161
|
+
fileName?: string;
|
|
162
|
+
url?: string;
|
|
163
|
+
dataId?: string;
|
|
164
|
+
parsingParams?: KnowhereParsingParams;
|
|
165
|
+
onJobCreated?: (job: KnowhereJob) => void | Promise<void>;
|
|
166
|
+
onJobUpdated?: (jobResult: KnowhereJobResult) => void | Promise<void>;
|
|
167
|
+
}
|
|
168
|
+
export interface KnowhereIngestResult {
|
|
169
|
+
job: KnowhereJob;
|
|
170
|
+
jobResult: KnowhereJobResult;
|
|
171
|
+
downloadedResult: KnowhereDownloadedResult;
|
|
172
|
+
}
|
|
173
|
+
export interface KnowhereScope {
|
|
174
|
+
mode: ScopeMode | "global";
|
|
175
|
+
key: string;
|
|
176
|
+
label: string;
|
|
177
|
+
rootDir: string;
|
|
178
|
+
documentsDir: string;
|
|
179
|
+
indexPath: string;
|
|
180
|
+
}
|
|
181
|
+
export interface StoredDocumentRecord {
|
|
182
|
+
id: string;
|
|
183
|
+
title: string;
|
|
184
|
+
sourceType: "file" | "url";
|
|
185
|
+
source: string;
|
|
186
|
+
sourceLabel: string;
|
|
187
|
+
fileName: string | null;
|
|
188
|
+
originalFileName: string | null;
|
|
189
|
+
dataId: string | null;
|
|
190
|
+
jobId: string | null;
|
|
191
|
+
checksum: string | null;
|
|
192
|
+
resultUrl: string | null;
|
|
193
|
+
resultUrlExpiresAt: string | null;
|
|
194
|
+
scopeLabel: string;
|
|
195
|
+
tags: string[];
|
|
196
|
+
ingestedAt: string;
|
|
197
|
+
updatedAt: string;
|
|
198
|
+
chunkCount: number;
|
|
199
|
+
statistics: KnowhereStatistics;
|
|
200
|
+
}
|
|
201
|
+
export interface StoredDocumentPayload {
|
|
202
|
+
version: number;
|
|
203
|
+
document: StoredDocumentRecord;
|
|
204
|
+
manifest: KnowhereManifest;
|
|
205
|
+
jobResult: KnowhereJobResult;
|
|
206
|
+
fullMarkdown: string;
|
|
207
|
+
hierarchy: unknown;
|
|
208
|
+
browseIndex: StoredBrowseIndex;
|
|
209
|
+
rawZipSha1: string;
|
|
210
|
+
chunks: StoredChunk[];
|
|
211
|
+
}
|
|
212
|
+
export interface StoredDocumentMetadata {
|
|
213
|
+
version: number;
|
|
214
|
+
document: StoredDocumentRecord;
|
|
215
|
+
jobResult: KnowhereJobResult;
|
|
216
|
+
rawZipSha1: string;
|
|
217
|
+
}
|
|
218
|
+
export interface KnowhereIndex {
|
|
219
|
+
version: number;
|
|
220
|
+
scopeMode: string;
|
|
221
|
+
scopeKey: string;
|
|
222
|
+
updatedAt: string | null;
|
|
223
|
+
documents: StoredDocumentRecord[];
|
|
224
|
+
}
|
|
225
|
+
export interface SaveStoredDocumentPayload {
|
|
226
|
+
sourceType: "file" | "url";
|
|
227
|
+
source: string;
|
|
228
|
+
sourceLabel?: string;
|
|
229
|
+
fileName: string | null;
|
|
230
|
+
docId?: string;
|
|
231
|
+
title?: string;
|
|
232
|
+
dataId?: string;
|
|
233
|
+
tags: string[];
|
|
234
|
+
job: KnowhereJob;
|
|
235
|
+
jobResult: KnowhereJobResult;
|
|
236
|
+
downloadedResult: KnowhereDownloadedResult;
|
|
237
|
+
}
|
|
238
|
+
export interface JsonSchemaObject {
|
|
239
|
+
[key: string]: unknown;
|
|
240
|
+
}
|
|
241
|
+
export interface ChannelRouteRecord {
|
|
242
|
+
readonly channelId: string;
|
|
243
|
+
readonly accountId: string;
|
|
244
|
+
readonly conversationId?: string;
|
|
245
|
+
readonly updatedAt: string;
|
|
246
|
+
}
|
|
247
|
+
export declare function isRecord(value: unknown): value is StringRecord;
|
|
248
|
+
export declare function isNodeError(error: unknown): error is NodeJS.ErrnoException;
|
|
249
|
+
export type KbIdSource = "disabled" | "agent" | "agent-session" | "global";
|
|
250
|
+
export interface KnowledgeGraphConnectConfig {
|
|
251
|
+
minKeywordOverlap: number;
|
|
252
|
+
keywordScoreWeight: number;
|
|
253
|
+
maxConnectionsPerChunk: number;
|
|
254
|
+
minScoreThreshold: number;
|
|
255
|
+
crossFileOnly: boolean;
|
|
256
|
+
maxContentOverlap: number;
|
|
257
|
+
}
|
|
258
|
+
export interface KnowledgeGraphConfig {
|
|
259
|
+
enableKnowledgeGraph: boolean;
|
|
260
|
+
kbId?: string;
|
|
261
|
+
kbIdSource?: KbIdSource;
|
|
262
|
+
concurrentBuildStrategy?: "queue" | "skip";
|
|
263
|
+
buildTimeout?: number;
|
|
264
|
+
notifyOnGraphFailure?: boolean;
|
|
265
|
+
connectConfig?: Partial<KnowledgeGraphConnectConfig>;
|
|
266
|
+
}
|
|
267
|
+
export interface GraphConnection {
|
|
268
|
+
source: string;
|
|
269
|
+
target: string;
|
|
270
|
+
score: number;
|
|
271
|
+
sharedKeywords: string[];
|
|
272
|
+
connectionType: string;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* File-level edge in knowledge graph (matches SKILL.md schema)
|
|
276
|
+
*/
|
|
277
|
+
export interface FileEdge {
|
|
278
|
+
source: string;
|
|
279
|
+
target: string;
|
|
280
|
+
connection_count: number;
|
|
281
|
+
avg_score: number;
|
|
282
|
+
top_connections: Array<{
|
|
283
|
+
source_chunk: string;
|
|
284
|
+
source_id: string;
|
|
285
|
+
target_chunk: string;
|
|
286
|
+
target_id: string;
|
|
287
|
+
relation: string;
|
|
288
|
+
score: number;
|
|
289
|
+
}>;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* File metadata in knowledge graph (matches SKILL.md schema)
|
|
293
|
+
*/
|
|
294
|
+
export interface FileMetadata {
|
|
295
|
+
chunks_count: number;
|
|
296
|
+
types: Record<string, number>;
|
|
297
|
+
top_keywords: string[];
|
|
298
|
+
top_summary: string;
|
|
299
|
+
importance: number;
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Knowledge graph structure (matches SKILL.md schema)
|
|
303
|
+
*/
|
|
304
|
+
export interface KnowledgeGraph {
|
|
305
|
+
version: string;
|
|
306
|
+
stats: {
|
|
307
|
+
total_files: number;
|
|
308
|
+
total_chunks: number;
|
|
309
|
+
total_cross_file_edges: number;
|
|
310
|
+
};
|
|
311
|
+
files: Record<string, FileMetadata>;
|
|
312
|
+
edges: FileEdge[];
|
|
313
|
+
}
|
|
314
|
+
export interface KbMetadata {
|
|
315
|
+
kbId: string;
|
|
316
|
+
createdAt: string;
|
|
317
|
+
lastUpdated: string;
|
|
318
|
+
documentCount: number;
|
|
319
|
+
config: Partial<KnowledgeGraphConnectConfig>;
|
|
320
|
+
}
|
package/openclaw.plugin.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"name": "Knowhere",
|
|
4
4
|
"description": "Parse documents with Knowhere and expose the stored result as tool-queryable document state for OpenClaw agents.",
|
|
5
5
|
"skills": ["./skills"],
|
|
6
|
-
"version": "0.1
|
|
6
|
+
"version": "0.2.1",
|
|
7
7
|
"uiHints": {
|
|
8
8
|
"apiKey": {
|
|
9
9
|
"label": "Knowhere API Key",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ontos-ai/knowhere-claw",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "OpenClaw plugin for Knowhere-powered document ingestion and automatic grounding.",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist/",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
20
|
"scripts": {
|
|
21
|
-
"build": "rolldown -c",
|
|
21
|
+
"build": "rolldown -c && tsc -p tsconfig.build.json",
|
|
22
22
|
"changeset": "changeset",
|
|
23
23
|
"changeset:publish": "changeset publish",
|
|
24
24
|
"fmt": "oxfmt",
|
|
@@ -69,4 +69,4 @@
|
|
|
69
69
|
"./dist/index.js"
|
|
70
70
|
]
|
|
71
71
|
}
|
|
72
|
-
}
|
|
72
|
+
}
|