feat: Gemini bridge, browser extension hardening, shared memory
Nexus gateway (measured 2026-08-07, not assumed):
- Gemini speaks Google-GenAI (/v1beta/models/{id}:streamGenerateContent, header
api-key), NOT the Azure-OpenAI path — that returned 404 "no Route matched" and
was the cause of the reported failures. New agent/gemini_bridge.py translates
Bedrock Converse <-> Gemini in both directions.
- Only gemini-3.6-flash is subscribed; 2.5-flash/2.5-pro/3.1-flash-lite give 403,
every other name 404. Catalog corrected.
- Four Gemini rules, each previously an HTTP 400, now covered by tests:
thought signatures are mandatory, they belong to the TURN (not the individual
call), functionResponse turns must be homogeneous, arrays need `items`.
- Prompt caching is NOT available: cachePoint is accepted and ignored.
System prompt:
- Was an f-string; a code sample containing braces broke build_system_prompt at
request time (CLI and web both 500, import stayed green). Now a plain template
with __TOKEN__ placeholders. Regression guards in tests/test_system_prompt.py.
CLI:
- `agent resume` now prints the stored transcript. The history was always loaded
into the model context, only the terminal stayed empty.
Memory (new, all three surfaces):
- agent/memory.py stores notes about the user in one local file, written
atomically; memory.cnull.net remains an optional mirror that can never fail a
write. Tools memory_save/search/forget, injected into the prompt with a budget.
HTTP surface /api/memory for the extension.
Browser extension (agent/extension, first commit of the source):
- driveMode 'direct' talks to Nexus without the Python broker: Claude via
Bedrock converse, GPT via Azure-OpenAI, Gemini via Google-GenAI.
- browser_type no longer guesses the focused element — that wrote whole mails
into Outlook's subject line. Read-back now reports where the text actually
landed, so a mis-target is visible instead of silent.
- aria-labelledby is resolved across all ids (it is a list); contenteditable is
interactive and marked editable. Without this, subject and message body look
identical to the model.
- Hard block against sending mail, independent of riskMode.
- Runs survive the panel: events are buffered and replayed by sequence number.
- Image input (paste, file, drag&drop), on-page glow/spotlight, memory tools.
Cost: fixed tokens per round 11434 -> 6540 (-43%) by trimming tool schemas,
dropping gateway docs from the browser prompt and sending site knowledge only
where it applies.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
# Nexus Browser Pilot
|
||||
|
||||
Chrome/Brave-Extension, die den Browser **wie ein Mensch bedient**: echter Mauszeiger,
|
||||
echte Tastatur, echte Ereignisse. Sie handelt selbstständig und fragt nicht nach — es sei
|
||||
denn, du schaltest den Nachfrage-Modus ein.
|
||||
|
||||
---
|
||||
|
||||
## Neue Features
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **Markdown-Output** | Assistenten-Antworten werden als Markdown gerendert — Code-Blöcke, Listen, Tabellen, Links. |
|
||||
| **Konversationsverlauf** | Gespräche werden persistent gespeichert und überleben Panel-Schließen und Browser-Neustart. Über das Dropdown wechselst du zwischen Konversationen. |
|
||||
| **Memory-Anbindung** | Anbindung an `memory.cnull.net` — relevante Erinnerungen werden automatisch als Kontext injiziert, Gespräche können per Klick synchronisiert werden. |
|
||||
| **Provider-Wahl** | Neben Anthropic und OpenAI jetzt auch **Requesty** (OpenAI-kompatibel). Basis-URL und Modell frei wählbar. |
|
||||
| **Coding-Agent-Anbindung** | Im Broker-Modus verbindet sich die Extension mit dem lokalen Coding-Agent (CLI/Web UI via `agent-web.bat`). |
|
||||
| **System-Prompt** | Frei editierbarer System-Prompt in den Einstellungen (driveMode 'direct'). |
|
||||
|
||||
---
|
||||
|
||||
## Was sie anders macht
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **Echte Eingaben** | Alle Klicks und Tastendrücke laufen über `chrome.debugger` + CDP `Input.dispatch*` und tragen `isTrusted=true`. Damit funktionieren Canvas/WebGL, natives Drag & Drop, native `<select>`-Dropdowns und strenge Enterprise-SPAs. |
|
||||
| **Sehen und zielen** | `browser_computer` arbeitet auf Pixelkoordinaten eines Screenshots — Screenshot ansehen, dann dorthin klicken. Genau wie ein Mensch. |
|
||||
| **Sichtbarer Mauszeiger** | Ein Overlay zeigt, wohin der Agent fährt und klickt. Du siehst zu, statt zu raten. |
|
||||
| **Autonom per Standard** | Keine Blocklisten, keine Domain-Sperren, keine Rückfragen. `riskMode` steht auf `off`. |
|
||||
| **Zuschaltbare Bestätigung** | `riskMode: 'confirm'` fragt **nur** vor Aktionen mit echter Außenwirkung — Formular absenden, Nachricht senden, Kauf, Löschen, Zahlung. Erkannt wird die **Wirkung**, nicht der Tool-Name. |
|
||||
|
||||
---
|
||||
|
||||
## Installation in Brave
|
||||
|
||||
1. `brave://extensions` öffnen
|
||||
2. Oben rechts **Entwicklermodus** einschalten
|
||||
3. **Entpackte Erweiterung laden** → dieses Verzeichnis wählen:
|
||||
`C:\Users\TTOMCZA\MB\extension`
|
||||
|
||||
Das war's — die Installation bleibt bestehen. Nach Codeänderungen genügt der
|
||||
**Aktualisieren**-Knopf auf derselben Seite.
|
||||
|
||||
> Brave zeigt beim ersten echten Klick eine Leiste „… wird debuggt". Das ist der Preis für
|
||||
> `isTrusted=true` und lässt sich nur per Startflag `--silent-debugger-extension-api`
|
||||
> oder Enterprise-Policy unterdrücken.
|
||||
|
||||
### Bauen
|
||||
|
||||
```bash
|
||||
cd extension
|
||||
npm install
|
||||
npm run build # erzeugt dist/ (prebuild generiert die Tool-Schemas)
|
||||
npm run typecheck
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Die drei Antriebe
|
||||
|
||||
Alle drei münden im selben Engpass `runTool()` — der Risikomodus gilt also überall.
|
||||
|
||||
**1. Broker (Standard).** Der Agent-Loop läuft in `agent/ext_bridge.py` und spricht über das
|
||||
Nexus-Gateway mit dem Modell. Starten:
|
||||
|
||||
```bat
|
||||
agent-web.bat
|
||||
```
|
||||
|
||||
Die Extension verbindet sich dann automatisch mit `ws://127.0.0.1:8765/ext/ws`.
|
||||
**Ohne laufenden Broker gibt es keine Verbindung** — das ist die häufigste Ursache für
|
||||
„nicht verbunden" im Panel.
|
||||
|
||||
**2. Eingebauter Loop.** In den Einstellungen `driveMode` auf `direct` stellen und einen
|
||||
Endpunkt eintragen (Anthropic oder OpenAI-kompatibel). Läuft ohne Python, ohne Broker.
|
||||
|
||||
**3. MCP-Bridge.** Für Claude Code, Claude Desktop oder Cursor:
|
||||
|
||||
```bash
|
||||
cd extension/mcp-bridge
|
||||
node server.js
|
||||
```
|
||||
|
||||
Der Server druckt beim Start ein Token und die fertige `brokerUrl`. Details in
|
||||
`mcp-bridge/README.md`.
|
||||
|
||||
---
|
||||
|
||||
## Bedienung
|
||||
|
||||
Klick auf den Mercedes-Stern in der Symbolleiste öffnet das Side Panel.
|
||||
|
||||
- **Autonom** (Standard) — handelt ohne Rückfrage
|
||||
- **Nachfragen** — fragt vor Absenden, Kauf, Löschen
|
||||
|
||||
Der Moduswechsel wirkt sofort und für alle Antriebe.
|
||||
|
||||
---
|
||||
|
||||
## Werkzeuge
|
||||
|
||||
31 Tools, definiert in `tools/schema/*.json`. Diese Dateien sind die **einzige Quelle**:
|
||||
`tools/generate_tool_defs.py` erzeugt daraus sowohl die Python-Definitionen für den Broker
|
||||
als auch die TypeScript-Typen für die Extension. Ein neues Tool wird dort angelegt, nicht
|
||||
an drei Stellen gepflegt.
|
||||
|
||||
Kernstücke:
|
||||
|
||||
- `browser_computer` — koordinatenbasiert: `screenshot`, `left_click`, `double_click`,
|
||||
`left_click_drag`, `scroll`, `type`, `key`, `hold_key`, `mouse_move` …
|
||||
- `browser_read_page` — Barrierefreiheits-Baum mit stabilen `ref_id`s, `type`-Attribut und
|
||||
Koordinaten je Element
|
||||
- `browser_find` — Element per natürlicher Beschreibung
|
||||
- `browser_execute_js` — läuft im **MAIN world**, sieht also `window.React`, App-State usw.
|
||||
- `browser_read_network` / `browser_read_console` — echter CDP-Mitschnitt, Konsole per
|
||||
MAIN-world-Hook (nicht durch die CSP der Seite blockierbar)
|
||||
|
||||
---
|
||||
|
||||
## Aufbau
|
||||
|
||||
```
|
||||
extension/
|
||||
├── manifest.json
|
||||
├── src/
|
||||
│ ├── background/
|
||||
│ │ ├── index.ts Engpass runTool(), Tool-Dispatch, Panel-Relay
|
||||
│ │ ├── cdp.ts CDP-Eingabeschicht — Maus, Tastatur, Screenshot, Netzwerk
|
||||
│ │ ├── computer.ts koordinatenbasiertes Bedienen
|
||||
│ │ ├── risk.ts wirkungsbasierte Risikoerkennung
|
||||
│ │ ├── agent.ts eingebauter Agent-Loop
|
||||
│ │ └── llm.ts Anthropic-/OpenAI-Adapter
|
||||
│ ├── content/
|
||||
│ │ ├── inject.ts ISOLATED world: Brücke und Seitenfehler
|
||||
│ │ ├── console-hook.ts MAIN world: Konsolen-Erfassung
|
||||
│ │ └── cursor.ts sichtbarer Mauszeiger
|
||||
│ ├── sidepanel/ Bedienoberfläche
|
||||
│ └── shared/ Konfiguration und Protokolltypen
|
||||
└── mcp-bridge/ MCP-Server für externe Clients
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Abnahme
|
||||
|
||||
Der Funktionsnachweis läuft gegen ein echtes Brave mit einer Prüfseite, die `isTrusted`
|
||||
protokolliert. Stand der letzten Ausführung: **35 von 35 Prüfungen bestanden** — darunter
|
||||
echter Canvas-Klick mit korrekter Koordinate, echte Tastatureingabe mit `keyCode`,
|
||||
Submit-Erkennung im Baum, MAIN-world-Zugriff, Konsolen- und Netzwerkmitschnitt sowie der
|
||||
vollständige Bestätigungskreislauf (Dialog → „Ausführen" → ausgeführt, „Abbrechen" →
|
||||
`USER_DECLINED`).
|
||||
Reference in New Issue
Block a user