chore: Fork als agenttwo-tools aufsetzen

Basis für die Tool-Calling- und Vision-Entwicklung. Die Historie von agenttwo
bleibt erhalten, damit sich Fixes aus der Basis per cherry-pick übernehmen
lassen; das Remote upstream zeigt dafür auf Jeuners/agenttwo.

Eigene Ports, damit beide Projekte gleichzeitig laufen können:
- Backend 8787 -> 8788, Vite 5173 -> 5174 samt Proxy-Zielen
- Origin-Allowlist in security.ts entsprechend auf 5174/8788
- OpenRouter-Attribution (HTTP-Referer, X-Title) angepasst

Die SQLite-Datei liegt wie gehabt neben dem Server, beide Instanzen haben
dadurch getrennte Sessions.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S1NXUpHbxTusqQmsjrFfbU
This commit is contained in:
Jeuner 2026-08-26 17:35:51 +02:00
parent e721540b80
commit e48228c570
7 changed files with 31 additions and 23 deletions

View file

@ -1,4 +1,10 @@
# oxagenttwo
# agenttwo-tools
> Fork von [agenttwo](https://github.com/Jeuners/agenttwo). Die Basis bleibt dort
> unverändert; hier kommen Tool-Calling und Vision dazu. Läuft auf eigenen Ports
> (Backend 8788, Frontend 5174), damit beide Projekte parallel laufen können.
> Fixes aus der Basis lassen sich per `git cherry-pick` aus dem Remote
> `upstream` übernehmen.
Voice-Chat-Oberfläche für lokale und Cloud-LLMs: lokales Qwen3 über
[Ollama](https://ollama.com), optionaler Fallback auf
@ -77,7 +83,7 @@ Weitere optionale Variablen mit ihren Defaults:
| Variable | Default |
|----------------------|--------------------------------------------------|
| `PORT` | `8787` |
| `PORT` | `8788` |
| `OLLAMA_URL` | `http://localhost:11434` |
| `MODEL` | `qwen3.5:latest` |
| `WHISPER_MODEL` | `~/whisper-models/ggml-large-v3-turbo.bin` |
@ -92,12 +98,12 @@ Der Server hat **keine Authentifizierung** und lauscht deshalb bewusst nur auf
Browser geöffnet ist, kann `localhost` per `fetch()` oder WebSocket erreichen.
Deshalb prüfen sowohl die HTTP-Endpunkte als auch der WebSocket-Handshake die
`Origin` gegen eine Allowlist (`server/src/security.ts`) — Standard sind
`localhost`/`127.0.0.1` auf Port 5173 und 8787.
`localhost`/`127.0.0.1` auf Port 5174 und 8788.
Läuft das Frontend woanders, die Origin ergänzen:
```bash
ALLOWED_ORIGINS=http://192.168.1.50:5173
ALLOWED_ORIGINS=http://192.168.1.50:5174
```
Weitere Maßnahmen: Rate-Limits auf `/api/stt` (10/min) und `/api/tts` (30/min),
@ -111,7 +117,7 @@ echte Authentifizierung.
```bash
npm install
npm run dev # Server (:8787) und Vite-Dev-Server (:5173) parallel
npm run dev # Server (:8788) und Vite-Dev-Server (:5174) parallel
```
Einzeln:

16
package-lock.json generated
View file

@ -1,16 +1,19 @@
{
"name": "oxagenttwo",
"name": "agenttwo-tools",
"version": "0.1.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "oxagenttwo",
"name": "agenttwo-tools",
"version": "0.1.0",
"workspaces": [
"server",
"web"
]
],
"engines": {
"node": ">=22.5.0"
}
},
"node_modules/@babel/code-frame": {
"version": "7.29.7",
@ -4651,7 +4654,6 @@
"version": "8.21.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.21.3.tgz",
"integrity": "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10.0.0"
@ -4690,14 +4692,14 @@
"version": "0.1.0",
"dependencies": {
"@fastify/cors": "^10.0.1",
"fastify": "^5.2.1"
"fastify": "^5.2.1",
"ws": "^8.18.0"
},
"devDependencies": {
"@types/node": "^22.13.0",
"@types/ws": "^8.5.14",
"tsx": "^4.19.3",
"typescript": "^5.7.3",
"ws": "^8.18.0"
"typescript": "^5.7.3"
}
},
"web": {

View file

@ -1,5 +1,5 @@
{
"name": "oxagenttwo",
"name": "agenttwo-tools",
"private": true,
"version": "0.1.0",
"workspaces": [

View file

@ -27,7 +27,7 @@ try {
/* keine .env vorhanden */
}
const PORT = Number(process.env.PORT ?? 8787);
const PORT = Number(process.env.PORT ?? 8788);
const OLLAMA_URL = process.env.OLLAMA_URL ?? "http://localhost:11434";
const app = Fastify({ logger: true, bodyLimit: MAX_AUDIO_BYTES });

View file

@ -50,8 +50,8 @@ export async function streamOpenRouter(
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
"HTTP-Referer": "http://localhost:5173",
"X-Title": "oxagenttwo",
"HTTP-Referer": "http://localhost:5174",
"X-Title": "agenttwo-tools",
},
body: JSON.stringify({
model: opts.model,

View file

@ -8,10 +8,10 @@
*/
const DEFAULT_ORIGINS = [
"http://localhost:5173",
"http://127.0.0.1:5173",
"http://localhost:8787",
"http://127.0.0.1:8787",
"http://localhost:5174",
"http://127.0.0.1:5174",
"http://localhost:8788",
"http://127.0.0.1:8788",
];
/** Zusätzliche Origins via ALLOWED_ORIGINS="https://a.example,https://b.example". */

View file

@ -4,11 +4,11 @@ import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react()],
server: {
port: 5173,
port: 5174,
proxy: {
"/api": "http://127.0.0.1:8787",
"/api": "http://127.0.0.1:8788",
"/ws": {
target: "ws://127.0.0.1:8787",
target: "ws://127.0.0.1:8788",
ws: true,
},
},