vortelio 6.0.5__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.
- vortelio-6.0.5/LICENSE +17 -0
- vortelio-6.0.5/MANIFEST.in +3 -0
- vortelio-6.0.5/PKG-INFO +333 -0
- vortelio-6.0.5/README.md +307 -0
- vortelio-6.0.5/pyproject.toml +42 -0
- vortelio-6.0.5/setup.cfg +4 -0
- vortelio-6.0.5/vortelio/__init__.py +30 -0
- vortelio-6.0.5/vortelio/client.py +876 -0
- vortelio-6.0.5/vortelio/py.typed +0 -0
- vortelio-6.0.5/vortelio/setup.py +320 -0
- vortelio-6.0.5/vortelio.egg-info/PKG-INFO +333 -0
- vortelio-6.0.5/vortelio.egg-info/SOURCES.txt +12 -0
- vortelio-6.0.5/vortelio.egg-info/dependency_links.txt +1 -0
- vortelio-6.0.5/vortelio.egg-info/top_level.txt +1 -0
vortelio-6.0.5/LICENSE
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
Copyright 2024 Metiu
|
|
6
|
+
|
|
7
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
you may not use this file except in compliance with the License.
|
|
9
|
+
You may obtain a copy of the License at
|
|
10
|
+
|
|
11
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
|
|
13
|
+
Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
See the License for the specific language governing permissions and
|
|
17
|
+
limitations under the License.
|
vortelio-6.0.5/PKG-INFO
ADDED
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: vortelio
|
|
3
|
+
Version: 6.0.5
|
|
4
|
+
Summary: Python SDK for Vortelio — run AI models locally (LLM, Image, Audio, Video, 3D)
|
|
5
|
+
Author: Metiu
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/vortelio/vortelio
|
|
8
|
+
Project-URL: Repository, https://github.com/vortelio/vortelio
|
|
9
|
+
Project-URL: Bug Tracker, https://github.com/vortelio/vortelio/issues
|
|
10
|
+
Keywords: ai,llm,local,ollama,llama,stable-diffusion,whisper,tts,video
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Requires-Python: >=3.8
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Dynamic: license-file
|
|
26
|
+
|
|
27
|
+
# Vortelio Python SDK
|
|
28
|
+
|
|
29
|
+
[](https://pypi.org/project/vortelio/)
|
|
30
|
+
[](https://www.python.org/)
|
|
31
|
+
[](LICENSE)
|
|
32
|
+
|
|
33
|
+
**Python SDK for [Vortelio](https://github.com/vortelio/vortelio)** — run AI models locally on your machine.
|
|
34
|
+
LLM · Image generation · Speech-to-Text · Text-to-Speech · Video generation · 3D.
|
|
35
|
+
|
|
36
|
+
No cloud. No API keys. Your data never leaves your computer.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Requirements
|
|
41
|
+
|
|
42
|
+
1. Install Vortelio: download `Vortelio-Setup-x.x.x.exe` from the [releases page](https://github.com/vortelio/vortelio/releases)
|
|
43
|
+
2. Start the server: `vortelio serve`
|
|
44
|
+
3. Install the SDK: `pip install vortelio`
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Quick Start
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
from vortelio import Vortelio
|
|
52
|
+
|
|
53
|
+
ai = Vortelio() # connects to vortelio serve on port 11500
|
|
54
|
+
|
|
55
|
+
# Check what's installed
|
|
56
|
+
ai.models()
|
|
57
|
+
|
|
58
|
+
# Download a model
|
|
59
|
+
ai.pull("llm/mistral:7b")
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## LLM — Text Generation
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
# Single message — tokens printed in real time
|
|
68
|
+
reply = ai.chat("llm/mistral:7b", "What is Python?")
|
|
69
|
+
print(reply)
|
|
70
|
+
|
|
71
|
+
# Multi-turn conversation (model remembers history)
|
|
72
|
+
conv = ai.conversation("llm/mistral:7b")
|
|
73
|
+
conv.say("My name is Marco.")
|
|
74
|
+
conv.say("What is my name?") # → "Your name is Marco."
|
|
75
|
+
|
|
76
|
+
# Interactive REPL
|
|
77
|
+
conv.start() # type messages, 'clear' to reset, 'exit' to quit
|
|
78
|
+
|
|
79
|
+
# With chain-of-thought reasoning (Qwen3, DeepSeek-R1, etc.)
|
|
80
|
+
reply = ai.chat("llm/janhq--jan-code-4b-gguf:q3-k-s",
|
|
81
|
+
"Solve: 2x + 5 = 17", think=True)
|
|
82
|
+
|
|
83
|
+
# Custom context window
|
|
84
|
+
reply = ai.chat("llm/mistral:7b", "Very long document...", context_size=32768)
|
|
85
|
+
|
|
86
|
+
# Continue existing conversation
|
|
87
|
+
history = [
|
|
88
|
+
{"role": "user", "content": "My favourite colour is blue."},
|
|
89
|
+
{"role": "assistant", "content": "Got it, blue!"},
|
|
90
|
+
]
|
|
91
|
+
reply = ai.chat("llm/mistral:7b", "What colour do I like?", history=history)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Real-Time Token Streaming
|
|
97
|
+
|
|
98
|
+
Four ways to receive tokens as they are generated, without waiting for the full reply.
|
|
99
|
+
|
|
100
|
+
### `on_token` callback
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
# Collect tokens into a list
|
|
104
|
+
tokens = []
|
|
105
|
+
ai.chat("llm/mistral:7b", "Tell me a joke",
|
|
106
|
+
on_token=lambda t: tokens.append(t))
|
|
107
|
+
reply = "".join(tokens)
|
|
108
|
+
|
|
109
|
+
# Write tokens to a file in real time
|
|
110
|
+
with open("output.txt", "w") as f:
|
|
111
|
+
ai.chat("llm/mistral:7b", "Write a poem",
|
|
112
|
+
on_token=lambda t: f.write(t))
|
|
113
|
+
|
|
114
|
+
# Update a GUI label (e.g. Tkinter, PyQt)
|
|
115
|
+
label_text = ""
|
|
116
|
+
def update_label(token):
|
|
117
|
+
global label_text
|
|
118
|
+
label_text += token
|
|
119
|
+
my_label.config(text=label_text) # Tkinter
|
|
120
|
+
|
|
121
|
+
ai.chat("llm/mistral:7b", "Hello!", on_token=update_label)
|
|
122
|
+
|
|
123
|
+
# Same for Conversation
|
|
124
|
+
conv = ai.conversation("llm/mistral:7b")
|
|
125
|
+
conv.say("Explain recursion", on_token=lambda t: print(t, end="", flush=True))
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### `stream()` generator
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
# Iterate token by token
|
|
132
|
+
for token in ai.stream("llm/mistral:7b", "Tell me a story"):
|
|
133
|
+
print(token, end="", flush=True)
|
|
134
|
+
print()
|
|
135
|
+
|
|
136
|
+
# Works with conversations too
|
|
137
|
+
conv = ai.conversation("llm/mistral:7b")
|
|
138
|
+
for token in conv.stream("What is Python?"):
|
|
139
|
+
print(token, end="", flush=True)
|
|
140
|
+
print()
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Flask — streaming HTTP endpoint
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
from flask import Flask, Response, stream_with_context, request
|
|
147
|
+
from vortelio import Vortelio
|
|
148
|
+
import json
|
|
149
|
+
|
|
150
|
+
app = Flask(__name__)
|
|
151
|
+
ai = Vortelio()
|
|
152
|
+
|
|
153
|
+
@app.route("/chat")
|
|
154
|
+
def chat():
|
|
155
|
+
prompt = request.args.get("q", "Hello!")
|
|
156
|
+
def generate():
|
|
157
|
+
for token in ai.stream("llm/mistral:7b", prompt):
|
|
158
|
+
yield f"data: {json.dumps(token)}\n\n"
|
|
159
|
+
yield "data: [DONE]\n\n"
|
|
160
|
+
return Response(stream_with_context(generate()),
|
|
161
|
+
content_type="text/event-stream")
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### FastAPI — async streaming endpoint
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
from fastapi import FastAPI
|
|
168
|
+
from fastapi.responses import StreamingResponse
|
|
169
|
+
from vortelio import Vortelio
|
|
170
|
+
import asyncio, json
|
|
171
|
+
|
|
172
|
+
app = FastAPI()
|
|
173
|
+
ai = Vortelio()
|
|
174
|
+
|
|
175
|
+
@app.get("/chat")
|
|
176
|
+
async def chat(q: str = "Hello!"):
|
|
177
|
+
loop = asyncio.get_event_loop()
|
|
178
|
+
|
|
179
|
+
def gen():
|
|
180
|
+
for token in ai.stream("llm/mistral:7b", q):
|
|
181
|
+
yield f"data: {json.dumps(token)}\n\n"
|
|
182
|
+
yield "data: [DONE]\n\n"
|
|
183
|
+
|
|
184
|
+
return StreamingResponse(gen(), media_type="text/event-stream")
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Silent mode (no terminal output)
|
|
188
|
+
|
|
189
|
+
```python
|
|
190
|
+
# Suppress output, just return the string
|
|
191
|
+
reply = ai.chat("llm/mistral:7b", "Hello!", silent=True)
|
|
192
|
+
print("Got:", reply)
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## Image Generation
|
|
198
|
+
|
|
199
|
+
```python
|
|
200
|
+
# Generate image from text
|
|
201
|
+
ai.image("image/sdxl", "a purple sunset over the ocean", "sunset.png")
|
|
202
|
+
ai.image("image/flux:schnell", "medieval castle", "castle.png", steps=30)
|
|
203
|
+
ai.image("image/dreamshaper", "portrait of a knight", "knight.png")
|
|
204
|
+
ai.image("image/openjourney", "futuristic city at night", "city.png")
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## Audio — Speech-to-Text (Whisper)
|
|
210
|
+
|
|
211
|
+
```python
|
|
212
|
+
# Transcribe audio to text
|
|
213
|
+
text = ai.transcribe("audio/whisper:large", "meeting.mp3")
|
|
214
|
+
print(text)
|
|
215
|
+
|
|
216
|
+
# Save transcript to file
|
|
217
|
+
ai.transcribe("audio/whisper:base", "recording.wav", save_to="transcript.txt")
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## Audio — Text-to-Speech
|
|
223
|
+
|
|
224
|
+
```python
|
|
225
|
+
ai.speak("audio/kokoro", "Hello! I am Vortelio.", "greeting.wav")
|
|
226
|
+
ai.speak("audio/bark", "Welcome to the future of local AI!", "welcome.wav")
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## Video Generation
|
|
232
|
+
|
|
233
|
+
```python
|
|
234
|
+
ai.video("video/wan:1.3b", "a cat flying through the sky", "cat.mp4")
|
|
235
|
+
ai.video("video/animatediff:v3", "ocean waves on a beach", "ocean.mp4", steps=30)
|
|
236
|
+
ai.video("video/cogvideo:5b", "a horse galloping in a field", "horse.mp4")
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## 3D Model Generation
|
|
242
|
+
|
|
243
|
+
```python
|
|
244
|
+
# From text description
|
|
245
|
+
ai.model3d("3d/shap-e", "chair.ply", description="a wooden chair with four legs")
|
|
246
|
+
|
|
247
|
+
# From image (image → 3D mesh)
|
|
248
|
+
ai.model3d("3d/triposr", "chair.obj", image="photo.jpg")
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## Server Status
|
|
254
|
+
|
|
255
|
+
```python
|
|
256
|
+
info = ai.status()
|
|
257
|
+
print(info["version"]) # "0.3.37"
|
|
258
|
+
print(info["hardware"]) # "CUDA (GPU 0: RTX 3080, 10 GB VRAM)"
|
|
259
|
+
print(info["model_count"])
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
## Download Models
|
|
265
|
+
|
|
266
|
+
```python
|
|
267
|
+
# Download from registry
|
|
268
|
+
ai.pull("llm/mistral:7b")
|
|
269
|
+
ai.pull("image/sdxl:latest")
|
|
270
|
+
ai.pull("audio/whisper:base")
|
|
271
|
+
|
|
272
|
+
# Download with progress callback
|
|
273
|
+
ai.pull("llm/llama3:8b", on_progress=lambda pct, msg: print(f"{pct}% — {msg}"))
|
|
274
|
+
|
|
275
|
+
# Download from HuggingFace directly
|
|
276
|
+
ai.pull("llm/hf.co/unsloth/Qwen2.5-0.5B-Instruct-GGUF:Q4_K_M")
|
|
277
|
+
ai.pull("llm/https://huggingface.co/HumeAI/tada-1b")
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
## Custom Port
|
|
283
|
+
|
|
284
|
+
```python
|
|
285
|
+
ai = Vortelio(port=8080) # if server started with: vortelio serve --port 8080
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## Error Handling
|
|
291
|
+
|
|
292
|
+
```python
|
|
293
|
+
from vortelio import Vortelio
|
|
294
|
+
|
|
295
|
+
ai = Vortelio()
|
|
296
|
+
|
|
297
|
+
try:
|
|
298
|
+
reply = ai.chat("llm/mistral:7b", "Hello!")
|
|
299
|
+
except ConnectionError:
|
|
300
|
+
print("Server not running. Start with: vortelio serve")
|
|
301
|
+
except RuntimeError as e:
|
|
302
|
+
print(f"Generation error: {e}")
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
## Full API Reference
|
|
308
|
+
|
|
309
|
+
| Method | Description |
|
|
310
|
+
|--------|-------------|
|
|
311
|
+
| `ai.status()` | Server status (version, hardware, model count) |
|
|
312
|
+
| `ai.models()` | List installed models |
|
|
313
|
+
| `ai.pull(model, on_progress)` | Download a model |
|
|
314
|
+
| `ai.chat(model, message, *, on_token, silent, think, context_size, history)` | Single LLM message — streams tokens |
|
|
315
|
+
| `ai.stream(model, message, *, think, history)` | **Generator** — yields one token at a time |
|
|
316
|
+
| `ai.conversation(model, system)` | Multi-turn conversation object |
|
|
317
|
+
| `conv.say(message, *, on_token, silent, think)` | Send message in conversation — streams tokens |
|
|
318
|
+
| `conv.stream(message, *, think)` | **Generator** — yields tokens, updates history |
|
|
319
|
+
| `conv.start()` | Interactive terminal REPL |
|
|
320
|
+
| `conv.clear()` | Reset conversation history |
|
|
321
|
+
| `ai.image(model, desc, save_to, steps)` | Generate image |
|
|
322
|
+
| `ai.transcribe(model, audio_file, save_to)` | Speech-to-text |
|
|
323
|
+
| `ai.speak(model, text, save_to)` | Text-to-speech |
|
|
324
|
+
| `ai.video(model, desc, save_to, steps)` | Generate video |
|
|
325
|
+
| `ai.model3d(model, save_to, desc, image)` | Generate 3D mesh |
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
## License
|
|
330
|
+
|
|
331
|
+
Apache 2.0 — see [LICENSE](LICENSE).
|
|
332
|
+
|
|
333
|
+
Made by **Metiu** with ❤️
|
vortelio-6.0.5/README.md
ADDED
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
# Vortelio Python SDK
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/vortelio/)
|
|
4
|
+
[](https://www.python.org/)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
|
|
7
|
+
**Python SDK for [Vortelio](https://github.com/vortelio/vortelio)** — run AI models locally on your machine.
|
|
8
|
+
LLM · Image generation · Speech-to-Text · Text-to-Speech · Video generation · 3D.
|
|
9
|
+
|
|
10
|
+
No cloud. No API keys. Your data never leaves your computer.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Requirements
|
|
15
|
+
|
|
16
|
+
1. Install Vortelio: download `Vortelio-Setup-x.x.x.exe` from the [releases page](https://github.com/vortelio/vortelio/releases)
|
|
17
|
+
2. Start the server: `vortelio serve`
|
|
18
|
+
3. Install the SDK: `pip install vortelio`
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
from vortelio import Vortelio
|
|
26
|
+
|
|
27
|
+
ai = Vortelio() # connects to vortelio serve on port 11500
|
|
28
|
+
|
|
29
|
+
# Check what's installed
|
|
30
|
+
ai.models()
|
|
31
|
+
|
|
32
|
+
# Download a model
|
|
33
|
+
ai.pull("llm/mistral:7b")
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## LLM — Text Generation
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
# Single message — tokens printed in real time
|
|
42
|
+
reply = ai.chat("llm/mistral:7b", "What is Python?")
|
|
43
|
+
print(reply)
|
|
44
|
+
|
|
45
|
+
# Multi-turn conversation (model remembers history)
|
|
46
|
+
conv = ai.conversation("llm/mistral:7b")
|
|
47
|
+
conv.say("My name is Marco.")
|
|
48
|
+
conv.say("What is my name?") # → "Your name is Marco."
|
|
49
|
+
|
|
50
|
+
# Interactive REPL
|
|
51
|
+
conv.start() # type messages, 'clear' to reset, 'exit' to quit
|
|
52
|
+
|
|
53
|
+
# With chain-of-thought reasoning (Qwen3, DeepSeek-R1, etc.)
|
|
54
|
+
reply = ai.chat("llm/janhq--jan-code-4b-gguf:q3-k-s",
|
|
55
|
+
"Solve: 2x + 5 = 17", think=True)
|
|
56
|
+
|
|
57
|
+
# Custom context window
|
|
58
|
+
reply = ai.chat("llm/mistral:7b", "Very long document...", context_size=32768)
|
|
59
|
+
|
|
60
|
+
# Continue existing conversation
|
|
61
|
+
history = [
|
|
62
|
+
{"role": "user", "content": "My favourite colour is blue."},
|
|
63
|
+
{"role": "assistant", "content": "Got it, blue!"},
|
|
64
|
+
]
|
|
65
|
+
reply = ai.chat("llm/mistral:7b", "What colour do I like?", history=history)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Real-Time Token Streaming
|
|
71
|
+
|
|
72
|
+
Four ways to receive tokens as they are generated, without waiting for the full reply.
|
|
73
|
+
|
|
74
|
+
### `on_token` callback
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
# Collect tokens into a list
|
|
78
|
+
tokens = []
|
|
79
|
+
ai.chat("llm/mistral:7b", "Tell me a joke",
|
|
80
|
+
on_token=lambda t: tokens.append(t))
|
|
81
|
+
reply = "".join(tokens)
|
|
82
|
+
|
|
83
|
+
# Write tokens to a file in real time
|
|
84
|
+
with open("output.txt", "w") as f:
|
|
85
|
+
ai.chat("llm/mistral:7b", "Write a poem",
|
|
86
|
+
on_token=lambda t: f.write(t))
|
|
87
|
+
|
|
88
|
+
# Update a GUI label (e.g. Tkinter, PyQt)
|
|
89
|
+
label_text = ""
|
|
90
|
+
def update_label(token):
|
|
91
|
+
global label_text
|
|
92
|
+
label_text += token
|
|
93
|
+
my_label.config(text=label_text) # Tkinter
|
|
94
|
+
|
|
95
|
+
ai.chat("llm/mistral:7b", "Hello!", on_token=update_label)
|
|
96
|
+
|
|
97
|
+
# Same for Conversation
|
|
98
|
+
conv = ai.conversation("llm/mistral:7b")
|
|
99
|
+
conv.say("Explain recursion", on_token=lambda t: print(t, end="", flush=True))
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### `stream()` generator
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
# Iterate token by token
|
|
106
|
+
for token in ai.stream("llm/mistral:7b", "Tell me a story"):
|
|
107
|
+
print(token, end="", flush=True)
|
|
108
|
+
print()
|
|
109
|
+
|
|
110
|
+
# Works with conversations too
|
|
111
|
+
conv = ai.conversation("llm/mistral:7b")
|
|
112
|
+
for token in conv.stream("What is Python?"):
|
|
113
|
+
print(token, end="", flush=True)
|
|
114
|
+
print()
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Flask — streaming HTTP endpoint
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
from flask import Flask, Response, stream_with_context, request
|
|
121
|
+
from vortelio import Vortelio
|
|
122
|
+
import json
|
|
123
|
+
|
|
124
|
+
app = Flask(__name__)
|
|
125
|
+
ai = Vortelio()
|
|
126
|
+
|
|
127
|
+
@app.route("/chat")
|
|
128
|
+
def chat():
|
|
129
|
+
prompt = request.args.get("q", "Hello!")
|
|
130
|
+
def generate():
|
|
131
|
+
for token in ai.stream("llm/mistral:7b", prompt):
|
|
132
|
+
yield f"data: {json.dumps(token)}\n\n"
|
|
133
|
+
yield "data: [DONE]\n\n"
|
|
134
|
+
return Response(stream_with_context(generate()),
|
|
135
|
+
content_type="text/event-stream")
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### FastAPI — async streaming endpoint
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
from fastapi import FastAPI
|
|
142
|
+
from fastapi.responses import StreamingResponse
|
|
143
|
+
from vortelio import Vortelio
|
|
144
|
+
import asyncio, json
|
|
145
|
+
|
|
146
|
+
app = FastAPI()
|
|
147
|
+
ai = Vortelio()
|
|
148
|
+
|
|
149
|
+
@app.get("/chat")
|
|
150
|
+
async def chat(q: str = "Hello!"):
|
|
151
|
+
loop = asyncio.get_event_loop()
|
|
152
|
+
|
|
153
|
+
def gen():
|
|
154
|
+
for token in ai.stream("llm/mistral:7b", q):
|
|
155
|
+
yield f"data: {json.dumps(token)}\n\n"
|
|
156
|
+
yield "data: [DONE]\n\n"
|
|
157
|
+
|
|
158
|
+
return StreamingResponse(gen(), media_type="text/event-stream")
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Silent mode (no terminal output)
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
# Suppress output, just return the string
|
|
165
|
+
reply = ai.chat("llm/mistral:7b", "Hello!", silent=True)
|
|
166
|
+
print("Got:", reply)
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Image Generation
|
|
172
|
+
|
|
173
|
+
```python
|
|
174
|
+
# Generate image from text
|
|
175
|
+
ai.image("image/sdxl", "a purple sunset over the ocean", "sunset.png")
|
|
176
|
+
ai.image("image/flux:schnell", "medieval castle", "castle.png", steps=30)
|
|
177
|
+
ai.image("image/dreamshaper", "portrait of a knight", "knight.png")
|
|
178
|
+
ai.image("image/openjourney", "futuristic city at night", "city.png")
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Audio — Speech-to-Text (Whisper)
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
# Transcribe audio to text
|
|
187
|
+
text = ai.transcribe("audio/whisper:large", "meeting.mp3")
|
|
188
|
+
print(text)
|
|
189
|
+
|
|
190
|
+
# Save transcript to file
|
|
191
|
+
ai.transcribe("audio/whisper:base", "recording.wav", save_to="transcript.txt")
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## Audio — Text-to-Speech
|
|
197
|
+
|
|
198
|
+
```python
|
|
199
|
+
ai.speak("audio/kokoro", "Hello! I am Vortelio.", "greeting.wav")
|
|
200
|
+
ai.speak("audio/bark", "Welcome to the future of local AI!", "welcome.wav")
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## Video Generation
|
|
206
|
+
|
|
207
|
+
```python
|
|
208
|
+
ai.video("video/wan:1.3b", "a cat flying through the sky", "cat.mp4")
|
|
209
|
+
ai.video("video/animatediff:v3", "ocean waves on a beach", "ocean.mp4", steps=30)
|
|
210
|
+
ai.video("video/cogvideo:5b", "a horse galloping in a field", "horse.mp4")
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## 3D Model Generation
|
|
216
|
+
|
|
217
|
+
```python
|
|
218
|
+
# From text description
|
|
219
|
+
ai.model3d("3d/shap-e", "chair.ply", description="a wooden chair with four legs")
|
|
220
|
+
|
|
221
|
+
# From image (image → 3D mesh)
|
|
222
|
+
ai.model3d("3d/triposr", "chair.obj", image="photo.jpg")
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## Server Status
|
|
228
|
+
|
|
229
|
+
```python
|
|
230
|
+
info = ai.status()
|
|
231
|
+
print(info["version"]) # "0.3.37"
|
|
232
|
+
print(info["hardware"]) # "CUDA (GPU 0: RTX 3080, 10 GB VRAM)"
|
|
233
|
+
print(info["model_count"])
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## Download Models
|
|
239
|
+
|
|
240
|
+
```python
|
|
241
|
+
# Download from registry
|
|
242
|
+
ai.pull("llm/mistral:7b")
|
|
243
|
+
ai.pull("image/sdxl:latest")
|
|
244
|
+
ai.pull("audio/whisper:base")
|
|
245
|
+
|
|
246
|
+
# Download with progress callback
|
|
247
|
+
ai.pull("llm/llama3:8b", on_progress=lambda pct, msg: print(f"{pct}% — {msg}"))
|
|
248
|
+
|
|
249
|
+
# Download from HuggingFace directly
|
|
250
|
+
ai.pull("llm/hf.co/unsloth/Qwen2.5-0.5B-Instruct-GGUF:Q4_K_M")
|
|
251
|
+
ai.pull("llm/https://huggingface.co/HumeAI/tada-1b")
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
## Custom Port
|
|
257
|
+
|
|
258
|
+
```python
|
|
259
|
+
ai = Vortelio(port=8080) # if server started with: vortelio serve --port 8080
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
## Error Handling
|
|
265
|
+
|
|
266
|
+
```python
|
|
267
|
+
from vortelio import Vortelio
|
|
268
|
+
|
|
269
|
+
ai = Vortelio()
|
|
270
|
+
|
|
271
|
+
try:
|
|
272
|
+
reply = ai.chat("llm/mistral:7b", "Hello!")
|
|
273
|
+
except ConnectionError:
|
|
274
|
+
print("Server not running. Start with: vortelio serve")
|
|
275
|
+
except RuntimeError as e:
|
|
276
|
+
print(f"Generation error: {e}")
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## Full API Reference
|
|
282
|
+
|
|
283
|
+
| Method | Description |
|
|
284
|
+
|--------|-------------|
|
|
285
|
+
| `ai.status()` | Server status (version, hardware, model count) |
|
|
286
|
+
| `ai.models()` | List installed models |
|
|
287
|
+
| `ai.pull(model, on_progress)` | Download a model |
|
|
288
|
+
| `ai.chat(model, message, *, on_token, silent, think, context_size, history)` | Single LLM message — streams tokens |
|
|
289
|
+
| `ai.stream(model, message, *, think, history)` | **Generator** — yields one token at a time |
|
|
290
|
+
| `ai.conversation(model, system)` | Multi-turn conversation object |
|
|
291
|
+
| `conv.say(message, *, on_token, silent, think)` | Send message in conversation — streams tokens |
|
|
292
|
+
| `conv.stream(message, *, think)` | **Generator** — yields tokens, updates history |
|
|
293
|
+
| `conv.start()` | Interactive terminal REPL |
|
|
294
|
+
| `conv.clear()` | Reset conversation history |
|
|
295
|
+
| `ai.image(model, desc, save_to, steps)` | Generate image |
|
|
296
|
+
| `ai.transcribe(model, audio_file, save_to)` | Speech-to-text |
|
|
297
|
+
| `ai.speak(model, text, save_to)` | Text-to-speech |
|
|
298
|
+
| `ai.video(model, desc, save_to, steps)` | Generate video |
|
|
299
|
+
| `ai.model3d(model, save_to, desc, image)` | Generate 3D mesh |
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## License
|
|
304
|
+
|
|
305
|
+
Apache 2.0 — see [LICENSE](LICENSE).
|
|
306
|
+
|
|
307
|
+
Made by **Metiu** with ❤️
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "vortelio"
|
|
7
|
+
version = "6.0.5"
|
|
8
|
+
description = "Python SDK for Vortelio — run AI models locally (LLM, Image, Audio, Video, 3D)"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { text = "Apache-2.0" }
|
|
11
|
+
authors = [{ name = "Metiu" }]
|
|
12
|
+
keywords = ["ai", "llm", "local", "ollama", "llama", "stable-diffusion", "whisper", "tts", "video"]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Development Status :: 4 - Beta",
|
|
15
|
+
"Intended Audience :: Developers",
|
|
16
|
+
"License :: OSI Approved :: Apache Software License",
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Programming Language :: Python :: 3.8",
|
|
19
|
+
"Programming Language :: Python :: 3.9",
|
|
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
|
+
requires-python = ">=3.8"
|
|
27
|
+
dependencies = [] # zero dependencies — pure stdlib
|
|
28
|
+
|
|
29
|
+
[project.urls]
|
|
30
|
+
Homepage = "https://github.com/vortelio/vortelio"
|
|
31
|
+
Repository = "https://github.com/vortelio/vortelio"
|
|
32
|
+
"Bug Tracker" = "https://github.com/vortelio/vortelio/issues"
|
|
33
|
+
|
|
34
|
+
[project.scripts]
|
|
35
|
+
# No CLI scripts — the vortelio.exe binary is separate
|
|
36
|
+
|
|
37
|
+
[tool.setuptools.packages.find]
|
|
38
|
+
where = ["."]
|
|
39
|
+
include = ["vortelio*"]
|
|
40
|
+
|
|
41
|
+
[tool.setuptools.package-data]
|
|
42
|
+
vortelio = ["py.typed"]
|
vortelio-6.0.5/setup.cfg
ADDED