@hydra-acp/budgeter 0.1.21 → 0.1.22
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.
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{readFileSync as k}from"node:fs";import{homedir as
|
|
2
|
-
`)){const a=
|
|
3
|
-
`).filter(i=>i.length>0)}export{j as fetchSessionHistory,F as fetchToolBlob,O as fetchUsageEventsFromDaemon,H as listSessionsFromDaemon};
|
|
1
|
+
import{readFileSync as k}from"node:fs";import{homedir as b}from"node:os";import{resolve as m}from"node:path";import{logger as I}from"../util/log.js";const d=I("cost/daemon-client");function x(){if(process.env.HYDRA_ACP_TOKEN)return process.env.HYDRA_ACP_TOKEN;const e=m(process.env.HYDRA_ACP_HOME??m(b(),".hydra-acp"),"auth-token");try{const t=k(e,"utf8").trim();if(t.length>0)return t}catch(t){const n=t;n.code!=="ENOENT"&&d.debug(`auth-token read failed: ${n.message}`)}}function T(e=m(process.env.HYDRA_ACP_HOME??m(b(),".hydra-acp"),"daemon.pid")){if(process.env.HYDRA_ACP_DAEMON_URL)return process.env.HYDRA_ACP_DAEMON_URL;try{const t=k(e,"utf8"),n=JSON.parse(t);if(typeof n.loopbackPort=="number")return`http://127.0.0.1:${n.loopbackPort}`;if(typeof n.host=="string"&&typeof n.port=="number")return`http://${n.host}:${n.port}`}catch(t){const n=t;n.code!=="ENOENT"&&d.debug(`daemon.pid read failed: ${n.message}`)}return"http://127.0.0.1:8765"}function l(){const e=x();if(e!==void 0)return{daemonUrl:T(),token:e}}function P(e){const t=typeof e.sessionId=="string"?e.sessionId:void 0;if(t===void 0)return;const n=typeof e.updatedAt=="string"?e.updatedAt:"",o=(e._meta??{})["hydra-acp"]??{},i=typeof e.cwd=="string"?e.cwd:typeof o.cwd=="string"?o.cwd:void 0,r=typeof e.agentId=="string"?e.agentId:typeof o.agentId=="string"?o.agentId:"",u=typeof e.currentModel=="string"?e.currentModel:typeof o.currentModel=="string"?o.currentModel:"",a=typeof e.title=="string"?e.title:"",c=e.interactive===!0||o.interactive===!0,p=typeof e.importedFromMachine=="string"?e.importedFromMachine:typeof o.importedFromMachine=="string"?o.importedFromMachine:"",$=p.length>0?p:void 0,y=typeof e.upstreamSessionId=="string"?e.upstreamSessionId:typeof o.upstreamSessionId=="string"?o.upstreamSessionId:"",A=y.length>0?y:void 0,h=typeof e.remote=="string"?e.remote:"",v=h.length>0?h:void 0,R=e.currentUsage,E=o.currentUsage,f=R??E,C=typeof f?.costAmount=="number"?f.costAmount:0,S=typeof f?.costCurrency=="string"?f.costCurrency:"",U=typeof f?.used=="number"?f.used:0;return{sessionId:t,cwd:i,agentId:r,model:u,interactive:c,costAmount:C,costCurrency:S,contextTokens:U,title:a,createdAt:"",updatedAt:n,importedFromMachine:$,upstreamSessionId:A,remote:v}}async function H(){const e=l();if(e===void 0){d.debug("no daemon token resolved; skipping daemon fetch");return}const t=`${e.daemonUrl.replace(/\/$/,"")}/v1/sessions?includeNonInteractive=1`;let n;try{n=await fetch(t,{headers:{Authorization:`Bearer ${e.token}`}})}catch(r){d.debug(`daemon fetch failed (${t}): ${r.message}`);return}if(!n.ok){d.debug(`daemon returned HTTP ${n.status} for ${t}`);return}let s;try{s=await n.json()}catch(r){d.debug(`daemon response not JSON: ${r.message}`);return}const o=s;if(!Array.isArray(o.sessions)){d.debug("daemon response missing sessions[]");return}const i=[];for(const r of o.sessions)if(r&&typeof r=="object"&&!Array.isArray(r)){const u=P(r);u!==void 0&&i.push(u)}return i}function _(e){const t=typeof e.sessionId=="string"?e.sessionId:void 0,n=typeof e.ts=="string"?e.ts:void 0;if(t===void 0||n===void 0)return;const s=e.update??void 0,o=typeof s?.cost?.amount=="number"?s.cost.amount:0,i=typeof s?.cost?.currency=="string"?s.cost.currency:"USD",r=typeof s?.used=="number"?s.used:0;return{sessionId:t,ts:n,costCumulative:o,costCurrency:i,contextTokens:r}}async function O(e){const t=l();if(t===void 0)return;const n=new URLSearchParams({kinds:"usage_update"});e!==void 0&&n.set("since",e.toISOString());const s=`${t.daemonUrl.replace(/\/$/,"")}/v1/sessions/events?${n.toString()}`;let o;try{o=await fetch(s,{headers:{Authorization:`Bearer ${t.token}`}})}catch(u){d.debug(`events fetch failed: ${u.message}`);return}if(!o.ok){d.debug(`events endpoint HTTP ${o.status}`);return}const i=await o.text(),r=[];for(const u of i.split(`
|
|
2
|
+
`)){const a=u.trim();if(a.length===0)continue;let c;try{c=JSON.parse(a)}catch{continue}if(c&&typeof c=="object"&&!Array.isArray(c)){const p=_(c);p!==void 0&&r.push(p)}}return r}const g=new Map;async function F(e,t){const n=`${e}|${t}`,s=g.get(n);if(s!==void 0)return s;const o=l();if(o===void 0)return g.set(n,null),null;const i=`${o.daemonUrl.replace(/\/$/,"")}/v1/sessions/${encodeURIComponent(e)}/tools/${encodeURIComponent(t)}`;let r;try{r=await fetch(i,{headers:{Authorization:`Bearer ${o.token}`}})}catch(a){return d.debug(`tool blob fetch failed: ${a.message}`),g.set(n,null),null}if(!r.ok)return d.debug(`tool blob endpoint HTTP ${r.status} for ${t}`),g.set(n,null),null;const u=await r.text();return g.set(n,u),u}async function j(e){const t=l();if(t===void 0)return;const n=`${t.daemonUrl.replace(/\/$/,"")}/v1/sessions/${encodeURIComponent(e)}/history`;let s;try{s=await fetch(n,{headers:{Authorization:`Bearer ${t.token}`}})}catch(i){d.debug(`session history fetch failed (${n}): ${i.message}`);return}if(!s.ok){d.debug(`session history endpoint HTTP ${s.status} for ${e}`);return}return(await s.text()).split(`
|
|
3
|
+
`).filter(i=>i.length>0)}export{j as fetchSessionHistory,F as fetchToolBlob,O as fetchUsageEventsFromDaemon,H as listSessionsFromDaemon,T as resolveDaemonUrl};
|
package/package.json
CHANGED