@theromans/convex-dobty 0.1.8 → 0.1.10
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/client/index.d.ts +40 -12
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +38 -12
- package/dist/client/index.js.map +1 -1
- package/dist/component/assessment.d.ts +26 -0
- package/dist/component/assessment.d.ts.map +1 -1
- package/dist/component/assessment.js +55 -0
- package/dist/component/assessment.js.map +1 -1
- package/dist/component/knowledge.d.ts +53 -20
- package/dist/component/knowledge.d.ts.map +1 -1
- package/dist/component/knowledge.js +91 -21
- package/dist/component/knowledge.js.map +1 -1
- package/dist/component/knowledgeSearch.d.ts +32 -7
- package/dist/component/knowledgeSearch.d.ts.map +1 -1
- package/dist/component/knowledgeSearch.js +99 -39
- package/dist/component/knowledgeSearch.js.map +1 -1
- package/dist/component/potentialAnalysis.d.ts.map +1 -1
- package/dist/component/potentialAnalysis.js +4 -0
- package/dist/component/potentialAnalysis.js.map +1 -1
- package/dist/component/schema.d.ts +35 -12
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/schema.js +21 -6
- package/dist/component/schema.js.map +1 -1
- package/dist/data/types.d.ts +6 -0
- package/dist/data/types.d.ts.map +1 -1
- package/dist/data/types.js.map +1 -1
- package/knowledge-chunks.json +247 -0
- package/package.json +5 -3
- package/src/client/index.ts +65 -16
- package/src/component/assessment.ts +58 -0
- package/src/component/knowledge.ts +104 -21
- package/src/component/knowledgeSearch.ts +154 -48
- package/src/component/potentialAnalysis.ts +5 -0
- package/src/component/schema.ts +21 -6
- package/src/data/types.ts +6 -0
|
@@ -3,13 +3,16 @@ export declare const seedKnowledgeChunks: import("convex/server").RegisteredMuta
|
|
|
3
3
|
chunks: {
|
|
4
4
|
topic: string;
|
|
5
5
|
chunkKey: string;
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
title_English: string;
|
|
7
|
+
title_Deutsch: string;
|
|
8
|
+
content_English: string;
|
|
9
|
+
content_Deutsch: string;
|
|
8
10
|
}[];
|
|
9
11
|
}, Promise<{
|
|
10
12
|
inserted: number;
|
|
11
13
|
updated: number;
|
|
12
14
|
skipped: number;
|
|
15
|
+
deleted: number;
|
|
13
16
|
}>>;
|
|
14
17
|
/** List chunks by topic. */
|
|
15
18
|
export declare const listChunks: import("convex/server").RegisteredQuery<"public", {
|
|
@@ -17,31 +20,53 @@ export declare const listChunks: import("convex/server").RegisteredQuery<"public
|
|
|
17
20
|
}, Promise<{
|
|
18
21
|
_id: import("convex/values").GenericId<"knowledgeChunks">;
|
|
19
22
|
_creationTime: number;
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
embedding_en?: number[] | undefined;
|
|
24
|
+
embedding_de?: number[] | undefined;
|
|
25
|
+
embeddedAt_en?: number | undefined;
|
|
26
|
+
embeddedAt_de?: number | undefined;
|
|
22
27
|
topic: string;
|
|
23
28
|
updatedAt: number;
|
|
24
29
|
chunkKey: string;
|
|
25
|
-
|
|
26
|
-
|
|
30
|
+
title_English: string;
|
|
31
|
+
title_Deutsch: string;
|
|
32
|
+
content_English: string;
|
|
33
|
+
content_Deutsch: string;
|
|
27
34
|
}[]>>;
|
|
28
35
|
/** Return distinct topic strings. */
|
|
29
36
|
export declare const listTopics: import("convex/server").RegisteredQuery<"public", {}, Promise<string[]>>;
|
|
30
|
-
/** List chunks that need (re-)embedding
|
|
31
|
-
export declare const
|
|
37
|
+
/** List chunks that need (re-)embedding for English. */
|
|
38
|
+
export declare const listStaleChunksEn: import("convex/server").RegisteredQuery<"public", {}, Promise<{
|
|
32
39
|
_id: import("convex/values").GenericId<"knowledgeChunks">;
|
|
33
40
|
topic: string;
|
|
34
41
|
chunkKey: string;
|
|
35
42
|
title: string;
|
|
36
43
|
content: string;
|
|
37
44
|
}[]>>;
|
|
38
|
-
/**
|
|
39
|
-
export declare const
|
|
45
|
+
/** List chunks that need (re-)embedding for Deutsch. */
|
|
46
|
+
export declare const listStaleChunksDe: import("convex/server").RegisteredQuery<"public", {}, Promise<{
|
|
47
|
+
_id: import("convex/values").GenericId<"knowledgeChunks">;
|
|
48
|
+
topic: string;
|
|
49
|
+
chunkKey: string;
|
|
50
|
+
title: string;
|
|
51
|
+
content: string;
|
|
52
|
+
}[]>>;
|
|
53
|
+
/** Update a chunk's English embedding by ID. */
|
|
54
|
+
export declare const updateChunkEmbeddingEn: import("convex/server").RegisteredMutation<"public", {
|
|
55
|
+
chunkId: import("convex/values").GenericId<"knowledgeChunks">;
|
|
56
|
+
embedding: number[];
|
|
57
|
+
}, Promise<void>>;
|
|
58
|
+
/** Update a chunk's Deutsch embedding by ID. */
|
|
59
|
+
export declare const updateChunkEmbeddingDe: import("convex/server").RegisteredMutation<"public", {
|
|
60
|
+
chunkId: import("convex/values").GenericId<"knowledgeChunks">;
|
|
61
|
+
embedding: number[];
|
|
62
|
+
}, Promise<void>>;
|
|
63
|
+
/** Patch English embedding for a single chunk. */
|
|
64
|
+
export declare const updateEmbeddingEn: import("convex/server").RegisteredMutation<"internal", {
|
|
40
65
|
chunkId: import("convex/values").GenericId<"knowledgeChunks">;
|
|
41
66
|
embedding: number[];
|
|
42
67
|
}, Promise<void>>;
|
|
43
|
-
/** Patch embedding
|
|
44
|
-
export declare const
|
|
68
|
+
/** Patch Deutsch embedding for a single chunk. */
|
|
69
|
+
export declare const updateEmbeddingDe: import("convex/server").RegisteredMutation<"internal", {
|
|
45
70
|
chunkId: import("convex/values").GenericId<"knowledgeChunks">;
|
|
46
71
|
embedding: number[];
|
|
47
72
|
}, Promise<void>>;
|
|
@@ -49,13 +74,17 @@ export declare const updateEmbedding: import("convex/server").RegisteredMutation
|
|
|
49
74
|
export declare const listAllChunks: import("convex/server").RegisteredQuery<"internal", {}, Promise<{
|
|
50
75
|
_id: import("convex/values").GenericId<"knowledgeChunks">;
|
|
51
76
|
_creationTime: number;
|
|
52
|
-
|
|
53
|
-
|
|
77
|
+
embedding_en?: number[] | undefined;
|
|
78
|
+
embedding_de?: number[] | undefined;
|
|
79
|
+
embeddedAt_en?: number | undefined;
|
|
80
|
+
embeddedAt_de?: number | undefined;
|
|
54
81
|
topic: string;
|
|
55
82
|
updatedAt: number;
|
|
56
83
|
chunkKey: string;
|
|
57
|
-
|
|
58
|
-
|
|
84
|
+
title_English: string;
|
|
85
|
+
title_Deutsch: string;
|
|
86
|
+
content_English: string;
|
|
87
|
+
content_Deutsch: string;
|
|
59
88
|
}[]>>;
|
|
60
89
|
/** Get a single chunk by ID. */
|
|
61
90
|
export declare const getChunk: import("convex/server").RegisteredQuery<"internal", {
|
|
@@ -63,12 +92,16 @@ export declare const getChunk: import("convex/server").RegisteredQuery<"internal
|
|
|
63
92
|
}, Promise<{
|
|
64
93
|
_id: import("convex/values").GenericId<"knowledgeChunks">;
|
|
65
94
|
_creationTime: number;
|
|
66
|
-
|
|
67
|
-
|
|
95
|
+
embedding_en?: number[] | undefined;
|
|
96
|
+
embedding_de?: number[] | undefined;
|
|
97
|
+
embeddedAt_en?: number | undefined;
|
|
98
|
+
embeddedAt_de?: number | undefined;
|
|
68
99
|
topic: string;
|
|
69
100
|
updatedAt: number;
|
|
70
101
|
chunkKey: string;
|
|
71
|
-
|
|
72
|
-
|
|
102
|
+
title_English: string;
|
|
103
|
+
title_Deutsch: string;
|
|
104
|
+
content_English: string;
|
|
105
|
+
content_Deutsch: string;
|
|
73
106
|
} | null>>;
|
|
74
107
|
//# sourceMappingURL=knowledge.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"knowledge.d.ts","sourceRoot":"","sources":["../../src/component/knowledge.ts"],"names":[],"mappings":"AAQA,oFAAoF;AACpF,eAAO,MAAM,mBAAmB
|
|
1
|
+
{"version":3,"file":"knowledge.d.ts","sourceRoot":"","sources":["../../src/component/knowledge.ts"],"names":[],"mappings":"AAQA,oFAAoF;AACpF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;GA6E9B,CAAC;AAEH,4BAA4B;AAC5B,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;KAQrB,CAAC;AAEH,qCAAqC;AACrC,eAAO,MAAM,UAAU,0EAOrB,CAAC;AAEH,wDAAwD;AACxD,eAAO,MAAM,iBAAiB;;;;;;KAmB5B,CAAC;AAEH,wDAAwD;AACxD,eAAO,MAAM,iBAAiB;;;;;;KAmB5B,CAAC;AAEH,gDAAgD;AAChD,eAAO,MAAM,sBAAsB;;;iBAWjC,CAAC;AAEH,gDAAgD;AAChD,eAAO,MAAM,sBAAsB;;;iBAWjC,CAAC;AAIH,kDAAkD;AAClD,eAAO,MAAM,iBAAiB;;;iBAW5B,CAAC;AAEH,kDAAkD;AAClD,eAAO,MAAM,iBAAiB;;;iBAW5B,CAAC;AAEH,yCAAyC;AACzC,eAAO,MAAM,aAAa;;;;;;;;;;;;;;KAKxB,CAAC;AAEH,gCAAgC;AAChC,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;UAKnB,CAAC"}
|
|
@@ -6,24 +6,37 @@ export const seedKnowledgeChunks = mutation({
|
|
|
6
6
|
chunks: v.array(v.object({
|
|
7
7
|
topic: v.string(),
|
|
8
8
|
chunkKey: v.string(),
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
title_English: v.string(),
|
|
10
|
+
title_Deutsch: v.string(),
|
|
11
|
+
content_English: v.string(),
|
|
12
|
+
content_Deutsch: v.string(),
|
|
11
13
|
})),
|
|
12
14
|
},
|
|
13
15
|
handler: async (ctx, { chunks }) => {
|
|
14
16
|
let inserted = 0;
|
|
15
17
|
let updated = 0;
|
|
16
18
|
let skipped = 0;
|
|
19
|
+
// Collect all existing chunkKeys for this topic to detect deletions
|
|
20
|
+
const incomingKeys = new Set(chunks.map((c) => `${c.topic}::${c.chunkKey}`));
|
|
17
21
|
for (const chunk of chunks) {
|
|
18
22
|
const existing = await ctx.db
|
|
19
23
|
.query("knowledgeChunks")
|
|
20
24
|
.withIndex("by_topic_chunkKey", (q) => q.eq("topic", chunk.topic).eq("chunkKey", chunk.chunkKey))
|
|
21
25
|
.unique();
|
|
22
26
|
if (existing) {
|
|
23
|
-
|
|
27
|
+
const contentChanged = existing.content_English !== chunk.content_English ||
|
|
28
|
+
existing.content_Deutsch !== chunk.content_Deutsch ||
|
|
29
|
+
existing.title_English !== chunk.title_English ||
|
|
30
|
+
existing.title_Deutsch !== chunk.title_Deutsch;
|
|
31
|
+
if (contentChanged) {
|
|
24
32
|
await ctx.db.patch(existing._id, {
|
|
25
|
-
|
|
26
|
-
|
|
33
|
+
title_English: chunk.title_English,
|
|
34
|
+
title_Deutsch: chunk.title_Deutsch,
|
|
35
|
+
content_English: chunk.content_English,
|
|
36
|
+
content_Deutsch: chunk.content_Deutsch,
|
|
37
|
+
// Invalidate both embeddings so they get re-embedded
|
|
38
|
+
embeddedAt_en: undefined,
|
|
39
|
+
embeddedAt_de: undefined,
|
|
27
40
|
updatedAt: Date.now(),
|
|
28
41
|
});
|
|
29
42
|
updated++;
|
|
@@ -36,14 +49,25 @@ export const seedKnowledgeChunks = mutation({
|
|
|
36
49
|
await ctx.db.insert("knowledgeChunks", {
|
|
37
50
|
topic: chunk.topic,
|
|
38
51
|
chunkKey: chunk.chunkKey,
|
|
39
|
-
|
|
40
|
-
|
|
52
|
+
title_English: chunk.title_English,
|
|
53
|
+
title_Deutsch: chunk.title_Deutsch,
|
|
54
|
+
content_English: chunk.content_English,
|
|
55
|
+
content_Deutsch: chunk.content_Deutsch,
|
|
41
56
|
updatedAt: Date.now(),
|
|
42
57
|
});
|
|
43
58
|
inserted++;
|
|
44
59
|
}
|
|
45
60
|
}
|
|
46
|
-
|
|
61
|
+
// Remove chunks that are no longer in the incoming set (full replacement semantics)
|
|
62
|
+
const allExisting = await ctx.db.query("knowledgeChunks").collect();
|
|
63
|
+
let deleted = 0;
|
|
64
|
+
for (const existing of allExisting) {
|
|
65
|
+
if (!incomingKeys.has(`${existing.topic}::${existing.chunkKey}`)) {
|
|
66
|
+
await ctx.db.delete(existing._id);
|
|
67
|
+
deleted++;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return { inserted, updated, skipped, deleted };
|
|
47
71
|
},
|
|
48
72
|
});
|
|
49
73
|
/** List chunks by topic. */
|
|
@@ -65,46 +89,92 @@ export const listTopics = query({
|
|
|
65
89
|
return [...topics];
|
|
66
90
|
},
|
|
67
91
|
});
|
|
68
|
-
/** List chunks that need (re-)embedding
|
|
69
|
-
export const
|
|
92
|
+
/** List chunks that need (re-)embedding for English. */
|
|
93
|
+
export const listStaleChunksEn = query({
|
|
94
|
+
args: {},
|
|
95
|
+
handler: async (ctx) => {
|
|
96
|
+
const all = await ctx.db.query("knowledgeChunks").collect();
|
|
97
|
+
return all
|
|
98
|
+
.filter((c) => !c.embedding_en ||
|
|
99
|
+
!c.embeddedAt_en ||
|
|
100
|
+
c.embeddedAt_en < c.updatedAt)
|
|
101
|
+
.map((c) => ({
|
|
102
|
+
_id: c._id,
|
|
103
|
+
topic: c.topic,
|
|
104
|
+
chunkKey: c.chunkKey,
|
|
105
|
+
title: c.title_English,
|
|
106
|
+
content: c.content_English,
|
|
107
|
+
}));
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
/** List chunks that need (re-)embedding for Deutsch. */
|
|
111
|
+
export const listStaleChunksDe = query({
|
|
70
112
|
args: {},
|
|
71
113
|
handler: async (ctx) => {
|
|
72
114
|
const all = await ctx.db.query("knowledgeChunks").collect();
|
|
73
115
|
return all
|
|
74
|
-
.filter((c) => !c.
|
|
116
|
+
.filter((c) => !c.embedding_de ||
|
|
117
|
+
!c.embeddedAt_de ||
|
|
118
|
+
c.embeddedAt_de < c.updatedAt)
|
|
75
119
|
.map((c) => ({
|
|
76
120
|
_id: c._id,
|
|
77
121
|
topic: c.topic,
|
|
78
122
|
chunkKey: c.chunkKey,
|
|
79
|
-
title: c.
|
|
80
|
-
content: c.
|
|
123
|
+
title: c.title_Deutsch,
|
|
124
|
+
content: c.content_Deutsch,
|
|
81
125
|
}));
|
|
82
126
|
},
|
|
83
127
|
});
|
|
84
|
-
/** Update a chunk's embedding by ID
|
|
85
|
-
export const
|
|
128
|
+
/** Update a chunk's English embedding by ID. */
|
|
129
|
+
export const updateChunkEmbeddingEn = mutation({
|
|
86
130
|
args: {
|
|
87
131
|
chunkId: v.id("knowledgeChunks"),
|
|
88
132
|
embedding: v.array(v.float64()),
|
|
89
133
|
},
|
|
90
134
|
handler: async (ctx, { chunkId, embedding }) => {
|
|
91
135
|
await ctx.db.patch(chunkId, {
|
|
92
|
-
embedding,
|
|
93
|
-
|
|
136
|
+
embedding_en: embedding,
|
|
137
|
+
embeddedAt_en: Date.now(),
|
|
138
|
+
});
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
/** Update a chunk's Deutsch embedding by ID. */
|
|
142
|
+
export const updateChunkEmbeddingDe = mutation({
|
|
143
|
+
args: {
|
|
144
|
+
chunkId: v.id("knowledgeChunks"),
|
|
145
|
+
embedding: v.array(v.float64()),
|
|
146
|
+
},
|
|
147
|
+
handler: async (ctx, { chunkId, embedding }) => {
|
|
148
|
+
await ctx.db.patch(chunkId, {
|
|
149
|
+
embedding_de: embedding,
|
|
150
|
+
embeddedAt_de: Date.now(),
|
|
94
151
|
});
|
|
95
152
|
},
|
|
96
153
|
});
|
|
97
154
|
// ── Internal functions (called by knowledgeSearch.ts) ──
|
|
98
|
-
/** Patch embedding
|
|
99
|
-
export const
|
|
155
|
+
/** Patch English embedding for a single chunk. */
|
|
156
|
+
export const updateEmbeddingEn = internalMutation({
|
|
157
|
+
args: {
|
|
158
|
+
chunkId: v.id("knowledgeChunks"),
|
|
159
|
+
embedding: v.array(v.float64()),
|
|
160
|
+
},
|
|
161
|
+
handler: async (ctx, { chunkId, embedding }) => {
|
|
162
|
+
await ctx.db.patch(chunkId, {
|
|
163
|
+
embedding_en: embedding,
|
|
164
|
+
embeddedAt_en: Date.now(),
|
|
165
|
+
});
|
|
166
|
+
},
|
|
167
|
+
});
|
|
168
|
+
/** Patch Deutsch embedding for a single chunk. */
|
|
169
|
+
export const updateEmbeddingDe = internalMutation({
|
|
100
170
|
args: {
|
|
101
171
|
chunkId: v.id("knowledgeChunks"),
|
|
102
172
|
embedding: v.array(v.float64()),
|
|
103
173
|
},
|
|
104
174
|
handler: async (ctx, { chunkId, embedding }) => {
|
|
105
175
|
await ctx.db.patch(chunkId, {
|
|
106
|
-
embedding,
|
|
107
|
-
|
|
176
|
+
embedding_de: embedding,
|
|
177
|
+
embeddedAt_de: Date.now(),
|
|
108
178
|
});
|
|
109
179
|
},
|
|
110
180
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"knowledge.js","sourceRoot":"","sources":["../../src/component/knowledge.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,KAAK,EACL,gBAAgB,EAChB,aAAa,GACd,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,CAAC,EAAE,MAAM,eAAe,CAAC;AAElC,oFAAoF;AACpF,MAAM,CAAC,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IAC1C,IAAI,EAAE;QACJ,MAAM,EAAE,CAAC,CAAC,KAAK,CACb,CAAC,CAAC,MAAM,CAAC;YACP,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;YACjB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;YACpB,
|
|
1
|
+
{"version":3,"file":"knowledge.js","sourceRoot":"","sources":["../../src/component/knowledge.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,29 +1,54 @@
|
|
|
1
|
-
interface KnowledgeResult {
|
|
1
|
+
export interface KnowledgeResult {
|
|
2
2
|
title: string;
|
|
3
3
|
content: string;
|
|
4
|
+
title_English: string;
|
|
5
|
+
title_Deutsch: string;
|
|
6
|
+
content_English: string;
|
|
7
|
+
content_Deutsch: string;
|
|
4
8
|
score: number;
|
|
9
|
+
language: "en" | "de";
|
|
10
|
+
embeddingLanguage: "en" | "de";
|
|
5
11
|
}
|
|
6
|
-
/**
|
|
12
|
+
/**
|
|
13
|
+
* Search knowledge chunks by embedding similarity.
|
|
14
|
+
*
|
|
15
|
+
* - language: the requested language for returned title/content ("en" | "de")
|
|
16
|
+
* - Uses the embedding index for the requested language.
|
|
17
|
+
* - Falls back to the other language's index if the primary has no vectors.
|
|
18
|
+
* - Returns up to `limit` results (default 5).
|
|
19
|
+
*/
|
|
7
20
|
export declare const searchKnowledge: import("convex/server").RegisteredAction<"public", {
|
|
8
21
|
limit?: number | undefined;
|
|
9
22
|
query: string;
|
|
10
23
|
topic: string;
|
|
11
24
|
apiToken: string;
|
|
25
|
+
language: "en" | "de";
|
|
12
26
|
}, Promise<KnowledgeResult[]>>;
|
|
13
|
-
/**
|
|
27
|
+
/**
|
|
28
|
+
* Search knowledge chunks by pre-computed embedding vector (no outbound fetch needed).
|
|
29
|
+
*
|
|
30
|
+
* - language: the requested language for returned title/content ("en" | "de")
|
|
31
|
+
* - Falls back to the other language's index if primary has no vectors.
|
|
32
|
+
* - Returns up to `limit` results (default 5).
|
|
33
|
+
*/
|
|
14
34
|
export declare const searchByVector: import("convex/server").RegisteredAction<"public", {
|
|
15
35
|
limit?: number | undefined;
|
|
16
36
|
topic: string;
|
|
17
37
|
embedding: number[];
|
|
38
|
+
language: "en" | "de";
|
|
18
39
|
}, Promise<KnowledgeResult[]>>;
|
|
19
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* Re-embed stale chunks for both languages.
|
|
42
|
+
* Embeds English and Deutsch separately, storing embedding_en and embedding_de.
|
|
43
|
+
*/
|
|
20
44
|
export declare const refreshEmbeddings: import("convex/server").RegisteredAction<"public", {
|
|
21
45
|
apiToken: string;
|
|
22
46
|
}, Promise<{
|
|
23
47
|
total: number;
|
|
24
|
-
|
|
25
|
-
|
|
48
|
+
staleEn: number;
|
|
49
|
+
staleDe: number;
|
|
50
|
+
embeddedEn: number;
|
|
51
|
+
embeddedDe: number;
|
|
26
52
|
errors: number;
|
|
27
53
|
}>>;
|
|
28
|
-
export {};
|
|
29
54
|
//# sourceMappingURL=knowledgeSearch.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"knowledgeSearch.d.ts","sourceRoot":"","sources":["../../src/component/knowledgeSearch.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"knowledgeSearch.d.ts","sourceRoot":"","sources":["../../src/component/knowledgeSearch.ts"],"names":[],"mappings":"AAmDA,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,iBAAiB,EAAE,IAAI,GAAG,IAAI,CAAC;CAChC;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe;;;;;;8BAgB1B,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,cAAc;;;;;8BAazB,CAAC;AAqEH;;;GAGG;AACH,eAAO,MAAM,iBAAiB;;;WAQnB,MAAM;aACJ,MAAM;aACN,MAAM;gBACH,MAAM;gBACN,MAAM;YACV,MAAM;GAmEhB,CAAC"}
|
|
@@ -5,6 +5,7 @@ const EMBEDDING_ENDPOINT = "https://openai.inference.de-txl.ionos.com/v1/embeddi
|
|
|
5
5
|
const EMBEDDING_MODEL = "BAAI/bge-m3";
|
|
6
6
|
const EMBEDDING_DIMENSIONS = 1024;
|
|
7
7
|
const EMBEDDING_TIMEOUT_MS = 10_000;
|
|
8
|
+
const DEFAULT_SEARCH_LIMIT = 5;
|
|
8
9
|
async function getEmbedding(text, apiToken) {
|
|
9
10
|
const controller = new AbortController();
|
|
10
11
|
const timer = setTimeout(() => controller.abort(), EMBEDDING_TIMEOUT_MS);
|
|
@@ -39,81 +40,140 @@ async function getEmbedding(text, apiToken) {
|
|
|
39
40
|
clearTimeout(timer);
|
|
40
41
|
}
|
|
41
42
|
}
|
|
42
|
-
/**
|
|
43
|
+
/**
|
|
44
|
+
* Search knowledge chunks by embedding similarity.
|
|
45
|
+
*
|
|
46
|
+
* - language: the requested language for returned title/content ("en" | "de")
|
|
47
|
+
* - Uses the embedding index for the requested language.
|
|
48
|
+
* - Falls back to the other language's index if the primary has no vectors.
|
|
49
|
+
* - Returns up to `limit` results (default 5).
|
|
50
|
+
*/
|
|
43
51
|
export const searchKnowledge = action({
|
|
44
52
|
args: {
|
|
45
53
|
topic: v.string(),
|
|
46
54
|
query: v.string(),
|
|
55
|
+
language: v.union(v.literal("en"), v.literal("de")),
|
|
47
56
|
limit: v.optional(v.number()),
|
|
48
57
|
apiToken: v.string(),
|
|
49
58
|
},
|
|
50
|
-
handler: async (ctx, { topic, query, limit =
|
|
59
|
+
handler: async (ctx, { topic, query, language, limit = DEFAULT_SEARCH_LIMIT, apiToken }) => {
|
|
51
60
|
const embedding = await getEmbedding(query, apiToken);
|
|
52
|
-
|
|
53
|
-
vector: embedding,
|
|
54
|
-
limit,
|
|
55
|
-
filter: (q) => q.eq("topic", topic),
|
|
56
|
-
});
|
|
57
|
-
if (results.length === 0)
|
|
58
|
-
return [];
|
|
59
|
-
const docs = await Promise.all(results.map(async (r) => {
|
|
60
|
-
const doc = await ctx.runQuery(internal.knowledge.getChunk, {
|
|
61
|
-
chunkId: r._id,
|
|
62
|
-
});
|
|
63
|
-
return doc ? { title: doc.title, content: doc.content, score: r._score } : null;
|
|
64
|
-
}));
|
|
65
|
-
return docs.filter((d) => d !== null);
|
|
61
|
+
return _searchByVector(ctx, { topic, embedding, language, limit });
|
|
66
62
|
},
|
|
67
63
|
});
|
|
68
|
-
/**
|
|
64
|
+
/**
|
|
65
|
+
* Search knowledge chunks by pre-computed embedding vector (no outbound fetch needed).
|
|
66
|
+
*
|
|
67
|
+
* - language: the requested language for returned title/content ("en" | "de")
|
|
68
|
+
* - Falls back to the other language's index if primary has no vectors.
|
|
69
|
+
* - Returns up to `limit` results (default 5).
|
|
70
|
+
*/
|
|
69
71
|
export const searchByVector = action({
|
|
70
72
|
args: {
|
|
71
73
|
topic: v.string(),
|
|
72
74
|
embedding: v.array(v.float64()),
|
|
75
|
+
language: v.union(v.literal("en"), v.literal("de")),
|
|
73
76
|
limit: v.optional(v.number()),
|
|
74
77
|
},
|
|
75
|
-
handler: async (ctx, { topic, embedding, limit =
|
|
76
|
-
|
|
78
|
+
handler: async (ctx, { topic, embedding, language, limit = DEFAULT_SEARCH_LIMIT }) => {
|
|
79
|
+
return _searchByVector(ctx, { topic, embedding, language, limit });
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
async function _searchByVector(ctx, { topic, embedding, language, limit, }) {
|
|
83
|
+
const primaryIndex = language === "en" ? "by_embedding_en" : "by_embedding_de";
|
|
84
|
+
const fallbackIndex = language === "en" ? "by_embedding_de" : "by_embedding_en";
|
|
85
|
+
const fallbackLanguage = language === "en" ? "de" : "en";
|
|
86
|
+
// Try primary language index first
|
|
87
|
+
let results = await ctx.vectorSearch("knowledgeChunks", primaryIndex, {
|
|
88
|
+
vector: embedding,
|
|
89
|
+
limit,
|
|
90
|
+
filter: (q) => q.eq("topic", topic),
|
|
91
|
+
});
|
|
92
|
+
let embeddingLanguage = language;
|
|
93
|
+
// Fall back to the other language's index if primary returned nothing
|
|
94
|
+
if (results.length === 0) {
|
|
95
|
+
results = await ctx.vectorSearch("knowledgeChunks", fallbackIndex, {
|
|
77
96
|
vector: embedding,
|
|
78
97
|
limit,
|
|
79
98
|
filter: (q) => q.eq("topic", topic),
|
|
80
99
|
});
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
})
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
100
|
+
embeddingLanguage = fallbackLanguage;
|
|
101
|
+
}
|
|
102
|
+
if (results.length === 0)
|
|
103
|
+
return [];
|
|
104
|
+
const docs = await Promise.all(results.map(async (r) => {
|
|
105
|
+
const doc = await ctx.runQuery(internal.knowledge.getChunk, {
|
|
106
|
+
chunkId: r._id,
|
|
107
|
+
});
|
|
108
|
+
if (!doc)
|
|
109
|
+
return null;
|
|
110
|
+
const title = language === "en" ? doc.title_English : doc.title_Deutsch;
|
|
111
|
+
const content = language === "en" ? doc.content_English : doc.content_Deutsch;
|
|
112
|
+
return {
|
|
113
|
+
title,
|
|
114
|
+
content,
|
|
115
|
+
title_English: doc.title_English,
|
|
116
|
+
title_Deutsch: doc.title_Deutsch,
|
|
117
|
+
content_English: doc.content_English,
|
|
118
|
+
content_Deutsch: doc.content_Deutsch,
|
|
119
|
+
score: r._score,
|
|
120
|
+
language,
|
|
121
|
+
embeddingLanguage,
|
|
122
|
+
};
|
|
123
|
+
}));
|
|
124
|
+
return docs.filter((d) => d !== null);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Re-embed stale chunks for both languages.
|
|
128
|
+
* Embeds English and Deutsch separately, storing embedding_en and embedding_de.
|
|
129
|
+
*/
|
|
93
130
|
export const refreshEmbeddings = action({
|
|
94
131
|
args: {
|
|
95
132
|
apiToken: v.string(),
|
|
96
133
|
},
|
|
97
134
|
handler: async (ctx, { apiToken }) => {
|
|
98
135
|
const allChunks = await ctx.runQuery(internal.knowledge.listAllChunks, {});
|
|
99
|
-
const
|
|
100
|
-
|
|
136
|
+
const staleEn = allChunks.filter((c) => !c.embedding_en || !c.embeddedAt_en || c.embeddedAt_en < c.updatedAt);
|
|
137
|
+
const staleDe = allChunks.filter((c) => !c.embedding_de || !c.embeddedAt_de || c.embeddedAt_de < c.updatedAt);
|
|
138
|
+
let embeddedEn = 0;
|
|
139
|
+
let embeddedDe = 0;
|
|
101
140
|
let errors = 0;
|
|
102
|
-
for (const chunk of
|
|
141
|
+
for (const chunk of staleEn) {
|
|
142
|
+
try {
|
|
143
|
+
const embedding = await getEmbedding(`${chunk.title_English}\n\n${chunk.content_English}`, apiToken);
|
|
144
|
+
await ctx.runMutation(internal.knowledge.updateEmbeddingEn, {
|
|
145
|
+
chunkId: chunk._id,
|
|
146
|
+
embedding,
|
|
147
|
+
});
|
|
148
|
+
embeddedEn++;
|
|
149
|
+
}
|
|
150
|
+
catch (e) {
|
|
151
|
+
console.error(`Failed to embed EN chunk ${chunk.chunkKey}: ${e.message}`);
|
|
152
|
+
errors++;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
for (const chunk of staleDe) {
|
|
103
156
|
try {
|
|
104
|
-
const embedding = await getEmbedding(`${chunk.
|
|
105
|
-
await ctx.runMutation(internal.knowledge.
|
|
157
|
+
const embedding = await getEmbedding(`${chunk.title_Deutsch}\n\n${chunk.content_Deutsch}`, apiToken);
|
|
158
|
+
await ctx.runMutation(internal.knowledge.updateEmbeddingDe, {
|
|
106
159
|
chunkId: chunk._id,
|
|
107
160
|
embedding,
|
|
108
161
|
});
|
|
109
|
-
|
|
162
|
+
embeddedDe++;
|
|
110
163
|
}
|
|
111
164
|
catch (e) {
|
|
112
|
-
console.error(`Failed to embed chunk ${chunk.chunkKey}: ${e.message}`);
|
|
165
|
+
console.error(`Failed to embed DE chunk ${chunk.chunkKey}: ${e.message}`);
|
|
113
166
|
errors++;
|
|
114
167
|
}
|
|
115
168
|
}
|
|
116
|
-
return {
|
|
169
|
+
return {
|
|
170
|
+
total: allChunks.length,
|
|
171
|
+
staleEn: staleEn.length,
|
|
172
|
+
staleDe: staleDe.length,
|
|
173
|
+
embeddedEn,
|
|
174
|
+
embeddedDe,
|
|
175
|
+
errors,
|
|
176
|
+
};
|
|
117
177
|
},
|
|
118
178
|
});
|
|
119
179
|
//# sourceMappingURL=knowledgeSearch.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"knowledgeSearch.js","sourceRoot":"","sources":["../../src/component/knowledgeSearch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,CAAC,EAAE,MAAM,eAAe,CAAC;AAElC,MAAM,kBAAkB,GACtB,yDAAyD,CAAC;AAC5D,MAAM,eAAe,GAAG,aAAa,CAAC;AACtC,MAAM,oBAAoB,GAAG,IAAI,CAAC;AAElC,MAAM,oBAAoB,GAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"knowledgeSearch.js","sourceRoot":"","sources":["../../src/component/knowledgeSearch.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"potentialAnalysis.d.ts","sourceRoot":"","sources":["../../src/component/potentialAnalysis.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,4CAA4C;AAC5C,eAAO,MAAM,cAAc;;;;;;GAmBzB,CAAC;AAEH,6CAA6C;AAC7C,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAgEtB,CAAC;AAEH,kCAAkC;AAClC,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAqCoB,MAAM;YAAM,MAAM;aAAO,MAAM;;;;;;;UAqC/E,CAAC;AAIH,uCAAuC;AACvC,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;GA0C/B,CAAC;AAIH,oCAAoC;AACpC,eAAO,MAAM,mBAAmB;;;;;;;;GAoC9B,CAAC;AAEH,uCAAuC;AACvC,eAAO,MAAM,sBAAsB;;;;;iBAyBjC,CAAC;AAEH,uCAAuC;AACvC,eAAO,MAAM,sBAAsB;;iBAQjC,CAAC;AAIH,+BAA+B;AAC/B,eAAO,MAAM,mBAAmB;;;;;;;;GAuC9B,CAAC;AAEH,iCAAiC;AACjC,eAAO,MAAM,qBAAqB;;iBAQhC,CAAC;AAIH,4BAA4B;AAC5B,eAAO,MAAM,gBAAgB;;;;;;;GAwB3B,CAAC;AAEH,+BAA+B;AAC/B,eAAO,MAAM,mBAAmB;;iBAQ9B,CAAC;AAIH,4BAA4B;AAC5B,eAAO,MAAM,gBAAgB;;;;;;;;;;GAsC3B,CAAC;AAEH,+BAA+B;AAC/B,eAAO,MAAM,mBAAmB;;iBAc9B,CAAC;AAIH,gDAAgD;AAChD,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"potentialAnalysis.d.ts","sourceRoot":"","sources":["../../src/component/potentialAnalysis.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,4CAA4C;AAC5C,eAAO,MAAM,cAAc;;;;;;GAmBzB,CAAC;AAEH,6CAA6C;AAC7C,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAgEtB,CAAC;AAEH,kCAAkC;AAClC,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAqCoB,MAAM;YAAM,MAAM;aAAO,MAAM;;;;;;;UAqC/E,CAAC;AAIH,uCAAuC;AACvC,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;GA0C/B,CAAC;AAIH,oCAAoC;AACpC,eAAO,MAAM,mBAAmB;;;;;;;;GAoC9B,CAAC;AAEH,uCAAuC;AACvC,eAAO,MAAM,sBAAsB;;;;;iBAyBjC,CAAC;AAEH,uCAAuC;AACvC,eAAO,MAAM,sBAAsB;;iBAQjC,CAAC;AAIH,+BAA+B;AAC/B,eAAO,MAAM,mBAAmB;;;;;;;;GAuC9B,CAAC;AAEH,iCAAiC;AACjC,eAAO,MAAM,qBAAqB;;iBAQhC,CAAC;AAIH,4BAA4B;AAC5B,eAAO,MAAM,gBAAgB;;;;;;;GAwB3B,CAAC;AAEH,+BAA+B;AAC/B,eAAO,MAAM,mBAAmB;;iBAQ9B,CAAC;AAIH,4BAA4B;AAC5B,eAAO,MAAM,gBAAgB;;;;;;;;;;GAsC3B,CAAC;AAEH,+BAA+B;AAC/B,eAAO,MAAM,mBAAmB;;iBAc9B,CAAC;AAIH,gDAAgD;AAChD,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;GAgE7B,CAAC;AAIH,kCAAkC;AAClC,eAAO,MAAM,aAAa;;;;;;;GAiBxB,CAAC;AAEH,qCAAqC;AACrC,eAAO,MAAM,gBAAgB;;iBAQ3B,CAAC;AAEH,8BAA8B;AAC9B,eAAO,MAAM,cAAc;;;;;;;;;GAqBzB,CAAC;AAEH,iCAAiC;AACjC,eAAO,MAAM,iBAAiB;;iBAQ5B,CAAC;AAIH,gDAAgD;AAChD,eAAO,MAAM,yBAAyB;;;;;;GAkKpC,CAAC;AAIH,+CAA+C;AAC/C,eAAO,MAAM,WAAW;;;;;GAoEtB,CAAC;AAEH,oCAAoC;AACpC,eAAO,MAAM,YAAY;;;;;;;;;;;;KAQvB,CAAC;AAIH,gFAAgF;AAChF,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;UAwDhC,CAAC;AAEH,+EAA+E;AAC/E,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAgE5B,CAAC;AAEH,2DAA2D;AAC3D,eAAO,MAAM,qBAAqB;;;;YAkBc,MAAM;aAAO,MAAM;;;;;;;;;;;;;;;;UAcjE,CAAC;AAIH,kDAAkD;AAClD,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAsDY,MAAM;aAAO,MAAM;eAAS,MAAM;;;;;;;;;;;;;;;;UAqDtF,CAAC"}
|