manifest 5.28.1 → 5.28.4
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 +1 -9
- package/dist/backend/analytics/controllers/agent-analytics.controller.js +0 -2
- package/dist/backend/analytics/controllers/agents.controller.js +0 -2
- package/dist/backend/app.module.js +1 -0
- package/dist/backend/auth/auth.instance.js +0 -10
- package/dist/backend/common/filters/spa-fallback.filter.js +7 -4
- package/dist/backend/common/utils/anthropic-model-id.js +36 -0
- package/dist/backend/database/local-bootstrap.service.js +0 -2
- package/dist/backend/database/migrations/1773600000000-AddOverrideProvider.js +18 -0
- package/dist/backend/entities/tier-assignment.entity.js +5 -0
- package/dist/backend/health/health.controller.js +0 -2
- package/dist/backend/main.js +1 -1
- package/dist/backend/model-prices/model-name-normalizer.js +11 -0
- package/dist/backend/model-prices/model-prices.module.js +11 -2
- package/dist/backend/model-prices/model-prices.service.js +1 -0
- package/dist/backend/model-prices/model-pricing-cache.service.js +26 -6
- package/dist/backend/otlp/otlp.controller.js +0 -7
- package/dist/backend/routing/dto/routing.dto.js +7 -0
- package/dist/backend/routing/model-discovery/model-discovery.service.js +12 -3
- package/dist/backend/routing/model-discovery/model-fallback.js +12 -3
- package/dist/backend/routing/model-discovery/provider-model-registry.service.js +84 -0
- package/dist/backend/routing/proxy/provider-client.js +68 -0
- package/dist/backend/routing/proxy/proxy.controller.js +1 -7
- package/dist/backend/routing/proxy/proxy.service.js +119 -15
- package/dist/backend/routing/resolve.controller.js +0 -4
- package/dist/backend/routing/resolve.service.js +6 -3
- package/dist/backend/routing/routing-invalidation.service.js +1 -0
- package/dist/backend/routing/routing.controller.js +1 -8
- package/dist/backend/routing/routing.service.js +14 -3
- package/dist/backend/routing/tier-auto-assign.service.js +1 -0
- package/dist/index.js +15 -15
- package/dist/index.js.map +4 -4
- package/dist/local-mode.js +2 -2
- package/dist/openclaw.plugin.json +3 -3
- package/dist/server.js +0 -3
- package/openclaw.plugin.json +3 -3
- package/package.json +1 -1
- package/public/assets/{Account-lMoZskop.js → Account-BCGnPZpy.js} +1 -1
- package/public/assets/{Limits-B-6iTyQT.js → Limits-oxYjJ-dc.js} +1 -1
- package/public/assets/{Login-DCJ6baks.js → Login-CO8qeCzE.js} +1 -1
- package/public/assets/{MessageLog-WSu2aiYt.js → MessageLog-Dgo_LIpr.js} +1 -1
- package/public/assets/{ModelPrices-COnpiTsJ.js → ModelPrices-C65v0VGg.js} +1 -1
- package/public/assets/{Overview-BFROKNs8.js → Overview-BxMRtfGQ.js} +1 -1
- package/public/assets/{Register-BRjUN5YN.js → Register-B23msCLK.js} +1 -1
- package/public/assets/{ResetPassword-ChtceLPF.js → ResetPassword-DxYU1h7s.js} +1 -1
- package/public/assets/Routing-DsotPZ7f.js +3 -0
- package/public/assets/{Settings-DRSVp3Qa.js → Settings-R67t6_xt.js} +1 -1
- package/public/assets/{SocialButtons-CHClLuQb.js → SocialButtons-2KTxe6fx.js} +1 -1
- package/public/assets/index-C5s5w1mG.js +2 -0
- package/public/assets/{model-display-CLqbKFOT.js → model-display-uKwr3P-q.js} +1 -1
- package/public/assets/{overview-NV8VepBt.js → overview-Bfro9DjY.js} +1 -1
- package/public/index.html +1 -1
- package/skills/manifest/SKILL.md +87 -81
- package/dist/backend/common/utils/posthog-sender.js +0 -19
- package/dist/backend/common/utils/product-telemetry.js +0 -55
- package/public/assets/Routing-CtIaVTz0.js +0 -3
- package/public/assets/index-CP_42-of.js +0 -2
package/README.md
CHANGED
|
@@ -108,15 +108,7 @@ tailscale serve --bg 2099
|
|
|
108
108
|
|
|
109
109
|
**In cloud mode, the blind proxy physically cannot read your prompts.** This is fundamentally different from services saying "trust us."
|
|
110
110
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
**Opting out:**
|
|
114
|
-
|
|
115
|
-
```bash
|
|
116
|
-
MANIFEST_TELEMETRY_OPTOUT=1
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
Or add `"telemetryOptOut": true` to `~/.openclaw/manifest/config.json`.
|
|
111
|
+
In local mode, all Manifest data stays on your machine. No analytics or telemetry data is sent externally.
|
|
120
112
|
|
|
121
113
|
|
|
122
114
|
## Manifest vs OpenRouter
|
|
@@ -21,7 +21,6 @@ const agent_analytics_service_1 = require("../services/agent-analytics.service")
|
|
|
21
21
|
const range_query_dto_1 = require("../../common/dto/range-query.dto");
|
|
22
22
|
const agent_cache_interceptor_1 = require("../../common/interceptors/agent-cache.interceptor");
|
|
23
23
|
const cache_constants_1 = require("../../common/constants/cache.constants");
|
|
24
|
-
const product_telemetry_1 = require("../../common/utils/product-telemetry");
|
|
25
24
|
let AgentAnalyticsController = class AgentAnalyticsController {
|
|
26
25
|
analytics;
|
|
27
26
|
constructor(analytics) {
|
|
@@ -34,7 +33,6 @@ let AgentAnalyticsController = class AgentAnalyticsController {
|
|
|
34
33
|
return {
|
|
35
34
|
...usage,
|
|
36
35
|
agentName: ctx.agentName,
|
|
37
|
-
telemetryId: (0, product_telemetry_1.hashForTelemetry)(ctx.userId),
|
|
38
36
|
};
|
|
39
37
|
}
|
|
40
38
|
async getCosts(query, req) {
|
|
@@ -26,7 +26,6 @@ const rename_agent_dto_1 = require("../../common/dto/rename-agent.dto");
|
|
|
26
26
|
const user_cache_interceptor_1 = require("../../common/interceptors/user-cache.interceptor");
|
|
27
27
|
const cache_constants_1 = require("../../common/constants/cache.constants");
|
|
28
28
|
const local_mode_constants_1 = require("../../common/constants/local-mode.constants");
|
|
29
|
-
const product_telemetry_1 = require("../../common/utils/product-telemetry");
|
|
30
29
|
const slugify_1 = require("../../common/utils/slugify");
|
|
31
30
|
const tenant_cache_service_1 = require("../../common/services/tenant-cache.service");
|
|
32
31
|
let AgentsController = class AgentsController {
|
|
@@ -68,7 +67,6 @@ let AgentsController = class AgentsController {
|
|
|
68
67
|
}
|
|
69
68
|
throw error;
|
|
70
69
|
}
|
|
71
|
-
(0, product_telemetry_1.trackCloudEvent)('agent_created', user.id, { agent_name: slug });
|
|
72
70
|
return {
|
|
73
71
|
agent: { id: result.agentId, name: slug, display_name: displayName },
|
|
74
72
|
apiKey: result.apiKey,
|
|
@@ -42,6 +42,7 @@ const serveStaticImports = frontendPath
|
|
|
42
42
|
? [
|
|
43
43
|
serve_static_1.ServeStaticModule.forRoot({
|
|
44
44
|
rootPath: frontendPath,
|
|
45
|
+
renderPath: '/__serve_static_never_match',
|
|
45
46
|
exclude: ['/api/{*path}', '/otlp/{*path}', '/v1/{*path}'],
|
|
46
47
|
serveStaticOptions: {
|
|
47
48
|
maxAge: ONE_YEAR_S * 1000,
|
|
@@ -6,7 +6,6 @@ const render_1 = require("@react-email/render");
|
|
|
6
6
|
const verify_email_1 = require("../notifications/emails/verify-email");
|
|
7
7
|
const reset_password_1 = require("../notifications/emails/reset-password");
|
|
8
8
|
const send_email_1 = require("../notifications/services/email-providers/send-email");
|
|
9
|
-
const product_telemetry_1 = require("../common/utils/product-telemetry");
|
|
10
9
|
const local_mode_constants_1 = require("../common/constants/local-mode.constants");
|
|
11
10
|
const isLocalMode = process.env['MANIFEST_MODE'] === 'local';
|
|
12
11
|
const port = process.env['PORT'] ?? '3001';
|
|
@@ -116,15 +115,6 @@ const authInstance = isLocalMode
|
|
|
116
115
|
},
|
|
117
116
|
},
|
|
118
117
|
trustedOrigins: buildTrustedOrigins(),
|
|
119
|
-
databaseHooks: {
|
|
120
|
-
user: {
|
|
121
|
-
create: {
|
|
122
|
-
after: async (user) => {
|
|
123
|
-
(0, product_telemetry_1.trackCloudEvent)('user_registered', user.id);
|
|
124
|
-
},
|
|
125
|
-
},
|
|
126
|
-
},
|
|
127
|
-
},
|
|
128
118
|
});
|
|
129
119
|
exports.auth = authInstance;
|
|
130
120
|
//# sourceMappingURL=auth.instance.js.map
|
|
@@ -12,27 +12,30 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.SpaFallbackFilter = void 0;
|
|
13
13
|
const common_1 = require("@nestjs/common");
|
|
14
14
|
const path_1 = require("path");
|
|
15
|
+
const fs_1 = require("fs");
|
|
15
16
|
const frontend_path_1 = require("../utils/frontend-path");
|
|
16
17
|
const API_PREFIXES = ['/api/', '/otlp/', '/v1/'];
|
|
17
18
|
let SpaFallbackFilter = class SpaFallbackFilter {
|
|
18
|
-
|
|
19
|
+
indexContent;
|
|
19
20
|
constructor() {
|
|
20
21
|
const frontendDir = (0, frontend_path_1.resolveFrontendDir)();
|
|
21
|
-
this.
|
|
22
|
+
this.indexContent = frontendDir ? (0, fs_1.readFileSync)((0, path_1.join)(frontendDir, 'index.html'), 'utf-8') : null;
|
|
22
23
|
}
|
|
23
24
|
catch(exception, host) {
|
|
24
25
|
const ctx = host.switchToHttp();
|
|
25
26
|
const req = ctx.getRequest();
|
|
26
27
|
const res = ctx.getResponse();
|
|
27
28
|
if (req.method !== 'GET' ||
|
|
28
|
-
!this.
|
|
29
|
+
!this.indexContent ||
|
|
29
30
|
API_PREFIXES.some((p) => req.originalUrl.startsWith(p))) {
|
|
30
31
|
const response = exception.getResponse();
|
|
31
32
|
const status = exception.getStatus();
|
|
32
33
|
res.status(status).json(response);
|
|
33
34
|
return;
|
|
34
35
|
}
|
|
35
|
-
res.
|
|
36
|
+
res.setHeader('Content-Type', 'text/html');
|
|
37
|
+
res.setHeader('Cache-Control', 'no-cache');
|
|
38
|
+
res.status(200).send(this.indexContent);
|
|
36
39
|
}
|
|
37
40
|
};
|
|
38
41
|
exports.SpaFallbackFilter = SpaFallbackFilter;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.normalizeAnthropicShortModelId = normalizeAnthropicShortModelId;
|
|
4
|
+
exports.buildAnthropicShortModelIdVariants = buildAnthropicShortModelIdVariants;
|
|
5
|
+
const ANTHROPIC_PREFIX = 'anthropic/';
|
|
6
|
+
const SHORT_ANTHROPIC_MODEL_RE = /^claude-(opus|sonnet|haiku)-/i;
|
|
7
|
+
const DOTTED_MINOR_RE = /-(\d+)\.(\d{1,2})(?=$|-\d{8}$)/g;
|
|
8
|
+
const DASHED_MINOR_RE = /-(\d+)-(\d{1,2})(?=$|-\d{8}$)/g;
|
|
9
|
+
function splitAnthropicPrefix(model) {
|
|
10
|
+
if (model.startsWith(ANTHROPIC_PREFIX)) {
|
|
11
|
+
return {
|
|
12
|
+
prefix: ANTHROPIC_PREFIX,
|
|
13
|
+
bare: model.slice(ANTHROPIC_PREFIX.length),
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
return { prefix: '', bare: model };
|
|
17
|
+
}
|
|
18
|
+
function supportsShortAnthropicMinorVersion(model) {
|
|
19
|
+
return SHORT_ANTHROPIC_MODEL_RE.test(model);
|
|
20
|
+
}
|
|
21
|
+
function normalizeAnthropicShortModelId(model) {
|
|
22
|
+
const { prefix, bare } = splitAnthropicPrefix(model);
|
|
23
|
+
if (!supportsShortAnthropicMinorVersion(bare))
|
|
24
|
+
return model;
|
|
25
|
+
return `${prefix}${bare.replace(DOTTED_MINOR_RE, '-$1-$2')}`;
|
|
26
|
+
}
|
|
27
|
+
function buildAnthropicShortModelIdVariants(model) {
|
|
28
|
+
const normalized = normalizeAnthropicShortModelId(model);
|
|
29
|
+
const { prefix, bare } = splitAnthropicPrefix(normalized);
|
|
30
|
+
if (!supportsShortAnthropicMinorVersion(bare))
|
|
31
|
+
return [model];
|
|
32
|
+
const variants = new Set([model, normalized]);
|
|
33
|
+
variants.add(`${prefix}${bare.replace(DASHED_MINOR_RE, '-$1.$2')}`);
|
|
34
|
+
return [...variants];
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=anthropic-model-id.js.map
|
|
@@ -62,7 +62,6 @@ const user_provider_entity_1 = require("../entities/user-provider.entity");
|
|
|
62
62
|
const tier_assignment_entity_1 = require("../entities/tier-assignment.entity");
|
|
63
63
|
const hash_util_1 = require("../common/utils/hash.util");
|
|
64
64
|
const local_mode_constants_1 = require("../common/constants/local-mode.constants");
|
|
65
|
-
const product_telemetry_1 = require("../common/utils/product-telemetry");
|
|
66
65
|
const seed_messages_1 = require("./seed-messages");
|
|
67
66
|
let LocalBootstrapService = LocalBootstrapService_1 = class LocalBootstrapService {
|
|
68
67
|
tenantRepo;
|
|
@@ -124,7 +123,6 @@ let LocalBootstrapService = LocalBootstrapService_1 = class LocalBootstrapServic
|
|
|
124
123
|
is_active: true,
|
|
125
124
|
tenant_id: local_mode_constants_1.LOCAL_TENANT_ID,
|
|
126
125
|
});
|
|
127
|
-
(0, product_telemetry_1.trackEvent)('agent_created', { agent_name: local_mode_constants_1.LOCAL_AGENT_NAME });
|
|
128
126
|
this.logger.log(`Created tenant/agent for local mode`);
|
|
129
127
|
}
|
|
130
128
|
const apiKey = this.readApiKeyFromConfig();
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AddOverrideProvider1773600000000 = void 0;
|
|
4
|
+
const typeorm_1 = require("typeorm");
|
|
5
|
+
class AddOverrideProvider1773600000000 {
|
|
6
|
+
async up(queryRunner) {
|
|
7
|
+
await queryRunner.addColumn('tier_assignments', new typeorm_1.TableColumn({
|
|
8
|
+
name: 'override_provider',
|
|
9
|
+
type: 'varchar',
|
|
10
|
+
isNullable: true,
|
|
11
|
+
}));
|
|
12
|
+
}
|
|
13
|
+
async down(queryRunner) {
|
|
14
|
+
await queryRunner.dropColumn('tier_assignments', 'override_provider');
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.AddOverrideProvider1773600000000 = AddOverrideProvider1773600000000;
|
|
18
|
+
//# sourceMappingURL=1773600000000-AddOverrideProvider.js.map
|
|
@@ -18,6 +18,7 @@ let TierAssignment = class TierAssignment {
|
|
|
18
18
|
agent_id;
|
|
19
19
|
tier;
|
|
20
20
|
override_model;
|
|
21
|
+
override_provider;
|
|
21
22
|
override_auth_type;
|
|
22
23
|
auto_assigned_model;
|
|
23
24
|
fallback_models;
|
|
@@ -44,6 +45,10 @@ __decorate([
|
|
|
44
45
|
(0, typeorm_1.Column)('varchar', { nullable: true }),
|
|
45
46
|
__metadata("design:type", Object)
|
|
46
47
|
], TierAssignment.prototype, "override_model", void 0);
|
|
48
|
+
__decorate([
|
|
49
|
+
(0, typeorm_1.Column)('varchar', { nullable: true }),
|
|
50
|
+
__metadata("design:type", Object)
|
|
51
|
+
], TierAssignment.prototype, "override_provider", void 0);
|
|
47
52
|
__decorate([
|
|
48
53
|
(0, typeorm_1.Column)('varchar', { nullable: true }),
|
|
49
54
|
__metadata("design:type", Object)
|
|
@@ -22,14 +22,12 @@ let HealthController = class HealthController {
|
|
|
22
22
|
getHealth() {
|
|
23
23
|
const isLocal = process.env['MANIFEST_MODE'] === 'local';
|
|
24
24
|
const isDev = process.env['NODE_ENV'] !== 'production';
|
|
25
|
-
const optOut = process.env['MANIFEST_TELEMETRY_OPTOUT'];
|
|
26
25
|
return {
|
|
27
26
|
status: 'healthy',
|
|
28
27
|
uptime_seconds: Math.floor((Date.now() - this.startTime) / 1000),
|
|
29
28
|
...(isLocal ? { version: this.versionCheck.getCurrentVersion() } : {}),
|
|
30
29
|
mode: isLocal ? 'local' : 'cloud',
|
|
31
30
|
devMode: isDev,
|
|
32
|
-
telemetryOptOut: optOut === '1' || optOut === 'true',
|
|
33
31
|
...this.versionCheck.getUpdateInfo(),
|
|
34
32
|
};
|
|
35
33
|
}
|
package/dist/backend/main.js
CHANGED
|
@@ -62,7 +62,7 @@ async function bootstrap() {
|
|
|
62
62
|
scriptSrc: ["'self'"],
|
|
63
63
|
styleSrc: ["'self'", "'unsafe-inline'"],
|
|
64
64
|
imgSrc: ["'self'", 'data:'],
|
|
65
|
-
connectSrc: ["'self'"
|
|
65
|
+
connectSrc: ["'self'"],
|
|
66
66
|
fontSrc: ["'self'"],
|
|
67
67
|
objectSrc: ["'none'"],
|
|
68
68
|
frameAncestors: ["'none'"],
|
|
@@ -5,6 +5,7 @@ exports.stripDateSuffix = stripDateSuffix;
|
|
|
5
5
|
exports.buildAliasMap = buildAliasMap;
|
|
6
6
|
exports.normalizeDots = normalizeDots;
|
|
7
7
|
exports.resolveModelName = resolveModelName;
|
|
8
|
+
const anthropic_model_id_1 = require("../common/utils/anthropic-model-id");
|
|
8
9
|
const KNOWN_ALIASES = [
|
|
9
10
|
['claude-opus-4', 'claude-opus-4-6'],
|
|
10
11
|
['claude-sonnet-4.5', 'claude-sonnet-4-5-20250929'],
|
|
@@ -61,10 +62,20 @@ function buildAliasMap(canonicalNames) {
|
|
|
61
62
|
const map = new Map();
|
|
62
63
|
for (const name of canonicalNames) {
|
|
63
64
|
map.set(name, name);
|
|
65
|
+
for (const variant of (0, anthropic_model_id_1.buildAnthropicShortModelIdVariants)(name)) {
|
|
66
|
+
if (!map.has(variant)) {
|
|
67
|
+
map.set(variant, name);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
64
70
|
const bare = stripProviderPrefix(name);
|
|
65
71
|
if (bare !== name && !map.has(bare)) {
|
|
66
72
|
map.set(bare, name);
|
|
67
73
|
}
|
|
74
|
+
for (const variant of (0, anthropic_model_id_1.buildAnthropicShortModelIdVariants)(bare)) {
|
|
75
|
+
if (!map.has(variant)) {
|
|
76
|
+
map.set(variant, name);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
68
79
|
}
|
|
69
80
|
for (const [alias, canonical] of KNOWN_ALIASES) {
|
|
70
81
|
if (map.has(alias))
|
|
@@ -8,18 +8,27 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.ModelPricesModule = void 0;
|
|
10
10
|
const common_1 = require("@nestjs/common");
|
|
11
|
+
const typeorm_1 = require("@nestjs/typeorm");
|
|
11
12
|
const model_prices_controller_1 = require("./model-prices.controller");
|
|
12
13
|
const model_prices_service_1 = require("./model-prices.service");
|
|
13
14
|
const model_pricing_cache_service_1 = require("./model-pricing-cache.service");
|
|
14
15
|
const pricing_sync_service_1 = require("../database/pricing-sync.service");
|
|
16
|
+
const provider_model_registry_service_1 = require("../routing/model-discovery/provider-model-registry.service");
|
|
17
|
+
const user_provider_entity_1 = require("../entities/user-provider.entity");
|
|
15
18
|
let ModelPricesModule = class ModelPricesModule {
|
|
16
19
|
};
|
|
17
20
|
exports.ModelPricesModule = ModelPricesModule;
|
|
18
21
|
exports.ModelPricesModule = ModelPricesModule = __decorate([
|
|
19
22
|
(0, common_1.Module)({
|
|
23
|
+
imports: [typeorm_1.TypeOrmModule.forFeature([user_provider_entity_1.UserProvider])],
|
|
20
24
|
controllers: [model_prices_controller_1.ModelPricesController],
|
|
21
|
-
providers: [
|
|
22
|
-
|
|
25
|
+
providers: [
|
|
26
|
+
model_prices_service_1.ModelPricesService,
|
|
27
|
+
model_pricing_cache_service_1.ModelPricingCacheService,
|
|
28
|
+
pricing_sync_service_1.PricingSyncService,
|
|
29
|
+
provider_model_registry_service_1.ProviderModelRegistryService,
|
|
30
|
+
],
|
|
31
|
+
exports: [model_pricing_cache_service_1.ModelPricingCacheService, pricing_sync_service_1.PricingSyncService, provider_model_registry_service_1.ProviderModelRegistryService],
|
|
23
32
|
})
|
|
24
33
|
], ModelPricesModule);
|
|
25
34
|
//# sourceMappingURL=model-prices.module.js.map
|
|
@@ -30,6 +30,7 @@ let ModelPricesService = class ModelPricesService {
|
|
|
30
30
|
input_price_per_million: r.input_price_per_token != null ? Number(r.input_price_per_token) * 1_000_000 : null,
|
|
31
31
|
output_price_per_million: r.output_price_per_token != null ? Number(r.output_price_per_token) * 1_000_000 : null,
|
|
32
32
|
display_name: r.display_name || null,
|
|
33
|
+
validated: r.validated,
|
|
33
34
|
})),
|
|
34
35
|
lastSyncedAt,
|
|
35
36
|
};
|
|
@@ -8,6 +8,9 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
8
8
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
9
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
10
|
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
11
14
|
var ModelPricingCacheService_1;
|
|
12
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
16
|
exports.ModelPricingCacheService = void 0;
|
|
@@ -15,13 +18,16 @@ const common_1 = require("@nestjs/common");
|
|
|
15
18
|
const model_name_normalizer_1 = require("./model-name-normalizer");
|
|
16
19
|
const pricing_sync_service_1 = require("../database/pricing-sync.service");
|
|
17
20
|
const providers_1 = require("../common/constants/providers");
|
|
21
|
+
const provider_model_registry_service_1 = require("../routing/model-discovery/provider-model-registry.service");
|
|
18
22
|
let ModelPricingCacheService = ModelPricingCacheService_1 = class ModelPricingCacheService {
|
|
19
23
|
pricingSync;
|
|
24
|
+
modelRegistry;
|
|
20
25
|
logger = new common_1.Logger(ModelPricingCacheService_1.name);
|
|
21
26
|
cache = new Map();
|
|
22
27
|
aliasMap = new Map();
|
|
23
|
-
constructor(pricingSync) {
|
|
28
|
+
constructor(pricingSync, modelRegistry) {
|
|
24
29
|
this.pricingSync = pricingSync;
|
|
30
|
+
this.modelRegistry = modelRegistry;
|
|
25
31
|
}
|
|
26
32
|
async onApplicationBootstrap() {
|
|
27
33
|
await this.reload();
|
|
@@ -30,14 +36,16 @@ let ModelPricingCacheService = ModelPricingCacheService_1 = class ModelPricingCa
|
|
|
30
36
|
this.cache.clear();
|
|
31
37
|
const orCache = this.pricingSync.getAll();
|
|
32
38
|
for (const [fullId, entry] of orCache) {
|
|
33
|
-
const { provider, canonical } = this.resolveProviderAndName(fullId);
|
|
39
|
+
const { provider, canonical, providerId } = this.resolveProviderAndName(fullId);
|
|
34
40
|
const displayName = entry.displayName ?? null;
|
|
41
|
+
const validated = this.resolveValidated(providerId, canonical);
|
|
35
42
|
this.cache.set(fullId, {
|
|
36
43
|
model_name: fullId,
|
|
37
44
|
provider,
|
|
38
45
|
input_price_per_token: entry.input,
|
|
39
46
|
output_price_per_token: entry.output,
|
|
40
47
|
display_name: displayName,
|
|
48
|
+
validated,
|
|
41
49
|
});
|
|
42
50
|
if (canonical !== fullId && !this.cache.has(canonical)) {
|
|
43
51
|
this.cache.set(canonical, {
|
|
@@ -46,6 +54,7 @@ let ModelPricingCacheService = ModelPricingCacheService_1 = class ModelPricingCa
|
|
|
46
54
|
input_price_per_token: entry.input,
|
|
47
55
|
output_price_per_token: entry.output,
|
|
48
56
|
display_name: displayName,
|
|
57
|
+
validated,
|
|
49
58
|
});
|
|
50
59
|
}
|
|
51
60
|
}
|
|
@@ -74,11 +83,11 @@ let ModelPricingCacheService = ModelPricingCacheService_1 = class ModelPricingCa
|
|
|
74
83
|
}
|
|
75
84
|
resolveProviderAndName(openRouterId) {
|
|
76
85
|
if (openRouterId.startsWith('openrouter/')) {
|
|
77
|
-
return { provider: 'OpenRouter', canonical: openRouterId };
|
|
86
|
+
return { provider: 'OpenRouter', canonical: openRouterId, providerId: null };
|
|
78
87
|
}
|
|
79
88
|
const slashIdx = openRouterId.indexOf('/');
|
|
80
89
|
if (slashIdx <= 0) {
|
|
81
|
-
return { provider: 'OpenRouter', canonical: openRouterId };
|
|
90
|
+
return { provider: 'OpenRouter', canonical: openRouterId, providerId: null };
|
|
82
91
|
}
|
|
83
92
|
const prefix = openRouterId.substring(0, slashIdx);
|
|
84
93
|
const displayName = providers_1.OPENROUTER_PREFIX_TO_PROVIDER.get(prefix);
|
|
@@ -86,14 +95,25 @@ let ModelPricingCacheService = ModelPricingCacheService_1 = class ModelPricingCa
|
|
|
86
95
|
return {
|
|
87
96
|
provider: displayName,
|
|
88
97
|
canonical: openRouterId.substring(slashIdx + 1),
|
|
98
|
+
providerId: prefix,
|
|
89
99
|
};
|
|
90
100
|
}
|
|
91
|
-
return { provider: 'OpenRouter', canonical: openRouterId };
|
|
101
|
+
return { provider: 'OpenRouter', canonical: openRouterId, providerId: null };
|
|
102
|
+
}
|
|
103
|
+
resolveValidated(providerId, canonical) {
|
|
104
|
+
if (!this.modelRegistry || !providerId)
|
|
105
|
+
return undefined;
|
|
106
|
+
const entry = providers_1.PROVIDER_BY_ID_OR_ALIAS.get(providerId);
|
|
107
|
+
const canonicalProviderId = entry?.id ?? providerId;
|
|
108
|
+
const result = this.modelRegistry.isModelConfirmed(canonicalProviderId, canonical);
|
|
109
|
+
return result ?? undefined;
|
|
92
110
|
}
|
|
93
111
|
};
|
|
94
112
|
exports.ModelPricingCacheService = ModelPricingCacheService;
|
|
95
113
|
exports.ModelPricingCacheService = ModelPricingCacheService = ModelPricingCacheService_1 = __decorate([
|
|
96
114
|
(0, common_1.Injectable)(),
|
|
97
|
-
|
|
115
|
+
__param(1, (0, common_1.Optional)()),
|
|
116
|
+
__param(1, (0, common_1.Inject)(provider_model_registry_service_1.ProviderModelRegistryService)),
|
|
117
|
+
__metadata("design:paramtypes", [pricing_sync_service_1.PricingSyncService, Object])
|
|
98
118
|
], ModelPricingCacheService);
|
|
99
119
|
//# sourceMappingURL=model-pricing-cache.service.js.map
|
|
@@ -26,7 +26,6 @@ const metric_ingest_service_1 = require("./services/metric-ingest.service");
|
|
|
26
26
|
const log_ingest_service_1 = require("./services/log-ingest.service");
|
|
27
27
|
const ingest_event_bus_service_1 = require("../common/services/ingest-event-bus.service");
|
|
28
28
|
const manifest_runtime_service_1 = require("../common/services/manifest-runtime.service");
|
|
29
|
-
const product_telemetry_1 = require("../common/utils/product-telemetry");
|
|
30
29
|
let OtlpController = OtlpController_1 = class OtlpController {
|
|
31
30
|
decoder;
|
|
32
31
|
traceIngest;
|
|
@@ -84,9 +83,6 @@ let OtlpController = OtlpController_1 = class OtlpController {
|
|
|
84
83
|
const markerPath = (0, path_1.join)(markerDir, '.first_telemetry_sent');
|
|
85
84
|
if ((0, fs_1.existsSync)(markerPath))
|
|
86
85
|
return;
|
|
87
|
-
(0, product_telemetry_1.trackEvent)('first_telemetry_received', {
|
|
88
|
-
agent_id_hash: ctx.agentId.slice(0, 8),
|
|
89
|
-
});
|
|
90
86
|
(0, fs_1.mkdirSync)(markerDir, { recursive: true });
|
|
91
87
|
(0, fs_1.writeFileSync)(markerPath, new Date().toISOString(), { mode: 0o600 });
|
|
92
88
|
}
|
|
@@ -94,9 +90,6 @@ let OtlpController = OtlpController_1 = class OtlpController {
|
|
|
94
90
|
if (this.seenAgents.has(ctx.agentId))
|
|
95
91
|
return;
|
|
96
92
|
this.seenAgents.add(ctx.agentId);
|
|
97
|
-
(0, product_telemetry_1.trackCloudEvent)('first_telemetry_received', ctx.userId, {
|
|
98
|
-
agent_id_hash: ctx.agentId.slice(0, 8),
|
|
99
|
-
});
|
|
100
93
|
}
|
|
101
94
|
}
|
|
102
95
|
};
|
|
@@ -88,6 +88,7 @@ __decorate([
|
|
|
88
88
|
], RemoveProviderQueryDto.prototype, "authType", void 0);
|
|
89
89
|
class SetOverrideDto {
|
|
90
90
|
model;
|
|
91
|
+
provider;
|
|
91
92
|
authType;
|
|
92
93
|
}
|
|
93
94
|
exports.SetOverrideDto = SetOverrideDto;
|
|
@@ -96,6 +97,12 @@ __decorate([
|
|
|
96
97
|
(0, class_validator_1.IsNotEmpty)(),
|
|
97
98
|
__metadata("design:type", String)
|
|
98
99
|
], SetOverrideDto.prototype, "model", void 0);
|
|
100
|
+
__decorate([
|
|
101
|
+
(0, class_validator_1.IsOptional)(),
|
|
102
|
+
(0, class_validator_1.IsString)(),
|
|
103
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
104
|
+
__metadata("design:type", String)
|
|
105
|
+
], SetOverrideDto.prototype, "provider", void 0);
|
|
99
106
|
__decorate([
|
|
100
107
|
(0, class_validator_1.IsOptional)(),
|
|
101
108
|
(0, class_validator_1.IsIn)(VALID_AUTH_TYPES),
|
|
@@ -20,6 +20,7 @@ const typeorm_2 = require("typeorm");
|
|
|
20
20
|
const user_provider_entity_1 = require("../../entities/user-provider.entity");
|
|
21
21
|
const custom_provider_entity_1 = require("../../entities/custom-provider.entity");
|
|
22
22
|
const provider_model_fetcher_service_1 = require("./provider-model-fetcher.service");
|
|
23
|
+
const provider_model_registry_service_1 = require("./provider-model-registry.service");
|
|
23
24
|
const crypto_util_1 = require("../../common/utils/crypto.util");
|
|
24
25
|
const quality_score_util_1 = require("../../database/quality-score.util");
|
|
25
26
|
const pricing_sync_service_1 = require("../../database/pricing-sync.service");
|
|
@@ -32,12 +33,14 @@ let ModelDiscoveryService = ModelDiscoveryService_1 = class ModelDiscoveryServic
|
|
|
32
33
|
customProviderRepo;
|
|
33
34
|
fetcher;
|
|
34
35
|
pricingSync;
|
|
36
|
+
modelRegistry;
|
|
35
37
|
logger = new common_1.Logger(ModelDiscoveryService_1.name);
|
|
36
|
-
constructor(providerRepo, customProviderRepo, fetcher, pricingSync) {
|
|
38
|
+
constructor(providerRepo, customProviderRepo, fetcher, pricingSync, modelRegistry) {
|
|
37
39
|
this.providerRepo = providerRepo;
|
|
38
40
|
this.customProviderRepo = customProviderRepo;
|
|
39
41
|
this.fetcher = fetcher;
|
|
40
42
|
this.pricingSync = pricingSync;
|
|
43
|
+
this.modelRegistry = modelRegistry;
|
|
41
44
|
}
|
|
42
45
|
async discoverModels(provider) {
|
|
43
46
|
let apiKey = '';
|
|
@@ -72,8 +75,12 @@ let ModelDiscoveryService = ModelDiscoveryService_1 = class ModelDiscoveryServic
|
|
|
72
75
|
}
|
|
73
76
|
else {
|
|
74
77
|
raw = await this.fetcher.fetch(provider.provider, apiKey, provider.auth_type, endpointOverride);
|
|
78
|
+
if (raw.length > 0 && this.modelRegistry) {
|
|
79
|
+
this.modelRegistry.registerModels(provider.provider, raw.map((m) => m.id));
|
|
80
|
+
}
|
|
75
81
|
if (raw.length === 0) {
|
|
76
|
-
|
|
82
|
+
const confirmed = this.modelRegistry?.getConfirmedModels(provider.provider) ?? null;
|
|
83
|
+
raw = (0, model_fallback_1.buildFallbackModels)(this.pricingSync, provider.provider, confirmed);
|
|
77
84
|
if (raw.length > 0) {
|
|
78
85
|
this.logger.log(`Native API returned 0 models for ${provider.provider} — using ${raw.length} models from pricing data`);
|
|
79
86
|
}
|
|
@@ -215,8 +222,10 @@ exports.ModelDiscoveryService = ModelDiscoveryService = ModelDiscoveryService_1
|
|
|
215
222
|
__param(1, (0, typeorm_1.InjectRepository)(custom_provider_entity_1.CustomProvider)),
|
|
216
223
|
__param(3, (0, common_1.Optional)()),
|
|
217
224
|
__param(3, (0, common_1.Inject)(pricing_sync_service_1.PricingSyncService)),
|
|
225
|
+
__param(4, (0, common_1.Optional)()),
|
|
226
|
+
__param(4, (0, common_1.Inject)(provider_model_registry_service_1.ProviderModelRegistryService)),
|
|
218
227
|
__metadata("design:paramtypes", [typeorm_2.Repository,
|
|
219
228
|
typeorm_2.Repository,
|
|
220
|
-
provider_model_fetcher_service_1.ProviderModelFetcherService, Object])
|
|
229
|
+
provider_model_fetcher_service_1.ProviderModelFetcherService, Object, Object])
|
|
221
230
|
], ModelDiscoveryService);
|
|
222
231
|
//# sourceMappingURL=model-discovery.service.js.map
|
|
@@ -7,6 +7,12 @@ exports.buildSubscriptionFallbackModels = buildSubscriptionFallbackModels;
|
|
|
7
7
|
exports.supplementWithKnownModels = supplementWithKnownModels;
|
|
8
8
|
const providers_1 = require("../../common/constants/providers");
|
|
9
9
|
const subscription_capabilities_1 = require("../../../../subscription-capabilities");
|
|
10
|
+
const anthropic_model_id_1 = require("../../common/utils/anthropic-model-id");
|
|
11
|
+
function normalizeProviderModelId(providerId, modelId) {
|
|
12
|
+
return providerId.toLowerCase() === 'anthropic'
|
|
13
|
+
? (0, anthropic_model_id_1.normalizeAnthropicShortModelId)(modelId)
|
|
14
|
+
: modelId;
|
|
15
|
+
}
|
|
10
16
|
function findOpenRouterPrefix(providerId) {
|
|
11
17
|
const lower = providerId.toLowerCase();
|
|
12
18
|
if (providers_1.OPENROUTER_PREFIX_TO_PROVIDER.has(lower))
|
|
@@ -54,20 +60,23 @@ function lookupWithVariants(pricingSync, prefix, modelId) {
|
|
|
54
60
|
}
|
|
55
61
|
return null;
|
|
56
62
|
}
|
|
57
|
-
function buildFallbackModels(pricingSync, providerId) {
|
|
63
|
+
function buildFallbackModels(pricingSync, providerId, confirmedModels) {
|
|
58
64
|
if (!pricingSync)
|
|
59
65
|
return [];
|
|
60
66
|
const models = [];
|
|
61
67
|
const seen = new Set();
|
|
68
|
+
const hasConfirmed = confirmedModels != null && confirmedModels.size > 0;
|
|
62
69
|
const orPrefix = findOpenRouterPrefix(providerId);
|
|
63
70
|
if (!orPrefix)
|
|
64
71
|
return [];
|
|
65
72
|
for (const [fullId, entry] of pricingSync.getAll()) {
|
|
66
73
|
if (!fullId.startsWith(`${orPrefix}/`))
|
|
67
74
|
continue;
|
|
68
|
-
const modelId = fullId.substring(orPrefix.length + 1);
|
|
75
|
+
const modelId = normalizeProviderModelId(providerId, fullId.substring(orPrefix.length + 1));
|
|
69
76
|
if (seen.has(modelId))
|
|
70
77
|
continue;
|
|
78
|
+
if (hasConfirmed && !confirmedModels.has(modelId.toLowerCase()))
|
|
79
|
+
continue;
|
|
71
80
|
seen.add(modelId);
|
|
72
81
|
models.push({
|
|
73
82
|
id: modelId,
|
|
@@ -96,7 +105,7 @@ function buildSubscriptionFallbackModels(pricingSync, providerId) {
|
|
|
96
105
|
for (const [fullId, entry] of pricingSync.getAll()) {
|
|
97
106
|
if (!fullId.startsWith(`${orPrefix}/`))
|
|
98
107
|
continue;
|
|
99
|
-
const modelId = fullId.substring(orPrefix.length + 1);
|
|
108
|
+
const modelId = normalizeProviderModelId(providerId, fullId.substring(orPrefix.length + 1));
|
|
100
109
|
if (!normalizedKnownPrefixes.some((p) => modelId.toLowerCase().startsWith(p))) {
|
|
101
110
|
continue;
|
|
102
111
|
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
var ProviderModelRegistryService_1;
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.ProviderModelRegistryService = void 0;
|
|
17
|
+
const common_1 = require("@nestjs/common");
|
|
18
|
+
const typeorm_1 = require("@nestjs/typeorm");
|
|
19
|
+
const typeorm_2 = require("typeorm");
|
|
20
|
+
const user_provider_entity_1 = require("../../entities/user-provider.entity");
|
|
21
|
+
let ProviderModelRegistryService = ProviderModelRegistryService_1 = class ProviderModelRegistryService {
|
|
22
|
+
providerRepo;
|
|
23
|
+
logger = new common_1.Logger(ProviderModelRegistryService_1.name);
|
|
24
|
+
registry = new Map();
|
|
25
|
+
constructor(providerRepo) {
|
|
26
|
+
this.providerRepo = providerRepo;
|
|
27
|
+
}
|
|
28
|
+
async onApplicationBootstrap() {
|
|
29
|
+
await this.loadFromCache();
|
|
30
|
+
}
|
|
31
|
+
registerModels(providerId, modelIds) {
|
|
32
|
+
const key = providerId.toLowerCase();
|
|
33
|
+
const existing = this.registry.get(key);
|
|
34
|
+
if (existing) {
|
|
35
|
+
for (const id of modelIds)
|
|
36
|
+
existing.add(id.toLowerCase());
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
this.registry.set(key, new Set(modelIds.map((id) => id.toLowerCase())));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
getConfirmedModels(providerId) {
|
|
43
|
+
return this.registry.get(providerId.toLowerCase()) ?? null;
|
|
44
|
+
}
|
|
45
|
+
isModelConfirmed(providerId, modelId) {
|
|
46
|
+
const confirmed = this.registry.get(providerId.toLowerCase());
|
|
47
|
+
if (!confirmed)
|
|
48
|
+
return null;
|
|
49
|
+
return confirmed.has(modelId.toLowerCase());
|
|
50
|
+
}
|
|
51
|
+
async loadFromCache() {
|
|
52
|
+
try {
|
|
53
|
+
const providers = await this.providerRepo
|
|
54
|
+
.createQueryBuilder('p')
|
|
55
|
+
.select(['p.provider', 'p.cached_models'])
|
|
56
|
+
.where('p.cached_models IS NOT NULL')
|
|
57
|
+
.getMany();
|
|
58
|
+
let totalModels = 0;
|
|
59
|
+
for (const p of providers) {
|
|
60
|
+
if (!Array.isArray(p.cached_models))
|
|
61
|
+
continue;
|
|
62
|
+
const ids = p.cached_models.map((m) => m.id).filter(Boolean);
|
|
63
|
+
if (ids.length > 0) {
|
|
64
|
+
this.registerModels(p.provider, ids);
|
|
65
|
+
totalModels += ids.length;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const providerCount = this.registry.size;
|
|
69
|
+
if (providerCount > 0) {
|
|
70
|
+
this.logger.log(`Provider model registry loaded: ${providerCount} providers, ${totalModels} model entries`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
this.logger.warn(`Failed to load provider model registry from cache: ${err}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
exports.ProviderModelRegistryService = ProviderModelRegistryService;
|
|
79
|
+
exports.ProviderModelRegistryService = ProviderModelRegistryService = ProviderModelRegistryService_1 = __decorate([
|
|
80
|
+
(0, common_1.Injectable)(),
|
|
81
|
+
__param(0, (0, typeorm_1.InjectRepository)(user_provider_entity_1.UserProvider)),
|
|
82
|
+
__metadata("design:paramtypes", [typeorm_2.Repository])
|
|
83
|
+
], ProviderModelRegistryService);
|
|
84
|
+
//# sourceMappingURL=provider-model-registry.service.js.map
|