Skip to main content

AgentLoop SDK — middleware that turns human corrections into searchable memory for your agent.

Project description

agentloop

Python SDK for AgentLoop — middleware that turns human corrections into searchable memory for your agent.

  • Python 3.9+, sync and async
  • One runtime dependency (httpx), nothing else
  • Graceful by default — network blips don't break your agent
  • Type hints throughout, full dataclass response shapes

Install

pip install agentloop-py

Quick start (sync)

import os
from openai import OpenAI
from agentloop import AgentLoop

loop = AgentLoop(api_key=os.environ["AGENTLOOP_API_KEY"])
openai = OpenAI()

def ask(question: str, user_id: str) -> str:
    # 1. Before calling the LLM, pull relevant corrections.
    memories = loop.search(question, user_id=user_id, limit=3)

    # 2. Inject them into your system prompt.
    facts = "\n".join(f"- {m.fact}" for m in memories) if memories else ""
    system = "You are a helpful assistant."
    if facts:
        system += f"\n\nTrusted facts from past corrections:\n{facts}"

    # 3. Call the LLM.
    resp = openai.chat.completions.create(
        model="gpt-4o-mini",
        messages=[
            {"role": "system", "content": system},
            {"role": "user", "content": question},
        ],
    )
    answer = resp.choices[0].message.content or ""

    # 4. Log the turn for review.
    loop.log_turn(question, answer, user_id=user_id)

    return answer

That's the whole integration — one call before the LLM, one after. For a zero-setup drop-in wrapper, install agentloop-py-openai or agentloop-py-anthropic instead.

Quick start (async)

from agentloop.aio import AsyncAgentLoop

async def ask(question: str, user_id: str) -> str:
    async with AsyncAgentLoop(api_key=...) as loop:
        memories = await loop.search(question, user_id=user_id)
        # ... LLM call ...
        await loop.log_turn(question, answer, user_id=user_id)

Use AsyncAgentLoop from agentloop.aio in asyncio code (FastAPI, aiohttp, etc.). Same API, all methods are coroutines except feedback_url() which stays sync — no network call, just HMAC.

Configuration

loop = AgentLoop(
    api_key="ak_...",                           # required
    base_url="https://...",                     # default: hosted Cloud Function
    timeout_s=10.0,                             # per-request timeout
    feedback_signing_secret="...",              # only needed for feedback_url()
    throw_on_error=False,                       # see "Graceful failures"
    http_client=my_httpx_client,                # inject custom httpx.Client
)

Base URL resolution

The base_url argument follows this priority order:

  1. Explicit base_url passed to the constructor (highest)
  2. AGENTLOOP_BASE_URL environment variable
  3. Hardcoded Cloud Function URL (fallback)

This lets you point the SDK at a local dev server, a self-hosted deployment, or a future gateway without code changes — just set AGENTLOOP_BASE_URL in the environment.

export AGENTLOOP_BASE_URL=https://api.agentloop.dev
python your_app.py  # now uses the gateway URL automatically

Four methods

search(query, *, user_id=None, limit=3, tags=None) → list[Memory]

Retrieve corrections before your LLM call. Returns [] on failure (unless throw_on_error=True).

memories = loop.search("pix limit at night", user_id="u_123", limit=5)
for m in memories:
    print(m.fact, m.score, m.tags)

log_turn(question, agent_response, *, user_id=None, session_id=None, signals=None, metadata=None) → LogTurnResponse

Queue a turn for review. Returns a default response on failure (unless throw_on_error=True).

result = loop.log_turn(
    question="What's the Pix limit?",
    agent_response="R$5,000",
    user_id="u_123",
    signals={"thumbs_down": True},
    metadata={"latency_ms": 240, "model": "gpt-4o-mini"},
)
if result.was_duplicate:
    # Backend deduplicated this turn against an existing pending one.
    # The returned turn_id points to the merged doc.
    ...

annotate(*, question, agent_response, correction, rating, ...) → AnnotateResponse

Create an annotation directly (bypass the review queue). Always throws on failure — silent degradation would hide reviewer work.

result = loop.annotate(
    question="What's the Pix limit at night?",
    agent_response="R$5,000",
    correction="Pix limit between 8pm and 6am is R$1,000.",
    rating="incorrect",
    root_cause="context",
    tags=["pix", "limits"],
    reviewer="maria@luma.com.br",
)

feedback_url(question, agent_response, *, user_id="", session_id="") → str

Generate an HMAC-signed URL for the embedded feedback widget. Requires feedback_signing_secret. Sync on both clients.

url = loop.feedback_url(question, answer, user_id="u_123")

Signatures are byte-identical to the JavaScript SDK, so URLs signed in Python validate on backends that also accept JS-signed URLs.

Graceful failures

By default, search() and log_turn() return empty/default values on failure. Agent-loop calls sit on the critical path of your agent's response; a blip shouldn't turn into a 500.

# Hard failures
from agentloop import AgentLoopError

loop = AgentLoop(api_key=..., throw_on_error=True)
try:
    memories = loop.search("...")
except AgentLoopError as e:
    print(e.status, e.body)

annotate() always raises regardless of this flag.

Context managers

Both clients support context management for clean resource cleanup:

with AgentLoop(api_key=...) as loop:
    loop.search("...")
# httpx.Client is closed on exit

async with AsyncAgentLoop(api_key=...) as loop:
    await loop.search("...")
# httpx.AsyncClient is closed on exit

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

agentloop_py-0.1.3.tar.gz (12.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

agentloop_py-0.1.3-py3-none-any.whl (12.8 kB view details)

Uploaded Python 3

File details

Details for the file agentloop_py-0.1.3.tar.gz.

File metadata

  • Download URL: agentloop_py-0.1.3.tar.gz
  • Upload date:
  • Size: 12.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for agentloop_py-0.1.3.tar.gz
Algorithm Hash digest
SHA256 10eaee97fc648fe267ff93c01e53e3b975f1c1fb1943ddfebd99c37a27b7223c
MD5 cb6e92ad477688454e2432f9beed6415
BLAKE2b-256 141da3127922629374b5cd5723fa8a9a69bb82926cd7f2947cbb50648416fb63

See more details on using hashes here.

File details

Details for the file agentloop_py-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: agentloop_py-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 12.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for agentloop_py-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 9cec81406d59f52a3770e91d80658adee50c74fc3c1e1c03fce18390cb2d324a
MD5 edd17a3b735d56806179a926ad71dac2
BLAKE2b-256 1432217123959740440bfec4e5db6b92240de25c7badef4c17725ba2557f8615

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page