@layer-ai/core 0.8.19 → 0.9.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/dist/lib/db/migrations/005_add_request_payloads.sql +14 -0
- package/dist/lib/db/postgres.d.ts +8 -0
- package/dist/lib/db/postgres.d.ts.map +1 -1
- package/dist/lib/db/postgres.js +37 -5
- package/dist/routes/v1/gates.d.ts.map +1 -1
- package/dist/routes/v1/gates.js +0 -92
- package/dist/routes/v1/logs.d.ts.map +1 -1
- package/dist/routes/v1/logs.js +9 -0
- package/dist/routes/v2/complete.d.ts.map +1 -1
- package/dist/routes/v2/complete.js +6 -4
- package/package.json +1 -1
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
-- Migration: 005_add_request_payloads
|
|
2
|
+
-- Description: Add JSONB payload columns to requests table for full observability
|
|
3
|
+
|
|
4
|
+
ALTER TABLE requests
|
|
5
|
+
ADD COLUMN request_payload JSONB NOT NULL DEFAULT '{}',
|
|
6
|
+
ADD COLUMN response_payload JSONB;
|
|
7
|
+
|
|
8
|
+
-- Add indexes for common query patterns
|
|
9
|
+
CREATE INDEX idx_requests_success ON requests(success, created_at DESC);
|
|
10
|
+
CREATE INDEX idx_requests_user_created ON requests(user_id, created_at DESC);
|
|
11
|
+
CREATE INDEX idx_requests_gate_created ON requests(gate_id, created_at DESC) WHERE gate_id IS NOT NULL;
|
|
12
|
+
|
|
13
|
+
COMMENT ON COLUMN requests.request_payload IS 'Full request payload including messages, system prompts, and metadata';
|
|
14
|
+
COMMENT ON COLUMN requests.response_payload IS 'Full response payload including completion text, model used, and usage stats';
|
|
@@ -19,6 +19,14 @@ export declare const db: {
|
|
|
19
19
|
updateGate(id: string, data: any): Promise<Gate | null>;
|
|
20
20
|
deleteGate(id: string): Promise<boolean>;
|
|
21
21
|
logRequest(data: any): Promise<void>;
|
|
22
|
+
getRequestLogs(userId: string, options?: {
|
|
23
|
+
gateId?: string;
|
|
24
|
+
success?: boolean;
|
|
25
|
+
startDate?: Date;
|
|
26
|
+
endDate?: Date;
|
|
27
|
+
limit?: number;
|
|
28
|
+
offset?: number;
|
|
29
|
+
}): Promise<any[]>;
|
|
22
30
|
getSessionKeyByHash(keyHash: string): Promise<{
|
|
23
31
|
userId: string;
|
|
24
32
|
expiresAt: Date;
|
|
@@ -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;oBA8BpC,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;mBAQ9B,MAAM,QAAQ,GAAG,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;mBAkDxC,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;qBASvB,GAAG,GAAG,OAAO,CAAC,IAAI,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
|
@@ -177,18 +177,50 @@ export const db = {
|
|
|
177
177
|
const result = await getPool().query('DELETE FROM gates WHERE id = $1', [id]);
|
|
178
178
|
return (result.rowCount ?? 0) > 0;
|
|
179
179
|
},
|
|
180
|
-
// Request Logging
|
|
180
|
+
// Request Logging
|
|
181
181
|
async logRequest(data) {
|
|
182
182
|
await getPool().query(`INSERT INTO requests (
|
|
183
183
|
user_id, gate_id, gate_name, model_requested, model_used, prompt_tokens,
|
|
184
|
-
completion_tokens, total_tokens, cost_usd, latency_ms, success,
|
|
185
|
-
error_message, user_agent, ip_address)
|
|
186
|
-
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)`, [
|
|
184
|
+
completion_tokens, total_tokens, cost_usd, latency_ms, success,
|
|
185
|
+
error_message, user_agent, ip_address, request_payload, response_payload)
|
|
186
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)`, [
|
|
187
187
|
data.userId, data.gateId, data.gateName, data.modelRequested, data.modelUsed, data.promptTokens,
|
|
188
188
|
data.completionTokens, data.totalTokens, data.costUsd, data.latencyMs, data.success,
|
|
189
|
-
data.errorMessage, data.userAgent, data.ipAddress
|
|
189
|
+
data.errorMessage, data.userAgent, data.ipAddress,
|
|
190
|
+
data.requestPayload ? JSON.stringify(data.requestPayload) : '{}',
|
|
191
|
+
data.responsePayload ? JSON.stringify(data.responsePayload) : null
|
|
190
192
|
]);
|
|
191
193
|
},
|
|
194
|
+
async getRequestLogs(userId, options) {
|
|
195
|
+
const { gateId, success, startDate, endDate, limit = 100, offset = 0 } = options || {};
|
|
196
|
+
let query = 'SELECT * FROM requests WHERE user_id = $1';
|
|
197
|
+
const params = [userId];
|
|
198
|
+
let paramIndex = 2;
|
|
199
|
+
if (gateId) {
|
|
200
|
+
query += ` AND gate_id = $${paramIndex}`;
|
|
201
|
+
params.push(gateId);
|
|
202
|
+
paramIndex++;
|
|
203
|
+
}
|
|
204
|
+
if (success !== undefined) {
|
|
205
|
+
query += ` AND success = $${paramIndex}`;
|
|
206
|
+
params.push(success);
|
|
207
|
+
paramIndex++;
|
|
208
|
+
}
|
|
209
|
+
if (startDate) {
|
|
210
|
+
query += ` AND created_at >= $${paramIndex}`;
|
|
211
|
+
params.push(startDate);
|
|
212
|
+
paramIndex++;
|
|
213
|
+
}
|
|
214
|
+
if (endDate) {
|
|
215
|
+
query += ` AND created_at <= $${paramIndex}`;
|
|
216
|
+
params.push(endDate);
|
|
217
|
+
paramIndex++;
|
|
218
|
+
}
|
|
219
|
+
query += ` ORDER BY created_at DESC LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`;
|
|
220
|
+
params.push(limit, offset);
|
|
221
|
+
const result = await getPool().query(query, params);
|
|
222
|
+
return result.rows.map(toCamelCase);
|
|
223
|
+
},
|
|
192
224
|
// Session Keys
|
|
193
225
|
async getSessionKeyByHash(keyHash) {
|
|
194
226
|
const result = await getPool().query('SELECT user_id, expires_at FROM session_keys WHERE key_hash = $1 AND expires_at > NOW()', [keyHash]);
|
|
@@ -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;AASpD,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;AASpD,QAAA,MAAM,MAAM,EAAE,UAAqB,CAAC;AA8gBpC,eAAe,MAAM,CAAC"}
|
package/dist/routes/v1/gates.js
CHANGED
|
@@ -186,77 +186,6 @@ router.get('/:id', async (req, res) => {
|
|
|
186
186
|
res.status(500).json({ error: 'internal_error', message: 'Failed to get gate' });
|
|
187
187
|
}
|
|
188
188
|
});
|
|
189
|
-
// PATCH /name/:name - Update a gate by name
|
|
190
|
-
router.patch('/name/:name', async (req, res) => {
|
|
191
|
-
if (!req.userId) {
|
|
192
|
-
res.status(401).json({ error: 'unauthorized', message: 'Missing user ID' });
|
|
193
|
-
return;
|
|
194
|
-
}
|
|
195
|
-
try {
|
|
196
|
-
const { description, taskType, model, systemPrompt, allowOverrides, temperature, maxTokens, topP, tags, routingStrategy, fallbackModels, costWeight, latencyWeight, qualityWeight, analysisMethod, reanalysisPeriod, taskAnalysis, autoApplyRecommendations } = req.body;
|
|
197
|
-
const existing = await db.getGateByUserAndName(req.userId, req.params.name);
|
|
198
|
-
if (!existing) {
|
|
199
|
-
res.status(404).json({ error: 'not_found', message: 'Gate not found' });
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
if (model && !MODEL_REGISTRY[model]) {
|
|
203
|
-
res.status(400).json({ error: 'bad_request', message: `Unsupported model: ${model}` });
|
|
204
|
-
return;
|
|
205
|
-
}
|
|
206
|
-
// Detect significant changes before updating
|
|
207
|
-
const changedFields = detectSignificantChanges(existing, {
|
|
208
|
-
description,
|
|
209
|
-
taskType,
|
|
210
|
-
model,
|
|
211
|
-
systemPrompt,
|
|
212
|
-
temperature,
|
|
213
|
-
maxTokens,
|
|
214
|
-
topP,
|
|
215
|
-
routingStrategy,
|
|
216
|
-
fallbackModels,
|
|
217
|
-
costWeight,
|
|
218
|
-
latencyWeight,
|
|
219
|
-
qualityWeight,
|
|
220
|
-
analysisMethod,
|
|
221
|
-
reanalysisPeriod,
|
|
222
|
-
autoApplyRecommendations,
|
|
223
|
-
});
|
|
224
|
-
const updated = await db.updateGate(existing.id, {
|
|
225
|
-
description,
|
|
226
|
-
taskType,
|
|
227
|
-
model,
|
|
228
|
-
systemPrompt,
|
|
229
|
-
allowOverrides,
|
|
230
|
-
temperature,
|
|
231
|
-
maxTokens,
|
|
232
|
-
topP,
|
|
233
|
-
tags,
|
|
234
|
-
routingStrategy,
|
|
235
|
-
fallbackModels,
|
|
236
|
-
costWeight,
|
|
237
|
-
latencyWeight,
|
|
238
|
-
qualityWeight,
|
|
239
|
-
analysisMethod,
|
|
240
|
-
reanalysisPeriod,
|
|
241
|
-
taskAnalysis,
|
|
242
|
-
autoApplyRecommendations,
|
|
243
|
-
});
|
|
244
|
-
// Only create history snapshot if significant changes were detected
|
|
245
|
-
if (updated && changedFields.length > 0) {
|
|
246
|
-
await db.createGateHistory(existing.id, updated, 'user', changedFields);
|
|
247
|
-
// Log manual update activity with specific changed fields
|
|
248
|
-
await db.createActivityLog(existing.id, req.userId, 'manual_update', {
|
|
249
|
-
changedFields
|
|
250
|
-
});
|
|
251
|
-
}
|
|
252
|
-
await cache.invalidateGate(req.userId, existing.name);
|
|
253
|
-
res.json(updated);
|
|
254
|
-
}
|
|
255
|
-
catch (error) {
|
|
256
|
-
console.error('Update gate by name error:', error);
|
|
257
|
-
res.status(500).json({ error: 'internal_error', message: 'Failed to update gate' });
|
|
258
|
-
}
|
|
259
|
-
});
|
|
260
189
|
// PATCH /:id - Update a gate by ID
|
|
261
190
|
router.patch('/:id', async (req, res) => {
|
|
262
191
|
if (!req.userId) {
|
|
@@ -334,27 +263,6 @@ router.patch('/:id', async (req, res) => {
|
|
|
334
263
|
res.status(500).json({ error: 'internal_error', message: 'Failed to update gate' });
|
|
335
264
|
}
|
|
336
265
|
});
|
|
337
|
-
// DELETE /name/:name - Delete a gate by name
|
|
338
|
-
router.delete('/name/:name', async (req, res) => {
|
|
339
|
-
if (!req.userId) {
|
|
340
|
-
res.status(401).json({ error: 'unauthorized', message: 'Missing user ID' });
|
|
341
|
-
return;
|
|
342
|
-
}
|
|
343
|
-
try {
|
|
344
|
-
const existing = await db.getGateByUserAndName(req.userId, req.params.name);
|
|
345
|
-
if (!existing) {
|
|
346
|
-
res.status(404).json({ error: 'not_found', message: 'Gate not found' });
|
|
347
|
-
return;
|
|
348
|
-
}
|
|
349
|
-
await db.deleteGate(existing.id);
|
|
350
|
-
await cache.invalidateGate(req.userId, existing.name);
|
|
351
|
-
res.status(204).send();
|
|
352
|
-
}
|
|
353
|
-
catch (error) {
|
|
354
|
-
console.error('Delete gate by name error:', error);
|
|
355
|
-
res.status(500).json({ error: 'internal_error', message: 'Failed to delete gate' });
|
|
356
|
-
}
|
|
357
|
-
});
|
|
358
266
|
// DELETE /:id - Delete a gate by ID
|
|
359
267
|
router.delete('/:id', async (req, res) => {
|
|
360
268
|
if (!req.userId) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../../src/routes/v1/logs.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,SAAS,CAAC;AAIpD,QAAA,MAAM,MAAM,EAAE,UAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../../src/routes/v1/logs.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,SAAS,CAAC;AAIpD,QAAA,MAAM,MAAM,EAAE,UAAqB,CAAC;AAgMpC,eAAe,MAAM,CAAC"}
|
package/dist/routes/v1/logs.js
CHANGED
|
@@ -11,6 +11,7 @@ router.get('/', async (req, res) => {
|
|
|
11
11
|
const limit = parseInt(req.query.limit) || 50;
|
|
12
12
|
const offset = parseInt(req.query.offset) || 0;
|
|
13
13
|
const gate = req.query.gate;
|
|
14
|
+
const success = req.query.success;
|
|
14
15
|
let query = `
|
|
15
16
|
SELECT
|
|
16
17
|
id,
|
|
@@ -25,6 +26,8 @@ router.get('/', async (req, res) => {
|
|
|
25
26
|
latency_ms,
|
|
26
27
|
success,
|
|
27
28
|
error_message,
|
|
29
|
+
request_payload,
|
|
30
|
+
response_payload,
|
|
28
31
|
created_at as logged_at
|
|
29
32
|
FROM requests
|
|
30
33
|
WHERE user_id = $1
|
|
@@ -34,6 +37,10 @@ router.get('/', async (req, res) => {
|
|
|
34
37
|
query += ` AND gate_id = $2`;
|
|
35
38
|
params.push(gate);
|
|
36
39
|
}
|
|
40
|
+
if (success !== undefined) {
|
|
41
|
+
query += ` AND success = $${params.length + 1}`;
|
|
42
|
+
params.push(success === 'true');
|
|
43
|
+
}
|
|
37
44
|
query += ` ORDER BY created_at DESC LIMIT $${params.length + 1} OFFSET $${params.length + 2}`;
|
|
38
45
|
params.push(limit, offset);
|
|
39
46
|
const result = await db.query(query, params);
|
|
@@ -50,6 +57,8 @@ router.get('/', async (req, res) => {
|
|
|
50
57
|
latencyMs: row.latency_ms,
|
|
51
58
|
success: row.success,
|
|
52
59
|
errorMessage: row.error_message,
|
|
60
|
+
requestPayload: row.request_payload,
|
|
61
|
+
responsePayload: row.response_payload,
|
|
53
62
|
loggedAt: row.logged_at,
|
|
54
63
|
}));
|
|
55
64
|
res.json(logs);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"complete.d.ts","sourceRoot":"","sources":["../../../src/routes/v2/complete.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,SAAS,CAAC;AASpD,QAAA,MAAM,MAAM,EAAE,UAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"complete.d.ts","sourceRoot":"","sources":["../../../src/routes/v2/complete.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,SAAS,CAAC;AASpD,QAAA,MAAM,MAAM,EAAE,UAAqB,CAAC;AAqQpC,eAAe,MAAM,CAAC"}
|
|
@@ -137,19 +137,21 @@ router.post('/', authenticate, async (req, res) => {
|
|
|
137
137
|
return;
|
|
138
138
|
}
|
|
139
139
|
const userId = req.userId;
|
|
140
|
+
let gateConfig = null;
|
|
141
|
+
let request = null;
|
|
140
142
|
try {
|
|
141
143
|
const rawRequest = req.body;
|
|
142
144
|
if (!rawRequest.gate) {
|
|
143
145
|
res.status(400).json({ error: 'bad_request', message: 'Missing required field: gate' });
|
|
144
146
|
return;
|
|
145
147
|
}
|
|
146
|
-
|
|
148
|
+
gateConfig = await getGateConfig(userId, rawRequest.gate);
|
|
147
149
|
if (!gateConfig) {
|
|
148
150
|
res.status(404).json({ error: 'not_found', message: `Gate "${rawRequest.gate}" not found` });
|
|
149
151
|
return;
|
|
150
152
|
}
|
|
151
153
|
const requestType = rawRequest.type || gateConfig.taskType || 'chat';
|
|
152
|
-
|
|
154
|
+
request = {
|
|
153
155
|
gate: rawRequest.gate,
|
|
154
156
|
type: requestType,
|
|
155
157
|
data: rawRequest.data,
|
|
@@ -195,9 +197,9 @@ router.post('/', authenticate, async (req, res) => {
|
|
|
195
197
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
196
198
|
db.logRequest({
|
|
197
199
|
userId,
|
|
198
|
-
gateId: null,
|
|
200
|
+
gateId: gateConfig?.id || null,
|
|
199
201
|
gateName: req.body?.gate || null,
|
|
200
|
-
modelRequested:
|
|
202
|
+
modelRequested: (request?.model || gateConfig?.model) || 'unknown',
|
|
201
203
|
modelUsed: null,
|
|
202
204
|
promptTokens: 0,
|
|
203
205
|
completionTokens: 0,
|