@layer-ai/core 2.0.47 → 2.0.49

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,2 @@
1
+ -- Rename 'document' task type to 'ocr' in gates table
2
+ UPDATE gates SET task_type = 'ocr' WHERE task_type = 'document';
@@ -0,0 +1 @@
1
+ ALTER TABLE gates ADD COLUMN task_subtype VARCHAR(20);
@@ -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;0BAQxC,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;4BAU7B,MAAM,GAAG,OAAO,CAAC;QAAE,eAAe,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,WAAW,EAAE,IAAI,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,oBAAoB,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;+BAexI,MAAM,eAAe,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;kCAOxC,MAAM,QAAQ,MAAM,GAAG,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;0BAexG,MAAM,UAAU,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;iCAO/B,MAAM,SAAS,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;mCAO1C,MAAM,mBAAmB,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;8BAOpD,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;+BAYrB,OAAO,CAAC,MAAM,EAAE,CAAC;uBASzB,OAAO,CAAC,IAAI,CAAC;yBAmBX,OAAO,CAAC,IAAI,CAAC;gCAkCN,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;6BAQzB,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;oBAoCpC,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;mBAQ9B,MAAM,QAAQ,GAAG,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;mBA8DxC,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;qBAUvB,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;2BAkBhC,MAAM,YACJ;QACR,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,SAAS,CAAC,EAAE,IAAI,CAAC;QACjB,OAAO,CAAC,EAAE,IAAI,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GACA,OAAO,CAAC,GAAG,EAAE,CAAC;iCAuCkB,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;oCAQrC,MAAM,YAAY,MAAM,YAAY,OAAO,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;kCAW3E,MAAM,YAAY,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;qCAQzC,MAAM,GAAQ,OAAO,CAAC,WAAW,EAAE,CAAC;8BAahE,MAAM,QACR,OAAO,CAAC,IAAI,CAAC,aACR,MAAM,GAAG,MAAM,kBACV,MAAM,EAAE,GACvB,OAAO,CAAC,IAAI,CAAC;2BA8Ca,MAAM,UAAS,MAAM,GAAQ,OAAO,CAAC,GAAG,EAAE,CAAC;2BAW3C,MAAM,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC;+BAQxB,MAAM,UAAS,MAAM,GAAS,OAAO,CAAC,GAAG,EAAE,CAAC;8BAcnE,MAAM,UACN,MAAM,GAAG,IAAI,UACb,eAAe,GAAG,aAAa,GAAG,YAAY,GAAG,UAAU,WAC1D,GAAG,GACX,OAAO,CAAC,IAAI,CAAC;2BAQa,MAAM,UAAS,MAAM,GAAQ,OAAO,CAAC,GAAG,EAAE,CAAC;gCAWtC,MAAM,UAAS,MAAM,GAAS,OAAO,CAAC,GAAG,EAAE,CAAC;4BAchD,MAAM,UAAS,MAAM,GAAS,OAAO,CAAC,GAAG,EAAE,CAAC;yBAa/C,MAAM,aAAa,MAAM,UAAU,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;4BAiF7D,MAAM,GAAG,OAAO,CAAC;QAC7C,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,mBAAmB,EAAE,SAAS,GAAG,OAAO,CAAC;QACzC,eAAe,EAAE,MAAM,CAAC;QACxB,mBAAmB,EAAE,MAAM,CAAC;QAC5B,mBAAmB,EAAE,YAAY,GAAG,OAAO,CAAC;QAC5C,cAAc,EAAE,QAAQ,GAAG,WAAW,CAAC;QACvC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;KAC5B,GAAG,IAAI,CAAC;iCAkC0B,MAAM,SAAS,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;uCAStC,MAAM,eAAe,YAAY,GAAG,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;kCAShE,MAAM,UAAU,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;8BASvD,MAAM,QAAQ,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;8BASpC,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;+BASrB,OAAO,CAAC,MAAM,EAAE,CAAC;mCAab,MAAM,GAAG,OAAO,CAAC;QACpD,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,eAAe,EAAE,MAAM,CAAC;QACxB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,WAAW,EAAE,YAAY,GAAG,OAAO,CAAC;KACrC,CAAC;CAgDH,CAAC;AAEF,eAAe,OAAO,CAAC"}
1
+ {"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../../src/lib/db/postgres.ts"],"names":[],"mappings":"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"}
@@ -202,12 +202,13 @@ export const db = {
202
202
  return result.rows.map(toCamelCase);
203
203
  },
204
204
  async createGate(userId, data) {
205
- const result = await getPool().query(`INSERT INTO gates (user_id, name, description, task_type, model, system_prompt, allow_overrides, temperature, max_tokens, top_p, tags, routing_strategy, fallback_models, cost_weight, latency_weight, quality_weight, analysis_method, reanalysis_period, auto_apply_recommendations, task_analysis, response_format_enabled, response_format_type, response_format_schema, spending_limit, spending_limit_period, spending_enforcement)
206
- VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26) RETURNING *`, [
205
+ const result = await getPool().query(`INSERT INTO gates (user_id, name, description, task_type, task_subtype, model, system_prompt, allow_overrides, temperature, max_tokens, top_p, tags, routing_strategy, fallback_models, cost_weight, latency_weight, quality_weight, analysis_method, reanalysis_period, auto_apply_recommendations, task_analysis, response_format_enabled, response_format_type, response_format_schema, spending_limit, spending_limit_period, spending_enforcement)
206
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27) RETURNING *`, [
207
207
  userId,
208
208
  data.name,
209
209
  data.description,
210
210
  data.taskType,
211
+ data.taskSubtype || null,
211
212
  data.model,
212
213
  data.systemPrompt,
213
214
  data.allowOverrides ? JSON.stringify(data.allowOverrides) : null,
@@ -242,34 +243,36 @@ export const db = {
242
243
  name = COALESCE($2, name),
243
244
  description = COALESCE($3, description),
244
245
  task_type = COALESCE($4, task_type),
245
- model = COALESCE($5, model),
246
- system_prompt = COALESCE($6, system_prompt),
247
- allow_overrides = COALESCE($7, allow_overrides),
248
- temperature = COALESCE($8, temperature),
249
- max_tokens = COALESCE($9, max_tokens),
250
- top_p = COALESCE($10, top_p),
251
- tags = COALESCE($11, tags),
252
- routing_strategy = COALESCE($12, routing_strategy),
253
- fallback_models = COALESCE($13, fallback_models),
254
- cost_weight = COALESCE($14, cost_weight),
255
- latency_weight = COALESCE($15, latency_weight),
256
- quality_weight = COALESCE($16, quality_weight),
257
- analysis_method = COALESCE($17, analysis_method),
258
- reanalysis_period = COALESCE($18, reanalysis_period),
259
- auto_apply_recommendations = COALESCE($19, auto_apply_recommendations),
260
- task_analysis = COALESCE($20, task_analysis),
261
- response_format_enabled = COALESCE($21, response_format_enabled),
262
- response_format_type = COALESCE($22, response_format_type),
263
- response_format_schema = COALESCE($23, response_format_schema),
264
- spending_limit = COALESCE($24, spending_limit),
265
- spending_limit_period = COALESCE($25, spending_limit_period),
266
- spending_enforcement = COALESCE($26, spending_enforcement),
246
+ task_subtype = COALESCE($5, task_subtype),
247
+ model = COALESCE($6, model),
248
+ system_prompt = COALESCE($7, system_prompt),
249
+ allow_overrides = COALESCE($8, allow_overrides),
250
+ temperature = COALESCE($9, temperature),
251
+ max_tokens = COALESCE($10, max_tokens),
252
+ top_p = COALESCE($11, top_p),
253
+ tags = COALESCE($12, tags),
254
+ routing_strategy = COALESCE($13, routing_strategy),
255
+ fallback_models = COALESCE($14, fallback_models),
256
+ cost_weight = COALESCE($15, cost_weight),
257
+ latency_weight = COALESCE($16, latency_weight),
258
+ quality_weight = COALESCE($17, quality_weight),
259
+ analysis_method = COALESCE($18, analysis_method),
260
+ reanalysis_period = COALESCE($19, reanalysis_period),
261
+ auto_apply_recommendations = COALESCE($20, auto_apply_recommendations),
262
+ task_analysis = COALESCE($21, task_analysis),
263
+ response_format_enabled = COALESCE($22, response_format_enabled),
264
+ response_format_type = COALESCE($23, response_format_type),
265
+ response_format_schema = COALESCE($24, response_format_schema),
266
+ spending_limit = COALESCE($25, spending_limit),
267
+ spending_limit_period = COALESCE($26, spending_limit_period),
268
+ spending_enforcement = COALESCE($27, spending_enforcement),
267
269
  updated_at = NOW()
268
270
  WHERE id = $1 RETURNING *`, [
269
271
  id,
270
272
  data.name,
271
273
  data.description,
272
274
  data.taskType,
275
+ data.taskSubtype || null,
273
276
  data.model,
274
277
  data.systemPrompt,
275
278
  data.allowOverrides ? JSON.stringify(data.allowOverrides) : null,
@@ -291,7 +291,7 @@ async function testMultiProviderFallback() {
291
291
  };
292
292
  const modelsToTry = [
293
293
  'invalid-openai-model',
294
- 'claude-3-7-sonnet-20250219',
294
+ 'claude-sonnet-4-20250514',
295
295
  ];
296
296
  let chunkCount = 0;
297
297
  let fullContent = '';
@@ -138,7 +138,7 @@ async function testAnthropicBetaMode() {
138
138
  console.log('-'.repeat(80));
139
139
  const gateConfig = {
140
140
  ...baseGateConfig,
141
- model: 'claude-3-7-sonnet-20250219',
141
+ model: 'claude-sonnet-4-20250514',
142
142
  responseFormatEnabled: true,
143
143
  responseFormatType: 'json_object',
144
144
  };
@@ -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;AAylBpC,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;AAQpD,QAAA,MAAM,MAAM,EAAE,UAAqB,CAAC;AA4lBpC,eAAe,MAAM,CAAC"}
@@ -12,7 +12,7 @@ router.post('/', async (req, res) => {
12
12
  return;
13
13
  }
14
14
  try {
15
- const { name, description, taskType, model, systemPrompt, allowOverrides, temperature, maxTokens, topP, tags, routingStrategy, fallbackModels, costWeight, latencyWeight, qualityWeight, reanalysisPeriod, taskAnalysis, responseFormatEnabled, responseFormatType, responseFormatSchema, spendingLimit, spendingLimitPeriod, spendingEnforcement } = req.body;
15
+ const { name, description, taskType, taskSubtype, model, systemPrompt, allowOverrides, temperature, maxTokens, topP, tags, routingStrategy, fallbackModels, costWeight, latencyWeight, qualityWeight, reanalysisPeriod, taskAnalysis, responseFormatEnabled, responseFormatType, responseFormatSchema, spendingLimit, spendingLimitPeriod, spendingEnforcement } = req.body;
16
16
  if (!name || !model) {
17
17
  res.status(400).json({ error: 'bad_request', message: 'Missing required fields: name and model' });
18
18
  return;
@@ -30,6 +30,7 @@ router.post('/', async (req, res) => {
30
30
  name,
31
31
  description,
32
32
  taskType,
33
+ taskSubtype,
33
34
  model,
34
35
  systemPrompt,
35
36
  allowOverrides,
@@ -249,7 +250,7 @@ router.patch('/:id', async (req, res) => {
249
250
  return;
250
251
  }
251
252
  try {
252
- const { name, description, taskType, model, systemPrompt, allowOverrides, temperature, maxTokens, topP, tags, routingStrategy, fallbackModels, costWeight, latencyWeight, qualityWeight, analysisMethod, reanalysisPeriod, taskAnalysis, autoApplyRecommendations, responseFormatEnabled, responseFormatType, responseFormatSchema, spendingLimit, spendingLimitPeriod, spendingEnforcement } = req.body;
253
+ const { name, description, taskType, taskSubtype, model, systemPrompt, allowOverrides, temperature, maxTokens, topP, tags, routingStrategy, fallbackModels, costWeight, latencyWeight, qualityWeight, analysisMethod, reanalysisPeriod, taskAnalysis, autoApplyRecommendations, responseFormatEnabled, responseFormatType, responseFormatSchema, spendingLimit, spendingLimitPeriod, spendingEnforcement } = req.body;
253
254
  const existing = await db.getGateById(req.params.id);
254
255
  if (!existing) {
255
256
  res.status(404).json({ error: 'not_found', message: 'Gate not found' });
@@ -268,6 +269,7 @@ router.patch('/:id', async (req, res) => {
268
269
  name,
269
270
  description,
270
271
  taskType,
272
+ taskSubtype,
271
273
  model,
272
274
  systemPrompt,
273
275
  temperature,
@@ -292,6 +294,7 @@ router.patch('/:id', async (req, res) => {
292
294
  name,
293
295
  description,
294
296
  taskType,
297
+ taskSubtype,
295
298
  model,
296
299
  systemPrompt,
297
300
  allowOverrides,
@@ -118,7 +118,7 @@ router.post('/', async (req, res) => {
118
118
  return;
119
119
  }
120
120
  // Warn if gate is configured for a different task type
121
- if (gateConfig.taskType && gateConfig.taskType !== 'document') {
121
+ if (gateConfig.taskType && gateConfig.taskType !== 'ocr') {
122
122
  console.warn(`[Type Mismatch] Gate "${gateConfig.name}" (${gateConfig.id}) configured for taskType="${gateConfig.taskType}" ` +
123
123
  `but received request to /v3/ocr endpoint. Processing as OCR request.`);
124
124
  }
@@ -1 +1 @@
1
- {"version":3,"file":"base-adapter.d.ts","sourceRoot":"","sources":["../../../src/services/providers/base-adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"base-adapter.d.ts","sourceRoot":"","sources":["../../../src/services/providers/base-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,aAAa,EACb,IAAI,EACJ,WAAW,EACX,SAAS,EACT,YAAY,EACZ,UAAU,EACV,SAAS,EACT,WAAW,EACX,aAAa,EACb,aAAa,EACb,YAAY,EACZ,UAAU,EACV,cAAc,EACd,eAAe,EAChB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAGhE,OAAO,EAAE,eAAe,EAAE,CAAC;AAE3B,8BAAsB,mBAAmB;IACvC,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IACtC,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAE1B,SAAS,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC9C,SAAS,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAC5D,SAAS,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;IAC/D,SAAS,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAC9D,SAAS,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACxD,SAAS,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAC9D,SAAS,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAC1D,SAAS,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACxD,SAAS,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAC5D,SAAS,CAAC,qBAAqB,CAAC,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IAChE,SAAS,CAAC,qBAAqB,CAAC,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IAChE,SAAS,CAAC,sBAAsB,CAAC,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;IAElE,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAG7E,UAAU,CAAC,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC,aAAa,CAAC;IAEjF,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM;IAcrC,SAAS,CAAC,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS;IAQjE,SAAS,CAAC,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS;IAQ3D,SAAS,CAAC,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,GAAG,SAAS;IAQpE,SAAS,CAAC,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,GAAG,SAAS;IAQ9D,SAAS,CAAC,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS;IAQ3D,SAAS,CAAC,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS;IAQjE,SAAS,CAAC,gBAAgB,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,GAAG,SAAS;IAQvE,SAAS,CAAC,gBAAgB,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,GAAG,SAAS;IAQvE,SAAS,CAAC,iBAAiB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,GAAG,SAAS;IAQvE,SAAS,CAAC,eAAe,CAAC,oBAAoB,EAAE,MAAM,GAAG,YAAY;IAQrE,SAAS,CAAC,aAAa,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS;IAYxE,SAAS,CAAC,aAAa,CACrB,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,MAAM,GACvB,MAAM;IAWT,SAAS,CAAC,kBAAkB,CAC1B,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,MAAM,EACb,KAAK,GAAE,MAAU,GAChB,MAAM;IA2BT,SAAS,CAAC,kBAAkB,CAC1B,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,MAAM,EACjB,KAAK,GAAE,MAAU,GAChB,MAAM;CA8BV"}
@@ -93,24 +93,16 @@ export class BaseProviderAdapter {
93
93
  }
94
94
  calculateImageCost(model, quality, size, count = 1) {
95
95
  const modelInfo = getModel(model);
96
- if (!modelInfo)
96
+ if (!modelInfo || !('unitPricing' in modelInfo) || !modelInfo.unitPricing) {
97
97
  return 0;
98
- // Support new unitPricing format (per_image key) and legacy imagePricing
99
- let perImagePricing;
100
- if ('unitPricing' in modelInfo && modelInfo.unitPricing?.per_image) {
101
- perImagePricing = modelInfo.unitPricing.per_image;
102
98
  }
103
- else if ('imagePricing' in modelInfo && modelInfo.imagePricing) {
104
- perImagePricing = modelInfo.imagePricing;
99
+ const unitPricing = modelInfo.unitPricing;
100
+ // Flat-rate pricing (e.g. Google Imagen: unitPricing = 0.02)
101
+ if (typeof unitPricing === 'number') {
102
+ return unitPricing * count;
105
103
  }
106
- if (!perImagePricing)
107
- return 0;
108
- // Flat-rate pricing (e.g. Google Imagen models)
109
- if (typeof perImagePricing === 'number') {
110
- return perImagePricing * count;
111
- }
112
- // Build pricing key from quality and size (e.g., 'hd-1024x1024' or 'standard-1024x1024')
113
- const pricingTable = perImagePricing;
104
+ // Object pricing (e.g. DALL-E: unitPricing = { "hd-1024x1024": 0.08, ... })
105
+ const pricingTable = unitPricing;
114
106
  const pricingKey = quality && size ? `${quality}-${size}` : size || 'standard-1024x1024';
115
107
  const pricePerImage = pricingTable[pricingKey];
116
108
  if (!pricePerImage) {
@@ -122,15 +114,25 @@ export class BaseProviderAdapter {
122
114
  }
123
115
  calculateVideoCost(model, duration, count = 1) {
124
116
  const modelInfo = getModel(model);
125
- if (!modelInfo || !('videoPricing' in modelInfo) || !modelInfo.videoPricing) {
117
+ if (!modelInfo || !('unitPricing' in modelInfo) || !modelInfo.unitPricing) {
126
118
  return 0;
127
119
  }
128
- const videoPricing = modelInfo.videoPricing;
129
- // Video pricing might be per-second or per-video
130
- const pricePerUnit = videoPricing.perVideo || videoPricing.perSecond || 0;
131
- if (videoPricing.perSecond && duration) {
132
- return pricePerUnit * duration * count;
120
+ const unitPricing = modelInfo.unitPricing;
121
+ // Flat-rate pricing (e.g. unitPricing = 0.50 per video)
122
+ if (typeof unitPricing === 'number') {
123
+ return unitPricing * count;
124
+ }
125
+ // Object pricing with per_second or per_video keys
126
+ const pricing = unitPricing;
127
+ if (pricing.per_second && duration) {
128
+ return pricing.per_second * duration * count;
129
+ }
130
+ if (pricing.per_video) {
131
+ return pricing.per_video * count;
132
+ }
133
+ if (pricing.per_minute && duration) {
134
+ return pricing.per_minute * (duration / 60) * count;
133
135
  }
134
- return pricePerUnit * count;
136
+ return 0;
135
137
  }
136
138
  }
@@ -53,7 +53,7 @@ async function testImageGeneration() {
53
53
  console.log('Testing image generation...');
54
54
  const request = {
55
55
  gateId: 'test-gate',
56
- model: 'imagen-4.0-generate-001',
56
+ model: 'imagen-4.0-fast-generate-001',
57
57
  type: 'image',
58
58
  data: {
59
59
  prompt: 'A cute cat playing with a ball of yarn',
@@ -64,6 +64,10 @@ async function testImageGeneration() {
64
64
  console.log('Generated images:', response.images?.length);
65
65
  console.log('Image base64 length:', response.images?.[0]?.base64?.length);
66
66
  console.log('Latency:', response.latencyMs + 'ms');
67
+ console.log('Cost:', response.cost);
68
+ if (!response.cost || response.cost <= 0) {
69
+ throw new Error(`Expected image generation cost > 0, got ${response.cost}`);
70
+ }
67
71
  console.log('✅ Image generation test passed\n');
68
72
  }
69
73
  async function testEmbeddings() {
@@ -196,6 +200,14 @@ async function testVideoGeneration() {
196
200
  console.log('Video URL:', response.videos?.[0]?.url);
197
201
  console.log('Video duration:', response.videos?.[0]?.duration);
198
202
  console.log('Latency:', response.latencyMs + 'ms');
203
+ console.log('Cost:', response.cost);
204
+ // Note: video cost may be 0 if unitPricing is not set for this model in the registry
205
+ if (response.cost && response.cost > 0) {
206
+ console.log('✅ Video cost calculation working');
207
+ }
208
+ else {
209
+ console.warn('⚠️ Video cost is 0 (unitPricing may not be set for this model)');
210
+ }
199
211
  console.log('✅ Video generation test passed\n');
200
212
  }
201
213
  async function runTests() {
@@ -203,9 +215,6 @@ async function runTests() {
203
215
  console.log('Chat completion tests...');
204
216
  await testChatCompletion();
205
217
  await testChatWithVision();
206
- console.log('Embeddings...');
207
- await testEmbeddings();
208
- await testEmbeddingsMultiple();
209
218
  console.log('Image generation...');
210
219
  await testImageGeneration();
211
220
  console.log('Text-to-speech...');
@@ -214,6 +223,9 @@ async function runTests() {
214
223
  await testVideoGeneration();
215
224
  console.log('Tool calling...');
216
225
  await testToolCalling();
226
+ console.log('Embeddings...');
227
+ await testEmbeddings();
228
+ await testEmbeddingsMultiple();
217
229
  console.log('✅ All tests passed!');
218
230
  }
219
231
  catch (error) {
@@ -14,7 +14,7 @@ async function testJsonObjectMode() {
14
14
  console.log('-'.repeat(80));
15
15
  const request = {
16
16
  gateId: 'test-gate',
17
- model: 'gpt-4o-mini',
17
+ model: 'gpt-4o',
18
18
  type: 'chat',
19
19
  data: {
20
20
  messages: [
@@ -118,7 +118,7 @@ async function testTextMode() {
118
118
  console.log('-'.repeat(80));
119
119
  const request = {
120
120
  gateId: 'test-gate',
121
- model: 'gpt-4o-mini',
121
+ model: 'gpt-4o',
122
122
  type: 'chat',
123
123
  data: {
124
124
  messages: [
@@ -8,7 +8,7 @@ async function testChatCompletion() {
8
8
  const request = {
9
9
  gateId: 'test-gate',
10
10
  type: 'chat',
11
- model: 'mistral-small-latest',
11
+ model: 'mistral-small-2501',
12
12
  data: {
13
13
  messages: [
14
14
  {
@@ -33,7 +33,7 @@ async function testChatWithSystemPrompt() {
33
33
  const request = {
34
34
  gateId: 'test-gate',
35
35
  type: 'chat',
36
- model: 'mistral-small-latest',
36
+ model: 'mistral-small-2501',
37
37
  data: {
38
38
  systemPrompt: 'You are a helpful assistant that responds in JSON format only.',
39
39
  messages: [
@@ -56,7 +56,7 @@ async function testChatWithTools() {
56
56
  const request = {
57
57
  gateId: 'test-gate',
58
58
  type: 'chat',
59
- model: 'mistral-small-latest',
59
+ model: 'mistral-small-2501',
60
60
  data: {
61
61
  messages: [
62
62
  {
@@ -104,7 +104,7 @@ async function testToolResponse() {
104
104
  const initialRequest = {
105
105
  gateId: 'test-gate',
106
106
  type: 'chat',
107
- model: 'mistral-small-latest',
107
+ model: 'mistral-small-2501',
108
108
  data: {
109
109
  messages: [
110
110
  {
@@ -145,7 +145,7 @@ async function testToolResponse() {
145
145
  const followUpRequest = {
146
146
  gateId: 'test-gate',
147
147
  type: 'chat',
148
- model: 'mistral-small-latest',
148
+ model: 'mistral-small-2501',
149
149
  data: {
150
150
  messages: [
151
151
  {
@@ -226,7 +226,7 @@ async function testResponseFormat() {
226
226
  const request = {
227
227
  gateId: 'test-gate',
228
228
  type: 'chat',
229
- model: 'mistral-small-latest',
229
+ model: 'mistral-small-2501',
230
230
  data: {
231
231
  messages: [
232
232
  {
@@ -247,7 +247,7 @@ async function testMultiTurn() {
247
247
  const request = {
248
248
  gateId: 'test-gate',
249
249
  type: 'chat',
250
- model: 'mistral-small-latest',
250
+ model: 'mistral-small-2501',
251
251
  data: {
252
252
  messages: [
253
253
  {
@@ -297,7 +297,7 @@ async function testUnsupportedModality() {
297
297
  const request = {
298
298
  gateId: 'test-gate',
299
299
  type: 'image',
300
- model: 'mistral-large-latest',
300
+ model: 'mistral-large-2512',
301
301
  data: {
302
302
  prompt: 'A sunset over the ocean',
303
303
  },
@@ -4,7 +4,7 @@ async function testChatCompletion() {
4
4
  console.log('Testing chat completion...');
5
5
  const request = {
6
6
  gateId: 'test-gate',
7
- model: 'gpt-4o-mini',
7
+ model: 'gpt-4o',
8
8
  type: 'chat',
9
9
  data: {
10
10
  messages: [
@@ -26,7 +26,7 @@ async function testChatWithVision() {
26
26
  console.log('Testing chat with vision...');
27
27
  const request = {
28
28
  gateId: 'test-gate',
29
- model: 'gpt-4o-mini',
29
+ model: 'gpt-4o',
30
30
  type: 'chat',
31
31
  data: {
32
32
  messages: [
@@ -64,6 +64,10 @@ async function testImageGeneration() {
64
64
  console.log('Generated images:', response.images?.length);
65
65
  console.log('Image URL:', response.images?.[0]?.url);
66
66
  console.log('Revised prompt:', response.images?.[0]?.revisedPrompt);
67
+ console.log('Cost:', response.cost);
68
+ if (!response.cost || response.cost <= 0) {
69
+ throw new Error(`Expected image generation cost > 0, got ${response.cost}`);
70
+ }
67
71
  console.log('✅ Image generation test passed\n');
68
72
  }
69
73
  async function testEmbeddings() {
@@ -105,7 +109,7 @@ async function testToolCalling() {
105
109
  // Step 1: Initial request with tool available
106
110
  const request = {
107
111
  gateId: 'test-gate',
108
- model: 'gpt-4o-mini',
112
+ model: 'gpt-4o',
109
113
  type: 'chat',
110
114
  data: {
111
115
  messages: [
@@ -146,7 +150,7 @@ async function testToolCalling() {
146
150
  // Step 2: Send tool response back
147
151
  const toolResponseRequest = {
148
152
  gateId: 'test-gate',
149
- model: 'gpt-4o-mini',
153
+ model: 'gpt-4o',
150
154
  type: 'chat',
151
155
  data: {
152
156
  messages: [
@@ -174,7 +178,7 @@ async function testContentAndToolCalls() {
174
178
  // This tests the fix we made - assistant messages can have BOTH content and toolCalls
175
179
  const request = {
176
180
  gateId: 'test-gate',
177
- model: 'gpt-4o-mini',
181
+ model: 'gpt-4o',
178
182
  type: 'chat',
179
183
  data: {
180
184
  messages: [
@@ -4,7 +4,7 @@ async function testChatStreamingBasic() {
4
4
  console.log('Testing basic chat streaming...');
5
5
  const request = {
6
6
  gateId: 'test-gate',
7
- model: 'gpt-4o-mini',
7
+ model: 'gpt-4o',
8
8
  type: 'chat',
9
9
  data: {
10
10
  messages: [
@@ -48,7 +48,7 @@ async function testChatStreamingWithToolCalls() {
48
48
  console.log('Testing chat streaming with tool calls...');
49
49
  const request = {
50
50
  gateId: 'test-gate',
51
- model: 'gpt-4o-mini',
51
+ model: 'gpt-4o',
52
52
  type: 'chat',
53
53
  data: {
54
54
  messages: [
@@ -1 +1 @@
1
- {"version":3,"file":"task-analysis.d.ts","sourceRoot":"","sources":["../../src/services/task-analysis.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAmC,MAAM,eAAe,CAAC;AA4D9E,wBAAsB,WAAW,CAC/B,WAAW,EAAE,MAAM,EACnB,eAAe,CAAC,EAAE;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B,GACA,OAAO,CAAC,YAAY,CAAC,CA6HvB"}
1
+ {"version":3,"file":"task-analysis.d.ts","sourceRoot":"","sources":["../../src/services/task-analysis.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAmC,MAAM,eAAe,CAAC;AA6D9E,wBAAsB,WAAW,CAC/B,WAAW,EAAE,MAAM,EACnB,eAAe,CAAC,EAAE;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B,GACA,OAAO,CAAC,YAAY,CAAC,CA8HvB"}
@@ -14,7 +14,8 @@ AVAILABLE TASK TYPES:
14
14
  - tts: Text-to-speech, voice synthesis
15
15
  - stt: Speech-to-text, audio transcription
16
16
  - embeddings: Text embeddings, semantic search
17
- - document: Document processing, OCR
17
+ - ocr: Document processing, OCR
18
+ - moderation: Content moderation
18
19
  - responses: Complex reasoning tasks (o3-pro style models)
19
20
  - language-completion: Legacy text completion
20
21
 
@@ -39,7 +40,7 @@ Return ONLY the task type as a single word, nothing else.`;
39
40
  throw new Error('Unexpected response type from Claude');
40
41
  }
41
42
  const detectedType = responseContent.text.trim().toLowerCase();
42
- const validTypes = ['chat', 'image', 'video', 'audio', 'tts', 'stt', 'embeddings', 'document', 'responses', 'language-completion'];
43
+ const validTypes = ['chat', 'image', 'video', 'audio', 'tts', 'stt', 'embeddings', 'ocr', 'moderation', 'responses', 'language-completion'];
43
44
  if (validTypes.includes(detectedType)) {
44
45
  return detectedType;
45
46
  }
@@ -99,6 +100,7 @@ USER PREFERENCES (0.0 = doesn't care, 1.0 = very important):
99
100
  Analyze this task and recommend the BEST models from our registry that match BOTH the task requirements AND user preferences.
100
101
 
101
102
  Consider:
103
+ - Model subtype (prefer "reasoning" subtype for complex multi-step reasoning, "code" subtype for programming, "realtime" subtype for low-latency streaming)
102
104
  - Math benchmarks (for quantitative tasks)
103
105
  - Coding benchmarks (for programming tasks)
104
106
  - Intelligence scores (for reasoning)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@layer-ai/core",
3
- "version": "2.0.47",
3
+ "version": "2.0.49",
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": "^2.5.11"
39
+ "@layer-ai/sdk": "^2.5.14"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@types/bcryptjs": "^2.4.6",