@whoz-oss/coday-server 0.48.1 → 0.49.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.
- package/package.json +1 -1
- package/server.js +3 -3
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -851,7 +851,7 @@ new Anthropic({ apiKey, dangerouslyAllowBrowser: true });
|
|
|
851
851
|
`);this.baseURL=a.baseURL,this.timeout=a.timeout??DO.DEFAULT_TIMEOUT,this.logger=a.logger??console;let s="warn";this.logLevel=s,this.logLevel=uO(a.logLevel,"ClientOptions.logLevel",this)??uO(T5("ANTHROPIC_LOG"),"process.env['ANTHROPIC_LOG']",this)??s,this.fetchOptions=a.fetchOptions,this.maxRetries=a.maxRetries??2,this.fetch=a.fetch??Bte(),Ke(this,Xy,Ute,"f"),this._options=a,this.apiKey=t,this.authToken=n}withOptions(e){return new this.constructor({...this._options,baseURL:this.baseURL,maxRetries:this.maxRetries,timeout:this.timeout,logger:this.logger,logLevel:this.logLevel,fetch:this.fetch,fetchOptions:this.fetchOptions,apiKey:this.apiKey,authToken:this.authToken,...e})}defaultQuery(){return this._options.defaultQuery}validateHeaders({values:e,nulls:t}){if(!(this.apiKey&&e.get("x-api-key"))&&!t.has("x-api-key")&&!(this.authToken&&e.get("authorization"))&&!t.has("authorization"))throw new Error('Could not resolve authentication method. Expected either apiKey or authToken to be set. Or for one of the "X-Api-Key" or "Authorization" headers to be explicitly omitted')}async authHeaders(e){return tr([await this.apiKeyAuth(e),await this.bearerAuth(e)])}async apiKeyAuth(e){if(this.apiKey!=null)return tr([{"X-Api-Key":this.apiKey}])}async bearerAuth(e){if(this.authToken!=null)return tr([{Authorization:`Bearer ${this.authToken}`}])}stringifyQuery(e){return Object.entries(e).filter(([t,n])=>typeof n<"u").map(([t,n])=>{if(typeof n=="string"||typeof n=="number"||typeof n=="boolean")return`${encodeURIComponent(t)}=${encodeURIComponent(n)}`;if(n===null)return`${encodeURIComponent(t)}=`;throw new lt(`Cannot stringify type ${typeof n}; Expected string, number, boolean, or null. If you need to pass nested query parameters, you can manually encode them, e.g. { query: { 'foo[key1]': value1, 'foo[key2]': value2 } }, and please open a GitHub issue requesting better support for your use case.`)}).join("&")}getUserAgent(){return`${this.constructor.name}/JS ${c2}`}defaultIdempotencyKey(){return`stainless-node-retry-${iO()}`}makeStatusError(e,t,n,i){return jn.generate(e,t,n,i)}buildURL(e,t,n){let i=!ye(this,TO,"m",fre).call(this)&&n||this.baseURL,a=Pte(e)?new URL(e):new URL(i+(i.endsWith("/")&&e.startsWith("/")?e.slice(1):e)),s=this.defaultQuery();return Ote(s)||(t={...s,...t}),typeof t=="object"&&t&&!Array.isArray(t)&&(a.search=this.stringifyQuery(t)),a.toString()}_calculateNonstreamingTimeout(e){if(3600*e/128e3>600)throw new lt("Streaming is required for operations that may take longer than 10 minutes. See https://github.com/anthropics/anthropic-sdk-typescript#streaming-responses for more details");return 600*1e3}async prepareOptions(e){}async prepareRequest(e,{url:t,options:n}){}get(e,t){return this.methodRequest("get",e,t)}post(e,t){return this.methodRequest("post",e,t)}patch(e,t){return this.methodRequest("patch",e,t)}put(e,t){return this.methodRequest("put",e,t)}delete(e,t){return this.methodRequest("delete",e,t)}methodRequest(e,t,n){return this.request(Promise.resolve(n).then(i=>({method:e,path:t,...i})))}request(e,t=null){return new o3(this,this.makeRequest(e,t,void 0))}async makeRequest(e,t,n){let i=await e,a=i.maxRetries??this.maxRetries;t==null&&(t=a),await this.prepareOptions(i);let{req:s,url:o,timeout:c}=await this.buildRequest(i,{retryCount:a-t});await this.prepareRequest(s,{url:o,options:i});let l="log_"+(Math.random()*(1<<24)|0).toString(16).padStart(6,"0"),u=n===void 0?"":`, retryOf: ${n}`,f=Date.now();if(Mn(this).debug(`[${l}] sending request`,_c({retryOfRequestLogID:n,method:i.method,url:o,options:i,headers:s.headers})),i.signal?.aborted)throw new ri;let d=new AbortController,p=await this.fetchWithTimeout(o,s,c,d).catch(c5),m=Date.now();if(p instanceof globalThis.Error){let v=`retrying, ${t} attempts remaining`;if(i.signal?.aborted)throw new ri;let b=xc(p)||/timed? ?out/i.test(String(p)+("cause"in p?String(p.cause):""));if(t)return Mn(this).info(`[${l}] connection ${b?"timed out":"failed"} - ${v}`),Mn(this).debug(`[${l}] connection ${b?"timed out":"failed"} (${v})`,_c({retryOfRequestLogID:n,url:o,durationMs:m-f,message:p.message})),this.retryRequest(i,t,n??l);throw Mn(this).info(`[${l}] connection ${b?"timed out":"failed"} - error; no more retries left`),Mn(this).debug(`[${l}] connection ${b?"timed out":"failed"} (error; no more retries left)`,_c({retryOfRequestLogID:n,url:o,durationMs:m-f,message:p.message})),b?new sd:new o2({cause:p})}let h=[...p.headers.entries()].filter(([v])=>v==="request-id").map(([v,b])=>", "+v+": "+JSON.stringify(b)).join(""),g=`[${l}${u}${h}] ${s.method} ${o} ${p.ok?"succeeded":"failed"} with status ${p.status} in ${m-f}ms`;if(!p.ok){let v=await this.shouldRetry(p);if(t&&v){let R=`retrying, ${t} attempts remaining`;return await $te(p.body),Mn(this).info(`${g} - ${R}`),Mn(this).debug(`[${l}] response error (${R})`,_c({retryOfRequestLogID:n,url:p.url,status:p.status,headers:p.headers,durationMs:m-f})),this.retryRequest(i,t,n??l,p.headers)}let b=v?"error; no more retries left":"error; not retryable";Mn(this).info(`${g} - ${b}`);let w=await p.text().catch(R=>c5(R).message),C=Ay(w),A=C?void 0:w;throw Mn(this).debug(`[${l}] response error (${b})`,_c({retryOfRequestLogID:n,url:p.url,status:p.status,headers:p.headers,message:A,durationMs:Date.now()-f})),this.makeStatusError(p.status,C,A,p.headers)}return Mn(this).info(g),Mn(this).debug(`[${l}] response start`,_c({retryOfRequestLogID:n,url:p.url,status:p.status,headers:p.headers,durationMs:m-f})),{response:p,options:i,controller:d,requestLogID:l,retryOfRequestLogID:n,startTime:f}}getAPIList(e,t,n){return this.requestAPIList(t,{method:"get",path:e,...n})}requestAPIList(e,t){let n=this.makeRequest(t,null,void 0);return new h5(this,n,e)}async fetchWithTimeout(e,t,n,i){let{signal:a,method:s,...o}=t||{};a&&a.addEventListener("abort",()=>i.abort());let c=setTimeout(()=>i.abort(),n),l=globalThis.ReadableStream&&o.body instanceof globalThis.ReadableStream||typeof o.body=="object"&&o.body!==null&&Symbol.asyncIterator in o.body,u={signal:i.signal,...l?{duplex:"half"}:{},method:"GET",...o};s&&(u.method=s.toUpperCase());try{return await this.fetch.call(void 0,e,u)}finally{clearTimeout(c)}}async shouldRetry(e){let t=e.headers.get("x-should-retry");return t==="true"?!0:t==="false"?!1:e.status===408||e.status===409||e.status===429||e.status>=500}async retryRequest(e,t,n,i){let a,s=i?.get("retry-after-ms");if(s){let c=parseFloat(s);Number.isNaN(c)||(a=c)}let o=i?.get("retry-after");if(o&&!a){let c=parseFloat(o);Number.isNaN(c)?a=Date.parse(o)-Date.now():a=c*1e3}if(!(a&&0<=a&&a<60*1e3)){let c=e.maxRetries??this.maxRetries;a=this.calculateDefaultRetryTimeoutMillis(t,c)}return await Fte(a),this.makeRequest(e,t-1,n)}calculateDefaultRetryTimeoutMillis(e,t){let a=t-e,s=Math.min(.5*Math.pow(2,a),8),o=1-Math.random()*.25;return s*o*1e3}calculateNonstreamingTimeout(e,t){if(36e5*e/128e3>6e5||t!=null&&e>t)throw new lt("Streaming is required for operations that may take longer than 10 minutes. See https://github.com/anthropics/anthropic-sdk-typescript#long-requests for more details");return 6e5}async buildRequest(e,{retryCount:t=0}={}){let n={...e},{method:i,path:a,query:s,defaultBaseURL:o}=n,c=this.buildURL(a,s,o);"timeout"in n&&Rte("timeout",n.timeout),n.timeout=n.timeout??this.timeout;let{bodyHeaders:l,body:u}=this.buildBody({options:n}),f=await this.buildHeaders({options:e,method:i,bodyHeaders:l,retryCount:t});return{req:{method:i,headers:f,...n.signal&&{signal:n.signal},...globalThis.ReadableStream&&u instanceof globalThis.ReadableStream&&{duplex:"half"},...u&&{body:u},...this.fetchOptions??{},...n.fetchOptions??{}},url:c,timeout:n.timeout}}async buildHeaders({options:e,method:t,bodyHeaders:n,retryCount:i}){let a={};this.idempotencyHeader&&t!=="get"&&(e.idempotencyKey||(e.idempotencyKey=this.defaultIdempotencyKey()),a[this.idempotencyHeader]=e.idempotencyKey);let s=tr([a,{Accept:"application/json","User-Agent":this.getUserAgent(),"X-Stainless-Retry-Count":String(i),...e.timeout?{"X-Stainless-Timeout":String(Math.trunc(e.timeout/1e3))}:{},...Lte(),...this._options.dangerouslyAllowBrowser?{"anthropic-dangerous-direct-browser-access":"true"}:void 0,"anthropic-version":"2023-06-01"},await this.authHeaders(e),this._options.defaultHeaders,n,e.headers]);return this.validateHeaders(s),s.values}buildBody({options:{body:e,headers:t}}){if(!e)return{bodyHeaders:void 0,body:void 0};let n=tr([t]);return ArrayBuffer.isView(e)||e instanceof ArrayBuffer||e instanceof DataView||typeof e=="string"&&n.values.has("content-type")||globalThis.Blob&&e instanceof globalThis.Blob||e instanceof FormData||e instanceof URLSearchParams||globalThis.ReadableStream&&e instanceof globalThis.ReadableStream?{bodyHeaders:void 0,body:e}:typeof e=="object"&&(Symbol.asyncIterator in e||Symbol.iterator in e&&"next"in e&&typeof e.next=="function")?{bodyHeaders:void 0,body:ky(e)}:ye(this,Xy,"f").call(this,{body:e,headers:n})}};DO=Ur,Xy=new WeakMap,TO=new WeakSet,fre=function(){return this.baseURL!=="https://api.anthropic.com"};Ur.Anthropic=DO;Ur.HUMAN_PROMPT=pre;Ur.AI_PROMPT=dre;Ur.DEFAULT_TIMEOUT=6e5;Ur.AnthropicError=lt;Ur.APIError=jn;Ur.APIConnectionError=o2;Ur.APIConnectionTimeoutError=sd;Ur.APIUserAbortError=ri;Ur.NotFoundError=ud;Ur.ConflictError=fd;Ur.RateLimitError=dd;Ur.BadRequestError=od;Ur.AuthenticationError=cd;Ur.InternalServerError=hd;Ur.PermissionDeniedError=ld;Ur.UnprocessableEntityError=pd;Ur.toFile=Iy;var Do=class extends Ur{constructor(){super(...arguments),this.completions=new u3(this),this.messages=new d2(this),this.models=new f3(this),this.beta=new To(this)}};Do.Completions=u3;Do.Messages=d2;Do.Models=f3;Do.Beta=To;var Zy=Tr(As(),1),qHe=[{name:"claude-sonnet-4-5",alias:"BIG",contextWindow:2e5,temperature:.8,maxOutputTokens:64e3,price:{inputMTokens:3,cacheWrite:3.75,cacheRead:.3,outputMTokens:15}},{name:"claude-opus-4-5",alias:"BIGGEST",contextWindow:2e5,temperature:.8,maxOutputTokens:64e3,price:{inputMTokens:15,cacheWrite:18.75,cacheRead:1.5,outputMTokens:75}},{name:"claude-haiku-4-5",alias:"SMALL",contextWindow:2e5,temperature:.8,maxOutputTokens:64e3,price:{inputMTokens:1,cacheWrite:1.25,cacheRead:.1,outputMTokens:5}}],LHe=60,PO=.4,OO=.9,hre=.5,BHe=5,Qy=class extends qf{constructor(t,n,i){super(n,i);this.interactor=t;this.name="Anthropic",this.mergeModels(qHe)}name;rateLimitInfo=null;async run(t,n){let i=this.isAnthropicReady(),a=this.getModel(t);if(!i||!a)return(0,Zy.of)();n.resetUsageForRun();let s=new Zy.Subject,o=this.startThinkingInterval();return this.processThread(i,t,a,n,s).catch(c=>{s.next(new Wi({error:c}))}).finally(()=>{this.stopThinkingInterval(o),this.showAgentAndUsage(t,"Anthropic",a.name,n);let c=n.usage?.price||0;this.logAgentUsage(t,a.name,c),s.complete()}),s}async processThread(t,n,i,a,s){await this.applyThrottlingDelay();let o=n.systemInstructions.length+n.tools.charLength+20,c=Math.max(i.contextWindow*this.charsPerToken-o,1e4),l,u;try{let p=await this.streamApiCall(t,i,n,a,c,s);l=p.data,u=p.response}catch(p){if(p.status===400&&p.error?.error?.message?.includes("prompt is too long")){this.interactor.displayText("\u26A0\uFE0F Context window exceeded. Forcing aggressive compaction...");let m=p.error.error.message.match(/(\d+) tokens > (\d+) maximum/);if(m){let h=parseInt(m[1]),g=parseInt(m[2]),v=h-g,b=Math.ceil(v*this.charsPerToken*1.2);c=Math.max(c-b,5e3),this.interactor.debug(`Token overshoot: ${v} 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 h=await this.streamApiCall(t,i,n,a,c,s,!0);l=h.data,u=h.response,this.interactor.displayText("\u2705 Successfully recovered with compacted context")}catch(h){this.handleError(h,s,this.name);return}}else if(p.status===429&&p.headers){let m=parseInt(p.headers["retry-after"]??"60");this.interactor.displayText(`\u23F3 Rate limit hit. Waiting ${m} seconds before retry...`),this.updateRateLimitsFromHeaders(p.headers),this.displayRateLimitStatus(p.headers);try{await this.delay(m*1e3,"rate limit retry")}catch{this.handleError(new Error("Rate limit retry interrupted by shutdown"),s,this.name);return}this.interactor.displayText("\u{1F504} Retrying request...");try{let h=await this.streamApiCall(t,i,n,a,c,s);l=h.data,u=h.response}catch(h){this.handleError(h,s,this.name);return}}else{this.handleError(p,s,this.name);return}}if(u&&this.updateRateLimitsFromHeaders(u.headers),this.updateUsage(l?.usage,n,a),l.stop_reason==="max_tokens")throw new Error("Max tokens reached for Anthropic \u{1F62C}");let f=l.content.filter(p=>p.type==="text").map(p=>p.text.trim()).filter(p=>!!p).join(`
|
|
852
852
|
`);this.handleText(a,f,n,s);let d=l.content.filter(p=>p.type==="tool_use").map(p=>new fn({toolRequestId:p.id,name:p.name,args:JSON.stringify(p.input)}));await this.shouldProcessAgainAfterResponse(f,d,n,a)&&await this.processThread(t,n,i,a,s)}updateUsage(t,n,i){let a=this.getModel(n),s=(t?.input_tokens??0)*(a?.price?.inputMTokens??0),o=(t?.output_tokens??0)*(a?.price?.outputMTokens??0),c=(t?.cache_creation_input_tokens??0)*(a?.price?.cacheWrite??0),l=(t?.cache_read_input_tokens??0)*(a?.price?.cacheRead??0),u=(s+o+c+l)/1e6;i.addUsage({input:t?.input_tokens??0,output:t?.output_tokens??0,cache_read:t?.cache_read_input_tokens??0,cache_write:t?.cache_creation_input_tokens??0,price:u})}isAnthropicReady(){if(!this.apiKey){this.interactor.warn("ANTHROPIC_API_KEY not set, skipping AI command. Please configure your API key.");return}try{return new Do({apiKey:this.apiKey,defaultHeaders:{"anthropic-beta":"prompt-caching-2024-07-31"}})}catch(t){let n=t instanceof Error?t.message:"Unknown error";this.interactor.warn(`Failed to initialize Anthropic client: ${n}`),console.error("Anthropic client initialization error:",t);return}}toClaudeMessage(t,n,i=!1){let a=this.getOrUpdateCacheMarker(n,t,i);return t.map((s,o)=>{let c,l=a&&s.timestamp===a;if(s instanceof Gi)c={role:"user",content:[{type:"text",text:s.summary,...l&&{cache_control:{type:"ephemeral"}}}]};else if(s instanceof Xt){let u=s.role==="user"&&o===t.length-1,f=this.enhanceWithCurrentDateTime(s.content,u),d=f.map((p,m)=>{let h;return p.type==="text"&&(h={type:"text",text:p.content}),p.type==="image"&&(h={type:"image",source:{type:"base64",media_type:p.mimeType,data:p.content}}),h?{...h,...l&&m===f.length-1&&{cache_control:{type:"ephemeral"}}}:(this.interactor.warn(`Unknown content type: ${p.type}`),null)}).filter(Boolean);c={role:s.role,content:d}}if(s instanceof fn&&(c={role:"assistant",content:[{type:"tool_use",id:s.toolRequestId,name:s.name,input:JSON.parse(s.args),...l&&{cache_control:{type:"ephemeral"}}}]}),s instanceof pn){let u;if(typeof s.output=="string")u=s.output;else{let f=s.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}`)}c={role:"user",content:[{type:"tool_result",tool_use_id:s.toolRequestId,content:u,...l&&{cache_control:{type:"ephemeral"}}}]}}return c}).filter(s=>!!s)}getOrUpdateCacheMarker(t,n,i){let a=n.length;if(a<BHe)return this.interactor.debug(`\u{1F4CB} Cache: Conversation too short (${a} messages), no marker`),null;t.data.anthropic||(t.data.anthropic={});let s=t.data.anthropic.cacheMarkerMessageId;if(s&&!i){let u=n.findIndex(f=>f.timestamp===s);if(u!==-1){let f=u/a,d=Math.round(f*100),p=Math.round(hre*100),m=Math.round(OO*100);if(f>=hre&&f<=OO)return this.interactor.debug(`\u2705 Cache: Keeping marker at message ${u+1}/${a} (${d}%)`),s;this.interactor.debug(`\u{1F504} Cache: Marker at ${d}% is out of range (${p}-${m}%), repositioning...`)}else this.interactor.debug("\u26A0\uFE0F Cache: Marker message not found, creating new marker")}else this.interactor.debug("\u{1F195} Cache: No existing marker, creating first marker");let o=Math.floor(a*OO),c=n[o]?.timestamp,l=Math.round(o/a*100);return c?(t.data.anthropic.cacheMarkerMessageId=c,this.interactor.debug(`\u{1F4CD} Cache: Placed marker at message ${o+1}/${a} (${l}%) - ID: ${c}`),c):(this.interactor.debug(`\u274C Cache: Failed to place marker at position ${o}`),null)}getClaudeTools(t){let n=t.getTools().map(i=>({name:i.function.name,description:i.function.description,input_schema:i.function.parameters}));return n.length>0&&(n[n.length-1].cache_control={type:"ephemeral"}),n}async streamApiCall(t,n,i,a,s,o,c=!1){let l=await this.getMessages(a,s,n.name),u=this.toClaudeMessage(l.messages,a,c),f=t.messages.stream({model:n.name,messages:u,system:[{text:i.systemInstructions,type:"text",cache_control:{type:"ephemeral"}}],tools:this.getClaudeTools(i.tools),temperature:i.definition.temperature??n.temperature??.8,max_tokens:i.definition.maxOutputTokens??n.maxOutputTokens??8192});return f.on("text",p=>{o.next(new Rf({chunk:p}))}),{data:await f.finalMessage(),response:void 0}}getHeader=(t,n)=>t?t instanceof Headers?t.get(n):t[n]||null:null;updateRateLimitsFromHeaders(t){if(!t){this.rateLimitInfo=null;return}let n=this.getHeader(t,"anthropic-ratelimit-input-tokens-remaining"),i=this.getHeader(t,"anthropic-ratelimit-output-tokens-remaining"),a=this.getHeader(t,"anthropic-ratelimit-requests-remaining"),s=this.getHeader(t,"anthropic-ratelimit-input-tokens-limit"),o=this.getHeader(t,"anthropic-ratelimit-output-tokens-limit"),c=this.getHeader(t,"anthropic-ratelimit-requests-limit");n&&!isNaN(parseInt(n))||i&&!isNaN(parseInt(i))||a&&!isNaN(parseInt(a))?this.rateLimitInfo={inputTokensRemaining:n?parseInt(n):999999,outputTokensRemaining:i?parseInt(i):999999,requestsRemaining:a?parseInt(a):999999,inputTokensLimit:s?parseInt(s):2e5,outputTokensLimit:o?parseInt(o):8e4,requestsLimit:c?parseInt(c):4e3}:this.rateLimitInfo=null}async applyThrottlingDelay(){if(!this.rateLimitInfo)return;let t=this.rateLimitInfo.inputTokensRemaining/Math.max(this.rateLimitInfo.inputTokensLimit,1),n=this.rateLimitInfo.outputTokensRemaining/Math.max(this.rateLimitInfo.outputTokensLimit,1),i=this.rateLimitInfo.requestsRemaining/Math.max(this.rateLimitInfo.requestsLimit,1);this.interactor.debug(`Rate limit ratios: ${JSON.stringify({inputTokensRatio:t,outputTokensRatio:n,requestsRatio:i,rateLimitInfo:this.rateLimitInfo})}`);let a=Math.min(t,n,i);if(a<PO){let s=(PO-a)/PO,o=Math.max(1,Math.round(s*LHe));this.interactor.displayText(`\u23F3 Rate limit approaching (${Math.round(a*100)}% remaining), waiting ${o} seconds...`);try{await this.delay(o*1e3,"throttling")}catch{throw new Error("Throttling delay interrupted by shutdown")}}}displayRateLimitStatus(t){let n=parseInt(t["anthropic-ratelimit-input-tokens-remaining"]??"0"),i=parseInt(t["anthropic-ratelimit-output-tokens-remaining"]??"0"),a=parseInt(t["anthropic-ratelimit-requests-remaining"]??"0"),s="unknown";n===0?s="input tokens":i===0?s="output tokens":a===0&&(s="requests"),this.interactor.debug(`\u{1F6A8} Rate limit exceeded: ${s} limit reached`)}handleError(t,n,i){super.handleError(t,n,i)}async complete(t,n){let i=this.isAnthropicReady();if(!i)throw new Error("Anthropic client not ready");let a=n?.model??this.models.find(s=>s.alias==="SMALL")?.name??"claude-3-5-haiku-latest";try{return(await i.messages.create({model:a,messages:[{role:"user",content:t}],max_tokens:n?.maxTokens??100,temperature:n?.temperature??.5,stop_sequences:n?.stopSequences})).content.filter(o=>o.type==="text").map(o=>o.text.trim()).join(" ")}catch(s){throw console.error("Anthropic completion error:",s),new Error(`Anthropic completion failed: ${s.message}`)}}};var ex=class extends ad{models=[{name:"gemini-3-pro-preview",contextWindow:1048576,alias:"BIG",temperature:.8,maxOutputTokens:65536,price:{inputMTokens:2,cacheRead:.2,outputMTokens:12}},{name:"gemini-2.5-flash",alias:"SMALL",contextWindow:1048576,temperature:.8,maxOutputTokens:65536,price:{inputMTokens:.3,cacheRead:.03,outputMTokens:2.5}}];constructor(e,t,n){let i={...t,url:t.url||"https://generativelanguage.googleapis.com/v1beta/openai/"};super(e,i,n)}};var mre={anthropic:"ANTHROPIC_API_KEY",openai:"OPENAI_API_KEY",google:"GEMINI_API_KEY"},Cd=class{constructor(e,t,n,i){this.interactor=e;this.userService=t;this.projectService=n;this.logger=i}aiClients=[];aiProviderConfigs;init(e){if(this.aiProviderConfigs)return;let t=e.project.ai||[],n=this.projectService.selectedProject?.config?.ai||[],i=this.userService.config.ai||[],a=this.detectProvidersFromEnvironment(),s=new Set([...t.map(u=>u.name.toLowerCase()),...n.map(u=>u.name.toLowerCase()),...i.map(u=>u.name.toLowerCase())]);this.aiProviderConfigs=[];for(let u of[...a,...t,...n,...i]){let f=this.aiProviderConfigs.findIndex(d=>d.name===u.name);if(f===-1)this.aiProviderConfigs.push(u);else{let d=this.aiProviderConfigs[f],p=d.models?[...d.models]:[];(u.models??[]).forEach(h=>{let g=p.findIndex(v=>v.alias===h.alias||v.name===h.name);if(g===-1)p.push(h);else{let v=p[g];p[g]={...v,...h,price:{...v.price,...h.price}}}}),this.aiProviderConfigs[f]={...d,...u,models:p}}}this.aiClients=this.aiProviderConfigs.map(u=>this.createClient(u)).filter(u=>!!u);let o=a.filter(u=>!s.has(u.name.toLowerCase())).map(u=>u.name.toLowerCase()),c=new Set(o),l=`AI providers (models listed as: name (alias)):
|
|
853
853
|
`+this.aiProviderConfigs.map(u=>{let f=this.aiClients.find(v=>v.name.toLowerCase()===u.name.toLowerCase()),d=!!f,p=d?"\u2705":"\u274C",h=c.has(u.name.toLowerCase())?" (auto-detected)":"",g=` - ${p} ${u.name}${h}`;if(d&&Array.isArray(f.models)&&f.models.length>0){let v=f.models.map(b=>b.alias&&b.alias!==b.name?`${b.name} (${b.alias})`:b.name).join(", ");g+=`, models: ${v}`}return g}).join(`
|
|
854
|
-
`);this.interactor.displayText(l)}getClient(e,t){let n=this.aiClients.filter(i=>{let a=!e||i.name.toLowerCase()===e.toLowerCase(),s=!t||i.supportsModel(t.toLowerCase());return a&&s});return n.length?n[0]:void 0}cleanup(){this.aiClients.forEach(e=>e.kill()),this.aiClients=[]}kill(){this.cleanup(),this.aiProviderConfigs=void 0}getApiKey(e){let t=mre[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(mre)){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 Qy(this.interactor,n,this.logger);case"google":return new ex(this.interactor,n,this.logger);default:return new ad(this.interactor,n,this.logger)}}};var Pue=Tr(Nl(),1);import*as Zw from"fs/promises";import*as K3 from"path";var Kr=class{constructor(e){this.interactor=e}tools=[];async kill(){}async getTools(e,t,n){return this.tools=await this.buildTools(e,n),this.tools.filter(i=>!t||!t.length||t.includes(i.function.name))}};function gre(r){let{context:e}=r;return({query:n,agentName:i})=>{try{let a=`@${i} ${n}`;return e.addCommands(a),`Query successfully redirected to agent '${i}'. The agent will process the query with full context after this run completes.`}catch(a){return`Error during redirection: ${a.message}`}}}var tx=class extends Kr{constructor(t,n){super(t);this.agentService=n}name="AI";async buildTools(t,n){let i=[];if(!t.oneshot){let s={type:"function",function:{name:"queryUser",description:`Allows to ask the user a question.
|
|
854
|
+
`);this.interactor.displayText(l)}getClient(e,t){let n=this.aiClients.filter(i=>{let a=!e||i.name.toLowerCase()===e.toLowerCase(),s=!t||i.supportsModel(t.toLowerCase());return a&&s});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=mre[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(mre)){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 Qy(this.interactor,n,this.logger);case"google":return new ex(this.interactor,n,this.logger);default:return new ad(this.interactor,n,this.logger)}}};var Pue=Tr(Nl(),1);import*as Zw from"fs/promises";import*as K3 from"path";var Kr=class{constructor(e){this.interactor=e}tools=[];async kill(){}async getTools(e,t,n){return this.tools=await this.buildTools(e,n),this.tools.filter(i=>!t||!t.length||t.includes(i.function.name))}};function gre(r){let{context:e}=r;return({query:n,agentName:i})=>{try{let a=`@${i} ${n}`;return e.addCommands(a),`Query successfully redirected to agent '${i}'. The agent will process the query with full context after this run completes.`}catch(a){return`Error during redirection: ${a.message}`}}}var tx=class extends Kr{constructor(t,n){super(t);this.agentService=n}name="AI";async buildTools(t,n){let i=[];if(!t.oneshot){let s={type:"function",function:{name:"queryUser",description:`Allows to ask the user a question.
|
|
855
855
|
IMPORTANT: Use this tool only when necessary, as it is intrusive for the user.
|
|
856
856
|
|
|
857
857
|
If no options are provided, the user can answer with free text.
|
|
@@ -1007,7 +1007,7 @@ ${i}`)}return n}createResourceTool(t,n,i){let a=`mcp__${t.id}__${i.name}`,s=asyn
|
|
|
1007
1007
|
|
|
1008
1008
|
\`\`\`json
|
|
1009
1009
|
`+JSON.stringify(o)+"\n```");try{let c=await n.callTool({name:i.name,arguments:o});if(this.serverConfig.debug&&this.interactor.debug("MCP tool output:\n\n```json\n"+JSON.stringify(c)+"\n```"),c&&"content"in c&&Array.isArray(c.content)){let l=c.content.map(p=>p.type==="text"?p.text:p.type==="image"&&p.data?{type:"image",content:p.data,mimeType:p.mimeType||"image/png",...p.width&&{width:p.width},...p.height&&{height:p.height}}:p.type==="resource"?p.resource:p),u=l.filter(p=>typeof p=="object"&&p!==null&&"type"in p&&p.type==="image");if(u.length>0)for(let p of u){let m=p,h=new Xt({role:"assistant",content:[m],name:a});this.interactor.sendEvent(h)}if(l.length===1){let p=l[0];if(typeof p=="object"&&p!==null&&"type"in p){if(p.type==="image")return p;if(p.type==="text")return p.content}if(typeof p=="string")return p}let f=l.filter(p=>typeof p=="string"),d=u.length>0;return d&&f.length>0||f.length>0?f.join(`
|
|
1010
|
-
`):d?u[0]:l}else if(c&&"toolResult"in c)return c.toolResult;return c}catch(c){throw this.interactor.error(`Error calling function ${i.name}: ${c}`),new Error(`Failed to call function: ${c}`)}};return{type:"function",function:{name:a,description:i.description||`Function from MCP server ${t.name}`,parameters:{type:"object",properties:i.inputSchema?.properties||{}},parse:JSON.parse,function:s}}}};var Xw=class{constructor(e,t,n){this.interactor=e;let i=t.mcp.getMergedConfiguration().servers;this.toolFactories=[new tx(e,n),new rx(e,n),new ix(e),new Sx(e,t.integration),new Cx(e),new Ax(e,t.integration),new kx(e,t.memory),new pw(e,t.integration),new Ex(e,t.integration),...i.map(a=>new Yw(e,a))]}toolFactories;tools=[];async kill(){console.log("Closing all toolFactories"),await Promise.all(this.toolFactories.map(e=>e.kill())),console.log("Closed all toolFactories")}async getTools(e){let{context:t,integrations:n,agentName:i}=e,a=this.toolFactories.filter(s=>!n||n.has(s.name));try{let s=await Promise.all(a.map(async o=>{try{return await o.getTools(t,n?.get(o.name)??[],i??"default")}catch(c){return this.interactor.debug(`Error building tools from ${o.name} for agent ${i}: ${c}`),[]}}));return this.tools=s.flat(),this.tools}catch(s){return this.interactor.debug(`Unexpected error building tools for agent ${i}: ${s}`),[]}}};var Qw=class{constructor(e){this.tools=e;this.charLength=JSON.stringify(e).length}charLength=0;getTools(){return[...this.tools]}async run(e){let t=this.tools.find(o=>o.function.name===e.name);if(!t)throw new Error(`Tool '${e.name}' not found`);let n,i=t.function.function,a=JSON.parse(e.args),s=Array.isArray(a)?a:[a];if(n=await i(...s),n||(n=`Tool function ${e.name} finished without error.`),typeof n!="string"){if(n&&typeof n=="object"&&"type"in n&&(n.type==="text"||n.type==="image"))return e.buildResponse(n);n=JSON.stringify(n)}return e.buildResponse(n)}};var p1=class{constructor(e,t,n,i,a=[]){this.interactor=e;this.aiClientProvider=t;this.services=n;this.projectPath=i;this.commandLineAgentFolders=a;this.services.project.selectedProject$.subscribe(()=>{this.agentCache.clear(),this.agentDefinitions=[]}),this.toolbox=new Xw(this.interactor,n,this)}agentCache=new Map;agentDefinitions=[];toolbox;listAgentSummaries(){return this.agentDefinitions.map(e=>({name:e.definition.name,description:e.definition.description})).sort((e,t)=>e.name.toLowerCase().localeCompare(t.name.toLowerCase()))}async initialize(e){if(this.agentDefinitions.length>0)return;let t=performance.now();this.interactor.debug("\u{1F680} Starting agent initialization..."),this.interactor.debug("\u{1F6E0}\uFE0F Pre-initializing tools in parallel..."),this.toolbox.getTools({context:e,integrations:void 0,agentName:"pre-init"}).then(i=>this.interactor.debug("\u{1F6E0}\uFE0F ...completed pre-initializing tools in parallel")).catch(i=>this.interactor.debug(`Pre-initialization warning: ${i.message}`));try{let i=performance.now();if(e.project.agents?.length)for(let
|
|
1010
|
+
`):d?u[0]:l}else if(c&&"toolResult"in c)return c.toolResult;return c}catch(c){throw this.interactor.error(`Error calling function ${i.name}: ${c}`),new Error(`Failed to call function: ${c}`)}};return{type:"function",function:{name:a,description:i.description||`Function from MCP server ${t.name}`,parameters:{type:"object",properties:i.inputSchema?.properties||{}},parse:JSON.parse,function:s}}}};var Xw=class{constructor(e,t,n){this.interactor=e;let i=t.mcp.getMergedConfiguration().servers;this.toolFactories=[new tx(e,n),new rx(e,n),new ix(e),new Sx(e,t.integration),new Cx(e),new Ax(e,t.integration),new kx(e,t.memory),new pw(e,t.integration),new Ex(e,t.integration),...i.map(a=>new Yw(e,a))]}toolFactories;tools=[];async kill(){console.log("Closing all toolFactories"),await Promise.all(this.toolFactories.map(e=>e.kill())),console.log("Closed all toolFactories")}async getTools(e){let{context:t,integrations:n,agentName:i}=e,a=this.toolFactories.filter(s=>!n||n.has(s.name));try{let s=await Promise.all(a.map(async o=>{try{return await o.getTools(t,n?.get(o.name)??[],i??"default")}catch(c){return this.interactor.debug(`Error building tools from ${o.name} for agent ${i}: ${c}`),[]}}));return this.tools=s.flat(),this.tools}catch(s){return this.interactor.debug(`Unexpected error building tools for agent ${i}: ${s}`),[]}}};var Qw=class{constructor(e){this.tools=e;this.charLength=JSON.stringify(e).length}charLength=0;getTools(){return[...this.tools]}async run(e){let t=this.tools.find(o=>o.function.name===e.name);if(!t)throw new Error(`Tool '${e.name}' not found`);let n,i=t.function.function,a=JSON.parse(e.args),s=Array.isArray(a)?a:[a];if(n=await i(...s),n||(n=`Tool function ${e.name} finished without error.`),typeof n!="string"){if(n&&typeof n=="object"&&"type"in n&&(n.type==="text"||n.type==="image"))return e.buildResponse(n);n=JSON.stringify(n)}return e.buildResponse(n)}};var p1=class{constructor(e,t,n,i,a=[]){this.interactor=e;this.aiClientProvider=t;this.services=n;this.projectPath=i;this.commandLineAgentFolders=a;this.services.project.selectedProject$.subscribe(()=>{this.agentCache.clear(),this.agentDefinitions=[]}),this.toolbox=new Xw(this.interactor,n,this)}agentCache=new Map;agentDefinitions=[];toolbox;listAgentSummaries(){return this.agentDefinitions.map(e=>({name:e.definition.name,description:e.definition.description})).sort((e,t)=>e.name.toLowerCase().localeCompare(t.name.toLowerCase()))}async initialize(e){if(this.agentDefinitions.length>0)return;let t=performance.now();this.interactor.debug("\u{1F680} Starting agent initialization..."),this.interactor.debug("\u{1F6E0}\uFE0F Pre-initializing tools in parallel..."),this.toolbox.getTools({context:e,integrations:void 0,agentName:"pre-init"}).then(i=>this.interactor.debug("\u{1F6E0}\uFE0F ...completed pre-initializing tools in parallel")).catch(i=>this.interactor.debug(`Pre-initialization warning: ${i.message}`));try{let i=performance.now();if(e.project.agents?.length)for(let p of e.project.agents)this.addDefinition(p,this.projectPath);let a=performance.now()-i;this.interactor.debug(`\u{1F4CB} Loaded agent definitions from coday.yml: ${a.toFixed(2)}ms (${e.project.agents?.length||0} agents)`);let s=performance.now(),o=this.services.project.selectedProject;if(o?.config.agents?.length)for(let p of o.config.agents)this.addDefinition(p,this.projectPath);let c=performance.now()-s;this.interactor.debug(`\u2699\uFE0F Loaded agent definitions from project local config: ${c.toFixed(2)}ms (${o?.config.agents?.length||0} agents)`);let l=performance.now();await this.loadFromFiles(e);let u=performance.now()-l;this.interactor.debug(`\u{1F4C1} Loaded agent definitions from files: ${u.toFixed(2)}ms`);let f=performance.now();this.generateVirtualAgentsFromModels();let d=performance.now()-f;this.interactor.debug(`\u{1F916} Generated virtual agents from models: ${d.toFixed(2)}ms`),this.agentDefinitions.length===0&&(this.addDefinition(mg,this.projectPath),this.interactor.debug("\u{1F504} No agent definitions found, using Coday as backup"))}catch(i){throw this.interactor.error(`Failed to initialize agent definitions: ${i}`),i}let n=performance.now()-t;this.interactor.debug(`\u{1F3AF} Total agent definition loading time: ${n.toFixed(2)}ms`)}async findByName(e,t){await this.initialize(t);let n=e.toLowerCase();if(this.agentCache.has(n))return this.agentCache.get(n);let i=this.agentDefinitions.find(a=>a.definition.name.toLowerCase()===n);if(i){let a=await this.tryAddAgent(i,t);if(a)return this.agentCache.set(n,a),a}}async findAgentByNameStart(e,t){if(!e)return;await this.initialize(t);let n=await this.findAgentsByNameStart(e?.toLowerCase()||"",t);if(n.length===0)return;if(n.length===1)return n[0];let i=n.map(a=>a.name);try{if(t.oneshot)throw new Error("Agent ambiguous names not allowed in oneshot context");let a=await this.interactor.chooseOption(i,`Multiple agents match '${e}', please select one:`);return n.find(s=>s.name===a)}catch{this.interactor.error("Selection cancelled");return}}async findAgentsByNameStart(e,t){await this.initialize(t);let n=e.toLowerCase(),i=this.agentDefinitions.filter(s=>s.definition.name.toLowerCase().startsWith(n)),a=[];for(let s of i){let o=s.definition.name.toLowerCase(),c=this.agentCache.get(o);c||(c=await this.tryAddAgent(s,t),c&&this.agentCache.set(o,c)),c&&a.push(c)}return a}getPreferredAgent(){let e=this.services.project.selectedProject?.name;return e?this.services.user.config.projects?.[e]?.defaultAgent:void 0}async kill(){this.aiClientProvider.kill(),await this.toolbox.kill()}addDefinition(e,t=this.projectPath){this.agentDefinitions.find(n=>n.definition.name===e.name)||this.agentDefinitions.push({definition:{...mg,...e},basePath:t})}generateVirtualAgentsFromModels(){let e=this.aiClientProvider.getAllModels();for(let t of e){let n={name:t.name,description:`Direct access to ${t.name} model (${t.providerName})`,instructions:"",aiProvider:t.providerName,modelName:t.name};this.addDefinition(n,this.projectPath)}this.interactor.debug(`\u{1F916} Generated ${e.length} virtual agents from available models: ${e.map(t=>t.name).join(", ")}`)}async loadFromFiles(e){let t=[],n=[],i=this.services.project.selectedProject;i&&t.push(K3.join(i.configPath,"agents"));let a=this.services.project.selectedProject?.config.path;if(a){let u=await Cu({text:"coday.yaml",root:a});if(u.length>0){let f=K3.dirname(u[0]);t.push(K3.join(a,f,"agents"))}e.project.agentFolders?.length&&t.push(...e.project.agentFolders)}t.push(...this.commandLineAgentFolders);let s=performance.now();await Promise.all(t.map(async u=>{try{n.push(...(await Zw.readdir(u)).filter(f=>f.endsWith(".yml")||f.endsWith(".yaml")).map(f=>K3.join(u,f)))}catch(f){f.code==="EPERM"?console.error(`Permission denied to access ${u}. This is common for protected directories.
|
|
1011
1011
|
Consider moving your agent files to a less restricted location.`):console.error(`Could not read directory ${u}: ${f.code}`)}}));let o=performance.now()-s;this.interactor.debug(` \u{1F4C2} Scanned agent directories: ${o.toFixed(2)}ms (found ${n.length} files)`);let c=performance.now();await Promise.all(n.map(async u=>{try{let f=await Zw.readFile(u,"utf-8"),d=Pue.parse(f),p=K3.dirname(u),h=p.startsWith(this.projectPath)?this.projectPath:p;this.addDefinition(d,h)}catch(f){console.error(f)}}));let l=performance.now()-c;this.interactor.debug(` \u{1F4DD} Parsed agent files: ${l.toFixed(2)}ms`)}async tryAddAgent(e,t){let n={...mg,...e.definition},i=performance.now();try{if(n.openaiAssistantId&&(n.aiProvider="openai"),!this.aiClientProvider||!this.toolbox){console.error(`Cannot create agent ${n.name}: dependencies not set. Call setDependencies first.`);return}this.interactor.debug(`\u{1F3D7}\uFE0F Creating agent '${n.name}' on-demand...`);let a=performance.now(),s=this.aiClientProvider.getClient(n.aiProvider,n.modelName);if(!s){this.interactor.error(`Cannot create agent ${n.name}: AI client creation failed`);return}let o=performance.now()-a,c=e.basePath,l=performance.now(),u=await ib(n,this.interactor,c,n.name),f=performance.now()-l;n.instructions=`${n.instructions}
|
|
1012
1012
|
|
|
1013
1013
|
|
|
@@ -1135,7 +1135,7 @@ ${d.output}`}else p=JSON.stringify(d,null,2);i.status(200).send(p)}catch(a){cons
|
|
|
1135
1135
|
in
|
|
1136
1136
|
project
|
|
1137
1137
|
:
|
|
1138
|
-
${a}`);let u=e.get(s);if(!u?.coday){i.status(404).json({error:`Thread '${s}' not found or not active`});return}if(u.username!==l){i.status(403).json({error:"Access denied: thread belongs to another user"});return}let f=u.coday.context?.aiThread;if(!f){i.status(500).json({error:"Thread not properly initialized"});return}f.truncateAtUserMessage(c)?(ke("MESSAGE",`Successfully truncated thread ${s} 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 s=a instanceof Error?a.message:"Unknown error";i.status(500).json({error:`Failed to delete message: ${s}`})}})}function O0e(r,e){r.get("/api/user/me",(t,n)=>{try{let i=e(t);if(!i){n.status(401).json({error:"Authentication required"});return}ke("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 I0e(r,e,t,n,i,a,s,o){r.get("/api/projects/:projectName/agents",async(c,l)=>{try{let u=t(c),{projectName:f}=c.params;if(!f){l.status(400).json({error:"Project name is required"});return}ke("AGENT",`GET agents list: project="${f}", user="${u}"`);let d=e.getProject(f);if(!d){l.status(404).json({error:`Project '${f}' not found`});return}let p=new T2("agent-autocomplete"),m=new O2(n,u,p),h=new g1(p,e,n),g=new v1(h,m),v=new b1(m,h,p),b=new y1(h,m),w=new x1(m,h,p),C={user:m,project:h,integration:g,integrationConfig:v,memory:b,mcp:w,thread:s,logger:i,webhook:a};h.selectProject(f);let A=new Cd(p,m,h,i),E=new p1(p,A,C,d.config.path,o.agentFolders),O={...await sb(d.config.path,p,{username:u,bio:m.config.bio}),root:d.config.path,name:f},x=new Nf(O,u);x.oneshot=!0,ke("AGENT",`Initializing AgentService with projectPath: ${d.config.path}`),ke("AGENT",`Project config agents: ${d.config.agents?.length||0}`),ke("AGENT",`AgentFolders from options: ${JSON.stringify(o.agentFolders)}`),await E.initialize(x);let _=E.listAgentSummaries();ke("AGENT",`Total agents loaded: ${_.length}`),ke("AGENT",`Agent names: ${_.map(y=>y.name).join(", ")}`),await E.kill(),l.status(200).json(_)}catch(u){console.error("Error in agent autocomplete:",u);let f=u instanceof Error?u.message:"Unknown error";l.status(500).json({error:`Failed to get agent autocomplete: ${f}`})}})}import*as R0e from"crypto";import*as Uj from"path";var A1=class r{constructor(e,t,n){this.repository=e;this.defaultProject=t;this.isForcedMode=n}maskingService=new P2;listProjects(){let e=this.repository.listProjects();return this.isForcedMode&&this.defaultProject?e.filter(t=>t===this.defaultProject).map(t=>{let n=this.repository.getConfig(t);return{name:t,volatile:n?.volatile}}):e.map(t=>{let n=this.repository.getConfig(t);return{name:t,volatile:n?.volatile}})}getDefaultProject(){return this.defaultProject||null}getForcedMode(){return this.isForcedMode}getProject(e){this.checkAgainstForced(e);let t=this.repository.getConfig(e);if(t)return{name:e,config:t};if(!this.isForcedMode&&this.defaultProject){let n=process.cwd(),i=r.generateProjectId(n),a=Uj.basename(n);if(e===a||e===i||e===this.defaultProject){let s=this.getOrCreateVolatileProject(n);if(t=this.repository.getConfig(s),t)return{name:s,config:t}}}return null}exists(e){return this.checkAgainstForced(e),this.repository.exists(e)}createProject(e,t){if(this.checkAgainstForced(e),!e||!t)throw new Error("Project name and path are required");if(!this.repository.createProject(e,t))throw new Error(`Project '${e}' already exists`)}updateProjectConfig(e,t){if(this.checkAgainstForced(e),!this.repository.exists(e))throw new Error(`Project '${e}' does not exist`);this.repository.saveConfig(e,t)}deleteProject(e){if(this.checkAgainstForced(e),!this.repository.deleteProject(e))throw new Error(`Project '${e}' does not exist`)}getProjectConfigForClient(e){this.checkAgainstForced(e);let t=this.repository.getConfig(e);return t?this.maskingService.maskConfig(t):null}updateProjectConfigFromClient(e,t){this.checkAgainstForced(e);let n=this.repository.getConfig(e);if(!n)throw new Error(`Project '${e}' does not exist`);let i=this.maskingService.unmaskConfig(t,n);this.repository.saveConfig(e,i)}checkAgainstForced(e){if(this.isForcedMode&&this.defaultProject&&this.defaultProject!==e)throw Error(`Project selection outside of ${this.defaultProject} not allowed`)}getOrCreateVolatileProject(e){let t=r.generateProjectId(e);if(this.repository.exists(t))return t;this.repository.createProject(t,e);let n=this.repository.getConfig(t);return n&&(n.volatile=!0,n.createdAt=Date.now(),this.repository.saveConfig(t,n)),t}static generateProjectId(e){let t=Uj.basename(e),n=R0e.createHash("sha256").update(e).digest("hex").substring(0,8);return`${t}_${n}`}};var zj=Tr(Nl(),1);import{promises as jc}from"fs";import f0 from"path";var art={version:1,description:"Migrate AiThread MessageEvent.content from string to MessageContent",migrate:r=>{let e={...r};return!e.messages||!Array.isArray(e.messages)?(e.messages=[],e):(e.messages=e.messages.map(t=>{if(t.type!=="message")return t;let n=t.content;return t.content={...t,content:[{type:"text",content:n}]},t}),e)}},srt={version:2,description:"Add starring field to threads for favorite functionality",migrate:r=>{let e={...r};return e.starring||(e.starring=[]),e}},Hj=[art,srt];var F0e=async r=>{try{let e=await jc.readFile(r,"utf-8");return zj.default.parse(e)}catch{return null}},P_=class{constructor(e){this.projectsDir=e}getThreadsDir(e){return f0.join(this.projectsDir,e,"threads")}async ensureThreadsDir(e){let t=this.getThreadsDir(e);try{await jc.mkdir(t,{recursive:!0})}catch(n){throw new ac(`Failed to initialize threads directory for project ${e}`,n)}}getThreadFileName(e){return`${e.id}.yml`}async findThreadFile(e,t){try{let n=this.getThreadsDir(e),i=`${t}.yml`;try{return await jc.access(f0.join(n,i)),i}catch{}return(await jc.readdir(n)).find(o=>o.endsWith(`-${t}.yml`))||null}catch(n){throw new ac(`Error finding thread ${t} in project ${e}`,n)}}async getById(e,t){try{let n=await this.findThreadFile(e,t);if(!n)return null;let i=this.getThreadsDir(e),a=f0.join(i,n),s=await F0e(a);if(!s)return null;let o=d1(s,Hj);return o.projectId||(o.projectId=e),o!==s&&Ln(a,o),new Al(o)}catch(n){throw new ac(`Failed to read thread ${t} from project ${e}`,n)}}async save(e,t){await this.ensureThreadsDir(e);try{if(t.id||(t.id=crypto.randomUUID()),t.projectId||(t.projectId=e),t.projectId!==e)throw new Error(`Thread projectId mismatch: expected ${e}, got ${t.projectId}`);let n=this.getThreadsDir(e),i=this.getThreadFileName(t),a=f0.join(n,i),s=await this.findThreadFile(e,t.id);if(s&&s!==i){let l=f0.join(n,s);try{await jc.unlink(l),console.log(`[THREAD-REPO] Migrated/renamed thread file: ${s} \u2192 ${i}`)}catch(u){console.warn(`[THREAD-REPO] Could not delete old thread file: ${s}`,u)}}let o={...t,version:Hj.length+1},c=zj.default.stringify(o);return await jc.writeFile(a,c,"utf-8"),t}catch(n){throw new ac(`Failed to save thread ${t.id} to project ${e}`,n)}}async listByProject(e,t){try{let n=this.getThreadsDir(e);try{await jc.access(n)}catch{return[]}let i=await jc.readdir(n);return(await Promise.all(i.filter(s=>s.endsWith(".yml")).map(async s=>{let o=await F0e(f0.join(n,s));if(!o)return null;let c=o.projectId||e;return{id:o.id,username:o.username,projectId:c,name:o.name??"...",summary:o.summary??"",createdDate:o.createdDate??"",modifiedDate:o.modifiedDate??"",price:o.price??0,starring:o.starring??[]}}))).filter(s=>!!s).filter(s=>s.username===t).sort((s,o)=>s.modifiedDate>o.modifiedDate?-1:1)}catch(n){throw new ac(`Failed to list threads for project ${e}`,n)}}async delete(e,t){try{let n=await this.findThreadFile(e,t);if(!n)return!1;let i=this.getThreadsDir(e);return await jc.unlink(f0.join(i,n)),!0}catch(n){throw new ac(`Failed to delete thread ${t} from project ${e}`,n)}}};var O_=class{constructor(e,t,n){this.projectRepository=e;this.projectsDir=t;this.threadFileService=n}repositoryCache=new Map;getThreadRepository(e){let t=this.repositoryCache.get(e);if(t)return t;if(!this.projectRepository.getProjectInfo(e))throw new Error(`Project '${e}' not found`);let i=new P_(this.projectsDir);return this.repositoryCache.set(e,i),i}clearCache(e){e?this.repositoryCache.delete(e):this.repositoryCache.clear()}async listThreads(e,t){return await this.getThreadRepository(e).listByProject(e,t)}async getThread(e,t){return await this.getThreadRepository(e).getById(e,t)}async createThread(e,t,n){let i=this.getThreadRepository(e),a=new Al({id:crypto.randomUUID(),username:t,projectId:e,name:n||"",price:0});return await i.save(e,a)}async updateThread(e,t,n){let i=this.getThreadRepository(e),a=await i.getById(e,t);if(!a)throw new Error(`Thread '${t}' not found in project '${e}'`);return n.name!==void 0&&(a.name=n.name),await i.save(e,a)}async starThread(e,t,n){let i=this.getThreadRepository(e),a=await i.getById(e,t);if(!a)throw new Error(`Thread '${t}' not found in project '${e}'`);return a.starring.includes(n)||a.starring.push(n),await i.save(e,a)}async unstarThread(e,t,n){let i=this.getThreadRepository(e),a=await i.getById(e,t);if(!a)throw new Error(`Thread '${t}' not found in project '${e}'`);return a.starring=a.starring.filter(s=>s!==n),await i.save(e,a)}async deleteThread(e,t){let i=await this.getThreadRepository(e).delete(e,t);return i&&await this.threadFileService.deleteThreadFiles(e,t),i}async exists(e,t){return await this.getThread(e,t)!==null}};import*as oi from"path";import*as p0 from"fs";import*as Ri from"fs/promises";var I_=class{constructor(e){this.projectsDir=e}getThreadFilesDir(e,t){return oi.join(this.projectsDir,e,"threads",`${t}-files`)}async ensureThreadFilesDir(e,t){let n=this.getThreadFilesDir(e,t);p0.existsSync(n)||await Ri.mkdir(n,{recursive:!0})}async listFiles(e,t){await this.ensureThreadFilesDir(e,t);let n=this.getThreadFilesDir(e,t),i=await Ri.readdir(n);return await Promise.all(i.map(async s=>{let o=oi.join(n,s),c=await Ri.stat(o);return{filename:s,size:c.size,lastModified:c.mtime.toISOString()}}))}async saveFile(e,t,n,i){let a=this.getThreadFilesDir(e,t);await Ri.mkdir(a,{recursive:!0});let s=oi.join(a,n);await Ri.writeFile(s,i)}async getFile(e,t,n){await this.ensureThreadFilesDir(e,t);let i=this.getThreadFilesDir(e,t),a=oi.join(i,n),s=oi.resolve(a),o=oi.resolve(i);if(!s.startsWith(o))throw new Error("Access denied: invalid file path");if(!p0.existsSync(a))throw new Error(`File '${n}' not found`);return await Ri.readFile(a)}async getFilePath(e,t,n){await this.ensureThreadFilesDir(e,t);let i=this.getThreadFilesDir(e,t),a=oi.join(i,n),s=oi.resolve(a),o=oi.resolve(i);if(!s.startsWith(o))throw new Error("Access denied: invalid file path");if(!p0.existsSync(a))throw new Error(`File '${n}' not found`);return a}fileExists(e,t,n){let i=this.getThreadFilesDir(e,t),a=oi.join(i,n),s=oi.resolve(a),o=oi.resolve(i);return s.startsWith(o)?p0.existsSync(a):!1}async deleteFile(e,t,n){await this.ensureThreadFilesDir(e,t);let i=this.getThreadFilesDir(e,t),a=oi.join(i,n),s=oi.resolve(a),o=oi.resolve(i);if(!s.startsWith(o))throw new Error("Access denied: invalid file path");if(!p0.existsSync(a))throw new Error(`File '${n}' not found`);await Ri.unlink(a)}async deleteThreadFiles(e,t){try{let n=this.getThreadFilesDir(e,t);p0.existsSync(n)&&(await Ri.rm(n,{recursive:!0,force:!0}),console.log(`Deleted thread files directory: ${n}`))}catch(n){console.error(`Error deleting thread files for ${t}:`,n)}}};import*as $o from"node:path";import*as q0e from"node:os";import{existsSync as M0e,lstatSync as ort,mkdirSync as N0e,readdirSync as crt}from"fs";var j0e=[r_];var R_=class r{projectsConfigPath;static PROJECT_FILENAME="project.yaml";constructor(e){let t=$o.join(q0e.userInfo().homedir,".coday");this.projectsConfigPath=$o.join(e??t,"projects"),N0e(this.projectsConfigPath,{recursive:!0})}listProjects(){return crt(this.projectsConfigPath).filter(t=>ort($o.join(this.projectsConfigPath,t)).isDirectory())}getProjectInfo(e){let t=$o.join(this.projectsConfigPath,e),n=$o.join(t,r.PROJECT_FILENAME);return M0e(n)?{name:e,configPath:t}:null}exists(e){return this.getProjectInfo(e)!==null}getConfig(e){let t=this.getProjectInfo(e);if(!t)return null;let n=$o.join(t.configPath,r.PROJECT_FILENAME),i=D2(n);if(!i)return null;let a=d1(i,j0e);return a!==i&&Ln(n,a),a}saveConfig(e,t){let n=this.getProjectInfo(e);if(!n)throw new Error(`Project '${e}' does not exist`);let i=$o.join(n.configPath,r.PROJECT_FILENAME);Ln(i,t)}createProject(e,t){let n=$o.join(this.projectsConfigPath,e),i=$o.join(n,r.PROJECT_FILENAME);return M0e(i)?!1:(N0e(n,{recursive:!0}),Ln(i,{version:1,path:t,integration:{},storage:{type:"file"},agents:[]}),!0)}deleteProject(e){return this.getProjectInfo(e),!1}};var ja=(0,cE.default)(),aat=process.env.PORT?parseInt(process.env.PORT):process.env.BUILD_ENV==="development"?4100:3e3,sat=x0e(aat),oat="x-forwarded-email",$n=p0e();ke("INIT","Coday options:",$n);var ide=!$n.noLog,lE=new C_(ide,$n.logFolder);ke("INIT",`Usage logging ${ide?"enabled":"disabled"} ${$n.logFolder?`(custom folder: ${$n.logFolder})`:""}`);var RM=new A_($n.configDir);ke("INIT","Webhook service initialized");ja.use(cE.default.json({limit:"20mb"}));if(process.env.BUILD_ENV==="development"){let r="http://localhost:4200";ke("INIT",`Development mode: proxying to Angular dev server at ${r}`),Promise.resolve().then(()=>Tr(rde(),1)).then(({createProxyMiddleware:e})=>{let t=e({target:r,changeOrigin:!0,ws:!0});ja.use("/",(n,i,a)=>{n.path.startsWith("/api")||n.path.startsWith("/events")?a():t(n,i,a)}),ke("INIT","Proxy middleware configured successfully")}).catch(e=>{console.error("Failed to load http-proxy-middleware:",e)})}else{let r=process.env.CODAY_CLIENT_PATH?Lc.resolve(process.env.CODAY_CLIENT_PATH):Lc.resolve(__dirname,"../coday-client/browser");if(ke("INIT",`Production mode: serving static files from ${r}`),process.env.CODAY_CLIENT_PATH&&ke("INIT","Using client path from CODAY_CLIENT_PATH environment variable"),!iE.existsSync(r))console.error(`ERROR: Client path does not exist: ${r}`),console.error("Please build the client first with: pnpm nx run client:build");else{let e=Lc.join(r,"index.html");iE.existsSync(e)?ke("INIT",`Verified index.html exists at ${e}`):(console.error(`ERROR: index.html not found at: ${e}`),console.error("Client build may be incomplete. Try rebuilding with: pnpm nx run client:build"))}ja.use(cE.default.static(r))}var aE=new R_($n.configDir),Om=$n.project;if(Om&&!$n.forcedProject){let r=process.cwd(),e=Lc.basename(r);if(aE.exists(e)){let t=aE.getConfig(e);if(t&&t.path===r&&!t.volatile)ke("INIT",`Default mode: found existing non-volatile project '${e}' for current directory`),Om=e;else{let n=A1.generateProjectId(r);ke("INIT",`Default mode: existing project '${e}' doesn't match path, using volatile ID ${n}`),Om=n}}else{let t=A1.generateProjectId(r);ke("INIT",`Default mode: no existing project found, using volatile ID ${t}`),Om=t}}var FM=new A1(aE,Om,$n.forcedProject),ade=Lc.join($n.configDir,"projects"),sde=new I_(ade),uE=new O_(aE,ade,sde),fE=new a_(lE,RM,FM,uE),cat=new T2("config-api"),lat=new D_($n.configDir,cat),uat=["root","admin","administrator","system","daemon","nobody","node","app","service","docker","www-data","nginx","apache","ansible"];function I1(r){let e=$n.auth?r.headers[oat]:nde.userInfo().username;if(uat.includes(e.toLowerCase()))throw new Error(`Security error: Cannot run with username "${e}". This appears to be a system or service account. When running locally, ensure you are running as a regular user account. When running in production, ensure authentication is properly configured with --auth flag.`);return e}O0e(ja,I1);w0e(ja,lat,I1);E0e(ja,RM,I1,uE,fE,$n,lE);S0e(ja,FM);D0e(ja,uE,sde,fE,I1,$n);P0e(ja,fE,I1);I0e(ja,FM,I1,$n.configDir,lE,RM,uE,$n);if(process.env.BUILD_ENV!=="development"){let r=process.env.CODAY_CLIENT_PATH?Lc.resolve(process.env.CODAY_CLIENT_PATH):Lc.resolve(__dirname,"../coday-client/browser"),e=Lc.resolve(r,"index.html");ke("INIT",`Catch-all route will serve: ${e}`),ja.use((t,n,i)=>{if(t.path.startsWith("/api")||t.path.startsWith("/events")){n.status(404).send("Not found");return}ke("ROUTER",`Serving index.html for client route: ${t.path}`),iE.readFile(e,"utf8",(a,s)=>{a?(ke("ERROR",`Failed to read index.html from ${e}:`,a),ke("ERROR",`File exists check: ${iE.existsSync(e)}`),i(a)):n.type("html").send(s)})})}var sE=null;ja.use((r,e,t,n)=>{ke("ERROR",`Request error on ${e.method} ${e.path}:`,r.message),console.error(r.stack),process.env.BUILD_ENV==="development"?t.status(500).json({error:"Internal Server Error",message:r.message,stack:r.stack}):t.status(500).send("Something went wrong!")});sat.then(async r=>{ja.listen(r,()=>{console.log(`Server is running on http://localhost:${r}`)});try{ke("CLEANUP","Starting thread cleanup service...");let e=Lc.join($n.configDir,"projects");sE=new T_(e,lE),await sE.start(),ke("CLEANUP","Thread cleanup service started successfully")}catch(e){console.error("Failed to start thread cleanup service:",e)}}).catch(r=>{console.error("Failed to start server:",r),process.exit(1)});var oE=!1;async function R1(r){oE&&(console.log(`Received ${r} during shutdown, forcing exit...`),process.exit(1)),oE=!0,console.log(`Received ${r}, shutting down gracefully...`);try{sE&&(console.log("Stopping thread cleanup service..."),await sE.stop()),console.log("Cleaning up thread Coday instances..."),await fE.shutdown(),console.log("Graceful shutdown completed"),process.exit(0)}catch(e){console.error("Error during graceful shutdown:",e),process.exit(1)}}process.on("SIGTERM",()=>R1("SIGTERM"));process.on("SIGINT",()=>R1("SIGINT"));process.on("SIGUSR2",()=>R1("SIGUSR2"));process.on("SIGHUP",()=>R1("SIGHUP"));process.on("uncaughtException",r=>{if(console.error("Uncaught exception:",r),r.message==="no elements in sequence"||r.constructor.name==="EmptyErrorImpl"){console.log("Detected RxJS EmptyError during system sleep - this is expected behavior"),console.log("Process will continue normally after system wake");return}oE||R1("uncaughtException")});process.on("unhandledRejection",(r,e)=>{if(console.error("Unhandled rejection at:",e,"reason:",r),r&&typeof r=="object"){let t=r;if(t.message==="no elements in sequence"||t.constructor?.name==="EmptyErrorImpl"){console.log("Detected RxJS EmptyError rejection during system sleep - this is expected behavior");return}if(t.name==="TimeoutError"||t.message?.includes("timeout")){console.log("Detected timeout error - handling gracefully without shutdown");return}if(t.name==="AbortError"||t.message?.includes("aborted")){console.log("Detected abort error - handling gracefully without shutdown");return}}console.error("Critical unhandled rejection detected"),oE||R1("unhandledRejection")});
|
|
1138
|
+
${a}`);let u=e.get(s);if(!u?.coday){i.status(404).json({error:`Thread '${s}' not found or not active`});return}if(u.username!==l){i.status(403).json({error:"Access denied: thread belongs to another user"});return}let f=u.coday.context?.aiThread;if(!f){i.status(500).json({error:"Thread not properly initialized"});return}f.truncateAtUserMessage(c)?(ke("MESSAGE",`Successfully truncated thread ${s} 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 s=a instanceof Error?a.message:"Unknown error";i.status(500).json({error:`Failed to delete message: ${s}`})}})}function O0e(r,e){r.get("/api/user/me",(t,n)=>{try{let i=e(t);if(!i){n.status(401).json({error:"Authentication required"});return}ke("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 I0e(r,e,t,n,i,a,s,o){r.get("/api/projects/:projectName/agents",async(c,l)=>{try{let u=t(c),{projectName:f}=c.params;if(!f){l.status(400).json({error:"Project name is required"});return}ke("AGENT",`GET agents list: project="${f}", user="${u}"`);let d=e.getProject(f);if(!d){l.status(404).json({error:`Project '${f}' not found`});return}let p=new T2("agent-autocomplete"),m=new O2(n,u,p),h=new g1(p,e,n),g=new v1(h,m),v=new b1(m,h,p),b=new y1(h,m),w=new x1(m,h,p),C={user:m,project:h,integration:g,integrationConfig:v,memory:b,mcp:w,thread:s,logger:i,webhook:a};h.selectProject(f);let A=new Cd(p,m,h,i),E=new p1(p,A,C,d.config.path,o.agentFolders),O={...await sb(d.config.path,p,{username:u,bio:m.config.bio}),root:d.config.path,name:f},x=new Nf(O,u);x.oneshot=!0,ke("AGENT",`Initializing AgentService with projectPath: ${d.config.path}`),ke("AGENT",`Project config agents: ${d.config.agents?.length||0}`),ke("AGENT",`AgentFolders from options: ${JSON.stringify(o.agentFolders)}`),A.init(x),await E.initialize(x);let _=E.listAgentSummaries();ke("AGENT",`Total agents loaded: ${_.length}`),ke("AGENT",`Agent names: ${_.map(y=>y.name).join(", ")}`),await E.kill(),l.status(200).json(_)}catch(u){console.error("Error in agent autocomplete:",u);let f=u instanceof Error?u.message:"Unknown error";l.status(500).json({error:`Failed to get agent autocomplete: ${f}`})}})}import*as R0e from"crypto";import*as Uj from"path";var A1=class r{constructor(e,t,n){this.repository=e;this.defaultProject=t;this.isForcedMode=n}maskingService=new P2;listProjects(){let e=this.repository.listProjects();return this.isForcedMode&&this.defaultProject?e.filter(t=>t===this.defaultProject).map(t=>{let n=this.repository.getConfig(t);return{name:t,volatile:n?.volatile}}):e.map(t=>{let n=this.repository.getConfig(t);return{name:t,volatile:n?.volatile}})}getDefaultProject(){return this.defaultProject||null}getForcedMode(){return this.isForcedMode}getProject(e){this.checkAgainstForced(e);let t=this.repository.getConfig(e);if(t)return{name:e,config:t};if(!this.isForcedMode&&this.defaultProject){let n=process.cwd(),i=r.generateProjectId(n),a=Uj.basename(n);if(e===a||e===i||e===this.defaultProject){let s=this.getOrCreateVolatileProject(n);if(t=this.repository.getConfig(s),t)return{name:s,config:t}}}return null}exists(e){return this.checkAgainstForced(e),this.repository.exists(e)}createProject(e,t){if(this.checkAgainstForced(e),!e||!t)throw new Error("Project name and path are required");if(!this.repository.createProject(e,t))throw new Error(`Project '${e}' already exists`)}updateProjectConfig(e,t){if(this.checkAgainstForced(e),!this.repository.exists(e))throw new Error(`Project '${e}' does not exist`);this.repository.saveConfig(e,t)}deleteProject(e){if(this.checkAgainstForced(e),!this.repository.deleteProject(e))throw new Error(`Project '${e}' does not exist`)}getProjectConfigForClient(e){this.checkAgainstForced(e);let t=this.repository.getConfig(e);return t?this.maskingService.maskConfig(t):null}updateProjectConfigFromClient(e,t){this.checkAgainstForced(e);let n=this.repository.getConfig(e);if(!n)throw new Error(`Project '${e}' does not exist`);let i=this.maskingService.unmaskConfig(t,n);this.repository.saveConfig(e,i)}checkAgainstForced(e){if(this.isForcedMode&&this.defaultProject&&this.defaultProject!==e)throw Error(`Project selection outside of ${this.defaultProject} not allowed`)}getOrCreateVolatileProject(e){let t=r.generateProjectId(e);if(this.repository.exists(t))return t;this.repository.createProject(t,e);let n=this.repository.getConfig(t);return n&&(n.volatile=!0,n.createdAt=Date.now(),this.repository.saveConfig(t,n)),t}static generateProjectId(e){let t=Uj.basename(e),n=R0e.createHash("sha256").update(e).digest("hex").substring(0,8);return`${t}_${n}`}};var zj=Tr(Nl(),1);import{promises as jc}from"fs";import f0 from"path";var art={version:1,description:"Migrate AiThread MessageEvent.content from string to MessageContent",migrate:r=>{let e={...r};return!e.messages||!Array.isArray(e.messages)?(e.messages=[],e):(e.messages=e.messages.map(t=>{if(t.type!=="message")return t;let n=t.content;return t.content={...t,content:[{type:"text",content:n}]},t}),e)}},srt={version:2,description:"Add starring field to threads for favorite functionality",migrate:r=>{let e={...r};return e.starring||(e.starring=[]),e}},Hj=[art,srt];var F0e=async r=>{try{let e=await jc.readFile(r,"utf-8");return zj.default.parse(e)}catch{return null}},P_=class{constructor(e){this.projectsDir=e}getThreadsDir(e){return f0.join(this.projectsDir,e,"threads")}async ensureThreadsDir(e){let t=this.getThreadsDir(e);try{await jc.mkdir(t,{recursive:!0})}catch(n){throw new ac(`Failed to initialize threads directory for project ${e}`,n)}}getThreadFileName(e){return`${e.id}.yml`}async findThreadFile(e,t){try{let n=this.getThreadsDir(e),i=`${t}.yml`;try{return await jc.access(f0.join(n,i)),i}catch{}return(await jc.readdir(n)).find(o=>o.endsWith(`-${t}.yml`))||null}catch(n){throw new ac(`Error finding thread ${t} in project ${e}`,n)}}async getById(e,t){try{let n=await this.findThreadFile(e,t);if(!n)return null;let i=this.getThreadsDir(e),a=f0.join(i,n),s=await F0e(a);if(!s)return null;let o=d1(s,Hj);return o.projectId||(o.projectId=e),o!==s&&Ln(a,o),new Al(o)}catch(n){throw new ac(`Failed to read thread ${t} from project ${e}`,n)}}async save(e,t){await this.ensureThreadsDir(e);try{if(t.id||(t.id=crypto.randomUUID()),t.projectId||(t.projectId=e),t.projectId!==e)throw new Error(`Thread projectId mismatch: expected ${e}, got ${t.projectId}`);let n=this.getThreadsDir(e),i=this.getThreadFileName(t),a=f0.join(n,i),s=await this.findThreadFile(e,t.id);if(s&&s!==i){let l=f0.join(n,s);try{await jc.unlink(l),console.log(`[THREAD-REPO] Migrated/renamed thread file: ${s} \u2192 ${i}`)}catch(u){console.warn(`[THREAD-REPO] Could not delete old thread file: ${s}`,u)}}let o={...t,version:Hj.length+1},c=zj.default.stringify(o);return await jc.writeFile(a,c,"utf-8"),t}catch(n){throw new ac(`Failed to save thread ${t.id} to project ${e}`,n)}}async listByProject(e,t){try{let n=this.getThreadsDir(e);try{await jc.access(n)}catch{return[]}let i=await jc.readdir(n);return(await Promise.all(i.filter(s=>s.endsWith(".yml")).map(async s=>{let o=await F0e(f0.join(n,s));if(!o)return null;let c=o.projectId||e;return{id:o.id,username:o.username,projectId:c,name:o.name??"...",summary:o.summary??"",createdDate:o.createdDate??"",modifiedDate:o.modifiedDate??"",price:o.price??0,starring:o.starring??[]}}))).filter(s=>!!s).filter(s=>s.username===t).sort((s,o)=>s.modifiedDate>o.modifiedDate?-1:1)}catch(n){throw new ac(`Failed to list threads for project ${e}`,n)}}async delete(e,t){try{let n=await this.findThreadFile(e,t);if(!n)return!1;let i=this.getThreadsDir(e);return await jc.unlink(f0.join(i,n)),!0}catch(n){throw new ac(`Failed to delete thread ${t} from project ${e}`,n)}}};var O_=class{constructor(e,t,n){this.projectRepository=e;this.projectsDir=t;this.threadFileService=n}repositoryCache=new Map;getThreadRepository(e){let t=this.repositoryCache.get(e);if(t)return t;if(!this.projectRepository.getProjectInfo(e))throw new Error(`Project '${e}' not found`);let i=new P_(this.projectsDir);return this.repositoryCache.set(e,i),i}clearCache(e){e?this.repositoryCache.delete(e):this.repositoryCache.clear()}async listThreads(e,t){return await this.getThreadRepository(e).listByProject(e,t)}async getThread(e,t){return await this.getThreadRepository(e).getById(e,t)}async createThread(e,t,n){let i=this.getThreadRepository(e),a=new Al({id:crypto.randomUUID(),username:t,projectId:e,name:n||"",price:0});return await i.save(e,a)}async updateThread(e,t,n){let i=this.getThreadRepository(e),a=await i.getById(e,t);if(!a)throw new Error(`Thread '${t}' not found in project '${e}'`);return n.name!==void 0&&(a.name=n.name),await i.save(e,a)}async starThread(e,t,n){let i=this.getThreadRepository(e),a=await i.getById(e,t);if(!a)throw new Error(`Thread '${t}' not found in project '${e}'`);return a.starring.includes(n)||a.starring.push(n),await i.save(e,a)}async unstarThread(e,t,n){let i=this.getThreadRepository(e),a=await i.getById(e,t);if(!a)throw new Error(`Thread '${t}' not found in project '${e}'`);return a.starring=a.starring.filter(s=>s!==n),await i.save(e,a)}async deleteThread(e,t){let i=await this.getThreadRepository(e).delete(e,t);return i&&await this.threadFileService.deleteThreadFiles(e,t),i}async exists(e,t){return await this.getThread(e,t)!==null}};import*as oi from"path";import*as p0 from"fs";import*as Ri from"fs/promises";var I_=class{constructor(e){this.projectsDir=e}getThreadFilesDir(e,t){return oi.join(this.projectsDir,e,"threads",`${t}-files`)}async ensureThreadFilesDir(e,t){let n=this.getThreadFilesDir(e,t);p0.existsSync(n)||await Ri.mkdir(n,{recursive:!0})}async listFiles(e,t){await this.ensureThreadFilesDir(e,t);let n=this.getThreadFilesDir(e,t),i=await Ri.readdir(n);return await Promise.all(i.map(async s=>{let o=oi.join(n,s),c=await Ri.stat(o);return{filename:s,size:c.size,lastModified:c.mtime.toISOString()}}))}async saveFile(e,t,n,i){let a=this.getThreadFilesDir(e,t);await Ri.mkdir(a,{recursive:!0});let s=oi.join(a,n);await Ri.writeFile(s,i)}async getFile(e,t,n){await this.ensureThreadFilesDir(e,t);let i=this.getThreadFilesDir(e,t),a=oi.join(i,n),s=oi.resolve(a),o=oi.resolve(i);if(!s.startsWith(o))throw new Error("Access denied: invalid file path");if(!p0.existsSync(a))throw new Error(`File '${n}' not found`);return await Ri.readFile(a)}async getFilePath(e,t,n){await this.ensureThreadFilesDir(e,t);let i=this.getThreadFilesDir(e,t),a=oi.join(i,n),s=oi.resolve(a),o=oi.resolve(i);if(!s.startsWith(o))throw new Error("Access denied: invalid file path");if(!p0.existsSync(a))throw new Error(`File '${n}' not found`);return a}fileExists(e,t,n){let i=this.getThreadFilesDir(e,t),a=oi.join(i,n),s=oi.resolve(a),o=oi.resolve(i);return s.startsWith(o)?p0.existsSync(a):!1}async deleteFile(e,t,n){await this.ensureThreadFilesDir(e,t);let i=this.getThreadFilesDir(e,t),a=oi.join(i,n),s=oi.resolve(a),o=oi.resolve(i);if(!s.startsWith(o))throw new Error("Access denied: invalid file path");if(!p0.existsSync(a))throw new Error(`File '${n}' not found`);await Ri.unlink(a)}async deleteThreadFiles(e,t){try{let n=this.getThreadFilesDir(e,t);p0.existsSync(n)&&(await Ri.rm(n,{recursive:!0,force:!0}),console.log(`Deleted thread files directory: ${n}`))}catch(n){console.error(`Error deleting thread files for ${t}:`,n)}}};import*as $o from"node:path";import*as q0e from"node:os";import{existsSync as M0e,lstatSync as ort,mkdirSync as N0e,readdirSync as crt}from"fs";var j0e=[r_];var R_=class r{projectsConfigPath;static PROJECT_FILENAME="project.yaml";constructor(e){let t=$o.join(q0e.userInfo().homedir,".coday");this.projectsConfigPath=$o.join(e??t,"projects"),N0e(this.projectsConfigPath,{recursive:!0})}listProjects(){return crt(this.projectsConfigPath).filter(t=>ort($o.join(this.projectsConfigPath,t)).isDirectory())}getProjectInfo(e){let t=$o.join(this.projectsConfigPath,e),n=$o.join(t,r.PROJECT_FILENAME);return M0e(n)?{name:e,configPath:t}:null}exists(e){return this.getProjectInfo(e)!==null}getConfig(e){let t=this.getProjectInfo(e);if(!t)return null;let n=$o.join(t.configPath,r.PROJECT_FILENAME),i=D2(n);if(!i)return null;let a=d1(i,j0e);return a!==i&&Ln(n,a),a}saveConfig(e,t){let n=this.getProjectInfo(e);if(!n)throw new Error(`Project '${e}' does not exist`);let i=$o.join(n.configPath,r.PROJECT_FILENAME);Ln(i,t)}createProject(e,t){let n=$o.join(this.projectsConfigPath,e),i=$o.join(n,r.PROJECT_FILENAME);return M0e(i)?!1:(N0e(n,{recursive:!0}),Ln(i,{version:1,path:t,integration:{},storage:{type:"file"},agents:[]}),!0)}deleteProject(e){return this.getProjectInfo(e),!1}};var ja=(0,cE.default)(),aat=process.env.PORT?parseInt(process.env.PORT):process.env.BUILD_ENV==="development"?4100:3e3,sat=x0e(aat),oat="x-forwarded-email",$n=p0e();ke("INIT","Coday options:",$n);var ide=!$n.noLog,lE=new C_(ide,$n.logFolder);ke("INIT",`Usage logging ${ide?"enabled":"disabled"} ${$n.logFolder?`(custom folder: ${$n.logFolder})`:""}`);var RM=new A_($n.configDir);ke("INIT","Webhook service initialized");ja.use(cE.default.json({limit:"20mb"}));if(process.env.BUILD_ENV==="development"){let r="http://localhost:4200";ke("INIT",`Development mode: proxying to Angular dev server at ${r}`),Promise.resolve().then(()=>Tr(rde(),1)).then(({createProxyMiddleware:e})=>{let t=e({target:r,changeOrigin:!0,ws:!0});ja.use("/",(n,i,a)=>{n.path.startsWith("/api")||n.path.startsWith("/events")?a():t(n,i,a)}),ke("INIT","Proxy middleware configured successfully")}).catch(e=>{console.error("Failed to load http-proxy-middleware:",e)})}else{let r=process.env.CODAY_CLIENT_PATH?Lc.resolve(process.env.CODAY_CLIENT_PATH):Lc.resolve(__dirname,"../coday-client/browser");if(ke("INIT",`Production mode: serving static files from ${r}`),process.env.CODAY_CLIENT_PATH&&ke("INIT","Using client path from CODAY_CLIENT_PATH environment variable"),!iE.existsSync(r))console.error(`ERROR: Client path does not exist: ${r}`),console.error("Please build the client first with: pnpm nx run client:build");else{let e=Lc.join(r,"index.html");iE.existsSync(e)?ke("INIT",`Verified index.html exists at ${e}`):(console.error(`ERROR: index.html not found at: ${e}`),console.error("Client build may be incomplete. Try rebuilding with: pnpm nx run client:build"))}ja.use(cE.default.static(r))}var aE=new R_($n.configDir),Om=$n.project;if(Om&&!$n.forcedProject){let r=process.cwd(),e=Lc.basename(r);if(aE.exists(e)){let t=aE.getConfig(e);if(t&&t.path===r&&!t.volatile)ke("INIT",`Default mode: found existing non-volatile project '${e}' for current directory`),Om=e;else{let n=A1.generateProjectId(r);ke("INIT",`Default mode: existing project '${e}' doesn't match path, using volatile ID ${n}`),Om=n}}else{let t=A1.generateProjectId(r);ke("INIT",`Default mode: no existing project found, using volatile ID ${t}`),Om=t}}var FM=new A1(aE,Om,$n.forcedProject),ade=Lc.join($n.configDir,"projects"),sde=new I_(ade),uE=new O_(aE,ade,sde),fE=new a_(lE,RM,FM,uE),cat=new T2("config-api"),lat=new D_($n.configDir,cat),uat=["root","admin","administrator","system","daemon","nobody","node","app","service","docker","www-data","nginx","apache","ansible"];function I1(r){let e=$n.auth?r.headers[oat]:nde.userInfo().username;if(uat.includes(e.toLowerCase()))throw new Error(`Security error: Cannot run with username "${e}". This appears to be a system or service account. When running locally, ensure you are running as a regular user account. When running in production, ensure authentication is properly configured with --auth flag.`);return e}O0e(ja,I1);w0e(ja,lat,I1);E0e(ja,RM,I1,uE,fE,$n,lE);S0e(ja,FM);D0e(ja,uE,sde,fE,I1,$n);P0e(ja,fE,I1);I0e(ja,FM,I1,$n.configDir,lE,RM,uE,$n);if(process.env.BUILD_ENV!=="development"){let r=process.env.CODAY_CLIENT_PATH?Lc.resolve(process.env.CODAY_CLIENT_PATH):Lc.resolve(__dirname,"../coday-client/browser"),e=Lc.resolve(r,"index.html");ke("INIT",`Catch-all route will serve: ${e}`),ja.use((t,n,i)=>{if(t.path.startsWith("/api")||t.path.startsWith("/events")){n.status(404).send("Not found");return}ke("ROUTER",`Serving index.html for client route: ${t.path}`),iE.readFile(e,"utf8",(a,s)=>{a?(ke("ERROR",`Failed to read index.html from ${e}:`,a),ke("ERROR",`File exists check: ${iE.existsSync(e)}`),i(a)):n.type("html").send(s)})})}var sE=null;ja.use((r,e,t,n)=>{ke("ERROR",`Request error on ${e.method} ${e.path}:`,r.message),console.error(r.stack),process.env.BUILD_ENV==="development"?t.status(500).json({error:"Internal Server Error",message:r.message,stack:r.stack}):t.status(500).send("Something went wrong!")});sat.then(async r=>{ja.listen(r,()=>{console.log(`Server is running on http://localhost:${r}`)});try{ke("CLEANUP","Starting thread cleanup service...");let e=Lc.join($n.configDir,"projects");sE=new T_(e,lE),await sE.start(),ke("CLEANUP","Thread cleanup service started successfully")}catch(e){console.error("Failed to start thread cleanup service:",e)}}).catch(r=>{console.error("Failed to start server:",r),process.exit(1)});var oE=!1;async function R1(r){oE&&(console.log(`Received ${r} during shutdown, forcing exit...`),process.exit(1)),oE=!0,console.log(`Received ${r}, shutting down gracefully...`);try{sE&&(console.log("Stopping thread cleanup service..."),await sE.stop()),console.log("Cleaning up thread Coday instances..."),await fE.shutdown(),console.log("Graceful shutdown completed"),process.exit(0)}catch(e){console.error("Error during graceful shutdown:",e),process.exit(1)}}process.on("SIGTERM",()=>R1("SIGTERM"));process.on("SIGINT",()=>R1("SIGINT"));process.on("SIGUSR2",()=>R1("SIGUSR2"));process.on("SIGHUP",()=>R1("SIGHUP"));process.on("uncaughtException",r=>{if(console.error("Uncaught exception:",r),r.message==="no elements in sequence"||r.constructor.name==="EmptyErrorImpl"){console.log("Detected RxJS EmptyError during system sleep - this is expected behavior"),console.log("Process will continue normally after system wake");return}oE||R1("uncaughtException")});process.on("unhandledRejection",(r,e)=>{if(console.error("Unhandled rejection at:",e,"reason:",r),r&&typeof r=="object"){let t=r;if(t.message==="no elements in sequence"||t.constructor?.name==="EmptyErrorImpl"){console.log("Detected RxJS EmptyError rejection during system sleep - this is expected behavior");return}if(t.name==="TimeoutError"||t.message?.includes("timeout")){console.log("Detected timeout error - handling gracefully without shutdown");return}if(t.name==="AbortError"||t.message?.includes("aborted")){console.log("Detected abort error - handling gracefully without shutdown");return}}console.error("Critical unhandled rejection detected"),oE||R1("unhandledRejection")});
|
|
1139
1139
|
/*! Bundled license information:
|
|
1140
1140
|
|
|
1141
1141
|
depd/index.js:
|