langtrain 0.2.4 → 0.2.5
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 +8 -8
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +8 -8
- package/dist/cli.mjs.map +1 -1
- package/package.json +1 -1
- package/src/cli/auth.ts +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {d as d$1,k,f as f$1,h,a,m,g,i,r,q as q$1}from'./chunk-A7PMJDMV.mjs';import {Command}from'commander';import {select,isCancel,confirm,text,cancel,note,password}from'@clack/prompts';import {dim,white,magenta,blue,bold,cyan,gray,yellow,green,red,black,bgMagenta}from'kleur/colors';import E from'gradient-string';import
|
|
2
|
+
import {d as d$1,k,f as f$1,h,a,m,g,i,r,q as q$1}from'./chunk-A7PMJDMV.mjs';import {Command}from'commander';import {select,isCancel,confirm,text,cancel,note,password}from'@clack/prompts';import {dim,white,magenta,blue,bold,cyan,gray,yellow,green,red,black,bgMagenta}from'kleur/colors';import E from'gradient-string';import ze from'cli-table3';import J from'fs';import ae from'path';import Ue from'os';import ke from'axios';import {exec}from'child_process';import {promisify}from'util';function q(e){return new ze({head:e.map(o=>A.magenta(A.bold(o))),chars:{top:"\u2500","top-mid":"\u252C","top-left":"\u250C","top-right":"\u2510",bottom:"\u2500","bottom-mid":"\u2534","bottom-left":"\u2514","bottom-right":"\u2518",left:"\u2502","left-mid":"\u251C",mid:"\u2500","mid-mid":"\u253C",right:"\u2502","right-mid":"\u2524",middle:"\u2502"},style:{"padding-left":1,"padding-right":1,head:[],border:["gray"]}})}function H(e){console.clear(),console.log(E(["#A855F7","#EC4899","#3B82F6"])(`
|
|
3
3
|
\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2557
|
|
4
4
|
\u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551
|
|
5
5
|
\u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551
|
|
@@ -7,7 +7,7 @@ import {d as d$1,k,f as f$1,h,a,m,g,i,r,q as q$1}from'./chunk-A7PMJDMV.mjs';impo
|
|
|
7
7
|
\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551
|
|
8
8
|
\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D
|
|
9
9
|
`)),console.log(`${bgMagenta(black(` Langtrain SDK v${e} `))}
|
|
10
|
-
`);}function $(e){console.log(magenta(`\u25C6 ${e}`));}function K(e){console.log(gray(`\u2514 ${e}`));}function d(){return {start:e=>process.stdout.write(`${magenta("\u25CF")} ${e}\r`),stop:e=>{console.log(e?`${green("\u2714")} ${e}`:"");},message:e=>process.stdout.write(`${magenta("\u25CF")} ${e}\r`)}}function R(e){console.log(green(`\u2714 ${e}`));}function ve(e){console.log(yellow(`\u26A0 Warning: ${e}`));}function $e(e){console.log(blue(`\u2139 ${e}`));}var A={bgMagenta:bgMagenta,black:black,red:red,green:green,yellow:yellow,gray:gray,cyan:cyan,bold:bold,dim:dim,blue:blue,magenta:magenta,white:white};var X=ae.join(Ue.homedir(),".langtrain"),ee=ae.join(X,"config.json");function f(){if(!J.existsSync(ee))return {};try{return JSON.parse(J.readFileSync(ee,"utf-8"))}catch{return {}}}function Z(e){J.existsSync(X)||J.mkdirSync(X,{recursive:true}),J.writeFileSync(ee,JSON.stringify(e,null,2));}var Ze=promisify(exec);function Se(){return `${(f().baseUrl||"https://api.langtrain.
|
|
10
|
+
`);}function $(e){console.log(magenta(`\u25C6 ${e}`));}function K(e){console.log(gray(`\u2514 ${e}`));}function d(){return {start:e=>process.stdout.write(`${magenta("\u25CF")} ${e}\r`),stop:e=>{console.log(e?`${green("\u2714")} ${e}`:"");},message:e=>process.stdout.write(`${magenta("\u25CF")} ${e}\r`)}}function R(e){console.log(green(`\u2714 ${e}`));}function ve(e){console.log(yellow(`\u26A0 Warning: ${e}`));}function $e(e){console.log(blue(`\u2139 ${e}`));}var A={bgMagenta:bgMagenta,black:black,red:red,green:green,yellow:yellow,gray:gray,cyan:cyan,bold:bold,dim:dim,blue:blue,magenta:magenta,white:white};var X=ae.join(Ue.homedir(),".langtrain"),ee=ae.join(X,"config.json");function f(){if(!J.existsSync(ee))return {};try{return JSON.parse(J.readFileSync(ee,"utf-8"))}catch{return {}}}function Z(e){J.existsSync(X)||J.mkdirSync(X,{recursive:true}),J.writeFileSync(ee,JSON.stringify(e,null,2));}var Ze=promisify(exec);function Se(){return `${(f().baseUrl||"https://api.langtrain.xyz").replace(/\/$/,"")}/api/v1`}async function Qe(e){try{let o=process.platform==="win32"?`start ${e}`:process.platform==="darwin"?`open "${e}"`:`xdg-open "${e}"`;await Ze(o);}catch{}}function te(){return !!f().apiKey}async function O(){let e=d();e.start("Connecting to Langtrain...");try{let{data:o}=await ke.post(`${Se()}/auth/device/code`),{device_code:a,user_code:t,verification_url:n,expires_in:i,interval:s}=o;e.stop(green("Connected.")),console.log(`
|
|
11
11
|
`+bgMagenta(black(" AUTHENTICATION "))+`
|
|
12
12
|
`),console.log(` To log in, please open your browser to:
|
|
13
13
|
${cyan(n+"?code="+t)}
|
|
@@ -18,14 +18,14 @@ ${bold(t)}`,"Verify in Browser"),console.log(gray(" Opening browser automatical
|
|
|
18
18
|
`));let o=await password({message:"Enter your Langtrain API Key:",validate(t){if(!t||t.length===0)return "API Key is required";if(t.length<10)return "Invalid key format"}});isCancel(o)&&(cancel("Operation cancelled"),process.exit(0));let a=d();a.start("Verifying API Key...");try{let n=await new h({apiKey:o}).getStatus(),i=n.plan==="pro"?bgMagenta(black(" PRO ")):n.plan==="enterprise"?bgMagenta(black(" ENTERPRISE ")):" FREE ";a.stop(green(`Authenticated ${i}`));let s=f();Z({...s,apiKey:o}),console.log(green(` \u2714 Credentials saved to ~/.langtrain/config.json
|
|
19
19
|
`));return}catch{a.stop(red("Invalid API Key. Please try again."));}}}async function ne(){let e=f();delete e.apiKey,Z(e),console.log(green(`
|
|
20
20
|
\u2714 Logged out. Credentials cleared.
|
|
21
|
-
`));}async function
|
|
21
|
+
`));}async function z(e){let o=new h({apiKey:e}),a=d();a.start("Checking subscription...");try{let t=await o.getStatus(),n=t.plan==="pro"?bgMagenta(black(" PRO ")):t.plan==="enterprise"?bgMagenta(black(" ENTERPRISE ")):bold(" FREE ");return a.stop(green(`Plan: ${n}`)),t.is_active===!1&&console.log(yellow(` \u26A0 Subscription inactive. Some features may be limited.
|
|
22
22
|
`)),t}catch(t){return a.stop(red("Failed to verify subscription.")),t.response&&t.response.status===401&&console.log(red(" API Key expired. Please login again.")),null}}function xe(e,o,a){if(!a)return [{value:"login",label:"\u2192 Login",hint:"Authenticate with your API key"},{value:"docs",label:" Documentation",hint:"https://docs.langtrain.ai"},{value:"exit",label:" Exit"}];let t=o?.plan==="pro"?"PRO":o?.plan==="enterprise"?"ENTERPRISE":"FREE";switch(e){case "main":return [{value:"nav-agents",label:" Agents",hint:"Manage & deploy AI agents"},{value:"nav-text",label:" Langtune",hint:"Text fine-tuning & generation"},{value:"nav-vision",label:" Langvision",hint:"Vision fine-tuning & analysis"},{value:"nav-guard",label:" Guardrails",hint:"Data quality & safety rules"},{value:"init",label:" Init Project",hint:"Scaffold new Langtrain app"},{value:"deploy",label:" Deploy",hint:"Push to Langtrain Cloud"},{value:"dev",label:" Dev Server",hint:"Local watch mode"},{value:"env",label:" Secrets",hint:"Manage environment variables"},{value:"logs",label:" Logs",hint:"Stream agent logs"},{value:"tokens",label:" Token Usage",hint:"View consumption this period"},{value:"telemetry",label:" Telemetry",hint:"Session stats & API health"},{value:"doctor",label:" Doctor",hint:"Check environment health"},{value:"nav-settings",label:" Settings",hint:`Plan: ${t}`},{value:"exit",label:" Exit"}];case "agents":return [{value:"agent-list",label:"List & Run Agents",hint:"Chat with active agents"},{value:"agent-create",label:"Create New Agent",hint:"Deploy a new agent"},{value:"agent-delete",label:"Delete Agent",hint:"Remove an agent"},{value:"back",label:"\u2190 Back"}];case "text":return [{value:"tune-finetune",label:"Fine-tune Text Model",hint:"Create custom LLM"},{value:"tune-list",label:"List Jobs",hint:"Check training status"},{value:"tune-generate",label:"Generate Text",hint:"Test your models"},{value:"data-upload",label:"Upload Dataset",hint:"Upload JSONL for training"},{value:"back",label:"\u2190 Back"}];case "guard":return [{value:"guard-list",label:"List Guardrails",hint:"View active rules"},{value:"guard-create",label:"Create Guardrail",hint:"Define new rules"},{value:"data-refine",label:"Refine Dataset",hint:"Apply guardrail to data"},{value:"back",label:"\u2190 Back"}];case "vision":return [{value:"vision-finetune",label:"Fine-tune Vision Model",hint:"Create custom VLM"},{value:"vision-generate",label:"Generate Vision Response",hint:"Test vision models"},{value:"back",label:"\u2190 Back"}];case "settings":return [{value:"status",label:`Subscription (${t})`,hint:"View plan details"},{value:"tokens",label:"Token Usage",hint:"View consumption"},{value:"telemetry",label:"Telemetry",hint:"Session & API health"},{value:"login",label:"Update API Key",hint:"Change credentials"},{value:"logout",label:"Logout",hint:"Clear stored credentials"},{value:"back",label:"\u2190 Back"}];default:return []}}async function Le(){let e=f();if(!e.apiKey){$(red('Not logged in. Run "login" first.'));return}let o=new h({apiKey:e.apiKey}),a=d();a.start("Fetching subscription status...");try{let t=await o.getStatus();a.stop(green("Subscription Status:")),console.log(gray("Plan: ")+(t.plan==="pro"?bgMagenta(" PRO "):t.plan.toUpperCase())),console.log(gray("Active: ")+(t.is_active?green("Yes"):red("No"))),t.expires_at&&console.log(gray("Expires: ")+new Date(t.expires_at).toLocaleDateString()),console.log(gray(`
|
|
23
|
-
Limits:`)),console.log(` Models: ${t.limits.max_models===-1?"Unlimited":t.limits.max_models}`),console.log(` Training Jobs: ${t.limits.max_training_jobs}`);}catch(t){a.stop(red("Failed to fetch status.")),console.error(t.message);}}async function Ae(e,o){let a="",t=d();t.start("Fetching available text models...");try{let c=await o.list("text");t.stop(`Found ${c.length} text models`),c.length>0&&(a=await select({message:"Select base model:",options:c.map(l=>({value:l.id,label:l.id,hint:l.owned_by}))}));}catch{t.stop(yellow("Failed to fetch models. Using manual input.")),a=await text({message:"Enter base model (e.g., gpt-3.5-turbo):",placeholder:"gpt-3.5-turbo",validate(l){if(!l||l.length===0)return "Value is required!"}});}isCancel(a)&&(cancel("Operation cancelled."),process.exit(0));let n=await text({message:"Enter path to training file:",placeholder:"./data.jsonl",validate(c){if(!c||c.length===0)return "Value is required!"}});isCancel(n)&&cancel("Operation cancelled.");let i=await text({message:"Num Epochs:",placeholder:"3",initialValue:"3"});isCancel(i)&&cancel("Operation cancelled.");let s=await select({message:"Track this job on Langtrain Cloud?",options:[{value:"yes",label:"Yes",hint:"Upload dataset and log job"},{value:"no",label:"No",hint:"Local only"}]});if(isCancel(s)&&cancel("Operation cancelled."),s==="yes"){let c=d();c.start("Connecting to Cloud...");try{let l=f();if(!l.apiKey)throw new Error('API Key required. Run "login" first.');if(!(await new h({apiKey:l.apiKey}).getStatus()).features.includes("cloud_finetuning")){c.stop(red('Feature "cloud_finetuning" is not available on your plan.'));let M=await confirm({message:"Upgrade to Pro for cloud tracking?"});M&&!isCancel(M)&&console.log(bgMagenta(black(" Visit https://langtrain.ai/dashboard/billing to upgrade. ")));return}let k=new f$1({apiKey:l.apiKey}),_=new g({apiKey:l.apiKey});c.message("Uploading dataset...");let T=await k.upload(n);c.message("Creating Job...");let G=await _.createJob({name:`cli-sft-${Date.now()}`,base_model:a,dataset_id:T.id,task:"text",hyperparameters:{n_epochs:parseInt(i)}});c.stop(green(`Job tracked: ${G.id}`));}catch(l){c.stop(red(`Tracking failed: ${l.message}`));let h=await confirm({message:"Continue with local training anyway?"});if(!h||isCancel(h))return}}let r=d();r.start("Starting local fine-tuning...");try{let c={model:a,trainFile:n,preset:"default",epochs:parseInt(i),batchSize:1,learningRate:2e-5,loraRank:16,outputDir:"./output"};await e.finetune(c),r.stop(green("Fine-tuning job started successfully!"));}catch(c){throw r.stop(red("Failed to start job.")),c}}async function Fe(e){let o=await text({message:"Enter model path:",placeholder:"./output/model",initialValue:"./output/model"});isCancel(o)&&cancel("Operation cancelled");let a=await text({message:"Enter prompt:",placeholder:"Hello world"});isCancel(a)&&cancel("Operation cancelled");let t=d();t.start("Connecting to Langtrain Inference API...");try{let n=await e.generate(o,{prompt:a});t.stop("Generation complete"),$("Response:"),console.log(E.pastel(n));}catch(n){throw t.stop(red("Generation failed.")),n}}async function Ie(e){let o=d();o.start("Fetching fine-tuning jobs...");let t=f().workspace_id;if(!(!t&&(o.stop(yellow("Workspace ID required to list jobs.")),t=await text({message:"Enter Workspace ID:"}),isCancel(t))))try{let n=await e.listJobs(t);if(o.stop(`Found ${n.data.length} jobs`),n.data.length===0){console.log(yellow("No jobs found."));return}let i=z(["ID","Status","Model","Progress","Created"]);n.data.forEach(r=>{let c=r.status==="succeeded"?green:r.status==="failed"?red:yellow;i.push([r.id.substring(0,8)+"...",c(r.status),r.base_model,(r.progress||0)+"%",new Date(r.created_at).toLocaleDateString()]);}),console.log(i.toString()),console.log("");let s=await select({message:"Select a job to view details:",options:n.data.map(r=>({value:r.id,label:`${r.name||r.id} (${r.status})`,hint:`Created: ${new Date(r.created_at).toLocaleDateString()}`}))});if(isCancel(s))return;await De(e,s);}catch(n){o.stop(red(`Failed to list jobs: ${n.message}`));}}async function De(e,o){let a=o;if(!a&&(a=await text({message:"Enter Job ID:"}),isCancel(a)))return;let t=d();t.start(`Fetching status for ${a}...`);try{let n=await e.getJob(a);if(t.stop(`Job Status: ${n.status.toUpperCase()}`),console.log(gray("------------------------------------------------")),console.log(`${bgMagenta(black(" Job Details "))}`),console.log(`ID: ${n.id}`),console.log(`Name: ${n.name}`),console.log(`Status: ${n.status==="succeeded"?green(n.status):n.status}`),console.log(`Model: ${n.base_model}`),console.log(`Progress: ${n.progress||0}%`),n.error_message&&console.log(red(`Error: ${n.error_message}`)),console.log(gray("------------------------------------------------")),n.status==="running"||n.status==="queued"){let i=await select({message:"Action:",options:[{value:"refresh",label:"Refresh Status"},{value:"cancel",label:"Cancel Job"},{value:"back",label:"Back"}]});i==="refresh"&&await De(e,a),i==="cancel"&&await Xe(e,a);}}catch(n){t.stop(red(`Failed to get job status: ${n.message}`));}}async function Xe(e,o){let a=await confirm({message:"Are you sure you want to cancel this job?"});if(!a||isCancel(a))return;let t=d();t.start("Canceling job...");try{await e.cancelJob(o),t.stop(green("Job canceled successfully."));}catch(n){t.stop(red(`Failed to cancel job: ${n.message}`));}}async function Ee(e,o){let a="",t=d();t.start("Fetching available vision models...");try{let c=await o.list("vision");t.stop(`Found ${c.length} vision models`),c.length>0?a=await select({message:"Select base vision model:",options:c.map(l=>({value:l.id,label:l.id,hint:l.owned_by}))}):a=await text({message:"Enter base vision model:",placeholder:"llava-v1.5-7b",initialValue:"llava-v1.5-7b"});}catch{t.stop(yellow("Failed to fetch models. Using manual input.")),a=await text({message:"Enter base vision model:",placeholder:"llava-v1.5-7b",initialValue:"llava-v1.5-7b"});}isCancel(a)&&(cancel("Operation cancelled"),process.exit(0));let n=await text({message:"Enter dataset path:",placeholder:"./dataset"});isCancel(n)&&cancel("Operation cancelled");let i=await text({message:"Num Epochs:",placeholder:"3",initialValue:"3"});isCancel(i)&&cancel("Operation cancelled");let s=await select({message:"Track this job on Langtrain Cloud?",options:[{value:"yes",label:"Yes",hint:"Upload dataset and log job"},{value:"no",label:"No",hint:"Local only"}]});if(isCancel(s)&&cancel("Operation cancelled"),s==="yes"){let c=d();c.start("Connecting to Cloud...");try{let l=f();if(!l.apiKey)throw new Error('API Key required. Run "login" first.');if(!(await new h({apiKey:l.apiKey}).getStatus()).features.includes("cloud_finetuning")){c.stop(red('Feature "cloud_finetuning" is not available on your plan.'));let M=await confirm({message:"Upgrade to Pro for cloud tracking?"});M&&!isCancel(M)&&console.log(bgMagenta(black(" Visit https://langtrain.ai/dashboard/billing to upgrade. ")));return}let k=new f$1({apiKey:l.apiKey}),_=new g({apiKey:l.apiKey});c.message("Uploading dataset...");let T=await k.upload(n,void 0,"fine-tune-vision");c.message("Creating Job...");let G=await _.createJob({name:`cli-vision-${Date.now()}`,base_model:a,dataset_id:T.id,task:"vision",training_method:"lora",hyperparameters:{n_epochs:parseInt(i)}});c.stop(green(`Job tracked: ${G.id}`));}catch(l){c.stop(red(`Tracking failed: ${l.message}`));let h=await confirm({message:"Continue with local training anyway?"});if(!h||isCancel(h))return}}let r=d();r.start("Analyzing dataset structure..."),await new Promise(c=>setTimeout(c,800)),r.message("Starting vision fine-tuning on Langtrain Cloud...");try{let c={model:a,dataset:n,epochs:parseInt(i),batchSize:1,learningRate:2e-5,loraRank:16,outputDir:"./vision-output"};await e.finetune(c),r.stop(green("Vision fine-tuning started successfully!"));}catch(c){throw r.stop(red("Failed to start vision job.")),c}}async function Pe(e){let o=await text({message:"Enter model path:",placeholder:"./vision-output/model",initialValue:"./vision-output/model"});isCancel(o)&&cancel("Operation cancelled");let a=await text({message:"Enter prompt/image path:",placeholder:"Describe this image..."});isCancel(a)&&cancel("Operation cancelled");let t=d();t.start("Uploading image and context..."),await new Promise(n=>setTimeout(n,600)),t.message("Generating vision response...");try{let n=await e.generate(o,{prompt:a});t.stop("Generation complete"),$("Response:"),console.log(E.pastel(n));}catch(n){throw t.stop(red("Generation failed.")),n}}async function Ke(e,o){let a=await text({message:"Agent Name:",placeholder:"e.g. Support Bot",validate(c){if(!c||c.length===0)return "API Key is required"}});if(isCancel(a)){cancel("Operation cancelled");return}let t=await text({message:"Description:",placeholder:"e.g. A helpful support assistant"});if(isCancel(t))return;let n=await text({message:"System Prompt:",placeholder:"e.g. You are a helpful assistant.",initialValue:"You are a helpful assistant."});if(isCancel(n))return;let i="gpt-4o",s=d();s.start("Fetching agent models...");try{let c=await o.list("agent");s.stop(`Found ${c.length} models`),c.length>0&&(i=await select({message:"Select Agent Model:",options:c.map(l=>({value:l.id,label:l.id}))}));}catch{s.stop(yellow("Could not fetch models, using default."));}if(isCancel(i))return;let r=d();r.start("Creating agent...");try{let c=await e.list(),l="";if(c.length>0)l=c[0].workspace_id;else {r.stop(yellow("Workspace ID needed (no existing agents found)."));let b=await text({message:"Enter Workspace ID (UUID):",validate(k){if(!k||k.length===0)return "Required"}});if(isCancel(b))return;l=b,r.start("Creating agent...");}let h=await e.create({workspace_id:l,name:a,description:t,config:{system_prompt:n,model:i}});r.stop(green(`Agent "${h.name}" created successfully! ID: ${h.id}`));}catch(c){throw r.stop(red("Failed to create agent.")),c}}async function _e(e){let o=d();o.start("Fetching agents...");let a=await e.list();if(o.stop(`Found ${a.length} agents`),a.length===0){$(yellow("No agents to delete."));return}let t=await select({message:"Select an agent to DELETE:",options:a.map(s=>({value:s.id,label:s.name,hint:s.description||"No description"}))});if(isCancel(t))return;if(await select({message:"Are you sure you want to delete this agent?",options:[{value:"yes",label:"Yes, delete it",hint:"Cannot be undone"},{value:"no",label:"No, keep it"}]})!=="yes"){$(gray("Deletion cancelled."));return}let i=d();i.start("Deleting agent...");try{await e.delete(t),i.stop(green("Agent deleted successfully."));}catch(s){throw i.stop(red("Failed to delete agent.")),s}}async function Te(e){let o=d();o.start("Fetching agents...");let a=await e.list();if(o.stop(`Found ${a.length} agents`),a.length===0){$(yellow("No agents found in your workspace."));return}let t=z(["ID","Name","Model","Created"]);a.forEach(i=>{t.push([i.id.substring(0,8)+"...",i.name,i.config?.model||"default",new Date(i.created_at).toLocaleDateString()]);}),console.log(t.toString()),console.log("");let n=await select({message:"Select an agent to run:",options:a.map(i=>({value:i.id,label:i.name,hint:i.description||"No description"}))});isCancel(n)||await Me(e,n,a.find(i=>i.id===n)?.name||"Agent");}async function Me(e,o,a,t){$(bgMagenta(black(` Chatting with ${a} `))),console.log(gray('Type "exit" to quit conversation.'));let n;for(;;){let i=await text({message:"You:",placeholder:"Type a message..."});if(isCancel(i)||i==="exit")break;let s=d();s.start("Agent is thinking...");try{let r=await e.execute(o,{prompt:i},[],n);s.stop(),r.output?.response?console.log(E.pastel(`Agent: ${r.output.response}`)):console.log(E.pastel(`Agent: ${JSON.stringify(r.output)}`)),n=r.conversation_id;}catch(r){s.stop(red("Error running agent.")),console.error(r);}}}async function oe(){$("Initializing new Langtrain project...");let e=process.cwd();if(J.existsSync(ae.join(e,"langtrain.config.json"))){$e("langtrain.config.json already exists in this directory.");let s=await confirm({message:"Do you want to re-initialize and overwrite the config?",initialValue:false});if(isCancel(s)||!s){K("Initialization cancelled.");return}}let o=await text({message:"What is the name of your project?",placeholder:"my-ai-app",initialValue:ae.basename(e),validate(s){if(!s||s.length===0)return "Project name is required!"}});if(isCancel(o)){cancel("Operation cancelled.");return}let a=f(),t=a.apiKey;if(t)R("Found existing Langtrain credentials.");else {let s=await confirm({message:"You are not logged in. Do you want to log in now?",initialValue:true});if(isCancel(s)){cancel("Operation cancelled.");return}if(s)await O(),a=f(),t=a.apiKey;else if(t=await text({message:"Enter your Langtrain API Key (optional for local dev):",placeholder:"lt_sk_...",initialValue:""}),isCancel(t)){cancel("Operation cancelled.");return}}d().start("Creating configuration...");let i={name:o,apiKey:t||void 0,environment:"development",agents:[{name:"support-bot",description:"A helpful customer support assistant",config:{model:"llama-3-8b",system_prompt:"You are a helpful customer support assistant.",temperature:.7}}]};J.writeFileSync(ae.join(e,"langtrain.config.json"),JSON.stringify(i,null,2)),R("Project initialized successfully!"),console.log(A.dim(`
|
|
24
|
-
Next steps:`)),console.log(` 1. Run ${A.cyan("lt deploy")} to push your agent to the cloud.`),console.log(` 2. Run ${A.cyan("lt dev")} to start the local development loop.`),K("Happy coding!");}async function Ne(){$("Running Langtrain Doctor...");let e=d(),o=0;e.start("Checking Node.js environment...");let a=process.version,t=Ue.platform(),n=Ue.arch();parseInt(a.replace("v","").split(".")[0])<18?(e.stop(A.red(`Node.js version ${a} is outdated. Please upgrade to v18+.`)),o++):e.stop(`Node.js ${a} (${t} ${n})`),e.start("Checking configuration...");let i=f();if(!i.apiKey)e.stop(A.yellow("API Key is missing. Run `langtrain login` or set LANGTRAIN_API_KEY.")),o++;else {e.stop("Configuration found."),e.start("Checking API connectivity...");try{let s=await
|
|
23
|
+
Limits:`)),console.log(` Models: ${t.limits.max_models===-1?"Unlimited":t.limits.max_models}`),console.log(` Training Jobs: ${t.limits.max_training_jobs}`);}catch(t){a.stop(red("Failed to fetch status.")),console.error(t.message);}}async function Ae(e,o){let a="",t=d();t.start("Fetching available text models...");try{let c=await o.list("text");t.stop(`Found ${c.length} text models`),c.length>0&&(a=await select({message:"Select base model:",options:c.map(l=>({value:l.id,label:l.id,hint:l.owned_by}))}));}catch{t.stop(yellow("Failed to fetch models. Using manual input.")),a=await text({message:"Enter base model (e.g., gpt-3.5-turbo):",placeholder:"gpt-3.5-turbo",validate(l){if(!l||l.length===0)return "Value is required!"}});}isCancel(a)&&(cancel("Operation cancelled."),process.exit(0));let n=await text({message:"Enter path to training file:",placeholder:"./data.jsonl",validate(c){if(!c||c.length===0)return "Value is required!"}});isCancel(n)&&cancel("Operation cancelled.");let i=await text({message:"Num Epochs:",placeholder:"3",initialValue:"3"});isCancel(i)&&cancel("Operation cancelled.");let s=await select({message:"Track this job on Langtrain Cloud?",options:[{value:"yes",label:"Yes",hint:"Upload dataset and log job"},{value:"no",label:"No",hint:"Local only"}]});if(isCancel(s)&&cancel("Operation cancelled."),s==="yes"){let c=d();c.start("Connecting to Cloud...");try{let l=f();if(!l.apiKey)throw new Error('API Key required. Run "login" first.');if(!(await new h({apiKey:l.apiKey}).getStatus()).features.includes("cloud_finetuning")){c.stop(red('Feature "cloud_finetuning" is not available on your plan.'));let M=await confirm({message:"Upgrade to Pro for cloud tracking?"});M&&!isCancel(M)&&console.log(bgMagenta(black(" Visit https://langtrain.ai/dashboard/billing to upgrade. ")));return}let k=new f$1({apiKey:l.apiKey}),_=new g({apiKey:l.apiKey});c.message("Uploading dataset...");let T=await k.upload(n);c.message("Creating Job...");let G=await _.createJob({name:`cli-sft-${Date.now()}`,base_model:a,dataset_id:T.id,task:"text",hyperparameters:{n_epochs:parseInt(i)}});c.stop(green(`Job tracked: ${G.id}`));}catch(l){c.stop(red(`Tracking failed: ${l.message}`));let h=await confirm({message:"Continue with local training anyway?"});if(!h||isCancel(h))return}}let r=d();r.start("Starting local fine-tuning...");try{let c={model:a,trainFile:n,preset:"default",epochs:parseInt(i),batchSize:1,learningRate:2e-5,loraRank:16,outputDir:"./output"};await e.finetune(c),r.stop(green("Fine-tuning job started successfully!"));}catch(c){throw r.stop(red("Failed to start job.")),c}}async function Fe(e){let o=await text({message:"Enter model path:",placeholder:"./output/model",initialValue:"./output/model"});isCancel(o)&&cancel("Operation cancelled");let a=await text({message:"Enter prompt:",placeholder:"Hello world"});isCancel(a)&&cancel("Operation cancelled");let t=d();t.start("Connecting to Langtrain Inference API...");try{let n=await e.generate(o,{prompt:a});t.stop("Generation complete"),$("Response:"),console.log(E.pastel(n));}catch(n){throw t.stop(red("Generation failed.")),n}}async function Ie(e){let o=d();o.start("Fetching fine-tuning jobs...");let t=f().workspace_id;if(!(!t&&(o.stop(yellow("Workspace ID required to list jobs.")),t=await text({message:"Enter Workspace ID:"}),isCancel(t))))try{let n=await e.listJobs(t);if(o.stop(`Found ${n.data.length} jobs`),n.data.length===0){console.log(yellow("No jobs found."));return}let i=q(["ID","Status","Model","Progress","Created"]);n.data.forEach(r=>{let c=r.status==="succeeded"?green:r.status==="failed"?red:yellow;i.push([r.id.substring(0,8)+"...",c(r.status),r.base_model,(r.progress||0)+"%",new Date(r.created_at).toLocaleDateString()]);}),console.log(i.toString()),console.log("");let s=await select({message:"Select a job to view details:",options:n.data.map(r=>({value:r.id,label:`${r.name||r.id} (${r.status})`,hint:`Created: ${new Date(r.created_at).toLocaleDateString()}`}))});if(isCancel(s))return;await De(e,s);}catch(n){o.stop(red(`Failed to list jobs: ${n.message}`));}}async function De(e,o){let a=o;if(!a&&(a=await text({message:"Enter Job ID:"}),isCancel(a)))return;let t=d();t.start(`Fetching status for ${a}...`);try{let n=await e.getJob(a);if(t.stop(`Job Status: ${n.status.toUpperCase()}`),console.log(gray("------------------------------------------------")),console.log(`${bgMagenta(black(" Job Details "))}`),console.log(`ID: ${n.id}`),console.log(`Name: ${n.name}`),console.log(`Status: ${n.status==="succeeded"?green(n.status):n.status}`),console.log(`Model: ${n.base_model}`),console.log(`Progress: ${n.progress||0}%`),n.error_message&&console.log(red(`Error: ${n.error_message}`)),console.log(gray("------------------------------------------------")),n.status==="running"||n.status==="queued"){let i=await select({message:"Action:",options:[{value:"refresh",label:"Refresh Status"},{value:"cancel",label:"Cancel Job"},{value:"back",label:"Back"}]});i==="refresh"&&await De(e,a),i==="cancel"&&await Xe(e,a);}}catch(n){t.stop(red(`Failed to get job status: ${n.message}`));}}async function Xe(e,o){let a=await confirm({message:"Are you sure you want to cancel this job?"});if(!a||isCancel(a))return;let t=d();t.start("Canceling job...");try{await e.cancelJob(o),t.stop(green("Job canceled successfully."));}catch(n){t.stop(red(`Failed to cancel job: ${n.message}`));}}async function Ee(e,o){let a="",t=d();t.start("Fetching available vision models...");try{let c=await o.list("vision");t.stop(`Found ${c.length} vision models`),c.length>0?a=await select({message:"Select base vision model:",options:c.map(l=>({value:l.id,label:l.id,hint:l.owned_by}))}):a=await text({message:"Enter base vision model:",placeholder:"llava-v1.5-7b",initialValue:"llava-v1.5-7b"});}catch{t.stop(yellow("Failed to fetch models. Using manual input.")),a=await text({message:"Enter base vision model:",placeholder:"llava-v1.5-7b",initialValue:"llava-v1.5-7b"});}isCancel(a)&&(cancel("Operation cancelled"),process.exit(0));let n=await text({message:"Enter dataset path:",placeholder:"./dataset"});isCancel(n)&&cancel("Operation cancelled");let i=await text({message:"Num Epochs:",placeholder:"3",initialValue:"3"});isCancel(i)&&cancel("Operation cancelled");let s=await select({message:"Track this job on Langtrain Cloud?",options:[{value:"yes",label:"Yes",hint:"Upload dataset and log job"},{value:"no",label:"No",hint:"Local only"}]});if(isCancel(s)&&cancel("Operation cancelled"),s==="yes"){let c=d();c.start("Connecting to Cloud...");try{let l=f();if(!l.apiKey)throw new Error('API Key required. Run "login" first.');if(!(await new h({apiKey:l.apiKey}).getStatus()).features.includes("cloud_finetuning")){c.stop(red('Feature "cloud_finetuning" is not available on your plan.'));let M=await confirm({message:"Upgrade to Pro for cloud tracking?"});M&&!isCancel(M)&&console.log(bgMagenta(black(" Visit https://langtrain.ai/dashboard/billing to upgrade. ")));return}let k=new f$1({apiKey:l.apiKey}),_=new g({apiKey:l.apiKey});c.message("Uploading dataset...");let T=await k.upload(n,void 0,"fine-tune-vision");c.message("Creating Job...");let G=await _.createJob({name:`cli-vision-${Date.now()}`,base_model:a,dataset_id:T.id,task:"vision",training_method:"lora",hyperparameters:{n_epochs:parseInt(i)}});c.stop(green(`Job tracked: ${G.id}`));}catch(l){c.stop(red(`Tracking failed: ${l.message}`));let h=await confirm({message:"Continue with local training anyway?"});if(!h||isCancel(h))return}}let r=d();r.start("Analyzing dataset structure..."),await new Promise(c=>setTimeout(c,800)),r.message("Starting vision fine-tuning on Langtrain Cloud...");try{let c={model:a,dataset:n,epochs:parseInt(i),batchSize:1,learningRate:2e-5,loraRank:16,outputDir:"./vision-output"};await e.finetune(c),r.stop(green("Vision fine-tuning started successfully!"));}catch(c){throw r.stop(red("Failed to start vision job.")),c}}async function Pe(e){let o=await text({message:"Enter model path:",placeholder:"./vision-output/model",initialValue:"./vision-output/model"});isCancel(o)&&cancel("Operation cancelled");let a=await text({message:"Enter prompt/image path:",placeholder:"Describe this image..."});isCancel(a)&&cancel("Operation cancelled");let t=d();t.start("Uploading image and context..."),await new Promise(n=>setTimeout(n,600)),t.message("Generating vision response...");try{let n=await e.generate(o,{prompt:a});t.stop("Generation complete"),$("Response:"),console.log(E.pastel(n));}catch(n){throw t.stop(red("Generation failed.")),n}}async function Ke(e,o){let a=await text({message:"Agent Name:",placeholder:"e.g. Support Bot",validate(c){if(!c||c.length===0)return "API Key is required"}});if(isCancel(a)){cancel("Operation cancelled");return}let t=await text({message:"Description:",placeholder:"e.g. A helpful support assistant"});if(isCancel(t))return;let n=await text({message:"System Prompt:",placeholder:"e.g. You are a helpful assistant.",initialValue:"You are a helpful assistant."});if(isCancel(n))return;let i="gpt-4o",s=d();s.start("Fetching agent models...");try{let c=await o.list("agent");s.stop(`Found ${c.length} models`),c.length>0&&(i=await select({message:"Select Agent Model:",options:c.map(l=>({value:l.id,label:l.id}))}));}catch{s.stop(yellow("Could not fetch models, using default."));}if(isCancel(i))return;let r=d();r.start("Creating agent...");try{let c=await e.list(),l="";if(c.length>0)l=c[0].workspace_id;else {r.stop(yellow("Workspace ID needed (no existing agents found)."));let b=await text({message:"Enter Workspace ID (UUID):",validate(k){if(!k||k.length===0)return "Required"}});if(isCancel(b))return;l=b,r.start("Creating agent...");}let h=await e.create({workspace_id:l,name:a,description:t,config:{system_prompt:n,model:i}});r.stop(green(`Agent "${h.name}" created successfully! ID: ${h.id}`));}catch(c){throw r.stop(red("Failed to create agent.")),c}}async function _e(e){let o=d();o.start("Fetching agents...");let a=await e.list();if(o.stop(`Found ${a.length} agents`),a.length===0){$(yellow("No agents to delete."));return}let t=await select({message:"Select an agent to DELETE:",options:a.map(s=>({value:s.id,label:s.name,hint:s.description||"No description"}))});if(isCancel(t))return;if(await select({message:"Are you sure you want to delete this agent?",options:[{value:"yes",label:"Yes, delete it",hint:"Cannot be undone"},{value:"no",label:"No, keep it"}]})!=="yes"){$(gray("Deletion cancelled."));return}let i=d();i.start("Deleting agent...");try{await e.delete(t),i.stop(green("Agent deleted successfully."));}catch(s){throw i.stop(red("Failed to delete agent.")),s}}async function Te(e){let o=d();o.start("Fetching agents...");let a=await e.list();if(o.stop(`Found ${a.length} agents`),a.length===0){$(yellow("No agents found in your workspace."));return}let t=q(["ID","Name","Model","Created"]);a.forEach(i=>{t.push([i.id.substring(0,8)+"...",i.name,i.config?.model||"default",new Date(i.created_at).toLocaleDateString()]);}),console.log(t.toString()),console.log("");let n=await select({message:"Select an agent to run:",options:a.map(i=>({value:i.id,label:i.name,hint:i.description||"No description"}))});isCancel(n)||await Me(e,n,a.find(i=>i.id===n)?.name||"Agent");}async function Me(e,o,a,t){$(bgMagenta(black(` Chatting with ${a} `))),console.log(gray('Type "exit" to quit conversation.'));let n;for(;;){let i=await text({message:"You:",placeholder:"Type a message..."});if(isCancel(i)||i==="exit")break;let s=d();s.start("Agent is thinking...");try{let r=await e.execute(o,{prompt:i},[],n);s.stop(),r.output?.response?console.log(E.pastel(`Agent: ${r.output.response}`)):console.log(E.pastel(`Agent: ${JSON.stringify(r.output)}`)),n=r.conversation_id;}catch(r){s.stop(red("Error running agent.")),console.error(r);}}}async function oe(){$("Initializing new Langtrain project...");let e=process.cwd();if(J.existsSync(ae.join(e,"langtrain.config.json"))){$e("langtrain.config.json already exists in this directory.");let s=await confirm({message:"Do you want to re-initialize and overwrite the config?",initialValue:false});if(isCancel(s)||!s){K("Initialization cancelled.");return}}let o=await text({message:"What is the name of your project?",placeholder:"my-ai-app",initialValue:ae.basename(e),validate(s){if(!s||s.length===0)return "Project name is required!"}});if(isCancel(o)){cancel("Operation cancelled.");return}let a=f(),t=a.apiKey;if(t)R("Found existing Langtrain credentials.");else {let s=await confirm({message:"You are not logged in. Do you want to log in now?",initialValue:true});if(isCancel(s)){cancel("Operation cancelled.");return}if(s)await O(),a=f(),t=a.apiKey;else if(t=await text({message:"Enter your Langtrain API Key (optional for local dev):",placeholder:"lt_sk_...",initialValue:""}),isCancel(t)){cancel("Operation cancelled.");return}}d().start("Creating configuration...");let i={name:o,apiKey:t||void 0,environment:"development",agents:[{name:"support-bot",description:"A helpful customer support assistant",config:{model:"llama-3-8b",system_prompt:"You are a helpful customer support assistant.",temperature:.7}}]};J.writeFileSync(ae.join(e,"langtrain.config.json"),JSON.stringify(i,null,2)),R("Project initialized successfully!"),console.log(A.dim(`
|
|
24
|
+
Next steps:`)),console.log(` 1. Run ${A.cyan("lt deploy")} to push your agent to the cloud.`),console.log(` 2. Run ${A.cyan("lt dev")} to start the local development loop.`),K("Happy coding!");}async function Ne(){$("Running Langtrain Doctor...");let e=d(),o=0;e.start("Checking Node.js environment...");let a=process.version,t=Ue.platform(),n=Ue.arch();parseInt(a.replace("v","").split(".")[0])<18?(e.stop(A.red(`Node.js version ${a} is outdated. Please upgrade to v18+.`)),o++):e.stop(`Node.js ${a} (${t} ${n})`),e.start("Checking configuration...");let i=f();if(!i.apiKey)e.stop(A.yellow("API Key is missing. Run `langtrain login` or set LANGTRAIN_API_KEY.")),o++;else {e.stop("Configuration found."),e.start("Checking API connectivity...");try{let s=await z(i.apiKey);e.stop(`Connected to Langtrain Cloud (Plan: ${A.green(s?.plan||"unknown")})`);}catch(s){e.stop(A.red(`Failed to connect to Langtrain Cloud: ${s.message}`)),o++;}}console.log(""),o===0?R("Your Langtrain environment is healthy! Ready to build."):ve(`Found ${o} issue(s). Please resolve them for the best experience.`),K("Doctor check complete.");}async function ie(e){let a=f().workspace_id,t=await text({message:"Path to file:",placeholder:"./dataset.jsonl",validate(s){if(!s)return "Required";if(!J.existsSync(s))return "File not found"}});if(isCancel(t))return;let n=await select({message:"File Purpose:",options:[{value:"fine-tune",label:"Fine-tuning (JSONL)"},{value:"vision-tune",label:"Vision Tuning (Image/Zip)"},{value:"agent-knowledge",label:"Agent Knowledge"}]});if(isCancel(n))return;let i=d();i.start("Uploading file...");try{let s=await e.upload(t,a,n);i.stop(green("File uploaded successfully!")),console.log(gray(`ID: ${s.id}`)),console.log(gray(`Name: ${s.filename}`)),console.log(gray(`Bytes: ${s.bytes}`));}catch(s){i.stop(red(`Upload failed: ${s.message}`));}}async function se(e,o){let a=f(),t=new m({apiKey:a.apiKey||"",baseUrl:a.baseUrl});if(!o){let r=d();r.start("Fetching files...");try{let c=a.workspace_id||"",l=await e.list(c);if(r.stop(`Found ${l.length} files`),l.length===0){console.log(yellow("No files found. Upload one first."));return}let h=await select({message:"Select file to refine:",options:l.map(b=>({value:b.id,label:`${b.filename} (${tt(b.bytes)})`}))});if(isCancel(h))return;o=h;}catch(c){r.stop(red(`Failed to fetch files: ${c.message}`));return}}let n=d();n.start("Fetching guardrails...");let i="";try{let r=await t.list();if(n.stop(`Found ${r.length} guardrails`),r.length===0){console.log(yellow('No guardrails found. Please create one first using "lt guardrails create".'));return}let c=await select({message:"Select a Guardrail to apply:",options:r.map(l=>({value:l.id,label:l.name,hint:l.description}))});if(isCancel(c))return;i=c;}catch(r){n.stop(red(`Failed to fetch guardrails: ${r.message}`));return}let s=d();s.start("Applying guardrail (filtering dataset)...");try{let r=await t.apply(o,i);s.stop(green("Dataset refined successfully!")),console.log(gray("Stats:")),console.log(`Original Rows: ${r.original_rows}`),console.log(`Filtered Rows: ${r.filtered_rows}`),console.log(red(`Removed: ${r.removed_rows} rows`)),console.log(green(`New Dataset ID: ${r.new_dataset_id}`));}catch(r){s.stop(red(`Failed to refine dataset: ${r.message}`));}}function tt(e,o=2){if(!+e)return "0 Bytes";let a=1024,t=o<0?0:o,n=["Bytes","KB","MB","GB","TB"],i=Math.floor(Math.log(e)/Math.log(a));return `${parseFloat((e/Math.pow(a,i)).toFixed(t))} ${n[i]}`}async function V(e){$("Deploying configuration to Langtrain Cloud...");let o=f(),a=o.agents||[];if(a.length===0){$(yellow("No agents found in langtrain.config.json"));return}for(let t of a){let n=d();n.start(`Deploying agent: ${t.name}...`);try{let i=await e.list(),s=i.find(r=>r.name===t.name);if(s)n.stop(yellow(`Agent ${t.name} already exists (ID: ${s.id}). Skipping update (not supported yet).`));else {let r={workspace_id:o.workspace_id||i[0]?.workspace_id||"",name:t.name,description:t.description,config:t.config};if(!r.workspace_id){n.stop(red(`Failed: Workspace ID missing in config for ${t.name}`));continue}await e.create(r),n.stop(green(`Agent ${t.name} deployed successfully!`));}}catch(i){n.stop(red(`Failed to deploy ${t.name}: ${i.message}`));}}R("Deployment complete.");}async function re(e){$("Starting Langtrain Development Server...");let o=ae.join(process.cwd(),"langtrain.config.json");if(!J.existsSync(o)){$(red('langtrain.config.json not found. Run "lt init" first.'));return}console.log(gray(`Watching ${o} for changes...`));let a=false;await V(e),J.watch(o,async t=>{if(t==="change"&&!a){a=true,console.log(yellow("Configuration changed. Redeploying...")),await new Promise(n=>setTimeout(n,500));try{await V(e);}catch(n){console.error(red(`Deploy failed: ${n.message}`));}finally{a=false,console.log(gray(`Watching ${o}...`));}}}),await new Promise(()=>{});}async function le(e){let o=f(),a=new m({apiKey:o.apiKey||"",baseUrl:o.baseUrl}),t=d();t.start("Fetching guardrails...");try{let n=await a.list();if(t.stop(`Found ${n.length} guardrails`),n.length===0){console.log(yellow('No guardrails found. Create one with "lt guardrails create".'));return}n.forEach(i=>{console.log(green(`\u2022 ${i.name}`)+gray(` (ID: ${i.id})`)),i.description&&console.log(gray(` ${i.description}`)),console.log(gray(` Config: PII=${i.config.pii_enabled}, MinLen=${i.config.min_length}`)),console.log("");});}catch(n){t.stop(red(`Failed to list guardrails: ${n.message}`));}}async function ce(e){let o=f(),a=new m({apiKey:o.apiKey||"",baseUrl:o.baseUrl});$("Create a new Data Guardrail");let t=await text({message:"Guardrail Name:",placeholder:"e.g. Strict Safety Policy",validate(l){if(!l)return "Name is required"}});if(isCancel(t))return;let n=await text({message:"Description (optional):",placeholder:"Filters PII and short text"});if(isCancel(n))return;let i=await text({message:"Minimum Text Length (0 for no limit):",initialValue:"0",validate(l){if(isNaN(Number(l)))return "Must be a number"}});if(isCancel(i))return;let s=await confirm({message:"Enable PII Filtering (Email/Phone)?",initialValue:false});if(isCancel(s))return;let r=await text({message:"Regex Patterns to Block (comma separated, optional):",placeholder:"e.g. bad_word, another_one"});if(isCancel(r))return;let c=d();c.start("Creating guardrail...");try{let l=r.split(",").map(k=>k.trim()).filter(k=>k.length>0),h={name:t,description:n,config:{min_length:Number(i),pii_enabled:s,regex_patterns:l,profanity_enabled:!1}},b=await a.create(h);c.stop(green(`Guardrail "${b.name}" created successfully!`)),console.log(gray(`ID: ${b.id}`));}catch(l){c.stop(red(`Failed to create guardrail: ${l.message}`));}}async function at(e){let o=d();o.start("Fetching secrets...");let a=f();try{let t=await e.list(a.workspace_id);if(o.stop(`Found ${t.length} secrets`),t.length===0){console.log(gray('No secrets found. Use "lt env set" to add one.'));return}console.log(gray("------------------------------------------------")),t.forEach(n=>{console.log(`${n.key.padEnd(30)} ${gray("******")}`);}),console.log(gray("------------------------------------------------"));}catch(t){o.stop(red(`Failed to list secrets: ${t.message}`));}}async function ot(e,o){let a="",t="";if(a=await text({message:"Secret Key:",placeholder:"OPENAI_API_KEY"}),isCancel(a)||(t=await text({message:"Secret Value:",placeholder:"sk-..."}),isCancel(t)))return;let n=d();n.start(`Setting ${a}...`);let i=f();try{await e.set(a,t,i.workspace_id),n.stop(green(`Secret ${a} set successfully.`));}catch(s){n.stop(red(`Failed to set secret: ${s.message}`));}}async function ge(e){let o=await select({message:"Manage Secrets",options:[{value:"list",label:"List Secrets"},{value:"set",label:"Set Secret"},{value:"remove",label:"Remove Secret"},{value:"back",label:"Back"}]});if(!(isCancel(o)||o==="back")&&(o==="list"&&await at(e),o==="set"&&await ot(e),o==="remove")){let a=await text({message:"Key to remove:"});if(!isCancel(a)){let t=d();t.start("Removing...");try{let n=f();await e.delete(a,n.workspace_id),t.stop(green("Removed."));}catch(n){t.stop(red(`Failed: ${n.message}`));}}}}async function pe(e,o){let a=d(),t="";if(o){a.start("Finding agent...");try{let s=(await e.list()).find(r=>r.name===o||r.id===o);if(s)t=s.id;else {a.stop(red(`Agent "${o}" not found.`));return}a.stop(green(`Found agent: ${s.name}`));}catch(i){a.stop(red(`Failed to list agents: ${i.message}`));return}}else {a.start("Fetching agents...");try{let i=await e.list();if(a.stop(`Found ${i.length} agents`),i.length===0){console.log(yellow("No agents found."));return}let s=await select({message:"Select agent to view logs:",options:i.map(r=>({value:r.id,label:r.name}))});if(isCancel(s))return;t=s;}catch(i){a.stop(red(`Failed to list agents: ${i.message}`));return}}let n=d();n.start("Fetching logs...");try{let i=await e.logs(t);n.stop("Logs fetched."),console.log(gray("------------------------------------------------")),console.log(`${bgMagenta(black(" Recent Logs "))}`),i.logs&&i.logs.length>0?i.logs.forEach(s=>console.log(s)):console.log(gray("(No logs found)")),console.log(gray("------------------------------------------------"));}catch(i){n.stop(red(`Failed to fetch logs: ${i.message}`));}}var it=Date.now(),U=0,Oe=0;async function de(){let e=f(),o=e.apiKey;if(console.log(""),console.log(bold(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557")),console.log(bold(" \u2551 TOKEN USAGE \u2551")),console.log(bold(" \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D")),console.log(""),!o){console.log(yellow(` Login required to view token usage.
|
|
25
25
|
`));return}let a$1=d();a$1.start("Fetching token usage...");try{let t=a("axios"),n=e.baseUrl||"https://api.langtrain.xyz",s=(await t.get(`${n}/v1/usage/tokens`,{headers:{Authorization:`Bearer ${o}`}})).data;a$1.stop(green("Token usage retrieved")),console.log("");let r=s.tokens_used||0,c=s.token_limit||1e4,l=Math.round(r/c*100),h=Math.max(0,c-r),b=30,k=Math.round(l/100*b),_="\u2588".repeat(k)+"\u2591".repeat(b-k),T=l>90?"\x1B[31m":l>70?"\x1B[33m":"\x1B[32m";console.log(` ${dim("Period:")} ${s.period||"Current Month"}`),console.log(` ${dim("Used:")} ${r.toLocaleString()} tokens`),console.log(` ${dim("Limit:")} ${c.toLocaleString()} tokens`),console.log(` ${dim("Remaining:")} ${h.toLocaleString()} tokens`),console.log(` ${dim("Usage:")} ${T}${_}\x1B[0m ${l}%`),console.log(""),s.breakdown&&(console.log(dim(" \u2500\u2500 Breakdown \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")),console.log(` ${dim("Training:")} ${(s.breakdown.training||0).toLocaleString()}`),console.log(` ${dim("Inference:")} ${(s.breakdown.inference||0).toLocaleString()}`),console.log(` ${dim("Agents:")} ${(s.breakdown.agents||0).toLocaleString()}`),console.log(""));}catch{a$1.stop(""),console.log(dim(" Token data not available from server.")),console.log(dim(` Showing session estimates:
|
|
26
|
-
`)),console.log(` ${dim("Session calls:")} ${U}`),console.log(` ${dim("Est. tokens:")} ~${U*150}`),console.log("");}}async function Ve(){let e=Date.now()-it,o=Math.round(e/1e3),a$1=Math.floor(o/60),t=a$1>0?`${a$1}m ${o%60}s`:`${o}s`,n=0,i=0;console.log(""),console.log(bold(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557")),console.log(bold(" \u2551 SESSION TELEMETRY \u2551")),console.log(bold(" \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D")),console.log(""),console.log(` ${dim("Session:")} ${t}`),console.log(` ${dim("API calls:")} ${U}`),console.log(` ${dim("Avg latency:")} ${n}ms`),console.log(` ${dim("Errors:")} ${Oe} (${i}%)`),console.log(""),console.log(dim(" \u2500\u2500 Environment \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")),console.log(` ${dim("Node:")} ${process.version}`),console.log(` ${dim("Platform:")} ${process.platform} ${process.arch}`),console.log(` ${dim("Memory:")} ${Math.round(process.memoryUsage().heapUsed/1024/1024)}MB heap`),console.log(` ${dim("Config:")} ~/.langtrain/config.json`),console.log("");let s=f();if(s.apiKey){let r=d();r.start("Pinging API...");try{let c=a("axios"),l=s.baseUrl||"https://api.langtrain.xyz",h=Date.now();await c.get(`${l}/health`,{timeout:5e3});let b=Date.now()-h;r.stop(green(`API healthy (${b}ms)`));}catch{r.stop(yellow("API unreachable"));}}console.log("");}var Ge={version:"0.2.
|
|
27
|
-
`));}function Je(e,o){return {vision:new q$1({apiKey:e}),tune:new r({apiKey:e}),agent:new d$1({apiKey:e,baseUrl:o}),model:new i({apiKey:e,baseUrl:o}),train:new g({apiKey:e,baseUrl:o}),secret:new k({apiKey:e,baseUrl:o})}}function ct(e){switch(e){case "main":return "What would you like to do?";case "agents":return "Agents:";case "text":return "Langtune (Text):";case "vision":return "Langvision (Vision):";case "guard":return "Guardrails:";case "settings":return "Settings:";default:return "Select an option:"}}async function gt(){let e=new Command,o=Ge.version;e.name("langtrain").description("Langtrain CLI \u2014 Fine-tuning, Agents, and AI Ops").version(o),e.command("init").description("Initialize a new Langtrain project").action(oe),e.command("deploy").description("Deploy configuration to Langtrain Cloud").action(async()=>{let n=f(),i=n.apiKey||"",s=new d$1({apiKey:i,baseUrl:n.baseUrl});await V(s);}),e.command("dev").description("Start local development server").action(async()=>{let n=f(),i=n.apiKey||"",s=new d$1({apiKey:i,baseUrl:n.baseUrl});await re(s);}),e.command("env").description("Manage secrets and environment variables").action(async()=>{let n=f(),i=n.apiKey||"",s=new k({apiKey:i,baseUrl:n.baseUrl});await ge(s);}),e.command("logs [agent]").description("Stream logs from a deployed agent").action(async n=>{let i=f(),s=i.apiKey||"",r=new d$1({apiKey:s,baseUrl:i.baseUrl});await pe(r,n);}),e.command("login").description("Authenticate with your API key").action(async()=>{await O();}),e.command("logout").description("Clear stored credentials").action(async()=>{await ne();}),e.command("tokens").description("View token usage for current period").action(de);let a=e.command("data").description("Manage datasets");a.command("upload [file]").description("Upload a dataset").action(async()=>{let n=f(),i=new f$1({apiKey:n.apiKey||"",baseUrl:n.baseUrl});await ie(i);}),a.command("refine [fileId]").description("Refine a dataset using guardrails").action(async n=>{let i=f(),s=new f$1({apiKey:i.apiKey||"",baseUrl:i.baseUrl});await se(s,n);});let t=e.command("guardrails").description("Manage data guardrails");t.command("list").description("List available guardrails").action(async()=>await le()),t.command("create").description("Create a new guardrail").action(async()=>await ce()),e.action(async()=>{H(o),process.argv.includes("--first-run")&&(process.stdin.isTTY?($("Welcome to Langtrain! Let's get you set up."),await O()):(console.log('Langtrain installed! Run "npx langtrain login" to authenticate.'),process.exit(0)));let i=f(),s=i.apiKey||"",r=te(),c=null;if(r&&s){try{c=await
|
|
28
|
-
`));let l=r?Je(s,i.baseUrl):null,h="main";for(;;){let b=await select({message:ct(h),options:xe(h,c,r)});if(isCancel(b))if(h==="main")K("Goodbye!"),process.exit(0);else {h="main";continue}let k=b;if(k==="exit"&&(K("Goodbye!"),process.exit(0)),k==="back"){h="main";continue}if(k.startsWith("nav-")){h=k.replace("nav-","");continue}try{switch(k){case "login":if(await O(),i=f(),s=i.apiKey||"",r=te(),r){try{c=await
|
|
26
|
+
`)),console.log(` ${dim("Session calls:")} ${U}`),console.log(` ${dim("Est. tokens:")} ~${U*150}`),console.log("");}}async function Ve(){let e=Date.now()-it,o=Math.round(e/1e3),a$1=Math.floor(o/60),t=a$1>0?`${a$1}m ${o%60}s`:`${o}s`,n=0,i=0;console.log(""),console.log(bold(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557")),console.log(bold(" \u2551 SESSION TELEMETRY \u2551")),console.log(bold(" \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D")),console.log(""),console.log(` ${dim("Session:")} ${t}`),console.log(` ${dim("API calls:")} ${U}`),console.log(` ${dim("Avg latency:")} ${n}ms`),console.log(` ${dim("Errors:")} ${Oe} (${i}%)`),console.log(""),console.log(dim(" \u2500\u2500 Environment \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")),console.log(` ${dim("Node:")} ${process.version}`),console.log(` ${dim("Platform:")} ${process.platform} ${process.arch}`),console.log(` ${dim("Memory:")} ${Math.round(process.memoryUsage().heapUsed/1024/1024)}MB heap`),console.log(` ${dim("Config:")} ~/.langtrain/config.json`),console.log("");let s=f();if(s.apiKey){let r=d();r.start("Pinging API...");try{let c=a("axios"),l=s.baseUrl||"https://api.langtrain.xyz",h=Date.now();await c.get(`${l}/health`,{timeout:5e3});let b=Date.now()-h;r.stop(green(`API healthy (${b}ms)`));}catch{r.stop(yellow("API unreachable"));}}console.log("");}var Ge={version:"0.2.5"};function Be(e){let{dim:o,green:a,yellow:t,cyan:n,bold:i,gray:s}=A,r=e?.plan==="pro"?i(a("PRO")):e?.plan==="enterprise"?i(a("ENTERPRISE")):o("FREE"),c=e?.usage?.tokensUsedThisMonth||0,l=e?.usage?.tokenLimit||1e4,h=Math.round(c/l*100),b=h>80?t(`${h}%`):a(`${h}%`);console.log(o(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")),console.log(` ${o("Plan:")} ${r} ${o("\u2502")} ${o("Tokens:")} ${c.toLocaleString()}/${l.toLocaleString()} ${b}`),console.log(o(` \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
27
|
+
`));}function Je(e,o){return {vision:new q$1({apiKey:e}),tune:new r({apiKey:e}),agent:new d$1({apiKey:e,baseUrl:o}),model:new i({apiKey:e,baseUrl:o}),train:new g({apiKey:e,baseUrl:o}),secret:new k({apiKey:e,baseUrl:o})}}function ct(e){switch(e){case "main":return "What would you like to do?";case "agents":return "Agents:";case "text":return "Langtune (Text):";case "vision":return "Langvision (Vision):";case "guard":return "Guardrails:";case "settings":return "Settings:";default:return "Select an option:"}}async function gt(){let e=new Command,o=Ge.version;e.name("langtrain").description("Langtrain CLI \u2014 Fine-tuning, Agents, and AI Ops").version(o),e.command("init").description("Initialize a new Langtrain project").action(oe),e.command("deploy").description("Deploy configuration to Langtrain Cloud").action(async()=>{let n=f(),i=n.apiKey||"",s=new d$1({apiKey:i,baseUrl:n.baseUrl});await V(s);}),e.command("dev").description("Start local development server").action(async()=>{let n=f(),i=n.apiKey||"",s=new d$1({apiKey:i,baseUrl:n.baseUrl});await re(s);}),e.command("env").description("Manage secrets and environment variables").action(async()=>{let n=f(),i=n.apiKey||"",s=new k({apiKey:i,baseUrl:n.baseUrl});await ge(s);}),e.command("logs [agent]").description("Stream logs from a deployed agent").action(async n=>{let i=f(),s=i.apiKey||"",r=new d$1({apiKey:s,baseUrl:i.baseUrl});await pe(r,n);}),e.command("login").description("Authenticate with your API key").action(async()=>{await O();}),e.command("logout").description("Clear stored credentials").action(async()=>{await ne();}),e.command("tokens").description("View token usage for current period").action(de);let a=e.command("data").description("Manage datasets");a.command("upload [file]").description("Upload a dataset").action(async()=>{let n=f(),i=new f$1({apiKey:n.apiKey||"",baseUrl:n.baseUrl});await ie(i);}),a.command("refine [fileId]").description("Refine a dataset using guardrails").action(async n=>{let i=f(),s=new f$1({apiKey:i.apiKey||"",baseUrl:i.baseUrl});await se(s,n);});let t=e.command("guardrails").description("Manage data guardrails");t.command("list").description("List available guardrails").action(async()=>await le()),t.command("create").description("Create a new guardrail").action(async()=>await ce()),e.action(async()=>{H(o),process.argv.includes("--first-run")&&(process.stdin.isTTY?($("Welcome to Langtrain! Let's get you set up."),await O()):(console.log('Langtrain installed! Run "npx langtrain login" to authenticate.'),process.exit(0)));let i=f(),s=i.apiKey||"",r=te(),c=null;if(r&&s){try{c=await z(s);}catch{}Be(c);}else console.log(A.dim(` Not logged in. Only basic options available.
|
|
28
|
+
`));let l=r?Je(s,i.baseUrl):null,h="main";for(;;){let b=await select({message:ct(h),options:xe(h,c,r)});if(isCancel(b))if(h==="main")K("Goodbye!"),process.exit(0);else {h="main";continue}let k=b;if(k==="exit"&&(K("Goodbye!"),process.exit(0)),k==="back"){h="main";continue}if(k.startsWith("nav-")){h=k.replace("nav-","");continue}try{switch(k){case "login":if(await O(),i=f(),s=i.apiKey||"",r=te(),r){try{c=await z(s);}catch{}l=Je(s,i.baseUrl),console.clear(),H(o),Be(c);}break;case "logout":await ne(),s="",r=!1,c=null,l=null,console.clear(),H(o),console.log(A.dim(` Logged out. Only basic options available.
|
|
29
29
|
`));break;case "docs":console.log(A.cyan(`
|
|
30
30
|
\u{1F4D6} https://docs.langtrain.ai
|
|
31
31
|
`));break;case "status":await Le();break;case "tokens":await de();break;case "telemetry":await Ve();break;case "doctor":await Ne();break;case "init":await oe();break;case "deploy":l&&await V(l.agent);break;case "dev":l&&await re(l.agent);break;case "env":l&&await ge(l.secret);break;case "logs":l&&await pe(l.agent);break;case "tune-finetune":l&&await Ae(l.tune,l.model);break;case "tune-list":l&&await Ie(l.train);break;case "tune-generate":l&&await Fe(l.tune);break;case "vision-finetune":l&&await Ee(l.vision,l.model);break;case "vision-generate":l&&await Pe(l.vision);break;case "agent-list":l&&await Te(l.agent);break;case "agent-create":l&&await Ke(l.agent,l.model);break;case "agent-delete":l&&await _e(l.agent);break;case "data-upload":s&&await ie(new f$1({apiKey:s}));break;case "data-refine":s&&await se(new f$1({apiKey:s}));break;case "guard-list":await le(null);break;case "guard-create":await ce(null);break}}catch(_){K(A.red(`Error: ${_.message}`));}}}),e.parse(process.argv);}gt().catch(console.error);export{gt as main};//# sourceMappingURL=cli.mjs.map
|