@theromans/convex-dobty 0.1.15 → 0.1.17
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/component/knowledge.d.ts.map +1 -1
- package/dist/component/knowledge.js +10 -5
- package/dist/component/knowledge.js.map +1 -1
- package/dist/component/knowledgeSearch.d.ts +11 -1
- package/dist/component/knowledgeSearch.d.ts.map +1 -1
- package/dist/component/knowledgeSearch.js +47 -12
- package/dist/component/knowledgeSearch.js.map +1 -1
- package/package.json +1 -1
- package/src/component/knowledge.ts +10 -5
- package/src/component/knowledgeSearch.ts +49 -12
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"knowledge.d.ts","sourceRoot":"","sources":["../../src/component/knowledge.ts"],"names":[],"mappings":"AASA,oFAAoF;AACpF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"knowledge.d.ts","sourceRoot":"","sources":["../../src/component/knowledge.ts"],"names":[],"mappings":"AASA,oFAAoF;AACpF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;GAyF9B,CAAC;AAEH,wGAAwG;AACxG,eAAO,MAAM,oBAAoB;;;;GAgB/B,CAAC;AAEH,4BAA4B;AAC5B,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;KAQrB,CAAC;AAEH,qCAAqC;AACrC,eAAO,MAAM,UAAU,0EAOrB,CAAC;AAMH,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"}
|
|
@@ -36,10 +36,12 @@ export const seedKnowledgeChunks = mutation({
|
|
|
36
36
|
// Bump updatedAt — scheduler will detect embeddedAt < updatedAt and re-embed
|
|
37
37
|
updatedAt: Date.now(),
|
|
38
38
|
});
|
|
39
|
-
// Schedule EN embedding
|
|
40
|
-
|
|
39
|
+
// Schedule EN embedding via mutation→mutation→action chain.
|
|
40
|
+
// 10s delay lets vector indexes finish bootstrapping after a fresh deploy.
|
|
41
|
+
await ctx.scheduler.runAfter(0, internal.knowledgeSearch.scheduleEmbedChunk, {
|
|
41
42
|
chunkId: existing._id,
|
|
42
43
|
language: "en",
|
|
44
|
+
delayMs: 10_000,
|
|
43
45
|
});
|
|
44
46
|
updated++;
|
|
45
47
|
}
|
|
@@ -50,9 +52,10 @@ export const seedKnowledgeChunks = mutation({
|
|
|
50
52
|
!existing.embeddedAt_en ||
|
|
51
53
|
!existing.embeddedAt_de;
|
|
52
54
|
if (needsEmbed) {
|
|
53
|
-
await ctx.scheduler.runAfter(0, internal.knowledgeSearch.
|
|
55
|
+
await ctx.scheduler.runAfter(0, internal.knowledgeSearch.scheduleEmbedChunk, {
|
|
54
56
|
chunkId: existing._id,
|
|
55
57
|
language: "en",
|
|
58
|
+
delayMs: 10_000,
|
|
56
59
|
});
|
|
57
60
|
}
|
|
58
61
|
skipped++;
|
|
@@ -68,10 +71,12 @@ export const seedKnowledgeChunks = mutation({
|
|
|
68
71
|
content_Deutsch: chunk.content_Deutsch,
|
|
69
72
|
updatedAt: Date.now(),
|
|
70
73
|
});
|
|
71
|
-
// Schedule EN embedding
|
|
72
|
-
|
|
74
|
+
// Schedule EN embedding via mutation→mutation→action chain.
|
|
75
|
+
// 10s delay lets vector indexes finish bootstrapping after a fresh deploy.
|
|
76
|
+
await ctx.scheduler.runAfter(0, internal.knowledgeSearch.scheduleEmbedChunk, {
|
|
73
77
|
chunkId: id,
|
|
74
78
|
language: "en",
|
|
79
|
+
delayMs: 10_000,
|
|
75
80
|
});
|
|
76
81
|
inserted++;
|
|
77
82
|
}
|
|
@@ -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,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,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,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE;YACzB,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE;YACzB,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE;YAC3B,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE;SAC5B,CAAC,CACH;KACF;IACD,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QACjC,IAAI,QAAQ,GAAG,CAAC,CAAC;QACjB,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,IAAI,OAAO,GAAG,CAAC,CAAC;QAEhB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,EAAE;iBAC1B,KAAK,CAAC,iBAAiB,CAAC;iBACxB,SAAS,CAAC,mBAAmB,EAAE,CAAC,CAAC,EAAE,EAAE,CACpC,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,CAC1D;iBACA,MAAM,EAAE,CAAC;YAEZ,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,cAAc,GAClB,QAAQ,CAAC,eAAe,KAAK,KAAK,CAAC,eAAe;oBAClD,QAAQ,CAAC,eAAe,KAAK,KAAK,CAAC,eAAe;oBAClD,QAAQ,CAAC,aAAa,KAAK,KAAK,CAAC,aAAa;oBAC9C,QAAQ,CAAC,aAAa,KAAK,KAAK,CAAC,aAAa,CAAC;gBAEjD,IAAI,cAAc,EAAE,CAAC;oBACnB,MAAM,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE;wBAC/B,aAAa,EAAE,KAAK,CAAC,aAAa;wBAClC,aAAa,EAAE,KAAK,CAAC,aAAa;wBAClC,eAAe,EAAE,KAAK,CAAC,eAAe;wBACtC,eAAe,EAAE,KAAK,CAAC,eAAe;wBACtC,6EAA6E;wBAC7E,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;qBACtB,CAAC,CAAC;oBACH,
|
|
1
|
+
{"version":3,"file":"knowledge.js","sourceRoot":"","sources":["../../src/component/knowledge.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thin mutation that schedules an embedChunk action.
|
|
3
|
+
* Mutations can schedule actions; other mutations cannot call actions directly.
|
|
4
|
+
*/
|
|
5
|
+
export declare const scheduleEmbedChunk: import("convex/server").RegisteredMutation<"internal", {
|
|
6
|
+
delayMs?: number | undefined;
|
|
7
|
+
chunkId: import("convex/values").GenericId<"knowledgeChunks">;
|
|
8
|
+
language: "en" | "de";
|
|
9
|
+
}, Promise<void>>;
|
|
1
10
|
/**
|
|
2
11
|
* Embed a single chunk for a single language.
|
|
3
12
|
* Called by the scheduler after a chunk is seeded or updated.
|
|
4
|
-
*
|
|
13
|
+
* Retries on failure with a delay. Chains to the other language when done.
|
|
5
14
|
*/
|
|
6
15
|
export declare const embedChunk: import("convex/server").RegisteredAction<"internal", {
|
|
16
|
+
attempt?: number | undefined;
|
|
7
17
|
chunkId: import("convex/values").GenericId<"knowledgeChunks">;
|
|
8
18
|
language: "en" | "de";
|
|
9
19
|
}, Promise<void>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"knowledgeSearch.d.ts","sourceRoot":"","sources":["../../src/component/knowledgeSearch.ts"],"names":[],"mappings":"AA4CA;;;;GAIG;AACH,eAAO,MAAM,UAAU
|
|
1
|
+
{"version":3,"file":"knowledgeSearch.d.ts","sourceRoot":"","sources":["../../src/component/knowledgeSearch.ts"],"names":[],"mappings":"AA4CA;;;GAGG;AACH,eAAO,MAAM,kBAAkB;;;;iBAa7B,CAAC;AAKH;;;;GAIG;AACH,eAAO,MAAM,UAAU;;;;iBAuFrB,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,uBAAuB;;;GAoClC,CAAC;AAEH,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;;;;;GAKG;AACH,eAAO,MAAM,eAAe;;;;;;8BAY1B,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,cAAc;;;;;8BAUzB,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { internalAction, action } from "./_generated/server.js";
|
|
1
|
+
import { internalAction, internalMutation, action } from "./_generated/server.js";
|
|
2
2
|
import { internal } from "./_generated/api.js";
|
|
3
3
|
import { v } from "convex/values";
|
|
4
4
|
const EMBEDDING_ENDPOINT = "https://openai.inference.de-txl.ionos.com/v1/embeddings";
|
|
@@ -40,17 +40,38 @@ async function getEmbedding(text, apiToken) {
|
|
|
40
40
|
clearTimeout(timer);
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Thin mutation that schedules an embedChunk action.
|
|
45
|
+
* Mutations can schedule actions; other mutations cannot call actions directly.
|
|
46
|
+
*/
|
|
47
|
+
export const scheduleEmbedChunk = internalMutation({
|
|
48
|
+
args: {
|
|
49
|
+
chunkId: v.id("knowledgeChunks"),
|
|
50
|
+
language: v.union(v.literal("en"), v.literal("de")),
|
|
51
|
+
delayMs: v.optional(v.number()),
|
|
52
|
+
},
|
|
53
|
+
handler: async (ctx, { chunkId, language, delayMs = 10_000 }) => {
|
|
54
|
+
await ctx.scheduler.runAfter(delayMs, internal.knowledgeSearch.embedChunk, {
|
|
55
|
+
chunkId,
|
|
56
|
+
language,
|
|
57
|
+
attempt: 0,
|
|
58
|
+
});
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
const EMBED_RETRY_DELAY_MS = 30_000; // retry after 30s on transient failure
|
|
62
|
+
const EMBED_MAX_RETRIES = 5;
|
|
43
63
|
/**
|
|
44
64
|
* Embed a single chunk for a single language.
|
|
45
65
|
* Called by the scheduler after a chunk is seeded or updated.
|
|
46
|
-
*
|
|
66
|
+
* Retries on failure with a delay. Chains to the other language when done.
|
|
47
67
|
*/
|
|
48
68
|
export const embedChunk = internalAction({
|
|
49
69
|
args: {
|
|
50
70
|
chunkId: v.id("knowledgeChunks"),
|
|
51
71
|
language: v.union(v.literal("en"), v.literal("de")),
|
|
72
|
+
attempt: v.optional(v.number()),
|
|
52
73
|
},
|
|
53
|
-
handler: async (ctx, { chunkId, language }) => {
|
|
74
|
+
handler: async (ctx, { chunkId, language, attempt = 0 }) => {
|
|
54
75
|
const apiToken = globalThis.process?.env?.IONOS_API_TOKEN;
|
|
55
76
|
if (!apiToken) {
|
|
56
77
|
console.error("[embedChunk] IONOS_API_TOKEN not set — cannot embed");
|
|
@@ -68,14 +89,15 @@ export const embedChunk = internalAction({
|
|
|
68
89
|
!chunk.embeddedAt_de ||
|
|
69
90
|
chunk.embeddedAt_de < chunk.updatedAt;
|
|
70
91
|
const isStale = language === "en" ? isStaleEn : isStaleDe;
|
|
92
|
+
const otherLanguage = language === "en" ? "de" : "en";
|
|
93
|
+
const otherStale = language === "en" ? isStaleDe : isStaleEn;
|
|
71
94
|
if (!isStale) {
|
|
72
|
-
// Already up to date —
|
|
73
|
-
const otherLanguage = language === "en" ? "de" : "en";
|
|
74
|
-
const otherStale = language === "en" ? isStaleDe : isStaleEn;
|
|
95
|
+
// Already up to date — chain to other language if needed
|
|
75
96
|
if (otherStale) {
|
|
76
97
|
await ctx.scheduler.runAfter(0, internal.knowledgeSearch.embedChunk, {
|
|
77
98
|
chunkId,
|
|
78
99
|
language: otherLanguage,
|
|
100
|
+
attempt: 0,
|
|
79
101
|
});
|
|
80
102
|
}
|
|
81
103
|
return;
|
|
@@ -94,19 +116,31 @@ export const embedChunk = internalAction({
|
|
|
94
116
|
else {
|
|
95
117
|
await ctx.runMutation(internal.knowledge.updateEmbeddingDe, { chunkId, embedding });
|
|
96
118
|
}
|
|
97
|
-
console.log(`[embedChunk]
|
|
98
|
-
//
|
|
99
|
-
const otherLanguage = language === "en" ? "de" : "en";
|
|
100
|
-
const otherStale = language === "en" ? isStaleDe : isStaleEn;
|
|
119
|
+
console.log(`[embedChunk] ✓ ${chunk.chunkKey} (${language})`);
|
|
120
|
+
// Chain to the other language if also stale
|
|
101
121
|
if (otherStale) {
|
|
102
122
|
await ctx.scheduler.runAfter(0, internal.knowledgeSearch.embedChunk, {
|
|
103
123
|
chunkId,
|
|
104
124
|
language: otherLanguage,
|
|
125
|
+
attempt: 0,
|
|
105
126
|
});
|
|
106
127
|
}
|
|
107
128
|
}
|
|
108
129
|
catch (e) {
|
|
109
|
-
console.error(`[embedChunk] failed
|
|
130
|
+
console.error(`[embedChunk] failed ${chunk.chunkKey} (${language}) attempt ${attempt}: ${e.message}`);
|
|
131
|
+
if (attempt < EMBED_MAX_RETRIES) {
|
|
132
|
+
// Exponential backoff: 30s, 60s, 120s, 240s, 480s
|
|
133
|
+
const delay = EMBED_RETRY_DELAY_MS * Math.pow(2, attempt);
|
|
134
|
+
console.log(`[embedChunk] retrying in ${delay / 1000}s (attempt ${attempt + 1}/${EMBED_MAX_RETRIES})`);
|
|
135
|
+
await ctx.scheduler.runAfter(delay, internal.knowledgeSearch.embedChunk, {
|
|
136
|
+
chunkId,
|
|
137
|
+
language,
|
|
138
|
+
attempt: attempt + 1,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
console.error(`[embedChunk] giving up on ${chunk.chunkKey} (${language}) after ${EMBED_MAX_RETRIES} attempts`);
|
|
143
|
+
}
|
|
110
144
|
}
|
|
111
145
|
},
|
|
112
146
|
});
|
|
@@ -131,14 +165,15 @@ export const scheduleStaleEmbeddings = internalAction({
|
|
|
131
165
|
await ctx.scheduler.runAfter(0, internal.knowledgeSearch.embedChunk, {
|
|
132
166
|
chunkId: chunk._id,
|
|
133
167
|
language: "en",
|
|
168
|
+
attempt: 0,
|
|
134
169
|
});
|
|
135
170
|
scheduled++;
|
|
136
171
|
}
|
|
137
172
|
else if (staleDe) {
|
|
138
|
-
// embedChunk for EN will chain to DE when EN is already fresh
|
|
139
173
|
await ctx.scheduler.runAfter(0, internal.knowledgeSearch.embedChunk, {
|
|
140
174
|
chunkId: chunk._id,
|
|
141
175
|
language: "de",
|
|
176
|
+
attempt: 0,
|
|
142
177
|
});
|
|
143
178
|
scheduled++;
|
|
144
179
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"knowledgeSearch.js","sourceRoot":"","sources":["../../src/component/knowledgeSearch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"knowledgeSearch.js","sourceRoot":"","sources":["../../src/component/knowledgeSearch.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -50,10 +50,12 @@ export const seedKnowledgeChunks = mutation({
|
|
|
50
50
|
// Bump updatedAt — scheduler will detect embeddedAt < updatedAt and re-embed
|
|
51
51
|
updatedAt: Date.now(),
|
|
52
52
|
});
|
|
53
|
-
// Schedule EN embedding
|
|
54
|
-
|
|
53
|
+
// Schedule EN embedding via mutation→mutation→action chain.
|
|
54
|
+
// 10s delay lets vector indexes finish bootstrapping after a fresh deploy.
|
|
55
|
+
await ctx.scheduler.runAfter(0, internal.knowledgeSearch.scheduleEmbedChunk, {
|
|
55
56
|
chunkId: existing._id,
|
|
56
57
|
language: "en",
|
|
58
|
+
delayMs: 10_000,
|
|
57
59
|
});
|
|
58
60
|
updated++;
|
|
59
61
|
} else {
|
|
@@ -64,9 +66,10 @@ export const seedKnowledgeChunks = mutation({
|
|
|
64
66
|
!existing.embeddedAt_en ||
|
|
65
67
|
!existing.embeddedAt_de;
|
|
66
68
|
if (needsEmbed) {
|
|
67
|
-
await ctx.scheduler.runAfter(0, internal.knowledgeSearch.
|
|
69
|
+
await ctx.scheduler.runAfter(0, internal.knowledgeSearch.scheduleEmbedChunk, {
|
|
68
70
|
chunkId: existing._id,
|
|
69
71
|
language: "en",
|
|
72
|
+
delayMs: 10_000,
|
|
70
73
|
});
|
|
71
74
|
}
|
|
72
75
|
skipped++;
|
|
@@ -81,10 +84,12 @@ export const seedKnowledgeChunks = mutation({
|
|
|
81
84
|
content_Deutsch: chunk.content_Deutsch,
|
|
82
85
|
updatedAt: Date.now(),
|
|
83
86
|
});
|
|
84
|
-
// Schedule EN embedding
|
|
85
|
-
|
|
87
|
+
// Schedule EN embedding via mutation→mutation→action chain.
|
|
88
|
+
// 10s delay lets vector indexes finish bootstrapping after a fresh deploy.
|
|
89
|
+
await ctx.scheduler.runAfter(0, internal.knowledgeSearch.scheduleEmbedChunk, {
|
|
86
90
|
chunkId: id,
|
|
87
91
|
language: "en",
|
|
92
|
+
delayMs: 10_000,
|
|
88
93
|
});
|
|
89
94
|
inserted++;
|
|
90
95
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { internalAction, internalMutation, action } from "./_generated/server.js";
|
|
1
|
+
import { internalAction, internalMutation, action, mutation } from "./_generated/server.js";
|
|
2
2
|
import { internal } from "./_generated/api.js";
|
|
3
3
|
import { v } from "convex/values";
|
|
4
4
|
|
|
@@ -42,17 +42,40 @@ async function getEmbedding(text: string, apiToken: string): Promise<number[]> {
|
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
/**
|
|
46
|
+
* Thin mutation that schedules an embedChunk action.
|
|
47
|
+
* Mutations can schedule actions; other mutations cannot call actions directly.
|
|
48
|
+
*/
|
|
49
|
+
export const scheduleEmbedChunk = internalMutation({
|
|
50
|
+
args: {
|
|
51
|
+
chunkId: v.id("knowledgeChunks"),
|
|
52
|
+
language: v.union(v.literal("en"), v.literal("de")),
|
|
53
|
+
delayMs: v.optional(v.number()),
|
|
54
|
+
},
|
|
55
|
+
handler: async (ctx, { chunkId, language, delayMs = 10_000 }) => {
|
|
56
|
+
await ctx.scheduler.runAfter(delayMs, internal.knowledgeSearch.embedChunk, {
|
|
57
|
+
chunkId,
|
|
58
|
+
language,
|
|
59
|
+
attempt: 0,
|
|
60
|
+
});
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const EMBED_RETRY_DELAY_MS = 30_000; // retry after 30s on transient failure
|
|
65
|
+
const EMBED_MAX_RETRIES = 5;
|
|
66
|
+
|
|
45
67
|
/**
|
|
46
68
|
* Embed a single chunk for a single language.
|
|
47
69
|
* Called by the scheduler after a chunk is seeded or updated.
|
|
48
|
-
*
|
|
70
|
+
* Retries on failure with a delay. Chains to the other language when done.
|
|
49
71
|
*/
|
|
50
72
|
export const embedChunk = internalAction({
|
|
51
73
|
args: {
|
|
52
74
|
chunkId: v.id("knowledgeChunks"),
|
|
53
75
|
language: v.union(v.literal("en"), v.literal("de")),
|
|
76
|
+
attempt: v.optional(v.number()),
|
|
54
77
|
},
|
|
55
|
-
handler: async (ctx, { chunkId, language }) => {
|
|
78
|
+
handler: async (ctx, { chunkId, language, attempt = 0 }) => {
|
|
56
79
|
const apiToken = (globalThis as any).process?.env?.IONOS_API_TOKEN as string | undefined;
|
|
57
80
|
if (!apiToken) {
|
|
58
81
|
console.error("[embedChunk] IONOS_API_TOKEN not set — cannot embed");
|
|
@@ -75,14 +98,16 @@ export const embedChunk = internalAction({
|
|
|
75
98
|
chunk.embeddedAt_de < chunk.updatedAt;
|
|
76
99
|
|
|
77
100
|
const isStale = language === "en" ? isStaleEn : isStaleDe;
|
|
101
|
+
const otherLanguage: "en" | "de" = language === "en" ? "de" : "en";
|
|
102
|
+
const otherStale = language === "en" ? isStaleDe : isStaleEn;
|
|
103
|
+
|
|
78
104
|
if (!isStale) {
|
|
79
|
-
// Already up to date —
|
|
80
|
-
const otherLanguage = language === "en" ? "de" : "en";
|
|
81
|
-
const otherStale = language === "en" ? isStaleDe : isStaleEn;
|
|
105
|
+
// Already up to date — chain to other language if needed
|
|
82
106
|
if (otherStale) {
|
|
83
107
|
await ctx.scheduler.runAfter(0, internal.knowledgeSearch.embedChunk, {
|
|
84
108
|
chunkId,
|
|
85
109
|
language: otherLanguage,
|
|
110
|
+
attempt: 0,
|
|
86
111
|
});
|
|
87
112
|
}
|
|
88
113
|
return;
|
|
@@ -105,19 +130,30 @@ export const embedChunk = internalAction({
|
|
|
105
130
|
await ctx.runMutation(internal.knowledge.updateEmbeddingDe, { chunkId, embedding });
|
|
106
131
|
}
|
|
107
132
|
|
|
108
|
-
console.log(`[embedChunk]
|
|
133
|
+
console.log(`[embedChunk] ✓ ${chunk.chunkKey} (${language})`);
|
|
109
134
|
|
|
110
|
-
//
|
|
111
|
-
const otherLanguage = language === "en" ? "de" : "en";
|
|
112
|
-
const otherStale = language === "en" ? isStaleDe : isStaleEn;
|
|
135
|
+
// Chain to the other language if also stale
|
|
113
136
|
if (otherStale) {
|
|
114
137
|
await ctx.scheduler.runAfter(0, internal.knowledgeSearch.embedChunk, {
|
|
115
138
|
chunkId,
|
|
116
139
|
language: otherLanguage,
|
|
140
|
+
attempt: 0,
|
|
117
141
|
});
|
|
118
142
|
}
|
|
119
143
|
} catch (e: any) {
|
|
120
|
-
console.error(`[embedChunk] failed
|
|
144
|
+
console.error(`[embedChunk] failed ${chunk.chunkKey} (${language}) attempt ${attempt}: ${e.message}`);
|
|
145
|
+
if (attempt < EMBED_MAX_RETRIES) {
|
|
146
|
+
// Exponential backoff: 30s, 60s, 120s, 240s, 480s
|
|
147
|
+
const delay = EMBED_RETRY_DELAY_MS * Math.pow(2, attempt);
|
|
148
|
+
console.log(`[embedChunk] retrying in ${delay / 1000}s (attempt ${attempt + 1}/${EMBED_MAX_RETRIES})`);
|
|
149
|
+
await ctx.scheduler.runAfter(delay, internal.knowledgeSearch.embedChunk, {
|
|
150
|
+
chunkId,
|
|
151
|
+
language,
|
|
152
|
+
attempt: attempt + 1,
|
|
153
|
+
});
|
|
154
|
+
} else {
|
|
155
|
+
console.error(`[embedChunk] giving up on ${chunk.chunkKey} (${language}) after ${EMBED_MAX_RETRIES} attempts`);
|
|
156
|
+
}
|
|
121
157
|
}
|
|
122
158
|
},
|
|
123
159
|
});
|
|
@@ -147,13 +183,14 @@ export const scheduleStaleEmbeddings = internalAction({
|
|
|
147
183
|
await ctx.scheduler.runAfter(0, internal.knowledgeSearch.embedChunk, {
|
|
148
184
|
chunkId: chunk._id,
|
|
149
185
|
language: "en",
|
|
186
|
+
attempt: 0,
|
|
150
187
|
});
|
|
151
188
|
scheduled++;
|
|
152
189
|
} else if (staleDe) {
|
|
153
|
-
// embedChunk for EN will chain to DE when EN is already fresh
|
|
154
190
|
await ctx.scheduler.runAfter(0, internal.knowledgeSearch.embedChunk, {
|
|
155
191
|
chunkId: chunk._id,
|
|
156
192
|
language: "de",
|
|
193
|
+
attempt: 0,
|
|
157
194
|
});
|
|
158
195
|
scheduled++;
|
|
159
196
|
}
|