@mariozechner/pi 0.30.1 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +1 -3
- package/dist/cli.js.map +1 -1
- package/package.json +2 -2
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"","sourcesContent":["#!/usr/bin/env node\nimport chalk from \"chalk\";\nimport { spawn } from \"child_process\";\nimport { readFileSync } from \"fs\";\nimport { dirname, join } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { listModels, startModel, stopModel, viewLogs } from \"./commands/models.js\";\nimport { listPods, removePodCommand, setupPod, switchActivePod } from \"./commands/pods.js\";\nimport { promptModel } from \"./commands/prompt.js\";\nimport { getActivePod, loadConfig } from \"./config.js\";\nimport { sshExecStream } from \"./ssh.js\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nconst packageJson = JSON.parse(readFileSync(join(__dirname, \"../package.json\"), \"utf-8\"));\n\nfunction printHelp() {\n\tconsole.log(`pi v${packageJson.version} - Manage vLLM deployments on GPU pods\n\nPod Management:\n pi pods setup <name> \"<ssh>\" --mount \"<mount>\" Setup pod with mount command\n Options:\n --vllm release Install latest vLLM release >=0.10.0 (default)\n --vllm nightly Install vLLM nightly build (latest features)\n --vllm gpt-oss Install vLLM 0.10.1+gptoss with PyTorch nightly (GPT-OSS only)\n pi pods List all pods (* = active)\n pi pods active <name> Switch active pod\n pi pods remove <name> Remove pod from local config\n pi shell [<name>] Open shell on pod (active or specified)\n pi ssh [<name>] \"<command>\" Run SSH command on pod\n\nModel Management:\n pi start <model> --name <name> [options] Start a model\n --memory <percent> GPU memory allocation (30%, 50%, 90%)\n --context <size> Context window (4k, 8k, 16k, 32k, 64k, 128k)\n --gpus <count> Number of GPUs to use (predefined models only)\n --vllm <args...> Pass remaining args to vLLM (ignores other options)\n pi stop [<name>] Stop model (or all if no name)\n pi list List running models\n pi logs <name> Stream model logs\n pi agent <name> [\"<message>\"...] [options] Chat with model using agent & tools\n pi agent <name> [options] Interactive chat mode\n --continue, -c Continue previous session\n --json Output as JSONL\n (All pi-agent options are supported)\n\n All model commands support --pod <name> to override the active pod.\n\nEnvironment:\n HF_TOKEN HuggingFace token for model downloads\n PI_API_KEY API key for vLLM endpoints\n PI_CONFIG_DIR Config directory (default: ~/.pi)`);\n}\n\n// Parse command line arguments\nconst args = process.argv.slice(2);\n\nif (args.length === 0 || args[0] === \"--help\" || args[0] === \"-h\") {\n\tprintHelp();\n\tprocess.exit(0);\n}\n\nif (args[0] === \"--version\" || args[0] === \"-v\") {\n\tconsole.log(packageJson.version);\n\tprocess.exit(0);\n}\n\nconst command = args[0];\nconst subcommand = args[1];\n\n// Main command handler\ntry {\n\t// Handle \"pi pods\" commands\n\tif (command === \"pods\") {\n\t\tif (!subcommand) {\n\t\t\t// pi pods - list all pods\n\t\t\tlistPods();\n\t\t} else if (subcommand === \"setup\") {\n\t\t\t// pi pods setup <name> \"<ssh>\" [--mount \"<mount>\"] [--models-path <path>] [--vllm release|nightly|gpt-oss]\n\t\t\tconst name = args[2];\n\t\t\tconst sshCmd = args[3];\n\n\t\t\tif (!name || !sshCmd) {\n\t\t\t\tconsole.error(\n\t\t\t\t\t'Usage: pi pods setup <name> \"<ssh>\" [--mount \"<mount>\"] [--models-path <path>] [--vllm release|nightly|gpt-oss]',\n\t\t\t\t);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\t// Parse options\n\t\t\tconst options: { mount?: string; modelsPath?: string; vllm?: \"release\" | \"nightly\" | \"gpt-oss\" } = {};\n\t\t\tfor (let i = 4; i < args.length; i++) {\n\t\t\t\tif (args[i] === \"--mount\" && i + 1 < args.length) {\n\t\t\t\t\toptions.mount = args[i + 1];\n\t\t\t\t\ti++;\n\t\t\t\t} else if (args[i] === \"--models-path\" && i + 1 < args.length) {\n\t\t\t\t\toptions.modelsPath = args[i + 1];\n\t\t\t\t\ti++;\n\t\t\t\t} else if (args[i] === \"--vllm\" && i + 1 < args.length) {\n\t\t\t\t\tconst vllmType = args[i + 1];\n\t\t\t\t\tif (vllmType === \"release\" || vllmType === \"nightly\" || vllmType === \"gpt-oss\") {\n\t\t\t\t\t\toptions.vllm = vllmType;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.error(chalk.red(`Invalid vLLM type: ${vllmType}`));\n\t\t\t\t\t\tconsole.error(\"Valid options: release, nightly, gpt-oss\");\n\t\t\t\t\t\tprocess.exit(1);\n\t\t\t\t\t}\n\t\t\t\t\ti++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If --mount provided but no --models-path, try to extract path from mount command\n\t\t\tif (options.mount && !options.modelsPath) {\n\t\t\t\t// Extract last part of mount command as models path\n\t\t\t\tconst parts = options.mount.trim().split(\" \");\n\t\t\t\tconst lastPart = parts[parts.length - 1];\n\t\t\t\tif (lastPart?.startsWith(\"/\")) {\n\t\t\t\t\toptions.modelsPath = lastPart;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tawait setupPod(name, sshCmd, options);\n\t\t} else if (subcommand === \"active\") {\n\t\t\t// pi pods active <name>\n\t\t\tconst name = args[2];\n\t\t\tif (!name) {\n\t\t\t\tconsole.error(\"Usage: pi pods active <name>\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\tswitchActivePod(name);\n\t\t} else if (subcommand === \"remove\") {\n\t\t\t// pi pods remove <name>\n\t\t\tconst name = args[2];\n\t\t\tif (!name) {\n\t\t\t\tconsole.error(\"Usage: pi pods remove <name>\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\tremovePodCommand(name);\n\t\t} else {\n\t\t\tconsole.error(`Unknown pods subcommand: ${subcommand}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t} else {\n\t\t// Parse --pod override for model commands\n\t\tlet podOverride: string | undefined;\n\t\tconst podIndex = args.indexOf(\"--pod\");\n\t\tif (podIndex !== -1 && podIndex + 1 < args.length) {\n\t\t\tpodOverride = args[podIndex + 1];\n\t\t\t// Remove --pod and its value from args\n\t\t\targs.splice(podIndex, 2);\n\t\t}\n\n\t\t// Handle SSH/shell commands and model commands\n\t\tswitch (command) {\n\t\t\tcase \"shell\": {\n\t\t\t\t// pi shell [<name>] - open interactive shell\n\t\t\t\tconst podName = args[1];\n\t\t\t\tlet podInfo: { name: string; pod: import(\"./types.js\").Pod } | null = null;\n\n\t\t\t\tif (podName) {\n\t\t\t\t\tconst config = loadConfig();\n\t\t\t\t\tconst pod = config.pods[podName];\n\t\t\t\t\tif (pod) {\n\t\t\t\t\t\tpodInfo = { name: podName, pod };\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tpodInfo = getActivePod();\n\t\t\t\t}\n\n\t\t\t\tif (!podInfo) {\n\t\t\t\t\tif (podName) {\n\t\t\t\t\t\tconsole.error(chalk.red(`Pod '${podName}' not found`));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.error(chalk.red(\"No active pod. Use 'pi pods active <name>' to set one.\"));\n\t\t\t\t\t}\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\n\t\t\t\tconsole.log(chalk.green(`Connecting to pod '${podInfo.name}'...`));\n\n\t\t\t\t// Execute SSH in interactive mode\n\t\t\t\tconst sshArgs = podInfo.pod.ssh.split(\" \").slice(1); // Remove 'ssh' from command\n\t\t\t\tconst sshProcess = spawn(\"ssh\", sshArgs, {\n\t\t\t\t\tstdio: \"inherit\",\n\t\t\t\t\tenv: process.env,\n\t\t\t\t});\n\n\t\t\t\tsshProcess.on(\"exit\", (code) => {\n\t\t\t\t\tprocess.exit(code || 0);\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"ssh\": {\n\t\t\t\t// pi ssh [<name>] \"<command>\" - run command via SSH\n\t\t\t\tlet podName: string | undefined;\n\t\t\t\tlet sshCommand: string;\n\n\t\t\t\tif (args.length === 2) {\n\t\t\t\t\t// pi ssh \"<command>\" - use active pod\n\t\t\t\t\tsshCommand = args[1];\n\t\t\t\t} else if (args.length === 3) {\n\t\t\t\t\t// pi ssh <name> \"<command>\"\n\t\t\t\t\tpodName = args[1];\n\t\t\t\t\tsshCommand = args[2];\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error('Usage: pi ssh [<name>] \"<command>\"');\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\n\t\t\t\tlet podInfo: { name: string; pod: import(\"./types.js\").Pod } | null = null;\n\n\t\t\t\tif (podName) {\n\t\t\t\t\tconst config = loadConfig();\n\t\t\t\t\tconst pod = config.pods[podName];\n\t\t\t\t\tif (pod) {\n\t\t\t\t\t\tpodInfo = { name: podName, pod };\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tpodInfo = getActivePod();\n\t\t\t\t}\n\n\t\t\t\tif (!podInfo) {\n\t\t\t\t\tif (podName) {\n\t\t\t\t\t\tconsole.error(chalk.red(`Pod '${podName}' not found`));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.error(chalk.red(\"No active pod. Use 'pi pods active <name>' to set one.\"));\n\t\t\t\t\t}\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\n\t\t\t\tconsole.log(chalk.gray(`Running on pod '${podInfo.name}': ${sshCommand}`));\n\n\t\t\t\t// Execute command and stream output\n\t\t\t\tconst exitCode = await sshExecStream(podInfo.pod.ssh, sshCommand);\n\t\t\t\tprocess.exit(exitCode);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"start\": {\n\t\t\t\t// pi start <model> --name <name> [options]\n\t\t\t\tconst modelId = args[1];\n\t\t\t\tif (!modelId) {\n\t\t\t\t\t// Show available models\n\t\t\t\t\tconst { showKnownModels } = await import(\"./commands/models.js\");\n\t\t\t\t\tawait showKnownModels();\n\t\t\t\t\tprocess.exit(0);\n\t\t\t\t}\n\n\t\t\t\t// Parse options\n\t\t\t\tlet name: string | undefined;\n\t\t\t\tlet memory: string | undefined;\n\t\t\t\tlet context: string | undefined;\n\t\t\t\tlet gpus: number | undefined;\n\t\t\t\tconst vllmArgs: string[] = [];\n\t\t\t\tlet inVllmArgs = false;\n\n\t\t\t\tfor (let i = 2; i < args.length; i++) {\n\t\t\t\t\tif (inVllmArgs) {\n\t\t\t\t\t\tvllmArgs.push(args[i]);\n\t\t\t\t\t} else if (args[i] === \"--name\" && i + 1 < args.length) {\n\t\t\t\t\t\tname = args[i + 1];\n\t\t\t\t\t\ti++;\n\t\t\t\t\t} else if (args[i] === \"--memory\" && i + 1 < args.length) {\n\t\t\t\t\t\tmemory = args[i + 1];\n\t\t\t\t\t\ti++;\n\t\t\t\t\t} else if (args[i] === \"--context\" && i + 1 < args.length) {\n\t\t\t\t\t\tcontext = args[i + 1];\n\t\t\t\t\t\ti++;\n\t\t\t\t\t} else if (args[i] === \"--gpus\" && i + 1 < args.length) {\n\t\t\t\t\t\tgpus = parseInt(args[i + 1], 10);\n\t\t\t\t\t\tif (Number.isNaN(gpus) || gpus < 1) {\n\t\t\t\t\t\t\tconsole.error(chalk.red(\"--gpus must be a positive number\"));\n\t\t\t\t\t\t\tprocess.exit(1);\n\t\t\t\t\t\t}\n\t\t\t\t\t\ti++;\n\t\t\t\t\t} else if (args[i] === \"--vllm\") {\n\t\t\t\t\t\tinVllmArgs = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!name) {\n\t\t\t\t\tconsole.error(\"--name is required\");\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\n\t\t\t\t// Warn if --vllm is used with other parameters\n\t\t\t\tif (vllmArgs.length > 0 && (memory || context || gpus)) {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\tchalk.yellow(\"⚠ Warning: --memory, --context, and --gpus are ignored when --vllm is specified\"),\n\t\t\t\t\t);\n\t\t\t\t\tconsole.log(chalk.yellow(\" Using only custom vLLM arguments\"));\n\t\t\t\t\tconsole.log(\"\");\n\t\t\t\t}\n\n\t\t\t\tawait startModel(modelId, name, {\n\t\t\t\t\tpod: podOverride,\n\t\t\t\t\tmemory,\n\t\t\t\t\tcontext,\n\t\t\t\t\tgpus,\n\t\t\t\t\tvllmArgs: vllmArgs.length > 0 ? vllmArgs : undefined,\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"stop\": {\n\t\t\t\t// pi stop [name] - stop specific model or all models\n\t\t\t\tconst name = args[1];\n\t\t\t\tif (!name) {\n\t\t\t\t\t// Stop all models on the active pod\n\t\t\t\t\tconst { stopAllModels } = await import(\"./commands/models.js\");\n\t\t\t\t\tawait stopAllModels({ pod: podOverride });\n\t\t\t\t} else {\n\t\t\t\t\tawait stopModel(name, { pod: podOverride });\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"list\":\n\t\t\t\t// pi list\n\t\t\t\tawait listModels({ pod: podOverride });\n\t\t\t\tbreak;\n\t\t\tcase \"logs\": {\n\t\t\t\t// pi logs <name>\n\t\t\t\tconst name = args[1];\n\t\t\t\tif (!name) {\n\t\t\t\t\tconsole.error(\"Usage: pi logs <name>\");\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tawait viewLogs(name, { pod: podOverride });\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"agent\": {\n\t\t\t\t// pi agent <name> [messages...] [options]\n\t\t\t\tconst name = args[1];\n\t\t\t\tif (!name) {\n\t\t\t\t\tconsole.error(\"Usage: pi agent <name> [messages...] [options]\");\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\n\t\t\t\tconst apiKey = process.env.PI_API_KEY;\n\n\t\t\t\t// Pass all args after the model name\n\t\t\t\tconst agentArgs = args.slice(2);\n\n\t\t\t\t// If no messages provided, it's interactive mode\n\t\t\t\tawait promptModel(name, agentArgs, {\n\t\t\t\t\tpod: podOverride,\n\t\t\t\t\tapiKey,\n\t\t\t\t}).catch(() => {\n\t\t\t\t\t// Error already handled in promptModel, just exit cleanly\n\t\t\t\t\tprocess.exit(0);\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tconsole.error(`Unknown command: ${command}`);\n\t\t\t\tprintHelp();\n\t\t\t\tprocess.exit(1);\n\t\t}\n\t}\n} catch (error) {\n\tconsole.error(\"Error:\", error);\n\tprocess.exit(1);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"","sourcesContent":["#!/usr/bin/env node\nimport chalk from \"chalk\";\nimport { spawn } from \"child_process\";\nimport { readFileSync } from \"fs\";\nimport { dirname, join } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { listModels, showKnownModels, startModel, stopAllModels, stopModel, viewLogs } from \"./commands/models.js\";\nimport { listPods, removePodCommand, setupPod, switchActivePod } from \"./commands/pods.js\";\nimport { promptModel } from \"./commands/prompt.js\";\nimport { getActivePod, loadConfig } from \"./config.js\";\nimport { sshExecStream } from \"./ssh.js\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nconst packageJson = JSON.parse(readFileSync(join(__dirname, \"../package.json\"), \"utf-8\"));\n\nfunction printHelp() {\n\tconsole.log(`pi v${packageJson.version} - Manage vLLM deployments on GPU pods\n\nPod Management:\n pi pods setup <name> \"<ssh>\" --mount \"<mount>\" Setup pod with mount command\n Options:\n --vllm release Install latest vLLM release >=0.10.0 (default)\n --vllm nightly Install vLLM nightly build (latest features)\n --vllm gpt-oss Install vLLM 0.10.1+gptoss with PyTorch nightly (GPT-OSS only)\n pi pods List all pods (* = active)\n pi pods active <name> Switch active pod\n pi pods remove <name> Remove pod from local config\n pi shell [<name>] Open shell on pod (active or specified)\n pi ssh [<name>] \"<command>\" Run SSH command on pod\n\nModel Management:\n pi start <model> --name <name> [options] Start a model\n --memory <percent> GPU memory allocation (30%, 50%, 90%)\n --context <size> Context window (4k, 8k, 16k, 32k, 64k, 128k)\n --gpus <count> Number of GPUs to use (predefined models only)\n --vllm <args...> Pass remaining args to vLLM (ignores other options)\n pi stop [<name>] Stop model (or all if no name)\n pi list List running models\n pi logs <name> Stream model logs\n pi agent <name> [\"<message>\"...] [options] Chat with model using agent & tools\n pi agent <name> [options] Interactive chat mode\n --continue, -c Continue previous session\n --json Output as JSONL\n (All pi-agent options are supported)\n\n All model commands support --pod <name> to override the active pod.\n\nEnvironment:\n HF_TOKEN HuggingFace token for model downloads\n PI_API_KEY API key for vLLM endpoints\n PI_CONFIG_DIR Config directory (default: ~/.pi)`);\n}\n\n// Parse command line arguments\nconst args = process.argv.slice(2);\n\nif (args.length === 0 || args[0] === \"--help\" || args[0] === \"-h\") {\n\tprintHelp();\n\tprocess.exit(0);\n}\n\nif (args[0] === \"--version\" || args[0] === \"-v\") {\n\tconsole.log(packageJson.version);\n\tprocess.exit(0);\n}\n\nconst command = args[0];\nconst subcommand = args[1];\n\n// Main command handler\ntry {\n\t// Handle \"pi pods\" commands\n\tif (command === \"pods\") {\n\t\tif (!subcommand) {\n\t\t\t// pi pods - list all pods\n\t\t\tlistPods();\n\t\t} else if (subcommand === \"setup\") {\n\t\t\t// pi pods setup <name> \"<ssh>\" [--mount \"<mount>\"] [--models-path <path>] [--vllm release|nightly|gpt-oss]\n\t\t\tconst name = args[2];\n\t\t\tconst sshCmd = args[3];\n\n\t\t\tif (!name || !sshCmd) {\n\t\t\t\tconsole.error(\n\t\t\t\t\t'Usage: pi pods setup <name> \"<ssh>\" [--mount \"<mount>\"] [--models-path <path>] [--vllm release|nightly|gpt-oss]',\n\t\t\t\t);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\t// Parse options\n\t\t\tconst options: { mount?: string; modelsPath?: string; vllm?: \"release\" | \"nightly\" | \"gpt-oss\" } = {};\n\t\t\tfor (let i = 4; i < args.length; i++) {\n\t\t\t\tif (args[i] === \"--mount\" && i + 1 < args.length) {\n\t\t\t\t\toptions.mount = args[i + 1];\n\t\t\t\t\ti++;\n\t\t\t\t} else if (args[i] === \"--models-path\" && i + 1 < args.length) {\n\t\t\t\t\toptions.modelsPath = args[i + 1];\n\t\t\t\t\ti++;\n\t\t\t\t} else if (args[i] === \"--vllm\" && i + 1 < args.length) {\n\t\t\t\t\tconst vllmType = args[i + 1];\n\t\t\t\t\tif (vllmType === \"release\" || vllmType === \"nightly\" || vllmType === \"gpt-oss\") {\n\t\t\t\t\t\toptions.vllm = vllmType;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.error(chalk.red(`Invalid vLLM type: ${vllmType}`));\n\t\t\t\t\t\tconsole.error(\"Valid options: release, nightly, gpt-oss\");\n\t\t\t\t\t\tprocess.exit(1);\n\t\t\t\t\t}\n\t\t\t\t\ti++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If --mount provided but no --models-path, try to extract path from mount command\n\t\t\tif (options.mount && !options.modelsPath) {\n\t\t\t\t// Extract last part of mount command as models path\n\t\t\t\tconst parts = options.mount.trim().split(\" \");\n\t\t\t\tconst lastPart = parts[parts.length - 1];\n\t\t\t\tif (lastPart?.startsWith(\"/\")) {\n\t\t\t\t\toptions.modelsPath = lastPart;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tawait setupPod(name, sshCmd, options);\n\t\t} else if (subcommand === \"active\") {\n\t\t\t// pi pods active <name>\n\t\t\tconst name = args[2];\n\t\t\tif (!name) {\n\t\t\t\tconsole.error(\"Usage: pi pods active <name>\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\tswitchActivePod(name);\n\t\t} else if (subcommand === \"remove\") {\n\t\t\t// pi pods remove <name>\n\t\t\tconst name = args[2];\n\t\t\tif (!name) {\n\t\t\t\tconsole.error(\"Usage: pi pods remove <name>\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\tremovePodCommand(name);\n\t\t} else {\n\t\t\tconsole.error(`Unknown pods subcommand: ${subcommand}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t} else {\n\t\t// Parse --pod override for model commands\n\t\tlet podOverride: string | undefined;\n\t\tconst podIndex = args.indexOf(\"--pod\");\n\t\tif (podIndex !== -1 && podIndex + 1 < args.length) {\n\t\t\tpodOverride = args[podIndex + 1];\n\t\t\t// Remove --pod and its value from args\n\t\t\targs.splice(podIndex, 2);\n\t\t}\n\n\t\t// Handle SSH/shell commands and model commands\n\t\tswitch (command) {\n\t\t\tcase \"shell\": {\n\t\t\t\t// pi shell [<name>] - open interactive shell\n\t\t\t\tconst podName = args[1];\n\t\t\t\tlet podInfo: { name: string; pod: import(\"./types.js\").Pod } | null = null;\n\n\t\t\t\tif (podName) {\n\t\t\t\t\tconst config = loadConfig();\n\t\t\t\t\tconst pod = config.pods[podName];\n\t\t\t\t\tif (pod) {\n\t\t\t\t\t\tpodInfo = { name: podName, pod };\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tpodInfo = getActivePod();\n\t\t\t\t}\n\n\t\t\t\tif (!podInfo) {\n\t\t\t\t\tif (podName) {\n\t\t\t\t\t\tconsole.error(chalk.red(`Pod '${podName}' not found`));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.error(chalk.red(\"No active pod. Use 'pi pods active <name>' to set one.\"));\n\t\t\t\t\t}\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\n\t\t\t\tconsole.log(chalk.green(`Connecting to pod '${podInfo.name}'...`));\n\n\t\t\t\t// Execute SSH in interactive mode\n\t\t\t\tconst sshArgs = podInfo.pod.ssh.split(\" \").slice(1); // Remove 'ssh' from command\n\t\t\t\tconst sshProcess = spawn(\"ssh\", sshArgs, {\n\t\t\t\t\tstdio: \"inherit\",\n\t\t\t\t\tenv: process.env,\n\t\t\t\t});\n\n\t\t\t\tsshProcess.on(\"exit\", (code) => {\n\t\t\t\t\tprocess.exit(code || 0);\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"ssh\": {\n\t\t\t\t// pi ssh [<name>] \"<command>\" - run command via SSH\n\t\t\t\tlet podName: string | undefined;\n\t\t\t\tlet sshCommand: string;\n\n\t\t\t\tif (args.length === 2) {\n\t\t\t\t\t// pi ssh \"<command>\" - use active pod\n\t\t\t\t\tsshCommand = args[1];\n\t\t\t\t} else if (args.length === 3) {\n\t\t\t\t\t// pi ssh <name> \"<command>\"\n\t\t\t\t\tpodName = args[1];\n\t\t\t\t\tsshCommand = args[2];\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error('Usage: pi ssh [<name>] \"<command>\"');\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\n\t\t\t\tlet podInfo: { name: string; pod: import(\"./types.js\").Pod } | null = null;\n\n\t\t\t\tif (podName) {\n\t\t\t\t\tconst config = loadConfig();\n\t\t\t\t\tconst pod = config.pods[podName];\n\t\t\t\t\tif (pod) {\n\t\t\t\t\t\tpodInfo = { name: podName, pod };\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tpodInfo = getActivePod();\n\t\t\t\t}\n\n\t\t\t\tif (!podInfo) {\n\t\t\t\t\tif (podName) {\n\t\t\t\t\t\tconsole.error(chalk.red(`Pod '${podName}' not found`));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.error(chalk.red(\"No active pod. Use 'pi pods active <name>' to set one.\"));\n\t\t\t\t\t}\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\n\t\t\t\tconsole.log(chalk.gray(`Running on pod '${podInfo.name}': ${sshCommand}`));\n\n\t\t\t\t// Execute command and stream output\n\t\t\t\tconst exitCode = await sshExecStream(podInfo.pod.ssh, sshCommand);\n\t\t\t\tprocess.exit(exitCode);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"start\": {\n\t\t\t\t// pi start <model> --name <name> [options]\n\t\t\t\tconst modelId = args[1];\n\t\t\t\tif (!modelId) {\n\t\t\t\t\t// Show available models\n\t\t\t\t\tawait showKnownModels();\n\t\t\t\t\tprocess.exit(0);\n\t\t\t\t}\n\n\t\t\t\t// Parse options\n\t\t\t\tlet name: string | undefined;\n\t\t\t\tlet memory: string | undefined;\n\t\t\t\tlet context: string | undefined;\n\t\t\t\tlet gpus: number | undefined;\n\t\t\t\tconst vllmArgs: string[] = [];\n\t\t\t\tlet inVllmArgs = false;\n\n\t\t\t\tfor (let i = 2; i < args.length; i++) {\n\t\t\t\t\tif (inVllmArgs) {\n\t\t\t\t\t\tvllmArgs.push(args[i]);\n\t\t\t\t\t} else if (args[i] === \"--name\" && i + 1 < args.length) {\n\t\t\t\t\t\tname = args[i + 1];\n\t\t\t\t\t\ti++;\n\t\t\t\t\t} else if (args[i] === \"--memory\" && i + 1 < args.length) {\n\t\t\t\t\t\tmemory = args[i + 1];\n\t\t\t\t\t\ti++;\n\t\t\t\t\t} else if (args[i] === \"--context\" && i + 1 < args.length) {\n\t\t\t\t\t\tcontext = args[i + 1];\n\t\t\t\t\t\ti++;\n\t\t\t\t\t} else if (args[i] === \"--gpus\" && i + 1 < args.length) {\n\t\t\t\t\t\tgpus = parseInt(args[i + 1], 10);\n\t\t\t\t\t\tif (Number.isNaN(gpus) || gpus < 1) {\n\t\t\t\t\t\t\tconsole.error(chalk.red(\"--gpus must be a positive number\"));\n\t\t\t\t\t\t\tprocess.exit(1);\n\t\t\t\t\t\t}\n\t\t\t\t\t\ti++;\n\t\t\t\t\t} else if (args[i] === \"--vllm\") {\n\t\t\t\t\t\tinVllmArgs = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!name) {\n\t\t\t\t\tconsole.error(\"--name is required\");\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\n\t\t\t\t// Warn if --vllm is used with other parameters\n\t\t\t\tif (vllmArgs.length > 0 && (memory || context || gpus)) {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\tchalk.yellow(\"⚠ Warning: --memory, --context, and --gpus are ignored when --vllm is specified\"),\n\t\t\t\t\t);\n\t\t\t\t\tconsole.log(chalk.yellow(\" Using only custom vLLM arguments\"));\n\t\t\t\t\tconsole.log(\"\");\n\t\t\t\t}\n\n\t\t\t\tawait startModel(modelId, name, {\n\t\t\t\t\tpod: podOverride,\n\t\t\t\t\tmemory,\n\t\t\t\t\tcontext,\n\t\t\t\t\tgpus,\n\t\t\t\t\tvllmArgs: vllmArgs.length > 0 ? vllmArgs : undefined,\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"stop\": {\n\t\t\t\t// pi stop [name] - stop specific model or all models\n\t\t\t\tconst name = args[1];\n\t\t\t\tif (!name) {\n\t\t\t\t\t// Stop all models on the active pod\n\t\t\t\t\tawait stopAllModels({ pod: podOverride });\n\t\t\t\t} else {\n\t\t\t\t\tawait stopModel(name, { pod: podOverride });\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"list\":\n\t\t\t\t// pi list\n\t\t\t\tawait listModels({ pod: podOverride });\n\t\t\t\tbreak;\n\t\t\tcase \"logs\": {\n\t\t\t\t// pi logs <name>\n\t\t\t\tconst name = args[1];\n\t\t\t\tif (!name) {\n\t\t\t\t\tconsole.error(\"Usage: pi logs <name>\");\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tawait viewLogs(name, { pod: podOverride });\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"agent\": {\n\t\t\t\t// pi agent <name> [messages...] [options]\n\t\t\t\tconst name = args[1];\n\t\t\t\tif (!name) {\n\t\t\t\t\tconsole.error(\"Usage: pi agent <name> [messages...] [options]\");\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\n\t\t\t\tconst apiKey = process.env.PI_API_KEY;\n\n\t\t\t\t// Pass all args after the model name\n\t\t\t\tconst agentArgs = args.slice(2);\n\n\t\t\t\t// If no messages provided, it's interactive mode\n\t\t\t\tawait promptModel(name, agentArgs, {\n\t\t\t\t\tpod: podOverride,\n\t\t\t\t\tapiKey,\n\t\t\t\t}).catch(() => {\n\t\t\t\t\t// Error already handled in promptModel, just exit cleanly\n\t\t\t\t\tprocess.exit(0);\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tconsole.error(`Unknown command: ${command}`);\n\t\t\t\tprintHelp();\n\t\t\t\tprocess.exit(1);\n\t\t}\n\t}\n} catch (error) {\n\tconsole.error(\"Error:\", error);\n\tprocess.exit(1);\n}\n"]}
|
package/dist/cli.js
CHANGED
|
@@ -4,7 +4,7 @@ import { spawn } from "child_process";
|
|
|
4
4
|
import { readFileSync } from "fs";
|
|
5
5
|
import { dirname, join } from "path";
|
|
6
6
|
import { fileURLToPath } from "url";
|
|
7
|
-
import { listModels, startModel, stopModel, viewLogs } from "./commands/models.js";
|
|
7
|
+
import { listModels, showKnownModels, startModel, stopAllModels, stopModel, viewLogs } from "./commands/models.js";
|
|
8
8
|
import { listPods, removePodCommand, setupPod, switchActivePod } from "./commands/pods.js";
|
|
9
9
|
import { promptModel } from "./commands/prompt.js";
|
|
10
10
|
import { getActivePod, loadConfig } from "./config.js";
|
|
@@ -229,7 +229,6 @@ try {
|
|
|
229
229
|
const modelId = args[1];
|
|
230
230
|
if (!modelId) {
|
|
231
231
|
// Show available models
|
|
232
|
-
const { showKnownModels } = await import("./commands/models.js");
|
|
233
232
|
await showKnownModels();
|
|
234
233
|
process.exit(0);
|
|
235
234
|
}
|
|
@@ -292,7 +291,6 @@ try {
|
|
|
292
291
|
const name = args[1];
|
|
293
292
|
if (!name) {
|
|
294
293
|
// Stop all models on the active pod
|
|
295
|
-
const { stopAllModels } = await import("./commands/models.js");
|
|
296
294
|
await stopAllModels({ pod: podOverride });
|
|
297
295
|
}
|
|
298
296
|
else {
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\nimport chalk from \"chalk\";\nimport { spawn } from \"child_process\";\nimport { readFileSync } from \"fs\";\nimport { dirname, join } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { listModels, startModel, stopModel, viewLogs } from \"./commands/models.js\";\nimport { listPods, removePodCommand, setupPod, switchActivePod } from \"./commands/pods.js\";\nimport { promptModel } from \"./commands/prompt.js\";\nimport { getActivePod, loadConfig } from \"./config.js\";\nimport { sshExecStream } from \"./ssh.js\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nconst packageJson = JSON.parse(readFileSync(join(__dirname, \"../package.json\"), \"utf-8\"));\n\nfunction printHelp() {\n\tconsole.log(`pi v${packageJson.version} - Manage vLLM deployments on GPU pods\n\nPod Management:\n pi pods setup <name> \"<ssh>\" --mount \"<mount>\" Setup pod with mount command\n Options:\n --vllm release Install latest vLLM release >=0.10.0 (default)\n --vllm nightly Install vLLM nightly build (latest features)\n --vllm gpt-oss Install vLLM 0.10.1+gptoss with PyTorch nightly (GPT-OSS only)\n pi pods List all pods (* = active)\n pi pods active <name> Switch active pod\n pi pods remove <name> Remove pod from local config\n pi shell [<name>] Open shell on pod (active or specified)\n pi ssh [<name>] \"<command>\" Run SSH command on pod\n\nModel Management:\n pi start <model> --name <name> [options] Start a model\n --memory <percent> GPU memory allocation (30%, 50%, 90%)\n --context <size> Context window (4k, 8k, 16k, 32k, 64k, 128k)\n --gpus <count> Number of GPUs to use (predefined models only)\n --vllm <args...> Pass remaining args to vLLM (ignores other options)\n pi stop [<name>] Stop model (or all if no name)\n pi list List running models\n pi logs <name> Stream model logs\n pi agent <name> [\"<message>\"...] [options] Chat with model using agent & tools\n pi agent <name> [options] Interactive chat mode\n --continue, -c Continue previous session\n --json Output as JSONL\n (All pi-agent options are supported)\n\n All model commands support --pod <name> to override the active pod.\n\nEnvironment:\n HF_TOKEN HuggingFace token for model downloads\n PI_API_KEY API key for vLLM endpoints\n PI_CONFIG_DIR Config directory (default: ~/.pi)`);\n}\n\n// Parse command line arguments\nconst args = process.argv.slice(2);\n\nif (args.length === 0 || args[0] === \"--help\" || args[0] === \"-h\") {\n\tprintHelp();\n\tprocess.exit(0);\n}\n\nif (args[0] === \"--version\" || args[0] === \"-v\") {\n\tconsole.log(packageJson.version);\n\tprocess.exit(0);\n}\n\nconst command = args[0];\nconst subcommand = args[1];\n\n// Main command handler\ntry {\n\t// Handle \"pi pods\" commands\n\tif (command === \"pods\") {\n\t\tif (!subcommand) {\n\t\t\t// pi pods - list all pods\n\t\t\tlistPods();\n\t\t} else if (subcommand === \"setup\") {\n\t\t\t// pi pods setup <name> \"<ssh>\" [--mount \"<mount>\"] [--models-path <path>] [--vllm release|nightly|gpt-oss]\n\t\t\tconst name = args[2];\n\t\t\tconst sshCmd = args[3];\n\n\t\t\tif (!name || !sshCmd) {\n\t\t\t\tconsole.error(\n\t\t\t\t\t'Usage: pi pods setup <name> \"<ssh>\" [--mount \"<mount>\"] [--models-path <path>] [--vllm release|nightly|gpt-oss]',\n\t\t\t\t);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\t// Parse options\n\t\t\tconst options: { mount?: string; modelsPath?: string; vllm?: \"release\" | \"nightly\" | \"gpt-oss\" } = {};\n\t\t\tfor (let i = 4; i < args.length; i++) {\n\t\t\t\tif (args[i] === \"--mount\" && i + 1 < args.length) {\n\t\t\t\t\toptions.mount = args[i + 1];\n\t\t\t\t\ti++;\n\t\t\t\t} else if (args[i] === \"--models-path\" && i + 1 < args.length) {\n\t\t\t\t\toptions.modelsPath = args[i + 1];\n\t\t\t\t\ti++;\n\t\t\t\t} else if (args[i] === \"--vllm\" && i + 1 < args.length) {\n\t\t\t\t\tconst vllmType = args[i + 1];\n\t\t\t\t\tif (vllmType === \"release\" || vllmType === \"nightly\" || vllmType === \"gpt-oss\") {\n\t\t\t\t\t\toptions.vllm = vllmType;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.error(chalk.red(`Invalid vLLM type: ${vllmType}`));\n\t\t\t\t\t\tconsole.error(\"Valid options: release, nightly, gpt-oss\");\n\t\t\t\t\t\tprocess.exit(1);\n\t\t\t\t\t}\n\t\t\t\t\ti++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If --mount provided but no --models-path, try to extract path from mount command\n\t\t\tif (options.mount && !options.modelsPath) {\n\t\t\t\t// Extract last part of mount command as models path\n\t\t\t\tconst parts = options.mount.trim().split(\" \");\n\t\t\t\tconst lastPart = parts[parts.length - 1];\n\t\t\t\tif (lastPart?.startsWith(\"/\")) {\n\t\t\t\t\toptions.modelsPath = lastPart;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tawait setupPod(name, sshCmd, options);\n\t\t} else if (subcommand === \"active\") {\n\t\t\t// pi pods active <name>\n\t\t\tconst name = args[2];\n\t\t\tif (!name) {\n\t\t\t\tconsole.error(\"Usage: pi pods active <name>\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\tswitchActivePod(name);\n\t\t} else if (subcommand === \"remove\") {\n\t\t\t// pi pods remove <name>\n\t\t\tconst name = args[2];\n\t\t\tif (!name) {\n\t\t\t\tconsole.error(\"Usage: pi pods remove <name>\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\tremovePodCommand(name);\n\t\t} else {\n\t\t\tconsole.error(`Unknown pods subcommand: ${subcommand}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t} else {\n\t\t// Parse --pod override for model commands\n\t\tlet podOverride: string | undefined;\n\t\tconst podIndex = args.indexOf(\"--pod\");\n\t\tif (podIndex !== -1 && podIndex + 1 < args.length) {\n\t\t\tpodOverride = args[podIndex + 1];\n\t\t\t// Remove --pod and its value from args\n\t\t\targs.splice(podIndex, 2);\n\t\t}\n\n\t\t// Handle SSH/shell commands and model commands\n\t\tswitch (command) {\n\t\t\tcase \"shell\": {\n\t\t\t\t// pi shell [<name>] - open interactive shell\n\t\t\t\tconst podName = args[1];\n\t\t\t\tlet podInfo: { name: string; pod: import(\"./types.js\").Pod } | null = null;\n\n\t\t\t\tif (podName) {\n\t\t\t\t\tconst config = loadConfig();\n\t\t\t\t\tconst pod = config.pods[podName];\n\t\t\t\t\tif (pod) {\n\t\t\t\t\t\tpodInfo = { name: podName, pod };\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tpodInfo = getActivePod();\n\t\t\t\t}\n\n\t\t\t\tif (!podInfo) {\n\t\t\t\t\tif (podName) {\n\t\t\t\t\t\tconsole.error(chalk.red(`Pod '${podName}' not found`));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.error(chalk.red(\"No active pod. Use 'pi pods active <name>' to set one.\"));\n\t\t\t\t\t}\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\n\t\t\t\tconsole.log(chalk.green(`Connecting to pod '${podInfo.name}'...`));\n\n\t\t\t\t// Execute SSH in interactive mode\n\t\t\t\tconst sshArgs = podInfo.pod.ssh.split(\" \").slice(1); // Remove 'ssh' from command\n\t\t\t\tconst sshProcess = spawn(\"ssh\", sshArgs, {\n\t\t\t\t\tstdio: \"inherit\",\n\t\t\t\t\tenv: process.env,\n\t\t\t\t});\n\n\t\t\t\tsshProcess.on(\"exit\", (code) => {\n\t\t\t\t\tprocess.exit(code || 0);\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"ssh\": {\n\t\t\t\t// pi ssh [<name>] \"<command>\" - run command via SSH\n\t\t\t\tlet podName: string | undefined;\n\t\t\t\tlet sshCommand: string;\n\n\t\t\t\tif (args.length === 2) {\n\t\t\t\t\t// pi ssh \"<command>\" - use active pod\n\t\t\t\t\tsshCommand = args[1];\n\t\t\t\t} else if (args.length === 3) {\n\t\t\t\t\t// pi ssh <name> \"<command>\"\n\t\t\t\t\tpodName = args[1];\n\t\t\t\t\tsshCommand = args[2];\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error('Usage: pi ssh [<name>] \"<command>\"');\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\n\t\t\t\tlet podInfo: { name: string; pod: import(\"./types.js\").Pod } | null = null;\n\n\t\t\t\tif (podName) {\n\t\t\t\t\tconst config = loadConfig();\n\t\t\t\t\tconst pod = config.pods[podName];\n\t\t\t\t\tif (pod) {\n\t\t\t\t\t\tpodInfo = { name: podName, pod };\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tpodInfo = getActivePod();\n\t\t\t\t}\n\n\t\t\t\tif (!podInfo) {\n\t\t\t\t\tif (podName) {\n\t\t\t\t\t\tconsole.error(chalk.red(`Pod '${podName}' not found`));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.error(chalk.red(\"No active pod. Use 'pi pods active <name>' to set one.\"));\n\t\t\t\t\t}\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\n\t\t\t\tconsole.log(chalk.gray(`Running on pod '${podInfo.name}': ${sshCommand}`));\n\n\t\t\t\t// Execute command and stream output\n\t\t\t\tconst exitCode = await sshExecStream(podInfo.pod.ssh, sshCommand);\n\t\t\t\tprocess.exit(exitCode);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"start\": {\n\t\t\t\t// pi start <model> --name <name> [options]\n\t\t\t\tconst modelId = args[1];\n\t\t\t\tif (!modelId) {\n\t\t\t\t\t// Show available models\n\t\t\t\t\tconst { showKnownModels } = await import(\"./commands/models.js\");\n\t\t\t\t\tawait showKnownModels();\n\t\t\t\t\tprocess.exit(0);\n\t\t\t\t}\n\n\t\t\t\t// Parse options\n\t\t\t\tlet name: string | undefined;\n\t\t\t\tlet memory: string | undefined;\n\t\t\t\tlet context: string | undefined;\n\t\t\t\tlet gpus: number | undefined;\n\t\t\t\tconst vllmArgs: string[] = [];\n\t\t\t\tlet inVllmArgs = false;\n\n\t\t\t\tfor (let i = 2; i < args.length; i++) {\n\t\t\t\t\tif (inVllmArgs) {\n\t\t\t\t\t\tvllmArgs.push(args[i]);\n\t\t\t\t\t} else if (args[i] === \"--name\" && i + 1 < args.length) {\n\t\t\t\t\t\tname = args[i + 1];\n\t\t\t\t\t\ti++;\n\t\t\t\t\t} else if (args[i] === \"--memory\" && i + 1 < args.length) {\n\t\t\t\t\t\tmemory = args[i + 1];\n\t\t\t\t\t\ti++;\n\t\t\t\t\t} else if (args[i] === \"--context\" && i + 1 < args.length) {\n\t\t\t\t\t\tcontext = args[i + 1];\n\t\t\t\t\t\ti++;\n\t\t\t\t\t} else if (args[i] === \"--gpus\" && i + 1 < args.length) {\n\t\t\t\t\t\tgpus = parseInt(args[i + 1], 10);\n\t\t\t\t\t\tif (Number.isNaN(gpus) || gpus < 1) {\n\t\t\t\t\t\t\tconsole.error(chalk.red(\"--gpus must be a positive number\"));\n\t\t\t\t\t\t\tprocess.exit(1);\n\t\t\t\t\t\t}\n\t\t\t\t\t\ti++;\n\t\t\t\t\t} else if (args[i] === \"--vllm\") {\n\t\t\t\t\t\tinVllmArgs = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!name) {\n\t\t\t\t\tconsole.error(\"--name is required\");\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\n\t\t\t\t// Warn if --vllm is used with other parameters\n\t\t\t\tif (vllmArgs.length > 0 && (memory || context || gpus)) {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\tchalk.yellow(\"⚠ Warning: --memory, --context, and --gpus are ignored when --vllm is specified\"),\n\t\t\t\t\t);\n\t\t\t\t\tconsole.log(chalk.yellow(\" Using only custom vLLM arguments\"));\n\t\t\t\t\tconsole.log(\"\");\n\t\t\t\t}\n\n\t\t\t\tawait startModel(modelId, name, {\n\t\t\t\t\tpod: podOverride,\n\t\t\t\t\tmemory,\n\t\t\t\t\tcontext,\n\t\t\t\t\tgpus,\n\t\t\t\t\tvllmArgs: vllmArgs.length > 0 ? vllmArgs : undefined,\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"stop\": {\n\t\t\t\t// pi stop [name] - stop specific model or all models\n\t\t\t\tconst name = args[1];\n\t\t\t\tif (!name) {\n\t\t\t\t\t// Stop all models on the active pod\n\t\t\t\t\tconst { stopAllModels } = await import(\"./commands/models.js\");\n\t\t\t\t\tawait stopAllModels({ pod: podOverride });\n\t\t\t\t} else {\n\t\t\t\t\tawait stopModel(name, { pod: podOverride });\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"list\":\n\t\t\t\t// pi list\n\t\t\t\tawait listModels({ pod: podOverride });\n\t\t\t\tbreak;\n\t\t\tcase \"logs\": {\n\t\t\t\t// pi logs <name>\n\t\t\t\tconst name = args[1];\n\t\t\t\tif (!name) {\n\t\t\t\t\tconsole.error(\"Usage: pi logs <name>\");\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tawait viewLogs(name, { pod: podOverride });\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"agent\": {\n\t\t\t\t// pi agent <name> [messages...] [options]\n\t\t\t\tconst name = args[1];\n\t\t\t\tif (!name) {\n\t\t\t\t\tconsole.error(\"Usage: pi agent <name> [messages...] [options]\");\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\n\t\t\t\tconst apiKey = process.env.PI_API_KEY;\n\n\t\t\t\t// Pass all args after the model name\n\t\t\t\tconst agentArgs = args.slice(2);\n\n\t\t\t\t// If no messages provided, it's interactive mode\n\t\t\t\tawait promptModel(name, agentArgs, {\n\t\t\t\t\tpod: podOverride,\n\t\t\t\t\tapiKey,\n\t\t\t\t}).catch(() => {\n\t\t\t\t\t// Error already handled in promptModel, just exit cleanly\n\t\t\t\t\tprocess.exit(0);\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tconsole.error(`Unknown command: ${command}`);\n\t\t\t\tprintHelp();\n\t\t\t\tprocess.exit(1);\n\t\t}\n\t}\n} catch (error) {\n\tconsole.error(\"Error:\", error);\n\tprocess.exit(1);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\nimport chalk from \"chalk\";\nimport { spawn } from \"child_process\";\nimport { readFileSync } from \"fs\";\nimport { dirname, join } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { listModels, showKnownModels, startModel, stopAllModels, stopModel, viewLogs } from \"./commands/models.js\";\nimport { listPods, removePodCommand, setupPod, switchActivePod } from \"./commands/pods.js\";\nimport { promptModel } from \"./commands/prompt.js\";\nimport { getActivePod, loadConfig } from \"./config.js\";\nimport { sshExecStream } from \"./ssh.js\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nconst packageJson = JSON.parse(readFileSync(join(__dirname, \"../package.json\"), \"utf-8\"));\n\nfunction printHelp() {\n\tconsole.log(`pi v${packageJson.version} - Manage vLLM deployments on GPU pods\n\nPod Management:\n pi pods setup <name> \"<ssh>\" --mount \"<mount>\" Setup pod with mount command\n Options:\n --vllm release Install latest vLLM release >=0.10.0 (default)\n --vllm nightly Install vLLM nightly build (latest features)\n --vllm gpt-oss Install vLLM 0.10.1+gptoss with PyTorch nightly (GPT-OSS only)\n pi pods List all pods (* = active)\n pi pods active <name> Switch active pod\n pi pods remove <name> Remove pod from local config\n pi shell [<name>] Open shell on pod (active or specified)\n pi ssh [<name>] \"<command>\" Run SSH command on pod\n\nModel Management:\n pi start <model> --name <name> [options] Start a model\n --memory <percent> GPU memory allocation (30%, 50%, 90%)\n --context <size> Context window (4k, 8k, 16k, 32k, 64k, 128k)\n --gpus <count> Number of GPUs to use (predefined models only)\n --vllm <args...> Pass remaining args to vLLM (ignores other options)\n pi stop [<name>] Stop model (or all if no name)\n pi list List running models\n pi logs <name> Stream model logs\n pi agent <name> [\"<message>\"...] [options] Chat with model using agent & tools\n pi agent <name> [options] Interactive chat mode\n --continue, -c Continue previous session\n --json Output as JSONL\n (All pi-agent options are supported)\n\n All model commands support --pod <name> to override the active pod.\n\nEnvironment:\n HF_TOKEN HuggingFace token for model downloads\n PI_API_KEY API key for vLLM endpoints\n PI_CONFIG_DIR Config directory (default: ~/.pi)`);\n}\n\n// Parse command line arguments\nconst args = process.argv.slice(2);\n\nif (args.length === 0 || args[0] === \"--help\" || args[0] === \"-h\") {\n\tprintHelp();\n\tprocess.exit(0);\n}\n\nif (args[0] === \"--version\" || args[0] === \"-v\") {\n\tconsole.log(packageJson.version);\n\tprocess.exit(0);\n}\n\nconst command = args[0];\nconst subcommand = args[1];\n\n// Main command handler\ntry {\n\t// Handle \"pi pods\" commands\n\tif (command === \"pods\") {\n\t\tif (!subcommand) {\n\t\t\t// pi pods - list all pods\n\t\t\tlistPods();\n\t\t} else if (subcommand === \"setup\") {\n\t\t\t// pi pods setup <name> \"<ssh>\" [--mount \"<mount>\"] [--models-path <path>] [--vllm release|nightly|gpt-oss]\n\t\t\tconst name = args[2];\n\t\t\tconst sshCmd = args[3];\n\n\t\t\tif (!name || !sshCmd) {\n\t\t\t\tconsole.error(\n\t\t\t\t\t'Usage: pi pods setup <name> \"<ssh>\" [--mount \"<mount>\"] [--models-path <path>] [--vllm release|nightly|gpt-oss]',\n\t\t\t\t);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\t// Parse options\n\t\t\tconst options: { mount?: string; modelsPath?: string; vllm?: \"release\" | \"nightly\" | \"gpt-oss\" } = {};\n\t\t\tfor (let i = 4; i < args.length; i++) {\n\t\t\t\tif (args[i] === \"--mount\" && i + 1 < args.length) {\n\t\t\t\t\toptions.mount = args[i + 1];\n\t\t\t\t\ti++;\n\t\t\t\t} else if (args[i] === \"--models-path\" && i + 1 < args.length) {\n\t\t\t\t\toptions.modelsPath = args[i + 1];\n\t\t\t\t\ti++;\n\t\t\t\t} else if (args[i] === \"--vllm\" && i + 1 < args.length) {\n\t\t\t\t\tconst vllmType = args[i + 1];\n\t\t\t\t\tif (vllmType === \"release\" || vllmType === \"nightly\" || vllmType === \"gpt-oss\") {\n\t\t\t\t\t\toptions.vllm = vllmType;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.error(chalk.red(`Invalid vLLM type: ${vllmType}`));\n\t\t\t\t\t\tconsole.error(\"Valid options: release, nightly, gpt-oss\");\n\t\t\t\t\t\tprocess.exit(1);\n\t\t\t\t\t}\n\t\t\t\t\ti++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If --mount provided but no --models-path, try to extract path from mount command\n\t\t\tif (options.mount && !options.modelsPath) {\n\t\t\t\t// Extract last part of mount command as models path\n\t\t\t\tconst parts = options.mount.trim().split(\" \");\n\t\t\t\tconst lastPart = parts[parts.length - 1];\n\t\t\t\tif (lastPart?.startsWith(\"/\")) {\n\t\t\t\t\toptions.modelsPath = lastPart;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tawait setupPod(name, sshCmd, options);\n\t\t} else if (subcommand === \"active\") {\n\t\t\t// pi pods active <name>\n\t\t\tconst name = args[2];\n\t\t\tif (!name) {\n\t\t\t\tconsole.error(\"Usage: pi pods active <name>\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\tswitchActivePod(name);\n\t\t} else if (subcommand === \"remove\") {\n\t\t\t// pi pods remove <name>\n\t\t\tconst name = args[2];\n\t\t\tif (!name) {\n\t\t\t\tconsole.error(\"Usage: pi pods remove <name>\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\tremovePodCommand(name);\n\t\t} else {\n\t\t\tconsole.error(`Unknown pods subcommand: ${subcommand}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t} else {\n\t\t// Parse --pod override for model commands\n\t\tlet podOverride: string | undefined;\n\t\tconst podIndex = args.indexOf(\"--pod\");\n\t\tif (podIndex !== -1 && podIndex + 1 < args.length) {\n\t\t\tpodOverride = args[podIndex + 1];\n\t\t\t// Remove --pod and its value from args\n\t\t\targs.splice(podIndex, 2);\n\t\t}\n\n\t\t// Handle SSH/shell commands and model commands\n\t\tswitch (command) {\n\t\t\tcase \"shell\": {\n\t\t\t\t// pi shell [<name>] - open interactive shell\n\t\t\t\tconst podName = args[1];\n\t\t\t\tlet podInfo: { name: string; pod: import(\"./types.js\").Pod } | null = null;\n\n\t\t\t\tif (podName) {\n\t\t\t\t\tconst config = loadConfig();\n\t\t\t\t\tconst pod = config.pods[podName];\n\t\t\t\t\tif (pod) {\n\t\t\t\t\t\tpodInfo = { name: podName, pod };\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tpodInfo = getActivePod();\n\t\t\t\t}\n\n\t\t\t\tif (!podInfo) {\n\t\t\t\t\tif (podName) {\n\t\t\t\t\t\tconsole.error(chalk.red(`Pod '${podName}' not found`));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.error(chalk.red(\"No active pod. Use 'pi pods active <name>' to set one.\"));\n\t\t\t\t\t}\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\n\t\t\t\tconsole.log(chalk.green(`Connecting to pod '${podInfo.name}'...`));\n\n\t\t\t\t// Execute SSH in interactive mode\n\t\t\t\tconst sshArgs = podInfo.pod.ssh.split(\" \").slice(1); // Remove 'ssh' from command\n\t\t\t\tconst sshProcess = spawn(\"ssh\", sshArgs, {\n\t\t\t\t\tstdio: \"inherit\",\n\t\t\t\t\tenv: process.env,\n\t\t\t\t});\n\n\t\t\t\tsshProcess.on(\"exit\", (code) => {\n\t\t\t\t\tprocess.exit(code || 0);\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"ssh\": {\n\t\t\t\t// pi ssh [<name>] \"<command>\" - run command via SSH\n\t\t\t\tlet podName: string | undefined;\n\t\t\t\tlet sshCommand: string;\n\n\t\t\t\tif (args.length === 2) {\n\t\t\t\t\t// pi ssh \"<command>\" - use active pod\n\t\t\t\t\tsshCommand = args[1];\n\t\t\t\t} else if (args.length === 3) {\n\t\t\t\t\t// pi ssh <name> \"<command>\"\n\t\t\t\t\tpodName = args[1];\n\t\t\t\t\tsshCommand = args[2];\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error('Usage: pi ssh [<name>] \"<command>\"');\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\n\t\t\t\tlet podInfo: { name: string; pod: import(\"./types.js\").Pod } | null = null;\n\n\t\t\t\tif (podName) {\n\t\t\t\t\tconst config = loadConfig();\n\t\t\t\t\tconst pod = config.pods[podName];\n\t\t\t\t\tif (pod) {\n\t\t\t\t\t\tpodInfo = { name: podName, pod };\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tpodInfo = getActivePod();\n\t\t\t\t}\n\n\t\t\t\tif (!podInfo) {\n\t\t\t\t\tif (podName) {\n\t\t\t\t\t\tconsole.error(chalk.red(`Pod '${podName}' not found`));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.error(chalk.red(\"No active pod. Use 'pi pods active <name>' to set one.\"));\n\t\t\t\t\t}\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\n\t\t\t\tconsole.log(chalk.gray(`Running on pod '${podInfo.name}': ${sshCommand}`));\n\n\t\t\t\t// Execute command and stream output\n\t\t\t\tconst exitCode = await sshExecStream(podInfo.pod.ssh, sshCommand);\n\t\t\t\tprocess.exit(exitCode);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"start\": {\n\t\t\t\t// pi start <model> --name <name> [options]\n\t\t\t\tconst modelId = args[1];\n\t\t\t\tif (!modelId) {\n\t\t\t\t\t// Show available models\n\t\t\t\t\tawait showKnownModels();\n\t\t\t\t\tprocess.exit(0);\n\t\t\t\t}\n\n\t\t\t\t// Parse options\n\t\t\t\tlet name: string | undefined;\n\t\t\t\tlet memory: string | undefined;\n\t\t\t\tlet context: string | undefined;\n\t\t\t\tlet gpus: number | undefined;\n\t\t\t\tconst vllmArgs: string[] = [];\n\t\t\t\tlet inVllmArgs = false;\n\n\t\t\t\tfor (let i = 2; i < args.length; i++) {\n\t\t\t\t\tif (inVllmArgs) {\n\t\t\t\t\t\tvllmArgs.push(args[i]);\n\t\t\t\t\t} else if (args[i] === \"--name\" && i + 1 < args.length) {\n\t\t\t\t\t\tname = args[i + 1];\n\t\t\t\t\t\ti++;\n\t\t\t\t\t} else if (args[i] === \"--memory\" && i + 1 < args.length) {\n\t\t\t\t\t\tmemory = args[i + 1];\n\t\t\t\t\t\ti++;\n\t\t\t\t\t} else if (args[i] === \"--context\" && i + 1 < args.length) {\n\t\t\t\t\t\tcontext = args[i + 1];\n\t\t\t\t\t\ti++;\n\t\t\t\t\t} else if (args[i] === \"--gpus\" && i + 1 < args.length) {\n\t\t\t\t\t\tgpus = parseInt(args[i + 1], 10);\n\t\t\t\t\t\tif (Number.isNaN(gpus) || gpus < 1) {\n\t\t\t\t\t\t\tconsole.error(chalk.red(\"--gpus must be a positive number\"));\n\t\t\t\t\t\t\tprocess.exit(1);\n\t\t\t\t\t\t}\n\t\t\t\t\t\ti++;\n\t\t\t\t\t} else if (args[i] === \"--vllm\") {\n\t\t\t\t\t\tinVllmArgs = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!name) {\n\t\t\t\t\tconsole.error(\"--name is required\");\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\n\t\t\t\t// Warn if --vllm is used with other parameters\n\t\t\t\tif (vllmArgs.length > 0 && (memory || context || gpus)) {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\tchalk.yellow(\"⚠ Warning: --memory, --context, and --gpus are ignored when --vllm is specified\"),\n\t\t\t\t\t);\n\t\t\t\t\tconsole.log(chalk.yellow(\" Using only custom vLLM arguments\"));\n\t\t\t\t\tconsole.log(\"\");\n\t\t\t\t}\n\n\t\t\t\tawait startModel(modelId, name, {\n\t\t\t\t\tpod: podOverride,\n\t\t\t\t\tmemory,\n\t\t\t\t\tcontext,\n\t\t\t\t\tgpus,\n\t\t\t\t\tvllmArgs: vllmArgs.length > 0 ? vllmArgs : undefined,\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"stop\": {\n\t\t\t\t// pi stop [name] - stop specific model or all models\n\t\t\t\tconst name = args[1];\n\t\t\t\tif (!name) {\n\t\t\t\t\t// Stop all models on the active pod\n\t\t\t\t\tawait stopAllModels({ pod: podOverride });\n\t\t\t\t} else {\n\t\t\t\t\tawait stopModel(name, { pod: podOverride });\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"list\":\n\t\t\t\t// pi list\n\t\t\t\tawait listModels({ pod: podOverride });\n\t\t\t\tbreak;\n\t\t\tcase \"logs\": {\n\t\t\t\t// pi logs <name>\n\t\t\t\tconst name = args[1];\n\t\t\t\tif (!name) {\n\t\t\t\t\tconsole.error(\"Usage: pi logs <name>\");\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tawait viewLogs(name, { pod: podOverride });\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"agent\": {\n\t\t\t\t// pi agent <name> [messages...] [options]\n\t\t\t\tconst name = args[1];\n\t\t\t\tif (!name) {\n\t\t\t\t\tconsole.error(\"Usage: pi agent <name> [messages...] [options]\");\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\n\t\t\t\tconst apiKey = process.env.PI_API_KEY;\n\n\t\t\t\t// Pass all args after the model name\n\t\t\t\tconst agentArgs = args.slice(2);\n\n\t\t\t\t// If no messages provided, it's interactive mode\n\t\t\t\tawait promptModel(name, agentArgs, {\n\t\t\t\t\tpod: podOverride,\n\t\t\t\t\tapiKey,\n\t\t\t\t}).catch(() => {\n\t\t\t\t\t// Error already handled in promptModel, just exit cleanly\n\t\t\t\t\tprocess.exit(0);\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tconsole.error(`Unknown command: ${command}`);\n\t\t\t\tprintHelp();\n\t\t\t\tprocess.exit(1);\n\t\t}\n\t}\n} catch (error) {\n\tconsole.error(\"Error:\", error);\n\tprocess.exit(1);\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mariozechner/pi",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.31.0",
|
|
4
4
|
"description": "CLI tool for managing vLLM deployments on GPU pods",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"node": ">=20.0.0"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@mariozechner/pi-agent-core": "^0.
|
|
36
|
+
"@mariozechner/pi-agent-core": "^0.31.0",
|
|
37
37
|
"chalk": "^5.5.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {}
|