@layer-ai/core 0.8.7 → 0.8.9
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.
|
@@ -45,6 +45,7 @@ export declare const db: {
|
|
|
45
45
|
getGateHistoryById(id: string): Promise<any | null>;
|
|
46
46
|
createActivityLog(gateId: string, userId: string | null, action: "manual_update" | "auto_update" | "reanalysis" | "rollback", details: any): Promise<void>;
|
|
47
47
|
getActivityLog(gateId: string, limit?: number): Promise<any[]>;
|
|
48
|
+
rollbackGate(gateId: string, historyId: string, userId: string): Promise<Gate | null>;
|
|
48
49
|
};
|
|
49
50
|
export default getPool;
|
|
50
51
|
//# sourceMappingURL=postgres.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../../src/lib/db/postgres.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../../src/lib/db/postgres.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/db/postgres.js
CHANGED
|
@@ -301,5 +301,70 @@ export const db = {
|
|
|
301
301
|
LIMIT $2`, [gateId, limit]);
|
|
302
302
|
return result.rows.map(toCamelCase);
|
|
303
303
|
},
|
|
304
|
+
async rollbackGate(gateId, historyId, userId) {
|
|
305
|
+
// Get the historical configuration
|
|
306
|
+
const historyEntry = await this.getGateHistoryById(historyId);
|
|
307
|
+
if (!historyEntry || historyEntry.gateId !== gateId) {
|
|
308
|
+
return null;
|
|
309
|
+
}
|
|
310
|
+
// Get the current gate state before rollback for history snapshot
|
|
311
|
+
const currentGate = await this.getGateById(gateId);
|
|
312
|
+
if (!currentGate) {
|
|
313
|
+
return null;
|
|
314
|
+
}
|
|
315
|
+
// Create a snapshot of the current state before rolling back
|
|
316
|
+
await this.createGateHistory(gateId, currentGate, 'user');
|
|
317
|
+
// Update the gate with the historical configuration
|
|
318
|
+
const result = await getPool().query(`UPDATE gates SET
|
|
319
|
+
name = $2,
|
|
320
|
+
description = $3,
|
|
321
|
+
model = $4,
|
|
322
|
+
fallback_models = $5,
|
|
323
|
+
routing_strategy = $6,
|
|
324
|
+
temperature = $7,
|
|
325
|
+
max_tokens = $8,
|
|
326
|
+
top_p = $9,
|
|
327
|
+
cost_weight = $10,
|
|
328
|
+
latency_weight = $11,
|
|
329
|
+
quality_weight = $12,
|
|
330
|
+
analysis_method = $13,
|
|
331
|
+
task_type = $14,
|
|
332
|
+
task_analysis = $15,
|
|
333
|
+
system_prompt = $16,
|
|
334
|
+
reanalysis_period = $17,
|
|
335
|
+
auto_apply_recommendations = $18,
|
|
336
|
+
updated_at = NOW()
|
|
337
|
+
WHERE id = $1 RETURNING *`, [
|
|
338
|
+
gateId,
|
|
339
|
+
historyEntry.name,
|
|
340
|
+
historyEntry.description,
|
|
341
|
+
historyEntry.model,
|
|
342
|
+
typeof historyEntry.fallbackModels === 'string' ? historyEntry.fallbackModels : JSON.stringify(historyEntry.fallbackModels || []),
|
|
343
|
+
historyEntry.routingStrategy,
|
|
344
|
+
historyEntry.temperature,
|
|
345
|
+
historyEntry.maxTokens,
|
|
346
|
+
historyEntry.topP,
|
|
347
|
+
historyEntry.costWeight ?? 0.33,
|
|
348
|
+
historyEntry.latencyWeight ?? 0.33,
|
|
349
|
+
historyEntry.qualityWeight ?? 0.34,
|
|
350
|
+
historyEntry.analysisMethod ?? 'balanced',
|
|
351
|
+
historyEntry.taskType,
|
|
352
|
+
typeof historyEntry.taskAnalysis === 'string' ? historyEntry.taskAnalysis : (historyEntry.taskAnalysis ? JSON.stringify(historyEntry.taskAnalysis) : null),
|
|
353
|
+
historyEntry.systemPrompt,
|
|
354
|
+
historyEntry.reanalysisPeriod ?? 'never',
|
|
355
|
+
historyEntry.autoApplyRecommendations ?? false
|
|
356
|
+
]);
|
|
357
|
+
const rolledBackGate = result.rows[0] ? toCamelCase(result.rows[0]) : null;
|
|
358
|
+
if (rolledBackGate) {
|
|
359
|
+
// Log the rollback activity
|
|
360
|
+
await this.createActivityLog(gateId, userId, 'rollback', {
|
|
361
|
+
historyId: historyId,
|
|
362
|
+
rolledBackTo: historyEntry.createdAt,
|
|
363
|
+
previousModel: currentGate.model,
|
|
364
|
+
newModel: historyEntry.model
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
return rolledBackGate;
|
|
368
|
+
},
|
|
304
369
|
};
|
|
305
370
|
export default getPool;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gates.d.ts","sourceRoot":"","sources":["../../../src/routes/v1/gates.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,SAAS,CAAC;AAQpD,QAAA,MAAM,MAAM,EAAE,UAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"gates.d.ts","sourceRoot":"","sources":["../../../src/routes/v1/gates.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,SAAS,CAAC;AAQpD,QAAA,MAAM,MAAM,EAAE,UAAqB,CAAC;AA6fpC,eAAe,MAAM,CAAC"}
|
package/dist/routes/v1/gates.js
CHANGED
|
@@ -128,8 +128,6 @@ router.patch('/name/:name', async (req, res) => {
|
|
|
128
128
|
res.status(400).json({ error: 'bad_request', message: `Unsupported model: ${model}` });
|
|
129
129
|
return;
|
|
130
130
|
}
|
|
131
|
-
// Create history snapshot before update
|
|
132
|
-
await db.createGateHistory(existing.id, existing, 'user');
|
|
133
131
|
const updated = await db.updateGate(existing.id, {
|
|
134
132
|
description,
|
|
135
133
|
taskType,
|
|
@@ -149,6 +147,10 @@ router.patch('/name/:name', async (req, res) => {
|
|
|
149
147
|
reanalysisPeriod,
|
|
150
148
|
taskAnalysis,
|
|
151
149
|
});
|
|
150
|
+
// Create history snapshot after update with the updated values
|
|
151
|
+
if (updated) {
|
|
152
|
+
await db.createGateHistory(existing.id, updated, 'user');
|
|
153
|
+
}
|
|
152
154
|
// Log manual update activity
|
|
153
155
|
await db.createActivityLog(existing.id, req.userId, 'manual_update', {
|
|
154
156
|
changedFields: Object.keys(req.body)
|
|
@@ -182,8 +184,6 @@ router.patch('/:id', async (req, res) => {
|
|
|
182
184
|
res.status(400).json({ error: 'bad_request', message: `Unsupported model: ${model}` });
|
|
183
185
|
return;
|
|
184
186
|
}
|
|
185
|
-
// Create history snapshot before update
|
|
186
|
-
await db.createGateHistory(req.params.id, existing, 'user');
|
|
187
187
|
const updated = await db.updateGate(req.params.id, {
|
|
188
188
|
name,
|
|
189
189
|
description,
|
|
@@ -204,6 +204,10 @@ router.patch('/:id', async (req, res) => {
|
|
|
204
204
|
reanalysisPeriod,
|
|
205
205
|
taskAnalysis,
|
|
206
206
|
});
|
|
207
|
+
// Create history snapshot after update with the updated values
|
|
208
|
+
if (updated) {
|
|
209
|
+
await db.createGateHistory(req.params.id, updated, 'user');
|
|
210
|
+
}
|
|
207
211
|
// Log manual update activity
|
|
208
212
|
await db.createActivityLog(req.params.id, req.userId, 'manual_update', {
|
|
209
213
|
changedFields: Object.keys(req.body)
|
|
@@ -400,4 +404,39 @@ router.post('/suggestions', async (req, res) => {
|
|
|
400
404
|
res.status(500).json({ error: 'internal_error', message: 'Failed to fetch suggestions' });
|
|
401
405
|
}
|
|
402
406
|
});
|
|
407
|
+
// POST /:id/rollback - Rollback gate to a previous configuration from history
|
|
408
|
+
router.post('/:id/rollback', async (req, res) => {
|
|
409
|
+
if (!req.userId) {
|
|
410
|
+
res.status(401).json({ error: 'unauthorized', message: 'Missing user ID' });
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
try {
|
|
414
|
+
const { historyId } = req.body;
|
|
415
|
+
if (!historyId) {
|
|
416
|
+
res.status(400).json({ error: 'bad_request', message: 'Missing required field: historyId' });
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
const gate = await db.getGateById(req.params.id);
|
|
420
|
+
if (!gate) {
|
|
421
|
+
res.status(404).json({ error: 'not_found', message: 'Gate not found' });
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
if (gate.userId !== req.userId) {
|
|
425
|
+
res.status(404).json({ error: 'not_found', message: 'Gate not found' });
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
428
|
+
// Rollback the gate to the historical configuration
|
|
429
|
+
const updated = await db.rollbackGate(req.params.id, historyId, req.userId);
|
|
430
|
+
if (!updated) {
|
|
431
|
+
res.status(404).json({ error: 'not_found', message: 'History entry not found' });
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
await cache.invalidateGate(req.userId, gate.name);
|
|
435
|
+
res.json(updated);
|
|
436
|
+
}
|
|
437
|
+
catch (error) {
|
|
438
|
+
console.error('Rollback gate error:', error);
|
|
439
|
+
res.status(500).json({ error: 'internal_error', message: 'Failed to rollback gate' });
|
|
440
|
+
}
|
|
441
|
+
});
|
|
403
442
|
export default router;
|