bopodev-db 0.1.13 → 0.1.14
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/.turbo/turbo-build.log +1 -1
- package/LICENSE +1 -1
- package/dist/repositories.d.ts +47 -3
- package/dist/schema.d.ts +456 -0
- package/package.json +1 -1
- package/src/bootstrap.ts +34 -0
- package/src/repositories.ts +75 -0
- package/src/schema.ts +24 -9
package/.turbo/turbo-build.log
CHANGED
package/LICENSE
CHANGED
package/dist/repositories.d.ts
CHANGED
|
@@ -319,7 +319,7 @@ export declare function createAgent(db: BopoDb, input: {
|
|
|
319
319
|
managerAgentId?: string | null;
|
|
320
320
|
role: string;
|
|
321
321
|
name: string;
|
|
322
|
-
providerType: "claude_code" | "codex" | "cursor" | "opencode" | "openai_api" | "anthropic_api" | "http" | "shell";
|
|
322
|
+
providerType: "claude_code" | "codex" | "cursor" | "opencode" | "gemini_cli" | "openai_api" | "anthropic_api" | "http" | "shell";
|
|
323
323
|
heartbeatCron: string;
|
|
324
324
|
monthlyBudgetUsd: string;
|
|
325
325
|
canHireAgents?: boolean;
|
|
@@ -341,7 +341,7 @@ export declare function createAgent(db: BopoDb, input: {
|
|
|
341
341
|
managerAgentId?: string | null;
|
|
342
342
|
role: string;
|
|
343
343
|
name: string;
|
|
344
|
-
providerType: "claude_code" | "codex" | "cursor" | "opencode" | "openai_api" | "anthropic_api" | "http" | "shell";
|
|
344
|
+
providerType: "claude_code" | "codex" | "cursor" | "opencode" | "gemini_cli" | "openai_api" | "anthropic_api" | "http" | "shell";
|
|
345
345
|
heartbeatCron: string;
|
|
346
346
|
monthlyBudgetUsd: string;
|
|
347
347
|
canHireAgents?: boolean;
|
|
@@ -392,7 +392,7 @@ export declare function updateAgent(db: BopoDb, input: {
|
|
|
392
392
|
managerAgentId?: string | null;
|
|
393
393
|
role?: string;
|
|
394
394
|
name?: string;
|
|
395
|
-
providerType?: "claude_code" | "codex" | "cursor" | "opencode" | "openai_api" | "anthropic_api" | "http" | "shell";
|
|
395
|
+
providerType?: "claude_code" | "codex" | "cursor" | "opencode" | "gemini_cli" | "openai_api" | "anthropic_api" | "http" | "shell";
|
|
396
396
|
status?: string;
|
|
397
397
|
heartbeatCron?: string;
|
|
398
398
|
monthlyBudgetUsd?: string;
|
|
@@ -514,6 +514,10 @@ export declare function clearApprovalInboxDismissed(db: BopoDb, input: {
|
|
|
514
514
|
export declare function appendCost(db: BopoDb, input: {
|
|
515
515
|
companyId: string;
|
|
516
516
|
providerType: string;
|
|
517
|
+
runtimeModelId?: string | null;
|
|
518
|
+
pricingProviderType?: string | null;
|
|
519
|
+
pricingModelId?: string | null;
|
|
520
|
+
pricingSource?: "exact" | "missing" | null;
|
|
517
521
|
tokenInput: number;
|
|
518
522
|
tokenOutput: number;
|
|
519
523
|
usdCost: string;
|
|
@@ -528,6 +532,10 @@ export declare function listCostEntries(db: BopoDb, companyId: string, limit?: n
|
|
|
528
532
|
issueId: string | null;
|
|
529
533
|
agentId: string | null;
|
|
530
534
|
providerType: string;
|
|
535
|
+
runtimeModelId: string | null;
|
|
536
|
+
pricingProviderType: string | null;
|
|
537
|
+
pricingModelId: string | null;
|
|
538
|
+
pricingSource: string | null;
|
|
531
539
|
tokenInput: number;
|
|
532
540
|
tokenOutput: number;
|
|
533
541
|
usdCost: string;
|
|
@@ -685,3 +693,39 @@ export declare function listPluginRuns(db: BopoDb, input: {
|
|
|
685
693
|
diagnosticsJson: string;
|
|
686
694
|
createdAt: Date;
|
|
687
695
|
}[]>;
|
|
696
|
+
export declare function listModelPricing(db: BopoDb, companyId: string): Promise<{
|
|
697
|
+
companyId: string;
|
|
698
|
+
providerType: string;
|
|
699
|
+
modelId: string;
|
|
700
|
+
displayName: string | null;
|
|
701
|
+
inputUsdPer1M: string;
|
|
702
|
+
outputUsdPer1M: string;
|
|
703
|
+
currency: string;
|
|
704
|
+
updatedAt: Date;
|
|
705
|
+
updatedBy: string | null;
|
|
706
|
+
}[]>;
|
|
707
|
+
export declare function getModelPricing(db: BopoDb, input: {
|
|
708
|
+
companyId: string;
|
|
709
|
+
providerType: string;
|
|
710
|
+
modelId: string;
|
|
711
|
+
}): Promise<{
|
|
712
|
+
companyId: string;
|
|
713
|
+
providerType: string;
|
|
714
|
+
modelId: string;
|
|
715
|
+
displayName: string | null;
|
|
716
|
+
inputUsdPer1M: string;
|
|
717
|
+
outputUsdPer1M: string;
|
|
718
|
+
currency: string;
|
|
719
|
+
updatedAt: Date;
|
|
720
|
+
updatedBy: string | null;
|
|
721
|
+
} | null>;
|
|
722
|
+
export declare function upsertModelPricing(db: BopoDb, input: {
|
|
723
|
+
companyId: string;
|
|
724
|
+
providerType: string;
|
|
725
|
+
modelId: string;
|
|
726
|
+
displayName?: string | null;
|
|
727
|
+
inputUsdPer1M?: string | null;
|
|
728
|
+
outputUsdPer1M?: string | null;
|
|
729
|
+
currency?: string | null;
|
|
730
|
+
updatedBy?: string | null;
|
|
731
|
+
}): Promise<void>;
|
package/dist/schema.d.ts
CHANGED
|
@@ -2296,6 +2296,74 @@ export declare const costLedger: import("drizzle-orm/pg-core").PgTableWithColumn
|
|
|
2296
2296
|
identity: undefined;
|
|
2297
2297
|
generated: undefined;
|
|
2298
2298
|
}, {}, {}>;
|
|
2299
|
+
runtimeModelId: import("drizzle-orm/pg-core").PgColumn<{
|
|
2300
|
+
name: "runtime_model_id";
|
|
2301
|
+
tableName: "cost_ledger";
|
|
2302
|
+
dataType: "string";
|
|
2303
|
+
columnType: "PgText";
|
|
2304
|
+
data: string;
|
|
2305
|
+
driverParam: string;
|
|
2306
|
+
notNull: false;
|
|
2307
|
+
hasDefault: false;
|
|
2308
|
+
isPrimaryKey: false;
|
|
2309
|
+
isAutoincrement: false;
|
|
2310
|
+
hasRuntimeDefault: false;
|
|
2311
|
+
enumValues: [string, ...string[]];
|
|
2312
|
+
baseColumn: never;
|
|
2313
|
+
identity: undefined;
|
|
2314
|
+
generated: undefined;
|
|
2315
|
+
}, {}, {}>;
|
|
2316
|
+
pricingProviderType: import("drizzle-orm/pg-core").PgColumn<{
|
|
2317
|
+
name: "pricing_provider_type";
|
|
2318
|
+
tableName: "cost_ledger";
|
|
2319
|
+
dataType: "string";
|
|
2320
|
+
columnType: "PgText";
|
|
2321
|
+
data: string;
|
|
2322
|
+
driverParam: string;
|
|
2323
|
+
notNull: false;
|
|
2324
|
+
hasDefault: false;
|
|
2325
|
+
isPrimaryKey: false;
|
|
2326
|
+
isAutoincrement: false;
|
|
2327
|
+
hasRuntimeDefault: false;
|
|
2328
|
+
enumValues: [string, ...string[]];
|
|
2329
|
+
baseColumn: never;
|
|
2330
|
+
identity: undefined;
|
|
2331
|
+
generated: undefined;
|
|
2332
|
+
}, {}, {}>;
|
|
2333
|
+
pricingModelId: import("drizzle-orm/pg-core").PgColumn<{
|
|
2334
|
+
name: "pricing_model_id";
|
|
2335
|
+
tableName: "cost_ledger";
|
|
2336
|
+
dataType: "string";
|
|
2337
|
+
columnType: "PgText";
|
|
2338
|
+
data: string;
|
|
2339
|
+
driverParam: string;
|
|
2340
|
+
notNull: false;
|
|
2341
|
+
hasDefault: false;
|
|
2342
|
+
isPrimaryKey: false;
|
|
2343
|
+
isAutoincrement: false;
|
|
2344
|
+
hasRuntimeDefault: false;
|
|
2345
|
+
enumValues: [string, ...string[]];
|
|
2346
|
+
baseColumn: never;
|
|
2347
|
+
identity: undefined;
|
|
2348
|
+
generated: undefined;
|
|
2349
|
+
}, {}, {}>;
|
|
2350
|
+
pricingSource: import("drizzle-orm/pg-core").PgColumn<{
|
|
2351
|
+
name: "pricing_source";
|
|
2352
|
+
tableName: "cost_ledger";
|
|
2353
|
+
dataType: "string";
|
|
2354
|
+
columnType: "PgText";
|
|
2355
|
+
data: string;
|
|
2356
|
+
driverParam: string;
|
|
2357
|
+
notNull: false;
|
|
2358
|
+
hasDefault: false;
|
|
2359
|
+
isPrimaryKey: false;
|
|
2360
|
+
isAutoincrement: false;
|
|
2361
|
+
hasRuntimeDefault: false;
|
|
2362
|
+
enumValues: [string, ...string[]];
|
|
2363
|
+
baseColumn: never;
|
|
2364
|
+
identity: undefined;
|
|
2365
|
+
generated: undefined;
|
|
2366
|
+
}, {}, {}>;
|
|
2299
2367
|
tokenInput: import("drizzle-orm/pg-core").PgColumn<{
|
|
2300
2368
|
name: "token_input";
|
|
2301
2369
|
tableName: "cost_ledger";
|
|
@@ -2738,6 +2806,166 @@ export declare const plugins: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
|
2738
2806
|
};
|
|
2739
2807
|
dialect: "pg";
|
|
2740
2808
|
}>;
|
|
2809
|
+
export declare const modelPricing: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
2810
|
+
name: "model_pricing";
|
|
2811
|
+
schema: undefined;
|
|
2812
|
+
columns: {
|
|
2813
|
+
companyId: import("drizzle-orm/pg-core").PgColumn<{
|
|
2814
|
+
name: "company_id";
|
|
2815
|
+
tableName: "model_pricing";
|
|
2816
|
+
dataType: "string";
|
|
2817
|
+
columnType: "PgText";
|
|
2818
|
+
data: string;
|
|
2819
|
+
driverParam: string;
|
|
2820
|
+
notNull: true;
|
|
2821
|
+
hasDefault: false;
|
|
2822
|
+
isPrimaryKey: false;
|
|
2823
|
+
isAutoincrement: false;
|
|
2824
|
+
hasRuntimeDefault: false;
|
|
2825
|
+
enumValues: [string, ...string[]];
|
|
2826
|
+
baseColumn: never;
|
|
2827
|
+
identity: undefined;
|
|
2828
|
+
generated: undefined;
|
|
2829
|
+
}, {}, {}>;
|
|
2830
|
+
providerType: import("drizzle-orm/pg-core").PgColumn<{
|
|
2831
|
+
name: "provider_type";
|
|
2832
|
+
tableName: "model_pricing";
|
|
2833
|
+
dataType: "string";
|
|
2834
|
+
columnType: "PgText";
|
|
2835
|
+
data: string;
|
|
2836
|
+
driverParam: string;
|
|
2837
|
+
notNull: true;
|
|
2838
|
+
hasDefault: false;
|
|
2839
|
+
isPrimaryKey: false;
|
|
2840
|
+
isAutoincrement: false;
|
|
2841
|
+
hasRuntimeDefault: false;
|
|
2842
|
+
enumValues: [string, ...string[]];
|
|
2843
|
+
baseColumn: never;
|
|
2844
|
+
identity: undefined;
|
|
2845
|
+
generated: undefined;
|
|
2846
|
+
}, {}, {}>;
|
|
2847
|
+
modelId: import("drizzle-orm/pg-core").PgColumn<{
|
|
2848
|
+
name: "model_id";
|
|
2849
|
+
tableName: "model_pricing";
|
|
2850
|
+
dataType: "string";
|
|
2851
|
+
columnType: "PgText";
|
|
2852
|
+
data: string;
|
|
2853
|
+
driverParam: string;
|
|
2854
|
+
notNull: true;
|
|
2855
|
+
hasDefault: false;
|
|
2856
|
+
isPrimaryKey: false;
|
|
2857
|
+
isAutoincrement: false;
|
|
2858
|
+
hasRuntimeDefault: false;
|
|
2859
|
+
enumValues: [string, ...string[]];
|
|
2860
|
+
baseColumn: never;
|
|
2861
|
+
identity: undefined;
|
|
2862
|
+
generated: undefined;
|
|
2863
|
+
}, {}, {}>;
|
|
2864
|
+
displayName: import("drizzle-orm/pg-core").PgColumn<{
|
|
2865
|
+
name: "display_name";
|
|
2866
|
+
tableName: "model_pricing";
|
|
2867
|
+
dataType: "string";
|
|
2868
|
+
columnType: "PgText";
|
|
2869
|
+
data: string;
|
|
2870
|
+
driverParam: string;
|
|
2871
|
+
notNull: false;
|
|
2872
|
+
hasDefault: false;
|
|
2873
|
+
isPrimaryKey: false;
|
|
2874
|
+
isAutoincrement: false;
|
|
2875
|
+
hasRuntimeDefault: false;
|
|
2876
|
+
enumValues: [string, ...string[]];
|
|
2877
|
+
baseColumn: never;
|
|
2878
|
+
identity: undefined;
|
|
2879
|
+
generated: undefined;
|
|
2880
|
+
}, {}, {}>;
|
|
2881
|
+
inputUsdPer1M: import("drizzle-orm/pg-core").PgColumn<{
|
|
2882
|
+
name: "input_usd_per_1m";
|
|
2883
|
+
tableName: "model_pricing";
|
|
2884
|
+
dataType: "string";
|
|
2885
|
+
columnType: "PgNumeric";
|
|
2886
|
+
data: string;
|
|
2887
|
+
driverParam: string;
|
|
2888
|
+
notNull: true;
|
|
2889
|
+
hasDefault: true;
|
|
2890
|
+
isPrimaryKey: false;
|
|
2891
|
+
isAutoincrement: false;
|
|
2892
|
+
hasRuntimeDefault: false;
|
|
2893
|
+
enumValues: undefined;
|
|
2894
|
+
baseColumn: never;
|
|
2895
|
+
identity: undefined;
|
|
2896
|
+
generated: undefined;
|
|
2897
|
+
}, {}, {}>;
|
|
2898
|
+
outputUsdPer1M: import("drizzle-orm/pg-core").PgColumn<{
|
|
2899
|
+
name: "output_usd_per_1m";
|
|
2900
|
+
tableName: "model_pricing";
|
|
2901
|
+
dataType: "string";
|
|
2902
|
+
columnType: "PgNumeric";
|
|
2903
|
+
data: string;
|
|
2904
|
+
driverParam: string;
|
|
2905
|
+
notNull: true;
|
|
2906
|
+
hasDefault: true;
|
|
2907
|
+
isPrimaryKey: false;
|
|
2908
|
+
isAutoincrement: false;
|
|
2909
|
+
hasRuntimeDefault: false;
|
|
2910
|
+
enumValues: undefined;
|
|
2911
|
+
baseColumn: never;
|
|
2912
|
+
identity: undefined;
|
|
2913
|
+
generated: undefined;
|
|
2914
|
+
}, {}, {}>;
|
|
2915
|
+
currency: import("drizzle-orm/pg-core").PgColumn<{
|
|
2916
|
+
name: "currency";
|
|
2917
|
+
tableName: "model_pricing";
|
|
2918
|
+
dataType: "string";
|
|
2919
|
+
columnType: "PgText";
|
|
2920
|
+
data: string;
|
|
2921
|
+
driverParam: string;
|
|
2922
|
+
notNull: true;
|
|
2923
|
+
hasDefault: true;
|
|
2924
|
+
isPrimaryKey: false;
|
|
2925
|
+
isAutoincrement: false;
|
|
2926
|
+
hasRuntimeDefault: false;
|
|
2927
|
+
enumValues: [string, ...string[]];
|
|
2928
|
+
baseColumn: never;
|
|
2929
|
+
identity: undefined;
|
|
2930
|
+
generated: undefined;
|
|
2931
|
+
}, {}, {}>;
|
|
2932
|
+
updatedAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
2933
|
+
name: "updated_at";
|
|
2934
|
+
tableName: "model_pricing";
|
|
2935
|
+
dataType: "date";
|
|
2936
|
+
columnType: "PgTimestamp";
|
|
2937
|
+
data: Date;
|
|
2938
|
+
driverParam: string;
|
|
2939
|
+
notNull: true;
|
|
2940
|
+
hasDefault: true;
|
|
2941
|
+
isPrimaryKey: false;
|
|
2942
|
+
isAutoincrement: false;
|
|
2943
|
+
hasRuntimeDefault: false;
|
|
2944
|
+
enumValues: undefined;
|
|
2945
|
+
baseColumn: never;
|
|
2946
|
+
identity: undefined;
|
|
2947
|
+
generated: undefined;
|
|
2948
|
+
}, {}, {}>;
|
|
2949
|
+
updatedBy: import("drizzle-orm/pg-core").PgColumn<{
|
|
2950
|
+
name: "updated_by";
|
|
2951
|
+
tableName: "model_pricing";
|
|
2952
|
+
dataType: "string";
|
|
2953
|
+
columnType: "PgText";
|
|
2954
|
+
data: string;
|
|
2955
|
+
driverParam: string;
|
|
2956
|
+
notNull: false;
|
|
2957
|
+
hasDefault: false;
|
|
2958
|
+
isPrimaryKey: false;
|
|
2959
|
+
isAutoincrement: false;
|
|
2960
|
+
hasRuntimeDefault: false;
|
|
2961
|
+
enumValues: [string, ...string[]];
|
|
2962
|
+
baseColumn: never;
|
|
2963
|
+
identity: undefined;
|
|
2964
|
+
generated: undefined;
|
|
2965
|
+
}, {}, {}>;
|
|
2966
|
+
};
|
|
2967
|
+
dialect: "pg";
|
|
2968
|
+
}>;
|
|
2741
2969
|
export declare const pluginConfigs: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
2742
2970
|
name: "plugin_configs";
|
|
2743
2971
|
schema: undefined;
|
|
@@ -5415,6 +5643,74 @@ export declare const schema: {
|
|
|
5415
5643
|
identity: undefined;
|
|
5416
5644
|
generated: undefined;
|
|
5417
5645
|
}, {}, {}>;
|
|
5646
|
+
runtimeModelId: import("drizzle-orm/pg-core").PgColumn<{
|
|
5647
|
+
name: "runtime_model_id";
|
|
5648
|
+
tableName: "cost_ledger";
|
|
5649
|
+
dataType: "string";
|
|
5650
|
+
columnType: "PgText";
|
|
5651
|
+
data: string;
|
|
5652
|
+
driverParam: string;
|
|
5653
|
+
notNull: false;
|
|
5654
|
+
hasDefault: false;
|
|
5655
|
+
isPrimaryKey: false;
|
|
5656
|
+
isAutoincrement: false;
|
|
5657
|
+
hasRuntimeDefault: false;
|
|
5658
|
+
enumValues: [string, ...string[]];
|
|
5659
|
+
baseColumn: never;
|
|
5660
|
+
identity: undefined;
|
|
5661
|
+
generated: undefined;
|
|
5662
|
+
}, {}, {}>;
|
|
5663
|
+
pricingProviderType: import("drizzle-orm/pg-core").PgColumn<{
|
|
5664
|
+
name: "pricing_provider_type";
|
|
5665
|
+
tableName: "cost_ledger";
|
|
5666
|
+
dataType: "string";
|
|
5667
|
+
columnType: "PgText";
|
|
5668
|
+
data: string;
|
|
5669
|
+
driverParam: string;
|
|
5670
|
+
notNull: false;
|
|
5671
|
+
hasDefault: false;
|
|
5672
|
+
isPrimaryKey: false;
|
|
5673
|
+
isAutoincrement: false;
|
|
5674
|
+
hasRuntimeDefault: false;
|
|
5675
|
+
enumValues: [string, ...string[]];
|
|
5676
|
+
baseColumn: never;
|
|
5677
|
+
identity: undefined;
|
|
5678
|
+
generated: undefined;
|
|
5679
|
+
}, {}, {}>;
|
|
5680
|
+
pricingModelId: import("drizzle-orm/pg-core").PgColumn<{
|
|
5681
|
+
name: "pricing_model_id";
|
|
5682
|
+
tableName: "cost_ledger";
|
|
5683
|
+
dataType: "string";
|
|
5684
|
+
columnType: "PgText";
|
|
5685
|
+
data: string;
|
|
5686
|
+
driverParam: string;
|
|
5687
|
+
notNull: false;
|
|
5688
|
+
hasDefault: false;
|
|
5689
|
+
isPrimaryKey: false;
|
|
5690
|
+
isAutoincrement: false;
|
|
5691
|
+
hasRuntimeDefault: false;
|
|
5692
|
+
enumValues: [string, ...string[]];
|
|
5693
|
+
baseColumn: never;
|
|
5694
|
+
identity: undefined;
|
|
5695
|
+
generated: undefined;
|
|
5696
|
+
}, {}, {}>;
|
|
5697
|
+
pricingSource: import("drizzle-orm/pg-core").PgColumn<{
|
|
5698
|
+
name: "pricing_source";
|
|
5699
|
+
tableName: "cost_ledger";
|
|
5700
|
+
dataType: "string";
|
|
5701
|
+
columnType: "PgText";
|
|
5702
|
+
data: string;
|
|
5703
|
+
driverParam: string;
|
|
5704
|
+
notNull: false;
|
|
5705
|
+
hasDefault: false;
|
|
5706
|
+
isPrimaryKey: false;
|
|
5707
|
+
isAutoincrement: false;
|
|
5708
|
+
hasRuntimeDefault: false;
|
|
5709
|
+
enumValues: [string, ...string[]];
|
|
5710
|
+
baseColumn: never;
|
|
5711
|
+
identity: undefined;
|
|
5712
|
+
generated: undefined;
|
|
5713
|
+
}, {}, {}>;
|
|
5418
5714
|
tokenInput: import("drizzle-orm/pg-core").PgColumn<{
|
|
5419
5715
|
name: "token_input";
|
|
5420
5716
|
tableName: "cost_ledger";
|
|
@@ -6177,6 +6473,166 @@ export declare const schema: {
|
|
|
6177
6473
|
};
|
|
6178
6474
|
dialect: "pg";
|
|
6179
6475
|
}>;
|
|
6476
|
+
modelPricing: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
6477
|
+
name: "model_pricing";
|
|
6478
|
+
schema: undefined;
|
|
6479
|
+
columns: {
|
|
6480
|
+
companyId: import("drizzle-orm/pg-core").PgColumn<{
|
|
6481
|
+
name: "company_id";
|
|
6482
|
+
tableName: "model_pricing";
|
|
6483
|
+
dataType: "string";
|
|
6484
|
+
columnType: "PgText";
|
|
6485
|
+
data: string;
|
|
6486
|
+
driverParam: string;
|
|
6487
|
+
notNull: true;
|
|
6488
|
+
hasDefault: false;
|
|
6489
|
+
isPrimaryKey: false;
|
|
6490
|
+
isAutoincrement: false;
|
|
6491
|
+
hasRuntimeDefault: false;
|
|
6492
|
+
enumValues: [string, ...string[]];
|
|
6493
|
+
baseColumn: never;
|
|
6494
|
+
identity: undefined;
|
|
6495
|
+
generated: undefined;
|
|
6496
|
+
}, {}, {}>;
|
|
6497
|
+
providerType: import("drizzle-orm/pg-core").PgColumn<{
|
|
6498
|
+
name: "provider_type";
|
|
6499
|
+
tableName: "model_pricing";
|
|
6500
|
+
dataType: "string";
|
|
6501
|
+
columnType: "PgText";
|
|
6502
|
+
data: string;
|
|
6503
|
+
driverParam: string;
|
|
6504
|
+
notNull: true;
|
|
6505
|
+
hasDefault: false;
|
|
6506
|
+
isPrimaryKey: false;
|
|
6507
|
+
isAutoincrement: false;
|
|
6508
|
+
hasRuntimeDefault: false;
|
|
6509
|
+
enumValues: [string, ...string[]];
|
|
6510
|
+
baseColumn: never;
|
|
6511
|
+
identity: undefined;
|
|
6512
|
+
generated: undefined;
|
|
6513
|
+
}, {}, {}>;
|
|
6514
|
+
modelId: import("drizzle-orm/pg-core").PgColumn<{
|
|
6515
|
+
name: "model_id";
|
|
6516
|
+
tableName: "model_pricing";
|
|
6517
|
+
dataType: "string";
|
|
6518
|
+
columnType: "PgText";
|
|
6519
|
+
data: string;
|
|
6520
|
+
driverParam: string;
|
|
6521
|
+
notNull: true;
|
|
6522
|
+
hasDefault: false;
|
|
6523
|
+
isPrimaryKey: false;
|
|
6524
|
+
isAutoincrement: false;
|
|
6525
|
+
hasRuntimeDefault: false;
|
|
6526
|
+
enumValues: [string, ...string[]];
|
|
6527
|
+
baseColumn: never;
|
|
6528
|
+
identity: undefined;
|
|
6529
|
+
generated: undefined;
|
|
6530
|
+
}, {}, {}>;
|
|
6531
|
+
displayName: import("drizzle-orm/pg-core").PgColumn<{
|
|
6532
|
+
name: "display_name";
|
|
6533
|
+
tableName: "model_pricing";
|
|
6534
|
+
dataType: "string";
|
|
6535
|
+
columnType: "PgText";
|
|
6536
|
+
data: string;
|
|
6537
|
+
driverParam: string;
|
|
6538
|
+
notNull: false;
|
|
6539
|
+
hasDefault: false;
|
|
6540
|
+
isPrimaryKey: false;
|
|
6541
|
+
isAutoincrement: false;
|
|
6542
|
+
hasRuntimeDefault: false;
|
|
6543
|
+
enumValues: [string, ...string[]];
|
|
6544
|
+
baseColumn: never;
|
|
6545
|
+
identity: undefined;
|
|
6546
|
+
generated: undefined;
|
|
6547
|
+
}, {}, {}>;
|
|
6548
|
+
inputUsdPer1M: import("drizzle-orm/pg-core").PgColumn<{
|
|
6549
|
+
name: "input_usd_per_1m";
|
|
6550
|
+
tableName: "model_pricing";
|
|
6551
|
+
dataType: "string";
|
|
6552
|
+
columnType: "PgNumeric";
|
|
6553
|
+
data: string;
|
|
6554
|
+
driverParam: string;
|
|
6555
|
+
notNull: true;
|
|
6556
|
+
hasDefault: true;
|
|
6557
|
+
isPrimaryKey: false;
|
|
6558
|
+
isAutoincrement: false;
|
|
6559
|
+
hasRuntimeDefault: false;
|
|
6560
|
+
enumValues: undefined;
|
|
6561
|
+
baseColumn: never;
|
|
6562
|
+
identity: undefined;
|
|
6563
|
+
generated: undefined;
|
|
6564
|
+
}, {}, {}>;
|
|
6565
|
+
outputUsdPer1M: import("drizzle-orm/pg-core").PgColumn<{
|
|
6566
|
+
name: "output_usd_per_1m";
|
|
6567
|
+
tableName: "model_pricing";
|
|
6568
|
+
dataType: "string";
|
|
6569
|
+
columnType: "PgNumeric";
|
|
6570
|
+
data: string;
|
|
6571
|
+
driverParam: string;
|
|
6572
|
+
notNull: true;
|
|
6573
|
+
hasDefault: true;
|
|
6574
|
+
isPrimaryKey: false;
|
|
6575
|
+
isAutoincrement: false;
|
|
6576
|
+
hasRuntimeDefault: false;
|
|
6577
|
+
enumValues: undefined;
|
|
6578
|
+
baseColumn: never;
|
|
6579
|
+
identity: undefined;
|
|
6580
|
+
generated: undefined;
|
|
6581
|
+
}, {}, {}>;
|
|
6582
|
+
currency: import("drizzle-orm/pg-core").PgColumn<{
|
|
6583
|
+
name: "currency";
|
|
6584
|
+
tableName: "model_pricing";
|
|
6585
|
+
dataType: "string";
|
|
6586
|
+
columnType: "PgText";
|
|
6587
|
+
data: string;
|
|
6588
|
+
driverParam: string;
|
|
6589
|
+
notNull: true;
|
|
6590
|
+
hasDefault: true;
|
|
6591
|
+
isPrimaryKey: false;
|
|
6592
|
+
isAutoincrement: false;
|
|
6593
|
+
hasRuntimeDefault: false;
|
|
6594
|
+
enumValues: [string, ...string[]];
|
|
6595
|
+
baseColumn: never;
|
|
6596
|
+
identity: undefined;
|
|
6597
|
+
generated: undefined;
|
|
6598
|
+
}, {}, {}>;
|
|
6599
|
+
updatedAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
6600
|
+
name: "updated_at";
|
|
6601
|
+
tableName: "model_pricing";
|
|
6602
|
+
dataType: "date";
|
|
6603
|
+
columnType: "PgTimestamp";
|
|
6604
|
+
data: Date;
|
|
6605
|
+
driverParam: string;
|
|
6606
|
+
notNull: true;
|
|
6607
|
+
hasDefault: true;
|
|
6608
|
+
isPrimaryKey: false;
|
|
6609
|
+
isAutoincrement: false;
|
|
6610
|
+
hasRuntimeDefault: false;
|
|
6611
|
+
enumValues: undefined;
|
|
6612
|
+
baseColumn: never;
|
|
6613
|
+
identity: undefined;
|
|
6614
|
+
generated: undefined;
|
|
6615
|
+
}, {}, {}>;
|
|
6616
|
+
updatedBy: import("drizzle-orm/pg-core").PgColumn<{
|
|
6617
|
+
name: "updated_by";
|
|
6618
|
+
tableName: "model_pricing";
|
|
6619
|
+
dataType: "string";
|
|
6620
|
+
columnType: "PgText";
|
|
6621
|
+
data: string;
|
|
6622
|
+
driverParam: string;
|
|
6623
|
+
notNull: false;
|
|
6624
|
+
hasDefault: false;
|
|
6625
|
+
isPrimaryKey: false;
|
|
6626
|
+
isAutoincrement: false;
|
|
6627
|
+
hasRuntimeDefault: false;
|
|
6628
|
+
enumValues: [string, ...string[]];
|
|
6629
|
+
baseColumn: never;
|
|
6630
|
+
identity: undefined;
|
|
6631
|
+
generated: undefined;
|
|
6632
|
+
}, {}, {}>;
|
|
6633
|
+
};
|
|
6634
|
+
dialect: "pg";
|
|
6635
|
+
}>;
|
|
6180
6636
|
agentIssueLabels: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
6181
6637
|
name: "agent_issue_labels";
|
|
6182
6638
|
schema: undefined;
|
package/package.json
CHANGED
package/src/bootstrap.ts
CHANGED
|
@@ -279,12 +279,46 @@ export async function bootstrapDatabase(dbPath?: string) {
|
|
|
279
279
|
issue_id TEXT REFERENCES issues(id) ON DELETE SET NULL,
|
|
280
280
|
agent_id TEXT REFERENCES agents(id) ON DELETE SET NULL,
|
|
281
281
|
provider_type TEXT NOT NULL,
|
|
282
|
+
runtime_model_id TEXT,
|
|
283
|
+
pricing_provider_type TEXT,
|
|
284
|
+
pricing_model_id TEXT,
|
|
285
|
+
pricing_source TEXT,
|
|
282
286
|
token_input INTEGER NOT NULL DEFAULT 0,
|
|
283
287
|
token_output INTEGER NOT NULL DEFAULT 0,
|
|
284
288
|
usd_cost NUMERIC(12, 6) NOT NULL DEFAULT 0,
|
|
285
289
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
286
290
|
);
|
|
287
291
|
`);
|
|
292
|
+
await db.execute(sql`
|
|
293
|
+
ALTER TABLE cost_ledger
|
|
294
|
+
ADD COLUMN IF NOT EXISTS runtime_model_id TEXT;
|
|
295
|
+
`);
|
|
296
|
+
await db.execute(sql`
|
|
297
|
+
ALTER TABLE cost_ledger
|
|
298
|
+
ADD COLUMN IF NOT EXISTS pricing_provider_type TEXT;
|
|
299
|
+
`);
|
|
300
|
+
await db.execute(sql`
|
|
301
|
+
ALTER TABLE cost_ledger
|
|
302
|
+
ADD COLUMN IF NOT EXISTS pricing_model_id TEXT;
|
|
303
|
+
`);
|
|
304
|
+
await db.execute(sql`
|
|
305
|
+
ALTER TABLE cost_ledger
|
|
306
|
+
ADD COLUMN IF NOT EXISTS pricing_source TEXT;
|
|
307
|
+
`);
|
|
308
|
+
await db.execute(sql`
|
|
309
|
+
CREATE TABLE IF NOT EXISTS model_pricing (
|
|
310
|
+
company_id TEXT NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
|
|
311
|
+
provider_type TEXT NOT NULL,
|
|
312
|
+
model_id TEXT NOT NULL,
|
|
313
|
+
display_name TEXT,
|
|
314
|
+
input_usd_per_1m NUMERIC(12, 6) NOT NULL DEFAULT 0,
|
|
315
|
+
output_usd_per_1m NUMERIC(12, 6) NOT NULL DEFAULT 0,
|
|
316
|
+
currency TEXT NOT NULL DEFAULT 'USD',
|
|
317
|
+
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
318
|
+
updated_by TEXT,
|
|
319
|
+
PRIMARY KEY (company_id, provider_type, model_id)
|
|
320
|
+
);
|
|
321
|
+
`);
|
|
288
322
|
await db.execute(sql`
|
|
289
323
|
CREATE TABLE IF NOT EXISTS audit_events (
|
|
290
324
|
id TEXT PRIMARY KEY,
|
package/src/repositories.ts
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
issueAttachments,
|
|
16
16
|
issueComments,
|
|
17
17
|
issues,
|
|
18
|
+
modelPricing,
|
|
18
19
|
pluginConfigs,
|
|
19
20
|
pluginRuns,
|
|
20
21
|
plugins,
|
|
@@ -542,6 +543,7 @@ export async function createAgent(
|
|
|
542
543
|
| "codex"
|
|
543
544
|
| "cursor"
|
|
544
545
|
| "opencode"
|
|
546
|
+
| "gemini_cli"
|
|
545
547
|
| "openai_api"
|
|
546
548
|
| "anthropic_api"
|
|
547
549
|
| "http"
|
|
@@ -612,6 +614,7 @@ export async function updateAgent(
|
|
|
612
614
|
| "codex"
|
|
613
615
|
| "cursor"
|
|
614
616
|
| "opencode"
|
|
617
|
+
| "gemini_cli"
|
|
615
618
|
| "openai_api"
|
|
616
619
|
| "anthropic_api"
|
|
617
620
|
| "http"
|
|
@@ -843,6 +846,10 @@ export async function appendCost(
|
|
|
843
846
|
input: {
|
|
844
847
|
companyId: string;
|
|
845
848
|
providerType: string;
|
|
849
|
+
runtimeModelId?: string | null;
|
|
850
|
+
pricingProviderType?: string | null;
|
|
851
|
+
pricingModelId?: string | null;
|
|
852
|
+
pricingSource?: "exact" | "missing" | null;
|
|
846
853
|
tokenInput: number;
|
|
847
854
|
tokenOutput: number;
|
|
848
855
|
usdCost: string;
|
|
@@ -856,6 +863,10 @@ export async function appendCost(
|
|
|
856
863
|
id,
|
|
857
864
|
companyId: input.companyId,
|
|
858
865
|
providerType: input.providerType,
|
|
866
|
+
runtimeModelId: input.runtimeModelId ?? null,
|
|
867
|
+
pricingProviderType: input.pricingProviderType ?? null,
|
|
868
|
+
pricingModelId: input.pricingModelId ?? null,
|
|
869
|
+
pricingSource: input.pricingSource ?? null,
|
|
859
870
|
tokenInput: input.tokenInput,
|
|
860
871
|
tokenOutput: input.tokenOutput,
|
|
861
872
|
usdCost: input.usdCost,
|
|
@@ -1247,6 +1258,70 @@ export async function listPluginRuns(
|
|
|
1247
1258
|
.limit(limit);
|
|
1248
1259
|
}
|
|
1249
1260
|
|
|
1261
|
+
export async function listModelPricing(db: BopoDb, companyId: string) {
|
|
1262
|
+
return db
|
|
1263
|
+
.select()
|
|
1264
|
+
.from(modelPricing)
|
|
1265
|
+
.where(eq(modelPricing.companyId, companyId))
|
|
1266
|
+
.orderBy(asc(modelPricing.providerType), asc(modelPricing.modelId));
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
export async function getModelPricing(
|
|
1270
|
+
db: BopoDb,
|
|
1271
|
+
input: { companyId: string; providerType: string; modelId: string }
|
|
1272
|
+
) {
|
|
1273
|
+
const rows = await db
|
|
1274
|
+
.select()
|
|
1275
|
+
.from(modelPricing)
|
|
1276
|
+
.where(
|
|
1277
|
+
and(
|
|
1278
|
+
eq(modelPricing.companyId, input.companyId),
|
|
1279
|
+
eq(modelPricing.providerType, input.providerType),
|
|
1280
|
+
eq(modelPricing.modelId, input.modelId)
|
|
1281
|
+
)
|
|
1282
|
+
)
|
|
1283
|
+
.limit(1);
|
|
1284
|
+
return rows[0] ?? null;
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
export async function upsertModelPricing(
|
|
1288
|
+
db: BopoDb,
|
|
1289
|
+
input: {
|
|
1290
|
+
companyId: string;
|
|
1291
|
+
providerType: string;
|
|
1292
|
+
modelId: string;
|
|
1293
|
+
displayName?: string | null;
|
|
1294
|
+
inputUsdPer1M?: string | null;
|
|
1295
|
+
outputUsdPer1M?: string | null;
|
|
1296
|
+
currency?: string | null;
|
|
1297
|
+
updatedBy?: string | null;
|
|
1298
|
+
}
|
|
1299
|
+
) {
|
|
1300
|
+
await db
|
|
1301
|
+
.insert(modelPricing)
|
|
1302
|
+
.values({
|
|
1303
|
+
companyId: input.companyId,
|
|
1304
|
+
providerType: input.providerType,
|
|
1305
|
+
modelId: input.modelId,
|
|
1306
|
+
displayName: input.displayName ?? null,
|
|
1307
|
+
inputUsdPer1M: input.inputUsdPer1M ?? "0.000000",
|
|
1308
|
+
outputUsdPer1M: input.outputUsdPer1M ?? "0.000000",
|
|
1309
|
+
currency: input.currency ?? "USD",
|
|
1310
|
+
updatedBy: input.updatedBy ?? null
|
|
1311
|
+
})
|
|
1312
|
+
.onConflictDoUpdate({
|
|
1313
|
+
target: [modelPricing.companyId, modelPricing.providerType, modelPricing.modelId],
|
|
1314
|
+
set: compactUpdate({
|
|
1315
|
+
displayName: input.displayName ?? null,
|
|
1316
|
+
inputUsdPer1M: input.inputUsdPer1M ?? "0.000000",
|
|
1317
|
+
outputUsdPer1M: input.outputUsdPer1M ?? "0.000000",
|
|
1318
|
+
currency: input.currency ?? "USD",
|
|
1319
|
+
updatedBy: input.updatedBy ?? null,
|
|
1320
|
+
updatedAt: touchUpdatedAtSql
|
|
1321
|
+
})
|
|
1322
|
+
});
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1250
1325
|
function compactUpdate<T extends Record<string, unknown>>(input: T) {
|
|
1251
1326
|
return Object.fromEntries(Object.entries(input).filter(([, value]) => value !== undefined));
|
|
1252
1327
|
}
|
package/src/schema.ts
CHANGED
|
@@ -1,13 +1,5 @@
|
|
|
1
1
|
import { sql } from "drizzle-orm";
|
|
2
|
-
import {
|
|
3
|
-
boolean,
|
|
4
|
-
integer,
|
|
5
|
-
numeric,
|
|
6
|
-
pgTable,
|
|
7
|
-
primaryKey,
|
|
8
|
-
text,
|
|
9
|
-
timestamp
|
|
10
|
-
} from "drizzle-orm/pg-core";
|
|
2
|
+
import { boolean, integer, numeric, pgTable, primaryKey, text, timestamp } from "drizzle-orm/pg-core";
|
|
11
3
|
|
|
12
4
|
export const companies = pgTable("companies", {
|
|
13
5
|
id: text("id").primaryKey(),
|
|
@@ -222,6 +214,10 @@ export const costLedger = pgTable("cost_ledger", {
|
|
|
222
214
|
issueId: text("issue_id").references(() => issues.id, { onDelete: "set null" }),
|
|
223
215
|
agentId: text("agent_id").references(() => agents.id, { onDelete: "set null" }),
|
|
224
216
|
providerType: text("provider_type").notNull(),
|
|
217
|
+
runtimeModelId: text("runtime_model_id"),
|
|
218
|
+
pricingProviderType: text("pricing_provider_type"),
|
|
219
|
+
pricingModelId: text("pricing_model_id"),
|
|
220
|
+
pricingSource: text("pricing_source"),
|
|
225
221
|
tokenInput: integer("token_input").notNull().default(0),
|
|
226
222
|
tokenOutput: integer("token_output").notNull().default(0),
|
|
227
223
|
usdCost: numeric("usd_cost", { precision: 12, scale: 6 }).notNull().default("0"),
|
|
@@ -257,6 +253,24 @@ export const plugins = pgTable("plugins", {
|
|
|
257
253
|
updatedAt: timestamp("updated_at", { mode: "date" }).defaultNow().notNull()
|
|
258
254
|
});
|
|
259
255
|
|
|
256
|
+
export const modelPricing = pgTable(
|
|
257
|
+
"model_pricing",
|
|
258
|
+
{
|
|
259
|
+
companyId: text("company_id")
|
|
260
|
+
.notNull()
|
|
261
|
+
.references(() => companies.id, { onDelete: "cascade" }),
|
|
262
|
+
providerType: text("provider_type").notNull(),
|
|
263
|
+
modelId: text("model_id").notNull(),
|
|
264
|
+
displayName: text("display_name"),
|
|
265
|
+
inputUsdPer1M: numeric("input_usd_per_1m", { precision: 12, scale: 6 }).notNull().default("0"),
|
|
266
|
+
outputUsdPer1M: numeric("output_usd_per_1m", { precision: 12, scale: 6 }).notNull().default("0"),
|
|
267
|
+
currency: text("currency").notNull().default("USD"),
|
|
268
|
+
updatedAt: timestamp("updated_at", { mode: "date" }).defaultNow().notNull(),
|
|
269
|
+
updatedBy: text("updated_by")
|
|
270
|
+
},
|
|
271
|
+
(table) => [primaryKey({ columns: [table.companyId, table.providerType, table.modelId] })]
|
|
272
|
+
);
|
|
273
|
+
|
|
260
274
|
export const pluginConfigs = pgTable(
|
|
261
275
|
"plugin_configs",
|
|
262
276
|
{
|
|
@@ -325,6 +339,7 @@ export const schema = {
|
|
|
325
339
|
plugins,
|
|
326
340
|
pluginConfigs,
|
|
327
341
|
pluginRuns,
|
|
342
|
+
modelPricing,
|
|
328
343
|
agentIssueLabels
|
|
329
344
|
};
|
|
330
345
|
|