@tuturuuu/ai 0.7.0 → 0.8.0
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/package.json +3 -3
- package/src/studio/metering.ts +24 -3
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tuturuuu/ai",
|
|
3
3
|
"license": "MIT",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.8.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "https://github.com/tutur3u/platform",
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"@streamdown/math": "^1.0.2",
|
|
77
77
|
"@streamdown/mermaid": "^1.0.2",
|
|
78
78
|
"@tuturuuu/google": "0.1.0",
|
|
79
|
-
"@tuturuuu/internal-api": "0.
|
|
79
|
+
"@tuturuuu/internal-api": "0.28.0",
|
|
80
80
|
"@tuturuuu/supabase": "0.5.0",
|
|
81
81
|
"@tuturuuu/utils": "0.22.0",
|
|
82
82
|
"@vercel/sandbox": "^2.9.2",
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
"zod": "^4.4.3"
|
|
104
104
|
},
|
|
105
105
|
"devDependencies": {
|
|
106
|
-
"@tuturuuu/types": "0.
|
|
106
|
+
"@tuturuuu/types": "0.27.0",
|
|
107
107
|
"@tuturuuu/typescript-config": "0.1.1",
|
|
108
108
|
"@types/node": "^26.1.2",
|
|
109
109
|
"@types/qrcode": "^1.5.6",
|
package/src/studio/metering.ts
CHANGED
|
@@ -188,7 +188,10 @@ export async function beginAiStudioRun(
|
|
|
188
188
|
}
|
|
189
189
|
|
|
190
190
|
export type BeginExternalAiStudioRunInput = {
|
|
191
|
-
|
|
191
|
+
/** Null for machine credentials, which run without a user. */
|
|
192
|
+
actorId: string | null;
|
|
193
|
+
/** Set when a bound API key authenticated the request, for rotation traceability. */
|
|
194
|
+
apiKeyId?: string | null;
|
|
192
195
|
externalAppId: string;
|
|
193
196
|
feature: string;
|
|
194
197
|
idempotencyKey?: string | null;
|
|
@@ -205,13 +208,18 @@ export async function beginExternalAiStudioRun(
|
|
|
205
208
|
const { data, error } = await sbAdmin
|
|
206
209
|
.schema('private')
|
|
207
210
|
.rpc('begin_external_ai_studio_run', {
|
|
211
|
+
p_api_key_id: input.apiKeyId ?? undefined,
|
|
208
212
|
p_external_app_id: input.externalAppId,
|
|
209
213
|
p_feature: input.feature,
|
|
210
214
|
p_idempotency_key: input.idempotencyKey ?? undefined,
|
|
211
215
|
p_metadata: input.metadata,
|
|
212
216
|
p_model_id: input.modelId,
|
|
213
217
|
p_request_id: input.requestId,
|
|
214
|
-
|
|
218
|
+
// Explicit null, never undefined: p_user_id has no default, so omitting it
|
|
219
|
+
// makes PostgREST fail to resolve the function. A machine credential
|
|
220
|
+
// genuinely has no user, and the column accepts NULL — the generated RPC
|
|
221
|
+
// types just cannot express a nullable argument.
|
|
222
|
+
p_user_id: input.actorId as unknown as string,
|
|
215
223
|
p_ws_id: input.workspaceId,
|
|
216
224
|
});
|
|
217
225
|
|
|
@@ -277,8 +285,20 @@ export async function settleAiStudioRun(
|
|
|
277
285
|
}
|
|
278
286
|
}
|
|
279
287
|
|
|
288
|
+
export type SettleExternalAiStudioRunInput = Omit<
|
|
289
|
+
SettleAiStudioRunInput,
|
|
290
|
+
'actualCredits'
|
|
291
|
+
> & {
|
|
292
|
+
/**
|
|
293
|
+
* What this run would have billed had it been metered. Recorded, not charged,
|
|
294
|
+
* so an app's consumption of its unmetered allocation is a reportable number
|
|
295
|
+
* rather than an invisible zero.
|
|
296
|
+
*/
|
|
297
|
+
unmeteredCredits?: number;
|
|
298
|
+
};
|
|
299
|
+
|
|
280
300
|
export async function settleExternalAiStudioRun(
|
|
281
|
-
input:
|
|
301
|
+
input: SettleExternalAiStudioRunInput
|
|
282
302
|
): Promise<void> {
|
|
283
303
|
const sbAdmin = await createAdminClient({ noCookie: true });
|
|
284
304
|
const { data, error } = await sbAdmin
|
|
@@ -297,6 +317,7 @@ export async function settleExternalAiStudioRun(
|
|
|
297
317
|
p_reasoning_tokens: input.reasoningTokens ?? 0,
|
|
298
318
|
p_run_id: input.runId,
|
|
299
319
|
p_status: input.status,
|
|
320
|
+
p_unmetered_credits: Math.max(0, input.unmeteredCredits ?? 0),
|
|
300
321
|
});
|
|
301
322
|
|
|
302
323
|
if (error || !data?.[0]?.success) {
|