@agenthippo-ai/agenthippo 1.110.33 → 1.110.34
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/out/cli/index.js
CHANGED
|
@@ -417,7 +417,7 @@ else {
|
|
|
417
417
|
${xe}`,ot.message=he)}return ot}onMaintenance(e){let n=Date.now();for(let[r,s]of this.activeSessions.entries())n-s.lastUsedAt>dP&&(this.activeSessions.delete(r),e.info(`[AgentIDE] Closed idle custom engine session (key=${r}, idleMs=${n-s.lastUsedAt})`));for(let{engine:r,manifest:s}of this.instances.values())try{r.onMaintenance?.(e)}catch(i){e.warn(`[AgentIDE] Custom engine "${s.id}" onMaintenance error: ${i}`)}this.workerPool.onMaintenance()}dispose(){this.clearInstances(),this.workerPool.disposeAll(),this.activeSessions.clear(),this.mtimeCache.clear()}};En.CustomEngine=Zu});var pi=T(ue=>{"use strict";var yP=ue&&ue.__createBinding||(Object.create?(function(t,e,n,r){r===void 0&&(r=n);var s=Object.getOwnPropertyDescriptor(e,n);(!s||("get"in s?!e.__esModule:s.writable||s.configurable))&&(s={enumerable:!0,get:function(){return e[n]}}),Object.defineProperty(t,r,s)}):(function(t,e,n,r){r===void 0&&(r=n),t[r]=e[n]})),wP=ue&&ue.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),AP=ue&&ue.__importStar||(function(){var t=function(e){return t=Object.getOwnPropertyNames||function(n){var r=[];for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(r[r.length]=s);return r},t(e)};return function(e){if(e&&e.__esModule)return e;var n={};if(e!=null)for(var r=t(e),s=0;s<r.length;s++)r[s]!=="default"&&yP(n,e,r[s]);return wP(n,e),n}})();Object.defineProperty(ue,"__esModule",{value:!0});ue.resolveModelAlias=ue.getSessionDir=ue.createSessionDir=ue.computeSkillsSignature=ue.syncPackToWorkspace=ue.initSessionStoreWithStore=ue.CLIPermissionHandler=ue.AutoApprovePermissionHandler=ue.DirectorySessionStore=ue.FileSessionStore=ue.MemorySessionStore=ue.StaticConfigProvider=ue.NoOpEditTracker=ue.NoOpLogger=ue.ConsoleLogger=void 0;ue.createHeadlessRunner=nd;ue.createEvalRunner=$P;ue.createCLIRunner=DP;var Tm=AP(require("path")),SP=tm(),TP=im(),bP=si(),Lt=Ca();Object.defineProperty(ue,"ConsoleLogger",{enumerable:!0,get:function(){return Lt.ConsoleLogger}});Object.defineProperty(ue,"NoOpLogger",{enumerable:!0,get:function(){return Lt.NoOpLogger}});Object.defineProperty(ue,"NoOpEditTracker",{enumerable:!0,get:function(){return Lt.NoOpEditTracker}});Object.defineProperty(ue,"StaticConfigProvider",{enumerable:!0,get:function(){return Lt.StaticConfigProvider}});Object.defineProperty(ue,"MemorySessionStore",{enumerable:!0,get:function(){return Lt.MemorySessionStore}});Object.defineProperty(ue,"FileSessionStore",{enumerable:!0,get:function(){return Lt.FileSessionStore}});Object.defineProperty(ue,"DirectorySessionStore",{enumerable:!0,get:function(){return Lt.DirectorySessionStore}});Object.defineProperty(ue,"AutoApprovePermissionHandler",{enumerable:!0,get:function(){return Lt.AutoApprovePermissionHandler}});Object.defineProperty(ue,"CLIPermissionHandler",{enumerable:!0,get:function(){return Lt.CLIPermissionHandler}});var bm=ri(),vP=Wu(),vm=xi(),OP=Er(),IP=is(),PP=ti(),NP="AGENTHIPPO_TURN_NONCE";function RP(t,e){let n=t?.trim();if(n)return n;let r=e?.trim();if(r)return r;let s=process.env.AGENTHIPPO_ANALYTICS_USER_ID?.trim()||process.env.AGENTIDE_ANALYTICS_USER_ID?.trim();if(s)return s;let i=process.env.LOGNAME?.trim()||process.env.USER?.trim()||process.env.LNAME?.trim()||process.env.USERNAME?.trim();return i||"anonymous"}function nd(t){if(t.freshState){let E=new Lt.MemorySessionStore;(0,bm.initSessionStoreWithStore)(E)}else(0,bm.initSessionStoreWithStore)(new Lt.DirectorySessionStore(Tm.join(t.storagePath,"provider-sessions")));let e=!!(t.litellmApiKey||t.openaiApiKey||t.anthropicApiKey),n={storagePath:t.storagePath,codexHome:void 0,claudeConfigDir:void 0,litellmApiKey:t.litellmApiKey??(e?void 0:t.apiKey),litellmBaseUrl:t.baseUrl,openaiApiKey:t.openaiApiKey,anthropicApiKey:t.anthropicApiKey,claudeCodeExecutablePath:t.claudeCodeExecutablePath,codexExecutablePath:t.codexExecutablePath},r=t.logger??new Lt.ConsoleLogger("[AgentIDE]"),s=t.editTracker??new Lt.NoOpEditTracker,i=new Lt.StaticConfigProvider({},t.customProviders??{},t.engineSettings??{}),o=t.permissionHandler??new Lt.AutoApprovePermissionHandler,a={logger:r,editTracker:s,configProvider:i,permissionHandler:o,cliEnvPatch:t.cliEnvPatch},c=t.packId??"default",l=E=>(0,vP.computeSkillsSignature)(E,c),d=()=>t.bundledPromptsDir,u,f,p,g=()=>(u||(u=new TP.ClaudeEngine(n,async(E,w)=>l(E)??`headless-${c}`,d)),u),m=()=>(f||(f=new SP.CodexEngine(n,l,d)),f),h=async()=>{if(!p){let{CustomEngine:E}=await Promise.resolve().then(()=>bn(td()));p=new E(n,d)}return p},y=new vm.SessionEventWriter(t.analyticsSessionsDir??Tm.join((0,PP.getAgentideHome)(),"analytics","sessions"));return{async run(E){let w={success:!1,text:"",thinking:"",toolCalls:[]},v=E.emitter??{async thinking(L){w.thinking+=L},async text(L){w.text+=L},async toolStart(L,ee,q){w.toolCalls.push({name:L,input:ee})},async toolEnd(L,ee,q,ge){let ce=w.toolCalls.find(fe=>fe.name===L&&!fe.result);ce&&(ce.result=q,ce.isError=ge)},async progress(L){r.debug(`[Progress] ${L}`)},async question(L){return r.debug(`[Question] ${L.prompt}`),{selected:[],freeText:null,declined:!0}},async error(L){w.error=L},async done(){w.error||(w.success=!0)}},I=(0,bP.generateRequestId)(),b=E.sessionId??`headless-${Date.now()}`,A=t.provenance?.(),S=(0,vm.wrapEmitterWithObservability)(v,y,b,I,(0,IP.currentCredential)()?.userId,A&&{policy_version:A.policyVersion,pack_digest:A.packDigest,engine_version:A.engineVersion,tier:A.tier,instance_id:A.instanceId}),O={modelId:E.modelId,engineId:E.engineId,workspaceRoot:E.workspaceRoot,additionalDirectories:E.additionalDirectories,sessionId:b,analyticsUserId:RP(E.analyticsUserId,t.analyticsUserId),apiKey:E.modelToken??(e?void 0:t.apiKey),baseUrl:t.baseUrl,useLiteLLM:t.useLiteLLM,agentPackId:c,agentPackVersion:t.packVersion,policyVersion:A?.policyVersion,packDigest:A?.packDigest,engineVersion:A?.engineVersion,tier:A?.tier,instanceId:A?.instanceId,permissions:E.permissions,engineHomeUserKey:E.engineHomeUserKey,requestId:I};await S.emitTurnStart();let M=null;if(t.dataPlane&&!E.turnEnv?.[NP])try{M=await t.dataPlane.beginTurn({sessionKey:b})}catch(L){return w.error=`data-plane turn registration failed: ${L instanceof Error?L.message:String(L)}`,await S.error(w.error),await S.emitTurnEnd(!1),w}let N={...a,cliEnvPatch:{...a.cliEnvPatch??{},...(0,OP.buildSessionEnvPatch)({workspaceRoot:E.workspaceRoot,chatSessionId:b,gatewaySessionKey:E.gatewaySessionKey}),...E.turnEnv??{},...M?.env??{}}};try{let L=E.engineId.trim().toLowerCase();L==="claude"?await g().stream(E.message,O,S,N,E.signal):L==="codex"?await m().stream(E.message,O,S,N,E.signal):await(await h()).stream(E.message,O,S,N,E.signal)}catch(L){w.error=L instanceof Error?L.message:String(L),w.success=!1,await S.error(w.error)}finally{try{await M?.release()}catch{}}return await S.emitTurnEnd(w.success),w},dispose(){u?.dispose(),f?.dispose(),p?.dispose()}}}var CP=ri();Object.defineProperty(ue,"initSessionStoreWithStore",{enumerable:!0,get:function(){return CP.initSessionStoreWithStore}});var Tc=Wu();Object.defineProperty(ue,"syncPackToWorkspace",{enumerable:!0,get:function(){return Tc.syncPackToWorkspace}});Object.defineProperty(ue,"computeSkillsSignature",{enumerable:!0,get:function(){return Tc.computeSkillsSignature}});Object.defineProperty(ue,"createSessionDir",{enumerable:!0,get:function(){return Tc.createSessionDir}});Object.defineProperty(ue,"getSessionDir",{enumerable:!0,get:function(){return Tc.getSessionDir}});var kP=$a();Object.defineProperty(ue,"resolveModelAlias",{enumerable:!0,get:function(){return kP.resolveModelAlias}});function $P(t,e,n){return nd({storagePath:t,apiKey:e,baseUrl:n,freshState:!0,logger:new Lt.NoOpLogger})}function DP(t,e,n){return nd({storagePath:t,apiKey:e,baseUrl:n,logger:new Lt.ConsoleLogger("[Agent]")})}});var gi=T(Vt=>{"use strict";var LP=Vt&&Vt.__createBinding||(Object.create?(function(t,e,n,r){r===void 0&&(r=n);var s=Object.getOwnPropertyDescriptor(e,n);(!s||("get"in s?!e.__esModule:s.writable||s.configurable))&&(s={enumerable:!0,get:function(){return e[n]}}),Object.defineProperty(t,r,s)}):(function(t,e,n,r){r===void 0&&(r=n),t[r]=e[n]})),MP=Vt&&Vt.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),bc=Vt&&Vt.__importStar||(function(){var t=function(e){return t=Object.getOwnPropertyNames||function(n){var r=[];for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(r[r.length]=s);return r},t(e)};return function(e){if(e&&e.__esModule)return e;var n={};if(e!=null)for(var r=t(e),s=0;s<r.length;s++)r[s]!=="default"&&LP(n,e,r[s]);return MP(n,e),n}})();Object.defineProperty(Vt,"__esModule",{value:!0});Vt.resolvePackPath=Im;Vt.listAvailablePacks=jP;Vt.loadAgentPack=xP;Vt.getDefaultConfig=VP;Vt.getEnvDefaultModel=WP;Vt.getApiConfig=Pm;Vt.hasCredentialForEngine=KP;Vt.getFileAccess=qP;var tn=bc(require("fs")),ft=bc(require("path")),GP=bc(require("os")),UP=bc(require("js-yaml")),vc=Je();function Go(t,e){return process.env[t]??(e?process.env[e]:void 0)}var HP=process.env.AGENTHIPPO_HOME||ft.join(GP.homedir(),vc.AGENTIDE_DIR_NAME),sd=ft.join(HP,"agents"),rd="agents";function Vi(t){if(!tn.existsSync(t))return;let e=ft.join(t,"current.txt");if(tn.existsSync(e)){let r=tn.readFileSync(e,"utf-8").trim(),s=ft.join(t,r);if(tn.existsSync(s))return s}let n=ft.join(t,"agent.yaml");if(tn.existsSync(n))return t;try{let s=tn.readdirSync(t,{withFileTypes:!0}).filter(i=>i.isDirectory()&&/^\d+\.\d+\.\d+/.test(i.name)).map(i=>i.name).sort((i,o)=>{let[a,c,l]=i.split(".").map(p=>parseInt(p,10)||0),[d,u,f]=o.split(".").map(p=>parseInt(p,10)||0);return d!==a?d-a:u!==c?u-c:f-l});for(let i of s){let o=ft.join(t,i),a=ft.join(o,"agent.yaml");if(tn.existsSync(a))return o}}catch{}}function Im(t,e){if(ft.isAbsolute(t)||t.startsWith("./")||t.startsWith("../")){let c=ft.isAbsolute(t)?t:ft.resolve(process.cwd(),t);if(tn.existsSync(c)){try{if(tn.statSync(c).isDirectory())return Vi(c)??c}catch{}return c}return}let n=ft.join(process.cwd(),t),r=Vi(n);if(r)return r;let s=ft.join(process.cwd(),rd,t),i=Vi(s);if(i)return i;if(e){let c=ft.join(e,vc.AGENTIDE_DIR_NAME,rd,t),l=Vi(c);if(l)return l}let o=ft.join(sd,t),a=Vi(o);if(a)return a}function Om(t,e){let n=[];if(!tn.existsSync(t))return n;let r=tn.readdirSync(t,{withFileTypes:!0});for(let s of r){if(!s.isDirectory()||s.name.startsWith("."))continue;let i=ft.join(t,s.name),o=Vi(i);if(!o)continue;let a;o!==i&&(a=ft.basename(o)),n.push({name:s.name,path:o,version:a,source:e})}return n}function jP(t){let e=[],n=new Set;if(t){let s=ft.join(t,vc.AGENTIDE_DIR_NAME,rd),i=Om(s,"workspace");for(let o of i)e.push(o),n.add(o.name)}let r=Om(sd,"user-library");for(let s of r)n.has(s.name)||e.push(s);return e}async function xP(t,e){let n=Im(t,e);if(!n){let u=ft.isAbsolute(t)||t.startsWith("./")||t.startsWith("../")?[ft.resolve(process.cwd(),t)]:[`${process.cwd()}/${t}`,`${process.cwd()}/agents/${t}`,e?`${e}/${vc.AGENTIDE_DIR_NAME}/agents/${t}`:null,`${sd}/${t}`].filter(Boolean);throw new Error(`Agent pack not found: ${t}
|
|
418
418
|
Searched: ${u.join(", ")}`)}let r=ft.join(n,"agent.yaml");if(!tn.existsSync(r))throw new Error(`Missing agent.yaml in pack: ${n}`);let s=tn.readFileSync(r,"utf-8"),i=UP.load(s);FP(i,r);let o=BP(i),a="",c=ft.join(n,"AGENTS.md");return tn.existsSync(c)&&(a=tn.readFileSync(c,"utf-8")),{manifest:o,packPath:n,systemPrompt:a,rules:[]}}function BP(t){let e=t.spec.engine?.trim()??"",n=e.toLowerCase();return e!==n?{...t,spec:{...t.spec,engine:n}}:t}function FP(t,e){let n=[];if(t.metadata?.name||n.push("Missing metadata.name"),t.metadata?.version||n.push("Missing metadata.version"),t.spec?.engine?.trim()||n.push("Missing spec.engine"),t.spec?.engine?.trim().toLowerCase()==="custom"&&n.push('Invalid spec.engine: use the concrete custom engine id (for example, openclaw), not "custom"'),t.spec?.cheapModel!==void 0&&typeof t.spec.cheapModel!="string"&&n.push("Invalid spec.cheapModel: must be a string when provided"),t.spec?.dataPlane!==void 0&&((typeof t.spec.dataPlane!="object"||!t.spec.dataPlane.connector?.trim())&&n.push("Invalid spec.dataPlane: requires a `connector` path (stdio MCP module run broker-side)"),t.spec.dataPlane?.provider!==void 0&&typeof t.spec.dataPlane.provider!="string"&&n.push("Invalid spec.dataPlane.provider: must be a string when provided")),n.length>0)throw new Error(`Invalid agent manifest at ${e}:
|
|
419
419
|
- ${n.join(`
|
|
420
|
-
- `)}`)}function VP(){return{engine:(Go("AGENTHIPPO_DEFAULT_ENGINE","AGENTIDE_DEFAULT_ENGINE")||"claude").trim().toLowerCase(),model:Go("AGENTHIPPO_DEFAULT_MODEL","AGENTIDE_DEFAULT_MODEL")||"claude-sonnet-4-5-20250929"}}function WP(){return Go("AGENTHIPPO_DEFAULT_MODEL","AGENTIDE_DEFAULT_MODEL")?.trim()||void 0}function Pm(){let t=Go("AGENTHIPPO_LITELLM_API_KEY","AGENTIDE_LITELLM_API_KEY"),e=Go("AGENTHIPPO_LITELLM_BASE_URL","AGENTIDE_LITELLM_BASE_URL"),n=process.env.ANTHROPIC_API_KEY||process.env.CLAUDE_API_KEY,r=process.env.OPENAI_API_KEY;return{apiKey:t||n||r,baseUrl:e,useLiteLLM:!!e,litellmApiKey:t,openaiApiKey:r,anthropicApiKey:n}}function KP(t,e=Pm()){if(e.useLiteLLM)return!0;let n=t.trim().toLowerCase();return n==="claude"?!!e.anthropicApiKey:n==="codex"?!!e.openaiApiKey:!0}function qP(t){return t?.manifest.spec.permissions?.fileAccess??"workspace-write"}});var Oc=T((fj,YP)=>{YP.exports={name:"agenthippo",displayName:"Agent Hippo",description:"Agent Hippo - The easiest way to build and test your AI agents",version:"1.110.33",agenthippo:{litellmImageTag:"0.2.21",hippoclawNpm:"@agenthippo-ai/hippoclaw@2026.7.28"},publisher:"agenthippo",private:!0,engines:{vscode:"^1.93.0"},enabledApiProposals:["chatParticipantAdditions","chatParticipantPrivate","languageModelThinkingPart"],activationEvents:["onStartupFinished","onCommand:agentide.customEngine.list","onCommand:agentide.engine.install","onCommand:agentide.engine.uninstall","onChatParticipant:agentide.claude","onChatParticipant:agentide.codex"],main:"./out/extension.js",contributes:{authentication:[{id:"agenthippo",label:"AgentHippo"}],chatParticipants:[{id:"agentide.claude",name:"claude",fullName:"Claude Agent",description:"AI coding agent powered by Anthropic's Claude Agent SDK",isSticky:!1},{id:"agentide.codex",name:"codex",fullName:"Codex Agent",description:"AI coding agent powered by OpenAI's Codex SDK",isSticky:!1}],mcpServerDefinitionProviders:[{id:"bundled-mcp-servers",label:"Agent Hippo Bundled MCP Servers"}],commands:[{command:"agentide.skills.syncRemote",title:"Sync Remote Skills",category:"Agent Hippo"},{command:"agentide.clearManagedResources",title:"Clear Managed Resources",category:"Agent Hippo"},{command:"agentide.showManagedResources",title:"Show Managed Resources",category:"Agent Hippo"},{command:"agentide.cleanupSessionLogs",title:"Cleanup Old Session Logs",category:"Agent Hippo"},{command:"agentide.pack.install",title:"Install Agent Pack",category:"Agent Hippo"},{command:"agentide.pack.list",title:"List Installed Packs",category:"Agent Hippo"},{command:"agentide.customEngine.list",title:"List Custom Engines",category:"Agent Hippo"},{command:"agentide.pack.uninstall",title:"Uninstall Agent Pack",category:"Agent Hippo"},{command:"agentide.pack.getActive",title:"Get Active Agent Pack",category:"Agent Hippo"},{command:"agentide.pack.create",title:"Create Agent Pack",category:"Agent Hippo"},{command:"agentide.pack.share",title:"Share Agent to User Library",category:"Agent Hippo"},{command:"agentide.pack.publish",title:"Publish Agent to Store",category:"Agent Hippo"},{command:"agentide.skill.share",title:"Save Skill to User Library",category:"Agent Hippo"},{command:"agentide.skill.publish",title:"Publish Skill to Store",category:"Agent Hippo"},{command:"agentide.mcp.share",title:"Save MCP Server to User Library",category:"Agent Hippo"},{command:"agentide.mcp.publish",title:"Publish MCP Server to Store",category:"Agent Hippo"},{command:"agenthippo.signIn",title:"Sign In to AgentHippo",category:"Agent Hippo"},{command:"agenthippo.signOut",title:"Sign Out of AgentHippo",category:"Agent Hippo"},{command:"agentide.store.find",title:"Install Packs, Skills, MCP Tools, Engines, Spotlight Views",category:"Agent Hippo"},{command:"agentide.engine.install",title:"Install Custom Engine",category:"Agent Hippo"},{command:"agentide.engine.uninstall",title:"Uninstall Custom Engine",category:"Agent Hippo"},{command:"agentide.engine.publish",title:"Publish Engine to Store",category:"Agent Hippo"},{command:"agentide.spotlight.publish",title:"Publish Spotlight View to Store (Full Bundle)",category:"Agent Hippo"},{command:"agentide.view.install",title:"Install Spotlight View",category:"Agent Hippo"},{command:"agentide.store.sync",title:"Sync Store Index",category:"Agent Hippo"},{command:"agentide.store.setup",title:"Setup Store Index Automation",category:"Agent Hippo"},{command:"agentide.pack.browseLibrary",title:"Browse User Library",category:"Agent Hippo"},{command:"agentide.pack.update",title:"Update Agent from User Library",category:"Agent Hippo"},{command:"agentide.pack.duplicate",title:"Duplicate Agent",category:"Agent Hippo"},{command:"agentide.pack.refresh",title:"Refresh Agent Packs",category:"Agent Hippo"},{command:"agentide.pack.resetDefault",title:"Reset Default Agent",category:"Agent Hippo"},{command:"agentide.gateway.connect",title:"Connect to Gateway",category:"Agent Hippo"},{command:"agentide.gateway.disconnect",title:"Disconnect from Gateway",category:"Agent Hippo"},{command:"agentide.gateway.toggle",title:"Toggle Gateway Connection",category:"Agent Hippo"},{command:"agentide.gateway.status",title:"Show Gateway Status",category:"Agent Hippo"},{command:"agentide.gateway.connectSession",title:"Connect Chat to Gateway",category:"Agent Hippo"},{command:"agentide.gateway.listSessions",title:"Show Connected Gateway Sessions",category:"Agent Hippo"},{command:"agentide.gateway.resetMappings",title:"Reset Agent Mappings (Gateway)",category:"Agent Hippo"},{command:"agentide.anywhere.toggle",title:"Agent Anywhere",category:"Agent Hippo"},{command:"agentide.anywhere.install",title:"Install Agent Anywhere (Gateway)",category:"Agent Hippo"},{command:"agentide.anywhere.uninstall",title:"Uninstall Agent Anywhere (OpenClaw CLI)",category:"Agent Hippo"},{command:"agentide.anywhere.start",title:"Start Agent Anywhere",category:"Agent Hippo"},{command:"agentide.anywhere.stop",title:"Stop Agent Anywhere",category:"Agent Hippo"},{command:"agentide.anywhere.status",title:"Agent Anywhere Status",category:"Agent Hippo"},{command:"agentide.anywhere.connect",title:"Connect Agent Anywhere",category:"Agent Hippo"},{command:"agentide.anywhere.disconnect",title:"Disconnect Agent Anywhere",category:"Agent Hippo"},{command:"agentide.anywhere.openConfig",title:"Open Agent Anywhere Config",category:"Agent Hippo"},{command:"agentide.anywhere.openWebUI",title:"Open Agent Anywhere Web UI",category:"Agent Hippo"},{command:"agentide.anywhere.detect",title:"Detect Agent Anywhere Gateway",category:"Agent Hippo"},{command:"agentide.anywhere.meetAgent",title:"Meet Agent Anywhere...",category:"Agent Hippo"},{command:"agentide.setupCli",title:"Setup AgentHippo CLI",category:"Agent Hippo"},{command:"agentide.cli.status",title:"AgentHippo CLI Status",category:"Agent Hippo"},{command:"agentide.installBundledTools",title:"Install Bundled Tools (rg, sg, tree-sitter)",category:"Agent Hippo"},{command:"agentide.setupAnalytics",title:"Install Spotlight (OTEL + DuckDB)",category:"Agent Hippo"},{command:"agentide.analytics.toggle",title:"Manage Spotlight",category:"Agent Hippo"},{command:"agentide.analytics.start",title:"Start Spotlight (OTEL + LiteLLM)",category:"Agent Hippo"},{command:"agentide.analytics.stop",title:"Stop Spotlight (OTEL + LiteLLM)",category:"Agent Hippo"},{command:"agentide.analytics.status",title:"Show Spotlight Status",category:"Agent Hippo"},{command:"agentide.analytics.query",title:"Query Spotlight (Cost, Sessions)",category:"Agent Hippo"},{command:"agentide.analytics.openDashboard",title:"Open Spotlight Dashboard",category:"Agent Hippo"},{command:"agentide.fleet.open",title:"Open Agent Team",category:"Agent Hippo"},{command:"agentide.analytics.clearArtifacts",title:"Clear Spotlight Artifacts",category:"Agent Hippo"},{command:"agentide.analytics.regenerateDefaults",title:"Regenerate Default Charts",category:"Agent Hippo"}],menus:{ChatModePicker:[{command:"agentide.anywhere.meetAgent",group:"navigation@30",when:"agentide.anywhere.enabled && !agentide.anywhere.hidden",icon:"$(broadcast)"}]},viewsContainers:{activitybar:[{id:"agentide-analytics",title:"Agent Hippo",icon:"$(graph)"},{id:"agentide-team",title:"Agent Team",icon:"$(organization)"}]},views:{"agentide-analytics":[{type:"webview",id:"agentide.analyticsView",name:"Spotlight"}],"agentide-team":[{type:"webview",id:"agentide.teamView",name:"Agent Team"}]},configuration:{title:"Agent Hippo",properties:{"agentide.permissions.fileAccess":{type:"string",scope:"application",enum:["read-only","workspace-write","full"],default:"full",markdownDescription:"Filesystem access scope (applies to all engines).\n- `read-only`: Read/search only (no file writes)\n- `workspace-write`: Read/write within workspace folders only\n- `full`: Full filesystem access (yolo, default)\n\n**Security**: Agent manifest permissions take precedence - user cannot override stricter pack permissions."},"agentide.claude.maxThinkingTokens":{type:"number",default:1024,description:"Claude extended thinking budget (tokens). Set to 0 to disable. Requires a compatible model; Anthropic requires >=1024 for extended thinking."},"agentide.claude.cheapModel":{type:"string",default:"",description:"Optional cheap Claude model for subagents/background routing (for example, claude-haiku-4-5-20251001). Main model selection still comes from the model picker."},"agentide.sessions.retentionDays":{type:"number",default:7,minimum:1,maximum:365,description:"Number of days to retain session logs before cleanup. Cleanup runs on startup (best-effort) and via the 'Agent Hippo: Cleanup Old Session Logs' command."},"agentide.fallbackDirectory":{type:"string",scope:"machine",default:".agent-hippo",description:"Directory name (relative to home) used as workspace when no folder is open. Default: ~/.agent-hippo"},"agentide.additionalEngineDir":{type:"string",scope:"machine",default:"",description:"Additional directories to scan for custom engines. Machine-scoped: engines discovered here are executed, so a workspace must not be able to point this at attacker-controlled code."},"agentide.auth.baseUrl":{type:"string",scope:"application",default:"https://auth.agenthippo.ai",markdownDescription:"AgentHippo auth broker base URL for team sign-in and bootstrap (`agenthippo.signIn`).\n\n**Application-scoped on purpose**: this endpoint receives your PKCE authorization code and your AgentHippo access token, and its `/api/ide/bootstrap` response is written into your model-routing settings. A workspace must never be able to redirect it. Must be `https://` (plain `http://` is accepted only for loopback dev hosts)."},"agentide.cli.path":{type:"string",scope:"machine",default:"",description:"Optional absolute path to the AgentHippo CLI binary. If unset, Agent Hippo auto-detects a bundled binary or falls back to PATH. Machine-scoped: this path is executed."},"agentide.cli.installSource":{type:"string",scope:"machine",default:"",description:"Optional setup source for AgentHippo CLI. Supports HTTPS URL to a prebuilt binary, or local file path. If empty, setup builds from the local repository. Machine-scoped: this source is downloaded and executed."},"agentide.storeRepo":{type:"string",scope:"application",default:"agenthippoai/agenthippo-store",markdownDescription:"GitHub repository for pack store (owner/repo format).\n\nDefault: `agenthippoai/agenthippo-store` ([github.com/agenthippoai/agenthippo-store](https://github.com/agenthippoai/agenthippo-store))\n\nSet to your own repo (e.g., `mycompany/our-packs`) to use a private or custom store."},"agentide.store.indexUrl":{type:"string",scope:"application",default:"https://agenthippoai.github.io/agenthippo-store",markdownDescription:`Base URL for the store index (Orama + metadata are loaded from paths under this URL).
|
|
420
|
+
- `)}`)}function VP(){return{engine:(Go("AGENTHIPPO_DEFAULT_ENGINE","AGENTIDE_DEFAULT_ENGINE")||"claude").trim().toLowerCase(),model:Go("AGENTHIPPO_DEFAULT_MODEL","AGENTIDE_DEFAULT_MODEL")||"claude-sonnet-4-5-20250929"}}function WP(){return Go("AGENTHIPPO_DEFAULT_MODEL","AGENTIDE_DEFAULT_MODEL")?.trim()||void 0}function Pm(){let t=Go("AGENTHIPPO_LITELLM_API_KEY","AGENTIDE_LITELLM_API_KEY"),e=Go("AGENTHIPPO_LITELLM_BASE_URL","AGENTIDE_LITELLM_BASE_URL"),n=process.env.ANTHROPIC_API_KEY||process.env.CLAUDE_API_KEY,r=process.env.OPENAI_API_KEY;return{apiKey:t||n||r,baseUrl:e,useLiteLLM:!!e,litellmApiKey:t,openaiApiKey:r,anthropicApiKey:n}}function KP(t,e=Pm()){if(e.useLiteLLM)return!0;let n=t.trim().toLowerCase();return n==="claude"?!!e.anthropicApiKey:n==="codex"?!!e.openaiApiKey:!0}function qP(t){return t?.manifest.spec.permissions?.fileAccess??"workspace-write"}});var Oc=T((fj,YP)=>{YP.exports={name:"agenthippo",displayName:"Agent Hippo",description:"Agent Hippo - The easiest way to build and test your AI agents",version:"1.110.34",agenthippo:{litellmImageTag:"0.2.21",hippoclawNpm:"@agenthippo-ai/hippoclaw@2026.7.28"},publisher:"agenthippo",private:!0,engines:{vscode:"^1.93.0"},enabledApiProposals:["chatParticipantAdditions","chatParticipantPrivate","languageModelThinkingPart"],activationEvents:["onStartupFinished","onCommand:agentide.customEngine.list","onCommand:agentide.engine.install","onCommand:agentide.engine.uninstall","onChatParticipant:agentide.claude","onChatParticipant:agentide.codex"],main:"./out/extension.js",contributes:{authentication:[{id:"agenthippo",label:"AgentHippo"}],chatParticipants:[{id:"agentide.claude",name:"claude",fullName:"Claude Agent",description:"AI coding agent powered by Anthropic's Claude Agent SDK",isSticky:!1},{id:"agentide.codex",name:"codex",fullName:"Codex Agent",description:"AI coding agent powered by OpenAI's Codex SDK",isSticky:!1}],mcpServerDefinitionProviders:[{id:"bundled-mcp-servers",label:"Agent Hippo Bundled MCP Servers"}],commands:[{command:"agentide.skills.syncRemote",title:"Sync Remote Skills",category:"Agent Hippo"},{command:"agentide.clearManagedResources",title:"Clear Managed Resources",category:"Agent Hippo"},{command:"agentide.showManagedResources",title:"Show Managed Resources",category:"Agent Hippo"},{command:"agentide.cleanupSessionLogs",title:"Cleanup Old Session Logs",category:"Agent Hippo"},{command:"agentide.pack.install",title:"Install Agent Pack",category:"Agent Hippo"},{command:"agentide.pack.list",title:"List Installed Packs",category:"Agent Hippo"},{command:"agentide.customEngine.list",title:"List Custom Engines",category:"Agent Hippo"},{command:"agentide.pack.uninstall",title:"Uninstall Agent Pack",category:"Agent Hippo"},{command:"agentide.pack.getActive",title:"Get Active Agent Pack",category:"Agent Hippo"},{command:"agentide.pack.create",title:"Create Agent Pack",category:"Agent Hippo"},{command:"agentide.pack.share",title:"Share Agent to User Library",category:"Agent Hippo"},{command:"agentide.pack.publish",title:"Publish Agent to Store",category:"Agent Hippo"},{command:"agentide.skill.share",title:"Save Skill to User Library",category:"Agent Hippo"},{command:"agentide.skill.publish",title:"Publish Skill to Store",category:"Agent Hippo"},{command:"agentide.mcp.share",title:"Save MCP Server to User Library",category:"Agent Hippo"},{command:"agentide.mcp.publish",title:"Publish MCP Server to Store",category:"Agent Hippo"},{command:"agenthippo.signIn",title:"Sign In to AgentHippo",category:"Agent Hippo"},{command:"agenthippo.signOut",title:"Sign Out of AgentHippo",category:"Agent Hippo"},{command:"agentide.store.find",title:"Install Packs, Skills, MCP Tools, Engines, Spotlight Views",category:"Agent Hippo"},{command:"agentide.engine.install",title:"Install Custom Engine",category:"Agent Hippo"},{command:"agentide.engine.uninstall",title:"Uninstall Custom Engine",category:"Agent Hippo"},{command:"agentide.engine.publish",title:"Publish Engine to Store",category:"Agent Hippo"},{command:"agentide.spotlight.publish",title:"Publish Spotlight View to Store (Full Bundle)",category:"Agent Hippo"},{command:"agentide.view.install",title:"Install Spotlight View",category:"Agent Hippo"},{command:"agentide.store.sync",title:"Sync Store Index",category:"Agent Hippo"},{command:"agentide.store.setup",title:"Setup Store Index Automation",category:"Agent Hippo"},{command:"agentide.pack.browseLibrary",title:"Browse User Library",category:"Agent Hippo"},{command:"agentide.pack.update",title:"Update Agent from User Library",category:"Agent Hippo"},{command:"agentide.pack.duplicate",title:"Duplicate Agent",category:"Agent Hippo"},{command:"agentide.pack.refresh",title:"Refresh Agent Packs",category:"Agent Hippo"},{command:"agentide.pack.resetDefault",title:"Reset Default Agent",category:"Agent Hippo"},{command:"agentide.gateway.connect",title:"Connect to Gateway",category:"Agent Hippo"},{command:"agentide.gateway.disconnect",title:"Disconnect from Gateway",category:"Agent Hippo"},{command:"agentide.gateway.toggle",title:"Toggle Gateway Connection",category:"Agent Hippo"},{command:"agentide.gateway.status",title:"Show Gateway Status",category:"Agent Hippo"},{command:"agentide.gateway.connectSession",title:"Connect Chat to Gateway",category:"Agent Hippo"},{command:"agentide.gateway.listSessions",title:"Show Connected Gateway Sessions",category:"Agent Hippo"},{command:"agentide.gateway.resetMappings",title:"Reset Agent Mappings (Gateway)",category:"Agent Hippo"},{command:"agentide.anywhere.toggle",title:"Agent Anywhere",category:"Agent Hippo"},{command:"agentide.anywhere.install",title:"Install Agent Anywhere (Gateway)",category:"Agent Hippo"},{command:"agentide.anywhere.uninstall",title:"Uninstall Agent Anywhere (OpenClaw CLI)",category:"Agent Hippo"},{command:"agentide.anywhere.start",title:"Start Agent Anywhere",category:"Agent Hippo"},{command:"agentide.anywhere.stop",title:"Stop Agent Anywhere",category:"Agent Hippo"},{command:"agentide.anywhere.status",title:"Agent Anywhere Status",category:"Agent Hippo"},{command:"agentide.anywhere.connect",title:"Connect Agent Anywhere",category:"Agent Hippo"},{command:"agentide.anywhere.disconnect",title:"Disconnect Agent Anywhere",category:"Agent Hippo"},{command:"agentide.anywhere.openConfig",title:"Open Agent Anywhere Config",category:"Agent Hippo"},{command:"agentide.anywhere.openWebUI",title:"Open Agent Anywhere Web UI",category:"Agent Hippo"},{command:"agentide.anywhere.detect",title:"Detect Agent Anywhere Gateway",category:"Agent Hippo"},{command:"agentide.anywhere.meetAgent",title:"Meet Agent Anywhere...",category:"Agent Hippo"},{command:"agentide.setupCli",title:"Setup AgentHippo CLI",category:"Agent Hippo"},{command:"agentide.cli.status",title:"AgentHippo CLI Status",category:"Agent Hippo"},{command:"agentide.installBundledTools",title:"Install Bundled Tools (rg, sg, tree-sitter)",category:"Agent Hippo"},{command:"agentide.setupAnalytics",title:"Install Spotlight (OTEL + DuckDB)",category:"Agent Hippo"},{command:"agentide.analytics.toggle",title:"Manage Spotlight",category:"Agent Hippo"},{command:"agentide.analytics.start",title:"Start Spotlight (OTEL + LiteLLM)",category:"Agent Hippo"},{command:"agentide.analytics.stop",title:"Stop Spotlight (OTEL + LiteLLM)",category:"Agent Hippo"},{command:"agentide.analytics.status",title:"Show Spotlight Status",category:"Agent Hippo"},{command:"agentide.analytics.query",title:"Query Spotlight (Cost, Sessions)",category:"Agent Hippo"},{command:"agentide.analytics.openDashboard",title:"Open Spotlight Dashboard",category:"Agent Hippo"},{command:"agentide.fleet.open",title:"Open Agent Team",category:"Agent Hippo"},{command:"agentide.analytics.clearArtifacts",title:"Clear Spotlight Artifacts",category:"Agent Hippo"},{command:"agentide.analytics.regenerateDefaults",title:"Regenerate Default Charts",category:"Agent Hippo"}],menus:{ChatModePicker:[{command:"agentide.anywhere.meetAgent",group:"navigation@30",when:"agentide.anywhere.enabled && !agentide.anywhere.hidden",icon:"$(broadcast)"}]},viewsContainers:{activitybar:[{id:"agentide-analytics",title:"Agent Hippo",icon:"$(graph)"},{id:"agentide-team",title:"Agent Team",icon:"$(organization)"}]},views:{"agentide-analytics":[{type:"webview",id:"agentide.analyticsView",name:"Spotlight"}],"agentide-team":[{type:"webview",id:"agentide.teamView",name:"Agent Team"}]},configuration:{title:"Agent Hippo",properties:{"agentide.permissions.fileAccess":{type:"string",scope:"application",enum:["read-only","workspace-write","full"],default:"full",markdownDescription:"Filesystem access scope (applies to all engines).\n- `read-only`: Read/search only (no file writes)\n- `workspace-write`: Read/write within workspace folders only\n- `full`: Full filesystem access (yolo, default)\n\n**Security**: Agent manifest permissions take precedence - user cannot override stricter pack permissions."},"agentide.claude.maxThinkingTokens":{type:"number",default:1024,description:"Claude extended thinking budget (tokens). Set to 0 to disable. Requires a compatible model; Anthropic requires >=1024 for extended thinking."},"agentide.claude.cheapModel":{type:"string",default:"",description:"Optional cheap Claude model for subagents/background routing (for example, claude-haiku-4-5-20251001). Main model selection still comes from the model picker."},"agentide.sessions.retentionDays":{type:"number",default:7,minimum:1,maximum:365,description:"Number of days to retain session logs before cleanup. Cleanup runs on startup (best-effort) and via the 'Agent Hippo: Cleanup Old Session Logs' command."},"agentide.fallbackDirectory":{type:"string",scope:"machine",default:".agent-hippo",description:"Directory name (relative to home) used as workspace when no folder is open. Default: ~/.agent-hippo"},"agentide.additionalEngineDir":{type:"string",scope:"machine",default:"",description:"Additional directories to scan for custom engines. Machine-scoped: engines discovered here are executed, so a workspace must not be able to point this at attacker-controlled code."},"agentide.auth.baseUrl":{type:"string",scope:"application",default:"https://auth.agenthippo.ai",markdownDescription:"AgentHippo auth broker base URL for team sign-in and bootstrap (`agenthippo.signIn`).\n\n**Application-scoped on purpose**: this endpoint receives your PKCE authorization code and your AgentHippo access token, and its `/api/ide/bootstrap` response is written into your model-routing settings. A workspace must never be able to redirect it. Must be `https://` (plain `http://` is accepted only for loopback dev hosts)."},"agentide.cli.path":{type:"string",scope:"machine",default:"",description:"Optional absolute path to the AgentHippo CLI binary. If unset, Agent Hippo auto-detects a bundled binary or falls back to PATH. Machine-scoped: this path is executed."},"agentide.cli.installSource":{type:"string",scope:"machine",default:"",description:"Optional setup source for AgentHippo CLI. Supports HTTPS URL to a prebuilt binary, or local file path. If empty, setup builds from the local repository. Machine-scoped: this source is downloaded and executed."},"agentide.storeRepo":{type:"string",scope:"application",default:"agenthippoai/agenthippo-store",markdownDescription:"GitHub repository for pack store (owner/repo format).\n\nDefault: `agenthippoai/agenthippo-store` ([github.com/agenthippoai/agenthippo-store](https://github.com/agenthippoai/agenthippo-store))\n\nSet to your own repo (e.g., `mycompany/our-packs`) to use a private or custom store."},"agentide.store.indexUrl":{type:"string",scope:"application",default:"https://agenthippoai.github.io/agenthippo-store",markdownDescription:`Base URL for the store index (Orama + metadata are loaded from paths under this URL).
|
|
421
421
|
|
|
422
422
|
Default: \`https://agenthippoai.github.io/agenthippo-store\`
|
|
423
423
|
|
|
@@ -48,7 +48,7 @@ def _parse_attr_dict(value: Any) -> Any:
|
|
|
48
48
|
return None
|
|
49
49
|
|
|
50
50
|
def _allowlisted_headers(headers: dict) -> dict:
|
|
51
|
-
return {k.lower(): v for k, v in headers.items() if isinstance(k, str) and k.lower() in _METADATA_HEADER_ALLOWLIST}
|
|
51
|
+
return {k.lower(): v for (k, v) in headers.items() if isinstance(k, str) and k.lower() in _METADATA_HEADER_ALLOWLIST}
|
|
52
52
|
|
|
53
53
|
def _filtered_metadata_headers(value: Any) -> str | None:
|
|
54
54
|
headers = _parse_attr_dict(value)
|
|
@@ -94,7 +94,7 @@ class _RedactingSpan:
|
|
|
94
94
|
|
|
95
95
|
def set_attributes(self, attributes: Any) -> Any:
|
|
96
96
|
if isinstance(attributes, dict):
|
|
97
|
-
for key, value in attributes.items():
|
|
97
|
+
for (key, value) in attributes.items():
|
|
98
98
|
self.set_attribute(key, value)
|
|
99
99
|
return None
|
|
100
100
|
return self._span.set_attributes(attributes)
|
|
@@ -102,7 +102,7 @@ class _RedactingSpan:
|
|
|
102
102
|
def add_event(self, name: Any, attributes: Any=None, **kwargs: Any) -> Any:
|
|
103
103
|
if isinstance(attributes, dict):
|
|
104
104
|
filtered = {}
|
|
105
|
-
for key, value in attributes.items():
|
|
105
|
+
for (key, value) in attributes.items():
|
|
106
106
|
if key == _REQUESTER_METADATA_KEY:
|
|
107
107
|
scrubbed = _scrub_requester_metadata(value)
|
|
108
108
|
if scrubbed is not None:
|
|
@@ -453,7 +453,7 @@ def strip_empty_thinking_blocks(messages: list[Any]) -> list[Any]:
|
|
|
453
453
|
if cleaned.get('role') == 'assistant' and 'reasoning_content' in cleaned:
|
|
454
454
|
rc = cleaned['reasoning_content']
|
|
455
455
|
if not rc or (isinstance(rc, str) and (not rc.strip())):
|
|
456
|
-
cleaned = {k: v for k, v in cleaned.items() if k != 'reasoning_content'}
|
|
456
|
+
cleaned = {k: v for (k, v) in cleaned.items() if k != 'reasoning_content'}
|
|
457
457
|
content = cleaned.get('content')
|
|
458
458
|
if isinstance(content, list):
|
|
459
459
|
original_len = len(content)
|
|
@@ -140,7 +140,7 @@ def run_query(duckdb_path, traces_dir, sql_after_cte, trace_filter_clause=''):
|
|
|
140
140
|
def chart_daily_costs(plt, data, output_dir):
|
|
141
141
|
if not data:
|
|
142
142
|
return None
|
|
143
|
-
fig, ax = plt.subplots()
|
|
143
|
+
(fig, ax) = plt.subplots()
|
|
144
144
|
dates = [r['date'] for r in data]
|
|
145
145
|
costs = [float(r['cost'] or 0) for r in data]
|
|
146
146
|
display_dates = [d[5:] for d in dates]
|
|
@@ -162,7 +162,7 @@ def chart_daily_costs(plt, data, output_dir):
|
|
|
162
162
|
def chart_model_breakdown(plt, data, output_dir):
|
|
163
163
|
if not data:
|
|
164
164
|
return None
|
|
165
|
-
fig, ax = plt.subplots()
|
|
165
|
+
(fig, ax) = plt.subplots()
|
|
166
166
|
models = [r['model'] or 'unknown' for r in data]
|
|
167
167
|
costs = [float(r['cost'] or 0) for r in data]
|
|
168
168
|
requests = [int(r['requests'] or 0) for r in data]
|
|
@@ -173,7 +173,7 @@ def chart_model_breakdown(plt, data, output_dir):
|
|
|
173
173
|
name = name[:18] + '..'
|
|
174
174
|
short_names.append(name)
|
|
175
175
|
colors = ACCENT_COLORS[:len(models)]
|
|
176
|
-
wedges, texts, autotexts = ax.pie(costs, labels=short_names, colors=colors, autopct='%1.0f%%', pctdistance=0.8, startangle=90, wedgeprops=dict(width=0.5, edgecolor=BG_COLOR, linewidth=2))
|
|
176
|
+
(wedges, texts, autotexts) = ax.pie(costs, labels=short_names, colors=colors, autopct='%1.0f%%', pctdistance=0.8, startangle=90, wedgeprops=dict(width=0.5, edgecolor=BG_COLOR, linewidth=2))
|
|
177
177
|
for t in texts:
|
|
178
178
|
t.set_color(FG_COLOR)
|
|
179
179
|
t.set_fontsize(9)
|
|
@@ -192,7 +192,7 @@ def chart_model_breakdown(plt, data, output_dir):
|
|
|
192
192
|
def chart_top_sessions(plt, data, output_dir):
|
|
193
193
|
if not data:
|
|
194
194
|
return None
|
|
195
|
-
fig, ax = plt.subplots()
|
|
195
|
+
(fig, ax) = plt.subplots()
|
|
196
196
|
data = data[:8]
|
|
197
197
|
session_ids = [format_session_handle(r.get('session_id')) for r in data]
|
|
198
198
|
costs = [float(r['cost'] or 0) for r in data]
|
|
@@ -206,7 +206,7 @@ def chart_top_sessions(plt, data, output_dir):
|
|
|
206
206
|
ax.set_xlabel('Cost ($)')
|
|
207
207
|
ax.set_title('Top Sessions by Cost')
|
|
208
208
|
ax.xaxis.set_major_formatter(plt.FuncFormatter(lambda x, _: f'${x:.4f}'))
|
|
209
|
-
for i, (bar, req) in enumerate(zip(bars, requests)):
|
|
209
|
+
for (i, (bar, req)) in enumerate(zip(bars, requests)):
|
|
210
210
|
ax.text(bar.get_width() + max(costs) * 0.02, bar.get_y() + bar.get_height() / 2, f'{req} req', va='center', fontsize=8, color=FG_COLOR)
|
|
211
211
|
plt.tight_layout()
|
|
212
212
|
path = os.path.join(output_dir, 'top-sessions.png')
|
|
@@ -217,7 +217,7 @@ def chart_top_sessions(plt, data, output_dir):
|
|
|
217
217
|
def chart_token_efficiency(plt, data, output_dir):
|
|
218
218
|
if not data:
|
|
219
219
|
return None
|
|
220
|
-
fig, ax = plt.subplots()
|
|
220
|
+
(fig, ax) = plt.subplots()
|
|
221
221
|
models = [r['model'] or 'unknown' for r in data]
|
|
222
222
|
input_t = [int(r['input_tokens'] or 0) for r in data]
|
|
223
223
|
output_t = [int(r['output_tokens'] or 0) for r in data]
|
|
@@ -250,7 +250,7 @@ def chart_token_efficiency(plt, data, output_dir):
|
|
|
250
250
|
def chart_latency_distribution(plt, data, output_dir):
|
|
251
251
|
if not data:
|
|
252
252
|
return None
|
|
253
|
-
fig, ax = plt.subplots()
|
|
253
|
+
(fig, ax) = plt.subplots()
|
|
254
254
|
models = [r['model'] or 'unknown' for r in data]
|
|
255
255
|
p50 = [float(r['p50'] or 0) for r in data]
|
|
256
256
|
p95 = [float(r['p95'] or 0) for r in data]
|
|
@@ -281,13 +281,13 @@ def chart_latency_distribution(plt, data, output_dir):
|
|
|
281
281
|
def chart_hourly_activity(plt, data, output_dir):
|
|
282
282
|
if not data:
|
|
283
283
|
return None
|
|
284
|
-
fig, ax = plt.subplots()
|
|
284
|
+
(fig, ax) = plt.subplots()
|
|
285
285
|
hours = [int(r['hour']) for r in data]
|
|
286
286
|
counts = [int(r['count'] or 0) for r in data]
|
|
287
287
|
costs = [float(r['cost'] or 0) for r in data]
|
|
288
288
|
hour_counts = [0] * 24
|
|
289
289
|
hour_costs = [0.0] * 24
|
|
290
|
-
for h, c, co in zip(hours, counts, costs):
|
|
290
|
+
for (h, c, co) in zip(hours, counts, costs):
|
|
291
291
|
if 0 <= h < 24:
|
|
292
292
|
hour_counts[h] = c
|
|
293
293
|
hour_costs[h] = co
|
|
@@ -342,7 +342,7 @@ def main():
|
|
|
342
342
|
else:
|
|
343
343
|
sys.stderr.write('[Dashboard] Indexed DB unavailable; falling back to JSONL mode\n')
|
|
344
344
|
chart_dir_override = os.environ.get('AGENTIDE_CHART_DIR', '').strip()
|
|
345
|
-
conn, conn_error = open_duckdb_connection(traces_dir, use_indexed_db, index_db_path, trace_filter_clause)
|
|
345
|
+
(conn, conn_error) = open_duckdb_connection(traces_dir, use_indexed_db, index_db_path, trace_filter_clause)
|
|
346
346
|
if conn is None:
|
|
347
347
|
print(json.dumps({'status': 'error', 'error': conn_error}))
|
|
348
348
|
sys.exit(1)
|
|
@@ -137,7 +137,7 @@ def get_changed_files(conn, traces_dir: Path) -> list[Path]:
|
|
|
137
137
|
changed: list[Path] = []
|
|
138
138
|
for jsonl_file in sorted(traces_dir.glob('*.jsonl')):
|
|
139
139
|
try:
|
|
140
|
-
mtime_ms, size_bytes = get_file_stats(jsonl_file)
|
|
140
|
+
(mtime_ms, size_bytes) = get_file_stats(jsonl_file)
|
|
141
141
|
except OSError:
|
|
142
142
|
continue
|
|
143
143
|
key = str(jsonl_file)
|
|
@@ -235,14 +235,14 @@ def _normalize_messages(payload: Any, default_role: str) -> list[dict[str, Any]]
|
|
|
235
235
|
def _tool_call_id(session_id: str | None, trace_id: str, call_id: str | None, idx: int) -> str:
|
|
236
236
|
if call_id:
|
|
237
237
|
return call_id
|
|
238
|
-
seed = f
|
|
238
|
+
seed = f"{session_id or ''}|{trace_id}|tool|{idx}"
|
|
239
239
|
return hashlib.sha1(seed.encode('utf-8')).hexdigest()
|
|
240
240
|
|
|
241
241
|
def extract_messages_and_tools(conn) -> None:
|
|
242
242
|
rows = conn.execute('\n SELECT\n model_call_id,\n trace_id,\n span_id,\n session_id,\n turn_id,\n request_id,\n start_ms,\n end_ms,\n status,\n error_type,\n error_message,\n input_messages_raw,\n output_messages_raw,\n span_tool_name,\n span_tool_call_id,\n span_tool_arguments_raw,\n span_tool_result_raw\n FROM tmp_model_calls\n ').fetchall()
|
|
243
243
|
tool_results_by_id: dict[str, dict[str, Any]] = {}
|
|
244
244
|
for row in rows:
|
|
245
|
-
model_call_id, trace_id, span_id, session_id, turn_id, request_id, start_ms, end_ms, call_status, call_error_type, call_error_message, input_raw, output_raw, span_tool_name, span_tool_call_id, span_tool_arguments_raw, span_tool_result_raw = row
|
|
245
|
+
(model_call_id, trace_id, span_id, session_id, turn_id, request_id, start_ms, end_ms, call_status, call_error_type, call_error_message, input_raw, output_raw, span_tool_name, span_tool_call_id, span_tool_arguments_raw, span_tool_result_raw) = row
|
|
246
246
|
tool_call_inserted = False
|
|
247
247
|
tool_base_ts = int(end_ms) if end_ms is not None else int(start_ms) if start_ms is not None else 0
|
|
248
248
|
if span_tool_name:
|
|
@@ -266,10 +266,10 @@ def extract_messages_and_tools(conn) -> None:
|
|
|
266
266
|
tool_results_by_id[str(span_tool_call_id)]['result_json'] = _to_json_text(span_tool_result_raw)
|
|
267
267
|
input_messages = _normalize_messages(input_raw, 'user')
|
|
268
268
|
output_messages = _normalize_messages(output_raw, 'assistant')
|
|
269
|
-
for i, msg in enumerate(input_messages):
|
|
269
|
+
for (i, msg) in enumerate(input_messages):
|
|
270
270
|
content = msg.get('content', msg.get('parts', msg.get('text', '')))
|
|
271
271
|
if isinstance(content, list):
|
|
272
|
-
for j, block in enumerate(content):
|
|
272
|
+
for (j, block) in enumerate(content):
|
|
273
273
|
if not isinstance(block, dict):
|
|
274
274
|
continue
|
|
275
275
|
block_type = str(block.get('type', '')).lower()
|
|
@@ -279,7 +279,7 @@ def extract_messages_and_tools(conn) -> None:
|
|
|
279
279
|
if not call_id:
|
|
280
280
|
continue
|
|
281
281
|
tool_results_by_id[str(call_id)] = {'result_json': _to_json_text(block.get('content', block.get('result'))), 'result_text': _extract_text_content(block.get('content', block.get('result'))), 'status': 'ok', 'updated_at_ms': int(start_ms) + j if start_ms is not None else 0}
|
|
282
|
-
for i, msg in enumerate(output_messages):
|
|
282
|
+
for (i, msg) in enumerate(output_messages):
|
|
283
283
|
content = msg.get('content', msg.get('parts', msg.get('text', '')))
|
|
284
284
|
output_ts = int(end_ms) if end_ms is not None else int(start_ms) if start_ms is not None else 0
|
|
285
285
|
tool_blocks: list[dict[str, Any]] = []
|
|
@@ -297,7 +297,7 @@ def extract_messages_and_tools(conn) -> None:
|
|
|
297
297
|
tool_blocks.append({'type': 'function_call', 'function': function_call})
|
|
298
298
|
if not tool_blocks:
|
|
299
299
|
continue
|
|
300
|
-
for j, block in enumerate(tool_blocks):
|
|
300
|
+
for (j, block) in enumerate(tool_blocks):
|
|
301
301
|
if not isinstance(block, dict):
|
|
302
302
|
continue
|
|
303
303
|
block_type = str(block.get('type', '')).lower()
|
|
@@ -357,7 +357,7 @@ def ingest_single_jsonl_file(conn, jsonl_file: Path) -> None:
|
|
|
357
357
|
conn.execute('\n UPDATE turns AS t\n SET turn_index = ranked.turn_index\n FROM (\n SELECT\n turn_id,\n row_number() OVER (PARTITION BY session_id ORDER BY started_at, turn_id) - 1 AS turn_index\n FROM turns\n WHERE session_id IN (SELECT session_id FROM tmp_touched_sessions)\n ) ranked\n WHERE t.turn_id = ranked.turn_id\n ')
|
|
358
358
|
|
|
359
359
|
def upsert_processed_file(conn, jsonl_file: Path) -> None:
|
|
360
|
-
mtime_ms, size_bytes = get_file_stats(jsonl_file)
|
|
360
|
+
(mtime_ms, size_bytes) = get_file_stats(jsonl_file)
|
|
361
361
|
conn.execute('\n INSERT INTO processed_files (file_path, mtime_ms, size_bytes, processed_at)\n VALUES (?, ?, ?, now())\n ON CONFLICT(file_path) DO UPDATE SET\n mtime_ms = excluded.mtime_ms,\n size_bytes = excluded.size_bytes,\n processed_at = excluded.processed_at\n ', [str(jsonl_file), mtime_ms, size_bytes])
|
|
362
362
|
|
|
363
363
|
def main() -> int:
|
|
@@ -424,7 +424,7 @@ def main() -> int:
|
|
|
424
424
|
log.debug(f'Ingestion complete. Total model_calls: {total_records}')
|
|
425
425
|
conn.close()
|
|
426
426
|
log.info(f'Indexing complete: {db_path}')
|
|
427
|
-
print(json.dumps({'status': 'ok', 'indexed': True, 'message': f
|
|
427
|
+
print(json.dumps({'status': 'ok', 'indexed': True, 'message': f"Indexed {len(changed_files)} changed file(s) at {state['indexedAt']}"}))
|
|
428
428
|
return 0
|
|
429
429
|
except Exception as e:
|
|
430
430
|
log.error(f'Indexing failed: {e}')
|
package/package.json
CHANGED