@crewx/sdk 0.8.9-rc.25 → 0.8.9-rc.27

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.
@@ -266,4 +266,5 @@ ${s.join(`
266
266
  `),c},{behavior:"immediate"})}}catch(r){throw r instanceof _?r:new _("DB_ERROR","Failed to save user message",r)}finally{n.close();}}saveAssistantMessage(t,e,s){if(!this.dbExists())return;let n=this.openHandle(true);try{let r=new Date().toISOString();n.db.update(u).set({last_message:e,updated_at:r}).where(eq(u.id,t)).run();}catch(r){throw r instanceof _?r:new _("DB_ERROR","Failed to save assistant message",r)}finally{n.close();}}updateThread(t,e){if(!this.dbExists())return;let s=this.openHandle(true);try{let n={updated_at:new Date().toISOString()};e.title!==void 0&&(n.title=e.title,n.title_locked=1),e.titleLocked!==void 0&&(n.title_locked=e.titleLocked?1:0),s.db.update(u).set(n).where(eq(u.id,t)).run();}catch(n){throw n instanceof _?n:new _("DB_ERROR","Failed to update thread",n)}finally{s.close();}}togglePin(t,e){let s=this.openHandle(true);try{let n=e?and(eq(u.id,t),eq(u.workspace_id,e)):eq(u.id,t),r=s.db.select({pinned:u.pinned,metadata:u.metadata}).from(u).where(n).get();if(!r)return null;let i=r.pinned?0:1,a=r.metadata?JSON.parse(r.metadata):{};if(i){let l=e?and(eq(u.pinned,1),eq(u.workspace_id,e)):eq(u.pinned,1),c=s.db.select({metadata:u.metadata}).from(u).where(l).all(),p=0;for(let k of c){let w=k.metadata?JSON.parse(k.metadata):{};typeof w.pinOrder=="number"&&w.pinOrder>p&&(p=w.pinOrder);}a.pinOrder=p+1;}else delete a.pinOrder;return s.db.update(u).set({pinned:i,metadata:Object.keys(a).length>0?JSON.stringify(a):null}).where(n).run(),{pinned:!!i}}catch(n){throw n instanceof _?n:new _("DB_ERROR","Failed to toggle pin",n)}finally{s.close();}}reorderPins(t,e){let s=this.openHandle(true);try{for(let n=0;n<t.length;n++){let r=e?and(eq(u.id,t[n]),eq(u.workspace_id,e)):eq(u.id,t[n]),i=s.db.select({metadata:u.metadata}).from(u).where(r).get();if(!i)continue;let a=i.metadata?JSON.parse(i.metadata):{};a.pinOrder=n+1,s.db.update(u).set({metadata:JSON.stringify(a)}).where(r).run();}}catch(n){throw n instanceof _?n:new _("DB_ERROR","Failed to reorder pins",n)}finally{s.close();}}toggleStar(t,e){let s=this.openHandle(true);try{let n=e?and(eq(u.id,t),eq(u.workspace_id,e)):eq(u.id,t),r=s.db.select({starred:u.starred}).from(u).where(n).get();if(!r)return null;let i=r.starred?0:1;return s.db.update(u).set({starred:i}).where(n).run(),{starred:!!i}}catch(n){throw n instanceof _?n:new _("DB_ERROR","Failed to toggle star",n)}finally{s.close();}}};function Ee(d){return d.replace(/<conversation_history[^>]*>[\s\S]*?<\/conversation_history>/g,"").split(`
267
267
  `).filter(n=>!(n.startsWith("Loaded ")&&n.includes("layouts from")||n.includes("[dotenv@")||n.includes("[Nest]")&&n.includes("DEBUG")||n.startsWith("Registered custom layout:")||n.startsWith("Updated custom layout:"))).join(`
268
268
  `).trim()}function Se(d){if(!d)return "";let t=d;try{let e=JSON.parse(t);Array.isArray(e)?t=e.filter(s=>s?.type==="text"&&s?.text).map(s=>s.text).join(`
269
- `):e&&typeof e=="object"&&e.result!==void 0&&(t=e.result||"");}catch{t=Ee(t);}return t}var nt=class{dbPath;constructor(t){this.dbPath=t??join(homedir(),".crewx","crewx.db");}getThreadRepo(){return new st({dbPath:this.dbPath})}updateThread(t,e){this.getThreadRepo().updateThread(t,{title:e.title});}async ensureThread(t,e,s){let n=this.getThreadRepo(),r=n.findThreadById(t);if(r){if(r.platform!==e)throw new Error(`Thread '${t}' already exists with platform '${r.platform}' \u2014 cannot change to '${e}' (platform is immutable)`);return {created:false}}return n.ensureThread(t,e,s),{created:true}}async fetchHistory(t,e){let s=e?.limit??100,n=this.getThreadRepo(),r=n.findThreadById(t),i=n.findTopLevelTasks(t,void 0,s),a=new Set(["queued","cancelled"]);i=i.filter(p=>(!p.status||!a.has(p.status))&&(!e?.currentTraceId||p.trace_id!==e.currentTraceId));let l=r?.platform??"cli",c=this.rowsToMessages(i);return {threadId:t,platform:l,messages:c,metadata:{title:r?.title??void 0,firstMessage:r?.first_message??void 0,lastMessage:r?.last_message??void 0,messageCount:r?.message_count??0,updatedAt:r?.updated_at?new Date(r.updated_at).getTime():void 0}}}async saveUserMessage(t,e,s,n){let{firstMessage:r}=this.getThreadRepo().saveUserMessage(t,e);return {id:t,firstMessage:r}}async saveAssistantMessage(t,e,s,n){return this.getThreadRepo().saveAssistantMessage(t,e),{id:t}}close(){}normalizeStatus(t){if(t&&!["success","completed","done"].includes(t)){if(["failed","error"].includes(t))return "failed";if(t==="running")return "running"}}rowsToMessages(t){let e=[];for(let s of t){s.prompt&&e.push({id:`${s.id}-user`,text:s.prompt,isAssistant:false,timestamp:new Date(s.started_at).getTime(),metadata:{caller_agent_id:s.caller_agent_id}});let n=Se(s.result),r=this.normalizeStatus(s.status);if(n||r==="running"||r==="failed"){let i={agent_id:s.agent_id,task_id:s.id};r&&(i.status=r),e.push({id:`${s.id}-assistant`,text:n,isAssistant:true,timestamp:new Date(s.started_at).getTime(),metadata:i});}}return e}};var _t=class extends L{name="conversation";_provider;unsubStart=null;unsubEnd=null;constructor(t){super(),this._provider=new nt(t?.dbPath);}get conversationProvider(){return this._provider}async afterUserMessage(t,e,s,n){}async afterAssistantMessage(t,e,s){}attach(t){this.unsubStart=t.on("task:start",async e=>{if(!e.threadId)return;let s=e.platform??"cli";try{let n=await this._provider.ensureThread(e.threadId,s,e.workspaceId),r=await this._provider.saveUserMessage(e.threadId,e.message??"");await this.afterUserMessage(e.threadId,r.id,n.created||r.firstMessage,e);}catch{}}),this.unsubEnd=t.on("task:end",async e=>{if(!e.result)return;let s=e.metadata?.threadId;if(!s)return;let n=e.agentRef?.replace(/^@/,"")??"";try{let{id:r}=await this._provider.saveAssistantMessage(s,e.result,n);await this.afterAssistantMessage(s,r,e);}catch{}});}detach(t){this.unsubStart?.(),this.unsubStart=null,this.unsubEnd?.(),this.unsubEnd=null,this._provider.close?.();}};export{_t as ConversationPlugin,rt as FileLoggerPlugin,ut as SqliteTracingPlugin};
269
+ `):e&&typeof e=="object"&&e.result!==void 0&&(t=e.result||"");}catch{t=Ee(t);}return t}var nt=class{dbPath;constructor(t){this.dbPath=t??join(homedir(),".crewx","crewx.db");}getThreadRepo(){return new st({dbPath:this.dbPath})}updateThread(t,e){this.getThreadRepo().updateThread(t,{title:e.title});}async ensureThread(t,e,s){let n=this.getThreadRepo(),r=n.findThreadById(t);if(r){if(r.platform!==e)throw new Error(`Thread '${t}' already exists with platform '${r.platform}' \u2014 cannot change to '${e}' (platform is immutable)`);return {created:false}}return n.ensureThread(t,e,s),{created:true}}async fetchHistory(t,e){let s=e?.limit??100,n=this.getThreadRepo(),r=n.findThreadById(t),i=n.findTopLevelTasks(t,void 0,s),a=new Set(["queued","cancelled"]);i=i.filter(p=>(!p.status||!a.has(p.status))&&(!e?.currentTraceId||p.trace_id!==e.currentTraceId));let l=r?.platform??"cli",c=this.rowsToMessages(i);return {threadId:t,platform:l,messages:c,metadata:{title:r?.title??void 0,firstMessage:r?.first_message??void 0,lastMessage:r?.last_message??void 0,messageCount:r?.message_count??0,updatedAt:r?.updated_at?new Date(r.updated_at).getTime():void 0}}}async saveUserMessage(t,e,s,n){let{firstMessage:r}=this.getThreadRepo().saveUserMessage(t,e);return {id:t,firstMessage:r}}async saveAssistantMessage(t,e,s,n){return this.getThreadRepo().saveAssistantMessage(t,e),{id:t}}close(){}normalizeStatus(t){if(t&&!["success","completed","done"].includes(t)){if(["failed","error"].includes(t))return "failed";if(t==="running")return "running"}}rowsToMessages(t){let e=[];for(let s of t){s.prompt&&e.push({id:`${s.id}-user`,text:s.prompt,isAssistant:false,timestamp:new Date(s.started_at).getTime(),metadata:{caller_agent_id:s.caller_agent_id}});let n=Se(s.result),r=this.normalizeStatus(s.status);if(n||r==="running"||r==="failed"){let i={agent_id:s.agent_id,task_id:s.id};r&&(i.status=r),r==="failed"&&s.error&&(i.reason=s.error.split(`
270
+ `)[0].slice(0,200)),e.push({id:`${s.id}-assistant`,text:n,isAssistant:true,timestamp:new Date(s.started_at).getTime(),metadata:i});}}return e}};var _t=class extends L{name="conversation";_provider;unsubStart=null;unsubEnd=null;constructor(t){super(),this._provider=new nt(t?.dbPath);}get conversationProvider(){return this._provider}async afterUserMessage(t,e,s,n){}async afterAssistantMessage(t,e,s){}attach(t){this.unsubStart=t.on("task:start",async e=>{if(!e.threadId)return;let s=e.platform??"cli";try{let n=await this._provider.ensureThread(e.threadId,s,e.workspaceId),r=await this._provider.saveUserMessage(e.threadId,e.message??"");await this.afterUserMessage(e.threadId,r.id,n.created||r.firstMessage,e);}catch{}}),this.unsubEnd=t.on("task:end",async e=>{if(!e.result)return;let s=e.metadata?.threadId;if(!s)return;let n=e.agentRef?.replace(/^@/,"")??"";try{let{id:r}=await this._provider.saveAssistantMessage(s,e.result,n);await this.afterAssistantMessage(s,r,e);}catch{}});}detach(t){this.unsubStart?.(),this.unsubStart=null,this.unsubEnd?.(),this.unsubEnd=null,this._provider.close?.();}};export{_t as ConversationPlugin,rt as FileLoggerPlugin,ut as SqliteTracingPlugin};
@@ -97,6 +97,7 @@ export declare class Crewx extends TypedEventEmitter {
97
97
  private _getConversationProvider;
98
98
  private _fetchHistoryMessages;
99
99
  private _resolveTimeout;
100
+ private _lookupCliAdapter;
100
101
  private _resolveEffectiveCwd;
101
102
  private _buildFileRemoteOptions;
102
103
  private emitToolEvents;
@@ -5,4 +5,5 @@ export type { ProviderRuntime, ProviderFactory, ProviderQueryOptions } from './p
5
5
  export { parseYamlContent, ConfigLoadError } from './config/loader.browser.js';
6
6
  export { BrowserFsAdapter } from './platform/BrowserFsAdapter.js';
7
7
  export type { IFsAdapter } from './platform/IFsAdapter.js';
8
+ export { PROVIDER_ORDER, providerRank, compareProviders } from './provider/order.js';
8
9
  export type { AgentConfig, CrewxProjectConfig, CrewxOptions, QueryOptions, QueryResult, ExecuteOptions, ExecuteResult, } from './types/index.js';
@@ -1,2 +1,2 @@
1
- import {load}from'js-yaml';import {z}from'zod';var m=class extends Error{constructor(e,n){let t=n.length>0?` Available: ${n.join(", ")}`:"";super(`Agent not found: "${e}".${t}`),this.name="AgentNotFoundError";}},_={claude:{id:"claude",provider:"cli/claude"},copilot:{id:"copilot",provider:"cli/copilot"},codex:{id:"codex",provider:"cli/codex"}};function h(p,e){let n=p.startsWith("@")?p.slice(1):p,t=e.find(r=>r.id===n);if(t)return t;let s=_[n];if(s)return s;throw new m(p,e.map(r=>r.id))}var l=class extends Error{constructor(n,t){super(n);this.providerStr=t;this.name="ProviderError";}providerStr};var O=new Map;function P(p,e){O.set(p,e);}function w(p){let e=p.split("/");if(e.length!==2)throw new l(`Invalid provider format: "${p}". Expected namespace/id (e.g., api/webllm)`,p);let[n,t]=e,s=O.get(n);if(s)return s(t,p);throw new l(`Unsupported provider namespace: "${n}". Register a factory with registerProviderFactory('${n}', factory).`,p)}var j=new Function("u","return import(u)"),C=class p{_agents;_config;_tools=new Map;_apiProviders=new Map;constructor(e,n){this._agents=new Map(e.map(t=>[t.id,t])),this._config=n;}static async fromConfig(e,n){let t=new p(e.agents??[],e),s=e.agents??[],r=i=>Array.isArray(i.provider)?i.provider[0]:i.provider,c=s.filter(i=>r(i)==="api/webllm"),a=s.filter(i=>r(i)==="api/openrouter");if(c.length>0&&await t._initWebLLM(c,n?.onProgress),a.length>0){if(!n?.openrouterApiKey)throw new Error("openrouterApiKey is required when using api/openrouter provider");t._initOpenRouter(a,n.openrouterApiKey);}return t._apiProviders.size>0&&P("api",(i,d)=>{let g=t._apiProviders.get(i);if(!g)throw new l(`Unknown api provider: ${i}`,d);return g}),t}async _initWebLLM(e,n){if(typeof navigator>"u"||!navigator.gpu)throw new Error("WebGPU is not available. Chrome 113+ or Edge 113+ required.");let t=await j("https://esm.run/@mlc-ai/web-llm"),s=e[0]?.inline?.model??"gemma-2-2b-it-q4f16_1-MLC",r=await t.CreateMLCEngine(s,{initProgressCallback:n?a=>n(a):void 0}),c=[];this._apiProviders.set("webllm",{async query(a,i){let d=[];i?.systemPrompt&&d.push({role:"system",content:i.systemPrompt}),d.push(...c),d.push({role:"user",content:a});let g="",u=await r.chat.completions.create({messages:d,stream:true,temperature:.7,max_tokens:4096});for await(let y of u){let v=y.choices?.[0]?.delta?.content??"";g+=v,i?.onOutput&&i.onOutput(g,"stdout");}return c.push({role:"user",content:a}),c.push({role:"assistant",content:g}),g},async execute(a,i){return this.query(a,i)}});}_initOpenRouter(e,n){let t=e[0]?.inline?.model??"google/gemma-2-2b-it",s=[];this._apiProviders.set("openrouter",{async query(r,c){let a=[];c?.systemPrompt&&a.push({role:"system",content:c.systemPrompt}),a.push(...s),a.push({role:"user",content:r});let i=await fetch("https://openrouter.ai/api/v1/chat/completions",{method:"POST",headers:{Authorization:`Bearer ${n}`,"Content-Type":"application/json"},body:JSON.stringify({model:c?.model||t,messages:a,stream:true})});if(!i.ok){let v=await i.text();throw new Error(`OpenRouter API error (${i.status}): ${v}`)}let d=i.body.getReader(),g=new TextDecoder,u="",y="";for(;;){let{done:v,value:I}=await d.read();if(v)break;y+=g.decode(I,{stream:true});let k=y.split(`
2
- `);y=k.pop();for(let M of k){let x=M.trim();if(!x||!x.startsWith("data: "))continue;let b=x.slice(6);if(b!=="[DONE]")try{let R=JSON.parse(b).choices?.[0]?.delta?.content??"";u+=R,R&&c?.onOutput&&c.onOutput(u,"stdout");}catch{}}}return s.push({role:"user",content:r}),s.push({role:"assistant",content:u}),u},async execute(r,c){return this.query(r,c)}});}get agents(){return this._agents}get config(){return this._config}get tools(){return this._tools}registerTool(e,n){this._tools.set(e,{name:e,...n});}async query(e,n,t){let s=Date.now(),r;try{r=h(e,Array.from(this._agents.values()));}catch(g){if(g instanceof m)return {ok:false,data:"",error:{code:"AGENT_NOT_FOUND",message:g.message},meta:{agentId:e.replace(/^@/,""),provider:"",durationMs:Date.now()-s}};throw g}let c=Array.isArray(r.provider)?r.provider[0]??"api/default":r.provider,a=t?.provider??c,i=t?.model??r.inline?.model,d;try{d=w(a);}catch(g){return {ok:false,data:"",error:{code:"PROVIDER_ERROR",message:g.message},meta:{agentId:r.id,provider:a,model:i,durationMs:Date.now()-s}}}try{return {ok:!0,data:await d.query(n,{model:i,context:t?.context,systemPrompt:r.inline?.system_prompt??r.inline?.prompt,onOutput:t?.onOutput?u=>t.onOutput(u):void 0}),meta:{agentId:r.id,provider:a,model:i,durationMs:Date.now()-s}}}catch(g){return {ok:false,data:"",error:{code:"QUERY_FAILED",message:g.message},meta:{agentId:r.id,provider:a,model:i,durationMs:Date.now()-s}}}}async execute(e,n,t){let s=Date.now(),r;try{r=h(e,Array.from(this._agents.values()));}catch(g){if(g instanceof m)return {ok:false,data:"",error:{code:"AGENT_NOT_FOUND",message:g.message},meta:{agentId:e.replace(/^@/,""),provider:"",durationMs:Date.now()-s}};throw g}let c=Array.isArray(r.provider)?r.provider[0]??"api/default":r.provider,a=t?.provider??c,i=t?.model??r.inline?.model,d;try{d=w(a);}catch(g){return {ok:false,data:"",error:{code:"PROVIDER_ERROR",message:g.message},meta:{agentId:r.id,provider:a,model:i,durationMs:Date.now()-s}}}try{return {ok:!0,data:await d.execute(n,{model:i,context:t?.context,systemPrompt:r.inline?.system_prompt??r.inline?.prompt}),meta:{agentId:r.id,provider:a,model:i,durationMs:Date.now()-s}}}catch(g){return {ok:false,data:"",error:{code:"EXECUTE_FAILED",message:g.message},meta:{agentId:r.id,provider:a,model:i,durationMs:Date.now()-s}}}}};var F=z.object({model:z.string().optional(),system_prompt:z.string().optional(),prompt:z.string().optional(),layout:z.union([z.string(),z.object({id:z.string(),props:z.record(z.unknown()).optional()}),z.object({props:z.record(z.unknown())}),z.object({template:z.string()})]).optional()}).catchall(z.unknown()),T=z.object({include:z.array(z.string()).optional()}).optional(),D=z.object({id:z.string(),name:z.string().optional(),role:z.string().optional(),team:z.string().optional(),provider:z.union([z.string(),z.array(z.string())]),working_directory:z.string().optional(),description:z.string().optional(),tags:z.array(z.string()).optional(),inline:F.optional(),skills:T}).catchall(z.unknown()),E=z.object({agents:z.array(D).optional(),hooks:z.array(z.unknown()).optional(),settings:z.record(z.unknown()).optional(),skills:z.unknown().optional(),layouts:z.record(z.unknown()).optional(),documents:z.record(z.unknown()).optional()}).catchall(z.unknown());var f=class extends Error{constructor(n,t){super(n);this.cause=t;this.name="ConfigLoadError";}cause};function $(p){if(!p||typeof p!="string"||!p.trim())throw new f("YAML content must be a non-empty string");let e;try{e=load(p);}catch(s){throw new f(`YAML parse error: ${s.message}`,s)}let n=S(e),t=E.safeParse(n);if(!t.success)throw new f(`Config validation error: ${t.error.message}`);return t.data}function S(p){if(!p||typeof p!="object")return {agents:[]};let e=p;if(e.agents&&typeof e.agents=="object"&&!Array.isArray(e.agents)){let n=e.agents,t=Object.entries(n).map(([s,r])=>({id:s,...r&&typeof r=="object"?r:{}}));return {...e,agents:t}}return e.agents?e:{...e,agents:[]}}var B="crewx:fs:",A=class{prefix;store;constructor(e){this.prefix=e?.prefix??B,this.store=e?.storage??new Map;}async readFile(e){let n=this.toKey(e),t=this.store.get(n);if(t===void 0)throw new Error(`BrowserFsAdapter: file not found: ${e}`);return t}async exists(e){return this.store.has(this.toKey(e))}resolvePath(...e){let n=e.map(c=>c.replace(/\\/g,"/")).join("/").replace(/\/+/g,"/"),t=n.split("/"),s=[];for(let c of t)c==="."||c===""||(c===".."?s.pop():s.push(c));let r=s.join("/");return n.startsWith("/")?`/${r}`:r}isAbsolute(e){return e.startsWith("/")}setItem(e,n){this.store.set(this.toKey(e),n);}removeItem(e){this.store.delete(this.toKey(e));}keys(){return Array.from(this.store.keys()).filter(e=>e.startsWith(this.prefix)).map(e=>e.slice(this.prefix.length))}async readdir(e){let n=e.replace(/\\/g,"/").replace(/\/$/,""),t=this.toKey(n+"/"),s=[];for(let r of this.store.keys())if(r.startsWith(t)){let a=r.slice(t.length).split("/")[0];a&&!s.includes(a)&&s.push(a);}return s}toKey(e){return `${this.prefix}${e.replace(/\\/g,"/")}`}};export{A as BrowserFsAdapter,f as ConfigLoadError,C as Crewx,l as ProviderError,w as createProvider,$ as parseYamlContent,P as registerProviderFactory};
1
+ import {load}from'js-yaml';import {z}from'zod';var m=class extends Error{constructor(e,r){let t=r.length>0?` Available: ${r.join(", ")}`:"";super(`Agent not found: "${e}".${t}`),this.name="AgentNotFoundError";}},D={claude:{id:"claude",provider:"cli/claude"},copilot:{id:"copilot",provider:"cli/copilot"},codex:{id:"codex",provider:"cli/codex"}};function h(i,e){let r=i.startsWith("@")?i.slice(1):i,t=e.find(n=>n.id===r);if(t)return t;let s=D[r];if(s)return s;throw new m(i,e.map(n=>n.id))}var l=class extends Error{constructor(r,t){super(r);this.providerStr=t;this.name="ProviderError";}providerStr};var I=new Map;function P(i,e){I.set(i,e);}function x(i){let e=i.split("/");if(e.length!==2)throw new l(`Invalid provider format: "${i}". Expected namespace/id (e.g., api/webllm)`,i);let[r,t]=e,s=I.get(r);if(s)return s(t,i);throw new l(`Unsupported provider namespace: "${r}". Register a factory with registerProviderFactory('${r}', factory).`,i)}var F=new Function("u","return import(u)"),C=class i{_agents;_config;_tools=new Map;_apiProviders=new Map;constructor(e,r){this._agents=new Map(e.map(t=>[t.id,t])),this._config=r;}static async fromConfig(e,r){let t=new i(e.agents??[],e),s=e.agents??[],n=a=>Array.isArray(a.provider)?a.provider[0]:a.provider,p=s.filter(a=>n(a)==="api/webllm"),c=s.filter(a=>n(a)==="api/openrouter");if(p.length>0&&await t._initWebLLM(p,r?.onProgress),c.length>0){if(!r?.openrouterApiKey)throw new Error("openrouterApiKey is required when using api/openrouter provider");t._initOpenRouter(c,r.openrouterApiKey);}return t._apiProviders.size>0&&P("api",(a,d)=>{let g=t._apiProviders.get(a);if(!g)throw new l(`Unknown api provider: ${a}`,d);return g}),t}async _initWebLLM(e,r){if(typeof navigator>"u"||!navigator.gpu)throw new Error("WebGPU is not available. Chrome 113+ or Edge 113+ required.");let t=await F("https://esm.run/@mlc-ai/web-llm"),s=e[0]?.inline?.model??"gemma-2-2b-it-q4f16_1-MLC",n=await t.CreateMLCEngine(s,{initProgressCallback:r?c=>r(c):void 0}),p=[];this._apiProviders.set("webllm",{async query(c,a){let d=[];a?.systemPrompt&&d.push({role:"system",content:a.systemPrompt}),d.push(...p),d.push({role:"user",content:c});let g="",u=await n.chat.completions.create({messages:d,stream:true,temperature:.7,max_tokens:4096});for await(let y of u){let v=y.choices?.[0]?.delta?.content??"";g+=v,a?.onOutput&&a.onOutput(g,"stdout");}return p.push({role:"user",content:c}),p.push({role:"assistant",content:g}),g},async execute(c,a){return this.query(c,a)}});}_initOpenRouter(e,r){let t=e[0]?.inline?.model??"google/gemma-2-2b-it",s=[];this._apiProviders.set("openrouter",{async query(n,p){let c=[];p?.systemPrompt&&c.push({role:"system",content:p.systemPrompt}),c.push(...s),c.push({role:"user",content:n});let a=await fetch("https://openrouter.ai/api/v1/chat/completions",{method:"POST",headers:{Authorization:`Bearer ${r}`,"Content-Type":"application/json"},body:JSON.stringify({model:p?.model||t,messages:c,stream:true})});if(!a.ok){let v=await a.text();throw new Error(`OpenRouter API error (${a.status}): ${v}`)}let d=a.body.getReader(),g=new TextDecoder,u="",y="";for(;;){let{done:v,value:_}=await d.read();if(v)break;y+=g.decode(_,{stream:true});let b=y.split(`
2
+ `);y=b.pop();for(let j of b){let w=j.trim();if(!w||!w.startsWith("data: "))continue;let O=w.slice(6);if(O!=="[DONE]")try{let E=JSON.parse(O).choices?.[0]?.delta?.content??"";u+=E,E&&p?.onOutput&&p.onOutput(u,"stdout");}catch{}}}return s.push({role:"user",content:n}),s.push({role:"assistant",content:u}),u},async execute(n,p){return this.query(n,p)}});}get agents(){return this._agents}get config(){return this._config}get tools(){return this._tools}registerTool(e,r){this._tools.set(e,{name:e,...r});}async query(e,r,t){let s=Date.now(),n;try{n=h(e,Array.from(this._agents.values()));}catch(g){if(g instanceof m)return {ok:false,data:"",error:{code:"AGENT_NOT_FOUND",message:g.message},meta:{agentId:e.replace(/^@/,""),provider:"",durationMs:Date.now()-s}};throw g}let p=Array.isArray(n.provider)?n.provider[0]??"api/default":n.provider,c=t?.provider??p,a=t?.model??n.inline?.model,d;try{d=x(c);}catch(g){return {ok:false,data:"",error:{code:"PROVIDER_ERROR",message:g.message},meta:{agentId:n.id,provider:c,model:a,durationMs:Date.now()-s}}}try{return {ok:!0,data:await d.query(r,{model:a,context:t?.context,systemPrompt:n.inline?.system_prompt??n.inline?.prompt,onOutput:t?.onOutput?u=>t.onOutput(u):void 0}),meta:{agentId:n.id,provider:c,model:a,durationMs:Date.now()-s}}}catch(g){return {ok:false,data:"",error:{code:"QUERY_FAILED",message:g.message},meta:{agentId:n.id,provider:c,model:a,durationMs:Date.now()-s}}}}async execute(e,r,t){let s=Date.now(),n;try{n=h(e,Array.from(this._agents.values()));}catch(g){if(g instanceof m)return {ok:false,data:"",error:{code:"AGENT_NOT_FOUND",message:g.message},meta:{agentId:e.replace(/^@/,""),provider:"",durationMs:Date.now()-s}};throw g}let p=Array.isArray(n.provider)?n.provider[0]??"api/default":n.provider,c=t?.provider??p,a=t?.model??n.inline?.model,d;try{d=x(c);}catch(g){return {ok:false,data:"",error:{code:"PROVIDER_ERROR",message:g.message},meta:{agentId:n.id,provider:c,model:a,durationMs:Date.now()-s}}}try{return {ok:!0,data:await d.execute(r,{model:a,context:t?.context,systemPrompt:n.inline?.system_prompt??n.inline?.prompt}),meta:{agentId:n.id,provider:c,model:a,durationMs:Date.now()-s}}}catch(g){return {ok:false,data:"",error:{code:"EXECUTE_FAILED",message:g.message},meta:{agentId:n.id,provider:c,model:a,durationMs:Date.now()-s}}}}};var T=z.object({model:z.string().optional(),system_prompt:z.string().optional(),prompt:z.string().optional(),layout:z.union([z.string(),z.object({id:z.string(),props:z.record(z.unknown()).optional()}),z.object({props:z.record(z.unknown())}),z.object({template:z.string()})]).optional()}).catchall(z.unknown()),Q=z.object({include:z.array(z.string()).optional()}).optional(),$=z.object({id:z.string(),name:z.string().optional(),role:z.string().optional(),team:z.string().optional(),provider:z.union([z.string(),z.array(z.string())]),working_directory:z.string().optional(),description:z.string().optional(),tags:z.array(z.string()).optional(),inline:T.optional(),skills:Q}).catchall(z.unknown()),M=z.object({agents:z.array($).optional(),hooks:z.array(z.unknown()).optional(),settings:z.record(z.unknown()).optional(),skills:z.unknown().optional(),layouts:z.record(z.unknown()).optional(),documents:z.record(z.unknown()).optional()}).catchall(z.unknown());var f=class extends Error{constructor(r,t){super(r);this.cause=t;this.name="ConfigLoadError";}cause};function B(i){if(!i||typeof i!="string"||!i.trim())throw new f("YAML content must be a non-empty string");let e;try{e=load(i);}catch(s){throw new f(`YAML parse error: ${s.message}`,s)}let r=L(e),t=M.safeParse(r);if(!t.success)throw new f(`Config validation error: ${t.error.message}`);return t.data}function L(i){if(!i||typeof i!="object")return {agents:[]};let e=i;if(e.agents&&typeof e.agents=="object"&&!Array.isArray(e.agents)){let r=e.agents,t=Object.entries(r).map(([s,n])=>({id:s,...n&&typeof n=="object"?n:{}}));return {...e,agents:t}}return e.agents?e:{...e,agents:[]}}var U="crewx:fs:",A=class{prefix;store;constructor(e){this.prefix=e?.prefix??U,this.store=e?.storage??new Map;}async readFile(e){let r=this.toKey(e),t=this.store.get(r);if(t===void 0)throw new Error(`BrowserFsAdapter: file not found: ${e}`);return t}async exists(e){return this.store.has(this.toKey(e))}resolvePath(...e){let r=e.map(p=>p.replace(/\\/g,"/")).join("/").replace(/\/+/g,"/"),t=r.split("/"),s=[];for(let p of t)p==="."||p===""||(p===".."?s.pop():s.push(p));let n=s.join("/");return r.startsWith("/")?`/${n}`:n}isAbsolute(e){return e.startsWith("/")}setItem(e,r){this.store.set(this.toKey(e),r);}removeItem(e){this.store.delete(this.toKey(e));}keys(){return Array.from(this.store.keys()).filter(e=>e.startsWith(this.prefix)).map(e=>e.slice(this.prefix.length))}async readdir(e){let r=e.replace(/\\/g,"/").replace(/\/$/,""),t=this.toKey(r+"/"),s=[];for(let n of this.store.keys())if(n.startsWith(t)){let c=n.slice(t.length).split("/")[0];c&&!s.includes(c)&&s.push(c);}return s}toKey(e){return `${this.prefix}${e.replace(/\\/g,"/")}`}};var k=["codex","claude","opencode","antigravity","copilot"];function N(i){let e=i.indexOf("/");return e===-1?i:i.slice(e+1)}function R(i){let e=N(i),r=k.indexOf(e);return r===-1?k.length:r}function q(i,e){return R(i)-R(e)}export{A as BrowserFsAdapter,f as ConfigLoadError,C as Crewx,k as PROVIDER_ORDER,l as ProviderError,q as compareProviders,x as createProvider,B as parseYamlContent,R as providerRank,P as registerProviderFactory};
package/dist/index.d.ts CHANGED
@@ -23,6 +23,7 @@ export { AgentSkillsSchema } from './types';
23
23
  export { loadYamlFile, parseYamlContent, ConfigLoadError } from './config/loader';
24
24
  export { resolveAgent, AgentNotFoundError } from './agent/resolver';
25
25
  export { resolveAgentSkills } from './agent/resolve-skills';
26
+ export { PROVIDER_ORDER, providerRank, compareProviders } from './provider/order';
26
27
  export { createProvider, ProviderError, ClientToolCallRequiredError, registerProviderFactory } from './provider/bridge';
27
28
  export type { ProviderRuntime, ProviderQueryOptions, ProviderFactory, ProviderUsage, ClientToolCall, ContinuationState } from './provider/bridge';
28
29
  export { VercelProviderRuntime } from './provider/vercel-runtime';