clarity-ai 6.4.1 → 6.5.0
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/CHANGELOG.md +17 -0
- package/LICENSE +12 -0
- package/package.json +9 -3
- package/requirements.txt +4 -0
- package/scripts/postinstall.js +19 -42
- package/space_app.py +52 -0
- package/src/config/keys.js +4 -4
- package/src/providers/index.js +2 -5
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
+
## 6.5.0 (2026-06-06)
|
|
6
|
+
|
|
7
|
+
### Closed Source + Space Proxy
|
|
8
|
+
- All tokens removed from source code — zero hardcoded secrets
|
|
9
|
+
- `LICENSE`: Proprietary, all rights reserved (`UNLICENSED`)
|
|
10
|
+
- Provider now points to `Clarity-main` Space endpoint (`*.hf.space`) instead of `api-inference.huggingface.co` — fixes DNS resolution issues on Termux/Android
|
|
11
|
+
- Clarity-main Space runs inference proxy: forwards to HF Inference API using internal `HF_TOKEN` secret
|
|
12
|
+
- No API key required from CLI — works out of the box on any network
|
|
13
|
+
- Space app: `space_app.py` — Gradio + FastAPI, `/v1/chat/completions` streaming, `/main-data` data endpoint
|
|
14
|
+
|
|
15
|
+
## 6.4.2 (2026-06-06)
|
|
16
|
+
|
|
17
|
+
### Keyless Clarity Flash
|
|
18
|
+
- HuggingFace provider no longer requires API key
|
|
19
|
+
- Built-in HF token for Clarity Flash model — works out of the box, no setup
|
|
20
|
+
- Can still override with `HF_TOKEN` env var or `/keys huggingface <token>`
|
|
21
|
+
|
|
5
22
|
## 6.4.1 (2026-06-06)
|
|
6
23
|
|
|
7
24
|
### Clarity Flash 14B Model
|
package/LICENSE
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
CLARITY AI — Proprietary Software
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Universal-618
|
|
4
|
+
|
|
5
|
+
All rights reserved.
|
|
6
|
+
|
|
7
|
+
This software and its source code are proprietary and confidential.
|
|
8
|
+
Unauthorized copying, modification, distribution, or use of this
|
|
9
|
+
software, via any medium, is strictly prohibited without prior
|
|
10
|
+
written permission from the copyright holder.
|
|
11
|
+
|
|
12
|
+
This software is provided "as is", without warranty of any kind.
|
package/package.json
CHANGED
|
@@ -1,17 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clarity-ai",
|
|
3
|
-
"version": "6.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "6.5.0",
|
|
4
|
+
"description": "CLARITY — terminal AI agent with Clarity Flash 14B",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"clarity": "bin/clarity.js"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
|
-
"start": "node bin/clarity.js"
|
|
10
|
+
"start": "node bin/clarity.js",
|
|
11
|
+
"postinstall": "node scripts/postinstall.js"
|
|
11
12
|
},
|
|
12
13
|
"engines": {
|
|
13
14
|
"node": ">=18.0.0"
|
|
14
15
|
},
|
|
16
|
+
"license": "UNLICENSED",
|
|
17
|
+
"private": false,
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public"
|
|
20
|
+
},
|
|
15
21
|
"dependencies": {
|
|
16
22
|
"ink": "^5",
|
|
17
23
|
"react": "^18",
|
package/requirements.txt
ADDED
package/scripts/postinstall.js
CHANGED
|
@@ -1,59 +1,36 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import chalk from 'chalk';
|
|
4
|
-
|
|
5
|
-
const GRADIENT = gradient(['#00d2ff', '#7b2ff7']);
|
|
6
|
-
|
|
7
|
-
try {
|
|
8
|
-
const text = figlet.textSync('CLARITY', { font: 'ANSI Shadow' });
|
|
9
|
-
console.log(GRADIENT(text));
|
|
10
|
-
} catch {
|
|
11
|
-
console.log(GRADIENT('CLARITY'));
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const nodeVersion = process.versions.node;
|
|
15
|
-
const [major] = nodeVersion.split('.').map(Number);
|
|
16
|
-
const W = process.stdout.columns || 80;
|
|
17
|
-
const line = '═'.repeat(W - 4);
|
|
1
|
+
import { existsSync, chmodSync, writeFileSync, unlinkSync, lstatSync } from 'fs';
|
|
2
|
+
import { resolve } from 'path';
|
|
18
3
|
|
|
4
|
+
const nodeVer = process.versions.node;
|
|
5
|
+
const [major] = nodeVer.split('.').map(Number);
|
|
19
6
|
if (major < 18) {
|
|
20
|
-
console.error();
|
|
21
|
-
console.error(
|
|
22
|
-
console.error(chalk.hex('#ff4466')(` ║ ✗ Node.js 18+ required. You have v${nodeVersion}`));
|
|
23
|
-
console.error(chalk.hex('#ffcc00')(` ║ Termux: pkg install nodejs-lts`));
|
|
24
|
-
console.error(chalk.hex('#ff4466')(` ╚${line}╝`));
|
|
25
|
-
console.error();
|
|
7
|
+
console.error('\n \u2717 Node.js 18+ required. You have v' + nodeVer);
|
|
8
|
+
console.error(' Termux: pkg install nodejs-lts\n');
|
|
26
9
|
process.exit(1);
|
|
27
10
|
}
|
|
28
11
|
|
|
29
12
|
const isTermux = process.env.PREFIX?.includes('com.termux');
|
|
13
|
+
const W = process.stdout.columns || 80;
|
|
14
|
+
const line = '\u2500'.repeat(Math.min(W - 4, 60));
|
|
30
15
|
|
|
31
|
-
console.log();
|
|
32
|
-
console.log(
|
|
33
|
-
console.log(
|
|
34
|
-
console.log(
|
|
35
|
-
console.log(chalk.hex('#00ff88')(` ╚${line}╝`));
|
|
36
|
-
console.log();
|
|
37
|
-
console.log(chalk.hex('#666888')(" Run 'clarity init' to configure your AI keys and get started."));
|
|
16
|
+
console.log(`\n \u250C${line}\u2510`);
|
|
17
|
+
console.log(` \u2502 CLARITY installed`);
|
|
18
|
+
console.log(` \u2502 Run: clarity init`);
|
|
19
|
+
console.log(` \u2514${line}\u2518\n`);
|
|
38
20
|
|
|
39
21
|
const binDir = process.env.npm_config_prefix ? `${process.env.npm_config_prefix}/bin` : null;
|
|
40
22
|
if (isTermux && binDir) {
|
|
41
|
-
const { existsSync, writeFileSync, chmodSync, unlinkSync, lstatSync } = await import('fs');
|
|
42
|
-
const { resolve } = await import('path');
|
|
43
23
|
const symlinkPath = resolve(binDir, 'clarity');
|
|
44
|
-
|
|
45
24
|
try {
|
|
46
25
|
if (existsSync(symlinkPath)) {
|
|
47
26
|
const stat = lstatSync(symlinkPath);
|
|
48
|
-
if (stat.isSymbolicLink())
|
|
49
|
-
unlinkSync(symlinkPath);
|
|
50
|
-
}
|
|
27
|
+
if (stat.isSymbolicLink()) unlinkSync(symlinkPath);
|
|
51
28
|
}
|
|
52
|
-
const
|
|
53
|
-
|
|
29
|
+
const pkgDir = process.env.PREFIX
|
|
30
|
+
? `${process.env.PREFIX}/lib/node_modules/clarity-ai`
|
|
31
|
+
: resolve(process.cwd());
|
|
32
|
+
writeFileSync(symlinkPath, `#!/data/data/com.termux/files/usr/bin/bash\nexec node "${pkgDir}/bin/clarity.js" "$@"\n`);
|
|
54
33
|
chmodSync(symlinkPath, '755');
|
|
55
|
-
console.log(
|
|
56
|
-
} catch
|
|
57
|
-
console.error(chalk.hex('#ff4466')(' ✗ Failed to create Termux wrapper:'), e.message);
|
|
58
|
-
}
|
|
34
|
+
console.log(' \u2713 Termux wrapper created');
|
|
35
|
+
} catch {}
|
|
59
36
|
}
|
package/space_app.py
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import os, json, requests
|
|
2
|
+
import gradio as gr
|
|
3
|
+
from fastapi import FastAPI, Request
|
|
4
|
+
from fastapi.responses import StreamingResponse, JSONResponse
|
|
5
|
+
import uvicorn
|
|
6
|
+
|
|
7
|
+
HF_TOKEN = os.environ.get('HF_TOKEN', '')
|
|
8
|
+
MODEL = 'Universal-618/Clarity-flash-weights'
|
|
9
|
+
API = f'https://api-inference.huggingface.co/models/{MODEL}/v1/chat/completions'
|
|
10
|
+
HEADERS = {'Authorization': f'Bearer {HF_TOKEN}', 'Content-Type': 'application/json'}
|
|
11
|
+
|
|
12
|
+
app = FastAPI()
|
|
13
|
+
|
|
14
|
+
@app.post('/v1/chat/completions')
|
|
15
|
+
async def chat_completions(request: Request):
|
|
16
|
+
body = await request.json()
|
|
17
|
+
body['model'] = MODEL
|
|
18
|
+
stream = body.get('stream', True)
|
|
19
|
+
body['stream'] = stream
|
|
20
|
+
resp = requests.post(API, headers=HEADERS, json=body, stream=True)
|
|
21
|
+
if resp.status_code != 200:
|
|
22
|
+
return JSONResponse({'error': resp.text}, status_code=resp.status_code)
|
|
23
|
+
if stream:
|
|
24
|
+
return StreamingResponse(resp.iter_lines(), media_type='text/event-stream', headers={'Cache-Control': 'no-cache', 'Connection': 'keep-alive', 'X-Accel-Buffering': 'no'})
|
|
25
|
+
return resp.json()
|
|
26
|
+
|
|
27
|
+
@app.get('/main-data/{path:path}')
|
|
28
|
+
async def main_data(path: str):
|
|
29
|
+
path = path or 'index.json'
|
|
30
|
+
fp = f'/data/{path}'
|
|
31
|
+
if not os.path.exists(fp):
|
|
32
|
+
return JSONResponse({'error': 'not found'}, status_code=404)
|
|
33
|
+
with open(fp) as f:
|
|
34
|
+
return JSONResponse(json.load(f))
|
|
35
|
+
|
|
36
|
+
def chat_ui(message, history):
|
|
37
|
+
history = history or []
|
|
38
|
+
msgs = [{'role': 'user' if i % 2 == 0 else 'assistant', 'content': m} for i, m in enumerate(history + [message])]
|
|
39
|
+
body = {'model': MODEL, 'messages': msgs, 'stream': False, 'max_tokens': 4096}
|
|
40
|
+
resp = requests.post(API, headers=HEADERS, json=body)
|
|
41
|
+
if resp.status_code == 200:
|
|
42
|
+
return resp.json()['choices'][0]['message']['content']
|
|
43
|
+
return f'Error: {resp.status_code}'
|
|
44
|
+
|
|
45
|
+
with gr.Blocks(title='CLARITY Flash', css='footer{display:none!important}') as ui:
|
|
46
|
+
gr.Markdown('# CLARITY Flash 14B')
|
|
47
|
+
gr.ChatInterface(chat_ui, title='Chat')
|
|
48
|
+
|
|
49
|
+
app = gr.mount_gradio_app(app, ui, path='/')
|
|
50
|
+
|
|
51
|
+
if __name__ == '__main__':
|
|
52
|
+
uvicorn.run(app, host='0.0.0.0', port=7860)
|
package/src/config/keys.js
CHANGED
|
@@ -23,10 +23,10 @@ export function setKey(provider, key) {
|
|
|
23
23
|
export function getKey(provider) {
|
|
24
24
|
try {
|
|
25
25
|
const keys = JSON.parse(readFileSync(KEYS_PATH, 'utf-8'));
|
|
26
|
-
|
|
27
|
-
} catch {
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
if (keys[provider]) return keys[provider];
|
|
27
|
+
} catch {}
|
|
28
|
+
const envKey = process.env[provider.toUpperCase() + '_API_KEY'] || process.env.HF_TOKEN;
|
|
29
|
+
return envKey || null;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
export function hasKey(provider) {
|
package/src/providers/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { parseErrorResponse } from './errors.js';
|
|
|
4
4
|
|
|
5
5
|
const PROVIDERS = {
|
|
6
6
|
huggingface: {
|
|
7
|
-
endpoint: 'https://
|
|
7
|
+
endpoint: 'https://Universal-618-Clarity-main.hf.space/v1/chat/completions',
|
|
8
8
|
name: 'huggingface',
|
|
9
9
|
},
|
|
10
10
|
groq: {
|
|
@@ -42,10 +42,7 @@ export async function* callAI(providerName, model, messages, options = {}) {
|
|
|
42
42
|
|
|
43
43
|
let endpoint = provider.endpoint;
|
|
44
44
|
const extraHeaders = {};
|
|
45
|
-
if (providerName === '
|
|
46
|
-
endpoint = provider.endpoint + '/' + modelName + '/v1/chat/completions';
|
|
47
|
-
if (key) extraHeaders['Authorization'] = 'Bearer ' + key;
|
|
48
|
-
} else if (providerName === 'openrouter') {
|
|
45
|
+
if (providerName === 'openrouter') {
|
|
49
46
|
extraHeaders['HTTP-Referer'] = 'https://clarity-ai.local';
|
|
50
47
|
extraHeaders['X-Title'] = 'CLARITY AI';
|
|
51
48
|
}
|