File size: 1,397 Bytes
8f766ee
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
"""
Thin Supabase wrapper. Every tool that needs a credential pulls it from the
`tool_keys` table in the `gate` Supabase project via get_tool_keys(tool_name).

Table shape (public.tool_keys):
    tool            text   -- matches TOOLS[i]["name"] in registry.py
    label           text
    key_type        text
    api_key         text   -- primary credential slot
    secondary_key   text   -- e.g. client_secret, cookie value, etc.
    is_active       bool
    notes           text
"""
import os
from functools import lru_cache
from supabase import create_client, Client


@lru_cache(maxsize=1)
def get_client() -> Client:
    url = os.environ["SUPABASE_URL"]
    key = os.environ["SUPABASE_SERVICE_KEY"]
    return create_client(url, key)


def get_tool_keys(tool_name: str) -> dict | None:
    """Return the active credential row for a tool, or None if missing/inactive."""
    client = get_client()
    resp = (
        client.table("tool_keys")
        .select("*")
        .eq("tool", tool_name)
        .eq("is_active", True)
        .limit(1)
        .execute()
    )
    return resp.data[0] if resp.data else None


def require_tool_keys(tool_name: str) -> dict:
    row = get_tool_keys(tool_name)
    if not row:
        raise ValueError(
            f"No active credentials for '{tool_name}' in tool_keys. "
            f"Add a row and set is_active = true."
        )
    return row