add basic model list

This commit is contained in:
Thien Tran 2025-05-26 13:11:37 +08:00 committed by Louis
parent d523166b61
commit cd36b423b6
No known key found for this signature in database
GPG Key ID: 44FA9F4D33C37DE2
2 changed files with 50 additions and 8 deletions

View File

@ -97,9 +97,6 @@ export interface modelInfo {
} }
// 1. /list // 1. /list
export interface listOptions {
providerId: string // To specify which provider if a central manager calls this
}
export type listResult = modelInfo[] export type listResult = modelInfo[]
// 3. /load // 3. /load
@ -195,7 +192,7 @@ export abstract class AIEngine extends BaseExtension {
/** /**
* Lists available models * Lists available models
*/ */
abstract list(opts: listOptions): Promise<listResult> abstract list(): Promise<listResult>
/** /**
* Loads a model into memory * Loads a model into memory

View File

@ -12,8 +12,6 @@ import {
fs, fs,
joinPath, joinPath,
modelInfo, modelInfo,
listOptions,
listResult,
loadOptions, loadOptions,
sessionInfo, sessionInfo,
unloadOptions, unloadOptions,
@ -94,8 +92,55 @@ export default class llamacpp_extension extends AIEngine {
} }
// Implement the required LocalProvider interface methods // Implement the required LocalProvider interface methods
override async list(opts: listOptions): Promise<listResult> { override async list(): Promise<modelInfo[]> {
throw new Error('method not implemented yet') const modelsDir = await joinPath([this.modelsBasePath, this.provider])
if (!(await fs.existsSync(modelsDir))) {
return []
}
let modelIds: string[] = []
// DFS
let stack = [modelsDir]
while (stack.length > 0) {
const currentDir = stack.pop()
// check if model.yml exists
const modelConfigPath = await joinPath([currentDir, 'model.yml'])
if (await fs.existsSync(modelConfigPath)) {
// +1 to remove the leading slash
// NOTE: this does not handle Windows path \\
modelIds.push(currentDir.slice(modelsDir.length + 1))
continue
}
// otherwise, look into subdirectories
const children = await fs.readdirSync(currentDir)
for (const child of children) {
// NOTE: currently fs.fileStat() output is a string
// TODO: fix this in core
// skip files
const dirInfo = await fs.fileStat(child).then(JSON.parse)
if (!dirInfo.isDirectory) {
continue
}
stack.push(child)
}
}
const modelInfos = modelIds.map((modelId) => {
return {
id: modelId,
name: modelId, // TODO: parse name from model.yml
quant_type: undefined, // TODO: parse quantization type from model.yml or model.gguf
providerId: this.provider,
port: 0, // port is not known until the model is loaded
sizeBytes: 0, // TODO: cache this in model.yml and read from it
}
})
return modelInfos
} }
override async import(modelId: string, opts: ImportOptions): Promise<void> { override async import(modelId: string, opts: ImportOptions): Promise<void> {