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
- await discovery.discoverAllForAgent(local_mode_constants_1.LOCAL_AGENT_ID);
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 = local_mode_constants_1.LOCAL_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 = local_mode_constants_1.LOCAL_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: local_mode_constants_1.LOCAL_AGENT_ID, is_active: true },
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(local_mode_constants_1.LOCAL_AGENT_ID);
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 s=require("fs"),c=require("path"),w=require("os"),$=require("crypto");var g=require("fs");function u(n){if(!(0,g.existsSync)(n))return{};try{let o=JSON.parse((0,g.readFileSync)(n,"utf-8"));return o&&typeof o=="object"&&!Array.isArray(o)?o:{}}catch{return{}}}var b="mnfst_",m=(0,c.join)((0,w.homedir)(),".openclaw","manifest"),y=(0,c.join)(m,"config.json"),k=(0,c.join)(m,".config.lock"),v=(0,c.join)((0,w.homedir)(),".openclaw"),S=(0,c.join)(v,"openclaw.json"),j=3e3;function E(){(0,s.existsSync)(m)||(0,s.mkdirSync)(m,{recursive:!0,mode:448})}function F(n){let o=null;try{o=(0,s.openSync)(k,"wx")}catch{return n()}try{return n()}finally{(0,s.closeSync)(o);try{(0,s.unlinkSync)(k)}catch{}}}function L(){return E(),F(()=>{if((0,s.existsSync)(y)){let t=u(y);if(t.apiKey&&t.apiKey.startsWith(b))return t.apiKey}let n=`${b}local_${(0,$.randomBytes)(24).toString("hex")}`,o=u(y);return(0,s.writeFileSync)(y,JSON.stringify({...o,apiKey:n},null,2),{mode:384}),n})}function h(n,o){let t=(0,c.dirname)(n);(0,s.existsSync)(t)||(0,s.mkdirSync)(t,{recursive:!0,mode:448});let i=`${n}.tmp.${process.pid}`;(0,s.writeFileSync)(i,JSON.stringify(o,null,2),{mode:384}),(0,s.renameSync)(i,n)}function x(n,o,t,i){let f={baseUrl:o,api:"openai-completions",apiKey:t,models:[{id:"auto",name:"auto"}]};try{let e=u(S);e.models||(e.models={}),e.models.providers||(e.models.providers={}),e.models.providers.manifest=f,e.agents||(e.agents={}),e.agents.defaults||(e.agents.defaults={}),e.agents.defaults.models||(e.agents.defaults.models={});let r=e.agents.defaults.models;Array.isArray(r)?r.includes("manifest/auto")||r.push("manifest/auto"):typeof r=="object"&&("manifest/auto"in r||(r["manifest/auto"]={})),h(S,e),i.debug("[manifest] Wrote provider config to openclaw.json")}catch(e){let r=e instanceof Error?e.message:String(e);i.debug(`[manifest] Could not write openclaw.json: ${r}`)}try{let e=(0,c.join)(v,"agents");if((0,s.existsSync)(e)){let r=(0,s.readdirSync)(e,{withFileTypes:!0}).filter(a=>a.isDirectory());for(let a of r){let l=(0,c.join)(e,a.name,"agent","models.json");if(!(0,s.existsSync)(l))continue;let d=u(l);d.providers?.manifest&&(delete d.providers.manifest,h(l,d))}}}catch{}try{if(n.config){n.config.models||(n.config.models={}),n.config.models.providers||(n.config.models.providers={}),n.config.models.providers.manifest=f,n.config.agents||(n.config.agents={}),n.config.agents.defaults||(n.config.agents.defaults={}),n.config.agents.defaults.models||(n.config.agents.defaults.models={});let e=n.config.agents.defaults.models;Array.isArray(e)?e.includes("manifest/auto")||e.push("manifest/auto"):typeof e=="object"&&("manifest/auto"in e||(e["manifest/auto"]={}))}}catch{}}function A(n,o){let t=(0,c.join)(v,"agents");if(!(0,s.existsSync)(t))return;let i={type:"api_key",provider:"manifest",key:n};try{let f=(0,s.readdirSync)(t,{withFileTypes:!0}).filter(e=>e.isDirectory());for(let e of f){let r=(0,c.join)(t,e.name,"agent","auth-profiles.json");if(!(0,s.existsSync)((0,c.dirname)(r)))continue;let a=u(r);a.version||(a.version=1),a.profiles||(a.profiles={});let l=a.profiles["manifest:default"];l&&l.key===n||(a.profiles["manifest:default"]=i,h(r,a))}}catch(f){let e=f instanceof Error?f.message:String(f);o.debug(`[manifest] Auth profile injection error: ${e}`)}}async function p(n,o){try{let t=await fetch(`http://${n}:${o}/api/v1/health`,{signal:AbortSignal.timeout(j)});if(!t.ok)return!1;let i=await t.json();return i!==null&&typeof i=="object"&&"status"in i&&i.status==="healthy"}catch{return!1}}function P(n,o,t,i){let f=L(),e=(0,c.join)(m,"manifest.db");i.debug("[manifest] Starting embedded server..."),x(n,`http://${t}:${o}/v1`,f,i),A(f,i);let r;try{r=require("./server")}catch(a){let l=a instanceof Error?a.message:String(a);i.error(`[manifest] Failed to load embedded server.
3
- Error: ${l}
4
- This is a packaging error \u2014 please reinstall the manifest plugin.`);return}n.registerService({id:"manifest",start:async()=>{if(i.debug("[manifest] Service start callback invoked"),await p(t,o)){i.info(`[manifest] Reusing existing server at http://${t}:${o}`);return}try{await r.start({port:o,host:t,dbPath:e,quiet:!0}),await p(t,o)?(i.info(`[manifest] Dashboard -> http://${t}:${o}`),i.info(`[manifest] DB: ${e}`)):(i.warn??i.info)(`[manifest] Server started but health check failed.
5
- The dashboard may not be accessible at http://${t}:${o}`)}catch(l){let d=l instanceof Error?l.message:String(l);d.includes("EADDRINUSE")||d.includes("address already in use")?await p(t,o)?i.info(`[manifest] Reusing existing server at http://${t}:${o}`):i.error(`[manifest] Port ${o} is already in use by another process.
6
- Change it with: openclaw config set plugins.entries.manifest.config.port ${o+1}
7
- Then restart the gateway.`):i.error(`[manifest] Failed to start local server: ${d}
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(n){let o=n.logger||{info:(...r)=>console.log(...r),debug:()=>{},error:(...r)=>console.error(...r),warn:(...r)=>console.warn(...r)},t=n.pluginConfig||{},i=t&&typeof t=="object"&&"config"in t&&t.config!=null&&typeof t.config=="object"?t.config:t,f=typeof i.port=="number"&&i.port>0?i.port:2099,e=typeof i.host=="string"&&i.host.length>0?i.host:"127.0.0.1";o.info(`[manifest] Dashboard: http://${e}:${f}
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.`),P(n,f,e,o)}};
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.12",
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'] = process.env['NODE_ENV'] || 'production';
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']) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "manifest",
3
3
  "name": "Manifest — Self-Hosted LLM Router",
4
- "version": "5.33.12",
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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "manifest",
3
- "version": "5.33.12",
3
+ "version": "5.33.13",
4
4
  "description": "Self-hosted Manifest LLM router with embedded server, SQLite database, and dashboard",
5
5
  "main": "dist/index.js",
6
6
  "license": "MIT",