@layer-ai/core 0.8.0 → 0.8.2
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/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/lib/db/postgres.d.ts +5 -0
- package/dist/lib/db/postgres.d.ts.map +1 -1
- package/dist/lib/db/postgres.js +62 -0
- package/dist/routes/v1/gate-history.d.ts +4 -0
- package/dist/routes/v1/gate-history.d.ts.map +1 -0
- package/dist/routes/v1/gate-history.js +108 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { default as authRouter } from './routes/v1/auth.js';
|
|
2
2
|
export { default as gatesRouter } from './routes/v1/gates.js';
|
|
3
|
+
export { default as gateHistoryRouter } from './routes/v1/gate-history.js';
|
|
3
4
|
export { default as keysRouter } from './routes/v1/keys.js';
|
|
4
5
|
export { default as logsRouter } from './routes/v1/logs.js';
|
|
5
6
|
export { default as completeRouter } from './routes/v2/complete.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAGpE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAG3C,OAAO,EAAE,EAAE,EAAE,MAAM,sBAAsB,CAAC;AAC1C,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAGrD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC9E,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGnD,eAAO,MAAM,gBAAgB,GAAU,QAAQ,MAAM,KAAG,OAAO,CAAC,MAAM,CAGrE,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAU,QAAQ,MAAM,KAAG,OAAO,CAAC,IAAI,CAG3E,CAAC;AAGF,cAAc,6BAA6B,CAAC;AAG5C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,QAAQ,EAAE,WAAW,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAGpE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAG3C,OAAO,EAAE,EAAE,EAAE,MAAM,sBAAsB,CAAC;AAC1C,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAGrD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC9E,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGnD,eAAO,MAAM,gBAAgB,GAAU,QAAQ,MAAM,KAAG,OAAO,CAAC,MAAM,CAGrE,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAU,QAAQ,MAAM,KAAG,OAAO,CAAC,IAAI,CAG3E,CAAC;AAGF,cAAc,6BAA6B,CAAC;AAG5C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,QAAQ,EAAE,WAAW,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Routes
|
|
2
2
|
export { default as authRouter } from './routes/v1/auth.js';
|
|
3
3
|
export { default as gatesRouter } from './routes/v1/gates.js';
|
|
4
|
+
export { default as gateHistoryRouter } from './routes/v1/gate-history.js';
|
|
4
5
|
export { default as keysRouter } from './routes/v1/keys.js';
|
|
5
6
|
export { default as logsRouter } from './routes/v1/logs.js';
|
|
6
7
|
export { default as completeRouter } from './routes/v2/complete.js';
|
|
@@ -40,6 +40,11 @@ export declare const db: {
|
|
|
40
40
|
deleteProviderKey(userId: string, provider: string): Promise<boolean>;
|
|
41
41
|
hardDeleteProviderKey(userId: string, provider: string): Promise<boolean>;
|
|
42
42
|
getDeletedProviderKeys(daysOld?: number): Promise<ProviderKey[]>;
|
|
43
|
+
createGateHistory(gateId: string, gate: Partial<Gate>, appliedBy: "user" | "auto", changedFields?: string[]): Promise<void>;
|
|
44
|
+
getGateHistory(gateId: string, limit?: number): Promise<any[]>;
|
|
45
|
+
getGateHistoryById(id: string): Promise<any | null>;
|
|
46
|
+
createActivityLog(gateId: string, userId: string | null, action: "manual_update" | "auto_update" | "reanalysis" | "rollback", details: any): Promise<void>;
|
|
47
|
+
getActivityLog(gateId: string, limit?: number): Promise<any[]>;
|
|
43
48
|
};
|
|
44
49
|
export default getPool;
|
|
45
50
|
//# sourceMappingURL=postgres.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../../src/lib/db/postgres.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAyB,WAAW,EAAE,MAAM,eAAe,CAAC;AAO5F,iBAAS,OAAO,IAAI,EAAE,CAAC,IAAI,CAqB1B;AA0BD,eAAO,MAAM,EAAE;gBAEK,MAAM,WAAW,GAAG,EAAE;0BASZ,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;oBAQnC,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;sBAQ3B,MAAM,gBAAgB,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;6BASrC,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;yBAQnC,MAAM,WAAW,MAAM,aAAa,MAAM,QAAQ,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;kCAQjE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;8BAO1B,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;qBAQnC,MAAM,UAAU,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;iCAS7B,MAAM,YAAY,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;+BAQjD,MAAM,UAAU,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;4BAQhD,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;uBAQ7B,MAAM,QAAQ,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;oBA4BpC,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;mBAQ9B,MAAM,QAAQ,GAAG,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;mBA4CxC,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;qBASvB,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;iCAgBP,MAAM,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;6BAQhE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;qCAehB,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;2BAQhC,MAAM,YAAY,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;4BAQrD,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;8BASnD,MAAM,YACJ,MAAM,gBACF;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,aACrD,MAAM,GAChB,OAAO,CAAC,WAAW,CAAC;8BAWb,MAAM,YACJ,MAAM,gBACF;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,aACrD,MAAM,GAChB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;8BAWE,MAAM,YAAY,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;kCAQvC,MAAM,YAAY,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;qCAQzC,MAAM,GAAQ,OAAO,CAAC,WAAW,EAAE,CAAC;
|
|
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
|
@@ -234,5 +234,67 @@ export const db = {
|
|
|
234
234
|
ORDER BY deleted_at ASC`, [daysOld]);
|
|
235
235
|
return result.rows.map(toCamelCase);
|
|
236
236
|
},
|
|
237
|
+
// Gate History
|
|
238
|
+
async createGateHistory(gateId, gate, appliedBy, changedFields) {
|
|
239
|
+
await getPool().query(`INSERT INTO gate_history (
|
|
240
|
+
gate_id, name, description, model, fallback_models, routing_strategy,
|
|
241
|
+
temperature, max_tokens, top_p, cost_weight, latency_weight, quality_weight,
|
|
242
|
+
analysis_method, task_type, task_analysis, system_prompt,
|
|
243
|
+
reanalysis_period, auto_apply_recommendations, applied_by, applied_at, changed_fields
|
|
244
|
+
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, NOW(), $20)`, [
|
|
245
|
+
gateId,
|
|
246
|
+
gate.name,
|
|
247
|
+
gate.description,
|
|
248
|
+
gate.model,
|
|
249
|
+
JSON.stringify(gate.fallbackModels || []),
|
|
250
|
+
gate.routingStrategy,
|
|
251
|
+
gate.temperature,
|
|
252
|
+
gate.maxTokens,
|
|
253
|
+
gate.topP,
|
|
254
|
+
gate.costWeight ?? 0.33,
|
|
255
|
+
gate.latencyWeight ?? 0.33,
|
|
256
|
+
gate.qualityWeight ?? 0.34,
|
|
257
|
+
gate.analysisMethod ?? 'balanced',
|
|
258
|
+
gate.taskType,
|
|
259
|
+
gate.taskAnalysis ? JSON.stringify(gate.taskAnalysis) : null,
|
|
260
|
+
gate.systemPrompt,
|
|
261
|
+
gate.reanalysisPeriod ?? 'never',
|
|
262
|
+
gate.autoApplyRecommendations ?? false,
|
|
263
|
+
appliedBy,
|
|
264
|
+
changedFields ? JSON.stringify(changedFields) : null
|
|
265
|
+
]);
|
|
266
|
+
// Prune old history entries, keeping only the last 20
|
|
267
|
+
await getPool().query(`DELETE FROM gate_history
|
|
268
|
+
WHERE gate_id = $1
|
|
269
|
+
AND id NOT IN (
|
|
270
|
+
SELECT id FROM gate_history
|
|
271
|
+
WHERE gate_id = $1
|
|
272
|
+
ORDER BY created_at DESC
|
|
273
|
+
LIMIT 20
|
|
274
|
+
)`, [gateId]);
|
|
275
|
+
},
|
|
276
|
+
async getGateHistory(gateId, limit = 20) {
|
|
277
|
+
const result = await getPool().query(`SELECT * FROM gate_history
|
|
278
|
+
WHERE gate_id = $1
|
|
279
|
+
ORDER BY created_at DESC
|
|
280
|
+
LIMIT $2`, [gateId, limit]);
|
|
281
|
+
return result.rows.map(toCamelCase);
|
|
282
|
+
},
|
|
283
|
+
async getGateHistoryById(id) {
|
|
284
|
+
const result = await getPool().query('SELECT * FROM gate_history WHERE id = $1', [id]);
|
|
285
|
+
return result.rows[0] ? toCamelCase(result.rows[0]) : null;
|
|
286
|
+
},
|
|
287
|
+
// Activity Log
|
|
288
|
+
async createActivityLog(gateId, userId, action, details) {
|
|
289
|
+
await getPool().query(`INSERT INTO gate_activity_log (gate_id, user_id, action, details)
|
|
290
|
+
VALUES ($1, $2, $3, $4)`, [gateId, userId, action, details ? JSON.stringify(details) : null]);
|
|
291
|
+
},
|
|
292
|
+
async getActivityLog(gateId, limit = 50) {
|
|
293
|
+
const result = await getPool().query(`SELECT * FROM gate_activity_log
|
|
294
|
+
WHERE gate_id = $1
|
|
295
|
+
ORDER BY timestamp DESC
|
|
296
|
+
LIMIT $2`, [gateId, limit]);
|
|
297
|
+
return result.rows.map(toCamelCase);
|
|
298
|
+
},
|
|
237
299
|
};
|
|
238
300
|
export default getPool;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate-history.d.ts","sourceRoot":"","sources":["../../../src/routes/v1/gate-history.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAGjC,QAAA,MAAM,MAAM,EAAE,MAAiB,CAAC;AA6HhC,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
import { db } from '../../lib/db/postgres.js';
|
|
3
|
+
const router = Router();
|
|
4
|
+
/**
|
|
5
|
+
* GET /v1/gates/:gateId/history
|
|
6
|
+
* Get history for a gate
|
|
7
|
+
*/
|
|
8
|
+
router.get('/:gateId/history', async (req, res) => {
|
|
9
|
+
try {
|
|
10
|
+
const { gateId } = req.params;
|
|
11
|
+
const limit = req.query.limit ? parseInt(req.query.limit, 10) : 20;
|
|
12
|
+
const gate = await db.getGateById(gateId);
|
|
13
|
+
if (!gate) {
|
|
14
|
+
return res.status(404).json({ error: 'Gate not found' });
|
|
15
|
+
}
|
|
16
|
+
if (gate.userId !== req.userId) {
|
|
17
|
+
return res.status(403).json({ error: 'Forbidden' });
|
|
18
|
+
}
|
|
19
|
+
const history = await db.getGateHistory(gateId, limit);
|
|
20
|
+
res.json(history);
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
console.error('Error fetching gate history:', error);
|
|
24
|
+
res.status(500).json({ error: 'Failed to fetch history' });
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
/**
|
|
28
|
+
* GET /v1/gates/:gateId/activity
|
|
29
|
+
* Get activity log for a gate
|
|
30
|
+
*/
|
|
31
|
+
router.get('/:gateId/activity', async (req, res) => {
|
|
32
|
+
try {
|
|
33
|
+
const { gateId } = req.params;
|
|
34
|
+
const limit = req.query.limit ? parseInt(req.query.limit, 10) : 50;
|
|
35
|
+
const gate = await db.getGateById(gateId);
|
|
36
|
+
if (!gate) {
|
|
37
|
+
return res.status(404).json({ error: 'Gate not found' });
|
|
38
|
+
}
|
|
39
|
+
if (gate.userId !== req.userId) {
|
|
40
|
+
return res.status(403).json({ error: 'Forbidden' });
|
|
41
|
+
}
|
|
42
|
+
const activity = await db.getActivityLog(gateId, limit);
|
|
43
|
+
res.json(activity);
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
console.error('Error fetching gate activity:', error);
|
|
47
|
+
res.status(500).json({ error: 'Failed to fetch activity' });
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
/**
|
|
51
|
+
* POST /v1/gates/:gateId/rollback/:historyId
|
|
52
|
+
* Rollback gate to a previous configuration
|
|
53
|
+
*/
|
|
54
|
+
router.post('/:gateId/rollback/:historyId', async (req, res) => {
|
|
55
|
+
try {
|
|
56
|
+
const { gateId, historyId } = req.params;
|
|
57
|
+
const gate = await db.getGateById(gateId);
|
|
58
|
+
if (!gate) {
|
|
59
|
+
return res.status(404).json({ error: 'Gate not found' });
|
|
60
|
+
}
|
|
61
|
+
if (gate.userId !== req.userId) {
|
|
62
|
+
return res.status(403).json({ error: 'Forbidden' });
|
|
63
|
+
}
|
|
64
|
+
// Get the history entry to rollback to
|
|
65
|
+
const historyEntry = await db.getGateHistoryById(historyId);
|
|
66
|
+
if (!historyEntry) {
|
|
67
|
+
return res.status(404).json({ error: 'History entry not found' });
|
|
68
|
+
}
|
|
69
|
+
if (historyEntry.gateId !== gateId) {
|
|
70
|
+
return res.status(400).json({ error: 'History entry does not belong to this gate' });
|
|
71
|
+
}
|
|
72
|
+
// Create a snapshot of current state before rollback
|
|
73
|
+
await db.createGateHistory(gateId, gate, 'user');
|
|
74
|
+
// Update gate with historical configuration
|
|
75
|
+
const updatedGate = await db.updateGate(gateId, {
|
|
76
|
+
name: historyEntry.name,
|
|
77
|
+
description: historyEntry.description,
|
|
78
|
+
model: historyEntry.model,
|
|
79
|
+
fallbackModels: historyEntry.fallbackModels,
|
|
80
|
+
routingStrategy: historyEntry.routingStrategy,
|
|
81
|
+
temperature: historyEntry.temperature,
|
|
82
|
+
maxTokens: historyEntry.maxTokens,
|
|
83
|
+
topP: historyEntry.topP,
|
|
84
|
+
costWeight: historyEntry.costWeight,
|
|
85
|
+
latencyWeight: historyEntry.latencyWeight,
|
|
86
|
+
qualityWeight: historyEntry.qualityWeight,
|
|
87
|
+
analysisMethod: historyEntry.analysisMethod,
|
|
88
|
+
taskType: historyEntry.taskType,
|
|
89
|
+
taskAnalysis: historyEntry.taskAnalysis,
|
|
90
|
+
systemPrompt: historyEntry.systemPrompt,
|
|
91
|
+
reanalysisPeriod: historyEntry.reanalysisPeriod,
|
|
92
|
+
autoApplyRecommendations: historyEntry.autoApplyRecommendations,
|
|
93
|
+
});
|
|
94
|
+
// Log the rollback activity
|
|
95
|
+
await db.createActivityLog(gateId, req.userId, 'rollback', {
|
|
96
|
+
historyId,
|
|
97
|
+
previousModel: gate.model,
|
|
98
|
+
rolledBackToModel: historyEntry.model,
|
|
99
|
+
appliedAt: historyEntry.appliedAt,
|
|
100
|
+
});
|
|
101
|
+
res.json(updatedGate);
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
console.error('Error rolling back gate:', error);
|
|
105
|
+
res.status(500).json({ error: 'Failed to rollback gate' });
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
export default router;
|