vortelio 0.3.49__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-0.3.49/LICENSE +17 -0
- vortelio-0.3.49/PKG-INFO +354 -0
- vortelio-0.3.49/README.md +324 -0
- vortelio-0.3.49/pyproject.toml +52 -0
- vortelio-0.3.49/setup.cfg +4 -0
- vortelio-0.3.49/vortelio/__init__.py +75 -0
- vortelio-0.3.49/vortelio/_http.py +102 -0
- vortelio-0.3.49/vortelio/async_client.py +493 -0
- vortelio-0.3.49/vortelio/client.py +983 -0
- vortelio-0.3.49/vortelio/py.typed +1 -0
- vortelio-0.3.49/vortelio/setup.py +77 -0
- vortelio-0.3.49/vortelio/types.py +28 -0
- vortelio-0.3.49/vortelio.egg-info/PKG-INFO +354 -0
- vortelio-0.3.49/vortelio.egg-info/SOURCES.txt +15 -0
- vortelio-0.3.49/vortelio.egg-info/dependency_links.txt +1 -0
- vortelio-0.3.49/vortelio.egg-info/requires.txt +3 -0
- vortelio-0.3.49/vortelio.egg-info/top_level.txt +1 -0
vortelio-0.3.49/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-0.3.49/PKG-INFO
ADDED
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: vortelio
|
|
3
|
+
Version: 0.3.49
|
|
4
|
+
Summary: Python SDK for Vortelio — run LLMs, images, audio, video & 3D locally. OpenAI & Ollama API compatible.
|
|
5
|
+
Author: Vortelio Contributors
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/metiu1/Vortelio
|
|
8
|
+
Project-URL: Repository, https://github.com/metiu1/Vortelio-python_libraries
|
|
9
|
+
Project-URL: Bug Tracker, https://github.com/metiu1/Vortelio/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/metiu1/Vortelio/blob/main/CHANGELOG.md
|
|
11
|
+
Keywords: ai,llm,local-ai,local-llm,offline-ai,ollama,ollama-alternative,openai-compatible,stable-diffusion,flux,sdxl,image-generation,whisper,tts,stt,audio,video-generation,3d,llama-cpp,gguf,huggingface,rag,embeddings,multimodal,ai-agent,privacy,self-hosted,cuda,rocm,metal
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
23
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
|
+
Requires-Python: >=3.8
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Provides-Extra: async
|
|
28
|
+
Requires-Dist: aiohttp>=3.8; extra == "async"
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
|
|
31
|
+
# Vortelio Python SDK
|
|
32
|
+
|
|
33
|
+
[](https://pypi.org/project/vortelio/)
|
|
34
|
+
[](https://www.python.org/)
|
|
35
|
+
[](LICENSE)
|
|
36
|
+
|
|
37
|
+
Official Python client for [Vortelio](https://github.com/metiu1/Vortelio) — run LLMs, generate images, audio, video, and 3D models locally.
|
|
38
|
+
|
|
39
|
+
Zero external dependencies. Fully OpenAI API and Ollama API compatible.
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install vortelio
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
For async support:
|
|
46
|
+
```bash
|
|
47
|
+
pip install "vortelio[async]" # adds aiohttp
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Prerequisites
|
|
53
|
+
|
|
54
|
+
Start the Vortelio server first:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
vortelio serve # default port 11500
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Or let the SDK auto-start it:
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
from vortelio import ensure_server
|
|
64
|
+
ensure_server() # finds and starts vortelio if installed
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Quick Start
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
from vortelio import Vortelio
|
|
73
|
+
|
|
74
|
+
ai = Vortelio() # connects to http://localhost:11500
|
|
75
|
+
|
|
76
|
+
# Download a model
|
|
77
|
+
ai.pull("llm/mistral:7b")
|
|
78
|
+
|
|
79
|
+
# Chat — streams tokens to stdout, returns full reply
|
|
80
|
+
reply = ai.chat("llm/mistral:7b", "What is quantum computing?")
|
|
81
|
+
|
|
82
|
+
# Generator streaming
|
|
83
|
+
for token in ai.chat_stream("llm/mistral:7b", "Tell me a story"):
|
|
84
|
+
print(token, end="", flush=True)
|
|
85
|
+
print()
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Chat & Conversations
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
# Simple chat
|
|
94
|
+
reply = ai.chat("llm/mistral:7b", "Hello!")
|
|
95
|
+
|
|
96
|
+
# With messages list (Ollama/OpenAI format)
|
|
97
|
+
reply = ai.chat("llm/mistral:7b", [
|
|
98
|
+
{"role": "system", "content": "You are a helpful assistant."},
|
|
99
|
+
{"role": "user", "content": "What is 2 + 2?"},
|
|
100
|
+
])
|
|
101
|
+
|
|
102
|
+
# Stateful multi-turn conversation
|
|
103
|
+
conv = ai.conversation("llm/mistral:7b", system="You are a pirate.")
|
|
104
|
+
conv.say("What is your name?")
|
|
105
|
+
reply = conv.say("Where do you sail?")
|
|
106
|
+
|
|
107
|
+
# Streaming from a conversation
|
|
108
|
+
for tok in conv.stream("Tell me about treasure"):
|
|
109
|
+
print(tok, end="", flush=True)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Generate (Ollama-style)
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
# Non-streaming
|
|
118
|
+
result = ai.generate("llm/mistral:7b", "The capital of France is")
|
|
119
|
+
print(result["response"])
|
|
120
|
+
|
|
121
|
+
# Streaming generator
|
|
122
|
+
for tok in ai.generate_stream("llm/mistral:7b", "Count to 10"):
|
|
123
|
+
print(tok, end="", flush=True)
|
|
124
|
+
|
|
125
|
+
# With options
|
|
126
|
+
result = ai.generate(
|
|
127
|
+
"llm/mistral:7b",
|
|
128
|
+
"Explain photosynthesis",
|
|
129
|
+
system="You are a biology teacher.",
|
|
130
|
+
options={"temperature": 0.7, "num_ctx": 4096},
|
|
131
|
+
think=True, # chain-of-thought with <think> models
|
|
132
|
+
)
|
|
133
|
+
print(result.get("thinking", ""))
|
|
134
|
+
print(result["response"])
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Embeddings
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
# Batch embeddings
|
|
143
|
+
vecs = ai.embed("llm/nomic-embed-text:latest", ["Hello", "World"])
|
|
144
|
+
# → [[0.1, 0.2, ...], [0.3, 0.4, ...]]
|
|
145
|
+
|
|
146
|
+
# Legacy single-prompt
|
|
147
|
+
vec = ai.embeddings("llm/nomic-embed-text:latest", "Hello world")
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## RAG (Retrieval-Augmented Generation)
|
|
153
|
+
|
|
154
|
+
```python
|
|
155
|
+
# Ingest documents
|
|
156
|
+
ai.rag_ingest(
|
|
157
|
+
"llm/nomic-embed-text:latest",
|
|
158
|
+
[
|
|
159
|
+
{"text": "Paris is the capital of France.", "meta": {"source": "facts"}},
|
|
160
|
+
{"text": "Berlin is the capital of Germany.", "meta": {"source": "facts"}},
|
|
161
|
+
],
|
|
162
|
+
collection="my-docs",
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
# Query
|
|
166
|
+
hits = ai.rag_query("llm/nomic-embed-text:latest", "capital of France", collection="my-docs")
|
|
167
|
+
for h in hits["results"]:
|
|
168
|
+
print(f"[{h['score']:.3f}] {h['text']}")
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Model Management
|
|
174
|
+
|
|
175
|
+
```python
|
|
176
|
+
ai.models() # list all downloaded models
|
|
177
|
+
ai.pull("llm/llama3:8b") # download from HuggingFace
|
|
178
|
+
ai.show("llm/mistral:7b") # model details, template, capabilities
|
|
179
|
+
ai.delete("llm/old-model:latest") # remove a model
|
|
180
|
+
ai.copy("llm/mistral:7b", "llm/my-mistral:latest") # duplicate
|
|
181
|
+
ai.quantize("llm/mistral:7b", "q4_k_m") # quantize
|
|
182
|
+
ai.create("llm/my-model:latest", from_model="llm/mistral:7b",
|
|
183
|
+
system="You are a helpful assistant.")
|
|
184
|
+
ai.ps() # currently loaded models
|
|
185
|
+
ai.version() # server version
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## Media Generation
|
|
191
|
+
|
|
192
|
+
```python
|
|
193
|
+
# Image
|
|
194
|
+
ai.image("image/sdxl:latest", "a red panda on the moon", "panda.png")
|
|
195
|
+
|
|
196
|
+
# Or get bytes directly
|
|
197
|
+
png_bytes = ai.generate_image("image/sdxl:latest", "sunset over mountains")
|
|
198
|
+
|
|
199
|
+
# Audio (TTS / music)
|
|
200
|
+
wav_bytes = ai.generate_audio("audio/kokoro:latest", "Hello, this is a test.")
|
|
201
|
+
|
|
202
|
+
# Video
|
|
203
|
+
mp4_bytes = ai.generate_video("video/wan2-1:latest", "a cat playing piano")
|
|
204
|
+
|
|
205
|
+
# 3D
|
|
206
|
+
obj_bytes = ai.generate_3d("3d/triposr:latest", "a wooden chair")
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## Advanced API
|
|
212
|
+
|
|
213
|
+
```python
|
|
214
|
+
# A/B compare models
|
|
215
|
+
result = ai.compare(
|
|
216
|
+
["llm/mistral:7b", "llm/llama3:8b"],
|
|
217
|
+
"Explain gravity in one sentence.",
|
|
218
|
+
)
|
|
219
|
+
for r in result["results"]:
|
|
220
|
+
print(f"{r['model']}: {r['response']}")
|
|
221
|
+
|
|
222
|
+
# Structured JSON output
|
|
223
|
+
result = ai.structured(
|
|
224
|
+
"llm/mistral:7b",
|
|
225
|
+
"List 3 programming languages",
|
|
226
|
+
schema={"type": "array", "items": {"type": "string"}},
|
|
227
|
+
)
|
|
228
|
+
print(result["parsed"])
|
|
229
|
+
|
|
230
|
+
# Long-text summarization (map-reduce)
|
|
231
|
+
summary = ai.summarize("llm/mistral:7b", very_long_text, style="bullets")
|
|
232
|
+
print(summary["summary"])
|
|
233
|
+
|
|
234
|
+
# Chain-of-thought
|
|
235
|
+
result = ai.think("llm/qwq:32b", "Is 97 a prime number?")
|
|
236
|
+
print("Reasoning:", result["thinking"])
|
|
237
|
+
print("Answer:", result["answer"])
|
|
238
|
+
|
|
239
|
+
# Smart model router
|
|
240
|
+
best = ai.route("code", prompt="Write a sorting algorithm")
|
|
241
|
+
print("Best model:", best["model"])
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## OpenAI-Compatible API
|
|
247
|
+
|
|
248
|
+
```python
|
|
249
|
+
# Drop-in OpenAI replacement
|
|
250
|
+
response = ai.openai_chat(
|
|
251
|
+
"mistral:7b",
|
|
252
|
+
[{"role": "user", "content": "Hello!"}],
|
|
253
|
+
temperature=0.7,
|
|
254
|
+
)
|
|
255
|
+
print(response["choices"][0]["message"]["content"])
|
|
256
|
+
|
|
257
|
+
# Streaming
|
|
258
|
+
for tok in ai.openai_chat_stream("mistral:7b", [{"role":"user","content":"Hi"}]):
|
|
259
|
+
print(tok, end="", flush=True)
|
|
260
|
+
|
|
261
|
+
# Embeddings (OpenAI format)
|
|
262
|
+
result = ai.openai_embeddings("nomic-embed-text:latest", "Hello world")
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## Async Client
|
|
268
|
+
|
|
269
|
+
```python
|
|
270
|
+
import asyncio
|
|
271
|
+
from vortelio import AsyncVortelio
|
|
272
|
+
|
|
273
|
+
async def main():
|
|
274
|
+
ai = AsyncVortelio()
|
|
275
|
+
|
|
276
|
+
# All methods are async
|
|
277
|
+
reply = await ai.chat("llm/mistral:7b", "Hello!")
|
|
278
|
+
|
|
279
|
+
# Async streaming
|
|
280
|
+
async for tok in ai.chat_stream("llm/mistral:7b", "Tell me a joke"):
|
|
281
|
+
print(tok, end="", flush=True)
|
|
282
|
+
|
|
283
|
+
# Async conversation
|
|
284
|
+
conv = ai.conversation("llm/mistral:7b", system="You are helpful.")
|
|
285
|
+
reply = await conv.say("My name is Alice.")
|
|
286
|
+
|
|
287
|
+
asyncio.run(main())
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## Agents
|
|
293
|
+
|
|
294
|
+
```python
|
|
295
|
+
# List available agents (Open WebUI, OpenClaw, CrewAI, AnythingLLM, ...)
|
|
296
|
+
catalog = ai.agents_catalog()
|
|
297
|
+
|
|
298
|
+
# Install and start an agent
|
|
299
|
+
ai.agents_install("open-webui")
|
|
300
|
+
ai.agents_start("open-webui")
|
|
301
|
+
|
|
302
|
+
# Stop an agent
|
|
303
|
+
ai.agents_stop("open-webui")
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
## Webhooks & Audit
|
|
309
|
+
|
|
310
|
+
```python
|
|
311
|
+
# Register a webhook
|
|
312
|
+
ai.hooks_create("https://my-server.com/webhook", event="generate")
|
|
313
|
+
|
|
314
|
+
# List webhooks
|
|
315
|
+
ai.hooks_list()
|
|
316
|
+
|
|
317
|
+
# Audit log
|
|
318
|
+
entries = ai.audit(limit=50)
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
## GGUF Inspect & Ollama Import
|
|
324
|
+
|
|
325
|
+
```python
|
|
326
|
+
# Inspect a local GGUF file
|
|
327
|
+
info = ai.gguf_inspect("/path/to/model.gguf")
|
|
328
|
+
|
|
329
|
+
# Import models from a local Ollama installation
|
|
330
|
+
ai.import_ollama() # imports all
|
|
331
|
+
ai.import_ollama(["mistral:7b", "llama3:8b"]) # selective
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
## Custom Port / Remote Server
|
|
337
|
+
|
|
338
|
+
```python
|
|
339
|
+
ai = Vortelio(host="http://192.168.1.100", port=11500)
|
|
340
|
+
ai = Vortelio(port=8080) # local custom port
|
|
341
|
+
ai = Vortelio(timeout=600) # longer timeout for large models
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
## Server Version Compatibility
|
|
347
|
+
|
|
348
|
+
This SDK version **0.3.49** requires Vortelio server **≥ 0.3.38**.
|
|
349
|
+
|
|
350
|
+
---
|
|
351
|
+
|
|
352
|
+
## License
|
|
353
|
+
|
|
354
|
+
Apache 2.0 — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
# Vortelio Python SDK
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/vortelio/)
|
|
4
|
+
[](https://www.python.org/)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
|
|
7
|
+
Official Python client for [Vortelio](https://github.com/metiu1/Vortelio) — run LLMs, generate images, audio, video, and 3D models locally.
|
|
8
|
+
|
|
9
|
+
Zero external dependencies. Fully OpenAI API and Ollama API compatible.
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pip install vortelio
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
For async support:
|
|
16
|
+
```bash
|
|
17
|
+
pip install "vortelio[async]" # adds aiohttp
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Prerequisites
|
|
23
|
+
|
|
24
|
+
Start the Vortelio server first:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
vortelio serve # default port 11500
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Or let the SDK auto-start it:
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
from vortelio import ensure_server
|
|
34
|
+
ensure_server() # finds and starts vortelio if installed
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Quick Start
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
from vortelio import Vortelio
|
|
43
|
+
|
|
44
|
+
ai = Vortelio() # connects to http://localhost:11500
|
|
45
|
+
|
|
46
|
+
# Download a model
|
|
47
|
+
ai.pull("llm/mistral:7b")
|
|
48
|
+
|
|
49
|
+
# Chat — streams tokens to stdout, returns full reply
|
|
50
|
+
reply = ai.chat("llm/mistral:7b", "What is quantum computing?")
|
|
51
|
+
|
|
52
|
+
# Generator streaming
|
|
53
|
+
for token in ai.chat_stream("llm/mistral:7b", "Tell me a story"):
|
|
54
|
+
print(token, end="", flush=True)
|
|
55
|
+
print()
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Chat & Conversations
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
# Simple chat
|
|
64
|
+
reply = ai.chat("llm/mistral:7b", "Hello!")
|
|
65
|
+
|
|
66
|
+
# With messages list (Ollama/OpenAI format)
|
|
67
|
+
reply = ai.chat("llm/mistral:7b", [
|
|
68
|
+
{"role": "system", "content": "You are a helpful assistant."},
|
|
69
|
+
{"role": "user", "content": "What is 2 + 2?"},
|
|
70
|
+
])
|
|
71
|
+
|
|
72
|
+
# Stateful multi-turn conversation
|
|
73
|
+
conv = ai.conversation("llm/mistral:7b", system="You are a pirate.")
|
|
74
|
+
conv.say("What is your name?")
|
|
75
|
+
reply = conv.say("Where do you sail?")
|
|
76
|
+
|
|
77
|
+
# Streaming from a conversation
|
|
78
|
+
for tok in conv.stream("Tell me about treasure"):
|
|
79
|
+
print(tok, end="", flush=True)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Generate (Ollama-style)
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
# Non-streaming
|
|
88
|
+
result = ai.generate("llm/mistral:7b", "The capital of France is")
|
|
89
|
+
print(result["response"])
|
|
90
|
+
|
|
91
|
+
# Streaming generator
|
|
92
|
+
for tok in ai.generate_stream("llm/mistral:7b", "Count to 10"):
|
|
93
|
+
print(tok, end="", flush=True)
|
|
94
|
+
|
|
95
|
+
# With options
|
|
96
|
+
result = ai.generate(
|
|
97
|
+
"llm/mistral:7b",
|
|
98
|
+
"Explain photosynthesis",
|
|
99
|
+
system="You are a biology teacher.",
|
|
100
|
+
options={"temperature": 0.7, "num_ctx": 4096},
|
|
101
|
+
think=True, # chain-of-thought with <think> models
|
|
102
|
+
)
|
|
103
|
+
print(result.get("thinking", ""))
|
|
104
|
+
print(result["response"])
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Embeddings
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
# Batch embeddings
|
|
113
|
+
vecs = ai.embed("llm/nomic-embed-text:latest", ["Hello", "World"])
|
|
114
|
+
# → [[0.1, 0.2, ...], [0.3, 0.4, ...]]
|
|
115
|
+
|
|
116
|
+
# Legacy single-prompt
|
|
117
|
+
vec = ai.embeddings("llm/nomic-embed-text:latest", "Hello world")
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## RAG (Retrieval-Augmented Generation)
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
# Ingest documents
|
|
126
|
+
ai.rag_ingest(
|
|
127
|
+
"llm/nomic-embed-text:latest",
|
|
128
|
+
[
|
|
129
|
+
{"text": "Paris is the capital of France.", "meta": {"source": "facts"}},
|
|
130
|
+
{"text": "Berlin is the capital of Germany.", "meta": {"source": "facts"}},
|
|
131
|
+
],
|
|
132
|
+
collection="my-docs",
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
# Query
|
|
136
|
+
hits = ai.rag_query("llm/nomic-embed-text:latest", "capital of France", collection="my-docs")
|
|
137
|
+
for h in hits["results"]:
|
|
138
|
+
print(f"[{h['score']:.3f}] {h['text']}")
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Model Management
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
ai.models() # list all downloaded models
|
|
147
|
+
ai.pull("llm/llama3:8b") # download from HuggingFace
|
|
148
|
+
ai.show("llm/mistral:7b") # model details, template, capabilities
|
|
149
|
+
ai.delete("llm/old-model:latest") # remove a model
|
|
150
|
+
ai.copy("llm/mistral:7b", "llm/my-mistral:latest") # duplicate
|
|
151
|
+
ai.quantize("llm/mistral:7b", "q4_k_m") # quantize
|
|
152
|
+
ai.create("llm/my-model:latest", from_model="llm/mistral:7b",
|
|
153
|
+
system="You are a helpful assistant.")
|
|
154
|
+
ai.ps() # currently loaded models
|
|
155
|
+
ai.version() # server version
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Media Generation
|
|
161
|
+
|
|
162
|
+
```python
|
|
163
|
+
# Image
|
|
164
|
+
ai.image("image/sdxl:latest", "a red panda on the moon", "panda.png")
|
|
165
|
+
|
|
166
|
+
# Or get bytes directly
|
|
167
|
+
png_bytes = ai.generate_image("image/sdxl:latest", "sunset over mountains")
|
|
168
|
+
|
|
169
|
+
# Audio (TTS / music)
|
|
170
|
+
wav_bytes = ai.generate_audio("audio/kokoro:latest", "Hello, this is a test.")
|
|
171
|
+
|
|
172
|
+
# Video
|
|
173
|
+
mp4_bytes = ai.generate_video("video/wan2-1:latest", "a cat playing piano")
|
|
174
|
+
|
|
175
|
+
# 3D
|
|
176
|
+
obj_bytes = ai.generate_3d("3d/triposr:latest", "a wooden chair")
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Advanced API
|
|
182
|
+
|
|
183
|
+
```python
|
|
184
|
+
# A/B compare models
|
|
185
|
+
result = ai.compare(
|
|
186
|
+
["llm/mistral:7b", "llm/llama3:8b"],
|
|
187
|
+
"Explain gravity in one sentence.",
|
|
188
|
+
)
|
|
189
|
+
for r in result["results"]:
|
|
190
|
+
print(f"{r['model']}: {r['response']}")
|
|
191
|
+
|
|
192
|
+
# Structured JSON output
|
|
193
|
+
result = ai.structured(
|
|
194
|
+
"llm/mistral:7b",
|
|
195
|
+
"List 3 programming languages",
|
|
196
|
+
schema={"type": "array", "items": {"type": "string"}},
|
|
197
|
+
)
|
|
198
|
+
print(result["parsed"])
|
|
199
|
+
|
|
200
|
+
# Long-text summarization (map-reduce)
|
|
201
|
+
summary = ai.summarize("llm/mistral:7b", very_long_text, style="bullets")
|
|
202
|
+
print(summary["summary"])
|
|
203
|
+
|
|
204
|
+
# Chain-of-thought
|
|
205
|
+
result = ai.think("llm/qwq:32b", "Is 97 a prime number?")
|
|
206
|
+
print("Reasoning:", result["thinking"])
|
|
207
|
+
print("Answer:", result["answer"])
|
|
208
|
+
|
|
209
|
+
# Smart model router
|
|
210
|
+
best = ai.route("code", prompt="Write a sorting algorithm")
|
|
211
|
+
print("Best model:", best["model"])
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## OpenAI-Compatible API
|
|
217
|
+
|
|
218
|
+
```python
|
|
219
|
+
# Drop-in OpenAI replacement
|
|
220
|
+
response = ai.openai_chat(
|
|
221
|
+
"mistral:7b",
|
|
222
|
+
[{"role": "user", "content": "Hello!"}],
|
|
223
|
+
temperature=0.7,
|
|
224
|
+
)
|
|
225
|
+
print(response["choices"][0]["message"]["content"])
|
|
226
|
+
|
|
227
|
+
# Streaming
|
|
228
|
+
for tok in ai.openai_chat_stream("mistral:7b", [{"role":"user","content":"Hi"}]):
|
|
229
|
+
print(tok, end="", flush=True)
|
|
230
|
+
|
|
231
|
+
# Embeddings (OpenAI format)
|
|
232
|
+
result = ai.openai_embeddings("nomic-embed-text:latest", "Hello world")
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## Async Client
|
|
238
|
+
|
|
239
|
+
```python
|
|
240
|
+
import asyncio
|
|
241
|
+
from vortelio import AsyncVortelio
|
|
242
|
+
|
|
243
|
+
async def main():
|
|
244
|
+
ai = AsyncVortelio()
|
|
245
|
+
|
|
246
|
+
# All methods are async
|
|
247
|
+
reply = await ai.chat("llm/mistral:7b", "Hello!")
|
|
248
|
+
|
|
249
|
+
# Async streaming
|
|
250
|
+
async for tok in ai.chat_stream("llm/mistral:7b", "Tell me a joke"):
|
|
251
|
+
print(tok, end="", flush=True)
|
|
252
|
+
|
|
253
|
+
# Async conversation
|
|
254
|
+
conv = ai.conversation("llm/mistral:7b", system="You are helpful.")
|
|
255
|
+
reply = await conv.say("My name is Alice.")
|
|
256
|
+
|
|
257
|
+
asyncio.run(main())
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## Agents
|
|
263
|
+
|
|
264
|
+
```python
|
|
265
|
+
# List available agents (Open WebUI, OpenClaw, CrewAI, AnythingLLM, ...)
|
|
266
|
+
catalog = ai.agents_catalog()
|
|
267
|
+
|
|
268
|
+
# Install and start an agent
|
|
269
|
+
ai.agents_install("open-webui")
|
|
270
|
+
ai.agents_start("open-webui")
|
|
271
|
+
|
|
272
|
+
# Stop an agent
|
|
273
|
+
ai.agents_stop("open-webui")
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## Webhooks & Audit
|
|
279
|
+
|
|
280
|
+
```python
|
|
281
|
+
# Register a webhook
|
|
282
|
+
ai.hooks_create("https://my-server.com/webhook", event="generate")
|
|
283
|
+
|
|
284
|
+
# List webhooks
|
|
285
|
+
ai.hooks_list()
|
|
286
|
+
|
|
287
|
+
# Audit log
|
|
288
|
+
entries = ai.audit(limit=50)
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## GGUF Inspect & Ollama Import
|
|
294
|
+
|
|
295
|
+
```python
|
|
296
|
+
# Inspect a local GGUF file
|
|
297
|
+
info = ai.gguf_inspect("/path/to/model.gguf")
|
|
298
|
+
|
|
299
|
+
# Import models from a local Ollama installation
|
|
300
|
+
ai.import_ollama() # imports all
|
|
301
|
+
ai.import_ollama(["mistral:7b", "llama3:8b"]) # selective
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## Custom Port / Remote Server
|
|
307
|
+
|
|
308
|
+
```python
|
|
309
|
+
ai = Vortelio(host="http://192.168.1.100", port=11500)
|
|
310
|
+
ai = Vortelio(port=8080) # local custom port
|
|
311
|
+
ai = Vortelio(timeout=600) # longer timeout for large models
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
## Server Version Compatibility
|
|
317
|
+
|
|
318
|
+
This SDK version **0.3.49** requires Vortelio server **≥ 0.3.38**.
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
## License
|
|
323
|
+
|
|
324
|
+
Apache 2.0 — see [LICENSE](LICENSE).
|