@layer-ai/core 0.8.20 → 0.9.1

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.
@@ -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;
@@ -38,6 +46,7 @@ export declare const db: {
38
46
  authTag: string;
39
47
  }, keyPrefix: string): Promise<ProviderKey | null>;
40
48
  deleteProviderKey(userId: string, provider: string): Promise<boolean>;
49
+ toggleProviderKeyActive(userId: string, provider: string, isActive: boolean): Promise<ProviderKey | null>;
41
50
  hardDeleteProviderKey(userId: string, provider: string): Promise<boolean>;
42
51
  getDeletedProviderKeys(daysOld?: number): Promise<ProviderKey[]>;
43
52
  createGateHistory(gateId: string, gate: Partial<Gate>, appliedBy: "user" | "auto", changedFields?: string[]): Promise<void>;
@@ -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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"}
@@ -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]);
@@ -222,7 +254,7 @@ export const db = {
222
254
  },
223
255
  async updateProviderKey(userId, provider, encryptedKey, keyPrefix) {
224
256
  const result = await getPool().query(`UPDATE provider_keys
225
- SET encrypted_key = $3, key_prefix = $4, deleted_at = NULL, updated_at = NOW()
257
+ SET encrypted_key = $3, key_prefix = $4, deleted_at = NULL, is_active = true, updated_at = NOW()
226
258
  WHERE user_id = $1 AND provider = $2
227
259
  RETURNING *`, [userId, provider, JSON.stringify(encryptedKey), keyPrefix]);
228
260
  return result.rows[0] ? toCamelCase(result.rows[0]) : null;
@@ -231,6 +263,13 @@ export const db = {
231
263
  const result = await getPool().query('UPDATE provider_keys SET deleted_at = NOW() WHERE user_id = $1 AND provider = $2 AND deleted_at IS NULL', [userId, provider]);
232
264
  return (result.rowCount ?? 0) > 0;
233
265
  },
266
+ async toggleProviderKeyActive(userId, provider, isActive) {
267
+ const result = await getPool().query(`UPDATE provider_keys
268
+ SET is_active = $3, updated_at = NOW()
269
+ WHERE user_id = $1 AND provider = $2 AND deleted_at IS NULL
270
+ RETURNING *`, [userId, provider, isActive]);
271
+ return result.rows[0] ? toCamelCase(result.rows[0]) : null;
272
+ },
234
273
  async hardDeleteProviderKey(userId, provider) {
235
274
  const result = await getPool().query('DELETE FROM provider_keys WHERE user_id = $1 AND provider = $2', [userId, provider]);
236
275
  return (result.rowCount ?? 0) > 0;
@@ -50,6 +50,10 @@ async function getUserProviderKey(userId, provider) {
50
50
  if (!providerKey) {
51
51
  return null;
52
52
  }
53
+ // Check if key is active
54
+ if (!providerKey.isActive) {
55
+ return null;
56
+ }
53
57
  // Decrypt the key
54
58
  const decryptedKey = decrypt(providerKey.encryptedKey, encryptionKey);
55
59
  return decryptedKey;
@@ -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;AAwnBpC,eAAe,MAAM,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"}
@@ -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;AAsLpC,eAAe,MAAM,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"}
@@ -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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@layer-ai/core",
3
- "version": "0.8.20",
3
+ "version": "0.9.1",
4
4
  "description": "Core API routes and services for Layer AI",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -36,7 +36,7 @@
36
36
  "nanoid": "^5.0.4",
37
37
  "openai": "^4.24.0",
38
38
  "pg": "^8.11.3",
39
- "@layer-ai/sdk": "^1.0.1"
39
+ "@layer-ai/sdk": "^1.0.2"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@types/bcryptjs": "^2.4.6",