@whoz-oss/coday-server 0.91.0 → 0.91.1
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/package.json +1 -1
- package/server.js +3 -3
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -1046,7 +1046,7 @@ Summary:
|
|
|
1046
1046
|
- Unique projects used: ${new Set(t.flatMap(u=>Array.from(u.projects))).size}`;return o+`
|
|
1047
1047
|
`+s.join(`
|
|
1048
1048
|
`)+c}};var IE=class extends Gn{constructor(t,n){super({commandWord:"stats",description:"Show usage statistics and analytics",isInternal:!0},t);this.services=n;this.handlers=[new PE(this.interactor,this.services),new DE(this.interactor,this.services)]}};var cat=100,OE=class{constructor(e,t,n,i){this.interactor=e;this.aiHandler=t;this.configHandler=n;this.services=i}handlers=[];maxIterations=cat;killed=!1;processing=!1;async init(e){try{let t=new Nx(this.interactor),n=new SE(this.interactor,this.services);if(this.handlers=[this.configHandler,new OS(this.interactor),new fw(this.interactor),t,n,new X_(this.interactor),new TE(this.interactor),new IE(this.interactor,this.services)],e?.prompts)for(let[i,a]of Object.entries(e.prompts))this.handlers.push(new PS(a,i));if(this.services.project.selectedProject){let i=await this.services.prompt.list(this.services.project.selectedProject.name),a=new IS(this.interactor,this.services.prompt,this.services.project.selectedProject.name,i);this.handlers.push(a)}this.handlers.push(this.aiHandler),this.handlers=this.handlers.filter(i=>i.requiredIntegrations.every(a=>this.services.integration.hasIntegration(a)))}catch(t){this.interactor.error(`Error initializing handlers: ${t}`)}}async handle(e){if(!e)throw new Error("Invalid command context");let t=0,n;this.processing=!0;try{do{if(this.killed)return e;if(n=e.getFirstCommand(),t++,this.isHelpAsked(n)){let a=["Available commands:",this.formatHelp("help/h/[nothing]","displays this help message"),...this.handlers.slice().filter(o=>!o.isInternal).map(o=>this.formatHelp(o.commandWord,o.description)).sort(),this.formatHelp("[any other text]","defaults to asking the AI with the current context.")];this.interactor.displayText(a.join(`
|
|
1049
|
-
`));continue}if(!n)break;let i=this.handlers.find(a=>a.accept(n,e));try{if(i){if(e=await i.handle(n,e),e.aiThread?.runStatus==="STOPPED")return e.clearCommands(),this.processing=!1,e}else n.startsWith(this.aiHandler.commandWord)?this.interactor.error(`Could not handle request ${n}, check your AI integration`):e.addCommands(`${this.aiHandler.commandWord} ${n}`)}catch(a){this.interactor.error(`An error occurred while trying to process your request: ${a}`)}}while((n||t<this.maxIterations)&&this.processing)}finally{this.processing=!1}return t>=this.maxIterations&&this.interactor.warn("Maximum iterations reached for a command"),e}isHelpAsked(e){return e===""||e==="help"||e==="h"}formatHelp(e,t){return` - ${e.padEnd(15," ")} : ${t}`}stop(){this.processing=!1}kill(){this.stop(),this.killed=!0,this.aiHandler.kill()}};var Wfe=wr(Ss(),1);function Hfe(r){let e=r.match(/^@(\S*)(?:\s+([\s\S]*))?$/);if(!e)return["",r];let t=e[1],n=e[2]||"";return[t?.toLowerCase()??"",n]}var $E=class extends Ne{constructor(t,n,i){super({commandWord:"@",description:"calls the AI with the given command and current context. 'reset' for using a new thread. You can call whatever assistant in your openai account by its name, ex: joke_generator called by @jok (choice prompt if multiple matches)."});this.interactor=t;this.agentService=n;this.threadService=i}async handle(t,n){let[i,a]=Hfe(t),o=i?t:a;this.interactor.debug(`Agent name extracted from command: ${i}`);let s=await this.selectAgent(i,n);return s?a.trim()?this.runAgent(s,o,n):(this.interactor.debug(`Agent ${s.name} selected.`),n):(this.interactor.error("Failed to find any agent"),n)}async selectAgent(t,n){if(t){let s=await this.agentService.findAgentByNameStart(t,n);return s&&this.interactor.debug(`Selected agent: ${s.name}`),s}let i=n?.aiThread?.getLastAgentName();if(i){let s=await this.agentService.findByName(i,n);if(s)return this.interactor.debug(`Select last used agent: ${s.name}`),s;this.interactor.warn("Previously selected agent not available anymore")}let a=this.agentService.getPreferredAgent();if(a){let s=await this.agentService.findByName(a,n);if(s)return this.interactor.debug(`Selected default agent: ${a}`),s;this.interactor.warn(`Preferred agent '${a}' not found, using default.`)}let o=await this.agentService.findByName("coday",n);return o?this.interactor.debug("Selected default 'Coday' agent"):this.interactor.error("Critical failure: Cannot initialize default Coday agent!"),o}async runAgent(t,n,i){let a=await t.run(n,i.aiThread);await this.checkAndAutoSave(i.aiThread,t),a.subscribe({next:o=>{this.interactor.sendEvent(o)},error:o=>{o.message==="Processing interrupted by user request"?this.interactor.debug("Processing stopped gracefully"):this.interactor.error(`Error in AI processing: ${o.message}`)}});try{await(0,Wfe.lastValueFrom)(a,{defaultValue:void 0})}catch(o){this.interactor.error(`Could not run agent ${t.name} : ${o.message}`)}finally{try{await this.threadService.autoSave()}catch(o){this.interactor.debug(`Final auto-save failed: ${o}`)}}return i}async checkAndAutoSave(t,n){if(t.getUserMessageCount()!==0)if(t.name)try{await this.threadService.autoSave()}catch(i){this.interactor.debug(`Auto-save failed: ${i}`)}else try{let i=await Xle(t,n);await this.threadService.autoSave(i),this.interactor.displayText(`Thread auto-renamed to "${i}"`)}catch(i){this.interactor.warn(`Auto-rename failed: ${i}`)}}async kill(){await this.agentService.kill()}};var x7e=wr(Tc(),1);import*as oT from"fs/promises";import*as Rd from"path";var Vfe={anthropic:"ANTHROPIC_API_KEY",openai:"OPENAI_API_KEY",google:"GEMINI_API_KEY"},km=class{constructor(e,t,n,i){this.interactor=e;this.userService=t;this.
|
|
1049
|
+
`));continue}if(!n)break;let i=this.handlers.find(a=>a.accept(n,e));try{if(i){if(e=await i.handle(n,e),e.aiThread?.runStatus==="STOPPED")return e.clearCommands(),this.processing=!1,e}else n.startsWith(this.aiHandler.commandWord)?this.interactor.error(`Could not handle request ${n}, check your AI integration`):e.addCommands(`${this.aiHandler.commandWord} ${n}`)}catch(a){this.interactor.error(`An error occurred while trying to process your request: ${a}`)}}while((n||t<this.maxIterations)&&this.processing)}finally{this.processing=!1}return t>=this.maxIterations&&this.interactor.warn("Maximum iterations reached for a command"),e}isHelpAsked(e){return e===""||e==="help"||e==="h"}formatHelp(e,t){return` - ${e.padEnd(15," ")} : ${t}`}stop(){this.processing=!1}kill(){this.stop(),this.killed=!0,this.aiHandler.kill()}};var Wfe=wr(Ss(),1);function Hfe(r){let e=r.match(/^@(\S*)(?:\s+([\s\S]*))?$/);if(!e)return["",r];let t=e[1],n=e[2]||"";return[t?.toLowerCase()??"",n]}var $E=class extends Ne{constructor(t,n,i){super({commandWord:"@",description:"calls the AI with the given command and current context. 'reset' for using a new thread. You can call whatever assistant in your openai account by its name, ex: joke_generator called by @jok (choice prompt if multiple matches)."});this.interactor=t;this.agentService=n;this.threadService=i}async handle(t,n){let[i,a]=Hfe(t),o=i?t:a;this.interactor.debug(`Agent name extracted from command: ${i}`);let s=await this.selectAgent(i,n);return s?a.trim()?this.runAgent(s,o,n):(this.interactor.debug(`Agent ${s.name} selected.`),n):(this.interactor.error("Failed to find any agent"),n)}async selectAgent(t,n){if(t){let s=await this.agentService.findAgentByNameStart(t,n);return s&&this.interactor.debug(`Selected agent: ${s.name}`),s}let i=n?.aiThread?.getLastAgentName();if(i){let s=await this.agentService.findByName(i,n);if(s)return this.interactor.debug(`Select last used agent: ${s.name}`),s;this.interactor.warn("Previously selected agent not available anymore")}let a=this.agentService.getPreferredAgent();if(a){let s=await this.agentService.findByName(a,n);if(s)return this.interactor.debug(`Selected default agent: ${a}`),s;this.interactor.warn(`Preferred agent '${a}' not found, using default.`)}let o=await this.agentService.findByName("coday",n);return o?this.interactor.debug("Selected default 'Coday' agent"):this.interactor.error("Critical failure: Cannot initialize default Coday agent!"),o}async runAgent(t,n,i){let a=await t.run(n,i.aiThread);await this.checkAndAutoSave(i.aiThread,t),a.subscribe({next:o=>{this.interactor.sendEvent(o)},error:o=>{o.message==="Processing interrupted by user request"?this.interactor.debug("Processing stopped gracefully"):this.interactor.error(`Error in AI processing: ${o.message}`)}});try{await(0,Wfe.lastValueFrom)(a,{defaultValue:void 0})}catch(o){this.interactor.error(`Could not run agent ${t.name} : ${o.message}`)}finally{try{await this.threadService.autoSave()}catch(o){this.interactor.debug(`Final auto-save failed: ${o}`)}}return i}async checkAndAutoSave(t,n){if(t.getUserMessageCount()!==0)if(t.name)try{await this.threadService.autoSave()}catch(i){this.interactor.debug(`Auto-save failed: ${i}`)}else try{let i=await Xle(t,n);await this.threadService.autoSave(i),this.interactor.displayText(`Thread auto-renamed to "${i}"`)}catch(i){this.interactor.warn(`Auto-rename failed: ${i}`)}}async kill(){await this.agentService.kill()}};var x7e=wr(Tc(),1);import*as oT from"fs/promises";import*as Rd from"path";var Vfe={anthropic:"ANTHROPIC_API_KEY",openai:"OPENAI_API_KEY",google:"GEMINI_API_KEY"},km=class{constructor(e,t,n,i){this.interactor=e;this.userService=t;this.projectStateService=n;this.logger=i}aiClients=[];aiProviderConfigs;init(e){if(this.aiProviderConfigs)return;let t=e.project.ai||[],n=this.projectStateService.selectedProject?.config?.ai||[],i=this.userService.config.ai||[],a=this.detectProvidersFromEnvironment(),o=new Set([...t.map(l=>l.name.toLowerCase()),...n.map(l=>l.name.toLowerCase()),...i.map(l=>l.name.toLowerCase())]);this.aiProviderConfigs=[];for(let l of[...a,...t,...n,...i]){let f=this.aiProviderConfigs.findIndex(p=>p.name===l.name);if(f===-1)this.aiProviderConfigs.push(l);else{let p=this.aiProviderConfigs[f],d=p.models?[...p.models]:[];(l.models??[]).forEach(h=>{let g=d.findIndex(v=>v.alias===h.alias||v.name===h.name);if(g===-1)d.push(h);else{let v=d[g];d[g]={...v,...h,price:{...v.price,...h.price}}}}),this.aiProviderConfigs[f]={...p,...l,models:d}}}this.aiClients=this.aiProviderConfigs.map(l=>this.createClient(l)).filter(l=>!!l);let s=a.filter(l=>!o.has(l.name.toLowerCase())).map(l=>l.name.toLowerCase()),c=new Set(s),u=`AI providers (models listed as: name (alias)):
|
|
1050
1050
|
`+this.aiProviderConfigs.map(l=>{let f=this.aiClients.find(v=>v.name.toLowerCase()===l.name.toLowerCase()),p=!!f,d=p?"\u2705":"\u274C",h=c.has(l.name.toLowerCase())?" (auto-detected)":"",g=` - ${d} ${l.name}${h}`;if(p&&Array.isArray(f.models)&&f.models.length>0){let v=f.models.map(y=>y.alias&&y.alias!==y.name?`${y.name} (${y.alias})`:y.name).join(", ");g+=`, models: ${v}`}return g}).join(`
|
|
1051
1051
|
`);this.interactor.displayText(u)}getClient(e,t){let n=this.aiClients.filter(i=>{let a=!e||i.name.toLowerCase()===e.toLowerCase(),o=!t||i.supportsModel(t.toLowerCase());return a&&o});return n.length?n[0]:void 0}getAllModels(){let e=[];for(let t of this.aiClients)if(t.models)for(let n of t.models)e.push({name:n.name,providerName:t.name});return e}cleanup(){this.aiClients.forEach(e=>e.kill()),this.aiClients=[]}kill(){this.cleanup(),this.aiProviderConfigs=void 0}getApiKey(e){let t=Vfe[e.name];return(t?process.env[t]??process.env[`${e.name.toUpperCase()}_API_KEY`]:void 0)??e.apiKey}detectProvidersFromEnvironment(){let e=[];for(let[t,n]of Object.entries(Vfe)){let i=process.env[n];if(i){let a={name:t,apiKey:i};e.push(a),this.interactor.debug(`\u{1F50D} Auto-detected ${t} provider from ${n} environment variable`)}}return e}createClient(e){let t=this.getApiKey(e);if(!t){this.interactor.displayText(`\u2139\uFE0F no api key for AI provider '${e.name}'`);return}let n={...e,apiKey:t};switch(e.name.toLowerCase()){case"anthropic":return new uw(this.interactor,n,this.logger);case"google":return new TS(this.interactor,n,this.logger);default:return new um(this.interactor,n,this.logger)}}};function Gfe(r){return({query:t,agentName:n})=>{try{let i=`@${n} ${t}`;return r.addCommands(i),`Query successfully redirected to agent '${n}'. The agent will process the query with full context after this run completes.`}catch(i){return`Error during redirection: ${i.message}`}}}var eg=class extends Vt{constructor(t,n,i,a){super(t,i,a);this.agentSummaries=n}static TYPE="AI";async buildTools(t,n){let i=[];if(!t.oneshot){let a=async({message:s,options:c})=>`User answered: ${c?.length?await this.interactor.chooseOption(c,s,void 0,!0):await this.interactor.promptText(s)}`,o={type:"function",function:{name:`${this.name}__queryUser`,description:`Allows to ask the user a question.
|
|
1052
1052
|
IMPORTANT: Use this tool only when necessary, as it is intrusive for the user.
|
|
@@ -1395,7 +1395,7 @@ ${this.services.memory.getFormattedMemories("PROJECT",n.name)}
|
|
|
1395
1395
|
|
|
1396
1396
|
${l}
|
|
1397
1397
|
|
|
1398
|
-
`;let p=n.integrations?new Map(Object.entries(n.integrations).map(([x,k])=>{let S=k&&k.length>0?k:[];return[x,S]})):void 0;this.interactor.debug(`Agent '${n.name}' integrations: ${p?Array.from(p.keys()).join(", "):"ALL (undefined)"}`);let d=performance.now(),m=await this.toolbox.getTools({context:t,integrations:p,agentName:n.name}),h=performance.now()-d;this.interactor.debug(` \u{1F4E6} Tools available for '${n.name}': ${m.map(x=>x.function.name).join(", ")}`);let g=new $x([...m]),v=new sv(n,o,g),y=performance.now()-i;return this.interactor.debug(`\u2728 Agent '${n.name}' created: ${y.toFixed(2)}ms (client: ${s.toFixed(2)}ms, docs: ${f.toFixed(2)}ms, tools: ${h.toFixed(2)}ms)`),v}catch(a){let o=`Failed to create agent ${n.name}`;console.error(`${o}:`,a),this.interactor.error(o);return}}};var P9t=100,sT=class{constructor(e,t,n){this.interactor=e;this.options=t;this.services=n;this.interactor.debugLevelEnabled=t.debug,this.interactor.debug("Coday started with debug"),this.configHandler=new yE(e,this.services),this.maxIterations=P9t,this.aiThreadService=new cE(n.user,n.thread.getThreadRepository(t.project),t.project,e),this.aiThreadService.activeThread.subscribe(i=>{!this.context||!i||(this.context.aiThread=i,this.replayThread(i))}),this.aiClientProvider=new km(this.interactor,this.services.user,this.services.project
|
|
1398
|
+
`;let p=n.integrations?new Map(Object.entries(n.integrations).map(([x,k])=>{let S=k&&k.length>0?k:[];return[x,S]})):void 0;this.interactor.debug(`Agent '${n.name}' integrations: ${p?Array.from(p.keys()).join(", "):"ALL (undefined)"}`);let d=performance.now(),m=await this.toolbox.getTools({context:t,integrations:p,agentName:n.name}),h=performance.now()-d;this.interactor.debug(` \u{1F4E6} Tools available for '${n.name}': ${m.map(x=>x.function.name).join(", ")}`);let g=new $x([...m]),v=new sv(n,o,g),y=performance.now()-i;return this.interactor.debug(`\u2728 Agent '${n.name}' created: ${y.toFixed(2)}ms (client: ${s.toFixed(2)}ms, docs: ${f.toFixed(2)}ms, tools: ${h.toFixed(2)}ms)`),v}catch(a){let o=`Failed to create agent ${n.name}`;console.error(`${o}:`,a),this.interactor.error(o);return}}};var P9t=100,sT=class{constructor(e,t,n){this.interactor=e;this.options=t;this.services=n;this.interactor.debugLevelEnabled=t.debug,this.interactor.debug("Coday started with debug"),this.configHandler=new yE(e,this.services),this.maxIterations=P9t,this.aiThreadService=new cE(n.user,n.thread.getThreadRepository(t.project),t.project,e),this.aiThreadService.activeThread.subscribe(i=>{!this.context||!i||(this.context.aiThread=i,this.replayThread(i))}),this.aiClientProvider=new km(this.interactor,this.services.user,this.services.project,this.services.logger)}context=null;configHandler;handlerLooper;aiHandler;maxIterations;initialPrompts=[];aiThreadService;killed=!1;aiClientProvider;replay(){let e=this.aiThreadService.getCurrentThread();if(!e){console.log("No active thread to replay");return}this.replayThread(e),!this.options.oneshot&&e.runStatus!=="RUNNING"&&this.interactor.replayLastInvite()}upload(e){let t=this.aiThreadService.getCurrentThread();if(!t){this.interactor.error("No active thread available for upload");return}let n=this.services.user.username;e.forEach(a=>{t.addUserMessage(n,a)});let i=new Wt({role:"user",content:e,name:n});this.interactor.sendEvent(i)}async run(){this.initialPrompts=this.options.prompts?[...this.options.prompts]:[],this.interactor.debug(`[CODAY] Starting run with ${this.initialPrompts.length} initial prompts`);try{do{if(this.killed)return;if(await this.initContext(),await this.initThread(),!this.context){this.interactor.error("Could not initialize context \u{1F62D}");break}let e=await this.initCommand();if(!e&&this.options.oneshot)break;let t=this.context?.aiThread;t&&(t.runStatus="RUNNING"),this.context?.addCommands(e),this.context=await this.handlerLooper?.handle(this.context)??null}while(!this.context?.oneshot)}finally{this.stop()}await this.cleanup()}stop(){let e=this.context?.aiThread;e&&(e.runStatus="STOPPED"),this.handlerLooper?.stop(),this.aiThreadService.autoSave()}async cleanup(){try{this.services.agent&&await this.services.agent.kill(),this.aiThreadService.kill(),this.aiClientProvider.cleanup(),this.context=null,this.handlerLooper=void 0,this.aiHandler=void 0}catch(e){console.error("Error during agent cleanup:",e)}}async kill(){this.killed=!0,this.stop();try{await this.cleanup()}catch(e){console.error("Error during kill cleanup:",e)}this.handlerLooper?.kill(),this.interactor.kill()}async replayThread(e){let t=(await e.getMessages(void 0,void 0)).messages;if(!t?.length)return;let n=[...t].sort((i,a)=>new Date(i.timestamp).getTime()-new Date(a.timestamp).getTime());for(let i of n)(i instanceof Wt||i instanceof cn||i instanceof En||i instanceof ua||i instanceof la||i instanceof Rr)&&this.interactor.sendEvent(i);this.interactor.displayText(`Selected thread '${e.name}'`)}async initContext(){if(this.context){this.interactor.debug("[CODAY] Context already initialized, skipping");return}if(this.interactor.debug(`[CODAY] Initializing context for project: ${this.options.project}`),this.context=await this.configHandler.selectProjectHandler.selectProject(this.options.project),!this.context){console.log("[CODAY] ERROR: Failed to create context from selectProject");return}console.log(`[CODAY] Context initialized: '${this.context.project.name}' at ${this.context.project.root}`),this.context&&(this.context.oneshot=this.options.oneshot,this.context.fileReadOnly=this.options.fileReadOnly,this.options.thread&&this.options.project&&(this.context.threadFilesRoot=w7e.join(this.options.configDir,"projects",this.options.project,"threads",`${this.options.thread}-files`),this.interactor.debug(`[CODAY] Thread files root: ${this.context.threadFilesRoot}`)),this.services.aiConfig=new KS(this.services.user,this.services.project),this.services.aiConfig.initialize(this.context),this.services.mcp.initialize(this.context),this.services.agent=new G1(this.interactor,this.aiClientProvider,this.services,this.context.project.root,this.options.agentFolders),this.aiHandler=new $E(this.interactor,this.services.agent,this.aiThreadService),this.handlerLooper=new OE(this.interactor,this.aiHandler,this.configHandler,this.services),this.aiClientProvider.init(this.context),await this.handlerLooper.init(this.context.project),console.log("[CODAY] Initializing services..."),await this.services.agent.initialize(this.context),console.log("[CODAY] Services initialized"))}async initThread(){if(!this.context?.aiThread){if(!this.options.thread)throw Error("No thread given, cannot start Coday instance");await this.aiThreadService.select(this.options.thread)}}async initCommand(){let e;return this.interactor.debug(`[CODAY] initCommand: ${this.initialPrompts.length} prompts available, oneshot=${this.options.oneshot}`),this.initialPrompts.length?(e=this.initialPrompts.shift(),this.interactor.debug(`[CODAY] Using initial prompt: ${e}`),this.initialPrompts.length&&(this.interactor.debug(`[CODAY] Adding ${this.initialPrompts.length} remaining prompts to queue`),this.context?.addCommands(...this.initialPrompts),this.initialPrompts=[])):this.options.oneshot?this.interactor.debug("[CODAY] No initial prompts and oneshot mode, exiting"):(this.interactor.debug("[CODAY] No initial prompts, waiting for user input"),e=await this.interactor.promptText($te)),e}};function pe(r,...e){console.log(`${new Date().toISOString()} ${r}`,...e)}var D9t=4,cT=class{constructor(e,t){this.aiClient=e;this.threadService=t}process(e,t){this.run(e,t).catch(n=>pe("POST_PROCESSOR",`Unhandled error for thread ${e.id}:`,n))}async run(e,t){let n=e.getUserMessageCount();if(n<D9t){pe("POST_PROCESSOR",`Skipping thread ${e.id}: only ${n} user message(s)`);return}pe("POST_PROCESSOR",`Processing thread ${e.id} (${n} user messages)`);let{messages:i}=await e.getMessages(void 0,void 0),a=i.filter(f=>f instanceof Wt).slice(-40).map(f=>{let p=f.role==="user"?"User":f.name||"Assistant",d=f.content.filter(m=>m.type==="text").map(m=>m.content).join(" ").slice(0,500);return`${p}: ${d}`});if(!a.length){pe("POST_PROCESSOR",`Skipping thread ${e.id}: no text messages`);return}let s=`You are given a conversation transcript. Reply ONLY with a valid JSON object (no markdown, no explanation) with two fields:
|
|
1399
1399
|
- "name": a short title for the conversation (max 60 chars, no quotes)
|
|
1400
1400
|
- "summary": 2-4 sentences summarising the main topics and outcomes
|
|
1401
1401
|
|
|
@@ -1434,7 +1434,7 @@ ${String(m)}`}else d=JSON.stringify(p,null,2);i.status(200).send(d)}catch(a){con
|
|
|
1434
1434
|
in
|
|
1435
1435
|
project
|
|
1436
1436
|
:
|
|
1437
|
-
${a}`);let l=e.get(o);if(!l?.coday){i.status(404).json({error:`Thread '${o}' not found or not active`});return}if(l.username!==u){i.status(403).json({error:"Access denied: thread belongs to another user"});return}let f=l.coday.context?.aiThread;if(!f){i.status(500).json({error:"Thread not properly initialized"});return}f.truncateAtUserMessage(c)?(pe("MESSAGE",`Successfully truncated thread ${o} at message ${c}`),i.status(200).json({success:!0,message:"Message deleted successfully"})):i.status(400).json({error:"Failed to delete message. Message may not exist, may not be a user message, or may be the first message."})}catch(a){console.error("Error deleting message:",a);let o=a instanceof Error?a.message:"Unknown error";i.status(500).json({error:`Failed to delete message: ${o}`})}})}function C7e(r,e){r.get("/api/user/me",(t,n)=>{try{let i=e(t);if(!i){n.status(401).json({error:"Authentication required"});return}pe("USER",`GET current user: ${i}`),n.status(200).json({username:i})}catch(i){console.error("Error retrieving user info:",i);let a=i instanceof Error?i.message:"Unknown error";n.status(500).json({error:`Failed to retrieve user info: ${a}`})}})}function T7e(r,e,t,n,i,a,o,s,c){r.get("/api/projects/:projectName/agents",async(u,l)=>{try{let f=t(u),{projectName:p}=u.params;if(!p){l.status(400).json({error:"Project name is required"});return}pe("AGENT",`GET agents list: project="${p}", user="${f}"`);let d=e.getProject(p);if(!d){l.status(404).json({error:`Project '${p}' not found`});return}let m=new vc("agent-autocomplete"),h=new U2(n,f,m),g=new wm(m,e,n),v=new pm(g,h),y=new fm(h,g,m),x=new mm(g,h),k=new hm(h,g,m),S=new Am,A={user:h,project:g,projectService:e,integration:v,integrationConfig:y,memory:x,mcp:k,mcpPool:S,thread:o,prompt:a,logger:i,options:c};g.selectProject(p);let $=new km(m,h,g.selectedProject?.config?.ai||[],i),O=new G1(m,$,A,d.config.path,c.agentFolders),E={...await XS(d.config.path,m,{username:f,bio:h.config.bio}),root:d.config.path,name:p},b=new S0(E,f);b.oneshot=!0,$.init(b),await O.initialize(b);let T=O.listAgentSummaries();await O.kill(),l.status(200).json(T)}catch(f){console.error("Error listing agents:",f);let p=f instanceof Error?f.message:"Unknown error";l.status(500).json({error:`Failed to list agents: ${p}`})}}),r.get("/api/projects/:projectName/agents/documents",async(u,l)=>{try{let f=Le(u.params.projectName);if(!f){l.status(400).json({error:"Project name is required"});return}let p=u.query.location==="colocated"?"colocated":"project";pe("AGENT",`GET documents pool: project="${f}", location="${p}"`);let d=await s.listDocuments(f,p);l.status(200).json(d)}catch(f){console.error("Error listing agent documents:",f);let p=f instanceof Error?f.message:"Unknown error";l.status(500).json({error:`Failed to list documents: ${p}`})}}),r.post("/api/projects/:projectName/agents/documents",async(u,l)=>{try{let f=Le(u.params.projectName);if(!f){l.status(400).json({error:"Project name is required"});return}let p=u.query.location==="colocated"?"colocated":"project",{filename:d,content:m}=u.body;if(!d||!m){l.status(400).json({error:"filename and content (base64) are required"});return}let h=Buffer.from(m,"base64");pe("AGENT",`POST upload document: "${d}" in ${p} for project="${f}"`);let g=await s.saveDocument(f,p,d,h);l.status(201).json({relativePath:g})}catch(f){console.error("Error uploading agent document:",f);let p=f instanceof Error?f.message:"Unknown error",d=p.includes("too large")||p.includes("not allowed")?422:500;l.status(d).json({error:p})}}),r.get("/api/projects/:projectName/agents/editable",async(u,l)=>{try{let f=Le(u.params.projectName);if(!f){l.status(400).json({error:"Project name is required"});return}pe("AGENT",`GET editable agents: project="${f}"`);let p=await s.list(f);l.status(200).json(p)}catch(f){console.error("Error listing editable agents:",f);let p=f instanceof Error?f.message:"Unknown error";l.status(500).json({error:`Failed to list editable agents: ${p}`})}}),r.get("/api/projects/:projectName/agents/:agentName",async(u,l)=>{try{let f=Le(u.params.projectName),p=Le(u.params.agentName);if(!f){l.status(400).json({error:"Project name is required"});return}if(!p){l.status(400).json({error:"Agent name is required"});return}pe("AGENT",`GET agent: "${p}" in project="${f}"`);let d=await s.get(f,p);if(!d){l.status(404).json({error:`Agent '${p}' not found`});return}l.status(200).json(d)}catch(f){console.error("Error getting agent:",f);let p=f instanceof Error?f.message:"Unknown error";l.status(500).json({error:`Failed to get agent: ${p}`})}}),r.post("/api/projects/:projectName/agents",async(u,l)=>{try{let f=Le(u.params.projectName);if(!f){l.status(400).json({error:"Project name is required"});return}let{location:p,definition:d}=u.body;if(!d||typeof d!="object"){l.status(422).json({error:"Agent definition is required"});return}if(!d.name||typeof d.name!="string"){l.status(422).json({error:"Agent name is required"});return}if(!d.description||typeof d.description!="string"){l.status(422).json({error:"Agent description is required"});return}let m=p==="colocated"?"colocated":"project";pe("AGENT",`POST create agent: "${d.name}" in ${m} for project="${f}"`);let h=await s.create(f,d,m);l.status(201).json(h)}catch(f){console.error("Error creating agent:",f);let p=f instanceof Error?f.message:"Unknown error";if(p.includes("already exists")||p.includes("must start with")){l.status(422).json({error:p});return}l.status(500).json({error:`Failed to create agent: ${p}`})}}),r.put("/api/projects/:projectName/agents/:agentName",async(u,l)=>{try{let f=Le(u.params.projectName),p=Le(u.params.agentName);if(!f){l.status(400).json({error:"Project name is required"});return}if(!p){l.status(400).json({error:"Agent name is required"});return}let{definition:d}=u.body;if(!d||typeof d!="object"){l.status(422).json({error:"Agent definition is required"});return}pe("AGENT",`PUT update agent: "${p}" in project="${f}"`);let m=await s.update(f,p,d);if(!m){l.status(404).json({error:`Agent '${p}' not found`});return}l.status(200).json(m)}catch(f){console.error("Error updating agent:",f);let p=f instanceof Error?f.message:"Unknown error";if(p.includes("cannot be empty")){l.status(422).json({error:p});return}l.status(500).json({error:`Failed to update agent: ${p}`})}}),r.delete("/api/projects/:projectName/agents/:agentName",async(u,l)=>{try{let f=Le(u.params.projectName),p=Le(u.params.agentName);if(!f){l.status(400).json({error:"Project name is required"});return}if(!p){l.status(400).json({error:"Agent name is required"});return}if(pe("AGENT",`DELETE agent: "${p}" in project="${f}"`),!await s.delete(f,p)){l.status(404).json({error:`Agent '${p}' not found`});return}l.status(200).json({success:!0,message:`Agent '${p}' deleted successfully`})}catch(f){console.error("Error deleting agent:",f);let p=f instanceof Error?f.message:"Unknown error";l.status(500).json({error:`Failed to delete agent: ${p}`})}})}function P7e(r,e,t){r.get("/api/projects/:projectName/prompts",async(n,i)=>{try{let a=Le(n.params.projectName);if(!a){i.status(400).json({error:"Project name is required"});return}pe("PROMPT_API",`GET prompts for project: ${a}`);let o=await e.list(a);i.status(200).json(o)}catch(a){console.error("Error listing prompts:",a),i.status(500).json({error:"Failed to list prompts"})}}),r.get("/api/projects/:projectName/prompts/:id",async(n,i)=>{try{let a=Le(n.params.projectName),o=Le(n.params.id);if(!a){i.status(400).json({error:"Project name is required"});return}if(!o){i.status(400).json({error:"Prompt ID is required"});return}pe("PROMPT_API",`GET prompt: ${o} in project: ${a}`);let s=await e.get(a,o);if(!s){i.status(404).json({error:`Prompt with ID '${o}' not found`});return}i.status(200).json(s)}catch(a){console.error("Error retrieving prompt:",a),i.status(500).json({error:"Failed to retrieve prompt"})}}),r.post("/api/projects/:projectName/prompts",async(n,i)=>{try{let a=Le(n.params.projectName);if(!a){i.status(400).json({error:"Project name is required"});return}let o=n.body;if(!o||typeof o!="object"){i.status(422).json({error:"Invalid prompt format"});return}if(!o.name||typeof o.name!="string"){i.status(422).json({error:"Prompt name is required"});return}if(!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(o.name)){i.status(422).json({error:"Prompt name must be lowercase alphanumeric with hyphens (e.g., my-prompt-name)"});return}if(!o.description||typeof o.description!="string"){i.status(422).json({error:"Prompt description is required"});return}if(!o.commands||!Array.isArray(o.commands)||o.commands.length===0){i.status(422).json({error:"Prompt must have at least one command"});return}if(o.webhookEnabled!==void 0&&typeof o.webhookEnabled!="boolean"){i.status(422).json({error:"webhookEnabled must be a boolean"});return}let s=o.source==="project"?"project":"local";if(o.source!==void 0&&o.source!=="local"&&o.source!=="project"){i.status(422).json({error:"source must be 'local' or 'project'"});return}let c=t(n);if(!c){i.status(401).json({error:"Username not found in request headers"});return}pe("PROMPT_API",`POST new prompt: ${o.name} in ${s} for project: ${a}`);let u=await e.create(a,{...o,webhookEnabled:o.webhookEnabled??!1,createdBy:c,source:s},s);i.status(201).json(u)}catch(a){console.error("Error creating prompt:",a);let o=a instanceof Error?a.message:"Unknown error";i.status(500).json({error:`Failed to create prompt: ${o}`})}}),r.put("/api/projects/:projectName/prompts/:id",async(n,i)=>{try{let a=Le(n.params.projectName),o=Le(n.params.id);if(!a){i.status(400).json({error:"Project name is required"});return}if(!o){i.status(404).json({error:"Prompt ID is required"});return}let s=n.body;if(!s||typeof s!="object"){i.status(422).json({error:"Invalid prompt format"});return}if(s.name!==void 0){if(typeof s.name!="string"){i.status(422).json({error:"Prompt name must be a string"});return}if(!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(s.name)){i.status(422).json({error:"Prompt name must be lowercase alphanumeric with hyphens (e.g., my-prompt-name)"});return}}if(s.commands!==void 0&&(!Array.isArray(s.commands)||s.commands.length===0)){i.status(422).json({error:"Prompt must have at least one command"});return}if(s.webhookEnabled!==void 0&&typeof s.webhookEnabled!="boolean"){i.status(422).json({error:"webhookEnabled must be a boolean"});return}if(s.source!==void 0){i.status(422).json({error:"source cannot be changed after creation"});return}let c=t(n);if(!c){i.status(401).json({error:"Username not found in request headers"});return}pe("PROMPT_API",`PUT prompt: ${o} in project: ${a}, user: ${c}`);let u=await e.update(a,o,s,c);if(!u){i.status(404).json({error:`Prompt with ID '${o}' not found`});return}i.status(200).json({success:!0,prompt:u})}catch(a){console.error("Error updating prompt:",a);let o=a instanceof Error?a.message:"Unknown error";if(o.includes("Only CODAY_ADMIN")){i.status(403).json({error:o});return}i.status(500).json({error:`Failed to update prompt: ${o}`})}}),r.delete("/api/projects/:projectName/prompts/:id",async(n,i)=>{try{let a=Le(n.params.projectName),o=Le(n.params.id);if(!a){i.status(400).json({error:"Project name is required"});return}if(!o){i.status(400).json({error:"Prompt ID is required"});return}if(pe("PROMPT_API",`DELETE prompt: ${o} in project: ${a}`),!await e.delete(a,o)){i.status(404).json({error:`Prompt with ID '${o}' not found`});return}i.status(200).json({success:!0,message:"Prompt deleted successfully"})}catch(a){console.error("Error deleting prompt:",a);let o=a instanceof Error?a.message:"Unknown error";i.status(500).json({error:`Failed to delete prompt: ${o}`})}}),r.post("/api/projects/:projectName/prompts/:id/webhook",async(n,i)=>{try{let a=Le(n.params.projectName),o=Le(n.params.id);if(!a){i.status(400).json({error:"Project name is required"});return}if(!o){i.status(400).json({error:"Prompt ID is required"});return}let s=t(n);if(!s){i.status(401).json({error:"Username not found in request headers"});return}pe("PROMPT_API",`POST enable webhook for prompt: ${o} in project: ${a}, user: ${s}`);let c=await e.enableWebhook(a,o,s);if(!c){i.status(404).json({error:`Prompt with ID '${o}' not found`});return}i.status(200).json({success:!0,prompt:c})}catch(a){console.error("Error enabling webhook:",a);let o=a instanceof Error?a.message:"Unknown error";if(o.includes("Only CODAY_ADMIN")){i.status(403).json({error:o});return}i.status(500).json({error:`Failed to enable webhook: ${o}`})}}),r.delete("/api/projects/:projectName/prompts/:id/webhook",async(n,i)=>{try{let a=Le(n.params.projectName),o=Le(n.params.id);if(!a){i.status(400).json({error:"Project name is required"});return}if(!o){i.status(400).json({error:"Prompt ID is required"});return}let s=t(n);if(!s){i.status(401).json({error:"Username not found in request headers"});return}pe("PROMPT_API",`DELETE disable webhook for prompt: ${o} in project: ${a}, user: ${s}`);let c=await e.disableWebhook(a,o,s);if(!c){i.status(404).json({error:`Prompt with ID '${o}' not found`});return}i.status(200).json({success:!0,prompt:c})}catch(a){console.error("Error disabling webhook:",a);let o=a instanceof Error?a.message:"Unknown error";if(o.includes("Only CODAY_ADMIN")){i.status(403).json({error:o});return}i.status(500).json({error:`Failed to disable webhook: ${o}`})}})}function D7e(r,e,t){r.get("/api/projects/:projectName/schedulers",async(n,i)=>{try{let a=Le(n.params.projectName);if(!a){i.status(400).json({error:"Project name is required"});return}let o=t(n);if(!o){i.status(401).json({error:"Username not found in request headers"});return}pe("SCHEDULER_API",`GET schedulers for project: ${a}, user: ${o}`);let s=await e.listSchedulers(a,o);i.json(s)}catch(a){console.error("Error listing schedulers:",a),i.status(500).json({error:"Failed to list schedulers"})}}),r.get("/api/projects/:projectName/schedulers/:id",async(n,i)=>{try{let a=Le(n.params.projectName),o=Le(n.params.id);if(!a){i.status(400).json({error:"Project name is required"});return}if(!o){i.status(400).json({error:"Scheduler ID is required"});return}let s=t(n);if(!s){i.status(401).json({error:"Username not found in request headers"});return}pe("SCHEDULER_API",`GET scheduler: ${o} in project: ${a}, user: ${s}`);let c=await e.getScheduler(a,o,s);if(!c){i.status(404).json({error:"Scheduler not found or access denied"});return}i.json(c)}catch(a){console.error("Error getting scheduler:",a),i.status(500).json({error:"Failed to get scheduler"})}}),r.post("/api/projects/:projectName/schedulers",async(n,i)=>{try{let a=Le(n.params.projectName);if(!a){i.status(400).json({error:"Project name is required"});return}let o=t(n);if(!o){i.status(401).json({error:"Username not found in request headers"});return}let{name:s,promptId:c,schedule:u,parameters:l,enabled:f}=n.body;if(!s||typeof s!="string"){i.status(400).json({error:"Name is required and must be a string"});return}if(!c||typeof c!="string"){i.status(400).json({error:"Prompt ID is required and must be a string"});return}if(!u||typeof u!="object"){i.status(400).json({error:"Schedule is required and must be an object"});return}let p=e.validateSchedule(u);if(!p.valid){i.status(400).json({error:p.error});return}if(l!==void 0&&typeof l!="object"){i.status(400).json({error:"Parameters must be an object"});return}if(f!==void 0&&typeof f!="boolean"){i.status(400).json({error:"Enabled must be a boolean"});return}pe("SCHEDULER_API",`POST new scheduler: ${s} in project: ${a}, user: ${o}`);let d=await e.createScheduler(a,{name:s,promptId:c,schedule:u,parameters:l,enabled:f},o);i.status(201).json(d)}catch(a){console.error("Error creating scheduler:",a);let o=a instanceof Error?a.message:"Failed to create scheduler";i.status(500).json({error:o})}}),r.put("/api/projects/:projectName/schedulers/:id",async(n,i)=>{try{let a=Le(n.params.projectName),o=Le(n.params.id);if(!a){i.status(400).json({error:"Project name is required"});return}if(!o){i.status(400).json({error:"Scheduler ID is required"});return}let s=t(n);if(!s){i.status(401).json({error:"Username not found in request headers"});return}let{name:c,enabled:u,promptId:l,schedule:f,parameters:p}=n.body;if(c!==void 0&&typeof c!="string"){i.status(400).json({error:"Name must be a string"});return}if(u!==void 0&&typeof u!="boolean"){i.status(400).json({error:"Enabled must be a boolean"});return}if(l!==void 0&&typeof l!="string"){i.status(400).json({error:"Prompt ID must be a string"});return}if(f!==void 0){if(typeof f!="object"){i.status(400).json({error:"Schedule must be an object"});return}let m=e.validateSchedule(f);if(!m.valid){i.status(400).json({error:m.error});return}}if(p!==void 0&&typeof p!="object"){i.status(400).json({error:"Parameters must be an object"});return}pe("SCHEDULER_API",`PUT scheduler: ${o} in project: ${a}, user: ${s}`);let d=await e.updateScheduler(a,o,{name:c,enabled:u,promptId:l,schedule:f,parameters:p},s);i.json(d)}catch(a){console.error("Error updating scheduler:",a);let o=a instanceof Error?a.message:"Failed to update scheduler";o.includes("not found")||o.includes("access denied")?i.status(404).json({error:o}):i.status(500).json({error:o})}}),r.delete("/api/projects/:projectName/schedulers/:id",async(n,i)=>{try{let a=Le(n.params.projectName),o=Le(n.params.id);if(!a){i.status(400).json({error:"Project name is required"});return}if(!o){i.status(400).json({error:"Scheduler ID is required"});return}let s=t(n);if(!s){i.status(401).json({error:"Username not found in request headers"});return}if(pe("SCHEDULER_API",`DELETE scheduler: ${o} in project: ${a}, user: ${s}`),!await e.deleteScheduler(a,o,s)){i.status(404).json({error:"Scheduler not found or access denied"});return}i.json({success:!0,message:"Scheduler deleted"})}catch(a){console.error("Error deleting scheduler:",a),i.status(500).json({error:"Failed to delete scheduler"})}}),r.post("/api/projects/:projectName/schedulers/:id/enable",async(n,i)=>{try{let a=Le(n.params.projectName),o=Le(n.params.id);if(!a){i.status(400).json({error:"Project name is required"});return}if(!o){i.status(400).json({error:"Scheduler ID is required"});return}let s=t(n);if(!s){i.status(401).json({error:"Username not found in request headers"});return}pe("SCHEDULER_API",`POST enable scheduler: ${o} in project: ${a}, user: ${s}`);let c=await e.enableScheduler(a,o,s);i.json(c)}catch(a){console.error("Error enabling scheduler:",a);let o=a instanceof Error?a.message:"Failed to enable scheduler";o.includes("not found")||o.includes("access denied")?i.status(404).json({error:o}):i.status(500).json({error:o})}}),r.post("/api/projects/:projectName/schedulers/:id/disable",async(n,i)=>{try{let a=Le(n.params.projectName),o=Le(n.params.id);if(!a){i.status(400).json({error:"Project name is required"});return}if(!o){i.status(400).json({error:"Scheduler ID is required"});return}let s=t(n);if(!s){i.status(401).json({error:"Username not found in request headers"});return}pe("SCHEDULER_API",`POST disable scheduler: ${o} in project: ${a}, user: ${s}`);let c=await e.disableScheduler(a,o,s);i.json(c)}catch(a){console.error("Error disabling scheduler:",a);let o=a instanceof Error?a.message:"Failed to disable scheduler";o.includes("not found")||o.includes("access denied")?i.status(404).json({error:o}):i.status(500).json({error:o})}}),r.post("/api/projects/:projectName/schedulers/:id/run-now",async(n,i)=>{try{let a=Le(n.params.projectName),o=Le(n.params.id);if(!a){i.status(400).json({error:"Project name is required"});return}if(!o){i.status(400).json({error:"Scheduler ID is required"});return}let s=t(n);if(!s){i.status(401).json({error:"Username not found in request headers"});return}pe("SCHEDULER_API",`POST run-now scheduler: ${o} in project: ${a}, user: ${s}`);let c=await e.runSchedulerNow(a,o,s);i.json({success:!0,message:"Scheduler executed",threadId:c})}catch(a){console.error("Error running scheduler:",a);let o=a instanceof Error?a.message:"Failed to run scheduler";o.includes("not found")||o.includes("access denied")?i.status(404).json({error:o}):i.status(500).json({error:o})}})}function I7e(r,e,t){r.post("/api/webhooks/:promptId/execute",async(n,i)=>{try{let a=Le(n.params.promptId);if(!a){pe("WEBHOOK","Missing promptId in request"),i.status(400).send({error:"Missing prompt ID in URL"});return}let{title:o,awaitFinalAnswer:s,...c}=n.body,u=t(n);if(!u){i.status(401).send({error:"Username not found in request headers"});return}pe("WEBHOOK",`Executing prompt ${a} for user ${u}`);let l=await e.executePrompt(a,c,u,"webhook",{title:o,awaitFinalAnswer:s});s?i.status(200).send(l):i.status(201).send(l)}catch(a){let o=a instanceof Error?a.message:"Unknown error";console.error("Error in webhook endpoint:",a),o.includes("not found")?i.status(404).send({error:o}):o.includes("not enabled for webhook")?i.status(403).send({error:o}):o.includes("Missing required parameters")||o.includes("contains structured placeholders")||o.includes("Missing or invalid")||o.includes("not configured")?i.status(422).send({error:o}):i.status(500).send({error:"Internal server error"})}})}function Z1(r,e){return e===void 0?r:(r??0)+e}function fT(r,e){if(typeof r!="string"||!/^\d{4}-\d{2}-\d{2}$/.test(r))return;let t=e?"00:00:00.000Z":"23:59:59.999Z",n=new Date(`${r}T${t}`);return isNaN(n.getTime())?void 0:n}function O7e(r,e,t){return`${r}|${e}|${t}`}function $7e(r,e,t){r.get("/api/token-usage",async(n,i)=>{try{let a=fT(n.query.from,!0)??new Date(0),o=fT(n.query.to,!1)??new Date,s=t(n);pe("TOKEN_USAGE",`GET /api/token-usage from=${a.toISOString()} to=${o.toISOString()} user=${s}`);let u=(await e.readLogs(a,o)).filter(h=>h.type==="AGENT_USAGE"&&(h.username===s||h.username==="no_username")),l=new Map;for(let h of u){let g=h.providerName??"",v=O7e(h.agent,g,h.model),y=l.get(v);y||(y={agentName:h.agent,providerName:g,modelId:h.model,promptTokens:null,completionTokens:null,totalTokens:null,callCount:0,cost:0,tokenDataPartial:!1},l.set(v,y)),y.promptTokens=Z1(y.promptTokens,h.promptTokens),y.completionTokens=Z1(y.completionTokens,h.completionTokens),y.totalTokens=Z1(y.totalTokens,h.totalTokens),y.callCount+=1,y.cost+=h.cost??0,(h.promptTokens===void 0||h.completionTokens===void 0||h.totalTokens===void 0)&&(y.tokenDataPartial=!0)}let f=Array.from(l.values()),p=f.some(h=>h.tokenDataPartial),d=h=>{let g=h.filter(v=>v!==null);return g.length>0?g.reduce((v,y)=>v+y,0):null},m={agentName:"total",providerName:"all",modelId:"all",promptTokens:d(f.map(h=>h.promptTokens)),completionTokens:d(f.map(h=>h.completionTokens)),totalTokens:d(f.map(h=>h.totalTokens)),callCount:f.reduce((h,g)=>h+g.callCount,0),cost:f.reduce((h,g)=>h+g.cost,0),tokenDataPartial:p};i.status(200).json({from:a.toISOString(),to:o.toISOString(),tokenDataPartial:p,models:f,total:m})}catch(a){console.error("Error reading token usage:",a);let o=a instanceof Error?a.message:"Unknown error";i.status(500).json({error:`Failed to read token usage: ${o}`})}}),r.get("/api/token-usage/series",async(n,i)=>{try{let a=fT(n.query.from,!0)??new Date(0),o=fT(n.query.to,!1)??new Date,s=t(n);pe("TOKEN_USAGE",`GET /api/token-usage/series from=${a.toISOString()} to=${o.toISOString()} user=${s}`);let u=(await e.readLogs(a,o)).filter(d=>d.type==="AGENT_USAGE"&&(d.username===s||d.username==="no_username")),l=new Map;for(let d of u){let m=d.timestamp.slice(0,10),h=d.providerName??"",g=`${m}|${O7e(d.agent,h,d.model)}`,v=l.get(g);v||(v={date:m,agentName:d.agent,providerName:h,modelId:d.model,promptTokens:null,completionTokens:null,totalTokens:null,callCount:0,cost:0,tokenDataPartial:!1},l.set(g,v)),v.promptTokens=Z1(v.promptTokens,d.promptTokens),v.completionTokens=Z1(v.completionTokens,d.completionTokens),v.totalTokens=Z1(v.totalTokens,d.totalTokens),v.callCount+=1,v.cost+=d.cost??0,(d.promptTokens===void 0||d.completionTokens===void 0||d.totalTokens===void 0)&&(v.tokenDataPartial=!0)}let f=Array.from(l.values()).sort((d,m)=>{let h=d.date.localeCompare(m.date);return h!==0?h:d.agentName.localeCompare(m.agentName)}),p=f.some(d=>d.tokenDataPartial);i.status(200).json({from:a.toISOString(),to:o.toISOString(),tokenDataPartial:p,points:f})}catch(a){console.error("Error reading token usage series:",a);let o=a instanceof Error?a.message:"Unknown error";i.status(500).json({error:`Failed to read token usage series: ${o}`})}})}import ZG from"path";import{notStrictEqual as k7t,strictEqual as A7t}from"assert";var $9t={right:M9t,center:L9t},j9t=0,pT=1,R9t=2,dT=3,mG=class{constructor(e){var t;this.width=e.width,this.wrap=(t=e.wrap)!==null&&t!==void 0?t:!0,this.rows=[]}span(...e){let t=this.div(...e);t.span=!0}resetOutput(){this.rows=[]}div(...e){if(e.length===0&&this.div(""),this.wrap&&this.shouldApplyLayoutDSL(...e)&&typeof e[0]=="string")return this.applyLayoutDSL(e[0]);let t=e.map(n=>typeof n=="string"?this.colFromString(n):n);return this.rows.push(t),t}shouldApplyLayoutDSL(...e){return e.length===1&&typeof e[0]=="string"&&/[\t\n]/.test(e[0])}applyLayoutDSL(e){let t=e.split(`
|
|
1437
|
+
${a}`);let l=e.get(o);if(!l?.coday){i.status(404).json({error:`Thread '${o}' not found or not active`});return}if(l.username!==u){i.status(403).json({error:"Access denied: thread belongs to another user"});return}let f=l.coday.context?.aiThread;if(!f){i.status(500).json({error:"Thread not properly initialized"});return}f.truncateAtUserMessage(c)?(pe("MESSAGE",`Successfully truncated thread ${o} at message ${c}`),i.status(200).json({success:!0,message:"Message deleted successfully"})):i.status(400).json({error:"Failed to delete message. Message may not exist, may not be a user message, or may be the first message."})}catch(a){console.error("Error deleting message:",a);let o=a instanceof Error?a.message:"Unknown error";i.status(500).json({error:`Failed to delete message: ${o}`})}})}function C7e(r,e){r.get("/api/user/me",(t,n)=>{try{let i=e(t);if(!i){n.status(401).json({error:"Authentication required"});return}pe("USER",`GET current user: ${i}`),n.status(200).json({username:i})}catch(i){console.error("Error retrieving user info:",i);let a=i instanceof Error?i.message:"Unknown error";n.status(500).json({error:`Failed to retrieve user info: ${a}`})}})}function T7e(r,e,t,n,i,a,o,s,c){r.get("/api/projects/:projectName/agents",async(u,l)=>{try{let f=t(u),{projectName:p}=u.params;if(!p){l.status(400).json({error:"Project name is required"});return}pe("AGENT",`GET agents list: project="${p}", user="${f}"`);let d=e.getProject(p);if(!d){l.status(404).json({error:`Project '${p}' not found`});return}let m=new vc("agent-autocomplete"),h=new U2(n,f,m),g=new wm(m,e,n),v=new pm(g,h),y=new fm(h,g,m),x=new mm(g,h),k=new hm(h,g,m),S=new Am,A={user:h,project:g,projectService:e,integration:v,integrationConfig:y,memory:x,mcp:k,mcpPool:S,thread:o,prompt:a,logger:i,options:c};g.selectProject(p);let $=new km(m,h,g,i),O=new G1(m,$,A,d.config.path,c.agentFolders),E={...await XS(d.config.path,m,{username:f,bio:h.config.bio}),root:d.config.path,name:p},b=new S0(E,f);b.oneshot=!0,$.init(b),await O.initialize(b);let T=O.listAgentSummaries();await O.kill(),l.status(200).json(T)}catch(f){console.error("Error listing agents:",f);let p=f instanceof Error?f.message:"Unknown error";l.status(500).json({error:`Failed to list agents: ${p}`})}}),r.get("/api/projects/:projectName/agents/documents",async(u,l)=>{try{let f=Le(u.params.projectName);if(!f){l.status(400).json({error:"Project name is required"});return}let p=u.query.location==="colocated"?"colocated":"project";pe("AGENT",`GET documents pool: project="${f}", location="${p}"`);let d=await s.listDocuments(f,p);l.status(200).json(d)}catch(f){console.error("Error listing agent documents:",f);let p=f instanceof Error?f.message:"Unknown error";l.status(500).json({error:`Failed to list documents: ${p}`})}}),r.post("/api/projects/:projectName/agents/documents",async(u,l)=>{try{let f=Le(u.params.projectName);if(!f){l.status(400).json({error:"Project name is required"});return}let p=u.query.location==="colocated"?"colocated":"project",{filename:d,content:m}=u.body;if(!d||!m){l.status(400).json({error:"filename and content (base64) are required"});return}let h=Buffer.from(m,"base64");pe("AGENT",`POST upload document: "${d}" in ${p} for project="${f}"`);let g=await s.saveDocument(f,p,d,h);l.status(201).json({relativePath:g})}catch(f){console.error("Error uploading agent document:",f);let p=f instanceof Error?f.message:"Unknown error",d=p.includes("too large")||p.includes("not allowed")?422:500;l.status(d).json({error:p})}}),r.get("/api/projects/:projectName/agents/editable",async(u,l)=>{try{let f=Le(u.params.projectName);if(!f){l.status(400).json({error:"Project name is required"});return}pe("AGENT",`GET editable agents: project="${f}"`);let p=await s.list(f);l.status(200).json(p)}catch(f){console.error("Error listing editable agents:",f);let p=f instanceof Error?f.message:"Unknown error";l.status(500).json({error:`Failed to list editable agents: ${p}`})}}),r.get("/api/projects/:projectName/agents/:agentName",async(u,l)=>{try{let f=Le(u.params.projectName),p=Le(u.params.agentName);if(!f){l.status(400).json({error:"Project name is required"});return}if(!p){l.status(400).json({error:"Agent name is required"});return}pe("AGENT",`GET agent: "${p}" in project="${f}"`);let d=await s.get(f,p);if(!d){l.status(404).json({error:`Agent '${p}' not found`});return}l.status(200).json(d)}catch(f){console.error("Error getting agent:",f);let p=f instanceof Error?f.message:"Unknown error";l.status(500).json({error:`Failed to get agent: ${p}`})}}),r.post("/api/projects/:projectName/agents",async(u,l)=>{try{let f=Le(u.params.projectName);if(!f){l.status(400).json({error:"Project name is required"});return}let{location:p,definition:d}=u.body;if(!d||typeof d!="object"){l.status(422).json({error:"Agent definition is required"});return}if(!d.name||typeof d.name!="string"){l.status(422).json({error:"Agent name is required"});return}if(!d.description||typeof d.description!="string"){l.status(422).json({error:"Agent description is required"});return}let m=p==="colocated"?"colocated":"project";pe("AGENT",`POST create agent: "${d.name}" in ${m} for project="${f}"`);let h=await s.create(f,d,m);l.status(201).json(h)}catch(f){console.error("Error creating agent:",f);let p=f instanceof Error?f.message:"Unknown error";if(p.includes("already exists")||p.includes("must start with")){l.status(422).json({error:p});return}l.status(500).json({error:`Failed to create agent: ${p}`})}}),r.put("/api/projects/:projectName/agents/:agentName",async(u,l)=>{try{let f=Le(u.params.projectName),p=Le(u.params.agentName);if(!f){l.status(400).json({error:"Project name is required"});return}if(!p){l.status(400).json({error:"Agent name is required"});return}let{definition:d}=u.body;if(!d||typeof d!="object"){l.status(422).json({error:"Agent definition is required"});return}pe("AGENT",`PUT update agent: "${p}" in project="${f}"`);let m=await s.update(f,p,d);if(!m){l.status(404).json({error:`Agent '${p}' not found`});return}l.status(200).json(m)}catch(f){console.error("Error updating agent:",f);let p=f instanceof Error?f.message:"Unknown error";if(p.includes("cannot be empty")){l.status(422).json({error:p});return}l.status(500).json({error:`Failed to update agent: ${p}`})}}),r.delete("/api/projects/:projectName/agents/:agentName",async(u,l)=>{try{let f=Le(u.params.projectName),p=Le(u.params.agentName);if(!f){l.status(400).json({error:"Project name is required"});return}if(!p){l.status(400).json({error:"Agent name is required"});return}if(pe("AGENT",`DELETE agent: "${p}" in project="${f}"`),!await s.delete(f,p)){l.status(404).json({error:`Agent '${p}' not found`});return}l.status(200).json({success:!0,message:`Agent '${p}' deleted successfully`})}catch(f){console.error("Error deleting agent:",f);let p=f instanceof Error?f.message:"Unknown error";l.status(500).json({error:`Failed to delete agent: ${p}`})}})}function P7e(r,e,t){r.get("/api/projects/:projectName/prompts",async(n,i)=>{try{let a=Le(n.params.projectName);if(!a){i.status(400).json({error:"Project name is required"});return}pe("PROMPT_API",`GET prompts for project: ${a}`);let o=await e.list(a);i.status(200).json(o)}catch(a){console.error("Error listing prompts:",a),i.status(500).json({error:"Failed to list prompts"})}}),r.get("/api/projects/:projectName/prompts/:id",async(n,i)=>{try{let a=Le(n.params.projectName),o=Le(n.params.id);if(!a){i.status(400).json({error:"Project name is required"});return}if(!o){i.status(400).json({error:"Prompt ID is required"});return}pe("PROMPT_API",`GET prompt: ${o} in project: ${a}`);let s=await e.get(a,o);if(!s){i.status(404).json({error:`Prompt with ID '${o}' not found`});return}i.status(200).json(s)}catch(a){console.error("Error retrieving prompt:",a),i.status(500).json({error:"Failed to retrieve prompt"})}}),r.post("/api/projects/:projectName/prompts",async(n,i)=>{try{let a=Le(n.params.projectName);if(!a){i.status(400).json({error:"Project name is required"});return}let o=n.body;if(!o||typeof o!="object"){i.status(422).json({error:"Invalid prompt format"});return}if(!o.name||typeof o.name!="string"){i.status(422).json({error:"Prompt name is required"});return}if(!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(o.name)){i.status(422).json({error:"Prompt name must be lowercase alphanumeric with hyphens (e.g., my-prompt-name)"});return}if(!o.description||typeof o.description!="string"){i.status(422).json({error:"Prompt description is required"});return}if(!o.commands||!Array.isArray(o.commands)||o.commands.length===0){i.status(422).json({error:"Prompt must have at least one command"});return}if(o.webhookEnabled!==void 0&&typeof o.webhookEnabled!="boolean"){i.status(422).json({error:"webhookEnabled must be a boolean"});return}let s=o.source==="project"?"project":"local";if(o.source!==void 0&&o.source!=="local"&&o.source!=="project"){i.status(422).json({error:"source must be 'local' or 'project'"});return}let c=t(n);if(!c){i.status(401).json({error:"Username not found in request headers"});return}pe("PROMPT_API",`POST new prompt: ${o.name} in ${s} for project: ${a}`);let u=await e.create(a,{...o,webhookEnabled:o.webhookEnabled??!1,createdBy:c,source:s},s);i.status(201).json(u)}catch(a){console.error("Error creating prompt:",a);let o=a instanceof Error?a.message:"Unknown error";i.status(500).json({error:`Failed to create prompt: ${o}`})}}),r.put("/api/projects/:projectName/prompts/:id",async(n,i)=>{try{let a=Le(n.params.projectName),o=Le(n.params.id);if(!a){i.status(400).json({error:"Project name is required"});return}if(!o){i.status(404).json({error:"Prompt ID is required"});return}let s=n.body;if(!s||typeof s!="object"){i.status(422).json({error:"Invalid prompt format"});return}if(s.name!==void 0){if(typeof s.name!="string"){i.status(422).json({error:"Prompt name must be a string"});return}if(!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(s.name)){i.status(422).json({error:"Prompt name must be lowercase alphanumeric with hyphens (e.g., my-prompt-name)"});return}}if(s.commands!==void 0&&(!Array.isArray(s.commands)||s.commands.length===0)){i.status(422).json({error:"Prompt must have at least one command"});return}if(s.webhookEnabled!==void 0&&typeof s.webhookEnabled!="boolean"){i.status(422).json({error:"webhookEnabled must be a boolean"});return}if(s.source!==void 0){i.status(422).json({error:"source cannot be changed after creation"});return}let c=t(n);if(!c){i.status(401).json({error:"Username not found in request headers"});return}pe("PROMPT_API",`PUT prompt: ${o} in project: ${a}, user: ${c}`);let u=await e.update(a,o,s,c);if(!u){i.status(404).json({error:`Prompt with ID '${o}' not found`});return}i.status(200).json({success:!0,prompt:u})}catch(a){console.error("Error updating prompt:",a);let o=a instanceof Error?a.message:"Unknown error";if(o.includes("Only CODAY_ADMIN")){i.status(403).json({error:o});return}i.status(500).json({error:`Failed to update prompt: ${o}`})}}),r.delete("/api/projects/:projectName/prompts/:id",async(n,i)=>{try{let a=Le(n.params.projectName),o=Le(n.params.id);if(!a){i.status(400).json({error:"Project name is required"});return}if(!o){i.status(400).json({error:"Prompt ID is required"});return}if(pe("PROMPT_API",`DELETE prompt: ${o} in project: ${a}`),!await e.delete(a,o)){i.status(404).json({error:`Prompt with ID '${o}' not found`});return}i.status(200).json({success:!0,message:"Prompt deleted successfully"})}catch(a){console.error("Error deleting prompt:",a);let o=a instanceof Error?a.message:"Unknown error";i.status(500).json({error:`Failed to delete prompt: ${o}`})}}),r.post("/api/projects/:projectName/prompts/:id/webhook",async(n,i)=>{try{let a=Le(n.params.projectName),o=Le(n.params.id);if(!a){i.status(400).json({error:"Project name is required"});return}if(!o){i.status(400).json({error:"Prompt ID is required"});return}let s=t(n);if(!s){i.status(401).json({error:"Username not found in request headers"});return}pe("PROMPT_API",`POST enable webhook for prompt: ${o} in project: ${a}, user: ${s}`);let c=await e.enableWebhook(a,o,s);if(!c){i.status(404).json({error:`Prompt with ID '${o}' not found`});return}i.status(200).json({success:!0,prompt:c})}catch(a){console.error("Error enabling webhook:",a);let o=a instanceof Error?a.message:"Unknown error";if(o.includes("Only CODAY_ADMIN")){i.status(403).json({error:o});return}i.status(500).json({error:`Failed to enable webhook: ${o}`})}}),r.delete("/api/projects/:projectName/prompts/:id/webhook",async(n,i)=>{try{let a=Le(n.params.projectName),o=Le(n.params.id);if(!a){i.status(400).json({error:"Project name is required"});return}if(!o){i.status(400).json({error:"Prompt ID is required"});return}let s=t(n);if(!s){i.status(401).json({error:"Username not found in request headers"});return}pe("PROMPT_API",`DELETE disable webhook for prompt: ${o} in project: ${a}, user: ${s}`);let c=await e.disableWebhook(a,o,s);if(!c){i.status(404).json({error:`Prompt with ID '${o}' not found`});return}i.status(200).json({success:!0,prompt:c})}catch(a){console.error("Error disabling webhook:",a);let o=a instanceof Error?a.message:"Unknown error";if(o.includes("Only CODAY_ADMIN")){i.status(403).json({error:o});return}i.status(500).json({error:`Failed to disable webhook: ${o}`})}})}function D7e(r,e,t){r.get("/api/projects/:projectName/schedulers",async(n,i)=>{try{let a=Le(n.params.projectName);if(!a){i.status(400).json({error:"Project name is required"});return}let o=t(n);if(!o){i.status(401).json({error:"Username not found in request headers"});return}pe("SCHEDULER_API",`GET schedulers for project: ${a}, user: ${o}`);let s=await e.listSchedulers(a,o);i.json(s)}catch(a){console.error("Error listing schedulers:",a),i.status(500).json({error:"Failed to list schedulers"})}}),r.get("/api/projects/:projectName/schedulers/:id",async(n,i)=>{try{let a=Le(n.params.projectName),o=Le(n.params.id);if(!a){i.status(400).json({error:"Project name is required"});return}if(!o){i.status(400).json({error:"Scheduler ID is required"});return}let s=t(n);if(!s){i.status(401).json({error:"Username not found in request headers"});return}pe("SCHEDULER_API",`GET scheduler: ${o} in project: ${a}, user: ${s}`);let c=await e.getScheduler(a,o,s);if(!c){i.status(404).json({error:"Scheduler not found or access denied"});return}i.json(c)}catch(a){console.error("Error getting scheduler:",a),i.status(500).json({error:"Failed to get scheduler"})}}),r.post("/api/projects/:projectName/schedulers",async(n,i)=>{try{let a=Le(n.params.projectName);if(!a){i.status(400).json({error:"Project name is required"});return}let o=t(n);if(!o){i.status(401).json({error:"Username not found in request headers"});return}let{name:s,promptId:c,schedule:u,parameters:l,enabled:f}=n.body;if(!s||typeof s!="string"){i.status(400).json({error:"Name is required and must be a string"});return}if(!c||typeof c!="string"){i.status(400).json({error:"Prompt ID is required and must be a string"});return}if(!u||typeof u!="object"){i.status(400).json({error:"Schedule is required and must be an object"});return}let p=e.validateSchedule(u);if(!p.valid){i.status(400).json({error:p.error});return}if(l!==void 0&&typeof l!="object"){i.status(400).json({error:"Parameters must be an object"});return}if(f!==void 0&&typeof f!="boolean"){i.status(400).json({error:"Enabled must be a boolean"});return}pe("SCHEDULER_API",`POST new scheduler: ${s} in project: ${a}, user: ${o}`);let d=await e.createScheduler(a,{name:s,promptId:c,schedule:u,parameters:l,enabled:f},o);i.status(201).json(d)}catch(a){console.error("Error creating scheduler:",a);let o=a instanceof Error?a.message:"Failed to create scheduler";i.status(500).json({error:o})}}),r.put("/api/projects/:projectName/schedulers/:id",async(n,i)=>{try{let a=Le(n.params.projectName),o=Le(n.params.id);if(!a){i.status(400).json({error:"Project name is required"});return}if(!o){i.status(400).json({error:"Scheduler ID is required"});return}let s=t(n);if(!s){i.status(401).json({error:"Username not found in request headers"});return}let{name:c,enabled:u,promptId:l,schedule:f,parameters:p}=n.body;if(c!==void 0&&typeof c!="string"){i.status(400).json({error:"Name must be a string"});return}if(u!==void 0&&typeof u!="boolean"){i.status(400).json({error:"Enabled must be a boolean"});return}if(l!==void 0&&typeof l!="string"){i.status(400).json({error:"Prompt ID must be a string"});return}if(f!==void 0){if(typeof f!="object"){i.status(400).json({error:"Schedule must be an object"});return}let m=e.validateSchedule(f);if(!m.valid){i.status(400).json({error:m.error});return}}if(p!==void 0&&typeof p!="object"){i.status(400).json({error:"Parameters must be an object"});return}pe("SCHEDULER_API",`PUT scheduler: ${o} in project: ${a}, user: ${s}`);let d=await e.updateScheduler(a,o,{name:c,enabled:u,promptId:l,schedule:f,parameters:p},s);i.json(d)}catch(a){console.error("Error updating scheduler:",a);let o=a instanceof Error?a.message:"Failed to update scheduler";o.includes("not found")||o.includes("access denied")?i.status(404).json({error:o}):i.status(500).json({error:o})}}),r.delete("/api/projects/:projectName/schedulers/:id",async(n,i)=>{try{let a=Le(n.params.projectName),o=Le(n.params.id);if(!a){i.status(400).json({error:"Project name is required"});return}if(!o){i.status(400).json({error:"Scheduler ID is required"});return}let s=t(n);if(!s){i.status(401).json({error:"Username not found in request headers"});return}if(pe("SCHEDULER_API",`DELETE scheduler: ${o} in project: ${a}, user: ${s}`),!await e.deleteScheduler(a,o,s)){i.status(404).json({error:"Scheduler not found or access denied"});return}i.json({success:!0,message:"Scheduler deleted"})}catch(a){console.error("Error deleting scheduler:",a),i.status(500).json({error:"Failed to delete scheduler"})}}),r.post("/api/projects/:projectName/schedulers/:id/enable",async(n,i)=>{try{let a=Le(n.params.projectName),o=Le(n.params.id);if(!a){i.status(400).json({error:"Project name is required"});return}if(!o){i.status(400).json({error:"Scheduler ID is required"});return}let s=t(n);if(!s){i.status(401).json({error:"Username not found in request headers"});return}pe("SCHEDULER_API",`POST enable scheduler: ${o} in project: ${a}, user: ${s}`);let c=await e.enableScheduler(a,o,s);i.json(c)}catch(a){console.error("Error enabling scheduler:",a);let o=a instanceof Error?a.message:"Failed to enable scheduler";o.includes("not found")||o.includes("access denied")?i.status(404).json({error:o}):i.status(500).json({error:o})}}),r.post("/api/projects/:projectName/schedulers/:id/disable",async(n,i)=>{try{let a=Le(n.params.projectName),o=Le(n.params.id);if(!a){i.status(400).json({error:"Project name is required"});return}if(!o){i.status(400).json({error:"Scheduler ID is required"});return}let s=t(n);if(!s){i.status(401).json({error:"Username not found in request headers"});return}pe("SCHEDULER_API",`POST disable scheduler: ${o} in project: ${a}, user: ${s}`);let c=await e.disableScheduler(a,o,s);i.json(c)}catch(a){console.error("Error disabling scheduler:",a);let o=a instanceof Error?a.message:"Failed to disable scheduler";o.includes("not found")||o.includes("access denied")?i.status(404).json({error:o}):i.status(500).json({error:o})}}),r.post("/api/projects/:projectName/schedulers/:id/run-now",async(n,i)=>{try{let a=Le(n.params.projectName),o=Le(n.params.id);if(!a){i.status(400).json({error:"Project name is required"});return}if(!o){i.status(400).json({error:"Scheduler ID is required"});return}let s=t(n);if(!s){i.status(401).json({error:"Username not found in request headers"});return}pe("SCHEDULER_API",`POST run-now scheduler: ${o} in project: ${a}, user: ${s}`);let c=await e.runSchedulerNow(a,o,s);i.json({success:!0,message:"Scheduler executed",threadId:c})}catch(a){console.error("Error running scheduler:",a);let o=a instanceof Error?a.message:"Failed to run scheduler";o.includes("not found")||o.includes("access denied")?i.status(404).json({error:o}):i.status(500).json({error:o})}})}function I7e(r,e,t){r.post("/api/webhooks/:promptId/execute",async(n,i)=>{try{let a=Le(n.params.promptId);if(!a){pe("WEBHOOK","Missing promptId in request"),i.status(400).send({error:"Missing prompt ID in URL"});return}let{title:o,awaitFinalAnswer:s,...c}=n.body,u=t(n);if(!u){i.status(401).send({error:"Username not found in request headers"});return}pe("WEBHOOK",`Executing prompt ${a} for user ${u}`);let l=await e.executePrompt(a,c,u,"webhook",{title:o,awaitFinalAnswer:s});s?i.status(200).send(l):i.status(201).send(l)}catch(a){let o=a instanceof Error?a.message:"Unknown error";console.error("Error in webhook endpoint:",a),o.includes("not found")?i.status(404).send({error:o}):o.includes("not enabled for webhook")?i.status(403).send({error:o}):o.includes("Missing required parameters")||o.includes("contains structured placeholders")||o.includes("Missing or invalid")||o.includes("not configured")?i.status(422).send({error:o}):i.status(500).send({error:"Internal server error"})}})}function Z1(r,e){return e===void 0?r:(r??0)+e}function fT(r,e){if(typeof r!="string"||!/^\d{4}-\d{2}-\d{2}$/.test(r))return;let t=e?"00:00:00.000Z":"23:59:59.999Z",n=new Date(`${r}T${t}`);return isNaN(n.getTime())?void 0:n}function O7e(r,e,t){return`${r}|${e}|${t}`}function $7e(r,e,t){r.get("/api/token-usage",async(n,i)=>{try{let a=fT(n.query.from,!0)??new Date(0),o=fT(n.query.to,!1)??new Date,s=t(n);pe("TOKEN_USAGE",`GET /api/token-usage from=${a.toISOString()} to=${o.toISOString()} user=${s}`);let u=(await e.readLogs(a,o)).filter(h=>h.type==="AGENT_USAGE"&&(h.username===s||h.username==="no_username")),l=new Map;for(let h of u){let g=h.providerName??"",v=O7e(h.agent,g,h.model),y=l.get(v);y||(y={agentName:h.agent,providerName:g,modelId:h.model,promptTokens:null,completionTokens:null,totalTokens:null,callCount:0,cost:0,tokenDataPartial:!1},l.set(v,y)),y.promptTokens=Z1(y.promptTokens,h.promptTokens),y.completionTokens=Z1(y.completionTokens,h.completionTokens),y.totalTokens=Z1(y.totalTokens,h.totalTokens),y.callCount+=1,y.cost+=h.cost??0,(h.promptTokens===void 0||h.completionTokens===void 0||h.totalTokens===void 0)&&(y.tokenDataPartial=!0)}let f=Array.from(l.values()),p=f.some(h=>h.tokenDataPartial),d=h=>{let g=h.filter(v=>v!==null);return g.length>0?g.reduce((v,y)=>v+y,0):null},m={agentName:"total",providerName:"all",modelId:"all",promptTokens:d(f.map(h=>h.promptTokens)),completionTokens:d(f.map(h=>h.completionTokens)),totalTokens:d(f.map(h=>h.totalTokens)),callCount:f.reduce((h,g)=>h+g.callCount,0),cost:f.reduce((h,g)=>h+g.cost,0),tokenDataPartial:p};i.status(200).json({from:a.toISOString(),to:o.toISOString(),tokenDataPartial:p,models:f,total:m})}catch(a){console.error("Error reading token usage:",a);let o=a instanceof Error?a.message:"Unknown error";i.status(500).json({error:`Failed to read token usage: ${o}`})}}),r.get("/api/token-usage/series",async(n,i)=>{try{let a=fT(n.query.from,!0)??new Date(0),o=fT(n.query.to,!1)??new Date,s=t(n);pe("TOKEN_USAGE",`GET /api/token-usage/series from=${a.toISOString()} to=${o.toISOString()} user=${s}`);let u=(await e.readLogs(a,o)).filter(d=>d.type==="AGENT_USAGE"&&(d.username===s||d.username==="no_username")),l=new Map;for(let d of u){let m=d.timestamp.slice(0,10),h=d.providerName??"",g=`${m}|${O7e(d.agent,h,d.model)}`,v=l.get(g);v||(v={date:m,agentName:d.agent,providerName:h,modelId:d.model,promptTokens:null,completionTokens:null,totalTokens:null,callCount:0,cost:0,tokenDataPartial:!1},l.set(g,v)),v.promptTokens=Z1(v.promptTokens,d.promptTokens),v.completionTokens=Z1(v.completionTokens,d.completionTokens),v.totalTokens=Z1(v.totalTokens,d.totalTokens),v.callCount+=1,v.cost+=d.cost??0,(d.promptTokens===void 0||d.completionTokens===void 0||d.totalTokens===void 0)&&(v.tokenDataPartial=!0)}let f=Array.from(l.values()).sort((d,m)=>{let h=d.date.localeCompare(m.date);return h!==0?h:d.agentName.localeCompare(m.agentName)}),p=f.some(d=>d.tokenDataPartial);i.status(200).json({from:a.toISOString(),to:o.toISOString(),tokenDataPartial:p,points:f})}catch(a){console.error("Error reading token usage series:",a);let o=a instanceof Error?a.message:"Unknown error";i.status(500).json({error:`Failed to read token usage series: ${o}`})}})}import ZG from"path";import{notStrictEqual as k7t,strictEqual as A7t}from"assert";var $9t={right:M9t,center:L9t},j9t=0,pT=1,R9t=2,dT=3,mG=class{constructor(e){var t;this.width=e.width,this.wrap=(t=e.wrap)!==null&&t!==void 0?t:!0,this.rows=[]}span(...e){let t=this.div(...e);t.span=!0}resetOutput(){this.rows=[]}div(...e){if(e.length===0&&this.div(""),this.wrap&&this.shouldApplyLayoutDSL(...e)&&typeof e[0]=="string")return this.applyLayoutDSL(e[0]);let t=e.map(n=>typeof n=="string"?this.colFromString(n):n);return this.rows.push(t),t}shouldApplyLayoutDSL(...e){return e.length===1&&typeof e[0]=="string"&&/[\t\n]/.test(e[0])}applyLayoutDSL(e){let t=e.split(`
|
|
1438
1438
|
`).map(i=>i.split(" ")),n=0;return t.forEach(i=>{i.length>1&&Io.stringWidth(i[0])>n&&(n=Math.min(Math.floor(this.width*.5),Io.stringWidth(i[0])))}),t.forEach(i=>{this.div(...i.map((a,o)=>({text:a.trim(),padding:this.measurePadding(a),width:o===0&&i.length>1?n:void 0})))}),this.rows[this.rows.length-1]}colFromString(e){return{text:e,padding:this.measurePadding(e)}}measurePadding(e){let t=Io.stripAnsi(e);return[0,t.match(/\s*$/)[0].length,0,t.match(/^\s*/)[0].length]}toString(){let e=[];return this.rows.forEach(t=>{this.rowToString(t,e)}),e.filter(t=>!t.hidden).map(t=>t.text).join(`
|
|
1439
1439
|
`)}rowToString(e,t){return this.rasterize(e).forEach((n,i)=>{let a="";n.forEach((o,s)=>{let{width:c}=e[s],u=this.negatePadding(e[s]),l=o;if(u>Io.stringWidth(o)&&(l+=" ".repeat(u-Io.stringWidth(o))),e[s].align&&e[s].align!=="left"&&this.wrap){let p=$9t[e[s].align];l=p(l,u),Io.stringWidth(l)<u&&(l+=" ".repeat((c||0)-Io.stringWidth(l)-1))}let f=e[s].padding||[0,0,0,0];f[dT]&&(a+=" ".repeat(f[dT])),a+=j7e(e[s],l,"| "),a+=l,a+=j7e(e[s],l," |"),f[pT]&&(a+=" ".repeat(f[pT])),i===0&&t.length>0&&(a=this.renderInline(a,t[t.length-1]))}),t.push({text:a.replace(/ +$/,""),span:e.span})}),t}renderInline(e,t){let n=e.match(/^ */),i=n?n[0].length:0,a=t.text,o=Io.stringWidth(a.trimRight());return t.span?this.wrap?i<o?e:(t.hidden=!0,a.trimRight()+" ".repeat(i-o)+e.trimLeft()):(t.hidden=!0,a+e):e}rasterize(e){let t=[],n=this.columnWidths(e),i;return e.forEach((a,o)=>{a.width=n[o],this.wrap?i=Io.wrap(a.text,this.negatePadding(a),{hard:!0}).split(`
|
|
1440
1440
|
`):i=a.text.split(`
|