@drawbridge/drawbridge-utils 0.0.29 → 0.0.32
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/ai.cjs +120 -135
- package/dist/ai.d.cts +117 -96
- package/dist/ai.d.ts +117 -96
- package/dist/ai.js +85 -71
- package/dist/chunk-RW2FJVIV.js +110 -0
- package/dist/transactions.cjs +51 -104
- package/dist/transactions.d.cts +93 -139
- package/dist/transactions.d.ts +93 -139
- package/dist/transactions.js +1 -3
- package/package.json +1 -1
- package/dist/chunk-H735KDYS.js +0 -162
package/dist/ai.cjs
CHANGED
|
@@ -19,6 +19,9 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
19
19
|
// ai.js
|
|
20
20
|
var ai_exports = {};
|
|
21
21
|
__export(ai_exports, {
|
|
22
|
+
MARKUP: () => MARKUP,
|
|
23
|
+
cost: () => cost,
|
|
24
|
+
costForRequest: () => costForRequest,
|
|
22
25
|
google: () => google,
|
|
23
26
|
priceForRequest: () => priceForRequest,
|
|
24
27
|
pricing: () => pricing
|
|
@@ -78,105 +81,73 @@ var circuit = ({
|
|
|
78
81
|
};
|
|
79
82
|
|
|
80
83
|
// transactions.js
|
|
81
|
-
var
|
|
84
|
+
var insertTransaction = async ({
|
|
82
85
|
db,
|
|
83
|
-
|
|
84
|
-
|
|
86
|
+
user,
|
|
87
|
+
type,
|
|
85
88
|
category,
|
|
86
|
-
|
|
89
|
+
source,
|
|
87
90
|
amount,
|
|
88
|
-
|
|
89
|
-
provider,
|
|
91
|
+
_id,
|
|
90
92
|
stripeInvoiceId,
|
|
91
93
|
stripeEventId,
|
|
92
|
-
session
|
|
94
|
+
session,
|
|
95
|
+
...rest
|
|
93
96
|
}) => {
|
|
97
|
+
var _a;
|
|
98
|
+
const beforeRaw = (_a = user == null ? void 0 : user.balance) == null ? void 0 : _a[type];
|
|
99
|
+
const balance = typeof beforeRaw === "number" ? { before: beforeRaw, after: beforeRaw + amount } : void 0;
|
|
94
100
|
await db.create({
|
|
95
|
-
authenticated,
|
|
101
|
+
authenticated: user,
|
|
96
102
|
collection: "transaction",
|
|
97
103
|
data: {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
},
|
|
104
|
+
..._id && { _id },
|
|
105
|
+
userId: user == null ? void 0 : user.id,
|
|
106
|
+
type,
|
|
102
107
|
category,
|
|
103
|
-
|
|
108
|
+
source,
|
|
104
109
|
amount,
|
|
105
|
-
balance,
|
|
106
|
-
...
|
|
110
|
+
...balance && { balance },
|
|
111
|
+
...rest,
|
|
107
112
|
...stripeInvoiceId && { stripeInvoiceId },
|
|
108
113
|
...stripeEventId && { stripeEventId }
|
|
109
114
|
},
|
|
110
115
|
...session && { options: { session } }
|
|
111
116
|
});
|
|
112
117
|
};
|
|
113
|
-
var InsufficientCreditsError = class extends Error {
|
|
114
|
-
constructor(message = "Insufficient AI credits") {
|
|
115
|
-
super(message);
|
|
116
|
-
this.name = "InsufficientCreditsError";
|
|
117
|
-
this.status = 402;
|
|
118
|
-
}
|
|
119
|
-
};
|
|
120
118
|
var debit = async ({
|
|
121
119
|
db,
|
|
122
|
-
|
|
123
|
-
userId,
|
|
120
|
+
user,
|
|
124
121
|
amount,
|
|
122
|
+
type,
|
|
125
123
|
category,
|
|
126
|
-
|
|
127
|
-
provider,
|
|
124
|
+
source,
|
|
128
125
|
stripeInvoiceId,
|
|
129
126
|
stripeEventId,
|
|
130
|
-
session
|
|
127
|
+
session,
|
|
128
|
+
...rest
|
|
131
129
|
}) => {
|
|
132
|
-
var _a, _b, _c;
|
|
133
130
|
if (!Number.isInteger(amount) || amount <= 0) {
|
|
134
131
|
throw new Error(`debit() requires a positive integer amount, got ${amount}`);
|
|
135
132
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
"balance.ai": {
|
|
142
|
-
$gte: amount
|
|
143
|
-
}
|
|
144
|
-
},
|
|
145
|
-
data: {
|
|
146
|
-
$inc: {
|
|
147
|
-
"balance.ai": -amount
|
|
148
|
-
}
|
|
149
|
-
},
|
|
150
|
-
...session && { options: { session } }
|
|
151
|
-
});
|
|
152
|
-
const after = ((_b = (_a = result == null ? void 0 : result.value) == null ? void 0 : _a.balance) == null ? void 0 : _b.ai) ?? ((_c = result == null ? void 0 : result.balance) == null ? void 0 : _c.ai);
|
|
153
|
-
if (typeof after !== "number") {
|
|
154
|
-
throw new InsufficientCreditsError();
|
|
133
|
+
if (!type) {
|
|
134
|
+
throw new Error('debit() requires a type (e.g., "ai")');
|
|
135
|
+
}
|
|
136
|
+
if (!source) {
|
|
137
|
+
throw new Error('debit() requires a source ("system" | "admin" | "user")');
|
|
155
138
|
}
|
|
156
|
-
|
|
157
|
-
await recordTransaction({
|
|
139
|
+
await insertTransaction({
|
|
158
140
|
db,
|
|
159
|
-
|
|
160
|
-
|
|
141
|
+
user,
|
|
142
|
+
type,
|
|
161
143
|
category,
|
|
162
|
-
|
|
144
|
+
source,
|
|
163
145
|
amount: -amount,
|
|
164
|
-
balance: {
|
|
165
|
-
before,
|
|
166
|
-
after
|
|
167
|
-
},
|
|
168
|
-
provider,
|
|
169
146
|
stripeInvoiceId,
|
|
170
147
|
stripeEventId,
|
|
171
|
-
session
|
|
148
|
+
session,
|
|
149
|
+
...rest
|
|
172
150
|
});
|
|
173
|
-
return {
|
|
174
|
-
amount: -amount,
|
|
175
|
-
balance: {
|
|
176
|
-
before,
|
|
177
|
-
after
|
|
178
|
-
}
|
|
179
|
-
};
|
|
180
151
|
};
|
|
181
152
|
|
|
182
153
|
// ai.js
|
|
@@ -192,7 +163,7 @@ var models = {
|
|
|
192
163
|
image: "gemini-2.5-flash-image",
|
|
193
164
|
text: "gemini-2.5-flash"
|
|
194
165
|
};
|
|
195
|
-
var
|
|
166
|
+
var cost = {
|
|
196
167
|
"gemini-2.5-flash": {
|
|
197
168
|
cached: 3,
|
|
198
169
|
input: 30,
|
|
@@ -204,18 +175,33 @@ var pricing = {
|
|
|
204
175
|
output: 250
|
|
205
176
|
}
|
|
206
177
|
};
|
|
178
|
+
var MARKUP = 1.3;
|
|
179
|
+
var pricing = Object.fromEntries(
|
|
180
|
+
Object.entries(cost).map(([model, rates]) => [
|
|
181
|
+
model,
|
|
182
|
+
{
|
|
183
|
+
cached: Math.round(rates.cached * MARKUP),
|
|
184
|
+
input: Math.round(rates.input * MARKUP),
|
|
185
|
+
output: Math.round(rates.output * MARKUP)
|
|
186
|
+
}
|
|
187
|
+
])
|
|
188
|
+
);
|
|
189
|
+
var sumCents = (rates, tokens) => Math.ceil(
|
|
190
|
+
(Number((tokens == null ? void 0 : tokens.cached) || 0) * rates.cached + Number((tokens == null ? void 0 : tokens.input) || 0) * rates.input + Number((tokens == null ? void 0 : tokens.output) || 0) * rates.output) / 1e6
|
|
191
|
+
);
|
|
207
192
|
var priceForRequest = (model, usage) => {
|
|
208
193
|
const rates = pricing[model];
|
|
209
194
|
if (!rates) {
|
|
210
195
|
throw new Error(`Unknown model for pricing: ${model}`);
|
|
211
196
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
197
|
+
return sumCents(rates, usage);
|
|
198
|
+
};
|
|
199
|
+
var costForRequest = (model, usage) => {
|
|
200
|
+
const rates = cost[model];
|
|
201
|
+
if (!rates) {
|
|
202
|
+
throw new Error(`Unknown model for cost: ${model}`);
|
|
203
|
+
}
|
|
204
|
+
return sumCents(rates, usage);
|
|
219
205
|
};
|
|
220
206
|
var tokensFromMetadata = (metadata) => ({
|
|
221
207
|
cached: Number(metadata == null ? void 0 : metadata.cachedContentTokenCount) || 0,
|
|
@@ -224,24 +210,32 @@ var tokensFromMetadata = (metadata) => ({
|
|
|
224
210
|
});
|
|
225
211
|
var billRequest = async ({
|
|
226
212
|
db,
|
|
227
|
-
|
|
228
|
-
userId,
|
|
213
|
+
user,
|
|
229
214
|
model,
|
|
230
215
|
usage
|
|
231
216
|
}) => {
|
|
232
|
-
const
|
|
217
|
+
const gross = priceForRequest(model, usage);
|
|
218
|
+
const cogs = costForRequest(model, usage);
|
|
233
219
|
await debit({
|
|
234
220
|
db,
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
221
|
+
user,
|
|
222
|
+
amount: gross,
|
|
223
|
+
type: "ai",
|
|
238
224
|
category: "usage",
|
|
239
|
-
|
|
240
|
-
|
|
225
|
+
source: "user",
|
|
226
|
+
ai: {
|
|
241
227
|
name: "google",
|
|
242
228
|
model,
|
|
243
229
|
tokens: usage,
|
|
244
|
-
|
|
230
|
+
rates: {
|
|
231
|
+
wholesale: cost[model],
|
|
232
|
+
retail: pricing[model]
|
|
233
|
+
},
|
|
234
|
+
totals: {
|
|
235
|
+
cost: cogs,
|
|
236
|
+
net: gross - cogs,
|
|
237
|
+
gross
|
|
238
|
+
}
|
|
245
239
|
}
|
|
246
240
|
});
|
|
247
241
|
};
|
|
@@ -252,8 +246,7 @@ var google = {
|
|
|
252
246
|
reference = null
|
|
253
247
|
}, {
|
|
254
248
|
db,
|
|
255
|
-
|
|
256
|
-
userId
|
|
249
|
+
user
|
|
257
250
|
}) => {
|
|
258
251
|
var _a, _b, _c, _d, _e, _f;
|
|
259
252
|
const model = models.image;
|
|
@@ -261,72 +254,64 @@ var google = {
|
|
|
261
254
|
...reference ? [{ inlineData: { data: reference.data, mimeType: reference.mimeType } }] : [],
|
|
262
255
|
{ text: prompt.join("\n") }
|
|
263
256
|
];
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
config
|
|
269
|
-
|
|
270
|
-
responseModalities: ["Image"]
|
|
271
|
-
}
|
|
272
|
-
}));
|
|
273
|
-
const content = (_f = (_e = (_d = (_c = (_b = (_a = response == null ? void 0 : response.candidates) == null ? void 0 : _a[0]) == null ? void 0 : _b.content) == null ? void 0 : _c.parts) == null ? void 0 : _d[0]) == null ? void 0 : _e.inlineData) == null ? void 0 : _f.data;
|
|
274
|
-
if (!content) {
|
|
275
|
-
throw new Error("Could not generate from prompt. Please try again with a different prompt.");
|
|
276
|
-
}
|
|
277
|
-
if (userId) {
|
|
278
|
-
await billRequest({
|
|
279
|
-
db,
|
|
280
|
-
authenticated,
|
|
281
|
-
userId,
|
|
282
|
-
model,
|
|
283
|
-
usage: tokensFromMetadata(response == null ? void 0 : response.usageMetadata)
|
|
284
|
-
});
|
|
257
|
+
const response = await googleCircuit(() => google_client.models.generateContent({
|
|
258
|
+
model,
|
|
259
|
+
contents: { parts },
|
|
260
|
+
config: {
|
|
261
|
+
...config,
|
|
262
|
+
responseModalities: ["Image"]
|
|
285
263
|
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
264
|
+
}));
|
|
265
|
+
const content = (_f = (_e = (_d = (_c = (_b = (_a = response == null ? void 0 : response.candidates) == null ? void 0 : _a[0]) == null ? void 0 : _b.content) == null ? void 0 : _c.parts) == null ? void 0 : _d[0]) == null ? void 0 : _e.inlineData) == null ? void 0 : _f.data;
|
|
266
|
+
if (!content) {
|
|
267
|
+
throw new Error("Could not generate from prompt. Please try again with a different prompt.");
|
|
289
268
|
}
|
|
269
|
+
if (user == null ? void 0 : user.id) {
|
|
270
|
+
await billRequest({
|
|
271
|
+
db,
|
|
272
|
+
user,
|
|
273
|
+
model,
|
|
274
|
+
usage: tokensFromMetadata(response == null ? void 0 : response.usageMetadata)
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
return { content };
|
|
290
278
|
},
|
|
291
279
|
text: async ({
|
|
292
280
|
config = {},
|
|
293
281
|
prompt = []
|
|
294
282
|
}, {
|
|
295
283
|
db,
|
|
296
|
-
|
|
297
|
-
userId
|
|
284
|
+
user
|
|
298
285
|
}) => {
|
|
299
286
|
const model = models.text;
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
config
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
usage: tokensFromMetadata(response == null ? void 0 : response.usageMetadata)
|
|
320
|
-
});
|
|
321
|
-
}
|
|
322
|
-
return { content };
|
|
323
|
-
} catch (error) {
|
|
324
|
-
throw new Error((error == null ? void 0 : error.message) || "AI error, please try again");
|
|
287
|
+
const response = await googleCircuit(() => google_client.models.generateContent({
|
|
288
|
+
config: {
|
|
289
|
+
...config,
|
|
290
|
+
responseModalities: ["Text"]
|
|
291
|
+
},
|
|
292
|
+
contents: prompt.join("\n"),
|
|
293
|
+
model
|
|
294
|
+
}));
|
|
295
|
+
const content = response == null ? void 0 : response.text;
|
|
296
|
+
if (!content) {
|
|
297
|
+
throw new Error("Could not generate from prompt. Please try again with a different prompt.");
|
|
298
|
+
}
|
|
299
|
+
if (user == null ? void 0 : user.id) {
|
|
300
|
+
await billRequest({
|
|
301
|
+
db,
|
|
302
|
+
user,
|
|
303
|
+
model,
|
|
304
|
+
usage: tokensFromMetadata(response == null ? void 0 : response.usageMetadata)
|
|
305
|
+
});
|
|
325
306
|
}
|
|
307
|
+
return { content };
|
|
326
308
|
}
|
|
327
309
|
};
|
|
328
310
|
// Annotate the CommonJS export names for ESM import in node:
|
|
329
311
|
0 && (module.exports = {
|
|
312
|
+
MARKUP,
|
|
313
|
+
cost,
|
|
314
|
+
costForRequest,
|
|
330
315
|
google,
|
|
331
316
|
priceForRequest,
|
|
332
317
|
pricing
|
package/dist/ai.d.cts
CHANGED
|
@@ -36,14 +36,12 @@ const models = {
|
|
|
36
36
|
text : 'gemini-2.5-flash'
|
|
37
37
|
};
|
|
38
38
|
|
|
39
|
-
//
|
|
40
|
-
//
|
|
41
|
-
//
|
|
42
|
-
// Values mirror LiteLLM's published pricing at the time of writing. Model
|
|
43
|
-
// providers update pricing periodically — verify against
|
|
39
|
+
// Raw per-model provider rates in cents per 1,000,000 tokens. This is what
|
|
40
|
+
// Drawbridge pays the provider — the wholesale cost. Sync from LiteLLM:
|
|
44
41
|
// https://github.com/BerriAI/litellm/blob/main/litellm/model_prices_and_context_window_backup.json
|
|
45
|
-
//
|
|
46
|
-
|
|
42
|
+
// Never apply markup here; the MARKUP constant below derives the retail
|
|
43
|
+
// `pricing` table.
|
|
44
|
+
const cost = {
|
|
47
45
|
'gemini-2.5-flash' : {
|
|
48
46
|
cached : 3,
|
|
49
47
|
input : 30,
|
|
@@ -56,9 +54,37 @@ const pricing = {
|
|
|
56
54
|
}
|
|
57
55
|
};
|
|
58
56
|
|
|
59
|
-
//
|
|
60
|
-
//
|
|
61
|
-
//
|
|
57
|
+
// Markup multiplier applied to every model's cost to produce the retail
|
|
58
|
+
// price. 1.3 = 30% margin. Change one number, all pricing updates. Mirrors
|
|
59
|
+
// the per-customer markup Stripe rate cards used to provide; keeping it
|
|
60
|
+
// global (rather than per-model or per-plan) for simplicity — easy to
|
|
61
|
+
// refactor later if tier-based pricing becomes a real need.
|
|
62
|
+
const MARKUP = 1.3;
|
|
63
|
+
|
|
64
|
+
// Derived retail pricing in cents per 1,000,000 tokens — what users pay.
|
|
65
|
+
// Rounded so the per-1M rate is a whole-cent value; per-request rounding
|
|
66
|
+
// happens in priceForRequest via Math.ceil so we never under-bill.
|
|
67
|
+
const pricing = Object.fromEntries(
|
|
68
|
+
Object.entries( cost ).map( ( [ model, rates ] ) => [
|
|
69
|
+
model,
|
|
70
|
+
{
|
|
71
|
+
cached : Math.round( rates.cached * MARKUP ),
|
|
72
|
+
input : Math.round( rates.input * MARKUP ),
|
|
73
|
+
output : Math.round( rates.output * MARKUP )
|
|
74
|
+
}
|
|
75
|
+
] )
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
const sumCents = ( rates, tokens ) => Math.ceil(
|
|
79
|
+
(
|
|
80
|
+
Number( tokens?.cached || 0 ) * rates.cached +
|
|
81
|
+
Number( tokens?.input || 0 ) * rates.input +
|
|
82
|
+
Number( tokens?.output || 0 ) * rates.output
|
|
83
|
+
) / 1_000_000
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
// What we charge the user, rounded up so we never under-bill. Throws on an
|
|
87
|
+
// unknown model so a typo doesn't silently fall back to a wrong price.
|
|
62
88
|
const priceForRequest = ( model, usage ) => {
|
|
63
89
|
|
|
64
90
|
const rates = pricing[ model ];
|
|
@@ -69,19 +95,23 @@ const priceForRequest = ( model, usage ) => {
|
|
|
69
95
|
|
|
70
96
|
}
|
|
71
97
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
output : Number( usage?.output ) || 0
|
|
76
|
-
};
|
|
98
|
+
return sumCents( rates, usage );
|
|
99
|
+
|
|
100
|
+
};
|
|
77
101
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
tokens.output * rates.output
|
|
82
|
-
);
|
|
102
|
+
// What we pay the provider. Recorded on each transaction row so margin is
|
|
103
|
+
// computable per request without backfilling from git history.
|
|
104
|
+
const costForRequest = ( model, usage ) => {
|
|
83
105
|
|
|
84
|
-
|
|
106
|
+
const rates = cost[ model ];
|
|
107
|
+
|
|
108
|
+
if( !rates ){
|
|
109
|
+
|
|
110
|
+
throw new Error( `Unknown model for cost: ${ model }` );
|
|
111
|
+
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return sumCents( rates, usage );
|
|
85
115
|
|
|
86
116
|
};
|
|
87
117
|
|
|
@@ -92,30 +122,41 @@ const tokensFromMetadata = ( metadata ) => ({
|
|
|
92
122
|
output : Number( metadata?.candidatesTokenCount ) || 0
|
|
93
123
|
});
|
|
94
124
|
|
|
95
|
-
// Compute cost from response usage and atomically debit the user.
|
|
96
|
-
//
|
|
125
|
+
// Compute gross + cost from response usage and atomically debit the user.
|
|
126
|
+
// Records the full income-statement line on the transaction row's `ai`
|
|
127
|
+
// sub-doc: wholesale + retail per-1M rate snapshots, plus rolled-up cost,
|
|
128
|
+
// net, and gross totals. Margin per request is `ai.net`; margin per query
|
|
129
|
+
// is a single $sum: '$ai.net'.
|
|
97
130
|
const billRequest = async ({
|
|
98
131
|
db,
|
|
99
|
-
|
|
100
|
-
userId,
|
|
132
|
+
user,
|
|
101
133
|
model,
|
|
102
134
|
usage
|
|
103
135
|
}) => {
|
|
104
136
|
|
|
105
|
-
const
|
|
137
|
+
const gross = priceForRequest( model, usage );
|
|
138
|
+
const cogs = costForRequest( model, usage );
|
|
106
139
|
|
|
107
140
|
await debit({
|
|
108
141
|
db,
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
142
|
+
user,
|
|
143
|
+
amount : gross,
|
|
144
|
+
type : 'ai',
|
|
112
145
|
category : 'usage',
|
|
113
|
-
|
|
114
|
-
|
|
146
|
+
source : 'user',
|
|
147
|
+
ai : {
|
|
115
148
|
name : 'google',
|
|
116
149
|
model,
|
|
117
150
|
tokens : usage,
|
|
118
|
-
|
|
151
|
+
rates : {
|
|
152
|
+
wholesale : cost[ model ],
|
|
153
|
+
retail : pricing[ model ]
|
|
154
|
+
},
|
|
155
|
+
totals : {
|
|
156
|
+
cost : cogs,
|
|
157
|
+
net : gross - cogs,
|
|
158
|
+
gross
|
|
159
|
+
}
|
|
119
160
|
}
|
|
120
161
|
});
|
|
121
162
|
|
|
@@ -131,8 +172,7 @@ const google = {
|
|
|
131
172
|
},
|
|
132
173
|
{
|
|
133
174
|
db,
|
|
134
|
-
|
|
135
|
-
userId
|
|
175
|
+
user
|
|
136
176
|
}
|
|
137
177
|
) => {
|
|
138
178
|
|
|
@@ -143,45 +183,36 @@ const google = {
|
|
|
143
183
|
{ text : prompt.join( '\n' ) }
|
|
144
184
|
];
|
|
145
185
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
...config,
|
|
153
|
-
responseModalities : [ 'Image' ]
|
|
154
|
-
}
|
|
155
|
-
}) );
|
|
156
|
-
|
|
157
|
-
const content = response?.candidates?.[ 0 ]?.content?.parts?.[ 0 ]?.inlineData?.data;
|
|
158
|
-
|
|
159
|
-
if( !content ){
|
|
160
|
-
|
|
161
|
-
throw new Error( 'Could not generate from prompt. Please try again with a different prompt.' );
|
|
162
|
-
|
|
186
|
+
const response = await googleCircuit( () => google_client.models.generateContent({
|
|
187
|
+
model,
|
|
188
|
+
contents : { parts },
|
|
189
|
+
config : {
|
|
190
|
+
...config,
|
|
191
|
+
responseModalities : [ 'Image' ]
|
|
163
192
|
}
|
|
193
|
+
}) );
|
|
164
194
|
|
|
165
|
-
|
|
195
|
+
const content = response?.candidates?.[ 0 ]?.content?.parts?.[ 0 ]?.inlineData?.data;
|
|
166
196
|
|
|
167
|
-
|
|
168
|
-
db,
|
|
169
|
-
authenticated,
|
|
170
|
-
userId,
|
|
171
|
-
model,
|
|
172
|
-
usage : tokensFromMetadata( response?.usageMetadata )
|
|
173
|
-
});
|
|
197
|
+
if( !content ){
|
|
174
198
|
|
|
175
|
-
|
|
199
|
+
throw new Error( 'Could not generate from prompt. Please try again with a different prompt.' );
|
|
176
200
|
|
|
177
|
-
|
|
201
|
+
}
|
|
178
202
|
|
|
179
|
-
|
|
203
|
+
if( user?.id ){
|
|
180
204
|
|
|
181
|
-
|
|
205
|
+
await billRequest({
|
|
206
|
+
db,
|
|
207
|
+
user,
|
|
208
|
+
model,
|
|
209
|
+
usage : tokensFromMetadata( response?.usageMetadata )
|
|
210
|
+
});
|
|
182
211
|
|
|
183
212
|
}
|
|
184
213
|
|
|
214
|
+
return { content };
|
|
215
|
+
|
|
185
216
|
},
|
|
186
217
|
|
|
187
218
|
text : async (
|
|
@@ -191,54 +222,44 @@ const google = {
|
|
|
191
222
|
},
|
|
192
223
|
{
|
|
193
224
|
db,
|
|
194
|
-
|
|
195
|
-
userId
|
|
225
|
+
user
|
|
196
226
|
}
|
|
197
227
|
) => {
|
|
198
228
|
|
|
199
229
|
const model = models.text;
|
|
200
230
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
model
|
|
210
|
-
}) );
|
|
211
|
-
|
|
212
|
-
const content = response?.text;
|
|
231
|
+
const response = await googleCircuit( () => google_client.models.generateContent({
|
|
232
|
+
config : {
|
|
233
|
+
...config,
|
|
234
|
+
responseModalities : [ 'Text' ]
|
|
235
|
+
},
|
|
236
|
+
contents : prompt.join( '\n' ),
|
|
237
|
+
model
|
|
238
|
+
}) );
|
|
213
239
|
|
|
214
|
-
|
|
240
|
+
const content = response?.text;
|
|
215
241
|
|
|
216
|
-
|
|
242
|
+
if( !content ){
|
|
217
243
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
if( userId ){
|
|
221
|
-
|
|
222
|
-
await billRequest({
|
|
223
|
-
db,
|
|
224
|
-
authenticated,
|
|
225
|
-
userId,
|
|
226
|
-
model,
|
|
227
|
-
usage : tokensFromMetadata( response?.usageMetadata )
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
}
|
|
244
|
+
throw new Error( 'Could not generate from prompt. Please try again with a different prompt.' );
|
|
231
245
|
|
|
232
|
-
|
|
246
|
+
}
|
|
233
247
|
|
|
234
|
-
|
|
248
|
+
if( user?.id ){
|
|
235
249
|
|
|
236
|
-
|
|
250
|
+
await billRequest({
|
|
251
|
+
db,
|
|
252
|
+
user,
|
|
253
|
+
model,
|
|
254
|
+
usage : tokensFromMetadata( response?.usageMetadata )
|
|
255
|
+
});
|
|
237
256
|
|
|
238
257
|
}
|
|
239
258
|
|
|
259
|
+
return { content };
|
|
260
|
+
|
|
240
261
|
}
|
|
241
262
|
|
|
242
263
|
};
|
|
243
264
|
|
|
244
|
-
export { google, priceForRequest, pricing };
|
|
265
|
+
export { MARKUP, cost, costForRequest, google, priceForRequest, pricing };
|