<div align="center">

<img src="./assets/frouter.png" alt="Frouter" width="180" />

# Frouter

> Agentic Gemini proxy with multi-account OAuth, token saving, and OpenAI-compatible API

[![npm version](https://img.shields.io/npm/v/f2router.svg?style=flat-square)](https://www.npmjs.com/package/f2router)
[![License: Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-green.svg?style=flat-square)](./LICENSE)
[![CI Status](https://img.shields.io/github/actions/workflow/status/keyreyla/Frouter/ci.yml?style=flat-square&label=CI)](https://github.com/keyreyla/Frouter/actions/workflows/ci.yml)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.3-blue?style=flat-square&logo=typescript&logoColor=white)](https://www.typescriptlang.org)
[![Node.js](https://img.shields.io/badge/Node.js-20-green?style=flat-square&logo=node.js&logoColor=white)](https://nodejs.org)

[Overview](#overview) • [Getting Started](#getting-started) • [Architecture](#architecture) • [Configuration](#configuration) • [CLI Reference](#cli-reference) • [Troubleshooting](#troubleshooting)

</div>

---

## Overview

Frouter is an agentic proxy that sits between your AI coding tools and Google Gemini. It pools multiple Google accounts via OAuth, automatically rotates on rate limits, and compresses prompts to reduce token usage.

## Getting Started

### Prerequisites

- Node.js 20+
- npm
- A Google account with Gemini access

### Installation

Install globally via npm:

```bash
npm install -g f2router
```

Verify installation:

```bash
frouter --version
```

### Quick Start

Add your first account:

```bash
frouter add-account gemini
```

Start the proxy:

```bash
frouter start
```

Point your tools to `http://localhost:20129/v1` using any OpenAI-compatible client.

### Using with AI Coding Tools

Frouter works with any tool that supports custom OpenAI endpoints.

**Aider**

```bash
OPENAI_API_BASE=http://localhost:20129/v1 aider
```

**Continue.dev**

```json
{
  "models": [{
    "title": "Frouter Gemini",
    "provider": "openai",
    "model": "gemini-pro",
    "apiBase": "http://localhost:20129/v1"
  }]
}
```

**OpenCode**

```bash
OPENAI_BASE_URL=http://localhost:20129/v1 opencode
```

## Architecture

```mermaid
sequenceDiagram
    participant C as Client
    participant F as Frouter
    participant T as Token Saver
    participant A as Account Pool
    participant G as Gemini API

    C->>F: POST /v1/chat/completions
    F->>T: compress + deduplicate
    T-->>F: slimmed payload
    F->>A: getNextAccount()
    A-->>F: account with valid token
    F->>G: httponly request
    G-->>F: completion
    F-->>C: OpenAI-compatible response
```

### Request Pipeline

1. **Client** sends an OpenAI-compatible request to `http://localhost:20129/v1/chat/completions`.
2. **Frouter** receives the request and passes it through the **Token Saver** pipeline.
3. **Token Saver** applies semantic compression, code diffing, and relevance filtering to reduce token count.
4. **Account Pool** selects the next available account based on priority and health status.
5. **Gemini API** processes the request and returns the completion.
6. **Frouter** transforms the response to OpenAI format and returns it to the client.

### Token Saving

Frouter targets up to 80% token reduction using these techniques:

- **Semantic compression** — summarizes older conversation turns into compact notes
- **Code diffing** — sends only changed functions with surrounding context
- **Relevance scoring** — drops chunks below a relevance threshold
- **Smart truncation** — keeps the beginning and end of long content, trims the middle
- **Prompt deduplication** — caches identical system prompt sections
- **Token budget** — enforces a maximum token limit per request

## Configuration

### Environment Variables

| Variable | Description | Default |
|----------|-------------|---------|
| `PORT` | Proxy port | `20129` |
| `HOST` | Bind address | `0.0.0.0` |
| `TOKEN_SAVING_ENABLED` | Enable token compression | `true` |
| `TOKEN_SAVING_TARGET_PERCENT` | Target reduction | `80` |

### Account Storage

Accounts are persisted locally at `~/.frouter/accounts.json`. Tokens are stored securely and refreshed automatically when needed.

## CLI Reference

```
Usage: frouter [options] [command]

Options:
  -p, --port <port>     Proxy port (default: 20129)
  -H, --host <host>     Bind address (default: 0.0.0.0)
  -n, --no-browser      Do not open browser on start
  -l, --log             Show server logs
  -t, --tray            Run in background tray
  --skip-update         Skip auto-update check
  -h, --help            Show help
  -v, --version         Show version

Commands:
  add-account <type>    Add account (gemini | antigravity)
  remove-account <id>   Remove account by ID
  list-accounts         List all configured accounts
  config set <key>      Set config value
  status                Show system status
  start                 Start the proxy server
```

### Commands

**Add Account**

```bash
frouter add-account gemini
frouter add-account antigravity
```

Opens a browser window for Google OAuth. After authentication, the token is saved to `~/.frouter/accounts.json`.

**List Accounts**

```bash
frouter list-accounts
```

Shows all configured accounts with their status and priority.

**Remove Account**

```bash
frouter remove-account <id>
```

**Show Status**

```bash
frouter status
```

Displays active accounts, token budget usage, and compression ratio.

## Dashboard

When running, the web dashboard is available at `http://localhost:20129`.

| Section | Description |
|---------|-------------|
| Dashboard | Server status, active accounts, requests today, token savings |
| Accounts | Manage accounts, add/remove, view quota usage |
| Config | Edit settings, export/import configuration |
| Logs | Real-time activity logs with filtering |
| Tokens | Token usage graphs and savings breakdown |

## Development

### Building

```bash
# Install root dependencies
npm install

# Install frontend dependencies
cd web && npm install

# Build everything
npm run build
```

### Testing

```bash
# Run tests
npm test

# Run with coverage
npm run test:coverage
```

### Dev Servers

```bash
# Backend (Express + CLI)
npm run dev

# Frontend (Vite)
npm run dev:web
```

## CI/CD

GitHub Actions runs on every push and PR:

1. Checkout code
2. Setup Node.js 20
3. Install dependencies (`npm ci` + `cd web && npm ci`)
4. Type check (`tsc --noEmit`)
5. Build (`npm run build`)
6. Test (`npm test`)

Status badge: ![CI Status](https://img.shields.io/github/actions/workflow/status/keyreyla/Frouter/ci.yml?style=flat-square&label=CI)

## Topics

gemini ai proxy agentic cli typescript openai-compatible multi-account token-saving codex opencode aider oauth google-ai

## Troubleshooting

**Port 20129 is already in use**

```bash
frouter start --port 20130
```

**OAuth flow does not complete**

Make sure you can open a browser in the current environment. The CLI uses a local HTTP server on a random port for the OAuth callback.

**Token saving is below target**

Check the dashboard for per-request savings. Long conversations and code-heavy requests see the highest reduction.

## Feedback

Issues and feature requests are welcome at [github.com/keyreyla/Frouter/issues](https://github.com/keyreyla/Frouter/issues).
