1 line
35 KiB
JSON
1 line
35 KiB
JSON
{"repo": "alexanys/ai-sub-auth", "files": {"AGENT.md": {"56279a3374d540301c3da75f9429cf46fcb553e6": {"t": 1785747165.708805, "n": 12860, "h": "050247f9533210d8", "c": "# Agent Integration Guide\n\n> **For AI Agents**: Read this file to understand how to integrate `ai-sub-auth` into any application.\n> This file is designed to be consumed by Claude Code, OpenClaw, Cursor, Copilot, or any agentic coding tool.\n\n## What is ai-sub-auth?\n\nA lightweight Python module (~500 LOC, only depends on `httpx`) that authenticates against AI providers using existing user subscriptions. It handles OAuth PKCE (OpenAI Codex), API keys (Claude, Gemini, DeepSeek), and device code (GitHub Copilot) — all through a unified `LLMClient` interface.\n\n**3-line integration:**\n```python\n# Recommended — auto-detects your subscription\nfrom ai_sub_auth import AI\nai = AI()\nresult = await ai.chat(\"your prompt here\", system=\"your system prompt\")\n\n# Or explicit provider selection\nfrom ai_sub_auth import LLMClient, PROVIDERS\nclient = LLMClient(PROVIDERS[\"openai_codex\"], model=\"openai-codex/gpt-4o\")\nresp = await client.chat(\"your prompt here\", system=\"your system prompt\")\n```\n\n## Subscription Reality (2026)\n\nWhich AI subscriptions can be bridged into third-party apps:\n\n| Provider | Method | Status | Notes |\n|----------|--------|--------|-------|\n| **OpenAI ChatGPT Plus/Pro** | OAuth PKCE | ✅ Safe & encouraged | OpenAI actively supports via Codex SDK, MCP, Apps SDK |\n| **Claude** | API Key | ✅ Works (pay-per-token) | Anthropic banned subscription OAuth (Feb 2026). Use API key only |\n| **GitHub Copilot** | Device Code | ⚠️ Works but violates ToS | Not recommended for production |\n| **Google Gemini** | API Key | ✅ Works (pay-per-token) | Google banned subscription OAuth. Accounts permanently banned |\n| **DeepSeek, OpenRouter** | API Key | ✅ Works | Standard API key auth |\n\n**Key insight:** OpenAI Codex OAuth is the only path where users can reuse their existing subscription ($20/mo ChatGPT Plus) in third-party apps at zero additional cost. All other providers require pay-per-token API keys.\n\n### Provider Selection Guide\n\nWhen integrating AI into an app, help the user choose:\n\n1. **User has ChatGPT Plus/Pro** → Use OpenAI Codex OAuth (zero extra cost, best value)\n2. **User has Claude API key** → Use Anthropic API Key (high quality, pay-per-token)\n3. **User has both** → Default to OpenAI Codex (free with subscription), fall back to Claude\n4. **User has neither** → Guide them to get ChatGPT Plus ($20/mo) or a free-tier API key\n\n⚠️ **Anti-Patterns — Do NOT:**\n- Attempt to bridge Claude Pro/Max subscription via OAuth (Anthropic will block it)\n- Attempt to bridge Google Gemini subscription via OAuth (Google will permanently ban the account)\n- Hardcode provider-specific API calls in the target app (use ai-sub-auth's unified interface)\n- Store tokens outside the module's TokenStore (security risk)\n\n---\n\n## Quick Reference\n\n| File | Purpose |\n|------|---------|\n| `ai_sub_auth/facade.py` | **AI Facade** — auto-detects subscription, recommended entry point |\n| `ai_sub_auth/providers.py` | Provider registry — add new providers here |\n| `ai_sub_auth/oauth_flow.py` | OAuth PKCE login + auto token refresh |\n| `ai_sub_auth/token_store.py` | Secure token storage (~/.ai-sub-auth/tokens/) |\n| `ai_sub_auth/api_client.py` | Unified LLMClient — routes to correct API |\n| `ai_sub_auth/models.py` | Data models: OAuthToken, ProviderConfig, LLMResponse |\n| `ai_sub_auth/exceptions.py` | AuthError, TokenExpiredError, LoginRequiredError |\n\n---\n\n## Meta Skill Framework\n\nWhen integrating AI into any application, every useful AI feature is a composition of exactly **8 meta skills**:\n\n```\nSkill Direction What it does\n───────── ───────────── ─────────────────────────────────────────\nSUMMARIZE many → few Reduce volume while preserving meaning\nGENERATE few → many Produce new content from intent or spec\nANALYZE raw → insight Find patterns, anomalies, trends in data\nTRANSFORM form A → form B Convert between formats, styles, languages\nCLASSIFY items → buckets Assign categories, priorities, or labels\nEVALUATE content → score Judge quality against criteria\nCONVERSE user ↔ AI Multi-turn contextual dialogue\nEXTRACT noise → signal Pull structured data from unstructured input\n```\n\n### When to apply each skill\n\n| Skill | Trigger signals in the target app |\n|-------|----------------------------------|\n| SUMMARIZE | Has collections of text (notes, emails, logs, threads, history) |\n| GENERATE | Has \"create/new\" buttons, blank editors, templates, boilerplate |\n| ANALYZE | Has charts, tables, dashboards, numerical/time-series data |\n| TRANSFORM | Has import/export, format conversion, audience adaptation |\n| CLASSIFY | Has inbox/queue/feed, manual tagging, predefined categories |\n| EVALUATE | Has submissions, reviews, quality checks, rubrics, checklists |\n| CONVERSE | Has help section, complex workflows, onboarding, Q&A needs |\n| EXTRACT | Has manual data entry, forms, paste-from-external, uploads |\n\n---\n\n## 3-Suggestion Protocol\n\nWhen you encounter a new application, follow this protocol to suggest AI integrations:\n\n### Step 1: SCAN — Build an App Profile\n\nExamine in order: README → directory structure → routes/endpoints → data models → UI entry points.\n\nProduce:\n```\ndomain: [e.g., \"education\", \"finance\", \"devtools\", \"personal\"]\nverbs: [what the app DOES — \"create tasks\", \"send emails\", \"track expenses\"]\nnouns: [what the app KNOWS — \"notes\", \"transactions\", \"users\", \"documents\"]\nroles: [who uses it — \"admin\", \"user\", \"viewer\"]\nexisting_ai: [what's already AI-powered, if anything]\n```\n\n### Step 2: MATCH — Score skills against the profile\n\nFor each of the 8 meta skills, check if its trigger signals are present in the app profile. Prioritize skills that are NOT yet implemented (greenfield bonus).\n\n### Step 3: RANK — Select exactly 3\n\nRank by: **Impact (3x)** × **Feasibility (2x)** × **Differentiation (1x)**\n\nHard rules:\n- 3 suggestions, never more, never fewer\n- No two suggestions use the same meta skill\n- At least one must be a **quick win** (< 50 lines to integrate)\n- At least one must be **high ceiling** (transformative if done fully)\n\n### Step 4: PRESENT — Use this template for each suggestion\n\n```\n## Suggestion [1/3]: [SKILL] — [One-line description]\n\n**What it does:** [2-3 sentences, user perspective]\n**Why this app needs it:** [Connect to a specific pain point from SCAN]\n**Integration point:** [Exact file(s) and function(s)]\n**Effort:** [Quick win | Moderate | Deep integration]\n\n**Implementation sketch:**\n1. [Hook: where in the app to add this]\n2. [Service: the ai-sub-auth call pattern]\n3. [UI: how the user triggers and sees it]\n```\n\n### Step 5: IMPLEMENT — Upon user approval\n\n```\n1. AUTH → from ai_sub_auth import LLMClient, PROVIDERS\n2. SERVICE → Create function: input → LLMClient.chat(prompt, system) → parsed output\n3. ROUTE → Wire into app's existing API/endpoint pattern\n4. UI → Add trigger (button/auto/hook) following app's component style\n5. VERIFY → Test auth, test output, test error handling\n```\n\n---\n\n## Integration Patterns by App Category\n\n| Category | Best 3 skills | Example integration |\n|----------|--------------|-------------------|\n| **Notes/PKM** (Obsidian, Logseq) | Summarize, Analyze, Generate | \"Summarize this week's notes\" button |\n| **Dev tools** (terminals, IDEs) | Evaluate, Analyze, Generate | Inline code review on git diff |\n| **Email/Chat** (Thunderbird, Element) | Generate, Summarize, Classify | Draft reply + inbox triage |\n| **CMS/Blog** (Hugo, WordPress) | Generate, Transform, Evaluate | AI first draft + SEO metadata |\n| **Data/Analytics** (Grafana, Metabase) | Analyze, Transform, Generate | Natural language → SQL query |\n| **Personal** (finance, health, calendar) | Analyze, Extract, Generate | Voice → structured expense entry |\n| **System/Infra** (monitoring, CI/CD) | Analyze, Generate, Transform | Log correlation → incident summary |\n\n---\n\n## Implementation Example\n\nHere's a complete example of adding SUMMARIZE to a note-taking app:\n\n```python\n# 1. AUTH — one-time setup\nfrom ai_sub_auth import LLMClient, PROVIDERS, oauth_login\n\n# If using ChatGPT subscription (OAuth):\n# oauth_login(PROVIDERS[\"openai_codex\"]) # first time only\nclient = LLMClient(PROVIDERS[\"openai_codex\"], model=\"openai-codex/gpt-4o\")\n\n# Or if using API key:\n# client = LLMClient(PROVIDERS[\"anthropic\"], api_key=\"sk-...\", model=\"claude-sonnet-4-5-20250514\")\n\n# 2. SERVICE — the AI function\nasync def summarize_notes(notes: list[str], max_points: int = 5) -> dict:\n combined = \"\\n---\\n\".join(notes)\n resp = await client.chat(\n message=combined,\n system=f\"Summarize these {len(notes)} notes into {max_points} key points. \"\n f\"Output JSON: {{\\\"points\\\": [\\\"...\\\"], \\\"action_items\\\": [\\\"...\\\"]}}\",\n )\n import json\n return json.loads(resp.content)\n\n# 3. ROUTE — hook into your app's API\n# @app.post(\"/api/ai/summarize\")\n# async def api_summarize(request): ...\n\n# 4. UI — add a button\n# <button onClick={summarize}>✨ Summarize</button>\n```\n\n### TRANSFORM Example: Adding translation to a messaging app\n\n```python\n# 1. AUTH — one-time setup\nfrom ai_sub_auth import LLMClient, PROVIDERS, oauth_login\n\n# Using ChatGPT subscription (zero cost for the user):\n# oauth_login(PROVIDERS[\"openai_codex\"]) # first time only\nclient = LLMClient(PROVIDERS[\"openai_codex\"], model=\"openai-codex/gpt-4o\")\n\n# 2. SERVICE — the AI function\nasync def translate_message(text: str, source_lang: str, target_lang: str) -> dict:\n resp = await client.chat(\n message=text,\n system=(\n f\"Translate the following from {source_lang} to {target_lang}. \"\n f\"Preserve tone, formatting, and any embedded links. \"\n f'Output JSON: {{\"translation\": \"...\", \"detected_lang\": \"...\", \"confidence\": 0.0-1.0}}'\n ),\n )\n import json\n return json.loads(resp.content)\n\n# 3. ROUTE — hook into your messaging app's API\nfrom fastapi import APIRouter\nrouter = APIRouter()\n\n@router.post(\"/api/ai/translate\")\nasync def api_translate(request: dict):\n result = await translate_message(\n text=request[\"text\"],\n source_lang=request.get(\"source_lang\", \"auto\"),\n target_lang=request[\"target_lang\"],\n )\n return result\n\n# 4. UI — add inline translate button on each message\n# <button onClick={() => translate(msg.id, userLang)}>🌐 Translate</button>\n# Shows translated text below original, with \"Translated from {detected_lang}\" label\n```\n\n### EXTRACT Example: Structured data extraction from documents\n\n```python\n# 1. AUTH — one-time setup\nfrom ai_sub_auth import LLMClient, PROVIDERS, oauth_login\n\n# Using ChatGPT subscription:\n# oauth_login(PROVIDERS[\"openai_codex\"]) # first time only\nclient = LLMClient(PROVIDERS[\"openai_codex\"], model=\"openai-codex/gpt-4o\")\n\n# Or using Claude API key for higher extraction accuracy:\n# client = LLMClient(PROVIDERS[\"anthropic\"], api_key=\"sk-...\", model=\"claude-sonnet-4-5-20250514\")\n\n# 2. SERVICE — the AI function\nasync def extract_invoice_data(raw_text: str) -> dict:\n resp = await client.chat(\n message=raw_text,\n system=(\n \"Extract structured data from this invoice/receipt. \"\n \"Output JSON: {\"\n '\"vendor\": \"...\", \"date\": \"YYYY-MM-DD\", \"currency\": \"...\", '\n '\"total\": 0.00, \"tax\": 0.00, \"subtotal\": 0.00, '\n '\"line_items\": [{\"description\": \"...\", \"qty\": 1, \"unit_price\": 0.00, \"amount\": 0.00}]'\n \"}\"\n \" If a field is not found, use null.\"\n ),\n )\n import json\n return json.loads(resp.content)\n\n# 3. ROUTE — hook into your document management app's API\nfrom fastapi import APIRouter, UploadFile\nrouter = APIRouter()\n\n@router.post(\"/api/ai/extract-invoice\")\nasync def api_extract_invoice(file: UploadFile):\n raw_text = (await file.read()).decode(\"utf-8\") # or use OCR for images\n result = await extract_invoice_data(raw_text)\n return result\n\n# 4. UI — add extract button on document upload\n# <button onClick={() => extractData(doc.id)}>📋 Extract Data</button>\n# Pre-fills form fields with extracted values; user reviews and confirms\n```\n\n---\n\n## Principles\n\n1. **Eight is enough.** Every AI feature maps to one of the 8 skills. Don't invent a ninth — it's a composition.\n2. **Skills are verbs, not features.** \"Summarize\" is a skill. \"Email summary\" is a feature = skill + context.\n3. **Three suggestions, never more.** Fewer forces prioritization. More creates paralysis.\n4. **Quick-win plus high-ceiling.** Build trust with a fast win, then go deep.\n5. **Follow the host.** Mirror the target app's conventions for auth, routing, and UI. Be a guest, not an invader.\n6. **Auth is first, not last.** Every AI feature goes through ai-sub-auth from step 1.\n7. **Subscription-first.** Prefer OAuth subscription bridge (ChatGPT Plus) over API keys when available. It's zero extra cost for the user.\n"}, "cf86f9f422516ecf0d15f7cffe77d1a613c0461b": {"t": 1785770834.5574625, "n": 12860, "h": "050247f9533210d8", "c": "# Agent Integration Guide\n\n> **For AI Agents**: Read this file to understand how to integrate `ai-sub-auth` into any application.\n> This file is designed to be consumed by Claude Code, OpenClaw, Cursor, Copilot, or any agentic coding tool.\n\n## What is ai-sub-auth?\n\nA lightweight Python module (~500 LOC, only depends on `httpx`) that authenticates against AI providers using existing user subscriptions. It handles OAuth PKCE (OpenAI Codex), API keys (Claude, Gemini, DeepSeek), and device code (GitHub Copilot) — all through a unified `LLMClient` interface.\n\n**3-line integration:**\n```python\n# Recommended — auto-detects your subscription\nfrom ai_sub_auth import AI\nai = AI()\nresult = await ai.chat(\"your prompt here\", system=\"your system prompt\")\n\n# Or explicit provider selection\nfrom ai_sub_auth import LLMClient, PROVIDERS\nclient = LLMClient(PROVIDERS[\"openai_codex\"], model=\"openai-codex/gpt-4o\")\nresp = await client.chat(\"your prompt here\", system=\"your system prompt\")\n```\n\n## Subscription Reality (2026)\n\nWhich AI subscriptions can be bridged into third-party apps:\n\n| Provider | Method | Status | Notes |\n|----------|--------|--------|-------|\n| **OpenAI ChatGPT Plus/Pro** | OAuth PKCE | ✅ Safe & encouraged | OpenAI actively supports via Codex SDK, MCP, Apps SDK |\n| **Claude** | API Key | ✅ Works (pay-per-token) | Anthropic banned subscription OAuth (Feb 2026). Use API key only |\n| **GitHub Copilot** | Device Code | ⚠️ Works but violates ToS | Not recommended for production |\n| **Google Gemini** | API Key | ✅ Works (pay-per-token) | Google banned subscription OAuth. Accounts permanently banned |\n| **DeepSeek, OpenRouter** | API Key | ✅ Works | Standard API key auth |\n\n**Key insight:** OpenAI Codex OAuth is the only path where users can reuse their existing subscription ($20/mo ChatGPT Plus) in third-party apps at zero additional cost. All other providers require pay-per-token API keys.\n\n### Provider Selection Guide\n\nWhen integrating AI into an app, help the user choose:\n\n1. **User has ChatGPT Plus/Pro** → Use OpenAI Codex OAuth (zero extra cost, best value)\n2. **User has Claude API key** → Use Anthropic API Key (high quality, pay-per-token)\n3. **User has both** → Default to OpenAI Codex (free with subscription), fall back to Claude\n4. **User has neither** → Guide them to get ChatGPT Plus ($20/mo) or a free-tier API key\n\n⚠️ **Anti-Patterns — Do NOT:**\n- Attempt to bridge Claude Pro/Max subscription via OAuth (Anthropic will block it)\n- Attempt to bridge Google Gemini subscription via OAuth (Google will permanently ban the account)\n- Hardcode provider-specific API calls in the target app (use ai-sub-auth's unified interface)\n- Store tokens outside the module's TokenStore (security risk)\n\n---\n\n## Quick Reference\n\n| File | Purpose |\n|------|---------|\n| `ai_sub_auth/facade.py` | **AI Facade** — auto-detects subscription, recommended entry point |\n| `ai_sub_auth/providers.py` | Provider registry — add new providers here |\n| `ai_sub_auth/oauth_flow.py` | OAuth PKCE login + auto token refresh |\n| `ai_sub_auth/token_store.py` | Secure token storage (~/.ai-sub-auth/tokens/) |\n| `ai_sub_auth/api_client.py` | Unified LLMClient — routes to correct API |\n| `ai_sub_auth/models.py` | Data models: OAuthToken, ProviderConfig, LLMResponse |\n| `ai_sub_auth/exceptions.py` | AuthError, TokenExpiredError, LoginRequiredError |\n\n---\n\n## Meta Skill Framework\n\nWhen integrating AI into any application, every useful AI feature is a composition of exactly **8 meta skills**:\n\n```\nSkill Direction What it does\n───────── ───────────── ─────────────────────────────────────────\nSUMMARIZE many → few Reduce volume while preserving meaning\nGENERATE few → many Produce new content from intent or spec\nANALYZE raw → insight Find patterns, anomalies, trends in data\nTRANSFORM form A → form B Convert between formats, styles, languages\nCLASSIFY items → buckets Assign categories, priorities, or labels\nEVALUATE content → score Judge quality against criteria\nCONVERSE user ↔ AI Multi-turn contextual dialogue\nEXTRACT noise → signal Pull structured data from unstructured input\n```\n\n### When to apply each skill\n\n| Skill | Trigger signals in the target app |\n|-------|----------------------------------|\n| SUMMARIZE | Has collections of text (notes, emails, logs, threads, history) |\n| GENERATE | Has \"create/new\" buttons, blank editors, templates, boilerplate |\n| ANALYZE | Has charts, tables, dashboards, numerical/time-series data |\n| TRANSFORM | Has import/export, format conversion, audience adaptation |\n| CLASSIFY | Has inbox/queue/feed, manual tagging, predefined categories |\n| EVALUATE | Has submissions, reviews, quality checks, rubrics, checklists |\n| CONVERSE | Has help section, complex workflows, onboarding, Q&A needs |\n| EXTRACT | Has manual data entry, forms, paste-from-external, uploads |\n\n---\n\n## 3-Suggestion Protocol\n\nWhen you encounter a new application, follow this protocol to suggest AI integrations:\n\n### Step 1: SCAN — Build an App Profile\n\nExamine in order: README → directory structure → routes/endpoints → data models → UI entry points.\n\nProduce:\n```\ndomain: [e.g., \"education\", \"finance\", \"devtools\", \"personal\"]\nverbs: [what the app DOES — \"create tasks\", \"send emails\", \"track expenses\"]\nnouns: [what the app KNOWS — \"notes\", \"transactions\", \"users\", \"documents\"]\nroles: [who uses it — \"admin\", \"user\", \"viewer\"]\nexisting_ai: [what's already AI-powered, if anything]\n```\n\n### Step 2: MATCH — Score skills against the profile\n\nFor each of the 8 meta skills, check if its trigger signals are present in the app profile. Prioritize skills that are NOT yet implemented (greenfield bonus).\n\n### Step 3: RANK — Select exactly 3\n\nRank by: **Impact (3x)** × **Feasibility (2x)** × **Differentiation (1x)**\n\nHard rules:\n- 3 suggestions, never more, never fewer\n- No two suggestions use the same meta skill\n- At least one must be a **quick win** (< 50 lines to integrate)\n- At least one must be **high ceiling** (transformative if done fully)\n\n### Step 4: PRESENT — Use this template for each suggestion\n\n```\n## Suggestion [1/3]: [SKILL] — [One-line description]\n\n**What it does:** [2-3 sentences, user perspective]\n**Why this app needs it:** [Connect to a specific pain point from SCAN]\n**Integration point:** [Exact file(s) and function(s)]\n**Effort:** [Quick win | Moderate | Deep integration]\n\n**Implementation sketch:**\n1. [Hook: where in the app to add this]\n2. [Service: the ai-sub-auth call pattern]\n3. [UI: how the user triggers and sees it]\n```\n\n### Step 5: IMPLEMENT — Upon user approval\n\n```\n1. AUTH → from ai_sub_auth import LLMClient, PROVIDERS\n2. SERVICE → Create function: input → LLMClient.chat(prompt, system) → parsed output\n3. ROUTE → Wire into app's existing API/endpoint pattern\n4. UI → Add trigger (button/auto/hook) following app's component style\n5. VERIFY → Test auth, test output, test error handling\n```\n\n---\n\n## Integration Patterns by App Category\n\n| Category | Best 3 skills | Example integration |\n|----------|--------------|-------------------|\n| **Notes/PKM** (Obsidian, Logseq) | Summarize, Analyze, Generate | \"Summarize this week's notes\" button |\n| **Dev tools** (terminals, IDEs) | Evaluate, Analyze, Generate | Inline code review on git diff |\n| **Email/Chat** (Thunderbird, Element) | Generate, Summarize, Classify | Draft reply + inbox triage |\n| **CMS/Blog** (Hugo, WordPress) | Generate, Transform, Evaluate | AI first draft + SEO metadata |\n| **Data/Analytics** (Grafana, Metabase) | Analyze, Transform, Generate | Natural language → SQL query |\n| **Personal** (finance, health, calendar) | Analyze, Extract, Generate | Voice → structured expense entry |\n| **System/Infra** (monitoring, CI/CD) | Analyze, Generate, Transform | Log correlation → incident summary |\n\n---\n\n## Implementation Example\n\nHere's a complete example of adding SUMMARIZE to a note-taking app:\n\n```python\n# 1. AUTH — one-time setup\nfrom ai_sub_auth import LLMClient, PROVIDERS, oauth_login\n\n# If using ChatGPT subscription (OAuth):\n# oauth_login(PROVIDERS[\"openai_codex\"]) # first time only\nclient = LLMClient(PROVIDERS[\"openai_codex\"], model=\"openai-codex/gpt-4o\")\n\n# Or if using API key:\n# client = LLMClient(PROVIDERS[\"anthropic\"], api_key=\"sk-...\", model=\"claude-sonnet-4-5-20250514\")\n\n# 2. SERVICE — the AI function\nasync def summarize_notes(notes: list[str], max_points: int = 5) -> dict:\n combined = \"\\n---\\n\".join(notes)\n resp = await client.chat(\n message=combined,\n system=f\"Summarize these {len(notes)} notes into {max_points} key points. \"\n f\"Output JSON: {{\\\"points\\\": [\\\"...\\\"], \\\"action_items\\\": [\\\"...\\\"]}}\",\n )\n import json\n return json.loads(resp.content)\n\n# 3. ROUTE — hook into your app's API\n# @app.post(\"/api/ai/summarize\")\n# async def api_summarize(request): ...\n\n# 4. UI — add a button\n# <button onClick={summarize}>✨ Summarize</button>\n```\n\n### TRANSFORM Example: Adding translation to a messaging app\n\n```python\n# 1. AUTH — one-time setup\nfrom ai_sub_auth import LLMClient, PROVIDERS, oauth_login\n\n# Using ChatGPT subscription (zero cost for the user):\n# oauth_login(PROVIDERS[\"openai_codex\"]) # first time only\nclient = LLMClient(PROVIDERS[\"openai_codex\"], model=\"openai-codex/gpt-4o\")\n\n# 2. SERVICE — the AI function\nasync def translate_message(text: str, source_lang: str, target_lang: str) -> dict:\n resp = await client.chat(\n message=text,\n system=(\n f\"Translate the following from {source_lang} to {target_lang}. \"\n f\"Preserve tone, formatting, and any embedded links. \"\n f'Output JSON: {{\"translation\": \"...\", \"detected_lang\": \"...\", \"confidence\": 0.0-1.0}}'\n ),\n )\n import json\n return json.loads(resp.content)\n\n# 3. ROUTE — hook into your messaging app's API\nfrom fastapi import APIRouter\nrouter = APIRouter()\n\n@router.post(\"/api/ai/translate\")\nasync def api_translate(request: dict):\n result = await translate_message(\n text=request[\"text\"],\n source_lang=request.get(\"source_lang\", \"auto\"),\n target_lang=request[\"target_lang\"],\n )\n return result\n\n# 4. UI — add inline translate button on each message\n# <button onClick={() => translate(msg.id, userLang)}>🌐 Translate</button>\n# Shows translated text below original, with \"Translated from {detected_lang}\" label\n```\n\n### EXTRACT Example: Structured data extraction from documents\n\n```python\n# 1. AUTH — one-time setup\nfrom ai_sub_auth import LLMClient, PROVIDERS, oauth_login\n\n# Using ChatGPT subscription:\n# oauth_login(PROVIDERS[\"openai_codex\"]) # first time only\nclient = LLMClient(PROVIDERS[\"openai_codex\"], model=\"openai-codex/gpt-4o\")\n\n# Or using Claude API key for higher extraction accuracy:\n# client = LLMClient(PROVIDERS[\"anthropic\"], api_key=\"sk-...\", model=\"claude-sonnet-4-5-20250514\")\n\n# 2. SERVICE — the AI function\nasync def extract_invoice_data(raw_text: str) -> dict:\n resp = await client.chat(\n message=raw_text,\n system=(\n \"Extract structured data from this invoice/receipt. \"\n \"Output JSON: {\"\n '\"vendor\": \"...\", \"date\": \"YYYY-MM-DD\", \"currency\": \"...\", '\n '\"total\": 0.00, \"tax\": 0.00, \"subtotal\": 0.00, '\n '\"line_items\": [{\"description\": \"...\", \"qty\": 1, \"unit_price\": 0.00, \"amount\": 0.00}]'\n \"}\"\n \" If a field is not found, use null.\"\n ),\n )\n import json\n return json.loads(resp.content)\n\n# 3. ROUTE — hook into your document management app's API\nfrom fastapi import APIRouter, UploadFile\nrouter = APIRouter()\n\n@router.post(\"/api/ai/extract-invoice\")\nasync def api_extract_invoice(file: UploadFile):\n raw_text = (await file.read()).decode(\"utf-8\") # or use OCR for images\n result = await extract_invoice_data(raw_text)\n return result\n\n# 4. UI — add extract button on document upload\n# <button onClick={() => extractData(doc.id)}>📋 Extract Data</button>\n# Pre-fills form fields with extracted values; user reviews and confirms\n```\n\n---\n\n## Principles\n\n1. **Eight is enough.** Every AI feature maps to one of the 8 skills. Don't invent a ninth — it's a composition.\n2. **Skills are verbs, not features.** \"Summarize\" is a skill. \"Email summary\" is a feature = skill + context.\n3. **Three suggestions, never more.** Fewer forces prioritization. More creates paralysis.\n4. **Quick-win plus high-ceiling.** Build trust with a fast win, then go deep.\n5. **Follow the host.** Mirror the target app's conventions for auth, routing, and UI. Be a guest, not an invader.\n6. **Auth is first, not last.** Every AI feature goes through ai-sub-auth from step 1.\n7. **Subscription-first.** Prefer OAuth subscription bridge (ChatGPT Plus) over API keys when available. It's zero extra cost for the user.\n"}, "5095f6781d517b62fba873e30397a70e44c9b373": {"t": 1785770836.3327777, "n": 7591, "h": "5189260059628372", "c": "# Agent Integration Guide\n\n> **For AI Agents**: Read this file to understand how to integrate `ai-sub-auth` into any application.\n> This file is designed to be consumed by Claude Code, OpenClaw, Cursor, Copilot, or any agentic coding tool.\n\n## What is ai-sub-auth?\n\nA lightweight Python module (~500 LOC, only depends on `httpx`) that authenticates against AI providers using existing user subscriptions. It handles OAuth PKCE (OpenAI Codex), API keys (Claude, Gemini, DeepSeek), and device code (GitHub Copilot) — all through a unified `LLMClient` interface.\n\n**3-line integration:**\n```python\nfrom ai_sub_auth import LLMClient, PROVIDERS\nclient = LLMClient(PROVIDERS[\"openai_codex\"], model=\"openai-codex/gpt-4o\")\nresp = await client.chat(\"your prompt here\", system=\"your system prompt\")\n```\n\n## Quick Reference\n\n| File | Purpose |\n|------|---------|\n| `ai_sub_auth/providers.py` | Provider registry — add new providers here |\n| `ai_sub_auth/oauth_flow.py` | OAuth PKCE login + auto token refresh |\n| `ai_sub_auth/token_store.py` | Secure token storage (~/.ai-sub-auth/tokens/) |\n| `ai_sub_auth/api_client.py` | Unified LLMClient — routes to correct API |\n| `ai_sub_auth/models.py` | Data models: OAuthToken, ProviderConfig, LLMResponse |\n| `ai_sub_auth/exceptions.py` | AuthError, TokenExpiredError, LoginRequiredError |\n\n---\n\n## Meta Skill Framework\n\nWhen integrating AI into any application, every useful AI feature is a composition of exactly **8 meta skills**:\n\n```\nSkill Direction What it does\n───────── ───────────── ─────────────────────────────────────────\nSUMMARIZE many → few Reduce volume while preserving meaning\nGENERATE few → many Produce new content from intent or spec\nANALYZE raw → insight Find patterns, anomalies, trends in data\nTRANSFORM form A → form B Convert between formats, styles, languages\nCLASSIFY items → buckets Assign categories, priorities, or labels\nEVALUATE content → score Judge quality against criteria\nCONVERSE user ↔ AI Multi-turn contextual dialogue\nEXTRACT noise → signal Pull structured data from unstructured input\n```\n\n### When to apply each skill\n\n| Skill | Trigger signals in the target app |\n|-------|----------------------------------|\n| SUMMARIZE | Has collections of text (notes, emails, logs, threads, history) |\n| GENERATE | Has \"create/new\" buttons, blank editors, templates, boilerplate |\n| ANALYZE | Has charts, tables, dashboards, numerical/time-series data |\n| TRANSFORM | Has import/export, format conversion, audience adaptation |\n| CLASSIFY | Has inbox/queue/feed, manual tagging, predefined categories |\n| EVALUATE | Has submissions, reviews, quality checks, rubrics, checklists |\n| CONVERSE | Has help section, complex workflows, onboarding, Q&A needs |\n| EXTRACT | Has manual data entry, forms, paste-from-external, uploads |\n\n---\n\n## 3-Suggestion Protocol\n\nWhen you encounter a new application, follow this protocol to suggest AI integrations:\n\n### Step 1: SCAN — Build an App Profile\n\nExamine in order: README → directory structure → routes/endpoints → data models → UI entry points.\n\nProduce:\n```\ndomain: [e.g., \"education\", \"finance\", \"devtools\", \"personal\"]\nverbs: [what the app DOES — \"create tasks\", \"send emails\", \"track expenses\"]\nnouns: [what the app KNOWS — \"notes\", \"transactions\", \"users\", \"documents\"]\nroles: [who uses it — \"admin\", \"user\", \"viewer\"]\nexisting_ai: [what's already AI-powered, if anything]\n```\n\n### Step 2: MATCH — Score skills against the profile\n\nFor each of the 8 meta skills, check if its trigger signals are present in the app profile. Prioritize skills that are NOT yet implemented (greenfield bonus).\n\n### Step 3: RANK — Select exactly 3\n\nRank by: **Impact (3x)** × **Feasibility (2x)** × **Differentiation (1x)**\n\nHard rules:\n- 3 suggestions, never more, never fewer\n- No two suggestions use the same meta skill\n- At least one must be a **quick win** (< 50 lines to integrate)\n- At least one must be **high ceiling** (transformative if done fully)\n\n### Step 4: PRESENT — Use this template for each suggestion\n\n```\n## Suggestion [1/3]: [SKILL] — [One-line description]\n\n**What it does:** [2-3 sentences, user perspective]\n**Why this app needs it:** [Connect to a specific pain point from SCAN]\n**Integration point:** [Exact file(s) and function(s)]\n**Effort:** [Quick win | Moderate | Deep integration]\n\n**Implementation sketch:**\n1. [Hook: where in the app to add this]\n2. [Service: the ai-sub-auth call pattern]\n3. [UI: how the user triggers and sees it]\n```\n\n### Step 5: IMPLEMENT — Upon user approval\n\n```\n1. AUTH → from ai_sub_auth import LLMClient, PROVIDERS\n2. SERVICE → Create function: input → LLMClient.chat(prompt, system) → parsed output\n3. ROUTE → Wire into app's existing API/endpoint pattern\n4. UI → Add trigger (button/auto/hook) following app's component style\n5. VERIFY → Test auth, test output, test error handling\n```\n\n---\n\n## Integration Patterns by App Category\n\n| Category | Best 3 skills | Example integration |\n|----------|--------------|-------------------|\n| **Notes/PKM** (Obsidian, Logseq) | Summarize, Analyze, Generate | \"Summarize this week's notes\" button |\n| **Dev tools** (terminals, IDEs) | Evaluate, Analyze, Generate | Inline code review on git diff |\n| **Email/Chat** (Thunderbird, Element) | Generate, Summarize, Classify | Draft reply + inbox triage |\n| **CMS/Blog** (Hugo, WordPress) | Generate, Transform, Evaluate | AI first draft + SEO metadata |\n| **Data/Analytics** (Grafana, Metabase) | Analyze, Transform, Generate | Natural language → SQL query |\n| **Personal** (finance, health, calendar) | Analyze, Extract, Generate | Voice → structured expense entry |\n| **System/Infra** (monitoring, CI/CD) | Analyze, Generate, Transform | Log correlation → incident summary |\n\n---\n\n## Implementation Example\n\nHere's a complete example of adding SUMMARIZE to a note-taking app:\n\n```python\n# 1. AUTH — one-time setup\nfrom ai_sub_auth import LLMClient, PROVIDERS, oauth_login\n\n# If using ChatGPT subscription (OAuth):\n# oauth_login(PROVIDERS[\"openai_codex\"]) # first time only\nclient = LLMClient(PROVIDERS[\"openai_codex\"], model=\"openai-codex/gpt-4o\")\n\n# Or if using API key:\n# client = LLMClient(PROVIDERS[\"anthropic\"], api_key=\"sk-...\", model=\"claude-sonnet-4-5-20250514\")\n\n# 2. SERVICE — the AI function\nasync def summarize_notes(notes: list[str], max_points: int = 5) -> dict:\n combined = \"\\n---\\n\".join(notes)\n resp = await client.chat(\n message=combined,\n system=f\"Summarize these {len(notes)} notes into {max_points} key points. \"\n f\"Output JSON: {{\\\"points\\\": [\\\"...\\\"], \\\"action_items\\\": [\\\"...\\\"]}}\",\n )\n import json\n return json.loads(resp.content)\n\n# 3. ROUTE — hook into your app's API\n# @app.post(\"/api/ai/summarize\")\n# async def api_summarize(request): ...\n\n# 4. UI — add a button\n# <button onClick={summarize}>✨ Summarize</button>\n```\n\n---\n\n## Principles\n\n1. **Eight is enough.** Every AI feature maps to one of the 8 skills. Don't invent a ninth — it's a composition.\n2. **Skills are verbs, not features.** \"Summarize\" is a skill. \"Email summary\" is a feature = skill + context.\n3. **Three suggestions, never more.** Fewer forces prioritization. More creates paralysis.\n4. **Quick-win plus high-ceiling.** Build trust with a fast win, then go deep.\n5. **Follow the host.** Mirror the target app's conventions for auth, routing, and UI. Be a guest, not an invader.\n6. **Auth is first, not last.** Every AI feature goes through ai-sub-auth from step 1.\n"}}}} |