agentnova 0.2.2__tar.gz → 0.2.3__tar.gz
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.
- {agentnova-0.2.2 → agentnova-0.2.3}/PKG-INFO +33 -17
- {agentnova-0.2.2 → agentnova-0.2.3}/README.md +32 -16
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/__init__.py +2 -2
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/__main__.py +27 -27
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/bitnet_client.py +150 -150
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/cli.py +12 -11
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/core/agent.py +11 -4
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/core/math_prompts.py +396 -396
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/core/memory.py +191 -191
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/core/model_family_config.py +57 -7
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/core/ollama_client.py +552 -542
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/core/orchestrator.py +190 -190
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/core/orchestrator_enhanced.py +393 -393
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/core/tools.py +303 -303
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/examples/10_skills_demo.py +1 -1
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/examples/11_skill_creator_test.py +1 -1
- agentnova-0.2.3/agentnova/examples/15_quick_diagnostic.py +241 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/model_discovery.py +341 -341
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/skills/__init__.py +24 -24
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/skills/loader.py +444 -444
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/tools/builtins.py +701 -701
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova.egg-info/PKG-INFO +33 -17
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova.egg-info/SOURCES.txt +1 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/pyproject.toml +1 -1
- {agentnova-0.2.2 → agentnova-0.2.3}/tests/test_acp_integration.py +217 -217
- {agentnova-0.2.2 → agentnova-0.2.3}/tests/test_acp_subagents.py +310 -310
- {agentnova-0.2.2 → agentnova-0.2.3}/LICENSE +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/acp_plugin.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/agent_mode.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/bitnet_setup.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/config.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/examples/00_backend_demo.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/examples/01_basic_agent.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/examples/02_tool_agent.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/examples/03_orchestrator.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/examples/04_comprehensive_test.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/examples/05_tool_tests.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/examples/06_interactive_chat.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/examples/07_model_comparison.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/examples/08_robust_comparison.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/examples/09_expanded_benchmark.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/examples/12_batch_operations.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/examples/13_shutdown_demo.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/examples/14_gsm8k_benchmark.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/shared_args.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/skills/acp/SKILL.md +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/skills/datetime/SKILL.md +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/skills/skill-creator/SKILL.md +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/skills/skill-creator/scripts/__init__.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/skills/skill-creator/scripts/aggregate_benchmark.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/skills/skill-creator/scripts/generate_report.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/skills/skill-creator/scripts/improve_description.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/skills/skill-creator/scripts/init_skill.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/skills/skill-creator/scripts/package_skill.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/skills/skill-creator/scripts/quick_validate.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/skills/skill-creator/scripts/run_eval.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/skills/skill-creator/scripts/run_loop.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/skills/skill-creator/scripts/security_scan.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/skills/skill-creator/scripts/test_package_skill.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/skills/skill-creator/scripts/test_quick_validate.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/skills/skill-creator/scripts/utils.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/skills/skill-creator/scripts/validate.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/skills/web_search/SKILL.md +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova/tools/sandboxed_repl.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova.egg-info/dependency_links.txt +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova.egg-info/entry_points.txt +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova.egg-info/requires.txt +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/agentnova.egg-info/top_level.txt +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/localclaw/__init__.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/localclaw/__main__.py +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/setup.cfg +0 -0
- {agentnova-0.2.2 → agentnova-0.2.3}/tests/test_agent.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentnova
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: A minimal, hackable agentic framework for Ollama and BitNet - local-first AI agent toolkit
|
|
5
5
|
Author-email: VTSTech <veritas@vts-tech.org>
|
|
6
6
|
Maintainer-email: VTSTech <veritas@vts-tech.org>
|
|
@@ -34,7 +34,7 @@ Requires-Dist: black>=23.0; extra == "dev"
|
|
|
34
34
|
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
35
35
|
Dynamic: license-file
|
|
36
36
|
|
|
37
|
-
# ⚛️ AgentNova R02
|
|
37
|
+
# ⚛️ AgentNova R02.3
|
|
38
38
|
|
|
39
39
|
A minimal, hackable agentic framework engineered to run **entirely locally** with [Ollama](https://ollama.com) or [BitNet](https://github.com/microsoft/BitNet).
|
|
40
40
|
|
|
@@ -42,7 +42,11 @@ Inspired by the architecture of OpenClaw, rebuilt from scratch for local-first o
|
|
|
42
42
|
|
|
43
43
|
**Written by [VTSTech](https://www.vts-tech.org)** · [GitHub](https://github.com/VTSTech/AgentNova)
|
|
44
44
|
|
|
45
|
+
[](https://colab.research.google.com/github/VTSTech/AgentNova/blob/main/AgentNova.ipynb)
|
|
45
46
|
[](https://GitHub.com/VTSTech/AgentNova/commit/) [](https://GitHub.com/VTSTech/AgentNova/commit/)
|
|
47
|
+
[](https://pypi.org/project/agentnova/)
|
|
48
|
+
[](#license) [](https://python.org)
|
|
49
|
+
|
|
46
50
|
---
|
|
47
51
|
|
|
48
52
|
## 📚 Documentation
|
|
@@ -195,20 +199,31 @@ agentnova models --tool_support
|
|
|
195
199
|
|
|
196
200
|
### Performance by Tool Support
|
|
197
201
|
|
|
198
|
-
|
|
202
|
+
R02.3 benchmark results (15-test suite):
|
|
203
|
+
|
|
204
|
+
| Model | Params | Tool Support | Score | Time |
|
|
205
|
+
|-------|--------|--------------|-------|------|
|
|
206
|
+
| **`granite3.1-moe:1b`** | 1B MoE | react | **93% (14/15)** | 87.8s |
|
|
207
|
+
| **`llama3.2:1b`** | 1.2B | native | **87% (13/15)** | 150.2s |
|
|
208
|
+
| `dolphin3.0-qwen2.5:0.5b` | 500M | none | 73% (11/15) | 27.2s |
|
|
209
|
+
| `qwen3:0.6b` | 600M | react | 67% (10/15) | 189.3s |
|
|
210
|
+
| `qwen2.5-coder:0.5b` | 494M | react | 60% (9/15) | 133.1s |
|
|
211
|
+
|
|
212
|
+
**Quick Diagnostic (Test 15 - 5 questions, ~30s/model):**
|
|
199
213
|
|
|
200
|
-
| Model |
|
|
201
|
-
|
|
202
|
-
|
|
|
203
|
-
|
|
|
204
|
-
| `
|
|
205
|
-
| `
|
|
214
|
+
| Model | Score | Tool Support |
|
|
215
|
+
|-------|-------|--------------|
|
|
216
|
+
| **`qwen3.5:0.8b`** | **100%** | native |
|
|
217
|
+
| **`qwen2.5:0.5b`** | **100%** | react |
|
|
218
|
+
| `functiongemma:270m` | 80% | native |
|
|
219
|
+
| `granite4:350m` | 80% | native |
|
|
220
|
+
| `qwen3:0.6b` | 60% | react |
|
|
206
221
|
|
|
207
|
-
**Key improvements in
|
|
208
|
-
-
|
|
209
|
-
-
|
|
210
|
-
-
|
|
211
|
-
-
|
|
222
|
+
**Key improvements in R02.3**:
|
|
223
|
+
- **+13%** for granite3.1-moe:1b (80% → 93%) from few-shot fix
|
|
224
|
+
- **+20%** for llama3.2:1b (67% → 87%) from observation role fix
|
|
225
|
+
- **qwen3:0.6b restored** from 0% (broken) with `think=False` API fix
|
|
226
|
+
- **qwen3.5:0.8b** new sub-1B champion with 100% on quick diagnostic
|
|
212
227
|
|
|
213
228
|
---
|
|
214
229
|
|
|
@@ -259,7 +274,7 @@ Output shows:
|
|
|
259
274
|
- **Tool Support** - `✓ native`, `ReAct`, `○ none`, or `untested`
|
|
260
275
|
|
|
261
276
|
```
|
|
262
|
-
⚛️ AgentNova R02 Models
|
|
277
|
+
⚛️ AgentNova R02.3 Models
|
|
263
278
|
Model Family Context Tool Support
|
|
264
279
|
──────────────────────────────────────────────────────────────────────────────
|
|
265
280
|
gemma3:270m gemma3 32K ○ none
|
|
@@ -276,8 +291,9 @@ Output shows:
|
|
|
276
291
|
# List all available tests
|
|
277
292
|
agentnova test --list
|
|
278
293
|
|
|
279
|
-
#
|
|
280
|
-
agentnova test
|
|
294
|
+
# Quick diagnostic - 5 questions, ~30s/model (NEW in R02.3)
|
|
295
|
+
agentnova test 15 --model granite3.1-moe:1b
|
|
296
|
+
agentnova test 15 --model all --debug
|
|
281
297
|
|
|
282
298
|
# Run GSM8K benchmark (50 math questions)
|
|
283
299
|
agentnova test 14 --acp --timeout 6400
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# ⚛️ AgentNova R02
|
|
1
|
+
# ⚛️ AgentNova R02.3
|
|
2
2
|
|
|
3
3
|
A minimal, hackable agentic framework engineered to run **entirely locally** with [Ollama](https://ollama.com) or [BitNet](https://github.com/microsoft/BitNet).
|
|
4
4
|
|
|
@@ -6,7 +6,11 @@ Inspired by the architecture of OpenClaw, rebuilt from scratch for local-first o
|
|
|
6
6
|
|
|
7
7
|
**Written by [VTSTech](https://www.vts-tech.org)** · [GitHub](https://github.com/VTSTech/AgentNova)
|
|
8
8
|
|
|
9
|
+
[](https://colab.research.google.com/github/VTSTech/AgentNova/blob/main/AgentNova.ipynb)
|
|
9
10
|
[](https://GitHub.com/VTSTech/AgentNova/commit/) [](https://GitHub.com/VTSTech/AgentNova/commit/)
|
|
11
|
+
[](https://pypi.org/project/agentnova/)
|
|
12
|
+
[](#license) [](https://python.org)
|
|
13
|
+
|
|
10
14
|
---
|
|
11
15
|
|
|
12
16
|
## 📚 Documentation
|
|
@@ -159,20 +163,31 @@ agentnova models --tool_support
|
|
|
159
163
|
|
|
160
164
|
### Performance by Tool Support
|
|
161
165
|
|
|
162
|
-
|
|
166
|
+
R02.3 benchmark results (15-test suite):
|
|
167
|
+
|
|
168
|
+
| Model | Params | Tool Support | Score | Time |
|
|
169
|
+
|-------|--------|--------------|-------|------|
|
|
170
|
+
| **`granite3.1-moe:1b`** | 1B MoE | react | **93% (14/15)** | 87.8s |
|
|
171
|
+
| **`llama3.2:1b`** | 1.2B | native | **87% (13/15)** | 150.2s |
|
|
172
|
+
| `dolphin3.0-qwen2.5:0.5b` | 500M | none | 73% (11/15) | 27.2s |
|
|
173
|
+
| `qwen3:0.6b` | 600M | react | 67% (10/15) | 189.3s |
|
|
174
|
+
| `qwen2.5-coder:0.5b` | 494M | react | 60% (9/15) | 133.1s |
|
|
175
|
+
|
|
176
|
+
**Quick Diagnostic (Test 15 - 5 questions, ~30s/model):**
|
|
163
177
|
|
|
164
|
-
| Model |
|
|
165
|
-
|
|
166
|
-
|
|
|
167
|
-
|
|
|
168
|
-
| `
|
|
169
|
-
| `
|
|
178
|
+
| Model | Score | Tool Support |
|
|
179
|
+
|-------|-------|--------------|
|
|
180
|
+
| **`qwen3.5:0.8b`** | **100%** | native |
|
|
181
|
+
| **`qwen2.5:0.5b`** | **100%** | react |
|
|
182
|
+
| `functiongemma:270m` | 80% | native |
|
|
183
|
+
| `granite4:350m` | 80% | native |
|
|
184
|
+
| `qwen3:0.6b` | 60% | react |
|
|
170
185
|
|
|
171
|
-
**Key improvements in
|
|
172
|
-
-
|
|
173
|
-
-
|
|
174
|
-
-
|
|
175
|
-
-
|
|
186
|
+
**Key improvements in R02.3**:
|
|
187
|
+
- **+13%** for granite3.1-moe:1b (80% → 93%) from few-shot fix
|
|
188
|
+
- **+20%** for llama3.2:1b (67% → 87%) from observation role fix
|
|
189
|
+
- **qwen3:0.6b restored** from 0% (broken) with `think=False` API fix
|
|
190
|
+
- **qwen3.5:0.8b** new sub-1B champion with 100% on quick diagnostic
|
|
176
191
|
|
|
177
192
|
---
|
|
178
193
|
|
|
@@ -223,7 +238,7 @@ Output shows:
|
|
|
223
238
|
- **Tool Support** - `✓ native`, `ReAct`, `○ none`, or `untested`
|
|
224
239
|
|
|
225
240
|
```
|
|
226
|
-
⚛️ AgentNova R02 Models
|
|
241
|
+
⚛️ AgentNova R02.3 Models
|
|
227
242
|
Model Family Context Tool Support
|
|
228
243
|
──────────────────────────────────────────────────────────────────────────────
|
|
229
244
|
gemma3:270m gemma3 32K ○ none
|
|
@@ -240,8 +255,9 @@ Output shows:
|
|
|
240
255
|
# List all available tests
|
|
241
256
|
agentnova test --list
|
|
242
257
|
|
|
243
|
-
#
|
|
244
|
-
agentnova test
|
|
258
|
+
# Quick diagnostic - 5 questions, ~30s/model (NEW in R02.3)
|
|
259
|
+
agentnova test 15 --model granite3.1-moe:1b
|
|
260
|
+
agentnova test 15 --model all --debug
|
|
245
261
|
|
|
246
262
|
# Run GSM8K benchmark (50 math questions)
|
|
247
263
|
agentnova test 14 --acp --timeout 6400
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""
|
|
2
|
-
⚛️ AgentNova R02 - A minimal, hackable agentic framework for Ollama and BitNet
|
|
2
|
+
⚛️ AgentNova R02.3 - A minimal, hackable agentic framework for Ollama and BitNet
|
|
3
3
|
|
|
4
4
|
Written by VTSTech
|
|
5
5
|
https://www.vts-tech.org
|
|
@@ -184,7 +184,7 @@ __all__ = [
|
|
|
184
184
|
"create_file_write_action", "create_file_delete_action",
|
|
185
185
|
"create_mkdir_action", "create_shell_action",
|
|
186
186
|
"format_status", "format_progress",
|
|
187
|
-
# R02: Model Family Configuration
|
|
187
|
+
# R02.3: Model Family Configuration
|
|
188
188
|
"ModelFamilyConfig", "FAMILY_CONFIGS",
|
|
189
189
|
"get_family_config", "get_stop_tokens", "supports_tools",
|
|
190
190
|
"get_tool_format", "get_preferred_temperature", "should_use_few_shot",
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
⚛️ AgentNova R00 — Command Line Interface
|
|
4
|
-
|
|
5
|
-
Entry point for: python -m agentnova [command] [options]
|
|
6
|
-
|
|
7
|
-
Commands:
|
|
8
|
-
run Run the agent on a single prompt and exit
|
|
9
|
-
chat Interactive multi-turn conversation with memory
|
|
10
|
-
models List models available in Ollama
|
|
11
|
-
tools List available built-in tools
|
|
12
|
-
skills List available Agent Skills
|
|
13
|
-
|
|
14
|
-
Examples:
|
|
15
|
-
python -m agentnova run "What is the capital of France?"
|
|
16
|
-
python -m agentnova chat --model llama3.1:8b --tools calculator,shell
|
|
17
|
-
python -m agentnova models
|
|
18
|
-
python -m agentnova tools
|
|
19
|
-
python -m agentnova skills
|
|
20
|
-
|
|
21
|
-
Written by VTSTech · https://www.vts-tech.org · https://github.com/VTSTech/AgentNova
|
|
22
|
-
"""
|
|
23
|
-
|
|
24
|
-
from agentnova.cli import main
|
|
25
|
-
|
|
26
|
-
if __name__ == "__main__":
|
|
27
|
-
main()
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
⚛️ AgentNova R00 — Command Line Interface
|
|
4
|
+
|
|
5
|
+
Entry point for: python -m agentnova [command] [options]
|
|
6
|
+
|
|
7
|
+
Commands:
|
|
8
|
+
run Run the agent on a single prompt and exit
|
|
9
|
+
chat Interactive multi-turn conversation with memory
|
|
10
|
+
models List models available in Ollama
|
|
11
|
+
tools List available built-in tools
|
|
12
|
+
skills List available Agent Skills
|
|
13
|
+
|
|
14
|
+
Examples:
|
|
15
|
+
python -m agentnova run "What is the capital of France?"
|
|
16
|
+
python -m agentnova chat --model llama3.1:8b --tools calculator,shell
|
|
17
|
+
python -m agentnova models
|
|
18
|
+
python -m agentnova tools
|
|
19
|
+
python -m agentnova skills
|
|
20
|
+
|
|
21
|
+
Written by VTSTech · https://www.vts-tech.org · https://github.com/VTSTech/AgentNova
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
from agentnova.cli import main
|
|
25
|
+
|
|
26
|
+
if __name__ == "__main__":
|
|
27
|
+
main()
|
|
@@ -1,151 +1,151 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
⚛️ AgentNova R00 — BitnetClient
|
|
4
|
-
Drop-in replacement for OllamaClient that uses Microsoft's bitnet.cpp
|
|
5
|
-
(llama-server) as the inference backend instead of Ollama.
|
|
6
|
-
|
|
7
|
-
Architecture:
|
|
8
|
-
- Wraps bitnet.cpp's llama-server HTTP process
|
|
9
|
-
- Exposes the same interface as OllamaClient: chat(), list_models(),
|
|
10
|
-
model_supports_tools(), is_running()
|
|
11
|
-
- Normalises OpenAI-format responses → Ollama-format so agent.py is
|
|
12
|
-
completely unmodified
|
|
13
|
-
- Manages llama-server lifecycle (start/stop/health-check)
|
|
14
|
-
- Falls back gracefully to ReAct tool-calling (no native function
|
|
15
|
-
calling in current bitnet models)
|
|
16
|
-
|
|
17
|
-
Supported models (as of bitnet.cpp 2025):
|
|
18
|
-
- microsoft/BitNet-b1.58-2B-4T (~0.4 GB, recommended)
|
|
19
|
-
- 1bitLLM/bitnet_b1_58-3B (~0.7 GB)
|
|
20
|
-
- HF1BitLLM/Llama3-8B-1.58-100B-tokens
|
|
21
|
-
- tiiuae/Falcon3-1B-Instruct-1.58bit
|
|
22
|
-
- tiiuae/Falcon3-3B-Instruct-1.58bit
|
|
23
|
-
- tiiuae/Falcon3-7B-Instruct-1.58bit
|
|
24
|
-
"""
|
|
25
|
-
|
|
26
|
-
import json
|
|
27
|
-
import urllib.request
|
|
28
|
-
from .config import BITNET_BASE_URL
|
|
29
|
-
|
|
30
|
-
# Known BitNet model identifiers
|
|
31
|
-
KNOWN_MODELS = [
|
|
32
|
-
"bitnet-b1.58-2b-4t",
|
|
33
|
-
"BitNet-b1.58-2B-4T",
|
|
34
|
-
"bitnet-b1.58-large",
|
|
35
|
-
]
|
|
36
|
-
|
|
37
|
-
class BitnetClient:
|
|
38
|
-
def __init__(self, base_url=None, timeout=120):
|
|
39
|
-
# Prioritize passed URL, fallback to config
|
|
40
|
-
self.base_url = base_url or BITNET_BASE_URL
|
|
41
|
-
self.timeout = timeout
|
|
42
|
-
|
|
43
|
-
def is_running(self) -> bool:
|
|
44
|
-
try:
|
|
45
|
-
with urllib.request.urlopen(f"{self.base_url}/health", timeout=2) as resp:
|
|
46
|
-
return resp.getcode() == 200
|
|
47
|
-
except:
|
|
48
|
-
return False
|
|
49
|
-
|
|
50
|
-
def list_models(self):
|
|
51
|
-
try:
|
|
52
|
-
with urllib.request.urlopen(f"{self.base_url}/v1/models", timeout=5) as resp:
|
|
53
|
-
if resp.getcode() == 200:
|
|
54
|
-
data = json.loads(resp.read().decode("utf-8"))
|
|
55
|
-
# Return the ID of the model(s), cleaned up to show just model folder/filename
|
|
56
|
-
models = []
|
|
57
|
-
for m in data.get('data', []):
|
|
58
|
-
model_id = m['id']
|
|
59
|
-
# Strip common prefixes to show just model_dir/filename.gguf
|
|
60
|
-
# e.g., /content/BitNet/models/BitNet-b1.58-2B-4T/bitnet_2b_i2_s.gguf
|
|
61
|
-
# -> BitNet-b1.58-2B-4T/bitnet_2b_i2_s.gguf
|
|
62
|
-
if '/models/' in model_id:
|
|
63
|
-
# Keep everything after /models/
|
|
64
|
-
model_id = model_id.split('/models/')[-1]
|
|
65
|
-
elif model_id.startswith('/'):
|
|
66
|
-
# Just keep last two path components
|
|
67
|
-
parts = model_id.strip('/').split('/')
|
|
68
|
-
if len(parts) >= 2:
|
|
69
|
-
model_id = '/'.join(parts[-2:])
|
|
70
|
-
models.append(model_id)
|
|
71
|
-
return models
|
|
72
|
-
except:
|
|
73
|
-
return []
|
|
74
|
-
|
|
75
|
-
def chat(
|
|
76
|
-
self,
|
|
77
|
-
model: str,
|
|
78
|
-
messages: list[dict],
|
|
79
|
-
options: dict | None = None,
|
|
80
|
-
stream: bool = False,
|
|
81
|
-
tools: list | None = None, # Signature fix for agent.py
|
|
82
|
-
**kwargs, # Catch-all for extra agent args
|
|
83
|
-
):
|
|
84
|
-
"""
|
|
85
|
-
Chat completion for BitNet.
|
|
86
|
-
|
|
87
|
-
Note: BitNet llama-server doesn't support streaming in the same way
|
|
88
|
-
as Ollama. When stream=True, this yields tokens from a streaming
|
|
89
|
-
response. Otherwise returns a complete response dict.
|
|
90
|
-
"""
|
|
91
|
-
url = f"{self.base_url}/v1/chat/completions"
|
|
92
|
-
|
|
93
|
-
data = {
|
|
94
|
-
"model": model,
|
|
95
|
-
"messages": messages,
|
|
96
|
-
"stream": stream,
|
|
97
|
-
"temperature": (options or {}).get("temperature", 0.7),
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
req = urllib.request.Request(
|
|
101
|
-
url,
|
|
102
|
-
data=json.dumps(data).encode("utf-8"),
|
|
103
|
-
headers={"Content-Type": "application/json"}
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
if stream:
|
|
107
|
-
# Return a generator for streaming
|
|
108
|
-
return self._stream_response(req, model)
|
|
109
|
-
else:
|
|
110
|
-
# Non-streaming: return complete response
|
|
111
|
-
with urllib.request.urlopen(req, timeout=self.timeout) as resp:
|
|
112
|
-
result = json.loads(resp.read().decode("utf-8"))
|
|
113
|
-
# Normalize OpenAI completion to Ollama format for the Agent
|
|
114
|
-
return {
|
|
115
|
-
"model": model,
|
|
116
|
-
"message": {
|
|
117
|
-
"role": "assistant",
|
|
118
|
-
"content": result["choices"][0]["message"]["content"]
|
|
119
|
-
},
|
|
120
|
-
"done": True
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
def _stream_response(self, req, model):
|
|
124
|
-
"""
|
|
125
|
-
Handle SSE streaming response from BitNet server.
|
|
126
|
-
Yields tokens one at a time.
|
|
127
|
-
"""
|
|
128
|
-
with urllib.request.urlopen(req, timeout=self.timeout) as resp:
|
|
129
|
-
buffer = ""
|
|
130
|
-
for line in resp:
|
|
131
|
-
line = line.decode("utf-8")
|
|
132
|
-
if line.startswith("data: "):
|
|
133
|
-
data_str = line[6:].strip()
|
|
134
|
-
if data_str == "[DONE]":
|
|
135
|
-
break
|
|
136
|
-
try:
|
|
137
|
-
chunk = json.loads(data_str)
|
|
138
|
-
if "choices" in chunk and len(chunk["choices"]) > 0:
|
|
139
|
-
delta = chunk["choices"][0].get("delta", {})
|
|
140
|
-
content = delta.get("content", "")
|
|
141
|
-
if content:
|
|
142
|
-
yield content
|
|
143
|
-
except json.JSONDecodeError:
|
|
144
|
-
continue
|
|
145
|
-
|
|
146
|
-
def model_supports_tools(self, model: str) -> bool:
|
|
147
|
-
return False # BitNet models require ReAct fallback in Agent.py
|
|
148
|
-
|
|
149
|
-
def supports_streaming(self) -> bool:
|
|
150
|
-
"""Return True if this client supports streaming."""
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
⚛️ AgentNova R00 — BitnetClient
|
|
4
|
+
Drop-in replacement for OllamaClient that uses Microsoft's bitnet.cpp
|
|
5
|
+
(llama-server) as the inference backend instead of Ollama.
|
|
6
|
+
|
|
7
|
+
Architecture:
|
|
8
|
+
- Wraps bitnet.cpp's llama-server HTTP process
|
|
9
|
+
- Exposes the same interface as OllamaClient: chat(), list_models(),
|
|
10
|
+
model_supports_tools(), is_running()
|
|
11
|
+
- Normalises OpenAI-format responses → Ollama-format so agent.py is
|
|
12
|
+
completely unmodified
|
|
13
|
+
- Manages llama-server lifecycle (start/stop/health-check)
|
|
14
|
+
- Falls back gracefully to ReAct tool-calling (no native function
|
|
15
|
+
calling in current bitnet models)
|
|
16
|
+
|
|
17
|
+
Supported models (as of bitnet.cpp 2025):
|
|
18
|
+
- microsoft/BitNet-b1.58-2B-4T (~0.4 GB, recommended)
|
|
19
|
+
- 1bitLLM/bitnet_b1_58-3B (~0.7 GB)
|
|
20
|
+
- HF1BitLLM/Llama3-8B-1.58-100B-tokens
|
|
21
|
+
- tiiuae/Falcon3-1B-Instruct-1.58bit
|
|
22
|
+
- tiiuae/Falcon3-3B-Instruct-1.58bit
|
|
23
|
+
- tiiuae/Falcon3-7B-Instruct-1.58bit
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
import json
|
|
27
|
+
import urllib.request
|
|
28
|
+
from .config import BITNET_BASE_URL
|
|
29
|
+
|
|
30
|
+
# Known BitNet model identifiers
|
|
31
|
+
KNOWN_MODELS = [
|
|
32
|
+
"bitnet-b1.58-2b-4t",
|
|
33
|
+
"BitNet-b1.58-2B-4T",
|
|
34
|
+
"bitnet-b1.58-large",
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
class BitnetClient:
|
|
38
|
+
def __init__(self, base_url=None, timeout=120):
|
|
39
|
+
# Prioritize passed URL, fallback to config
|
|
40
|
+
self.base_url = base_url or BITNET_BASE_URL
|
|
41
|
+
self.timeout = timeout
|
|
42
|
+
|
|
43
|
+
def is_running(self) -> bool:
|
|
44
|
+
try:
|
|
45
|
+
with urllib.request.urlopen(f"{self.base_url}/health", timeout=2) as resp:
|
|
46
|
+
return resp.getcode() == 200
|
|
47
|
+
except:
|
|
48
|
+
return False
|
|
49
|
+
|
|
50
|
+
def list_models(self):
|
|
51
|
+
try:
|
|
52
|
+
with urllib.request.urlopen(f"{self.base_url}/v1/models", timeout=5) as resp:
|
|
53
|
+
if resp.getcode() == 200:
|
|
54
|
+
data = json.loads(resp.read().decode("utf-8"))
|
|
55
|
+
# Return the ID of the model(s), cleaned up to show just model folder/filename
|
|
56
|
+
models = []
|
|
57
|
+
for m in data.get('data', []):
|
|
58
|
+
model_id = m['id']
|
|
59
|
+
# Strip common prefixes to show just model_dir/filename.gguf
|
|
60
|
+
# e.g., /content/BitNet/models/BitNet-b1.58-2B-4T/bitnet_2b_i2_s.gguf
|
|
61
|
+
# -> BitNet-b1.58-2B-4T/bitnet_2b_i2_s.gguf
|
|
62
|
+
if '/models/' in model_id:
|
|
63
|
+
# Keep everything after /models/
|
|
64
|
+
model_id = model_id.split('/models/')[-1]
|
|
65
|
+
elif model_id.startswith('/'):
|
|
66
|
+
# Just keep last two path components
|
|
67
|
+
parts = model_id.strip('/').split('/')
|
|
68
|
+
if len(parts) >= 2:
|
|
69
|
+
model_id = '/'.join(parts[-2:])
|
|
70
|
+
models.append(model_id)
|
|
71
|
+
return models
|
|
72
|
+
except:
|
|
73
|
+
return []
|
|
74
|
+
|
|
75
|
+
def chat(
|
|
76
|
+
self,
|
|
77
|
+
model: str,
|
|
78
|
+
messages: list[dict],
|
|
79
|
+
options: dict | None = None,
|
|
80
|
+
stream: bool = False,
|
|
81
|
+
tools: list | None = None, # Signature fix for agent.py
|
|
82
|
+
**kwargs, # Catch-all for extra agent args
|
|
83
|
+
):
|
|
84
|
+
"""
|
|
85
|
+
Chat completion for BitNet.
|
|
86
|
+
|
|
87
|
+
Note: BitNet llama-server doesn't support streaming in the same way
|
|
88
|
+
as Ollama. When stream=True, this yields tokens from a streaming
|
|
89
|
+
response. Otherwise returns a complete response dict.
|
|
90
|
+
"""
|
|
91
|
+
url = f"{self.base_url}/v1/chat/completions"
|
|
92
|
+
|
|
93
|
+
data = {
|
|
94
|
+
"model": model,
|
|
95
|
+
"messages": messages,
|
|
96
|
+
"stream": stream,
|
|
97
|
+
"temperature": (options or {}).get("temperature", 0.7),
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
req = urllib.request.Request(
|
|
101
|
+
url,
|
|
102
|
+
data=json.dumps(data).encode("utf-8"),
|
|
103
|
+
headers={"Content-Type": "application/json"}
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
if stream:
|
|
107
|
+
# Return a generator for streaming
|
|
108
|
+
return self._stream_response(req, model)
|
|
109
|
+
else:
|
|
110
|
+
# Non-streaming: return complete response
|
|
111
|
+
with urllib.request.urlopen(req, timeout=self.timeout) as resp:
|
|
112
|
+
result = json.loads(resp.read().decode("utf-8"))
|
|
113
|
+
# Normalize OpenAI completion to Ollama format for the Agent
|
|
114
|
+
return {
|
|
115
|
+
"model": model,
|
|
116
|
+
"message": {
|
|
117
|
+
"role": "assistant",
|
|
118
|
+
"content": result["choices"][0]["message"]["content"]
|
|
119
|
+
},
|
|
120
|
+
"done": True
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
def _stream_response(self, req, model):
|
|
124
|
+
"""
|
|
125
|
+
Handle SSE streaming response from BitNet server.
|
|
126
|
+
Yields tokens one at a time.
|
|
127
|
+
"""
|
|
128
|
+
with urllib.request.urlopen(req, timeout=self.timeout) as resp:
|
|
129
|
+
buffer = ""
|
|
130
|
+
for line in resp:
|
|
131
|
+
line = line.decode("utf-8")
|
|
132
|
+
if line.startswith("data: "):
|
|
133
|
+
data_str = line[6:].strip()
|
|
134
|
+
if data_str == "[DONE]":
|
|
135
|
+
break
|
|
136
|
+
try:
|
|
137
|
+
chunk = json.loads(data_str)
|
|
138
|
+
if "choices" in chunk and len(chunk["choices"]) > 0:
|
|
139
|
+
delta = chunk["choices"][0].get("delta", {})
|
|
140
|
+
content = delta.get("content", "")
|
|
141
|
+
if content:
|
|
142
|
+
yield content
|
|
143
|
+
except json.JSONDecodeError:
|
|
144
|
+
continue
|
|
145
|
+
|
|
146
|
+
def model_supports_tools(self, model: str) -> bool:
|
|
147
|
+
return False # BitNet models require ReAct fallback in Agent.py
|
|
148
|
+
|
|
149
|
+
def supports_streaming(self) -> bool:
|
|
150
|
+
"""Return True if this client supports streaming."""
|
|
151
151
|
return True
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
"""
|
|
3
|
-
⚛️ AgentNova R02 — CLI
|
|
3
|
+
⚛️ AgentNova R02.3 — CLI
|
|
4
4
|
Entry point: agentnova <command> [options]
|
|
5
5
|
|
|
6
6
|
Commands:
|
|
@@ -924,7 +924,7 @@ def cmd_models(args):
|
|
|
924
924
|
print(red("✗ bitnet_client.py not found. Copy it into agentnova/."))
|
|
925
925
|
sys.exit(1)
|
|
926
926
|
|
|
927
|
-
print(bold("\n⚛️ AgentNova R02 BitNet Model (Remote)"))
|
|
927
|
+
print(bold("\n⚛️ AgentNova R02.3 BitNet Model (Remote)"))
|
|
928
928
|
|
|
929
929
|
# We use the client logic to see what is actually running at the URL
|
|
930
930
|
try:
|
|
@@ -952,7 +952,7 @@ def cmd_models(args):
|
|
|
952
952
|
print(yellow("No models found. Pull one with: ollama pull llama3.2:3b"))
|
|
953
953
|
return
|
|
954
954
|
|
|
955
|
-
print(bold("\n⚛️ AgentNova R02 Models") + dim(" · Written by VTSTech · https://www.vts-tech.org · https://github.com/VTSTech/AgentNova"))
|
|
955
|
+
print(bold("\n⚛️ AgentNova R02.3 Models") + dim(" · Written by VTSTech · https://www.vts-tech.org · https://github.com/VTSTech/AgentNova"))
|
|
956
956
|
|
|
957
957
|
# Load tested models from storage
|
|
958
958
|
tested_models = _load_tested_models()
|
|
@@ -1091,7 +1091,7 @@ def cmd_models(args):
|
|
|
1091
1091
|
|
|
1092
1092
|
def cmd_tools(args):
|
|
1093
1093
|
tools = BUILTIN_REGISTRY.all()
|
|
1094
|
-
print(bold("\n⚛️ AgentNova R02 Tools") + dim(" · Written by VTSTech · https://www.vts-tech.org · https://github.com/VTSTech/AgentNova"))
|
|
1094
|
+
print(bold("\n⚛️ AgentNova R02.3 Tools") + dim(" · Written by VTSTech · https://www.vts-tech.org · https://github.com/VTSTech/AgentNova"))
|
|
1095
1095
|
print(bold(f"{'Tool':<20} Description"))
|
|
1096
1096
|
print(dim("─" * 70))
|
|
1097
1097
|
for t in tools:
|
|
@@ -1116,7 +1116,7 @@ def cmd_modelfile(args):
|
|
|
1116
1116
|
sys.exit(1)
|
|
1117
1117
|
|
|
1118
1118
|
model = args.model
|
|
1119
|
-
print(bold(f"\n⚛️ AgentNova R02 Modelfile") + dim(" · Written by VTSTech · https://www.vts-tech.org · https://github.com/VTSTech/AgentNova"))
|
|
1119
|
+
print(bold(f"\n⚛️ AgentNova R02.3 Modelfile") + dim(" · Written by VTSTech · https://www.vts-tech.org · https://github.com/VTSTech/AgentNova"))
|
|
1120
1120
|
print()
|
|
1121
1121
|
|
|
1122
1122
|
try:
|
|
@@ -1181,7 +1181,7 @@ def cmd_skills(args):
|
|
|
1181
1181
|
loader = SkillLoader()
|
|
1182
1182
|
skills = loader.list_skills()
|
|
1183
1183
|
|
|
1184
|
-
print(bold("\n⚛️ AgentNova R02 Skills") + dim(" · Written by VTSTech · https://www.vts-tech.org · https://github.com/VTSTech/AgentNova"))
|
|
1184
|
+
print(bold("\n⚛️ AgentNova R02.3 Skills") + dim(" · Written by VTSTech · https://www.vts-tech.org · https://github.com/VTSTech/AgentNova"))
|
|
1185
1185
|
|
|
1186
1186
|
if not skills:
|
|
1187
1187
|
print(yellow(" No skills found."))
|
|
@@ -1266,7 +1266,7 @@ def cmd_run(args):
|
|
|
1266
1266
|
if acp_plugin:
|
|
1267
1267
|
bootstrap_result = acp_plugin.bootstrap(claim_primary=False) # AgentNova is secondary
|
|
1268
1268
|
|
|
1269
|
-
print(bold("⚛️ AgentNova R02") + dim(" · Written by VTSTech · https://www.vts-tech.org · https://github.com/VTSTech/AgentNova"))
|
|
1269
|
+
print(bold("⚛️ AgentNova R02.3") + dim(" · Written by VTSTech · https://www.vts-tech.org · https://github.com/VTSTech/AgentNova"))
|
|
1270
1270
|
print(f"Prompt: {args.prompt}")
|
|
1271
1271
|
|
|
1272
1272
|
# Log user message to ACP
|
|
@@ -1359,7 +1359,7 @@ def cmd_chat(args):
|
|
|
1359
1359
|
parts.append("]")
|
|
1360
1360
|
status = " ".join(parts)
|
|
1361
1361
|
|
|
1362
|
-
print(bold(f"\n⚛️ AgentNova R02 chat") + dim(f" {status} · Written by VTSTech · https://www.vts-tech.org · https://github.com/VTSTech/AgentNova"))
|
|
1362
|
+
print(bold(f"\n⚛️ AgentNova R02.3 chat") + dim(f" {status} · Written by VTSTech · https://www.vts-tech.org · https://github.com/VTSTech/AgentNova"))
|
|
1363
1363
|
print(dim(" Type 'exit', 'quit', or Ctrl+C to quit."))
|
|
1364
1364
|
print(dim(" Type '/help' to see all available commands."))
|
|
1365
1365
|
print(dim(" Type '/ollama' to manage Ollama models (works with remote Ollama)."))
|
|
@@ -1909,7 +1909,7 @@ def cmd_agent(args):
|
|
|
1909
1909
|
parts.append("]")
|
|
1910
1910
|
status = " ".join(parts)
|
|
1911
1911
|
|
|
1912
|
-
print(bold(f"\n⚛️ AgentNova R02 agent mode") + dim(f" {status} · Written by VTSTech · https://www.vts-tech.org · https://github.com/VTSTech/AgentNova"))
|
|
1912
|
+
print(bold(f"\n⚛️ AgentNova R02.3 agent mode") + dim(f" {status} · Written by VTSTech · https://www.vts-tech.org · https://github.com/VTSTech/AgentNova"))
|
|
1913
1913
|
print(dim(" Agent mode: Give tasks and the agent will work autonomously."))
|
|
1914
1914
|
print(dim(" Type '/help' to see available commands."))
|
|
1915
1915
|
print(dim(" ─────────────────────────────────────"))
|
|
@@ -2290,11 +2290,12 @@ def cmd_test(args):
|
|
|
2290
2290
|
"13_acp": "Shutdown demo with ACP tracking",
|
|
2291
2291
|
"14": "GSM8K benchmark - 50 math questions",
|
|
2292
2292
|
"14_acp": "GSM8K benchmark with ACP tracking",
|
|
2293
|
+
"15": "Quick diagnostic - 5 questions, ~30s/model",
|
|
2293
2294
|
"backend": "Backend demo - Ollama/BitNet switching",
|
|
2294
2295
|
}
|
|
2295
2296
|
|
|
2296
2297
|
# Quick test set (skips long-running benchmarks)
|
|
2297
|
-
QUICK_TESTS = ["01", "02", "03", "04", "05", "10", "11"]
|
|
2298
|
+
QUICK_TESTS = ["01", "02", "03", "04", "05", "10", "11", "15"]
|
|
2298
2299
|
|
|
2299
2300
|
if args.list:
|
|
2300
2301
|
print(bold("\n⚛️ AgentNova Test Examples"))
|
|
@@ -2456,7 +2457,7 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
2456
2457
|
|
|
2457
2458
|
parser = argparse.ArgumentParser(
|
|
2458
2459
|
prog="agentnova",
|
|
2459
|
-
description="⚛️ AgentNova R02 - local agentic AI powered by Ollama",
|
|
2460
|
+
description="⚛️ AgentNova R02.3 - local agentic AI powered by Ollama",
|
|
2460
2461
|
)
|
|
2461
2462
|
|
|
2462
2463
|
sub = parser.add_subparsers(dest="command", metavar="command")
|