@lastbrain/module-ai 2.0.26 → 2.0.30
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/README.md +52 -1
- package/dist/ai.build.config.d.ts.map +1 -1
- package/dist/ai.build.config.js +508 -9
- package/dist/api/admin/ai-provider-models/[id].d.ts +18 -0
- package/dist/api/admin/ai-provider-models/[id].d.ts.map +1 -0
- package/dist/api/admin/ai-provider-models/[id].js +58 -0
- package/dist/api/admin/ai-provider-models.d.ts +20 -0
- package/dist/api/admin/ai-provider-models.d.ts.map +1 -0
- package/dist/api/admin/ai-provider-models.js +26 -0
- package/dist/api/admin/ai-providers/[key].d.ts +18 -0
- package/dist/api/admin/ai-providers/[key].d.ts.map +1 -0
- package/dist/api/admin/ai-providers/[key].js +55 -0
- package/dist/api/admin/ai-providers.d.ts +20 -0
- package/dist/api/admin/ai-providers.d.ts.map +1 -0
- package/dist/api/admin/ai-providers.js +26 -0
- package/dist/api/admin/billing-analytics.d.ts +43 -0
- package/dist/api/admin/billing-analytics.d.ts.map +1 -0
- package/dist/api/admin/billing-analytics.js +144 -0
- package/dist/api/admin/global-ai-settings.d.ts +14 -0
- package/dist/api/admin/global-ai-settings.d.ts.map +1 -0
- package/dist/api/admin/global-ai-settings.js +63 -0
- package/dist/api/admin/token-packs/[id].d.ts.map +1 -1
- package/dist/api/admin/token-packs/[id].js +3 -2
- package/dist/api/admin/token-packs.d.ts.map +1 -1
- package/dist/api/admin/token-packs.js +3 -2
- package/dist/api/admin/user-monthly-details.d.ts +49 -0
- package/dist/api/admin/user-monthly-details.d.ts.map +1 -0
- package/dist/api/admin/user-monthly-details.js +140 -0
- package/dist/api/admin/user-quota.d.ts +21 -0
- package/dist/api/admin/user-quota.d.ts.map +1 -0
- package/dist/api/admin/user-quota.js +59 -0
- package/dist/api/admin/user-token/[id].d.ts.map +1 -1
- package/dist/api/admin/user-token/[id].js +2 -1
- package/dist/api/admin/user-token.d.ts +5 -2
- package/dist/api/admin/user-token.d.ts.map +1 -1
- package/dist/api/admin/user-token.js +91 -17
- package/dist/api/admin/user-usage-by-model.d.ts +22 -0
- package/dist/api/admin/user-usage-by-model.d.ts.map +1 -0
- package/dist/api/admin/user-usage-by-model.js +78 -0
- package/dist/api/admin/user-wallet-analytics.d.ts +15 -0
- package/dist/api/admin/user-wallet-analytics.d.ts.map +1 -0
- package/dist/api/admin/user-wallet-analytics.js +67 -0
- package/dist/api/admin/wallet-repair/route.d.ts +30 -0
- package/dist/api/admin/wallet-repair/route.d.ts.map +1 -0
- package/dist/api/admin/wallet-repair/route.js +63 -0
- package/dist/api/auth/ai-model-settings.d.ts +21 -0
- package/dist/api/auth/ai-model-settings.d.ts.map +1 -0
- package/dist/api/auth/ai-model-settings.js +86 -0
- package/dist/api/auth/ai-settings.d.ts +17 -0
- package/dist/api/auth/ai-settings.d.ts.map +1 -0
- package/dist/api/auth/ai-settings.js +87 -0
- package/dist/api/auth/api-keys/[id].d.ts +17 -0
- package/dist/api/auth/api-keys/[id].d.ts.map +1 -0
- package/dist/api/auth/api-keys/[id].js +66 -0
- package/dist/api/auth/api-keys.d.ts +19 -0
- package/dist/api/auth/api-keys.d.ts.map +1 -0
- package/dist/api/auth/api-keys.js +94 -0
- package/dist/api/auth/create-checkout.d.ts +1 -1
- package/dist/api/auth/create-checkout.d.ts.map +1 -1
- package/dist/api/auth/create-checkout.js +8 -6
- package/dist/api/auth/generate-image.d.ts +2 -2
- package/dist/api/auth/generate-image.d.ts.map +1 -1
- package/dist/api/auth/generate-image.js +404 -104
- package/dist/api/auth/generate-text.d.ts +3 -2
- package/dist/api/auth/generate-text.d.ts.map +1 -1
- package/dist/api/auth/generate-text.js +130 -58
- package/dist/api/auth/process-ocr.d.ts +9 -0
- package/dist/api/auth/process-ocr.d.ts.map +1 -0
- package/dist/api/auth/process-ocr.js +43 -0
- package/dist/api/auth/prompts/stats.d.ts +14 -0
- package/dist/api/auth/prompts/stats.d.ts.map +1 -0
- package/dist/api/auth/prompts/stats.js +46 -0
- package/dist/api/auth/prompts.d.ts +26 -0
- package/dist/api/auth/prompts.d.ts.map +1 -0
- package/dist/api/auth/prompts.js +175 -0
- package/dist/api/auth/token-balance.d.ts +26 -0
- package/dist/api/auth/token-balance.d.ts.map +1 -0
- package/dist/api/auth/token-balance.js +47 -0
- package/dist/api/auth/token-checkout.d.ts.map +1 -1
- package/dist/api/auth/token-checkout.js +22 -4
- package/dist/api/auth/token-packs.d.ts.map +1 -1
- package/dist/api/auth/token-packs.js +2 -1
- package/dist/api/auth/usage-by-model.d.ts +25 -0
- package/dist/api/auth/usage-by-model.d.ts.map +1 -0
- package/dist/api/auth/usage-by-model.js +95 -0
- package/dist/api/auth/usage.d.ts +26 -0
- package/dist/api/auth/usage.d.ts.map +1 -0
- package/dist/api/auth/usage.js +127 -0
- package/dist/api/auth/user-tokens.d.ts.map +1 -1
- package/dist/api/auth/user-tokens.js +36 -2
- package/dist/api/auth/wallet/route.d.ts +17 -0
- package/dist/api/auth/wallet/route.d.ts.map +1 -0
- package/dist/api/auth/wallet/route.js +68 -0
- package/dist/api/auth/wallet.d.ts +16 -0
- package/dist/api/auth/wallet.d.ts.map +1 -0
- package/dist/api/auth/wallet.js +71 -0
- package/dist/api/public/gateway-models.d.ts +25 -0
- package/dist/api/public/gateway-models.d.ts.map +1 -0
- package/dist/api/public/gateway-models.js +49 -0
- package/dist/api/public/pricing-summary.d.ts +46 -0
- package/dist/api/public/pricing-summary.d.ts.map +1 -0
- package/dist/api/public/pricing-summary.js +70 -0
- package/dist/api/public/prompts/[id]/stats.d.ts +15 -0
- package/dist/api/public/prompts/[id]/stats.d.ts.map +1 -0
- package/dist/api/public/prompts/[id]/stats.js +37 -0
- package/dist/api/public/prompts/[id]/view.d.ts +15 -0
- package/dist/api/public/prompts/[id]/view.d.ts.map +1 -0
- package/dist/api/public/prompts/[id]/view.js +41 -0
- package/dist/api/public/prompts/slug/[slug].d.ts +15 -0
- package/dist/api/public/prompts/slug/[slug].d.ts.map +1 -0
- package/dist/api/public/prompts/slug/[slug].js +40 -0
- package/dist/api/public/prompts/user/[username].d.ts +17 -0
- package/dist/api/public/prompts/user/[username].d.ts.map +1 -0
- package/dist/api/public/prompts/user/[username].js +51 -0
- package/dist/api/public/prompts.d.ts +15 -0
- package/dist/api/public/prompts.d.ts.map +1 -0
- package/dist/api/public/prompts.js +45 -0
- package/dist/api/public/token-packs.d.ts +11 -0
- package/dist/api/public/token-packs.d.ts.map +1 -0
- package/dist/api/public/token-packs.js +25 -0
- package/dist/api/public/token-pricing.d.ts +44 -0
- package/dist/api/public/token-pricing.d.ts.map +1 -0
- package/dist/api/public/token-pricing.js +168 -0
- package/dist/api/public/v1/_lib/artifacts.d.ts +52 -0
- package/dist/api/public/v1/_lib/artifacts.d.ts.map +1 -0
- package/dist/api/public/v1/_lib/artifacts.js +217 -0
- package/dist/api/public/v1/_lib/auth.d.ts +43 -0
- package/dist/api/public/v1/_lib/auth.d.ts.map +1 -0
- package/dist/api/public/v1/_lib/auth.js +108 -0
- package/dist/api/public/v1/_lib/errors.d.ts +17 -0
- package/dist/api/public/v1/_lib/errors.d.ts.map +1 -0
- package/dist/api/public/v1/_lib/errors.js +16 -0
- package/dist/api/public/v1/_lib/log.d.ts +29 -0
- package/dist/api/public/v1/_lib/log.d.ts.map +1 -0
- package/dist/api/public/v1/_lib/log.js +68 -0
- package/dist/api/public/v1/_lib/quota.d.ts +24 -0
- package/dist/api/public/v1/_lib/quota.d.ts.map +1 -0
- package/dist/api/public/v1/_lib/quota.js +118 -0
- package/dist/api/public/v1/_lib/router.d.ts +54 -0
- package/dist/api/public/v1/_lib/router.d.ts.map +1 -0
- package/dist/api/public/v1/_lib/router.js +119 -0
- package/dist/api/public/v1/connect.d.ts +20 -0
- package/dist/api/public/v1/connect.d.ts.map +1 -0
- package/dist/api/public/v1/connect.js +119 -0
- package/dist/api/public/v1/doc.d.ts +239 -0
- package/dist/api/public/v1/doc.d.ts.map +1 -0
- package/dist/api/public/v1/doc.js +253 -0
- package/dist/api/public/v1/history/[id].d.ts +92 -0
- package/dist/api/public/v1/history/[id].d.ts.map +1 -0
- package/dist/api/public/v1/history/[id].js +176 -0
- package/dist/api/public/v1/history.d.ts +30 -0
- package/dist/api/public/v1/history.d.ts.map +1 -0
- package/dist/api/public/v1/history.js +142 -0
- package/dist/api/public/v1/image-ai.d.ts +24 -0
- package/dist/api/public/v1/image-ai.d.ts.map +1 -0
- package/dist/api/public/v1/image-ai.js +233 -0
- package/dist/api/public/v1/prompts.d.ts +19 -0
- package/dist/api/public/v1/prompts.d.ts.map +1 -0
- package/dist/api/public/v1/prompts.js +107 -0
- package/dist/api/public/v1/provider.d.ts +16 -0
- package/dist/api/public/v1/provider.d.ts.map +1 -0
- package/dist/api/public/v1/provider.js +130 -0
- package/dist/api/public/v1/purchase.d.ts +11 -0
- package/dist/api/public/v1/purchase.d.ts.map +1 -0
- package/dist/api/public/v1/purchase.js +18 -0
- package/dist/api/public/v1/status.d.ts +35 -0
- package/dist/api/public/v1/status.d.ts.map +1 -0
- package/dist/api/public/v1/status.js +163 -0
- package/dist/api/public/v1/text-ai.d.ts +26 -0
- package/dist/api/public/v1/text-ai.d.ts.map +1 -0
- package/dist/api/public/v1/text-ai.js +239 -0
- package/dist/api/public/webhook.d.ts.map +1 -1
- package/dist/api/public/webhook.js +50 -39
- package/dist/api/track-usage.d.ts +12 -0
- package/dist/api/track-usage.d.ts.map +1 -0
- package/dist/api/track-usage.js +37 -0
- package/dist/components/Doc.d.ts.map +1 -1
- package/dist/components/Doc.js +1 -1
- package/dist/components/DocUsageCustom.js +6 -6
- package/dist/components/admin/UserTokenTab.d.ts.map +1 -1
- package/dist/components/admin/UserTokenTab.js +170 -23
- package/dist/components/auth/AuthDashboardAi.d.ts +2 -0
- package/dist/components/auth/AuthDashboardAi.d.ts.map +1 -0
- package/dist/components/auth/AuthDashboardAi.js +53 -0
- package/dist/docs/REFACTORING_BILLING_GUIDE.d.ts +277 -0
- package/dist/docs/REFACTORING_BILLING_GUIDE.d.ts.map +1 -0
- package/dist/docs/REFACTORING_BILLING_GUIDE.js +276 -0
- package/dist/index.d.ts +15 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -1
- package/dist/scripts/migrate-tokens-to-wallet.d.ts +13 -0
- package/dist/scripts/migrate-tokens-to-wallet.d.ts.map +1 -0
- package/dist/scripts/migrate-tokens-to-wallet.js +165 -0
- package/dist/server/__tests__/billing.test.d.ts +5 -0
- package/dist/server/__tests__/billing.test.d.ts.map +1 -0
- package/dist/server/__tests__/billing.test.js +223 -0
- package/dist/server/ai-client.d.ts +59 -0
- package/dist/server/ai-client.d.ts.map +1 -0
- package/dist/server/ai-client.js +111 -0
- package/dist/server/ai-generation-service.d.ts +66 -0
- package/dist/server/ai-generation-service.d.ts.map +1 -0
- package/dist/server/ai-generation-service.js +274 -0
- package/dist/server/billing.d.ts +200 -0
- package/dist/server/billing.d.ts.map +1 -0
- package/dist/server/billing.js +488 -0
- package/dist/server/gateway-service.d.ts +13 -0
- package/dist/server/gateway-service.d.ts.map +1 -0
- package/dist/server/gateway-service.js +161 -0
- package/dist/server/global-settings.d.ts +16 -0
- package/dist/server/global-settings.d.ts.map +1 -0
- package/dist/server/global-settings.js +42 -0
- package/dist/server/model-filter.d.ts +25 -0
- package/dist/server/model-filter.d.ts.map +1 -0
- package/dist/server/model-filter.js +240 -0
- package/dist/server/ocr.d.ts +39 -0
- package/dist/server/ocr.d.ts.map +1 -0
- package/dist/server/ocr.js +280 -0
- package/dist/server/openai-client.d.ts +19 -0
- package/dist/server/openai-client.d.ts.map +1 -0
- package/dist/server/openai-client.js +26 -0
- package/dist/server/pricing-config.d.ts +18 -0
- package/dist/server/pricing-config.d.ts.map +1 -0
- package/dist/server/pricing-config.js +94 -0
- package/dist/server/pricing-validator.d.ts +41 -0
- package/dist/server/pricing-validator.d.ts.map +1 -0
- package/dist/server/pricing-validator.js +113 -0
- package/dist/server/pricing.d.ts +121 -0
- package/dist/server/pricing.d.ts.map +1 -0
- package/dist/server/pricing.js +225 -0
- package/dist/server/quota.d.ts +66 -0
- package/dist/server/quota.d.ts.map +1 -0
- package/dist/server/quota.js +538 -0
- package/dist/server/wallet-repair.d.ts +32 -0
- package/dist/server/wallet-repair.d.ts.map +1 -0
- package/dist/server/wallet-repair.js +189 -0
- package/dist/server.d.ts +13 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +87 -16
- package/dist/sitemap/handlers/prompts.d.ts +6 -0
- package/dist/sitemap/handlers/prompts.d.ts.map +1 -0
- package/dist/sitemap/handlers/prompts.js +72 -0
- package/dist/sitemap/handlers/users.d.ts +6 -0
- package/dist/sitemap/handlers/users.d.ts.map +1 -0
- package/dist/sitemap/handlers/users.js +80 -0
- package/dist/sitemap/manifest.d.ts +8 -0
- package/dist/sitemap/manifest.d.ts.map +1 -0
- package/dist/sitemap/manifest.js +27 -0
- package/dist/types/gateway.d.ts +40 -0
- package/dist/types/gateway.d.ts.map +1 -0
- package/dist/types/gateway.js +4 -0
- package/dist/types/quota.d.ts +74 -0
- package/dist/types/quota.d.ts.map +1 -0
- package/dist/types/quota.js +11 -0
- package/dist/utils/date.d.ts +7 -0
- package/dist/utils/date.d.ts.map +1 -0
- package/dist/utils/date.js +17 -0
- package/dist/web/admin/AdminTokenPacksPage.js +1 -1
- package/dist/web/admin/BillingAnalyticsPage.d.ts +2 -0
- package/dist/web/admin/BillingAnalyticsPage.d.ts.map +1 -0
- package/dist/web/admin/BillingAnalyticsPage.js +141 -0
- package/dist/web/admin/GlobalAISettingsPage.d.ts +2 -0
- package/dist/web/admin/GlobalAISettingsPage.d.ts.map +1 -0
- package/dist/web/admin/GlobalAISettingsPage.js +93 -0
- package/dist/web/admin/UserTokenPage.d.ts.map +1 -1
- package/dist/web/admin/UserTokenPage.js +20 -7
- package/dist/web/auth/AISettingsPage.d.ts +2 -0
- package/dist/web/auth/AISettingsPage.d.ts.map +1 -0
- package/dist/web/auth/AISettingsPage.js +258 -0
- package/dist/web/auth/APIKeysPage.d.ts +2 -0
- package/dist/web/auth/APIKeysPage.d.ts.map +1 -0
- package/dist/web/auth/APIKeysPage.js +154 -0
- package/dist/web/auth/HistoryPage.d.ts +2 -0
- package/dist/web/auth/HistoryPage.d.ts.map +1 -0
- package/dist/web/auth/HistoryPage.js +279 -0
- package/dist/web/auth/PromptsPage.d.ts +5 -0
- package/dist/web/auth/PromptsPage.d.ts.map +1 -0
- package/dist/web/auth/PromptsPage.js +137 -0
- package/dist/web/auth/TokenPage.d.ts.map +1 -1
- package/dist/web/auth/TokenPage.js +88 -31
- package/dist/web/auth/UsageAndTokensPage.d.ts +2 -0
- package/dist/web/auth/UsageAndTokensPage.d.ts.map +1 -0
- package/dist/web/auth/UsageAndTokensPage.js +157 -0
- package/dist/web/auth/UsagePage.d.ts +2 -0
- package/dist/web/auth/UsagePage.d.ts.map +1 -0
- package/dist/web/auth/UsagePage.js +62 -0
- package/dist/web/auth/components/ApiKeyFilterSelect.d.ts +13 -0
- package/dist/web/auth/components/ApiKeyFilterSelect.d.ts.map +1 -0
- package/dist/web/auth/components/ApiKeyFilterSelect.js +16 -0
- package/dist/web/auth/components/ModelUsageTable.d.ts +19 -0
- package/dist/web/auth/components/ModelUsageTable.d.ts.map +1 -0
- package/dist/web/auth/components/ModelUsageTable.js +37 -0
- package/dist/web/auth/components/PurchaseButton.d.ts +7 -0
- package/dist/web/auth/components/PurchaseButton.d.ts.map +1 -0
- package/dist/web/auth/components/PurchaseButton.js +13 -0
- package/dist/web/auth/components/TokenHistoryCard.d.ts +20 -0
- package/dist/web/auth/components/TokenHistoryCard.d.ts.map +1 -0
- package/dist/web/auth/components/TokenHistoryCard.js +76 -0
- package/dist/web/auth/components/TokenKpiGrid.d.ts +24 -0
- package/dist/web/auth/components/TokenKpiGrid.d.ts.map +1 -0
- package/dist/web/auth/components/TokenKpiGrid.js +38 -0
- package/dist/web/auth/components/UsageByDayChart.d.ts +11 -0
- package/dist/web/auth/components/UsageByDayChart.d.ts.map +1 -0
- package/dist/web/auth/components/UsageByDayChart.js +32 -0
- package/dist/web/auth/components/UsageByModelBarChart.d.ts +12 -0
- package/dist/web/auth/components/UsageByModelBarChart.d.ts.map +1 -0
- package/dist/web/auth/components/UsageByModelBarChart.js +32 -0
- package/dist/web/auth/components/WalletStatusCard.d.ts +9 -0
- package/dist/web/auth/components/WalletStatusCard.d.ts.map +1 -0
- package/dist/web/auth/components/WalletStatusCard.js +50 -0
- package/dist/web/components/ImageGenerative.d.ts +3 -1
- package/dist/web/components/ImageGenerative.d.ts.map +1 -1
- package/dist/web/components/ImageGenerative.js +139 -52
- package/dist/web/components/TextareaGenerative.d.ts +3 -1
- package/dist/web/components/TextareaGenerative.d.ts.map +1 -1
- package/dist/web/components/TextareaGenerative.js +10 -5
- package/dist/web/public/PromptDetailPage.d.ts +25 -0
- package/dist/web/public/PromptDetailPage.d.ts.map +1 -0
- package/dist/web/public/PromptDetailPage.js +71 -0
- package/dist/web/public/PromptDetailPageServer.d.ts +15 -0
- package/dist/web/public/PromptDetailPageServer.d.ts.map +1 -0
- package/dist/web/public/PromptDetailPageServer.js +68 -0
- package/dist/web/public/PublicPromptsPage.d.ts +5 -0
- package/dist/web/public/PublicPromptsPage.d.ts.map +1 -0
- package/dist/web/public/PublicPromptsPage.js +110 -0
- package/dist/web/public/PurchaseTokensPage.d.ts +2 -0
- package/dist/web/public/PurchaseTokensPage.d.ts.map +1 -0
- package/dist/web/public/PurchaseTokensPage.js +98 -0
- package/dist/web/public/UserAvatar.d.ts +13 -0
- package/dist/web/public/UserAvatar.d.ts.map +1 -0
- package/dist/web/public/UserAvatar.js +13 -0
- package/dist/web/public/UserDetailPageServer.d.ts +15 -0
- package/dist/web/public/UserDetailPageServer.d.ts.map +1 -0
- package/dist/web/public/UserDetailPageServer.js +31 -0
- package/dist/web/public/UserPromptsPage.d.ts +9 -0
- package/dist/web/public/UserPromptsPage.d.ts.map +1 -0
- package/dist/web/public/UserPromptsPage.js +112 -0
- package/dist/web/public/UserPromptsPageServer.d.ts +15 -0
- package/dist/web/public/UserPromptsPageServer.d.ts.map +1 -0
- package/dist/web/public/UserPromptsPageServer.js +31 -0
- package/package.json +18 -9
- package/supabase/migrations/20251125000000_ai_tokens.sql +7 -0
- package/supabase/migrations/20260123100002_user_token_quota_monthly copy.sql +173 -0
- package/supabase/migrations/20260128100003_update_and_add_table.sql +368 -0
- package/supabase/migrations/20260128120000_seed_providers_models.sql +78 -0
- package/supabase/migrations/20260128131405_add_api_key_id_to_ledgers.sql +41 -0
- package/supabase/migrations/20260128140000_ai_artifacts_storage.sql +99 -0
- package/supabase/migrations/20260128140002_ai_user_settings.sql +57 -0
- package/supabase/migrations/20260128150000_drop_ai_user_settings.sql +21 -0
- package/supabase/migrations/20260128160000_wallet_billing_system.sql +192 -0
- package/supabase/migrations/20260128160001_wallet_rpc_functions.sql +165 -0
- package/supabase/migrations/20260128170000_add_pack_coef_to_token_packs.sql +30 -0
- package/supabase/migrations/20260129120000_wallet_view_rpc.sql +41 -0
- package/supabase/migrations/20260129220003_update_pack_margins.sql +31 -0
- package/supabase/migrations/20260129330004_ai_user_prompts.sql +151 -0
- package/supabase/migrations/20260129330005_ai_prompts_ip_tracking.sql +92 -0
- package/supabase/migrations/20260129330006_ai_prompts_slug.sql +64 -0
- package/supabase/migrations/20260129330007_ai_prompts_view_slug.sql +26 -0
- package/supabase/migrations/20260129440000_ai_prompts_view_username.sql +33 -0
- package/supabase/migrations/20260129450000_ai_prompts_add_lang.sql +40 -0
- package/supabase/migrations/20260131000000_extract_model_prompt_in_ledger.sql +92 -0
- package/supabase/migrations/20260131140000_fix_duplicate_purchases.sql +64 -0
- package/supabase/migrations/20260201120000_module-ai_default_models.sql +63 -0
- package/supabase/migrations/20260201130000_module-ai_remove_provider_tables.sql +17 -0
- package/supabase/migrations-down/20251217120000_user_token_quota_monthly.sql +34 -0
- package/supabase/migrations-down/20260128131405_add_api_key_id_to_ledgers.sql +25 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests unitaires pour le système de billing centralisé
|
|
3
|
+
*/
|
|
4
|
+
import { describe, it, expect } from "vitest";
|
|
5
|
+
import { computeAndDebitAIUsage } from "../billing";
|
|
6
|
+
describe("computeAndDebitAIUsage - Système de billing centralisé", () => {
|
|
7
|
+
// Wallet mock standard (pack 5$ avec coef 2.5)
|
|
8
|
+
const mockWallet = {
|
|
9
|
+
tokenBalance: 100000,
|
|
10
|
+
walletProviderBudgetUsd: 2.0, // 5$ / 2.5
|
|
11
|
+
walletSellValueUsd: 5.0,
|
|
12
|
+
};
|
|
13
|
+
describe("Application des minimums par action", () => {
|
|
14
|
+
it("recette applique minimum 0.20$", () => {
|
|
15
|
+
const result = computeAndDebitAIUsage({
|
|
16
|
+
userId: "test-user-123",
|
|
17
|
+
actionType: "generate-recipe-text",
|
|
18
|
+
providerCostUsd: 0.001, // Très bas
|
|
19
|
+
wallet: mockWallet,
|
|
20
|
+
metadata: { model: "gpt-4o-mini", provider: "openai" },
|
|
21
|
+
});
|
|
22
|
+
expect(result.success).toBe(true);
|
|
23
|
+
expect(result.sellCostUsd).toBeGreaterThanOrEqual(0.2);
|
|
24
|
+
expect(result.sellCostUsd).toBe(0.2); // Exactement le minimum
|
|
25
|
+
});
|
|
26
|
+
it("image applique minimum 0.05$", () => {
|
|
27
|
+
const result = computeAndDebitAIUsage({
|
|
28
|
+
userId: "test-user-456",
|
|
29
|
+
actionType: "generate-image",
|
|
30
|
+
providerCostUsd: 0.001,
|
|
31
|
+
wallet: mockWallet,
|
|
32
|
+
metadata: { model: "dall-e-3", provider: "openai" },
|
|
33
|
+
});
|
|
34
|
+
expect(result.success).toBe(true);
|
|
35
|
+
expect(result.sellCostUsd).toBeGreaterThanOrEqual(0.05);
|
|
36
|
+
});
|
|
37
|
+
it("generate-text générique n'applique pas de minimum", () => {
|
|
38
|
+
const result = computeAndDebitAIUsage({
|
|
39
|
+
userId: "test-user-789",
|
|
40
|
+
actionType: "generate-text",
|
|
41
|
+
providerCostUsd: 0.001,
|
|
42
|
+
wallet: mockWallet,
|
|
43
|
+
metadata: { model: "gpt-4o-mini", provider: "openai" },
|
|
44
|
+
});
|
|
45
|
+
expect(result.success).toBe(true);
|
|
46
|
+
// Avec marge 60%, sell = 0.001 / 0.4 = 0.0025, arrondi ceil = 0.0025
|
|
47
|
+
expect(result.sellCostUsd).toBeLessThan(0.01);
|
|
48
|
+
});
|
|
49
|
+
it("autocomplete n'applique pas de minimum", () => {
|
|
50
|
+
const result = computeAndDebitAIUsage({
|
|
51
|
+
userId: "test-user-abc",
|
|
52
|
+
actionType: "autocomplete",
|
|
53
|
+
providerCostUsd: 0.0001,
|
|
54
|
+
wallet: mockWallet,
|
|
55
|
+
metadata: { model: "gpt-4o-mini", provider: "openai" },
|
|
56
|
+
});
|
|
57
|
+
expect(result.success).toBe(true);
|
|
58
|
+
expect(result.sellCostUsd).toBeLessThan(0.001);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
describe("Calcul de la marge (60%)", () => {
|
|
62
|
+
it("marge correcte pour coût sans minimum", () => {
|
|
63
|
+
const result = computeAndDebitAIUsage({
|
|
64
|
+
userId: "test-user",
|
|
65
|
+
actionType: "generate-text",
|
|
66
|
+
providerCostUsd: 0.1,
|
|
67
|
+
wallet: mockWallet,
|
|
68
|
+
metadata: { model: "gpt-4o-mini" },
|
|
69
|
+
});
|
|
70
|
+
expect(result.success).toBe(true);
|
|
71
|
+
// sell = 0.1 / 0.4 = 0.25
|
|
72
|
+
expect(result.sellCostUsd).toBeCloseTo(0.25, 2);
|
|
73
|
+
expect(result.marginUsd).toBeCloseTo(0.15, 2);
|
|
74
|
+
expect(result.marginPercent).toBeCloseTo(60, 0);
|
|
75
|
+
});
|
|
76
|
+
it("marge élevée quand minimum appliqué", () => {
|
|
77
|
+
const result = computeAndDebitAIUsage({
|
|
78
|
+
userId: "test-user",
|
|
79
|
+
actionType: "generate-recipe-text",
|
|
80
|
+
providerCostUsd: 0.001, // Très bas
|
|
81
|
+
wallet: mockWallet,
|
|
82
|
+
metadata: { model: "gpt-4o-mini" },
|
|
83
|
+
});
|
|
84
|
+
expect(result.success).toBe(true);
|
|
85
|
+
expect(result.sellCostUsd).toBe(0.2); // Minimum
|
|
86
|
+
expect(result.marginUsd).toBeCloseTo(0.199, 3);
|
|
87
|
+
// Marge très élevée: (0.199 / 0.2) * 100 ≈ 99.5%
|
|
88
|
+
expect(result.marginPercent).toBeGreaterThan(99);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
describe("Vérifications budget provider", () => {
|
|
92
|
+
it("refuse si budget provider insuffisant", () => {
|
|
93
|
+
const result = computeAndDebitAIUsage({
|
|
94
|
+
userId: "test-user",
|
|
95
|
+
actionType: "generate-recipe-text",
|
|
96
|
+
providerCostUsd: 3.0, // Plus que 2.0 disponible
|
|
97
|
+
wallet: mockWallet,
|
|
98
|
+
metadata: { model: "gpt-4" },
|
|
99
|
+
});
|
|
100
|
+
expect(result.success).toBe(false);
|
|
101
|
+
expect(result.error).toBe("insufficient_credits");
|
|
102
|
+
});
|
|
103
|
+
it("refuse si sell value insuffisante", () => {
|
|
104
|
+
const result = computeAndDebitAIUsage({
|
|
105
|
+
userId: "test-user",
|
|
106
|
+
actionType: "generate-recipe-text",
|
|
107
|
+
providerCostUsd: 0.5, // OK pour provider
|
|
108
|
+
wallet: {
|
|
109
|
+
...mockWallet,
|
|
110
|
+
walletSellValueUsd: 0.1, // Insuffisant pour 0.2$ minimum
|
|
111
|
+
},
|
|
112
|
+
metadata: { model: "gpt-4o-mini" },
|
|
113
|
+
});
|
|
114
|
+
expect(result.success).toBe(false);
|
|
115
|
+
expect(result.error).toBe("insufficient_credits");
|
|
116
|
+
});
|
|
117
|
+
it("accepte si budgets suffisants", () => {
|
|
118
|
+
const result = computeAndDebitAIUsage({
|
|
119
|
+
userId: "test-user",
|
|
120
|
+
actionType: "generate-recipe-text",
|
|
121
|
+
providerCostUsd: 0.05,
|
|
122
|
+
wallet: mockWallet,
|
|
123
|
+
metadata: { model: "gpt-4o-mini" },
|
|
124
|
+
});
|
|
125
|
+
expect(result.success).toBe(true);
|
|
126
|
+
expect(result.newWallet).toBeDefined();
|
|
127
|
+
expect(result.newWallet.walletProviderBudgetUsd).toBeCloseTo(1.95, 2);
|
|
128
|
+
expect(result.newWallet.walletSellValueUsd).toBeCloseTo(4.8, 2);
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
describe("Calcul percent remaining", () => {
|
|
132
|
+
it("calcule correctement le pourcentage restant", () => {
|
|
133
|
+
const result = computeAndDebitAIUsage({
|
|
134
|
+
userId: "test-user",
|
|
135
|
+
actionType: "generate-recipe-text",
|
|
136
|
+
providerCostUsd: 0.1,
|
|
137
|
+
wallet: mockWallet,
|
|
138
|
+
metadata: { model: "gpt-4o-mini" },
|
|
139
|
+
});
|
|
140
|
+
expect(result.success).toBe(true);
|
|
141
|
+
// Débite 0.20$ (minimum) sur 5$ = reste 4.8$
|
|
142
|
+
// 4.8 / 5 = 96%
|
|
143
|
+
expect(result.newWallet.percentRemaining).toBeCloseTo(96, 0);
|
|
144
|
+
});
|
|
145
|
+
it("pourcentage proche de 0 quand presque épuisé", () => {
|
|
146
|
+
const lowWallet = {
|
|
147
|
+
tokenBalance: 1000,
|
|
148
|
+
walletProviderBudgetUsd: 0.1,
|
|
149
|
+
walletSellValueUsd: 0.25,
|
|
150
|
+
};
|
|
151
|
+
const result = computeAndDebitAIUsage({
|
|
152
|
+
userId: "test-user",
|
|
153
|
+
actionType: "generate-recipe-text",
|
|
154
|
+
providerCostUsd: 0.05,
|
|
155
|
+
wallet: lowWallet,
|
|
156
|
+
metadata: { model: "gpt-4o-mini" },
|
|
157
|
+
});
|
|
158
|
+
expect(result.success).toBe(true);
|
|
159
|
+
// 0.25 - 0.20 = 0.05 restant
|
|
160
|
+
// 0.05 / 0.25 = 20%
|
|
161
|
+
expect(result.newWallet.percentRemaining).toBeCloseTo(20, 0);
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
describe("Override minimum", () => {
|
|
165
|
+
it("permet de surcharger le minimum par action", () => {
|
|
166
|
+
const result = computeAndDebitAIUsage({
|
|
167
|
+
userId: "test-user",
|
|
168
|
+
actionType: "generate-recipe-text", // Min 0.20 par défaut
|
|
169
|
+
providerCostUsd: 0.001,
|
|
170
|
+
wallet: mockWallet,
|
|
171
|
+
metadata: { model: "gpt-4o-mini" },
|
|
172
|
+
minSellUsdOverride: 0.5, // Forcer 0.50$ minimum
|
|
173
|
+
});
|
|
174
|
+
expect(result.success).toBe(true);
|
|
175
|
+
expect(result.sellCostUsd).toBe(0.5);
|
|
176
|
+
});
|
|
177
|
+
it("override à 0 désactive le minimum", () => {
|
|
178
|
+
const result = computeAndDebitAIUsage({
|
|
179
|
+
userId: "test-user",
|
|
180
|
+
actionType: "generate-recipe-text", // Min 0.20 par défaut
|
|
181
|
+
providerCostUsd: 0.001,
|
|
182
|
+
wallet: mockWallet,
|
|
183
|
+
metadata: { model: "gpt-4o-mini" },
|
|
184
|
+
minSellUsdOverride: 0, // Désactiver minimum
|
|
185
|
+
});
|
|
186
|
+
expect(result.success).toBe(true);
|
|
187
|
+
// Marge 60% seulement: 0.001 / 0.4 = 0.0025
|
|
188
|
+
expect(result.sellCostUsd).toBeLessThan(0.01);
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
describe("Protection contre abus", () => {
|
|
192
|
+
it("empêche génération de 1000 recettes pour 5$", () => {
|
|
193
|
+
const wallet = { ...mockWallet };
|
|
194
|
+
let successCount = 0;
|
|
195
|
+
let totalCost = 0;
|
|
196
|
+
// Tenter de générer jusqu'à épuisement
|
|
197
|
+
for (let i = 0; i < 1000; i++) {
|
|
198
|
+
const result = computeAndDebitAIUsage({
|
|
199
|
+
userId: "test-user",
|
|
200
|
+
actionType: "generate-recipe-text",
|
|
201
|
+
providerCostUsd: 0.001, // Coût très bas
|
|
202
|
+
wallet,
|
|
203
|
+
metadata: { model: "gpt-4o-mini" },
|
|
204
|
+
});
|
|
205
|
+
if (result.success) {
|
|
206
|
+
successCount++;
|
|
207
|
+
totalCost += result.sellCostUsd;
|
|
208
|
+
// Mettre à jour wallet simulé
|
|
209
|
+
wallet.walletProviderBudgetUsd =
|
|
210
|
+
result.newWallet.walletProviderBudgetUsd;
|
|
211
|
+
wallet.walletSellValueUsd = result.newWallet.walletSellValueUsd;
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
// Avec minimum 0.20$ par recette, max = 5 / 0.20 = 25 recettes
|
|
218
|
+
expect(successCount).toBeLessThanOrEqual(25);
|
|
219
|
+
expect(successCount).toBeGreaterThanOrEqual(20); // Au moins 20
|
|
220
|
+
expect(totalCost).toBeLessThanOrEqual(5.01); // Légèrement plus pour arrondis
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
});
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI client using Vercel AI SDK with Gateway
|
|
3
|
+
* Gateway key (vck_...) enables direct model string usage
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Text generation using Vercel AI Gateway
|
|
7
|
+
* Model format: "provider/model" (e.g., "openai/gpt-4o-mini", "anthropic/claude-sonnet-4.5")
|
|
8
|
+
*/
|
|
9
|
+
export interface TextAIParams {
|
|
10
|
+
prompt: string;
|
|
11
|
+
model?: string;
|
|
12
|
+
system?: string;
|
|
13
|
+
maxTokens?: number;
|
|
14
|
+
temperature?: number;
|
|
15
|
+
}
|
|
16
|
+
export interface TextAIResult {
|
|
17
|
+
text: string;
|
|
18
|
+
usage?: {
|
|
19
|
+
promptTokens: number;
|
|
20
|
+
completionTokens: number;
|
|
21
|
+
totalTokens: number;
|
|
22
|
+
};
|
|
23
|
+
raw?: any;
|
|
24
|
+
}
|
|
25
|
+
export declare function textAI(params: TextAIParams): Promise<TextAIResult>;
|
|
26
|
+
/**
|
|
27
|
+
* Image generation using Vercel AI Gateway
|
|
28
|
+
* Model format: "provider/model" (e.g., "openai/dall-e-3")
|
|
29
|
+
*/
|
|
30
|
+
export interface ImageAIParams {
|
|
31
|
+
prompt: string;
|
|
32
|
+
model?: string;
|
|
33
|
+
size?: string;
|
|
34
|
+
n?: number;
|
|
35
|
+
}
|
|
36
|
+
export interface ImageAIResult {
|
|
37
|
+
imageUrl: string;
|
|
38
|
+
tokensUsed?: number;
|
|
39
|
+
raw?: any;
|
|
40
|
+
}
|
|
41
|
+
export declare function imageAI(params: ImageAIParams): Promise<ImageAIResult>;
|
|
42
|
+
/**
|
|
43
|
+
* Embedding generation using Vercel AI Gateway
|
|
44
|
+
* Model format: "provider/model" (e.g., "openai/text-embedding-3-small")
|
|
45
|
+
*/
|
|
46
|
+
export interface EmbedAIParams {
|
|
47
|
+
input: string | string[];
|
|
48
|
+
model?: string;
|
|
49
|
+
}
|
|
50
|
+
export interface EmbedAIResult {
|
|
51
|
+
embedding?: number[];
|
|
52
|
+
embeddings?: number[][];
|
|
53
|
+
usage?: {
|
|
54
|
+
tokens: number;
|
|
55
|
+
};
|
|
56
|
+
raw?: any;
|
|
57
|
+
}
|
|
58
|
+
export declare function embedAI(params: EmbedAIParams): Promise<EmbedAIResult>;
|
|
59
|
+
//# sourceMappingURL=ai-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-client.d.ts","sourceRoot":"","sources":["../../src/server/ai-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAyBH;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE;QACN,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;QACzB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,GAAG,CAAC,EAAE,GAAG,CAAC;CACX;AAED,wBAAsB,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAkCxE;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,CAAC,CAAC,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,GAAG,CAAC;CACX;AAED,wBAAsB,OAAO,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CA6C3E;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE;QACN,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,GAAG,CAAC,EAAE,GAAG,CAAC;CACX;AAED,wBAAsB,OAAO,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAwB3E"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI client using Vercel AI SDK with Gateway
|
|
3
|
+
* Gateway key (vck_...) enables direct model string usage
|
|
4
|
+
*/
|
|
5
|
+
import { generateText, generateImage, embed } from "ai";
|
|
6
|
+
import { logger } from "@lastbrain/core";
|
|
7
|
+
// Gateway API key - no need to create providers
|
|
8
|
+
const gatewayKey = process.env.AI_GATEWAY_API_KEY;
|
|
9
|
+
if (!gatewayKey) {
|
|
10
|
+
logger.error("[AI Client] AI_GATEWAY_API_KEY not configured");
|
|
11
|
+
}
|
|
12
|
+
// Get default models from environment with fallbacks
|
|
13
|
+
function getDefaultTextModel() {
|
|
14
|
+
return process.env.AI_DEFAULT_TEXT_MODEL || "openai/gpt-4o-mini";
|
|
15
|
+
}
|
|
16
|
+
function getDefaultImageModel() {
|
|
17
|
+
return process.env.AI_DEFAULT_IMAGE_MODEL || "openai/dall-e-3";
|
|
18
|
+
}
|
|
19
|
+
function getDefaultEmbedModel() {
|
|
20
|
+
return process.env.AI_DEFAULT_EMBED_MODEL || "openai/text-embedding-3-small";
|
|
21
|
+
}
|
|
22
|
+
export async function textAI(params) {
|
|
23
|
+
const fullModel = params.model || getDefaultTextModel();
|
|
24
|
+
logger.info(`[textAI] Generating text with model: ${fullModel}`);
|
|
25
|
+
try {
|
|
26
|
+
// With Gateway, pass model string directly (e.g., "openai/gpt-4o-mini")
|
|
27
|
+
const result = await generateText({
|
|
28
|
+
model: fullModel,
|
|
29
|
+
prompt: params.prompt,
|
|
30
|
+
system: params.system,
|
|
31
|
+
temperature: params.temperature,
|
|
32
|
+
...(params.maxTokens && { maxTokens: params.maxTokens }),
|
|
33
|
+
});
|
|
34
|
+
logger.info(`[textAI] Generation complete. Usage: ${JSON.stringify(result.usage)}`);
|
|
35
|
+
return {
|
|
36
|
+
text: result.text,
|
|
37
|
+
usage: result.usage
|
|
38
|
+
? {
|
|
39
|
+
promptTokens: result.usage.inputTokens ?? 0,
|
|
40
|
+
completionTokens: result.usage.outputTokens ?? 0,
|
|
41
|
+
totalTokens: result.usage.totalTokens ?? 0,
|
|
42
|
+
}
|
|
43
|
+
: undefined,
|
|
44
|
+
raw: result,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
logger.error(`[textAI] Error with model ${fullModel}:`, error);
|
|
49
|
+
throw new Error(`Text generation failed: ${error.message}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export async function imageAI(params) {
|
|
53
|
+
const fullModel = params.model || getDefaultImageModel();
|
|
54
|
+
logger.info(`[imageAI] Generating image with model: ${fullModel}`);
|
|
55
|
+
try {
|
|
56
|
+
// Use generateImage API for image generation
|
|
57
|
+
const result = await generateImage({
|
|
58
|
+
model: fullModel,
|
|
59
|
+
prompt: params.prompt,
|
|
60
|
+
});
|
|
61
|
+
// Image is available in result.image
|
|
62
|
+
if (!result.image) {
|
|
63
|
+
logger.error("[imageAI] No image generated", { result });
|
|
64
|
+
throw new Error("No image generated by the model");
|
|
65
|
+
}
|
|
66
|
+
// Convert to base64 data URL
|
|
67
|
+
const imageUrl = `data:${result.image.mediaType};base64,${result.image.base64}`;
|
|
68
|
+
// Log pour déboguer l'usage réel
|
|
69
|
+
logger.info(`[imageAI] Generated image with model ${fullModel}`, {
|
|
70
|
+
usage: result.usage,
|
|
71
|
+
rawUsage: JSON.stringify(result.usage),
|
|
72
|
+
});
|
|
73
|
+
// Use token usage from result - vérifier plusieurs formats possibles
|
|
74
|
+
const tokensUsed = result.usage?.totalTokens ||
|
|
75
|
+
result.usage?.total ||
|
|
76
|
+
result.usage?.tokens ||
|
|
77
|
+
6000;
|
|
78
|
+
logger.info(`[imageAI] Tokens used: ${tokensUsed}`);
|
|
79
|
+
return {
|
|
80
|
+
imageUrl,
|
|
81
|
+
tokensUsed,
|
|
82
|
+
raw: result,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
logger.error(`[imageAI] Error with model ${fullModel}:`, error);
|
|
87
|
+
throw new Error(`Image generation failed: ${error.message}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
export async function embedAI(params) {
|
|
91
|
+
const fullModel = params.model || getDefaultEmbedModel();
|
|
92
|
+
logger.info(`[embedAI] Generating embedding with model: ${fullModel}`);
|
|
93
|
+
try {
|
|
94
|
+
// With Gateway, pass model string directly
|
|
95
|
+
const result = await embed({
|
|
96
|
+
model: fullModel,
|
|
97
|
+
value: typeof params.input === "string"
|
|
98
|
+
? params.input
|
|
99
|
+
: params.input.join("\n"),
|
|
100
|
+
});
|
|
101
|
+
return {
|
|
102
|
+
embedding: result.embedding,
|
|
103
|
+
usage: result.usage ? { tokens: result.usage.tokens } : undefined,
|
|
104
|
+
raw: result,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
logger.error(`[embedAI] Error with model ${fullModel}:`, error);
|
|
109
|
+
throw new Error(`Embedding generation failed: ${error.message}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized AI Generation Service
|
|
3
|
+
*
|
|
4
|
+
* SINGLE SOURCE OF TRUTH for all AI generation with billing
|
|
5
|
+
* Used by both internal auth endpoints AND public API v1
|
|
6
|
+
*
|
|
7
|
+
* This service handles:
|
|
8
|
+
* 1. Pricing validation
|
|
9
|
+
* 2. Wallet pre-check (> 0)
|
|
10
|
+
* 3. AI API call
|
|
11
|
+
* 4. Real cost computation with minimums
|
|
12
|
+
* 5. Wallet debit
|
|
13
|
+
* 6. Ledger recording
|
|
14
|
+
*/
|
|
15
|
+
import { type ActionType } from "./billing";
|
|
16
|
+
export interface TextGenerationParams {
|
|
17
|
+
prompt: string;
|
|
18
|
+
model?: string;
|
|
19
|
+
systemPrompt?: string;
|
|
20
|
+
maxTokens?: number;
|
|
21
|
+
temperature?: number;
|
|
22
|
+
actionType?: ActionType;
|
|
23
|
+
context?: string;
|
|
24
|
+
promptUser?: string;
|
|
25
|
+
metadata?: Record<string, any>;
|
|
26
|
+
}
|
|
27
|
+
export interface ImageGenerationParams {
|
|
28
|
+
prompt: string;
|
|
29
|
+
model?: string;
|
|
30
|
+
size?: "256x256" | "512x512" | "1024x1024" | "1792x1024" | "1024x1792";
|
|
31
|
+
quality?: "standard" | "hd";
|
|
32
|
+
actionType?: ActionType;
|
|
33
|
+
metadata?: Record<string, any>;
|
|
34
|
+
}
|
|
35
|
+
export interface GenerationResult {
|
|
36
|
+
success: boolean;
|
|
37
|
+
error?: string;
|
|
38
|
+
errorCode?: "NO_CREDITS" | "NO_PRICING" | "MODEL_NOT_ALLOWED" | "PROVIDER_ERROR";
|
|
39
|
+
text?: string;
|
|
40
|
+
inputTokens?: number;
|
|
41
|
+
outputTokens?: number;
|
|
42
|
+
imageUrl?: string;
|
|
43
|
+
revisedPrompt?: string;
|
|
44
|
+
model?: string;
|
|
45
|
+
provider?: string;
|
|
46
|
+
providerCostUsd?: number;
|
|
47
|
+
sellCostUsd?: number;
|
|
48
|
+
marginPercent?: number;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Generate text with automatic billing
|
|
52
|
+
*
|
|
53
|
+
* @param userId User ID
|
|
54
|
+
* @param params Generation parameters
|
|
55
|
+
* @returns Generation result with billing info
|
|
56
|
+
*/
|
|
57
|
+
export declare function generateTextWithBilling(userId: string, params: TextGenerationParams): Promise<GenerationResult>;
|
|
58
|
+
/**
|
|
59
|
+
* Generate image with automatic billing
|
|
60
|
+
*
|
|
61
|
+
* @param userId User ID
|
|
62
|
+
* @param params Generation parameters
|
|
63
|
+
* @returns Generation result with billing info
|
|
64
|
+
*/
|
|
65
|
+
export declare function generateImageWithBilling(userId: string, params: ImageGenerationParams): Promise<GenerationResult>;
|
|
66
|
+
//# sourceMappingURL=ai-generation-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-generation-service.d.ts","sourceRoot":"","sources":["../../src/server/ai-generation-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAOH,OAAO,EAKL,KAAK,UAAU,EAChB,MAAM,WAAW,CAAC;AAMnB,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,CAAC;IACvE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC5B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EACN,YAAY,GACZ,YAAY,GACZ,mBAAmB,GACnB,gBAAgB,CAAC;IAGrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IAGtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IAGvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAMD;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,gBAAgB,CAAC,CAqK3B;AAMD;;;;;;GAMG;AACH,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,gBAAgB,CAAC,CAwJ3B"}
|