zuzu 0.0.1-java → 0.2.2-java
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.
- checksums.yaml +4 -4
- data/README.md +47 -32
- data/bin/setup +3 -6
- data/bin/zuzu +32 -5
- data/lib/zuzu/agent.rb +18 -11
- data/lib/zuzu/config.rb +4 -3
- data/lib/zuzu/version.rb +1 -1
- data/templates/.claude/skills/add-tool/SKILL.md +162 -0
- data/templates/.claude/skills/customize/SKILL.md +192 -0
- data/templates/.claude/skills/debug/SKILL.md +197 -0
- data/templates/.claude/skills/setup/SKILL.md +102 -0
- data/templates/AGENTS.md +557 -0
- data/templates/CLAUDE.md +70 -0
- data/templates/app.rb +52 -11
- data/warble.rb +19 -0
- metadata +31 -15
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: customize
|
|
3
|
+
description: Customize the Zuzu app — change the app name, window size, system prompt persona, or extend the UI. Use when the developer wants to rebrand the app, add personality to the assistant, or make visual/behavioral changes.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Customize Zuzu App
|
|
7
|
+
|
|
8
|
+
Ask what the developer wants to change, then make the changes directly.
|
|
9
|
+
|
|
10
|
+
## Step 1 — Understand the request
|
|
11
|
+
|
|
12
|
+
AskUserQuestion: "What would you like to customize? Choose one or more:
|
|
13
|
+
1. App name / window title
|
|
14
|
+
2. Window size
|
|
15
|
+
3. Assistant persona / system prompt instructions
|
|
16
|
+
4. Add a new button or panel to the UI
|
|
17
|
+
5. Something else — describe it"
|
|
18
|
+
|
|
19
|
+
Route to the relevant section below based on the answer.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Route A — App name and window title
|
|
24
|
+
|
|
25
|
+
Read the current value from `app.rb`:
|
|
26
|
+
|
|
27
|
+
```ruby
|
|
28
|
+
Zuzu.configure do |c|
|
|
29
|
+
c.app_name = 'Current Name'
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
AskUserQuestion: "What should the app be called?"
|
|
33
|
+
|
|
34
|
+
Edit `app.rb` — update `c.app_name`. Done. Tell the user to restart the app.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Route B — Window size
|
|
39
|
+
|
|
40
|
+
Read current values (`c.window_width`, `c.window_height`).
|
|
41
|
+
|
|
42
|
+
AskUserQuestion: "What size should the window be? (e.g. 1024 × 768, 1280 × 800)"
|
|
43
|
+
|
|
44
|
+
Edit `app.rb`:
|
|
45
|
+
```ruby
|
|
46
|
+
c.window_width = 1024
|
|
47
|
+
c.window_height = 768
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Done. Tell the user to restart.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Route C — Assistant persona and system prompt
|
|
55
|
+
|
|
56
|
+
Read the current `c.system_prompt_extras` from `app.rb` (may be nil/absent).
|
|
57
|
+
|
|
58
|
+
AskUserQuestion: "Describe the assistant's persona or any extra rules you want it to follow. Examples:
|
|
59
|
+
- 'You are a Ruby developer assistant. Always use Ruby in code examples.'
|
|
60
|
+
- 'You are a cooking assistant. Only discuss food, recipes, and nutrition.'
|
|
61
|
+
- 'Always respond concisely in bullet points.'"
|
|
62
|
+
|
|
63
|
+
AskUserQuestion: "Should this replace the current instructions or be added to them?"
|
|
64
|
+
|
|
65
|
+
Edit `app.rb` — set or update `c.system_prompt_extras`:
|
|
66
|
+
|
|
67
|
+
```ruby
|
|
68
|
+
Zuzu.configure do |c|
|
|
69
|
+
# ...
|
|
70
|
+
c.system_prompt_extras = <<~EXTRA
|
|
71
|
+
<the persona instructions here>
|
|
72
|
+
EXTRA
|
|
73
|
+
end
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Important rules to preserve** — always keep these in `system_prompt_extras` if the developer's text doesn't already cover them:
|
|
77
|
+
- Do not override the tool-calling rules (those come from the base prompt automatically)
|
|
78
|
+
- Keep instructions concise — the model sees this verbatim on every request
|
|
79
|
+
|
|
80
|
+
Verify it loads:
|
|
81
|
+
```bash
|
|
82
|
+
bundle exec ruby -e "require 'zuzu'; load 'app.rb' rescue nil; puts Zuzu.config.system_prompt_extras" 2>&1
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Done. Tell the user to restart.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Route D — UI: add a button to the Admin Panel
|
|
90
|
+
|
|
91
|
+
The Admin Panel is the popup window opened by the "Admin Panel" button.
|
|
92
|
+
The easiest UI extension is adding a button there.
|
|
93
|
+
|
|
94
|
+
AskUserQuestion: "What should the button do when clicked?"
|
|
95
|
+
AskUserQuestion: "What label should the button have?"
|
|
96
|
+
|
|
97
|
+
This requires subclassing `Zuzu::App`. Check if `app.rb` already subclasses it.
|
|
98
|
+
|
|
99
|
+
**If not subclassing yet**, add this pattern to `app.rb` before `Zuzu::App.launch!`:
|
|
100
|
+
|
|
101
|
+
```ruby
|
|
102
|
+
class MyApp < Zuzu::App
|
|
103
|
+
private
|
|
104
|
+
|
|
105
|
+
def open_admin_panel
|
|
106
|
+
file_list_widget = nil
|
|
107
|
+
|
|
108
|
+
admin = shell {
|
|
109
|
+
text 'Admin Panel'
|
|
110
|
+
minimum_size 380, 500
|
|
111
|
+
grid_layout 1, false
|
|
112
|
+
|
|
113
|
+
label {
|
|
114
|
+
layout_data(:fill, :fill, true, false)
|
|
115
|
+
text 'AgentFS — Virtual File Browser'
|
|
116
|
+
font height: 12, style: :bold
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
file_list_widget = list(:single, :v_scroll, :border) {
|
|
120
|
+
layout_data(:fill, :fill, true, true)
|
|
121
|
+
font name: 'Monospace', height: 11
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
# ── Default buttons (keep these) ─────────────────────────
|
|
125
|
+
button {
|
|
126
|
+
layout_data(:fill, :fill, true, false)
|
|
127
|
+
text 'Create Test File'
|
|
128
|
+
on_widget_selected {
|
|
129
|
+
@fs.write_file('/test.txt', "Hello!\nCreated at: #{Time.now}")
|
|
130
|
+
populate_file_list(file_list_widget)
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
button {
|
|
135
|
+
layout_data(:fill, :fill, true, false)
|
|
136
|
+
text 'Clear Chat History'
|
|
137
|
+
on_widget_selected {
|
|
138
|
+
@memory.clear
|
|
139
|
+
message_box { text 'Done'; message 'History cleared.' }.open
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
button {
|
|
144
|
+
layout_data(:fill, :fill, true, false)
|
|
145
|
+
text 'Refresh'
|
|
146
|
+
on_widget_selected { populate_file_list(file_list_widget) }
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
# ── New custom button ─────────────────────────────────────
|
|
150
|
+
button {
|
|
151
|
+
layout_data(:fill, :fill, true, false)
|
|
152
|
+
text '<Button Label>'
|
|
153
|
+
on_widget_selected {
|
|
154
|
+
# your action here
|
|
155
|
+
message_box { text 'Done'; message 'Action completed.' }.open
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
populate_file_list(file_list_widget)
|
|
161
|
+
admin.open
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Then change the launch line to:
|
|
167
|
+
```ruby
|
|
168
|
+
MyApp.launch!(use_llamafile: true)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**Glimmer DSL rules to enforce:**
|
|
172
|
+
- `layout_data(:fill, :fill, true, false)` — always use argument form, never block form
|
|
173
|
+
- Never call widget methods from a background thread — wrap in `async_exec { }`
|
|
174
|
+
- Never use `sash_form` — invisible on macOS
|
|
175
|
+
|
|
176
|
+
Verify syntax:
|
|
177
|
+
```bash
|
|
178
|
+
bundle exec ruby -e "require 'zuzu'; load 'app.rb' rescue puts $!.message" 2>&1
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Done. Tell the user to restart.
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Route E — Something else
|
|
186
|
+
|
|
187
|
+
Read `AGENTS.md` for the relevant section and implement accordingly.
|
|
188
|
+
Always verify with a syntax check after making changes:
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
bundle exec ruby -e "require 'zuzu'; load 'app.rb' rescue puts $!.message" 2>&1
|
|
192
|
+
```
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: debug
|
|
3
|
+
description: Diagnose and fix Zuzu app issues. Use when the app won't start, the agent isn't responding, tools aren't being called, the LLM seems stuck, or the UI is broken. Runs a systematic health check and fixes what it finds.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Debug Zuzu App
|
|
7
|
+
|
|
8
|
+
Run each check in order. Fix problems as they're found — don't present a list and ask the user to fix them.
|
|
9
|
+
|
|
10
|
+
## Check 1 — Ruby code syntax
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
bundle exec ruby -e "require 'zuzu'; load 'app.rb'" 2>&1
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
- If syntax error or LoadError: fix the error in `app.rb`, re-run, continue.
|
|
17
|
+
- If clean: continue.
|
|
18
|
+
|
|
19
|
+
## Check 2 — Registered tools
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
bundle exec ruby -e "
|
|
23
|
+
require 'zuzu'
|
|
24
|
+
load 'app.rb' rescue nil
|
|
25
|
+
tools = Zuzu::ToolRegistry.tools
|
|
26
|
+
if tools.empty?
|
|
27
|
+
puts 'WARNING: No tools registered'
|
|
28
|
+
else
|
|
29
|
+
tools.each { |t| puts ' - ' + t.name + ': ' + t.description }
|
|
30
|
+
end
|
|
31
|
+
" 2>&1
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
- No tools: check `app.rb` — registrations must be before `Zuzu::App.launch!`. Fix and retry.
|
|
35
|
+
- Tools listed: continue.
|
|
36
|
+
|
|
37
|
+
## Check 3 — Model file
|
|
38
|
+
|
|
39
|
+
Read `app.rb` to find `c.llamafile_path`. Then:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
ls -lh <model_path> 2>&1
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
- File not found: tell the user they need to download the model to the `models/` directory.
|
|
46
|
+
- File exists but not executable: `chmod +x <model_path>` — do this automatically.
|
|
47
|
+
- File ok: continue.
|
|
48
|
+
|
|
49
|
+
## Check 4 — Is llamafile running?
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
curl -s --max-time 3 http://127.0.0.1:8080/v1/models 2>&1
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
- Connection refused / timeout: llamafile isn't running. The app starts it — check the log:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
ls models/*.log 2>/dev/null && tail -30 models/*.log 2>/dev/null || echo "No log file found"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Common causes:
|
|
62
|
+
- Model file not found (covered above)
|
|
63
|
+
- Port 8080 already in use: `lsof -i :8080` — if another process, kill it or change port in `app.rb`
|
|
64
|
+
- Model too large for available RAM — check `tail -5 models/llama.log` for OOM errors
|
|
65
|
+
|
|
66
|
+
- Returns JSON with models: llamafile is running. Continue.
|
|
67
|
+
|
|
68
|
+
## Check 5 — LLM responds to a basic chat
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
curl -s --max-time 30 http://127.0.0.1:8080/v1/chat/completions \
|
|
72
|
+
-H 'Content-Type: application/json' \
|
|
73
|
+
-d '{"model":"LLaMA_CPP","messages":[{"role":"user","content":"reply with the single word: OK"}],"temperature":0.1}' \
|
|
74
|
+
2>&1 | head -5
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
- Returns JSON with `OK` in choices: LLM is healthy. Continue.
|
|
78
|
+
- Times out: model is still loading. Wait 30s, retry.
|
|
79
|
+
- Error: check `models/llama.log` for details.
|
|
80
|
+
|
|
81
|
+
## Check 6 — Tool call parsing (agent loop)
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
bundle exec zuzu console 2>/dev/null <<'EOF'
|
|
85
|
+
store = Zuzu::Store.new
|
|
86
|
+
fs = Zuzu::AgentFS.new(store)
|
|
87
|
+
memory = Zuzu::Memory.new(store)
|
|
88
|
+
llm = Zuzu::LlmClient.new
|
|
89
|
+
agent = Zuzu::Agent.new(agent_fs: fs, memory: memory, llm: llm)
|
|
90
|
+
result = agent.process('What time is it? Use the current_time tool if available, otherwise just say hello.')
|
|
91
|
+
puts "Agent response: #{result}"
|
|
92
|
+
EOF
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
- Response contains sensible text: agent loop works.
|
|
96
|
+
- `Max iterations reached`: model isn't calling tools. See "Agent not calling tools" below.
|
|
97
|
+
- Error: read the traceback, fix the root cause.
|
|
98
|
+
|
|
99
|
+
## Check 7 — Recent tool call history
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
bundle exec ruby -e "
|
|
103
|
+
require 'zuzu'
|
|
104
|
+
store = Zuzu::Store.new
|
|
105
|
+
rows = store.query_all('SELECT tool_name, input, output, started_at FROM tool_calls ORDER BY started_at DESC LIMIT 10')
|
|
106
|
+
if rows.empty?
|
|
107
|
+
puts 'No tool calls recorded yet'
|
|
108
|
+
else
|
|
109
|
+
rows.each { |r| puts r['tool_name'] + ' → ' + r['output'].to_s[0,80] }
|
|
110
|
+
end
|
|
111
|
+
" 2>&1
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
- Shows recent calls: tools are firing.
|
|
115
|
+
- Empty: either app hasn't been used yet, or tools aren't being called.
|
|
116
|
+
|
|
117
|
+
## Check 8 — AgentFS health
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
bundle exec ruby -e "
|
|
121
|
+
require 'zuzu'
|
|
122
|
+
store = Zuzu::Store.new
|
|
123
|
+
fs = Zuzu::AgentFS.new(store)
|
|
124
|
+
fs.write_file('/debug_test.txt', 'hello')
|
|
125
|
+
result = fs.read_file('/debug_test.txt')
|
|
126
|
+
puts result == 'hello' ? 'AgentFS OK' : 'AgentFS BROKEN: got ' + result.inspect
|
|
127
|
+
fs.delete('/debug_test.txt')
|
|
128
|
+
" 2>&1
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
- "AgentFS OK": filesystem healthy.
|
|
132
|
+
- Error: check that `.zuzu/` directory is writable: `ls -la .zuzu/`
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Known issues and fixes
|
|
137
|
+
|
|
138
|
+
### Agent not calling tools
|
|
139
|
+
|
|
140
|
+
The most common cause is the model not following the system prompt reliably.
|
|
141
|
+
|
|
142
|
+
1. **Check the system prompt is being built**: open `bundle exec zuzu console` and run:
|
|
143
|
+
```ruby
|
|
144
|
+
require 'zuzu'; load 'app.rb' rescue nil
|
|
145
|
+
store = Zuzu::Store.new; fs = Zuzu::AgentFS.new(store); memory = Zuzu::Memory.new(store); llm = Zuzu::LlmClient.new
|
|
146
|
+
agent = Zuzu::Agent.new(agent_fs: fs, memory: memory, llm: llm)
|
|
147
|
+
puts agent.send(:build_system_prompt)
|
|
148
|
+
```
|
|
149
|
+
Verify your tools appear in the "Available tools:" section.
|
|
150
|
+
|
|
151
|
+
2. **Check `system_prompt_extras`** — if it contains conflicting instructions (e.g. "never use tools") it can override the base prompt.
|
|
152
|
+
|
|
153
|
+
3. **Model quality** — llava-v1.5-7b-q4 is a vision model and follows tool-calling instructions inconsistently. Try a more capable model or rephrase your request to more explicitly ask for tool use.
|
|
154
|
+
|
|
155
|
+
### Blank or invisible UI widgets
|
|
156
|
+
|
|
157
|
+
Caused by wrong `layout_data`. Check `app.rb` for any subclassed body or UI code:
|
|
158
|
+
|
|
159
|
+
- `layout_data(:fill, :fill, true, true)` on an input composite → change last arg to `false`
|
|
160
|
+
- `layout_data { height_hint N }` → replace with `layout_data(:fill, :center, false, false)`
|
|
161
|
+
- `sash_form` → remove and replace with plain `composite`
|
|
162
|
+
|
|
163
|
+
### SWT thread error / crash on UI update
|
|
164
|
+
|
|
165
|
+
Wrap all widget updates that happen inside `Thread.new` with `async_exec`:
|
|
166
|
+
|
|
167
|
+
```ruby
|
|
168
|
+
Thread.new do
|
|
169
|
+
result = do_something_slow
|
|
170
|
+
async_exec { @chat_display.swt_widget.set_text(result) } # ← required
|
|
171
|
+
end
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Port 8080 already in use
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
lsof -i :8080
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Kill the occupying process, or change `c.port = 8081` in `app.rb` — the LLM client and manager both read from config.
|
|
181
|
+
|
|
182
|
+
### Database locked
|
|
183
|
+
|
|
184
|
+
Only one process can write to `.zuzu/zuzu.db` at a time. Ensure only one instance of the app is running.
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Summary output
|
|
189
|
+
|
|
190
|
+
After all checks, tell the user:
|
|
191
|
+
- ✅/❌ Ruby syntax
|
|
192
|
+
- ✅/❌ Tools registered (list names)
|
|
193
|
+
- ✅/❌ Model file
|
|
194
|
+
- ✅/❌ LLM running
|
|
195
|
+
- ✅/❌ LLM responding
|
|
196
|
+
- ✅/❌ AgentFS healthy
|
|
197
|
+
- Any fixes applied + next steps
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: setup
|
|
3
|
+
description: First-time setup for a Zuzu app. Verifies JRuby and Java versions, runs bundle install, checks the model file exists, and does a smoke-test launch. Use when the developer first clones or scaffolds the app, or when the runtime environment seems broken.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Zuzu App Setup
|
|
7
|
+
|
|
8
|
+
Run each step automatically. Only pause when the user must take an action (e.g. downloading a model file). Fix problems directly — don't tell the user to fix them unless it genuinely requires their input.
|
|
9
|
+
|
|
10
|
+
## Step 1 — Verify Java 21+
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
java -version 2>&1
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
- If missing or < 21: `brew install --cask temurin@21` (macOS) or `sudo apt-get install openjdk-21-jdk` (Linux). Re-check after.
|
|
17
|
+
- If correct: continue.
|
|
18
|
+
|
|
19
|
+
## Step 2 — Verify JRuby 10.0.3.0
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
ruby -v
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
- Must show `jruby 10.0.3.0`. If not:
|
|
26
|
+
- Check rbenv: `rbenv versions`
|
|
27
|
+
- If jruby-10.0.3.0 is listed but not active: `rbenv local jruby-10.0.3.0`
|
|
28
|
+
- If not installed: `rbenv install jruby-10.0.3.0 && rbenv local jruby-10.0.3.0`
|
|
29
|
+
- Re-check after.
|
|
30
|
+
|
|
31
|
+
## Step 3 — Bundle install
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
bundle install 2>&1
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
- If fails: read the error. Common fixes:
|
|
38
|
+
- Native extension failure → ensure Java 21 is on PATH, retry
|
|
39
|
+
- Network error → `bundle config mirror.https://rubygems.org https://rubygems.org`, retry
|
|
40
|
+
- Wrong ruby → `rbenv local jruby-10.0.3.0`, retry
|
|
41
|
+
|
|
42
|
+
## Step 4 — Verify Zuzu loads
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
bundle exec ruby -e "require 'zuzu'; puts 'Zuzu ' + Zuzu::VERSION + ' loaded OK'"
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
- If LoadError: re-run `bundle install`, then retry.
|
|
49
|
+
|
|
50
|
+
## Step 5 — Check model file
|
|
51
|
+
|
|
52
|
+
Read `app.rb` and find the `c.llamafile_path` value.
|
|
53
|
+
|
|
54
|
+
Check if the model file exists at that path:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
ls -lh <extracted_model_path>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
- If missing:
|
|
61
|
+
- AskUserQuestion: "No model file found. Would you like instructions for downloading llava-v1.5-7b-q4.llamafile (~4 GB)?"
|
|
62
|
+
- If yes, tell the user:
|
|
63
|
+
```bash
|
|
64
|
+
mkdir -p models
|
|
65
|
+
curl -L -o models/llava-v1.5-7b-q4.llamafile \
|
|
66
|
+
https://huggingface.co/Mozilla/llava-v1.5-7b-llamafile/resolve/main/llava-v1.5-7b-q4.llamafile
|
|
67
|
+
chmod +x models/llava-v1.5-7b-q4.llamafile
|
|
68
|
+
```
|
|
69
|
+
- This requires the user to run it (large download). Tell them to re-run `/setup` after.
|
|
70
|
+
- If exists but not executable: `chmod +x <path>` — do this automatically.
|
|
71
|
+
- If exists and executable: continue.
|
|
72
|
+
|
|
73
|
+
## Step 6 — Smoke test (without model)
|
|
74
|
+
|
|
75
|
+
Test that the Ruby code parses and tools load without launching the GUI:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
bundle exec ruby -e "
|
|
79
|
+
require 'zuzu'
|
|
80
|
+
load 'app.rb' rescue nil
|
|
81
|
+
puts 'Tools registered: ' + Zuzu::ToolRegistry.tools.map(&:name).join(', ')
|
|
82
|
+
" 2>&1 | head -20
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
- If it shows tool names: good.
|
|
86
|
+
- If Ruby syntax error or LoadError: read the error, fix it in `app.rb`, retry.
|
|
87
|
+
|
|
88
|
+
## Step 7 — Summary
|
|
89
|
+
|
|
90
|
+
Tell the user:
|
|
91
|
+
- ✅ Java version found
|
|
92
|
+
- ✅ JRuby version confirmed
|
|
93
|
+
- ✅ Gems installed
|
|
94
|
+
- ✅ Zuzu loads
|
|
95
|
+
- ✅/⚠️ Model file status
|
|
96
|
+
- ✅ Tools registered: (list them)
|
|
97
|
+
|
|
98
|
+
If model is ready:
|
|
99
|
+
> Everything is set. Run `bundle exec zuzu start` to launch the app.
|
|
100
|
+
|
|
101
|
+
If model is missing:
|
|
102
|
+
> Download the model file (see step 5), then run `bundle exec zuzu start`.
|