manifest 5.29.2 → 5.29.3

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.
Files changed (29) hide show
  1. package/dist/backend/analytics/controllers/agents.controller.js +11 -2
  2. package/dist/index.js +1 -1
  3. package/dist/local-mode.js +1 -1
  4. package/dist/openclaw.plugin.json +1 -1
  5. package/dist/subscription.js +1 -1
  6. package/openclaw.plugin.json +1 -1
  7. package/package.json +1 -1
  8. package/public/assets/{Account-CF4wgeMs.js → Account-DgN0If8E.js} +1 -1
  9. package/public/assets/Limits-DacH-NDI.js +1 -0
  10. package/public/assets/{Login-5EhIDyx7.js → Login-BtP7FQbL.js} +1 -1
  11. package/public/assets/{MessageLog-7w6G7p64.js → MessageLog-DnZanm5d.js} +1 -1
  12. package/public/assets/{ModelPrices-Ci5Bj0jz.js → ModelPrices-DjwlOfGS.js} +1 -1
  13. package/public/assets/Overview-DNH071hw.js +1 -0
  14. package/public/assets/ProviderIcon-C2rOmoQI.js +1 -0
  15. package/public/assets/{Register-DcICkbfv.js → Register-lZkDe51g.js} +1 -1
  16. package/public/assets/{ResetPassword-DHFYOGoI.js → ResetPassword-CU2RJNS4.js} +1 -1
  17. package/public/assets/{Routing-DS0kfXk7.js → Routing-DR9NB8L7.js} +1 -1
  18. package/public/assets/Settings-DMXAXNDe.js +1 -0
  19. package/public/assets/{SocialButtons-GPyj4m9O.js → SocialButtons-B1Tjaa6o.js} +1 -1
  20. package/public/assets/index-Dz1pR1L8.js +2 -0
  21. package/public/assets/{model-display-Ccvhy_hh.js → model-display-DxUMzFUC.js} +1 -1
  22. package/public/assets/{overview-Dlu8R4Q3.js → overview-JbOqLfAe.js} +1 -1
  23. package/public/index.html +1 -1
  24. package/subscription-capabilities/index.js +10 -9
  25. package/public/assets/Limits-CJIMr5xp.js +0 -1
  26. package/public/assets/Overview-BJvJuFB4.js +0 -1
  27. package/public/assets/ProviderIcon-BpwSBcTb.js +0 -1
  28. package/public/assets/Settings-DAh81Avg.js +0 -1
  29. package/public/assets/index-9iQrgNF-.js +0 -2
@@ -34,12 +34,17 @@ let AgentsController = class AgentsController {
34
34
  apiKeyGenerator;
35
35
  config;
36
36
  tenantCache;
37
- constructor(timeseries, aggregation, apiKeyGenerator, config, tenantCache) {
37
+ cacheManager;
38
+ constructor(timeseries, aggregation, apiKeyGenerator, config, tenantCache, cacheManager) {
38
39
  this.timeseries = timeseries;
39
40
  this.aggregation = aggregation;
40
41
  this.apiKeyGenerator = apiKeyGenerator;
41
42
  this.config = config;
42
43
  this.tenantCache = tenantCache;
44
+ this.cacheManager = cacheManager;
45
+ }
46
+ agentListCacheKey(userId) {
47
+ return `${userId}:/api/v1/agents`;
43
48
  }
44
49
  async getAgents(user) {
45
50
  const tenantId = (await this.tenantCache.resolve(user.id)) ?? undefined;
@@ -67,6 +72,7 @@ let AgentsController = class AgentsController {
67
72
  }
68
73
  throw error;
69
74
  }
75
+ await this.cacheManager.del(this.agentListCacheKey(user.id));
70
76
  return {
71
77
  agent: { id: result.agentId, name: slug, display_name: displayName },
72
78
  apiKey: result.apiKey,
@@ -94,6 +100,7 @@ let AgentsController = class AgentsController {
94
100
  }
95
101
  const displayName = body.name.trim();
96
102
  await this.aggregation.renameAgent(user.id, agentName, slug, displayName);
103
+ await this.cacheManager.del(this.agentListCacheKey(user.id));
97
104
  return { renamed: true, name: slug, display_name: displayName };
98
105
  }
99
106
  async deleteAgent(user, agentName) {
@@ -101,6 +108,7 @@ let AgentsController = class AgentsController {
101
108
  throw new common_1.ForbiddenException('Cannot delete agents in local mode');
102
109
  }
103
110
  await this.aggregation.deleteAgent(user.id, agentName);
111
+ await this.cacheManager.del(this.agentListCacheKey(user.id));
104
112
  return { deleted: true };
105
113
  }
106
114
  };
@@ -157,10 +165,11 @@ __decorate([
157
165
  ], AgentsController.prototype, "deleteAgent", null);
158
166
  exports.AgentsController = AgentsController = __decorate([
159
167
  (0, common_1.Controller)('api/v1'),
168
+ __param(5, (0, common_1.Inject)(cache_manager_1.CACHE_MANAGER)),
160
169
  __metadata("design:paramtypes", [timeseries_queries_service_1.TimeseriesQueriesService,
161
170
  aggregation_service_1.AggregationService,
162
171
  api_key_service_1.ApiKeyGeneratorService,
163
172
  config_1.ConfigService,
164
- tenant_cache_service_1.TenantCacheService])
173
+ tenant_cache_service_1.TenantCacheService, Object])
165
174
  ], AgentsController);
166
175
  //# sourceMappingURL=agents.controller.js.map
package/dist/index.js CHANGED
@@ -16,7 +16,7 @@ To resolve the conflict:`,(0,ri.getConflictResolutionRecipe)(u,r))),c=a):QM.diag
16
16
  openclaw config set plugins.entries.manifest.config.endpoint https://app.manifest.build/otlp`:`Invalid apiKey format. Keys must start with '${Qe}'. Fix it via:
17
17
  openclaw config set manifest.apiKey ${Qe}YOUR_KEY`:`Missing apiKey. Set it via:
18
18
  openclaw config set manifest.apiKey ${Qe}YOUR_KEY
19
- or export MANIFEST_API_KEY=${Qe}YOUR_KEY`}var na=ve(sM()),oa=ve(di()),wI=ve(LI()),BI=ve(VI()),GI=ve(Oo());m();var en=null,tn=null,gc=null,Lc=null;function HI(o,r){let i=new GI.Resource({"service.name":fr.SERVICE_NAME,"service.version":"5.29.2","manifest.plugin":"true"}),c=o.apiKey?{Authorization:`Bearer ${o.apiKey}`}:{},a=new wI.OTLPTraceExporter({url:`${o.endpoint}/v1/traces`,headers:c});en=new na.BasicTracerProvider({resource:i,spanProcessors:[new na.BatchSpanProcessor(a,{scheduledDelayMillis:5e3,maxQueueSize:2048,maxExportBatchSize:512})]}),en.register(),r.debug(`[manifest] Trace exporter -> ${o.endpoint}/v1/traces`);let u=new BI.OTLPMetricExporter({url:`${o.endpoint}/v1/metrics`,headers:c}),t=o.devMode||o.mode==="local"?xc.METRICS_INTERVAL_MS:fr.METRICS_INTERVAL_MS;return tn=new oa.MeterProvider({resource:i,readers:[new oa.PeriodicExportingMetricReader({exporter:u,exportIntervalMillis:t})]}),Mt.setGlobalMeterProvider(tn),r.debug(`[manifest] Metrics exporter -> ${o.endpoint}/v1/metrics (interval=${t}ms)`),gc=Be.getTracer("manifest-plugin","5.29.2"),Lc=Mt.getMeter("manifest-plugin","5.29.2"),{tracer:gc,meter:Lc}}async function kI(o){o.info("[manifest] Shutting down telemetry..."),en&&(await en.shutdown(),en=null),tn&&(await tn.shutdown(),tn=null),gc=null,Lc=null,o.info("[manifest] Telemetry shut down")}m();var g5=5,FI=30*60*1e3,L5=3e3,I5=5*60*1e3,x5=new Set(["system","developer"]),C5=10,rn=new Map,YI=!1;function b5(){if(YI)return;YI=!0;let o=setInterval(()=>{let r=Date.now();for(let[i,c]of rn)r-c.lastUpdated>FI&&rn.delete(i)},I5);typeof o=="object"&&"unref"in o&&o.unref()}async function KI(o,r,i,c){b5();let u=`${o.endpoint.replace(/\/otlp(\/v1)?\/?$/,"")}/api/v1/routing/resolve`;try{if(!r||!Array.isArray(r)||r.length===0)return c.debug("[manifest] Routing resolve: no messages, skipping"),null;let t=r.filter(C=>C&&typeof C=="object"&&"role"in C&&!x5.has(C.role)).slice(-C5).map(C=>({role:C.role,content:C.content}));if(t.length===0)return c.debug("[manifest] Routing resolve: no scorable messages, skipping"),null;let e=rn.get(i),n=e&&Date.now()-e.lastUpdated<FI?e.tiers:void 0,s={messages:t};n&&(s.recentTiers=n);let l={"Content-Type":"application/json"};o.apiKey&&(l.Authorization=`Bearer ${o.apiKey}`);let E=await fetch(u,{method:"POST",headers:l,body:JSON.stringify(s),signal:AbortSignal.timeout(L5)});if(!E.ok)return c.debug(`[manifest] Routing resolve returned ${E.status}`),null;let A=await E.json();if(!A.model)return c.debug(`[manifest] Routing resolve: no model for tier=${A.tier}`),null;let g=rn.get(i);return g?(g.tiers=[A.tier,...g.tiers].slice(0,g5),g.lastUpdated=Date.now()):rn.set(i,{tiers:[A.tier],lastUpdated:Date.now()}),c.debug(`[manifest] Routing resolved: tier=${A.tier} model=${A.model} provider=${A.provider}`),{tier:A.tier,model:A.model,provider:A.provider??"unknown",reason:A.reason??"",auth_type:A.auth_type??"api_key"}}catch(t){let e=t instanceof Error?t.message:String(t);return c.debug(`[manifest] Routing resolve failed (${e})`),null}}function jI(o,r,i){if(typeof o.registerProvider!="function"){i.debug("[manifest] registerProvider not available, skipping provider registration");return}let c=r.endpoint.replace(/\/otlp(\/v1)?\/?$/,"");try{o.registerProvider({id:"manifest",name:"Manifest Router",label:"Manifest Router",api:"openai-completions",baseUrl:c,apiKey:r.apiKey,models:["auto"]}),i.info("[manifest] Registered as OpenAI-compatible provider (proxy mode)")}catch(a){let u=a instanceof Error?a.message:String(a);i.debug(`[manifest] registerProvider failed (${u})`)}}var _r=new Map,qI,WI,zI,JI,U5,XI,$I,QI,ZI;function ex(o){qI=o.createCounter(Oe.LLM_REQUESTS,{description:"Total LLM inference requests"}),WI=o.createCounter(Oe.LLM_TOKENS_INPUT,{description:"Total input tokens sent to LLM"}),zI=o.createCounter(Oe.LLM_TOKENS_OUTPUT,{description:"Total output tokens from LLM"}),JI=o.createCounter(Oe.LLM_TOKENS_CACHE_READ,{description:"Total cache-read tokens"}),U5=o.createHistogram(Oe.LLM_DURATION,{description:"LLM request duration in ms",unit:"ms"}),XI=o.createCounter(Oe.TOOL_CALLS,{description:"Total tool invocations"}),$I=o.createCounter(Oe.TOOL_ERRORS,{description:"Total tool errors"}),QI=o.createHistogram(Oe.TOOL_DURATION,{description:"Tool execution duration in ms",unit:"ms"}),ZI=o.createCounter(Oe.MESSAGES_RECEIVED,{description:"Total messages received from users"})}function ia(o,r,i){typeof o.on=="function"?o.on(r,i):typeof o.registerHook=="function"&&o.registerHook(r,i)}function tx(o,r,i,c){ia(o,"message_received",a=>{let u=a.sessionKey||a.session?.key||`agent:${a.agent||"main"}:main`,t=a.channel||"unknown",e=r.startSpan(un.REQUEST,{kind:Ve.SERVER,attributes:{[b.SESSION_KEY]:u,[b.CHANNEL]:t}});_r.set(u,{root:e}),ZI.add(1,{[b.CHANNEL]:t}),c.debug(`[manifest] Root span started for session=${u}`)}),ia(o,"before_agent_start",a=>{let u=a.sessionKey||a.session?.key||`agent:${a.agent||"main"}:main`,t=a.agent||"main",e=_r.get(u),n=e?.root?Be.setSpan(we.active(),e.root):we.active(),s=r.startSpan(un.AGENT_TURN,{kind:Ve.INTERNAL,attributes:{[b.AGENT_NAME]:t,[b.SESSION_KEY]:u}},n);e?e.turn=s:_r.set(u,{root:s,turn:s}),c.debug(`[manifest] Agent turn started: agent=${t}, session=${u}`)}),ia(o,"tool_result_persist",a=>{let u=a.toolName||a.tool||"unknown",t=a.durationMs||0,e=a.error==null,n=a.sessionKey||"unknown",s=_r.get(n),l=s?.turn?Be.setSpan(we.active(),s.turn):we.active(),E=r.startSpan(`${un.TOOL_PREFIX}${u}`,{kind:Ve.INTERNAL,attributes:{[b.TOOL_NAME]:u,[b.TOOL_SUCCESS]:String(e),[b.SESSION_KEY]:n}},l);e||(E.setStatus({code:rt.ERROR,message:a.error?.message||"Tool execution failed"}),$I.add(1,{[b.TOOL_NAME]:u})),E.end(),XI.add(1,{[b.TOOL_NAME]:u}),QI.record(t,{[b.TOOL_NAME]:u})}),ia(o,"agent_end",async a=>{let u=a.sessionKey||a.session?.key||`agent:${a.agent||"main"}:main`,t=a.messages||[],e=[...t].reverse().find(k=>k.role==="assistant"&&k.usage),n=e?.model||a.model||"unknown",s=e?.provider||a.provider||"unknown",l=e?.usage||a.usage||{},E=l.input||l.inputTokens||l.prompt_tokens||l.promptTokens||0,A=l.output||l.outputTokens||l.completion_tokens||l.completionTokens||0,g=l.prompt_tokens_details||{},C=l.cacheRead||l.cacheReadTokens||l.cache_read_tokens||g.cached_tokens||0,nn=l.cacheWrite||l.cacheWriteTokens||l.cache_creation_tokens||0,Le=n,Tr=s,$e=null,mt=null;if(Le==="auto"){let k=await KI(i,t,u,c);k&&(Le=k.model,Tr=k.provider,$e=k.tier,mt=k.reason||null)}let ht=[...t].reverse().find(k=>k?.role==="user");(ht?typeof ht.content=="string"?ht.content.includes("HEARTBEAT_OK"):Array.isArray(ht.content)?ht.content.some(k=>k.type==="text"&&typeof k.text=="string"&&k.text.includes("HEARTBEAT_OK")):!1:!1)&&(mt="heartbeat",$e="simple");let Ae=_r.get(u);if(Ae?.turn){if(Ae.turn.setAttributes({[b.MODEL]:Le,[b.PROVIDER]:Tr,[b.INPUT_TOKENS]:E,[b.OUTPUT_TOKENS]:A,[b.CACHE_READ_TOKENS]:C,[b.CACHE_WRITE_TOKENS]:nn}),$e&&Ae.turn.setAttribute(b.ROUTING_TIER,$e),mt&&Ae.turn.setAttribute(b.ROUTING_REASON,mt),a.success===!1||a.error!=null){let k=a.error?.message||a.errorMessage||"Agent turn failed";Ae.turn.setStatus({code:rt.ERROR,message:typeof k=="string"?k.slice(0,500):String(k)})}Ae.turn.end()}Ae?.root&&Ae.root!==Ae.turn&&Ae.root.end(),_r.delete(u);let on={[b.MODEL]:Le,[b.PROVIDER]:Tr};qI.add(1,on),WI.add(E,on),zI.add(A,on),C>0&&JI.add(C,on),c.debug(`[manifest] agent_end tokens: in=${E}, out=${A}, cache=${C}`),c.debug(`[manifest] Trace completed for session=${u}`)}),c.debug("[manifest] All hooks registered")}async function Ot(o){let r=o.endpoint.replace(/\/otlp(\/v1)?\/?$/,""),i={endpointReachable:!1,authValid:!1,agentName:null,error:null};try{let c=await fetch(`${r}/api/v1/health`,{signal:AbortSignal.timeout(5e3)});if(!c.ok)return i.error=`Health endpoint returned ${c.status}`,i;i.endpointReachable=!0}catch(c){let a=c instanceof Error?c.message:String(c);return i.error=`Cannot reach endpoint: ${a}`,i}try{let c=o.apiKey?{Authorization:`Bearer ${o.apiKey}`}:{},a=await fetch(`${r}/api/v1/agent/usage?range=24h`,{headers:c,signal:AbortSignal.timeout(5e3)});if(a.status===401||a.status===403)return i.error="API key rejected \u2014 check your mnfst_ key is correct",i;if(!a.ok)return i.error=`Usage endpoint returned ${a.status}`,i;i.authValid=!0;let u=await a.json();u&&typeof u.agentName=="string"&&(i.agentName=u.agentName)}catch(c){let a=c instanceof Error?c.message:String(c);return i.error=`Auth check failed: ${a}`,i}return i}var aa={today:"24h",week:"7d",month:"30d"};async function ua(o,r,i,c){let a=`${o}${r}`;try{let u=i?{Authorization:`Bearer ${i}`}:{},t=await fetch(a,{headers:u});if(!t.ok)return{content:[{type:"text",text:JSON.stringify({error:`API returned ${t.status}`})}]};let e=await t.json();return{content:[{type:"text",text:JSON.stringify(e)}]}}catch(u){let t=u instanceof Error?u.message:String(u);return c.error(`[manifest] API call failed: ${t}`),{content:[{type:"text",text:JSON.stringify({error:t})}]}}}function rx(o){try{let r=JSON.parse(o.content[0].text);return r.error?{error:r.error}:{result:r}}catch{return{result:o.content[0].text}}}function nx(o,r,i){let c=r.endpoint.replace(/\/otlp(\/v1)?\/?$/,"");o.registerTool({name:"manifest_usage",description:"Get token consumption for this agent: total, input, output, cache-read tokens, and action count. Use when the user asks about token usage or consumption.",parameters:{type:"object",properties:{period:{type:"string",enum:["today","week","month"],default:"today",description:"Time period"}}},async handler(a){let u=aa[a.period||"today"]||"24h";return rx(await ua(c,`/api/v1/agent/usage?range=${u}`,r.apiKey,i))},async execute(a,u){let t=aa[u.period||"today"]||"24h";return ua(c,`/api/v1/agent/usage?range=${t}`,r.apiKey,i)}},{optional:!0}),o.registerTool({name:"manifest_costs",description:"Get cost breakdown for this agent in USD, grouped by model. Use when the user asks about costs, spending, or money burned.",parameters:{type:"object",properties:{period:{type:"string",enum:["today","week","month"],default:"week",description:"Time period"}}},async handler(a){let u=aa[a.period||"week"]||"7d";return rx(await ua(c,`/api/v1/agent/costs?range=${u}`,r.apiKey,i))},async execute(a,u){let t=aa[u.period||"week"]||"7d";return ua(c,`/api/v1/agent/costs?range=${t}`,r.apiKey,i)}},{optional:!0}),o.registerTool({name:"manifest_health",description:"Check whether Manifest observability is connected and working. Use when the user asks if monitoring is set up or wants a connectivity test.",parameters:{type:"object",properties:{}},async handler(){let a=await Ot(r);return a.error?{error:a.error}:{result:{endpointReachable:a.endpointReachable,authValid:a.authValid,agentName:a.agentName,status:"ok"}}},async execute(){let a=await Ot(r);return a.error?{content:[{type:"text",text:JSON.stringify({error:a.error})}]}:{content:[{type:"text",text:JSON.stringify({endpointReachable:a.endpointReachable,authValid:a.authValid,agentName:a.agentName,status:"ok"})}]}}},{optional:!0}),i.debug("[manifest] Registered agent tools: manifest_usage, manifest_costs, manifest_health")}function ox(o,r,i){if(typeof o.registerCommand!="function"){i.debug("[manifest] registerCommand not available, skipping /manifest command");return}let c=async()=>{try{let a=await Ot(r),u=[`Mode: ${r.mode}`,`Dev mode: ${r.devMode?"yes":"no"}`,`Endpoint reachable: ${a.endpointReachable?"yes":"no"}`,`Auth valid: ${a.authValid?"yes":"no"}`];return a.agentName&&u.push(`Agent: ${a.agentName}`),a.error&&u.push(`Error: ${a.error}`),u.join(`
19
+ or export MANIFEST_API_KEY=${Qe}YOUR_KEY`}var na=ve(sM()),oa=ve(di()),wI=ve(LI()),BI=ve(VI()),GI=ve(Oo());m();var en=null,tn=null,gc=null,Lc=null;function HI(o,r){let i=new GI.Resource({"service.name":fr.SERVICE_NAME,"service.version":"5.29.3","manifest.plugin":"true"}),c=o.apiKey?{Authorization:`Bearer ${o.apiKey}`}:{},a=new wI.OTLPTraceExporter({url:`${o.endpoint}/v1/traces`,headers:c});en=new na.BasicTracerProvider({resource:i,spanProcessors:[new na.BatchSpanProcessor(a,{scheduledDelayMillis:5e3,maxQueueSize:2048,maxExportBatchSize:512})]}),en.register(),r.debug(`[manifest] Trace exporter -> ${o.endpoint}/v1/traces`);let u=new BI.OTLPMetricExporter({url:`${o.endpoint}/v1/metrics`,headers:c}),t=o.devMode||o.mode==="local"?xc.METRICS_INTERVAL_MS:fr.METRICS_INTERVAL_MS;return tn=new oa.MeterProvider({resource:i,readers:[new oa.PeriodicExportingMetricReader({exporter:u,exportIntervalMillis:t})]}),Mt.setGlobalMeterProvider(tn),r.debug(`[manifest] Metrics exporter -> ${o.endpoint}/v1/metrics (interval=${t}ms)`),gc=Be.getTracer("manifest-plugin","5.29.3"),Lc=Mt.getMeter("manifest-plugin","5.29.3"),{tracer:gc,meter:Lc}}async function kI(o){o.info("[manifest] Shutting down telemetry..."),en&&(await en.shutdown(),en=null),tn&&(await tn.shutdown(),tn=null),gc=null,Lc=null,o.info("[manifest] Telemetry shut down")}m();var g5=5,FI=30*60*1e3,L5=3e3,I5=5*60*1e3,x5=new Set(["system","developer"]),C5=10,rn=new Map,YI=!1;function b5(){if(YI)return;YI=!0;let o=setInterval(()=>{let r=Date.now();for(let[i,c]of rn)r-c.lastUpdated>FI&&rn.delete(i)},I5);typeof o=="object"&&"unref"in o&&o.unref()}async function KI(o,r,i,c){b5();let u=`${o.endpoint.replace(/\/otlp(\/v1)?\/?$/,"")}/api/v1/routing/resolve`;try{if(!r||!Array.isArray(r)||r.length===0)return c.debug("[manifest] Routing resolve: no messages, skipping"),null;let t=r.filter(C=>C&&typeof C=="object"&&"role"in C&&!x5.has(C.role)).slice(-C5).map(C=>({role:C.role,content:C.content}));if(t.length===0)return c.debug("[manifest] Routing resolve: no scorable messages, skipping"),null;let e=rn.get(i),n=e&&Date.now()-e.lastUpdated<FI?e.tiers:void 0,s={messages:t};n&&(s.recentTiers=n);let l={"Content-Type":"application/json"};o.apiKey&&(l.Authorization=`Bearer ${o.apiKey}`);let E=await fetch(u,{method:"POST",headers:l,body:JSON.stringify(s),signal:AbortSignal.timeout(L5)});if(!E.ok)return c.debug(`[manifest] Routing resolve returned ${E.status}`),null;let A=await E.json();if(!A.model)return c.debug(`[manifest] Routing resolve: no model for tier=${A.tier}`),null;let g=rn.get(i);return g?(g.tiers=[A.tier,...g.tiers].slice(0,g5),g.lastUpdated=Date.now()):rn.set(i,{tiers:[A.tier],lastUpdated:Date.now()}),c.debug(`[manifest] Routing resolved: tier=${A.tier} model=${A.model} provider=${A.provider}`),{tier:A.tier,model:A.model,provider:A.provider??"unknown",reason:A.reason??"",auth_type:A.auth_type??"api_key"}}catch(t){let e=t instanceof Error?t.message:String(t);return c.debug(`[manifest] Routing resolve failed (${e})`),null}}function jI(o,r,i){if(typeof o.registerProvider!="function"){i.debug("[manifest] registerProvider not available, skipping provider registration");return}let c=r.endpoint.replace(/\/otlp(\/v1)?\/?$/,"");try{o.registerProvider({id:"manifest",name:"Manifest Router",label:"Manifest Router",api:"openai-completions",baseUrl:c,apiKey:r.apiKey,models:["auto"]}),i.info("[manifest] Registered as OpenAI-compatible provider (proxy mode)")}catch(a){let u=a instanceof Error?a.message:String(a);i.debug(`[manifest] registerProvider failed (${u})`)}}var _r=new Map,qI,WI,zI,JI,U5,XI,$I,QI,ZI;function ex(o){qI=o.createCounter(Oe.LLM_REQUESTS,{description:"Total LLM inference requests"}),WI=o.createCounter(Oe.LLM_TOKENS_INPUT,{description:"Total input tokens sent to LLM"}),zI=o.createCounter(Oe.LLM_TOKENS_OUTPUT,{description:"Total output tokens from LLM"}),JI=o.createCounter(Oe.LLM_TOKENS_CACHE_READ,{description:"Total cache-read tokens"}),U5=o.createHistogram(Oe.LLM_DURATION,{description:"LLM request duration in ms",unit:"ms"}),XI=o.createCounter(Oe.TOOL_CALLS,{description:"Total tool invocations"}),$I=o.createCounter(Oe.TOOL_ERRORS,{description:"Total tool errors"}),QI=o.createHistogram(Oe.TOOL_DURATION,{description:"Tool execution duration in ms",unit:"ms"}),ZI=o.createCounter(Oe.MESSAGES_RECEIVED,{description:"Total messages received from users"})}function ia(o,r,i){typeof o.on=="function"?o.on(r,i):typeof o.registerHook=="function"&&o.registerHook(r,i)}function tx(o,r,i,c){ia(o,"message_received",a=>{let u=a.sessionKey||a.session?.key||`agent:${a.agent||"main"}:main`,t=a.channel||"unknown",e=r.startSpan(un.REQUEST,{kind:Ve.SERVER,attributes:{[b.SESSION_KEY]:u,[b.CHANNEL]:t}});_r.set(u,{root:e}),ZI.add(1,{[b.CHANNEL]:t}),c.debug(`[manifest] Root span started for session=${u}`)}),ia(o,"before_agent_start",a=>{let u=a.sessionKey||a.session?.key||`agent:${a.agent||"main"}:main`,t=a.agent||"main",e=_r.get(u),n=e?.root?Be.setSpan(we.active(),e.root):we.active(),s=r.startSpan(un.AGENT_TURN,{kind:Ve.INTERNAL,attributes:{[b.AGENT_NAME]:t,[b.SESSION_KEY]:u}},n);e?e.turn=s:_r.set(u,{root:s,turn:s}),c.debug(`[manifest] Agent turn started: agent=${t}, session=${u}`)}),ia(o,"tool_result_persist",a=>{let u=a.toolName||a.tool||"unknown",t=a.durationMs||0,e=a.error==null,n=a.sessionKey||"unknown",s=_r.get(n),l=s?.turn?Be.setSpan(we.active(),s.turn):we.active(),E=r.startSpan(`${un.TOOL_PREFIX}${u}`,{kind:Ve.INTERNAL,attributes:{[b.TOOL_NAME]:u,[b.TOOL_SUCCESS]:String(e),[b.SESSION_KEY]:n}},l);e||(E.setStatus({code:rt.ERROR,message:a.error?.message||"Tool execution failed"}),$I.add(1,{[b.TOOL_NAME]:u})),E.end(),XI.add(1,{[b.TOOL_NAME]:u}),QI.record(t,{[b.TOOL_NAME]:u})}),ia(o,"agent_end",async a=>{let u=a.sessionKey||a.session?.key||`agent:${a.agent||"main"}:main`,t=a.messages||[],e=[...t].reverse().find(k=>k.role==="assistant"&&k.usage),n=e?.model||a.model||"unknown",s=e?.provider||a.provider||"unknown",l=e?.usage||a.usage||{},E=l.input||l.inputTokens||l.prompt_tokens||l.promptTokens||0,A=l.output||l.outputTokens||l.completion_tokens||l.completionTokens||0,g=l.prompt_tokens_details||{},C=l.cacheRead||l.cacheReadTokens||l.cache_read_tokens||g.cached_tokens||0,nn=l.cacheWrite||l.cacheWriteTokens||l.cache_creation_tokens||0,Le=n,Tr=s,$e=null,mt=null;if(Le==="auto"){let k=await KI(i,t,u,c);k&&(Le=k.model,Tr=k.provider,$e=k.tier,mt=k.reason||null)}let ht=[...t].reverse().find(k=>k?.role==="user");(ht?typeof ht.content=="string"?ht.content.includes("HEARTBEAT_OK"):Array.isArray(ht.content)?ht.content.some(k=>k.type==="text"&&typeof k.text=="string"&&k.text.includes("HEARTBEAT_OK")):!1:!1)&&(mt="heartbeat",$e="simple");let Ae=_r.get(u);if(Ae?.turn){if(Ae.turn.setAttributes({[b.MODEL]:Le,[b.PROVIDER]:Tr,[b.INPUT_TOKENS]:E,[b.OUTPUT_TOKENS]:A,[b.CACHE_READ_TOKENS]:C,[b.CACHE_WRITE_TOKENS]:nn}),$e&&Ae.turn.setAttribute(b.ROUTING_TIER,$e),mt&&Ae.turn.setAttribute(b.ROUTING_REASON,mt),a.success===!1||a.error!=null){let k=a.error?.message||a.errorMessage||"Agent turn failed";Ae.turn.setStatus({code:rt.ERROR,message:typeof k=="string"?k.slice(0,500):String(k)})}Ae.turn.end()}Ae?.root&&Ae.root!==Ae.turn&&Ae.root.end(),_r.delete(u);let on={[b.MODEL]:Le,[b.PROVIDER]:Tr};qI.add(1,on),WI.add(E,on),zI.add(A,on),C>0&&JI.add(C,on),c.debug(`[manifest] agent_end tokens: in=${E}, out=${A}, cache=${C}`),c.debug(`[manifest] Trace completed for session=${u}`)}),c.debug("[manifest] All hooks registered")}async function Ot(o){let r=o.endpoint.replace(/\/otlp(\/v1)?\/?$/,""),i={endpointReachable:!1,authValid:!1,agentName:null,error:null};try{let c=await fetch(`${r}/api/v1/health`,{signal:AbortSignal.timeout(5e3)});if(!c.ok)return i.error=`Health endpoint returned ${c.status}`,i;i.endpointReachable=!0}catch(c){let a=c instanceof Error?c.message:String(c);return i.error=`Cannot reach endpoint: ${a}`,i}try{let c=o.apiKey?{Authorization:`Bearer ${o.apiKey}`}:{},a=await fetch(`${r}/api/v1/agent/usage?range=24h`,{headers:c,signal:AbortSignal.timeout(5e3)});if(a.status===401||a.status===403)return i.error="API key rejected \u2014 check your mnfst_ key is correct",i;if(!a.ok)return i.error=`Usage endpoint returned ${a.status}`,i;i.authValid=!0;let u=await a.json();u&&typeof u.agentName=="string"&&(i.agentName=u.agentName)}catch(c){let a=c instanceof Error?c.message:String(c);return i.error=`Auth check failed: ${a}`,i}return i}var aa={today:"24h",week:"7d",month:"30d"};async function ua(o,r,i,c){let a=`${o}${r}`;try{let u=i?{Authorization:`Bearer ${i}`}:{},t=await fetch(a,{headers:u});if(!t.ok)return{content:[{type:"text",text:JSON.stringify({error:`API returned ${t.status}`})}]};let e=await t.json();return{content:[{type:"text",text:JSON.stringify(e)}]}}catch(u){let t=u instanceof Error?u.message:String(u);return c.error(`[manifest] API call failed: ${t}`),{content:[{type:"text",text:JSON.stringify({error:t})}]}}}function rx(o){try{let r=JSON.parse(o.content[0].text);return r.error?{error:r.error}:{result:r}}catch{return{result:o.content[0].text}}}function nx(o,r,i){let c=r.endpoint.replace(/\/otlp(\/v1)?\/?$/,"");o.registerTool({name:"manifest_usage",description:"Get token consumption for this agent: total, input, output, cache-read tokens, and action count. Use when the user asks about token usage or consumption.",parameters:{type:"object",properties:{period:{type:"string",enum:["today","week","month"],default:"today",description:"Time period"}}},async handler(a){let u=aa[a.period||"today"]||"24h";return rx(await ua(c,`/api/v1/agent/usage?range=${u}`,r.apiKey,i))},async execute(a,u){let t=aa[u.period||"today"]||"24h";return ua(c,`/api/v1/agent/usage?range=${t}`,r.apiKey,i)}},{optional:!0}),o.registerTool({name:"manifest_costs",description:"Get cost breakdown for this agent in USD, grouped by model. Use when the user asks about costs, spending, or money burned.",parameters:{type:"object",properties:{period:{type:"string",enum:["today","week","month"],default:"week",description:"Time period"}}},async handler(a){let u=aa[a.period||"week"]||"7d";return rx(await ua(c,`/api/v1/agent/costs?range=${u}`,r.apiKey,i))},async execute(a,u){let t=aa[u.period||"week"]||"7d";return ua(c,`/api/v1/agent/costs?range=${t}`,r.apiKey,i)}},{optional:!0}),o.registerTool({name:"manifest_health",description:"Check whether Manifest observability is connected and working. Use when the user asks if monitoring is set up or wants a connectivity test.",parameters:{type:"object",properties:{}},async handler(){let a=await Ot(r);return a.error?{error:a.error}:{result:{endpointReachable:a.endpointReachable,authValid:a.authValid,agentName:a.agentName,status:"ok"}}},async execute(){let a=await Ot(r);return a.error?{content:[{type:"text",text:JSON.stringify({error:a.error})}]}:{content:[{type:"text",text:JSON.stringify({endpointReachable:a.endpointReachable,authValid:a.authValid,agentName:a.agentName,status:"ok"})}]}}},{optional:!0}),i.debug("[manifest] Registered agent tools: manifest_usage, manifest_costs, manifest_health")}function ox(o,r,i){if(typeof o.registerCommand!="function"){i.debug("[manifest] registerCommand not available, skipping /manifest command");return}let c=async()=>{try{let a=await Ot(r),u=[`Mode: ${r.mode}`,`Dev mode: ${r.devMode?"yes":"no"}`,`Endpoint reachable: ${a.endpointReachable?"yes":"no"}`,`Auth valid: ${a.authValid?"yes":"no"}`];return a.agentName&&u.push(`Agent: ${a.agentName}`),a.error&&u.push(`Error: ${a.error}`),u.join(`
20
20
  `)}catch(a){return`Manifest status check failed: ${a instanceof Error?a.message:String(a)}`}};o.registerCommand({name:"manifest",description:"Show Manifest plugin status and connection info",async handler(){return c()},async execute(){let a=await c();return{text:a,content:[{type:"text",text:a}]}}}),i.debug("[manifest] Registered /manifest command")}var Er=require("./local-mode"),sa=require("./subscription");module.exports={id:"manifest",name:"Manifest \u2014 Agent Observability",register(o){let r=o.logger||{info:(...A)=>console.log(...A),debug:()=>{},error:(...A)=>console.error(...A),warn:(...A)=>console.warn(...A)},{config:i,_deprecatedDevMode:c}=Cc(o.pluginConfig);if(c&&r.warn?.(`[manifest] mode: "dev" is deprecated. Use mode: "cloud" with devMode: true instead.
21
21
  openclaw config set plugins.entries.manifest.config.mode cloud
22
22
  openclaw config set plugins.entries.manifest.config.devMode true`),i.mode==="local"){(0,Er.registerLocalMode)(o,i,r);return}let a=bc(i);if(a){!i.devMode&&i.mode==="cloud"&&!i.apiKey?r.info(`[manifest] Cloud mode requires an API key: