trajectorykit 0.1.0__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.
- trajectorykit-0.1.0/LICENSE +21 -0
- trajectorykit-0.1.0/PKG-INFO +246 -0
- trajectorykit-0.1.0/README.md +210 -0
- trajectorykit-0.1.0/pyproject.toml +52 -0
- trajectorykit-0.1.0/setup.cfg +4 -0
- trajectorykit-0.1.0/src/trajectorykit/README.md +210 -0
- trajectorykit-0.1.0/src/trajectorykit/__init__.py +9 -0
- trajectorykit-0.1.0/src/trajectorykit/agent.py +213 -0
- trajectorykit-0.1.0/src/trajectorykit/config.py +48 -0
- trajectorykit-0.1.0/src/trajectorykit/examples.py +157 -0
- trajectorykit-0.1.0/src/trajectorykit/tool_store.py +612 -0
- trajectorykit-0.1.0/src/trajectorykit/tracing.py +597 -0
- trajectorykit-0.1.0/src/trajectorykit/utils.py +93 -0
- trajectorykit-0.1.0/src/trajectorykit.egg-info/PKG-INFO +246 -0
- trajectorykit-0.1.0/src/trajectorykit.egg-info/SOURCES.txt +16 -0
- trajectorykit-0.1.0/src/trajectorykit.egg-info/dependency_links.txt +1 -0
- trajectorykit-0.1.0/src/trajectorykit.egg-info/requires.txt +15 -0
- trajectorykit-0.1.0/src/trajectorykit.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 William Lugoloobi
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: trajectorykit
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A lightweight, local-first agentic framework with tool calling, recursive sub-agents, and full execution tracing.
|
|
5
|
+
Author: William Lugoloobi
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/KabakaWilliam/trajectorykit
|
|
8
|
+
Project-URL: Repository, https://github.com/KabakaWilliam/trajectorykit
|
|
9
|
+
Project-URL: Issues, https://github.com/KabakaWilliam/trajectorykit/issues
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: requests
|
|
23
|
+
Requires-Dist: python-dotenv
|
|
24
|
+
Provides-Extra: serve
|
|
25
|
+
Requires-Dist: vllm>=0.15; extra == "serve"
|
|
26
|
+
Requires-Dist: torch>=2.9; extra == "serve"
|
|
27
|
+
Requires-Dist: transformers; extra == "serve"
|
|
28
|
+
Provides-Extra: all
|
|
29
|
+
Requires-Dist: vllm>=0.15; extra == "all"
|
|
30
|
+
Requires-Dist: torch>=2.9; extra == "all"
|
|
31
|
+
Requires-Dist: transformers; extra == "all"
|
|
32
|
+
Requires-Dist: matplotlib; extra == "all"
|
|
33
|
+
Requires-Dist: openai>=2.0; extra == "all"
|
|
34
|
+
Requires-Dist: pydantic; extra == "all"
|
|
35
|
+
Dynamic: license-file
|
|
36
|
+
|
|
37
|
+
# 🤖 TrajectoryKit: An Agent Starter Pack
|
|
38
|
+
|
|
39
|
+
> A lightweight, local-first agentic framework for HuggingFace models with built-in tool calling, recursive sub-agents, and full execution tracing.
|
|
40
|
+
|
|
41
|
+
[](LICENSE)
|
|
42
|
+
[](https://www.python.org/downloads/)
|
|
43
|
+
|
|
44
|
+
## 🏎💨 Quickstart
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
from trajectorykit import dispatch
|
|
48
|
+
|
|
49
|
+
result = dispatch(
|
|
50
|
+
user_input="Compare the stats of Blue Eyes White Dragon vs Dark Magician",
|
|
51
|
+
turn_length=5,
|
|
52
|
+
verbose=True
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
print(result["final_response"])
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
The agent writes and executes code in a sandbox, returning results with inline images:
|
|
59
|
+
|
|
60
|
+
<p align="center">
|
|
61
|
+
<img src="../../docs/trace_example.png" width="500" alt="Yu-Gi-Oh Card Stats Comparison">
|
|
62
|
+
</p>
|
|
63
|
+
|
|
64
|
+
## ✨ Features
|
|
65
|
+
|
|
66
|
+
- 🏠 **100% Local** — runs on your own GPU via vLLM, no API keys needed
|
|
67
|
+
- 🔄 **Agentic Loop** — iterative tool calling until the task is done
|
|
68
|
+
- 🤖 **Recursive Sub-Agents** — spawn child agents to decompose complex tasks (up to 3 levels deep)
|
|
69
|
+
- 💻 **Sandboxed Code Execution** — run Python (and 40+ languages) in an Apptainer sandbox with file I/O
|
|
70
|
+
- 🔍 **Web Search** — built-in Google search via SerpAPI
|
|
71
|
+
- 📊 **Full Execution Tracing** — every turn, tool call, token count, and sub-agent is recorded
|
|
72
|
+
- 🌐 **HTML Trace Viewer** — self-contained dark-themed trace pages with collapsible reasoning, inline images, and token stats
|
|
73
|
+
|
|
74
|
+
## 📦 Package Structure
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
src/trajectorykit/
|
|
78
|
+
├── __init__.py # Public API: dispatch, EpisodeTrace, render_trace_html, render_trace_file
|
|
79
|
+
├── config.py # Model, API URL, traces directory, system prompt
|
|
80
|
+
├── agent.py # Core agentic loop with tool dispatch and trace building
|
|
81
|
+
├── tool_store.py # Tool definitions + wrapper functions
|
|
82
|
+
├── tracing.py # Dataclasses, pretty-print, JSON/HTML serialization
|
|
83
|
+
├── examples.py # Ready-to-run examples
|
|
84
|
+
└── serve_vllm.sh # Script to launch vLLM server
|
|
85
|
+
traces/ # Auto-created directory for saved traces (JSON + HTML)
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## 🛠 Built-in Tools
|
|
89
|
+
|
|
90
|
+
| Tool | Description |
|
|
91
|
+
|------|-------------|
|
|
92
|
+
| `execute_code` | Run code in a sandboxed Apptainer container. Supports file upload (`files`) and retrieval (`fetch_files`) as base64. |
|
|
93
|
+
| `search_web` | Google search via SerpAPI. Returns titles, snippets, and links. |
|
|
94
|
+
| `get_current_time` | Returns the current date and time. |
|
|
95
|
+
| `add_numbers` | Adds two numbers (demo tool). |
|
|
96
|
+
| `spawn_agent` | Spawns a recursive sub-agent with its own tool access and trace. |
|
|
97
|
+
|
|
98
|
+
## 🔁 Recursive Sub-Agents
|
|
99
|
+
|
|
100
|
+
Dispatch can spawn child agents to handle subtasks independently. Each sub-agent runs its own agentic loop with full tool access and produces its own trace, nested inside the parent's trace tree.
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
from trajectorykit import dispatch
|
|
104
|
+
|
|
105
|
+
result = dispatch(
|
|
106
|
+
user_input=(
|
|
107
|
+
"How has the market price of the card 'Blue-Eyes White Dragon' moved over the last years?"
|
|
108
|
+
),
|
|
109
|
+
turn_length=5,
|
|
110
|
+
max_tokens=4096
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
result["trace"].pretty_print()
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Max recursion depth is controlled by `MAX_RECURSION_DEPTH` in `config.py` (default: 3).
|
|
117
|
+
|
|
118
|
+
## 📜 Tracing
|
|
119
|
+
|
|
120
|
+
Every `dispatch()` call returns a full execution trace in `result["trace"]`.
|
|
121
|
+
|
|
122
|
+
### Pretty-print to terminal
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
result["trace"].pretty_print()
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
🏁 Agent [root] trace_id=154b9f2e
|
|
130
|
+
Input: What is the current time? What is 123 + 456?
|
|
131
|
+
Duration: 8.42s | Turns: 2 | Tool calls: 2
|
|
132
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
133
|
+
┌─ Turn 1 (4.00s)
|
|
134
|
+
│ 🔧 get_current_time({}) [0.01s]
|
|
135
|
+
│ → 2026-02-19 21:04:29
|
|
136
|
+
│ 🔧 add_numbers({"a": 123, "b": 456}) [0.00s]
|
|
137
|
+
│ → 579
|
|
138
|
+
└─
|
|
139
|
+
...
|
|
140
|
+
📊 Episode Summary:
|
|
141
|
+
Prompt tokens: 3,621
|
|
142
|
+
Completion tokens: 686
|
|
143
|
+
Total tokens: 4,307
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Save to disk
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
path = result["trace"].save()
|
|
150
|
+
# Writes traces/trace_20260219_210429_154b9f2e.json
|
|
151
|
+
# Also writes traces/trace_20260219_210429_154b9f2e.html
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Traces are saved to the `traces/` directory automatically.
|
|
155
|
+
|
|
156
|
+
### HTML trace viewer
|
|
157
|
+
|
|
158
|
+
The HTML file is a self-contained dark-themed page with:
|
|
159
|
+
- **Prompt** at the top (always visible)
|
|
160
|
+
- **Stats bar** — duration, turns, tool calls, sub-agents, total tokens (prompt + completion)
|
|
161
|
+
- **Collapsible trace detail** — starts collapsed, expand to drill into turns
|
|
162
|
+
- **Reasoning dropdowns** — model chain-of-thought shown per turn
|
|
163
|
+
- **Inline images** — plots and generated images rendered directly
|
|
164
|
+
- **Final response** at the bottom (always visible)
|
|
165
|
+
|
|
166
|
+
You can also render any trace JSON to HTML:
|
|
167
|
+
|
|
168
|
+
```python
|
|
169
|
+
from trajectorykit import render_trace_file
|
|
170
|
+
|
|
171
|
+
render_trace_file("traces/trace_20260219_210429_154b9f2e.json")
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## ⚙️ Configuration
|
|
175
|
+
|
|
176
|
+
All settings live in `config.py`:
|
|
177
|
+
|
|
178
|
+
| Setting | Default | Description |
|
|
179
|
+
|---------|---------|-------------|
|
|
180
|
+
| `MODEL_NAME` | `Qwen/Qwen3-8B` | HuggingFace model served by vLLM |
|
|
181
|
+
| `VLLM_API_URL` | `http://localhost:3030/v1` | vLLM OpenAI-compatible endpoint |
|
|
182
|
+
| `MAX_RECURSION_DEPTH` | `3` | Max sub-agent nesting depth |
|
|
183
|
+
| `TRACES_DIR` | `<repo_root>/traces/` | Where `.json` and `.html` traces are saved |
|
|
184
|
+
|
|
185
|
+
## 🚀 Running
|
|
186
|
+
|
|
187
|
+
### 1. Install conda env
|
|
188
|
+
```bash
|
|
189
|
+
conda env create -f environment. yml.
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### 2. Start the Apptainer sandbox (code execution)
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
bash src/trajectorykit/apptainer.sh
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
This pulls and runs the [SandboxFusion](https://github.com/volcengine/sandbox-fusion) container, exposing a code execution API on `http://localhost:8080`.
|
|
199
|
+
|
|
200
|
+
### 3. Start vLLM
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
bash src/trajectorykit/serve_vllm.sh
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### 4. Run an example
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
cd src && python -m trajectorykit.examples
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### API
|
|
213
|
+
|
|
214
|
+
```python
|
|
215
|
+
result = dispatch(
|
|
216
|
+
user_input="Your task here",
|
|
217
|
+
turn_length=5, # Max turns (None = unlimited)
|
|
218
|
+
verbose=True, # Print turn-by-turn output
|
|
219
|
+
max_tokens=2000, # Max tokens per generation
|
|
220
|
+
temperature=0.7, # Sampling temperature
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
# result keys:
|
|
224
|
+
result["final_response"] # str — the model's final answer
|
|
225
|
+
result["turns"] # int — number of turns taken
|
|
226
|
+
result["tool_calls"] # int — total tool calls made
|
|
227
|
+
result["messages"] # list — full conversation history
|
|
228
|
+
result["trace"] # EpisodeTrace — full execution tree
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## 📚 Citation
|
|
232
|
+
|
|
233
|
+
If you use TrajectoryKit in your research or project, please cite it:
|
|
234
|
+
|
|
235
|
+
```bibtex
|
|
236
|
+
@software{trajectorykit2026,
|
|
237
|
+
title={TrajectoryKit: An Agent Starter Pack},
|
|
238
|
+
author={Lugoloobi, William},
|
|
239
|
+
year={2026},
|
|
240
|
+
url={https://github.com/KabakaWilliam/TrajectoryKit}
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### License
|
|
245
|
+
|
|
246
|
+
MIT
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# 🤖 TrajectoryKit: An Agent Starter Pack
|
|
2
|
+
|
|
3
|
+
> A lightweight, local-first agentic framework for HuggingFace models with built-in tool calling, recursive sub-agents, and full execution tracing.
|
|
4
|
+
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](https://www.python.org/downloads/)
|
|
7
|
+
|
|
8
|
+
## 🏎💨 Quickstart
|
|
9
|
+
|
|
10
|
+
```python
|
|
11
|
+
from trajectorykit import dispatch
|
|
12
|
+
|
|
13
|
+
result = dispatch(
|
|
14
|
+
user_input="Compare the stats of Blue Eyes White Dragon vs Dark Magician",
|
|
15
|
+
turn_length=5,
|
|
16
|
+
verbose=True
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
print(result["final_response"])
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The agent writes and executes code in a sandbox, returning results with inline images:
|
|
23
|
+
|
|
24
|
+
<p align="center">
|
|
25
|
+
<img src="docs/trace_example.png" width="500" alt="Yu-Gi-Oh Card Stats Comparison">
|
|
26
|
+
</p>
|
|
27
|
+
|
|
28
|
+
## ✨ Features
|
|
29
|
+
|
|
30
|
+
- 🏠 **100% Local** — runs on your own GPU via vLLM, no API keys needed
|
|
31
|
+
- 🔄 **Agentic Loop** — iterative tool calling until the task is done
|
|
32
|
+
- 🤖 **Recursive Sub-Agents** — spawn child agents to decompose complex tasks (up to 3 levels deep)
|
|
33
|
+
- 💻 **Sandboxed Code Execution** — run Python (and 40+ languages) in an Apptainer sandbox with file I/O
|
|
34
|
+
- 🔍 **Web Search** — built-in Google search via SerpAPI
|
|
35
|
+
- 📊 **Full Execution Tracing** — every turn, tool call, token count, and sub-agent is recorded
|
|
36
|
+
- 🌐 **HTML Trace Viewer** — self-contained dark-themed trace pages with collapsible reasoning, inline images, and token stats
|
|
37
|
+
|
|
38
|
+
## 📦 Package Structure
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
src/trajectorykit/
|
|
42
|
+
├── __init__.py # Public API: dispatch, EpisodeTrace, render_trace_html, render_trace_file
|
|
43
|
+
├── config.py # Model, API URL, traces directory, system prompt
|
|
44
|
+
├── agent.py # Core agentic loop with tool dispatch and trace building
|
|
45
|
+
├── tool_store.py # Tool definitions + wrapper functions
|
|
46
|
+
├── tracing.py # Dataclasses, pretty-print, JSON/HTML serialization
|
|
47
|
+
├── examples.py # Ready-to-run examples
|
|
48
|
+
└── serve_vllm.sh # Script to launch vLLM server
|
|
49
|
+
traces/ # Auto-created directory for saved traces (JSON + HTML)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## 🛠 Built-in Tools
|
|
53
|
+
|
|
54
|
+
| Tool | Description |
|
|
55
|
+
|------|-------------|
|
|
56
|
+
| `execute_code` | Run code in a sandboxed Apptainer container. Supports file upload (`files`) and retrieval (`fetch_files`) as base64. |
|
|
57
|
+
| `search_web` | Google search via SerpAPI. Returns titles, snippets, and links. |
|
|
58
|
+
| `get_current_time` | Returns the current date and time. |
|
|
59
|
+
| `add_numbers` | Adds two numbers (demo tool). |
|
|
60
|
+
| `spawn_agent` | Spawns a recursive sub-agent with its own tool access and trace. |
|
|
61
|
+
|
|
62
|
+
## 🔁 Recursive Sub-Agents
|
|
63
|
+
|
|
64
|
+
Dispatch can spawn child agents to handle subtasks independently. Each sub-agent runs its own agentic loop with full tool access and produces its own trace, nested inside the parent's trace tree.
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
from trajectorykit import dispatch
|
|
68
|
+
|
|
69
|
+
result = dispatch(
|
|
70
|
+
user_input=(
|
|
71
|
+
"How has the market price of the card 'Blue-Eyes White Dragon' moved over the last years?"
|
|
72
|
+
),
|
|
73
|
+
turn_length=5,
|
|
74
|
+
max_tokens=4096
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
result["trace"].pretty_print()
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Max recursion depth is controlled by `MAX_RECURSION_DEPTH` in `config.py` (default: 3).
|
|
81
|
+
|
|
82
|
+
## 📜 Tracing
|
|
83
|
+
|
|
84
|
+
Every `dispatch()` call returns a full execution trace in `result["trace"]`.
|
|
85
|
+
|
|
86
|
+
### Pretty-print to terminal
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
result["trace"].pretty_print()
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
🏁 Agent [root] trace_id=154b9f2e
|
|
94
|
+
Input: What is the current time? What is 123 + 456?
|
|
95
|
+
Duration: 8.42s | Turns: 2 | Tool calls: 2
|
|
96
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
97
|
+
┌─ Turn 1 (4.00s)
|
|
98
|
+
│ 🔧 get_current_time({}) [0.01s]
|
|
99
|
+
│ → 2026-02-19 21:04:29
|
|
100
|
+
│ 🔧 add_numbers({"a": 123, "b": 456}) [0.00s]
|
|
101
|
+
│ → 579
|
|
102
|
+
└─
|
|
103
|
+
...
|
|
104
|
+
📊 Episode Summary:
|
|
105
|
+
Prompt tokens: 3,621
|
|
106
|
+
Completion tokens: 686
|
|
107
|
+
Total tokens: 4,307
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Save to disk
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
path = result["trace"].save()
|
|
114
|
+
# Writes traces/trace_20260219_210429_154b9f2e.json
|
|
115
|
+
# Also writes traces/trace_20260219_210429_154b9f2e.html
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Traces are saved to the `traces/` directory automatically.
|
|
119
|
+
|
|
120
|
+
### HTML trace viewer
|
|
121
|
+
|
|
122
|
+
The HTML file is a self-contained dark-themed page with:
|
|
123
|
+
- **Prompt** at the top (always visible)
|
|
124
|
+
- **Stats bar** — duration, turns, tool calls, sub-agents, total tokens (prompt + completion)
|
|
125
|
+
- **Collapsible trace detail** — starts collapsed, expand to drill into turns
|
|
126
|
+
- **Reasoning dropdowns** — model chain-of-thought shown per turn
|
|
127
|
+
- **Inline images** — plots and generated images rendered directly
|
|
128
|
+
- **Final response** at the bottom (always visible)
|
|
129
|
+
|
|
130
|
+
You can also render any trace JSON to HTML:
|
|
131
|
+
|
|
132
|
+
```python
|
|
133
|
+
from trajectorykit import render_trace_file
|
|
134
|
+
|
|
135
|
+
render_trace_file("traces/trace_20260219_210429_154b9f2e.json")
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## ⚙️ Configuration
|
|
139
|
+
|
|
140
|
+
All settings live in `config.py`:
|
|
141
|
+
|
|
142
|
+
| Setting | Default | Description |
|
|
143
|
+
|---------|---------|-------------|
|
|
144
|
+
| `MODEL_NAME` | `Qwen/Qwen3-8B` | HuggingFace model served by vLLM |
|
|
145
|
+
| `VLLM_API_URL` | `http://localhost:3030/v1` | vLLM OpenAI-compatible endpoint |
|
|
146
|
+
| `MAX_RECURSION_DEPTH` | `3` | Max sub-agent nesting depth |
|
|
147
|
+
| `TRACES_DIR` | `<repo_root>/traces/` | Where `.json` and `.html` traces are saved |
|
|
148
|
+
|
|
149
|
+
## 🚀 Running
|
|
150
|
+
|
|
151
|
+
### 1. Install conda env
|
|
152
|
+
```bash
|
|
153
|
+
conda env create -f environment. yml.
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### 2. Start the Apptainer sandbox (code execution)
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
bash src/trajectorykit/apptainer.sh
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
This pulls and runs the [SandboxFusion](https://github.com/volcengine/sandbox-fusion) container, exposing a code execution API on `http://localhost:8080`.
|
|
163
|
+
|
|
164
|
+
### 3. Start vLLM
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
bash src/trajectorykit/serve_vllm.sh
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### 4. Run an example
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
cd src && python -m trajectorykit.examples
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### API
|
|
177
|
+
|
|
178
|
+
```python
|
|
179
|
+
result = dispatch(
|
|
180
|
+
user_input="Your task here",
|
|
181
|
+
turn_length=5, # Max turns (None = unlimited)
|
|
182
|
+
verbose=True, # Print turn-by-turn output
|
|
183
|
+
max_tokens=2000, # Max tokens per generation
|
|
184
|
+
temperature=0.7, # Sampling temperature
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
# result keys:
|
|
188
|
+
result["final_response"] # str — the model's final answer
|
|
189
|
+
result["turns"] # int — number of turns taken
|
|
190
|
+
result["tool_calls"] # int — total tool calls made
|
|
191
|
+
result["messages"] # list — full conversation history
|
|
192
|
+
result["trace"] # EpisodeTrace — full execution tree
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## 📚 Citation
|
|
196
|
+
|
|
197
|
+
If you use TrajectoryKit in your research or project, please cite it:
|
|
198
|
+
|
|
199
|
+
```bibtex
|
|
200
|
+
@software{trajectorykit2026,
|
|
201
|
+
title={TrajectoryKit: An Agent Starter Pack},
|
|
202
|
+
author={Lugoloobi, William},
|
|
203
|
+
year={2026},
|
|
204
|
+
url={https://github.com/KabakaWilliam/TrajectoryKit}
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### License
|
|
209
|
+
|
|
210
|
+
MIT
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "trajectorykit"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "A lightweight, local-first agentic framework with tool calling, recursive sub-agents, and full execution tracing."
|
|
9
|
+
readme = "src/trajectorykit/README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "William Lugoloobi" },
|
|
14
|
+
]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 3 - Alpha",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"Intended Audience :: Science/Research",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3.10",
|
|
21
|
+
"Programming Language :: Python :: 3.11",
|
|
22
|
+
"Programming Language :: Python :: 3.12",
|
|
23
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
24
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
25
|
+
]
|
|
26
|
+
dependencies = [
|
|
27
|
+
"requests",
|
|
28
|
+
"python-dotenv",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
[project.urls]
|
|
32
|
+
Homepage = "https://github.com/KabakaWilliam/trajectorykit"
|
|
33
|
+
Repository = "https://github.com/KabakaWilliam/trajectorykit"
|
|
34
|
+
Issues = "https://github.com/KabakaWilliam/trajectorykit/issues"
|
|
35
|
+
|
|
36
|
+
[project.optional-dependencies]
|
|
37
|
+
serve = [
|
|
38
|
+
"vllm>=0.15",
|
|
39
|
+
"torch>=2.9",
|
|
40
|
+
"transformers",
|
|
41
|
+
]
|
|
42
|
+
all = [
|
|
43
|
+
"vllm>=0.15",
|
|
44
|
+
"torch>=2.9",
|
|
45
|
+
"transformers",
|
|
46
|
+
"matplotlib",
|
|
47
|
+
"openai>=2.0",
|
|
48
|
+
"pydantic",
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
[tool.setuptools.packages.find]
|
|
52
|
+
where = ["src"]
|