@tienne/gestalt 0.26.0 → 0.27.0
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/README.md +110 -58
- package/dist/package.json +2 -1
- package/dist/src/code-graph/providers/local-embedding.d.ts +1 -1
- package/dist/src/code-graph/providers/local-embedding.d.ts.map +1 -1
- package/dist/src/code-graph/providers/local-embedding.js +11 -5
- package/dist/src/code-graph/providers/local-embedding.js.map +1 -1
- package/dist/src/gestalt/analyzer.d.ts.map +1 -1
- package/dist/src/gestalt/analyzer.js +10 -10
- package/dist/src/gestalt/analyzer.js.map +1 -1
- package/dist/src/graph-viz/evolution-html-generator.d.ts +7 -0
- package/dist/src/graph-viz/evolution-html-generator.d.ts.map +1 -0
- package/dist/src/graph-viz/evolution-html-generator.js +360 -0
- package/dist/src/graph-viz/evolution-html-generator.js.map +1 -0
- package/dist/src/knowledge-base/embedding.d.ts +4 -3
- package/dist/src/knowledge-base/embedding.d.ts.map +1 -1
- package/dist/src/knowledge-base/embedding.js +17 -9
- package/dist/src/knowledge-base/embedding.js.map +1 -1
- package/dist/src/llm/factory.d.ts +6 -0
- package/dist/src/llm/factory.d.ts.map +1 -1
- package/dist/src/llm/factory.js +19 -4
- package/dist/src/llm/factory.js.map +1 -1
- package/dist/src/llm/fallback-adapter.d.ts +7 -0
- package/dist/src/llm/fallback-adapter.d.ts.map +1 -0
- package/dist/src/llm/fallback-adapter.js +23 -0
- package/dist/src/llm/fallback-adapter.js.map +1 -0
- package/dist/src/llm/retry-adapter.d.ts +9 -0
- package/dist/src/llm/retry-adapter.d.ts.map +1 -0
- package/dist/src/llm/retry-adapter.js +43 -0
- package/dist/src/llm/retry-adapter.js.map +1 -0
- package/dist/src/mcp/schemas.d.ts +4 -4
- package/dist/src/mcp/schemas.d.ts.map +1 -1
- package/dist/src/mcp/schemas.js +1 -0
- package/dist/src/mcp/schemas.js.map +1 -1
- package/dist/src/mcp/tools/execute/utility.d.ts +1 -0
- package/dist/src/mcp/tools/execute/utility.d.ts.map +1 -1
- package/dist/src/mcp/tools/execute/utility.js +30 -1
- package/dist/src/mcp/tools/execute/utility.js.map +1 -1
- package/dist/src/mcp/tools/execute-passthrough.d.ts.map +1 -1
- package/dist/src/mcp/tools/execute-passthrough.js +2 -1
- package/dist/src/mcp/tools/execute-passthrough.js.map +1 -1
- package/dist/src/mcp/tools/generate-kb.d.ts.map +1 -1
- package/dist/src/mcp/tools/generate-kb.js +5 -3
- package/dist/src/mcp/tools/generate-kb.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates a self-contained HTML page visualizing the evolution history of an execute session.
|
|
3
|
+
* Uses Chart.js CDN for line charts showing evaluationScore and goalAlignment per generation.
|
|
4
|
+
*/
|
|
5
|
+
export function generateEvolutionHtml(session) {
|
|
6
|
+
const history = session.evolutionHistory;
|
|
7
|
+
if (history.length === 0) {
|
|
8
|
+
return `<!DOCTYPE html>
|
|
9
|
+
<html lang="en">
|
|
10
|
+
<head>
|
|
11
|
+
<meta charset="UTF-8" />
|
|
12
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
13
|
+
<title>Gestalt Evolution Visualization</title>
|
|
14
|
+
<style>
|
|
15
|
+
body {
|
|
16
|
+
background: #0d1117;
|
|
17
|
+
color: #e6edf3;
|
|
18
|
+
font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
|
|
19
|
+
display: flex;
|
|
20
|
+
align-items: center;
|
|
21
|
+
justify-content: center;
|
|
22
|
+
height: 100vh;
|
|
23
|
+
margin: 0;
|
|
24
|
+
}
|
|
25
|
+
.empty-state {
|
|
26
|
+
text-align: center;
|
|
27
|
+
color: #8b949e;
|
|
28
|
+
}
|
|
29
|
+
.empty-state h2 {
|
|
30
|
+
font-size: 20px;
|
|
31
|
+
margin-bottom: 8px;
|
|
32
|
+
color: #e6edf3;
|
|
33
|
+
}
|
|
34
|
+
</style>
|
|
35
|
+
</head>
|
|
36
|
+
<body>
|
|
37
|
+
<div class="empty-state">
|
|
38
|
+
<h2>No evolution data</h2>
|
|
39
|
+
<p>Session <code>${session.sessionId}</code> has not entered the evolution loop yet.</p>
|
|
40
|
+
</div>
|
|
41
|
+
</body>
|
|
42
|
+
</html>`;
|
|
43
|
+
}
|
|
44
|
+
const labels = history.map((g) => `Gen ${g.generation}`);
|
|
45
|
+
const evaluationScores = history.map((g) => g.evaluationScore);
|
|
46
|
+
const goalAlignments = history.map((g) => g.goalAlignment);
|
|
47
|
+
const labelsJson = JSON.stringify(labels);
|
|
48
|
+
const evalScoresJson = JSON.stringify(evaluationScores);
|
|
49
|
+
const goalAlignJson = JSON.stringify(goalAlignments);
|
|
50
|
+
const lastGen = history[history.length - 1];
|
|
51
|
+
const finalScore = lastGen.evaluationScore;
|
|
52
|
+
const triedPersonas = session.lateralTriedPersonas;
|
|
53
|
+
const terminationReason = session.terminationReason ?? null;
|
|
54
|
+
return `<!DOCTYPE html>
|
|
55
|
+
<html lang="en">
|
|
56
|
+
<head>
|
|
57
|
+
<meta charset="UTF-8" />
|
|
58
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
59
|
+
<title>Gestalt Evolution Visualization — ${session.sessionId}</title>
|
|
60
|
+
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
61
|
+
<style>
|
|
62
|
+
*, *::before, *::after {
|
|
63
|
+
box-sizing: border-box;
|
|
64
|
+
margin: 0;
|
|
65
|
+
padding: 0;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
body {
|
|
69
|
+
background: #0d1117;
|
|
70
|
+
color: #e6edf3;
|
|
71
|
+
font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
|
|
72
|
+
min-height: 100vh;
|
|
73
|
+
padding: 32px;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
h1 {
|
|
77
|
+
font-size: 20px;
|
|
78
|
+
font-weight: 700;
|
|
79
|
+
margin-bottom: 4px;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.subtitle {
|
|
83
|
+
font-size: 13px;
|
|
84
|
+
color: #8b949e;
|
|
85
|
+
margin-bottom: 32px;
|
|
86
|
+
font-family: 'JetBrains Mono', 'Fira Code', monospace;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.layout {
|
|
90
|
+
display: grid;
|
|
91
|
+
grid-template-columns: 1fr 300px;
|
|
92
|
+
gap: 24px;
|
|
93
|
+
align-items: start;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.chart-card {
|
|
97
|
+
background: #161b22;
|
|
98
|
+
border: 1px solid #30363d;
|
|
99
|
+
border-radius: 12px;
|
|
100
|
+
padding: 24px;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.chart-card h2 {
|
|
104
|
+
font-size: 14px;
|
|
105
|
+
font-weight: 600;
|
|
106
|
+
color: #8b949e;
|
|
107
|
+
text-transform: uppercase;
|
|
108
|
+
letter-spacing: 0.05em;
|
|
109
|
+
margin-bottom: 16px;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.chart-container {
|
|
113
|
+
position: relative;
|
|
114
|
+
height: 320px;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.summary-card {
|
|
118
|
+
background: #161b22;
|
|
119
|
+
border: 1px solid #30363d;
|
|
120
|
+
border-radius: 12px;
|
|
121
|
+
padding: 24px;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.summary-card h2 {
|
|
125
|
+
font-size: 14px;
|
|
126
|
+
font-weight: 600;
|
|
127
|
+
color: #8b949e;
|
|
128
|
+
text-transform: uppercase;
|
|
129
|
+
letter-spacing: 0.05em;
|
|
130
|
+
margin-bottom: 20px;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.stat-row {
|
|
134
|
+
margin-bottom: 16px;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.stat-label {
|
|
138
|
+
font-size: 10px;
|
|
139
|
+
font-weight: 600;
|
|
140
|
+
color: #8b949e;
|
|
141
|
+
text-transform: uppercase;
|
|
142
|
+
letter-spacing: 0.07em;
|
|
143
|
+
margin-bottom: 4px;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.stat-value {
|
|
147
|
+
font-size: 15px;
|
|
148
|
+
color: #e6edf3;
|
|
149
|
+
font-weight: 600;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.stat-value.score {
|
|
153
|
+
font-size: 24px;
|
|
154
|
+
color: #3b82f6;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.badge {
|
|
158
|
+
display: inline-block;
|
|
159
|
+
padding: 2px 8px;
|
|
160
|
+
border-radius: 999px;
|
|
161
|
+
font-size: 11px;
|
|
162
|
+
font-weight: 600;
|
|
163
|
+
margin-bottom: 4px;
|
|
164
|
+
margin-right: 4px;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.badge-persona {
|
|
168
|
+
background: #1f4068;
|
|
169
|
+
color: #58a6ff;
|
|
170
|
+
border: 1px solid #388bfd40;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.badge-termination {
|
|
174
|
+
background: #3d2000;
|
|
175
|
+
color: #f0883e;
|
|
176
|
+
border: 1px solid #f0883e40;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
.badge-success {
|
|
180
|
+
background: #1a3a1a;
|
|
181
|
+
color: #3fb950;
|
|
182
|
+
border: 1px solid #3fb95040;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.legend {
|
|
186
|
+
display: flex;
|
|
187
|
+
gap: 20px;
|
|
188
|
+
margin-top: 12px;
|
|
189
|
+
font-size: 12px;
|
|
190
|
+
color: #8b949e;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
.legend-item {
|
|
194
|
+
display: flex;
|
|
195
|
+
align-items: center;
|
|
196
|
+
gap: 6px;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.legend-dot {
|
|
200
|
+
width: 12px;
|
|
201
|
+
height: 3px;
|
|
202
|
+
border-radius: 2px;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
@media (max-width: 768px) {
|
|
206
|
+
.layout {
|
|
207
|
+
grid-template-columns: 1fr;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
</style>
|
|
211
|
+
</head>
|
|
212
|
+
<body>
|
|
213
|
+
<h1>Evolution Visualization</h1>
|
|
214
|
+
<div class="subtitle">Session: ${session.sessionId}</div>
|
|
215
|
+
|
|
216
|
+
<div class="layout">
|
|
217
|
+
<div class="chart-card">
|
|
218
|
+
<h2>Score per Generation</h2>
|
|
219
|
+
<div class="chart-container">
|
|
220
|
+
<canvas id="evolutionChart"></canvas>
|
|
221
|
+
</div>
|
|
222
|
+
<div class="legend">
|
|
223
|
+
<div class="legend-item">
|
|
224
|
+
<div class="legend-dot" style="background:#3b82f6;"></div>
|
|
225
|
+
Evaluation Score
|
|
226
|
+
</div>
|
|
227
|
+
<div class="legend-item">
|
|
228
|
+
<div class="legend-dot" style="background:#22c55e;"></div>
|
|
229
|
+
Goal Alignment
|
|
230
|
+
</div>
|
|
231
|
+
</div>
|
|
232
|
+
</div>
|
|
233
|
+
|
|
234
|
+
<div class="summary-card">
|
|
235
|
+
<h2>Summary</h2>
|
|
236
|
+
|
|
237
|
+
<div class="stat-row">
|
|
238
|
+
<div class="stat-label">Total Generations</div>
|
|
239
|
+
<div class="stat-value">${history.length}</div>
|
|
240
|
+
</div>
|
|
241
|
+
|
|
242
|
+
<div class="stat-row">
|
|
243
|
+
<div class="stat-label">Current Generation</div>
|
|
244
|
+
<div class="stat-value">${session.currentGeneration}</div>
|
|
245
|
+
</div>
|
|
246
|
+
|
|
247
|
+
<div class="stat-row">
|
|
248
|
+
<div class="stat-label">Final Eval Score</div>
|
|
249
|
+
<div class="stat-value score">${finalScore.toFixed(3)}</div>
|
|
250
|
+
</div>
|
|
251
|
+
|
|
252
|
+
<div class="stat-row">
|
|
253
|
+
<div class="stat-label">Tried Personas</div>
|
|
254
|
+
<div class="stat-value">
|
|
255
|
+
${triedPersonas.length > 0
|
|
256
|
+
? triedPersonas.map((p) => `<span class="badge badge-persona">${p}</span>`).join('')
|
|
257
|
+
: '<span style="color:#484f58;font-size:13px;">none</span>'}
|
|
258
|
+
</div>
|
|
259
|
+
</div>
|
|
260
|
+
|
|
261
|
+
<div class="stat-row">
|
|
262
|
+
<div class="stat-label">Termination Reason</div>
|
|
263
|
+
<div class="stat-value">
|
|
264
|
+
${terminationReason
|
|
265
|
+
? terminationReason === 'success'
|
|
266
|
+
? `<span class="badge badge-success">${terminationReason}</span>`
|
|
267
|
+
: `<span class="badge badge-termination">${terminationReason}</span>`
|
|
268
|
+
: '<span style="color:#484f58;font-size:13px;">in progress</span>'}
|
|
269
|
+
</div>
|
|
270
|
+
</div>
|
|
271
|
+
</div>
|
|
272
|
+
</div>
|
|
273
|
+
|
|
274
|
+
<script>
|
|
275
|
+
(function () {
|
|
276
|
+
'use strict';
|
|
277
|
+
|
|
278
|
+
const labels = ${labelsJson};
|
|
279
|
+
const evalScores = ${evalScoresJson};
|
|
280
|
+
const goalAlignments = ${goalAlignJson};
|
|
281
|
+
|
|
282
|
+
const ctx = document.getElementById('evolutionChart').getContext('2d');
|
|
283
|
+
|
|
284
|
+
new Chart(ctx, {
|
|
285
|
+
type: 'line',
|
|
286
|
+
data: {
|
|
287
|
+
labels: labels,
|
|
288
|
+
datasets: [
|
|
289
|
+
{
|
|
290
|
+
label: 'Evaluation Score',
|
|
291
|
+
data: evalScores,
|
|
292
|
+
borderColor: '#3b82f6',
|
|
293
|
+
backgroundColor: 'rgba(59, 130, 246, 0.08)',
|
|
294
|
+
borderWidth: 2,
|
|
295
|
+
pointBackgroundColor: '#3b82f6',
|
|
296
|
+
pointRadius: 4,
|
|
297
|
+
pointHoverRadius: 6,
|
|
298
|
+
fill: true,
|
|
299
|
+
tension: 0.3,
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
label: 'Goal Alignment',
|
|
303
|
+
data: goalAlignments,
|
|
304
|
+
borderColor: '#22c55e',
|
|
305
|
+
backgroundColor: 'rgba(34, 197, 94, 0.08)',
|
|
306
|
+
borderWidth: 2,
|
|
307
|
+
pointBackgroundColor: '#22c55e',
|
|
308
|
+
pointRadius: 4,
|
|
309
|
+
pointHoverRadius: 6,
|
|
310
|
+
fill: true,
|
|
311
|
+
tension: 0.3,
|
|
312
|
+
},
|
|
313
|
+
],
|
|
314
|
+
},
|
|
315
|
+
options: {
|
|
316
|
+
responsive: true,
|
|
317
|
+
maintainAspectRatio: false,
|
|
318
|
+
scales: {
|
|
319
|
+
x: {
|
|
320
|
+
ticks: {
|
|
321
|
+
color: '#8b949e',
|
|
322
|
+
font: { size: 11 },
|
|
323
|
+
},
|
|
324
|
+
grid: {
|
|
325
|
+
color: '#21262d',
|
|
326
|
+
},
|
|
327
|
+
},
|
|
328
|
+
y: {
|
|
329
|
+
min: 0,
|
|
330
|
+
max: 1,
|
|
331
|
+
ticks: {
|
|
332
|
+
color: '#8b949e',
|
|
333
|
+
font: { size: 11 },
|
|
334
|
+
stepSize: 0.2,
|
|
335
|
+
},
|
|
336
|
+
grid: {
|
|
337
|
+
color: '#21262d',
|
|
338
|
+
},
|
|
339
|
+
},
|
|
340
|
+
},
|
|
341
|
+
plugins: {
|
|
342
|
+
legend: {
|
|
343
|
+
display: false,
|
|
344
|
+
},
|
|
345
|
+
tooltip: {
|
|
346
|
+
backgroundColor: '#161b22',
|
|
347
|
+
borderColor: '#30363d',
|
|
348
|
+
borderWidth: 1,
|
|
349
|
+
titleColor: '#e6edf3',
|
|
350
|
+
bodyColor: '#8b949e',
|
|
351
|
+
},
|
|
352
|
+
},
|
|
353
|
+
},
|
|
354
|
+
});
|
|
355
|
+
})();
|
|
356
|
+
</script>
|
|
357
|
+
</body>
|
|
358
|
+
</html>`;
|
|
359
|
+
}
|
|
360
|
+
//# sourceMappingURL=evolution-html-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evolution-html-generator.js","sourceRoot":"","sources":["../../../src/graph-viz/evolution-html-generator.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAuB;IAC3D,MAAM,OAAO,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAEzC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uBA+BY,OAAO,CAAC,SAAS;;;QAGhC,CAAC;IACP,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;IACzD,MAAM,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;IAC/D,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;IAE3D,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IACxD,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAErD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC;IAC7C,MAAM,UAAU,GAAG,OAAO,CAAC,eAAe,CAAC;IAC3C,MAAM,aAAa,GAAG,OAAO,CAAC,oBAAoB,CAAC;IACnD,MAAM,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,IAAI,IAAI,CAAC;IAE5D,OAAO;;;;;6CAKoC,OAAO,CAAC,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mCA2J3B,OAAO,CAAC,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;kCAyBlB,OAAO,CAAC,MAAM;;;;;kCAKd,OAAO,CAAC,iBAAiB;;;;;wCAKnB,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;;;;;;YAOjD,aAAa,CAAC,MAAM,GAAG,CAAC;QACtB,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,qCAAqC,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;QACpF,CAAC,CAAC,yDACN;;;;;;;YAQE,iBAAiB;QACf,CAAC,CAAC,iBAAiB,KAAK,SAAS;YAC/B,CAAC,CAAC,qCAAqC,iBAAiB,SAAS;YACjE,CAAC,CAAC,yCAAyC,iBAAiB,SAAS;QACvE,CAAC,CAAC,gEACN;;;;;;;;;;qBAUW,UAAU;yBACN,cAAc;6BACV,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA8ElC,CAAC;AACT,CAAC"}
|
|
@@ -8,12 +8,13 @@ export declare class EmbeddingService {
|
|
|
8
8
|
private getPipeline;
|
|
9
9
|
/**
|
|
10
10
|
* 텍스트 하나를 임베딩 벡터로 변환한다.
|
|
11
|
-
*
|
|
11
|
+
* embedBatch에 위임한다.
|
|
12
12
|
*/
|
|
13
13
|
embed(text: string): Promise<number[]>;
|
|
14
14
|
/**
|
|
15
|
-
* 텍스트 배열을
|
|
15
|
+
* 텍스트 배열을 batchSize 단위로 청크 처리한다.
|
|
16
|
+
* mean pooling + normalize 옵션을 사용해 384차원 number[][] 를 반환한다.
|
|
16
17
|
*/
|
|
17
|
-
embedBatch(texts: string[]): Promise<number[][]>;
|
|
18
|
+
embedBatch(texts: string[], batchSize?: number): Promise<number[][]>;
|
|
18
19
|
}
|
|
19
20
|
//# sourceMappingURL=embedding.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embedding.d.ts","sourceRoot":"","sources":["../../../src/knowledge-base/embedding.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,gBAAgB,CAA0C;IAClE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA6B;YAEzC,WAAW;IASzB;;;OAGG;IACG,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"embedding.d.ts","sourceRoot":"","sources":["../../../src/knowledge-base/embedding.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,gBAAgB,CAA0C;IAClE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA6B;YAEzC,WAAW;IASzB;;;OAGG;IACG,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAK5C;;;OAGG;IACG,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,SAAS,SAAK,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;CAevE"}
|
|
@@ -17,21 +17,29 @@ export class EmbeddingService {
|
|
|
17
17
|
}
|
|
18
18
|
/**
|
|
19
19
|
* 텍스트 하나를 임베딩 벡터로 변환한다.
|
|
20
|
-
*
|
|
20
|
+
* embedBatch에 위임한다.
|
|
21
21
|
*/
|
|
22
22
|
async embed(text) {
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
return Array.from(output.data);
|
|
23
|
+
const results = await this.embedBatch([text]);
|
|
24
|
+
return results[0] ?? [];
|
|
26
25
|
}
|
|
27
26
|
/**
|
|
28
|
-
* 텍스트 배열을
|
|
27
|
+
* 텍스트 배열을 batchSize 단위로 청크 처리한다.
|
|
28
|
+
* mean pooling + normalize 옵션을 사용해 384차원 number[][] 를 반환한다.
|
|
29
29
|
*/
|
|
30
|
-
async embedBatch(texts) {
|
|
30
|
+
async embedBatch(texts, batchSize = 32) {
|
|
31
|
+
if (texts.length === 0)
|
|
32
|
+
return [];
|
|
33
|
+
const extractor = await this.getPipeline();
|
|
31
34
|
const results = [];
|
|
32
|
-
for (
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
+
for (let i = 0; i < texts.length; i += batchSize) {
|
|
36
|
+
const chunk = texts.slice(i, i + batchSize);
|
|
37
|
+
const output = (await extractor(chunk, { pooling: 'mean', normalize: true }));
|
|
38
|
+
const flat = output.data;
|
|
39
|
+
const dim = flat.length / chunk.length;
|
|
40
|
+
for (let j = 0; j < chunk.length; j++) {
|
|
41
|
+
results.push(Array.from(flat.slice(j * dim, (j + 1) * dim)));
|
|
42
|
+
}
|
|
35
43
|
}
|
|
36
44
|
return results;
|
|
37
45
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embedding.js","sourceRoot":"","sources":["../../../src/knowledge-base/embedding.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAqC,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAErC;;;GAGG;AACH,MAAM,OAAO,gBAAgB;IACnB,gBAAgB,GAAqC,IAAI,CAAC;IACjD,SAAS,GAAG,yBAAyB,CAAC;IAE/C,KAAK,CAAC,WAAW;QACvB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC3B,GAAG,CAAC,4BAA4B,IAAI,CAAC,SAAS,KAAK,CAAC,CAAC;YACrD,IAAI,CAAC,gBAAgB,GAAG,MAAM,QAAQ,CAAC,oBAAoB,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YAC7E,GAAG,CAAC,yBAAyB,CAAC,CAAC;QACjC,CAAC;QACD,OAAO,IAAI,CAAC,gBAAgB,CAAC;IAC/B,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,KAAK,CAAC,IAAY;QACtB,MAAM,
|
|
1
|
+
{"version":3,"file":"embedding.js","sourceRoot":"","sources":["../../../src/knowledge-base/embedding.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAqC,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAErC;;;GAGG;AACH,MAAM,OAAO,gBAAgB;IACnB,gBAAgB,GAAqC,IAAI,CAAC;IACjD,SAAS,GAAG,yBAAyB,CAAC;IAE/C,KAAK,CAAC,WAAW;QACvB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC3B,GAAG,CAAC,4BAA4B,IAAI,CAAC,SAAS,KAAK,CAAC,CAAC;YACrD,IAAI,CAAC,gBAAgB,GAAG,MAAM,QAAQ,CAAC,oBAAoB,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YAC7E,GAAG,CAAC,yBAAyB,CAAC,CAAC;QACjC,CAAC;QACD,OAAO,IAAI,CAAC,gBAAgB,CAAC;IAC/B,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,KAAK,CAAC,IAAY;QACtB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC9C,OAAO,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1B,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,UAAU,CAAC,KAAe,EAAE,SAAS,GAAG,EAAE;QAC9C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAClC,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,OAAO,GAAe,EAAE,CAAC;QAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,SAAS,EAAE,CAAC;YACjD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC;YAC5C,MAAM,MAAM,GAAG,CAAC,MAAM,SAAS,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAW,CAAC;YACxF,MAAM,IAAI,GAAG,MAAM,CAAC,IAAoB,CAAC;YACzC,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;YACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACtC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;YAC/D,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;CACF"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { GestaltConfig, LLMTierConfig } from '../core/config.js';
|
|
2
2
|
import type { LLMAdapter } from './types.js';
|
|
3
3
|
import type { TierMapping } from '../agent/figural-router.js';
|
|
4
|
+
import { FallbackAdapter } from './fallback-adapter.js';
|
|
4
5
|
/**
|
|
5
6
|
* tier config 또는 flat config(apiKey + model)에서 LLMAdapter를 생성한다.
|
|
6
7
|
* flat config인 경우 Anthropic을 기본 provider로 사용한다.
|
|
@@ -16,6 +17,11 @@ export declare function createAdapterFromTierConfig(tierCfg: LLMTierConfig, llmC
|
|
|
16
17
|
* tier 설정이 없는 경우 flat config(apiKey + model)로 모든 tier에 AnthropicAdapter를 할당한다.
|
|
17
18
|
*/
|
|
18
19
|
export declare function createTierMapping(config: GestaltConfig): TierMapping;
|
|
20
|
+
/**
|
|
21
|
+
* GestaltConfig에서 FallbackAdapter를 생성한다.
|
|
22
|
+
* tier 순서(frontier → standard → frugal)로 시도하며, tier가 없으면 flat config로 폴백한다.
|
|
23
|
+
*/
|
|
24
|
+
export declare function createFallbackAdapter(config: GestaltConfig): FallbackAdapter;
|
|
19
25
|
/**
|
|
20
26
|
* LLM API 키가 설정되어 있는지 확인한다.
|
|
21
27
|
* flat config의 apiKey 또는 any tier의 apiKey가 있으면 true.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/llm/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAItE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAI9D;;;GAGG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,aAAa,CAAC,KAAK,CAAC,GAAG,UAAU,CASzE;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,aAAa,EACtB,SAAS,EAAE,aAAa,CAAC,KAAK,CAAC,GAC9B,UAAU,CAWZ;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,GAAG,WAAW,CAwBpE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAO3D"}
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/llm/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAItE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAI9D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,aAAa,CAAC,KAAK,CAAC,GAAG,UAAU,CASzE;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,aAAa,EACtB,SAAS,EAAE,aAAa,CAAC,KAAK,CAAC,GAC9B,UAAU,CAWZ;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,GAAG,WAAW,CAwBpE;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,GAAG,eAAe,CAO5E;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAO3D"}
|
package/dist/src/llm/factory.js
CHANGED
|
@@ -2,6 +2,8 @@ import { DEFAULT_MODEL } from '../core/constants.js';
|
|
|
2
2
|
import { LLMError } from '../core/errors.js';
|
|
3
3
|
import { AnthropicAdapter } from './adapter.js';
|
|
4
4
|
import { OpenAIAdapter } from './openai-adapter.js';
|
|
5
|
+
import { RetryingAdapter } from './retry-adapter.js';
|
|
6
|
+
import { FallbackAdapter } from './fallback-adapter.js';
|
|
5
7
|
/**
|
|
6
8
|
* tier config 또는 flat config(apiKey + model)에서 LLMAdapter를 생성한다.
|
|
7
9
|
* flat config인 경우 Anthropic을 기본 provider로 사용한다.
|
|
@@ -13,7 +15,7 @@ export function createAdapter(llmConfig) {
|
|
|
13
15
|
return createAdapterFromTierConfig(tierCfg, llmConfig);
|
|
14
16
|
}
|
|
15
17
|
// flat config fallback (기존 호환)
|
|
16
|
-
return new AnthropicAdapter(llmConfig.apiKey, llmConfig.model);
|
|
18
|
+
return new RetryingAdapter(new AnthropicAdapter(llmConfig.apiKey, llmConfig.model));
|
|
17
19
|
}
|
|
18
20
|
/**
|
|
19
21
|
* LLMTierConfig에서 provider별 LLMAdapter를 생성한다.
|
|
@@ -23,9 +25,9 @@ export function createAdapterFromTierConfig(tierCfg, llmConfig) {
|
|
|
23
25
|
const apiKey = tierCfg.apiKey ?? llmConfig.apiKey;
|
|
24
26
|
switch (tierCfg.provider) {
|
|
25
27
|
case 'anthropic':
|
|
26
|
-
return new AnthropicAdapter(apiKey, tierCfg.model);
|
|
28
|
+
return new RetryingAdapter(new AnthropicAdapter(apiKey, tierCfg.model));
|
|
27
29
|
case 'openai':
|
|
28
|
-
return new OpenAIAdapter(apiKey, tierCfg.model, tierCfg.baseURL);
|
|
30
|
+
return new RetryingAdapter(new OpenAIAdapter(apiKey, tierCfg.model, tierCfg.baseURL));
|
|
29
31
|
default:
|
|
30
32
|
throw new LLMError(`Unsupported LLM provider: ${String(tierCfg.provider)}`);
|
|
31
33
|
}
|
|
@@ -52,12 +54,25 @@ export function createTierMapping(config) {
|
|
|
52
54
|
mapping[tier] = {
|
|
53
55
|
provider: 'anthropic',
|
|
54
56
|
model: llm.model || DEFAULT_MODEL,
|
|
55
|
-
adapter: new AnthropicAdapter(llm.apiKey, llm.model || DEFAULT_MODEL),
|
|
57
|
+
adapter: new RetryingAdapter(new AnthropicAdapter(llm.apiKey, llm.model || DEFAULT_MODEL)),
|
|
56
58
|
};
|
|
57
59
|
}
|
|
58
60
|
}
|
|
59
61
|
return mapping;
|
|
60
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* GestaltConfig에서 FallbackAdapter를 생성한다.
|
|
65
|
+
* tier 순서(frontier → standard → frugal)로 시도하며, tier가 없으면 flat config로 폴백한다.
|
|
66
|
+
*/
|
|
67
|
+
export function createFallbackAdapter(config) {
|
|
68
|
+
const tiers = ['frontier', 'standard', 'frugal'];
|
|
69
|
+
const adapters = tiers
|
|
70
|
+
.filter((t) => config.llm[t])
|
|
71
|
+
.map((t) => createAdapterFromTierConfig(config.llm[t], config.llm));
|
|
72
|
+
if (adapters.length === 0)
|
|
73
|
+
adapters.push(createAdapter(config.llm));
|
|
74
|
+
return new FallbackAdapter(adapters);
|
|
75
|
+
}
|
|
61
76
|
/**
|
|
62
77
|
* LLM API 키가 설정되어 있는지 확인한다.
|
|
63
78
|
* flat config의 apiKey 또는 any tier의 apiKey가 있으면 true.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../../../src/llm/factory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAI7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../../../src/llm/factory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { LLMAdapter, LLMRequest, LLMResponse } from './types.js';
|
|
2
|
+
export declare class FallbackAdapter implements LLMAdapter {
|
|
3
|
+
private readonly adapters;
|
|
4
|
+
constructor(adapters: LLMAdapter[]);
|
|
5
|
+
chat(request: LLMRequest): Promise<LLMResponse>;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=fallback-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fallback-adapter.d.ts","sourceRoot":"","sources":["../../../src/llm/fallback-adapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEtE,qBAAa,eAAgB,YAAW,UAAU;IACpC,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,UAAU,EAAE;IAM7C,IAAI,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;CAWtD"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { LLMError } from '../core/errors.js';
|
|
2
|
+
export class FallbackAdapter {
|
|
3
|
+
adapters;
|
|
4
|
+
constructor(adapters) {
|
|
5
|
+
this.adapters = adapters;
|
|
6
|
+
if (adapters.length === 0) {
|
|
7
|
+
throw new LLMError('FallbackAdapter: no adapters available');
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
async chat(request) {
|
|
11
|
+
let lastError;
|
|
12
|
+
for (const adapter of this.adapters) {
|
|
13
|
+
try {
|
|
14
|
+
return await adapter.chat(request);
|
|
15
|
+
}
|
|
16
|
+
catch (e) {
|
|
17
|
+
lastError = e;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
throw lastError ?? new LLMError('FallbackAdapter: no adapters available');
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=fallback-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fallback-adapter.js","sourceRoot":"","sources":["../../../src/llm/fallback-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAG7C,MAAM,OAAO,eAAe;IACG;IAA7B,YAA6B,QAAsB;QAAtB,aAAQ,GAAR,QAAQ,CAAc;QACjD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,QAAQ,CAAC,wCAAwC,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAAmB;QAC5B,IAAI,SAAkB,CAAC;QACvB,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpC,IAAI,CAAC;gBACH,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACrC,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,SAAS,GAAG,CAAC,CAAC;YAChB,CAAC;QACH,CAAC;QACD,MAAM,SAAS,IAAI,IAAI,QAAQ,CAAC,wCAAwC,CAAC,CAAC;IAC5E,CAAC;CACF"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { LLMAdapter, LLMRequest, LLMResponse } from './types.js';
|
|
2
|
+
export declare class RetryingAdapter implements LLMAdapter {
|
|
3
|
+
private readonly inner;
|
|
4
|
+
private readonly maxAttempts;
|
|
5
|
+
private readonly baseDelayMs;
|
|
6
|
+
constructor(inner: LLMAdapter, maxAttempts?: number, baseDelayMs?: number);
|
|
7
|
+
chat(request: LLMRequest): Promise<LLMResponse>;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=retry-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry-adapter.d.ts","sourceRoot":"","sources":["../../../src/llm/retry-adapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAmBtE,qBAAa,eAAgB,YAAW,UAAU;IAE9C,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAFX,KAAK,EAAE,UAAU,EACjB,WAAW,SAAI,EACf,WAAW,SAAO;IAG/B,IAAI,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;CAatD"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { LLMError } from '../core/errors.js';
|
|
2
|
+
const RETRIABLE_KEYWORDS = [
|
|
3
|
+
'429',
|
|
4
|
+
'rate limit',
|
|
5
|
+
'503',
|
|
6
|
+
'502',
|
|
7
|
+
'500',
|
|
8
|
+
'timeout',
|
|
9
|
+
'ECONNRESET',
|
|
10
|
+
'ETIMEDOUT',
|
|
11
|
+
];
|
|
12
|
+
function isRetriable(err) {
|
|
13
|
+
if (!(err instanceof LLMError))
|
|
14
|
+
return false;
|
|
15
|
+
const msg = err.message.toLowerCase();
|
|
16
|
+
return RETRIABLE_KEYWORDS.some((k) => msg.includes(k.toLowerCase()));
|
|
17
|
+
}
|
|
18
|
+
export class RetryingAdapter {
|
|
19
|
+
inner;
|
|
20
|
+
maxAttempts;
|
|
21
|
+
baseDelayMs;
|
|
22
|
+
constructor(inner, maxAttempts = 3, baseDelayMs = 1000) {
|
|
23
|
+
this.inner = inner;
|
|
24
|
+
this.maxAttempts = maxAttempts;
|
|
25
|
+
this.baseDelayMs = baseDelayMs;
|
|
26
|
+
}
|
|
27
|
+
async chat(request) {
|
|
28
|
+
let lastError;
|
|
29
|
+
for (let attempt = 0; attempt < this.maxAttempts; attempt++) {
|
|
30
|
+
try {
|
|
31
|
+
return await this.inner.chat(request);
|
|
32
|
+
}
|
|
33
|
+
catch (e) {
|
|
34
|
+
lastError = e;
|
|
35
|
+
if (!isRetriable(e) || attempt === this.maxAttempts - 1)
|
|
36
|
+
throw e;
|
|
37
|
+
await new Promise((r) => setTimeout(r, this.baseDelayMs * Math.pow(2, attempt)));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
throw lastError;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=retry-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry-adapter.js","sourceRoot":"","sources":["../../../src/llm/retry-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAG7C,MAAM,kBAAkB,GAAG;IACzB,KAAK;IACL,YAAY;IACZ,KAAK;IACL,KAAK;IACL,KAAK;IACL,SAAS;IACT,YAAY;IACZ,WAAW;CACZ,CAAC;AAEF,SAAS,WAAW,CAAC,GAAY;IAC/B,IAAI,CAAC,CAAC,GAAG,YAAY,QAAQ,CAAC;QAAE,OAAO,KAAK,CAAC;IAC7C,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;IACtC,OAAO,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,OAAO,eAAe;IAEP;IACA;IACA;IAHnB,YACmB,KAAiB,EACjB,cAAc,CAAC,EACf,cAAc,IAAI;QAFlB,UAAK,GAAL,KAAK,CAAY;QACjB,gBAAW,GAAX,WAAW,CAAI;QACf,gBAAW,GAAX,WAAW,CAAO;IAClC,CAAC;IAEJ,KAAK,CAAC,IAAI,CAAC,OAAmB;QAC5B,IAAI,SAAkB,CAAC;QACvB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC;YAC5D,IAAI,CAAC;gBACH,OAAO,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACxC,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,SAAS,GAAG,CAAC,CAAC;gBACd,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,OAAO,KAAK,IAAI,CAAC,WAAW,GAAG,CAAC;oBAAE,MAAM,CAAC,CAAC;gBACjE,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;YACnF,CAAC;QACH,CAAC;QACD,MAAM,SAAS,CAAC;IAClB,CAAC;CACF"}
|