@layer-ai/core 2.0.22 → 2.0.24
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/migrations/008_add_gate_spending_limits.sql +23 -0
- package/dist/lib/db/postgres.d.ts +21 -0
- package/dist/lib/db/postgres.d.ts.map +1 -1
- package/dist/lib/db/postgres.js +95 -0
- package/dist/lib/gate-spending-tracker.d.ts +17 -0
- package/dist/lib/gate-spending-tracker.d.ts.map +1 -0
- package/dist/lib/gate-spending-tracker.js +57 -0
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -23,4 +23,5 @@ export * from './services/task-analysis.js';
|
|
|
23
23
|
export { PROVIDER, PROVIDERS, type Provider, callAdapter, normalizeModelId, getProviderForModel } from './lib/provider-factory.js';
|
|
24
24
|
export { spendingTracker } from './lib/spending-tracker.js';
|
|
25
25
|
export { spendingJobs } from './lib/spending-jobs.js';
|
|
26
|
+
export { gateSpendingTracker } from './lib/gate-spending-tracker.js';
|
|
26
27
|
//# sourceMappingURL=index.d.ts.map
|
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,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AACnF,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAGpE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAGpE,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAG1D,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;AAGnI,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,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,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AACnF,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAGpE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAGpE,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAG1D,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;AAGnI,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -37,3 +37,4 @@ export { PROVIDER, PROVIDERS, callAdapter, normalizeModelId, getProviderForModel
|
|
|
37
37
|
// Spending Management
|
|
38
38
|
export { spendingTracker } from './lib/spending-tracker.js';
|
|
39
39
|
export { spendingJobs } from './lib/spending-jobs.js';
|
|
40
|
+
export { gateSpendingTracker } from './lib/gate-spending-tracker.js';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
-- Migration: Add gate-level spending limits
|
|
2
|
+
-- Description: Add spending limit tracking fields to gates table for per-gate cost controls
|
|
3
|
+
|
|
4
|
+
-- Add spending limit fields to gates table
|
|
5
|
+
ALTER TABLE gates
|
|
6
|
+
ADD COLUMN IF NOT EXISTS spending_limit DECIMAL(10, 2) DEFAULT NULL,
|
|
7
|
+
ADD COLUMN IF NOT EXISTS spending_limit_period VARCHAR(20) DEFAULT 'monthly' CHECK (spending_limit_period IN ('monthly', 'daily')),
|
|
8
|
+
ADD COLUMN IF NOT EXISTS spending_current DECIMAL(10, 2) DEFAULT 0,
|
|
9
|
+
ADD COLUMN IF NOT EXISTS spending_period_start TIMESTAMP DEFAULT NOW(),
|
|
10
|
+
ADD COLUMN IF NOT EXISTS spending_enforcement VARCHAR(20) DEFAULT 'alert_only' CHECK (spending_enforcement IN ('alert_only', 'block')),
|
|
11
|
+
ADD COLUMN IF NOT EXISTS spending_status VARCHAR(20) DEFAULT 'active' CHECK (spending_status IN ('active', 'suspended'));
|
|
12
|
+
|
|
13
|
+
-- Create index for faster spending queries
|
|
14
|
+
CREATE INDEX IF NOT EXISTS idx_gates_spending_status ON gates(spending_status);
|
|
15
|
+
CREATE INDEX IF NOT EXISTS idx_gates_spending_period ON gates(spending_period_start);
|
|
16
|
+
|
|
17
|
+
-- Add comment explaining the fields
|
|
18
|
+
COMMENT ON COLUMN gates.spending_limit IS 'Maximum spending allowed per period in USD (NULL = no limit)';
|
|
19
|
+
COMMENT ON COLUMN gates.spending_limit_period IS 'Period for spending limit: monthly or daily';
|
|
20
|
+
COMMENT ON COLUMN gates.spending_current IS 'Current period spending in USD';
|
|
21
|
+
COMMENT ON COLUMN gates.spending_period_start IS 'Start of current spending period';
|
|
22
|
+
COMMENT ON COLUMN gates.spending_enforcement IS 'How to enforce limits: alert_only or block';
|
|
23
|
+
COMMENT ON COLUMN gates.spending_status IS 'Gate spending status: active or suspended';
|
|
@@ -78,6 +78,27 @@ export declare const db: {
|
|
|
78
78
|
getAllGatesActivity(userId: string, limit?: number): Promise<any[]>;
|
|
79
79
|
getGateActivity(gateId: string, limit?: number): Promise<any[]>;
|
|
80
80
|
rollbackGate(gateId: string, historyId: string, userId: string): Promise<Gate | null>;
|
|
81
|
+
getGateSpending(gateId: string): Promise<{
|
|
82
|
+
spendingLimit: number | null;
|
|
83
|
+
spendingLimitPeriod: "monthly" | "daily";
|
|
84
|
+
spendingCurrent: number;
|
|
85
|
+
spendingPeriodStart: string;
|
|
86
|
+
spendingEnforcement: "alert_only" | "block";
|
|
87
|
+
spendingStatus: "active" | "suspended";
|
|
88
|
+
percentUsed: number | null;
|
|
89
|
+
} | null>;
|
|
90
|
+
setGateSpendingLimit(gateId: string, limit: number | null): Promise<void>;
|
|
91
|
+
setGateSpendingEnforcement(gateId: string, enforcement: "alert_only" | "block"): Promise<void>;
|
|
92
|
+
setGateSpendingPeriod(gateId: string, period: "monthly" | "daily"): Promise<void>;
|
|
93
|
+
trackGateSpending(gateId: string, cost: number): Promise<void>;
|
|
94
|
+
resetGateSpending(gateId: string): Promise<void>;
|
|
95
|
+
checkGateSpendingLimit(gateId: string): Promise<{
|
|
96
|
+
allowed: boolean;
|
|
97
|
+
reason?: string;
|
|
98
|
+
currentSpending: number;
|
|
99
|
+
limit: number | null;
|
|
100
|
+
enforcement: "alert_only" | "block";
|
|
101
|
+
}>;
|
|
81
102
|
};
|
|
82
103
|
export default getPool;
|
|
83
104
|
//# sourceMappingURL=postgres.d.ts.map
|
|
@@ -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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"}
|
package/dist/lib/db/postgres.js
CHANGED
|
@@ -504,5 +504,100 @@ export const db = {
|
|
|
504
504
|
}
|
|
505
505
|
return rolledBackGate;
|
|
506
506
|
},
|
|
507
|
+
// Gate spending management
|
|
508
|
+
async getGateSpending(gateId) {
|
|
509
|
+
const result = await getPool().query(`SELECT
|
|
510
|
+
spending_limit,
|
|
511
|
+
spending_limit_period,
|
|
512
|
+
spending_current,
|
|
513
|
+
spending_period_start,
|
|
514
|
+
spending_enforcement,
|
|
515
|
+
spending_status
|
|
516
|
+
FROM gates
|
|
517
|
+
WHERE id = $1 AND deleted_at IS NULL`, [gateId]);
|
|
518
|
+
if (result.rows.length === 0) {
|
|
519
|
+
return null;
|
|
520
|
+
}
|
|
521
|
+
const row = result.rows[0];
|
|
522
|
+
const spendingLimit = row.spending_limit ? parseFloat(row.spending_limit) : null;
|
|
523
|
+
const spendingCurrent = parseFloat(row.spending_current || 0);
|
|
524
|
+
const percentUsed = spendingLimit ? Math.round((spendingCurrent / spendingLimit) * 100) : null;
|
|
525
|
+
return {
|
|
526
|
+
spendingLimit,
|
|
527
|
+
spendingLimitPeriod: row.spending_limit_period,
|
|
528
|
+
spendingCurrent,
|
|
529
|
+
spendingPeriodStart: row.spending_period_start,
|
|
530
|
+
spendingEnforcement: row.spending_enforcement,
|
|
531
|
+
spendingStatus: row.spending_status,
|
|
532
|
+
percentUsed,
|
|
533
|
+
};
|
|
534
|
+
},
|
|
535
|
+
async setGateSpendingLimit(gateId, limit) {
|
|
536
|
+
await getPool().query(`UPDATE gates
|
|
537
|
+
SET spending_limit = $2, updated_at = NOW()
|
|
538
|
+
WHERE id = $1`, [gateId, limit]);
|
|
539
|
+
},
|
|
540
|
+
async setGateSpendingEnforcement(gateId, enforcement) {
|
|
541
|
+
await getPool().query(`UPDATE gates
|
|
542
|
+
SET spending_enforcement = $2, updated_at = NOW()
|
|
543
|
+
WHERE id = $1`, [gateId, enforcement]);
|
|
544
|
+
},
|
|
545
|
+
async setGateSpendingPeriod(gateId, period) {
|
|
546
|
+
await getPool().query(`UPDATE gates
|
|
547
|
+
SET spending_limit_period = $2, spending_period_start = NOW(), spending_current = 0, updated_at = NOW()
|
|
548
|
+
WHERE id = $1`, [gateId, period]);
|
|
549
|
+
},
|
|
550
|
+
async trackGateSpending(gateId, cost) {
|
|
551
|
+
await getPool().query(`UPDATE gates
|
|
552
|
+
SET spending_current = spending_current + $2, updated_at = NOW()
|
|
553
|
+
WHERE id = $1`, [gateId, cost]);
|
|
554
|
+
},
|
|
555
|
+
async resetGateSpending(gateId) {
|
|
556
|
+
await getPool().query(`UPDATE gates
|
|
557
|
+
SET spending_current = 0, spending_period_start = NOW(), updated_at = NOW()
|
|
558
|
+
WHERE id = $1`, [gateId]);
|
|
559
|
+
},
|
|
560
|
+
async checkGateSpendingLimit(gateId) {
|
|
561
|
+
const spending = await this.getGateSpending(gateId);
|
|
562
|
+
if (!spending) {
|
|
563
|
+
return { allowed: true, currentSpending: 0, limit: null, enforcement: 'alert_only' };
|
|
564
|
+
}
|
|
565
|
+
// If suspended, block regardless of enforcement type
|
|
566
|
+
if (spending.spendingStatus === 'suspended') {
|
|
567
|
+
return {
|
|
568
|
+
allowed: false,
|
|
569
|
+
reason: 'Gate spending is suspended',
|
|
570
|
+
currentSpending: spending.spendingCurrent,
|
|
571
|
+
limit: spending.spendingLimit,
|
|
572
|
+
enforcement: spending.spendingEnforcement,
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
// If no limit set, allow
|
|
576
|
+
if (!spending.spendingLimit) {
|
|
577
|
+
return {
|
|
578
|
+
allowed: true,
|
|
579
|
+
currentSpending: spending.spendingCurrent,
|
|
580
|
+
limit: null,
|
|
581
|
+
enforcement: spending.spendingEnforcement,
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
// Check if limit exceeded
|
|
585
|
+
const limitExceeded = spending.spendingCurrent >= spending.spendingLimit;
|
|
586
|
+
if (limitExceeded && spending.spendingEnforcement === 'block') {
|
|
587
|
+
return {
|
|
588
|
+
allowed: false,
|
|
589
|
+
reason: `Gate spending limit of $${spending.spendingLimit.toFixed(2)} exceeded`,
|
|
590
|
+
currentSpending: spending.spendingCurrent,
|
|
591
|
+
limit: spending.spendingLimit,
|
|
592
|
+
enforcement: spending.spendingEnforcement,
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
return {
|
|
596
|
+
allowed: true,
|
|
597
|
+
currentSpending: spending.spendingCurrent,
|
|
598
|
+
limit: spending.spendingLimit,
|
|
599
|
+
enforcement: spending.spendingEnforcement,
|
|
600
|
+
};
|
|
601
|
+
},
|
|
507
602
|
};
|
|
508
603
|
export default getPool;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
interface GateSpendingUpdate {
|
|
2
|
+
gateId: string;
|
|
3
|
+
cost: number;
|
|
4
|
+
exceeded?: boolean;
|
|
5
|
+
newSpending?: number;
|
|
6
|
+
blocked?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare const gateSpendingTracker: {
|
|
9
|
+
trackSpending(gateId: string, cost: number): Promise<GateSpendingUpdate>;
|
|
10
|
+
checkAlertThresholds(gateId: string, currentSpending: number, limit: number | null): Promise<void>;
|
|
11
|
+
checkBeforeRequest(gateId: string): Promise<{
|
|
12
|
+
allowed: boolean;
|
|
13
|
+
reason?: string;
|
|
14
|
+
}>;
|
|
15
|
+
};
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=gate-spending-tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate-spending-tracker.d.ts","sourceRoot":"","sources":["../../src/lib/gate-spending-tracker.ts"],"names":[],"mappings":"AAEA,UAAU,kBAAkB;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,mBAAmB;0BACF,MAAM,QAAQ,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;iCAsCpE,MAAM,mBACG,MAAM,SAChB,MAAM,GAAG,IAAI,GACnB,OAAO,CAAC,IAAI,CAAC;+BAiBiB,MAAM,GAAG,OAAO,CAAC;QAChD,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CAYH,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { db } from './db/postgres.js';
|
|
2
|
+
export const gateSpendingTracker = {
|
|
3
|
+
async trackSpending(gateId, cost) {
|
|
4
|
+
try {
|
|
5
|
+
const limitCheck = await db.checkGateSpendingLimit(gateId);
|
|
6
|
+
if (!limitCheck.allowed) {
|
|
7
|
+
return {
|
|
8
|
+
gateId,
|
|
9
|
+
cost,
|
|
10
|
+
blocked: true,
|
|
11
|
+
newSpending: limitCheck.currentSpending,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
await db.trackGateSpending(gateId, cost);
|
|
15
|
+
const spendingInfo = await db.getGateSpending(gateId);
|
|
16
|
+
if (!spendingInfo) {
|
|
17
|
+
return { gateId, cost };
|
|
18
|
+
}
|
|
19
|
+
const { spendingLimit, spendingCurrent, spendingEnforcement } = spendingInfo;
|
|
20
|
+
const exceeded = spendingLimit !== null && spendingCurrent > spendingLimit;
|
|
21
|
+
await this.checkAlertThresholds(gateId, spendingCurrent, spendingLimit);
|
|
22
|
+
return {
|
|
23
|
+
gateId,
|
|
24
|
+
cost,
|
|
25
|
+
exceeded,
|
|
26
|
+
newSpending: spendingCurrent,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
console.error('[Gate Spending] Error tracking spending:', error);
|
|
31
|
+
return { gateId, cost };
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
async checkAlertThresholds(gateId, currentSpending, limit) {
|
|
35
|
+
if (!limit || limit === 0)
|
|
36
|
+
return;
|
|
37
|
+
const percentage = (currentSpending / limit) * 100;
|
|
38
|
+
const thresholds = [80, 90, 100];
|
|
39
|
+
for (const threshold of thresholds) {
|
|
40
|
+
if (percentage >= threshold && percentage < threshold + 10) {
|
|
41
|
+
console.log(`[Gate Spending] Alert: Gate ${gateId} at ${threshold}% of limit ($${currentSpending}/$${limit})`);
|
|
42
|
+
// TODO: Send email/webhook alert
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
async checkBeforeRequest(gateId) {
|
|
48
|
+
const limitCheck = await db.checkGateSpendingLimit(gateId);
|
|
49
|
+
if (!limitCheck.allowed) {
|
|
50
|
+
return {
|
|
51
|
+
allowed: false,
|
|
52
|
+
reason: limitCheck.reason || 'Gate spending limit exceeded',
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
return { allowed: true };
|
|
56
|
+
},
|
|
57
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@layer-ai/core",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.24",
|
|
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.
|
|
39
|
+
"@layer-ai/sdk": "^2.5.9"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@types/bcryptjs": "^2.4.6",
|