Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

104 changes: 44 additions & 60 deletions src/lib/extend/index.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,10 @@
import { type Command } from "@commander-js/extra-typings";
import { render } from "ink";
import dayjs from "npm:dayjs@1.11.13";
import duration from "npm:dayjs@1.11.13/plugin/duration.js";
import relativeTime from "npm:dayjs@1.11.13/plugin/relativeTime.js";
import { parseDuration, SfBuyOptions } from "../buy/index.tsx";
import React from "react";
import { getContract } from "../../helpers/fetchers.ts";
import { logAndQuit } from "../../helpers/errors.ts";
import { QuoteAndBuy, QuoteComponent } from "../buy/index.tsx";
import { ActiveContract } from "../contracts/types.ts";
import { GPUS_PER_NODE } from "../constants.ts";
import {
getContractAcceleratorQuantity,
getContractRange,
} from "../contracts/utils.ts";
import boxen from "npm:boxen@8.0.1";
import console from "node:console";
import process from "node:process";

dayjs.extend(relativeTime);
dayjs.extend(duration);
Expand All @@ -29,7 +20,6 @@ function _registerExtend(program: Command) {
.requiredOption(
"-d, --duration <duration>",
"Extension duration (rounded up to the nearest hour)",
parseDuration,
)
.option(
"-p, --price <price>",
Expand All @@ -44,61 +34,55 @@ function _registerExtend(program: Command) {
"--standing",
"Places a standing order. Default behavior is to place an order that auto-cancels if it can't be filled immediately.",
)
.configureHelp({
optionDescription: (option) => {
if (option.flags === "-h, --help") {
return "Display help for extend";
}
return option.description;
},
})
.addHelpText(
"after",
"before",
`
Examples:
\x1b[2m# Get a Quote to extend a contract for 1 hour\x1b[0m
$ sf extend --contract <contract_id> --duration 1h --quote

\x1b[2m# Auto confirm extending a contract by 1 hour at market price\x1b[0m
$ sf extend -c <contract_id> -d 1h --yes

\x1b[2m# Extend a contract for 2 hours at a specific price\x1b[0m
$ sf extend -c <contract_id> -d 2h --price 1.50
${
boxen(
`\x1b[31m\x1b[97msf extend\x1b[31m is deprecated.\x1b[0m
\x1b[31mTo create, extend, and release specific machines directly, use \x1b[97msf nodes\x1b[31m.\x1b[0m
\x1b[31mTo "extend" a contract, use \x1b[97msf buy -colo <contract_id> -d <duration>\x1b[31m.\x1b[0m
\x1b[31mHowever, contracts don't map to specific machines, so you can't choose which will persist.\x1b[0m
\x1b[31mWe strongly recommend using \x1b[97msf nodes\x1b[31m instead.\x1b[0m`,
{
padding: 0.75,
borderColor: "red",
},
)
}
`,
)
.action(async function extendAction(options) {
const contract = await getContract(options.contract);
if (!contract) {
logAndQuit(`Contract ${options.contract} not found`);
}
.action(function extendAction(options) {
// Build the equivalent sf buy command
let equivalentCommand =
`sf buy -colo ${options.contract} -d ${options.duration}`;

if (contract.status !== "active") {
logAndQuit(
`Contract ${contract.id} is ${contract.status}. Only active contracts can be extended.`,
);
if (options.price) {
equivalentCommand += ` -p ${options.price}`;
}
if (options.yes) {
equivalentCommand += ` -y`;
}

const activeContract = contract as ActiveContract;
const activeContractRange = getContractRange(activeContract.shape);

const quoteOptions: SfBuyOptions = {
type: activeContract.instance_type,
accelerators: getContractAcceleratorQuantity(activeContract.shape) *
GPUS_PER_NODE,
colocate: activeContract.id,
duration: options.duration,
price: options.price,
start: activeContractRange.endsAt,
quote: options.quote,
yes: options.yes,
standing: options.standing,
};

if (options.quote) {
render(<QuoteComponent options={quoteOptions} />);
} else {
render(<QuoteAndBuy options={quoteOptions} />);
equivalentCommand += ` -q`;
}
if (options.standing) {
equivalentCommand += ` --standing`;
}

console.error(boxen(
`\x1b[31m\x1b[97msf extend\x1b[31m is deprecated.\x1b[0m
\x1b[31mTo create, extend, and release specific machines directly, use \x1b[97msf nodes\x1b[31m.\x1b[0m
\x1b[31mTo "extend" a contract, use: \x1b[97m${equivalentCommand}\x1b[31m.\x1b[0m
\x1b[31mHowever, contracts don't map to specific machines, so you can't choose which will persist.\x1b[0m
\x1b[31mWe strongly recommend using \x1b[97msf nodes\x1b[31m instead.\x1b[0m`,
{
padding: 0.75,
borderColor: "red",
},
));

process.exit(0);
});
}

Expand Down