diff --git a/src/subcommands/list.ts b/src/subcommands/list.ts index 8560da7..27e3b91 100644 --- a/src/subcommands/list.ts +++ b/src/subcommands/list.ts @@ -1,13 +1,13 @@ import { Command, type OptionValues } from "@commander-js/extra-typings"; import { text } from "@lmstudio/lms-common"; -import { type LMStudioClient, type ModelInfo } from "@lmstudio/sdk"; +import { LLM, type LMStudioClient, type ModelInfo } from "@lmstudio/sdk"; import chalk from "chalk"; import columnify from "columnify"; import { architectureInfoLookup } from "../architectureStylizations.js"; import { addCreateClientOptions, createClient, type CreateClientArgs } from "../createClient.js"; import { createDeviceNameResolver, type DeviceNameResolver } from "../deviceNameLookup.js"; -import { formatTimeLean } from "../formatElapsedTime.js"; import { formatSizeBytes1000 } from "../formatBytes.js"; +import { formatTimeLean } from "../formatElapsedTime.js"; import { addLogLevelOptions, createLogger, type LogLevelArgs } from "../logLevel.js"; function loadedCheck(count: number) { @@ -448,11 +448,17 @@ psCommand.action(async (options: PsCommandOptions) => { loadedModels.map(async model => { const info = await model.getModelInfo(); const { instanceReference: _, ...filteredInfo } = info; + let parallel: number | null = null; + if (model instanceof LLM) { + const loadConfig = await model.getLoadConfig(); + parallel = loadConfig.maxParallelPredictions ?? null; + } const instanceProcessingState = await model.getInstanceProcessingState(); return { ...filteredInfo, status: instanceProcessingState.status, queued: instanceProcessingState.queued, + parallel, }; }), ); @@ -476,6 +482,11 @@ psCommand.action(async (options: PsCommandOptions) => { const { identifier } = loadedModel; const contextLength = await loadedModel.getContextLength(); const modelInstanceInfo = await loadedModel.getModelInfo(); + let parallel: number | "-" = "-"; + if (loadedModel instanceof LLM) { + const loadConfig = await loadedModel.getLoadConfig(); + parallel = loadConfig.maxParallelPredictions ?? "-"; + } const timeLeft = modelInstanceInfo.ttlMs !== null ? modelInstanceInfo.lastUsedTime === null @@ -489,6 +500,7 @@ psCommand.action(async (options: PsCommandOptions) => { path: modelInstanceInfo.modelKey, sizeBytes: formatSizeBytes1000(modelInstanceInfo.sizeBytes), contextLength: contextLength, + parallel, ttlMs: timeLeft !== undefined && modelInstanceInfo.ttlMs !== null ? `${formatTimeLean(timeLeft)} ${chalk.dim(`/ ${formatTimeLean(modelInstanceInfo.ttlMs)}`)}` @@ -504,7 +516,16 @@ psCommand.action(async (options: PsCommandOptions) => { console.info(); console.info( columnify(loadedModelsWithInfo, { - columns: ["identifier", "path", "status", "sizeBytes", "contextLength", "device", "ttlMs"], + columns: [ + "identifier", + "path", + "status", + "sizeBytes", + "contextLength", + "parallel", + "device", + "ttlMs", + ], config: { identifier: { headingTransform: () => chalk.dim("IDENTIFIER"), @@ -526,6 +547,10 @@ psCommand.action(async (options: PsCommandOptions) => { headingTransform: () => chalk.dim("CONTEXT"), align: "left", }, + parallel: { + headingTransform: () => chalk.dim("PARALLEL"), + align: "left", + }, device: { headingTransform: () => chalk.dim("DEVICE"), align: "left",