Skip to content
Open
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
53 changes: 48 additions & 5 deletions packages/backend/src/managers/modelsManager.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ test('getModelsInfo should get models in local directory', async () => {
file: {
size: 32000,
creation: now,
path: path.resolve(dirent[0].parentPath, dirent[0].name),
path: path.resolve(modelsDir, dirent[0].name),
file: 'model-id-1-model',
},
},
Expand All @@ -244,13 +244,55 @@ test('getModelsInfo should get models in local directory', async () => {
file: {
size: 32000,
creation: now,
path: path.resolve(dirent[1].parentPath, dirent[1].name),
path: path.resolve(modelsDir, dirent[1].name),
file: 'model-id-2-model',
},
},
]);
});

test('URLModelHandler.getLocalModelsFromDisk should work with undefined parentPath', async () => {
const modelsDir = 'models';
const manager = {
getModelInfo: vi.fn(id => ({ id, name: `${id}-model` }) as ModelInfo),
} as unknown as ModelsManager;

const handler = new URLModelHandler(manager, modelsDir);

vi.spyOn(fs, 'existsSync').mockReturnValue(true);

const mockReaddir = vi.fn().mockImplementation(async path => {
if (path === modelsDir) {
return [
{
isDirectory: () => true,
parentPath: undefined, // This simulates the issue
name: 'test-model',
isFile: () => false,
isBlockDevice: () => false,
isCharacterDevice: () => false,
isSymbolicLink: () => false,
isFIFO: () => false,
isSocket: () => false,
} as unknown as fs.Dirent,
];
}
return ['test-model.gguf'];
});

vi.spyOn(fs.promises, 'readdir').mockImplementation(mockReaddir);
vi.spyOn(fs.promises, 'stat').mockResolvedValue({
size: 1000,
mtime: new Date(),
} as fs.Stats);

// Should not throw error even with undefined parentPath
await expect(handler.getLocalModelsFromDisk()).resolves.not.toThrow();

// Verify the model was updated with correct path
expect(manager.getModelInfo).toHaveBeenCalledWith('test-model');
});

test('getModelsInfo should return an empty array if the models folder does not exist', async () => {
vi.spyOn(os, 'homedir').mockReturnValue('/home/user');
const existsSyncSpy = vi.spyOn(fs, 'existsSync');
Expand Down Expand Up @@ -327,7 +369,7 @@ test('getLocalModelsFromDisk should return undefined Date and size when stat fai
file: {
size: undefined,
creation: undefined,
path: path.resolve(dirent[0].parentPath, dirent[0].name),
path: path.resolve(modelsDir, dirent[0].name),
file: 'model-id-1-model',
},
},
Expand Down Expand Up @@ -425,7 +467,7 @@ test('loadLocalModels should post a message with the message on disk and on cata
creation: now,
file: 'model-id-1-model',
size: 32000,
path: path.resolve(dirent[0].parentPath, dirent[0].name),
path: path.resolve(modelsDir, dirent[0].name),
},
id: 'model-id-1',
},
Expand Down Expand Up @@ -552,8 +594,9 @@ describe('deleting models', () => {
creation: now,
file: 'model-id-1-model',
size: 32000,
path: path.resolve(dirent[0].parentPath, dirent[0].name),
path: path.resolve(modelsDir, dirent[0].name),
},
state: undefined,
},
]);
expect(mocks.showErrorMessageMock).toHaveBeenCalledOnce();
Expand Down
6 changes: 3 additions & 3 deletions packages/backend/src/models/URLModelHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,13 @@ export class URLModelHandler extends ModelHandler {
const entries = await fs.promises.readdir(this.modelsDir, { withFileTypes: true });
const dirs = entries.filter(dir => dir.isDirectory());
for (const d of dirs) {
const modelEntries = await fs.promises.readdir(resolve(d.parentPath, d.name));
const modelEntries = await fs.promises.readdir(resolve(this.modelsDir, d.name));
if (modelEntries.length !== 1) {
// we support models with one file only for now
continue;
}
const modelFile = modelEntries[0];
const fullPath = resolve(d.parentPath, d.name, modelFile);
const fullPath = resolve(this.modelsDir, d.name, modelFile);

// Check for corresponding models or tmp file that should be ignored
try {
Expand All @@ -84,7 +84,7 @@ export class URLModelHandler extends ModelHandler {

model.file = {
file: modelFile,
path: resolve(d.parentPath, d.name),
path: resolve(this.modelsDir, d.name),
size: info.size,
creation: info.mtime,
};
Expand Down
Loading