codecane 1.0.206 → 1.0.235
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/code-map/languages.d.ts +0 -1
- package/dist/code-map/languages.js +23 -224
- package/dist/code-map/languages.js.map +1 -1
- package/dist/code-map/parse.js +1 -0
- package/dist/code-map/parse.js.map +1 -1
- package/dist/code-map/tsconfig.tsbuildinfo +1 -1
- package/dist/common/actions.d.ts +369 -826
- package/dist/common/actions.js +25 -31
- package/dist/common/actions.js.map +1 -1
- package/dist/common/api-keys/constants.d.ts +8 -0
- package/dist/common/api-keys/constants.js +26 -0
- package/dist/common/api-keys/constants.js.map +1 -0
- package/dist/common/api-keys/crypto.d.ts +24 -0
- package/dist/common/api-keys/crypto.js +186 -0
- package/dist/common/api-keys/crypto.js.map +1 -0
- package/dist/common/bigquery/client.d.ts +15 -0
- package/dist/common/bigquery/client.js +246 -0
- package/dist/common/bigquery/client.js.map +1 -0
- package/dist/common/bigquery/schema.d.ts +55 -0
- package/dist/common/bigquery/schema.js +24 -0
- package/dist/common/bigquery/schema.js.map +1 -0
- package/dist/common/billing/auto-topup.d.ts +8 -0
- package/dist/common/billing/auto-topup.js +192 -0
- package/dist/common/billing/auto-topup.js.map +1 -0
- package/dist/common/billing/balance-calculator.d.ts +57 -0
- package/dist/common/billing/balance-calculator.js +218 -0
- package/dist/common/billing/balance-calculator.js.map +1 -0
- package/dist/common/billing/conversion.d.ts +9 -0
- package/dist/common/billing/conversion.js +20 -0
- package/dist/common/billing/conversion.js.map +1 -0
- package/dist/common/billing/credit-conversion.d.ts +24 -0
- package/dist/common/billing/credit-conversion.js +48 -0
- package/dist/common/billing/credit-conversion.js.map +1 -0
- package/dist/common/billing/grant-credits.d.ts +43 -0
- package/dist/common/billing/grant-credits.js +266 -0
- package/dist/common/billing/grant-credits.js.map +1 -0
- package/dist/common/billing/plans.d.ts +13 -0
- package/dist/common/billing/plans.js +44 -0
- package/dist/common/billing/plans.js.map +1 -0
- package/dist/common/browser-actions.d.ts +1 -1
- package/dist/common/browser-actions.js +4 -4
- package/dist/common/browser-actions.js.map +1 -1
- package/dist/common/constants/grant-priorities.d.ts +2 -0
- package/dist/common/constants/grant-priorities.js +10 -0
- package/dist/common/constants/grant-priorities.js.map +1 -0
- package/dist/common/constants/tools.d.ts +2 -0
- package/dist/common/constants/tools.js +24 -3
- package/dist/common/constants/tools.js.map +1 -1
- package/dist/common/constants.d.ts +93 -5
- package/dist/common/constants.js +111 -10
- package/dist/common/constants.js.map +1 -1
- package/dist/common/db/env.mjs +5 -5
- package/dist/common/db/env.mjs.map +1 -1
- package/dist/common/db/schema.d.ts +413 -83
- package/dist/common/db/schema.js +70 -9
- package/dist/common/db/schema.js.map +1 -1
- package/dist/common/db/transaction.d.ts +12 -0
- package/dist/common/db/transaction.js +36 -0
- package/dist/common/db/transaction.js.map +1 -0
- package/dist/common/env.mjs +11 -8
- package/dist/common/env.mjs.map +1 -1
- package/dist/common/json-config/__tests__/__snapshots__/stringify-schema.test.js.snap +66 -0
- package/dist/common/json-config/__tests__/stringify-schema.test.js +66 -0
- package/dist/common/json-config/__tests__/stringify-schema.test.js.map +1 -0
- package/dist/common/json-config/constants.d.ts +82 -0
- package/dist/common/json-config/constants.js +48 -0
- package/dist/common/json-config/constants.js.map +1 -0
- package/dist/common/json-config/parser.d.ts +7 -0
- package/dist/common/json-config/parser.js +51 -0
- package/dist/common/json-config/parser.js.map +1 -0
- package/dist/common/json-config/stringify-schema.d.ts +10 -0
- package/dist/common/json-config/stringify-schema.js +102 -0
- package/dist/common/json-config/stringify-schema.js.map +1 -0
- package/dist/common/project-file-tree.d.ts +2 -1
- package/dist/common/project-file-tree.js +59 -27
- package/dist/common/project-file-tree.js.map +1 -1
- package/dist/common/types/agent-state.d.ts +25 -22
- package/dist/common/types/agent-state.js +2 -0
- package/dist/common/types/agent-state.js.map +1 -1
- package/dist/common/types/grant.d.ts +2 -0
- package/dist/common/types/grant.js +10 -0
- package/dist/common/types/grant.js.map +1 -0
- package/dist/common/types/usage.d.ts +37 -18
- package/dist/common/types/usage.js +9 -6
- package/dist/common/types/usage.js.map +1 -1
- package/dist/common/util/__tests__/saxy.test.js +262 -0
- package/dist/common/util/__tests__/saxy.test.js.map +1 -0
- package/dist/common/util/__tests__/string.test.js +2 -3
- package/dist/common/util/__tests__/string.test.js.map +1 -1
- package/dist/common/util/changes.d.ts +1 -0
- package/dist/common/util/changes.js +8 -2
- package/dist/common/util/changes.js.map +1 -1
- package/dist/common/util/dates.d.ts +10 -1
- package/dist/common/util/dates.js +11 -2
- package/dist/common/util/dates.js.map +1 -1
- package/dist/common/util/file.d.ts +10 -9
- package/dist/common/util/file.js +12 -4
- package/dist/common/util/file.js.map +1 -1
- package/dist/common/util/logger.d.ts +8 -0
- package/dist/common/util/logger.js +52 -0
- package/dist/common/util/logger.js.map +1 -0
- package/dist/common/util/lru-cache.d.ts +23 -2
- package/dist/common/util/lru-cache.js +44 -18
- package/dist/common/util/lru-cache.js.map +1 -1
- package/dist/common/util/messages.d.ts +3 -0
- package/dist/common/util/messages.js +50 -3
- package/dist/common/util/messages.js.map +1 -1
- package/dist/common/util/min-heap.js +2 -2
- package/dist/common/util/min-heap.js.map +1 -1
- package/dist/common/util/promise.d.ts +1 -1
- package/dist/common/util/promise.js +2 -2
- package/dist/common/util/promise.js.map +1 -1
- package/dist/common/util/saxy.d.ts +8 -0
- package/dist/common/util/saxy.js +35 -12
- package/dist/common/util/saxy.js.map +1 -1
- package/dist/common/util/string.d.ts +7 -1
- package/dist/common/util/string.js +20 -4
- package/dist/common/util/string.js.map +1 -1
- package/dist/common/util/stripe.d.ts +1 -0
- package/dist/common/util/stripe.js +10 -7
- package/dist/common/util/stripe.js.map +1 -1
- package/dist/common/util/sync-failure.d.ts +1 -0
- package/dist/common/util/sync-failure.js +57 -0
- package/dist/common/util/sync-failure.js.map +1 -0
- package/dist/common/websockets/websocket-client.d.ts +2 -1
- package/dist/common/websockets/websocket-client.js +34 -6
- package/dist/common/websockets/websocket-client.js.map +1 -1
- package/dist/common/websockets/websocket-schema.d.ts +1440 -2642
- package/dist/utils/__tests__/response-example-4-files.txt +621 -0
- package/package.json +20 -35
- package/dist/browser-runner.d.ts +0 -35
- package/dist/browser-runner.js +0 -674
- package/dist/browser-runner.js.map +0 -1
- package/dist/chat-storage.d.ts +0 -2
- package/dist/chat-storage.js +0 -93
- package/dist/chat-storage.js.map +0 -1
- package/dist/checkpoints/checkpoint-manager.d.ts +0 -73
- package/dist/checkpoints/checkpoint-manager.js +0 -193
- package/dist/checkpoints/checkpoint-manager.js.map +0 -1
- package/dist/checkpoints/file-manager.d.ts +0 -72
- package/dist/checkpoints/file-manager.js +0 -303
- package/dist/checkpoints/file-manager.js.map +0 -1
- package/dist/cli.d.ts +0 -48
- package/dist/cli.js +0 -604
- package/dist/cli.js.map +0 -1
- package/dist/client.d.ts +0 -229
- package/dist/client.js +0 -550
- package/dist/client.js.map +0 -1
- package/dist/common/billing/quota-manager.d.ts +0 -29
- package/dist/common/billing/quota-manager.js +0 -213
- package/dist/common/billing/quota-manager.js.map +0 -1
- package/dist/common/util/tools.d.ts +0 -2
- package/dist/common/util/tools.js +0 -13
- package/dist/common/util/tools.js.map +0 -1
- package/dist/config.d.ts +0 -3
- package/dist/config.js +0 -9
- package/dist/config.js.map +0 -1
- package/dist/create-template-project.d.ts +0 -1
- package/dist/create-template-project.js +0 -107
- package/dist/create-template-project.js.map +0 -1
- package/dist/credentials.d.ts +0 -4
- package/dist/credentials.js +0 -37
- package/dist/credentials.js.map +0 -1
- package/dist/fingerprint.d.ts +0 -1
- package/dist/fingerprint.js +0 -43
- package/dist/fingerprint.js.map +0 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -108
- package/dist/index.js.map +0 -1
- package/dist/menu.d.ts +0 -3
- package/dist/menu.js +0 -117
- package/dist/menu.js.map +0 -1
- package/dist/project-files.d.ts +0 -110
- package/dist/project-files.js +0 -490
- package/dist/project-files.js.map +0 -1
- package/dist/tool-handlers.d.ts +0 -27
- package/dist/tool-handlers.js +0 -217
- package/dist/tool-handlers.js.map +0 -1
- package/dist/types.d.ts +0 -7
- package/dist/types.js +0 -3
- package/dist/types.js.map +0 -1
- package/dist/update-codebuff.d.ts +0 -1
- package/dist/update-codebuff.js +0 -156
- package/dist/update-codebuff.js.map +0 -1
- package/dist/utils/__tests__/xml-stream-parser.test.js +0 -221
- package/dist/utils/__tests__/xml-stream-parser.test.js.map +0 -1
- package/dist/utils/detect-shell.d.ts +0 -1
- package/dist/utils/detect-shell.js +0 -60
- package/dist/utils/detect-shell.js.map +0 -1
- package/dist/utils/logger.d.ts +0 -2
- package/dist/utils/logger.js +0 -33
- package/dist/utils/logger.js.map +0 -1
- package/dist/utils/spinner.d.ts +0 -11
- package/dist/utils/spinner.js +0 -87
- package/dist/utils/spinner.js.map +0 -1
- package/dist/utils/system-info.d.ts +0 -8
- package/dist/utils/system-info.js +0 -22
- package/dist/utils/system-info.js.map +0 -1
- package/dist/utils/terminal.d.ts +0 -27
- package/dist/utils/terminal.js +0 -335
- package/dist/utils/terminal.js.map +0 -1
- package/dist/utils/tool-renderers.d.ts +0 -16
- package/dist/utils/tool-renderers.js +0 -117
- package/dist/utils/tool-renderers.js.map +0 -1
- package/dist/utils/xml-stream-parser.d.ts +0 -9
- package/dist/utils/xml-stream-parser.js +0 -128
- package/dist/utils/xml-stream-parser.js.map +0 -1
- package/dist/web-scraper.d.ts +0 -3
- package/dist/web-scraper.js +0 -57
- package/dist/web-scraper.js.map +0 -1
- package/dist/workers/checkpoint-worker.js +0 -47
- package/dist/workers/checkpoint-worker.js.map +0 -1
- package/dist/workers/project-context.d.ts +0 -1
- package/dist/workers/project-context.js +0 -17
- package/dist/workers/project-context.js.map +0 -1
- /package/dist/{utils/__tests__/xml-stream-parser.test.d.ts → common/json-config/__tests__/stringify-schema.test.d.ts} +0 -0
- /package/dist/{workers/checkpoint-worker.d.ts → common/util/__tests__/saxy.test.d.ts} +0 -0
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.setupBigQuery = setupBigQuery;
|
|
4
|
+
exports.insertTrace = insertTrace;
|
|
5
|
+
exports.insertRelabel = insertRelabel;
|
|
6
|
+
exports.getRecentTraces = getRecentTraces;
|
|
7
|
+
exports.getRecentRelabels = getRecentRelabels;
|
|
8
|
+
exports.getTracesWithoutRelabels = getTracesWithoutRelabels;
|
|
9
|
+
exports.getTracesWithRelabels = getTracesWithRelabels;
|
|
10
|
+
exports.getTracesAndRelabelsForUser = getTracesAndRelabelsForUser;
|
|
11
|
+
const bigquery_1 = require("@google-cloud/bigquery");
|
|
12
|
+
const logger_1 = require("../util/logger");
|
|
13
|
+
const schema_1 = require("./schema");
|
|
14
|
+
const DATASET = process.env.NEXT_PUBLIC_CB_ENVIRONMENT === 'production'
|
|
15
|
+
? 'codebuff_data'
|
|
16
|
+
: 'codebuff_data_dev';
|
|
17
|
+
const TRACES_TABLE = 'traces';
|
|
18
|
+
const RELABELS_TABLE = 'relabels';
|
|
19
|
+
// Create a single BigQuery client instance to be used by all functions
|
|
20
|
+
const client = new bigquery_1.BigQuery();
|
|
21
|
+
async function setupBigQuery(dataset = DATASET) {
|
|
22
|
+
try {
|
|
23
|
+
// Ensure dataset exists
|
|
24
|
+
const [ds] = await client.dataset(dataset).get({ autoCreate: true });
|
|
25
|
+
// Ensure tables exist
|
|
26
|
+
await ds.table(TRACES_TABLE).get({
|
|
27
|
+
autoCreate: true,
|
|
28
|
+
schema: schema_1.TRACES_SCHEMA,
|
|
29
|
+
timePartitioning: {
|
|
30
|
+
type: 'MONTH',
|
|
31
|
+
field: 'created_at',
|
|
32
|
+
},
|
|
33
|
+
clustering: {
|
|
34
|
+
fields: ['user_id', 'agent_step_id'],
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
await ds.table(RELABELS_TABLE).get({
|
|
38
|
+
autoCreate: true,
|
|
39
|
+
schema: schema_1.RELABELS_SCHEMA,
|
|
40
|
+
timePartitioning: {
|
|
41
|
+
type: 'MONTH',
|
|
42
|
+
field: 'created_at',
|
|
43
|
+
},
|
|
44
|
+
clustering: {
|
|
45
|
+
fields: ['user_id', 'agent_step_id'],
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
console.log('Failed to initialize BigQuery', JSON.stringify(error));
|
|
51
|
+
logger_1.logger.error({ error }, 'Failed to initialize BigQuery');
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
async function insertTrace(trace, dataset = DATASET) {
|
|
55
|
+
try {
|
|
56
|
+
// Create a copy of the trace and stringify payload if needed
|
|
57
|
+
const traceToInsert = {
|
|
58
|
+
...trace,
|
|
59
|
+
payload: trace.payload && typeof trace.payload !== 'string'
|
|
60
|
+
? JSON.stringify(trace.payload)
|
|
61
|
+
: trace.payload,
|
|
62
|
+
};
|
|
63
|
+
await client.dataset(dataset).table(TRACES_TABLE).insert(traceToInsert);
|
|
64
|
+
logger_1.logger.debug({ traceId: trace.id, type: trace.type }, 'Inserted trace into BigQuery');
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
logger_1.logger.error({ error, traceId: trace.id }, 'Failed to insert trace into BigQuery');
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async function insertRelabel(relabel, dataset = DATASET) {
|
|
73
|
+
try {
|
|
74
|
+
// Stringify payload if needed
|
|
75
|
+
const relabelToInsert = {
|
|
76
|
+
...relabel,
|
|
77
|
+
payload: relabel.payload && typeof relabel.payload !== 'string'
|
|
78
|
+
? JSON.stringify(relabel.payload)
|
|
79
|
+
: relabel.payload,
|
|
80
|
+
};
|
|
81
|
+
await client.dataset(dataset).table(RELABELS_TABLE).insert(relabelToInsert);
|
|
82
|
+
logger_1.logger.debug({ relabelId: relabel.id }, 'Inserted relabel into BigQuery');
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
logger_1.logger.error({ error, relabelId: relabel.id }, 'Failed to insert relabel into BigQuery');
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async function getRecentTraces(limit = 10, dataset = DATASET) {
|
|
91
|
+
const query = `
|
|
92
|
+
SELECT * FROM ${dataset}.${TRACES_TABLE}
|
|
93
|
+
ORDER BY created_at DESC
|
|
94
|
+
LIMIT ${limit}
|
|
95
|
+
`;
|
|
96
|
+
const [rows] = await client.query(query);
|
|
97
|
+
// Parse the payload as JSON if it's a string
|
|
98
|
+
return rows.map((row) => ({
|
|
99
|
+
...row,
|
|
100
|
+
payload: typeof row.payload === 'string' ? JSON.parse(row.payload) : row.payload,
|
|
101
|
+
}));
|
|
102
|
+
}
|
|
103
|
+
async function getRecentRelabels(limit = 10, dataset = DATASET) {
|
|
104
|
+
const query = `
|
|
105
|
+
SELECT * FROM ${dataset}.${RELABELS_TABLE}
|
|
106
|
+
ORDER BY created_at DESC
|
|
107
|
+
LIMIT ${limit}
|
|
108
|
+
`;
|
|
109
|
+
const [rows] = await client.query(query);
|
|
110
|
+
// Parse the payload as JSON if it's a string
|
|
111
|
+
return rows.map((row) => ({
|
|
112
|
+
...row,
|
|
113
|
+
payload: typeof row.payload === 'string' ? JSON.parse(row.payload) : row.payload,
|
|
114
|
+
}));
|
|
115
|
+
}
|
|
116
|
+
async function getTracesWithoutRelabels(model, limit = 100, userId = undefined, dataset = DATASET) {
|
|
117
|
+
// TODO: Optimize query, maybe only get traces in last 30 days etc
|
|
118
|
+
const query = `
|
|
119
|
+
SELECT t.*
|
|
120
|
+
FROM \`${dataset}.${TRACES_TABLE}\` t
|
|
121
|
+
LEFT JOIN (
|
|
122
|
+
SELECT r.agent_step_id, r.user_id, JSON_EXTRACT_SCALAR(r.payload, '$.user_input_id') as user_input_id
|
|
123
|
+
FROM \`${dataset}.${RELABELS_TABLE}\` r
|
|
124
|
+
WHERE r.model = '${model}'
|
|
125
|
+
${userId ? `AND r.user_id = '${userId}'` : ''}
|
|
126
|
+
) r
|
|
127
|
+
ON t.agent_step_id = r.agent_step_id
|
|
128
|
+
AND t.user_id = r.user_id
|
|
129
|
+
AND JSON_EXTRACT_SCALAR(t.payload, '$.user_input_id') = r.user_input_id
|
|
130
|
+
WHERE t.type = 'get-relevant-files'
|
|
131
|
+
AND r.agent_step_id IS NULL
|
|
132
|
+
${userId ? `AND t.user_id = '${userId}'` : ''}
|
|
133
|
+
ORDER BY t.created_at DESC
|
|
134
|
+
LIMIT ${limit}
|
|
135
|
+
`;
|
|
136
|
+
const [rows] = await client.query(query);
|
|
137
|
+
// Parse the payload as JSON if it's a string
|
|
138
|
+
return rows.map((row) => ({
|
|
139
|
+
...row,
|
|
140
|
+
payload: typeof row.payload === 'string' ? JSON.parse(row.payload) : row.payload,
|
|
141
|
+
}));
|
|
142
|
+
}
|
|
143
|
+
async function getTracesWithRelabels(model, limit = 100, dataset = DATASET) {
|
|
144
|
+
// Get traces that DO have matching relabels for the specified model
|
|
145
|
+
const query = `
|
|
146
|
+
SELECT
|
|
147
|
+
ANY_VALUE(t) as trace,
|
|
148
|
+
ARRAY_AGG(r ORDER BY r.created_at DESC LIMIT 1)[OFFSET(0)] as relabel
|
|
149
|
+
FROM \`${dataset}.${TRACES_TABLE}\` t
|
|
150
|
+
INNER JOIN (
|
|
151
|
+
SELECT *
|
|
152
|
+
FROM \`${dataset}.${RELABELS_TABLE}\` r
|
|
153
|
+
WHERE r.model = '${model}'
|
|
154
|
+
) r
|
|
155
|
+
ON t.agent_step_id = r.agent_step_id
|
|
156
|
+
AND t.user_id = r.user_id
|
|
157
|
+
AND JSON_EXTRACT_SCALAR(t.payload, '$.user_input_id') = JSON_EXTRACT_SCALAR(r.payload, '$.user_input_id')
|
|
158
|
+
WHERE t.type = 'get-relevant-files'
|
|
159
|
+
AND JSON_EXTRACT_SCALAR(t.payload, '$.output') IS NOT NULL
|
|
160
|
+
AND JSON_EXTRACT_SCALAR(r.payload, '$.output') IS NOT NULL
|
|
161
|
+
GROUP BY t.agent_step_id
|
|
162
|
+
ORDER BY MAX(t.created_at) DESC
|
|
163
|
+
LIMIT ${limit}
|
|
164
|
+
`;
|
|
165
|
+
const [rows] = await client.query(query);
|
|
166
|
+
// Filter out any results where either trace or relabel data is missing
|
|
167
|
+
const res = rows
|
|
168
|
+
.filter((row) => row.trace && row.relabel)
|
|
169
|
+
.map((row) => ({
|
|
170
|
+
trace: row.trace,
|
|
171
|
+
relabel: row.relabel,
|
|
172
|
+
}));
|
|
173
|
+
// Parse the payload as JSON if it's a string
|
|
174
|
+
return res.map((row) => ({
|
|
175
|
+
...row,
|
|
176
|
+
trace: {
|
|
177
|
+
...row.trace,
|
|
178
|
+
payload: typeof row.trace.payload === 'string'
|
|
179
|
+
? JSON.parse(row.trace.payload)
|
|
180
|
+
: row.trace.payload,
|
|
181
|
+
},
|
|
182
|
+
relabel: {
|
|
183
|
+
...row.relabel,
|
|
184
|
+
payload: typeof row.relabel.payload === 'string'
|
|
185
|
+
? JSON.parse(row.relabel.payload)
|
|
186
|
+
: row.relabel.payload,
|
|
187
|
+
},
|
|
188
|
+
}));
|
|
189
|
+
}
|
|
190
|
+
async function getTracesAndRelabelsForUser(userId, limit = 50, dataset = DATASET) {
|
|
191
|
+
// Get recent traces for the user and any associated relabels
|
|
192
|
+
const query = `
|
|
193
|
+
WITH traces AS (
|
|
194
|
+
SELECT
|
|
195
|
+
id,
|
|
196
|
+
agent_step_id,
|
|
197
|
+
user_id,
|
|
198
|
+
created_at,
|
|
199
|
+
type,
|
|
200
|
+
payload
|
|
201
|
+
FROM \`${dataset}.${TRACES_TABLE}\`
|
|
202
|
+
WHERE user_id = '${userId}' AND type = 'get-relevant-files'
|
|
203
|
+
ORDER BY created_at DESC
|
|
204
|
+
LIMIT ${limit}
|
|
205
|
+
)
|
|
206
|
+
SELECT
|
|
207
|
+
t.id,
|
|
208
|
+
ANY_VALUE(t.agent_step_id) as agent_step_id,
|
|
209
|
+
ANY_VALUE(t.user_id) as user_id,
|
|
210
|
+
ANY_VALUE(t.created_at) as created_at,
|
|
211
|
+
ANY_VALUE(t.type) as type,
|
|
212
|
+
ANY_VALUE(t.payload) as payload,
|
|
213
|
+
ARRAY_AGG(r IGNORE NULLS) as relabels
|
|
214
|
+
FROM traces t
|
|
215
|
+
LEFT JOIN \`${dataset}.${RELABELS_TABLE}\` r
|
|
216
|
+
ON t.agent_step_id = r.agent_step_id
|
|
217
|
+
AND t.user_id = r.user_id
|
|
218
|
+
AND JSON_EXTRACT_SCALAR(t.payload, '$.user_input_id') = JSON_EXTRACT_SCALAR(r.payload, '$.user_input_id')
|
|
219
|
+
GROUP BY t.id
|
|
220
|
+
ORDER BY ANY_VALUE(t.created_at) DESC
|
|
221
|
+
`;
|
|
222
|
+
const [rows] = await client.query(query);
|
|
223
|
+
// Process and parse the results
|
|
224
|
+
return rows.map((row) => {
|
|
225
|
+
// Create trace object from individual fields
|
|
226
|
+
const trace = {
|
|
227
|
+
id: row.id,
|
|
228
|
+
agent_step_id: row.agent_step_id,
|
|
229
|
+
user_id: row.user_id,
|
|
230
|
+
created_at: row.created_at,
|
|
231
|
+
type: row.type,
|
|
232
|
+
payload: typeof row.payload === 'string' ? JSON.parse(row.payload) : row.payload,
|
|
233
|
+
};
|
|
234
|
+
// Parse relabel payloads (if any exist)
|
|
235
|
+
const relabels = row.relabels && row.relabels.length > 0
|
|
236
|
+
? row.relabels.map((relabel) => ({
|
|
237
|
+
...relabel,
|
|
238
|
+
payload: typeof relabel.payload === 'string'
|
|
239
|
+
? JSON.parse(relabel.payload)
|
|
240
|
+
: relabel.payload,
|
|
241
|
+
}))
|
|
242
|
+
: [];
|
|
243
|
+
return { trace, relabels };
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/bigquery/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { TableSchema } from '@google-cloud/bigquery';
|
|
2
|
+
interface BaseEvent {
|
|
3
|
+
id: string;
|
|
4
|
+
agent_step_id: string;
|
|
5
|
+
user_id: string;
|
|
6
|
+
}
|
|
7
|
+
interface BasePayload {
|
|
8
|
+
user_input_id: string;
|
|
9
|
+
client_session_id: string;
|
|
10
|
+
fingerprint_id: string;
|
|
11
|
+
}
|
|
12
|
+
export type TraceType = 'get-relevant-files' | 'file-trees' | 'agent-response';
|
|
13
|
+
export interface BaseTrace extends BaseEvent {
|
|
14
|
+
created_at: Date;
|
|
15
|
+
type: TraceType;
|
|
16
|
+
payload: unknown;
|
|
17
|
+
}
|
|
18
|
+
export interface GetRelevantFilesPayload extends BasePayload {
|
|
19
|
+
messages: unknown;
|
|
20
|
+
system: unknown;
|
|
21
|
+
output: string;
|
|
22
|
+
request_type: string;
|
|
23
|
+
cost_mode: string;
|
|
24
|
+
model?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface GetRelevantFilesTrace extends BaseTrace {
|
|
27
|
+
type: 'get-relevant-files';
|
|
28
|
+
payload: GetRelevantFilesPayload;
|
|
29
|
+
}
|
|
30
|
+
interface FileTreePayload extends BasePayload {
|
|
31
|
+
filetrees: Record<number, string>;
|
|
32
|
+
}
|
|
33
|
+
export interface FileTreeTrace extends BaseTrace {
|
|
34
|
+
type: 'file-trees';
|
|
35
|
+
payload: FileTreePayload;
|
|
36
|
+
}
|
|
37
|
+
interface AgentResponsePayload extends BasePayload {
|
|
38
|
+
output: string;
|
|
39
|
+
}
|
|
40
|
+
export interface AgentResponseTrace extends BaseTrace {
|
|
41
|
+
type: 'agent-response';
|
|
42
|
+
payload: AgentResponsePayload;
|
|
43
|
+
}
|
|
44
|
+
export type Trace = GetRelevantFilesTrace | FileTreeTrace | AgentResponseTrace;
|
|
45
|
+
export declare const TRACES_SCHEMA: TableSchema;
|
|
46
|
+
interface RelabelPayload extends BasePayload {
|
|
47
|
+
output: string;
|
|
48
|
+
}
|
|
49
|
+
export interface Relabel extends BaseEvent {
|
|
50
|
+
created_at: Date;
|
|
51
|
+
model: string;
|
|
52
|
+
payload: RelabelPayload;
|
|
53
|
+
}
|
|
54
|
+
export declare const RELABELS_SCHEMA: TableSchema;
|
|
55
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RELABELS_SCHEMA = exports.TRACES_SCHEMA = void 0;
|
|
4
|
+
exports.TRACES_SCHEMA = {
|
|
5
|
+
fields: [
|
|
6
|
+
{ name: 'id', type: 'STRING', mode: 'REQUIRED' }, // UUID
|
|
7
|
+
{ name: 'agent_step_id', type: 'STRING', mode: 'REQUIRED' }, // Used to link traces together within a single agent step
|
|
8
|
+
{ name: 'user_id', type: 'STRING', mode: 'REQUIRED' }, // user ID
|
|
9
|
+
{ name: 'created_at', type: 'TIMESTAMP', mode: 'REQUIRED' },
|
|
10
|
+
{ name: 'type', type: 'STRING', mode: 'REQUIRED' },
|
|
11
|
+
{ name: 'payload', type: 'JSON', mode: 'REQUIRED' },
|
|
12
|
+
],
|
|
13
|
+
};
|
|
14
|
+
exports.RELABELS_SCHEMA = {
|
|
15
|
+
fields: [
|
|
16
|
+
{ name: 'id', type: 'STRING', mode: 'REQUIRED' }, // UUID
|
|
17
|
+
{ name: 'agent_step_id', type: 'STRING', mode: 'REQUIRED' }, // Used to link traces together within a single agent step
|
|
18
|
+
{ name: 'user_id', type: 'STRING', mode: 'REQUIRED' }, // user ID
|
|
19
|
+
{ name: 'created_at', type: 'TIMESTAMP', mode: 'REQUIRED' },
|
|
20
|
+
{ name: 'model', type: 'STRING', mode: 'REQUIRED' },
|
|
21
|
+
{ name: 'payload', type: 'JSON', mode: 'REQUIRED' },
|
|
22
|
+
],
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/bigquery/schema.ts"],"names":[],"mappings":";;;AA4Da,QAAA,aAAa,GAAgB;IACxC,MAAM,EAAE;QACN,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,OAAO;QACzD,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,0DAA0D;QACvH,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,UAAU;QACjE,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE;QAC3D,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE;QAClD,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE;KACpD;CACF,CAAA;AAYY,QAAA,eAAe,GAAgB;IAC1C,MAAM,EAAE;QACN,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,OAAO;QACzD,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,0DAA0D;QACvH,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,UAAU;QACjE,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE;QAC3D,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE;QACnD,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE;KACpD;CACF,CAAA"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type Stripe from 'stripe';
|
|
2
|
+
interface AutoTopupValidationResult {
|
|
3
|
+
blockedReason: string | null;
|
|
4
|
+
validPaymentMethod: Stripe.PaymentMethod | null;
|
|
5
|
+
}
|
|
6
|
+
export declare function validateAutoTopupStatus(userId: string): Promise<AutoTopupValidationResult>;
|
|
7
|
+
export declare function checkAndTriggerAutoTopup(userId: string): Promise<void>;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.validateAutoTopupStatus = validateAutoTopupStatus;
|
|
30
|
+
exports.checkAndTriggerAutoTopup = checkAndTriggerAutoTopup;
|
|
31
|
+
const db_1 = __importDefault(require("../db"));
|
|
32
|
+
const schema = __importStar(require("../db/schema"));
|
|
33
|
+
const drizzle_orm_1 = require("drizzle-orm");
|
|
34
|
+
const stripe_1 = require("../util/stripe");
|
|
35
|
+
const logger_1 = require("../util/logger");
|
|
36
|
+
const grant_credits_1 = require("./grant-credits");
|
|
37
|
+
const balance_calculator_1 = require("./balance-calculator");
|
|
38
|
+
const conversion_1 = require("./conversion");
|
|
39
|
+
const string_1 = require("../util/string");
|
|
40
|
+
const env_mjs_1 = require("src/env.mjs");
|
|
41
|
+
const MINIMUM_PURCHASE_CREDITS = 500;
|
|
42
|
+
class AutoTopupValidationError extends Error {
|
|
43
|
+
constructor(message) {
|
|
44
|
+
super(message);
|
|
45
|
+
this.name = 'AutoTopupValidationError';
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
class AutoTopupPaymentError extends Error {
|
|
49
|
+
constructor(message) {
|
|
50
|
+
super(message);
|
|
51
|
+
this.name = 'AutoTopupPaymentError';
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
async function validateAutoTopupStatus(userId) {
|
|
55
|
+
const logContext = { userId };
|
|
56
|
+
try {
|
|
57
|
+
const user = await db_1.default.query.user.findFirst({
|
|
58
|
+
where: (0, drizzle_orm_1.eq)(schema.user.id, userId),
|
|
59
|
+
columns: {
|
|
60
|
+
stripe_customer_id: true,
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
if (!user?.stripe_customer_id) {
|
|
64
|
+
throw new AutoTopupValidationError(`You don't have a valid account with us. Please log in at ${env_mjs_1.env.NEXT_PUBLIC_APP_URL}/login`);
|
|
65
|
+
}
|
|
66
|
+
const paymentMethods = await stripe_1.stripeServer.paymentMethods.list({
|
|
67
|
+
customer: user.stripe_customer_id,
|
|
68
|
+
type: 'card',
|
|
69
|
+
});
|
|
70
|
+
const validPaymentMethod = paymentMethods.data.find((pm) => pm.card?.exp_year &&
|
|
71
|
+
pm.card.exp_month &&
|
|
72
|
+
new Date(pm.card.exp_year, pm.card.exp_month - 1) > new Date());
|
|
73
|
+
if (!validPaymentMethod) {
|
|
74
|
+
throw new AutoTopupValidationError('You need a valid payment method to enable auto top-up. Try buying some credits!');
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
blockedReason: null,
|
|
78
|
+
validPaymentMethod,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
const blockedReason = error instanceof AutoTopupValidationError
|
|
83
|
+
? error.message
|
|
84
|
+
: 'Unable to verify payment method status.';
|
|
85
|
+
await disableAutoTopup(userId, blockedReason);
|
|
86
|
+
return {
|
|
87
|
+
blockedReason,
|
|
88
|
+
validPaymentMethod: null,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
async function disableAutoTopup(userId, reason) {
|
|
93
|
+
await db_1.default
|
|
94
|
+
.update(schema.user)
|
|
95
|
+
.set({ auto_topup_enabled: false })
|
|
96
|
+
.where((0, drizzle_orm_1.eq)(schema.user.id, userId));
|
|
97
|
+
logger_1.logger.info({ userId, reason }, 'Disabled auto top-up');
|
|
98
|
+
}
|
|
99
|
+
async function processAutoTopupPayment(userId, amountToTopUp, stripeCustomerId, paymentMethod) {
|
|
100
|
+
const logContext = { userId, amountToTopUp };
|
|
101
|
+
const operationId = `auto-${userId}-${(0, string_1.generateCompactId)()}`;
|
|
102
|
+
const centsPerCredit = await (0, conversion_1.getUserCostPerCredit)(userId);
|
|
103
|
+
const amountInCents = (0, conversion_1.convertCreditsToUsdCents)(amountToTopUp, centsPerCredit);
|
|
104
|
+
if (amountInCents <= 0) {
|
|
105
|
+
throw new AutoTopupPaymentError('Invalid payment amount calculated');
|
|
106
|
+
}
|
|
107
|
+
const paymentIntent = await stripe_1.stripeServer.paymentIntents.create({
|
|
108
|
+
amount: amountInCents,
|
|
109
|
+
currency: 'usd',
|
|
110
|
+
customer: stripeCustomerId,
|
|
111
|
+
payment_method: paymentMethod.id,
|
|
112
|
+
off_session: true,
|
|
113
|
+
confirm: true,
|
|
114
|
+
description: `Auto top-up: ${amountToTopUp.toLocaleString()} credits`,
|
|
115
|
+
metadata: {
|
|
116
|
+
userId,
|
|
117
|
+
credits: amountToTopUp.toString(),
|
|
118
|
+
operationId,
|
|
119
|
+
grantType: 'purchase',
|
|
120
|
+
type: 'auto-topup',
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
if (paymentIntent.status !== 'succeeded') {
|
|
124
|
+
throw new AutoTopupPaymentError('Payment failed or requires action');
|
|
125
|
+
}
|
|
126
|
+
await (0, grant_credits_1.processAndGrantCredit)(userId, amountToTopUp, 'purchase', `Auto top-up of ${amountToTopUp.toLocaleString()} credits`, null, operationId);
|
|
127
|
+
logger_1.logger.info({
|
|
128
|
+
...logContext,
|
|
129
|
+
operationId,
|
|
130
|
+
paymentIntentId: paymentIntent.id,
|
|
131
|
+
}, 'Auto top-up payment succeeded and credits granted');
|
|
132
|
+
}
|
|
133
|
+
async function checkAndTriggerAutoTopup(userId) {
|
|
134
|
+
const logContext = { userId };
|
|
135
|
+
try {
|
|
136
|
+
const user = await db_1.default.query.user.findFirst({
|
|
137
|
+
where: (0, drizzle_orm_1.eq)(schema.user.id, userId),
|
|
138
|
+
columns: {
|
|
139
|
+
id: true,
|
|
140
|
+
stripe_customer_id: true,
|
|
141
|
+
auto_topup_enabled: true,
|
|
142
|
+
auto_topup_threshold: true,
|
|
143
|
+
auto_topup_amount: true,
|
|
144
|
+
next_quota_reset: true,
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
if (!user ||
|
|
148
|
+
!user.auto_topup_enabled ||
|
|
149
|
+
user.auto_topup_threshold === null ||
|
|
150
|
+
user.auto_topup_amount === null ||
|
|
151
|
+
!user.stripe_customer_id) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
const { blockedReason, validPaymentMethod } = await validateAutoTopupStatus(userId);
|
|
155
|
+
if (blockedReason || !validPaymentMethod) {
|
|
156
|
+
throw new Error(blockedReason || 'Auto top-up is not available.');
|
|
157
|
+
}
|
|
158
|
+
const { balance } = await (0, balance_calculator_1.calculateUsageAndBalance)(userId, user.next_quota_reset ?? new Date(0));
|
|
159
|
+
if (balance.totalRemaining >= user.auto_topup_threshold && balance.totalDebt === 0) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const amountToTopUp = balance.totalDebt > 0
|
|
163
|
+
? Math.max(user.auto_topup_amount, balance.totalDebt)
|
|
164
|
+
: user.auto_topup_amount;
|
|
165
|
+
if (amountToTopUp < MINIMUM_PURCHASE_CREDITS) {
|
|
166
|
+
logger_1.logger.warn(logContext, `Auto-top-up triggered but amount ${amountToTopUp} is less than minimum ${MINIMUM_PURCHASE_CREDITS}. Skipping top-up. Check user settings.`);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
logger_1.logger.info({
|
|
170
|
+
...logContext,
|
|
171
|
+
currentBalance: balance.totalRemaining,
|
|
172
|
+
currentDebt: balance.totalDebt,
|
|
173
|
+
threshold: user.auto_topup_threshold,
|
|
174
|
+
amountToTopUp,
|
|
175
|
+
}, `Auto-top-up triggered for user ${userId}. Attempting to purchase ${amountToTopUp} credits.`);
|
|
176
|
+
try {
|
|
177
|
+
await processAutoTopupPayment(userId, amountToTopUp, user.stripe_customer_id, validPaymentMethod);
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
const message = error instanceof AutoTopupPaymentError
|
|
181
|
+
? error.message
|
|
182
|
+
: 'Payment failed. Please check your payment method and re-enable auto top-up.';
|
|
183
|
+
await disableAutoTopup(userId, message);
|
|
184
|
+
throw new Error(message);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
logger_1.logger.error({ ...logContext, error }, `Error during auto-top-up check for user ${userId}`);
|
|
189
|
+
throw error;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=auto-topup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-topup.js","sourceRoot":"","sources":["../../src/billing/auto-topup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import db from '../db';
|
|
2
|
+
import { GrantType } from '../db/schema';
|
|
3
|
+
export interface CreditBalance {
|
|
4
|
+
totalRemaining: number;
|
|
5
|
+
totalDebt: number;
|
|
6
|
+
netBalance: number;
|
|
7
|
+
breakdown: Partial<Record<GrantType, number>>;
|
|
8
|
+
principals: Partial<Record<GrantType, number>>;
|
|
9
|
+
}
|
|
10
|
+
export interface CreditUsageAndBalance {
|
|
11
|
+
usageThisCycle: number;
|
|
12
|
+
balance: CreditBalance;
|
|
13
|
+
}
|
|
14
|
+
export interface CreditConsumptionResult {
|
|
15
|
+
consumed: number;
|
|
16
|
+
fromPurchased: number;
|
|
17
|
+
}
|
|
18
|
+
type DbConn = Pick<typeof db, 'select' | 'update'>;
|
|
19
|
+
/**
|
|
20
|
+
* Gets active grants for a user, ordered by expiration (soonest first), then priority, and creation date.
|
|
21
|
+
* Added optional `conn` param so callers inside a transaction can supply their TX object.
|
|
22
|
+
*/
|
|
23
|
+
export declare function getOrderedActiveGrants(userId: string, now: Date, conn?: DbConn): Promise<{
|
|
24
|
+
created_at: Date;
|
|
25
|
+
type: import("../types/grant").GrantType;
|
|
26
|
+
expires_at: Date | null;
|
|
27
|
+
operation_id: string;
|
|
28
|
+
user_id: string;
|
|
29
|
+
principal: number;
|
|
30
|
+
balance: number;
|
|
31
|
+
description: string | null;
|
|
32
|
+
priority: number;
|
|
33
|
+
}[]>;
|
|
34
|
+
/**
|
|
35
|
+
* Calculates both the current balance and usage in this cycle in a single query.
|
|
36
|
+
* This is more efficient than calculating them separately.
|
|
37
|
+
*/
|
|
38
|
+
export declare function calculateUsageAndBalance(userId: string, quotaResetDate: Date, now?: Date): Promise<CreditUsageAndBalance>;
|
|
39
|
+
/**
|
|
40
|
+
* Updates the remaining amounts in credit grants after consumption.
|
|
41
|
+
* Follows priority order strictly - higher priority grants (lower number) are consumed first.
|
|
42
|
+
* Returns details about credit consumption including how many came from purchased credits.
|
|
43
|
+
*
|
|
44
|
+
* Uses SERIALIZABLE isolation to prevent concurrent modifications that could lead to
|
|
45
|
+
* incorrect credit usage (e.g., "double spending" credits).
|
|
46
|
+
*
|
|
47
|
+
* @param userId The ID of the user
|
|
48
|
+
* @param creditsToConsume Number of credits being consumed
|
|
49
|
+
* @returns Promise resolving to number of credits consumed
|
|
50
|
+
*/
|
|
51
|
+
export declare function consumeCredits(userId: string, creditsToConsume: number): Promise<CreditConsumptionResult>;
|
|
52
|
+
/**
|
|
53
|
+
* Calculate the total credits used during the current billing cycle for a user
|
|
54
|
+
* by summing the difference between initial and remaining amounts for all relevant grants.
|
|
55
|
+
*/
|
|
56
|
+
export declare function calculateUsageThisCycle(userId: string, quotaResetDate: Date): Promise<number>;
|
|
57
|
+
export {};
|