manifest 5.33.12 → 5.33.13
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.
|
@@ -51,18 +51,12 @@ const common_1 = require("@nestjs/common");
|
|
|
51
51
|
const core_1 = require("@nestjs/core");
|
|
52
52
|
const typeorm_1 = require("@nestjs/typeorm");
|
|
53
53
|
const typeorm_2 = require("typeorm");
|
|
54
|
-
const fs_1 = require("fs");
|
|
55
|
-
const path_1 = require("path");
|
|
56
|
-
const os_1 = require("os");
|
|
57
54
|
const tenant_entity_1 = require("../entities/tenant.entity");
|
|
58
55
|
const agent_entity_1 = require("../entities/agent.entity");
|
|
59
56
|
const agent_api_key_entity_1 = require("../entities/agent-api-key.entity");
|
|
60
57
|
const agent_message_entity_1 = require("../entities/agent-message.entity");
|
|
61
58
|
const user_provider_entity_1 = require("../entities/user-provider.entity");
|
|
62
59
|
const tier_assignment_entity_1 = require("../entities/tier-assignment.entity");
|
|
63
|
-
const hash_util_1 = require("../common/utils/hash.util");
|
|
64
|
-
const local_mode_constants_1 = require("../common/constants/local-mode.constants");
|
|
65
|
-
const seed_messages_1 = require("./seed-messages");
|
|
66
60
|
let LocalBootstrapService = LocalBootstrapService_1 = class LocalBootstrapService {
|
|
67
61
|
tenantRepo;
|
|
68
62
|
agentRepo;
|
|
@@ -82,99 +76,45 @@ let LocalBootstrapService = LocalBootstrapService_1 = class LocalBootstrapServic
|
|
|
82
76
|
this.moduleRef = moduleRef;
|
|
83
77
|
}
|
|
84
78
|
async onModuleInit() {
|
|
85
|
-
await this.ensureTenantAndAgent();
|
|
86
79
|
await this.fixupRoutingAgentIds();
|
|
87
80
|
await this.recalculateTiersIfNeeded();
|
|
88
|
-
if (!process.env['MANIFEST_EMBEDDED']) {
|
|
89
|
-
await (0, seed_messages_1.seedAgentMessages)(this.messageRepo, local_mode_constants_1.LOCAL_USER_ID, this.logger, {
|
|
90
|
-
tenantId: local_mode_constants_1.LOCAL_TENANT_ID,
|
|
91
|
-
agentId: local_mode_constants_1.LOCAL_AGENT_ID,
|
|
92
|
-
agentName: local_mode_constants_1.LOCAL_AGENT_NAME,
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
81
|
this.logger.log('Local mode bootstrap complete');
|
|
96
82
|
this.discoverModelsInBackground().catch((err) => {
|
|
97
83
|
this.logger.warn(`Background model discovery failed: ${err}`);
|
|
98
84
|
});
|
|
99
85
|
}
|
|
100
86
|
async discoverModelsInBackground() {
|
|
87
|
+
const agents = await this.agentRepo.find({ where: { is_active: true } });
|
|
88
|
+
if (agents.length === 0)
|
|
89
|
+
return;
|
|
101
90
|
try {
|
|
102
91
|
const { ModelDiscoveryService } = await Promise.resolve().then(() => __importStar(require('../model-discovery/model-discovery.service')));
|
|
103
92
|
const discovery = this.moduleRef.get(ModelDiscoveryService, { strict: false });
|
|
104
|
-
|
|
93
|
+
for (const agent of agents) {
|
|
94
|
+
await discovery.discoverAllForAgent(agent.id);
|
|
95
|
+
}
|
|
105
96
|
await this.recalculateTiersIfNeeded();
|
|
106
97
|
}
|
|
107
98
|
catch (err) {
|
|
108
99
|
this.logger.warn(`Model discovery failed: ${err}`);
|
|
109
100
|
}
|
|
110
101
|
}
|
|
111
|
-
async ensureTenantAndAgent() {
|
|
112
|
-
const count = await this.tenantRepo.count({ where: { id: local_mode_constants_1.LOCAL_TENANT_ID } });
|
|
113
|
-
if (count === 0) {
|
|
114
|
-
await this.tenantRepo.insert({
|
|
115
|
-
id: local_mode_constants_1.LOCAL_TENANT_ID,
|
|
116
|
-
name: local_mode_constants_1.LOCAL_USER_ID,
|
|
117
|
-
organization_name: 'Local',
|
|
118
|
-
email: local_mode_constants_1.LOCAL_EMAIL,
|
|
119
|
-
is_active: true,
|
|
120
|
-
});
|
|
121
|
-
await this.agentRepo.insert({
|
|
122
|
-
id: local_mode_constants_1.LOCAL_AGENT_ID,
|
|
123
|
-
name: local_mode_constants_1.LOCAL_AGENT_NAME,
|
|
124
|
-
description: 'Default local agent',
|
|
125
|
-
is_active: true,
|
|
126
|
-
tenant_id: local_mode_constants_1.LOCAL_TENANT_ID,
|
|
127
|
-
});
|
|
128
|
-
this.logger.log(`Created tenant/agent for local mode`);
|
|
129
|
-
}
|
|
130
|
-
const apiKey = this.readApiKeyFromConfig();
|
|
131
|
-
if (apiKey) {
|
|
132
|
-
await this.registerApiKey(apiKey);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
readApiKeyFromConfig() {
|
|
136
|
-
try {
|
|
137
|
-
const configPath = (0, path_1.join)((0, os_1.homedir)(), '.openclaw', 'manifest', 'config.json');
|
|
138
|
-
if (!(0, fs_1.existsSync)(configPath))
|
|
139
|
-
return null;
|
|
140
|
-
const data = JSON.parse((0, fs_1.readFileSync)(configPath, 'utf-8'));
|
|
141
|
-
return typeof data.apiKey === 'string' ? data.apiKey : null;
|
|
142
|
-
}
|
|
143
|
-
catch {
|
|
144
|
-
return null;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
async registerApiKey(apiKey) {
|
|
148
|
-
const prefix = (0, hash_util_1.keyPrefix)(apiKey);
|
|
149
|
-
const candidates = await this.agentKeyRepo.find({ where: { key_prefix: prefix } });
|
|
150
|
-
const alreadyExists = candidates.some((c) => (0, hash_util_1.verifyKey)(apiKey, c.key_hash));
|
|
151
|
-
if (alreadyExists)
|
|
152
|
-
return;
|
|
153
|
-
const hash = (0, hash_util_1.hashKey)(apiKey);
|
|
154
|
-
await this.agentKeyRepo.upsert({
|
|
155
|
-
id: 'local-otlp-key-001',
|
|
156
|
-
key: null,
|
|
157
|
-
key_hash: hash,
|
|
158
|
-
key_prefix: (0, hash_util_1.keyPrefix)(apiKey),
|
|
159
|
-
label: 'Local OTLP ingest key',
|
|
160
|
-
tenant_id: local_mode_constants_1.LOCAL_TENANT_ID,
|
|
161
|
-
agent_id: local_mode_constants_1.LOCAL_AGENT_ID,
|
|
162
|
-
is_active: true,
|
|
163
|
-
}, ['id']);
|
|
164
|
-
}
|
|
165
102
|
async fixupRoutingAgentIds() {
|
|
166
103
|
const orphanedProviders = await this.providerRepo.find({
|
|
167
104
|
where: { agent_id: (0, typeorm_2.IsNull)() },
|
|
168
105
|
});
|
|
106
|
+
const firstAgent = await this.agentRepo.findOne({ where: { is_active: true } });
|
|
107
|
+
if (!firstAgent)
|
|
108
|
+
return;
|
|
169
109
|
for (const row of orphanedProviders) {
|
|
170
|
-
row.agent_id =
|
|
110
|
+
row.agent_id = firstAgent.id;
|
|
171
111
|
await this.providerRepo.save(row);
|
|
172
112
|
}
|
|
173
113
|
const orphanedTiers = await this.tierRepo.find({
|
|
174
114
|
where: { agent_id: (0, typeorm_2.IsNull)() },
|
|
175
115
|
});
|
|
176
116
|
for (const row of orphanedTiers) {
|
|
177
|
-
row.agent_id =
|
|
117
|
+
row.agent_id = firstAgent.id;
|
|
178
118
|
await this.tierRepo.save(row);
|
|
179
119
|
}
|
|
180
120
|
if (orphanedProviders.length > 0 || orphanedTiers.length > 0) {
|
|
@@ -182,15 +122,18 @@ let LocalBootstrapService = LocalBootstrapService_1 = class LocalBootstrapServic
|
|
|
182
122
|
}
|
|
183
123
|
}
|
|
184
124
|
async recalculateTiersIfNeeded() {
|
|
125
|
+
const firstAgent = await this.agentRepo.findOne({ where: { is_active: true } });
|
|
126
|
+
if (!firstAgent)
|
|
127
|
+
return;
|
|
185
128
|
const activeProviders = await this.providerRepo.count({
|
|
186
|
-
where: { agent_id:
|
|
129
|
+
where: { agent_id: firstAgent.id, is_active: true },
|
|
187
130
|
});
|
|
188
131
|
if (activeProviders === 0)
|
|
189
132
|
return;
|
|
190
133
|
try {
|
|
191
134
|
const { TierAutoAssignService } = await Promise.resolve().then(() => __importStar(require('../routing/routing-core/tier-auto-assign.service')));
|
|
192
135
|
const autoAssign = this.moduleRef.get(TierAutoAssignService, { strict: false });
|
|
193
|
-
await autoAssign.recalculate(
|
|
136
|
+
await autoAssign.recalculate(firstAgent.id);
|
|
194
137
|
this.logger.log('Recalculated tier assignments on startup');
|
|
195
138
|
}
|
|
196
139
|
catch (err) {
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/* manifest-local — OpenClaw Self-Hosted LLM Router */
|
|
2
|
-
"use strict";var
|
|
3
|
-
Error: ${
|
|
4
|
-
This is a packaging error \u2014 please reinstall the manifest plugin.`);return}
|
|
5
|
-
The dashboard may not be accessible at http://${
|
|
6
|
-
Change it with: openclaw config set plugins.entries.manifest.config.port ${
|
|
7
|
-
Then restart the gateway.`):
|
|
2
|
+
"use strict";var f=require("fs"),l=require("path"),g=require("os"),u=(0,l.join)((0,g.homedir)(),".openclaw","manifest"),h=3e3;async function d(i,t){try{let n=await fetch(`http://${i}:${t}/api/v1/health`,{signal:AbortSignal.timeout(h)});if(!n.ok)return!1;let e=await n.json();return e!==null&&typeof e=="object"&&"status"in e&&e.status==="healthy"}catch{return!1}}function m(i,t,n,e){(0,f.existsSync)(u)||(0,f.mkdirSync)(u,{recursive:!0,mode:448});let a=(0,l.join)(u,"manifest.db");e.debug("[manifest] Starting embedded server...");let o;try{o=require("./server")}catch(r){let s=r instanceof Error?r.message:String(r);e.error(`[manifest] Failed to load embedded server.
|
|
3
|
+
Error: ${s}
|
|
4
|
+
This is a packaging error \u2014 please reinstall the manifest plugin.`);return}i.registerService({id:"manifest",start:async()=>{if(e.debug("[manifest] Service start callback invoked"),await d(n,t)){e.info(`[manifest] Reusing existing server at http://${n}:${t}`);return}try{await o.start({port:t,host:n,dbPath:a,quiet:!0}),await d(n,t)?(e.info(`[manifest] Dashboard -> http://${n}:${t}`),e.info(`[manifest] DB: ${a}`)):(e.warn??e.info)(`[manifest] Server started but health check failed.
|
|
5
|
+
The dashboard may not be accessible at http://${n}:${t}`)}catch(s){let c=s instanceof Error?s.message:String(s);c.includes("EADDRINUSE")||c.includes("address already in use")?await d(n,t)?e.info(`[manifest] Reusing existing server at http://${n}:${t}`):e.error(`[manifest] Port ${t} is already in use by another process.
|
|
6
|
+
Change it with: openclaw config set plugins.entries.manifest.config.port ${t+1}
|
|
7
|
+
Then restart the gateway.`):e.error(`[manifest] Failed to start local server: ${c}
|
|
8
8
|
Try reinstalling: openclaw plugins install manifest
|
|
9
|
-
Then restart: openclaw gateway restart`)}}})}module.exports={id:"manifest",name:"Manifest \u2014 Self-Hosted LLM Router",register(
|
|
9
|
+
Then restart: openclaw gateway restart`)}}})}module.exports={id:"manifest",name:"Manifest \u2014 Self-Hosted LLM Router",register(i){let t=i.logger||{info:(...r)=>console.log(...r),debug:()=>{},error:(...r)=>console.error(...r),warn:(...r)=>console.warn(...r)},n=i.pluginConfig||{},e=n&&typeof n=="object"&&"config"in n&&n.config!=null&&typeof n.config=="object"?n.config:n,a=typeof e.port=="number"&&e.port>0?e.port:2099,o=typeof e.host=="string"&&e.host.length>0?e.host:"127.0.0.1";t.info(`[manifest] Dashboard: http://${o}:${a}
|
|
10
10
|
The plugin starts an embedded server and registers manifest/auto as a model.
|
|
11
|
-
Open the dashboard to connect a provider and start routing.`),
|
|
11
|
+
Open the dashboard to connect a provider and start routing.`),m(i,a,o,t)}};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "manifest",
|
|
3
3
|
"name": "Manifest — Self-Hosted LLM Router",
|
|
4
|
-
"version": "5.33.
|
|
4
|
+
"version": "5.33.13",
|
|
5
5
|
"description": "Run the Manifest LLM router locally with SQLite. Zero-config dashboard included.",
|
|
6
6
|
"author": "MNFST Inc.",
|
|
7
7
|
"homepage": "https://manifest.build",
|
package/dist/server.js
CHANGED
|
@@ -55,7 +55,7 @@ async function start(options = {}) {
|
|
|
55
55
|
process.env['PORT'] = String(port);
|
|
56
56
|
process.env['BIND_ADDRESS'] = host;
|
|
57
57
|
process.env['MANIFEST_DB_PATH'] = dbPath;
|
|
58
|
-
process.env['NODE_ENV'] =
|
|
58
|
+
process.env['NODE_ENV'] = 'production';
|
|
59
59
|
process.env['MANIFEST_FRONTEND_DIR'] = (0, path_1.join)(__dirname, '..', 'public');
|
|
60
60
|
// Generate a random persistent secret for local mode
|
|
61
61
|
if (!process.env['BETTER_AUTH_SECRET']) {
|
package/openclaw.plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "manifest",
|
|
3
3
|
"name": "Manifest — Self-Hosted LLM Router",
|
|
4
|
-
"version": "5.33.
|
|
4
|
+
"version": "5.33.13",
|
|
5
5
|
"description": "Run the Manifest LLM router locally with SQLite. Zero-config dashboard included.",
|
|
6
6
|
"author": "MNFST Inc.",
|
|
7
7
|
"homepage": "https://manifest.build",
|