@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.
@@ -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":"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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]);
@@ -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);
@@ -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;AAkQpC,eAAe,MAAM,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
- const gateConfig = await getGateConfig(userId, rawRequest.gate);
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
- const request = {
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: null,
202
+ modelRequested: (request?.model || gateConfig?.model) || 'unknown',
201
203
  modelUsed: null,
202
204
  promptTokens: 0,
203
205
  completionTokens: 0,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@layer-ai/core",
3
- "version": "0.8.19",
3
+ "version": "0.9.0",
4
4
  "description": "Core API routes and services for Layer AI",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",