@vierratale/ai 0.1.0-beta.3 → 0.1.0-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/package.json +1 -1
- package/src/cli.js +14 -7
- package/src/config.js +4 -2
- package/src/index.js +1 -1
- package/src/installer.js +10 -9
- package/src/providers/{ollama.js → cortex.js} +7 -7
- package/src/providers/index.js +3 -3
- package/src/ui/branding.js +8 -9
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ npx @vierratale/ai
|
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
18
|
vierrataleai # Start chat (auto-detect provider)
|
|
19
|
-
vierrataleai --provider
|
|
19
|
+
vierrataleai --provider cortex # Use local models
|
|
20
20
|
vierrataleai --provider openai # Use cloud models
|
|
21
21
|
vierrataleai --model vierratale-pro # Use specific model
|
|
22
22
|
```
|
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -29,7 +29,7 @@ ${Branding.APP_NAME} ${Branding.VERSION}
|
|
|
29
29
|
Usage: vierrataleai [options]
|
|
30
30
|
|
|
31
31
|
Options:
|
|
32
|
-
--provider, -p <name> Provider:
|
|
32
|
+
--provider, -p <name> Provider: cortex, openai (default: auto-detect)
|
|
33
33
|
--model, -m <name> Model: vierratale-lite/fast/balanced/pro/cloud
|
|
34
34
|
--clear Clear screen on start
|
|
35
35
|
--version, -v Show version
|
|
@@ -47,7 +47,7 @@ Commands (in chat):
|
|
|
47
47
|
`);
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
async function answerWithSearch(messages, provider, query) {
|
|
50
|
+
async function answerWithSearch(messages, provider, query, systemPrompt) {
|
|
51
51
|
Terminal.printInfo('Searching the web...');
|
|
52
52
|
const results = await WebSearch.search(query);
|
|
53
53
|
|
|
@@ -85,6 +85,7 @@ async function answerWithSearch(messages, provider, query) {
|
|
|
85
85
|
if (response) {
|
|
86
86
|
messages.push({ role: 'assistant', content: response });
|
|
87
87
|
}
|
|
88
|
+
Session.save(messages);
|
|
88
89
|
}
|
|
89
90
|
|
|
90
91
|
async function chat(provider, systemPrompt) {
|
|
@@ -156,7 +157,7 @@ async function chat(provider, systemPrompt) {
|
|
|
156
157
|
}
|
|
157
158
|
|
|
158
159
|
if (cmd === '/models') {
|
|
159
|
-
const models = provider.name === '
|
|
160
|
+
const models = provider.name === 'cortex'
|
|
160
161
|
? Catalog.getLocalModels()
|
|
161
162
|
: Catalog.getCloudModels();
|
|
162
163
|
Terminal.printInfo('Available models:');
|
|
@@ -188,9 +189,15 @@ async function chat(provider, systemPrompt) {
|
|
|
188
189
|
|
|
189
190
|
if (cmd.startsWith('/provider ')) {
|
|
190
191
|
const prov = cmd.split(' ')[1];
|
|
191
|
-
if (['
|
|
192
|
+
if (['cortex', 'openai'].includes(prov)) {
|
|
192
193
|
Config.save({ provider: prov });
|
|
193
|
-
|
|
194
|
+
const next = ProviderFactory.create(prov);
|
|
195
|
+
if (next && await next.isAvailable()) {
|
|
196
|
+
provider = next;
|
|
197
|
+
Terminal.printSuccess(`Provider: ${prov}`);
|
|
198
|
+
} else {
|
|
199
|
+
Terminal.printWarning(`Provider saved, but ${prov} is not available right now. Will apply on restart.`);
|
|
200
|
+
}
|
|
194
201
|
} else {
|
|
195
202
|
Terminal.printError(`Unknown provider: ${prov}`);
|
|
196
203
|
}
|
|
@@ -208,14 +215,14 @@ async function chat(provider, systemPrompt) {
|
|
|
208
215
|
Terminal.printWarning('Usage: /search <query>');
|
|
209
216
|
continue;
|
|
210
217
|
}
|
|
211
|
-
await answerWithSearch(messages, provider, query);
|
|
218
|
+
await answerWithSearch(messages, provider, query, systemPrompt);
|
|
212
219
|
continue;
|
|
213
220
|
}
|
|
214
221
|
|
|
215
222
|
const intent = detectIntent(trimmed);
|
|
216
223
|
if (intent.type === 'knowledge') {
|
|
217
224
|
Terminal.printSuccess(`Auto-search: "${trimmed}"`);
|
|
218
|
-
await answerWithSearch(messages, provider, trimmed);
|
|
225
|
+
await answerWithSearch(messages, provider, trimmed, systemPrompt);
|
|
219
226
|
continue;
|
|
220
227
|
}
|
|
221
228
|
|
package/src/config.js
CHANGED
|
@@ -8,7 +8,7 @@ const CONFIG_FILE = join(CONFIG_DIR, 'config.json');
|
|
|
8
8
|
const DEFAULTS = {
|
|
9
9
|
provider: 'auto',
|
|
10
10
|
model: 'vierratale-fast',
|
|
11
|
-
|
|
11
|
+
engineHost: 'http://127.0.0.1:11434',
|
|
12
12
|
numCtx: 8192,
|
|
13
13
|
temperature: 0.7,
|
|
14
14
|
maxTokens: 4096,
|
|
@@ -33,10 +33,12 @@ export const Config = {
|
|
|
33
33
|
|
|
34
34
|
load() {
|
|
35
35
|
const file = loadConfigFile();
|
|
36
|
+
// Migrate legacy 'cortexHost' key to 'engineHost' if present.
|
|
37
|
+
const engineHost = file.engineHost || file.cortexHost || DEFAULTS.engineHost;
|
|
36
38
|
this._config = {
|
|
37
39
|
provider: getEnv('VIERRATALE_PROVIDER', file.provider || DEFAULTS.provider),
|
|
38
40
|
model: getEnv('VIERRATALE_MODEL', file.model || DEFAULTS.model),
|
|
39
|
-
|
|
41
|
+
engineHost: getEnv('VIERRATALE_ENGINE_HOST', engineHost),
|
|
40
42
|
numCtx: parseInt(getEnv('VIERRATALE_NUM_CTX', String(file.numCtx || DEFAULTS.numCtx))),
|
|
41
43
|
temperature: parseFloat(getEnv('VIERRATALE_TEMPERATURE', String(file.temperature || DEFAULTS.temperature))),
|
|
42
44
|
maxTokens: parseInt(getEnv('VIERRATALE_MAX_TOKENS', String(file.maxTokens || DEFAULTS.maxTokens))),
|
package/src/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { Catalog } from './catalog.js';
|
|
2
2
|
export { Config } from './config.js';
|
|
3
3
|
export { Installer } from './installer.js';
|
|
4
|
-
export {
|
|
4
|
+
export { CortexProvider } from './providers/cortex.js';
|
|
5
5
|
export { OpenAIProvider } from './providers/openai.js';
|
|
6
6
|
export { Branding } from './ui/branding.js';
|
package/src/installer.js
CHANGED
|
@@ -9,13 +9,13 @@ function runSilent(cmd) {
|
|
|
9
9
|
});
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
function
|
|
12
|
+
function isEngineRunning(host) {
|
|
13
13
|
return fetch(`${host}/api/tags`, { signal: AbortSignal.timeout(3000) })
|
|
14
14
|
.then((r) => r.ok)
|
|
15
15
|
.catch(() => false);
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
function
|
|
18
|
+
function isEngineInstalled() {
|
|
19
19
|
try {
|
|
20
20
|
execSync('which ollama 2>/dev/null', { stdio: 'ignore' });
|
|
21
21
|
return true;
|
|
@@ -24,8 +24,9 @@ function isOllamaInstalled() {
|
|
|
24
24
|
return paths.some((p) => existsSync(p));
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
async function
|
|
27
|
+
async function installEngine() {
|
|
28
28
|
await runSilent('curl -fsSL https://ollama.com/install.sh | sh');
|
|
29
|
+
return isEngineInstalled();
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
async function pullModel(host, model) {
|
|
@@ -55,13 +56,13 @@ async function getInstalledModels(host) {
|
|
|
55
56
|
|
|
56
57
|
export const Installer = {
|
|
57
58
|
async ensure() {
|
|
58
|
-
const host = Config.get('
|
|
59
|
+
const host = Config.get('engineHost');
|
|
59
60
|
|
|
60
|
-
if (!
|
|
61
|
-
await
|
|
61
|
+
if (!isEngineInstalled()) {
|
|
62
|
+
await installEngine();
|
|
62
63
|
}
|
|
63
64
|
|
|
64
|
-
const running = await
|
|
65
|
+
const running = await isEngineRunning(host);
|
|
65
66
|
if (!running) {
|
|
66
67
|
try {
|
|
67
68
|
execSync('ollama serve &', { stdio: 'ignore' });
|
|
@@ -83,7 +84,7 @@ export const Installer = {
|
|
|
83
84
|
},
|
|
84
85
|
|
|
85
86
|
async isReady() {
|
|
86
|
-
const host = Config.get('
|
|
87
|
-
return
|
|
87
|
+
const host = Config.get('engineHost');
|
|
88
|
+
return isEngineRunning(host);
|
|
88
89
|
},
|
|
89
90
|
};
|
|
@@ -2,10 +2,10 @@ import { BaseProvider } from './base.js';
|
|
|
2
2
|
import { Catalog } from '../catalog.js';
|
|
3
3
|
import { Config } from '../config.js';
|
|
4
4
|
|
|
5
|
-
export class
|
|
5
|
+
export class CortexProvider extends BaseProvider {
|
|
6
6
|
constructor() {
|
|
7
|
-
super('
|
|
8
|
-
this.host = Config.get('
|
|
7
|
+
super('cortex');
|
|
8
|
+
this.host = Config.get('engineHost');
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
get displayName() {
|
|
@@ -40,12 +40,12 @@ export class OllamaProvider extends BaseProvider {
|
|
|
40
40
|
const model = Catalog.getRealModel(options.model || Config.get('model'));
|
|
41
41
|
const systemPrompt = options.systemPrompt || '';
|
|
42
42
|
|
|
43
|
-
const
|
|
43
|
+
const engineMessages = [];
|
|
44
44
|
if (systemPrompt) {
|
|
45
|
-
|
|
45
|
+
engineMessages.push({ role: 'system', content: systemPrompt });
|
|
46
46
|
}
|
|
47
47
|
for (const msg of messages) {
|
|
48
|
-
|
|
48
|
+
engineMessages.push({ role: msg.role, content: msg.content });
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
const resp = await fetch(`${this.host}/api/chat`, {
|
|
@@ -53,7 +53,7 @@ export class OllamaProvider extends BaseProvider {
|
|
|
53
53
|
headers: { 'Content-Type': 'application/json' },
|
|
54
54
|
body: JSON.stringify({
|
|
55
55
|
model,
|
|
56
|
-
messages:
|
|
56
|
+
messages: engineMessages,
|
|
57
57
|
stream: true,
|
|
58
58
|
options: {
|
|
59
59
|
num_ctx: Config.get('numCtx'),
|
package/src/providers/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CortexProvider } from './cortex.js';
|
|
2
2
|
import { OpenAIProvider } from './openai.js';
|
|
3
3
|
import { Config } from '../config.js';
|
|
4
4
|
|
|
@@ -7,7 +7,7 @@ let providers = {};
|
|
|
7
7
|
function getProviders() {
|
|
8
8
|
if (Object.keys(providers).length === 0) {
|
|
9
9
|
providers = {
|
|
10
|
-
|
|
10
|
+
cortex: new CortexProvider(),
|
|
11
11
|
openai: new OpenAIProvider(),
|
|
12
12
|
};
|
|
13
13
|
}
|
|
@@ -23,7 +23,7 @@ export const ProviderFactory = {
|
|
|
23
23
|
if (await ps[requested].isAvailable()) return ps[requested];
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
for (const name of ['
|
|
26
|
+
for (const name of ['cortex', 'openai']) {
|
|
27
27
|
if (await ps[name].isAvailable()) return ps[name];
|
|
28
28
|
}
|
|
29
29
|
|
package/src/ui/branding.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export const Branding = {
|
|
2
2
|
APP_NAME: 'VierrataleAI',
|
|
3
|
-
VERSION: '0.1.0-beta.
|
|
3
|
+
VERSION: '0.1.0-beta.5',
|
|
4
4
|
|
|
5
5
|
colors: {
|
|
6
6
|
primary: '\x1b[38;2;124;58;237m',
|
|
@@ -14,14 +14,13 @@ export const Branding = {
|
|
|
14
14
|
},
|
|
15
15
|
|
|
16
16
|
BANNER: [
|
|
17
|
-
'',
|
|
18
|
-
'
|
|
19
|
-
'
|
|
20
|
-
'
|
|
21
|
-
'
|
|
22
|
-
'
|
|
23
|
-
'
|
|
24
|
-
'',
|
|
17
|
+
' _',
|
|
18
|
+
' _ _ _ / \\ _______',
|
|
19
|
+
' | | | | / _ \\\\_ _ /',
|
|
20
|
+
' | | | |_ ___ _ __ _ __ __ _/ /_\\ \\ | | ',
|
|
21
|
+
' | | | | |/ _ \\ \'__| \'__/ _` | _ | | | ',
|
|
22
|
+
' \\ \\_/ / | __/ | | | | (_| | | | |_| |_ ',
|
|
23
|
+
' \\___/|_|\\___|_| |_| \\__,_|_| |_/\\___/ ',
|
|
25
24
|
].join('\n'),
|
|
26
25
|
|
|
27
26
|
USER_PROMPT: 'You',
|