@undefineds.co/xpod 0.1.7 → 0.2.0-preview.2
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 +141 -2
- package/config/cli.json +9 -71
- package/config/cloud.json +34 -7
- package/config/local.json +6 -2
- package/config/resolver.json +11 -49
- package/config/runtime-open.json +22 -0
- package/config/xpod.base.json +32 -0
- package/config/xpod.cluster.json +2 -44
- package/config/xpod.json +5 -2
- package/dist/api/auth/AuthContext.d.ts +12 -1
- package/dist/api/auth/AuthContext.js +18 -1
- package/dist/api/auth/AuthContext.js.map +1 -1
- package/dist/api/auth/ClientCredentialsAuthenticator.d.ts +0 -1
- package/dist/api/auth/ClientCredentialsAuthenticator.js.map +1 -1
- package/dist/api/auth/ServiceTokenAuthenticator.d.ts +18 -0
- package/dist/api/auth/ServiceTokenAuthenticator.js +50 -0
- package/dist/api/auth/ServiceTokenAuthenticator.js.map +1 -0
- package/dist/api/auth/index.d.ts +1 -0
- package/dist/api/auth/index.js +1 -0
- package/dist/api/auth/index.js.map +1 -1
- package/dist/api/chatkit/ai-provider.d.ts +0 -10
- package/dist/api/chatkit/ai-provider.js +11 -120
- package/dist/api/chatkit/ai-provider.js.map +1 -1
- package/dist/api/chatkit/default-agent.js +11 -8
- package/dist/api/chatkit/default-agent.js.map +1 -1
- package/dist/api/chatkit/pod-store.js +19 -3
- package/dist/api/chatkit/pod-store.js.map +1 -1
- package/dist/api/chatkit/schema.d.ts +9 -3
- package/dist/api/chatkit/schema.js +14 -6
- package/dist/api/chatkit/schema.js.map +1 -1
- package/dist/api/container/business-token.d.ts +9 -0
- package/dist/api/container/business-token.js +32 -0
- package/dist/api/container/business-token.js.map +1 -0
- package/dist/api/container/cloud.js +36 -12
- package/dist/api/container/cloud.js.map +1 -1
- package/dist/api/container/common.js +12 -5
- package/dist/api/container/common.js.map +1 -1
- package/dist/api/container/index.js +94 -14
- package/dist/api/container/index.js.map +1 -1
- package/dist/api/container/local.js +2 -1
- package/dist/api/container/local.js.map +1 -1
- package/dist/api/container/routes.js +81 -9
- package/dist/api/container/routes.js.map +1 -1
- package/dist/api/container/types.d.ts +8 -6
- package/dist/api/container/types.js.map +1 -1
- package/dist/api/handlers/AdminHandler.js +9 -9
- package/dist/api/handlers/AdminHandler.js.map +1 -1
- package/dist/api/handlers/ApiKeyHandler.js +0 -6
- package/dist/api/handlers/ApiKeyHandler.js.map +1 -1
- package/dist/api/handlers/EdgeNodeSignalHandler.d.ts +17 -0
- package/dist/api/handlers/EdgeNodeSignalHandler.js +171 -0
- package/dist/api/handlers/EdgeNodeSignalHandler.js.map +1 -0
- package/dist/api/handlers/PodManagementHandler.d.ts +5 -4
- package/dist/api/handlers/PodManagementHandler.js +11 -10
- package/dist/api/handlers/PodManagementHandler.js.map +1 -1
- package/dist/api/handlers/ProvisionHandler.d.ts +42 -0
- package/dist/api/handlers/ProvisionHandler.js +161 -0
- package/dist/api/handlers/ProvisionHandler.js.map +1 -0
- package/dist/api/handlers/QuotaHandler.d.ts +7 -7
- package/dist/api/handlers/QuotaHandler.js +143 -73
- package/dist/api/handlers/QuotaHandler.js.map +1 -1
- package/dist/api/handlers/SubdomainClientHandler.js +2 -2
- package/dist/api/handlers/SubdomainClientHandler.js.map +1 -1
- package/dist/api/handlers/SubdomainHandler.js +13 -8
- package/dist/api/handlers/SubdomainHandler.js.map +1 -1
- package/dist/api/handlers/UsageHandler.d.ts +14 -0
- package/dist/api/handlers/UsageHandler.js +123 -0
- package/dist/api/handlers/UsageHandler.js.map +1 -0
- package/dist/api/handlers/index.d.ts +3 -1
- package/dist/api/handlers/index.js +3 -1
- package/dist/api/handlers/index.js.map +1 -1
- package/dist/api/main.js +18 -0
- package/dist/api/main.js.map +1 -1
- package/dist/api/middleware/OpenAuthMiddleware.d.ts +12 -0
- package/dist/api/middleware/OpenAuthMiddleware.js +27 -0
- package/dist/api/middleware/OpenAuthMiddleware.js.map +1 -0
- package/dist/api/runtime.d.ts +15 -0
- package/dist/api/runtime.js +104 -0
- package/dist/api/runtime.js.map +1 -0
- package/dist/api/service/VercelChatService.d.ts +16 -7
- package/dist/api/service/VercelChatService.js +98 -178
- package/dist/api/service/VercelChatService.js.map +1 -1
- package/dist/api/store/DrizzleClientCredentialsStore.d.ts +6 -11
- package/dist/api/store/DrizzleClientCredentialsStore.js +9 -39
- package/dist/api/store/DrizzleClientCredentialsStore.js.map +1 -1
- package/dist/authorization/AuthModeSelector.d.ts +10 -0
- package/dist/authorization/AuthModeSelector.js +27 -0
- package/dist/authorization/AuthModeSelector.js.map +1 -0
- package/dist/authorization/AuthModeSelector.jsonld +81 -0
- package/dist/cli/commands/account.d.ts +6 -0
- package/dist/cli/commands/account.js +119 -0
- package/dist/cli/commands/account.js.map +1 -0
- package/dist/cli/commands/auth.js +20 -29
- package/dist/cli/commands/auth.js.map +1 -1
- package/dist/cli/commands/backup.d.ts +15 -0
- package/dist/cli/commands/backup.js +286 -0
- package/dist/cli/commands/backup.js.map +1 -0
- package/dist/cli/commands/config.d.ts +34 -3
- package/dist/cli/commands/config.js +195 -258
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/doctor.d.ts +6 -0
- package/dist/cli/commands/doctor.js +94 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/pod.d.ts +6 -0
- package/dist/cli/commands/pod.js +124 -0
- package/dist/cli/commands/pod.js.map +1 -0
- package/dist/cli/commands/start.js +28 -5
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/index.js +9 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/lib/credentials-store.d.ts +17 -0
- package/dist/cli/lib/credentials-store.js +73 -0
- package/dist/cli/lib/credentials-store.js.map +1 -0
- package/dist/cli/lib/css-account.d.ts +17 -0
- package/dist/cli/lib/css-account.js +56 -0
- package/dist/cli/lib/css-account.js.map +1 -1
- package/dist/cli/lib/pod-thread-store.d.ts +57 -0
- package/dist/cli/lib/pod-thread-store.js +310 -0
- package/dist/cli/lib/pod-thread-store.js.map +1 -0
- package/dist/cli/lib/solid-auth.d.ts +20 -0
- package/dist/cli/lib/solid-auth.js +70 -0
- package/dist/cli/lib/solid-auth.js.map +1 -0
- package/dist/components/components.jsonld +5 -8
- package/dist/components/context.jsonld +114 -244
- package/dist/edge/EdgeNodeAgent.js +2 -2
- package/dist/edge/EdgeNodeAgent.js.map +1 -1
- package/dist/edge/EdgeNodeDnsCoordinator.d.ts +1 -7
- package/dist/edge/EdgeNodeDnsCoordinator.js +31 -41
- package/dist/edge/EdgeNodeDnsCoordinator.js.map +1 -1
- package/dist/edge/EdgeNodeDnsCoordinator.jsonld +1 -27
- package/dist/edge/EdgeNodeModeDetector.d.ts +1 -1
- package/dist/edge/EdgeNodeModeDetector.js +9 -11
- package/dist/edge/EdgeNodeModeDetector.js.map +1 -1
- package/dist/http/ClusterIngressRouter.js +3 -3
- package/dist/http/ClusterIngressRouter.js.map +1 -1
- package/dist/http/ClusterWebSocketConfigurator.js +2 -2
- package/dist/http/ClusterWebSocketConfigurator.js.map +1 -1
- package/dist/http/PodRoutingHttpHandler.js +2 -2
- package/dist/http/PodRoutingHttpHandler.js.map +1 -1
- package/dist/http/cluster/PodMigrationHttpHandler.d.ts +1 -1
- package/dist/http/cluster/PodMigrationHttpHandler.js +1 -1
- package/dist/http/cluster/PodMigrationHttpHandler.js.map +1 -1
- package/dist/identity/drizzle/EdgeNodeRepository.d.ts +37 -4
- package/dist/identity/drizzle/EdgeNodeRepository.js +120 -128
- package/dist/identity/drizzle/EdgeNodeRepository.js.map +1 -1
- package/dist/identity/drizzle/ServiceTokenRepository.d.ts +52 -0
- package/dist/identity/drizzle/ServiceTokenRepository.js +143 -0
- package/dist/identity/drizzle/ServiceTokenRepository.js.map +1 -0
- package/dist/identity/drizzle/db.d.ts +9 -0
- package/dist/identity/drizzle/db.js +208 -1
- package/dist/identity/drizzle/db.js.map +1 -1
- package/dist/identity/drizzle/schema.pg.d.ts +5 -0
- package/dist/identity/drizzle/schema.pg.js +49 -20
- package/dist/identity/drizzle/schema.pg.js.map +1 -1
- package/dist/identity/drizzle/schema.sqlite.d.ts +332 -57
- package/dist/identity/drizzle/schema.sqlite.js +48 -18
- package/dist/identity/drizzle/schema.sqlite.js.map +1 -1
- package/dist/identity/oidc/AutoDetectIdentityProviderHandler.js +6 -4
- package/dist/identity/oidc/AutoDetectIdentityProviderHandler.js.map +1 -1
- package/dist/index.d.ts +6 -9
- package/dist/index.js +12 -14
- package/dist/index.js.map +1 -1
- package/dist/main.js +25 -8
- package/dist/main.js.map +1 -1
- package/dist/provision/ProvisionCodeCodec.d.ts +39 -0
- package/dist/provision/ProvisionCodeCodec.js +65 -0
- package/dist/provision/ProvisionCodeCodec.js.map +1 -0
- package/dist/provision/ProvisionCodeCodec.jsonld +47 -0
- package/dist/provision/ProvisionPodCreator.d.ts +20 -0
- package/dist/provision/ProvisionPodCreator.js +84 -0
- package/dist/provision/ProvisionPodCreator.js.map +1 -0
- package/dist/provision/ProvisionPodCreator.jsonld +118 -0
- package/dist/quota/DrizzleQuotaService.d.ts +17 -3
- package/dist/quota/DrizzleQuotaService.js +108 -8
- package/dist/quota/DrizzleQuotaService.js.map +1 -1
- package/dist/quota/DrizzleQuotaService.jsonld +33 -22
- package/dist/quota/NoopQuotaService.d.ts +7 -1
- package/dist/quota/NoopQuotaService.js +12 -0
- package/dist/quota/NoopQuotaService.js.map +1 -1
- package/dist/quota/NoopQuotaService.jsonld +24 -0
- package/dist/quota/QuotaService.d.ts +17 -0
- package/dist/quota/QuotaService.js +5 -0
- package/dist/quota/QuotaService.js.map +1 -1
- package/dist/quota/QuotaService.jsonld +50 -0
- package/dist/runtime/Proxy.d.ts +22 -4
- package/dist/runtime/Proxy.js +154 -35
- package/dist/runtime/Proxy.js.map +1 -1
- package/dist/runtime/XpodRuntime.d.ts +49 -0
- package/dist/runtime/XpodRuntime.js +374 -0
- package/dist/runtime/XpodRuntime.js.map +1 -0
- package/dist/runtime/env-utils.d.ts +2 -0
- package/dist/runtime/env-utils.js +55 -0
- package/dist/runtime/env-utils.js.map +1 -0
- package/dist/runtime/index.d.ts +4 -0
- package/dist/runtime/index.js +8 -1
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/socket-fetch.d.ts +1 -0
- package/dist/runtime/socket-fetch.js +72 -0
- package/dist/runtime/socket-fetch.js.map +1 -0
- package/dist/runtime/socket-http.d.ts +1 -0
- package/dist/runtime/socket-http.js +142 -0
- package/dist/runtime/socket-http.js.map +1 -0
- package/dist/runtime/socket-utils.d.ts +2 -0
- package/dist/runtime/socket-utils.js +34 -0
- package/dist/runtime/socket-utils.js.map +1 -0
- package/dist/service/{EdgeNodeHeartbeatService.d.ts → EdgeNodeSignalClient.d.ts} +3 -3
- package/dist/service/{EdgeNodeHeartbeatService.js → EdgeNodeSignalClient.js} +4 -4
- package/dist/service/EdgeNodeSignalClient.js.map +1 -0
- package/dist/service/PodMigrationService.d.ts +1 -2
- package/dist/service/PodMigrationService.js +1 -2
- package/dist/service/PodMigrationService.js.map +1 -1
- package/dist/storage/SparqlUpdateResourceStore.js +1 -1
- package/dist/storage/SparqlUpdateResourceStore.js.map +1 -1
- package/dist/storage/accessors/MinioDataAccessor.d.ts +6 -0
- package/dist/storage/accessors/MinioDataAccessor.js +10 -0
- package/dist/storage/accessors/MinioDataAccessor.js.map +1 -1
- package/dist/storage/accessors/MinioDataAccessor.jsonld +4 -0
- package/dist/storage/accessors/MixDataAccessor.d.ts +2 -1
- package/dist/storage/accessors/MixDataAccessor.js +12 -1
- package/dist/storage/accessors/MixDataAccessor.js.map +1 -1
- package/dist/storage/accessors/MixDataAccessor.jsonld +19 -0
- package/dist/storage/locking/UrlAwareRedisLocker.d.ts +18 -0
- package/dist/storage/locking/UrlAwareRedisLocker.js +60 -0
- package/dist/storage/locking/UrlAwareRedisLocker.js.map +1 -0
- package/dist/storage/locking/UrlAwareRedisLocker.jsonld +123 -0
- package/dist/storage/quota/UsageRepository.d.ts +41 -8
- package/dist/storage/quota/UsageRepository.js +252 -50
- package/dist/storage/quota/UsageRepository.js.map +1 -1
- package/dist/storage/sparql/ComunicaQuintEngine.d.ts +9 -0
- package/dist/storage/sparql/ComunicaQuintEngine.js +50 -9
- package/dist/storage/sparql/ComunicaQuintEngine.js.map +1 -1
- package/dist/storage/sparql/QueryOptimizer.js +13 -1
- package/dist/storage/sparql/QueryOptimizer.js.map +1 -1
- package/dist/storage/sparql/QuintQuerySource.d.ts +14 -0
- package/dist/storage/sparql/QuintQuerySource.js +152 -1
- package/dist/storage/sparql/QuintQuerySource.js.map +1 -1
- package/dist/storage/sparql/SubgraphQueryEngine.d.ts +1 -0
- package/dist/storage/sparql/SubgraphQueryEngine.js +6 -2
- package/dist/storage/sparql/SubgraphQueryEngine.js.map +1 -1
- package/dist/storage/sparql/SubgraphQueryEngine.jsonld +4 -0
- package/dist/subdomain/SubdomainClient.d.ts +3 -3
- package/dist/subdomain/SubdomainClient.js +1 -1
- package/dist/subdomain/SubdomainClient.js.map +1 -1
- package/dist/subdomain/SubdomainService.d.ts +15 -16
- package/dist/subdomain/SubdomainService.js +80 -54
- package/dist/subdomain/SubdomainService.js.map +1 -1
- package/dist/subdomain/SubdomainService.jsonld +22 -26
- package/dist/supervisor/Supervisor.d.ts +7 -2
- package/dist/supervisor/Supervisor.js +33 -1
- package/dist/supervisor/Supervisor.js.map +1 -1
- package/dist/test-utils/index.d.ts +4 -0
- package/dist/test-utils/index.js +8 -0
- package/dist/test-utils/index.js.map +1 -0
- package/dist/test-utils/no-auth-xpod.d.ts +11 -0
- package/dist/test-utils/no-auth-xpod.js +25 -0
- package/dist/test-utils/no-auth-xpod.js.map +1 -0
- package/dist/test-utils/seed-pod.d.ts +5 -0
- package/dist/test-utils/seed-pod.js +61 -0
- package/dist/test-utils/seed-pod.js.map +1 -0
- package/package.json +23 -5
- package/templates/identity/account/create-pod.html.ejs +110 -0
- package/templates/main.html.ejs +10 -0
- package/dist/api/handlers/DevHandler.d.ts +0 -18
- package/dist/api/handlers/DevHandler.js +0 -276
- package/dist/api/handlers/DevHandler.js.map +0 -1
- package/dist/api/handlers/SignalHandler.d.ts +0 -13
- package/dist/api/handlers/SignalHandler.js +0 -122
- package/dist/api/handlers/SignalHandler.js.map +0 -1
- package/dist/gateway/Proxy.d.ts +0 -24
- package/dist/gateway/Proxy.js +0 -209
- package/dist/gateway/Proxy.js.map +0 -1
- package/dist/gateway/Supervisor.d.ts +0 -2
- package/dist/gateway/Supervisor.js +0 -7
- package/dist/gateway/Supervisor.js.map +0 -1
- package/dist/gateway/port-finder.d.ts +0 -4
- package/dist/gateway/port-finder.js +0 -15
- package/dist/gateway/port-finder.js.map +0 -1
- package/dist/gateway/types.d.ts +0 -1
- package/dist/gateway/types.js +0 -3
- package/dist/gateway/types.js.map +0 -1
- package/dist/http/SignalInterceptHttpHandler.d.ts +0 -24
- package/dist/http/SignalInterceptHttpHandler.js +0 -47
- package/dist/http/SignalInterceptHttpHandler.js.map +0 -1
- package/dist/http/SignalInterceptHttpHandler.jsonld +0 -103
- package/dist/http/admin/EdgeNodeSignalHttpHandler.d.ts +0 -71
- package/dist/http/admin/EdgeNodeSignalHttpHandler.js +0 -674
- package/dist/http/admin/EdgeNodeSignalHttpHandler.js.map +0 -1
- package/dist/http/admin/EdgeNodeSignalHttpHandler.jsonld +0 -406
- package/dist/http/cluster/PodMigrationHttpHandler.jsonld +0 -169
- package/dist/quota/DefaultQuotaService.d.ts +0 -16
- package/dist/quota/DefaultQuotaService.js +0 -37
- package/dist/quota/DefaultQuotaService.js.map +0 -1
- package/dist/quota/DefaultQuotaService.jsonld +0 -85
- package/dist/service/EdgeNodeHeartbeatService.js.map +0 -1
- package/dist/service/PodMigrationService.jsonld +0 -76
- package/dist/storage/MigratableDataAccessor.d.ts +0 -63
- package/dist/storage/MigratableDataAccessor.js +0 -11
- package/dist/storage/MigratableDataAccessor.js.map +0 -1
- package/dist/storage/MigratableDataAccessor.jsonld +0 -60
- package/dist/storage/accessors/TieredMinioDataAccessor.d.ts +0 -150
- package/dist/storage/accessors/TieredMinioDataAccessor.js +0 -582
- package/dist/storage/accessors/TieredMinioDataAccessor.js.map +0 -1
- package/dist/storage/accessors/TieredMinioDataAccessor.jsonld +0 -333
- package/static/app/assets/index.css +0 -1
- package/static/app/assets/main.js +0 -11
|
@@ -6,7 +6,6 @@ const ai_1 = require("ai");
|
|
|
6
6
|
const global_logger_factory_1 = require("global-logger-factory");
|
|
7
7
|
const undici_1 = require("undici");
|
|
8
8
|
const AuthContext_1 = require("../auth/AuthContext");
|
|
9
|
-
const default_agent_1 = require("../chatkit/default-agent");
|
|
10
9
|
const types_1 = require("../../credential/schema/types");
|
|
11
10
|
const provider_registry_1 = require("./provider-registry");
|
|
12
11
|
// Create a proxy-aware fetch function
|
|
@@ -20,6 +19,13 @@ class VercelChatService {
|
|
|
20
19
|
this.logger = (0, global_logger_factory_1.getLoggerFor)(this);
|
|
21
20
|
this.logger.info('Initializing VercelChatService with Pod-based config support');
|
|
22
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Set optional usage tracking dependencies (injected after construction)
|
|
24
|
+
*/
|
|
25
|
+
setUsageTracking(usageRepo, quotaService) {
|
|
26
|
+
this.usageRepo = usageRepo;
|
|
27
|
+
this.quotaService = quotaService;
|
|
28
|
+
}
|
|
23
29
|
/**
|
|
24
30
|
* Create a StoreContext from AuthContext for Pod operations
|
|
25
31
|
*/
|
|
@@ -39,26 +45,26 @@ class VercelChatService {
|
|
|
39
45
|
this.logger.warn(`Failed to get Pod config, falling back to defaults: ${error}`);
|
|
40
46
|
config = undefined;
|
|
41
47
|
}
|
|
42
|
-
// Priority: Pod config >
|
|
48
|
+
// Priority: Pod config > Platform Provider
|
|
43
49
|
if (config?.apiKey) {
|
|
44
50
|
const baseURL = config.baseUrl || (0, provider_registry_1.getDefaultBaseUrl)();
|
|
45
51
|
const proxy = config.proxyUrl;
|
|
46
52
|
this.logger.info(`Provider config: baseURL=${baseURL}, proxy=${proxy || 'none'} (source=pod)`);
|
|
47
53
|
return { baseURL, apiKey: config.apiKey, proxy, credentialId: config.credentialId };
|
|
48
54
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
this.logger.info(`Provider config: baseURL=${
|
|
53
|
-
return { baseURL, apiKey: process.env.DEFAULT_API_KEY, proxy: undefined, credentialId: undefined };
|
|
55
|
+
// 平台 Provider
|
|
56
|
+
const platformBase = process.env.DEFAULT_API_BASE;
|
|
57
|
+
if (platformBase) {
|
|
58
|
+
this.logger.info(`Provider config: baseURL=${platformBase}, proxy=none (source=platform)`);
|
|
59
|
+
return { baseURL: platformBase, apiKey: process.env.DEFAULT_API_KEY || '', proxy: undefined, credentialId: undefined };
|
|
54
60
|
}
|
|
55
|
-
this.logger.warn('No AI provider config found in Pod or
|
|
61
|
+
this.logger.warn('No AI provider config found in Pod or DEFAULT_API_BASE');
|
|
56
62
|
return null;
|
|
57
63
|
}
|
|
58
64
|
async getProvider(context) {
|
|
59
65
|
const providerConfig = await this.getProviderConfig(context);
|
|
60
66
|
if (!providerConfig) {
|
|
61
|
-
const err = new Error('No AI provider configured. Please configure Pod AI provider or
|
|
67
|
+
const err = new Error('No AI provider configured. Please configure Pod AI provider or set DEFAULT_API_BASE.');
|
|
62
68
|
err.code = 'model_not_configured';
|
|
63
69
|
throw err;
|
|
64
70
|
}
|
|
@@ -75,7 +81,14 @@ class VercelChatService {
|
|
|
75
81
|
const context = this.createStoreContext(auth);
|
|
76
82
|
const config = await this.getProviderConfig(context);
|
|
77
83
|
if (!config) {
|
|
78
|
-
|
|
84
|
+
const err = new Error('No AI provider configured. Please configure Pod AI provider or set DEFAULT_API_BASE.');
|
|
85
|
+
err.code = 'model_not_configured';
|
|
86
|
+
throw err;
|
|
87
|
+
}
|
|
88
|
+
// Token quota check
|
|
89
|
+
const accountId = (0, AuthContext_1.getAccountId)(auth);
|
|
90
|
+
if (accountId) {
|
|
91
|
+
await this.checkTokenQuota(accountId);
|
|
79
92
|
}
|
|
80
93
|
try {
|
|
81
94
|
const provider = await this.getProvider(context);
|
|
@@ -95,6 +108,11 @@ class VercelChatService {
|
|
|
95
108
|
this.logger.debug(`Failed to record credential success: ${err}`);
|
|
96
109
|
});
|
|
97
110
|
}
|
|
111
|
+
// Record token usage
|
|
112
|
+
const totalTokens = result.usage?.totalTokens ?? 0;
|
|
113
|
+
if (accountId && totalTokens > 0) {
|
|
114
|
+
this.recordTokenUsage(accountId, String(context.userId), totalTokens);
|
|
115
|
+
}
|
|
98
116
|
return {
|
|
99
117
|
id: `chatcmpl-${Date.now()}`,
|
|
100
118
|
object: 'chat.completion',
|
|
@@ -131,7 +149,9 @@ class VercelChatService {
|
|
|
131
149
|
const context = this.createStoreContext(auth);
|
|
132
150
|
const config = await this.getProviderConfig(context);
|
|
133
151
|
if (!config) {
|
|
134
|
-
|
|
152
|
+
const err = new Error('No AI provider configured. Please configure Pod AI provider or set DEFAULT_API_BASE.');
|
|
153
|
+
err.code = 'model_not_configured';
|
|
154
|
+
throw err;
|
|
135
155
|
}
|
|
136
156
|
const provider = await this.getProvider(context);
|
|
137
157
|
const coreMessages = messages.map((m) => ({
|
|
@@ -151,7 +171,9 @@ class VercelChatService {
|
|
|
151
171
|
const accountId = (0, AuthContext_1.getAccountId)(auth);
|
|
152
172
|
const providerConfig = await this.getProviderConfig(context);
|
|
153
173
|
if (!providerConfig) {
|
|
154
|
-
|
|
174
|
+
const err = new Error('No AI provider configured. Please configure Pod AI provider or set DEFAULT_API_BASE.');
|
|
175
|
+
err.code = 'model_not_configured';
|
|
176
|
+
throw err;
|
|
155
177
|
}
|
|
156
178
|
const { baseURL } = providerConfig;
|
|
157
179
|
// Only OpenAI natively supports /v1/responses; all others go through Chat Completions
|
|
@@ -202,7 +224,9 @@ class VercelChatService {
|
|
|
202
224
|
const accountId = (0, AuthContext_1.getAccountId)(auth);
|
|
203
225
|
const providerConfig = await this.getProviderConfig(context);
|
|
204
226
|
if (!providerConfig) {
|
|
205
|
-
|
|
227
|
+
const err = new Error('No AI provider configured. Please configure Pod AI provider or set DEFAULT_API_BASE.');
|
|
228
|
+
err.code = 'model_not_configured';
|
|
229
|
+
throw err;
|
|
206
230
|
}
|
|
207
231
|
const { baseURL } = providerConfig;
|
|
208
232
|
// Only Anthropic natively supports /v1/messages; all others go through Chat Completions
|
|
@@ -336,57 +360,6 @@ class VercelChatService {
|
|
|
336
360
|
},
|
|
337
361
|
};
|
|
338
362
|
}
|
|
339
|
-
async responsesWithDefaultAgent(body, auth) {
|
|
340
|
-
const prompt = this.extractPromptFromResponsesBody(body);
|
|
341
|
-
const result = await (0, default_agent_1.runDefaultAgent)(prompt, this.buildDefaultAgentContext(auth));
|
|
342
|
-
if (!result.success) {
|
|
343
|
-
const err = new Error(result.error || 'Default Agent is not available');
|
|
344
|
-
err.code = 'model_not_configured';
|
|
345
|
-
throw err;
|
|
346
|
-
}
|
|
347
|
-
const outputText = result.content;
|
|
348
|
-
const now = Math.floor(Date.now() / 1000);
|
|
349
|
-
return {
|
|
350
|
-
id: `resp_${Date.now()}`,
|
|
351
|
-
object: 'response',
|
|
352
|
-
created: now,
|
|
353
|
-
status: 'completed',
|
|
354
|
-
model: body?.model || process.env.DEFAULT_MODEL || 'stepfun/step-3.5-flash:free',
|
|
355
|
-
output: [{
|
|
356
|
-
type: 'message',
|
|
357
|
-
role: 'assistant',
|
|
358
|
-
content: [{ type: 'output_text', text: outputText }],
|
|
359
|
-
}],
|
|
360
|
-
usage: {
|
|
361
|
-
input_tokens: prompt.length,
|
|
362
|
-
output_tokens: outputText.length,
|
|
363
|
-
total_tokens: prompt.length + outputText.length,
|
|
364
|
-
},
|
|
365
|
-
};
|
|
366
|
-
}
|
|
367
|
-
async messagesWithDefaultAgent(body, auth) {
|
|
368
|
-
const prompt = this.extractPromptFromMessagesBody(body);
|
|
369
|
-
const result = await (0, default_agent_1.runDefaultAgent)(prompt, this.buildDefaultAgentContext(auth));
|
|
370
|
-
if (!result.success) {
|
|
371
|
-
const err = new Error(result.error || 'Default Agent is not available');
|
|
372
|
-
err.code = 'model_not_configured';
|
|
373
|
-
throw err;
|
|
374
|
-
}
|
|
375
|
-
const text = result.content;
|
|
376
|
-
return {
|
|
377
|
-
id: `msg_${Date.now()}`,
|
|
378
|
-
type: 'message',
|
|
379
|
-
role: 'assistant',
|
|
380
|
-
model: body?.model || process.env.DEFAULT_MODEL || 'stepfun/step-3.5-flash:free',
|
|
381
|
-
content: [{ type: 'text', text }],
|
|
382
|
-
stop_reason: 'end_turn',
|
|
383
|
-
stop_sequence: null,
|
|
384
|
-
usage: {
|
|
385
|
-
input_tokens: prompt.length,
|
|
386
|
-
output_tokens: text.length,
|
|
387
|
-
},
|
|
388
|
-
};
|
|
389
|
-
}
|
|
390
363
|
extractPromptFromResponsesBody(body) {
|
|
391
364
|
if (!body || typeof body !== 'object') {
|
|
392
365
|
return '';
|
|
@@ -444,126 +417,34 @@ class VercelChatService {
|
|
|
444
417
|
return '';
|
|
445
418
|
}
|
|
446
419
|
async listModels(_auth) {
|
|
447
|
-
|
|
448
|
-
//
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
}
|
|
464
|
-
async completeWithDefaultAgent(messages, auth, requestedModel) {
|
|
465
|
-
const agentContext = this.buildDefaultAgentContext(auth);
|
|
466
|
-
const prompt = messages.filter((m) => m.role === 'user').pop()?.content || '';
|
|
467
|
-
const result = await (0, default_agent_1.runDefaultAgent)(prompt, agentContext);
|
|
468
|
-
if (!result.success) {
|
|
469
|
-
const err = new Error(result.error || 'Default Agent is not available');
|
|
470
|
-
err.code = 'model_not_configured';
|
|
471
|
-
throw err;
|
|
472
|
-
}
|
|
473
|
-
const completionTokens = result.content.length;
|
|
474
|
-
return {
|
|
475
|
-
id: `chatcmpl-${Date.now()}`,
|
|
476
|
-
object: 'chat.completion',
|
|
477
|
-
created: Math.floor(Date.now() / 1000),
|
|
478
|
-
model: requestedModel,
|
|
479
|
-
choices: [{
|
|
480
|
-
index: 0,
|
|
481
|
-
message: { role: 'assistant', content: result.content },
|
|
482
|
-
finish_reason: 'stop',
|
|
483
|
-
}],
|
|
484
|
-
usage: {
|
|
485
|
-
prompt_tokens: prompt.length,
|
|
486
|
-
completion_tokens: completionTokens,
|
|
487
|
-
total_tokens: prompt.length + completionTokens,
|
|
488
|
-
},
|
|
489
|
-
};
|
|
490
|
-
}
|
|
491
|
-
async streamWithDefaultAgent(messages, auth, _requestedModel) {
|
|
492
|
-
const agentContext = this.buildDefaultAgentContext(auth);
|
|
493
|
-
const prompt = messages.filter((m) => m.role === 'user').pop()?.content || '';
|
|
494
|
-
const encoder = new TextEncoder();
|
|
495
|
-
const stream = new ReadableStream({
|
|
496
|
-
start: async (controller) => {
|
|
497
|
-
try {
|
|
498
|
-
for await (const chunk of (0, default_agent_1.streamDefaultAgent)(prompt, agentContext)) {
|
|
499
|
-
controller.enqueue(encoder.encode(chunk));
|
|
420
|
+
const models = [];
|
|
421
|
+
// 平台 Provider 模型(从 DEFAULT_API_BASE 获取)
|
|
422
|
+
const platformBase = process.env.DEFAULT_API_BASE;
|
|
423
|
+
const platformKey = process.env.DEFAULT_API_KEY;
|
|
424
|
+
if (platformBase) {
|
|
425
|
+
try {
|
|
426
|
+
const url = platformBase.replace(/\/$/, '') + '/models';
|
|
427
|
+
const headers = { 'Content-Type': 'application/json' };
|
|
428
|
+
if (platformKey) {
|
|
429
|
+
headers['Authorization'] = `Bearer ${platformKey}`;
|
|
430
|
+
}
|
|
431
|
+
const resp = await fetch(url, { headers });
|
|
432
|
+
if (resp.ok) {
|
|
433
|
+
const data = await resp.json();
|
|
434
|
+
if (data.data) {
|
|
435
|
+
models.push(...data.data);
|
|
500
436
|
}
|
|
501
|
-
controller.close();
|
|
502
437
|
}
|
|
503
|
-
|
|
504
|
-
|
|
438
|
+
else {
|
|
439
|
+
this.logger.warn(`Failed to fetch platform models: ${resp.status}`);
|
|
505
440
|
}
|
|
506
|
-
},
|
|
507
|
-
});
|
|
508
|
-
return {
|
|
509
|
-
toTextStreamResponse: () => new Response(stream, {
|
|
510
|
-
status: 200,
|
|
511
|
-
headers: {
|
|
512
|
-
'Content-Type': 'text/plain; charset=utf-8',
|
|
513
|
-
'X-Vercel-AI-Data-Stream': 'v1',
|
|
514
|
-
},
|
|
515
|
-
}),
|
|
516
|
-
};
|
|
517
|
-
}
|
|
518
|
-
buildDefaultAgentContext(auth) {
|
|
519
|
-
if (!(0, default_agent_1.isDefaultAgentAvailable)()) {
|
|
520
|
-
const err = new Error('No AI provider configured. Please configure Pod AI provider or DEFAULT_API_KEY');
|
|
521
|
-
err.code = 'model_not_configured';
|
|
522
|
-
throw err;
|
|
523
|
-
}
|
|
524
|
-
const webId = (0, AuthContext_1.getWebId)(auth);
|
|
525
|
-
if (!webId) {
|
|
526
|
-
const err = new Error('No WebID in auth context');
|
|
527
|
-
err.code = 'model_not_configured';
|
|
528
|
-
throw err;
|
|
529
|
-
}
|
|
530
|
-
const solidToken = this.getSolidToken(auth);
|
|
531
|
-
if (!solidToken) {
|
|
532
|
-
const err = new Error('No Solid token available for Default Agent');
|
|
533
|
-
err.code = 'model_not_configured';
|
|
534
|
-
throw err;
|
|
535
|
-
}
|
|
536
|
-
return {
|
|
537
|
-
solidToken,
|
|
538
|
-
podBaseUrl: this.getPodBaseUrlFromWebId(webId),
|
|
539
|
-
webId,
|
|
540
|
-
};
|
|
541
|
-
}
|
|
542
|
-
getPodBaseUrlFromWebId(webId) {
|
|
543
|
-
const url = new URL(webId);
|
|
544
|
-
if (url.pathname.endsWith('/profile/card')) {
|
|
545
|
-
const podPath = url.pathname.replace('/profile/card', '');
|
|
546
|
-
return `${url.protocol}//${url.host}${podPath}/`;
|
|
547
|
-
}
|
|
548
|
-
return `${url.protocol}//${url.host}/`;
|
|
549
|
-
}
|
|
550
|
-
getSolidToken(auth) {
|
|
551
|
-
const candidate = auth;
|
|
552
|
-
if (typeof candidate.token === 'string') {
|
|
553
|
-
return candidate.token;
|
|
554
|
-
}
|
|
555
|
-
if (typeof candidate.accessToken === 'string') {
|
|
556
|
-
return candidate.accessToken;
|
|
557
|
-
}
|
|
558
|
-
if (candidate.credentials && typeof candidate.credentials === 'object') {
|
|
559
|
-
if (typeof candidate.credentials.accessToken === 'string') {
|
|
560
|
-
return candidate.credentials.accessToken;
|
|
561
441
|
}
|
|
562
|
-
|
|
563
|
-
|
|
442
|
+
catch (error) {
|
|
443
|
+
this.logger.warn(`Failed to fetch platform models: ${error}`);
|
|
564
444
|
}
|
|
565
445
|
}
|
|
566
|
-
|
|
446
|
+
// TODO: 合并用户 Pod Providers 的模型
|
|
447
|
+
return models;
|
|
567
448
|
}
|
|
568
449
|
mapFinishReason(reason) {
|
|
569
450
|
return reason;
|
|
@@ -623,6 +504,45 @@ class VercelChatService {
|
|
|
623
504
|
}
|
|
624
505
|
return { statusCode: 0 };
|
|
625
506
|
}
|
|
507
|
+
/**
|
|
508
|
+
* Check if account has remaining token quota
|
|
509
|
+
*/
|
|
510
|
+
async checkTokenQuota(accountId) {
|
|
511
|
+
if (!this.quotaService || !this.usageRepo) {
|
|
512
|
+
return; // No quota enforcement if not configured
|
|
513
|
+
}
|
|
514
|
+
try {
|
|
515
|
+
const quota = await this.quotaService.getAccountQuota(accountId);
|
|
516
|
+
if (!quota.tokenLimitMonthly) {
|
|
517
|
+
return; // No limit set
|
|
518
|
+
}
|
|
519
|
+
const usage = await this.usageRepo.getAccountUsage(accountId);
|
|
520
|
+
const tokensUsed = usage?.tokensUsed ?? 0;
|
|
521
|
+
if (tokensUsed >= quota.tokenLimitMonthly) {
|
|
522
|
+
const err = new Error('Token quota exceeded for this month');
|
|
523
|
+
err.code = 'quota_exceeded';
|
|
524
|
+
throw err;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
catch (error) {
|
|
528
|
+
if (error.code === 'quota_exceeded') {
|
|
529
|
+
throw error;
|
|
530
|
+
}
|
|
531
|
+
// Log but don't block on quota check errors
|
|
532
|
+
this.logger.warn(`Token quota check failed: ${error}`);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
/**
|
|
536
|
+
* Record token usage (fire-and-forget)
|
|
537
|
+
*/
|
|
538
|
+
recordTokenUsage(accountId, podId, tokens) {
|
|
539
|
+
if (!this.usageRepo) {
|
|
540
|
+
return;
|
|
541
|
+
}
|
|
542
|
+
this.usageRepo.incrementTokenUsage(accountId, podId, tokens).catch((err) => {
|
|
543
|
+
this.logger.warn(`Failed to record token usage: ${err}`);
|
|
544
|
+
});
|
|
545
|
+
}
|
|
626
546
|
}
|
|
627
547
|
exports.VercelChatService = VercelChatService;
|
|
628
548
|
//# sourceMappingURL=VercelChatService.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VercelChatService.js","sourceRoot":"","sources":["../../../src/api/service/VercelChatService.ts"],"names":[],"mappings":"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","sourcesContent":["import { createOpenAI } from '@ai-sdk/openai';\nimport { generateText, streamText } from 'ai';\nimport { getLoggerFor } from 'global-logger-factory';\nimport { ProxyAgent } from 'undici';\nimport type { ChatCompletionRequest, ChatCompletionResponse } from '../handlers/ChatHandler';\nimport type { PodChatKitStore } from '../chatkit/pod-store';\nimport type { StoreContext } from '../chatkit/store';\nimport { type AuthContext, getWebId, getAccountId, getDisplayName } from '../auth/AuthContext';\nimport { isDefaultAgentAvailable, runDefaultAgent, streamDefaultAgent, type DefaultAgentContext } from '../chatkit/default-agent';\nimport { CredentialStatus } from '../../credential/schema/types';\nimport {\n getDefaultBaseUrl,\n supportsResponsesApi,\n supportsMessagesApi,\n} from './provider-registry';\n\n// Create a proxy-aware fetch function\nfunction createProxyFetch(proxyUrl: string): typeof fetch {\n const agent = new ProxyAgent(proxyUrl);\n return (url, init) => fetch(url, { ...init, dispatcher: agent } as any);\n}\n\nexport class VercelChatService {\n private readonly logger = getLoggerFor(this);\n\n public constructor(private readonly store: PodChatKitStore) {\n this.logger.info('Initializing VercelChatService with Pod-based config support');\n }\n\n /**\n * Create a StoreContext from AuthContext for Pod operations\n */\n private createStoreContext(auth: AuthContext): StoreContext {\n return {\n userId: getWebId(auth) ?? getAccountId(auth) ?? 'anonymous',\n auth,\n };\n }\n\n\n\n\n private async getProviderConfig(context: StoreContext): Promise<{\n baseURL: string;\n apiKey: string;\n proxy?: string;\n credentialId?: string;\n } | null> {\n let config: Awaited<ReturnType<PodChatKitStore['getAiConfig']>> | undefined;\n try {\n config = await this.store.getAiConfig(context);\n this.logger.info(`Pod config: ${JSON.stringify(config)}`);\n } catch (error) {\n this.logger.warn(`Failed to get Pod config, falling back to defaults: ${error}`);\n config = undefined;\n }\n\n // Priority: Pod config > DEFAULT_API_KEY env > Default Agent fallback\n if (config?.apiKey) {\n const baseURL = config.baseUrl || getDefaultBaseUrl();\n const proxy = config.proxyUrl;\n this.logger.info(`Provider config: baseURL=${baseURL}, proxy=${proxy || 'none'} (source=pod)`);\n return { baseURL, apiKey: config.apiKey, proxy, credentialId: config.credentialId };\n }\n\n if (process.env.DEFAULT_API_KEY) {\n const provider = process.env.DEFAULT_PROVIDER || 'openrouter';\n const baseURL = process.env.DEFAULT_API_BASE || getDefaultBaseUrl(provider);\n this.logger.info(`Provider config: baseURL=${baseURL}, proxy=none (source=default-env)`);\n return { baseURL, apiKey: process.env.DEFAULT_API_KEY, proxy: undefined, credentialId: undefined };\n }\n\n this.logger.warn('No AI provider config found in Pod or DEFAULT_API_KEY');\n return null;\n }\n\n private async getProvider(context: StoreContext) {\n const providerConfig = await this.getProviderConfig(context);\n if (!providerConfig) {\n const err = new Error('No AI provider configured. Please configure Pod AI provider or DEFAULT_API_KEY');\n (err as any).code = 'model_not_configured';\n throw err;\n }\n\n const { baseURL, apiKey, proxy } = providerConfig;\n\n this.logger.debug(`Using AI Provider: ${baseURL} (key length: ${apiKey?.length || 0}, proxy: ${proxy || 'none'})`);\n\n const options: any = { baseURL, apiKey };\n if (proxy) {\n options.fetch = createProxyFetch(proxy);\n }\n\n return createOpenAI(options);\n }\n\n public async complete(request: ChatCompletionRequest, auth: AuthContext): Promise<ChatCompletionResponse> {\n const { model, messages, temperature, max_tokens } = request;\n const context = this.createStoreContext(auth);\n const config = await this.getProviderConfig(context);\n\n if (!config) {\n return this.completeWithDefaultAgent(messages, auth, model);\n }\n\n try {\n const provider = await this.getProvider(context);\n\n const coreMessages: any[] = messages.map((m) => ({\n role: m.role as any,\n content: m.content,\n }));\n\n const result = await generateText({\n model: provider.chat(model),\n messages: coreMessages,\n temperature,\n maxTokens: max_tokens,\n } as any);\n\n // Record successful API call\n if (config?.credentialId) {\n this.store.recordCredentialSuccess(context, config.credentialId).catch((err) => {\n this.logger.debug(`Failed to record credential success: ${err}`);\n });\n }\n\n return {\n id: `chatcmpl-${Date.now()}`,\n object: 'chat.completion',\n created: Math.floor(Date.now() / 1000),\n model,\n choices: [\n {\n index: 0,\n message: {\n role: 'assistant',\n content: result.text,\n },\n finish_reason: this.mapFinishReason(result.finishReason),\n },\n ],\n usage: {\n prompt_tokens: (result.usage as any).promptTokens,\n completion_tokens: (result.usage as any).completionTokens,\n total_tokens: (result.usage as any).totalTokens,\n },\n };\n } catch (error) {\n this.logger.error(`AI completion failed: ${error}`);\n\n // Handle error and update credential status\n if (config?.credentialId) {\n await this.handleApiError(error, context, config.credentialId);\n }\n\n throw error;\n }\n }\n\n public async stream(request: ChatCompletionRequest, auth: AuthContext): Promise<any> {\n const { model, messages, temperature, max_tokens } = request;\n const context = this.createStoreContext(auth);\n const config = await this.getProviderConfig(context);\n\n if (!config) {\n return this.streamWithDefaultAgent(messages, auth, model);\n }\n\n const provider = await this.getProvider(context);\n\n const coreMessages: any[] = messages.map((m) => ({\n role: m.role as any,\n content: m.content,\n }));\n\n return streamText({\n model: provider.chat(model),\n messages: coreMessages,\n temperature,\n maxTokens: max_tokens,\n } as any);\n }\n\n public async responses(body: any, auth: AuthContext): Promise<any> {\n const context = this.createStoreContext(auth);\n const displayName = getDisplayName(auth) || context.userId;\n const accountId = getAccountId(auth);\n\n const providerConfig = await this.getProviderConfig(context);\n if (!providerConfig) {\n return this.responsesWithDefaultAgent(body, auth);\n }\n\n const { baseURL } = providerConfig;\n\n // Only OpenAI natively supports /v1/responses; all others go through Chat Completions\n if (!supportsResponsesApi(baseURL)) {\n this.logger.info(`Provider ${baseURL} does not support Responses API, converting to Chat Completions for ${displayName} (acc: ${accountId})`);\n return this.responsesViaCompletions(body, context, providerConfig);\n }\n\n const { apiKey, proxy, credentialId } = providerConfig;\n\n // Remove trailing slash if present\n const cleanBaseUrl = baseURL.endsWith('/') ? baseURL.slice(0, -1) : baseURL;\n const url = `${cleanBaseUrl}/responses`;\n\n this.logger.info(`Proxying responses request to ${url} for ${displayName} (acc: ${accountId}), proxy: ${proxy || 'none'}`);\n\n const fetchFn = proxy ? createProxyFetch(proxy) : fetch;\n\n try {\n const response = await fetchFn(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${apiKey}`,\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n this.logger.error(`Responses API failed: ${response.status} ${errorText}`);\n\n // Handle error and update credential status\n if (credentialId) {\n await this.handleApiError(\n { status: response.status, headers: response.headers },\n context,\n credentialId,\n );\n }\n\n throw new Error(`Provider error: ${response.statusText}`);\n }\n\n // Record successful API call\n if (credentialId) {\n this.store.recordCredentialSuccess(context, credentialId).catch(() => {});\n }\n\n return response.json();\n } catch (error) {\n if (credentialId && !(error instanceof Error && error.message.startsWith('Provider error'))) {\n await this.handleApiError(error, context, credentialId);\n }\n throw error;\n }\n }\n\n public async messages(body: any, auth: AuthContext): Promise<any> {\n const context = this.createStoreContext(auth);\n const displayName = getDisplayName(auth) || context.userId;\n const accountId = getAccountId(auth);\n\n const providerConfig = await this.getProviderConfig(context);\n if (!providerConfig) {\n return this.messagesWithDefaultAgent(body, auth);\n }\n\n const { baseURL } = providerConfig;\n\n // Only Anthropic natively supports /v1/messages; all others go through Chat Completions\n if (!supportsMessagesApi(baseURL)) {\n this.logger.info(`Provider ${baseURL} does not support Messages API, converting to Chat Completions for ${displayName} (acc: ${accountId})`);\n return this.messagesViaCompletions(body, context, providerConfig);\n }\n\n const { apiKey, proxy, credentialId } = providerConfig;\n\n // Remove trailing slash if present\n const cleanBaseUrl = baseURL.endsWith('/') ? baseURL.slice(0, -1) : baseURL;\n const url = `${cleanBaseUrl}/messages`;\n\n this.logger.info(`Proxying messages request to ${url} for ${displayName} (acc: ${accountId}), proxy: ${proxy || 'none'}`);\n\n const fetchFn = proxy ? createProxyFetch(proxy) : fetch;\n\n try {\n const response = await fetchFn(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${apiKey}`,\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n this.logger.error(`Messages API failed: ${response.status} ${errorText}`);\n\n // Handle error and update credential status\n if (credentialId) {\n await this.handleApiError(\n { status: response.status, headers: response.headers },\n context,\n credentialId,\n );\n }\n\n throw new Error(`Provider error: ${response.statusText}`);\n }\n\n // Record successful API call\n if (credentialId) {\n this.store.recordCredentialSuccess(context, credentialId).catch(() => {});\n }\n\n return response.json();\n } catch (error) {\n if (credentialId && !(error instanceof Error && error.message.startsWith('Provider error'))) {\n await this.handleApiError(error, context, credentialId);\n }\n throw error;\n }\n }\n\n\n\n\n private async responsesViaCompletions(\n body: any,\n context: StoreContext,\n providerConfig: { baseURL: string; apiKey: string; proxy?: string; credentialId?: string },\n ): Promise<any> {\n const prompt = this.extractPromptFromResponsesBody(body);\n const model = body?.model || process.env.DEFAULT_MODEL || 'openai/gpt-4o-mini';\n\n const provider = await this.getProvider(context);\n const result = await generateText({\n model: provider.chat(model),\n messages: [{ role: 'user' as const, content: prompt }],\n ...(body?.temperature != null ? { temperature: body.temperature } : {}),\n ...(body?.max_output_tokens != null ? { maxTokens: body.max_output_tokens } : {}),\n } as any);\n\n if (providerConfig.credentialId) {\n this.store.recordCredentialSuccess(context, providerConfig.credentialId).catch(() => {});\n }\n\n const outputText = result.text;\n const now = Math.floor(Date.now() / 1000);\n return {\n id: `resp_${Date.now()}`,\n object: 'response',\n created: now,\n status: 'completed',\n model,\n output: [{\n type: 'message',\n role: 'assistant',\n content: [{ type: 'output_text', text: outputText }],\n }],\n usage: {\n input_tokens: (result.usage as any)?.promptTokens ?? prompt.length,\n output_tokens: (result.usage as any)?.completionTokens ?? outputText.length,\n total_tokens: (result.usage as any)?.totalTokens ?? (prompt.length + outputText.length),\n },\n };\n }\n\n private async messagesViaCompletions(\n body: any,\n context: StoreContext,\n providerConfig: { baseURL: string; apiKey: string; proxy?: string; credentialId?: string },\n ): Promise<any> {\n const prompt = this.extractPromptFromMessagesBody(body);\n const model = body?.model || process.env.DEFAULT_MODEL || 'openai/gpt-4o-mini';\n\n const coreMessages: any[] = [];\n if (body?.system) {\n const systemText = typeof body.system === 'string'\n ? body.system\n : Array.isArray(body.system)\n ? body.system.map((b: any) => b?.text ?? '').join('\\n')\n : '';\n if (systemText) {\n coreMessages.push({ role: 'system', content: systemText });\n }\n }\n if (Array.isArray(body?.messages)) {\n for (const msg of body.messages) {\n if (msg?.role && msg?.content != null) {\n const content = typeof msg.content === 'string'\n ? msg.content\n : Array.isArray(msg.content)\n ? msg.content.filter((p: any) => p?.type === 'text').map((p: any) => p.text).join('\\n')\n : String(msg.content);\n coreMessages.push({ role: msg.role, content });\n }\n }\n }\n if (coreMessages.length === 0) {\n coreMessages.push({ role: 'user', content: prompt });\n }\n\n const provider = await this.getProvider(context);\n const result = await generateText({\n model: provider.chat(model),\n messages: coreMessages,\n ...(body?.temperature != null ? { temperature: body.temperature } : {}),\n ...(body?.max_tokens != null ? { maxTokens: body.max_tokens } : {}),\n } as any);\n\n if (providerConfig.credentialId) {\n this.store.recordCredentialSuccess(context, providerConfig.credentialId).catch(() => {});\n }\n\n const text = result.text;\n return {\n id: `msg_${Date.now()}`,\n type: 'message',\n role: 'assistant',\n model,\n content: [{ type: 'text', text }],\n stop_reason: 'end_turn',\n stop_sequence: null,\n usage: {\n input_tokens: (result.usage as any)?.promptTokens ?? prompt.length,\n output_tokens: (result.usage as any)?.completionTokens ?? text.length,\n },\n };\n }\n\n private async responsesWithDefaultAgent(body: any, auth: AuthContext): Promise<any> {\n const prompt = this.extractPromptFromResponsesBody(body);\n const result = await runDefaultAgent(prompt, this.buildDefaultAgentContext(auth));\n\n if (!result.success) {\n const err = new Error(result.error || 'Default Agent is not available');\n (err as any).code = 'model_not_configured';\n throw err;\n }\n\n const outputText = result.content;\n const now = Math.floor(Date.now() / 1000);\n\n return {\n id: `resp_${Date.now()}`,\n object: 'response',\n created: now,\n status: 'completed',\n model: body?.model || process.env.DEFAULT_MODEL || 'stepfun/step-3.5-flash:free',\n output: [{\n type: 'message',\n role: 'assistant',\n content: [{ type: 'output_text', text: outputText }],\n }],\n usage: {\n input_tokens: prompt.length,\n output_tokens: outputText.length,\n total_tokens: prompt.length + outputText.length,\n },\n };\n }\n\n private async messagesWithDefaultAgent(body: any, auth: AuthContext): Promise<any> {\n const prompt = this.extractPromptFromMessagesBody(body);\n const result = await runDefaultAgent(prompt, this.buildDefaultAgentContext(auth));\n\n if (!result.success) {\n const err = new Error(result.error || 'Default Agent is not available');\n (err as any).code = 'model_not_configured';\n throw err;\n }\n\n const text = result.content;\n return {\n id: `msg_${Date.now()}`,\n type: 'message',\n role: 'assistant',\n model: body?.model || process.env.DEFAULT_MODEL || 'stepfun/step-3.5-flash:free',\n content: [{ type: 'text', text }],\n stop_reason: 'end_turn',\n stop_sequence: null,\n usage: {\n input_tokens: prompt.length,\n output_tokens: text.length,\n },\n };\n }\n\n private extractPromptFromResponsesBody(body: any): string {\n if (!body || typeof body !== 'object') {\n return '';\n }\n\n if (typeof body.input === 'string') {\n return body.input;\n }\n\n if (typeof body.prompt === 'string') {\n return body.prompt;\n }\n\n if (Array.isArray(body.input)) {\n const textParts: string[] = [];\n for (const item of body.input) {\n if (item && typeof item === 'object') {\n const candidate = (item as any).content;\n if (typeof candidate === 'string') {\n textParts.push(candidate);\n } else if (Array.isArray(candidate)) {\n for (const part of candidate) {\n if (part && typeof part === 'object' && typeof (part as any).text === 'string') {\n textParts.push((part as any).text);\n }\n }\n }\n }\n }\n if (textParts.length > 0) {\n return textParts.join('\\n');\n }\n }\n\n return '';\n }\n\n private extractPromptFromMessagesBody(body: any): string {\n if (!body || typeof body !== 'object') {\n return '';\n }\n\n if (typeof body.content === 'string') {\n return body.content;\n }\n\n if (Array.isArray(body.messages)) {\n const lastUser = [...body.messages].reverse().find((item: any) => item?.role === 'user');\n if (lastUser) {\n if (typeof lastUser.content === 'string') {\n return lastUser.content;\n }\n if (Array.isArray(lastUser.content)) {\n return lastUser.content\n .filter((part: any) => part && typeof part === 'object' && typeof part.text === 'string')\n .map((part: any) => part.text)\n .join('\\n');\n }\n }\n }\n\n return '';\n }\n\n public async listModels(_auth?: AuthContext): Promise<any[]> {\n // TODO: Get models from Pod when store.listModels is implemented\n // Fallback to default models\n return [\n {\n id: 'llama3',\n object: 'model',\n created: Math.floor(Date.now() / 1000),\n owned_by: 'ollama',\n },\n {\n id: 'gpt-4o',\n object: 'model',\n created: Math.floor(Date.now() / 1000),\n owned_by: 'openai',\n },\n ];\n }\n\n private async completeWithDefaultAgent(\n messages: ChatCompletionRequest['messages'],\n auth: AuthContext,\n requestedModel: string,\n ): Promise<ChatCompletionResponse> {\n const agentContext = this.buildDefaultAgentContext(auth);\n const prompt = messages.filter((m) => m.role === 'user').pop()?.content || '';\n\n const result = await runDefaultAgent(prompt, agentContext);\n if (!result.success) {\n const err = new Error(result.error || 'Default Agent is not available');\n (err as any).code = 'model_not_configured';\n throw err;\n }\n\n const completionTokens = result.content.length;\n return {\n id: `chatcmpl-${Date.now()}`,\n object: 'chat.completion',\n created: Math.floor(Date.now() / 1000),\n model: requestedModel,\n choices: [{\n index: 0,\n message: { role: 'assistant', content: result.content },\n finish_reason: 'stop',\n }],\n usage: {\n prompt_tokens: prompt.length,\n completion_tokens: completionTokens,\n total_tokens: prompt.length + completionTokens,\n },\n };\n }\n\n private async streamWithDefaultAgent(\n messages: ChatCompletionRequest['messages'],\n auth: AuthContext,\n _requestedModel: string,\n ): Promise<{ toTextStreamResponse: () => Response }> {\n const agentContext = this.buildDefaultAgentContext(auth);\n const prompt = messages.filter((m) => m.role === 'user').pop()?.content || '';\n\n const encoder = new TextEncoder();\n const stream = new ReadableStream<Uint8Array>({\n start: async (controller) => {\n try {\n for await (const chunk of streamDefaultAgent(prompt, agentContext)) {\n controller.enqueue(encoder.encode(chunk));\n }\n controller.close();\n } catch (error) {\n controller.error(error);\n }\n },\n });\n\n return {\n toTextStreamResponse: () => new Response(stream, {\n status: 200,\n headers: {\n 'Content-Type': 'text/plain; charset=utf-8',\n 'X-Vercel-AI-Data-Stream': 'v1',\n },\n }),\n };\n }\n\n private buildDefaultAgentContext(auth: AuthContext): DefaultAgentContext {\n if (!isDefaultAgentAvailable()) {\n const err = new Error('No AI provider configured. Please configure Pod AI provider or DEFAULT_API_KEY');\n (err as any).code = 'model_not_configured';\n throw err;\n }\n\n const webId = getWebId(auth);\n if (!webId) {\n const err = new Error('No WebID in auth context');\n (err as any).code = 'model_not_configured';\n throw err;\n }\n\n const solidToken = this.getSolidToken(auth);\n if (!solidToken) {\n const err = new Error('No Solid token available for Default Agent');\n (err as any).code = 'model_not_configured';\n throw err;\n }\n\n return {\n solidToken,\n podBaseUrl: this.getPodBaseUrlFromWebId(webId),\n webId,\n };\n }\n\n private getPodBaseUrlFromWebId(webId: string): string {\n const url = new URL(webId);\n if (url.pathname.endsWith('/profile/card')) {\n const podPath = url.pathname.replace('/profile/card', '');\n return `${url.protocol}//${url.host}${podPath}/`;\n }\n return `${url.protocol}//${url.host}/`;\n }\n\n private getSolidToken(auth: AuthContext): string | undefined {\n const candidate = auth as any;\n if (typeof candidate.token === 'string') {\n return candidate.token;\n }\n if (typeof candidate.accessToken === 'string') {\n return candidate.accessToken;\n }\n if (candidate.credentials && typeof candidate.credentials === 'object') {\n if (typeof candidate.credentials.accessToken === 'string') {\n return candidate.credentials.accessToken;\n }\n if (typeof candidate.credentials.token === 'string') {\n return candidate.credentials.token;\n }\n }\n return undefined;\n }\n\n private mapFinishReason(reason: string): 'stop' | 'length' | 'content_filter' {\n return reason as any;\n }\n\n /**\n * Handle API errors and update credential status accordingly\n */\n private async handleApiError(\n error: unknown,\n context: StoreContext,\n credentialId: string,\n ): Promise<void> {\n const errorInfo = this.parseApiError(error);\n\n if (errorInfo.statusCode === 429) {\n // Rate limit error - mark credential as rate limited\n const resetAt = errorInfo.retryAfter\n ? new Date(Date.now() + errorInfo.retryAfter * 1000)\n : new Date(Date.now() + 60000); // Default 1 minute cooldown\n\n this.logger.warn(`Rate limit hit for credential ${credentialId}, reset at: ${resetAt.toISOString()}`);\n\n await this.store.updateCredentialStatus(\n context,\n credentialId,\n CredentialStatus.RATE_LIMITED,\n { rateLimitResetAt: resetAt },\n );\n } else if (errorInfo.statusCode === 401 || errorInfo.statusCode === 403) {\n // Auth error - mark credential as inactive\n this.logger.warn(`Auth error for credential ${credentialId}, marking as inactive`);\n\n await this.store.updateCredentialStatus(\n context,\n credentialId,\n CredentialStatus.INACTIVE,\n { incrementFailCount: true },\n );\n } else if (errorInfo.statusCode >= 500) {\n // Server error - increment fail count but keep active\n this.logger.warn(`Server error ${errorInfo.statusCode} for credential ${credentialId}`);\n\n await this.store.updateCredentialStatus(\n context,\n credentialId,\n CredentialStatus.ACTIVE,\n { incrementFailCount: true },\n );\n }\n }\n\n /**\n * Parse error to extract status code and retry-after header\n */\n private parseApiError(error: unknown): { statusCode: number; retryAfter?: number } {\n // Handle different error formats from AI SDK\n if (error && typeof error === 'object') {\n const err = error as any;\n\n // Direct status code\n if (typeof err.status === 'number') {\n return {\n statusCode: err.status,\n retryAfter: err.retryAfter || err.headers?.['retry-after'],\n };\n }\n\n // Nested response object\n if (err.response && typeof err.response.status === 'number') {\n return {\n statusCode: err.response.status,\n retryAfter: err.response.headers?.get?.('retry-after'),\n };\n }\n\n // Error message parsing (fallback)\n if (err.message) {\n const match = err.message.match(/(\\d{3})/);\n if (match) {\n return { statusCode: parseInt(match[1], 10) };\n }\n }\n }\n\n return { statusCode: 0 };\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"VercelChatService.js","sourceRoot":"","sources":["../../../src/api/service/VercelChatService.ts"],"names":[],"mappings":"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","sourcesContent":["import { createOpenAI } from '@ai-sdk/openai';\nimport { generateText, streamText } from 'ai';\nimport { getLoggerFor } from 'global-logger-factory';\nimport { ProxyAgent } from 'undici';\nimport type { ChatCompletionRequest, ChatCompletionResponse } from '../handlers/ChatHandler';\nimport type { PodChatKitStore } from '../chatkit/pod-store';\nimport type { StoreContext } from '../chatkit/store';\nimport { type AuthContext, getWebId, getAccountId, getDisplayName } from '../auth/AuthContext';\nimport { CredentialStatus } from '../../credential/schema/types';\nimport type { UsageRepository } from '../../storage/quota/UsageRepository';\nimport type { QuotaService } from '../../quota/QuotaService';\nimport {\n getDefaultBaseUrl,\n supportsResponsesApi,\n supportsMessagesApi,\n} from './provider-registry';\n\n// Create a proxy-aware fetch function\nfunction createProxyFetch(proxyUrl: string): typeof fetch {\n const agent = new ProxyAgent(proxyUrl);\n return (url, init) => fetch(url, { ...init, dispatcher: agent } as any);\n}\n\nexport class VercelChatService {\n private readonly logger = getLoggerFor(this);\n private usageRepo?: UsageRepository;\n private quotaService?: QuotaService;\n\n public constructor(private readonly store: PodChatKitStore) {\n this.logger.info('Initializing VercelChatService with Pod-based config support');\n }\n\n /**\n * Set optional usage tracking dependencies (injected after construction)\n */\n public setUsageTracking(usageRepo: UsageRepository, quotaService: QuotaService): void {\n this.usageRepo = usageRepo;\n this.quotaService = quotaService;\n }\n\n /**\n * Create a StoreContext from AuthContext for Pod operations\n */\n private createStoreContext(auth: AuthContext): StoreContext {\n return {\n userId: getWebId(auth) ?? getAccountId(auth) ?? 'anonymous',\n auth,\n };\n }\n\n\n\n\n private async getProviderConfig(context: StoreContext): Promise<{\n baseURL: string;\n apiKey: string;\n proxy?: string;\n credentialId?: string;\n } | null> {\n let config: Awaited<ReturnType<PodChatKitStore['getAiConfig']>> | undefined;\n try {\n config = await this.store.getAiConfig(context);\n this.logger.info(`Pod config: ${JSON.stringify(config)}`);\n } catch (error) {\n this.logger.warn(`Failed to get Pod config, falling back to defaults: ${error}`);\n config = undefined;\n }\n\n // Priority: Pod config > Platform Provider\n if (config?.apiKey) {\n const baseURL = config.baseUrl || getDefaultBaseUrl();\n const proxy = config.proxyUrl;\n this.logger.info(`Provider config: baseURL=${baseURL}, proxy=${proxy || 'none'} (source=pod)`);\n return { baseURL, apiKey: config.apiKey, proxy, credentialId: config.credentialId };\n }\n\n // 平台 Provider\n const platformBase = process.env.DEFAULT_API_BASE;\n if (platformBase) {\n this.logger.info(`Provider config: baseURL=${platformBase}, proxy=none (source=platform)`);\n return { baseURL: platformBase, apiKey: process.env.DEFAULT_API_KEY || '', proxy: undefined, credentialId: undefined };\n }\n\n this.logger.warn('No AI provider config found in Pod or DEFAULT_API_BASE');\n return null;\n }\n\n private async getProvider(context: StoreContext) {\n const providerConfig = await this.getProviderConfig(context);\n if (!providerConfig) {\n const err = new Error('No AI provider configured. Please configure Pod AI provider or set DEFAULT_API_BASE.');\n (err as any).code = 'model_not_configured';\n throw err;\n }\n\n const { baseURL, apiKey, proxy } = providerConfig;\n\n this.logger.debug(`Using AI Provider: ${baseURL} (key length: ${apiKey?.length || 0}, proxy: ${proxy || 'none'})`);\n\n const options: any = { baseURL, apiKey };\n if (proxy) {\n options.fetch = createProxyFetch(proxy);\n }\n\n return createOpenAI(options);\n }\n\n public async complete(request: ChatCompletionRequest, auth: AuthContext): Promise<ChatCompletionResponse> {\n const { model, messages, temperature, max_tokens } = request;\n const context = this.createStoreContext(auth);\n const config = await this.getProviderConfig(context);\n\n if (!config) {\n const err = new Error('No AI provider configured. Please configure Pod AI provider or set DEFAULT_API_BASE.');\n (err as any).code = 'model_not_configured';\n throw err;\n }\n\n // Token quota check\n const accountId = getAccountId(auth);\n if (accountId) {\n await this.checkTokenQuota(accountId);\n }\n\n try {\n const provider = await this.getProvider(context);\n\n const coreMessages: any[] = messages.map((m) => ({\n role: m.role as any,\n content: m.content,\n }));\n\n const result = await generateText({\n model: provider.chat(model),\n messages: coreMessages,\n temperature,\n maxTokens: max_tokens,\n } as any);\n\n // Record successful API call\n if (config?.credentialId) {\n this.store.recordCredentialSuccess(context, config.credentialId).catch((err) => {\n this.logger.debug(`Failed to record credential success: ${err}`);\n });\n }\n\n // Record token usage\n const totalTokens = (result.usage as any)?.totalTokens ?? 0;\n if (accountId && totalTokens > 0) {\n this.recordTokenUsage(accountId, String(context.userId), totalTokens);\n }\n\n return {\n id: `chatcmpl-${Date.now()}`,\n object: 'chat.completion',\n created: Math.floor(Date.now() / 1000),\n model,\n choices: [\n {\n index: 0,\n message: {\n role: 'assistant',\n content: result.text,\n },\n finish_reason: this.mapFinishReason(result.finishReason),\n },\n ],\n usage: {\n prompt_tokens: (result.usage as any).promptTokens,\n completion_tokens: (result.usage as any).completionTokens,\n total_tokens: (result.usage as any).totalTokens,\n },\n };\n } catch (error) {\n this.logger.error(`AI completion failed: ${error}`);\n\n // Handle error and update credential status\n if (config?.credentialId) {\n await this.handleApiError(error, context, config.credentialId);\n }\n\n throw error;\n }\n }\n\n public async stream(request: ChatCompletionRequest, auth: AuthContext): Promise<any> {\n const { model, messages, temperature, max_tokens } = request;\n const context = this.createStoreContext(auth);\n const config = await this.getProviderConfig(context);\n\n if (!config) {\n const err = new Error('No AI provider configured. Please configure Pod AI provider or set DEFAULT_API_BASE.');\n (err as any).code = 'model_not_configured';\n throw err;\n }\n\n const provider = await this.getProvider(context);\n\n const coreMessages: any[] = messages.map((m) => ({\n role: m.role as any,\n content: m.content,\n }));\n\n return streamText({\n model: provider.chat(model),\n messages: coreMessages,\n temperature,\n maxTokens: max_tokens,\n } as any);\n }\n\n public async responses(body: any, auth: AuthContext): Promise<any> {\n const context = this.createStoreContext(auth);\n const displayName = getDisplayName(auth) || context.userId;\n const accountId = getAccountId(auth);\n\n const providerConfig = await this.getProviderConfig(context);\n if (!providerConfig) {\n const err = new Error('No AI provider configured. Please configure Pod AI provider or set DEFAULT_API_BASE.');\n (err as any).code = 'model_not_configured';\n throw err;\n }\n\n const { baseURL } = providerConfig;\n\n // Only OpenAI natively supports /v1/responses; all others go through Chat Completions\n if (!supportsResponsesApi(baseURL)) {\n this.logger.info(`Provider ${baseURL} does not support Responses API, converting to Chat Completions for ${displayName} (acc: ${accountId})`);\n return this.responsesViaCompletions(body, context, providerConfig);\n }\n\n const { apiKey, proxy, credentialId } = providerConfig;\n\n // Remove trailing slash if present\n const cleanBaseUrl = baseURL.endsWith('/') ? baseURL.slice(0, -1) : baseURL;\n const url = `${cleanBaseUrl}/responses`;\n\n this.logger.info(`Proxying responses request to ${url} for ${displayName} (acc: ${accountId}), proxy: ${proxy || 'none'}`);\n\n const fetchFn = proxy ? createProxyFetch(proxy) : fetch;\n\n try {\n const response = await fetchFn(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${apiKey}`,\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n this.logger.error(`Responses API failed: ${response.status} ${errorText}`);\n\n // Handle error and update credential status\n if (credentialId) {\n await this.handleApiError(\n { status: response.status, headers: response.headers },\n context,\n credentialId,\n );\n }\n\n throw new Error(`Provider error: ${response.statusText}`);\n }\n\n // Record successful API call\n if (credentialId) {\n this.store.recordCredentialSuccess(context, credentialId).catch(() => {});\n }\n\n return response.json();\n } catch (error) {\n if (credentialId && !(error instanceof Error && error.message.startsWith('Provider error'))) {\n await this.handleApiError(error, context, credentialId);\n }\n throw error;\n }\n }\n\n public async messages(body: any, auth: AuthContext): Promise<any> {\n const context = this.createStoreContext(auth);\n const displayName = getDisplayName(auth) || context.userId;\n const accountId = getAccountId(auth);\n\n const providerConfig = await this.getProviderConfig(context);\n if (!providerConfig) {\n const err = new Error('No AI provider configured. Please configure Pod AI provider or set DEFAULT_API_BASE.');\n (err as any).code = 'model_not_configured';\n throw err;\n }\n\n const { baseURL } = providerConfig;\n\n // Only Anthropic natively supports /v1/messages; all others go through Chat Completions\n if (!supportsMessagesApi(baseURL)) {\n this.logger.info(`Provider ${baseURL} does not support Messages API, converting to Chat Completions for ${displayName} (acc: ${accountId})`);\n return this.messagesViaCompletions(body, context, providerConfig);\n }\n\n const { apiKey, proxy, credentialId } = providerConfig;\n\n // Remove trailing slash if present\n const cleanBaseUrl = baseURL.endsWith('/') ? baseURL.slice(0, -1) : baseURL;\n const url = `${cleanBaseUrl}/messages`;\n\n this.logger.info(`Proxying messages request to ${url} for ${displayName} (acc: ${accountId}), proxy: ${proxy || 'none'}`);\n\n const fetchFn = proxy ? createProxyFetch(proxy) : fetch;\n\n try {\n const response = await fetchFn(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${apiKey}`,\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n this.logger.error(`Messages API failed: ${response.status} ${errorText}`);\n\n // Handle error and update credential status\n if (credentialId) {\n await this.handleApiError(\n { status: response.status, headers: response.headers },\n context,\n credentialId,\n );\n }\n\n throw new Error(`Provider error: ${response.statusText}`);\n }\n\n // Record successful API call\n if (credentialId) {\n this.store.recordCredentialSuccess(context, credentialId).catch(() => {});\n }\n\n return response.json();\n } catch (error) {\n if (credentialId && !(error instanceof Error && error.message.startsWith('Provider error'))) {\n await this.handleApiError(error, context, credentialId);\n }\n throw error;\n }\n }\n\n\n\n\n private async responsesViaCompletions(\n body: any,\n context: StoreContext,\n providerConfig: { baseURL: string; apiKey: string; proxy?: string; credentialId?: string },\n ): Promise<any> {\n const prompt = this.extractPromptFromResponsesBody(body);\n const model = body?.model || process.env.DEFAULT_MODEL || 'openai/gpt-4o-mini';\n\n const provider = await this.getProvider(context);\n const result = await generateText({\n model: provider.chat(model),\n messages: [{ role: 'user' as const, content: prompt }],\n ...(body?.temperature != null ? { temperature: body.temperature } : {}),\n ...(body?.max_output_tokens != null ? { maxTokens: body.max_output_tokens } : {}),\n } as any);\n\n if (providerConfig.credentialId) {\n this.store.recordCredentialSuccess(context, providerConfig.credentialId).catch(() => {});\n }\n\n const outputText = result.text;\n const now = Math.floor(Date.now() / 1000);\n return {\n id: `resp_${Date.now()}`,\n object: 'response',\n created: now,\n status: 'completed',\n model,\n output: [{\n type: 'message',\n role: 'assistant',\n content: [{ type: 'output_text', text: outputText }],\n }],\n usage: {\n input_tokens: (result.usage as any)?.promptTokens ?? prompt.length,\n output_tokens: (result.usage as any)?.completionTokens ?? outputText.length,\n total_tokens: (result.usage as any)?.totalTokens ?? (prompt.length + outputText.length),\n },\n };\n }\n\n private async messagesViaCompletions(\n body: any,\n context: StoreContext,\n providerConfig: { baseURL: string; apiKey: string; proxy?: string; credentialId?: string },\n ): Promise<any> {\n const prompt = this.extractPromptFromMessagesBody(body);\n const model = body?.model || process.env.DEFAULT_MODEL || 'openai/gpt-4o-mini';\n\n const coreMessages: any[] = [];\n if (body?.system) {\n const systemText = typeof body.system === 'string'\n ? body.system\n : Array.isArray(body.system)\n ? body.system.map((b: any) => b?.text ?? '').join('\\n')\n : '';\n if (systemText) {\n coreMessages.push({ role: 'system', content: systemText });\n }\n }\n if (Array.isArray(body?.messages)) {\n for (const msg of body.messages) {\n if (msg?.role && msg?.content != null) {\n const content = typeof msg.content === 'string'\n ? msg.content\n : Array.isArray(msg.content)\n ? msg.content.filter((p: any) => p?.type === 'text').map((p: any) => p.text).join('\\n')\n : String(msg.content);\n coreMessages.push({ role: msg.role, content });\n }\n }\n }\n if (coreMessages.length === 0) {\n coreMessages.push({ role: 'user', content: prompt });\n }\n\n const provider = await this.getProvider(context);\n const result = await generateText({\n model: provider.chat(model),\n messages: coreMessages,\n ...(body?.temperature != null ? { temperature: body.temperature } : {}),\n ...(body?.max_tokens != null ? { maxTokens: body.max_tokens } : {}),\n } as any);\n\n if (providerConfig.credentialId) {\n this.store.recordCredentialSuccess(context, providerConfig.credentialId).catch(() => {});\n }\n\n const text = result.text;\n return {\n id: `msg_${Date.now()}`,\n type: 'message',\n role: 'assistant',\n model,\n content: [{ type: 'text', text }],\n stop_reason: 'end_turn',\n stop_sequence: null,\n usage: {\n input_tokens: (result.usage as any)?.promptTokens ?? prompt.length,\n output_tokens: (result.usage as any)?.completionTokens ?? text.length,\n },\n };\n }\n\n private extractPromptFromResponsesBody(body: any): string {\n if (!body || typeof body !== 'object') {\n return '';\n }\n\n if (typeof body.input === 'string') {\n return body.input;\n }\n\n if (typeof body.prompt === 'string') {\n return body.prompt;\n }\n\n if (Array.isArray(body.input)) {\n const textParts: string[] = [];\n for (const item of body.input) {\n if (item && typeof item === 'object') {\n const candidate = (item as any).content;\n if (typeof candidate === 'string') {\n textParts.push(candidate);\n } else if (Array.isArray(candidate)) {\n for (const part of candidate) {\n if (part && typeof part === 'object' && typeof (part as any).text === 'string') {\n textParts.push((part as any).text);\n }\n }\n }\n }\n }\n if (textParts.length > 0) {\n return textParts.join('\\n');\n }\n }\n\n return '';\n }\n\n private extractPromptFromMessagesBody(body: any): string {\n if (!body || typeof body !== 'object') {\n return '';\n }\n\n if (typeof body.content === 'string') {\n return body.content;\n }\n\n if (Array.isArray(body.messages)) {\n const lastUser = [...body.messages].reverse().find((item: any) => item?.role === 'user');\n if (lastUser) {\n if (typeof lastUser.content === 'string') {\n return lastUser.content;\n }\n if (Array.isArray(lastUser.content)) {\n return lastUser.content\n .filter((part: any) => part && typeof part === 'object' && typeof part.text === 'string')\n .map((part: any) => part.text)\n .join('\\n');\n }\n }\n }\n\n return '';\n }\n\n public async listModels(_auth?: AuthContext): Promise<any[]> {\n const models: any[] = [];\n\n // 平台 Provider 模型(从 DEFAULT_API_BASE 获取)\n const platformBase = process.env.DEFAULT_API_BASE;\n const platformKey = process.env.DEFAULT_API_KEY;\n if (platformBase) {\n try {\n const url = platformBase.replace(/\\/$/, '') + '/models';\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (platformKey) {\n headers['Authorization'] = `Bearer ${platformKey}`;\n }\n const resp = await fetch(url, { headers });\n if (resp.ok) {\n const data = await resp.json() as { data?: any[] };\n if (data.data) {\n models.push(...data.data);\n }\n } else {\n this.logger.warn(`Failed to fetch platform models: ${resp.status}`);\n }\n } catch (error) {\n this.logger.warn(`Failed to fetch platform models: ${error}`);\n }\n }\n\n // TODO: 合并用户 Pod Providers 的模型\n return models;\n }\n\n private mapFinishReason(reason: string): 'stop' | 'length' | 'content_filter' {\n return reason as any;\n }\n\n /**\n * Handle API errors and update credential status accordingly\n */\n private async handleApiError(\n error: unknown,\n context: StoreContext,\n credentialId: string,\n ): Promise<void> {\n const errorInfo = this.parseApiError(error);\n\n if (errorInfo.statusCode === 429) {\n // Rate limit error - mark credential as rate limited\n const resetAt = errorInfo.retryAfter\n ? new Date(Date.now() + errorInfo.retryAfter * 1000)\n : new Date(Date.now() + 60000); // Default 1 minute cooldown\n\n this.logger.warn(`Rate limit hit for credential ${credentialId}, reset at: ${resetAt.toISOString()}`);\n\n await this.store.updateCredentialStatus(\n context,\n credentialId,\n CredentialStatus.RATE_LIMITED,\n { rateLimitResetAt: resetAt },\n );\n } else if (errorInfo.statusCode === 401 || errorInfo.statusCode === 403) {\n // Auth error - mark credential as inactive\n this.logger.warn(`Auth error for credential ${credentialId}, marking as inactive`);\n\n await this.store.updateCredentialStatus(\n context,\n credentialId,\n CredentialStatus.INACTIVE,\n { incrementFailCount: true },\n );\n } else if (errorInfo.statusCode >= 500) {\n // Server error - increment fail count but keep active\n this.logger.warn(`Server error ${errorInfo.statusCode} for credential ${credentialId}`);\n\n await this.store.updateCredentialStatus(\n context,\n credentialId,\n CredentialStatus.ACTIVE,\n { incrementFailCount: true },\n );\n }\n }\n\n /**\n * Parse error to extract status code and retry-after header\n */\n private parseApiError(error: unknown): { statusCode: number; retryAfter?: number } {\n // Handle different error formats from AI SDK\n if (error && typeof error === 'object') {\n const err = error as any;\n\n // Direct status code\n if (typeof err.status === 'number') {\n return {\n statusCode: err.status,\n retryAfter: err.retryAfter || err.headers?.['retry-after'],\n };\n }\n\n // Nested response object\n if (err.response && typeof err.response.status === 'number') {\n return {\n statusCode: err.response.status,\n retryAfter: err.response.headers?.get?.('retry-after'),\n };\n }\n\n // Error message parsing (fallback)\n if (err.message) {\n const match = err.message.match(/(\\d{3})/);\n if (match) {\n return { statusCode: parseInt(match[1], 10) };\n }\n }\n }\n\n return { statusCode: 0 };\n }\n\n /**\n * Check if account has remaining token quota\n */\n private async checkTokenQuota(accountId: string): Promise<void> {\n if (!this.quotaService || !this.usageRepo) {\n return; // No quota enforcement if not configured\n }\n\n try {\n const quota = await this.quotaService.getAccountQuota(accountId);\n if (!quota.tokenLimitMonthly) {\n return; // No limit set\n }\n\n const usage = await this.usageRepo.getAccountUsage(accountId);\n const tokensUsed = usage?.tokensUsed ?? 0;\n\n if (tokensUsed >= quota.tokenLimitMonthly) {\n const err = new Error('Token quota exceeded for this month');\n (err as any).code = 'quota_exceeded';\n throw err;\n }\n } catch (error) {\n if ((error as any).code === 'quota_exceeded') {\n throw error;\n }\n // Log but don't block on quota check errors\n this.logger.warn(`Token quota check failed: ${error}`);\n }\n }\n\n /**\n * Record token usage (fire-and-forget)\n */\n private recordTokenUsage(accountId: string, podId: string, tokens: number): void {\n if (!this.usageRepo) {\n return;\n }\n\n this.usageRepo.incrementTokenUsage(accountId, podId, tokens).catch((err) => {\n this.logger.warn(`Failed to record token usage: ${err}`);\n });\n }\n}\n"]}
|