manifest 5.9.4 → 5.9.5
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/dist/index.js +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -16,13 +16,13 @@ To resolve the conflict:`,(0,ti.getConflictResolutionRecipe)(u,r))),c=a):ng.diag
|
|
|
16
16
|
openclaw config set plugins.entries.manifest.config.endpoint https://app.manifest.build/otlp`:`Invalid apiKey format. Keys must start with '${Ie}'. Fix it via:
|
|
17
17
|
openclaw config set manifest.apiKey ${Ie}YOUR_KEY`:`Missing apiKey. Set it via:
|
|
18
18
|
openclaw config set manifest.apiKey ${Ie}YOUR_KEY
|
|
19
|
-
or export MANIFEST_API_KEY=${Ie}YOUR_KEY`}var ra=Oe(EM()),na=Oe(fi()),YI=Oe(UI()),FI=Oe(kI()),KI=Oe(vo());m();var Qr=null,Zr=null,Cc=null,xc=null;function oa(o,r){let i=new KI.Resource({"service.name":o.serviceName,"service.version":"5.9.4","manifest.plugin":"true"}),c={Authorization:`Bearer ${o.apiKey}`},a=new YI.OTLPTraceExporter({url:`${o.endpoint}/v1/traces`,headers:c});Qr=new ra.BasicTracerProvider({resource:i,spanProcessors:[new ra.BatchSpanProcessor(a,{scheduledDelayMillis:5e3,maxQueueSize:2048,maxExportBatchSize:512})]}),Qr.register(),r.debug(`[manifest] Trace exporter -> ${o.endpoint}/v1/traces`);let u=new FI.OTLPMetricExporter({url:`${o.endpoint}/v1/metrics`,headers:c});return Zr=new na.MeterProvider({resource:i,readers:[new na.PeriodicExportingMetricReader({exporter:u,exportIntervalMillis:o.metricsIntervalMs})]}),gt.setGlobalMeterProvider(Zr),r.debug(`[manifest] Metrics exporter -> ${o.endpoint}/v1/metrics (interval=${o.metricsIntervalMs}ms)`),Cc=Ye.getTracer("manifest-plugin","5.9.4"),xc=gt.getMeter("manifest-plugin","5.9.4"),{tracer:Cc,meter:xc}}async function ia(o){o.info("[manifest] Shutting down telemetry..."),Qr&&(await Qr.shutdown(),Qr=null),Zr&&(await Zr.shutdown(),Zr=null),Cc=null,xc=null,o.info("[manifest] Telemetry shut down")}m();var U5=5,qI=30*60*1e3,D5=3e3,V5=5*60*1e3,w5=new Set(["system","developer"]),B5=10,en=new Map,jI=!1;function G5(){if(jI)return;jI=!0;let o=setInterval(()=>{let r=Date.now();for(let[i,c]of en)r-c.lastUpdated>qI&&en.delete(i)},V5);typeof o=="object"&&"unref"in o&&o.unref()}async function WI(o,r,i,c){G5();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(y=>y&&typeof y=="object"&&"role"in y&&!w5.has(y.role)).slice(-B5).map(y=>({role:y.role,content:y.content}));if(t.length===0)return c.debug("[manifest] Routing resolve: no scorable messages, skipping"),null;let e=en.get(i),n=e&&Date.now()-e.lastUpdated<qI?e.tiers:void 0,s={messages:t};n&&(s.recentTiers=n);let l=await fetch(u,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o.apiKey}`},body:JSON.stringify(s),signal:AbortSignal.timeout(D5)});if(!l.ok)return c.debug(`[manifest] Routing resolve returned ${l.status}`),null;let E=await l.json();if(!E.model)return c.debug(`[manifest] Routing resolve: no model for tier=${E.tier}`),null;let A=en.get(i);return A?(A.tiers=[E.tier,...A.tiers].slice(0,U5),A.lastUpdated=Date.now()):en.set(i,{tiers:[E.tier],lastUpdated:Date.now()}),c.debug(`[manifest] Routing resolved: tier=${E.tier} model=${E.model} provider=${E.provider}`),{tier:E.tier,model:E.model,provider:E.provider??"unknown"}}catch(t){let e=t instanceof Error?t.message:String(t);return c.debug(`[manifest] Routing resolve failed (${e})`),null}}function aa(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",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 Er=new Map,zI,JI,XI,$I,H5,QI,ZI,eC,tC;function ua(o){zI=o.createCounter(me.LLM_REQUESTS,{description:"Total LLM inference requests"}),JI=o.createCounter(me.LLM_TOKENS_INPUT,{description:"Total input tokens sent to LLM"}),XI=o.createCounter(me.LLM_TOKENS_OUTPUT,{description:"Total output tokens from LLM"}),$I=o.createCounter(me.LLM_TOKENS_CACHE_READ,{description:"Total cache-read tokens"}),H5=o.createHistogram(me.LLM_DURATION,{description:"LLM request duration in ms",unit:"ms"}),QI=o.createCounter(me.TOOL_CALLS,{description:"Total tool invocations"}),ZI=o.createCounter(me.TOOL_ERRORS,{description:"Total tool errors"}),eC=o.createHistogram(me.TOOL_DURATION,{description:"Tool execution duration in ms",unit:"ms"}),tC=o.createCounter(me.MESSAGES_RECEIVED,{description:"Total messages received from users"})}function sa(o,r,i,c){o.on("message_received",a=>{let u=a.sessionKey||a.session?.key||`agent:${a.agent||"main"}:main`,t=a.channel||"unknown",e=r.startSpan(on.REQUEST,{kind:He.SERVER,attributes:{[D.SESSION_KEY]:u,[D.CHANNEL]:t}});Er.set(u,{root:e}),tC.add(1,{[D.CHANNEL]:t}),c.debug(`[manifest] Root span started for session=${u}`)}),o.on("before_agent_start",a=>{let u=a.sessionKey||a.session?.key||`agent:${a.agent||"main"}:main`,t=a.agent||"main",e=Er.get(u),n=e?.root?Ye.setSpan(ke.active(),e.root):ke.active(),s=r.startSpan(on.AGENT_TURN,{kind:He.INTERNAL,attributes:{[D.AGENT_NAME]:t,[D.SESSION_KEY]:u}},n);e?e.turn=s:Er.set(u,{root:s,turn:s}),c.debug(`[manifest] Agent turn started: agent=${t}, session=${u}`)}),o.on("tool_result_persist",a=>{let u=a.toolName||a.tool||"unknown",t=a.durationMs||0,e=a.error==null,n=a.sessionKey||"unknown",s=Er.get(n),l=s?.turn?Ye.setSpan(ke.active(),s.turn):ke.active(),E=r.startSpan(`${on.TOOL_PREFIX}${u}`,{kind:He.INTERNAL,attributes:{[D.TOOL_NAME]:u,[D.TOOL_SUCCESS]:String(e),[D.SESSION_KEY]:n}},l);e||(E.setStatus({code:Mt.ERROR,message:a.error?.message||"Tool execution failed"}),ZI.add(1,{[D.TOOL_NAME]:u})),E.end(),QI.add(1,{[D.TOOL_NAME]:u}),eC.record(t,{[D.TOOL_NAME]:u})}),o.on("agent_end",async a=>{let u=a.sessionKey||a.session?.key||`agent:${a.agent||"main"}:main`,t=a.messages||[],e=[...t].reverse().find(we=>we.role==="assistant"&&we.usage),n=e?.model||a.model||"unknown",s=e?.provider||a.provider||"unknown",l=e?.usage||a.usage||{},E=l.input||l.inputTokens||0,A=l.output||l.outputTokens||0,y=l.cacheRead||l.cacheReadTokens||0,ue=l.cacheWrite||l.cacheWriteTokens||0,tt=n,Ve=s,Tr=null;if(tt==="auto"&&i.mode==="local"){let we=await WI(i,t,u,c);we&&(tt=we.model,Ve=we.provider,Tr=we.tier)}let Ee=Er.get(u);Ee?.turn&&(Ee.turn.setAttributes({[D.MODEL]:tt,[D.PROVIDER]:Ve,[D.INPUT_TOKENS]:E,[D.OUTPUT_TOKENS]:A,[D.CACHE_READ_TOKENS]:y,[D.CACHE_WRITE_TOKENS]:ue}),Tr&&Ee.turn.setAttribute(D.ROUTING_TIER,Tr),Ee.turn.end()),Ee?.root&&Ee.root!==Ee.turn&&Ee.root.end(),Er.delete(u);let ht={[D.MODEL]:tt,[D.PROVIDER]:Ve};zI.add(1,ht),JI.add(E,ht),XI.add(A,ht),y>0&&$I.add(y,ht),c.debug(`[manifest] agent_end tokens: in=${E}, out=${A}, cache=${y}`),c.debug(`[manifest] Trace completed for session=${u}`)}),c.debug("[manifest] All hooks registered")}async function ca(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=await fetch(`${r}/api/v1/agent/usage?range=24h`,{headers:{Authorization:`Bearer ${o.apiKey}`},signal:AbortSignal.timeout(5e3)});if(c.status===401||c.status===403)return i.error="API key rejected \u2014 check your mnfst_ key is correct",i;if(!c.ok)return i.error=`Usage endpoint returned ${c.status}`,i;i.authValid=!0;let a=await c.json();a&&typeof a.agentName=="string"&&(i.agentName=a.agentName)}catch(c){let a=c instanceof Error?c.message:String(c);return i.error=`Auth check failed: ${a}`,i}return i}var rC={today:"24h",week:"7d",month:"30d"};async function nC(o,r,i,c){let a=`${o}${r}`;try{let u=await fetch(a,{headers:{Authorization:`Bearer ${i}`}});return u.ok?{result:await u.json()}:{error:`API returned ${u.status}`}}catch(u){let t=u instanceof Error?u.message:String(u);return c.error(`[manifest] API call failed: ${t}`),{error:t}}}function la(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"}}},handler:async a=>{let u=rC[a.period||"today"]||"24h";return nC(c,`/api/v1/agent/usage?range=${u}`,r.apiKey,i)}}),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"}}},handler:async a=>{let u=rC[a.period||"week"]||"7d";return nC(c,`/api/v1/agent/costs?range=${u}`,r.apiKey,i)}}),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:{}},handler:async()=>{let a=await ca(r);return a.error?{error:a.error}:{result:{endpointReachable:a.endpointReachable,authValid:a.authValid,agentName:a.agentName,status:"ok"}}}}),i.debug("[manifest] Registered agent tools: manifest_usage, manifest_costs, manifest_health")}var U=require("fs"),ve=require("path"),bc=require("os"),iC=require("crypto");var pa=(0,ve.join)((0,bc.homedir)(),".openclaw","manifest"),tn=(0,ve.join)(pa,"config.json"),aC=(0,ve.join)((0,bc.homedir)(),".openclaw"),oC=(0,ve.join)(aC,"openclaw.json"),k5=3e3;function Y5(){(0,U.existsSync)(pa)||(0,U.mkdirSync)(pa,{recursive:!0,mode:448})}function F5(){if(Y5(),(0,U.existsSync)(tn))try{let i=JSON.parse((0,U.readFileSync)(tn,"utf-8"));if(i.apiKey&&i.apiKey.startsWith(Ie))return i.apiKey}catch{}let o=`${Ie}local_${(0,iC.randomBytes)(24).toString("hex")}`,r={};if((0,U.existsSync)(tn))try{r=JSON.parse((0,U.readFileSync)(tn,"utf-8"))}catch{}return(0,U.writeFileSync)(tn,JSON.stringify({...r,apiKey:o},null,2),{mode:384}),o}function uC(o){if(!(0,U.existsSync)(o))return{};try{return JSON.parse((0,U.readFileSync)(o,"utf-8"))}catch{return{}}}function sC(o,r){let i=(0,ve.dirname)(o);(0,U.existsSync)(i)||(0,U.mkdirSync)(i,{recursive:!0,mode:448});let c=`${o}.tmp.${process.pid}`;(0,U.writeFileSync)(c,JSON.stringify(r,null,2),{mode:384}),(0,U.renameSync)(c,o)}function K5(o,r,i,c,a){let t={baseUrl:`http://${r}:${i}/v1`,api:"openai-completions",apiKey:c,models:[{id:"auto",name:"auto"}]};try{let e=uC(oC);e.models||(e.models={}),e.models.providers||(e.models.providers={}),e.models.providers.manifest=t,e.agents||(e.agents={}),e.agents.defaults||(e.agents.defaults={}),e.agents.defaults.models||(e.agents.defaults.models={});let n=e.agents.defaults.models;Array.isArray(n)?n.includes("manifest/auto")||n.push("manifest/auto"):typeof n=="object"&&("manifest/auto"in n||(n["manifest/auto"]={})),sC(oC,e),a.debug("[manifest] Wrote provider config to openclaw.json")}catch(e){let n=e instanceof Error?e.message:String(e);a.debug(`[manifest] Could not write openclaw.json: ${n}`)}try{if(o.config){o.config.models||(o.config.models={}),o.config.models.providers||(o.config.models.providers={}),o.config.models.providers.manifest=t,o.config.agents||(o.config.agents={}),o.config.agents.defaults||(o.config.agents.defaults={}),o.config.agents.defaults.models||(o.config.agents.defaults.models={});let e=o.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"]={}))}a.debug("[manifest] Injected provider into runtime config")}catch(e){let n=e instanceof Error?e.message:String(e);a.debug(`[manifest] Could not inject runtime config: ${n}`)}}function j5(o,r){let i=(0,ve.join)(aC,"agents");if(!(0,U.existsSync)(i)){r.debug("[manifest] No agents directory found, skipping auth profile injection");return}let c={type:"api_key",provider:"manifest",key:o},a=0;try{let u=(0,U.readdirSync)(i,{withFileTypes:!0}).filter(t=>t.isDirectory());for(let t of u){let e=(0,ve.join)(i,t.name,"agent","auth-profiles.json"),n=(0,ve.dirname)(e);if(!(0,U.existsSync)(n))continue;let s=uC(e);s.version||(s.version=1),s.profiles||(s.profiles={});let l=s.profiles["manifest:default"];l&&l.key===o||(s.profiles["manifest:default"]=c,sC(e,s),a++)}}catch(u){let t=u instanceof Error?u.message:String(u);r.debug(`[manifest] Auth profile injection error: ${t}`)}a>0&&r.debug(`[manifest] Injected auth profile into ${a} agent(s)`)}async function q5(o,r){try{return(await fetch(`http://${o}:${r}/api/v1/health`,{signal:AbortSignal.timeout(k5)})).ok}catch{return!1}}function cC(o,r,i){let c=r.port,a=r.host,u=F5(),t=(0,ve.join)(pa,"manifest.db");i.debug("[manifest] Local mode \u2014 starting embedded server..."),K5(o,a,c,u,i),j5(u,i);let e;try{e=require("./server")}catch(A){let y=A instanceof Error?A.message:String(A);i.error(`[manifest] Failed to load embedded server.
|
|
19
|
+
or export MANIFEST_API_KEY=${Ie}YOUR_KEY`}var ra=Oe(EM()),na=Oe(fi()),YI=Oe(UI()),FI=Oe(kI()),KI=Oe(vo());m();var Qr=null,Zr=null,Cc=null,xc=null;function oa(o,r){let i=new KI.Resource({"service.name":o.serviceName,"service.version":"5.9.5","manifest.plugin":"true"}),c={Authorization:`Bearer ${o.apiKey}`},a=new YI.OTLPTraceExporter({url:`${o.endpoint}/v1/traces`,headers:c});Qr=new ra.BasicTracerProvider({resource:i,spanProcessors:[new ra.BatchSpanProcessor(a,{scheduledDelayMillis:5e3,maxQueueSize:2048,maxExportBatchSize:512})]}),Qr.register(),r.debug(`[manifest] Trace exporter -> ${o.endpoint}/v1/traces`);let u=new FI.OTLPMetricExporter({url:`${o.endpoint}/v1/metrics`,headers:c});return Zr=new na.MeterProvider({resource:i,readers:[new na.PeriodicExportingMetricReader({exporter:u,exportIntervalMillis:o.metricsIntervalMs})]}),gt.setGlobalMeterProvider(Zr),r.debug(`[manifest] Metrics exporter -> ${o.endpoint}/v1/metrics (interval=${o.metricsIntervalMs}ms)`),Cc=Ye.getTracer("manifest-plugin","5.9.5"),xc=gt.getMeter("manifest-plugin","5.9.5"),{tracer:Cc,meter:xc}}async function ia(o){o.info("[manifest] Shutting down telemetry..."),Qr&&(await Qr.shutdown(),Qr=null),Zr&&(await Zr.shutdown(),Zr=null),Cc=null,xc=null,o.info("[manifest] Telemetry shut down")}m();var U5=5,qI=30*60*1e3,D5=3e3,V5=5*60*1e3,w5=new Set(["system","developer"]),B5=10,en=new Map,jI=!1;function G5(){if(jI)return;jI=!0;let o=setInterval(()=>{let r=Date.now();for(let[i,c]of en)r-c.lastUpdated>qI&&en.delete(i)},V5);typeof o=="object"&&"unref"in o&&o.unref()}async function WI(o,r,i,c){G5();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(y=>y&&typeof y=="object"&&"role"in y&&!w5.has(y.role)).slice(-B5).map(y=>({role:y.role,content:y.content}));if(t.length===0)return c.debug("[manifest] Routing resolve: no scorable messages, skipping"),null;let e=en.get(i),n=e&&Date.now()-e.lastUpdated<qI?e.tiers:void 0,s={messages:t};n&&(s.recentTiers=n);let l=await fetch(u,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o.apiKey}`},body:JSON.stringify(s),signal:AbortSignal.timeout(D5)});if(!l.ok)return c.debug(`[manifest] Routing resolve returned ${l.status}`),null;let E=await l.json();if(!E.model)return c.debug(`[manifest] Routing resolve: no model for tier=${E.tier}`),null;let A=en.get(i);return A?(A.tiers=[E.tier,...A.tiers].slice(0,U5),A.lastUpdated=Date.now()):en.set(i,{tiers:[E.tier],lastUpdated:Date.now()}),c.debug(`[manifest] Routing resolved: tier=${E.tier} model=${E.model} provider=${E.provider}`),{tier:E.tier,model:E.model,provider:E.provider??"unknown"}}catch(t){let e=t instanceof Error?t.message:String(t);return c.debug(`[manifest] Routing resolve failed (${e})`),null}}function aa(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",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 Er=new Map,zI,JI,XI,$I,H5,QI,ZI,eC,tC;function ua(o){zI=o.createCounter(me.LLM_REQUESTS,{description:"Total LLM inference requests"}),JI=o.createCounter(me.LLM_TOKENS_INPUT,{description:"Total input tokens sent to LLM"}),XI=o.createCounter(me.LLM_TOKENS_OUTPUT,{description:"Total output tokens from LLM"}),$I=o.createCounter(me.LLM_TOKENS_CACHE_READ,{description:"Total cache-read tokens"}),H5=o.createHistogram(me.LLM_DURATION,{description:"LLM request duration in ms",unit:"ms"}),QI=o.createCounter(me.TOOL_CALLS,{description:"Total tool invocations"}),ZI=o.createCounter(me.TOOL_ERRORS,{description:"Total tool errors"}),eC=o.createHistogram(me.TOOL_DURATION,{description:"Tool execution duration in ms",unit:"ms"}),tC=o.createCounter(me.MESSAGES_RECEIVED,{description:"Total messages received from users"})}function sa(o,r,i,c){o.on("message_received",a=>{let u=a.sessionKey||a.session?.key||`agent:${a.agent||"main"}:main`,t=a.channel||"unknown",e=r.startSpan(on.REQUEST,{kind:He.SERVER,attributes:{[D.SESSION_KEY]:u,[D.CHANNEL]:t}});Er.set(u,{root:e}),tC.add(1,{[D.CHANNEL]:t}),c.debug(`[manifest] Root span started for session=${u}`)}),o.on("before_agent_start",a=>{let u=a.sessionKey||a.session?.key||`agent:${a.agent||"main"}:main`,t=a.agent||"main",e=Er.get(u),n=e?.root?Ye.setSpan(ke.active(),e.root):ke.active(),s=r.startSpan(on.AGENT_TURN,{kind:He.INTERNAL,attributes:{[D.AGENT_NAME]:t,[D.SESSION_KEY]:u}},n);e?e.turn=s:Er.set(u,{root:s,turn:s}),c.debug(`[manifest] Agent turn started: agent=${t}, session=${u}`)}),o.on("tool_result_persist",a=>{let u=a.toolName||a.tool||"unknown",t=a.durationMs||0,e=a.error==null,n=a.sessionKey||"unknown",s=Er.get(n),l=s?.turn?Ye.setSpan(ke.active(),s.turn):ke.active(),E=r.startSpan(`${on.TOOL_PREFIX}${u}`,{kind:He.INTERNAL,attributes:{[D.TOOL_NAME]:u,[D.TOOL_SUCCESS]:String(e),[D.SESSION_KEY]:n}},l);e||(E.setStatus({code:Mt.ERROR,message:a.error?.message||"Tool execution failed"}),ZI.add(1,{[D.TOOL_NAME]:u})),E.end(),QI.add(1,{[D.TOOL_NAME]:u}),eC.record(t,{[D.TOOL_NAME]:u})}),o.on("agent_end",async a=>{let u=a.sessionKey||a.session?.key||`agent:${a.agent||"main"}:main`,t=a.messages||[],e=[...t].reverse().find(we=>we.role==="assistant"&&we.usage),n=e?.model||a.model||"unknown",s=e?.provider||a.provider||"unknown",l=e?.usage||a.usage||{},E=l.input||l.inputTokens||0,A=l.output||l.outputTokens||0,y=l.cacheRead||l.cacheReadTokens||0,ue=l.cacheWrite||l.cacheWriteTokens||0,tt=n,Ve=s,Tr=null;if(tt==="auto"&&i.mode==="local"){let we=await WI(i,t,u,c);we&&(tt=we.model,Ve=we.provider,Tr=we.tier)}let Ee=Er.get(u);Ee?.turn&&(Ee.turn.setAttributes({[D.MODEL]:tt,[D.PROVIDER]:Ve,[D.INPUT_TOKENS]:E,[D.OUTPUT_TOKENS]:A,[D.CACHE_READ_TOKENS]:y,[D.CACHE_WRITE_TOKENS]:ue}),Tr&&Ee.turn.setAttribute(D.ROUTING_TIER,Tr),Ee.turn.end()),Ee?.root&&Ee.root!==Ee.turn&&Ee.root.end(),Er.delete(u);let ht={[D.MODEL]:tt,[D.PROVIDER]:Ve};zI.add(1,ht),JI.add(E,ht),XI.add(A,ht),y>0&&$I.add(y,ht),c.debug(`[manifest] agent_end tokens: in=${E}, out=${A}, cache=${y}`),c.debug(`[manifest] Trace completed for session=${u}`)}),c.debug("[manifest] All hooks registered")}async function ca(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=await fetch(`${r}/api/v1/agent/usage?range=24h`,{headers:{Authorization:`Bearer ${o.apiKey}`},signal:AbortSignal.timeout(5e3)});if(c.status===401||c.status===403)return i.error="API key rejected \u2014 check your mnfst_ key is correct",i;if(!c.ok)return i.error=`Usage endpoint returned ${c.status}`,i;i.authValid=!0;let a=await c.json();a&&typeof a.agentName=="string"&&(i.agentName=a.agentName)}catch(c){let a=c instanceof Error?c.message:String(c);return i.error=`Auth check failed: ${a}`,i}return i}var rC={today:"24h",week:"7d",month:"30d"};async function nC(o,r,i,c){let a=`${o}${r}`;try{let u=await fetch(a,{headers:{Authorization:`Bearer ${i}`}});return u.ok?{result:await u.json()}:{error:`API returned ${u.status}`}}catch(u){let t=u instanceof Error?u.message:String(u);return c.error(`[manifest] API call failed: ${t}`),{error:t}}}function la(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"}}},handler:async a=>{let u=rC[a.period||"today"]||"24h";return nC(c,`/api/v1/agent/usage?range=${u}`,r.apiKey,i)}}),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"}}},handler:async a=>{let u=rC[a.period||"week"]||"7d";return nC(c,`/api/v1/agent/costs?range=${u}`,r.apiKey,i)}}),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:{}},handler:async()=>{let a=await ca(r);return a.error?{error:a.error}:{result:{endpointReachable:a.endpointReachable,authValid:a.authValid,agentName:a.agentName,status:"ok"}}}}),i.debug("[manifest] Registered agent tools: manifest_usage, manifest_costs, manifest_health")}var U=require("fs"),ve=require("path"),bc=require("os"),iC=require("crypto");var pa=(0,ve.join)((0,bc.homedir)(),".openclaw","manifest"),tn=(0,ve.join)(pa,"config.json"),aC=(0,ve.join)((0,bc.homedir)(),".openclaw"),oC=(0,ve.join)(aC,"openclaw.json"),k5=3e3;function Y5(){(0,U.existsSync)(pa)||(0,U.mkdirSync)(pa,{recursive:!0,mode:448})}function F5(){if(Y5(),(0,U.existsSync)(tn))try{let i=JSON.parse((0,U.readFileSync)(tn,"utf-8"));if(i.apiKey&&i.apiKey.startsWith(Ie))return i.apiKey}catch{}let o=`${Ie}local_${(0,iC.randomBytes)(24).toString("hex")}`,r={};if((0,U.existsSync)(tn))try{r=JSON.parse((0,U.readFileSync)(tn,"utf-8"))}catch{}return(0,U.writeFileSync)(tn,JSON.stringify({...r,apiKey:o},null,2),{mode:384}),o}function uC(o){if(!(0,U.existsSync)(o))return{};try{return JSON.parse((0,U.readFileSync)(o,"utf-8"))}catch{return{}}}function sC(o,r){let i=(0,ve.dirname)(o);(0,U.existsSync)(i)||(0,U.mkdirSync)(i,{recursive:!0,mode:448});let c=`${o}.tmp.${process.pid}`;(0,U.writeFileSync)(c,JSON.stringify(r,null,2),{mode:384}),(0,U.renameSync)(c,o)}function K5(o,r,i,c,a){let t={baseUrl:`http://${r}:${i}/v1`,api:"openai-completions",apiKey:c,models:[{id:"auto",name:"auto"}]};try{let e=uC(oC);e.models||(e.models={}),e.models.providers||(e.models.providers={}),e.models.providers.manifest=t,e.agents||(e.agents={}),e.agents.defaults||(e.agents.defaults={}),e.agents.defaults.models||(e.agents.defaults.models={});let n=e.agents.defaults.models;Array.isArray(n)?n.includes("manifest/auto")||n.push("manifest/auto"):typeof n=="object"&&("manifest/auto"in n||(n["manifest/auto"]={})),sC(oC,e),a.debug("[manifest] Wrote provider config to openclaw.json")}catch(e){let n=e instanceof Error?e.message:String(e);a.debug(`[manifest] Could not write openclaw.json: ${n}`)}try{if(o.config){o.config.models||(o.config.models={}),o.config.models.providers||(o.config.models.providers={}),o.config.models.providers.manifest=t,o.config.agents||(o.config.agents={}),o.config.agents.defaults||(o.config.agents.defaults={}),o.config.agents.defaults.models||(o.config.agents.defaults.models={});let e=o.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"]={}))}a.debug("[manifest] Injected provider into runtime config")}catch(e){let n=e instanceof Error?e.message:String(e);a.debug(`[manifest] Could not inject runtime config: ${n}`)}}function j5(o,r){let i=(0,ve.join)(aC,"agents");if(!(0,U.existsSync)(i)){r.debug("[manifest] No agents directory found, skipping auth profile injection");return}let c={type:"api_key",provider:"manifest",key:o},a=0;try{let u=(0,U.readdirSync)(i,{withFileTypes:!0}).filter(t=>t.isDirectory());for(let t of u){let e=(0,ve.join)(i,t.name,"agent","auth-profiles.json"),n=(0,ve.dirname)(e);if(!(0,U.existsSync)(n))continue;let s=uC(e);s.version||(s.version=1),s.profiles||(s.profiles={});let l=s.profiles["manifest:default"];l&&l.key===o||(s.profiles["manifest:default"]=c,sC(e,s),a++)}}catch(u){let t=u instanceof Error?u.message:String(u);r.debug(`[manifest] Auth profile injection error: ${t}`)}a>0&&r.debug(`[manifest] Injected auth profile into ${a} agent(s)`)}async function q5(o,r){try{return(await fetch(`http://${o}:${r}/api/v1/health`,{signal:AbortSignal.timeout(k5)})).ok}catch{return!1}}function cC(o,r,i){let c=r.port,a=r.host,u=F5(),t=(0,ve.join)(pa,"manifest.db");i.debug("[manifest] Local mode \u2014 starting embedded server..."),K5(o,a,c,u,i),j5(u,i);let e;try{e=require("./server")}catch(A){let y=A instanceof Error?A.message:String(A);i.error(`[manifest] Failed to load embedded server.
|
|
20
20
|
Error: ${y}
|
|
21
21
|
This is a packaging error \u2014 please reinstall the manifest plugin.`);return}let n=`http://${a}:${c}/otlp`,s={...r,apiKey:u,endpoint:n,captureContent:!0,metricsIntervalMs:Vc.METRICS_INTERVAL_MS},{tracer:l,meter:E}=oa(s,i);ua(E),sa(o,l,s,i),aa(o,s,i),typeof o.registerTool=="function"&&la(o,s,i),i.info(`[manifest] \u{1F99A} View your Manifest Dashboard -> http://${a}:${c}`),o.registerService({id:"manifest-local",start:async()=>{try{await e.start({port:c,host:a,dbPath:t,quiet:!0}),i.info(`[manifest] Local server running on http://${a}:${c}`),i.info(`[manifest] Dashboard: http://${a}:${c}`),i.info(`[manifest] DB: ${t}`)}catch(A){let y=A instanceof Error?A.message:String(A);y.includes("EADDRINUSE")||y.includes("address already in use")?await q5(a,c)?i.info(`[manifest] Reusing existing server at http://${a}:${c}`):i.error(`[manifest] Port ${c} is already in use by another process.
|
|
22
22
|
Change it with: openclaw config set plugins.entries.manifest.config.port ${c+1}
|
|
23
23
|
Then restart the gateway.`):i.error(`[manifest] Failed to start local server: ${y}
|
|
24
24
|
Try reinstalling: openclaw plugins install manifest
|
|
25
|
-
Then restart: openclaw gateway restart`)}},stop:async()=>{await ia(i)}})}var pC=require("crypto"),De=require("os");function lC(){return{optedOut:__fromEnv.MANIFEST_TELEMETRY_OPTOUT==="1"||__fromEnv.MANIFEST_TELEMETRY_OPTOUT==="true",packageVersion:"5.9.
|
|
25
|
+
Then restart: openclaw gateway restart`)}},stop:async()=>{await ia(i)}})}var pC=require("crypto"),De=require("os");function lC(){return{optedOut:__fromEnv.MANIFEST_TELEMETRY_OPTOUT==="1"||__fromEnv.MANIFEST_TELEMETRY_OPTOUT==="true",packageVersion:"5.9.5"}}var W5="https://eu.i.posthog.com",z5="phc_g5pLOu5bBRjhVJBwAsx0eCzJFWq0cri2TyVLQLxf045";function J5(){let o=`${(0,De.hostname)()}-${(0,De.platform)()}-${(0,De.arch)()}`;return(0,pC.createHash)("sha256").update(o).digest("hex").slice(0,16)}function Uc(o,r){let i=lC();if(i.optedOut)return;let c={api_key:z5,event:o,properties:{distinct_id:J5(),os:(0,De.platform)(),os_version:(0,De.release)(),node_version:process.versions.node,package_version:i.packageVersion,...r},timestamp:new Date().toISOString()};fetch(`${W5}/capture`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(c)}).catch(()=>{})}module.exports={id:"manifest",name:"Manifest \u2014 Agent Observability",register(o){let r=o.logger||{info:(...e)=>console.log(...e),debug:()=>{},error:(...e)=>console.error(...e),warn:(...e)=>console.warn(...e)},i=wc(o.pluginConfig);if(Uc("plugin_registered"),Uc("plugin_mode_selected",{mode:i.mode}),i.mode==="local"){cC(o,i,r);return}let c=Bc(i);if(c){i.apiKey?r.error(`[manifest] Configuration error:
|
|
26
26
|
${c}`):r.info(`[manifest] Cloud mode requires an API key:
|
|
27
27
|
openclaw config set plugins.entries.manifest.config.apiKey mnfst_YOUR_KEY
|
|
28
28
|
openclaw gateway restart
|