@whoz-oss/coday-server 0.232.0 → 0.233.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/server.js +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@whoz-oss/coday-server",
3
- "version": "0.232.0",
3
+ "version": "0.233.0",
4
4
  "repository": "https://github.com/whoz-oss/coday",
5
5
  "type": "module",
6
6
  "main": "server/server.js",
package/server.js CHANGED
@@ -897,7 +897,7 @@ Stopping will:
897
897
  - Clear pending commands
898
898
  - Return to prompt`;if(await this.interactor.chooseOption(["proceed","stop"],u,"What do you want to do?")==="stop")return i.runStatus="STOPPED",!1;s.price>0?(s.priceThreshold*=2,this.interactor.displayText(`Cost threshold increased to ${s.priceThreshold.toFixed(2)}`)):(s.iterationsThreshold*=2,this.interactor.displayText(`Iteration threshold increased to ${s.iterationsThreshold}`))}return await Promise.all(r.map(async a=>{let o;try{a.threadId=i.id,this.interactor.sendEvent(a),o=await n.tools.run(a,i)}catch(c){let u=`Error running tool ${a.name}: ${c}`;console.error(u),o=a.buildResponse(u)}o.threadId=i.id,this.interactor.sendEvent(o),i.addToolRequests(n.name,[a]),i.addToolResponseEvents([o])})),this.shouldProceed(i)}handleError(e,r,n){let i=`${n} error occurred`;if(e instanceof Error){i=`${n} error: ${e.message}`;let s=e;s.status===401||s.statusCode===401?i=`${n} authentication failed. Please check your API key.`:s.status===429||s.statusCode===429?i=`${n} rate limit exceeded. Please try again later.`:s.code==="ECONNREFUSED"||s.code==="ENOTFOUND"||s.code==="ETIMEDOUT"?i=`Network error connecting to ${n}. Please check your internet connection.`:e.message?.includes("Max tokens")&&(i=`${n} response exceeded token limit. Try simplifying your request or splitting it into smaller parts.`)}console.error(`${n} client error:`,e),r.next(new fc({error:e instanceof Error?e:new Error(i)})),this.interactor.displayText(`\u26A0\uFE0F ${i}`)}shouldProceed(e){return e.runStatus==="RUNNING"&&!this.killed}showAgentAndUsage(e,r,n,i){let s=`\u{1F916} ${e.name} | ${r} - ${n} `;if(!i.usage)return;let a=`Loop${i.usage.iterations>1?"s":""}: ${i.usage.iterations} | `,o=`Input: ${i.usage.input}, Output: ${i.usage.output} | `,c=`Cache write: ${i.usage.cache_write}, Cache read: ${i.usage.cache_read}`,u=`\u{1F3C3}${i.usage.price.toFixed(3)} / \u{1F9F5}${i.price.toFixed(3)}`;this.interactor.sendEvent(new Hp({text:s+u,threadId:i.id})),this.interactor.debug(a+o+c)}getModel(e){let r=e.definition.modelName?.toLowerCase(),n=this.models.find(i=>i.alias?.toLowerCase()===r);return n||this.models.find(i=>i.name.toLowerCase()===r)}supportsModel(e){return this.models.some(r=>r.name.toLowerCase()===e||r?.alias?.toLowerCase()===e)}returnError(e){return(0,BTe.of)(new fc({error:e}))}logAgentUsage(e,r,n,i){let s=i?.usage?.input??0,a=i?.usage?.output??0,o=s+a;this.logger?.logAgentUsage(i?.username??this.username??"no_username",e.name,r,n,this.name,s,a,o)}};var Tr=class{constructor(e,r,n){this.interactor=e;this.name=r,this.config=n}tools=[];name;config;async kill(){}async getTools(e,r,n){return this.tools=await this.buildTools(e,n),this.tools.filter(i=>{if(!r||!r.length)return!0;let s=i.function.name.split("__")[1]??i.function.name;return r.includes(s)})}};var Nv=class t{constructor(e,r){this.project=e;this.username=r}commandQueue=[];clearCommands(){this.commandQueue=[]}oneshot=!1;fileReadOnly=!1;threadFilesRoot;stackDepth=10;data={};aiThread;addCommands(...e){this.commandQueue.unshift(...e)}getFirstCommand(){return this.commandQueue.shift()}getSubContext(...e){let r=new t(this.project,this.username);return r.oneshot=this.oneshot,r.fileReadOnly=this.fileReadOnly,r.addCommands(...e),r.stackDepth=this.stackDepth-1,r}cloneWithoutCommands(){let e=new t(this.project,this.username);return e.oneshot=this.oneshot,e.fileReadOnly=this.fileReadOnly,e.stackDepth=this.stackDepth,e.data=this.data,e}};var XBt=["project","user"],Ia=class{static validate(e){if(!XBt.includes(e))throw new Error(`Invalid configuration level: ${e}. Only PROJECT and USER levels are allowed.`)}};var zTe=[".pdf",".doc",".docx",".odt",".rtf",".xls",".xlsx",".ods",".csv",".tsv",".txt",".md",".markdown",".rst",".json",".xml",".yaml",".yml",".toml",".html",".htm",".css",".svg",".ts",".tsx",".js",".jsx",".py",".java",".cpp",".c",".h",".hpp",".cs",".go",".rs",".rb",".php",".swift",".kt",".scala",".sh",".bash",".sql",".env",".properties",".ini",".conf",".config",".log"];function lj(t){let e=t.toLowerCase().substring(t.lastIndexOf("."));return zTe.includes(e)}function UTe(){return zTe.join(", ")}var fj=class{constructor(e){this.tools=e;this.charLength=JSON.stringify(e).length}charLength=0;getTools(){return[...this.tools]}async run(e,r){let n=this.tools.find(c=>c.function.name===e.name);if(!n)throw new Error(`Tool '${e.name}' not found`);let i,s=n.function.function,a=JSON.parse(e.args),o=Array.isArray(a)?a:[a];if(i=await s(...o,r),i||(i=`Tool function ${e.name} finished without error.`),typeof i!="string"){if(i&&typeof i=="object"&&"type"in i&&(i.type==="text"||i.type==="image"))return e.buildResponse(i);i=JSON.stringify(i)}return e.buildResponse(i)}};var dj={CONFLUENCE:[],GIT:[],GIT_WORKTREE:[],GITLAB:[],JIRA:[],SLACK:[],ZENDESK:[],BASECAMP:[]},c1=Object.keys(dj).filter(t=>dj[t]?.length===0);var qs=sn(ru(),1),pj=class{events=new qs.Subject;thinking$=new qs.Subject;subs=[];lastQuestionEvent;debugLevelEnabled=!1;constructor(){this.subs.push(this.thinking$.pipe((0,qs.throttleTime)(o1.debounce)).subscribe(()=>this.sendEvent(new o1({}))))}lastAnswerName=void 0;async promptText(e,r){let n=new ks({invite:e,defaultValue:r});this.lastQuestionEvent=n;let i=this.events.pipe((0,qs.filter)(s=>s.parentKey===n.timestamp),(0,qs.filter)(s=>s instanceof An),(0,qs.take)(1),(0,qs.map)(s=>s));this.sendEvent(n);try{let s=await(0,qs.firstValueFrom)(i);return this.lastAnswerName=s.name,this.lastQuestionEvent=void 0,s.answer}catch(s){throw new Error(`No answer received over invite ${n.timestamp} : ${s.message}`)}}async promptSecretText(e,r,n="********"){let i=r?n:"",s=await this.promptText(e,i);if(s===n&&r)return r;if(s)return s}async chooseOption(e,r,n,i){let s=new As({options:e,invite:r,optionalQuestion:n,allowFreeText:i??!1});this.lastQuestionEvent=s;let a=this.events.pipe((0,qs.filter)(o=>o.parentKey===s.timestamp),(0,qs.filter)(o=>o instanceof An),(0,qs.take)(1),(0,qs.map)(o=>o.answer));this.sendEvent(s);try{let o=await(0,qs.firstValueFrom)(a);return this.lastQuestionEvent=void 0,o}catch(o){throw new Error(`No answer received over choice ${s.timestamp} : ${o.message}`)}}displayText(e,r){this.sendEvent(new Hp({text:e,speaker:r}))}debug(e){if(!this.debugLevelEnabled)return;let r=`${new Date().toISOString()} DEBUG: ${e.toString()}`;console.log(r),this.sendEvent(new Hp({text:r}))}warn(e){this.sendEvent(new Dv({warning:e}))}error(e){this.sendEvent(new fc({error:e}))}thinking(){this.thinking$.next(null)}sendEvent(e){this.events.next(e)}replayLastQuestion(){this.lastQuestionEvent&&this.sendEvent(this.lastQuestionEvent)}getLastQuestionEvent(){return this.lastQuestionEvent}kill(){this.subs.forEach(e=>e.unsubscribe()),this.events.complete()}};var gw=class{title;content;level;agentName;createdAt;updatedAt;constructor(e){this.title=e.title??"no title",this.content=e.content??"no content",this.level=e.level??"PROJECT",this.agentName=e.agentName,this.createdAt=e.createdAt??new Date,this.updatedAt=e.updatedAt}update(e){return this.title=e.title??this.title,this.content=e.content??this.content,this.level=e.level??this.level,this.agentName=e.agentName,this.createdAt=e.createdAt??new Date,this.updatedAt=e.updatedAt??new Date,this}};var vd=class extends pj{constructor(r){super();this.clientId=r}addAnswerEvent(r,n){let i=new An({answer:r,parentKey:n});this.sendEvent(i)}kill(){console.log(`Interactor for clientId ${this.clientId} killed`),super.kill()}};var HTe={version:1};var hj=class extends mt{constructor(r){super({commandWord:"add-query",description:"[internal] used to allow user feedback between flow commands.",isInternal:!0});this.interactor=r}async handle(r,n){let i=this.getSubCommand(r),s=i||"What message would you want to add ?",a=await this.interactor.promptText(`${s}
899
899
  (type nothing to proceed) `),o=i?`To the following query: "${i}"
900
- I answer: `:"",c=a?`"${a}"`:i?'nothing."':"";return(a||i)&&n.addCommands(`@ ${o}${c}`),n}};Yee();var PN=sn(ru(),1);var yHt=[{name:"claude-fable-5",alias:"FRONTIER",contextWindow:2e5,maxOutputTokens:64e3,price:{inputMTokens:10,cacheWrite:12.5,cacheRead:1,outputMTokens:50}},{name:"claude-sonnet-5",alias:"BIG",contextWindow:2e5,maxOutputTokens:64e3,price:{inputMTokens:2,cacheWrite:2.5,cacheRead:.2,outputMTokens:10}},{name:"claude-opus-5",alias:"BIGGEST",contextWindow:2e5,maxOutputTokens:64e3,price:{inputMTokens:5,cacheWrite:6.25,cacheRead:.5,outputMTokens:25}},{name:"claude-haiku-4-5",alias:"SMALL",contextWindow:2e5,temperature:.8,maxOutputTokens:64e3,price:{inputMTokens:1,cacheWrite:1.25,cacheRead:.1,outputMTokens:5}}],bHt=60,sre=.4,xHt=16e3,are=.9,bOe=.5,_Ht=5,TN=class extends jv{constructor(r,n,i){super(n,i);this.interactor=r;this.name="Anthropic",this.mergeModels(yHt)}name;rateLimitInfo=null;async run(r,n){let i=this.isAnthropicReady(),s=this.getModel(r);if(!i||!s)return(0,PN.of)();n.resetUsageForRun();let a=new PN.Subject,o=this.startThinkingInterval();return this.processThread(i,r,s,n,a).catch(c=>{a.next(new fc({error:c}))}).finally(()=>{this.stopThinkingInterval(o),this.showAgentAndUsage(r,"Anthropic",s.name,n);let c=n.usage?.price||0;this.logAgentUsage(r,s.name,c,n),a.complete()}),a}async processThread(r,n,i,s,a){await this.applyThrottlingDelay();let o=n.systemInstructions.length+n.tools.charLength+20,c=Math.max(i.contextWindow*this.charsPerToken-o,1e4),u,f;try{let h=await this.streamApiCall(r,i,n,s,c,a);u=h.data,f=h.response}catch(h){if(h.status===400&&h.error?.error?.message?.includes("prompt is too long")){this.interactor.displayText("\u26A0\uFE0F Context window exceeded. Forcing aggressive compaction...");let m=h.error.error.message.match(/(\d+) tokens > (\d+) maximum/);if(m){let g=parseInt(m[1]),v=parseInt(m[2]),y=g-v,b=Math.ceil(y*this.charsPerToken*1.2);c=Math.max(c-b,5e3),this.interactor.debug(`Token overshoot: ${y} tokens (${b} chars). Reduced budget to ${c} chars.`)}else c=Math.floor(c*.7),this.interactor.debug(`Reduced budget by 30% to ${c} chars.`);try{let g=await this.streamApiCall(r,i,n,s,c,a,!0);u=g.data,f=g.response,this.interactor.displayText("\u2705 Successfully recovered with compacted context")}catch(g){this.handleError(g,a,this.name);return}}else if(h.status===429&&h.headers){let m=parseInt(h.headers["retry-after"]??"60");this.interactor.displayText(`\u23F3 Rate limit hit. Waiting ${m} seconds before retry...`),this.updateRateLimitsFromHeaders(h.headers),this.displayRateLimitStatus(h.headers);try{await this.delay(m*1e3,"rate limit retry")}catch{this.handleError(new Error("Rate limit retry interrupted by shutdown"),a,this.name);return}this.interactor.displayText("\u{1F504} Retrying request...");try{let g=await this.streamApiCall(r,i,n,s,c,a);u=g.data,f=g.response}catch(g){this.handleError(g,a,this.name);return}}else{this.handleError(h,a,this.name);return}}if(f&&this.updateRateLimitsFromHeaders(f.headers),this.updateUsage(u?.usage,n,s),u.stop_reason==="max_tokens")throw new Error("Max tokens reached for Anthropic \u{1F62C}");let d=u.content.filter(h=>h.type==="text").map(h=>h.text.trim()).filter(h=>!!h).join(`
900
+ I answer: `:"",c=a?`"${a}"`:i?'nothing."':"";return(a||i)&&n.addCommands(`@ ${o}${c}`),n}};Yee();var PN=sn(ru(),1);var yHt=[{name:"claude-fable-5",alias:"FRONTIER",contextWindow:2e5,maxOutputTokens:64e3,price:{inputMTokens:10,cacheWrite:12.5,cacheRead:1,outputMTokens:50}},{name:"claude-sonnet-4-6",alias:"BIG",contextWindow:2e5,temperature:.8,maxOutputTokens:64e3,price:{inputMTokens:3,cacheWrite:3.75,cacheRead:.3,outputMTokens:15}},{name:"claude-opus-5",alias:"BIGGEST",contextWindow:2e5,maxOutputTokens:64e3,price:{inputMTokens:5,cacheWrite:6.25,cacheRead:.5,outputMTokens:25}},{name:"claude-haiku-4-5",alias:"SMALL",contextWindow:2e5,temperature:.8,maxOutputTokens:64e3,price:{inputMTokens:1,cacheWrite:1.25,cacheRead:.1,outputMTokens:5}}],bHt=60,sre=.4,xHt=16e3,are=.9,bOe=.5,_Ht=5,TN=class extends jv{constructor(r,n,i){super(n,i);this.interactor=r;this.name="Anthropic",this.mergeModels(yHt)}name;rateLimitInfo=null;async run(r,n){let i=this.isAnthropicReady(),s=this.getModel(r);if(!i||!s)return(0,PN.of)();n.resetUsageForRun();let a=new PN.Subject,o=this.startThinkingInterval();return this.processThread(i,r,s,n,a).catch(c=>{a.next(new fc({error:c}))}).finally(()=>{this.stopThinkingInterval(o),this.showAgentAndUsage(r,"Anthropic",s.name,n);let c=n.usage?.price||0;this.logAgentUsage(r,s.name,c,n),a.complete()}),a}async processThread(r,n,i,s,a){await this.applyThrottlingDelay();let o=n.systemInstructions.length+n.tools.charLength+20,c=Math.max(i.contextWindow*this.charsPerToken-o,1e4),u,f;try{let h=await this.streamApiCall(r,i,n,s,c,a);u=h.data,f=h.response}catch(h){if(h.status===400&&h.error?.error?.message?.includes("prompt is too long")){this.interactor.displayText("\u26A0\uFE0F Context window exceeded. Forcing aggressive compaction...");let m=h.error.error.message.match(/(\d+) tokens > (\d+) maximum/);if(m){let g=parseInt(m[1]),v=parseInt(m[2]),y=g-v,b=Math.ceil(y*this.charsPerToken*1.2);c=Math.max(c-b,5e3),this.interactor.debug(`Token overshoot: ${y} tokens (${b} chars). Reduced budget to ${c} chars.`)}else c=Math.floor(c*.7),this.interactor.debug(`Reduced budget by 30% to ${c} chars.`);try{let g=await this.streamApiCall(r,i,n,s,c,a,!0);u=g.data,f=g.response,this.interactor.displayText("\u2705 Successfully recovered with compacted context")}catch(g){this.handleError(g,a,this.name);return}}else if(h.status===429&&h.headers){let m=parseInt(h.headers["retry-after"]??"60");this.interactor.displayText(`\u23F3 Rate limit hit. Waiting ${m} seconds before retry...`),this.updateRateLimitsFromHeaders(h.headers),this.displayRateLimitStatus(h.headers);try{await this.delay(m*1e3,"rate limit retry")}catch{this.handleError(new Error("Rate limit retry interrupted by shutdown"),a,this.name);return}this.interactor.displayText("\u{1F504} Retrying request...");try{let g=await this.streamApiCall(r,i,n,s,c,a);u=g.data,f=g.response}catch(g){this.handleError(g,a,this.name);return}}else{this.handleError(h,a,this.name);return}}if(f&&this.updateRateLimitsFromHeaders(f.headers),this.updateUsage(u?.usage,n,s),u.stop_reason==="max_tokens")throw new Error("Max tokens reached for Anthropic \u{1F62C}");let d=u.content.filter(h=>h.type==="text").map(h=>h.text.trim()).filter(h=>!!h).join(`
901
901
  `);this.handleText(s,d,n,a);let p=u.content.filter(h=>h.type==="tool_use").map(h=>new Di({toolRequestId:h.id,name:h.name,args:JSON.stringify(h.input)}));await this.shouldProcessAgainAfterResponse(d,p,n,s)&&await this.processThread(r,n,i,s,a)}updateUsage(r,n,i){let s=this.getModel(n),a=(r?.input_tokens??0)*(s?.price?.inputMTokens??0),o=(r?.output_tokens??0)*(s?.price?.outputMTokens??0),c=(r?.cache_creation_input_tokens??0)*(s?.price?.cacheWrite??0),u=(r?.cache_read_input_tokens??0)*(s?.price?.cacheRead??0),f=(a+o+c+u)/1e6;i.addUsage({input:r?.input_tokens??0,output:r?.output_tokens??0,cache_read:r?.cache_read_input_tokens??0,cache_write:r?.cache_creation_input_tokens??0,price:f})}isAnthropicReady(){if(!this.apiKey){this.interactor.warn("ANTHROPIC_API_KEY not set, skipping AI command. Please configure your API key.");return}try{return new Ad({apiKey:this.apiKey,defaultHeaders:{"anthropic-beta":"prompt-caching-2024-07-31"}})}catch(r){let n=r instanceof Error?r.message:"Unknown error";this.interactor.warn(`Failed to initialize Anthropic client: ${n}`),console.error("Anthropic client initialization error:",r);return}}toClaudeMessage(r,n,i=!1){let s=this.getOrUpdateCacheMarker(n,r,i);return r.map(a=>{let o,c=s&&a.timestamp===s;if(a instanceof Ro)o={role:"user",content:[{type:"text",text:a.summary,...c&&{cache_control:{type:"ephemeral"}}}]};else if(a instanceof wr){let u=a.content,f=u.map((d,p)=>{let h;return d.type==="text"&&(h={type:"text",text:d.content}),d.type==="image"&&(h={type:"image",source:{type:"base64",media_type:d.mimeType,data:d.content}}),d.type==="audio"&&(h={type:"text",text:d.transcription?`[Voice message]: ${d.transcription}`:"[Voice message: no transcription available]"}),h?{...h,...c&&p===u.length-1&&{cache_control:{type:"ephemeral"}}}:(this.interactor.warn(`Unknown content type: ${d.type}`),null)}).filter(Boolean);o={role:a.role,content:f}}if(a instanceof Di&&(o={role:"assistant",content:[{type:"tool_use",id:a.toolRequestId,name:a.name,input:JSON.parse(a.args),...c&&{cache_control:{type:"ephemeral"}}}]}),a instanceof Qi){let u;if(typeof a.output=="string")u=a.output;else{let f=a.output;if(f.type==="text")u=[{type:"text",text:f.content}];else if(f.type==="image")u=[{type:"image",source:{type:"base64",media_type:f.mimeType,data:f.content}}];else throw new Error(`Unknown content type: ${f.type}`)}o={role:"user",content:[{type:"tool_result",tool_use_id:a.toolRequestId,content:u,...c&&{cache_control:{type:"ephemeral"}}}]}}else if(a instanceof ks)o={role:"assistant",content:[{type:"text",text:a.invite,...c&&{cache_control:{type:"ephemeral"}}}]};else if(a instanceof As){let f=(Array.isArray(a.options)?a.options:[]).map((p,h)=>`${h+1}. ${p}`).join(`
902
902
  `);o={role:"assistant",content:[{type:"text",text:a.optionalQuestion?`${a.optionalQuestion}
903
903
  ${a.invite}