clarity-ai 6.3.2 → 6.4.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 CHANGED
@@ -2,6 +2,25 @@
2
2
 
3
3
  ---
4
4
 
5
+ ## 6.4.0 (2026-06-06)
6
+
7
+ ### Clarity Flash 14B Model
8
+ - Added `Clarity Flash 14B` to `/model` picker — 128K context, HuggingFace Inference API
9
+ - New `huggingface` provider: calls `https://api-inference.huggingface.co/models/{model}/v1/chat/completions`
10
+ - `getKey()` falls back to `HF_TOKEN` env var for seamless auth
11
+ - Model weights at `Universal-618/Clarity-flash-weights` on HF Hub
12
+
13
+ ### Fixed-Height Engine (v6.3.x carried forward)
14
+ - Fixed-height viewport with `sliceToViewport()` + `buildLineArray()`
15
+ - Line-by-line streaming via `LineRenderer` (14 line types)
16
+ - Composer: multiline input with auto-grow (max 3 rows), Shift+Enter newline
17
+
18
+ ### Training Notebooks
19
+ - `clarity_flash_14b.ipynb`: Colab T4 — DeepSeek-R1-Distill-Qwen-14B, 4-bit QLoRA, 500 steps, 20 datasets
20
+ - `clarity_heavy_20b_moe.ipynb`: Kaggle T4 — GPT-OSS-20B MoE, MXFP4 native, LoRA, 20 datasets
21
+
22
+ ---
23
+
5
24
  ## 3.1.0 (2026-06-05)
6
25
 
7
26
  ### UI Rewrite — OpenCode Style
package/README.md CHANGED
@@ -92,16 +92,26 @@ clarity /bash ls -la
92
92
  | `/help [command]` | Command help |
93
93
  | `/exit` | Exit CLARITY |
94
94
 
95
+ ## Available Models
96
+
97
+ | Model | Provider | Context |
98
+ |---|---|---|
99
+ | **Clarity Flash 14B** | HuggingFace Inference | 128K |
100
+ | Llama 3.3 70B Versatile | Groq | 32K |
101
+ | Llama 3.1 8B Instant | Groq | 8K (fast) |
102
+ | DeepSeek R1 Distill 70B | Groq | 32K (reasoning) |
103
+ | Gemini 2.0 Flash | Google | 32K (fast) |
104
+ | DeepSeek R1 Free | OpenRouter | 128K |
105
+
95
106
  ## Provider Comparison
96
107
 
97
108
  | Provider | Free Tier | Streaming | Priority |
98
109
  |---|---|---|---|
99
110
  | Groq | ✓ | ✓ | 1 (fastest) |
100
111
  | Google Gemini | ✓ | ✓ | 2 |
101
- | DeepSeek | Cheap | ✓ | 3 |
102
- | OpenRouter | | ✓ | 4 |
103
- | OpenAI | Paid | ✓ | 5 |
104
- | Anthropic | Paid | ✓ | 6 |
112
+ | HuggingFace (Clarity Flash) | Needs HF_TOKEN | ✓ | 3 |
113
+ | DeepSeek | Cheap | ✓ | 4 |
114
+ | OpenRouter | | ✓ | 5 |
105
115
 
106
116
  ## License
107
117
 
@@ -0,0 +1,226 @@
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "source": [
6
+ "# CLARITY Flash 14B — Trained! Push to Universal-618/Clarity-flash-weights\n",
7
+ "Model: deepseek-ai/DeepSeek-R1-Distill-Qwen-14B\n",
8
+ "4-bit QLoRA + grad ckpt + max_len=256\n",
9
+ "Weights pushed to HF dataset repo for inference on 6 Clarity Spaces\n"
10
+ ],
11
+ "metadata": {}
12
+ },
13
+ {
14
+ "cell_type": "code",
15
+ "source": [
16
+ "import os,gc,torch\n",
17
+ "from huggingface_hub import create_repo\n",
18
+ "from google.colab import userdata\n",
19
+ "HF_TOKEN = os.environ.get('HF_TOKEN') or userdata.get('HF_TOKEN')\n",
20
+ "assert HF_TOKEN and len(HF_TOKEN)>10, 'Set HF_TOKEN in Colab secrets'\n"
21
+ ],
22
+ "metadata": {},
23
+ "execution_count": null,
24
+ "outputs": []
25
+ },
26
+ {
27
+ "cell_type": "code",
28
+ "source": [
29
+ "!pip install -q transformers datasets accelerate peft bitsandbytes sentencepiece huggingface_hub\n"
30
+ ],
31
+ "metadata": {},
32
+ "execution_count": null,
33
+ "outputs": []
34
+ },
35
+ {
36
+ "cell_type": "code",
37
+ "source": [
38
+ "assert torch.cuda.is_available()\n",
39
+ "print('GPU:', torch.cuda.get_device_name(0))\n",
40
+ "gc.collect(); torch.cuda.empty_cache()\n"
41
+ ],
42
+ "metadata": {},
43
+ "execution_count": null,
44
+ "outputs": []
45
+ },
46
+ {
47
+ "cell_type": "code",
48
+ "source": [
49
+ "import requests,sys\n",
50
+ "from datasets import Dataset, load_dataset\n",
51
+ "import random\n",
52
+ "\n",
53
+ "all_samples = []\n",
54
+ "def add(i,r): all_samples.append(dict(instruction=str(i or ''), response=str(r or '')))\n",
55
+ "\n",
56
+ "def load_std(n,s,f,l,**kw):\n",
57
+ " try:\n",
58
+ " for i,row in enumerate(load_dataset(n,split=s,streaming=True,token=HF_TOKEN,**kw)):\n",
59
+ " if i>=l: break\n",
60
+ " add(row.get(f['instruction'],''),row.get(f['response'],''))\n",
61
+ " except Exception as e: print(f' skip {n}: {e}', file=sys.stderr)\n",
62
+ "\n",
63
+ "def load_msgs(n,s,l,**kw):\n",
64
+ " try:\n",
65
+ " for i,row in enumerate(load_dataset(n,split=s,streaming=True,token=HF_TOKEN,**kw)):\n",
66
+ " if i>=l: break\n",
67
+ " msgs=row.get('messages',[])\n",
68
+ " if len(msgs)>=2: add(msgs[0].get('content',''),msgs[-1].get('content',''))\n",
69
+ " except Exception as e: print(f' skip {n}: {e}', file=sys.stderr)\n",
70
+ "\n",
71
+ "for sfx in ['main','2','3','4','5','6']:\n",
72
+ " try:\n",
73
+ " r=requests.get(f'https://huggingface.co/spaces/Universal-618/Clarity-{sfx}/main-data',headers={'Authorization':f'Bearer {HF_TOKEN}'},timeout=30)\n",
74
+ " if r.status_code==200:\n",
75
+ " d=r.json()\n",
76
+ " for x in (d if isinstance(d,list) else d.get('data',[])):\n",
77
+ " add(x.get('instruction',x.get('prompt',x.get('problem',''))),x.get('response',x.get('completion',x.get('output',x.get('solution','')))))\n",
78
+ " except: pass\n",
79
+ "\n",
80
+ "load_std('Open-Orca/OpenOrca','train',dict(instruction='question',response='response'),800)\n",
81
+ "load_msgs('HuggingFaceH4/no_robots','train',500)\n",
82
+ "load_msgs('HuggingFaceH4/ultrachat_200k','train_sft',500)\n",
83
+ "load_std('tatsu-lab/alpaca','train',dict(instruction='instruction',response='output'),500)\n",
84
+ "load_std('TIGER-Lab/MathInstruct','train',dict(instruction='instruction',response='output'),800)\n",
85
+ "load_std('AI-MO/NuminaMath-CoT','train',dict(instruction='problem',response='solution'),600)\n",
86
+ "load_std('meta-math/MetaMathQA','train',dict(instruction='query',response='response'),600)\n",
87
+ "load_std('microsoft/orca-math-word-problems-200k','train',dict(instruction='question',response='answer'),500)\n",
88
+ "load_std('GAIR/Reasoning-Intensive','train',dict(instruction='question',response='answer'),500)\n",
89
+ "load_std('BAAI/AgentInstruct','train',dict(instruction='instruction',response='output'),500)\n",
90
+ "load_std('bigcode/commitpackft','train',dict(instruction='instruction',response='response'),500)\n",
91
+ "load_std('sahil2801/CodeAlpaca-20k','train',dict(instruction='instruction',response='output'),500)\n",
92
+ "load_std('jondurbin/airoboros-3.2','train',dict(instruction='instruction',response='response'),500)\n",
93
+ "load_std('cognitivecomputations/dolphin','train',dict(instruction='instruction',response='response'),500)\n",
94
+ "load_std('databricks/databricks-dolly-15k','train',dict(instruction='instruction',response='response'),500)\n",
95
+ "load_std('WizardLM/WizardLM_evol_instruct_V2_196k','train',dict(instruction='instruction',response='output'),500)\n",
96
+ "load_std('Intel/orca_dpo_pairs','train',dict(instruction='question',response='chosen'),500)\n",
97
+ "load_std('nvidia/HelpSteer','train',dict(instruction='instruction',response='response'),500)\n",
98
+ "load_std('Dahoas/full-hh-rlhf','train',dict(instruction='instruction',response='response'),500)\n",
99
+ "load_std('BAAI/Infinity-Instruct','0625',dict(instruction='instruction',response='output'),500)\n",
100
+ "\n",
101
+ "print(f'Total: {len(all_samples)}')\n",
102
+ "random.shuffle(all_samples); gc.collect()\n"
103
+ ],
104
+ "metadata": {},
105
+ "execution_count": null,
106
+ "outputs": []
107
+ },
108
+ {
109
+ "cell_type": "code",
110
+ "source": [
111
+ "from transformers import AutoTokenizer\n",
112
+ "\n",
113
+ "MODEL_ID='deepseek-ai/DeepSeek-R1-Distill-Qwen-14B'\n",
114
+ "tokz=AutoTokenizer.from_pretrained(MODEL_ID,token=HF_TOKEN,trust_remote_code=True,use_fast=True)\n",
115
+ "tokz.pad_token=tokz.eos_token\n",
116
+ "\n",
117
+ "def fmt(s): return tokz.apply_chat_template([{'role':'user','content':s.get('instruction','')},{'role':'assistant','content':s.get('response','')}],tokenize=False)\n",
118
+ "\n",
119
+ "ds=Dataset.from_list([{'text':fmt(s)} for s in all_samples])\n",
120
+ "sp=ds.train_test_split(test_size=0.01,seed=42)\n",
121
+ "del all_samples,ds; gc.collect()\n",
122
+ "print(f'Train: {len(sp[\"train\"])} Test: {len(sp[\"test\"])}')\n"
123
+ ],
124
+ "metadata": {},
125
+ "execution_count": null,
126
+ "outputs": []
127
+ },
128
+ {
129
+ "cell_type": "code",
130
+ "source": [
131
+ "from transformers import AutoModelForCausalLM,BitsAndBytesConfig\n",
132
+ "gc.collect(); torch.cuda.empty_cache()\n",
133
+ "\n",
134
+ "bnb=BitsAndBytesConfig(load_in_4bit=True,bnb_4bit_use_double_quant=True,bnb_4bit_quant_type='nf4',bnb_4bit_compute_dtype=torch.float16)\n",
135
+ "\n",
136
+ "model=AutoModelForCausalLM.from_pretrained(MODEL_ID,quantization_config=bnb,device_map='auto',dtype=torch.float16,token=HF_TOKEN,trust_remote_code=True,low_cpu_mem_usage=True)\n",
137
+ "model.gradient_checkpointing_enable()\n",
138
+ "model.config.use_cache=False\n",
139
+ "gc.collect(); torch.cuda.empty_cache()\n",
140
+ "print('Model:',round(model.num_parameters()/1e9,1),'B trainable:',round(model.num_parameters(only_trainable=True)/1e6,1),'M')\n"
141
+ ],
142
+ "metadata": {},
143
+ "execution_count": null,
144
+ "outputs": []
145
+ },
146
+ {
147
+ "cell_type": "code",
148
+ "source": [
149
+ "from peft import LoraConfig,get_peft_model,TaskType\n",
150
+ "lora=LoraConfig(task_type=TaskType.CAUSAL_LM,r=4,lora_alpha=8,lora_dropout=0.05,target_modules=['q_proj','k_proj','v_proj','o_proj','gate_proj','up_proj','down_proj'],bias='none')\n",
151
+ "model=get_peft_model(model,lora)\n",
152
+ "model.print_trainable_parameters()\n",
153
+ "gc.collect(); torch.cuda.empty_cache()\n"
154
+ ],
155
+ "metadata": {},
156
+ "execution_count": null,
157
+ "outputs": []
158
+ },
159
+ {
160
+ "cell_type": "code",
161
+ "source": [
162
+ "from transformers import TrainingArguments,Trainer,DataCollatorForSeq2Seq\n",
163
+ "\n",
164
+ "def tok_fn(ex):\n",
165
+ " t=tokz(ex['text'],truncation=True,max_length=256,padding=False)\n",
166
+ " t['labels']=t['input_ids'].copy()\n",
167
+ " return t\n",
168
+ "\n",
169
+ "tok=sp.map(tok_fn,remove_columns=['text'],batched=True,num_proc=2)\n",
170
+ "del sp; gc.collect()\n",
171
+ "\n",
172
+ "args=TrainingArguments(\n",
173
+ " output_dir='./clarity-flash',\n",
174
+ " per_device_train_batch_size=1,\n",
175
+ " gradient_accumulation_steps=4,\n",
176
+ " max_steps=500,\n",
177
+ " learning_rate=3e-4,\n",
178
+ " fp16=True,\n",
179
+ " logging_steps=10,\n",
180
+ " save_strategy='no',\n",
181
+ " optim='adamw_8bit',\n",
182
+ " report_to='none',\n",
183
+ " dataloader_num_workers=0,\n",
184
+ " lr_scheduler_type='cosine',\n",
185
+ " warmup_steps=25,\n",
186
+ ")\n",
187
+ "\n",
188
+ "trainer=Trainer(model=model,args=args,train_dataset=tok['train'],data_collator=DataCollatorForSeq2Seq(tokz,padding=True,pad_to_multiple_of=8))\n",
189
+ "gc.collect(); torch.cuda.empty_cache()\n",
190
+ "trainer.train()\n"
191
+ ],
192
+ "metadata": {},
193
+ "execution_count": null,
194
+ "outputs": []
195
+ },
196
+ {
197
+ "cell_type": "code",
198
+ "source": [
199
+ "WEIGHTS_REPO='Universal-618/Clarity-flash-weights'\n",
200
+ "create_repo(WEIGHTS_REPO,repo_type='model',exist_ok=True,token=HF_TOKEN)\n",
201
+ "model.push_to_hub(WEIGHTS_REPO,token=HF_TOKEN,use_temp_dir=True)\n",
202
+ "tokz.push_to_hub(WEIGHTS_REPO,token=HF_TOKEN)\n",
203
+ "import sys; print('done',file=sys.stderr)\n"
204
+ ],
205
+ "metadata": {},
206
+ "execution_count": null,
207
+ "outputs": []
208
+ }
209
+ ],
210
+ "metadata": {
211
+ "accelerator": "GPU",
212
+ "colab": {
213
+ "provenance": []
214
+ },
215
+ "kernelspec": {
216
+ "display_name": "Python 3",
217
+ "name": "python3"
218
+ },
219
+ "language_info": {
220
+ "name": "python",
221
+ "version": "3.10.0"
222
+ }
223
+ },
224
+ "nbformat": 4,
225
+ "nbformat_minor": 4
226
+ }
@@ -0,0 +1,232 @@
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "source": [
6
+ "# CLARITY Heavy 20B MoE — Kaggle Single T4\n",
7
+ "Model: openai/gpt-oss-20b (21B MoE, 3.6B active, native MXFP4)\n",
8
+ "LoRA + grad ckpt + max_len=256 + no eval + no checkpoints\n"
9
+ ],
10
+ "metadata": {}
11
+ },
12
+ {
13
+ "cell_type": "code",
14
+ "source": [
15
+ "import os,gc,torch\n",
16
+ "from huggingface_hub import create_repo\n",
17
+ "HF_TOKEN=os.environ.get('HF_TOKEN')\n",
18
+ "if not HF_TOKEN:\n",
19
+ " from kaggle_secrets import UserSecretsClient\n",
20
+ " HF_TOKEN=UserSecretsClient().get_secret('HF_TOKEN')\n",
21
+ "assert HF_TOKEN and len(HF_TOKEN)>10, 'Set HF_TOKEN as Kaggle secret'\n"
22
+ ],
23
+ "metadata": {},
24
+ "execution_count": null,
25
+ "outputs": []
26
+ },
27
+ {
28
+ "cell_type": "code",
29
+ "source": [
30
+ "!pip install -q transformers datasets accelerate peft bitsandbytes sentencepiece huggingface_hub\n"
31
+ ],
32
+ "metadata": {},
33
+ "execution_count": null,
34
+ "outputs": []
35
+ },
36
+ {
37
+ "cell_type": "code",
38
+ "source": [
39
+ "assert torch.cuda.is_available()\n",
40
+ "print('GPU:',torch.cuda.get_device_name(0))\n",
41
+ "gc.collect(); torch.cuda.empty_cache()\n"
42
+ ],
43
+ "metadata": {},
44
+ "execution_count": null,
45
+ "outputs": []
46
+ },
47
+ {
48
+ "cell_type": "code",
49
+ "source": [
50
+ "import requests,sys\n",
51
+ "from datasets import Dataset, load_dataset\n",
52
+ "import random\n",
53
+ "\n",
54
+ "all_samples=[]\n",
55
+ "def add(i,r): all_samples.append(dict(instruction=str(i or ''), response=str(r or '')))\n",
56
+ "\n",
57
+ "def load_std(n,s,f,l,**kw):\n",
58
+ " try:\n",
59
+ " for i,row in enumerate(load_dataset(n,split=s,streaming=True,token=HF_TOKEN,**kw)):\n",
60
+ " if i>=l: break\n",
61
+ " add(row.get(f['instruction'],''),row.get(f['response'],''))\n",
62
+ " except Exception as e: print(f' skip {n}: {e}', file=sys.stderr)\n",
63
+ "\n",
64
+ "def load_msgs(n,s,l,**kw):\n",
65
+ " try:\n",
66
+ " for i,row in enumerate(load_dataset(n,split=s,streaming=True,token=HF_TOKEN,**kw)):\n",
67
+ " if i>=l: break\n",
68
+ " msgs=row.get('messages',[])\n",
69
+ " if len(msgs)>=2: add(msgs[0].get('content',''),msgs[-1].get('content',''))\n",
70
+ " except Exception as e: print(f' skip {n}: {e}', file=sys.stderr)\n",
71
+ "\n",
72
+ "for sfx in ['main','2','3','4','5','6']:\n",
73
+ " try:\n",
74
+ " r=requests.get(f'https://huggingface.co/spaces/Universal-618/Clarity-{sfx}/main-data',headers={'Authorization':f'Bearer {HF_TOKEN}'},timeout=30)\n",
75
+ " if r.status_code==200:\n",
76
+ " d=r.json()\n",
77
+ " for x in (d if isinstance(d,list) else d.get('data',[])):\n",
78
+ " add(x.get('instruction',x.get('prompt',x.get('problem',''))),x.get('response',x.get('completion',x.get('output',x.get('solution','')))))\n",
79
+ " except: pass\n",
80
+ "\n",
81
+ "load_std('Open-Orca/OpenOrca','train',dict(instruction='question',response='response'),800)\n",
82
+ "load_msgs('HuggingFaceH4/no_robots','train',500)\n",
83
+ "load_msgs('HuggingFaceH4/ultrachat_200k','train_sft',500)\n",
84
+ "load_std('tatsu-lab/alpaca','train',dict(instruction='instruction',response='output'),500)\n",
85
+ "load_std('TIGER-Lab/MathInstruct','train',dict(instruction='instruction',response='output'),800)\n",
86
+ "load_std('AI-MO/NuminaMath-CoT','train',dict(instruction='problem',response='solution'),600)\n",
87
+ "load_std('meta-math/MetaMathQA','train',dict(instruction='query',response='response'),600)\n",
88
+ "load_std('microsoft/orca-math-word-problems-200k','train',dict(instruction='question',response='answer'),500)\n",
89
+ "load_std('GAIR/Reasoning-Intensive','train',dict(instruction='question',response='answer'),500)\n",
90
+ "load_std('BAAI/AgentInstruct','train',dict(instruction='instruction',response='output'),500)\n",
91
+ "load_std('bigcode/commitpackft','train',dict(instruction='instruction',response='response'),500)\n",
92
+ "load_std('sahil2801/CodeAlpaca-20k','train',dict(instruction='instruction',response='output'),500)\n",
93
+ "load_std('jondurbin/airoboros-3.2','train',dict(instruction='instruction',response='response'),500)\n",
94
+ "load_std('cognitivecomputations/dolphin','train',dict(instruction='instruction',response='response'),500)\n",
95
+ "load_std('databricks/databricks-dolly-15k','train',dict(instruction='instruction',response='response'),500)\n",
96
+ "load_std('WizardLM/WizardLM_evol_instruct_V2_196k','train',dict(instruction='instruction',response='output'),500)\n",
97
+ "load_std('Intel/orca_dpo_pairs','train',dict(instruction='question',response='chosen'),500)\n",
98
+ "load_std('nvidia/HelpSteer','train',dict(instruction='instruction',response='response'),500)\n",
99
+ "load_std('Dahoas/full-hh-rlhf','train',dict(instruction='instruction',response='response'),500)\n",
100
+ "load_std('BAAI/Infinity-Instruct','0625',dict(instruction='instruction',response='output'),500)\n",
101
+ "\n",
102
+ "print(f'Total: {len(all_samples)}')\n",
103
+ "random.shuffle(all_samples); gc.collect()\n"
104
+ ],
105
+ "metadata": {},
106
+ "execution_count": null,
107
+ "outputs": []
108
+ },
109
+ {
110
+ "cell_type": "code",
111
+ "source": [
112
+ "from transformers import AutoTokenizer\n",
113
+ "\n",
114
+ "MODEL_ID='openai/gpt-oss-20b'\n",
115
+ "tokz=AutoTokenizer.from_pretrained(MODEL_ID,token=HF_TOKEN,trust_remote_code=True)\n",
116
+ "tokz.pad_token=tokz.eos_token\n",
117
+ "\n",
118
+ "def fmt(s): return tokz.apply_chat_template([{'role':'system','content':'Reasoning: high'},{'role':'user','content':s.get('instruction','')},{'role':'assistant','content':s.get('response','')}],tokenize=False)\n",
119
+ "\n",
120
+ "ds=Dataset.from_list([{'text':fmt(s)} for s in all_samples])\n",
121
+ "sp=ds.train_test_split(test_size=0.01,seed=42)\n",
122
+ "del all_samples,ds; gc.collect()\n",
123
+ "print(f'Train: {len(sp[\"train\"])} Test: {len(sp[\"test\"])}')\n"
124
+ ],
125
+ "metadata": {},
126
+ "execution_count": null,
127
+ "outputs": []
128
+ },
129
+ {
130
+ "cell_type": "code",
131
+ "source": [
132
+ "from transformers import AutoModelForCausalLM\n",
133
+ "import requests as req\n",
134
+ "gc.collect(); torch.cuda.empty_cache()\n",
135
+ "\n",
136
+ "r=req.get(f'https://huggingface.co/{MODEL_ID}/raw/main/config.json',headers={'Authorization':f'Bearer {HF_TOKEN}'})\n",
137
+ "cd=r.json()\n",
138
+ "cd.pop('_attn_implementation',None); cd.pop('attn_implementation',None)\n",
139
+ "\n",
140
+ "model=AutoModelForCausalLM.from_pretrained(MODEL_ID,config=cd,device_map='auto',token=HF_TOKEN,trust_remote_code=True,low_cpu_mem_usage=True)\n",
141
+ "model.gradient_checkpointing_enable()\n",
142
+ "model.config.use_cache=False\n",
143
+ "gc.collect(); torch.cuda.empty_cache()\n",
144
+ "print('Model:',round(model.num_parameters()/1e9,1),'B')\n"
145
+ ],
146
+ "metadata": {},
147
+ "execution_count": null,
148
+ "outputs": []
149
+ },
150
+ {
151
+ "cell_type": "code",
152
+ "source": [
153
+ "from peft import LoraConfig,get_peft_model,TaskType\n",
154
+ "lora=LoraConfig(task_type=TaskType.CAUSAL_LM,r=4,lora_alpha=8,lora_dropout=0.1,target_modules=['q_proj','k_proj','v_proj','o_proj','gate_proj','up_proj','down_proj'],bias='none')\n",
155
+ "model=get_peft_model(model,lora)\n",
156
+ "model.print_trainable_parameters()\n",
157
+ "gc.collect(); torch.cuda.empty_cache()\n"
158
+ ],
159
+ "metadata": {},
160
+ "execution_count": null,
161
+ "outputs": []
162
+ },
163
+ {
164
+ "cell_type": "code",
165
+ "source": [
166
+ "from transformers import TrainingArguments,Trainer,DataCollatorForSeq2Seq\n",
167
+ "\n",
168
+ "def tok_fn(ex):\n",
169
+ " t=tokz(ex['text'],truncation=True,max_length=256,padding=False)\n",
170
+ " t['labels']=t['input_ids'].copy()\n",
171
+ " return t\n",
172
+ "\n",
173
+ "tok=sp.map(tok_fn,remove_columns=['text'],batched=True,num_proc=2)\n",
174
+ "del sp; gc.collect()\n",
175
+ "\n",
176
+ "args=TrainingArguments(\n",
177
+ " output_dir='./clarity-heavy',\n",
178
+ " per_device_train_batch_size=1,\n",
179
+ " gradient_accumulation_steps=16,\n",
180
+ " num_train_epochs=1,\n",
181
+ " learning_rate=2e-4,\n",
182
+ " fp16=True,\n",
183
+ " logging_steps=10,\n",
184
+ " save_strategy='no',\n",
185
+ " optim='adamw_8bit',\n",
186
+ " report_to='none',\n",
187
+ " dataloader_num_workers=0,\n",
188
+ " lr_scheduler_type='cosine',\n",
189
+ " warmup_steps=25,\n",
190
+ ")\n",
191
+ "\n",
192
+ "trainer=Trainer(model=model,args=args,train_dataset=tok['train'],data_collator=DataCollatorForSeq2Seq(tokz,padding=True,pad_to_multiple_of=8))\n",
193
+ "gc.collect(); torch.cuda.empty_cache()\n",
194
+ "trainer.train()\n"
195
+ ],
196
+ "metadata": {},
197
+ "execution_count": null,
198
+ "outputs": []
199
+ },
200
+ {
201
+ "cell_type": "code",
202
+ "source": [
203
+ "WEIGHTS_REPO='Universal-618/Clarity-heavy-weights'\n",
204
+ "create_repo(WEIGHTS_REPO,repo_type='model',exist_ok=True,token=HF_TOKEN)\n",
205
+ "model.push_to_hub(WEIGHTS_REPO,token=HF_TOKEN,use_temp_dir=True)\n",
206
+ "tokz.push_to_hub(WEIGHTS_REPO,token=HF_TOKEN)\n",
207
+ "import sys; print('done',file=sys.stderr)\n"
208
+ ],
209
+ "metadata": {},
210
+ "execution_count": null,
211
+ "outputs": []
212
+ }
213
+ ],
214
+ "metadata": {
215
+ "accelerator": "GPU",
216
+ "kaggle": {
217
+ "accelerator": "GPU",
218
+ "gpuModel": "T4",
219
+ "gpuCount": 2
220
+ },
221
+ "kernelspec": {
222
+ "display_name": "Python 3",
223
+ "name": "python3"
224
+ },
225
+ "language_info": {
226
+ "name": "python",
227
+ "version": "3.10.0"
228
+ }
229
+ },
230
+ "nbformat": 4,
231
+ "nbformat_minor": 4
232
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "clarity-ai",
3
- "version": "6.3.2",
4
- "description": "Premium terminal AI agent — fixed-height viewport, box-drawing UI, TrueColor theme, streaming with abort",
3
+ "version": "6.4.0",
4
+ "description": "Premium terminal AI agent — Clarity Flash 14B model, HF Inference API, fixed-height viewport, TrueColor theme",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "clarity": "bin/clarity.js"
@@ -1,6 +1,6 @@
1
1
  import React, { useMemo } from 'react';
2
2
  import { Box, Text } from 'ink';
3
- import { hex, usym } from '../config/theme.js';
3
+ import { hex, sym } from '../config/theme.js';
4
4
  import { getLayout } from '../config/layout.js';
5
5
  const { createElement: h } = React;
6
6
 
@@ -40,7 +40,7 @@ export function CodeBlock({ code, language }) {
40
40
  ),
41
41
  lines.length > maxLines
42
42
  ? h(Text, { color: hex.textMuted, backgroundColor: hex.codeBg },
43
- ' ' + usym.ellipsis + ' ' + (lines.length - maxLines) + ' more lines')
43
+ ' ' + sym.ellipsis + ' ' + (lines.length - maxLines) + ' more lines')
44
44
  : null
45
45
  )
46
46
  );
@@ -1,6 +1,7 @@
1
1
  import React, { useState } from 'react';
2
2
  import { Box, Text, useInput } from 'ink';
3
- import { hex, usym } from '../config/theme.js';
3
+ import { hex, sym } from '../config/theme.js';
4
+ import { getLayout } from '../config/layout.js';
4
5
  const { createElement: h } = React;
5
6
 
6
7
  const COMMANDS = [
@@ -8,7 +9,7 @@ const COMMANDS = [
8
9
  { name: '/model', desc: 'Switch model' },
9
10
  { name: '/provider', desc: 'Switch provider' },
10
11
  { name: '/agent', desc: 'Toggle agent mode' },
11
- { name: '/stop', desc: 'Cancel streaming' },
12
+ { name: '/stop', desc: 'Cancel running stream' },
12
13
  { name: '/clear', desc: 'Clear conversation' },
13
14
  { name: '/export', desc: 'Export conversation' },
14
15
  { name: '/help', desc: 'Show all commands' },
@@ -18,6 +19,7 @@ const COMMANDS = [
18
19
  export function CommandPicker({ query, onSelect, onClose }) {
19
20
  const [search, setSearch] = useState('');
20
21
  const [idx, setIdx] = useState(0);
22
+ const { cols } = getLayout();
21
23
 
22
24
  const filtered = COMMANDS.filter(c =>
23
25
  c.name.includes(search) || c.desc.toLowerCase().includes(search.toLowerCase())
@@ -26,40 +28,36 @@ export function CommandPicker({ query, onSelect, onClose }) {
26
28
  useInput((input, key) => {
27
29
  if (key.upArrow) setIdx(i => Math.max(0, i - 1));
28
30
  if (key.downArrow) setIdx(i => Math.min(filtered.length - 1, i + 1));
29
- if (key.return) onSelect(filtered[idx]?.name || '');
31
+ if (key.return && filtered[idx]) onSelect(filtered[idx].name);
30
32
  if (key.escape) onClose();
31
33
  if (key.backspace) setSearch(s => s.slice(0, -1));
32
34
  else if (input && !key.ctrl && !key.meta) setSearch(s => s + input);
33
35
  });
34
36
 
35
- const tw = process.stdout.columns || 80;
36
- const boxWidth = Math.min(tw - 4, 50);
37
+ const w = Math.min(cols - 4, 48);
37
38
 
38
- return h(Box, { flexDirection: 'column', width: boxWidth },
39
- h(Box, { flexDirection: 'row', marginBottom: 1, gap: 1 },
40
- h(Text, { color: hex.textMuted }, usym.bulb),
41
- h(Text, { color: search ? hex.text : hex.textMuted }, search || 'type to filter...'),
39
+ return h(Box, { flexDirection: 'column', backgroundColor: hex.surfaceAlt, width: w },
40
+ h(Box, { height: 1, backgroundColor: hex.surfaceAlt },
41
+ h(Text, { color: hex.textMuted, backgroundColor: hex.surfaceAlt }, ' ' + sym.star + ' ' + (search || 'filter commands...'))
42
42
  ),
43
43
  filtered.map((cmd, i) =>
44
44
  h(Box, {
45
- key: cmd.name,
46
- flexDirection: 'row',
47
- backgroundColor: i === idx ? hex.selectionBg : undefined,
48
- width: boxWidth,
45
+ key: cmd.name, height: 1,
46
+ backgroundColor: i === idx ? hex.selectionBg : 'transparent',
49
47
  },
50
48
  h(Text, {
51
49
  color: i === idx ? hex.selectionText : hex.text,
52
50
  bold: i === idx,
53
- backgroundColor: i === idx ? hex.selectionBg : undefined,
54
- wrap: 'truncate-end',
55
- }, ' ' + cmd.name.padEnd(16)),
51
+ backgroundColor: i === idx ? hex.selectionBg : 'transparent',
52
+ }, ' ' + cmd.name + ' '),
56
53
  h(Text, {
57
54
  color: i === idx ? hex.selectionText : hex.textDim,
58
- backgroundColor: i === idx ? hex.selectionBg : undefined,
59
- wrap: 'truncate-end',
55
+ backgroundColor: i === idx ? hex.selectionBg : 'transparent',
60
56
  }, cmd.desc)
61
57
  )
62
58
  ),
63
- h(Text, { color: hex.textMuted }, ' ' + usym.arrowU + usym.arrowD + ' nav Enter select Esc close')
59
+ h(Box, { height: 1, backgroundColor: hex.surfaceAlt },
60
+ h(Text, { color: hex.textMuted, backgroundColor: hex.surfaceAlt }, ' ' + sym.arrowU + sym.arrowD + ' nav ' + sym.arrowR + ' select Esc close')
61
+ )
64
62
  );
65
63
  }