Skill: sabrinaaquino/venice-admin (version 1.0.1)

--- name: venice-admin description: Venice AI account administration - check balance, view usage history, and manage API keys. Requires an Admin API key. homepage: https://venice.ai metadata: { "openclaw": { "emoji": "⚙️", "requires": { "bins": ["uv"], "env": ["VENICE_API_KEY"] }, "primaryEnv": "VENICE_API_KEY", "install": [ { "id": "uv-brew", "kind": "brew", "formula": "uv", "bins": ["uv"], "label": "Install uv (brew)", }, ], }, } --- # Venice Admin Manage your Venice AI account - check balance, view usage history, and manage API keys. **⚠️ Important:** These endpoints require an **Admin API key**, not a regular inference key. Create one at [venice.ai](https://venice.ai) → Settings → API Keys → Create Admin Key. **API Base URL:** `https://api.venice.ai/api/v1` ## Setup 1. Create an **Admin API key** from [venice.ai](https://venice.ai) → Settings → API Keys 2. Set the environment variable: ```bash export VENICE_API_KEY="your_admin_api_key_here" ``` --- ## Check Balance View your current DIEM and USD balances. ```bash uv run {baseDir}/scripts/balance.py ``` **Output includes:** - Whether you can consume (has balance) - Current consumption currency (DIEM or USD) - DIEM balance and epoch allocation - USD balance --- ## View Usage History View detailed usage history with filtering and pagination. ```bash uv run {baseDir}/scripts/usage.py ``` **Options:** - `--currency`: Filter by currency: `DIEM`, `USD`, `VCU` (default: `DIEM`) - `--start-date`: Start date filter (ISO format: `2024-01-01`) - `--end-date`: End date filter (ISO format: `2024-12-31`) - `--limit`: Results per page (default: `50`, max: `200`) - `--page`: Page number (default: `1`) - `--sort`: Sort order: `asc` or `desc` (default: `desc`) - `--format`: Output format: `json` or `csv` (default: `json`) - `--output`: Save to file instead of stdout **Examples:** ```bash # Last 50 DIEM transactions uv run {baseDir}/scripts/usage.py # USD usage in January 2024 uv run {baseDir}/scripts/usage.py --currency USD --start-date 2024-01-01 --end-date 2024-01-31 # Export to CSV uv run {baseDir}/scripts/usage.py --format csv --output usage.csv ``` --- ## List API Keys View all your API keys. ```bash uv run {baseDir}/scripts/api_keys_list.py ``` **Output includes:** - Key ID and name - Key type (Admin, Inference, etc.) - Creation date - Last used date - Rate limits --- ## Runtime Note This skill uses `uv run` which automatically installs Python dependencies (httpx) via [PEP 723](https://peps.python.org/pep-0723/) inline script metadata. No manual Python package installation required - `uv` handles everything. --- ## Security Notes - **Admin keys have elevated permissions** - protect them carefully - Admin keys can view billing info and manage other keys - Never commit admin keys to version control - Consider using inference-only keys for production workloads ## API Reference | Endpoint | Description | Auth Required | |----------|-------------|---------------| | `GET /billing/balance` | Check DIEM/USD balance | Admin key | | `GET /billing/usage` | View usage history | Admin key | | `GET /api_keys` | List all API keys | Admin key | Full API docs: [docs.venice.ai](https://docs.venice.ai)

path: scripts/api_keys_list.py
content: # /// script
# requires-python = ">=3.10"
# dependencies = ["httpx"]
# ///
"""
Venice AI API Keys List

List all your API keys.
Requires an Admin API key.
API docs: https://docs.venice.ai
"""

import json
import os
import sys
from datetime import datetime

import httpx

VENICE_BASE_URL = "https://api.venice.ai/api/v1"


def get_api_key() -> str:
    """Get Venice API key from environment."""
    [REDACTED_SECRET]"VENICE_API_KEY")
    if not [REDACTED_SECRET]"Error: VENICE_API_KEY environment variable is not set", file=sys.stderr)
        print("Get your ADMIN API key at https://venice.ai → Settings → API Keys", file=sys.stderr)
        sys.exit(1)
    return api_key


def format_date(date_str: str | None) -> str:
    """Format ISO date string for display."""
    if not date_str:
        return "Never"
    try:
        dt = datetime.fromisoformat(date_str.replace("Z", "+00:00"))
        return dt.strftime("%Y-%m-%d %H:%M")
    except Exception:
        return date_str


def list_api_keys() -> list:
    """List all API keys."""
    [REDACTED_SECRET])

    headers = {
        "Authorization": f"Bearer {api_key}",
    }

    print("Fetching API keys...", file=sys.stderr)

    try:
        with httpx.Client(timeout=30.0) as client:
            response = client.get(
                f"{VENICE_BASE_URL}/api_keys",
                headers=headers
            )
            response.raise_for_status()
            
            data = response.json()
            keys = data.get("data", [])
            
            # Pretty print the keys
            print("\n" + "=" * 70, file=sys.stderr)
            print("VENICE AI API KEYS", file=sys.stderr)
            print("=" * 70, file=sys.stderr)
            
            if not keys:
                print("\nNo API keys found.", file=sys.stderr)
            else:
                print(f"\nFound {len(keys)} API key(s):\n", file=sys.stderr)
                
                for i, key in enumerate(keys, 1):
                    key_id = key.get("id", "unknown")
                    name = key.get("name", "Unnamed")
                    key_type = key.get("apiKeyType", "unknown")
                    created = format_date(key.get("createdAt"))
                    last_used = format_date(key.get("lastUsedAt"))
                    
                    # Mask the key prefix if available
                    key_prefix = key.get("keyPrefix", "")
                    if key_prefix:
                        masked_key = f"{key_prefix}..."
                    else:
                        masked_key = "***"
                    
                    print(f"[{i}] {name}", file=sys.stderr)
                    print(f"    ID: {key_id}", file=sys.stderr)
                    print(f"    Type: {key_type}", file=sys.stderr)
                    print(f"    Key: {masked_key}", file=sys.stderr)
                    print(f"    Created: {created}", file=sys.stderr)
                    print(f"    Last Used: {last_used}", file=sys.stderr)
                    
                    # Show rate limits if available
                    rate_limits = key.get("rateLimits")
                    if rate_limits:
                        print(f"    Rate Limits: {rate_limits}", file=sys.stderr)
                    
                    print("", file=sys.stderr)
            
            print("=" * 70 + "\n", file=sys.stderr)
            
            # Also output as JSON for programmatic use
            print(json.dumps(data, indent=2, default=str))
            
            return keys

    except httpx.HTTPStatusError as e:
        if e.response.status_code == 401:
            print("Error: Authentication failed. Make sure you're using an ADMIN API key.", file=sys.stderr)
        else:
            print(f"HTTP Error: {e.response.status_code}", file=sys.stderr)
        try:
            error_data = e.response.json()
            print(f"Details: {error_data}", file=sys.stderr)
        except Exception:
            print(f"Response: {e.response.text[:500]}", file=sys.stderr)
        sys.exit(1)
    except httpx.RequestError as e:
        print(f"Request Error: {e}", file=sys.stderr)
        sys.exit(1)


def main():
    list_api_keys()


if __name__ == "__main__":
    main()



path: scripts/balance.py
content: # /// script
# requires-python = ">=3.10"
# dependencies = ["httpx"]
# ///
"""
Venice AI Balance Check

Check your DIEM and USD balances.
Requires an Admin API key.
API docs: https://docs.venice.ai
"""

import json
import os
import sys

import httpx

VENICE_BASE_URL = "https://api.venice.ai/api/v1"


def get_api_key() -> str:
    """Get Venice API key from environment."""
    [REDACTED_SECRET]"VENICE_API_KEY")
    if not [REDACTED_SECRET]"Error: VENICE_API_KEY environment variable is not set", file=sys.stderr)
        print("Get your ADMIN API key at https://venice.ai → Settings → API Keys", file=sys.stderr)
        sys.exit(1)
    return api_key


def check_balance() -> dict:
    """Check current balance."""
    [REDACTED_SECRET])

    headers = {
        "Authorization": f"Bearer {api_key}",
    }

    print("Checking balance...", file=sys.stderr)

    try:
        with httpx.Client(timeout=30.0) as client:
            response = client.get(
                f"{VENICE_BASE_URL}/billing/balance",
                headers=headers
            )
            response.raise_for_status()
            
            data = response.json()
            
            # Pretty print the balance info
            print("\n" + "=" * 50, file=sys.stderr)
            print("VENICE AI BALANCE", file=sys.stderr)
            print("=" * 50, file=sys.stderr)
            
            can_consume = data.get("canConsume", False)
            currency = data.get("consumptionCurrency", "None")
            balances = data.get("balances", {})
            diem_allocation = data.get("diemEpochAllocation", 0)
            
            print(f"\n✓ Can Consume: {'Yes' if can_consume else 'No'}", file=sys.stderr)
            print(f"✓ Active Currency: {currency or 'None'}", file=sys.stderr)
            
            print("\nBalances:", file=sys.stderr)
            diem_balance = balances.get("diem")
            usd_balance = balances.get("usd")
            
            if diem_balance is not None:
                print(f"  • DIEM: {diem_balance:.4f}", file=sys.stderr)
            else:
                print("  • DIEM: -", file=sys.stderr)
                
            if usd_balance is not None:
                print(f"  • USD: ${usd_balance:.2f}", file=sys.stderr)
            else:
                print("  • USD: -", file=sys.stderr)
            
            if diem_allocation:
                print(f"\nDIEM Epoch Allocation: {diem_allocation:.4f}", file=sys.stderr)
            
            print("=" * 50 + "\n", file=sys.stderr)
            
            # Also output as JSON for programmatic use
            print(json.dumps(data, indent=2))
            
            return data

    except httpx.HTTPStatusError as e:
        if e.response.status_code == 401:
            print("Error: Authentication failed. Make sure you're using an ADMIN API key.", file=sys.stderr)
        else:
            print(f"HTTP Error: {e.response.status_code}", file=sys.stderr)
        try:
            error_data = e.response.json()
            print(f"Details: {error_data}", file=sys.stderr)
        except Exception:
            print(f"Response: {e.response.text[:500]}", file=sys.stderr)
        sys.exit(1)
    except httpx.RequestError as e:
        print(f"Request Error: {e}", file=sys.stderr)
        sys.exit(1)


def main():
    check_balance()


if __name__ == "__main__":
    main()



path: scripts/usage.py
content: # /// script
# requires-python = ">=3.10"
# dependencies = ["httpx"]
# ///
"""
Venice AI Usage History

View detailed usage history with filtering and pagination.
Requires an Admin API key.
API docs: https://docs.venice.ai
"""

import argparse
import json
import os
import sys
from pathlib import Path

import httpx

VENICE_BASE_URL = "https://api.venice.ai/api/v1"

VALID_CURRENCIES = ["DIEM", "USD", "VCU"]


def get_api_key() -> str:
    """Get Venice API key from environment."""
    [REDACTED_SECRET]"VENICE_API_KEY")
    if not [REDACTED_SECRET]"Error: VENICE_API_KEY environment variable is not set", file=sys.stderr)
        print("Get your ADMIN API key at https://venice.ai → Settings → API Keys", file=sys.stderr)
        sys.exit(1)
    return api_key


def get_usage(
    currency: str = "DIEM",
    start_date: str | None = None,
    end_date: str | None = None,
    limit: int = 50,
    page: int = 1,
    sort_order: str = "desc",
    output_format: str = "json",
    output_file: str | None = None,
) -> dict:
    """Get usage history."""
    [REDACTED_SECRET])

    headers = {
        "Authorization": f"Bearer {api_key}",
    }

    params: dict = {
        "currency": currency,
        "limit": min(limit, 200),
        "page": page,
        "sortOrder": sort_order,
    }

    if start_date:
        params["startDate"] = start_date
    if end_date:
        params["endDate"] = end_date

    print(f"Fetching {currency} usage (page {page}, limit {limit})...", file=sys.stderr)

    try:
        with httpx.Client(timeout=60.0) as client:
            response = client.get(
                f"{VENICE_BASE_URL}/billing/usage",
                headers=headers,
                params=params
            )
            response.raise_for_status()
            
            data = response.json()
            
            # Print summary
            total = data.get("total", 0)
            results = data.get("data", [])
            pagination = data.get("pagination", {})
            
            print(f"\nFound {total} total records", file=sys.stderr)
            print(f"Showing {len(results)} records (page {page})", file=sys.stderr)
            
            if data.get("warning"):
                print(f"\n⚠️  {data['warning']}", file=sys.stderr)
            
            # Format output
            if output_format == "csv":
                output = format_csv(results)
            else:
                output = json.dumps(data, indent=2, default=str)
            
            # Save or print
            if output_file:
                output_path = Path(output_file).resolve()
                output_path.write_text(output)
                print(f"\nSaved to: {output_path}", file=sys.stderr)
            else:
                print(output)
            
            return data

    except httpx.HTTPStatusError as e:
        if e.response.status_code == 401:
            print("Error: Authentication failed. Make sure you're using an ADMIN API key.", file=sys.stderr)
        else:
            print(f"HTTP Error: {e.response.status_code}", file=sys.stderr)
        try:
            error_data = e.response.json()
            print(f"Details: {error_data}", file=sys.stderr)
        except Exception:
            print(f"Response: {e.response.text[:500]}", file=sys.stderr)
        sys.exit(1)
    except httpx.RequestError as e:
        print(f"Request Error: {e}", file=sys.stderr)
        sys.exit(1)


def format_csv(results: list) -> str:
    """Format results as CSV."""
    if not results:
        return "No data"
    
    # Get headers from first result
    headers = list(results[0].keys())
    lines = [",".join(headers)]
    
    for row in results:
        values = []
        for h in headers:
            val = row.get(h, "")
            # Escape commas and quotes
            if isinstance(val, str) and ("," in val or '"' in val):
                val = f'"{val.replace(chr(34), chr(34)+chr(34))}"'
            values.append(str(val) if val is not None else "")
        lines.append(",".join(values))
    
    return "\n".join(lines)


def main():
    parser = argparse.ArgumentParser(
        description="View Venice AI usage history"
    )
    parser.add_argument(
        "--currency", "-c",
        choices=VALID_CURRENCIES,
        default="DIEM",
        help="Currency to filter by (default: DIEM)"
    )
    parser.add_argument(
        "--start-date",
        help="Start date filter (ISO format: 2024-01-01)"
    )
    parser.add_argument(
        "--end-date",
        help="End date filter (ISO format: 2024-12-31)"
    )
    parser.add_argument(
        "--limit", "-l",
        type=int,
        default=50,
        help="Results per page, max 200 (default: 50)"
    )
    parser.add_argument(
        "--page", "-p",
        type=int,
        default=1,
        help="Page number (default: 1)"
    )
    parser.add_argument(
        "--sort", "-s",
        choices=["asc", "desc"],
        default="desc",
        help="Sort order (default: desc)"
    )
    parser.add_argument(
        "--format", "-f",
        dest="output_format",
        choices=["json", "csv"],
        default="json",
        help="Output format (default: json)"
    )
    parser.add_argument(
        "--output", "-o",
        help="Save output to file"
    )

    args = parser.parse_args()
    
    get_usage(
        currency=args.currency,
        start_date=args.start_date,
        end_date=args.end_date,
        limit=args.limit,
        page=args.page,
        sort_order=args.sort,
        output_format=args.output_format,
        output_file=args.output,
    )


if __name__ == "__main__":
    main()



Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: suspicious | SkillSpector: clean (LOW)