diff --git a/.claude/skills/doc-guide/SKILL.md b/.claude/skills/doc-guide/SKILL.md new file mode 100644 index 000000000..09249f548 --- /dev/null +++ b/.claude/skills/doc-guide/SKILL.md @@ -0,0 +1,231 @@ +--- +name: doc-guide +description: Generate or update the Tingly-Box Web UI guide at docs/guide/. Use when the user asks to "update the docs", "write documentation", "add a guide page", "retake screenshots", or when UI pages have changed and the guide needs to reflect them. Produces bilingual (zh + en) markdown under docs/guide/zh/ and docs/guide/en/, with screenshots in docs/guide/images/. +--- + +# Tingly-Box Guide Documentation + +The guide lives at `docs/guide/` (force-added because `docs/` is in `.gitignore`): + +``` +docs/guide/ +├── README.md ← language selector (2 lines) +├── zh/ +│ ├── README.md ← Chinese TOC +│ └── NN-.md ← numbered content files +├── en/ +│ ├── README.md ← English TOC +│ └── NN-.md ← English mirrors of zh files +└── images/ + └── *.png ← screenshots referenced by both zh/ and en/ +``` + +## Structure conventions + +- Files are numbered `01`–`NN` in reading order. +- Each topic is its own file (zh + en pair). The image path in both is `../images/.png`. +- TOC sections in both README files: + 1. Getting Started + 2. Agent Scenarios + 3. Configuration Chain + 4. Other Main Entry Points + 5. System Settings + 6. Experimental Features + 7. Advanced Topics (routing rules, etc.) + +## Writing a new doc page + +1. Write the Chinese version under `docs/guide/zh/`. +2. Translate it to English under `docs/guide/en/`. +3. Add an entry to both `docs/guide/zh/README.md` and `docs/guide/en/README.md`. +4. Stage with `git add -f` (the `docs/` tree is gitignored): + +```bash +git add -f docs/guide/zh/.md docs/guide/en/.md +git add -f docs/guide/zh/README.md docs/guide/en/README.md +# images (if new): +git add -f docs/guide/images/.png +``` + +## Taking screenshots + +All screenshots are captured by a single script: + +``` +.claude/skills/doc-guide/screenshot-docs.mjs +``` + +### Prerequisites (once per fresh container) + +**1. Start the mock dev server** + +```bash +cd frontend +USE_MOCK=true npm run dev:mock # serves on :3000 +``` + +`USE_MOCK=true` must be set as a shell env var — vite reads it from +`process.env` before `.env.mock` is applied. Without it you get 502s. + +Wait until ready: +```bash +until curl -fs http://localhost:3000 >/dev/null; do sleep 1; done +``` + +**2. Install Playwright (not in package.json)** + +```bash +cd frontend && npm i -D playwright +``` + +Playwright is tooling-only; do NOT commit `package.json` changes. +Revert if accidentally staged: `git checkout -- frontend/package.json`. + +**3. Chromium auto-detection** + +The script tries these paths in order: +- `/opt/pw-browsers/chromium-1194/chrome-linux/chrome` ← pre-installed in this container +- `/opt/pw-browsers/chromium_headless_shell-1194/…/chrome-headless-shell` +- `/tmp/chrome/chrome-linux64/chrome` ← manually downloaded fallback + +If the pre-installed path is missing (different container build), download Chrome for Testing: + +```bash +mkdir -p /tmp/chrome && cd /tmp/chrome +curl -fsSL -o chrome.zip \ + "https://storage.googleapis.com/chrome-for-testing-public/148.0.7778.96/linux64/chrome-linux64.zip" +unzip -q chrome.zip +``` + +`cdn.playwright.dev` is blocked by the container network policy; use the +`storage.googleapis.com/chrome-for-testing-public/` URL instead. + +**4. Fix recharts / es-toolkit Vite error** (if you see `require_isUnsafeProperty is not a function`) + +Rolldown inlines `es-toolkit/compat/*.js` CJS shims with broken IIFE-helper naming. +Patch them once per container: + +```bash +for func in get isPlainObject last maxBy minBy omit range sortBy sumBy throttle uniqBy; do + echo "export { ${func} as default } from '../dist/compat/index.mjs';" \ + > frontend/node_modules/es-toolkit/compat/${func}.js +done +rm -rf frontend/node_modules/.vite +``` + +### Run + +From repo root: + +```bash +node .claude/skills/doc-guide/screenshot-docs.mjs +``` + +The script outputs all PNGs directly to `docs/guide/images/`. It runs three batches: + +| Batch | What | +|-------|------| +| 1 | 18 top-level pages (full viewport, mock data) | +| 2 | Detail / interaction shots (config modal, routing-related pages) | +| 3 | Routing graph (claude-code and sdk-proxy scenario pages) | + +### Auth token injection + +`src/contexts/AuthContext` redirects every route to the login screen when +`localStorage.user_auth_token` is missing. The script seeds it via +`context.addInitScript()` before any navigation, so all pages load authenticated. + +### Feature flags + +Guardrails and MCP pages only appear when their feature flags are enabled. +The script sets `feature_guardrails` and `feature_mcp` in localStorage so +those pages render correctly. + +### Compressing screenshots (recommended) + +The capture script writes plain `page.screenshot()` PNGs, which run +60–160 KB each — the doc set adds up fast (30+ images). Compress +after capturing, before committing, with `pngquant` (lossy, ~60–70% +smaller, no visible quality loss on UI screenshots): + +```bash +apt-get install -y pngquant # once per fresh container +cd docs/guide/images +for f in *.png; do + pngquant --quality=75-92 --strip --force --skip-if-larger --output "/tmp/pq_$f" "$f" + [ -f "/tmp/pq_$f" ] && mv "/tmp/pq_$f" "$f" +done +``` + +`oxipng`, `sharp`, or `Pillow` also work if `pngquant` isn't available. +Spot-check a few compressed images (Read tool) before committing — +text and fine UI lines should still be crisp. + +## Routing graph screenshots + +The routing graph (Direct/Tier mode, circuit breaker, Smart routing with +SmartOp conditions) is embedded in each scenario's rule card. **Mock mode +renders it** — the mock API returns a default rule with tier config. + +For the most representative shot, use `/agent/claude_code` (Direct/Tier) and +`/agent/sdk-proxy` (often shows a simpler single-tier layout). + +To capture Smart routing mode, add a click action in the script that targets +the Smart toggle button in the `EntryNode` at the top of the rule card: + +```js +action: async (page) => { + // Click the Smart toggle (AutoAwesome icon button in the EntryNode) + const smartBtn = await page.$('[data-mode="smart"], button[aria-label*="Smart"]'); + if (smartBtn) { await smartBtn.click(); await page.waitForTimeout(1500); } +} +``` + +## Routing system reference + +### Direct routing (Tier mode) + +Services are arranged in priority tiers (T0 = highest). Within a tier: round-robin +load sharing. Across tiers: failover when all services in the current tier have +open circuits. + +Circuit breaker per service: **Closed** → (3 failures) → **Open** → (30s cooldown) +→ **HalfOpen** (probe) → Closed or back to Open. + +Mid-request failover via `firstChunkGate` buffer: if upstream fails before the +first response chunk arrives, the request transparently retries on another service. + +### Smart routing + +`smartEnabled: true` activates a chain of SmartOp sub-rules. First-match wins. +Each sub-rule uses AND logic across its conditions. The last rule must be +unconditional (ops=[]) as a catch-all. + +SmartOp condition keys: `agent.claude_code` (main/subagent/compact), `token` +(ge/le N), `thinking` (on/off), `service_ttft` (fastest/fast/slow/slowest), +`service_capacity` (available/degraded/unavailable), `context_system` +(exists/missing), `latest_user` (text/image/file/rich). + +### Rule extension flags + +Flags live in `internal/typ/flag_registry.go` (backend source of truth) and +are rendered in `FlagCatalogDialog.tsx`. Categories: + +- **App**: `cursor_compat`, `cursor_compat_auto`, `claude_code_compat` +- **Request (OpenAI)**: `custom_user_agent`, `openai_endpoint_override`, + `use_max_completion_tokens`, `use_max_tokens`, `block_tools` +- **Response**: `skip_usage` +- **Reasoning**: `thinking_effort` (off / low ~1K / medium ~5K / high ~20K / max ~32K) +- **Vision**: `vision_proxy_service` (service_ref — model picker) +- **Routing**: `session_affinity` (TTL in seconds; 0 = disabled) + +## Committing docs + +All content under `docs/` is gitignored. Always use `git add -f`: + +```bash +git add -f docs/guide/zh/ docs/guide/en/ +git add -f docs/guide/images/.png +# Modified TOC files are already tracked, no -f needed: +git add docs/guide/zh/README.md docs/guide/en/README.md +``` diff --git a/.claude/skills/doc-guide/screenshot-docs.mjs b/.claude/skills/doc-guide/screenshot-docs.mjs new file mode 100644 index 000000000..6946c93ac --- /dev/null +++ b/.claude/skills/doc-guide/screenshot-docs.mjs @@ -0,0 +1,328 @@ +/** + * screenshot-docs.mjs + * + * Captures all docs/guide/images screenshots in one pass. + * Run from repo root: node .claude/skills/doc-guide/screenshot-docs.mjs + * + * Prerequisites: + * - Mock dev server running: cd frontend && USE_MOCK=true npm run dev:mock + * - Playwright installed in frontend/: cd frontend && npm i -D playwright + * - es-toolkit shim patched (see doc-guide SKILL.md) if recharts errors appear + * + * Note: mock mode auto-seeds user_auth_token in main.tsx, so no manual + * localStorage injection is needed for auth. Feature flags and onboarding + * suppression are still injected via addInitScript below. + */ + +// playwright lives in frontend/node_modules; createRequire resolves from cwd +// when called as: node .claude/skills/doc-guide/screenshot-docs.mjs (repo root) +import { createRequire } from 'module'; +const { chromium } = createRequire(new URL('file:///home/user/tingly-box/frontend/'))('playwright'); +import path from 'path'; +import fs from 'fs'; +import { fileURLToPath } from 'url'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const REPO = path.resolve(__dirname, '../../../'); +const OUT_DIR = path.join(REPO, 'docs/guide/images'); +const BASE = 'http://localhost:3000'; + +// Auto-detect Chromium: prefer pre-installed container path, fall back to +// a manually downloaded Chrome for Testing at /tmp/chrome. +const CHROME = [ + '/opt/pw-browsers/chromium-1194/chrome-linux/chrome', + '/opt/pw-browsers/chromium_headless_shell-1194/chrome-headless-shell-linux64/chrome-headless-shell', + '/tmp/chrome/chrome-linux64/chrome', +].find(p => fs.existsSync(p)); +if (!CHROME) { + console.error('No Chromium found. See SKILL.md for download instructions.'); + process.exit(1); +} +console.log(`Using Chrome: ${CHROME}`); +fs.mkdirSync(OUT_DIR, { recursive: true }); + +const browser = await chromium.launch({ + executablePath: CHROME, + args: ['--no-sandbox', '--disable-dev-shm-usage'], + headless: true, +}); + +// --- Context --------------------------------------------------------------- +// auth token is auto-seeded by MSW mock in main.tsx; we only need feature flags +// and onboarding suppression here. +const ctx = await browser.newContext({ viewport: { width: 1440, height: 900 } }); +await ctx.addInitScript(() => { + localStorage.setItem('feature_guardrails', 'true'); + localStorage.setItem('feature_mcp', 'true'); + // Suppress the onboarding wizard overlay on scenario pages + localStorage.setItem('onboarding_complete', 'true'); + localStorage.setItem('onboarding_dismissed', 'true'); + // Suppress the once-per-user Direct Routing Guide overlay (captured + // separately, deliberately unsuppressed, further down this script). + localStorage.setItem('tb.routingGuideAutoShown', 'true'); +}); + +// --- Helpers --------------------------------------------------------------- + +async function shot(name, route, { action, waitMs = 3500 } = {}) { + const page = await ctx.newPage(); + page.on('pageerror', err => { + if (!err.message.includes('Failed to get version')) + console.error(` [err] ${err.message.slice(0, 80)}`); + }); + await page.goto(`${BASE}${route}`, { waitUntil: 'domcontentloaded', timeout: 20000 }); + await page.waitForTimeout(waitMs); + if (action) { + await action(page); + await page.waitForTimeout(1500); + } + const out = path.join(OUT_DIR, `${name}.png`); + await page.screenshot({ path: out, fullPage: false }); + const size = fs.statSync(out).size; + console.log(` [${size > 10000 ? 'OK ' : 'BLNK'}] ${name}.png (${size}b)`); + await page.close(); +} + +// Scroll the page's internal overflow container up by `px` pixels so the +// target element has breathing room above it in the viewport. +async function nudgeScrollUp(page, px = 120) { + await page.evaluate((px) => { + for (const n of document.querySelectorAll('*')) { + const s = window.getComputedStyle(n); + if ((s.overflowY === 'auto' || s.overflowY === 'scroll') && n.scrollHeight > n.clientHeight) { + n.scrollTop = Math.max(0, n.scrollTop - px); + break; + } + } + }, px); + await page.waitForTimeout(400); +} + +// --- Batch 1: top-level pages ---------------------------------------------- +console.log('\nBatch 1: top-level pages'); + +await shot('scenario-overview', '/agent'); +await shot('claude-code', '/agent/claude_code', { waitMs: 4500 }); +await shot('credentials', '/credentials'); +await shot('dashboard', '/dashboard/7d', { waitMs: 4000 }); +await shot('guardrails', '/guardrails', { waitMs: 4000 }); +await shot('guardrails-rules', '/guardrails/rules', { waitMs: 4500 }); +await shot('guardrails-history', '/guardrails/history', { waitMs: 4000 }); +await shot('mcp', '/mcp/sources', { waitMs: 4000 }); +await shot('system', '/system'); +await shot('remote-control', '/remote-control/telegram'); +await shot('remote-coder', '/remote-coder/chat'); +await shot('experimental', '/system/experimental'); +await shot('api-tokens', '/tingly-box-token'); +await shot('virtual-models', '/credentials/virtual-models'); +await shot('access-control', '/access-control'); +await shot('prompt-skills', '/prompt/skill'); +await shot('imagegen', '/agent/imagegen', { waitMs: 4500 }); +await shot('playground', '/agent/playground', { waitMs: 4500 }); + +// --- Batch 2: detail / interaction shots ----------------------------------- +console.log('\nBatch 2: detail & interaction shots'); + +await shot('dashboard-today', '/dashboard/today', { waitMs: 4500 }); +await shot('remote-coder-sessions', '/remote-coder/sessions'); +await shot('guardrails-groups', '/guardrails/groups', { waitMs: 4000 }); +await shot('mcp-local-mode', '/mcp/local-mode'); +await shot('logs', '/system/logs'); +await shot('servertool', '/tools/servertool'); + +// Onboarding — shown without the suppression flags so the wizard appears. +{ + const page = await browser.newPage(); + page.on('pageerror', err => { + if (!err.message.includes('Failed to get version')) + console.error(` [err] ${err.message.slice(0, 80)}`); + }); + await page.addInitScript(() => { + localStorage.setItem('feature_guardrails', 'true'); + localStorage.setItem('feature_mcp', 'true'); + // intentionally NOT setting onboarding_complete so the wizard renders + }); + await page.goto(`${BASE}/onboarding`, { waitUntil: 'domcontentloaded', timeout: 20000 }); + await page.waitForTimeout(3500); + const out = path.join(OUT_DIR, 'onboarding.png'); + await page.screenshot({ path: out, fullPage: false }); + console.log(` [${fs.statSync(out).size > 10000 ? 'OK ' : 'BLNK'}] onboarding.png (${fs.statSync(out).size}b)`); + await page.close(); +} + +// Config modal on the Claude Code page +await shot('claude-code-config-modal', '/agent/claude_code', { + waitMs: 3000, + action: async (page) => { + const btns = await page.locator('button').all(); + for (const btn of btns) { + const txt = (await btn.textContent() || '').trim(); + if (txt === 'Config' || txt === 'Auto Config') { + await btn.click(); + await page.waitForTimeout(2000); + break; + } + } + }, +}); + +// Connect AI dialog on the credentials page +await shot('connect-ai', '/credentials', { + waitMs: 2500, + action: async (page) => { + try { + const btn = page.getByRole('button', { name: /Connect AI/i }).first(); + await btn.waitFor({ timeout: 6000 }); + await btn.click(); + await page.waitForTimeout(2000); + } catch { /* ok if button not present */ } + }, +}); + +// --- Batch 3: routing graph & extensions catalog --------------------------- +console.log('\nBatch 3: routing graph & extensions'); + +// Routing graph — Direct mode: scroll to T0 tier label, nudge up for headroom. +{ + const page = await ctx.newPage(); + page.on('pageerror', err => console.error(` [err] ${err.message.slice(0, 80)}`)); + await page.goto(`${BASE}/agent/claude_code`, { waitUntil: 'domcontentloaded', timeout: 20000 }); + await page.waitForTimeout(5000); + await page.locator('text="T0"').first().scrollIntoViewIfNeeded().catch(() => {}); + await page.waitForTimeout(800); + await nudgeScrollUp(page, 120); + const out = path.join(OUT_DIR, 'routing-graph-direct.png'); + await page.screenshot({ path: out, fullPage: false }); + console.log(` [${fs.statSync(out).size > 10000 ? 'OK ' : 'BLNK'}] routing-graph-direct.png (${fs.statSync(out).size}b)`); + await page.close(); +} + +// Routing graph — Smart mode: same scroll, then click the "Smart" ToggleButton. +{ + const page = await ctx.newPage(); + page.on('pageerror', err => console.error(` [err] ${err.message.slice(0, 80)}`)); + await page.goto(`${BASE}/agent/claude_code`, { waitUntil: 'domcontentloaded', timeout: 20000 }); + await page.waitForTimeout(5000); + await page.locator('text="T0"').first().scrollIntoViewIfNeeded().catch(() => {}); + await page.waitForTimeout(600); + await nudgeScrollUp(page, 120); + await page.locator('button:has-text("Smart")').first().click().catch(() => {}); + await page.waitForTimeout(2000); + const out = path.join(OUT_DIR, 'routing-graph-smart.png'); + await page.screenshot({ path: out, fullPage: false }); + console.log(` [${fs.statSync(out).size > 10000 ? 'OK ' : 'BLNK'}] routing-graph-smart.png (${fs.statSync(out).size}b)`); + await page.close(); +} + +// Rule Plugins catalog: scroll to the "Plugins" card, click, capture dialog. +// (The card reads "Plugins" in the UI — "Extensions" was this doc's stale name.) +{ + const page = await ctx.newPage(); + page.on('pageerror', err => console.error(` [err] ${err.message.slice(0, 80)}`)); + await page.goto(`${BASE}/agent/claude_code`, { waitUntil: 'domcontentloaded', timeout: 20000 }); + await page.waitForTimeout(5000); + const pluginsHeader = page.locator('text=/^Plugins/').first(); + await pluginsHeader.scrollIntoViewIfNeeded().catch(() => {}); + await page.waitForTimeout(600); + await nudgeScrollUp(page, 80); + await pluginsHeader.click(); + await page.waitForSelector('[role="dialog"]', { timeout: 8000 }).catch(() => {}); + await page.waitForTimeout(1500); + const out = path.join(OUT_DIR, 'rule-extensions.png'); + await page.screenshot({ path: out, fullPage: false }); + console.log(` [${fs.statSync(out).size > 10000 ? 'OK ' : 'BLNK'}] rule-extensions.png (${fs.statSync(out).size}b)`); + await page.close(); +} + +// Model Select dialog: switch to Direct mode, click the claude-sonnet ServiceNode +// (cursor:pointer card, w<300, h≈72) to open the "Choose Model" dialog. +{ + const page = await ctx.newPage(); + page.on('pageerror', err => console.error(` [err] ${err.message.slice(0, 80)}`)); + await page.goto(`${BASE}/agent/claude_code`, { waitUntil: 'domcontentloaded', timeout: 20000 }); + await page.waitForTimeout(5000); + // Ensure Direct routing mode so ServiceNodes are rendered as cards + await page.locator('button[aria-label="Direct routing mode"]').click().catch(() => {}); + await page.waitForTimeout(2000); + // Find the ServiceNode card by cursor:pointer + contains "claude-sonnet" + Anthropic + no "routing" text + const svcNode = await page.evaluate(() => { + for (const el of document.querySelectorAll('div')) { + if (window.getComputedStyle(el).cursor !== 'pointer') continue; + const text = el.innerText?.trim() || ''; + if (text.startsWith('claude-sonnet') && text.includes('Anthropic') && !text.includes('routing')) { + const r = el.getBoundingClientRect(); + if (r.height > 40 && r.height < 120 && r.width < 400) return { x: r.x, y: r.y, w: r.width, h: r.height }; + } + } + return null; + }); + if (svcNode) { + await page.mouse.click(svcNode.x + svcNode.w / 2, svcNode.y + svcNode.h / 2); + await page.waitForSelector('[role="dialog"]', { timeout: 6000 }).catch(() => {}); + await page.waitForTimeout(1500); + } + const out = path.join(OUT_DIR, 'model-select.png'); + await page.screenshot({ path: out, fullPage: false }); + console.log(` [${fs.statSync(out).size > 10000 ? 'OK ' : 'BLNK'}] model-select.png (${fs.statSync(out).size}b)`); + await page.close(); +} + +// Codex scenario page +await shot('codex', '/agent/codex', { waitMs: 3500 }); + +// Connect AI form (step 2): open connect-ai picker, click a non-OAuth provider card +{ + const page = await ctx.newPage(); + page.on('pageerror', err => console.error(` [err] ${err.message.slice(0, 80)}`)); + await page.goto(`${BASE}/credentials`, { waitUntil: 'domcontentloaded', timeout: 20000 }); + await page.waitForTimeout(2500); + const btn = page.getByRole('button', { name: /Connect AI/i }).first(); + await btn.waitFor({ timeout: 6000 }); + await btn.click(); + await page.waitForTimeout(2000); + // Click a non-OAuth provider to open the config form (e.g. "Custom endpoint") + // Target the card's subtitle text rather than the title to avoid hitting header text + const customCard = page.locator('text="Not listed? Bring your own URL"').first(); + await customCard.click().catch(async () => { + // fallback: click "OpenAI" API key provider card + await page.locator('text=OpenAI').first().click().catch(() => {}); + }); + await page.waitForTimeout(1500); + const out = path.join(OUT_DIR, 'connect-ai-form.png'); + await page.screenshot({ path: out, fullPage: false }); + console.log(` [${fs.statSync(out).size > 10000 ? 'OK ' : 'BLNK'}] connect-ai-form.png (${fs.statSync(out).size}b)`); + await page.close(); +} + +// Dashboard Activity heatmap: click the "Activity" toggle in the chart pane +// (heatmap is now inline in the Dashboard, not a standalone /overview page). +await shot('dashboard-activity', '/dashboard/7d', { + waitMs: 4000, + action: async (page) => { + await page.locator('button:has-text("Activity")').first().click().catch(() => {}); + await page.waitForTimeout(1500); + }, +}); + +// Routing guide — open once-per-user routing guide by NOT suppressing it +{ + const page = await browser.newPage(); + page.on('pageerror', err => console.error(` [err] ${err.message.slice(0, 80)}`)); + await page.addInitScript(() => { + localStorage.setItem('feature_guardrails', 'true'); + localStorage.setItem('feature_mcp', 'true'); + localStorage.setItem('onboarding_complete', 'true'); + localStorage.setItem('onboarding_dismissed', 'true'); + // intentionally NOT setting tb.routingGuideAutoShown so the routing guide auto-opens + }); + await page.goto(`${BASE}/agent/claude_code`, { waitUntil: 'domcontentloaded', timeout: 20000 }); + await page.waitForTimeout(5000); + const out = path.join(OUT_DIR, 'routing-guide.png'); + await page.screenshot({ path: out, fullPage: false }); + console.log(` [${fs.statSync(out).size > 10000 ? 'OK ' : 'BLNK'}] routing-guide.png (${fs.statSync(out).size}b)`); + await page.close(); +} + +// --- Done ------------------------------------------------------------------ +await browser.close(); +console.log(`\nAll screenshots written to ${OUT_DIR}`); diff --git a/docs/guide/README.md b/docs/guide/README.md new file mode 100644 index 000000000..6a44f0265 --- /dev/null +++ b/docs/guide/README.md @@ -0,0 +1,4 @@ +# Tingly-Box Guide + +- [中文文档](./zh/README.md) +- [English Documentation](./en/README.md) diff --git a/docs/guide/en/01-getting-started.md b/docs/guide/en/01-getting-started.md new file mode 100644 index 000000000..bf4d32e6e --- /dev/null +++ b/docs/guide/en/01-getting-started.md @@ -0,0 +1,72 @@ +# Getting Started + +This chapter guides you through the first-time startup and provider setup so that all agent scenarios are ready to use. + +--- + +## First Launch + +When you access the Tingly-Box Web UI for the first time, the system detects that no providers are configured and automatically redirects to the **Onboarding** page at `/onboarding`. + +--- + +## Onboarding Page + +Page title: **Welcome to Tingly Box** + +![Onboarding Page](../images/onboarding.png) + +Two methods are available to add your first AI provider: + +### Method 1: Browse and Select a Provider + +Switch to the **Browse providers** tab. Providers are grouped into two categories: + +**Custom** +- **Custom endpoint**: Manually specify any OpenAI/Anthropic-compatible API endpoint + +**OAuth sign-in** +- Lists providers that support OAuth authorization (e.g. Claude Code, Google Gemini CLI, Codex) +- Clicking one launches the OAuth flow directly — no API Key required + +Scroll down to see more providers that use API Keys (Anthropic, OpenAI, DeepSeek, etc.), grouped by protocol (OpenAI / Anthropic). + +After clicking a provider: +- **OAuth provider**: An OAuth authorization dialog opens automatically — complete the auth to save +- **API Key provider**: A configuration form appears — fill in: + - **Name**: Display name (customizable) + - **API Base**: API endpoint (pre-filled, editable) + - **API Style**: `openai` or `anthropic` + - **Token**: API Key + - **Proxy URL** (optional): HTTP/HTTPS proxy address + +For OAuth-enabled providers (e.g. Claude.ai), the system automatically initiates the OAuth authorization flow. + +### Method 2: Paste Config for Auto-Detection + +Switch to the **Paste & detect** tab: + +1. Paste a provider configuration snippet (JSON or YAML) into the input area +2. The system automatically parses and identifies the provider type and credentials +3. Confirm to save + +### Completing Onboarding + +After successfully adding a provider, a success dialog appears with two options: +- **Go to Agents** — Navigate to the scenario overview and start using agents +- **Stay Here** — Continue adding more providers + +--- + +## Existing Installations: Adding Providers via Credentials + +If you have already completed onboarding and need to add a new provider, go to the [Credentials](./08-credentials.md) page (`/credentials`) and click **Connect AI**. It uses the same picker as Onboarding; the full two-step "pick a type, then fill in the config" flow is documented in [Credentials · Adding a Provider](./08-credentials.md#adding-a-provider-the-connect-ai-flow). + +![Connect AI Picker](../images/connect-ai.png) + +--- + +## Next Steps + +- Go to [Scenario Overview](./02-scenario-overview.md) to see all available agents +- See [Claude Code Configuration](./03-scenario-claude-code.md) to start with the primary scenario diff --git a/docs/guide/en/02-scenario-overview.md b/docs/guide/en/02-scenario-overview.md new file mode 100644 index 000000000..c13148eaf --- /dev/null +++ b/docs/guide/en/02-scenario-overview.md @@ -0,0 +1,68 @@ +# Scenario Overview + +Path: `/agent` + +--- + +![Scenario Overview](../images/scenario-overview.png) + +## Page Function + +The **Agents** page is Tingly-Box's agent navigation hub, displaying all available scenarios as a card grid. Page subtitle: *"Pick a scenario to configure. Hide the ones you don't use to keep the sidebar tidy."* + +### Scenario Cards + +Each card contains: +- **Icon**: The logo of the tool/platform the scenario represents +- **Name**: Scenario name (e.g. Claude Code, Codex, OpenCode) +- **Description**: A two-line truncated summary +- **Status line**: The card's live configuration state — a rule count (e.g. `3 rules`) if any routing rules exist, or `Not configured yet` if none do — so the page answers "what have I already set up?" at a glance +- **Hidden badge**: Gray `Hidden` badge shown on hidden scenarios + +### Visibility Management + +A small **eye icon** in the card's top-right corner controls whether the scenario appears in the left sidebar (Activity Bar). It's hidden by default and only appears on hover (or always-on for already-hidden cards), so it doesn't compete with the scenario name/description for attention. + +- Click to hide → scenario is hidden from the sidebar but still directly accessible via the overview page (shown with a `Hidden` badge and a crossed-out eye icon) +- Click to unhide → scenario reappears in the sidebar + +> Only certain scenarios support hiding; Claude Code always appears in the sidebar. + +--- + +## Full Scenario List + +| Scenario | Path | Description | +|----------|------|-------------| +| Claude Code | `/agent/claude_code` | Route Claude Code with custom profiles and per-task models | +| Claude Desktop | `/agent/claude_desktop` | Connect Claude Desktop as an MCP client through Tingly Box | +| Codex | `/agent/codex` | Configure Codex CLI through your provider keys | +| OpenCode | `/agent/opencode` | Open-source coding agent powered by your provider | +| Xcode | `/agent/xcode` | Bring your model into Xcode's coding intelligence | +| VS Code | `/agent/vscode` | Power VS Code Copilot Chat through Tingly Box | +| OpenAI SDK | `/agent/openai` | Drop-in OpenAI-compatible SDK endpoint | +| Anthropic SDK | `/agent/anthropic` | Drop-in Anthropic-compatible SDK endpoint | +| Embedding | `/agent/embed` | Route embedding requests to your provider | +| Image Gen | `/agent/imagegen` | Route image generation through Tingly Box | +| OpenClaw | `/agent/agent` | Universal agent runner (hidden by default) | +| Team | `/agent/team` | Shared central model deployment for your whole team (hidden by default) | +| Playground | `/agent/playground` | Interactive image generation test bench (not part of the card grid; reached via sidebar) | + +--- + +## Navigation Structure + +The left Activity Bar icon corresponds to the **Scenarios** group. Clicking it displays all visible scenario navigation items in the secondary sidebar. + +- Each scenario nav item supports direct-click navigation to the configuration page +- Claude Code supports multiple Profiles; each Profile appears as a separate sub-item + +--- + +## Related Pages + +- [Claude Code Scenario](./03-scenario-claude-code.md) +- [Other Coding Agents](./04-scenario-coding-agents.md) +- [OpenAI / Anthropic SDK Proxy](./05-scenario-sdk-proxy.md) +- [Claw / Embed / ImageGen](./06-scenario-special.md) +- [Playground](./07-scenario-playground.md) diff --git a/docs/guide/en/03-scenario-claude-code.md b/docs/guide/en/03-scenario-claude-code.md new file mode 100644 index 000000000..34704b97e --- /dev/null +++ b/docs/guide/en/03-scenario-claude-code.md @@ -0,0 +1,198 @@ +# Claude Code Scenario + +Path: `/agent/claude_code` + +Claude Code is Tingly-Box's primary scenario. It proxies Claude Code CLI API requests to your configured providers, with support for multiple profiles, unified/separate model modes, and fine-grained forwarding rules. + +--- + +![Claude Code Scenario](../images/claude-code.png) + +## Page Structure + +The page is organized top to bottom as follows: + +### 1. Provider Configuration Card (Claude Code Configuration) + +Shows the connection information for the current Claude Code scenario: +- **Base URL**: The proxy address Claude Code CLI should use (with copy button) +- **API Key**: Token for CLI use (with copy/reveal button) + +Three buttons in the top-right: +- **Unified Model / Separate Model**: Switch model configuration mode (see below) +- **Auto Config**: Quick-config button — opens the configuration wizard modal + +#### Plugin Toggles + +The **Plugins** row in the config card provides several scenario-level plugin dropdowns: + +| Plugin | Description | +|--------|-------------| +| **Thinking** | Extended thinking budget level: `By Client` (pass through client setting) / `Off` / `Low` (~1K) / `Medium` (~5K) / `High` (~20K) / `Max` (~32K) | +| **Smart Compact** | Compresses conversation history to save tokens: `Off` / `On` | +| **Vision Proxy** | Proxies image URLs so providers that can't reach external images still work: `Off` / `On` | +| **Record** | Records sessions to Prompt Management: `Off` / `Request Only` / `Request + Response` / `Request + Transform + Response` | + +--- + +### 2. Quick Start Stepper + +A **4-step expandable card** shown on first use (progress persisted in browser local storage, auto-collapses when all steps are complete): + +| Step | Status indicator | Details | +|------|-----------------|---------| +| 1. Connect AI Provider | Connected provider count | Expand to click **Connect** | +| 2. Select a Model | Configured / pending | Expand to click **Choose Model** | +| 3. Install Claude Code | Installed / pending | Expand to see npm official + mirror install commands (one-click copy) and **I've installed it** to mark manually | +| 4. Auto Config | Applied / pending | Expand to run **Quick Apply** (optionally check **Install Tingly-Box status line**); **Skip** button lets you bypass this step if you don't need auto-config | + +- Completed steps show a ✓ icon and can be re-expanded by clicking +- Click **Reset** at the top to clear all step progress + +--- + +### 3. Model Configuration Mode + +Toggle **Unified Model** or **Separate Model** in the top-right: + +| Mode | Description | +|------|-------------| +| **Unified Model** | All requests share one forwarding rule (`built-in-cc`) — simple, ideal for a single provider | +| **Separate Model** | Separate routing rules for default / haiku / sonnet / opus / subagent request types | + +> **Important**: After switching modes, you must click **Auto Config** again to write the new configuration to Claude Code — the CLI won't pick it up automatically. + +--- + +### 4. Auto Config Wizard + +![Auto Config Modal](../images/claude-code-config-modal.png) + +Click **Auto Config** to open the **Claude Code Configuration Guide** modal with two tabs: + +**Auto Config Tab (recommended)** + +- **Model routing**: 5 model slots matching Claude Code's internal use cases: + - `ANTHROPIC_MODEL` (Default model) + - `ANTHROPIC_DEFAULT_HAIKU_MODEL` (Haiku slot — lightweight tasks) + - `ANTHROPIC_DEFAULT_SONNET_MODEL` (Sonnet slot — primary tasks) + - `ANTHROPIC_DEFAULT_OPUS_MODEL` (Opus slot — complex reasoning) + - `CLAUDE_CODE_SUBAGENT_MODEL` (Sub-agent model — sub-task delegation) + + Each slot auto-populates from current forwarding rules and can be overridden manually. + +- **Performance & limits**: + - `API_TIMEOUT_MS`: API request timeout (ms) + - `CLAUDE_CODE_MAX_OUTPUT_TOKENS`: Max output token count + - `MAX_THINKING_TOKENS`: Thinking token budget (blank = model default) + - `BASH_DEFAULT_TIMEOUT_MS`: Bash command default timeout + - `BASH_MAX_TIMEOUT_MS`: Bash command max timeout + - `CLAUDE_AUTOCOMPACT_PCT_OVERRIDE`: Auto-compact trigger threshold (%, default 85). When context usage reaches this %, history is automatically compacted. Set to 0 to disable. + +- **Preview generated env**: Preview the env variable block that will be written to `~/.claude/settings.json` + +- **Install Tingly-Box Claude Code status line** checkbox: When checked, also installs the status line script into `~/.claude/settings.json` — shows connection status in the Claude Code prompt. + +Bottom button: +- **Quick Apply**: Writes the configuration (and optionally the status line) to Claude Code's config file; shows a result list of created/updated/backed-up files + +**Manual Tab** + +Shows and allows direct editing of the raw configuration scripts (JSON / PowerShell / Bash), for advanced users or manual deployments. + +--- + +### 5. Model Rules + +A collapsible node graph at the bottom (section title: **Model Rules**) showing the full routing chain for the current scenario: + +![Model Select Dialog](../images/model-select.png) + +Click a provider node in the routing graph, or use the "add" action on a forwarding rule, to open the **[Model Select](./21-model-select.md)** dialog. Models are grouped by provider, with search and quick-select support. + +``` +Entry node (Direct/Smart) → IF condition (e.g. agent.claude_code = subagent) → Provider +``` + +- Each rule can be expanded to see condition details +- Top-right: **Test All** (runs a quick streaming test against every active rule), **Troubleshoot** (view routing logs / diagnostics), **Connect AI** (add a provider), and — where rule creation is allowed on the page — **New Rule** +- Provider cards in the graph show model name and provider source + +#### 1M Context Window Toggle + +Each rule's model header shows a **1M** label with a toggle switch. Enabling it activates the `context_1m` flag for that rule — Tingly-Box appends `[1m]` to the model name in the generated env, signaling Claude Code to use 1M-token context windows. When you toggle this, the **Auto Config** modal opens automatically with a pending-change banner reminding you to re-apply the config and restart Claude Code. + +--- + +## Profile Management + +Claude Code supports multiple **Profiles** for projects or teams that need different providers or routing rules. + +- All profiles are listed below Claude Code in the sidebar — click to switch +- Each profile has an independent path: `/agent/claude_code/profile/:profileId` +- Each profile has its own Base URL, API Key, and forwarding rules +- Profile pages additionally offer **npx** / **global** install mode: + - `npx -y tingly-box@{version} cc --profile {profileId}` + - `tingly-box cc --profile {profileId}` + +Each profile materializes its Claude Code settings on disk under a readable `--` directory (e.g. `p1--deepseek`), instead of an opaque ID — renaming or deleting a profile keeps the artifact directory in sync. + +### CLI: launching with a profile + +There are two CLI commands for working with profiles from the terminal. + +#### `tingly-box profile` — inspect and launch + +Focused on profile management. Launches without any Claude CLI passthrough. + +**Launch** + +```bash +tingly-box profile # Interactive: list profiles, prompt to select and launch +tingly-box profile p1 # Launch Claude Code with profile p1 +tingly-box profile p1 --port 12580 # Launch against a remote Tingly-Box on port 12580 +``` + +**Inspect** + +```bash +tingly-box profile --list # List all profiles (non-interactive, ID · name · mode) +tingly-box profile --show # Interactive: pick a profile to inspect +tingly-box profile --show p1 # Show details for profile p1: + # Profile ID/name, Scenario path, Mode (unified/separate) + # Rules table: request_model → provider / model [active|inactive] +``` + +> `--list` and `--show` are mutually exclusive. If the profile name is not found, both launch and inspect fall back to an interactive picker. + +#### `tingly-box cc` — launch with full Claude CLI passthrough + +Use this when you also need to pass Claude Code's own flags. Tingly-Box consumes its own flags first, then passes everything else verbatim to the Claude CLI — no `--` separator needed. + +```bash +tingly-box cc # Launch Claude Code (default profile) +tingly-box cc --profile p1 # Launch with profile p1 (short: -p p1) +tingly-box cc -p p1 --tingly-port 12580 # Profile p1, remote Tingly-Box on port 12580 +tingly-box cc -p p1 --dangerously-skip-permissions # Pass claude flags through unchanged +tingly-box cc -p p1 /path/to/project # Open a specific directory in Claude Code +``` + +Tingly-Box flags (`--profile`/`-p`, `--tingly-port`) must come before any Claude flags. The first unrecognized token ends Tingly-Box flag scanning and the rest goes to Claude. + +--- + +## Common Configuration Flow + +1. Add at least one provider in [Credentials](./08-credentials.md) +2. Open the Claude Code page and confirm the Base URL and API Key +3. (Optional) Assign specific models to different request types in the forwarding rules +4. Click **Auto Config** → review settings → **Quick Apply** (optionally enable status line checkbox) +5. Start using Claude Code CLI + +--- + +## Related Pages + +- [Scenario Overview](./02-scenario-overview.md) +- [Credentials](./08-credentials.md) +- [Other Coding Agents](./04-scenario-coding-agents.md) diff --git a/docs/guide/en/04-scenario-codex.md b/docs/guide/en/04-scenario-codex.md new file mode 100644 index 000000000..14358ed48 --- /dev/null +++ b/docs/guide/en/04-scenario-codex.md @@ -0,0 +1,48 @@ +# Codex Scenario + +Path: `/agent/codex` + +The Codex scenario proxies OpenAI Codex CLI API requests to your configured providers, with support for automatic configuration and flexible forwarding rules. + +--- + +![Codex Scenario](../images/codex.png) + +## Page Structure + +The page is organized top to bottom as follows: + +### 1. Codex Configuration Card + +Shows connection information for the current scenario: +- **Base URL**: The proxy address Codex CLI should use (with copy button) +- **API Key**: Token for CLI use (with copy/reveal button) + +### 2. Agent Setup Card + +- **Installation command**: Provides the Codex CLI install command with one-click copy +- **Auto Config** button: Automatically writes the proxy configuration to the Codex config file (sets `OPENAI_BASE_URL` and `OPENAI_API_KEY`) + +### 3. Models and Forwarding Rules (collapsible) + +Manage routing rules for the Codex scenario — add, edit, and delete rules. + +--- + +## Configuration Flow + +1. Add at least one provider in [Credentials](./08-credentials.md) +2. Open the Codex scenario page and confirm the Base URL and API Key +3. Install Codex CLI (see the install command) +4. Click **Auto Config** to write the proxy configuration automatically, or set manually: + - `OPENAI_BASE_URL`: Set to the Base URL value + - `OPENAI_API_KEY`: Set to the API Key value +5. Use Codex CLI in your terminal + +--- + +## Related Pages + +- [Claude Code Scenario](./03-scenario-claude-code.md) +- [Other Coding Agents](./05-scenario-coding-agents.md) +- [Credentials](./08-credentials.md) diff --git a/docs/guide/en/04-scenario-coding-agents.md b/docs/guide/en/04-scenario-coding-agents.md new file mode 100644 index 000000000..edfd00a92 --- /dev/null +++ b/docs/guide/en/04-scenario-coding-agents.md @@ -0,0 +1,71 @@ +# Other Coding Agent Scenarios + +This chapter covers coding tool proxy scenarios beyond Claude Code and Codex: OpenCode, VS Code, Xcode, and Claude Desktop. Their configuration structure is similar to Claude Code. + +--- + +## OpenCode + +Path: `/agent/opencode` + +Proxies OpenCode CLI requests. The page structure is identical to Codex: + +- Config card + proxy address/key +- Agent setup + install guide +- Forwarding rules management + +--- + +## VS Code + +Path: `/agent/vscode` + +Proxies API requests from VS Code AI extensions (e.g. GitHub Copilot Chat, Continue). + +### Setup + +VS Code extensions typically specify the API endpoint via a `baseURL` environment variable or extension settings. Point it to the proxy address provided by Tingly-Box. + +--- + +## Xcode + +Path: `/agent/xcode` + +Proxies Apple Xcode AI feature (Xcode Intelligence) API requests. Configuration is similar to VS Code — point the API endpoint to the Tingly-Box proxy address. + +--- + +## Claude Desktop + +Path: `/agent/claude_desktop` + +Proxies Claude Desktop app API requests. + +### Page Structure + +1. **Claude Desktop Configuration Card**: Shows proxy address and API Key +2. **Config Modal**: Provides the complete `claude_desktop_config.json` snippet — copy and paste into Claude Desktop's configuration file +3. **Models and Forwarding Rules** (collapsible) + +### Configuration Flow + +1. Click **Config** to open the configuration modal +2. Copy the JSON snippet +3. Open Claude Desktop settings file and paste the configuration +4. Restart Claude Desktop + +--- + +## Scenario Visibility + +On the [Scenario Overview](./02-scenario-overview.md) page, use the toggle at the bottom of each card to hide infrequently used scenarios from the sidebar. + +--- + +## Related Pages + +- [Claude Code Scenario](./03-scenario-claude-code.md) +- [Codex Scenario](./04-scenario-codex.md) +- [Scenario Overview](./02-scenario-overview.md) +- [Credentials](./08-credentials.md) diff --git a/docs/guide/en/05-scenario-sdk-proxy.md b/docs/guide/en/05-scenario-sdk-proxy.md new file mode 100644 index 000000000..984e8f39b --- /dev/null +++ b/docs/guide/en/05-scenario-sdk-proxy.md @@ -0,0 +1,82 @@ +# OpenAI / Anthropic SDK Proxy + +This chapter covers the OpenAI-compatible interface proxy and the Anthropic native interface proxy — both designed for applications that call AI APIs directly in code. + +--- + +## OpenAI Scenario + +Path: `/agent/openai` + +Transparently proxies requests from any application using the OpenAI SDK to the providers managed by Tingly-Box. + +### Use Cases + +- Your own Python/Node.js/Go applications using the `openai` official SDK +- Third-party tools configured with an OpenAI-compatible endpoint (LangChain, LlamaIndex, etc.) +- Unified management of API credentials across multiple OpenAI-compatible providers + +### Page Structure + +1. **OpenAI Configuration Card**: Shows proxy Base URL and API Key +2. **Models and Forwarding Rules** (collapsible): Configure which provider requests are routed to + +### Integration + +Point the OpenAI SDK's `baseURL` to the proxy address provided by Tingly-Box: + +```python +from openai import OpenAI +client = OpenAI( + base_url="", + api_key="", +) +``` + +```javascript +import OpenAI from 'openai'; +const client = new OpenAI({ + baseURL: '', + apiKey: '', +}); +``` + +--- + +## Anthropic Scenario + +Path: `/agent/anthropic` + +Proxies requests from applications using the Anthropic official SDK to providers managed by Tingly-Box (including non-Anthropic providers that support the Anthropic protocol). + +### Use Cases + +- Applications using the `anthropic` official SDK to call the Claude API +- Switching underlying providers without code changes +- Auditing and tracking Anthropic API usage + +### Integration + +Point the Anthropic SDK's `base_url` to the Tingly-Box proxy address: + +```python +import anthropic +client = anthropic.Anthropic( + base_url="", + api_key="", +) +``` + +--- + +## Relationship to Credentials + +The forwarding rules for these scenarios determine which provider requests are ultimately sent to. If no providers have been added, go to [Credentials](./08-credentials.md) first. + +--- + +## Related Pages + +- [Scenario Overview](./02-scenario-overview.md) +- [Claude Code Scenario](./03-scenario-claude-code.md) +- [Credentials](./08-credentials.md) diff --git a/docs/guide/en/06-scenario-special.md b/docs/guide/en/06-scenario-special.md new file mode 100644 index 000000000..c6604e316 --- /dev/null +++ b/docs/guide/en/06-scenario-special.md @@ -0,0 +1,91 @@ +# Claw Agent / Embed / ImageGen + +This chapter covers three specialized scenarios: OpenClaw universal agent, Embedding API proxy, and Image Generation API proxy. + +--- + +## Claw Agent (OpenClaw) + +Path: `/agent/agent` + +OpenClaw is a universal agent interface providing a standardized API endpoint for custom agent frameworks to connect to. + +### Page Structure + +1. **Provider Configuration Card**: + - **Base URL**: Agent interface address (with copy button) + - **API Key**: Access credentials (with copy button) +2. **Models and Forwarding Rules** (collapsible): Configure routing rules for agent requests + +### Use Cases + +- Custom agent frameworks needing a unified API endpoint +- Multiple agents sharing the same set of provider credentials +- Independent routing rules for agent access + +--- + +## Embed (Embedding API) + +Path: `/agent/embed` + +Proxies Embedding API requests, for text vectorization applications. + +### Page Structure + +1. **Embed API Configuration Card**: Shows proxy address and key +2. **Embedding Models and Forwarding Rules** (collapsible): Routing rules specifically for embedding models + +### Use Cases + +- Text vectorization for RAG (Retrieval-Augmented Generation) applications +- Semantic search systems +- Text similarity computation + +### Integration + +```python +from openai import OpenAI +client = OpenAI( + base_url="", + api_key="", +) +response = client.embeddings.create( + model="text-embedding-3-small", + input="your text here", +) +``` + +--- + +## ImageGen (Image Generation) + +Path: `/agent/imagegen` + +![ImageGen Scenario](../images/imagegen.png) + +Proxies image generation API requests (DALL-E compatible interface). + +### Page Structure + +1. **ImageGen API Configuration Card**: Shows proxy address and key +2. **Quick Start Example**: Provides a curl example request with one-click copy +3. **Image Generation Models and Forwarding Rules** (collapsible) +4. **Open Playground** button: Navigates to the [Playground](./07-scenario-playground.md) for interactive testing + +### Integration + +```bash +curl /images/generations \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + -d '{"model": "dall-e-3", "prompt": "a cute cat", "n": 1, "size": "1024x1024"}' +``` + +--- + +## Related Pages + +- [Playground](./07-scenario-playground.md) +- [Scenario Overview](./02-scenario-overview.md) +- [Credentials](./08-credentials.md) diff --git a/docs/guide/en/07-scenario-playground.md b/docs/guide/en/07-scenario-playground.md new file mode 100644 index 000000000..c467eb47b --- /dev/null +++ b/docs/guide/en/07-scenario-playground.md @@ -0,0 +1,54 @@ +# Playground + +Path: `/agent/playground` + +![Playground](../images/playground.png) + +The Playground is an interactive image generation test interface that lets you test the image generation API without writing any code. + +--- + +## Page Structure + +### Parameter Panel + +Located on the left or top, containing the following controls: + +| Parameter | Description | +|-----------|-------------| +| **Model** | Dropdown — automatically populated from configured ImageGen forwarding rules | +| **Size** | Image dimensions: 256×256 / 512×512 / 1024×1024 / 1024×1792 / 1792×1024 | +| **Quality** | Image quality: auto / low / medium / high / standard | +| **N** | Generation count, range 1–10 | +| **Prompt** | Multi-line text box for the image description | + +### Generate & Results Area + +- **Generate button**: Submits the generation request (disabled if no model or prompt is selected) +- A loading spinner shows while generating +- Generated images are displayed in a grid after completion +- Each image can be viewed directly in the browser or right-click saved + +--- + +## Prerequisites + +The Playground requires at least one forwarding rule to be configured in the [ImageGen scenario](./06-scenario-special.md) before the Model dropdown shows any options. + +--- + +## Usage Flow + +1. Go to `/agent/imagegen` and confirm at least one image generation forwarding rule is configured +2. Click the **Open Playground** button, or navigate directly to `/agent/playground` +3. Select a model and parameters +4. Enter a description in the Prompt box, e.g.: `a watercolor painting of a mountain lake at sunset` +5. Click **Generate** and wait for the images +6. Review the results, adjust parameters, and continue testing + +--- + +## Related Pages + +- [ImageGen Scenario](./06-scenario-special.md) +- [Scenario Overview](./02-scenario-overview.md) diff --git a/docs/guide/en/08-credentials.md b/docs/guide/en/08-credentials.md new file mode 100644 index 000000000..744dc5c55 --- /dev/null +++ b/docs/guide/en/08-credentials.md @@ -0,0 +1,132 @@ +# Credentials + +Path: `/credentials` + +![Credentials](../images/credentials.png) + +The Credentials page is the core of Tingly-Box's configuration chain. All provider API keys and OAuth credentials are centrally managed here. + +--- + +## Page Overview + +In the sidebar, this page's group is labeled **Credential** and contains three sub-pages: **Model Key** (this page), **Sharing** (see [API Tokens](./10-api-tokens.md)), and **Virtual Models**. + +The page header shows the total credential count (e.g. `Managing 5 credentials`). The top action bar includes: + +| Button | Function | +|--------|----------| +| **Connect AI** | Opens the unified provider picker to add new credentials (same flow as Onboarding) | +| **Import** | Bulk-import provider configurations (JSON/YAML format) | +| **Providers** | Navigates to the Onboarding page (browse all providers) | + +--- + +## Credential Types + +### API Keys Table + +Lists all providers connected via API Key: + +| Column | Description | +|--------|-------------| +| Provider | Provider name and icon | +| Base URL | API endpoint address | +| Token | API Key (masked by default) | +| Status | Enabled/disabled | +| Quota | Known quota info (click to refresh) | +| Actions | Edit, delete, enable/disable | + +### OAuth Table + +Lists all providers connected via OAuth (e.g. Claude.ai): + +| Column | Description | +|--------|-------------| +| Provider | Provider name | +| Status | Authorization status | +| Expiry | Token expiration time | +| Actions | Refresh token, edit, delete, enable/disable | + +--- + +## Adding a Provider (the Connect AI flow) + +Click **Connect AI** to open the provider picker. This is the single entry point for connecting any AI service, and it works in two steps: **pick a type, then fill in the config**. + +### Step 1: Pick a provider + +![Connect AI Picker](../images/connect-ai.png) + +A search box (filters by name) sits at the top; below it providers are grouped by connection type, and each card carries a coloured badge marking its kind: + +| Section | What's in it | What happens on click | +|---------|--------------|------------------------| +| **Custom** | `Custom endpoint` (bring your own Base URL), `Import` (from file/clipboard) | Opens a blank config form / the import dialog | +| **OAuth sign-in** | Providers that support OAuth (Claude Code, Google Gemini CLI, Codex, …) | **Launches the OAuth flow directly** — no API key needed | +| **Self-hosted** | Locally hosted services (e.g. Ollama); the card shows `localhost:port` | Opens the config form with the Base URL pre-filled but **editable** (adjust to your host/port) | +| **API key providers** | Cloud providers accessed via API key, grouped by region (CN / Global); each card shows its protocol (OpenAI · Anthropic) | Opens the config form with name and Base URL pre-filled | + +> Most providers are pre-configured, so you'll only be asked for what they need. Not listed? Pick **Custom endpoint** to enter any base URL yourself. + +### Step 2: Fill in the config form + +![Provider Config Form](../images/connect-ai-form.png) + +Choosing any non-OAuth provider opens the config form: + +- **Base URL** (required): the API endpoint. Pre-filled for known providers; freely editable for Custom / Self-hosted +- **API Key** (required): the access token. For a local service with no auth, flip the **No API Key Required** toggle to skip it +- **API Style (protocol)**: + - **OpenAI Compatible** (recommended): most endpoints speak the OpenAI API — start here unless you know otherwise + - **Anthropic**: native Anthropic protocol + - Both can be enabled at once (a fusion provider), letting one credential serve both OpenAI and Anthropic inbound protocols +- **Proxy URL** (optional, under advanced): route this provider through a dedicated HTTP proxy +- **User Agent** (optional, under advanced): custom request header + +Click **Test** to verify connectivity, then **Save**. + +> **OAuth providers are the exception**: selecting an OAuth card in step 1 jumps straight to the authorization page — there's no step-2 form, and the token is saved automatically once you authorize. + +--- + +## Bulk Import + +Click the **Import** button: + +1. Select a file (JSON or YAML) or paste configuration content directly +2. Supported format example: + ```yaml + providers: + - name: "My OpenAI" + api_base: "https://api.openai.com/v1" + api_style: "openai" + token: "sk-..." + ``` +3. Click **Import** to confirm +4. If a provider already exists, the system prompts whether to force-overwrite (Force Add) + +--- + +## Editing a Provider + +Click the edit icon on the right of a provider row to open the edit form. You can modify: +- Name +- API Base URL +- API Key/Token +- Proxy settings +- Enabled/disabled status + +--- + +## Enable / Disable a Provider + +Each provider row has a toggle for quick enable/disable. Disabled providers will not receive new routing requests, but their configuration is retained. + +--- + +## Related Pages + +- [Virtual Models](./09-virtual-models.md) +- [API Tokens](./10-api-tokens.md) +- [Getting Started](./01-getting-started.md) diff --git a/docs/guide/en/09-virtual-models.md b/docs/guide/en/09-virtual-models.md new file mode 100644 index 000000000..8849ff6a0 --- /dev/null +++ b/docs/guide/en/09-virtual-models.md @@ -0,0 +1,58 @@ +# Virtual Models + +Path: `/credentials/virtual-models` + +![Virtual Models](../images/virtual-models.png) + +Virtual Models are Tingly-Box's built-in synthetic model providers. They require no real API keys and are suitable for demos, development debugging, and dry-run scenarios. + +--- + +## Page Overview + +Page subtitle: `Built-in synthetic model providers for onboarding, demos, and dry-runs.` + +### Virtual Models Table + +Lists all built-in virtual model providers: + +| Column | Description | +|--------|-------------| +| Provider | Virtual provider name | +| Status | Enable/disable toggle | + +--- + +## Use Cases + +| Scenario | Description | +|----------|-------------| +| **Onboarding demo** | Walk through the full UI flow without configuring a real provider | +| **Development debugging** | Test forwarding rule configurations without consuming real API quota | +| **Feature demos** | Demonstrate Tingly-Box features to your team without exposing real API keys | + +--- + +## Differences from Real Providers + +- Virtual providers are **built-in** and cannot be added or deleted via the UI +- Responses contain **simulated content** — no real AI model is called +- Individual virtual providers can be **enabled/disabled** via the toggle +- Compatible with **all scenarios** (Claude Code, OpenAI, Anthropic, etc.) + +--- + +## How to Enable + +1. Go to `/credentials/virtual-models` +2. Find the target virtual provider +3. Switch the toggle to **enabled** + +Once enabled, the virtual provider appears in each scenario's model routing options and can be configured as a forwarding target just like a real provider. + +--- + +## Related Pages + +- [Credentials](./08-credentials.md) +- [API Tokens](./10-api-tokens.md) diff --git a/docs/guide/en/10-api-tokens.md b/docs/guide/en/10-api-tokens.md new file mode 100644 index 000000000..8ae38e372 --- /dev/null +++ b/docs/guide/en/10-api-tokens.md @@ -0,0 +1,89 @@ +# API Tokens + +Path: `/tingly-box-token` — labeled **Sharing** in the sidebar (under Credential), since these tokens are how you share model access with others. + +![API Tokens](../images/api-tokens.png) + +The API Tokens page manages Bearer Tokens for external clients accessing Tingly-Box. Multiple named tokens can be created, suitable for scripts, CI/CD pipelines, or third-party integrations. + +--- + +## Page Structure + +### Token List Table + +| Column | Description | +|--------|-------------| +| Name | Token name (specified at creation) | +| UUID | Unique token identifier (truncated) | +| Token | Token value (masked by default; click to show/hide) | +| Status | Active / Disabled | +| Created | Creation date | +| Last Used | Most recent usage date | +| Actions | Copy, show/hide, delete | + +An empty state icon and message are shown when no tokens exist. + +--- + +## Creating a Token + +1. Click the **Create Token** button in the top-right +2. Enter a **Display Name** in the dialog (e.g. `ci-pipeline`, `my-script`) +3. Confirm — the token value is generated and shown immediately + +> **Note**: The token value is only shown once, immediately after creation. Copy it right away. + +--- + +## Using a Token + +Created tokens can be used as Bearer Tokens to access Tingly-Box's proxy interfaces: + +```bash +curl https:///api/... \ + -H "Authorization: Bearer " +``` + +Or as the `api_key` in SDK configurations: + +```python +client = OpenAI( + base_url="https:///agent/openai/v1", + api_key="", +) +``` + +--- + +## Managing Tokens + +### View Token Value + +Click the eye icon on a token row to toggle between plaintext and masked display. + +### Copy Token + +Click the copy icon — the token value is written to the clipboard. + +### Delete Token + +Click the delete icon to open a confirmation dialog (showing the token name). After confirmation, the token is permanently deleted and immediately invalidated. Any clients holding the deleted token will no longer be able to access Tingly-Box. + +--- + +## Comparison with User Token + +| | API Token | User Token | +|-|-----------|------------| +| Location | `/tingly-box-token` | `/access-control` | +| Purpose | External clients/scripts | Web UI login | +| Quantity | Multiple | Single | +| Named | Yes | No | + +--- + +## Related Pages + +- [Access Control](./18-access-control.md) +- [Credentials](./08-credentials.md) diff --git a/docs/guide/en/11-dashboard.md b/docs/guide/en/11-dashboard.md new file mode 100644 index 000000000..c996952d8 --- /dev/null +++ b/docs/guide/en/11-dashboard.md @@ -0,0 +1,126 @@ +# Usage Dashboard + +Path: `/dashboard/:timeRange` (default: `/dashboard/7d`) + +![Usage Dashboard](../images/dashboard.png) + +The Usage Dashboard provides statistics and visualizations of AI request activity, helping you understand call volume, token consumption, cache hit rate, and other metrics across providers and models. + +--- + +## Time Range Selection + +Quick-switch buttons at the top of the page: + +| Option | Path | Description | +|--------|------|-------------| +| Today | `/dashboard/today` | Current day (minute-level granularity, auto-refreshes every minute) | +| Yesterday | `/dashboard/yesterday` | Previous day (minute-level granularity) | +| 3D | `/dashboard/3d` | Last 3 days (daily view) | +| 7D | `/dashboard/7d` | Last 7 days (daily view, default) | +| 30D | `/dashboard/30d` | Last 30 days (daily view) | +| 90D | `/dashboard/90d` | Last 90 days (daily view) | + +--- + +## Summary Cards + +Five stat cards at the top summarize key metrics for the selected time range: + +| Metric | Description | +|--------|-------------| +| **Total Requests** | Total number of requests | +| **Total Tokens** | Total token count (broken down into Input / Cache / Output) | +| **Cache Hit Rate** | Cache hit rate (percentage); green ≥50%, yellow ≥20%, orange <20% | +| **Error Rate** | Request failure rate | +| **Streamed Rate** | Proportion of streaming responses | + +--- + +## Filters + +Three dropdowns sit side by side in the top bar: + +**Provider**: Groups all available providers by auth type (OAuth / API Key / Bearer Token / Basic Auth / Virtual Model). Selecting a provider filters all charts and tables to that provider's data. + +**Model**: Lists all models that have data in the current time range, sorted by token usage. Selecting a model filters to that model's data. + +**Identity**: Filters by the requesting user/identity (`user_id`), when available. + +All three dropdowns can be combined; a **Clear filters** button appears when any is active. + +--- + +## Auto-Refresh + +An **Auto-refresh** toggle and a manual **Refresh** button are provided. When enabled, data updates automatically every minute. + +--- + +## Chart Area + +### Token History Chart + +- **Today/Yesterday**: **Minute-level** token usage (Input / Cache / Output stacked bars, auto-refreshes every minute) +- **3D / 7D / 30D / 90D**: Daily token usage + +### View Toggle: Summary / By Request / Activity + +A toggle button group above the chart switches its display mode: +- **Summary**: The token history chart above (minute-level sparkline for Today/Yesterday, daily bars otherwise) +- **By Request**: Only shown for `today` / `yesterday` — an individual request list with time, model, token count, response time, etc. +- **Activity**: A GitHub-style contribution heatmap — see [Activity Heatmap](#activity-heatmap) below + +--- + +## Right Panel: Models by Token Usage + +Displays all models by token consumption for the current time range, with pagination: +- Model name + provider +- Token consumption with progress bar +- Click to **filter by that model** (not by provider) + +--- + +## Bottom: Service Stats Table + +Detailed breakdown by model/provider: + +| Column | Description | +|--------|-------------| +| Model | Model name + provider | +| Requests | Request count | +| Input Tokens | Input token count | +| Output Tokens | Output token count | +| Cache Tokens | Cache-hit token count | +| Errors | Error count | +| Cache Hit % | Cache hit rate | +| Streamed % | Streaming response proportion | + +--- + +## Today / Yesterday View + +![Today View (hourly)](../images/dashboard-today.png) + +When **Today** or **Yesterday** is selected, the chart switches to **minute-level** granularity showing a live token curve that refreshes every minute, and the **By Request** option becomes available in the Summary/By Request/Activity toggle, showing a per-request detail list. + +--- + +## Activity Heatmap + +![Activity Heatmap](../images/dashboard-activity.png) + +Click the **Activity** button in the chart-area view toggle to switch to a GitHub-style contribution heatmap, right inside the Dashboard — this used to be a standalone `/overview` page; it is now a view of the same chart pane, sharing the Provider / Model / Identity filters with the rest of the dashboard. + +- **Fixed window**: Always shows the **last 365 days**, regardless of the page's selected time range (7D/30D/etc. only affects the Summary/By Request views) +- **Grid**: Horizontal axis = months, vertical axis = day of week (Mon–Sun); cell darkness = that day's token usage (darker = more) +- **Bottom stats**: Total tokens for the window, active days / total days, longest streak, and max single-day usage +- A first-load skeleton is shown instead of flashing an empty state before data arrives + +--- + +## Related Pages + +- [System Settings](./17-system-settings.md) +- [Credentials](./08-credentials.md) diff --git a/docs/guide/en/12-remote-control.md b/docs/guide/en/12-remote-control.md new file mode 100644 index 000000000..c08fac396 --- /dev/null +++ b/docs/guide/en/12-remote-control.md @@ -0,0 +1,112 @@ +# Remote Control + +Path: `/remote-control/:platform` (Full Edition) + +![Remote Control (Telegram)](../images/remote-control.png) + +The Remote Control feature enables controlling Claude Code remotely through mainstream IM platforms (instant messaging tools), allowing you to send commands and receive results anywhere, anytime. + +> **Note**: Remote Control is available in **Full Edition** only. + +--- + +## Supported Platforms + +All supported platforms appear under the **Remote** group in the left sidebar: + +| Platform | Path | +|----------|------| +| WeChat (Weixin) | `/remote-control/weixin` | +| WeCom (Enterprise WeChat) | `/remote-control/wecom` | +| Telegram | `/remote-control/telegram` | +| Feishu | `/remote-control/feishu` | +| Lark | `/remote-control/lark` | +| DingTalk | `/remote-control/dingtalk` | +| QQ | `/remote-control/qq` | +| Discord | `/remote-control/discord` | +| Slack | `/remote-control/slack` | + +--- + +## Page Structure + +Each platform page has a consistent structure: + +### Platform Setup Guide (collapsible) + +When expanded, shows bot configuration instructions for that platform: +- How to create a bot on the platform +- Which credentials to obtain (Token, Secret, etc.) +- How to set a webhook URL (if applicable) + +### Bot List + +Shows all configured bots for the current platform: +- Bot name/alias +- Status indicator (running / stopped / error) +- Summary count (`active N / total N`) + +### Actions + +Each bot card provides: +- **Enable/Disable** toggle +- **Restart** button +- **Delete** button +- **Edit** configuration + +--- + +## Adding a Bot + +Click **Add Bot** and fill in the configuration form: + +| Field | Description | +|-------|-------------| +| **Name** | Bot alias (optional, for identification) | +| **Platform** | Platform selection (pre-selected on current page) | +| **Token** | Platform API Token / Bot Token | +| **Proxy URL** | HTTP/HTTPS proxy (optional, for restricted platform access) | +| **Chat ID Lock** | Restrict the bot to only respond to a specific chat ID (optional) | +| **Bash Allowlist** | Allowed shell commands (multi-line, optional) | +| **Model** | Specify the AI model this bot uses | +| **Working Directory** | Default working directory | + +### WeChat Special Configuration + +WeChat bots use **QR code scanning** instead of a token. After configuration, the system displays a QR code to scan for login. + +--- + +## Bot Security Settings + +### Chat ID Lock + +Enter a chat ID (group ID or user ID) to restrict the bot to only respond to messages from that specific conversation, preventing unauthorized users from controlling the bot. + +### Bash Allowlist + +One command pattern per line — limits which shell commands the bot can execute. Commands not in the allowlist will be rejected. Example: + +``` +ls +cat *.md +git status +git diff +``` + +--- + +## Usage + +Once configured, find the bot in the corresponding IM platform and send messages: + +- Send a code request → Bot calls Claude Code to execute it +- Query status → Bot returns current run status +- Send a file → Bot processes the file in the working directory + +--- + +## Related Pages + +- [Remote Coder](./13-remote-coder.md) +- [System Settings](./17-system-settings.md) diff --git a/docs/guide/en/13-remote-coder.md b/docs/guide/en/13-remote-coder.md new file mode 100644 index 000000000..697817a15 --- /dev/null +++ b/docs/guide/en/13-remote-coder.md @@ -0,0 +1,95 @@ +# Remote Coder + +Paths: `/remote-coder/chat`, `/remote-coder/sessions` + +![Remote Coder](../images/remote-coder.png) + +Remote Coder provides a browser-based chat interface to interact with Claude Code sessions directly, along with session management and monitoring capabilities. + +--- + +## Chat Page (`/remote-coder/chat`) + +### Page Structure + +**Top bar:** +- Current session ID display +- **New Chat** button: Create a new session +- **Manage Sessions** button: Navigate to session management + +**Configuration area:** +- **Session selector**: Dropdown to choose an existing session +- **Project Path field**: Specify the Claude Code working directory (required before the first message) + +**Conversation area:** +- Chat history with auto-scrolling to the latest message +- Message summaries with expand/collapse toggles for full content +- `Claude Code is thinking...` loading indicator +- Error alert area + +**Input area:** +- Multi-line text input (`Shift+Enter` for newline, `Enter` to send) + +--- + +## Usage Flow + +1. Go to `/remote-coder/chat` +2. Enter the project path in **Project Path** (e.g. `/home/user/my-project`) +3. Select an existing session or send the first message to automatically create a new one +4. Type your request in the input box, e.g.: `Analyze the structure of this project` or `Fix the bug on line 42` +5. Wait for Claude Code to execute and return results + +--- + +## Sessions Page (`/remote-coder/sessions`) + +### Page Structure + +**Summary Cards (top):** + +| Metric | Description | +|--------|-------------| +| Total | Total session count | +| Active | Running sessions | +| Completed | Successfully completed sessions | +| Failed | Failed sessions | +| Closed | Manually closed sessions | +| Uptime | Service uptime | + +**Left Panel (40% width): Session List** + +- Status filter: All / Running / Completed / Failed / Closed +- Search box: Filter by session ID or content +- Each session shows: ID, status badge, timestamp + +**Right Panel (60% width): Session Details** + +Click a session on the left to see on the right: +- Full request content +- Response summary +- Error message (if any) +- Session metadata + +### Actions + +- **Refresh** button: Manually refresh the session list +- **Clear All Sessions** button: Clear all session records (requires confirmation) + +--- + +## Comparison with Remote Control + +| | Remote Coder | Remote Control | +|-|-------------|----------------| +| Interface | Web browser chat | IM platform messages | +| Latency | Real-time (Web Push) | Depends on platform push delay | +| Session management | Built-in session view | No independent management | +| Best for | Developers working directly | Remote triggering on the go | + +--- + +## Related Pages + +- [Remote Control](./12-remote-control.md) +- [Scenario Overview](./02-scenario-overview.md) diff --git a/docs/guide/en/14-prompt-management.md b/docs/guide/en/14-prompt-management.md new file mode 100644 index 000000000..793a5dc78 --- /dev/null +++ b/docs/guide/en/14-prompt-management.md @@ -0,0 +1,98 @@ +# Prompt Management + +Paths: `/prompt/user`, `/prompt/skill`, `/prompt/command` (Full Edition) + +Prompt Management provides IDE recording browsing and Skills management, helping teams accumulate and reuse AI coding knowledge. + +> **Note**: Prompt Management is available in **Full Edition** only, and the corresponding toggles must be enabled in [Experimental Features](./19-experimental.md). + +--- + +## User Requests + +Path: `/prompt/user` + +### Function + +The User Requests page browses and manages interaction recordings captured from Claude Code IDE sessions. Use cases: +- Reviewing past AI-assisted decision processes +- Extracting successful prompt templates +- Team knowledge sharing + +### Three-Column Layout + +**Left column: Calendar** +- Calendar view showing recording counts per date +- Range filter buttons (Today / This Week / This Month / All) + +**Center column: Recording List** +- Search box: filter by content +- User filter: filter by recording user +- Project filter: filter by project +- Type filter: code-review / debug / refactor / test +- Each recording shows title, type badge, timestamp + +**Right column: Recording Details** +- Summary +- Metadata: user, project, type, duration, model, timestamp +- Full conversation content + +--- + +## Skills Management + +Path: `/prompt/skill` + +![Skills Management](../images/prompt-skills.png) + +### Function + +The Skills page manages reusable prompt snippets synced from IDE configurations (e.g. `.claude/skills/` directories), supporting: +- Auto-discovery of skills from multiple IDE sources +- Grouped browsing and search +- Viewing skill content in Markdown or raw format + +### Three-Column Layout + +**Left column: Skill Locations** + +Each location corresponds to a directory source: +- Location name +- Path +- IDE source badge (e.g. claude_code) +- Skill count +- Actions: refresh, edit, delete + +Top buttons: +- **Add Location**: Manually add a skill directory +- **Auto Discovery**: Scan all configured IDEs for skill directories + +**Center column: Skills List** + +After selecting a location, shows all skills in that location: +- Toggle between **Grouped** and **Flat** view +- Grouping strategies: Auto / Pattern / Flat +- Search filter + +**Right column: Skill Content** + +After selecting a skill: +- File metadata (path, size, modification time) +- **Markdown** rendered view (default) +- **Raw** plaintext view +- Copy button + +--- + +## Commands + +Path: `/prompt/command` + +Current status: **Coming Soon** (feature under development) + +--- + +## Related Pages + +- [Experimental Features](./19-experimental.md) +- [Claude Code Scenario](./03-scenario-claude-code.md) diff --git a/docs/guide/en/15-guardrails.md b/docs/guide/en/15-guardrails.md new file mode 100644 index 000000000..b66161980 --- /dev/null +++ b/docs/guide/en/15-guardrails.md @@ -0,0 +1,178 @@ +# Guardrails + +Paths: `/guardrails`, `/guardrails/groups`, `/guardrails/rules`, `/guardrails/history` + +Guardrails enforce rule-based safety checks on AI agent tool calls and tool results, preventing dangerous operations, protecting private data, and controlling resource access. + +> **Note**: The Guardrails feature must be enabled on the [Experimental Features](./19-experimental.md) page before the sidebar entry appears. + +--- + +## Guardrails Overview (`/guardrails`) + +![Guardrails Overview](../images/guardrails.png) + +### Statistics Dashboard + +**Policy Breakdown (left card)** — summarized by policy type: + +| Type | Description | +|------|-------------| +| Resource Access | File read/write/delete and network access policy count (enabled/total) | +| Command Execution | Shell command execution control policy count | +| Privacy (Content) | Content privacy filter policy count | + +**Event Summary (right card)** — guardrail event statistics: + +| Metric | Color | +|--------|-------| +| Total Events | — | +| Allow | Green | +| Review | Yellow | +| Blocked | Red | +| Masked | Purple | + +### Policy Import/Export + +**Import Policies** button → opens import dialog: +- Select a file (YAML/JSON policy fragment) +- Or paste policy content directly (multiple formats supported) +- Confirm **Import** + +**Export Imports** button → opens export dialog: +- Checkbox list to select which policy fragment files to export +- **Select All** / **Clear** bulk operations +- Click **Export** to download selected policies as YAML files + +--- + +## Policy Groups (`/guardrails/groups`) + +![Policy Groups](../images/guardrails-groups.png) + +Policy groups organize multiple policies for collective management, with group-level enable/disable support. + +> Page note: `Groups organize policies and control whether those policy sets participate in evaluation. Built-in is a policy label, not a group type.` + +### Group List + +Each policy group shows: +- Group name +- Severity level (Low / Medium / High) +- Enabled/disabled status +- Policy count +- Actions: edit, delete + +> The `Default` group is built-in and cannot be deleted (lock icon shown). + +### Create/Edit a Group + +Click **New Group** or the edit icon: +- **Name**: Group name +- **Severity**: Low / Medium / High +- **Enabled**: Toggle + +### Assign Policies + +The lower half of the page shows the **assignable policy list**. Each policy entry has: +- Policy name and type badge (e.g. `Privacy`) +- Description (e.g. `No patterns configured`) +- An individual toggle + +Toggle a policy on to include it in the current group; toggle off to remove it. A single policy can belong to multiple groups. + +--- + +## Policy Rules (`/guardrails/rules`) + +![Guardrails Rules](../images/guardrails-rules.png) + +### Three Tabs + +| Tab | Description | +|-----|-------------| +| **Resource Access** | File read/write/delete and network access rules | +| **Command Execution** | Shell command execution pattern-matching rules | +| **Privacy** | Content regex/keyword filtering rules | + +### Bulk Actions + +Each tab provides: +- **Enable All**: Enable all policies in the current tab +- **Disable All**: Disable all policies in the current tab + +### Policy List + +Each policy shows: +- Policy ID (auto-generated) +- Policy name +- Status (Enabled / Disabled / No active group) +- Assigned group +- Actions: edit (all policies), delete (custom policies only) + +### Creating a Policy + +Click **Add Policy** or the edit icon to open the policy editor: + +**Basic fields:** +- ID (auto-generated, customizable) +- Name +- Assigned policy group + +**Resource Access specific:** +- Actions: read / write / delete / network (multi-select) +- Resources: resource path list (glob patterns) +- Tools: applicable tool name list + +**Command Execution specific:** +- Terms/Patterns: command keyword or regex list +- Actions: execute / install (multi-select) + +**Privacy specific:** +- Patterns: keyword or regex list +- Pattern Mode: substring / regex +- Case Sensitive: toggle + +**Common fields:** +- Scenario Scope: applicable scenario (Anthropic / Claude Code / OpenAI, etc.) +- Verdict: block / allow / mask / review +- Reason: explanation shown to the agent when blocked + +### Policy Registry + +The **Registry** section at the bottom allows downloading and installing pre-built policy sets from a curated remote repository, for quickly establishing baseline guardrails. + +--- + +## Audit History (`/guardrails/history`) + +![Guardrails History](../images/guardrails-history.png) + +Path: `/guardrails/history` + +View all guardrail trigger records. + +### Filters + +- **Verdict**: All / Allow / Review / Block / Mask +- **Time**: All / 1h / 24h / 7d + +### Event List + +Expandable table rows — shows a summary by default; expand to view: +- Provider and model +- Request direction (request/response) +- Triggered policy list +- Block/review message + +### Actions + +- **Refresh**: Manually refresh the event list +- **Clear History**: Clear all history (requires confirmation) + +--- + +## Related Pages + +- [Experimental Features](./19-experimental.md) +- [MCP & Tools](./16-mcp-tools.md) diff --git a/docs/guide/en/16-mcp-tools.md b/docs/guide/en/16-mcp-tools.md new file mode 100644 index 000000000..223e63c62 --- /dev/null +++ b/docs/guide/en/16-mcp-tools.md @@ -0,0 +1,117 @@ +# MCP & Tools + +Paths: `/mcp/sources`, `/mcp/local-mode`, `/tools/servertool` + +![MCP & Tools](../images/mcp.png) + +MCP (Model Context Protocol) tool support allows registering external tool servers for Claude Code and other scenarios, including built-in web tools and custom MCP servers. + +> **Note**: The MCP feature must be enabled on the [Experimental Features](./19-experimental.md) page before the sidebar entry appears. + +--- + +## MCP Registered Servers (`/mcp/sources`) + +### Two-Step Setup + +**Step 1: Install Agent** + +The top of the page shows agent installation instructions for configuring Tingly-Box as an MCP proxy, including a one-click-copy CLI install command. + +**Step 2: Configure Tools** + +Two sections: + +#### Built-in Web Tools + +| Tool | Description | +|------|-------------| +| **mcp_web_search** | Web search tool — requires Serper API Key configuration | +| **mcp_web_fetch** | Web content fetching (Jina Reader integration) | + +Each tool has an independent toggle (enable/disable) and required configuration fields (e.g. API Key input). + +#### Custom MCP Servers + +**Toolbar:** +- **Add Server**: Add a new custom MCP server +- Status filter: All / Active / Disabled + +**Server list:** + +| Column | Description | +|--------|-------------| +| Server ID | Unique server identifier | +| Connection | Connection info (command/URL) | +| Transport | Transport type badge: STDIO / HTTP / SSE | +| Visibility | Client-side or Server-side | +| Status | Enable/disable toggle | +| Actions | Edit, delete | + +**Custom server configuration:** +- Server ID +- Transport type (STDIO / HTTP / SSE) +- Connection parameters (command or URL) +- Visibility setting + +--- + +## MCP Local Mode (`/mcp/local-mode`) + +![MCP Local Mode](../images/mcp-local-mode.png) + +Configure Claude Code to use Tingly-Box as an MCP server. + +The top of the page shows the current status: +- **Active** badge (green): MCP service is running and external clients can connect +- Info banner: `Tingly-Box is running in Client Tool mode. Register MCP sources in the Sources page, then connect your MCP client using the instructions below.` + +### Connection Information + +Displays the **MCP Endpoint URL** — the complete endpoint (including auth) that Claude Code needs to connect. + +### Connect Claude Code + +**Method 1: Claude CLI** + +```bash +claude mcp add --transport http tb "" \ + --header "Authorization: Bearer $(cat ~/.tingly-box/config.json | jq -r '.user_token')" +``` + +The command auto-reads the User Token from `~/.tingly-box/config.json` as the Bearer Token — no manual token entry needed. + +**Method 2: Manual Configuration File** + +Add the following to Claude Desktop's configuration file (includes the Authorization header): + +```json +{ + "mcpServers": { + "tb": { + "url": "", + "headers": { "Authorization": "Bearer " } + } + } +} +``` + +The page notes the default configuration file path for each OS. + +--- + +## Server Tool (`/tools/servertool`) + +Path: `/tools/servertool` + +![Server Tool](../images/servertool.png) + +View and test the MCP tools currently available on the Tingly-Box server side. + +--- + +## Related Pages + +- [Experimental Features](./19-experimental.md) +- [Guardrails](./15-guardrails.md) +- [Claude Code Scenario](./03-scenario-claude-code.md) diff --git a/docs/guide/en/17-system-settings.md b/docs/guide/en/17-system-settings.md new file mode 100644 index 000000000..732d5e3c8 --- /dev/null +++ b/docs/guide/en/17-system-settings.md @@ -0,0 +1,85 @@ +# System Settings + +Paths: `/system`, `/system/logs` + +![System Settings](../images/system.png) + +The System Settings page provides global preference configuration, server status monitoring, proxy settings, language/theme switching, and log viewing. + +--- + +## System Settings Main Page (`/system`) + +The General tab is organized into four cards, each answering one question: + +### Server Status Card + +Answers "is the gateway healthy?" — nothing else: + +| Field | Description | +|-------|-------------| +| Server | Running / Stopped / Unavailable, plus a Connected/Disconnected indicator | +| Uptime | How long the server has been running | +| Proxy | Whether a proxy is currently in effect | + +**Actions** (top-right icons): **Force Logout** (force-exit the current web session — clears token, returns to login page) and **Refresh Status**. + +--- + +### Quick Proxy Card + +Configure a unified HTTP/HTTPS proxy for all outbound API requests — a reusable preset that providers and OAuth can pick up with one click (a per-provider proxy still wins if set): + +1. Enter the proxy address in the text field (e.g. `http://127.0.0.1:7890`) +2. Click **Save** +3. A green checkmark icon appears when saved successfully + +> To configure a proxy for a specific provider only, use the Proxy URL field in the provider edit form in [Credentials](./08-credentials.md). + +--- + +### Appearance & Language Card + +User preferences, kept separate from Server Status so that card only answers "is the gateway healthy?" instead of mixing in personal settings: + +- **Language**: `English` / `中文` +- **Theme**: `Light` / `Dark` / `Sunlit` / `Claude` / `System` (follows OS setting) + +--- + +### About Card + +- **Current version**: Version number display + - Shows an update notice when a new version is available + - Development builds show a `dev` badge +- **License**: MPL-2.0 + Commercial +- **GitHub**: Project repository link + +--- + +## Logs Page (`/system/logs`) + +Path: `/system/logs` + +![Logs Page](../images/logs.png) + +View real-time Tingly-Box server logs. + +### Features + +**Debug Mode toggle** (top-right): +- On: Log level switches to `debug` — more detailed output +- Off: Log level is `info` (default) + +**LogExplorer area:** +- Real-time streaming server logs +- Scrollable history +- Each log entry includes: timestamp, level, source module, message + +--- + +## Related Pages + +- [Access Control](./18-access-control.md) +- [Experimental Features](./19-experimental.md) +- [Credentials](./08-credentials.md) diff --git a/docs/guide/en/18-access-control.md b/docs/guide/en/18-access-control.md new file mode 100644 index 000000000..af08274cf --- /dev/null +++ b/docs/guide/en/18-access-control.md @@ -0,0 +1,74 @@ +# Access Control + +Path: `/access-control` + +![Access Control](../images/access-control.png) + +The Access Control page manages Tingly-Box's core authentication tokens: the User Token (Web UI login credential) and the Model Token (API key for all agent scenarios). + +--- + +## User Token + +Used for Web UI authentication. + +### Viewing the Current Token + +- Masked by default (`••••••••`) +- Click the eye icon to toggle plaintext display +- Click the copy icon to copy the token to the clipboard + +### Security Notes + +A **Token Security** summary near the top of the page explains the difference between the User Token and Model Token, and warns never to share the User Token with API users. + +If the **default token** is in use (set at initial installation), the page shows a security warning recommending a prompt reset to a random token. + +### Resetting the Token + +Click the **Reset** button — a confirmation dialog explains the consequences: +- A new random token is generated +- All sessions using the old token (browser tabs, scripts, CLI) are immediately invalidated +- You must re-login with the new token + +After confirmation, the new token is shown in a success dialog (with copy button). Save it immediately. + +--- + +## Model Token + +The Model Token is the universal API Key for all agent scenario proxy interfaces. + +### Characteristics + +- All scenarios (Claude Code, OpenAI proxy, etc.) share the same Model Token +- Can be shared with other developers or environments for proxy interface access +- **Not** the same as the User Token; cannot be used to log into the Web UI + +### View and Copy + +Same operation as User Token: eye icon to toggle display, copy icon to write to clipboard. + +### Resetting the Model Token + +Click **Reset** to open a confirmation dialog. After confirmation, a new token is generated. + +> **Note**: After resetting the Model Token, all tools configured with the old token (Claude Code CLI, OpenAI SDK clients, etc.) must update their token configuration. + +--- + +## Relationship to API Tokens + +| | User Token | Model Token | API Tokens | +|-|-----------|-------------|-----------| +| Location | `/access-control` | `/access-control` | `/tingly-box-token` | +| Quantity | 1 | 1 | Multiple | +| Purpose | Web UI login | Agent scenario API Key | External client access | +| Named | No | No | Yes | + +--- + +## Related Pages + +- [API Tokens](./10-api-tokens.md) +- [System Settings](./17-system-settings.md) diff --git a/docs/guide/en/19-experimental.md b/docs/guide/en/19-experimental.md new file mode 100644 index 000000000..c03bfeda1 --- /dev/null +++ b/docs/guide/en/19-experimental.md @@ -0,0 +1,83 @@ +# Experimental Features + +Path: `/system/experimental` + +![Experimental Features](../images/experimental.png) + +The Experimental Features page centrally manages feature toggles for capabilities that are still in early iteration. Enabling a feature makes the corresponding sidebar entry appear. + +--- + +## Page Overview + +Page title: **Experimental Features** + +The page subtitle notes that these features are experimental and may change in future versions. + +--- + +## Available Experimental Features + +### Skills (IDE Skills) + +**Toggle key**: `skill_ide` + +When enabled, activates the **Skills** navigation item (`/prompt/skill`) under the **Prompt** group in the left sidebar, allowing syncing and managing reusable prompt snippets from IDE configuration directories. + +- Only visible in **Full Edition** +- See [Prompt Management](./14-prompt-management.md) for details + +--- + +### Guardrails + +**Toggle key**: `guardrails` + +When enabled, shows the **Guardrails** group in the left sidebar, containing: +- Guardrails Overview (`/guardrails`) +- Policy Groups (`/guardrails/groups`) +- Policy Rules (`/guardrails/rules`) +- Audit History (`/guardrails/history`) + +An informational alert guides users on how to configure Guardrails. + +See [Guardrails](./15-guardrails.md) for details. + +--- + +### MCP Tools + +**Toggle key**: `mcp` + +When enabled, shows the **Tools** group in the left sidebar, containing: +- MCP Registered Servers (`/mcp/sources`) +- MCP Local Mode (`/mcp/local-mode`) +- Server Tool (`/tools/servertool`) + +An informational alert guides users on how to configure MCP. + +See [MCP & Tools](./16-mcp-tools.md) for details. + +--- + +## How to Enable + +1. Go to **System Settings** → **Experimental** (`/system/experimental`) +2. Find the Chip toggle for the target feature +3. Click to switch to **On** +4. The sidebar refreshes immediately to show the new feature entry + +--- + +## Disabling Experimental Features + +Switch the Chip toggle to **Off** — the corresponding sidebar entry is hidden, but existing configuration data is preserved. + +--- + +## Related Pages + +- [Guardrails](./15-guardrails.md) +- [MCP & Tools](./16-mcp-tools.md) +- [Prompt Management](./14-prompt-management.md) +- [System Settings](./17-system-settings.md) diff --git a/docs/guide/en/20-routing-rules.md b/docs/guide/en/20-routing-rules.md new file mode 100644 index 000000000..41428db8c --- /dev/null +++ b/docs/guide/en/20-routing-rules.md @@ -0,0 +1,171 @@ +# Routing Rules & Plugins + +Path: `/scenario/*` (Rule cards within each scenario page) + +Routing rules are the core mechanism by which Tingly-Box dispatches requests. Each rule is bound to a request model (`request_model`) and determines how requests are distributed across one or more upstream services (Credential/Provider). + +--- + +## First-Run Guide + +![Routing Guide](../images/routing-guide.png) + +The first time you open any scenario page, a **Direct Routing Guide** opens **automatically, once**, walking you through how routing is built up from scratch: **Connect AI to add a provider → + Add model for your first model → change/remove a model → load balancing within a tier → tier-based failover**. + +- It auto-opens **only once per user**, then never nags again +- The left side is the step navigator; the right side shows the matching routing diagram plus an explanation. Steps that reference a toolbar button display a **mock toolbar** with the target button highlighted so you know exactly where to click +- To see it again, click the **?** (How routing works) button on the right of the toolbar at any time +- Use **Previous / Next** at the bottom to page through; the last step's button is **Got it!** to close + +> Smart routing has its own Smart Routing Guide — switch to Smart mode and open it via the same **?** button. + +--- + +## Routing Graph Overview + +![Direct Routing Graph](../images/routing-graph-direct.png) + +Each rule card embeds a routing graph that visualizes the request flow path. The graph supports two modes, switchable via the toggle button inside the rule card: **Direct** and **Smart**. + +--- + +## Direct Routing (Tier Mode) + +Direct routing is the default mode (`lbTactic: "tier"`). Service nodes are arranged in priority tiers: + +``` +Request Entry + │ + ├── T0 (highest priority): multiple services share load + ├── T1: fallback when T0 circuit is fully open + └── T2: final fallback when T1 is also open +``` + +### Tier Behavior + +| Concept | Description | +|---------|-------------| +| Same-tier services | Round-robin or weighted load sharing | +| Cross-tier fallback | When all services in the current tier have open circuits, requests automatically route to the next tier | +| Tier number (T0/T1…) | Lower number = higher priority; drag service nodes to adjust tier | + +### Circuit Breaker + +Each service node has an independent circuit breaker with the following states: + +``` +Closed (normal) ──── 3 consecutive failures ──→ Open (tripped) + │ + 30s cooldown + │ + HalfOpen (probe) + │ + ┌─── success ───→ Closed (recovered) + └─── failure ───→ Open (re-tripped) +``` + +| State | Meaning | +|-------|---------| +| **Closed** | Normal — accepts requests | +| **Open** | Tripped — rejects requests, waiting for cooldown (default 30s) | +| **HalfOpen** | Sends a probe request; success → Closed, failure → Open again | + +### Mid-request Failover + +Via the `firstChunkGate` buffer mechanism (v2), if an upstream fails before the first response chunk is received, the request silently switches to another service in the same tier or the next tier — transparent to the client. + +--- + +## Smart Routing + +![Smart Routing Graph](../images/routing-graph-smart.png) + +When smart routing is enabled (`smartEnabled: true`), each sub-rule (SmartOp) in the rule chain can carry conditions. Requests are matched in order; the **first sub-rule where all conditions pass** wins. + +``` +Request Entry + │ + ├── SmartOp 1 (condition A AND condition B) ── matches ──→ route to service group A + ├── SmartOp 2 (condition C) ── matches ──→ route to service group B + └── SmartOp N (no conditions — catch-all) ──────────────→ route to default service group +``` + +### SmartOp Condition Catalog + +| Condition Key | Type | Values | Description | +|--------------|------|--------|-------------| +| `agent.claude_code` | enum | `main` / `subagent` / `compact` | Claude Code request type | +| `token` | threshold | `ge:` / `le:` | Input token count (greater-than-or-equal / less-than-or-equal) | +| `thinking` | bool | `on` / `off` | Whether the client has enabled extended thinking | +| `service_ttft` | performance | `fastest` / `fast` / `slow` / `slowest` | Upstream TTFT (time-to-first-token) performance tier | +| `service_capacity` | status | `available` / `degraded` / `unavailable` | Upstream service current capacity state | +| `context_system` | presence | `exists` / `missing` | Whether the request carries a system prompt | +| `latest_user` | content type | `text` / `image` / `file` / `rich` | Content type of the most recent user message | + +### Design Tips + +- Multiple conditions in one SmartOp use **AND logic** (all must pass) +- The last sub-rule should be **unconditional** (ops=[]) as the default catch-all fallback +- Use `agent.claude_code=compact` to route compact-mode requests to cheaper models +- Use `token ge:100000` to route very long contexts to services with large context windows + +--- + +## Rule Plugins (Flags) + +The **Plugins** card on the right of each rule card provides pre-built flags that tune request/response behavior at the rule level — without touching service configuration. + +Click the Plugins card to open the **Flag Catalog** (category sidebar + detail panel). + +![Rule Plugins Catalog](../images/rule-extensions.png) + +### App + +| Flag | Key | Description | +|------|-----|-------------| +| Cursor compatibility | `cursor_compat` | Normalize rich content, gate tools, and strip stream usage for Cursor clients | +| Auto-detect Cursor | `cursor_compat_auto` | Automatically detect Cursor via request headers and apply compatibility processing | +| Claude Code compatibility | `claude_code_compat` | Rewrite `system` role entries in the messages array to `user` before forwarding, for third-party Anthropic-compatible providers that reject the non-standard role | + +### Request (OpenAI) + +| Flag | Key | Type | Description | +|------|-----|------|-------------| +| Custom User-Agent | `custom_user_agent` | String | Override the outbound User-Agent header (applies to generic OpenAI/Anthropic clients; vendor-specific clients like Claude Code OAuth keep their own UA) | +| OpenAI endpoint override | `openai_endpoint_override` | Enum | Force Chat Completions or Responses API, overriding the provider default (OpenAI providers only) | +| Use max_completion_tokens | `use_max_completion_tokens` | Toggle | Rewrite `max_tokens` → `max_completion_tokens`; required by o1/o3/gpt-5 model families | +| Use max_tokens (legacy) | `use_max_tokens` | Toggle | Rewrite `max_completion_tokens` → `max_tokens`; for older OpenAI-compatible providers | +| Block tools | `block_tools` | String | Comma-separated tool names to strip from requests before forwarding (works across OpenAI Chat/Responses, Anthropic, and Google) | + +### Response + +| Flag | Key | Type | Description | +|------|-----|------|-------------| +| Skip usage in response | `skip_usage` | Toggle | Strip the `usage` block from responses (both SSE deltas and final body) | + +### Reasoning + +| Flag | Key | Type | Description | +|------|-----|------|-------------| +| Thinking | `thinking_effort` | Enum | Unified extended-thinking control: `By Client` (pass-through) / `Off` (force disabled) / `Low` (~1K tokens) / `Medium` (~5K) / `High` (~20K) / `Max` (~32K). Mapped to `budget_tokens` for Anthropic targets and `reasoning_effort` for OpenAI targets | + +### Vision + +| Flag | Key | Type | Description | +|------|-----|------|-------------| +| Vision Proxy | `vision_proxy_service` | Service ref | Describe images via a vision-capable model so text-only downstream models can process image-bearing requests. Takes precedence over the scenario-level Vision Proxy when both are configured | + +### Routing + +| Flag | Key | Type | Description | +|------|-----|------|-------------| +| Session affinity | `session_affinity` | Integer (seconds) | **Rule-level** TTL for session-to-service pinning: follow-up requests in the same session keep hitting the same service until TTL expires. 0 disables. Built-in Claude Code, Claude Desktop, and Codex rules default to 1800 s. Session identity resolved from `metadata.user_id`, `X-Tingly-Session-ID` header, or client IP | + +--- + +## Related Pages + +- [Scenario Overview](./02-scenario-overview.md) +- [Claude Code Scenario](./03-scenario-claude-code.md) +- [Credentials](./08-credentials.md) +- [Experimental Features](./19-experimental.md) diff --git a/docs/guide/en/21-model-select.md b/docs/guide/en/21-model-select.md new file mode 100644 index 000000000..05eb5182b --- /dev/null +++ b/docs/guide/en/21-model-select.md @@ -0,0 +1,56 @@ +# Model Select + +The Model Select dialog is used to assign a target provider and model to a forwarding rule — it is the primary interaction point for configuring routing rules. + +--- + +![Model Select Dialog](../images/model-select.png) + +## How to Open + +In any scenario's (Claude Code, Codex, etc.) **Model Rules** section, you can open the dialog in several ways: + +- **Click an existing provider node**: Click the card showing a model name (e.g. `claude-sonnet-4-6`) in the routing graph — opens in "edit" mode +- **Click the "+ Add" button**: Click the add button at the end of a rule row — opens in "add" mode +- **AgentSetupCard Quick Start**: In Claude Code's Quick Start step 2, expand it and click **Choose Model** + +--- + +## Dialog Structure + +### Left Panel: Provider List + +- Lists all configured providers (from [Credentials](./08-credentials.md)) +- Click a provider name to expand/collapse its model list +- Each provider shows all supported models + +### Top: Search & Filter + +- **Search box**: Filter by model name or provider name +- Quickly locate a specific model + +### Selection + +- Click a model row to select it; confirming writes it to the routing rule +- In "add" mode, selecting a model automatically creates a new forwarding rule + +### Per-Card Test Action + +Each model card follows a consistent corner convention: + +| Corner | Content | +|--------|---------| +| Top-left | Category marker — `NEW` badge, or a triangle marking a custom model | +| Top-right | A checkmark on the currently selected model | +| Bottom-left | A persistent pass/fail status dot from the last test run, if any — click it to reopen the dialog with that result | +| Bottom-right | Hover-only action icons: **Edit**, **Delete**, and **Test** (bolt icon) | + +Clicking the bolt icon opens a **Test** dialog to run a model directly from the card — pick a request shape, click **Run Test**, and see the request journey, token usage, and response — without first selecting the model into a rule. The result persists as the status dot after the dialog closes, so testing several models leaves a quick visual scorecard. + +--- + +## Related Pages + +- [Claude Code Scenario](./03-scenario-claude-code.md) +- [Routing Rules & Plugins](./20-routing-rules.md) +- [Credentials](./08-credentials.md) diff --git a/docs/guide/en/README.md b/docs/guide/en/README.md new file mode 100644 index 000000000..e329085fb --- /dev/null +++ b/docs/guide/en/README.md @@ -0,0 +1,66 @@ +# Tingly-Box User Guide + +Tingly-Box is an AI agent orchestration platform providing an LLM gateway, remote control, and safety guardrails. This guide documents the complete Web UI organized by feature area. + +--- + +## Table of Contents + +### I. Getting Started +- [Initialization & Provider Setup](./01-getting-started.md) + +### II. Agent Scenarios + +Agent scenarios are the core of Tingly-Box — they proxy API requests from AI coding tools to your configured providers. + +- [Scenario Overview](./02-scenario-overview.md) — Navigation hub and visibility management +- [Claude Code](./03-scenario-claude-code.md) — Primary scenario with Profile support, unified/separate model modes, and forwarding rules +- [Codex](./04-scenario-codex.md) — OpenAI Codex CLI proxy with auto-config support +- [Other Coding Agents](./04-scenario-coding-agents.md) — OpenCode, VS Code, Xcode, Claude Desktop +- [OpenAI / Anthropic SDK Proxy](./05-scenario-sdk-proxy.md) — OpenAI-compatible and Anthropic native interfaces +- [Claw Agent / Embed / ImageGen](./06-scenario-special.md) — OpenClaw, Embedding API, Image Generation +- [Playground](./07-scenario-playground.md) — Interactive image generation test bench + +### III. Configuration Chain + +Provider and credential management is a prerequisite for all scenarios. + +- [Credentials](./08-credentials.md) — API Keys, OAuth, import/export, provider configuration +- [Virtual Models](./09-virtual-models.md) — Built-in synthetic models for demos and dry-runs +- [API Tokens](./10-api-tokens.md) — Manage access tokens for external clients + +### IV. Other Main Entry Points + +- [Usage Dashboard](./11-dashboard.md) — Request stats, token usage, cache hit rate +- [Remote Control](./12-remote-control.md) — Control Claude Code via IM platforms (WeChat, Telegram, Feishu, etc.) +- [Remote Coder](./13-remote-coder.md) — Web chat interface and session management +- [Prompt Management](./14-prompt-management.md) — User recordings, Skills, Commands (Full Edition) +- [Guardrails](./15-guardrails.md) — Policy import/export, rule management, audit history +- [MCP & Tools](./16-mcp-tools.md) — MCP server registration and local mode + +### V. System Settings + +- [System Settings](./17-system-settings.md) — Proxy, language, theme, version info, logs +- [Access Control](./18-access-control.md) — User token and model token management + +### VI. Experimental Features + +- [Experimental Features](./19-experimental.md) — Skills IDE, Guardrails, MCP toggles + +### VII. Advanced Topics + +- [Routing Rules & Plugins](./20-routing-rules.md) — Direct routing (tiers/circuit breaker), Smart routing (SmartOp conditions), rule plugin flags +- [Model Select](./21-model-select.md) — Assign providers and models to forwarding rules + +--- + +## Edition Notes + +Some features are available in **Full Edition** only: +- Prompt Management (user recordings, Skills) +- Remote Control (IM bots) +- Remote Coder + +Some features must be manually enabled on the Experimental Features page before appearing in the sidebar: +- Guardrails +- MCP Tools diff --git a/docs/guide/images/access-control.png b/docs/guide/images/access-control.png new file mode 100644 index 000000000..5d89c834d Binary files /dev/null and b/docs/guide/images/access-control.png differ diff --git a/docs/guide/images/api-tokens.png b/docs/guide/images/api-tokens.png new file mode 100644 index 000000000..f087a5264 Binary files /dev/null and b/docs/guide/images/api-tokens.png differ diff --git a/docs/guide/images/claude-code-config-modal.png b/docs/guide/images/claude-code-config-modal.png new file mode 100644 index 000000000..c41a8cd61 Binary files /dev/null and b/docs/guide/images/claude-code-config-modal.png differ diff --git a/docs/guide/images/claude-code.png b/docs/guide/images/claude-code.png new file mode 100644 index 000000000..f7decd838 Binary files /dev/null and b/docs/guide/images/claude-code.png differ diff --git a/docs/guide/images/codex.png b/docs/guide/images/codex.png new file mode 100644 index 000000000..7825ef5d7 Binary files /dev/null and b/docs/guide/images/codex.png differ diff --git a/docs/guide/images/connect-ai-form.png b/docs/guide/images/connect-ai-form.png new file mode 100644 index 000000000..3dc92fcb5 Binary files /dev/null and b/docs/guide/images/connect-ai-form.png differ diff --git a/docs/guide/images/connect-ai.png b/docs/guide/images/connect-ai.png new file mode 100644 index 000000000..1c6c2ea8b Binary files /dev/null and b/docs/guide/images/connect-ai.png differ diff --git a/docs/guide/images/credentials.png b/docs/guide/images/credentials.png new file mode 100644 index 000000000..f7a97d210 Binary files /dev/null and b/docs/guide/images/credentials.png differ diff --git a/docs/guide/images/dashboard-activity.png b/docs/guide/images/dashboard-activity.png new file mode 100644 index 000000000..f869bd0c7 Binary files /dev/null and b/docs/guide/images/dashboard-activity.png differ diff --git a/docs/guide/images/dashboard-today.png b/docs/guide/images/dashboard-today.png new file mode 100644 index 000000000..2be97fc70 Binary files /dev/null and b/docs/guide/images/dashboard-today.png differ diff --git a/docs/guide/images/dashboard.png b/docs/guide/images/dashboard.png new file mode 100644 index 000000000..2033cd3da Binary files /dev/null and b/docs/guide/images/dashboard.png differ diff --git a/docs/guide/images/experimental.png b/docs/guide/images/experimental.png new file mode 100644 index 000000000..76b667c08 Binary files /dev/null and b/docs/guide/images/experimental.png differ diff --git a/docs/guide/images/guardrails-groups.png b/docs/guide/images/guardrails-groups.png new file mode 100644 index 000000000..f1ca9df8a Binary files /dev/null and b/docs/guide/images/guardrails-groups.png differ diff --git a/docs/guide/images/guardrails-history.png b/docs/guide/images/guardrails-history.png new file mode 100644 index 000000000..92d3d06a1 Binary files /dev/null and b/docs/guide/images/guardrails-history.png differ diff --git a/docs/guide/images/guardrails-rules.png b/docs/guide/images/guardrails-rules.png new file mode 100644 index 000000000..874c433d2 Binary files /dev/null and b/docs/guide/images/guardrails-rules.png differ diff --git a/docs/guide/images/guardrails.png b/docs/guide/images/guardrails.png new file mode 100644 index 000000000..0ababac4e Binary files /dev/null and b/docs/guide/images/guardrails.png differ diff --git a/docs/guide/images/imagegen.png b/docs/guide/images/imagegen.png new file mode 100644 index 000000000..f76244883 Binary files /dev/null and b/docs/guide/images/imagegen.png differ diff --git a/docs/guide/images/logs.png b/docs/guide/images/logs.png new file mode 100644 index 000000000..0262b4956 Binary files /dev/null and b/docs/guide/images/logs.png differ diff --git a/docs/guide/images/mcp-local-mode.png b/docs/guide/images/mcp-local-mode.png new file mode 100644 index 000000000..de75dd653 Binary files /dev/null and b/docs/guide/images/mcp-local-mode.png differ diff --git a/docs/guide/images/mcp.png b/docs/guide/images/mcp.png new file mode 100644 index 000000000..c4b4f37e1 Binary files /dev/null and b/docs/guide/images/mcp.png differ diff --git a/docs/guide/images/model-select.png b/docs/guide/images/model-select.png new file mode 100644 index 000000000..596f892ec Binary files /dev/null and b/docs/guide/images/model-select.png differ diff --git a/docs/guide/images/onboarding.png b/docs/guide/images/onboarding.png new file mode 100644 index 000000000..81a942105 Binary files /dev/null and b/docs/guide/images/onboarding.png differ diff --git a/docs/guide/images/playground.png b/docs/guide/images/playground.png new file mode 100644 index 000000000..dd04bf972 Binary files /dev/null and b/docs/guide/images/playground.png differ diff --git a/docs/guide/images/prompt-skills.png b/docs/guide/images/prompt-skills.png new file mode 100644 index 000000000..921b2a3e9 Binary files /dev/null and b/docs/guide/images/prompt-skills.png differ diff --git a/docs/guide/images/remote-coder-sessions.png b/docs/guide/images/remote-coder-sessions.png new file mode 100644 index 000000000..9e46d92f8 Binary files /dev/null and b/docs/guide/images/remote-coder-sessions.png differ diff --git a/docs/guide/images/remote-coder.png b/docs/guide/images/remote-coder.png new file mode 100644 index 000000000..8d45103aa Binary files /dev/null and b/docs/guide/images/remote-coder.png differ diff --git a/docs/guide/images/remote-control.png b/docs/guide/images/remote-control.png new file mode 100644 index 000000000..20aef5c47 Binary files /dev/null and b/docs/guide/images/remote-control.png differ diff --git a/docs/guide/images/routing-graph-direct.png b/docs/guide/images/routing-graph-direct.png new file mode 100644 index 000000000..05d9e8527 Binary files /dev/null and b/docs/guide/images/routing-graph-direct.png differ diff --git a/docs/guide/images/routing-graph-smart.png b/docs/guide/images/routing-graph-smart.png new file mode 100644 index 000000000..77e2b1056 Binary files /dev/null and b/docs/guide/images/routing-graph-smart.png differ diff --git a/docs/guide/images/routing-guide.png b/docs/guide/images/routing-guide.png new file mode 100644 index 000000000..230a01723 Binary files /dev/null and b/docs/guide/images/routing-guide.png differ diff --git a/docs/guide/images/rule-extensions.png b/docs/guide/images/rule-extensions.png new file mode 100644 index 000000000..c754cbe8a Binary files /dev/null and b/docs/guide/images/rule-extensions.png differ diff --git a/docs/guide/images/scenario-overview.png b/docs/guide/images/scenario-overview.png new file mode 100644 index 000000000..c549cce00 Binary files /dev/null and b/docs/guide/images/scenario-overview.png differ diff --git a/docs/guide/images/servertool.png b/docs/guide/images/servertool.png new file mode 100644 index 000000000..a58e6c48b Binary files /dev/null and b/docs/guide/images/servertool.png differ diff --git a/docs/guide/images/system.png b/docs/guide/images/system.png new file mode 100644 index 000000000..32da0b421 Binary files /dev/null and b/docs/guide/images/system.png differ diff --git a/docs/guide/images/virtual-models.png b/docs/guide/images/virtual-models.png new file mode 100644 index 000000000..506f59fd3 Binary files /dev/null and b/docs/guide/images/virtual-models.png differ diff --git a/docs/guide/zh/01-getting-started.md b/docs/guide/zh/01-getting-started.md new file mode 100644 index 000000000..3c1511d44 --- /dev/null +++ b/docs/guide/zh/01-getting-started.md @@ -0,0 +1,72 @@ +# 快速上手 + +本章引导你完成 Tingly-Box 的第一次启动与 Provider 接入,使后续所有 Agent 场景可用。 + +--- + +## 初次启动 + +首次访问 Tingly-Box Web UI 时,系统检测到尚无 Provider 配置,会自动跳转到 **Onboarding(初始化向导)** 页面,路径为 `/onboarding`。 + +--- + +## Onboarding 页面 + +页面标题:**Welcome to Tingly Box** + +![Onboarding 页面](../images/onboarding.png) + +提供两种方式添加第一个 AI Provider: + +### 方式一:浏览并选择 Provider + +切换到 **Browse providers** 标签页,Provider 分两类展示: + +**Custom(自定义)** +- **Custom endpoint**:手动填写任意 OpenAI/Anthropic 兼容的 API 端点 + +**OAuth sign-in** +- 列出支持 OAuth 授权的 Provider(如 Claude Code、Google Gemini CLI、Codex 等) +- 点击后直接发起 OAuth 授权流程,无需手动输入 API Key + +向下滚动可看到更多通过 API Key 接入的 Provider(Anthropic、OpenAI、DeepSeek 等),按协议风格(OpenAI / Anthropic)分组展示。 + +点击目标 Provider 后: +- **OAuth Provider**:自动弹出 OAuth 授权对话框,完成授权即保存 +- **API Key Provider**:弹出配置表单,填写: + - **Name**:Provider 显示名称 + - **API Base**:API 端点(通常已预填) + - **API Style**:`openai` 或 `anthropic` + - **Token**:API Key + - **Proxy URL**(可选):HTTP/HTTPS 代理地址 + +对于支持 OAuth 的 Provider(如 Claude.ai),系统会自动发起 OAuth 授权流程。 + +### 方式二:粘贴配置自动识别 + +切换到 **Paste & detect** 标签页: + +1. 将 Provider 配置片段(JSON 或 YAML)粘贴到输入区 +2. 系统自动解析并识别 Provider 类型和凭证信息 +3. 确认后保存 + +### 完成 Onboarding + +成功添加 Provider 后,弹出成功对话框,可选择: +- **Go to Agents** — 前往场景总览页,开始使用 +- **Stay Here** — 继续添加更多 Provider + +--- + +## 已有环境:从凭证页添加 Provider + +如果已完成初始化,需要添加新 Provider,请访问 [凭证管理](./08-credentials.md) 页面(`/credentials`),点击 **Connect AI** 按钮。它与 Onboarding 用的是同一个选择器,完整的「先选类型、再填配置」两步流程见 [凭证管理 · 添加 Provider](./08-credentials.md#添加-providerconnect-ai-流程)。 + +![Connect AI 选择器](../images/connect-ai.png) + +--- + +## 下一步 + +- 进入 [场景总览](./02-scenario-overview.md) 查看所有可用 Agent +- 查看 [Claude Code 配置](./03-scenario-claude-code.md) 开始主力场景 diff --git a/docs/guide/zh/02-scenario-overview.md b/docs/guide/zh/02-scenario-overview.md new file mode 100644 index 000000000..e018312c1 --- /dev/null +++ b/docs/guide/zh/02-scenario-overview.md @@ -0,0 +1,68 @@ +# 场景总览 + +路径:`/agent` + +--- + +![场景总览](../images/scenario-overview.png) + +## 页面功能 + +**Agents** 是 Tingly-Box 的 Agent 场景导航中心,以卡片网格形式展示所有可用场景。页面副标题:「Pick a scenario to configure. Hide the ones you don't use to keep the sidebar tidy.」 + +### 场景卡片 + +每张卡片包含: +- **图标**:场景对应工具/平台的 Logo +- **名称**:场景名称(如 Claude Code、Codex、OpenCode 等) +- **描述**:两行截断的场景简介 +- **状态行**:卡片的实时配置状态——若已有路由规则则显示规则数(如 `3 rules`),否则显示 `Not configured yet`,让页面一眼回答「我已经配置了什么」 +- **Hidden 标记**:已隐藏的场景显示灰色 `Hidden` 徽章 + +### 可见性管理 + +卡片右上角有一个小巧的**眼睛图标**,用于控制该场景是否出现在左侧活动栏(Sidebar)中。默认隐藏,仅在悬停时出现(已隐藏的卡片则始终显示),避免和场景名称/描述抢占视觉焦点。 + +- 点击隐藏 → 场景从侧边栏隐藏,但仍可通过总览页直接访问(显示 `Hidden` 徽章和带斜杠的眼睛图标) +- 点击取消隐藏 → 场景重新显示在侧边栏 + +> 仅部分场景支持隐藏,Claude Code 始终显示在侧边栏。 + +--- + +## 全部场景列表 + +| 场景 | 路径 | 说明 | +|------|------|------| +| Claude Code | `/agent/claude_code` | 通过自定义 Profile 和分任务模型路由 Claude Code | +| Claude Desktop | `/agent/claude_desktop` | 通过 Tingly Box 将 Claude Desktop 接入为 MCP 客户端 | +| Codex | `/agent/codex` | 通过你的 Provider 密钥配置 Codex CLI | +| OpenCode | `/agent/opencode` | 由你的 Provider 驱动的开源编程 Agent | +| Xcode | `/agent/xcode` | 将你的模型接入 Xcode 的编程智能功能 | +| VS Code | `/agent/vscode` | 通过 Tingly Box 驱动 VS Code Copilot Chat | +| OpenAI SDK | `/agent/openai` | OpenAI 兼容 SDK 端点,即插即用 | +| Anthropic SDK | `/agent/anthropic` | Anthropic 兼容 SDK 端点,即插即用 | +| Embedding | `/agent/embed` | 将 Embedding 请求路由到你的 Provider | +| Image Gen | `/agent/imagegen` | 通过 Tingly Box 路由图像生成请求 | +| OpenClaw | `/agent/agent` | 通用 Agent 运行器(默认隐藏) | +| Team | `/agent/team` | 面向全团队的共享中央模型部署(默认隐藏) | +| Playground | `/agent/playground` | 图像生成交互测试台(不在卡片网格中,通过侧边栏进入) | + +--- + +## 导航结构 + +左侧活动栏(Activity Bar)图标对应 **Scenarios** 分组,点击后在次级侧边栏展示所有可见场景的导航项。 + +- 每个场景导航项支持直接点击跳转到对应配置页 +- Claude Code 支持多 Profile,每个 Profile 作为独立导航子项展示 + +--- + +## 相关页面 + +- [Claude Code 场景](./03-scenario-claude-code.md) +- [其他编程 Agent](./04-scenario-coding-agents.md) +- [OpenAI / Anthropic SDK 代理](./05-scenario-sdk-proxy.md) +- [Claw / Embed / ImageGen](./06-scenario-special.md) +- [Playground](./07-scenario-playground.md) diff --git a/docs/guide/zh/03-scenario-claude-code.md b/docs/guide/zh/03-scenario-claude-code.md new file mode 100644 index 000000000..677547141 --- /dev/null +++ b/docs/guide/zh/03-scenario-claude-code.md @@ -0,0 +1,199 @@ +# Claude Code 场景 + +路径:`/agent/claude_code` + +Claude Code 是 Tingly-Box 的主力场景,将 Claude Code CLI 的 API 请求代理到你配置的 Provider,支持多 Profile 管理、统一/分离模型配置和细粒度转发规则。 + +--- + +![Claude Code 场景](../images/claude-code.png) + +## 页面结构 + +页面由以下几个区域从上到下依次构成: + +### 1. Provider 配置卡(Claude Code Configuration) + +展示当前 Claude Code 场景的连接信息: +- **Base URL**:Claude Code CLI 应配置的代理地址(含复制按钮) +- **API Key**:供 CLI 使用的令牌(含复制/显示按钮) + +右上角三个按钮: +- **Unified Model / Separate Model**:模型配置模式切换(见下文) +- **Auto Config**:快捷配置按钮,直接打开配置向导模态框 + +#### Plugin 插件开关 + +配置卡中部的 **Plugins** 一行提供多个场景级插件开关,均为下拉菜单: + +| 插件 | 说明 | +|------|------| +| **Thinking** | Extended thinking 预算等级:`By Client`(透传客户端设置)/ `Off` / `Low`(~1K)/ `Medium`(~5K)/ `High`(~20K)/ `Max`(~32K) | +| **Smart Compact** | 智能压缩对话历史,节省 Token:`Off` / `On` | +| **Vision Proxy** | 代理图片 URL,解决 Provider 无法访问外网图片的问题:`Off` / `On` | +| **Record** | 录制会话到 Prompt 管理:`Off` / `Request Only` / `Request + Response` / `Request + Transform + Response` | + +--- + +### 2. Quick Start 引导步骤 + +首次使用时显示的 **4 步可展开引导卡**(进度持久化在浏览器本地,完成后自动折叠): + +| 步骤 | 状态指示 | 说明 | +|------|----------|------| +| 1. Connect AI Provider | 已连接 Provider 数量 | 展开后显示 **Connect** 按钮 | +| 2. Select a Model | Configured / 未完成 | 展开后显示 **Choose Model** 按钮 | +| 3. Install Claude Code | Installed / 未完成 | 展开后提供 npm 官方源和镜像源两个安装命令(可一键复制),以及 **I've installed it** 手动标记 | +| 4. Auto Config | Applied / 未完成 | 展开后显示 **Quick Apply** 按钮(可勾选"安装状态栏");**Skip** 按钮可跳过此步(无需运行配置时使用) | + +- 已完成的步骤显示 ✓ 图标,点击可再次展开查看内容 +- 全部完成后引导卡自动折叠 +- 点击顶部 **Reset** 可重置全部步骤进度 + +--- + +### 3. 模型配置模式 + +右上角切换 **Unified Model** 或 **Separate Model**: + +| 模式 | 说明 | +|------|------| +| **Unified Model(统一模型)** | 全部请求共用同一条转发规则 `built-in-cc`,配置简单,适合单一 Provider | +| **Separate Model(分离模型)** | 为 default / haiku / sonnet / opus / subagent 各请求类型分别配置独立路由规则 | + +> **注意**:切换模式后需要重新点击 **Auto Config** 将新配置写入 Claude Code,否则 CLI 侧不会生效。 + +--- + +### 4. Auto Config 配置向导 + +![Auto Config 模态框](../images/claude-code-config-modal.png) + +点击 **Auto Config** 打开 **Claude Code Configuration Guide** 模态框,包含两个 Tab: + +**Auto Config Tab(推荐)** + +- **Model routing**:5 个模型插槽,对应 Claude Code 的不同用途: + - `ANTHROPIC_MODEL`(Default model) + - `ANTHROPIC_DEFAULT_HAIKU_MODEL`(Haiku slot — 轻量任务) + - `ANTHROPIC_DEFAULT_SONNET_MODEL`(Sonnet slot — 主力任务) + - `ANTHROPIC_DEFAULT_OPUS_MODEL`(Opus slot — 复杂推理) + - `CLAUDE_CODE_SUBAGENT_MODEL`(Sub-agent model — 子任务代理) + + 每个插槽自动从当前转发规则中读取可用模型,也可手动输入。 + +- **Performance & limits**: + - `API_TIMEOUT_MS`:API 请求超时(ms) + - `CLAUDE_CODE_MAX_OUTPUT_TOKENS`:最大输出 Token 数 + - `MAX_THINKING_TOKENS`:Thinking Token 预算(留空 = 模型默认) + - `BASH_DEFAULT_TIMEOUT_MS`:Bash 命令默认超时 + - `BASH_MAX_TIMEOUT_MS`:Bash 命令最大超时 + - `CLAUDE_AUTOCOMPACT_PCT_OVERRIDE`:自动压缩阈值(%,默认 85)。上下文使用率达到该百分比时触发自动压缩,设为 0 则禁用。 + +- **Preview generated env**:预览将要写入的环境变量块(写入 `~/.claude/settings.json`) + +- **Install Tingly-Box Claude Code status line** 复选框:勾选后同时将状态栏脚本安装到 `~/.claude/settings.json`,在 Claude Code 提示符中显示 Tingly-Box 连接状态。 + +底部按钮: +- **Quick Apply**:将配置(及可选的状态栏)写入 Claude Code 配置文件,执行后显示创建/更新/备份的文件列表 + +**Manual Tab** + +直接展示和编辑将要写入的原始配置脚本(JSON / PowerShell / Bash),适合高级用户或手动部署。 + +--- + +### 5. Model Rules(模型规则) + +页面底部的可折叠节点图(区块标题为 **Model Rules**),展示当前场景的完整路由链路: + +![模型选择对话框](../images/model-select.png) + +点击路由图中的 Provider 节点,或通过转发规则的"添加"操作,即可打开 **[模型选择](./21-model-select.md)** 对话框。对话框按 Provider 分组展示所有可用模型,支持搜索和快速选择。 + +``` +入口节点(Direct/Smart)→ IF 条件(如 agent.claude_code = subagent)→ Provider +``` + +- 每条规则可展开查看条件详情 +- 右上角提供 **Test All**(对所有启用规则运行一次快速流式测试)、**Troubleshoot**(查看路由日志/诊断)、**Connect AI**(添加 Provider)操作;页面允许新建规则时还会显示 **New Rule** +- 节点图中的 Provider 卡片显示模型名称和 Provider 来源 + +#### 1M 上下文窗口开关 + +每条规则的模型标题栏右侧显示 **1M** 标签和开关。启用后,Tingly-Box 会将 `context_1m` 标记写入该规则,并在生成的环境变量中的模型名后追加 `[1m]`,通知 Claude Code 使用 100 万 Token 上下文窗口。切换后,**Auto Config** 模态框会自动打开,并显示变更待应用的提示,需要重新点击应用并重启 Claude Code 才能生效。 + +--- + +## Profile 管理 + +Claude Code 支持多 **Profile**,适用于不同项目或团队需要不同 Provider/规则的场景。 + +- 侧边栏 Claude Code 下方列出所有 Profile,点击直接切换 +- 每个 Profile 路径独立:`/agent/claude_code/profile/:profileId` +- 各 Profile 有独立的 Base URL、API Key 和转发规则 +- Profile 页面额外提供 **npx** / **global** 安装模式切换: + - `npx -y tingly-box@{version} cc --profile {profileId}` + - `tingly-box cc --profile {profileId}` + +每个 Profile 会在磁盘上以可读的 `--` 目录(如 `p1--deepseek`)落地其 Claude Code 设置,而非用不可读的内部 ID 命名——重命名或删除 Profile 时该目录会同步更新。 + +### CLI:通过命令行启动 Profile + +有两条命令可以在终端使用 Profile。 + +#### `tingly-box profile` — 查看与启动 + +专注于 Profile 管理,启动时不支持透传 Claude CLI 参数。 + +**启动** + +```bash +tingly-box profile # 交互式:列出 Profile,选择后启动 Claude Code +tingly-box profile p1 # 使用 Profile p1 启动 Claude Code +tingly-box profile p1 --port 12580 # 连接到指定端口的远程 Tingly-Box 实例 +``` + +**查看** + +```bash +tingly-box profile --list # 非交互式列出所有 Profile(ID · 名称 · 模式) +tingly-box profile --show # 交互式:选择一个 Profile 查看详情 +tingly-box profile --show p1 # 查看 Profile p1 的详细信息: + # Profile ID/名称、Scenario 路径、模式(unified/separate) + # 规则列表:request_model → provider / model [active|inactive] +``` + +> `--list` 与 `--show` 互斥。Profile 名称未找到时,启动和查看均会回退到交互式选择器。 + +#### `tingly-box cc` — 带 Claude CLI 透传的启动方式 + +需要同时传递 Claude Code 自身参数时使用此命令。Tingly-Box 先消费自己的参数,其余部分原样转发给 Claude CLI,无需 `--` 分隔符。 + +```bash +tingly-box cc # 使用默认 Profile 启动 Claude Code +tingly-box cc --profile p1 # 使用 Profile p1 启动(短写:-p p1) +tingly-box cc -p p1 --tingly-port 12580 # Profile p1,连接远程 Tingly-Box +tingly-box cc -p p1 --dangerously-skip-permissions # 将 Claude 参数原样透传 +tingly-box cc -p p1 /path/to/project # 在 Claude Code 中打开指定目录 +``` + +Tingly-Box 参数(`--profile`/`-p`、`--tingly-port`)必须放在所有 Claude 参数之前。遇到第一个无法识别的 token 后,后续内容均透传给 Claude。 + +--- + +## 常见配置流程 + +1. 在 [凭证管理](./08-credentials.md) 添加至少一个 Provider +2. 进入 Claude Code 页面,确认 Base URL 和 API Key +3. (可选)在转发规则中为不同请求类型指定模型 +4. 点击 **Auto Config** → 确认配置 → **Quick Apply**(可勾选状态栏选项) +5. 开始使用 Claude Code CLI + +--- + +## 相关页面 + +- [场景总览](./02-scenario-overview.md) +- [凭证管理](./08-credentials.md) +- [其他编程 Agent](./04-scenario-coding-agents.md) diff --git a/docs/guide/zh/04-scenario-codex.md b/docs/guide/zh/04-scenario-codex.md new file mode 100644 index 000000000..0062d3538 --- /dev/null +++ b/docs/guide/zh/04-scenario-codex.md @@ -0,0 +1,48 @@ +# Codex 场景 + +路径:`/agent/codex` + +Codex 场景将 OpenAI Codex CLI 的 API 请求代理到你配置的 Provider,支持自动配置和灵活的转发规则。 + +--- + +![Codex 场景](../images/codex.png) + +## 页面结构 + +页面由以下区域从上到下依次构成: + +### 1. Codex 配置卡 + +展示当前场景的连接信息: +- **Base URL**:Codex CLI 应配置的代理地址(含复制按钮) +- **API Key**:供 CLI 使用的令牌(含复制/显示按钮) + +### 2. Agent 设置卡 + +- **安装命令**:提供 Codex CLI 的安装命令,支持一键复制 +- **Auto Config** 按钮:自动将代理配置写入 Codex 配置文件(设置 `OPENAI_BASE_URL` 和 `OPENAI_API_KEY`) + +### 3. 模型与转发规则(可折叠) + +管理 Codex 场景的路由规则,支持添加、编辑和删除规则。 + +--- + +## 配置流程 + +1. 在 [凭证管理](./08-credentials.md) 添加至少一个 Provider +2. 打开 Codex 场景页,确认 Base URL 和 API Key +3. 安装 Codex CLI(见安装命令) +4. 点击 **Auto Config** 自动写入代理配置,或手动设置: + - `OPENAI_BASE_URL`:填写 Base URL + - `OPENAI_API_KEY`:填写 API Key +5. 在终端中使用 Codex CLI + +--- + +## 相关页面 + +- [Claude Code 场景](./03-scenario-claude-code.md) +- [其他编程 Agent](./05-scenario-coding-agents.md) +- [凭证管理](./08-credentials.md) diff --git a/docs/guide/zh/04-scenario-coding-agents.md b/docs/guide/zh/04-scenario-coding-agents.md new file mode 100644 index 000000000..652140073 --- /dev/null +++ b/docs/guide/zh/04-scenario-coding-agents.md @@ -0,0 +1,71 @@ +# 其他编程 Agent 场景 + +本章介绍除 Claude Code 和 Codex 之外的编程工具代理场景,包括 OpenCode、VS Code、Xcode 和 Claude Desktop。这些场景的配置结构与 Claude Code 类似。 + +--- + +## OpenCode + +路径:`/agent/opencode` + +代理 OpenCode CLI 的请求。页面结构与 Codex 完全一致: + +- 配置卡 + 代理地址/Key +- Agent 设置 + 安装引导 +- 转发规则管理 + +--- + +## VS Code + +路径:`/agent/vscode` + +代理 VS Code AI 扩展(如 GitHub Copilot Chat、Continue 等)的 API 请求。 + +### 说明 + +VS Code 扩展通常通过 `baseURL` 环境变量或扩展设置指定 API 端点,将其指向 Tingly-Box 提供的代理地址即可。 + +--- + +## Xcode + +路径:`/agent/xcode` + +代理 Apple Xcode AI 功能(Xcode Intelligence)的 API 请求。配置方式与 VS Code 类似,将 API 端点指向 Tingly-Box 提供的代理地址。 + +--- + +## Claude Desktop + +路径:`/agent/claude_desktop` + +代理 Claude 桌面客户端(Desktop App)的 API 请求。 + +### 页面结构 + +1. **Claude Desktop 配置卡**:展示代理地址和 API Key +2. **Config 模态框**:提供完整的 `claude_desktop_config.json` 配置片段,可一键复制并粘贴到 Claude Desktop 的配置文件中 +3. **模型与转发规则**(可折叠) + +### 配置流程 + +1. 点击 **Config** 打开配置模态框 +2. 复制 JSON 配置片段 +3. 打开 Claude Desktop 设置文件,粘贴配置 +4. 重启 Claude Desktop + +--- + +## 场景可见性 + +在 [场景总览](./02-scenario-overview.md) 页面,可通过卡片底部的开关将不常用的场景从侧边栏隐藏。 + +--- + +## 相关页面 + +- [Claude Code 场景](./03-scenario-claude-code.md) +- [Codex 场景](./04-scenario-codex.md) +- [场景总览](./02-scenario-overview.md) +- [凭证管理](./08-credentials.md) diff --git a/docs/guide/zh/05-scenario-sdk-proxy.md b/docs/guide/zh/05-scenario-sdk-proxy.md new file mode 100644 index 000000000..8a98e8514 --- /dev/null +++ b/docs/guide/zh/05-scenario-sdk-proxy.md @@ -0,0 +1,82 @@ +# OpenAI / Anthropic SDK 代理 + +本章介绍 OpenAI 兼容接口代理和 Anthropic 原生接口代理两个场景,适用于在代码中直接调用 API 的应用程序。 + +--- + +## OpenAI 场景 + +路径:`/agent/openai` + +将任何使用 OpenAI SDK 的应用程序的请求,透明代理到 Tingly-Box 管理的 Provider。 + +### 使用场景 + +- 自己开发的 Python/Node.js/Go 应用使用 `openai` 官方 SDK +- 第三方工具配置了 OpenAI 兼容端点(如 LangChain、LlamaIndex 等) +- 需要统一管理多个 OpenAI 兼容 Provider 的访问凭证 + +### 页面结构 + +1. **OpenAI 配置卡**:展示代理 Base URL 和 API Key +2. **模型与转发规则**(可折叠):配置请求路由到哪个 Provider + +### 接入方式 + +在你的应用程序中,将 OpenAI SDK 的 `baseURL` 指向 Tingly-Box 提供的代理地址: + +```python +from openai import OpenAI +client = OpenAI( + base_url="", + api_key="", +) +``` + +```javascript +import OpenAI from 'openai'; +const client = new OpenAI({ + baseURL: '', + apiKey: '', +}); +``` + +--- + +## Anthropic 场景 + +路径:`/agent/anthropic` + +将使用 Anthropic 官方 SDK 的应用程序请求,代理到 Tingly-Box 管理的 Provider(包括非 Anthropic 的 Provider,只要支持 Anthropic 协议即可)。 + +### 使用场景 + +- 应用程序使用 `anthropic` 官方 SDK 直接调用 Claude API +- 需要在不改变代码的情况下切换底层 Provider +- 需要统计和审计 Anthropic API 调用 + +### 接入方式 + +将 Anthropic SDK 的 `base_url` 指向 Tingly-Box 提供的代理地址: + +```python +import anthropic +client = anthropic.Anthropic( + base_url="", + api_key="", +) +``` + +--- + +## 与凭证管理的关系 + +这两个场景的转发规则决定了请求最终发往哪个 Provider。若尚未添加 Provider,请先前往 [凭证管理](./08-credentials.md) 完成配置。 + +--- + +## 相关页面 + +- [场景总览](./02-scenario-overview.md) +- [Claude Code 场景](./03-scenario-claude-code.md) +- [凭证管理](./08-credentials.md) diff --git a/docs/guide/zh/06-scenario-special.md b/docs/guide/zh/06-scenario-special.md new file mode 100644 index 000000000..2febbaa31 --- /dev/null +++ b/docs/guide/zh/06-scenario-special.md @@ -0,0 +1,91 @@ +# Claw Agent / Embed / ImageGen + +本章介绍三个专用场景:OpenClaw 通用 Agent、Embedding API 代理和图像生成 API 代理。 + +--- + +## Claw Agent(OpenClaw) + +路径:`/agent/agent` + +OpenClaw 是一个通用 Agent 接口,提供标准化的 API 端点供自定义 Agent 框架接入。 + +### 页面结构 + +1. **Provider 配置卡**: + - **Base URL**:Agent 接口地址(含复制按钮) + - **API Key**:访问凭证(含复制按钮) +2. **模型与转发规则**(可折叠):配置 Agent 请求的路由规则 + +### 使用场景 + +- 自定义 Agent 框架需要统一的 API 端点 +- 多个 Agent 需要共享同一组 Provider 凭证 +- 需要为 Agent 访问配置独立的路由规则 + +--- + +## Embed(Embedding API) + +路径:`/agent/embed` + +代理 Embedding API 请求,适用于文本向量化应用。 + +### 页面结构 + +1. **Embed API 配置卡**:展示代理地址和 Key +2. **Embedding 模型与转发规则**(可折叠):专门针对 Embedding 模型配置路由 + +### 使用场景 + +- RAG(检索增强生成)应用的文本向量化 +- 语义搜索系统 +- 文本相似度计算 + +### 接入方式 + +```python +from openai import OpenAI +client = OpenAI( + base_url="", + api_key="", +) +response = client.embeddings.create( + model="text-embedding-3-small", + input="your text here", +) +``` + +--- + +## ImageGen(图像生成) + +![ImageGen 场景](../images/imagegen.png) + +路径:`/agent/imagegen` + +代理图像生成 API 请求(如 DALL-E 兼容接口)。 + +### 页面结构 + +1. **ImageGen API 配置卡**:展示代理地址和 Key +2. **快速入门示例**:提供 curl 示例请求,一键复制 +3. **图像生成模型与转发规则**(可折叠) +4. **Open Playground** 按钮:跳转到 [Playground](./07-scenario-playground.md) 页面进行交互测试 + +### 接入方式 + +```bash +curl /images/generations \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + -d '{"model": "dall-e-3", "prompt": "a cute cat", "n": 1, "size": "1024x1024"}' +``` + +--- + +## 相关页面 + +- [Playground(图像生成测试台)](./07-scenario-playground.md) +- [场景总览](./02-scenario-overview.md) +- [凭证管理](./08-credentials.md) diff --git a/docs/guide/zh/07-scenario-playground.md b/docs/guide/zh/07-scenario-playground.md new file mode 100644 index 000000000..408ba0c88 --- /dev/null +++ b/docs/guide/zh/07-scenario-playground.md @@ -0,0 +1,54 @@ +# Playground(图像生成测试台) + +路径:`/agent/playground` + +Playground 是一个交互式的图像生成测试界面,让你无需写代码即可测试图像生成 API 的效果。 + +--- + +![Playground](../images/playground.png) + +## 页面结构 + +### 参数面板 + +位于页面左侧或顶部,包含以下控制项: + +| 参数 | 说明 | +|------|------| +| **Model** | 下拉选择,从已配置的 ImageGen 转发规则中自动读取可用模型 | +| **Size** | 图像尺寸:256×256 / 512×512 / 1024×1024 / 1024×1792 / 1792×1024 | +| **Quality** | 图像质量:auto / low / medium / high / standard | +| **N** | 生成数量,范围 1–10 | +| **Prompt** | 多行文本框,输入图像描述 | + +### 生成与结果区 + +- **Generate 按钮**:提交生成请求(未选择模型或未填写 Prompt 时禁用) +- 生成中显示加载旋转图标 +- 生成完成后,结果图片以网格方式展示在页面中 +- 每张生成图片可直接在浏览器中查看或右键保存 + +--- + +## 使用前提 + +Playground 需要先在 [ImageGen 场景](./06-scenario-special.md) 中配置至少一条转发规则,Model 下拉列表才会有可选项。 + +--- + +## 使用流程 + +1. 前往 `/agent/imagegen`,确认已配置图像生成转发规则 +2. 点击页面上的 **Open Playground** 按钮,或直接访问 `/agent/playground` +3. 选择模型和参数 +4. 在 Prompt 框中输入描述,如:`a watercolor painting of a mountain lake at sunset` +5. 点击 **Generate**,等待图片生成 +6. 查看结果,调整参数后可继续测试 + +--- + +## 相关页面 + +- [ImageGen 场景](./06-scenario-special.md) +- [场景总览](./02-scenario-overview.md) diff --git a/docs/guide/zh/08-credentials.md b/docs/guide/zh/08-credentials.md new file mode 100644 index 000000000..2a02585bf --- /dev/null +++ b/docs/guide/zh/08-credentials.md @@ -0,0 +1,132 @@ +# 凭证管理 + +路径:`/credentials` + +凭证管理页面是 Tingly-Box 的配置主链路核心,所有 Provider 的 API Key 和 OAuth 凭证均在此集中管理。 + +--- + +![凭证管理](../images/credentials.png) + +## 页面概览 + +侧边栏中该页面所在分组标签为 **Credential**,下含三个子页面:**Model Key**(本页)、**Sharing**(见 [API Tokens](./10-api-tokens.md))、**Virtual Models**。 + +页面顶部显示当前凭证总数(如 `Managing 5 credentials`),顶部操作栏包含: + +| 按钮 | 功能 | +|------|------| +| **Connect AI** | 打开统一 Provider 选择器,添加新凭证(与 Onboarding 流程相同) | +| **Import** | 批量导入 Provider 配置(JSON/YAML 格式) | +| **Providers** | 跳转到 Onboarding 页面(浏览全部 Provider) | + +--- + +## 凭证类型 + +### API Keys 表格 + +展示所有通过 API Key 方式接入的 Provider: + +| 列 | 说明 | +|----|------| +| Provider | Provider 名称与图标 | +| Base URL | API 端点地址 | +| Token | API Key(脱敏显示) | +| Status | 启用/禁用状态 | +| Quota | 已知配额信息(可点击刷新) | +| Actions | 编辑、删除、启用/禁用 | + +### OAuth 表格 + +展示所有通过 OAuth 授权接入的 Provider(如 Claude.ai): + +| 列 | 说明 | +|----|------| +| Provider | Provider 名称 | +| Status | 授权状态 | +| Expiry | Token 过期时间 | +| Actions | 刷新 Token、编辑、删除、启用/禁用 | + +--- + +## 添加 Provider(Connect AI 流程) + +点击 **Connect AI** 打开 Provider 选择器。这是接入任何 AI 服务的统一入口,分两步完成:**先选类型,再填配置**。 + +### 第一步:选择 Provider + +![Connect AI 选择器](../images/connect-ai.png) + +顶部是搜索框(按名称过滤),下方按接入方式分区展示,每张卡片右上角有彩色标签标明类型: + +| 分区 | 说明 | 选中后 | +|------|------|--------| +| **Custom** | `Custom endpoint`(自带任意 Base URL)、`Import`(从文件/剪贴板导入) | 打开空白配置表单 / 导入对话框 | +| **OAuth sign-in** | 支持 OAuth 授权的 Provider(Claude Code、Google Gemini CLI、Codex 等) | **直接发起 OAuth 授权**,无需填 API Key | +| **Self-hosted** | 本地自托管服务(如 Ollama),卡片显示 `localhost:端口` | 打开配置表单,Base URL 已预填但**可编辑**(按你的主机/端口调整) | +| **API key providers** | 通过 API Key 接入的云端 Provider,按区域分组(CN / Global),卡片标注协议(OpenAI · Anthropic) | 打开配置表单,名称和 Base URL 已预填 | + +> 大多数 Provider 都已内置,只需提供它们各自需要的信息。列表里没有?选 **Custom endpoint** 手动填任意端点。 + +### 第二步:填写配置表单 + +![Provider 配置表单](../images/connect-ai-form.png) + +选中非 OAuth 的 Provider 后弹出配置表单: + +- **Base URL**(必填):API 端点。预置 Provider 已预填;Custom / Self-hosted 可自由编辑 +- **API Key**(必填):访问令牌;若是本地无鉴权服务,打开 **No API Key Required** 开关即可免填 +- **API Style(协议)**: + - **OpenAI Compatible**(推荐):大多数端点都兼容 OpenAI 协议,不确定时选它 + - **Anthropic**:原生 Anthropic 协议 + - 两者可同时启用(融合 Provider),让同一凭证同时服务 OpenAI 和 Anthropic 两种入站协议 +- **Proxy URL**(可选,展开高级):为该 Provider 单独走 HTTP 代理 +- **User Agent**(可选,展开高级):自定义请求头 + +填好后可点 **Test** 验证连通性,再 **Save** 保存。 + +> **OAuth Provider 例外**:在第一步选中 OAuth 卡片后直接跳转授权页,无需第二步表单,授权完成自动保存 Token。 + +--- + +## 批量导入 + +点击 **Import** 按钮: + +1. 选择文件(JSON 或 YAML 格式)或直接粘贴配置内容 +2. 支持的格式示例: + ```yaml + providers: + - name: "My OpenAI" + api_base: "https://api.openai.com/v1" + api_style: "openai" + token: "sk-..." + ``` +3. 点击 **Import** 确认导入 +4. 如有重复 Provider,系统提示是否强制覆盖(Force Add) + +--- + +## 编辑 Provider + +点击 Provider 行右侧的编辑图标,打开编辑表单,可修改: +- 名称 +- API Base URL +- API Key/Token +- 代理设置 +- 启用/禁用状态 + +--- + +## 启用 / 禁用 Provider + +每个 Provider 行都有一个开关,用于快速启用或禁用。禁用的 Provider 不会接受新的路由请求,但配置保留。 + +--- + +## 相关页面 + +- [虚拟模型](./09-virtual-models.md) +- [API Tokens](./10-api-tokens.md) +- [快速上手](./01-getting-started.md) diff --git a/docs/guide/zh/09-virtual-models.md b/docs/guide/zh/09-virtual-models.md new file mode 100644 index 000000000..c8b8b1926 --- /dev/null +++ b/docs/guide/zh/09-virtual-models.md @@ -0,0 +1,58 @@ +# 虚拟模型 + +路径:`/credentials/virtual-models` + +虚拟模型(Virtual Models)是 Tingly-Box 内置的合成模型 Provider,无需真实 API Key 即可使用,适用于演示、开发调试和干运行(dry-run)场景。 + +--- + +![虚拟模型](../images/virtual-models.png) + +## 页面概览 + +页面副标题:`Built-in synthetic model providers for onboarding, demos, and dry-runs.` + +### 虚拟模型表格 + +展示所有内置的虚拟模型 Provider: + +| 列 | 说明 | +|----|------| +| Provider | 虚拟 Provider 名称 | +| Status | 启用/禁用状态开关 | + +--- + +## 使用场景 + +| 场景 | 说明 | +|------|------| +| **初始化演示** | 在未配置真实 Provider 时,通过虚拟模型走通完整 UI 流程 | +| **开发调试** | 测试转发规则配置是否正确,无需消耗真实 API 配额 | +| **功能演示** | 向团队演示 Tingly-Box 功能,无需暴露真实 API Key | + +--- + +## 与真实 Provider 的区别 + +- 虚拟模型 Provider **内置**,无法通过 UI 新增或删除 +- 返回的响应为**模拟内容**,不调用真实 AI 模型 +- 可通过开关**启用/禁用**单个虚拟 Provider +- 适用于 Tingly-Box 的**所有场景**(Claude Code、OpenAI、Anthropic 等) + +--- + +## 启用方式 + +1. 访问 `/credentials/virtual-models` +2. 找到目标虚拟 Provider +3. 将对应开关切换为**启用** + +启用后,虚拟 Provider 将出现在各场景的模型路由选项中,可像真实 Provider 一样配置转发规则。 + +--- + +## 相关页面 + +- [凭证管理](./08-credentials.md) +- [API Tokens](./10-api-tokens.md) diff --git a/docs/guide/zh/10-api-tokens.md b/docs/guide/zh/10-api-tokens.md new file mode 100644 index 000000000..3d9c00d7d --- /dev/null +++ b/docs/guide/zh/10-api-tokens.md @@ -0,0 +1,89 @@ +# API Tokens + +路径:`/tingly-box-token`——侧边栏(Credential 分组下)显示为 **Sharing**,因为这些令牌正是用来向他人分享模型访问权限的。 + +API Tokens 页面用于管理外部客户端访问 Tingly-Box 所使用的 Bearer Token,支持创建多个具名令牌,适用于脚本、CI/CD 或第三方集成。 + +--- + +![API Tokens](../images/api-tokens.png) + +## 页面结构 + +### Token 列表表格 + +| 列 | 说明 | +|----|------| +| Name | Token 名称(创建时指定) | +| UUID | Token 唯一标识(截断显示) | +| Token | Token 值(默认脱敏,可点击显示/隐藏) | +| Status | Active / Disabled | +| Created | 创建日期 | +| Last Used | 最近使用日期 | +| Actions | 复制、显示/隐藏、删除 | + +无 Token 时显示空状态图标和提示。 + +--- + +## 创建 Token + +1. 点击右上角 **Create Token** 按钮 +2. 在对话框中输入 **Display Name**(如 `ci-pipeline`、`my-script`) +3. 点击确认,Token 值即时生成并显示 + +> **注意**:Token 值仅在创建后首次显示,请立即复制保存。 + +--- + +## 使用 Token + +创建的 Token 可作为 Bearer Token 用于访问 Tingly-Box 的代理接口: + +```bash +curl https:///api/... \ + -H "Authorization: Bearer " +``` + +也可在 SDK 配置中作为 `api_key` 使用: + +```python +client = OpenAI( + base_url="https:///agent/openai/v1", + api_key="", +) +``` + +--- + +## 管理 Token + +### 查看 Token 值 + +点击 Token 行的眼睛图标,切换明文/脱敏显示。 + +### 复制 Token + +点击复制图标,Token 值写入剪贴板。 + +### 删除 Token + +点击删除图标,弹出确认对话框(显示 Token 名称),确认后永久删除。删除后该 Token 立即失效,持有该 Token 的客户端将无法再访问。 + +--- + +## 与用户令牌的区别 + +| | API Token | 用户令牌(User Token) | +|-|-----------|----------------------| +| 管理位置 | `/tingly-box-token` | `/access-control` | +| 用途 | 外部客户端/脚本 | Web UI 登录认证 | +| 数量 | 多个 | 单一 | +| 可命名 | 是 | 否 | + +--- + +## 相关页面 + +- [访问控制](./18-access-control.md) +- [凭证管理](./08-credentials.md) diff --git a/docs/guide/zh/11-dashboard.md b/docs/guide/zh/11-dashboard.md new file mode 100644 index 000000000..6a19e97b3 --- /dev/null +++ b/docs/guide/zh/11-dashboard.md @@ -0,0 +1,126 @@ +# 用量看板 + +路径:`/dashboard/:timeRange`(默认 `/dashboard/7d`) + +用量看板提供 AI 请求的使用统计和可视化分析,帮助了解各 Provider 和模型的调用量、Token 消耗、缓存命中率等指标。 + +--- + +![用量看板](../images/dashboard.png) + +## 时间范围选择 + +页面顶部提供时间范围快速切换: + +| 选项 | 路径 | 说明 | +|------|------|------| +| Today | `/dashboard/today` | 当日(按分钟粒度,每分钟自动刷新) | +| Yesterday | `/dashboard/yesterday` | 昨日(按分钟粒度) | +| 3D | `/dashboard/3d` | 近 3 天(按日展示) | +| 7D | `/dashboard/7d` | 近 7 天(按日展示,默认) | +| 30D | `/dashboard/30d` | 近 30 天(按日展示) | +| 90D | `/dashboard/90d` | 近 90 天(按日展示) | + +--- + +## 统计卡片 + +页面顶部 5 个统计卡片汇总当前时间范围内的关键指标: + +| 指标 | 说明 | +|------|------| +| **Total Requests** | 总请求次数 | +| **Total Tokens** | 总 Token 数(细分显示 Input / Cache / Output) | +| **Cache Hit Rate** | 缓存命中率(百分比);绿色 ≥50%,黄色 ≥20%,橙色 <20% | +| **Error Rate** | 请求失败率 | +| **Streamed Rate** | 流式响应比例 | + +--- + +## 筛选器 + +顶部提供三个并排下拉菜单: + +**Provider 筛选**:按认证类型分组展示所有可用 Provider(OAuth / API Key / Bearer Token / Basic Auth / Virtual Model)。选择后,图表和表格仅显示该 Provider 的数据。 + +**Model 筛选**:下拉列出当前时间范围内有数据的所有模型(按 Token 用量降序)。选择后仅展示该模型的数据。 + +**Identity 筛选**:按请求方身份(`user_id`)筛选(如有数据)。 + +三个筛选器可组合使用;有活跃筛选时顶部显示 **Clear filters** 按钮。 + +--- + +## 自动刷新 + +顶部提供 **自动刷新** 开关(Auto-refresh)和手动 **刷新** 按钮,开启后数据每分钟自动更新。 + +--- + +## 图表区域 + +### 时序图(Token 历史) + +- **今日/昨日**:按**分钟**粒度展示 Token 使用量(每分钟自动刷新,Input / Cache / Output 堆叠) +- **3D / 7D / 30D / 90D**:按天粒度展示每日 Token 使用量 + +### Summary / By Request / Activity 切换 + +图表上方的分段按钮组用于切换展示模式: +- **Summary**:上述时序图(今日/昨日为分钟粒度折线,其余为按日柱状图) +- **By Request**:仅今日/昨日可见——单条请求明细列表(时间、模型、Token 数、响应时间等) +- **Activity**:GitHub 风格的贡献热力图,详见下文「活动热力图」一节 + +--- + +## 右侧:Models by Token Usage + +显示当前时间范围内按 Token 消耗量排名的所有模型(带分页): +- 模型名称 + 所属 Provider +- Token 消耗量(带进度条) +- 点击可快速**按该模型筛选**(而非 Provider) + +--- + +## 底部:服务统计表格 + +按模型/Provider 细分展示详细统计数据: + +| 列 | 说明 | +|----|------| +| Model | 模型名称 + Provider | +| Requests | 请求次数 | +| Input Tokens | 输入 Token 数 | +| Output Tokens | 输出 Token 数 | +| Cache Tokens | 缓存命中 Token 数 | +| Errors | 错误次数 | +| Cache Hit % | 缓存命中率 | +| Streamed % | 流式响应比例 | + +--- + +## 今日/昨日视图补充 + +![今日视图(按小时)](../images/dashboard-today.png) + +当选择 `Today` 或 `Yesterday` 时,图表切换为**按分钟**粒度,可实时看到 Token 用量曲线,每分钟自动刷新;同时 Summary/By Request/Activity 切换按钮组中会出现 **By Request** 选项,展示每条请求的详细记录。 + +--- + +## 活动热力图 + +![活动热力图](../images/dashboard-activity.png) + +点击图表区切换按钮组中的 **Activity**,即可在 Dashboard 内部切换为 GitHub 风格的贡献热力图——该视图原本是独立的 `/overview` 页面,现已合并为同一图表区的一种视图,并与看板的 Provider / Model / Identity 筛选器共享数据。 + +- **固定窗口**:始终展示**最近 365 天**,不受页面选定时间范围影响(7D/30D 等仅影响 Summary/By Request 视图) +- **网格**:横轴为月份,纵轴为周内星期(Mon–Sun);色块深浅对应当日 Token 使用量(颜色越深 = 使用越多) +- **底部统计**:该窗口内的 Token 总量、活跃天数/总天数、最长连续活跃天数、单日最高用量 +- 首次加载时显示骨架占位,避免在数据到达前闪现空状态 + +--- + +## 相关页面 + +- [系统设置](./17-system-settings.md) +- [凭证管理](./08-credentials.md) diff --git a/docs/guide/zh/12-remote-control.md b/docs/guide/zh/12-remote-control.md new file mode 100644 index 000000000..ebec04ff4 --- /dev/null +++ b/docs/guide/zh/12-remote-control.md @@ -0,0 +1,112 @@ +# 远程控制 + +路径:`/remote-control/:platform`(Full Edition) + +远程控制功能允许通过主流 IM 平台(即时通讯工具)远程操控 Claude Code,实现随时随地通过聊天发送指令、接收结果。 + +> **注意**:远程控制功能仅在 **Full Edition** 中可用。 + +--- + +![远程控制(Telegram)](../images/remote-control.png) + +## 支持的平台 + +在左侧侧边栏「Remote」分组下可看到所有支持的平台: + +| 平台 | 路径 | +|------|------| +| 微信(Weixin) | `/remote-control/weixin` | +| 企业微信(WeCom) | `/remote-control/wecom` | +| Telegram | `/remote-control/telegram` | +| 飞书(Feishu) | `/remote-control/feishu` | +| Lark | `/remote-control/lark` | +| 钉钉(DingTalk) | `/remote-control/dingtalk` | +| QQ | `/remote-control/qq` | +| Discord | `/remote-control/discord` | +| Slack | `/remote-control/slack` | + +--- + +## 页面结构 + +每个平台页面结构基本一致: + +### 平台接入指南(可折叠) + +展开后显示该平台的 Bot 配置说明,包括: +- 如何在对应平台创建 Bot +- 需要获取哪些凭证(Token、Secret 等) +- Webhook 地址设置方式(如有) + +### Bot 列表 + +展示当前平台已配置的所有 Bot: +- Bot 名称/别名 +- 状态指示器(运行中/已停止/错误) +- Bot 数量汇总(`active N / total N`) + +### 操作 + +每个 Bot 卡片提供以下操作: +- **启用/禁用**开关 +- **重启** 按钮 +- **删除** 按钮 +- **编辑** 配置 + +--- + +## 添加 Bot + +点击 **Add Bot** 按钮,填写 Bot 配置表单: + +| 字段 | 说明 | +|------|------| +| **Name** | Bot 别名(可选,便于识别) | +| **Platform** | 平台选择(当前页面已预选) | +| **Token** | 平台 API Token / Bot Token | +| **Proxy URL** | HTTP/HTTPS 代理(可选,用于访问受限平台) | +| **Chat ID Lock** | 限制 Bot 只响应指定聊天 ID 的消息(可选) | +| **Bash Allowlist** | 允许执行的 Shell 命令白名单(多行,可选) | +| **Model** | 指定该 Bot 使用的 AI 模型 | +| **Working Directory** | 默认工作目录 | + +### 微信特殊配置 + +微信 Bot 使用**扫码授权**而非 Token 方式,配置后系统显示二维码供扫码登录。 + +--- + +## Bot 安全设置 + +### Chat ID Lock + +填写聊天 ID(群 ID 或用户 ID)后,Bot 只会响应来自指定对话的消息,防止 Bot 被未授权用户控制。 + +### Bash Allowlist + +每行一条命令模式,限制 Bot 可以执行的 Shell 命令范围。未在白名单中的命令将被拒绝执行。示例: + +``` +ls +cat *.md +git status +git diff +``` + +--- + +## 使用方式 + +配置完成后,在对应 IM 平台中找到 Bot,发送消息即可: + +- 发送代码需求 → Bot 调用 Claude Code 执行 +- 查询状态 → Bot 返回当前运行状态 +- 发送文件 → Bot 在工作目录处理文件 + +--- + +## 相关页面 + +- [Remote Coder](./13-remote-coder.md) +- [系统设置](./17-system-settings.md) diff --git a/docs/guide/zh/13-remote-coder.md b/docs/guide/zh/13-remote-coder.md new file mode 100644 index 000000000..423b01f1b --- /dev/null +++ b/docs/guide/zh/13-remote-coder.md @@ -0,0 +1,97 @@ +# Remote Coder + +路径:`/remote-coder/chat`、`/remote-coder/sessions` + +Remote Coder 提供基于 Web 的对话界面,直接在浏览器中与 Claude Code 会话交互,并提供会话管理和监控能力。 + +--- + +![Remote Coder](../images/remote-coder.png) + +## Chat 页面(`/remote-coder/chat`) + +### 页面结构 + +**顶部栏:** +- 当前会话 ID 显示 +- **New Chat** 按钮:创建新会话 +- **Manage Sessions** 按钮:跳转到会话管理页 + +**配置区:** +- **Session 选择器**:下拉菜单选择已有会话 +- **Project Path 字段**:指定 Claude Code 的工作目录(首次发送消息前必填) + +**对话区:** +- 聊天历史记录,自动滚动到最新消息 +- 消息摘要显示,支持展开/折叠完整内容 +- `Claude Code is thinking...` 加载状态指示 +- 错误信息提示区 + +**输入区:** +- 多行文本输入框(`Shift+Enter` 换行,`Enter` 发送) + +--- + +## 使用流程 + +1. 访问 `/remote-coder/chat` +2. 在 **Project Path** 中填写要操作的项目路径(如 `/home/user/my-project`) +3. 选择已有会话或发送第一条消息自动创建新会话 +4. 在输入框中输入需求,如:`帮我分析这个项目的结构` 或 `修复第 42 行的 bug` +5. 等待 Claude Code 执行并返回结果 + +--- + +## Sessions 页面(`/remote-coder/sessions`) + +![Remote Coder Sessions](../images/remote-coder-sessions.png) + +### 页面结构 + +**统计卡片(顶部):** + +| 指标 | 说明 | +|------|------| +| Total | 总会话数 | +| Active | 运行中会话数 | +| Completed | 已完成会话数 | +| Failed | 失败会话数 | +| Closed | 已关闭会话数 | +| Uptime | 服务运行时长 | + +**左侧面板(40%宽):会话列表** + +- 状态筛选:All / Running / Completed / Failed / Closed +- 搜索框:按会话 ID 或内容搜索 +- 每条会话显示:ID、状态徽章、时间 + +**右侧面板(60%宽):会话详情** + +点击左侧会话后,右侧展示: +- 完整请求内容 +- 响应摘要 +- 错误信息(如有) +- 会话元数据 + +### 操作 + +- **Refresh** 按钮:手动刷新会话列表 +- **Clear All Sessions** 按钮:清空全部会话记录(需确认) + +--- + +## 与远程控制的区别 + +| | Remote Coder | 远程控制 | +|-|-------------|----------| +| 交互方式 | Web 浏览器 Chat | IM 平台消息 | +| 实时性 | 实时(Web Push) | 依赖平台推送延迟 | +| 会话管理 | 内置会话视图 | 无独立管理 | +| 适用场景 | 开发者直接操作 | 随时随地远程触发 | + +--- + +## 相关页面 + +- [远程控制](./12-remote-control.md) +- [场景总览](./02-scenario-overview.md) diff --git a/docs/guide/zh/14-prompt-management.md b/docs/guide/zh/14-prompt-management.md new file mode 100644 index 000000000..23c0ca246 --- /dev/null +++ b/docs/guide/zh/14-prompt-management.md @@ -0,0 +1,98 @@ +# Prompt 管理 + +路径:`/prompt/user`、`/prompt/skill`、`/prompt/command`(Full Edition) + +Prompt 管理提供 IDE 录制浏览、Skills 管理等功能,帮助团队积累和复用 AI 编程知识。 + +> **注意**:Prompt 管理功能仅在 **Full Edition** 中可用,且需要在 [实验性功能](./19-experimental.md) 中开启对应开关。 + +--- + +## 用户录制(User Requests) + +路径:`/prompt/user` + +### 功能说明 + +User Requests 页面浏览和管理从 Claude Code IDE 会话中录制的交互记录,适合: +- 回顾历史 AI 辅助决策过程 +- 提取成功的提示词模板 +- 团队经验分享 + +### 三列布局 + +**左列:日历** +- 日历视图,日期上显示录制条数 +- 范围筛选按钮(今日/本周/本月/全部) + +**中列:录制列表** +- 搜索框:按内容搜索 +- User 筛选:按录制用户过滤 +- Project 筛选:按项目过滤 +- Type 筛选:code-review / debug / refactor / test +- 每条录制显示标题、类型徽章、时间 + +**右列:录制详情** +- 摘要(Summary) +- 元数据:用户、项目、类型、时长、模型、时间戳 +- 完整对话内容 + +--- + +## Skills 管理 + +![Skills 管理](../images/prompt-skills.png) + +路径:`/prompt/skill` + +### 功能说明 + +Skills 页面管理从 IDE 配置(如 `.claude/skills/` 目录)同步的可复用 Prompt 片段,支持: +- 从多个 IDE 来源自动发现 Skills +- 分组浏览和搜索 +- 查看 Skill 的 Markdown/原始内容 + +### 三列布局 + +**左列:Skill 位置(Locations)** + +每个 Skill 位置(Location)对应一个目录来源: +- 位置名称 +- 路径 +- IDE 来源徽章(如 claude_code) +- Skill 数量 +- 操作:刷新、编辑、删除 + +顶部按钮: +- **Add Location**:手动添加 Skill 目录 +- **Auto Discovery**:自动扫描所有已配置 IDE 中的 Skill 目录 + +**中列:Skills 列表** + +选中位置后展示该位置下的所有 Skills: +- **分组/平铺** 视图切换 +- 分组策略:Auto / Pattern / Flat +- 搜索过滤 + +**右列:Skill 内容** + +选中 Skill 后展示: +- 文件元数据(路径、大小、修改时间) +- **Markdown 渲染**视图(默认) +- **Raw** 原始文本视图 +- 复制按钮 + +--- + +## Commands(命令管理) + +路径:`/prompt/command` + +当前状态:**Coming Soon**(功能开发中) + +--- + +## 相关页面 + +- [实验性功能](./19-experimental.md) +- [Claude Code 场景](./03-scenario-claude-code.md) diff --git a/docs/guide/zh/15-guardrails.md b/docs/guide/zh/15-guardrails.md new file mode 100644 index 000000000..084e2d4e7 --- /dev/null +++ b/docs/guide/zh/15-guardrails.md @@ -0,0 +1,182 @@ +# 防护栏(Guardrails) + +路径:`/guardrails`、`/guardrails/groups`、`/guardrails/rules`、`/guardrails/history` + +防护栏(Guardrails)对 AI Agent 的工具调用和工具结果进行基于规则的安全检查,防止危险操作、保护隐私数据、控制资源访问。 + +> **注意**:Guardrails 功能需要在 [实验性功能](./19-experimental.md) 中开启 Guardrails 开关后,侧边栏才会显示。 + +--- + +![防护栏总览](../images/guardrails.png) + +## 防护栏总览(`/guardrails`) + +### 统计看板 + +**Policy Breakdown(左卡)** — 按策略类型汇总: + +| 类型 | 说明 | +|------|------| +| Resource Access | 文件读写、网络访问控制策略数量(启用/总计) | +| Command Execution | Shell 命令执行控制策略数量 | +| Privacy (Content) | 内容隐私过滤策略数量 | + +**Event Summary(右卡)** — 防护事件统计: + +| 指标 | 颜色 | +|------|------| +| Total Events | — | +| Allow | 绿色 | +| Review | 黄色 | +| Blocked | 红色 | +| Masked | 紫色 | + +### 策略导入/导出 + +**Import Policies** 按钮 → 打开导入对话框: +- 选择文件(YAML/JSON 格式的策略片段) +- 或直接粘贴策略内容(支持多种格式) +- 确认 **Import** + +**Export Imports** 按钮 → 打开导出对话框: +- 复选框列表,选择要导出的策略片段文件 +- 支持 **Select All** / **Clear** 批量操作 +- 点击 **Export** 下载所选策略为 YAML 文件 + +--- + +## 策略组(`/guardrails/groups`) + +![策略组](../images/guardrails-groups.png) + +策略组将多条策略归类管理,支持整体启用/禁用。 + +> 页面说明文字:`Groups organize policies and control whether those policy sets participate in evaluation. Built-in is a policy label, not a group type.` + +### 组列表 + +每个策略组显示: +- 组名称 +- 严重级别(Low / Medium / High) +- 启用/禁用状态 +- 包含的策略数量 +- 操作:编辑、删除 + +> `Default` 组为内置组,不可删除(显示锁定图标)。 + +### 创建/编辑组 + +点击 **New Group** 或编辑图标: +- **Name**:组名称 +- **Severity**:Low / Medium / High +- **Enabled**:启用开关 + +### 策略分配(Assign Policies) + +页面下半部分展示**可分配的策略列表**,每条策略带有: +- 策略名称和类型标签(如 `Privacy`) +- 描述(如 `No patterns configured`) +- 独立的开关控制 + +勾选后该策略加入当前组,取消勾选则从组中移除。一条策略可以同时属于多个组。 + +--- + +## 策略规则(`/guardrails/rules`) + +![防护栏规则](../images/guardrails-rules.png) + +路径:`/guardrails/rules` + +详见 [防护栏规则管理](#策略规则详解) 节。 + +### 三个标签页 + +| 标签 | 说明 | +|------|------| +| **Resource Access** | 文件读/写/删除和网络访问规则 | +| **Command Execution** | Shell 命令执行模式匹配规则 | +| **Privacy** | 内容正则/关键词过滤规则 | + +### 批量操作 + +每个标签页顶部提供: +- **Enable All**:启用当前标签下所有策略 +- **Disable All**:禁用当前标签下所有策略 + +### 策略列表 + +每条策略显示: +- 策略 ID(自动生成) +- 策略名称 +- 状态(Enabled / Disabled / No active group) +- 所属组 +- 操作:编辑(内置 + 自定义)、删除(仅自定义) + +### 创建策略 + +点击 **Add Policy** 或编辑图标打开策略编辑器: + +**基础字段:** +- ID(自动生成,可自定义) +- 名称 +- 所属策略组 + +**Resource Access 特有字段:** +- Actions:read / write / delete / network(多选) +- Resources:资源路径列表(glob 模式) +- Tools:适用的工具名称列表 + +**Command Execution 特有字段:** +- Terms/Patterns:命令关键词或正则列表 +- Actions:execute / install(多选) + +**Privacy 特有字段:** +- Patterns:关键词或正则表达式列表 +- Pattern Mode:substring(子串匹配)/ regex(正则) +- Case Sensitive:大小写敏感开关 + +**通用字段:** +- Scenario Scope:适用场景(Anthropic / Claude Code / OpenAI 等) +- Verdict:block(拦截)/ allow(放行)/ mask(脱敏)/ review(人工审核) +- Reason:拦截原因说明(会在拦截时返回给 Agent) + +### 策略注册表 + +底部 **Registry** 区域允许从远程策略仓库下载和安装预置策略集,快速建立基础防护规则。 + +--- + +## 历史审计(`/guardrails/history`) + +![防护栏历史](../images/guardrails-history.png) + +路径:`/guardrails/history` + +查看所有防护栏触发记录。 + +### 筛选 + +- **Verdict**:All / Allow / Review / Block / Mask +- **Time**:All / 1h / 24h / 7d + +### 事件列表 + +可展开的表格行,展示摘要后展开可查看: +- Provider 和模型 +- 请求方向(请求/响应) +- 触发的策略列表 +- 拦截/审核消息 + +### 操作 + +- **Refresh**:手动刷新事件列表 +- **Clear History**:清空全部历史(需确认) + +--- + +## 相关页面 + +- [实验性功能](./19-experimental.md) +- [MCP 与工具](./16-mcp-tools.md) diff --git a/docs/guide/zh/16-mcp-tools.md b/docs/guide/zh/16-mcp-tools.md new file mode 100644 index 000000000..2e25ba298 --- /dev/null +++ b/docs/guide/zh/16-mcp-tools.md @@ -0,0 +1,117 @@ +# MCP 与工具 + +路径:`/mcp/sources`、`/mcp/local-mode`、`/tools/servertool` + +MCP(Model Context Protocol)工具扩展支持为 Claude Code 等场景注册外部工具服务器,包括内置 Web 工具和自定义 MCP 服务器。 + +> **注意**:MCP 功能需要在 [实验性功能](./19-experimental.md) 中开启 MCP Tools 开关后,侧边栏才会显示。 + +--- + +![MCP 工具](../images/mcp.png) + +## MCP 注册服务器(`/mcp/sources`) + +### 两步配置流程 + +**Step 1:安装 Agent** + +页面顶部展示将 Tingly-Box 配置为 MCP 代理的 Agent 安装说明,包括 CLI 安装命令(一键复制)。 + +**Step 2:配置工具(Configure Tools)** + +分为两部分: + +#### 内置 Web 工具 + +| 工具 | 说明 | +|------|------| +| **mcp_web_search** | 网络搜索工具,需配置 Serper API Key | +| **mcp_web_fetch** | 网页内容抓取工具(基于 Jina Reader) | + +每个工具提供独立开关(启用/禁用)和必要的配置字段(如 API Key 输入框)。 + +#### 自定义 MCP 服务器 + +**工具栏:** +- **Add Server**:添加新的自定义 MCP 服务器 +- 状态筛选:All / Active / Disabled + +**服务器列表:** + +| 列 | 说明 | +|----|------| +| Server ID | 服务器唯一标识 | +| Connection | 连接信息(命令/URL) | +| Transport | 传输类型徽章:STDIO / HTTP / SSE | +| Visibility | Client(客户端侧) / Server(服务端侧) | +| Status | 启用/禁用开关 | +| Actions | 编辑、删除 | + +**添加自定义服务器配置:** +- 服务器 ID +- 传输类型(STDIO / HTTP / SSE) +- 连接参数(命令或 URL) +- Visibility 设置 + +--- + +## MCP 本地模式(`/mcp/local-mode`) + +![MCP 本地模式](../images/mcp-local-mode.png) + +配置 Claude Code 将 Tingly-Box 作为 MCP 服务器使用。 + +页面顶部显示当前状态: +- **Active**(绿色):MCP 服务正在运行,外部客户端可以连接 +- 提示信息:`Tingly-Box is running in Client Tool mode. Register MCP sources in the Sources page, then connect your MCP client using the instructions below.` + +### Connection Information + +展示 **MCP Endpoint URL**(完整地址,含认证信息),是 Claude Code 连接所需的端点。 + +### Connect Claude Code + +**方法一:Claude CLI** + +```bash +claude mcp add --transport http tb "" \ + --header "Authorization: Bearer $(cat ~/.tingly-box/config.json | jq -r '.user_token')" +``` + +命令会自动从 `~/.tingly-box/config.json` 中读取 User Token 作为 Bearer Token,无需手动输入。 + +**方法二:手动配置文件** + +将以下片段添加到 Claude Desktop 配置文件(含认证 Header): + +```json +{ + "mcpServers": { + "tb": { + "url": "", + "headers": { "Authorization": "Bearer " } + } + } +} +``` + +页面标注了各操作系统下配置文件的默认路径。 + +--- + +## Server Tool(`/tools/servertool`) + +路径:`/tools/servertool` + +![Server Tool](../images/servertool.png) + +查看和测试 Tingly-Box 服务端当前可用的 MCP 工具列表。 + +--- + +## 相关页面 + +- [实验性功能](./19-experimental.md) +- [防护栏](./15-guardrails.md) +- [Claude Code 场景](./03-scenario-claude-code.md) diff --git a/docs/guide/zh/17-system-settings.md b/docs/guide/zh/17-system-settings.md new file mode 100644 index 000000000..e0c4964bc --- /dev/null +++ b/docs/guide/zh/17-system-settings.md @@ -0,0 +1,85 @@ +# 系统设置 + +路径:`/system`、`/system/logs` + +系统设置页面提供全局偏好配置、服务器状态查看、代理设置、语言/主题切换和日志查看功能。 + +--- + +![系统设置](../images/system.png) + +## 系统设置主页(`/system`) + +General 标签页由四张卡片组成,每张各自回答一个问题: + +### 服务器状态卡(Server Status) + +只回答「网关是否健康」这一个问题: + +| 字段 | 说明 | +|------|------| +| Server | 运行中(Running)/ 已停止 / 不可用,附带 Connected/Disconnected 指示 | +| Uptime | 服务器已运行时长 | +| Proxy | 当前是否生效代理 | + +**操作**(右上角图标):**Force Logout**(强制退出当前 Web 会话,清除 Token 并返回登录页)与 **Refresh Status**(手动刷新状态)。 + +--- + +### Quick Proxy 卡 + +为所有对外 API 请求配置统一的 HTTP/HTTPS 代理——一个可复用的预设,Provider 和 OAuth 一键即可采用(若某 Provider 单独设置了代理,则以该设置为准): + +1. 在文本框中输入代理地址(如 `http://127.0.0.1:7890`) +2. 点击 **Save** 保存 +3. 保存成功后显示绿色对号图标 + +> 如需为某个 Provider 单独配置代理,请在 [凭证管理](./08-credentials.md) 的 Provider 编辑表单中设置。 + +--- + +### Appearance & Language 卡 + +用户偏好设置,与服务器状态卡分离,使后者只回答「网关是否健康」,不与个人偏好混在一起: + +- **Language**:`English` / `中文` +- **Theme**:`Light` / `Dark` / `Sunlit` / `Claude` / `System`(跟随系统设置) + +--- + +### About 卡 + +- **当前版本**:显示版本号 + - 有可用更新时显示更新提示 + - 开发版本显示 `dev` 标记 +- **License**:MPL-2.0 + Commercial +- **GitHub**:项目仓库链接 + +--- + +## 日志页面(`/system/logs`) + +路径:`/system/logs` + +实时查看 Tingly-Box 服务器的运行日志。 + +### 功能 + +![日志页面](../images/logs.png) + +**Debug Mode 开关**(右上角): +- 开启:日志级别切换为 `debug`,输出更详细的调试信息 +- 关闭:日志级别为 `info`(默认) + +**LogExplorer 区域:** +- 实时流式显示服务器日志 +- 支持滚动查看历史日志 +- 日志条目包含时间戳、级别、来源模块、消息内容 + +--- + +## 相关页面 + +- [访问控制](./18-access-control.md) +- [实验性功能](./19-experimental.md) +- [凭证管理](./08-credentials.md) diff --git a/docs/guide/zh/18-access-control.md b/docs/guide/zh/18-access-control.md new file mode 100644 index 000000000..e9c3b0398 --- /dev/null +++ b/docs/guide/zh/18-access-control.md @@ -0,0 +1,74 @@ +# 访问控制 + +路径:`/access-control` + +访问控制页面管理 Tingly-Box 的核心认证令牌,包括用户令牌(Web UI 登录凭证)和模型令牌(各场景 API Key)。 + +--- + +![访问控制](../images/access-control.png) + +## 用户令牌(User Token) + +用于 Web UI 的登录认证。 + +### 查看当前令牌 + +- 默认脱敏显示(`••••••••`) +- 点击眼睛图标切换明文显示 +- 点击复制图标将令牌复制到剪贴板 + +### 安全提示 + +页面顶部的 **Token Security** 摘要说明用户令牌与模型令牌的区别,并提醒切勿将用户令牌分享给 API 用户。 + +若当前使用**默认令牌**(初始安装时设置),页面会显示安全警告,建议尽快重置为随机令牌。 + +### 重置令牌 + +点击 **Reset** 按钮,弹出确认对话框,说明重置后果: +- 生成新的随机令牌 +- 所有使用旧令牌的会话(浏览器 Tab、脚本、CLI)将立即失效 +- 需要用新令牌重新登录 + +确认后,新令牌显示在成功对话框中(含复制按钮),请立即保存。 + +--- + +## 模型令牌(Model Token) + +模型令牌是各 Agent 场景代理接口的通用 API Key。 + +### 特点 + +- 所有场景(Claude Code、OpenAI 代理等)共享同一模型令牌 +- 可与其他开发人员或环境共享,用于访问代理接口 +- **不等同于**用户令牌,不能用于登录 Web UI + +### 查看与复制 + +操作方式与用户令牌相同:眼睛图标切换显示,复制图标写入剪贴板。 + +### 重置模型令牌 + +点击 **Reset** 弹出确认对话框,确认后生成新令牌。 + +> **注意**:重置模型令牌后,所有配置了旧令牌的工具(Claude Code CLI、OpenAI SDK 客户端等)都需要更新令牌配置。 + +--- + +## 与 API Tokens 的关系 + +| | 用户令牌 | 模型令牌 | API Tokens | +|-|---------|---------|-----------| +| 页面 | `/access-control` | `/access-control` | `/tingly-box-token` | +| 数量 | 1 个 | 1 个 | 多个 | +| 用途 | Web UI 登录 | Agent 场景 API Key | 外部客户端访问 | +| 命名 | 无 | 无 | 可自定义名称 | + +--- + +## 相关页面 + +- [API Tokens](./10-api-tokens.md) +- [系统设置](./17-system-settings.md) diff --git a/docs/guide/zh/19-experimental.md b/docs/guide/zh/19-experimental.md new file mode 100644 index 000000000..716867eed --- /dev/null +++ b/docs/guide/zh/19-experimental.md @@ -0,0 +1,83 @@ +# 实验性功能 + +路径:`/system/experimental` + +实验性功能页面集中管理尚在早期迭代阶段的特性开关,开启后相关功能将出现在侧边栏导航中。 + +--- + +![实验性功能](../images/experimental.png) + +## 页面说明 + +页面标题:**Experimental Features** + +页面副标题描述这些功能处于实验阶段,可能在未来版本中有所调整。 + +--- + +## 可用实验功能 + +### Skills(IDE Skills) + +**开关标识**:`skill_ide` + +开启后,在左侧侧边栏「Prompt」分组下激活 **Skills** 导航项(`/prompt/skill`),允许从 IDE 配置目录同步和管理可复用的 Prompt 片段。 + +- 仅 **Full Edition** 可见此开关 +- 详见 [Prompt 管理](./14-prompt-management.md) + +--- + +### Guardrails(防护栏) + +**开关标识**:`guardrails` + +开启后,左侧侧边栏显示 **Guardrails** 分组,包含: +- 防护栏总览(`/guardrails`) +- 策略组管理(`/guardrails/groups`) +- 策略规则(`/guardrails/rules`) +- 历史审计(`/guardrails/history`) + +开启时页面显示说明信息(Alert),引导用户了解 Guardrails 的配置方式。 + +详见 [防护栏](./15-guardrails.md)。 + +--- + +### MCP Tools + +**开关标识**:`mcp` + +开启后,左侧侧边栏显示 **Tools** 分组,包含: +- MCP 注册服务器(`/mcp/sources`) +- MCP 本地模式(`/mcp/local-mode`) +- Server Tool(`/tools/servertool`) + +开启时页面显示说明信息(Alert),引导用户了解 MCP 的配置方式。 + +详见 [MCP 与工具](./16-mcp-tools.md)。 + +--- + +## 开启方式 + +1. 访问 **系统设置** → **Experimental**(`/system/experimental`) +2. 找到目标功能的 Chip 开关 +3. 点击切换为 **On** 状态 +4. 侧边栏将立即刷新,显示新功能入口 + +--- + +## 关闭实验功能 + +将 Chip 开关切换为 **Off**,侧边栏对应功能入口隐藏,但已有配置数据保留。 + +--- + +## 相关页面 + +- [防护栏](./15-guardrails.md) +- [MCP 与工具](./16-mcp-tools.md) +- [Prompt 管理](./14-prompt-management.md) +- [系统设置](./17-system-settings.md) diff --git a/docs/guide/zh/20-routing-rules.md b/docs/guide/zh/20-routing-rules.md new file mode 100644 index 000000000..47111307c --- /dev/null +++ b/docs/guide/zh/20-routing-rules.md @@ -0,0 +1,171 @@ +# 路由规则与插件标记 + +路径:`/scenario/*`(各场景页面中的规则卡片) + +路由规则是 Tingly-Box 调度请求的核心机制。每条规则绑定一个请求模型(request_model),并决定如何将请求分发到一个或多个上游服务(Credential/Provider)。 + +--- + +## 首次使用引导 + +![路由引导](../images/routing-guide.png) + +第一次进入任意场景页时,会**自动弹出一次**「Direct Routing Guide(直接路由引导)」,用图示分步讲解路由是怎么搭起来的——从零开始:**Connect AI 接入 Provider → + Add model 加第一个模型 → 修改/删除模型 → 同层负载均衡 → 跨层熔断兜底**。 + +- 引导每位用户**只自动弹一次**,之后不再打扰 +- 左侧是步骤导航,右侧是对应的路由图示意 + 文字说明;涉及工具栏按钮的步骤会显示一个高亮按钮的**模拟工具栏**,告诉你该点哪里 +- 想再看时,点击工具栏右侧的 **?**(How routing works)按钮即可随时重新打开 +- 底部 **Previous / Next** 翻页,最后一步是 **Got it!** 关闭 + +> 智能路由也有独立的 Smart Routing Guide,切换到 Smart 模式后通过同一个 **?** 按钮查看。 + +--- + +## 路由图总览 + +![直接路由图](../images/routing-graph-direct.png) + +规则卡片中内嵌路由图,直观展示请求的流转路径。路由图有两种模式,通过规则卡片内的切换按钮在 **直接路由**(Direct)和 **智能路由**(Smart)之间切换。 + +--- + +## 直接路由(Direct / Tier 模式) + +直接路由是默认模式(`lbTactic: "tier"`)。服务节点按优先级分层排列: + +``` +请求入口 + │ + ├── T0(最高优先级):多个服务共享负载 + ├── T1:T0 整体熔断后的备用层 + └── T2:T1 熔断后的最终兜底 +``` + +### 层级行为 + +| 概念 | 说明 | +|------|------| +| 同层服务 | 轮询或加权共享流量(负载均衡) | +| 跨层 Fallback | 当前层所有服务均熔断时,请求自动路由到下一层 | +| 层号(T0/T1…) | 数字越小优先级越高;拖拽服务节点可调整层级 | + +### 熔断器(Circuit Breaker) + +每个服务节点维护独立的熔断器,状态如下: + +``` +Closed(正常) ──── 连续 3 次失败 ──→ Open(熔断) + │ + 30 秒冷却期 + │ + HalfOpen(探针) + │ + ┌─── 成功 ───→ Closed(恢复) + └─── 失败 ───→ Open(重新熔断) +``` + +| 状态 | 含义 | +|------|------| +| **Closed** | 正常接收请求 | +| **Open** | 拒绝请求,等待冷却(默认 30 秒) | +| **HalfOpen** | 发送探针请求;成功则恢复,失败则重新熔断 | + +### 请求中途 Failover(Mid-request Failover) + +通过 `firstChunkGate` 缓冲机制(v2),在收到上游第一个响应块之前,若上游失败,请求可无缝切换到同层其他服务或下一层,对客户端透明。 + +--- + +## 智能路由(Smart Routing) + +![智能路由图](../images/routing-graph-smart.png) + +启用智能路由后(`smartEnabled: true`),规则链中的每条子规则(SmartOp)均可附带条件。请求按顺序匹配,**第一条所有条件均满足**的子规则生效。 + +``` +请求入口 + │ + ├── SmartOp 1(条件 A AND 条件 B)── 满足 ──→ 路由到服务组 A + ├── SmartOp 2(条件 C) ── 满足 ──→ 路由到服务组 B + └── SmartOp N(无条件,兜底) ──────────→ 路由到默认服务组 +``` + +### SmartOp 条件目录 + +| 条件键 | 类型 | 可选值 | 说明 | +|--------|------|--------|------| +| `agent.claude_code` | enum | `main` / `subagent` / `compact` | Claude Code 请求类型 | +| `token` | 阈值 | `ge:` / `le:` | 输入 Token 数量(大于等于/小于等于) | +| `thinking` | bool | `on` / `off` | 客户端是否开启了扩展思考 | +| `service_ttft` | 性能 | `fastest` / `fast` / `slow` / `slowest` | 上游服务首字节延迟(TTFT)性能档位 | +| `service_capacity` | 状态 | `available` / `degraded` / `unavailable` | 上游服务当前容量状态 | +| `context_system` | 存在性 | `exists` / `missing` | 请求是否携带 system prompt | +| `latest_user` | 内容类型 | `text` / `image` / `file` / `rich` | 最新一条 user 消息的内容类型 | + +### 设计技巧 + +- 多个条件使用 **AND 逻辑**(同一 SmartOp 内所有条件均须满足) +- 最后一条子规则保持**无条件**(ops=[]),作为兜底默认路径 +- 利用 `agent.claude_code=compact` 将 Compact 压缩请求路由到更便宜的模型 +- 利用 `token ge:100000` 将超长上下文请求路由到支持大窗口的服务 + +--- + +## 规则插件标记(Rule Plugins) + +每条规则右侧的 **Plugins** 卡片提供预制的附加标记(Flags),可在规则层面精调请求/响应行为,无需改动服务配置。 + +点击 Plugins 卡片,打开 **Flag 目录**(分类侧边栏 + 详情面板)。 + +![规则插件标记目录](../images/rule-extensions.png) + +### App 类 + +| 标记 | Key | 说明 | +|------|-----|------| +| Cursor compatibility | `cursor_compat` | 对 Cursor 客户端规范化富内容、封锁工具、去除 stream usage | +| Auto-detect Cursor | `cursor_compat_auto` | 根据请求头自动识别 Cursor 并应用兼容处理 | +| Claude Code compatibility | `claude_code_compat` | 将 messages 数组中 `system` 角色条目重写为 `user`,兼容不支持此扩展角色的第三方 Anthropic 兼容服务 | + +### Request (OpenAI) 类 + +| 标记 | Key | 类型 | 说明 | +|------|-----|------|------| +| Custom User-Agent | `custom_user_agent` | 字符串 | 覆盖出向请求的 User-Agent 头(仅对通用 OpenAI/Anthropic 客户端生效;专属客户端如 Claude Code OAuth 保留自身 UA) | +| OpenAI endpoint override | `openai_endpoint_override` | 枚举 | 强制使用 Chat Completions 或 Responses API,覆盖 Provider 默认设置(仅 OpenAI 类服务) | +| Use max_completion_tokens | `use_max_completion_tokens` | 开关 | 将 `max_tokens` 重写为 `max_completion_tokens`,适用于 o1/o3/gpt-5 系列 | +| Use max_tokens (legacy) | `use_max_tokens` | 开关 | 将 `max_completion_tokens` 重写为 `max_tokens`,兼容较旧的 OpenAI 兼容服务 | +| Block tools | `block_tools` | 字符串 | 逗号分隔的工具名列表,在转发前从请求中移除(跨 OpenAI Chat/Responses/Anthropic/Google) | + +### Response 类 + +| 标记 | Key | 类型 | 说明 | +|------|-----|------|------| +| Skip usage in response | `skip_usage` | 开关 | 从响应中剥离 `usage` 块(SSE 增量和最终 body 均处理) | + +### Reasoning 类 + +| 标记 | Key | 类型 | 说明 | +|------|-----|------|------| +| Thinking | `thinking_effort` | 枚举 | 统一控制扩展思考:`By Client`(透传)/ `Off`(强制关闭)/ `Low`(~1K token)/ `Medium`(~5K)/ `High`(~20K)/ `Max`(~32K)。Anthropic 端映射为 `budget_tokens`,OpenAI 端映射为 `reasoning_effort` | + +### Vision 类 + +| 标记 | Key | 类型 | 说明 | +|------|-----|------|------| +| Vision Proxy | `vision_proxy_service` | 服务引用 | 通过视觉模型描述图片,使纯文本下游模型也能处理含图请求。优先级高于场景级视觉代理 | + +### Routing 类 + +| 标记 | Key | 类型 | 说明 | +|------|-----|------|------| +| Session affinity | `session_affinity` | 整数(秒) | 会话粘性 TTL(**规则级**):同一会话在 TTL 内持续命中同一服务。0 表示禁用。内置 Claude Code、Claude Desktop、Codex 规则默认 1800 秒。通过 `metadata.user_id`、`X-Tingly-Session-ID` 请求头或客户端 IP 识别会话 | + +--- + +## 相关页面 + +- [场景总览](./02-scenario-overview.md) +- [Claude Code 场景](./03-scenario-claude-code.md) +- [凭证管理](./08-credentials.md) +- [实验性功能](./19-experimental.md) diff --git a/docs/guide/zh/21-model-select.md b/docs/guide/zh/21-model-select.md new file mode 100644 index 000000000..05ed8685e --- /dev/null +++ b/docs/guide/zh/21-model-select.md @@ -0,0 +1,56 @@ +# 模型选择 + +模型选择对话框用于为路由规则指定目标 Provider 和模型,是配置转发规则的核心交互入口。 + +--- + +![模型选择对话框](../images/model-select.png) + +## 打开方式 + +在任意场景(Claude Code、Codex 等)的 **Model Rules** 区域,有以下几种方式可以打开模型选择对话框: + +- **点击现有 Provider 节点**:在路由图中点击显示模型名称的卡片(如 `claude-sonnet-4-6`),进入"编辑"模式 +- **点击「+ Add」按钮**:在规则行末尾点击添加按钮,进入"新增"模式 +- **AgentSetupCard 引导步骤**:在 Claude Code 场景的 Quick Start 第 2 步展开后,点击 **Choose Model** 按钮 + +--- + +## 对话框结构 + +### 左侧:Provider 列表 + +- 列出所有已配置的 Provider(来自 [凭证管理](./08-credentials.md)) +- 点击 Provider 名称展开/折叠其模型列表 +- 每个 Provider 显示支持的所有模型 + +### 右侧/顶部:搜索与筛选 + +- **搜索框**:按模型名称或 Provider 名称过滤 +- 支持快速定位特定模型 + +### 选择操作 + +- 点击模型行即选中,确认后写入路由规则 +- 在"新增"模式下,选中模型会自动创建新的转发规则 + +### 单卡测试操作 + +每张模型卡片遵循统一的四角约定: + +| 角落 | 内容 | +|------|------| +| 左上 | 分类标记——`NEW` 徽章,或标记自定义模型的三角形图标 | +| 右上 | 当前选中模型的对勾标记 | +| 左下 | 若有上次测试结果,会显示一个持久化的成功/失败状态点;点击可重新打开对话框查看该结果 | +| 右下 | 悬停时才显示的操作图标:**Edit**、**Delete**、**Test**(闪电图标) | + +点击闪电图标会打开一个 **Test** 对话框,可直接从卡片测试模型——选择请求形态、点击 **Run Test**,即可查看请求过程、Token 用量和响应内容,无需先把该模型选入某条规则。测试结果会以状态点的形式在对话框关闭后持续显示,方便一次测试多个模型时快速对比结果。 + +--- + +## 相关页面 + +- [Claude Code 场景](./03-scenario-claude-code.md) +- [路由规则与插件标记](./20-routing-rules.md) +- [凭证管理](./08-credentials.md) diff --git a/docs/guide/zh/README.md b/docs/guide/zh/README.md new file mode 100644 index 000000000..e0f4a16ea --- /dev/null +++ b/docs/guide/zh/README.md @@ -0,0 +1,66 @@ +# Tingly-Box 用户指南 + +Tingly-Box 是一个 AI 智能体编排平台,提供 LLM 网关、远程控制和安全防护能力。本指南按功能模块分章节说明 Web UI 的完整使用方法。 + +--- + +## 目录 + +### 一、快速上手 +- [初始化与 Provider 接入](./01-getting-started.md) + +### 二、Agent 场景 + +Agent 场景是 Tingly-Box 的核心功能,将各类 AI 编程工具的 API 请求统一代理到你配置的 Provider。 + +- [场景总览](./02-scenario-overview.md) — 场景导航与可见性管理 +- [Claude Code](./03-scenario-claude-code.md) — 主力场景,支持 Profile、统一/分离模型、转发规则 +- [Codex](./04-scenario-codex.md) — OpenAI Codex CLI 代理,自动配置支持 +- [其他编程 Agent](./04-scenario-coding-agents.md) — OpenCode、VS Code、Xcode、Claude Desktop +- [OpenAI / Anthropic SDK 代理](./05-scenario-sdk-proxy.md) — OpenAI 兼容接口与 Anthropic 原生接口 +- [Claw Agent / Embed / ImageGen](./06-scenario-special.md) — OpenClaw、Embedding、图像生成 +- [Playground(图像生成测试台)](./07-scenario-playground.md) + +### 三、配置主链路 + +Provider 和凭证管理是所有场景正常工作的前提。 + +- [凭证管理](./08-credentials.md) — API Key、OAuth、导入导出、Provider 配置 +- [虚拟模型](./09-virtual-models.md) — 内置合成模型,用于演示与测试 +- [API Tokens](./10-api-tokens.md) — 管理外部客户端访问令牌 + +### 四、其他主入口 + +- [用量看板](./11-dashboard.md) — 请求统计、Token 消耗、缓存命中率 +- [远程控制](./12-remote-control.md) — 通过 IM 平台(微信、Telegram、飞书等)远程操控 Claude Code +- [Remote Coder](./13-remote-coder.md) — Web Chat 与会话管理 +- [Prompt 管理](./14-prompt-management.md) — 用户录制、Skill、Command(Full Edition) +- [防护栏(Guardrails)](./15-guardrails.md) — 策略导入/导出、规则管理、历史审计 +- [MCP 与工具](./16-mcp-tools.md) — MCP 服务器注册与本地模式 + +### 五、系统设置 + +- [系统设置](./17-system-settings.md) — 代理、语言、主题、版本信息、日志 +- [访问控制](./18-access-control.md) — 用户令牌与模型令牌管理 + +### 六、实验性功能 + +- [实验性功能](./19-experimental.md) — Skills IDE、Guardrails、MCP 开关 + +### 七、高阶特性 + +- [路由规则与插件标记](./20-routing-rules.md) — 直接路由(Tier/熔断器)、智能路由(SmartOp 条件)、规则插件标记 +- [模型选择](./21-model-select.md) — 为路由规则指定 Provider 与模型的交互入口 + +--- + +## 版本说明 + +部分功能仅在 **Full Edition** 中提供: +- Prompt 管理(用户录制、Skills) +- 远程控制(IM Bot) +- Remote Coder + +部分功能需在「实验性功能」页面手动开启后方可在侧边栏看到: +- Guardrails(防护栏) +- MCP 工具