UNPKG

alwaysai

Version:

The alwaysAI command-line interface (CLI)

143 lines (127 loc) 4.58 kB
import { CliLeaf, CliOneOfInput, CliStringInput } from '@alwaysai/alwayscli'; import { yesCliInput } from '../../cli-inputs'; import { checkUserIsLoggedInComponent } from '../../components/user'; import { getModels } from '../../core/model'; import { echo } from '../../util'; export const modelList = CliLeaf({ name: 'list', description: 'List models', namedInputs: { yes: yesCliInput, owner: CliStringInput({ description: 'Filter by the owner of the model.' }), filter: CliStringInput({ description: 'Filter by a custom string in the id of the model.' }), sortBy: CliOneOfInput({ description: 'Sort the results.', required: false, values: ['ascending', 'descending', 'oldest', 'latest'] }) }, async action(_, { yes, owner, filter, sortBy }) { await checkUserIsLoggedInComponent({ yes }); const models = await getModels({ yes }); const modelTable: { id: string; version: number; updated_at: string }[] = []; // Create an array of models dropping the other parameters for (const model of models) { modelTable.push({ id: model.id, version: model.version, updated_at: formatUpdatedAt(model.updated_at) }); } // Group models by ids and select the one with the highest version for each group const latestModels = Object.values( modelTable.reduce((acc, model) => { // If this is the first model or a newer version, update the model in the accumulator if (!acc[model.id] || acc[model.id].version < model.version) { acc[model.id] = model; } return acc; }, {}) ); // Filter data if filter provided const filteredData = filterModels(latestModels, { owner, id: filter }); // Sort data if sort flag provided, otherwise use latest. sortBy = sortBy || 'latest'; const sortedData = sortModels(filteredData, sortBy); // Transform data for display const transformedData = sortedData.map((item) => ({ id: item.id, version: item.version, updated_at: item.updated_at.toLocaleString() })); // Inform user of chosen filters and how many results are given if (owner || filter) { const filterBy: string[] = []; if (owner) filterBy.push(`owner: '${owner}'`); if (filter) filterBy.push(`id: '${filter}'`); echo(`Filtering by ${filterBy.join(' and ')}`); } if (transformedData.length < 1) { echo(`Did not find any matching results. Try using a different filter`); } else { echo( `Displaying ${transformedData.length}/${latestModels.length} models in the ${sortBy} order.` ); console.table(transformedData); } } }); // Filter by ID and description function filterModels(modelTable, filter: { owner?: string; id?: string }) { return modelTable.filter((model) => { // Split the model.id into owner and id const owner = model.id.split('/')[0]; const id = model.id.split('/')[1]; // Filter the results const matchesOwner = filter.owner ? owner.includes(filter.owner) : true; const matchesId = filter.id ? id.includes(filter.id) : true; return matchesOwner && matchesId; }); } // Sort models by sorting flag function sortModels(models, sortBy: string) { let sortedModels = [...models]; // Create a shallow copy to avoid modifying the original array switch (sortBy) { case 'ascending': sortedModels = sortedModels.sort((a, b) => a.id.localeCompare(b.id, undefined, { sensitivity: 'accent' }) ); break; case 'descending': sortedModels = sortedModels.sort((a, b) => b.id.localeCompare(a.id, undefined, { sensitivity: 'accent' }) ); break; case 'oldest': sortedModels = sortedModels.sort((a, b) => a.updated_at - b.updated_at); break; case 'latest': sortedModels = sortedModels.sort((a, b) => b.updated_at - a.updated_at); break; default: console.log('Invalid sorting option'); } return sortedModels; } function formatUpdatedAt(updatedAt: string): string { let date; // Try to convert to a Date object if (!isNaN(Number(updatedAt))) { // If the value is a numeric string (timestamp in milliseconds) date = new Date(Number(updatedAt)); } else { // Otherwise, treat it as an ISO string (e.g., '2022-05-12T21:18:26.596Z') date = new Date(updatedAt); } // If the date is valid, format it as a readable string if (!isNaN(date.getTime())) { return date; } else { return 'Invalid Date'; } }