nosana-mcp 0.2.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/LICENSE +21 -0
- package/README.md +128 -0
- package/dist/cli/commands/account.d.ts +7 -0
- package/dist/cli/commands/account.js +108 -0
- package/dist/cli/commands/account.js.map +1 -0
- package/dist/cli/commands/deploy.d.ts +3 -0
- package/dist/cli/commands/deploy.js +311 -0
- package/dist/cli/commands/deploy.js.map +1 -0
- package/dist/cli/commands/gpus.d.ts +3 -0
- package/dist/cli/commands/gpus.js +38 -0
- package/dist/cli/commands/gpus.js.map +1 -0
- package/dist/cli/commands/job.d.ts +3 -0
- package/dist/cli/commands/job.js +31 -0
- package/dist/cli/commands/job.js.map +1 -0
- package/dist/cli/commands/run.d.ts +33 -0
- package/dist/cli/commands/run.js +365 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/templates.d.ts +3 -0
- package/dist/cli/commands/templates.js +115 -0
- package/dist/cli/commands/templates.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +45 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/client.d.ts +23 -0
- package/dist/core/client.js +38 -0
- package/dist/core/client.js.map +1 -0
- package/dist/core/config.d.ts +18 -0
- package/dist/core/config.js +52 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/credits.d.ts +9 -0
- package/dist/core/credits.js +9 -0
- package/dist/core/credits.js.map +1 -0
- package/dist/core/deploy.d.ts +146 -0
- package/dist/core/deploy.js +400 -0
- package/dist/core/deploy.js.map +1 -0
- package/dist/core/format.d.ts +25 -0
- package/dist/core/format.js +144 -0
- package/dist/core/format.js.map +1 -0
- package/dist/core/markets.d.ts +74 -0
- package/dist/core/markets.js +146 -0
- package/dist/core/markets.js.map +1 -0
- package/dist/core/templates.d.ts +61 -0
- package/dist/core/templates.js +190 -0
- package/dist/core/templates.js.map +1 -0
- package/dist/mcp/index.d.ts +2 -0
- package/dist/mcp/index.js +73 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/tools.d.ts +52 -0
- package/dist/mcp/tools.js +994 -0
- package/dist/mcp/tools.js.map +1 -0
- package/docs/CLI.md +144 -0
- package/docs/COST.md +32 -0
- package/docs/MINIMAX-H3.md +79 -0
- package/examples/hello-world.json +18 -0
- package/examples/minimax-h3-i2v-32gb.json +56 -0
- package/package.json +66 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { createClient, createPublicClient } from '../../core/client.js';
|
|
2
|
+
import { resolveApiKey } from '../../core/config.js';
|
|
3
|
+
import { parseIntStrict, printJson } from '../../core/format.js';
|
|
4
|
+
import { gpuTable, loadGpuCatalog } from '../../core/markets.js';
|
|
5
|
+
import { hardwareHints, isBlackwell, listTemplates, resolveTemplate } from '../../core/templates.js';
|
|
6
|
+
export function registerGpuCommands(program, globals) {
|
|
7
|
+
program
|
|
8
|
+
.command('gpus')
|
|
9
|
+
.alias('markets')
|
|
10
|
+
.description('List GPU markets with price per hour and how many hosts are idle right now.')
|
|
11
|
+
.option('--template <id>', 'Mark which GPUs fit a template (uses its VRAM and hardware requirements)')
|
|
12
|
+
.option('--variant <id>', 'Template variant, e.g. i2v-32gb')
|
|
13
|
+
.option('--vram <gb>', 'Mark which GPUs have at least this much VRAM')
|
|
14
|
+
.option('--all', 'Include community and special markets, not only the premium ones the dashboard shows')
|
|
15
|
+
.option('--queue', 'Also read the on-chain queues to show how many jobs are waiting per market')
|
|
16
|
+
.action(async (cmd) => {
|
|
17
|
+
const options = globals();
|
|
18
|
+
const client = resolveApiKey(options.apiKey) ? createClient(options) : createPublicClient(options);
|
|
19
|
+
let minVramGb = cmd.vram ? parseIntStrict(cmd.vram, '--vram') : null;
|
|
20
|
+
let recommend;
|
|
21
|
+
if (cmd.template) {
|
|
22
|
+
const resolved = resolveTemplate(await listTemplates(client), cmd.template, cmd.variant);
|
|
23
|
+
minVramGb = minVramGb ?? resolved.template.vramRequirementGb;
|
|
24
|
+
if (hardwareHints(resolved.parent).blackwellOnly)
|
|
25
|
+
recommend = (m) => isBlackwell(m.name, m.slug);
|
|
26
|
+
}
|
|
27
|
+
const catalog = await loadGpuCatalog(client, { includeAll: cmd.all, onchain: cmd.queue });
|
|
28
|
+
if (options.json) {
|
|
29
|
+
printJson(catalog);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
console.log(gpuTable(catalog, { minVramGb, recommend, showQueue: cmd.queue }));
|
|
33
|
+
console.log('\nPrice/h includes the network fee, matching deploy.nosana.com. "Available" counts idle hosts waiting for work in that market.');
|
|
34
|
+
if (!cmd.all)
|
|
35
|
+
console.log('Add --all to include community markets.');
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=gpus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gpus.js","sourceRoot":"","sources":["../../../src/cli/commands/gpus.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAsB,MAAM,sBAAsB,CAAC;AAC5F,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAkB,MAAM,uBAAuB,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAErG,MAAM,UAAU,mBAAmB,CAAC,OAAgB,EAAE,OAA4B;IAChF,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,KAAK,CAAC,SAAS,CAAC;SAChB,WAAW,CAAC,6EAA6E,CAAC;SAC1F,MAAM,CAAC,iBAAiB,EAAE,0EAA0E,CAAC;SACrG,MAAM,CAAC,gBAAgB,EAAE,iCAAiC,CAAC;SAC3D,MAAM,CAAC,aAAa,EAAE,8CAA8C,CAAC;SACrE,MAAM,CAAC,OAAO,EAAE,sFAAsF,CAAC;SACvG,MAAM,CAAC,SAAS,EAAE,4EAA4E,CAAC;SAC/F,MAAM,CAAC,KAAK,EAAE,GAA2F,EAAE,EAAE;QAC5G,MAAM,OAAO,GAAG,OAAO,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;QACnG,IAAI,SAAS,GAAkB,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACpF,IAAI,SAAkD,CAAC;QACvD,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;YACjB,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,aAAa,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;YACzF,SAAS,GAAG,SAAS,IAAI,QAAQ,CAAC,QAAQ,CAAC,iBAAiB,CAAC;YAC7D,IAAI,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,aAAa;gBAAE,SAAS,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QACnG,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,MAAM,EAAE,EAAE,UAAU,EAAE,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;QAC1F,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,SAAS,CAAC,OAAO,CAAC,CAAC;YACnB,OAAO;QACT,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC/E,OAAO,CAAC,GAAG,CAAC,gIAAgI,CAAC,CAAC;QAC9I,IAAI,CAAC,GAAG,CAAC,GAAG;YAAE,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { createClient } from '../../core/client.js';
|
|
2
|
+
import { explorerJobUrl, normalizeJobState } from '../../core/deploy.js';
|
|
3
|
+
import { fmtDate, printJson, statusColor } from '../../core/format.js';
|
|
4
|
+
export function registerJobCommands(program, globals) {
|
|
5
|
+
const job = program.command('job').description('Look up individual jobs by address.');
|
|
6
|
+
job
|
|
7
|
+
.command('get')
|
|
8
|
+
.description('Show a job by its address (as listed on explore.nosana.com).')
|
|
9
|
+
.argument('<address>', 'Job address')
|
|
10
|
+
.action(async (address) => {
|
|
11
|
+
const options = globals();
|
|
12
|
+
const client = createClient(options);
|
|
13
|
+
const result = (await client.api.jobs.get(address));
|
|
14
|
+
if (options.json) {
|
|
15
|
+
printJson(result);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const state = normalizeJobState(result.state);
|
|
19
|
+
console.log(`Job ${address}`);
|
|
20
|
+
console.log(`State ${statusColor(state)}`);
|
|
21
|
+
for (const key of ['market', 'node', 'project', 'ipfsJob', 'ipfsResult', 'timeStart', 'timeEnd', 'timeout', 'price']) {
|
|
22
|
+
if (result[key] !== undefined && result[key] !== null) {
|
|
23
|
+
const isTimestamp = (key === 'timeStart' || key === 'timeEnd') && typeof result[key] === 'number';
|
|
24
|
+
const value = isTimestamp ? fmtDate(result[key]) : key === 'timeout' ? `${String(result[key])} s` : String(result[key]);
|
|
25
|
+
console.log(`${key.padEnd(9)} ${value}`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
console.log(`Explorer ${explorerJobUrl(address, options.network)}`);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=job.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job.js","sourceRoot":"","sources":["../../../src/cli/commands/job.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAsB,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEvE,MAAM,UAAU,mBAAmB,CAAC,OAAgB,EAAE,OAA4B;IAChF,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,qCAAqC,CAAC,CAAC;IAEtF,GAAG;SACA,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,8DAA8D,CAAC;SAC3E,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC;SACpC,MAAM,CAAC,KAAK,EAAE,OAAe,EAAE,EAAE;QAChC,MAAM,OAAO,GAAG,OAAO,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAA4B,CAAC;QAC/E,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,SAAS,CAAC,MAAM,CAAC,CAAC;YAClB,OAAO;QACT,CAAC;QACD,MAAM,KAAK,GAAG,iBAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC9C,OAAO,CAAC,GAAG,CAAC,aAAa,OAAO,EAAE,CAAC,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,aAAa,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC/C,KAAK,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,CAAU,EAAE,CAAC;YAC9H,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,SAAS,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;gBACtD,MAAM,WAAW,GAAG,CAAC,GAAG,KAAK,WAAW,IAAI,GAAG,KAAK,SAAS,CAAC,IAAI,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,QAAQ,CAAC;gBAClG,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAW,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;gBAClI,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,aAAa,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
import { type GlobalOptions } from '../../core/client.js';
|
|
3
|
+
import { summarizeDeployment } from '../../core/deploy.js';
|
|
4
|
+
export interface RunFlags {
|
|
5
|
+
template?: string;
|
|
6
|
+
variant?: string;
|
|
7
|
+
file?: string;
|
|
8
|
+
gpu?: string;
|
|
9
|
+
name?: string;
|
|
10
|
+
timeout?: string;
|
|
11
|
+
replicas?: string;
|
|
12
|
+
strategy?: string;
|
|
13
|
+
schedule?: string;
|
|
14
|
+
rotationTime?: string;
|
|
15
|
+
startupTimeout?: string;
|
|
16
|
+
confidential?: boolean;
|
|
17
|
+
sshKey?: string[];
|
|
18
|
+
start?: boolean;
|
|
19
|
+
wait?: boolean;
|
|
20
|
+
waitTimeout?: string;
|
|
21
|
+
yes?: boolean;
|
|
22
|
+
force?: boolean;
|
|
23
|
+
all?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export declare const DEFAULT_WAIT_MINUTES = 45;
|
|
26
|
+
export declare function addDeployFlags(command: Command, defaults: {
|
|
27
|
+
start: boolean;
|
|
28
|
+
}): Command;
|
|
29
|
+
export declare function runDeployFlow(options: GlobalOptions, flags: RunFlags, interactive: boolean, defaults: {
|
|
30
|
+
start: boolean;
|
|
31
|
+
}): Promise<void>;
|
|
32
|
+
export declare function registerRunCommand(program: Command, globals: () => GlobalOptions): void;
|
|
33
|
+
export { summarizeDeployment };
|
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { confirm, input, select } from '@inquirer/prompts';
|
|
4
|
+
import { validateJobDefinition } from '@nosana/kit';
|
|
5
|
+
import pc from 'picocolors';
|
|
6
|
+
import { CliError, createClient } from '../../core/client.js';
|
|
7
|
+
import { isInteractive, resolveApiKey } from '../../core/config.js';
|
|
8
|
+
import { assessPlan, createDeployment, dashboardUrl, defaultDeploymentName, estimateCost, explorerJobUrl, formatJobResult, MIN_TIMEOUT_MINUTES, parseStrategy, STRATEGIES, summarizeDeployment, validatePlan, waitForDeployment, } from '../../core/deploy.js';
|
|
9
|
+
import { fmtMinutes, parseIntStrict, printJson, sym, usd } from '../../core/format.js';
|
|
10
|
+
import { fitLabel, fitsVram, loadGpuCatalog, resolveGpu } from '../../core/markets.js';
|
|
11
|
+
import { hardwareHints, isBlackwell, listTemplates, NeedsVariantError, prepareJobDefinition, resolveTemplate, topLevelTemplates, vramFromDefinition, } from '../../core/templates.js';
|
|
12
|
+
import { availableCredits, loginInteractive } from './account.js';
|
|
13
|
+
export const DEFAULT_WAIT_MINUTES = 45;
|
|
14
|
+
export function addDeployFlags(command, defaults) {
|
|
15
|
+
return command
|
|
16
|
+
.option('-t, --template <id>', 'Template id or name, e.g. minimax-h3 (see `templates list`)')
|
|
17
|
+
.option('--variant <id>', 'Template variant, e.g. i2v-32gb')
|
|
18
|
+
.option('-f, --file <path>', 'Deploy a custom job definition JSON instead of a template')
|
|
19
|
+
.option('-g, --gpu <market>', 'GPU market slug, short name or address, e.g. nvidia-5090 or 5090')
|
|
20
|
+
.option('--name <name>', 'Deployment name (default: <template>-<timestamp>)')
|
|
21
|
+
.option('--timeout <minutes>', `How long the GPU stays reserved per job, in minutes (minimum and default ${MIN_TIMEOUT_MINUTES})`)
|
|
22
|
+
.option('--replicas <count>', 'Number of parallel jobs', '1')
|
|
23
|
+
.option('--strategy <strategy>', `One of ${STRATEGIES.join(', ')} (default SIMPLE)`)
|
|
24
|
+
.option('--schedule <cron>', 'Cron schedule, required for SCHEDULED')
|
|
25
|
+
.option('--rotation-time <value>', 'INFINITE only: rotation time passed to the API as-is (the dashboard uses 20 with a 360 min timeout)')
|
|
26
|
+
.option('--startup-timeout <minutes>', 'INFINITE only: minutes a job has to open its tunnel before it is replaced')
|
|
27
|
+
.option('--confidential', 'Create a confidential deployment (endpoint needs the header from `deploy auth-header`)')
|
|
28
|
+
.option('--ssh-key <publicKey...>', 'SSH public keys allowed to reach the jobs (max 10)')
|
|
29
|
+
.option('--all', 'Allow community GPU markets, not only premium ones')
|
|
30
|
+
.option('--wait-timeout <minutes>', `How long to wait for the workload to come online (default ${DEFAULT_WAIT_MINUTES})`)
|
|
31
|
+
.option('--no-wait', 'Do not wait for the workload after starting it')
|
|
32
|
+
.option(defaults.start ? '--no-start' : '--start', defaults.start ? 'Create as a draft without starting' : 'Start right after creating')
|
|
33
|
+
.option('-y, --yes', 'Skip the confirmation prompt')
|
|
34
|
+
.option('--force', 'Deploy even if the GPU looks too small or credits look insufficient');
|
|
35
|
+
}
|
|
36
|
+
function readJobDefinitionFile(file) {
|
|
37
|
+
const fullPath = path.resolve(file);
|
|
38
|
+
let parsed;
|
|
39
|
+
try {
|
|
40
|
+
parsed = JSON.parse(fs.readFileSync(fullPath, 'utf8'));
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
throw new CliError(`Could not read job definition ${fullPath}: ${error.message}`, 2);
|
|
44
|
+
}
|
|
45
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
46
|
+
throw new CliError(`Job definition must be a JSON object: ${fullPath}`, 2);
|
|
47
|
+
}
|
|
48
|
+
const validation = validateJobDefinition(parsed);
|
|
49
|
+
if (!validation.success) {
|
|
50
|
+
throw new CliError(`Invalid job definition ${fullPath}:\n${JSON.stringify(validation.errors, null, 2)}`, 2);
|
|
51
|
+
}
|
|
52
|
+
return parsed;
|
|
53
|
+
}
|
|
54
|
+
async function pickTemplate(all, flags, tty) {
|
|
55
|
+
if (flags.template) {
|
|
56
|
+
try {
|
|
57
|
+
return resolveTemplate(all, flags.template, flags.variant);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
if (error instanceof NeedsVariantError && tty) {
|
|
61
|
+
const variant = await select({
|
|
62
|
+
message: `Variant of ${error.template.name}`,
|
|
63
|
+
choices: error.template.variants.map((v) => ({ name: v.name, value: v.id, description: v.description })),
|
|
64
|
+
});
|
|
65
|
+
return resolveTemplate(all, error.template.id, variant);
|
|
66
|
+
}
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (!tty) {
|
|
71
|
+
throw new CliError('Pass --template <id> (or --file <job.json>). Run `nosana-deploy templates list` to see the catalog.', 2);
|
|
72
|
+
}
|
|
73
|
+
const top = topLevelTemplates(all);
|
|
74
|
+
const squash = (s) => s.toLowerCase().replace(/[^a-z0-9]+/g, '');
|
|
75
|
+
const term = squash(await input({ message: 'Search templates (press Enter to list all)' }));
|
|
76
|
+
const matches = term
|
|
77
|
+
? top.filter((t) => squash(t.id).includes(term) || squash(t.name).includes(term) || squash(t.category.join(' ')).includes(term))
|
|
78
|
+
: top;
|
|
79
|
+
if (!matches.length) {
|
|
80
|
+
console.log(`${sym.warn} No template matches that search. Try again or press Enter to see all.`);
|
|
81
|
+
return pickTemplate(all, flags, tty);
|
|
82
|
+
}
|
|
83
|
+
const describe = (t) => t.variants.length ? `${t.variants.length} variants: ${t.variants.map((v) => v.name).join(', ')}` : t.description;
|
|
84
|
+
let id;
|
|
85
|
+
if (matches.length === 1) {
|
|
86
|
+
id = matches[0].id;
|
|
87
|
+
console.log(`${sym.ok} Template: ${matches[0].name}`);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
id = await select({
|
|
91
|
+
message: 'Template',
|
|
92
|
+
pageSize: 14,
|
|
93
|
+
choices: matches.map((t) => ({
|
|
94
|
+
name: `${t.name} ${pc.dim(t.category.filter((c) => c !== 'Official').join(', '))}`,
|
|
95
|
+
value: t.id,
|
|
96
|
+
description: describe(t),
|
|
97
|
+
})),
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
return pickTemplate(all, { ...flags, template: id }, tty);
|
|
101
|
+
}
|
|
102
|
+
async function pickGpu(catalog, flags, tty, fit) {
|
|
103
|
+
if (flags.gpu) {
|
|
104
|
+
const gpu = resolveGpu(catalog, flags.gpu);
|
|
105
|
+
if (!gpu) {
|
|
106
|
+
throw new CliError(`Unknown GPU "${flags.gpu}". Run \`nosana-deploy gpus${flags.all ? ' --all' : ''}\` to list markets${flags.all ? '' : ' (add --all for community markets)'}.`, 2);
|
|
107
|
+
}
|
|
108
|
+
return gpu;
|
|
109
|
+
}
|
|
110
|
+
if (!tty)
|
|
111
|
+
throw new CliError('Pass --gpu <slug>, for example --gpu nvidia-5090. Run `nosana-deploy gpus` for prices and availability.', 2);
|
|
112
|
+
const score = (m) => (fitsVram(m, fit.minVramGb) ? 4 : 0) + (fit.recommend ? (fit.recommend(m) ? 2 : 0) : 2) + (m.availableNodes > 0 ? 1 : 0);
|
|
113
|
+
const ranked = [...catalog].sort((a, b) => score(b) - score(a) || a.pricePerHour - b.pricePerHour);
|
|
114
|
+
const slug = await select({
|
|
115
|
+
message: 'GPU',
|
|
116
|
+
pageSize: 14,
|
|
117
|
+
choices: ranked.map((m) => ({
|
|
118
|
+
name: `${m.name.padEnd(24)} ${(m.vramGb ? `${m.vramGb} GB` : '?').padStart(6)} ${usd(m.pricePerHour).padStart(7)}/h ${String(m.availableNodes).padStart(3)} available ${fitLabel(m, fit)}`,
|
|
119
|
+
value: m.slug,
|
|
120
|
+
disabled: fitsVram(m, fit.minVramGb) ? false : 'too little VRAM',
|
|
121
|
+
})),
|
|
122
|
+
});
|
|
123
|
+
return catalog.find((m) => m.slug === slug);
|
|
124
|
+
}
|
|
125
|
+
async function pickTimeout(flags, tty, strategy) {
|
|
126
|
+
const min = MIN_TIMEOUT_MINUTES;
|
|
127
|
+
if (flags.timeout) {
|
|
128
|
+
const requested = parseIntStrict(flags.timeout, '--timeout', 1);
|
|
129
|
+
if (requested < min) {
|
|
130
|
+
throw new CliError(`--timeout must be at least ${min} minutes: Nosana only schedules credit-paid jobs that run for 3600 seconds or more.`, 2);
|
|
131
|
+
}
|
|
132
|
+
return requested;
|
|
133
|
+
}
|
|
134
|
+
if (!tty)
|
|
135
|
+
return min;
|
|
136
|
+
const answer = await input({
|
|
137
|
+
message: `Timeout in minutes, minimum ${min} (GPU time reserved${strategy === 'SIMPLE' ? '; the deployment stops when it elapses' : ' per job'})`,
|
|
138
|
+
default: String(min),
|
|
139
|
+
validate: (value) => (/^\d+$/.test(value.trim()) && Number(value) >= min ? true : `Enter a whole number >= ${min}`),
|
|
140
|
+
});
|
|
141
|
+
return Number(answer.trim());
|
|
142
|
+
}
|
|
143
|
+
function printPlan(plan, available, resolved, start, out) {
|
|
144
|
+
const cost = estimateCost(plan);
|
|
145
|
+
out(`\n${pc.bold('Plan')}`);
|
|
146
|
+
const workload = resolved ? `${resolved.id} ${pc.dim(resolved.template.name)}` : plan.workload;
|
|
147
|
+
out(` Workload ${workload}`);
|
|
148
|
+
out(` GPU ${plan.gpu.name} (${plan.gpu.slug}) ${plan.gpu.vramGb ? `${plan.gpu.vramGb} GB` : ''} ${plan.gpu.availableNodes} host${plan.gpu.availableNodes === 1 ? '' : 's'} available ${usd(plan.gpu.pricePerHour)}/h`);
|
|
149
|
+
const strategyBits = [plan.strategy, `${plan.replicas} replica${plan.replicas === 1 ? '' : 's'}`, `timeout ${fmtMinutes(plan.timeoutMinutes)}`];
|
|
150
|
+
if (plan.schedule)
|
|
151
|
+
strategyBits.push(`schedule "${plan.schedule}"`);
|
|
152
|
+
if (plan.rotationTime !== undefined)
|
|
153
|
+
strategyBits.push(`rotation ${plan.rotationTime}`);
|
|
154
|
+
out(` Strategy ${strategyBits.join(', ')}`);
|
|
155
|
+
out(` Confidential ${plan.confidential ? 'yes' : 'no'}`);
|
|
156
|
+
const window = `${usd(plan.gpu.pricePerHour)}/h x ${cost.hours.toFixed(2)} h x ${plan.replicas}`;
|
|
157
|
+
out(` Estimate ${pc.bold(cost.total.toFixed(3))} credits for one timeout window (${window})${cost.recurring ? ', charged again for every extension' : ''}`);
|
|
158
|
+
out(` Credits ${available.toFixed(3)} available${cost.total > available ? pc.red(' (not enough for the full window)') : ''}`);
|
|
159
|
+
out(` Action ${start ? 'create and start now' : 'create as a draft (start later with `deploy start`)'}`);
|
|
160
|
+
}
|
|
161
|
+
async function reportOutcome(outcome, options) {
|
|
162
|
+
const dep = outcome.deployment;
|
|
163
|
+
if (options.json) {
|
|
164
|
+
const payload = { outcome: outcome.kind, deployment: dep.id, status: dep.status, endpoints: dep.endpoints, dashboard: dashboardUrl(dep.id, options.network) };
|
|
165
|
+
if (outcome.kind === 'online')
|
|
166
|
+
payload.readyUrls = outcome.readyUrls;
|
|
167
|
+
if (outcome.kind === 'completed') {
|
|
168
|
+
payload.job = outcome.job;
|
|
169
|
+
try {
|
|
170
|
+
payload.result = (await dep.getJob(outcome.job)).jobResult;
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
/* results may lag */
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
printJson(payload);
|
|
177
|
+
return outcome.kind === 'failed' ? 1 : 0;
|
|
178
|
+
}
|
|
179
|
+
console.log();
|
|
180
|
+
switch (outcome.kind) {
|
|
181
|
+
case 'online': {
|
|
182
|
+
console.log(`${sym.ok} ${pc.bold('Your workload is online and answering.')}`);
|
|
183
|
+
for (const endpoint of dep.endpoints.filter((e) => outcome.readyUrls.includes(e.url)))
|
|
184
|
+
console.log(` ${pc.bold(endpoint.url)} (${endpoint.opId}, port ${endpoint.port})`);
|
|
185
|
+
if (dep.confidential) {
|
|
186
|
+
try {
|
|
187
|
+
const header = await dep.generateAuthHeader();
|
|
188
|
+
console.log(` Confidential deployment: send this header with requests:\n Authorization: ${header}`);
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
console.log(` Confidential deployment: run \`nosana-deploy deploy auth-header ${dep.id}\` to get the access header.`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
console.log(` Dashboard: ${dashboardUrl(dep.id, options.network)}`);
|
|
195
|
+
console.log(` Stop it any time: nosana-deploy deploy stop ${dep.id}`);
|
|
196
|
+
return 0;
|
|
197
|
+
}
|
|
198
|
+
case 'completed': {
|
|
199
|
+
console.log(`${sym.ok} ${pc.bold('Job completed.')} ${explorerJobUrl(outcome.job, options.network)}`);
|
|
200
|
+
try {
|
|
201
|
+
const job = await dep.getJob(outcome.job);
|
|
202
|
+
for (const line of formatJobResult(job.jobResult))
|
|
203
|
+
console.log(` ${line}`);
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
console.log(` Results not available yet: ${error.message}`);
|
|
207
|
+
}
|
|
208
|
+
return 0;
|
|
209
|
+
}
|
|
210
|
+
case 'stopped': {
|
|
211
|
+
console.log(`${sym.warn} The deployment was stopped (by you or by its timeout) before the workload came up. Start it again with: nosana-deploy deploy start ${dep.id} --wait`);
|
|
212
|
+
return 1;
|
|
213
|
+
}
|
|
214
|
+
case 'failed': {
|
|
215
|
+
if (outcome.error) {
|
|
216
|
+
console.log(`${sym.err} The scheduler cannot run this deployment: ${pc.red(outcome.error)}`);
|
|
217
|
+
if (!['STOPPED', 'ERROR', 'INSUFFICIENT_FUNDS', 'ARCHIVED'].includes(dep.status)) {
|
|
218
|
+
try {
|
|
219
|
+
await dep.stop();
|
|
220
|
+
console.log(' Stopped the deployment so it does not keep retrying.');
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
console.log(` Could not stop it automatically (${error.message}); run: nosana-deploy deploy stop ${dep.id}`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
console.log(`${sym.err} Deployment ended with status ${pc.red(outcome.reason)} before the workload came up.`);
|
|
229
|
+
}
|
|
230
|
+
if (outcome.reason === 'INSUFFICIENT_FUNDS' || /insufficient/i.test(outcome.error ?? '')) {
|
|
231
|
+
console.log(' Top up credits at https://deploy.nosana.com (Billing) and start it again with `deploy start`.');
|
|
232
|
+
}
|
|
233
|
+
console.log(` Inspect with: nosana-deploy deploy events ${dep.id}`);
|
|
234
|
+
return 1;
|
|
235
|
+
}
|
|
236
|
+
case 'timeout':
|
|
237
|
+
default: {
|
|
238
|
+
console.log(`${sym.warn} Still waiting after the watch window. The deployment keeps running; big templates need time to download their weights.`);
|
|
239
|
+
console.log(` Keep watching: nosana-deploy deploy watch ${dep.id}`);
|
|
240
|
+
console.log(` Dashboard: ${dashboardUrl(dep.id, options.network)}`);
|
|
241
|
+
return 0;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
export async function runDeployFlow(options, flags, interactive, defaults) {
|
|
246
|
+
const tty = interactive && isInteractive() && !options.json;
|
|
247
|
+
// With --json only the final JSON document goes to stdout; progress lines go to stderr.
|
|
248
|
+
const out = (line) => (options.json ? console.error(line) : console.log(line));
|
|
249
|
+
const start = flags.start ?? defaults.start;
|
|
250
|
+
const wait = start && flags.wait !== false;
|
|
251
|
+
if (flags.file && flags.template)
|
|
252
|
+
throw new CliError('Use either --template or --file, not both.', 2);
|
|
253
|
+
// Validate cheap things before touching the network so mistakes fail instantly.
|
|
254
|
+
const strategy = parseStrategy(flags.strategy);
|
|
255
|
+
if (flags.timeout !== undefined) {
|
|
256
|
+
const requested = parseIntStrict(flags.timeout, '--timeout', 1);
|
|
257
|
+
if (requested < MIN_TIMEOUT_MINUTES) {
|
|
258
|
+
throw new CliError(`--timeout must be at least ${MIN_TIMEOUT_MINUTES} minutes: Nosana only schedules credit-paid jobs that run for 3600 seconds or more.`, 2);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
const replicas = parseIntStrict(flags.replicas ?? '1', '--replicas');
|
|
262
|
+
const waitMinutes = flags.waitTimeout ? parseIntStrict(flags.waitTimeout, '--wait-timeout') : DEFAULT_WAIT_MINUTES;
|
|
263
|
+
if (strategy === 'SCHEDULED' && !flags.schedule)
|
|
264
|
+
throw new CliError('--schedule <cron> is required for SCHEDULED deployments.', 2);
|
|
265
|
+
let apiKey = resolveApiKey(options.apiKey)?.key;
|
|
266
|
+
if (!apiKey) {
|
|
267
|
+
if (!tty)
|
|
268
|
+
throw new CliError('No API key. Run `nosana-deploy login`, set NOSANA_API_KEY or pass --api-key.', 2);
|
|
269
|
+
apiKey = await loginInteractive(options);
|
|
270
|
+
}
|
|
271
|
+
const client = createClient(options, apiKey);
|
|
272
|
+
const [balance, templates, catalog] = await Promise.all([
|
|
273
|
+
client.api.credits.balance(),
|
|
274
|
+
flags.file ? Promise.resolve([]) : listTemplates(client),
|
|
275
|
+
loadGpuCatalog(client, { includeAll: flags.all }),
|
|
276
|
+
]);
|
|
277
|
+
const available = availableCredits(balance);
|
|
278
|
+
if (tty)
|
|
279
|
+
console.log(`${pc.bold('Nosana Deploy')} ${pc.dim('credits available:')} ${available.toFixed(3)}\n`);
|
|
280
|
+
let resolved = null;
|
|
281
|
+
let jobDefinition;
|
|
282
|
+
let workload;
|
|
283
|
+
if (flags.file) {
|
|
284
|
+
jobDefinition = readJobDefinitionFile(flags.file);
|
|
285
|
+
workload = path.basename(flags.file);
|
|
286
|
+
}
|
|
287
|
+
else {
|
|
288
|
+
resolved = await pickTemplate(templates, flags, tty);
|
|
289
|
+
jobDefinition = prepareJobDefinition(resolved.jobDefinition);
|
|
290
|
+
workload = resolved.id;
|
|
291
|
+
}
|
|
292
|
+
const minVramGb = resolved ? resolved.template.vramRequirementGb : vramFromDefinition(jobDefinition);
|
|
293
|
+
const hints = resolved ? hardwareHints(resolved.parent) : { blackwellOnly: false, minDriver: null, notes: [] };
|
|
294
|
+
const fit = { minVramGb, recommend: hints.blackwellOnly ? (m) => isBlackwell(m.name, m.slug) : undefined };
|
|
295
|
+
if (tty && (minVramGb || hints.notes.length)) {
|
|
296
|
+
console.log(pc.dim(` ${[minVramGb ? `Needs ${minVramGb} GB VRAM.` : null, ...hints.notes].filter(Boolean).join(' ')}\n`));
|
|
297
|
+
}
|
|
298
|
+
const gpu = await pickGpu(catalog, flags, tty, fit);
|
|
299
|
+
const timeoutMinutes = await pickTimeout(flags, tty, strategy);
|
|
300
|
+
const name = flags.name ?? (tty ? await input({ message: 'Deployment name', default: defaultDeploymentName(workload) }) : defaultDeploymentName(workload));
|
|
301
|
+
const plan = {
|
|
302
|
+
name: name.trim(),
|
|
303
|
+
workload,
|
|
304
|
+
jobDefinition,
|
|
305
|
+
gpu,
|
|
306
|
+
timeoutMinutes,
|
|
307
|
+
replicas,
|
|
308
|
+
strategy,
|
|
309
|
+
schedule: flags.schedule,
|
|
310
|
+
rotationTime: flags.rotationTime !== undefined ? Number(flags.rotationTime) : undefined,
|
|
311
|
+
startupTimeoutMinutes: flags.startupTimeout !== undefined ? parseIntStrict(flags.startupTimeout, '--startup-timeout') : undefined,
|
|
312
|
+
confidential: Boolean(flags.confidential),
|
|
313
|
+
sshPublicKeys: flags.sshKey,
|
|
314
|
+
};
|
|
315
|
+
validatePlan(plan);
|
|
316
|
+
const { warnings, blocking } = assessPlan(plan, fit, available);
|
|
317
|
+
for (const warning of warnings)
|
|
318
|
+
out(`${sym.warn} ${warning}`);
|
|
319
|
+
if (blocking.length && !flags.force && !tty)
|
|
320
|
+
throw new CliError('Refusing to deploy with the warnings above. Add --force to override.', 2);
|
|
321
|
+
printPlan(plan, available, resolved, start, out);
|
|
322
|
+
if (!flags.yes) {
|
|
323
|
+
if (!tty)
|
|
324
|
+
throw new CliError('Add --yes to confirm the plan when not running interactively.', 2);
|
|
325
|
+
const proceed = await confirm({ message: blocking.length ? 'Deploy despite the warnings?' : start ? 'Create and start this deployment?' : 'Create this deployment as a draft?', default: !blocking.length });
|
|
326
|
+
if (!proceed) {
|
|
327
|
+
out('Aborted. Nothing was created.');
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
const deployment = await createDeployment(client, plan);
|
|
332
|
+
out(`\n${sym.ok} Created deployment ${pc.bold(deployment.id)} (${deployment.status})`);
|
|
333
|
+
if (start) {
|
|
334
|
+
await deployment.start();
|
|
335
|
+
out(`${sym.ok} Started`);
|
|
336
|
+
}
|
|
337
|
+
out(`${sym.info} Dashboard: ${dashboardUrl(deployment.id, options.network)}`);
|
|
338
|
+
if (!wait) {
|
|
339
|
+
if (options.json)
|
|
340
|
+
printJson({ deployment: deployment.id, status: start ? 'STARTING' : deployment.status, dashboard: dashboardUrl(deployment.id, options.network) });
|
|
341
|
+
else if (start)
|
|
342
|
+
console.log(` Follow it with: nosana-deploy deploy watch ${deployment.id}`);
|
|
343
|
+
else
|
|
344
|
+
console.log(` Start it with: nosana-deploy deploy start ${deployment.id} --wait`);
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
out(`\nWaiting up to ${fmtMinutes(waitMinutes)} for the workload to come online. Ctrl+C only stops watching; the deployment keeps running.`);
|
|
348
|
+
const outcome = await waitForDeployment(client, deployment.id, { timeoutMinutes: waitMinutes, network: options.network, replayEvents: true, quiet: Boolean(options.json) });
|
|
349
|
+
const code = await reportOutcome(outcome, options);
|
|
350
|
+
if (code !== 0)
|
|
351
|
+
throw new CliError(`Deployment ${deployment.id} did not come up (status ${outcome.deployment.status}).`, code);
|
|
352
|
+
}
|
|
353
|
+
export function registerRunCommand(program, globals) {
|
|
354
|
+
addDeployFlags(program
|
|
355
|
+
.command('run')
|
|
356
|
+
.description('Guided deploy: pick a template (e.g. MiniMax H3), a GPU, a timeout, confirm the cost, then create, start and watch it come online.')
|
|
357
|
+
.addHelpText('after', `
|
|
358
|
+
Examples:
|
|
359
|
+
nosana-deploy run
|
|
360
|
+
nosana-deploy run --template minimax-h3 --variant i2v-32gb --gpu nvidia-5090 --timeout 120
|
|
361
|
+
nosana-deploy run --template hello-world --gpu nvidia-3060 --timeout 5 --yes
|
|
362
|
+
nosana-deploy run --file my-job.json --gpu 4090 --timeout 60 --yes --json`), { start: true }).action(async (flags) => runDeployFlow(globals(), flags, true, { start: true }));
|
|
363
|
+
}
|
|
364
|
+
export { summarizeDeployment };
|
|
365
|
+
//# sourceMappingURL=run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/cli/commands/run.ts"],"names":[],"mappings":"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"}
|