Skill: aimlapihello/aiml-llm-reasoning (version 1.0.1)

--- name: aimlapi-llm-reasoning description: Run AIMLAPI LLM and reasoning workflows through chat completions with retries, structured outputs, and explicit User-Agent headers. Use when Codex needs scripted prompting/reasoning calls against AIMLAPI models. env: - AIMLAPI_API_KEY primaryEnv: AIMLAPI_API_KEY --- # AIMLAPI LLM + Reasoning ## Overview Use `run_chat.py` to call AIMLAPI chat completions with retries, optional API key file fallback, and a `User-Agent` header on every request. ## Quick start ```bash export AIMLAPI_API_KEY="sk-aimlapi-..." python3 {baseDir}/scripts/run_chat.py --model aimlapi/openai/gpt-5-nano-2025-08-07 --user "Summarize this in 3 bullets." ``` ## Tasks ### Run a basic chat completion ```bash python3 {baseDir}/scripts/run_chat.py \ --model aimlapi/openai/gpt-5-nano-2025-08-07 \ --system "You are a concise assistant." \ --user "Draft a project kickoff checklist." \ --user-agent "openclaw-custom/1.0" ``` ### Add reasoning parameters ```bash python3 {baseDir}/scripts/run_chat.py \ --model aimlapi/openai/gpt-5-nano-2025-08-07 \ --user "Plan a 5-step rollout for a new chatbot feature." \ --extra-json '{"reasoning": {"effort": "medium"}, "temperature": 0.3}' ``` ### Structured JSON output ```bash python3 {baseDir}/scripts/run_chat.py \ --model aimlapi/openai/gpt-5-nano-2025-08-07 \ --user "Return a JSON array of 3 project risks with mitigation." \ --extra-json '{"response_format": {"type": "json_object"}}' \ --output ./out/risks.json ``` ## References - `references/aimlapi-llm.md`: payload and troubleshooting notes. - `README.md`: changelog-style summary of new instructions.

path: _meta.json
content: ownerId: kn7eawz1fm8s9b4p37hf4z3fm580jpk8
slug: aimlapi-llm-reasoning
version: 1.0.4
publishedAt: 1770809152063

path: README.md
content: # aimlapi-llm-reasoning

This skill provides a helper script for AIMLAPI chat + reasoning workflows.

## Security & Credentials

- This skill requires an `AIMLAPI_API_KEY` environment variable.
- Be cautious when using the `--apikey-file` flag; ensure the provided path is correct and secure.
- Avoid including sensitive or private data in `--extra-json`, as this payload is sent to the remote API.

## New instructions

- Every HTTP request sends a `User-Agent` header (configurable via `--user-agent`).
- `run_chat.py` supports retries, API key from `--apikey-file`, and verbose logs.
- Use `--extra-json` for reasoning/tooling/provider-specific fields.

See `SKILL.md` for examples.


path: scripts/run_chat.py
content: #!/usr/bin/env python3
from __future__ import annotations

import argparse
import json
import os
import pathlib
import time
import urllib.error
import urllib.request
from typing import Any

DEFAULT_BASE_URL = "https://api.aimlapi.com/v1"
DEFAULT_USER_AGENT = "openclaw-skill-aimlapi-llm-reasoning/1.1"


def parse_args() -> argparse.Namespace:
    parser = argparse.ArgumentParser(description="Run AIMLAPI chat completions")
    parser.add_argument("--model", required=True, help="Model reference")
    parser.add_argument("--system", default=None, help="System message")
    parser.add_argument("--user", required=True, help="User message")
    parser.add_argument("--extra-json", default=None, help="Extra JSON to merge into payload")
    parser.add_argument("--apikey-file", default=None, help="Path to a file containing the API key")
    parser.add_argument("--timeout", type=int, default=120, help="Request timeout in seconds")
    parser.add_argument("--retry-max", type=int, default=3, help="Retry attempts on failure")
    parser.add_argument("--retry-delay", type=float, default=1.0, help="Retry delay in seconds")
    parser.add_argument("--user-agent", default=DEFAULT_USER_AGENT, help="User-Agent header")
    parser.add_argument("--output", default=None, help="Write full JSON response to file")
    parser.add_argument("--verbose", action="store_true", help="Enable verbose output")
    return parser.parse_args()


def load_extra(extra_json: str | None) -> dict[str, Any]:
    if not extra_json:
        return {}
    try:
        data = json.loads(extra_json)
        # Security: Whitelist allowed extra fields
        allowed = {"reasoning", "temperature", "max_tokens", "top_p", "response_format", "stop"}
        return {k: v for k, v in data.items() if k in allowed}
    except json.JSONDecodeError as exc:
        raise SystemExit(f"Invalid --extra-json: {exc}") from exc


def load_api_key(args: argparse.Namespace) -> str:
    [REDACTED_SECRET]"AIMLAPI_API_KEY")
    if [REDACTED_SECRET] api_key
    if args.apikey_file:
        key = pathlib.Path(args.apikey_file).read_text(encoding="utf-8").strip()
        if key:
            return key
    raise SystemExit("Missing AIMLAPI_API_KEY")


def request_json(
    url: str,
    payload: dict[str, Any],
    api_key: str,
    timeout: int,
    retry_max: int,
    retry_delay: float,
    user_agent: str,
    verbose: bool,
) -> dict[str, Any]:
    req = urllib.request.Request(
        url,
        data=json.dumps(payload).encode("utf-8"),
        headers={
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json",
            "Accept": "application/json",
            "User-Agent": user_agent,
        },
        method="POST",
    )

    attempt = 0
    while True:
        try:
            if verbose:
                print(f"[debug] POST {url} attempt {attempt + 1}")
            with urllib.request.urlopen(req, timeout=timeout) as response:
                return json.loads(response.read().decode("utf-8"))
        except urllib.error.HTTPError as exc:
            detail = exc.read().decode("utf-8") if exc.fp else str(exc)
            if attempt < retry_max:
                attempt += 1
                if verbose:
                    print(f"[warning] HTTPError {exc.code}; retry in {retry_delay}s")
                time.sleep(retry_delay)
                continue
            raise SystemExit(f"Request failed: {exc.code} {detail}") from exc
        except urllib.error.URLError as exc:
            if attempt < retry_max:
                attempt += 1
                if verbose:
                    print(f"[warning] URLError; retry in {retry_delay}s: {exc}")
                time.sleep(retry_delay)
                continue
            raise SystemExit(f"Request failed: {exc}") from exc


def main() -> None:
    args = parse_args()
    [REDACTED_SECRET])

    messages: list[dict[str, str]] = []
    if args.system:
        messages.append({"role": "system", "content": args.system})
    messages.append({"role": "user", "content": args.user})

    payload = {
        "model": args.model,
        "messages": messages,
        **load_extra(args.extra_json),
    }
    url = f"{DEFAULT_BASE_URL.rstrip('/')}/chat/completions"
    response = request_json(
        url,
        payload,
        api_key,
        args.timeout,
        args.retry_max,
        args.retry_delay,
        args.user_agent,
        args.verbose,
    )

    if args.output:
        pathlib.Path(args.output).write_text(json.dumps(response, indent=2), encoding="utf-8")
        print(f"Saved JSON response to {args.output}")
        return

    choices = response.get("choices", [])
    content = choices[0].get("message", {}).get("content") if choices else None
    print(content if content else json.dumps(response, indent=2))


if __name__ == "__main__":
    main()


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