Skip to content
This repository was archived by the owner on Jul 4, 2025. It is now read-only.

Commit 779907f

Browse files
authored
feature: support local model pull (#944)
1 parent bb1edef commit 779907f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+565
-427
lines changed

cortex-js/.eslintrc.cjs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
module.exports = {
2+
parser: '@typescript-eslint/parser',
3+
parserOptions: {
4+
project: 'tsconfig.json',
5+
tsconfigRootDir: __dirname,
6+
sourceType: 'module',
7+
},
8+
plugins: ['@typescript-eslint/eslint-plugin'],
9+
extends: [
10+
'plugin:@typescript-eslint/recommended',
11+
'plugin:prettier/recommended',
12+
],
13+
root: true,
14+
env: {
15+
node: true,
16+
jest: true,
17+
},
18+
ignorePatterns: ['.eslintrc.js'],
19+
rules: {
20+
'@typescript-eslint/interface-name-prefix': 'off',
21+
'@typescript-eslint/explicit-function-return-type': 'off',
22+
'@typescript-eslint/explicit-module-boundary-types': 'off',
23+
'@typescript-eslint/no-explicit-any': 'off',
24+
'@typescript-eslint/no-unused-vars': ['warn'],
25+
'@typescript-eslint/no-floating-promises': 'warn',
26+
'@typescript-eslint/no-var-requires': 'warn',
27+
'@typescript-eslint/ban-types': 'warn',
28+
'no-unused-vars': 'off',
29+
'require-await': 'off',
30+
'prefer-const': 'warn',
31+
'no-restricted-syntax': [
32+
'warn',
33+
{
34+
selector:
35+
'CallExpression[callee.object.name=configService][callee.property.name=/^(get|getOrThrow)$/]:not(:has([arguments.1] Property[key.name=infer][value.value=true])), CallExpression[callee.object.property.name=configService][callee.property.name=/^(get|getOrThrow)$/]:not(:has([arguments.1] Property[key.name=infer][value.value=true]))',
36+
message:
37+
'Add "{ infer: true }" to configService.get() for correct typechecking. Example: configService.get("database.port", { infer: true })',
38+
},
39+
{
40+
selector:
41+
'CallExpression[callee.name=it][arguments.0.value!=/^should/]',
42+
message: '"it" should start with "should"',
43+
},
44+
],
45+
},
46+
};

cortex-js/.eslintrc.js

Lines changed: 0 additions & 31 deletions
This file was deleted.

cortex-js/package.json

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"start:dev": "nest start --watch",
2525
"start:debug": "nest start --debug --watch",
2626
"start:prod": "node dist/src/main --trace-deprecation",
27-
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
27+
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\"",
2828
"test": "jest",
2929
"test:watch": "jest --watch",
3030
"test:cov": "jest --coverage",
@@ -39,8 +39,6 @@
3939
},
4040
"dependencies": {
4141
"@cortexso/cortex.js": "^0.1.5",
42-
"@huggingface/gguf": "^0.1.5",
43-
"@huggingface/hub": "^0.15.1",
4442
"@nestjs/axios": "^3.0.2",
4543
"@nestjs/common": "^10.0.0",
4644
"@nestjs/config": "^3.2.2",
@@ -59,6 +57,7 @@
5957
"cortex-cpp": "0.4.34",
6058
"cpu-instructions": "^0.0.11",
6159
"decompress": "^4.2.1",
60+
"hyllama": "^0.2.2",
6261
"js-yaml": "^4.1.0",
6362
"nest-commander": "^3.13.0",
6463
"ora": "5.4.1",
@@ -88,14 +87,16 @@
8887
"@types/supertest": "^6.0.2",
8988
"@types/update-notifier": "^6.0.8",
9089
"@types/uuid": "^9.0.8",
91-
"@typescript-eslint/eslint-plugin": "^6.0.0",
92-
"@typescript-eslint/parser": "^6.0.0",
90+
"@typescript-eslint/eslint-plugin": "7.16.1",
91+
"@typescript-eslint/parser": "7.16.1",
9392
"@vercel/ncc": "^0.38.0",
9493
"@yao-pkg/pkg": "^5.12.0",
9594
"cpx": "^1.5.0",
96-
"eslint": "^8.42.0",
97-
"eslint-config-prettier": "^9.0.0",
98-
"eslint-plugin-prettier": "^5.0.0",
95+
"env-cmd": "10.1.0",
96+
"eslint": "8.57.0",
97+
"eslint-config-prettier": "9.1.0",
98+
"eslint-plugin-import": "2.29.1",
99+
"eslint-plugin-prettier": "5.2.1",
99100
"hanbi": "^1.0.3",
100101
"is-primitive": "^3.0.1",
101102
"jest": "^29.5.0",
@@ -112,10 +113,6 @@
112113
"tsconfig-paths": "^4.2.0",
113114
"typescript": "^5.1.3"
114115
},
115-
"resolutions": {
116-
"ajv": "8.15.0",
117-
"whatwg-url": "14.0.0"
118-
},
119116
"files": [
120117
"dist"
121118
],

cortex-js/src/infrastructure/commanders/chat.command.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ export class ChatCommand extends BaseCommand {
9393
) {
9494
console.log('Downloading engine...');
9595
await this.cortex.engines.init(engine);
96-
await downloadProgress(this.cortex, undefined, DownloadType.Engine)
96+
await downloadProgress(this.cortex, undefined, DownloadType.Engine);
9797
}
9898

9999
if (!message) options.attach = true;
@@ -108,13 +108,13 @@ export class ChatCommand extends BaseCommand {
108108
);
109109

110110
const preset = await this.fileService.getPreset(options.preset);
111-
111+
112112
return this.chatClient.chat(
113-
modelId,
114-
options.threadId,
115-
message, // Accept both message from inputs or arguments
116-
preset ? preset : {},
117-
)
113+
modelId,
114+
options.threadId,
115+
message, // Accept both message from inputs or arguments
116+
preset ? preset : {},
117+
);
118118
}
119119

120120
modelInquiry = async (models: Cortex.Model[]) => {

cortex-js/src/infrastructure/commanders/cortex-command.commander.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,7 @@ export class CortexCommand extends CommandRunner {
8484
return this.startServer(showLogs, dataFolderPath);
8585
}
8686

87-
private async startServer(
88-
attach: boolean,
89-
dataFolderPath?: string,
90-
) {
87+
private async startServer(attach: boolean, dataFolderPath?: string) {
9188
const config = await this.fileManagerService.getConfig();
9289
try {
9390
const startEngineSpinner = ora('Starting Cortex engine...');
@@ -119,9 +116,13 @@ export class CortexCommand extends CommandRunner {
119116
} else {
120117
await this.cortexUseCases.startServerDetached(this.host, this.port);
121118
}
122-
console.log(chalk.blue(`Started server at http://${this.host}:${this.port}`));
123119
console.log(
124-
chalk.blue(`API Playground available at http://${this.host}:${this.port}/api`),
120+
chalk.blue(`Started server at http://${this.host}:${this.port}`),
121+
);
122+
console.log(
123+
chalk.blue(
124+
`API Playground available at http://${this.host}:${this.port}/api`,
125+
),
125126
);
126127
await this.fileManagerService.writeConfigFile({
127128
...config,

cortex-js/src/infrastructure/commanders/models/model-pull.command.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { downloadProgress } from '@/utils/download-progress';
1919
import { CortexClient } from '../services/cortex.client';
2020
import { DownloadType } from '@/domain/models/download.interface';
2121
import ora from 'ora';
22+
import { isLocalFile } from '@/utils/urls';
2223

2324
@SubCommand({
2425
name: 'pull',
@@ -61,9 +62,8 @@ export class ModelPullCommand extends BaseCommand {
6162
exit(1);
6263
});
6364

64-
ora().succeed('Model downloaded');
65-
6665
await downloadProgress(this.cortex, modelId);
66+
ora().succeed('Model downloaded');
6767

6868
const existingModel = await this.cortex.models.retrieve(modelId);
6969
const engine = existingModel?.engine || Engines.llamaCPP;

cortex-js/src/infrastructure/commanders/run.command.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import { ChatClient } from './services/chat-client';
1313
import { downloadProgress } from '@/utils/download-progress';
1414
import { CortexClient } from './services/cortex.client';
1515
import { DownloadType } from '@/domain/models/download.interface';
16+
import { isLocalFile } from '@/utils/urls';
17+
import { parse } from 'node:path';
1618

1719
type RunOptions = {
1820
threadId?: string;
@@ -71,6 +73,12 @@ export class RunCommand extends BaseCommand {
7173
await downloadProgress(this.cortex, modelId);
7274
checkingSpinner.succeed('Model downloaded');
7375

76+
// Update to persisted modelId
77+
// TODO: Should be retrieved from the request
78+
if (isLocalFile(modelId)) {
79+
modelId = parse(modelId).name;
80+
}
81+
7482
// Second check if model is available
7583
existingModel = await this.cortex.models.retrieve(modelId);
7684
if (!existingModel) {
@@ -93,6 +101,7 @@ export class RunCommand extends BaseCommand {
93101
}
94102

95103
const startingSpinner = ora('Loading model...').start();
104+
96105
return this.cortex.models
97106
.start(modelId, await this.fileService.getPreset(options.preset))
98107
.then(() => {

cortex-js/src/infrastructure/commanders/services/chat-client.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,14 @@ export class ChatClient {
5555
});
5656

5757
rl.on('line', (input) =>
58-
this.sendCompletionMessage(input, messages, modelId, thread.id, rl, settings),
58+
this.sendCompletionMessage(
59+
input,
60+
messages,
61+
modelId,
62+
thread.id,
63+
rl,
64+
settings,
65+
),
5966
);
6067
}
6168

0 commit comments

Comments
 (0)