@whoz-oss/coday-server 0.66.1 → 0.66.2
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 +1 -1
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -1301,7 +1301,7 @@ ${f}`;return l>0&&o.comments_url&&(d+=`
|
|
|
1301
1301
|
|
|
1302
1302
|
## Comments
|
|
1303
1303
|
|
|
1304
|
-
To get comments, use the URL: ${o.comments_url}`),d}catch(n){return`Error: ${n.message}`}}var dC=class extends Ar{constructor(t,n,i){super(t);this.integrationService=n;this.userService=i}name="BASECAMP";oauth=null;async handleOAuthCallback(t){this.oauth&&await this.oauth.handleCallback(t)}async buildTools(t){let n=[];if(!this.integrationService.hasIntegration(this.name))return n;let i=this.integrationService.getIntegration(this.name);if(!i)return n;let a=i.username,o=i.apiKey,s=i.oauth2?.redirect_uri;if(!s)return this.interactor.displayText("Basecamp integration requires redirectUri"),n;if(!a||!o)return this.interactor.displayText("Basecamp integration requires clientId (username) and clientSecret (apiKey)"),n;let c=t.project.name;this.oauth=new pC(a,o,s,this.interactor,this.userService,c);let u={type:"function",function:{name:"listBasecampProjects",description:"List all projects in the connected Basecamp account. Will prompt for OAuth authentication if not already connected. Basecamp uses geared pagination: page 1 returns 15 results, page 2 returns 30, page 3 returns 50, and page 4+ return 100 results each. Use the page parameter to navigate through results.",parameters:{type:"object",properties:{page:{type:"number",description:"Page number to retrieve (optional). If not provided, returns page 1."}}},parse:JSON.parse,function:async({page:p})=>r9e(this.oauth,p)}};n.push(u);let l={type:"function",function:{name:"getBasecampMessageBoard",description:"Get the message board ID for a Basecamp project. You need this ID to retrieve messages from the project.",parameters:{type:"object",properties:{projectId:{type:"number",description:"The project ID (from listBasecampProjects)"}}},parse:JSON.parse,function:async({projectId:p})=>n9e(this.oauth,p)}};n.push(l);let f={type:"function",function:{name:"getBasecampMessages",description:"List all messages in a Basecamp message board. Returns a summary of each message with title, author, date, and preview. Basecamp uses geared pagination: page 1 returns 15 results, page 2 returns 30, page 3 returns 50, and page 4+ return 100 results each. Use the page parameter to navigate through results.",parameters:{type:"object",properties:{projectId:{type:"number",description:"The project ID (from listBasecampProjects)"},messageBoardId:{type:"number",description:"The message board ID (from getBasecampMessageBoard)"},page:{type:"number",description:"Page number to retrieve (optional). If not provided, returns page 1."}}},parse:JSON.parse,function:async({projectId:p,messageBoardId:m,page:h})=>i9e(this.oauth,p,m,h)}};n.push(f);let d={type:"function",function:{name:"getBasecampMessage",description:"Get the full content of a specific Basecamp message, including title, author, date, and complete text content.",parameters:{type:"object",properties:{projectId:{type:"number",description:"The project ID (from listBasecampProjects)"},messageId:{type:"number",description:"The message ID (from getBasecampMessages)"}}},parse:JSON.parse,function:async({projectId:p,messageId:m})=>a9e(this.oauth,p,m)}};return n.push(d),n}};var hC=class{constructor(e,t,n,i){this.interactor=e;this.services=t;this.mcpConfigs=t.mcp.getMergedConfiguration().servers,this.toolFactories=[new GE(e,t.options?.baseUrl),new LS(e,i),new US(e,n,i),new OS(e),new YE(e,t.integration),new KE(e),new hA(e,t.integration),new JE(e,t.memory),new QA(e,t.integration),new eC(e,t.integration),new iC(e,t.integration),new aC(e,t.integration),new dC(e,t.integration,t.user)]}toolFactories;mcpConfigs;tools=[];async kill(){console.log("[TOOLBOX] Closing non-MCP tool factories"),await Promise.all(this.toolFactories.map(e=>e.kill())),console.log("[TOOLBOX] Closed non-MCP tool factories")}async getTools(e){let{context:t,integrations:n,agentName:i}=e,a=t.aiThread?.id;a||this.interactor.warn("No thread ID in context, MCP tools will not be available");let o=[];if(a)for(let u of this.mcpConfigs)try{let l=await this.services.mcpPool.getOrCreateFactory(u,a,()=>new ZE(u));o.push(l)}catch(l){this.interactor.debug(`Error creating MCP factory for ${u.name}: ${l}`)}let c=[...this.toolFactories,...o].filter(u=>!n||n.has(u.name));try{let u=await Promise.all(c.map(async l=>{try{return await l.getTools(t,n?.get(l.name)??[],i??"default")}catch(f){return this.interactor.debug(`Error building tools from ${l.name} for agent ${i}: ${f}`),[]}}));return this.tools=u.flat(),this.tools}catch(u){return this.interactor.debug(`Unexpected error building tools for agent ${i}: ${u}`),[]}}async handleOAuthCallback(e){let t=this.toolFactories.find(n=>n.name===e.integrationName);if(!t){this.interactor.warn(`No integration found for OAuth callback: ${e.integrationName}`);return}if("handleOAuthCallback"in t&&typeof t.handleOAuthCallback=="function")try{await t.handleOAuthCallback(e)}catch(n){this.interactor.error(`Error handling OAuth callback for ${e.integrationName}: ${n}`)}else this.interactor.warn(`Integration ${e.integrationName} does not support OAuth callbacks`)}};var Cm=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 hC(this.interactor,n,this.findAgentByNameStart,this.listAgentSummaries)}agentCache=new Map;agentDefinitions=[];toolbox;listAgentSummaries=()=>this.agentDefinitions.map(e=>({name:e.definition.name,description:e.definition.description})).sort((e,t)=>e.name.toLowerCase().localeCompare(t.name.toLowerCase()));initialize=async e=>{if(this.agentDefinitions.length>0)return;let t=performance.now();this.interactor.debug("\u{1F680} Starting agent initialization...")
|
|
1304
|
+
To get comments, use the URL: ${o.comments_url}`),d}catch(n){return`Error: ${n.message}`}}var dC=class extends Ar{constructor(t,n,i){super(t);this.integrationService=n;this.userService=i}name="BASECAMP";oauth=null;async handleOAuthCallback(t){this.oauth&&await this.oauth.handleCallback(t)}async buildTools(t){let n=[];if(!this.integrationService.hasIntegration(this.name))return n;let i=this.integrationService.getIntegration(this.name);if(!i)return n;let a=i.username,o=i.apiKey,s=i.oauth2?.redirect_uri;if(!s)return this.interactor.displayText("Basecamp integration requires redirectUri"),n;if(!a||!o)return this.interactor.displayText("Basecamp integration requires clientId (username) and clientSecret (apiKey)"),n;let c=t.project.name;this.oauth=new pC(a,o,s,this.interactor,this.userService,c);let u={type:"function",function:{name:"listBasecampProjects",description:"List all projects in the connected Basecamp account. Will prompt for OAuth authentication if not already connected. Basecamp uses geared pagination: page 1 returns 15 results, page 2 returns 30, page 3 returns 50, and page 4+ return 100 results each. Use the page parameter to navigate through results.",parameters:{type:"object",properties:{page:{type:"number",description:"Page number to retrieve (optional). If not provided, returns page 1."}}},parse:JSON.parse,function:async({page:p})=>r9e(this.oauth,p)}};n.push(u);let l={type:"function",function:{name:"getBasecampMessageBoard",description:"Get the message board ID for a Basecamp project. You need this ID to retrieve messages from the project.",parameters:{type:"object",properties:{projectId:{type:"number",description:"The project ID (from listBasecampProjects)"}}},parse:JSON.parse,function:async({projectId:p})=>n9e(this.oauth,p)}};n.push(l);let f={type:"function",function:{name:"getBasecampMessages",description:"List all messages in a Basecamp message board. Returns a summary of each message with title, author, date, and preview. Basecamp uses geared pagination: page 1 returns 15 results, page 2 returns 30, page 3 returns 50, and page 4+ return 100 results each. Use the page parameter to navigate through results.",parameters:{type:"object",properties:{projectId:{type:"number",description:"The project ID (from listBasecampProjects)"},messageBoardId:{type:"number",description:"The message board ID (from getBasecampMessageBoard)"},page:{type:"number",description:"Page number to retrieve (optional). If not provided, returns page 1."}}},parse:JSON.parse,function:async({projectId:p,messageBoardId:m,page:h})=>i9e(this.oauth,p,m,h)}};n.push(f);let d={type:"function",function:{name:"getBasecampMessage",description:"Get the full content of a specific Basecamp message, including title, author, date, and complete text content.",parameters:{type:"object",properties:{projectId:{type:"number",description:"The project ID (from listBasecampProjects)"},messageId:{type:"number",description:"The message ID (from getBasecampMessages)"}}},parse:JSON.parse,function:async({projectId:p,messageId:m})=>a9e(this.oauth,p,m)}};return n.push(d),n}};var hC=class{constructor(e,t,n,i){this.interactor=e;this.services=t;this.mcpConfigs=t.mcp.getMergedConfiguration().servers,this.toolFactories=[new GE(e,t.options?.baseUrl),new LS(e,i),new US(e,n,i),new OS(e),new YE(e,t.integration),new KE(e),new hA(e,t.integration),new JE(e,t.memory),new QA(e,t.integration),new eC(e,t.integration),new iC(e,t.integration),new aC(e,t.integration),new dC(e,t.integration,t.user)]}toolFactories;mcpConfigs;tools=[];async kill(){console.log("[TOOLBOX] Closing non-MCP tool factories"),await Promise.all(this.toolFactories.map(e=>e.kill())),console.log("[TOOLBOX] Closed non-MCP tool factories")}async getTools(e){let{context:t,integrations:n,agentName:i}=e,a=t.aiThread?.id;a||this.interactor.warn("No thread ID in context, MCP tools will not be available");let o=[];if(a)for(let u of this.mcpConfigs)try{let l=await this.services.mcpPool.getOrCreateFactory(u,a,()=>new ZE(u));o.push(l)}catch(l){this.interactor.debug(`Error creating MCP factory for ${u.name}: ${l}`)}let c=[...this.toolFactories,...o].filter(u=>!n||n.has(u.name));try{let u=await Promise.all(c.map(async l=>{try{return await l.getTools(t,n?.get(l.name)??[],i??"default")}catch(f){return this.interactor.debug(`Error building tools from ${l.name} for agent ${i}: ${f}`),[]}}));return this.tools=u.flat(),this.tools}catch(u){return this.interactor.debug(`Unexpected error building tools for agent ${i}: ${u}`),[]}}async handleOAuthCallback(e){let t=this.toolFactories.find(n=>n.name===e.integrationName);if(!t){this.interactor.warn(`No integration found for OAuth callback: ${e.integrationName}`);return}if("handleOAuthCallback"in t&&typeof t.handleOAuthCallback=="function")try{await t.handleOAuthCallback(e)}catch(n){this.interactor.error(`Error handling OAuth callback for ${e.integrationName}: ${n}`)}else this.interactor.warn(`Integration ${e.integrationName} does not support OAuth callbacks`)}};var Cm=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 hC(this.interactor,n,this.findAgentByNameStart,this.listAgentSummaries)}agentCache=new Map;agentDefinitions=[];toolbox;listAgentSummaries=()=>this.agentDefinitions.map(e=>({name:e.definition.name,description:e.definition.description})).sort((e,t)=>e.name.toLowerCase().localeCompare(t.name.toLowerCase()));initialize=async e=>{if(this.agentDefinitions.length>0)return;let t=performance.now();this.interactor.debug("\u{1F680} Starting agent initialization...");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 o=performance.now(),s=this.services.project.selectedProject;if(s?.config.agents?.length)for(let p of s.config.agents)this.addDefinition(p,this.projectPath);let c=performance.now()-o;this.interactor.debug(`\u2699\uFE0F Loaded agent definitions from project local config: ${c.toFixed(2)}ms (${s?.config.agents?.length??0} agents)`);let u=performance.now();await this.loadFromFiles(e);let l=performance.now()-u;this.interactor.debug(`\u{1F4C1} Loaded agent definitions from files: ${l.toFixed(2)}ms`),this.agentDefinitions.length===0&&(this.addDefinition(f7,this.projectPath),this.interactor.debug("\u{1F504} No agent definitions found, using Coday as backup"));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`)}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}}findAgentByNameStart=async(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)return;let a=await this.interactor.chooseOption(i,`Multiple agents match '${e}', please select one:`);return n.find(o=>o.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(o=>o.definition.name.toLowerCase().startsWith(n)),a=[];for(let o of i){let s=o.definition.name.toLowerCase(),c=this.agentCache.get(s);c||(c=await this.tryAddAgent(o,t),c&&this.agentCache.set(s,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:{...f7,...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(bd.join(i.configPath,"agents"));let a=this.services.project.selectedProject?.config.path;if(a){let l=await Bf({text:"coday.yaml",root:a});if(l.length>0){let f=bd.dirname(l[0]);t.push(bd.join(a,f,"agents"))}e.project.agentFolders?.length&&t.push(...e.project.agentFolders)}t.push(...this.commandLineAgentFolders);let o=performance.now();await Promise.all(t.map(async l=>{try{n.push(...(await mC.readdir(l)).filter(f=>f.endsWith(".yml")||f.endsWith(".yaml")).map(f=>bd.join(l,f)))}catch(f){f.code==="EPERM"?console.error(`Permission denied to access ${l}. This is common for protected directories.
|
|
1305
1305
|
Consider moving your agent files to a less restricted location.`):console.error(`Could not read directory ${l}: ${f.code}`)}}));let s=performance.now()-o;this.interactor.debug(` \u{1F4C2} Scanned agent directories: ${s.toFixed(2)}ms (found ${n.length} files)`);let c=performance.now();await Promise.all(n.map(async l=>{try{let f=await mC.readFile(l,"utf-8"),d=o9e.parse(f),p=bd.dirname(l),h=p.startsWith(this.projectPath)?this.projectPath:p;this.addDefinition(d,h)}catch(f){console.error(f)}}));let u=performance.now()-c;this.interactor.debug(` \u{1F4DD} Parsed agent files: ${u.toFixed(2)}ms`)}async tryAddAgent(e,t){let n={...f7,...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(),o=this.aiClientProvider.getClient(n.aiProvider,n.modelName);if(!o){this.interactor.error(`Cannot create agent ${n.name}: AI client creation failed`);return}let s=performance.now()-a,c=e.basePath,u=performance.now(),l=await nw(n,this.interactor,c,n.name),f=performance.now()-u;n.instructions=`${n.instructions}
|
|
1306
1306
|
|
|
1307
1307
|
|