agentnova 0.3.3__tar.gz → 0.3.4__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.3.3 → agentnova-0.3.4}/PKG-INFO +2 -2
- {agentnova-0.3.3 → agentnova-0.3.4}/README.md +321 -321
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/__init__.py +1 -1
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/agent.py +9 -1
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/backends/ollama.py +59 -1
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova.egg-info/PKG-INFO +2 -2
- {agentnova-0.3.3 → agentnova-0.3.4}/pyproject.toml +1 -1
- {agentnova-0.3.3 → agentnova-0.3.4}/LICENSE +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/__main__.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/acp_plugin.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/agent_mode.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/backends/__init__.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/backends/base.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/backends/bitnet.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/cli.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/config.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/core/__init__.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/core/args_normal.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/core/error_recovery.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/core/helpers.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/core/math_prompts.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/core/memory.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/core/model_config.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/core/model_family_config.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/core/models.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/core/openresponses.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/core/prompts.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/core/tool_parse.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/core/types.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/examples/00_basic_agent.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/examples/01_quick_diagnostic.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/examples/02_tool_test.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/examples/03_reasoning_test.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/examples/04_gsm8k_benchmark.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/examples/05_common_sense.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/examples/06_causal_reasoning.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/examples/07_logical_deduction.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/examples/08_reading_comprehension.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/examples/09_general_knowledge.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/examples/10_implicit_reasoning.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/examples/11_analogical_reasoning.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/examples/__init__.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/model_discovery.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/orchestrator.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/orchestrator_enhanced.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/py.typed +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/shared_args.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/skills/__init__.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/skills/acp/SKILL.md +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/skills/datetime/SKILL.md +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/skills/loader.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/skills/skill-creator/SKILL.md +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/skills/skill-creator/scripts/__init__.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/skills/skill-creator/scripts/aggregate_benchmark.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/skills/skill-creator/scripts/generate_report.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/skills/skill-creator/scripts/improve_description.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/skills/skill-creator/scripts/init_skill.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/skills/skill-creator/scripts/package_skill.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/skills/skill-creator/scripts/quick_validate.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/skills/skill-creator/scripts/run_eval.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/skills/skill-creator/scripts/run_loop.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/skills/skill-creator/scripts/security_scan.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/skills/skill-creator/scripts/test_package_skill.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/skills/skill-creator/scripts/test_quick_validate.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/skills/skill-creator/scripts/utils.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/skills/skill-creator/scripts/validate.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/skills/web-search/SKILL.md +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/soul/__init__.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/soul/loader.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/soul/types.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/souls/nova-helper/IDENTITY.md +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/souls/nova-helper/SOUL.md +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/souls/nova-helper/STYLE.md +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/souls/nova-helper/soul.json +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/tools/__init__.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/tools/builtins.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/tools/registry.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova/tools/sandboxed_repl.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova.egg-info/SOURCES.txt +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova.egg-info/dependency_links.txt +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova.egg-info/entry_points.txt +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova.egg-info/requires.txt +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/agentnova.egg-info/top_level.txt +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/localclaw/__init__.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/localclaw-redirect/localclaw/__init__.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/setup.cfg +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/tests/test_acp_integration.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/tests/test_acp_subagents.py +0 -0
- {agentnova-0.3.3 → agentnova-0.3.4}/tests/test_agent.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentnova
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.4
|
|
4
4
|
Summary: ⚛️ AgentNova - A minimal, hackable agentic framework for local LLM inference
|
|
5
5
|
Author-email: VTSTech <veritas@vts-tech.org>
|
|
6
6
|
Maintainer-email: VTSTech <veritas@vts-tech.org>
|
|
@@ -49,7 +49,7 @@ Inspired by the architecture of OpenClaw, rebuilt from scratch for local-first o
|
|
|
49
49
|
|
|
50
50
|
[](#license) [](https://python.org)
|
|
51
51
|
|
|
52
|
-
<img width="
|
|
52
|
+
<img width="1400" height="1001" alt="image" src="https://github.com/user-attachments/assets/1bc8fb7a-415b-4750-9ce2-1e721bbf9149" />
|
|
53
53
|
|
|
54
54
|
## 📚 Documentation
|
|
55
55
|
|
|
@@ -1,321 +1,321 @@
|
|
|
1
|
-
# ⚛️ AgentNova R03.3
|
|
2
|
-
|
|
3
|
-
**Status: Alpha**
|
|
4
|
-
|
|
5
|
-
A minimal, hackable agentic framework engineered to run **entirely locally** with [Ollama](https://ollama.com) or [BitNet](https://github.com/microsoft/BitNet).
|
|
6
|
-
|
|
7
|
-
Inspired by the architecture of OpenClaw, rebuilt from scratch for local-first operation.
|
|
8
|
-
|
|
9
|
-
**Written by [VTSTech](https://www.vts-tech.org)** · [GitHub](https://github.com/VTSTech/AgentNova)
|
|
10
|
-
|
|
11
|
-
[](https://colab.research.google.com/github/VTSTech/AgentNova/blob/main/AgentNova.ipynb)
|
|
12
|
-
[](https://GitHub.com/VTSTech/AgentNova/commit/) [](https://GitHub.com/VTSTech/AgentNova/commit/)
|
|
13
|
-
|
|
14
|
-
[](https://pypi.org/project/agentnova/) [](https://pypi.org/project/agentnova/) [](https://pypi.org/project/agentnova/) [](https://pypi.org/project/agentnova/)
|
|
15
|
-
|
|
16
|
-
[](#license) [](https://python.org)
|
|
17
|
-
|
|
18
|
-
<img width="
|
|
19
|
-
|
|
20
|
-
## 📚 Documentation
|
|
21
|
-
|
|
22
|
-
| Document | Description |
|
|
23
|
-
|----------|-------------|
|
|
24
|
-
| [Architecture.md](https://github.com/VTSTech/AgentNova/blob/main/Architecture.md) | Technical documentation for developers (directory structure, core design, orchestrator modes) |
|
|
25
|
-
| [CHANGELOG.md](https://github.com/VTSTech/AgentNova/blob/main/CHANGELOG.md) | Version history and release notes (includes LocalClaw history) |
|
|
26
|
-
| [TESTS.md](https://github.com/VTSTech/AgentNova/blob/main/TESTS.md) | Benchmark results, model recommendations, and testing guide |
|
|
27
|
-
|
|
28
|
-
## Features
|
|
29
|
-
|
|
30
|
-
- **Zero dependencies** — Uses Python stdlib only (urllib for HTTP)
|
|
31
|
-
- **Ollama + BitNet backends** — Switch with `--backend` flag
|
|
32
|
-
- **Dual API support** — OpenResponses (`--api resp`) and Chat-Completions (`--api comp`)
|
|
33
|
-
- **Three-tier tool support** — Native, ReAct, or none (auto-detected)
|
|
34
|
-
- **Small model optimized** — Fuzzy matching, argument normalization
|
|
35
|
-
- **Built-in security** — Path validation, command blocklist, SSRF protection
|
|
36
|
-
- **Multi-agent orchestration** — Router, pipeline, and parallel modes
|
|
37
|
-
- **Soul Spec v0.5** — Persona packages with progressive disclosure
|
|
38
|
-
- **ACP v1.0.5 integration** — Agent Control Panel for monitoring and control
|
|
39
|
-
- **AgentSkills spec** — Skill loading with SPDX license validation
|
|
40
|
-
|
|
41
|
-
## Installation
|
|
42
|
-
|
|
43
|
-
```bash
|
|
44
|
-
# From source
|
|
45
|
-
git clone https://github.com/VTSTech/AgentNova.git
|
|
46
|
-
cd AgentNova
|
|
47
|
-
pip install -e .
|
|
48
|
-
|
|
49
|
-
# Or from PyPI (when published)
|
|
50
|
-
pip install agentnova
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
## Quick Start
|
|
54
|
-
|
|
55
|
-
### CLI Usage
|
|
56
|
-
|
|
57
|
-
```bash
|
|
58
|
-
# Run a single prompt
|
|
59
|
-
agentnova run "What is 15 * 8?" --tools calculator
|
|
60
|
-
|
|
61
|
-
# Interactive chat
|
|
62
|
-
agentnova chat -m qwen2.5:0.5b --tools calculator,shell
|
|
63
|
-
|
|
64
|
-
# Autonomous agent mode
|
|
65
|
-
agentnova agent -m qwen2.5:7b --tools calculator,shell,write_file
|
|
66
|
-
|
|
67
|
-
# Use Chat-Completions API (OpenAI-compatible)
|
|
68
|
-
agentnova chat -m qwen2.5:0.5b --api comp
|
|
69
|
-
|
|
70
|
-
# List available models
|
|
71
|
-
agentnova models
|
|
72
|
-
|
|
73
|
-
# List available tools
|
|
74
|
-
agentnova tools
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
### Python API
|
|
78
|
-
|
|
79
|
-
```python
|
|
80
|
-
from agentnova import Agent
|
|
81
|
-
from agentnova.tools import make_builtin_registry
|
|
82
|
-
|
|
83
|
-
# Create tools
|
|
84
|
-
tools = make_builtin_registry().subset(["calculator", "shell"])
|
|
85
|
-
|
|
86
|
-
# Create agent
|
|
87
|
-
agent = Agent(
|
|
88
|
-
model="qwen2.5:0.5b",
|
|
89
|
-
tools=tools,
|
|
90
|
-
backend="ollama",
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
# Run
|
|
94
|
-
result = agent.run("What is 15 * 8?")
|
|
95
|
-
print(result.final_answer)
|
|
96
|
-
print(f"Completed in {result.total_ms:.0f}ms")
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
### Chat-Completions Streaming
|
|
100
|
-
|
|
101
|
-
```python
|
|
102
|
-
from agentnova.backends import get_backend
|
|
103
|
-
from agentnova.core.types import ApiMode
|
|
104
|
-
|
|
105
|
-
# Use Chat-Completions mode with streaming
|
|
106
|
-
backend = get_backend("ollama", api_mode=ApiMode.COMPLETIONS)
|
|
107
|
-
|
|
108
|
-
for chunk in backend.generate_completions_stream(
|
|
109
|
-
model="qwen2.5:0.5b",
|
|
110
|
-
messages=[{"role": "user", "content": "Hello!"}],
|
|
111
|
-
response_format={"type": "json_object"}
|
|
112
|
-
):
|
|
113
|
-
print(chunk["delta"], end="", flush=True)
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
### Skill License Validation
|
|
117
|
-
|
|
118
|
-
```python
|
|
119
|
-
from agentnova.skills import validate_spdx_license, parse_compatibility
|
|
120
|
-
|
|
121
|
-
# Validate SPDX license identifier
|
|
122
|
-
valid, msg = validate_spdx_license("MIT") # (True, "Valid SPDX identifier: MIT")
|
|
123
|
-
valid, msg = validate_spdx_license("Custom") # (False, "Unknown license...")
|
|
124
|
-
|
|
125
|
-
# Parse compatibility requirements
|
|
126
|
-
compat = parse_compatibility("python>=3.8, ollama")
|
|
127
|
-
# Returns: {"python": ">=3.8", "runtimes": ["ollama"], "frameworks": []}
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
### Multi-Agent Orchestration
|
|
131
|
-
|
|
132
|
-
```python
|
|
133
|
-
from agentnova import Agent, Orchestrator, AgentCard
|
|
134
|
-
|
|
135
|
-
orchestrator = Orchestrator(mode="router")
|
|
136
|
-
|
|
137
|
-
# Register specialized agents
|
|
138
|
-
orchestrator.register(AgentCard(
|
|
139
|
-
name="math_agent",
|
|
140
|
-
description="Handles mathematical calculations",
|
|
141
|
-
capabilities=["calculate", "math", "compute"],
|
|
142
|
-
tools=["calculator"],
|
|
143
|
-
))
|
|
144
|
-
|
|
145
|
-
orchestrator.register(AgentCard(
|
|
146
|
-
name="file_agent",
|
|
147
|
-
description="Handles file operations",
|
|
148
|
-
capabilities=["read", "write", "file"],
|
|
149
|
-
tools=["read_file", "write_file"],
|
|
150
|
-
))
|
|
151
|
-
|
|
152
|
-
# Route tasks to appropriate agent
|
|
153
|
-
result = orchestrator.run("Calculate 15 * 8 and save to file")
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
## Tool Support Levels
|
|
157
|
-
|
|
158
|
-
AgentNova supports three levels of tool use:
|
|
159
|
-
|
|
160
|
-
1. **Native** — Models with built-in function calling (qwen2.5, llama3.1+, mistral, granite, functiongemma)
|
|
161
|
-
2. **ReAct** — Text-based tool use via reasoning prompts (qwen2.5-coder, qwen3)
|
|
162
|
-
3. **None** — Pure reasoning without tools
|
|
163
|
-
|
|
164
|
-
Tool support is auto-detected by running `agentnova models --tool-support`. Results are cached in `~/.cache/agentnova/tool_support.json`.
|
|
165
|
-
|
|
166
|
-
```bash
|
|
167
|
-
# Test and cache tool support for all models
|
|
168
|
-
agentnova models --tool-support
|
|
169
|
-
|
|
170
|
-
# Re-test (ignore cache)
|
|
171
|
-
agentnova models --tool-support --no-cache
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
You can also force ReAct mode:
|
|
175
|
-
|
|
176
|
-
```python
|
|
177
|
-
agent = Agent(model="qwen2.5:0.5b", force_react=True)
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
## Model Families
|
|
181
|
-
|
|
182
|
-
Configured model families with optimized prompts:
|
|
183
|
-
|
|
184
|
-
- **qwen2.5** — Native tool support, excellent performance
|
|
185
|
-
- **llama3.1/3.2/3.3** — Native tool support
|
|
186
|
-
- **mistral/mixtral** — Native tool support
|
|
187
|
-
- **gemma2/gemma3** — ReAct mode, special prompting
|
|
188
|
-
- **granite/granitemoe** — Native tool support
|
|
189
|
-
- **phi3** — Native tool support
|
|
190
|
-
- **deepseek** — Native with `<think/>` tag handling
|
|
191
|
-
|
|
192
|
-
## Security Features
|
|
193
|
-
|
|
194
|
-
Built-in security for safe operation:
|
|
195
|
-
|
|
196
|
-
- **Command blocklist** — Blocks dangerous shell commands (rm, sudo, etc.)
|
|
197
|
-
- **Path validation** — Prevents access to sensitive directories
|
|
198
|
-
- **SSRF protection** — Blocks requests to local/internal URLs
|
|
199
|
-
- **Injection detection** — Detects shell injection patterns
|
|
200
|
-
|
|
201
|
-
## Configuration
|
|
202
|
-
|
|
203
|
-
Environment variables:
|
|
204
|
-
|
|
205
|
-
```bash
|
|
206
|
-
# Backend URLs
|
|
207
|
-
OLLAMA_BASE_URL=https://your-ollama-server.com # Default: http://localhost:11434
|
|
208
|
-
BITNET_BASE_URL=http://localhost:8765 # BitNet server URL
|
|
209
|
-
BITNET_TUNNEL=https://your-tunnel.com # Alternative BitNet URL
|
|
210
|
-
ACP_BASE_URL=http://localhost:8766 # ACP server URL
|
|
211
|
-
|
|
212
|
-
# Agent settings
|
|
213
|
-
AGENTNOVA_BACKEND=ollama # Default backend: ollama or bitnet
|
|
214
|
-
AGENTNOVA_MODEL=qwen2.5:0.5b # Default model
|
|
215
|
-
AGENTNOVA_MAX_STEPS=10 # Maximum reasoning steps
|
|
216
|
-
AGENTNOVA_DEBUG=false # Enable debug output
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
Check current configuration:
|
|
220
|
-
```bash
|
|
221
|
-
agentnova config
|
|
222
|
-
agentnova config --urls # Show only URLs
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
### CLI Options (run, chat, agent)
|
|
226
|
-
|
|
227
|
-
| Option | Description |
|
|
228
|
-
|--------|-------------|
|
|
229
|
-
| `--api resp\|comp` | API mode: OpenResponses (default) or Chat-Completions |
|
|
230
|
-
| `--response-format text\|json` | Response format (Chat-Completions mode) |
|
|
231
|
-
| `--truncation auto\|disabled` | Truncation behavior for long responses |
|
|
232
|
-
| `--soul <path>` | Load Soul Spec persona package |
|
|
233
|
-
| `--soul-level 1-3` | Progressive disclosure level |
|
|
234
|
-
| `--num-ctx <tokens>` | Context window size (default: 4096) |
|
|
235
|
-
| `--timeout <seconds>` | Request timeout (default: 120) |
|
|
236
|
-
| `--acp` | Enable ACP (Agent Control Panel) logging |
|
|
237
|
-
| `--acp-url <url>` | ACP server URL |
|
|
238
|
-
|
|
239
|
-
## LocalClaw Redirect
|
|
240
|
-
|
|
241
|
-
The `localclaw` command is provided for backward compatibility:
|
|
242
|
-
|
|
243
|
-
```bash
|
|
244
|
-
# Both work identically
|
|
245
|
-
localclaw run "What is 2+2?"
|
|
246
|
-
agentnova run "What is 2+2?"
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
## Tests & Examples
|
|
250
|
-
|
|
251
|
-
AgentNova includes a suite of tests for validating agent capabilities:
|
|
252
|
-
|
|
253
|
-
```bash
|
|
254
|
-
# Basic agent test (no tools)
|
|
255
|
-
python -m agentnova.examples.00_basic_agent
|
|
256
|
-
|
|
257
|
-
# Quick 5-question diagnostic
|
|
258
|
-
python -m agentnova.examples.01_quick_diagnostic
|
|
259
|
-
|
|
260
|
-
# Tool usage tests (calculator, shell, datetime)
|
|
261
|
-
python -m agentnova.examples.02_tool_test
|
|
262
|
-
|
|
263
|
-
# Logic and reasoning tests (BBH-style)
|
|
264
|
-
python -m agentnova.examples.03_reasoning_test
|
|
265
|
-
|
|
266
|
-
# GSM8K math benchmark (50 questions)
|
|
267
|
-
python -m agentnova.examples.04_gsm8k_benchmark
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
### Test Categories
|
|
271
|
-
|
|
272
|
-
| Test | Questions | Focus |
|
|
273
|
-
|------|-----------|-------|
|
|
274
|
-
| Quick Diagnostic | 5 | Calculator tool, multi-step reasoning |
|
|
275
|
-
| Tool Test | 10 | Calculator, shell, datetime tools |
|
|
276
|
-
| Reasoning Test | 13 | Logic, deduction, patterns, spatial |
|
|
277
|
-
| GSM8K Benchmark | 50 | Math word problems |
|
|
278
|
-
|
|
279
|
-
### Benchmark Results (Quick Diagnostic)
|
|
280
|
-
|
|
281
|
-
| Model | Score | Time | Tool Support |
|
|
282
|
-
|-------|-------|------|-------------|
|
|
283
|
-
| functiongemma:270m | 5/5 (100%) | ~20s | native |
|
|
284
|
-
| granite4:350m | 5/5 (100%) | ~50s | native |
|
|
285
|
-
| qwen2.5:0.5b | 5/5 (100%) | 38s | native |
|
|
286
|
-
| qwen2.5-coder:0.5b | 5/5 (100%) | 93s | react |
|
|
287
|
-
| qwen3:0.6b | 5/5 (100%) | 70s | react |
|
|
288
|
-
|
|
289
|
-
All tested models achieve 100% on the Quick Diagnostic. Native models are ~2x faster than ReAct models due to direct API tool calling.
|
|
290
|
-
|
|
291
|
-
## Development
|
|
292
|
-
|
|
293
|
-
```bash
|
|
294
|
-
# Install dev dependencies
|
|
295
|
-
pip install -e ".[dev]"
|
|
296
|
-
|
|
297
|
-
# Run unit tests
|
|
298
|
-
pytest
|
|
299
|
-
|
|
300
|
-
# Format code
|
|
301
|
-
black agentnova
|
|
302
|
-
ruff check agentnova
|
|
303
|
-
```
|
|
304
|
-
|
|
305
|
-
## License
|
|
306
|
-
|
|
307
|
-
MIT License - See LICENSE file for details.
|
|
308
|
-
|
|
309
|
-
## Author
|
|
310
|
-
|
|
311
|
-
**VTSTech** — [https://www.vts-tech.org](https://www.vts-tech.org)
|
|
312
|
-
|
|
313
|
-
## Contributing
|
|
314
|
-
|
|
315
|
-
Contributions welcome! Please read the contributing guidelines first.
|
|
316
|
-
|
|
317
|
-
## Acknowledgments
|
|
318
|
-
|
|
319
|
-
- Built for local inference with [Ollama](https://ollama.ai)
|
|
320
|
-
- Optimized for small, efficient models
|
|
321
|
-
- Inspired by ReAct and other agentic frameworks
|
|
1
|
+
# ⚛️ AgentNova R03.3
|
|
2
|
+
|
|
3
|
+
**Status: Alpha**
|
|
4
|
+
|
|
5
|
+
A minimal, hackable agentic framework engineered to run **entirely locally** with [Ollama](https://ollama.com) or [BitNet](https://github.com/microsoft/BitNet).
|
|
6
|
+
|
|
7
|
+
Inspired by the architecture of OpenClaw, rebuilt from scratch for local-first operation.
|
|
8
|
+
|
|
9
|
+
**Written by [VTSTech](https://www.vts-tech.org)** · [GitHub](https://github.com/VTSTech/AgentNova)
|
|
10
|
+
|
|
11
|
+
[](https://colab.research.google.com/github/VTSTech/AgentNova/blob/main/AgentNova.ipynb)
|
|
12
|
+
[](https://GitHub.com/VTSTech/AgentNova/commit/) [](https://GitHub.com/VTSTech/AgentNova/commit/)
|
|
13
|
+
|
|
14
|
+
[](https://pypi.org/project/agentnova/) [](https://pypi.org/project/agentnova/) [](https://pypi.org/project/agentnova/) [](https://pypi.org/project/agentnova/)
|
|
15
|
+
|
|
16
|
+
[](#license) [](https://python.org)
|
|
17
|
+
|
|
18
|
+
<img width="1400" height="1001" alt="image" src="https://github.com/user-attachments/assets/1bc8fb7a-415b-4750-9ce2-1e721bbf9149" />
|
|
19
|
+
|
|
20
|
+
## 📚 Documentation
|
|
21
|
+
|
|
22
|
+
| Document | Description |
|
|
23
|
+
|----------|-------------|
|
|
24
|
+
| [Architecture.md](https://github.com/VTSTech/AgentNova/blob/main/Architecture.md) | Technical documentation for developers (directory structure, core design, orchestrator modes) |
|
|
25
|
+
| [CHANGELOG.md](https://github.com/VTSTech/AgentNova/blob/main/CHANGELOG.md) | Version history and release notes (includes LocalClaw history) |
|
|
26
|
+
| [TESTS.md](https://github.com/VTSTech/AgentNova/blob/main/TESTS.md) | Benchmark results, model recommendations, and testing guide |
|
|
27
|
+
|
|
28
|
+
## Features
|
|
29
|
+
|
|
30
|
+
- **Zero dependencies** — Uses Python stdlib only (urllib for HTTP)
|
|
31
|
+
- **Ollama + BitNet backends** — Switch with `--backend` flag
|
|
32
|
+
- **Dual API support** — OpenResponses (`--api resp`) and Chat-Completions (`--api comp`)
|
|
33
|
+
- **Three-tier tool support** — Native, ReAct, or none (auto-detected)
|
|
34
|
+
- **Small model optimized** — Fuzzy matching, argument normalization
|
|
35
|
+
- **Built-in security** — Path validation, command blocklist, SSRF protection
|
|
36
|
+
- **Multi-agent orchestration** — Router, pipeline, and parallel modes
|
|
37
|
+
- **Soul Spec v0.5** — Persona packages with progressive disclosure
|
|
38
|
+
- **ACP v1.0.5 integration** — Agent Control Panel for monitoring and control
|
|
39
|
+
- **AgentSkills spec** — Skill loading with SPDX license validation
|
|
40
|
+
|
|
41
|
+
## Installation
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# From source
|
|
45
|
+
git clone https://github.com/VTSTech/AgentNova.git
|
|
46
|
+
cd AgentNova
|
|
47
|
+
pip install -e .
|
|
48
|
+
|
|
49
|
+
# Or from PyPI (when published)
|
|
50
|
+
pip install agentnova
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Quick Start
|
|
54
|
+
|
|
55
|
+
### CLI Usage
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Run a single prompt
|
|
59
|
+
agentnova run "What is 15 * 8?" --tools calculator
|
|
60
|
+
|
|
61
|
+
# Interactive chat
|
|
62
|
+
agentnova chat -m qwen2.5:0.5b --tools calculator,shell
|
|
63
|
+
|
|
64
|
+
# Autonomous agent mode
|
|
65
|
+
agentnova agent -m qwen2.5:7b --tools calculator,shell,write_file
|
|
66
|
+
|
|
67
|
+
# Use Chat-Completions API (OpenAI-compatible)
|
|
68
|
+
agentnova chat -m qwen2.5:0.5b --api comp
|
|
69
|
+
|
|
70
|
+
# List available models
|
|
71
|
+
agentnova models
|
|
72
|
+
|
|
73
|
+
# List available tools
|
|
74
|
+
agentnova tools
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Python API
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
from agentnova import Agent
|
|
81
|
+
from agentnova.tools import make_builtin_registry
|
|
82
|
+
|
|
83
|
+
# Create tools
|
|
84
|
+
tools = make_builtin_registry().subset(["calculator", "shell"])
|
|
85
|
+
|
|
86
|
+
# Create agent
|
|
87
|
+
agent = Agent(
|
|
88
|
+
model="qwen2.5:0.5b",
|
|
89
|
+
tools=tools,
|
|
90
|
+
backend="ollama",
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
# Run
|
|
94
|
+
result = agent.run("What is 15 * 8?")
|
|
95
|
+
print(result.final_answer)
|
|
96
|
+
print(f"Completed in {result.total_ms:.0f}ms")
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Chat-Completions Streaming
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
from agentnova.backends import get_backend
|
|
103
|
+
from agentnova.core.types import ApiMode
|
|
104
|
+
|
|
105
|
+
# Use Chat-Completions mode with streaming
|
|
106
|
+
backend = get_backend("ollama", api_mode=ApiMode.COMPLETIONS)
|
|
107
|
+
|
|
108
|
+
for chunk in backend.generate_completions_stream(
|
|
109
|
+
model="qwen2.5:0.5b",
|
|
110
|
+
messages=[{"role": "user", "content": "Hello!"}],
|
|
111
|
+
response_format={"type": "json_object"}
|
|
112
|
+
):
|
|
113
|
+
print(chunk["delta"], end="", flush=True)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Skill License Validation
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
from agentnova.skills import validate_spdx_license, parse_compatibility
|
|
120
|
+
|
|
121
|
+
# Validate SPDX license identifier
|
|
122
|
+
valid, msg = validate_spdx_license("MIT") # (True, "Valid SPDX identifier: MIT")
|
|
123
|
+
valid, msg = validate_spdx_license("Custom") # (False, "Unknown license...")
|
|
124
|
+
|
|
125
|
+
# Parse compatibility requirements
|
|
126
|
+
compat = parse_compatibility("python>=3.8, ollama")
|
|
127
|
+
# Returns: {"python": ">=3.8", "runtimes": ["ollama"], "frameworks": []}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Multi-Agent Orchestration
|
|
131
|
+
|
|
132
|
+
```python
|
|
133
|
+
from agentnova import Agent, Orchestrator, AgentCard
|
|
134
|
+
|
|
135
|
+
orchestrator = Orchestrator(mode="router")
|
|
136
|
+
|
|
137
|
+
# Register specialized agents
|
|
138
|
+
orchestrator.register(AgentCard(
|
|
139
|
+
name="math_agent",
|
|
140
|
+
description="Handles mathematical calculations",
|
|
141
|
+
capabilities=["calculate", "math", "compute"],
|
|
142
|
+
tools=["calculator"],
|
|
143
|
+
))
|
|
144
|
+
|
|
145
|
+
orchestrator.register(AgentCard(
|
|
146
|
+
name="file_agent",
|
|
147
|
+
description="Handles file operations",
|
|
148
|
+
capabilities=["read", "write", "file"],
|
|
149
|
+
tools=["read_file", "write_file"],
|
|
150
|
+
))
|
|
151
|
+
|
|
152
|
+
# Route tasks to appropriate agent
|
|
153
|
+
result = orchestrator.run("Calculate 15 * 8 and save to file")
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Tool Support Levels
|
|
157
|
+
|
|
158
|
+
AgentNova supports three levels of tool use:
|
|
159
|
+
|
|
160
|
+
1. **Native** — Models with built-in function calling (qwen2.5, llama3.1+, mistral, granite, functiongemma)
|
|
161
|
+
2. **ReAct** — Text-based tool use via reasoning prompts (qwen2.5-coder, qwen3)
|
|
162
|
+
3. **None** — Pure reasoning without tools
|
|
163
|
+
|
|
164
|
+
Tool support is auto-detected by running `agentnova models --tool-support`. Results are cached in `~/.cache/agentnova/tool_support.json`.
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
# Test and cache tool support for all models
|
|
168
|
+
agentnova models --tool-support
|
|
169
|
+
|
|
170
|
+
# Re-test (ignore cache)
|
|
171
|
+
agentnova models --tool-support --no-cache
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
You can also force ReAct mode:
|
|
175
|
+
|
|
176
|
+
```python
|
|
177
|
+
agent = Agent(model="qwen2.5:0.5b", force_react=True)
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Model Families
|
|
181
|
+
|
|
182
|
+
Configured model families with optimized prompts:
|
|
183
|
+
|
|
184
|
+
- **qwen2.5** — Native tool support, excellent performance
|
|
185
|
+
- **llama3.1/3.2/3.3** — Native tool support
|
|
186
|
+
- **mistral/mixtral** — Native tool support
|
|
187
|
+
- **gemma2/gemma3** — ReAct mode, special prompting
|
|
188
|
+
- **granite/granitemoe** — Native tool support
|
|
189
|
+
- **phi3** — Native tool support
|
|
190
|
+
- **deepseek** — Native with `<think/>` tag handling
|
|
191
|
+
|
|
192
|
+
## Security Features
|
|
193
|
+
|
|
194
|
+
Built-in security for safe operation:
|
|
195
|
+
|
|
196
|
+
- **Command blocklist** — Blocks dangerous shell commands (rm, sudo, etc.)
|
|
197
|
+
- **Path validation** — Prevents access to sensitive directories
|
|
198
|
+
- **SSRF protection** — Blocks requests to local/internal URLs
|
|
199
|
+
- **Injection detection** — Detects shell injection patterns
|
|
200
|
+
|
|
201
|
+
## Configuration
|
|
202
|
+
|
|
203
|
+
Environment variables:
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
# Backend URLs
|
|
207
|
+
OLLAMA_BASE_URL=https://your-ollama-server.com # Default: http://localhost:11434
|
|
208
|
+
BITNET_BASE_URL=http://localhost:8765 # BitNet server URL
|
|
209
|
+
BITNET_TUNNEL=https://your-tunnel.com # Alternative BitNet URL
|
|
210
|
+
ACP_BASE_URL=http://localhost:8766 # ACP server URL
|
|
211
|
+
|
|
212
|
+
# Agent settings
|
|
213
|
+
AGENTNOVA_BACKEND=ollama # Default backend: ollama or bitnet
|
|
214
|
+
AGENTNOVA_MODEL=qwen2.5:0.5b # Default model
|
|
215
|
+
AGENTNOVA_MAX_STEPS=10 # Maximum reasoning steps
|
|
216
|
+
AGENTNOVA_DEBUG=false # Enable debug output
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Check current configuration:
|
|
220
|
+
```bash
|
|
221
|
+
agentnova config
|
|
222
|
+
agentnova config --urls # Show only URLs
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### CLI Options (run, chat, agent)
|
|
226
|
+
|
|
227
|
+
| Option | Description |
|
|
228
|
+
|--------|-------------|
|
|
229
|
+
| `--api resp\|comp` | API mode: OpenResponses (default) or Chat-Completions |
|
|
230
|
+
| `--response-format text\|json` | Response format (Chat-Completions mode) |
|
|
231
|
+
| `--truncation auto\|disabled` | Truncation behavior for long responses |
|
|
232
|
+
| `--soul <path>` | Load Soul Spec persona package |
|
|
233
|
+
| `--soul-level 1-3` | Progressive disclosure level |
|
|
234
|
+
| `--num-ctx <tokens>` | Context window size (default: 4096) |
|
|
235
|
+
| `--timeout <seconds>` | Request timeout (default: 120) |
|
|
236
|
+
| `--acp` | Enable ACP (Agent Control Panel) logging |
|
|
237
|
+
| `--acp-url <url>` | ACP server URL |
|
|
238
|
+
|
|
239
|
+
## LocalClaw Redirect
|
|
240
|
+
|
|
241
|
+
The `localclaw` command is provided for backward compatibility:
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
# Both work identically
|
|
245
|
+
localclaw run "What is 2+2?"
|
|
246
|
+
agentnova run "What is 2+2?"
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Tests & Examples
|
|
250
|
+
|
|
251
|
+
AgentNova includes a suite of tests for validating agent capabilities:
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
# Basic agent test (no tools)
|
|
255
|
+
python -m agentnova.examples.00_basic_agent
|
|
256
|
+
|
|
257
|
+
# Quick 5-question diagnostic
|
|
258
|
+
python -m agentnova.examples.01_quick_diagnostic
|
|
259
|
+
|
|
260
|
+
# Tool usage tests (calculator, shell, datetime)
|
|
261
|
+
python -m agentnova.examples.02_tool_test
|
|
262
|
+
|
|
263
|
+
# Logic and reasoning tests (BBH-style)
|
|
264
|
+
python -m agentnova.examples.03_reasoning_test
|
|
265
|
+
|
|
266
|
+
# GSM8K math benchmark (50 questions)
|
|
267
|
+
python -m agentnova.examples.04_gsm8k_benchmark
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Test Categories
|
|
271
|
+
|
|
272
|
+
| Test | Questions | Focus |
|
|
273
|
+
|------|-----------|-------|
|
|
274
|
+
| Quick Diagnostic | 5 | Calculator tool, multi-step reasoning |
|
|
275
|
+
| Tool Test | 10 | Calculator, shell, datetime tools |
|
|
276
|
+
| Reasoning Test | 13 | Logic, deduction, patterns, spatial |
|
|
277
|
+
| GSM8K Benchmark | 50 | Math word problems |
|
|
278
|
+
|
|
279
|
+
### Benchmark Results (Quick Diagnostic)
|
|
280
|
+
|
|
281
|
+
| Model | Score | Time | Tool Support |
|
|
282
|
+
|-------|-------|------|-------------|
|
|
283
|
+
| functiongemma:270m | 5/5 (100%) | ~20s | native |
|
|
284
|
+
| granite4:350m | 5/5 (100%) | ~50s | native |
|
|
285
|
+
| qwen2.5:0.5b | 5/5 (100%) | 38s | native |
|
|
286
|
+
| qwen2.5-coder:0.5b | 5/5 (100%) | 93s | react |
|
|
287
|
+
| qwen3:0.6b | 5/5 (100%) | 70s | react |
|
|
288
|
+
|
|
289
|
+
All tested models achieve 100% on the Quick Diagnostic. Native models are ~2x faster than ReAct models due to direct API tool calling.
|
|
290
|
+
|
|
291
|
+
## Development
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
# Install dev dependencies
|
|
295
|
+
pip install -e ".[dev]"
|
|
296
|
+
|
|
297
|
+
# Run unit tests
|
|
298
|
+
pytest
|
|
299
|
+
|
|
300
|
+
# Format code
|
|
301
|
+
black agentnova
|
|
302
|
+
ruff check agentnova
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
## License
|
|
306
|
+
|
|
307
|
+
MIT License - See LICENSE file for details.
|
|
308
|
+
|
|
309
|
+
## Author
|
|
310
|
+
|
|
311
|
+
**VTSTech** — [https://www.vts-tech.org](https://www.vts-tech.org)
|
|
312
|
+
|
|
313
|
+
## Contributing
|
|
314
|
+
|
|
315
|
+
Contributions welcome! Please read the contributing guidelines first.
|
|
316
|
+
|
|
317
|
+
## Acknowledgments
|
|
318
|
+
|
|
319
|
+
- Built for local inference with [Ollama](https://ollama.ai)
|
|
320
|
+
- Optimized for small, efficient models
|
|
321
|
+
- Inspired by ReAct and other agentic frameworks
|
|
@@ -900,7 +900,15 @@ Final Answer: <the answer>
|
|
|
900
900
|
role = msg.get('role', '?')
|
|
901
901
|
content = msg.get('content', '')
|
|
902
902
|
tc = msg.get('tool_calls', [])
|
|
903
|
-
|
|
903
|
+
tool_call_id = msg.get('tool_call_id', '')
|
|
904
|
+
# Show just length for system prompts, content for others
|
|
905
|
+
if role == 'system':
|
|
906
|
+
content_preview = f"<{len(content)} chars>"
|
|
907
|
+
elif role == 'tool':
|
|
908
|
+
# Show tool message with tool_call_id
|
|
909
|
+
content_preview = f"{content[:100] if content else '(empty)'} (tool_call_id={tool_call_id})"
|
|
910
|
+
else:
|
|
911
|
+
content_preview = content[:200] if content else '(empty)'
|
|
904
912
|
print(f" [MSG {i}] role={role}, content={content_preview!r}{' as tool_calls]' if tc else ']'}")
|
|
905
913
|
print(f" [DEBUG] Tools: {[t.name for t in self.tools.all()] if self.tools else None}")
|
|
906
914
|
|
|
@@ -73,6 +73,48 @@ class OllamaBackend(BaseBackend):
|
|
|
73
73
|
value = ApiMode(value.lower())
|
|
74
74
|
self._api_mode = value
|
|
75
75
|
|
|
76
|
+
def _convert_messages_to_ollama_format(self, messages: list[dict]) -> list[dict]:
|
|
77
|
+
"""
|
|
78
|
+
Convert messages to Ollama native format.
|
|
79
|
+
|
|
80
|
+
Key difference from OpenAI format:
|
|
81
|
+
- OpenAI: tool_calls[].function.arguments is a JSON STRING
|
|
82
|
+
- Ollama: tool_calls[].function.arguments should be an OBJECT
|
|
83
|
+
|
|
84
|
+
This method parses the JSON string arguments back to objects for
|
|
85
|
+
Ollama's native /api/chat endpoint.
|
|
86
|
+
"""
|
|
87
|
+
converted = []
|
|
88
|
+
for msg in messages:
|
|
89
|
+
converted_msg = dict(msg) # Copy the message
|
|
90
|
+
|
|
91
|
+
# Convert tool_calls if present
|
|
92
|
+
if "tool_calls" in msg and msg["tool_calls"]:
|
|
93
|
+
ollama_tool_calls = []
|
|
94
|
+
for tc in msg["tool_calls"]:
|
|
95
|
+
ollama_tc = dict(tc)
|
|
96
|
+
if "function" in tc:
|
|
97
|
+
func = tc["function"]
|
|
98
|
+
args = func.get("arguments", "{}")
|
|
99
|
+
|
|
100
|
+
# Parse JSON string to object for Ollama
|
|
101
|
+
if isinstance(args, str):
|
|
102
|
+
try:
|
|
103
|
+
args = json.loads(args)
|
|
104
|
+
except json.JSONDecodeError:
|
|
105
|
+
args = {}
|
|
106
|
+
|
|
107
|
+
ollama_tc["function"] = {
|
|
108
|
+
"name": func.get("name", ""),
|
|
109
|
+
"arguments": args
|
|
110
|
+
}
|
|
111
|
+
ollama_tool_calls.append(ollama_tc)
|
|
112
|
+
converted_msg["tool_calls"] = ollama_tool_calls
|
|
113
|
+
|
|
114
|
+
converted.append(converted_msg)
|
|
115
|
+
|
|
116
|
+
return converted
|
|
117
|
+
|
|
76
118
|
def generate(
|
|
77
119
|
self,
|
|
78
120
|
model: str,
|
|
@@ -114,10 +156,14 @@ class OllamaBackend(BaseBackend):
|
|
|
114
156
|
|
|
115
157
|
url = f"{self.base_url}/api/chat"
|
|
116
158
|
|
|
159
|
+
# Convert messages to Ollama native format
|
|
160
|
+
# Key difference: Ollama expects tool_call arguments as OBJECT, not JSON string
|
|
161
|
+
ollama_messages = self._convert_messages_to_ollama_format(messages)
|
|
162
|
+
|
|
117
163
|
# Build request body
|
|
118
164
|
body = {
|
|
119
165
|
"model": model,
|
|
120
|
-
"messages":
|
|
166
|
+
"messages": ollama_messages,
|
|
121
167
|
"stream": False,
|
|
122
168
|
"keep_alive": "1m", # Keep model loaded briefly but clear KV cache between requests
|
|
123
169
|
"options": {
|
|
@@ -144,6 +190,18 @@ class OllamaBackend(BaseBackend):
|
|
|
144
190
|
# Debug output for request
|
|
145
191
|
if os.environ.get("AGENTNOVA_DEBUG"):
|
|
146
192
|
print(f" [Ollama] Request: tools={len(tools) if tools else 0}, think={think}")
|
|
193
|
+
# Show messages being sent (truncated for readability)
|
|
194
|
+
for i, msg in enumerate(body.get("messages", [])):
|
|
195
|
+
role = msg.get("role", "?")
|
|
196
|
+
if role == "system":
|
|
197
|
+
print(f" [Ollama.Body] msg[{i}]: role={role}, content=<{len(msg.get('content', ''))} chars>")
|
|
198
|
+
elif role == "tool":
|
|
199
|
+
print(f" [Ollama.Body] msg[{i}]: role={role}, tool_call_id={msg.get('tool_call_id', 'MISSING')!r}, content={msg.get('content', '')[:50]!r}")
|
|
200
|
+
elif "tool_calls" in msg:
|
|
201
|
+
tc = msg.get("tool_calls", [])
|
|
202
|
+
print(f" [Ollama.Body] msg[{i}]: role={role}, tool_calls={tc}")
|
|
203
|
+
else:
|
|
204
|
+
print(f" [Ollama.Body] msg[{i}]: role={role}, content={msg.get('content', '')[:100]!r}")
|
|
147
205
|
|
|
148
206
|
# Make request
|
|
149
207
|
start_time = time.time()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentnova
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.4
|
|
4
4
|
Summary: ⚛️ AgentNova - A minimal, hackable agentic framework for local LLM inference
|
|
5
5
|
Author-email: VTSTech <veritas@vts-tech.org>
|
|
6
6
|
Maintainer-email: VTSTech <veritas@vts-tech.org>
|
|
@@ -49,7 +49,7 @@ Inspired by the architecture of OpenClaw, rebuilt from scratch for local-first o
|
|
|
49
49
|
|
|
50
50
|
[](#license) [](https://python.org)
|
|
51
51
|
|
|
52
|
-
<img width="
|
|
52
|
+
<img width="1400" height="1001" alt="image" src="https://github.com/user-attachments/assets/1bc8fb7a-415b-4750-9ce2-1e721bbf9149" />
|
|
53
53
|
|
|
54
54
|
## 📚 Documentation
|
|
55
55
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentnova-0.3.3 → agentnova-0.3.4}/agentnova/skills/skill-creator/scripts/aggregate_benchmark.py
RENAMED
|
File without changes
|
{agentnova-0.3.3 → agentnova-0.3.4}/agentnova/skills/skill-creator/scripts/generate_report.py
RENAMED
|
File without changes
|
{agentnova-0.3.3 → agentnova-0.3.4}/agentnova/skills/skill-creator/scripts/improve_description.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentnova-0.3.3 → agentnova-0.3.4}/agentnova/skills/skill-creator/scripts/quick_validate.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentnova-0.3.3 → agentnova-0.3.4}/agentnova/skills/skill-creator/scripts/test_package_skill.py
RENAMED
|
File without changes
|
{agentnova-0.3.3 → agentnova-0.3.4}/agentnova/skills/skill-creator/scripts/test_quick_validate.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|