freeaiagent 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.
- freeaiagent-0.1.0/PKG-INFO +374 -0
- freeaiagent-0.1.0/README.md +344 -0
- freeaiagent-0.1.0/freeaiagent/__init__.py +1 -0
- freeaiagent-0.1.0/freeaiagent/backends/__init__.py +4 -0
- freeaiagent-0.1.0/freeaiagent/backends/base.py +13 -0
- freeaiagent-0.1.0/freeaiagent/backends/groq.py +35 -0
- freeaiagent-0.1.0/freeaiagent/backends/ollama.py +31 -0
- freeaiagent-0.1.0/freeaiagent/cli.py +207 -0
- freeaiagent-0.1.0/freeaiagent/config.py +46 -0
- freeaiagent-0.1.0/freeaiagent/context.py +56 -0
- freeaiagent-0.1.0/freeaiagent/endpoints/__init__.py +0 -0
- freeaiagent-0.1.0/freeaiagent/endpoints/chat.py +34 -0
- freeaiagent-0.1.0/freeaiagent/endpoints/context.py +18 -0
- freeaiagent-0.1.0/freeaiagent/endpoints/health.py +26 -0
- freeaiagent-0.1.0/freeaiagent/endpoints/task.py +31 -0
- freeaiagent-0.1.0/freeaiagent/main.py +19 -0
- freeaiagent-0.1.0/freeaiagent/router.py +51 -0
- freeaiagent-0.1.0/freeaiagent.egg-info/PKG-INFO +374 -0
- freeaiagent-0.1.0/freeaiagent.egg-info/SOURCES.txt +24 -0
- freeaiagent-0.1.0/freeaiagent.egg-info/dependency_links.txt +1 -0
- freeaiagent-0.1.0/freeaiagent.egg-info/entry_points.txt +2 -0
- freeaiagent-0.1.0/freeaiagent.egg-info/requires.txt +15 -0
- freeaiagent-0.1.0/freeaiagent.egg-info/top_level.txt +1 -0
- freeaiagent-0.1.0/pyproject.toml +57 -0
- freeaiagent-0.1.0/setup.cfg +4 -0
- freeaiagent-0.1.0/setup.py +3 -0
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: freeaiagent
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Local AI agent service — HTTP endpoints, persistent context, multi-model LLM backend
|
|
5
|
+
Author-email: Subham <shubham.divakar@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Keywords: llm,agent,ollama,groq,local,ai,fastapi
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
16
|
+
Requires-Python: >=3.10
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
Requires-Dist: fastapi>=0.110.0
|
|
19
|
+
Requires-Dist: uvicorn[standard]>=0.29.0
|
|
20
|
+
Requires-Dist: typer>=0.12.0
|
|
21
|
+
Requires-Dist: httpx2
|
|
22
|
+
Provides-Extra: groq
|
|
23
|
+
Requires-Dist: groq>=0.9.0; extra == "groq"
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
26
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
|
|
27
|
+
Requires-Dist: httpx2; extra == "dev"
|
|
28
|
+
Provides-Extra: all
|
|
29
|
+
Requires-Dist: groq>=0.9.0; extra == "all"
|
|
30
|
+
|
|
31
|
+
# freeaiagent
|
|
32
|
+
|
|
33
|
+
A local AI agent service you `pip install` once and call from anywhere.
|
|
34
|
+
|
|
35
|
+
Runs as a persistent HTTP server on `localhost:7731`. Stores conversation history in SQLite. Any app — script, CLI tool, personal project — can delegate tasks to it with a single HTTP call, no LLM code required on the caller's side.
|
|
36
|
+
|
|
37
|
+
Built on free LLM backends: **Ollama** (local, no API key) and **Groq** (free-tier cloud).
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Why
|
|
42
|
+
|
|
43
|
+
Embedding LLM logic directly into every app that needs it means duplicating prompt management, context handling, model configuration, and install detection across projects. When something changes — a new model, a different provider, a context bug — you fix it in every app separately.
|
|
44
|
+
|
|
45
|
+
`freeaiagent` is the single place that owns all of that. Your apps just call an endpoint.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Install
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pip install freeaiagent # Ollama only
|
|
53
|
+
pip install "freeaiagent[groq]" # + Groq support
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Requires Python 3.10+.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Quick start
|
|
61
|
+
|
|
62
|
+
**1. Start the server**
|
|
63
|
+
```bash
|
|
64
|
+
freeaiagent start
|
|
65
|
+
# Running at http://localhost:7731
|
|
66
|
+
# API docs at http://localhost:7731/docs
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**2. Chat with it**
|
|
70
|
+
```bash
|
|
71
|
+
freeaiagent chat
|
|
72
|
+
# You: what is the capital of France?
|
|
73
|
+
# Agent [llama3.2:3b]: Paris.
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**3. Call it from any app**
|
|
77
|
+
```python
|
|
78
|
+
import urllib.request, json
|
|
79
|
+
|
|
80
|
+
req = urllib.request.Request(
|
|
81
|
+
"http://localhost:7731/chat",
|
|
82
|
+
data=json.dumps({"message": "summarize this for me: ..."}).encode(),
|
|
83
|
+
headers={"Content-Type": "application/json"},
|
|
84
|
+
)
|
|
85
|
+
response = json.loads(urllib.request.urlopen(req).read())["response"]
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
No pip dependencies needed in the calling app. Pure stdlib.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## CLI
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
freeaiagent start # start server (default port 7731)
|
|
96
|
+
freeaiagent start --port 8080 # custom port
|
|
97
|
+
freeaiagent start --reload # dev mode: auto-reload on code change
|
|
98
|
+
|
|
99
|
+
freeaiagent chat # interactive chat (context preserved)
|
|
100
|
+
freeaiagent chat "quick one-liner" # single message, then exit
|
|
101
|
+
|
|
102
|
+
freeaiagent task "explain this" \
|
|
103
|
+
--input "$(cat file.py)" # one-shot task, no context read/written
|
|
104
|
+
freeaiagent task "translate to French" \
|
|
105
|
+
--input "Hello world" \
|
|
106
|
+
--model mistral:7b # override model for this task
|
|
107
|
+
|
|
108
|
+
freeaiagent status # health check + active backend/model
|
|
109
|
+
freeaiagent models # list models on active backend
|
|
110
|
+
|
|
111
|
+
freeaiagent context show # print conversation history
|
|
112
|
+
freeaiagent context clear # wipe conversation history
|
|
113
|
+
|
|
114
|
+
freeaiagent config show # print current config
|
|
115
|
+
freeaiagent config set default_model mistral:7b
|
|
116
|
+
freeaiagent config set default_backend groq
|
|
117
|
+
freeaiagent config set backends.groq.api_key gsk_...
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## HTTP API
|
|
123
|
+
|
|
124
|
+
All endpoints accept and return JSON.
|
|
125
|
+
|
|
126
|
+
### `POST /chat`
|
|
127
|
+
Send a message. Conversation history is read and updated automatically.
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
curl -X POST http://localhost:7731/chat \
|
|
131
|
+
-H "Content-Type: application/json" \
|
|
132
|
+
-d '{"message": "what did I just ask you?"}'
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
```json
|
|
136
|
+
{
|
|
137
|
+
"response": "You asked me what you just asked me.",
|
|
138
|
+
"model": "llama3.2:3b",
|
|
139
|
+
"context_length": 4
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
| Field | Type | Description |
|
|
144
|
+
|---|---|---|
|
|
145
|
+
| `message` | string | required |
|
|
146
|
+
| `system` | string | optional system prompt override |
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
### `POST /task`
|
|
151
|
+
One-shot task. No context is read or written — clean slate every time.
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
curl -X POST http://localhost:7731/task \
|
|
155
|
+
-H "Content-Type: application/json" \
|
|
156
|
+
-d '{"task": "list all TODO comments", "input": "..."}'
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
```json
|
|
160
|
+
{
|
|
161
|
+
"result": "Line 42: TODO fix this\nLine 87: TODO add tests",
|
|
162
|
+
"model": "llama3.2:3b"
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
| Field | Type | Description |
|
|
167
|
+
|---|---|---|
|
|
168
|
+
| `task` | string | required — the instruction |
|
|
169
|
+
| `input` | string | optional — content to work on |
|
|
170
|
+
| `model` | string | optional — override model for this call |
|
|
171
|
+
| `system` | string | optional — override system prompt |
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
### `GET /context`
|
|
176
|
+
Returns the full conversation history.
|
|
177
|
+
|
|
178
|
+
```json
|
|
179
|
+
{
|
|
180
|
+
"messages": [
|
|
181
|
+
{"role": "user", "content": "hello", "timestamp": "2026-06-21T10:00:00+00:00"},
|
|
182
|
+
{"role": "assistant", "content": "hi there", "timestamp": "2026-06-21T10:00:01+00:00"}
|
|
183
|
+
],
|
|
184
|
+
"total": 2
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### `DELETE /context`
|
|
189
|
+
Clears all conversation history.
|
|
190
|
+
|
|
191
|
+
```json
|
|
192
|
+
{"cleared": 4, "message": "Cleared 4 messages."}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### `GET /health`
|
|
196
|
+
```json
|
|
197
|
+
{"status": "ok", "active_backend": "ollama", "default_model": "llama3.2:3b"}
|
|
198
|
+
```
|
|
199
|
+
Returns `"status": "degraded"` with an `"error"` field if no backend is reachable.
|
|
200
|
+
|
|
201
|
+
### `GET /models`
|
|
202
|
+
```json
|
|
203
|
+
{"models": ["llama3.2:3b", "mistral:7b", "phi3:mini"]}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Configuration
|
|
209
|
+
|
|
210
|
+
Config lives at `~/.freeaiagent/config.json` and is created on first run.
|
|
211
|
+
|
|
212
|
+
```json
|
|
213
|
+
{
|
|
214
|
+
"default_backend": "ollama",
|
|
215
|
+
"default_model": "llama3.2:3b",
|
|
216
|
+
"port": 7731,
|
|
217
|
+
"backends": {
|
|
218
|
+
"ollama": {
|
|
219
|
+
"base_url": "http://localhost:11434"
|
|
220
|
+
},
|
|
221
|
+
"groq": {
|
|
222
|
+
"api_key": ""
|
|
223
|
+
}
|
|
224
|
+
},
|
|
225
|
+
"fallback_order": ["ollama", "groq"]
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Edit directly or use `freeaiagent config set <key> <value>` with dotted keys:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
freeaiagent config set port 8080
|
|
233
|
+
freeaiagent config set backends.ollama.base_url http://192.168.1.10:11434
|
|
234
|
+
freeaiagent config set backends.groq.api_key gsk_abc123
|
|
235
|
+
freeaiagent config set default_backend groq
|
|
236
|
+
freeaiagent config set default_model llama-3.1-8b-instant
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## Backends
|
|
242
|
+
|
|
243
|
+
### Ollama (default)
|
|
244
|
+
Runs locally. No API key. No data leaves your machine.
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
# Install Ollama from https://ollama.com
|
|
248
|
+
ollama pull llama3.2:3b
|
|
249
|
+
freeaiagent start
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
Any model available on your Ollama instance works. Switch with:
|
|
253
|
+
```bash
|
|
254
|
+
freeaiagent config set default_model mistral:7b
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Groq (free-tier cloud)
|
|
258
|
+
Fast inference. Free API key at [console.groq.com](https://console.groq.com).
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
freeaiagent config set backends.groq.api_key gsk_...
|
|
262
|
+
freeaiagent config set default_backend groq
|
|
263
|
+
freeaiagent config set default_model llama-3.1-8b-instant
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
Free-tier models available on Groq:
|
|
267
|
+
|
|
268
|
+
| Model | Context |
|
|
269
|
+
|---|---|
|
|
270
|
+
| `llama-3.1-8b-instant` | 128k |
|
|
271
|
+
| `llama-3.3-70b-versatile` | 128k |
|
|
272
|
+
| `mixtral-8x7b-32768` | 32k |
|
|
273
|
+
| `gemma2-9b-it` | 8k |
|
|
274
|
+
|
|
275
|
+
### Automatic fallback
|
|
276
|
+
If the default backend is unreachable, `freeaiagent` tries the next one in `fallback_order` automatically. No configuration needed for this to work — just have both set up.
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## Using from another app
|
|
281
|
+
|
|
282
|
+
The agent runs as a separate process. Your app calls it over HTTP — no LLM dependencies, no model management, no context handling in your code.
|
|
283
|
+
|
|
284
|
+
**Python (stdlib only):**
|
|
285
|
+
```python
|
|
286
|
+
import urllib.request, json
|
|
287
|
+
|
|
288
|
+
def ask(message):
|
|
289
|
+
body = json.dumps({"message": message}).encode()
|
|
290
|
+
req = urllib.request.Request(
|
|
291
|
+
"http://localhost:7731/chat",
|
|
292
|
+
data=body,
|
|
293
|
+
headers={"Content-Type": "application/json"},
|
|
294
|
+
)
|
|
295
|
+
return json.loads(urllib.request.urlopen(req).read())["response"]
|
|
296
|
+
|
|
297
|
+
def run_task(task, input_text=None):
|
|
298
|
+
body = json.dumps({"task": task, "input": input_text}).encode()
|
|
299
|
+
req = urllib.request.Request(
|
|
300
|
+
"http://localhost:7731/task",
|
|
301
|
+
data=body,
|
|
302
|
+
headers={"Content-Type": "application/json"},
|
|
303
|
+
)
|
|
304
|
+
return json.loads(urllib.request.urlopen(req).read())["result"]
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
**Shell:**
|
|
308
|
+
```bash
|
|
309
|
+
curl -s -X POST http://localhost:7731/task \
|
|
310
|
+
-H "Content-Type: application/json" \
|
|
311
|
+
-d "{\"task\": \"summarize\", \"input\": \"$(cat notes.txt)\"}" \
|
|
312
|
+
| python -c "import sys,json; print(json.load(sys.stdin)['result'])"
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
**JavaScript / Node:**
|
|
316
|
+
```js
|
|
317
|
+
const res = await fetch("http://localhost:7731/chat", {
|
|
318
|
+
method: "POST",
|
|
319
|
+
headers: { "Content-Type": "application/json" },
|
|
320
|
+
body: JSON.stringify({ message: "hello" }),
|
|
321
|
+
});
|
|
322
|
+
const { response } = await res.json();
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
## Context storage
|
|
328
|
+
|
|
329
|
+
Conversation history is stored in `~/.freeaiagent/context.db` (SQLite). It persists across server restarts. Clear it any time:
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
freeaiagent context clear
|
|
333
|
+
# or
|
|
334
|
+
curl -X DELETE http://localhost:7731/context
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
## Roadmap
|
|
340
|
+
|
|
341
|
+
**Phase 2 — Named sessions**
|
|
342
|
+
Multiple apps keep separate conversation histories via a `session_id` field.
|
|
343
|
+
```json
|
|
344
|
+
{"message": "hello", "session_id": "my-project"}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
**Phase 3 — Auto caller detection**
|
|
348
|
+
Sessions created automatically per caller using `X-Caller-ID` header or caller port. Zero config for multi-app setups.
|
|
349
|
+
|
|
350
|
+
**Phase 4 — More backends and features**
|
|
351
|
+
- llamafile (single-file model, no Ollama install needed)
|
|
352
|
+
- Together AI, OpenRouter
|
|
353
|
+
- Streaming responses (`/chat/stream` SSE)
|
|
354
|
+
- Tool use / function calling
|
|
355
|
+
- Minimal web UI at `localhost:7731`
|
|
356
|
+
|
|
357
|
+
---
|
|
358
|
+
|
|
359
|
+
## Development
|
|
360
|
+
|
|
361
|
+
```bash
|
|
362
|
+
git clone <repo>
|
|
363
|
+
cd freeaiagent
|
|
364
|
+
pip install -e ".[dev,groq]"
|
|
365
|
+
|
|
366
|
+
pytest # unit + integration (no LLM needed)
|
|
367
|
+
pytest tests/smoke/ -m smoke -v # smoke tests (requires Ollama running)
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
## License
|
|
373
|
+
|
|
374
|
+
MIT
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
# freeaiagent
|
|
2
|
+
|
|
3
|
+
A local AI agent service you `pip install` once and call from anywhere.
|
|
4
|
+
|
|
5
|
+
Runs as a persistent HTTP server on `localhost:7731`. Stores conversation history in SQLite. Any app — script, CLI tool, personal project — can delegate tasks to it with a single HTTP call, no LLM code required on the caller's side.
|
|
6
|
+
|
|
7
|
+
Built on free LLM backends: **Ollama** (local, no API key) and **Groq** (free-tier cloud).
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Why
|
|
12
|
+
|
|
13
|
+
Embedding LLM logic directly into every app that needs it means duplicating prompt management, context handling, model configuration, and install detection across projects. When something changes — a new model, a different provider, a context bug — you fix it in every app separately.
|
|
14
|
+
|
|
15
|
+
`freeaiagent` is the single place that owns all of that. Your apps just call an endpoint.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Install
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install freeaiagent # Ollama only
|
|
23
|
+
pip install "freeaiagent[groq]" # + Groq support
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Requires Python 3.10+.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Quick start
|
|
31
|
+
|
|
32
|
+
**1. Start the server**
|
|
33
|
+
```bash
|
|
34
|
+
freeaiagent start
|
|
35
|
+
# Running at http://localhost:7731
|
|
36
|
+
# API docs at http://localhost:7731/docs
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**2. Chat with it**
|
|
40
|
+
```bash
|
|
41
|
+
freeaiagent chat
|
|
42
|
+
# You: what is the capital of France?
|
|
43
|
+
# Agent [llama3.2:3b]: Paris.
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**3. Call it from any app**
|
|
47
|
+
```python
|
|
48
|
+
import urllib.request, json
|
|
49
|
+
|
|
50
|
+
req = urllib.request.Request(
|
|
51
|
+
"http://localhost:7731/chat",
|
|
52
|
+
data=json.dumps({"message": "summarize this for me: ..."}).encode(),
|
|
53
|
+
headers={"Content-Type": "application/json"},
|
|
54
|
+
)
|
|
55
|
+
response = json.loads(urllib.request.urlopen(req).read())["response"]
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
No pip dependencies needed in the calling app. Pure stdlib.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## CLI
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
freeaiagent start # start server (default port 7731)
|
|
66
|
+
freeaiagent start --port 8080 # custom port
|
|
67
|
+
freeaiagent start --reload # dev mode: auto-reload on code change
|
|
68
|
+
|
|
69
|
+
freeaiagent chat # interactive chat (context preserved)
|
|
70
|
+
freeaiagent chat "quick one-liner" # single message, then exit
|
|
71
|
+
|
|
72
|
+
freeaiagent task "explain this" \
|
|
73
|
+
--input "$(cat file.py)" # one-shot task, no context read/written
|
|
74
|
+
freeaiagent task "translate to French" \
|
|
75
|
+
--input "Hello world" \
|
|
76
|
+
--model mistral:7b # override model for this task
|
|
77
|
+
|
|
78
|
+
freeaiagent status # health check + active backend/model
|
|
79
|
+
freeaiagent models # list models on active backend
|
|
80
|
+
|
|
81
|
+
freeaiagent context show # print conversation history
|
|
82
|
+
freeaiagent context clear # wipe conversation history
|
|
83
|
+
|
|
84
|
+
freeaiagent config show # print current config
|
|
85
|
+
freeaiagent config set default_model mistral:7b
|
|
86
|
+
freeaiagent config set default_backend groq
|
|
87
|
+
freeaiagent config set backends.groq.api_key gsk_...
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## HTTP API
|
|
93
|
+
|
|
94
|
+
All endpoints accept and return JSON.
|
|
95
|
+
|
|
96
|
+
### `POST /chat`
|
|
97
|
+
Send a message. Conversation history is read and updated automatically.
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
curl -X POST http://localhost:7731/chat \
|
|
101
|
+
-H "Content-Type: application/json" \
|
|
102
|
+
-d '{"message": "what did I just ask you?"}'
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
```json
|
|
106
|
+
{
|
|
107
|
+
"response": "You asked me what you just asked me.",
|
|
108
|
+
"model": "llama3.2:3b",
|
|
109
|
+
"context_length": 4
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
| Field | Type | Description |
|
|
114
|
+
|---|---|---|
|
|
115
|
+
| `message` | string | required |
|
|
116
|
+
| `system` | string | optional system prompt override |
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
### `POST /task`
|
|
121
|
+
One-shot task. No context is read or written — clean slate every time.
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
curl -X POST http://localhost:7731/task \
|
|
125
|
+
-H "Content-Type: application/json" \
|
|
126
|
+
-d '{"task": "list all TODO comments", "input": "..."}'
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
```json
|
|
130
|
+
{
|
|
131
|
+
"result": "Line 42: TODO fix this\nLine 87: TODO add tests",
|
|
132
|
+
"model": "llama3.2:3b"
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
| Field | Type | Description |
|
|
137
|
+
|---|---|---|
|
|
138
|
+
| `task` | string | required — the instruction |
|
|
139
|
+
| `input` | string | optional — content to work on |
|
|
140
|
+
| `model` | string | optional — override model for this call |
|
|
141
|
+
| `system` | string | optional — override system prompt |
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
### `GET /context`
|
|
146
|
+
Returns the full conversation history.
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
{
|
|
150
|
+
"messages": [
|
|
151
|
+
{"role": "user", "content": "hello", "timestamp": "2026-06-21T10:00:00+00:00"},
|
|
152
|
+
{"role": "assistant", "content": "hi there", "timestamp": "2026-06-21T10:00:01+00:00"}
|
|
153
|
+
],
|
|
154
|
+
"total": 2
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### `DELETE /context`
|
|
159
|
+
Clears all conversation history.
|
|
160
|
+
|
|
161
|
+
```json
|
|
162
|
+
{"cleared": 4, "message": "Cleared 4 messages."}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### `GET /health`
|
|
166
|
+
```json
|
|
167
|
+
{"status": "ok", "active_backend": "ollama", "default_model": "llama3.2:3b"}
|
|
168
|
+
```
|
|
169
|
+
Returns `"status": "degraded"` with an `"error"` field if no backend is reachable.
|
|
170
|
+
|
|
171
|
+
### `GET /models`
|
|
172
|
+
```json
|
|
173
|
+
{"models": ["llama3.2:3b", "mistral:7b", "phi3:mini"]}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Configuration
|
|
179
|
+
|
|
180
|
+
Config lives at `~/.freeaiagent/config.json` and is created on first run.
|
|
181
|
+
|
|
182
|
+
```json
|
|
183
|
+
{
|
|
184
|
+
"default_backend": "ollama",
|
|
185
|
+
"default_model": "llama3.2:3b",
|
|
186
|
+
"port": 7731,
|
|
187
|
+
"backends": {
|
|
188
|
+
"ollama": {
|
|
189
|
+
"base_url": "http://localhost:11434"
|
|
190
|
+
},
|
|
191
|
+
"groq": {
|
|
192
|
+
"api_key": ""
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
"fallback_order": ["ollama", "groq"]
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Edit directly or use `freeaiagent config set <key> <value>` with dotted keys:
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
freeaiagent config set port 8080
|
|
203
|
+
freeaiagent config set backends.ollama.base_url http://192.168.1.10:11434
|
|
204
|
+
freeaiagent config set backends.groq.api_key gsk_abc123
|
|
205
|
+
freeaiagent config set default_backend groq
|
|
206
|
+
freeaiagent config set default_model llama-3.1-8b-instant
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## Backends
|
|
212
|
+
|
|
213
|
+
### Ollama (default)
|
|
214
|
+
Runs locally. No API key. No data leaves your machine.
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
# Install Ollama from https://ollama.com
|
|
218
|
+
ollama pull llama3.2:3b
|
|
219
|
+
freeaiagent start
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Any model available on your Ollama instance works. Switch with:
|
|
223
|
+
```bash
|
|
224
|
+
freeaiagent config set default_model mistral:7b
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Groq (free-tier cloud)
|
|
228
|
+
Fast inference. Free API key at [console.groq.com](https://console.groq.com).
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
freeaiagent config set backends.groq.api_key gsk_...
|
|
232
|
+
freeaiagent config set default_backend groq
|
|
233
|
+
freeaiagent config set default_model llama-3.1-8b-instant
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Free-tier models available on Groq:
|
|
237
|
+
|
|
238
|
+
| Model | Context |
|
|
239
|
+
|---|---|
|
|
240
|
+
| `llama-3.1-8b-instant` | 128k |
|
|
241
|
+
| `llama-3.3-70b-versatile` | 128k |
|
|
242
|
+
| `mixtral-8x7b-32768` | 32k |
|
|
243
|
+
| `gemma2-9b-it` | 8k |
|
|
244
|
+
|
|
245
|
+
### Automatic fallback
|
|
246
|
+
If the default backend is unreachable, `freeaiagent` tries the next one in `fallback_order` automatically. No configuration needed for this to work — just have both set up.
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## Using from another app
|
|
251
|
+
|
|
252
|
+
The agent runs as a separate process. Your app calls it over HTTP — no LLM dependencies, no model management, no context handling in your code.
|
|
253
|
+
|
|
254
|
+
**Python (stdlib only):**
|
|
255
|
+
```python
|
|
256
|
+
import urllib.request, json
|
|
257
|
+
|
|
258
|
+
def ask(message):
|
|
259
|
+
body = json.dumps({"message": message}).encode()
|
|
260
|
+
req = urllib.request.Request(
|
|
261
|
+
"http://localhost:7731/chat",
|
|
262
|
+
data=body,
|
|
263
|
+
headers={"Content-Type": "application/json"},
|
|
264
|
+
)
|
|
265
|
+
return json.loads(urllib.request.urlopen(req).read())["response"]
|
|
266
|
+
|
|
267
|
+
def run_task(task, input_text=None):
|
|
268
|
+
body = json.dumps({"task": task, "input": input_text}).encode()
|
|
269
|
+
req = urllib.request.Request(
|
|
270
|
+
"http://localhost:7731/task",
|
|
271
|
+
data=body,
|
|
272
|
+
headers={"Content-Type": "application/json"},
|
|
273
|
+
)
|
|
274
|
+
return json.loads(urllib.request.urlopen(req).read())["result"]
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
**Shell:**
|
|
278
|
+
```bash
|
|
279
|
+
curl -s -X POST http://localhost:7731/task \
|
|
280
|
+
-H "Content-Type: application/json" \
|
|
281
|
+
-d "{\"task\": \"summarize\", \"input\": \"$(cat notes.txt)\"}" \
|
|
282
|
+
| python -c "import sys,json; print(json.load(sys.stdin)['result'])"
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
**JavaScript / Node:**
|
|
286
|
+
```js
|
|
287
|
+
const res = await fetch("http://localhost:7731/chat", {
|
|
288
|
+
method: "POST",
|
|
289
|
+
headers: { "Content-Type": "application/json" },
|
|
290
|
+
body: JSON.stringify({ message: "hello" }),
|
|
291
|
+
});
|
|
292
|
+
const { response } = await res.json();
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## Context storage
|
|
298
|
+
|
|
299
|
+
Conversation history is stored in `~/.freeaiagent/context.db` (SQLite). It persists across server restarts. Clear it any time:
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
freeaiagent context clear
|
|
303
|
+
# or
|
|
304
|
+
curl -X DELETE http://localhost:7731/context
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
## Roadmap
|
|
310
|
+
|
|
311
|
+
**Phase 2 — Named sessions**
|
|
312
|
+
Multiple apps keep separate conversation histories via a `session_id` field.
|
|
313
|
+
```json
|
|
314
|
+
{"message": "hello", "session_id": "my-project"}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
**Phase 3 — Auto caller detection**
|
|
318
|
+
Sessions created automatically per caller using `X-Caller-ID` header or caller port. Zero config for multi-app setups.
|
|
319
|
+
|
|
320
|
+
**Phase 4 — More backends and features**
|
|
321
|
+
- llamafile (single-file model, no Ollama install needed)
|
|
322
|
+
- Together AI, OpenRouter
|
|
323
|
+
- Streaming responses (`/chat/stream` SSE)
|
|
324
|
+
- Tool use / function calling
|
|
325
|
+
- Minimal web UI at `localhost:7731`
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
## Development
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
git clone <repo>
|
|
333
|
+
cd freeaiagent
|
|
334
|
+
pip install -e ".[dev,groq]"
|
|
335
|
+
|
|
336
|
+
pytest # unit + integration (no LLM needed)
|
|
337
|
+
pytest tests/smoke/ -m smoke -v # smoke tests (requires Ollama running)
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
---
|
|
341
|
+
|
|
342
|
+
## License
|
|
343
|
+
|
|
344
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.0"
|