@agentlist/client 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +20 -18
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -1,39 +1,41 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{Command as
|
|
3
|
-
`)}function
|
|
2
|
+
import{Command as Ie}from"commander";import q from"chalk";import*as A from"fs";import*as ee from"os";import*as B from"path";import{AgentListClient as xe}from"@agentlist/api";var te=B.join(ee.homedir(),".agentlist"),P=B.join(te,"config.json");function oe(){return A.existsSync(P)}function W(){if(!A.existsSync(P))return null;try{let t=A.readFileSync(P,"utf-8");return JSON.parse(t)}catch{return null}}function ne(t){A.mkdirSync(te,{recursive:!0}),A.writeFileSync(P,`${JSON.stringify(t,null,2)}
|
|
3
|
+
`)}function ie(){return P}function h(t){let e=t??W();if(!e)throw new Error("Not configured. Run `agentlist init` first.");return new xe({baseUrl:e.base_url,apiKey:e.api_key})}import C from"chalk";var Ee={DISCOVERY:C.cyan,NEGOTIATING:C.yellow,ESCROWED:C.blue,IN_PROGRESS:C.magenta,DELIVERED:C.green,COMPLETED:C.greenBright,DISPUTED:C.red,CANCELLED:C.gray,FAILED:C.redBright,ACTIVE:C.green,INACTIVE:C.gray,SUSPENDED:C.red};function O(t){return(Ee[t]??C.white)(` ${t} `)}function re(t,e){return t.length>=e?t.slice(0,e):t+" ".repeat(e-t.length)}function I(t,e){let o=t.map((l,p)=>{let d=e.reduce((g,a)=>Math.max(g,(a[p]??"").length),0);return Math.max(l.length,d)}),n=t.map((l,p)=>C.bold(re(l,o[p]??0))).join(" "),i=o.map(l=>"\u2500".repeat(l)).join("\u2500\u2500"),r=e.map(l=>l.map((p,d)=>re(p,o[d]??0)).join(" ")).join(`
|
|
4
4
|
`);return`${n}
|
|
5
5
|
${i}
|
|
6
|
-
${r}`}function s(t,e){let o=e==null?C.dim("\u2014"):String(e);return`${C.dim(`${t}:`)} ${o}`}function m(t){console.error(C.red("Error:"),t)}function
|
|
6
|
+
${r}`}function s(t,e){let o=e==null?C.dim("\u2014"):String(e);return`${C.dim(`${t}:`)} ${o}`}function m(t){console.error(C.red("Error:"),t)}function E(t){console.log(),console.log(C.bold.underline(t)),console.log()}async function se(t){try{let e=h(),{agents:o,total:n}=await e.agents.list({skill:t.skill,min_rating:t.minRating});if(o.length===0){console.log(`
|
|
7
7
|
No agents found.
|
|
8
|
-
`);return}
|
|
8
|
+
`);return}E("Agent Directory"),console.log(I(["Username","Rating","Jobs","Skills","Endpoint"],o.map(i=>[i.username,`${i.rating.toFixed(1)}/5`,String(i.completed_jobs),i.skills.map(r=>r.name).join(", ")||"\u2014",i.has_endpoint?"yes":"no"]))),console.log(),console.log(q.dim(` ${n} agent(s) total`)),console.log()}catch(e){m(e instanceof Error?e.message:String(e)),process.exit(1)}}async function ae(t){try{let o=await h().agents.get(t);if(E(`Agent: ${o.username}`),console.log(s("Status",o.status)),console.log(s("Bio",o.bio)),console.log(s("Description",o.description)),console.log(s("Rating",`${o.rating}/5`)),console.log(s("Completed Jobs",o.completed_jobs)),console.log(s("Dispute Rate",`${(o.dispute_rate*100).toFixed(1)}%`)),console.log(s("Has Endpoint",o.has_endpoint)),console.log(s("Registered",o.registration?.registered_at??null)),console.log(s("Expires",o.registration?.expires_at??null)),o.skills.length>0){console.log(),console.log(q.bold(" Skills:"));for(let n of o.skills)console.log(` \u2022 ${n.name} (${n.uri}) \u2014 $${n.base_price}${n.max_price?`\u2013$${n.max_price}`:""} ${n.pricing_model}`),n.tags.length>0&&console.log(q.dim(` Tags: ${n.tags.join(", ")}`))}console.log()}catch(e){m(e instanceof Error?e.message:String(e)),process.exit(1)}}import*as R from"@clack/prompts";import K from"chalk";async function le(t){try{let e=h(),o=await e.jobs.get(t);if(o.status!=="DELIVERED"){console.log(K.yellow(`
|
|
9
9
|
Job status is ${o.status}, not DELIVERED. Cannot confirm.
|
|
10
|
-
`));return}o.output&&(console.log(
|
|
10
|
+
`));return}o.output&&(console.log(K.bold(`
|
|
11
11
|
Delivered output:`)),console.log(` ${JSON.stringify(o.output,null,2).split(`
|
|
12
12
|
`).join(`
|
|
13
|
-
`)}`),console.log());let n=await R.confirm({message:"Confirm this delivery? (releases escrow to worker)"});if(R.isCancel(n)||!n){R.log.info("Confirmation cancelled.");return}let i=R.spinner();i.start("Confirming delivery..."),await e.jobs.confirm(t),i.stop("Delivery confirmed"),console.log(
|
|
13
|
+
`)}`),console.log());let n=await R.confirm({message:"Confirm this delivery? (releases escrow to worker)"});if(R.isCancel(n)||!n){R.log.info("Confirmation cancelled.");return}let i=R.spinner();i.start("Confirming delivery..."),await e.jobs.confirm(t),i.stop("Delivery confirmed"),console.log(K.green(`
|
|
14
14
|
Escrow released to worker. Job completed.
|
|
15
|
-
`))}catch(e){m(e instanceof Error?e.message:String(e)),process.exit(1)}}import*as k from"@clack/prompts";import
|
|
15
|
+
`))}catch(e){m(e instanceof Error?e.message:String(e)),process.exit(1)}}import*as k from"@clack/prompts";import F from"chalk";async function ce(t){try{let e=h(),o=await e.jobs.get(t);if(o.status!=="DELIVERED"){console.log(F.yellow(`
|
|
16
16
|
Job status is ${o.status}, not DELIVERED. Cannot dispute.
|
|
17
|
-
`));return}o.output&&(console.log(
|
|
17
|
+
`));return}o.output&&(console.log(F.bold(`
|
|
18
18
|
Delivered output:`)),console.log(` ${JSON.stringify(o.output,null,2).split(`
|
|
19
19
|
`).join(`
|
|
20
|
-
`)}`),console.log()),k.intro("Raise Dispute");let n=await k.text({message:"Reason for dispute",placeholder:"Output does not match expected format",validate:g=>{if(!g.trim())return"Reason is required"}});if(k.isCancel(n))return;let i=await k.confirm({message:"Add evidence? (JSON)",initialValue:!1});if(k.isCancel(i))return;let r;if(i){let g=await k.text({message:"Evidence (JSON)",placeholder:'{"expected": "...", "received": "..."}',validate:a=>{try{JSON.parse(a)}catch{return"Must be valid JSON"}}});if(k.isCancel(g))return;r=JSON.parse(g)}let l=await k.confirm({message:"Submit this dispute?"});if(k.isCancel(l)||!l){k.log.info("Dispute cancelled.");return}let
|
|
21
|
-
Dispute ID: ${d.dispute_id}`)),console.log(
|
|
22
|
-
`))}catch(e){m(e instanceof Error?e.message:String(e)),process.exit(1)}}import{AgentListClient as
|
|
20
|
+
`)}`),console.log()),k.intro("Raise Dispute");let n=await k.text({message:"Reason for dispute",placeholder:"Output does not match expected format",validate:g=>{if(!g.trim())return"Reason is required"}});if(k.isCancel(n))return;let i=await k.confirm({message:"Add evidence? (JSON)",initialValue:!1});if(k.isCancel(i))return;let r;if(i){let g=await k.text({message:"Evidence (JSON)",placeholder:'{"expected": "...", "received": "..."}',validate:a=>{try{JSON.parse(a)}catch{return"Must be valid JSON"}}});if(k.isCancel(g))return;r=JSON.parse(g)}let l=await k.confirm({message:"Submit this dispute?"});if(k.isCancel(l)||!l){k.log.info("Dispute cancelled.");return}let p=k.spinner();p.start("Raising dispute...");let d=await e.jobs.dispute(t,{reason:n,evidence:r});p.stop("Dispute raised"),console.log(F.yellow(`
|
|
21
|
+
Dispute ID: ${d.dispute_id}`)),console.log(F.dim(` The platform will review and render a verdict.
|
|
22
|
+
`))}catch(e){m(e instanceof Error?e.message:String(e)),process.exit(1)}}import{AgentListClient as ve}from"@agentlist/api";import*as u from"@clack/prompts";async function ue(){if(u.intro("AgentList \u2014 Client Setup"),oe()){let a=await u.confirm({message:"Configuration already exists. Overwrite?",initialValue:!1});if(u.isCancel(a)||!a){u.outro("Setup cancelled.");return}}let t=await u.text({message:"Platform API base URL",placeholder:"http://localhost:4000/api/v1",defaultValue:"http://localhost:4000/api/v1",validate:a=>{if(!a.startsWith("http"))return"Must start with http:// or https://"}});if(u.isCancel(t))return;let e=await u.text({message:"Your API key",placeholder:"username.ak_...",validate:a=>{if(!a.includes(".ak_"))return"Invalid format. Expected: username.ak_..."}});if(u.isCancel(e))return;let o=u.spinner();o.start("Validating API key...");try{let x=await new ve({baseUrl:t,apiKey:e}).agents.me();o.stop(`Authenticated as ${x.username}`),u.log.info(`Username: ${x.username}`),u.log.info(`Rating: ${x.rating}/5`),u.log.info(`Jobs: ${x.completed_jobs}`),u.log.info(`Skills: ${x.skills_count}`)}catch(a){o.stop("Validation failed");let x=a instanceof Error?a.message:String(a);u.log.error(x),process.exit(1)}u.log.step("AI Provider Configuration");let n=await u.select({message:"AI provider",options:[{value:"openai",label:"OpenAI",hint:"gpt-4o, gpt-4o-mini, o3-mini"},{value:"anthropic",label:"Anthropic",hint:"claude-sonnet-4-20250514, claude-3.5-haiku"},{value:"google",label:"Google",hint:"gemini-2.0-flash, gemini-2.5-pro"}]});if(u.isCancel(n))return;let i={openai:"gpt-4o",anthropic:"claude-sonnet-4-20250514",google:"gemini-2.0-flash"},r=await u.text({message:"Model name",placeholder:i[n],defaultValue:i[n]});if(u.isCancel(r))return;let l=await u.text({message:`${n.charAt(0).toUpperCase()+n.slice(1)} API key`,placeholder:"sk-...",validate:a=>{if(!a.trim())return"API key is required"}});if(u.isCancel(l))return;let p,d=await u.confirm({message:"Use a custom base URL? (for Ollama, Azure, etc.)",initialValue:!1});if(u.isCancel(d))return;if(d){let a=await u.text({message:"Custom base URL",placeholder:"http://localhost:11434/v1",validate:x=>{if(!x.startsWith("http"))return"Must start with http:// or https://"}});if(u.isCancel(a))return;p=a}let g={provider:n,model:r,api_key:l,...p?{base_url:p}:{}};ne({api_key:e,base_url:t,ai:g}),u.note(`Config saved to ${ie()}`,"Setup complete"),u.outro('You\'re all set! Run `agentlist submit "your prompt"` to submit a job.')}import S from"chalk";async function ge(t){try{let o=await h().jobs.list({status:t.status,role:t.role}),n=Array.isArray(o)?o:[];if(n.length===0){console.log(`
|
|
23
23
|
No jobs found.
|
|
24
|
-
`);return}
|
|
24
|
+
`);return}E("Jobs"),console.log(I(["ID","Title","Status","Price","Created"],n.map(i=>[`${i.id.slice(0,8)}...`,(i.title??"").slice(0,30),i.status,i.agreed_price!==null&&i.agreed_price!==void 0?`$${i.agreed_price.toFixed(2)}`:"\u2014",i.created_at?new Date(i.created_at).toLocaleDateString():"\u2014"]))),console.log(),console.log(S.dim(` ${n.length} job(s) total`)),console.log()}catch(e){m(e instanceof Error?e.message:String(e)),process.exit(1)}}async function Y(t,e){try{let o=h();if(e.poll){await Ne(o,t);return}await De(o,t)}catch(o){m(o instanceof Error?o.message:String(o)),process.exit(1)}}function pe(t){return t==null?"\u2014":typeof t=="object"&&t!==null&&"username"in t?String(t.username??"\u2014"):String(t)}function $e(t){let e=t.skill;return e?.name?`${e.name} (${e.uri??t.skill_uri??""})`:e?.uri?e.uri:t.skill_uri?t.skill_uri:"\u2014"}async function De(t,e){let[o,n]=await Promise.all([t.jobs.get(e),t.jobs.getLogs(e).catch(()=>({logs:[]}))]),i=Array.isArray(n.logs)?n.logs:[];if(E("Job Details"),console.log(s("ID",o.id)),console.log(s("Title",o.title)),console.log(s("Status",o.status)),console.log(s("Skill",$e(o))),console.log(s("Client",pe(o.client))),console.log(s("Worker",pe(o.worker))),console.log(s("Price",o.agreed_price!==null&&o.agreed_price!==void 0?`$${o.agreed_price}`:null)),console.log(s("Currency",o.currency??null)),console.log(s("Chain",o.chain??null)),console.log(s("Created",o.created_at??null)),console.log(s("Started",o.started_at??null)),console.log(s("Completed",o.completed_at??null)),o.output&&(console.log(),console.log(S.bold("Output:")),console.log(JSON.stringify(o.output,null,2))),o.status==="DELIVERED"&&(console.log(),console.log(S.yellow(" This job is delivered and awaiting confirmation.")),console.log(S.dim(` Run: agentlist confirm ${o.id}`)),console.log(S.dim(` Or: agentlist dispute ${o.id}`))),i.length>0){console.log(),E("Timeline");for(let r of i){let l=r.eventType??r.event_type??"\u2014",p=r.createdAt??r.created_at??"",d=p?new Date(p).toLocaleString():"\u2014",g=r.actor??"\u2014",a=r.payload,x=a&&Object.keys(a).length>0;console.log(S.dim(` ${d}`)),console.log(` ${S.bold(l)} ${S.dim(`by ${g}`)}`),x&&console.log(S.dim(" ")+JSON.stringify(a).replace(/\n/g," ")),console.log()}}console.log()}async function Ne(t,e){let o=["COMPLETED","DISPUTED","CANCELLED","FAILED"];console.log(S.dim(`
|
|
25
25
|
Polling job ${e.slice(0,8)}... (Ctrl+C to stop)
|
|
26
26
|
`));let i="";for(;;){let r=await t.jobs.get(e);if(r.status!==i){let l=new Date().toLocaleTimeString();console.log(` ${S.dim(l)} ${O(r.status)} ${r.title}`),i=r.status,r.agreed_price!==null&&r.agreed_price!==void 0&&console.log(S.dim(` Price: $${r.agreed_price}`)),r.worker&&console.log(S.dim(` Worker: ${r.worker}`))}if(o.includes(r.status)){console.log(),r.status==="COMPLETED"&&r.output?(console.log(S.bold(" Result:")),console.log(` ${JSON.stringify(r.output,null,2).split(`
|
|
27
27
|
`).join(`
|
|
28
|
-
`)}`)):r.status==="DELIVERED"&&(console.log(S.yellow(" Delivered \u2014 awaiting your confirmation.")),console.log(S.dim(` Run: agentlist confirm ${r.id}`))),console.log();break}await new Promise(l=>setTimeout(l,3e3))}}import*as
|
|
28
|
+
`)}`)):r.status==="DELIVERED"&&(console.log(S.yellow(" Delivered \u2014 awaiting your confirmation.")),console.log(S.dim(` Run: agentlist confirm ${r.id}`))),console.log();break}await new Promise(l=>setTimeout(l,3e3))}}import*as y from"@clack/prompts";async function de(){try{let e=await h().agents.me();if(E("Agent Profile"),console.log(s("Username",e.username)),console.log(s("Bio",e.bio)),console.log(s("Description",e.description)),console.log(s("Endpoint",e.endpoint)),console.log(s("Wallet",e.wallet_address)),console.log(s("Currency",e.default_currency)),console.log(s("Chain",e.default_chain)),console.log(s("Rating",`${e.rating}/5`)),console.log(s("Completed Jobs",e.completed_jobs)),console.log(s("Dispute Rate",`${(e.dispute_rate*100).toFixed(1)}%`)),console.log(s("Strategy",e.has_strategy?"Configured":"Not set")),console.log(s("Skills",e.skills_count)),e.skills.length>0){console.log(),console.log("Skills:");for(let o of e.skills)console.log(` \u2022 ${o.name} (${o.uri}) \u2014 $${o.base_price} ${o.pricing_model}`)}console.log()}catch(t){m(t instanceof Error?t.message:String(t)),process.exit(1)}}async function me(){try{let t=h(),e=await t.agents.me();y.intro("Edit Profile");let o=await y.text({message:"Bio",defaultValue:e.bio??"",placeholder:"Short description of your agent"});if(y.isCancel(o))return;let n=await y.text({message:"Description",defaultValue:e.description??"",placeholder:"Detailed description of capabilities"});if(y.isCancel(n))return;let i=await y.text({message:"A2A Endpoint URL (leave empty to skip)",defaultValue:e.endpoint??"",placeholder:"https://my-agent.example.com/a2a"});if(y.isCancel(i))return;let r=await y.text({message:"Wallet address",defaultValue:e.wallet_address??"",placeholder:"7xKX..."});if(y.isCancel(r))return;let l=await y.select({message:"Default currency",initialValue:e.default_currency??"USDC",options:[{value:"USDC",label:"USDC"},{value:"USDT",label:"USDT"},{value:"SOL",label:"SOL"},{value:"ETH",label:"ETH"}]});if(y.isCancel(l))return;let p=await y.select({message:"Default chain",initialValue:e.default_chain??"solana",options:[{value:"solana",label:"Solana"},{value:"ethereum",label:"Ethereum"},{value:"base",label:"Base"},{value:"arbitrum",label:"Arbitrum"},{value:"bsc",label:"BSC"}]});if(y.isCancel(p))return;let d=y.spinner();d.start("Updating profile..."),await t.agents.updateMe({bio:o||void 0,description:n||void 0,endpoint:i||void 0,wallet_address:r||void 0,default_currency:l,default_chain:p}),d.stop("Profile updated"),y.outro("Done!")}catch(t){m(t instanceof Error?t.message:String(t)),process.exit(1)}}import Ae from"chalk";async function fe(t){try{let e=h(),{skills:o,total:n}=await e.skills.list({category:t.category});if(o.length===0){console.log(`
|
|
29
29
|
No skills found.
|
|
30
|
-
`);return}
|
|
31
|
-
`))console.log(T.dim(` ${n}`))},warn(...t){console.warn(T.yellow("\u26A0"),...t)}};async function
|
|
30
|
+
`);return}E("Skill Taxonomy"),console.log(I(["URI","Name","Category","Min Price"],o.map(i=>[i.uri,i.name,i.category??"\u2014",`$${i.min_price.toFixed(2)}`]))),console.log(),console.log(Ae.dim(` ${n} skill(s) total`)),console.log()}catch(e){m(e instanceof Error?e.message:String(e)),process.exit(1)}}import*as f from"@clack/prompts";async function be(){try{let e=await h().agents.getStrategy();E("Autonomous Strategy"),console.log(s("Max Budget/Job",`$${e.max_budget_per_job}`)),console.log(s("Max Budget/Day",e.max_budget_daily!==null?`$${e.max_budget_daily}`:null)),console.log(s("Min Worker Rating",e.min_worker_rating!==null?`${e.min_worker_rating}/5`:null)),console.log(s("Prefer Reputation",e.prefer_reputation)),console.log(s("Negotiation Style",e.negotiation_style)),console.log(s("Max Rounds",e.max_rounds)),console.log(s("Anchor Multiplier",e.anchor_multiplier)),console.log(s("Concession Rate",e.concession_rate)),console.log(s("Auto Accept Ratio",e.auto_accept_ratio)),console.log(s("Auto Confirm",e.auto_confirm)),console.log(s("Quality Threshold",e.quality_threshold)),console.log(s("Auto Dispute",e.auto_dispute)),console.log()}catch(t){let e=t instanceof Error?t.message:String(t);e.includes("No strategy")?console.log("\n No strategy configured. Run `agentlist strategy set` to configure.\n"):(m(e),process.exit(1))}}async function ye(){try{let t=h();f.intro("Configure Autonomous Strategy");let e=await f.text({message:"Max budget per job (USD)",placeholder:"50",defaultValue:"50",validate:g=>{let a=Number(g);if(Number.isNaN(a)||a<.01)return"Must be a number >= 0.01"}});if(f.isCancel(e))return;let o=await f.text({message:"Max daily budget (USD, leave empty for no limit)",placeholder:"200",defaultValue:"200"});if(f.isCancel(o))return;let n=await f.text({message:"Min worker rating (0-5)",placeholder:"3.5",defaultValue:"3.5",validate:g=>{let a=Number(g);if(Number.isNaN(a)||a<0||a>5)return"Must be 0-5"}});if(f.isCancel(n))return;let i=await f.select({message:"Negotiation style",initialValue:"FAIR",options:[{value:"AGGRESSIVE",label:"Aggressive \u2014 push for lowest price, slow concessions"},{value:"FAIR",label:"Fair \u2014 balanced approach"},{value:"GENEROUS",label:"Generous \u2014 accept quickly, higher offers"}]});if(f.isCancel(i))return;let r=await f.text({message:"Max negotiation rounds (1-10)",placeholder:"5",defaultValue:"5",validate:g=>{let a=Number(g);if(Number.isNaN(a)||a<1||a>10)return"Must be 1-10"}});if(f.isCancel(r))return;let l=await f.confirm({message:"Auto-confirm deliveries?",initialValue:!1});if(f.isCancel(l))return;let p=await f.confirm({message:"Auto-dispute on SLA breach?",initialValue:!0});if(f.isCancel(p))return;let d=f.spinner();d.start("Saving strategy..."),await t.agents.setStrategy({max_budget_per_job:Number(e),max_budget_daily:o?Number(o):void 0,min_worker_rating:Number(n),prefer_reputation:!0,negotiation_style:i,max_rounds:Number(r),anchor_multiplier:i==="AGGRESSIVE"?.6:i==="GENEROUS"?.95:.8,concession_rate:i==="AGGRESSIVE"?.2:i==="GENEROUS"?.6:.4,auto_accept_ratio:1.2,auto_confirm:l,quality_threshold:.7,auto_dispute:p}),d.stop("Strategy saved"),f.outro("Your agent will now negotiate autonomously based on these settings.")}catch(t){m(t instanceof Error?t.message:String(t)),process.exit(1)}}import*as $ from"@clack/prompts";import w from"chalk";import{generateText as Re}from"ai";import T from"chalk";var H=!1;function he(t){H=t}var b={info(...t){console.log(T.blue("\u2139"),...t)},debug(...t){H&&console.log(T.dim(` [debug] ${t.map(String).join(" ")}`))},trace(t,e){if(!H)return;console.log(T.dim(` [trace] ${t}:`));let o=typeof e=="string"?e:JSON.stringify(e,null,2);for(let n of o.split(`
|
|
31
|
+
`))console.log(T.dim(` ${n}`))},warn(...t){console.warn(T.yellow("\u26A0"),...t)}};async function Le(t){switch(b.debug(`Creating model: ${t.provider} / ${t.model}`),t.provider){case"openai":{let{createOpenAI:e}=await import("@ai-sdk/openai");return e({apiKey:t.api_key,...t.base_url?{baseURL:t.base_url}:{}})(t.model)}case"anthropic":{let{createAnthropic:e}=await import("@ai-sdk/anthropic");return e({apiKey:t.api_key,...t.base_url?{baseURL:t.base_url}:{}})(t.model)}case"google":{let{createGoogleGenerativeAI:e}=await import("@ai-sdk/google");return e({apiKey:t.api_key,...t.base_url?{baseURL:t.base_url}:{}})(t.model)}default:throw new Error(`Unsupported provider: ${t.provider}`)}}async function we(t,e,o){let n=await Le(o),r=["You are a job planning assistant for the AgentList platform.","Given a user request and the list of available skills, you must:","1. Select the most appropriate skill for the request.","2. Generate a concise title for the job.","3. Craft a structured input object that matches the selected skill's input_schema.","","Extract all relevant information from the user prompt to fill the input fields.","If the prompt does not provide enough information for a required field, use a reasonable default or describe what is needed.","","You MUST respond with a valid JSON object containing exactly these fields:","- skill_uri: string \u2014 the URI of the selected skill","- title: string \u2014 a concise title for the job","- input: object \u2014 structured input matching the skill's input_schema","","Respond ONLY with the JSON object. No markdown, no explanation.","","Available skills:",e.map(a=>`- **${a.name}** (uri: \`${a.uri}\`, category: ${a.category??"general"})
|
|
32
32
|
Description: ${a.description??"No description"}
|
|
33
33
|
Input schema: ${JSON.stringify(a.input_schema)}`).join(`
|
|
34
34
|
|
|
35
35
|
`)].join(`
|
|
36
|
-
`);b.debug("System prompt length:",r.length,"chars"),b.debug("User prompt:",t);let l=await
|
|
37
|
-
`));let
|
|
36
|
+
`);b.debug("System prompt length:",r.length,"chars"),b.debug("User prompt:",t);let l=await Re({model:n,system:r,prompt:t});b.debug("LLM response:",l.text),b.debug("Usage:",JSON.stringify(l.usage));let p=l.text.trim(),d=p.match(/\{[\s\S]*\}/);if(!d)throw new Error("AI did not return valid JSON. Try rephrasing your request.");let g;try{g=JSON.parse(d[0])}catch{throw new Error(`AI returned invalid JSON: ${p.slice(0,200)}`)}if(!g.skill_uri||!g.title||!g.input)throw new Error(`AI response missing required fields. Got: ${JSON.stringify(Object.keys(g))}`);return g}function z(t,e,o,n={}){t.jobs.logEvent(e,o,n).catch(()=>{})}async function _e(t,e){try{let o=W();o||(m("Not configured. Run `agentlist init` first."),process.exit(1)),b.debug("Config loaded from","~/.agentlist/config.json"),b.debug("Platform URL:",o.base_url),b.debug("AI provider:",o.ai?.provider??"not configured");let n=h(o),i=Date.now(),r=[],l=e.skill,p=e.title,d={};if(l&&p&&e.input)d=JSON.parse(e.input),b.debug("Manual mode \u2014 skill:",l,"title:",p),r.push({eventType:"client.prompt_received",payload:{mode:"manual",skill_uri:l,title:p}});else if(t){o.ai||(m("AI not configured. Run `agentlist init` to set up your AI provider."),process.exit(1)),r.push({eventType:"client.prompt_received",payload:{mode:"ai",prompt:t}});let c=$.spinner();c.start("Loading skills...");let{skills:v}=await n.skills.list();b.debug("Fetched",v.length,"skills from platform");let L=await Promise.all(v.map(async _=>{try{let j=await n.skills.get(_.uri);return b.debug("Loaded schema for",_.uri),{uri:_.uri,name:_.name,description:_.description,category:_.category,input_schema:j.input_schema}}catch(j){return b.debug("Failed to load schema for",_.uri,"\u2014",j instanceof Error?j.message:String(j)),{uri:_.uri,name:_.name,description:_.description,category:_.category,input_schema:{}}}}));c.stop(`${L.length} skills loaded`),r.push({eventType:"client.skills_fetched",payload:{count:L.length}}),b.trace("Skills sent to LLM",L.map(_=>({uri:_.uri,name:_.name})));let U=$.spinner();U.start("Planning job..."),r.push({eventType:"client.llm_planning",payload:{provider:o.ai.provider,model:o.ai.model}});let M=await we(t,L,o.ai);U.stop("Job planned"),b.trace("Job plan",M),l=M.skill_uri,p=M.title,d=M.input,r.push({eventType:"client.skill_selected",payload:{skill_uri:l,title:p}});let Se=v.find(_=>_.uri===l)?.name??l,G=e.maxPrice!=null?Number.parseFloat(e.maxPrice):void 0;if(console.log(),console.log(` ${w.bold("Skill:")} ${Se} ${w.dim(`(${l})`)}`),console.log(` ${w.bold("Title:")} ${p}`),G!=null&&!Number.isNaN(G)&&console.log(` ${w.bold("Max price:")} $${G} (client will negotiate up to this)`),console.log(` ${w.bold("Input:")} ${w.dim(JSON.stringify(d,null,2))}`),console.log(),!e.noConfirm){let _=await $.confirm({message:"Submit this job?",initialValue:!0});if($.isCancel(_)||!_){$.outro("Cancelled.");return}}}else m("Provide a prompt or use --skill, --title, --input flags."),console.log(w.dim(' Example: agentlist submit "Search for the latest AI news"')),process.exit(1);(!l||!p)&&(m("Could not determine skill or title."),process.exit(1));let g=!1;try{let c=await n.agents.getStrategy();b.debug("Strategy exists:",JSON.stringify(c))}catch{b.debug("No strategy found \u2014 creating default"),g=!0;let c=$.spinner();c.start("Setting up default strategy..."),await n.agents.setStrategy({max_budget_per_job:100,max_budget_daily:500,min_worker_rating:0,prefer_reputation:!1,negotiation_style:"GENEROUS",max_rounds:5,anchor_multiplier:.95,concession_rate:.6,auto_accept_ratio:1.5,auto_confirm:!0,quality_threshold:.5,auto_dispute:!0}),c.stop("Default strategy configured")}r.push({eventType:"client.strategy_checked",payload:{existed:!g,created:g}});let a=$.spinner();a.start("Creating job...");let x={skill_uri:l,title:p,input:d},J=e.maxPrice!=null?Number.parseFloat(e.maxPrice):void 0;J!=null&&!Number.isNaN(J)&&J>0&&(x.max_price=J),b.debug("Creating job:",JSON.stringify(x));let D=await n.jobs.create(x);a.stop("Job created"),b.debug("Job ID:",D.id),b.debug("Initial status:",D.status);for(let c of r)z(n,D.id,c.eventType,c.payload);z(n,D.id,"client.job_submitted",{skill_uri:l,title:p}),console.log(),console.log(` ${w.bold("Job ID:")} ${D.id}`),console.log(` ${w.bold("Status:")} ${O(D.status)}`);let Q=D.max_price;Q!=null&&console.log(` ${w.bold("Max price:")} $${Q}`),console.log();let X=["COMPLETED","DISPUTED","CANCELLED","FAILED","DELIVERED"],Ce=3e3,ke=10;console.log(w.dim(` Waiting for result... (Ctrl+C to stop)
|
|
37
|
+
`));let Z=D.status,V=0;for(;;){let c=await n.jobs.get(D.id);if(V++,b.debug(`Poll #${V}: status=${c.status}`),c.status!==Z){let v=new Date().toLocaleTimeString();if(console.log(` ${w.dim(v)} ${O(c.status)} ${c.title}`),Z=c.status,c.agreed_price!==null&&c.agreed_price!==void 0&&console.log(w.dim(` Price: $${c.agreed_price}`)),c.worker){let L=typeof c.worker=="object"&&c.worker!==null&&"username"in c.worker?c.worker.username:String(c.worker);console.log(w.dim(` Worker: ${L}`))}}else if(V>1&&V%ke===0&&!X.includes(c.status)){let v=new Date().toLocaleTimeString();console.log(w.dim(` ${v} \u2026 still ${c.status.toLowerCase()}, waiting for result`))}if(X.includes(c.status)){let v=Date.now()-i;if(z(n,D.id,"client.result_received",{status:c.status,elapsed_ms:v}),console.log(),c.status==="COMPLETED"&&c.output)console.log(w.bold(" Result:")),console.log(` ${JSON.stringify(c.output,null,2).split(`
|
|
38
38
|
`).join(`
|
|
39
|
-
`)}`);else if(
|
|
39
|
+
`)}`);else if(c.status==="CANCELLED"){let U=c.output?.reason??"No reason provided";console.log(w.red(` Cancelled: ${U}`))}else c.status==="DELIVERED"&&(console.log(w.yellow(" Delivered \u2014 awaiting confirmation.")),c.output&&(console.log(w.bold(" Output preview:")),console.log(` ${JSON.stringify(c.output,null,2).split(`
|
|
40
|
+
`).join(`
|
|
41
|
+
`)}`)),console.log(w.dim(` Run: agentlist confirm ${c.id}`)));console.log();break}await new Promise(v=>setTimeout(v,Ce))}}catch(o){m(o instanceof Error?o.message:String(o)),b.trace("Full error",o instanceof Error?o.stack??o.message:String(o)),process.exit(1)}}var N=new Ie().name("agentlist").description("AgentList \u2014 Client Agent CLI").version("0.1.0").option("-v, --verbose","Enable verbose logging").hook("preAction",t=>{t.opts().verbose&&he(!0)});N.command("init").description("Setup: configure API key and platform URL").action(ue);var je=N.command("profile").description("View your agent profile").action(de);je.command("edit").description("Edit your profile interactively").action(me);var Pe=N.command("strategy").description("View your autonomous strategy").action(be);Pe.command("set").description("Configure your strategy interactively").action(ye);N.command("submit [prompt...]").description("Submit a job from a natural language prompt").option("-s, --skill <uri>","Skill URI (manual mode)").option("-t, --title <title>","Job title (manual mode)").option("-i, --input <json>","Job input JSON (manual mode)").option("-m, --max-price <number>","Max price (USD) for this job; client negotiates up to this ceiling").option("-y, --no-confirm","Skip confirmation prompt").action((t,e)=>_e(t.length>0?t.join(" "):void 0,e));var Oe=N.command("jobs [jobId]").description("List jobs, or view a specific job by ID").option("--status <status>","Filter by status").option("--role <role>","Filter by role (client or worker)").option("--poll","Poll until completed (requires job ID)").action((t,e)=>{t?Y(t,e):ge(e)});Oe.command("view <jobId>").description("View job details").option("--poll","Poll until completed").action((t,e)=>Y(t,e));N.command("confirm <jobId>").description("Confirm a delivery").action(le);N.command("dispute <jobId>").description("Dispute a delivery").action(ce);N.command("skills").description("Browse available skills").option("-c, --category <category>","Filter by category").action(fe);var Te=N.command("agents").description("Browse the agent directory").option("-s, --skill <uri>","Filter by skill").option("-r, --min-rating <rating>","Minimum rating").action(t=>se(t));Te.command("view <username>").description("View an agent's profile").action(ae);N.parse();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentlist/client",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/cli.js",
|
|
6
6
|
"types": "./dist/cli.d.ts",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"typecheck": "tsc --noEmit"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@agentlist/api": "
|
|
21
|
+
"@agentlist/api": "0.1.0",
|
|
22
22
|
"@ai-sdk/anthropic": "3.0.43",
|
|
23
23
|
"@ai-sdk/google": "3.0.29",
|
|
24
24
|
"@ai-sdk/openai": "3.0.28",
|