ReskPoints · Documentation

Agent action logging

ReskPoints records structured “agent action” events — agent, action, probability, parameters, result, timing — masks sensitive fields, samples what matters and fans out to console, file, webhook, Datadog and Prometheus.

  • Version 0.1.3
  • Python 3.10+
  • Apache-2.0

Install

pip install reskpoints
pip install "reskpoints[datadog,prometheus,opentelemetry,webhook]"
pip install "reskpoints[all]"

Core dependencies are pyyaml, httpx and python-dotenv. Exporter SDKs are optional extras.

Quick start

from reskpoints import AgentLogger

logger = AgentLogger()   # reads ./reskpoints.yaml, falls back to defaults

results = logger.log(
    "agent-1",                     # agent_id
    "tool_call",                   # action
    0.95,                          # probability
    {"tool": "search", "api_key": "sk-abcdef1234567890"},
    "3 results",                   # result
)
print(results)          # [LogResult(success=True, platform='console', …)]
print(logger.health())  # per-platform status

Console output masks credentials by default:

[11:13:43.120] ✓ agent-1 | tool_call p=0.95 | params={"api_key": "sk****90"} | result=3 results

Decorator and async

from reskpoints import log_action

@log_action(agent_id="coder")
def execute_python(code: str) -> str:
    ...

await logger.alog("agent-1", "search", 0.95, {"q": "papers"}, "3 results")

The decorator targets synchronous functions; for async def call alog() yourself. Exceptions are logged with success=False and re-raised.

API

SymbolPurpose
AgentLogger(config=None)Loads ./reskpoints.yaml when no config/path is given.
logger.log(...) / alog(...)Build, mask, sample and dispatch an ActionLog; returns one LogResult per platform.
logger.log_action(entry)Dispatch an existing ActionLog.
logger.health()Status, queue size and last success/failure per platform.
ActionLog / LogResultDataclasses with to_dict()/from_dict() for JSONL and webhooks.
FieldMaskerField-name masking plus regex masking of long identifiers and keys.

Configuration

# reskpoints.yaml
agent_logger:
  environment: "${ENV:development}"
  masking:
    enabled: true
    sensitive_fields: [api_key, password, token, secret, authorization]
  sampling:
    default_rate: 1.0
    rules:
      - action: "heartbeat"
        rate: 0.01
      - action: "message_*"
        rate: 0.5
  platforms:
    console: {enabled: true, format: "human"}
    file: {enabled: false, path: "/var/log/resk/agent_actions.jsonl"}
    webhook:
      enabled: false
      url: "https://example.internal/events"
      signing_secret: "${WEBHOOK_SECRET}"
    prometheus: {enabled: false, pushgateway_url: "http://localhost:9091", job_name: "resk"}
    datadog: {enabled: false, api_key: "${DD_API_KEY}", site: "datadoghq.com"}

${VAR} and ${VAR:default} are interpolated recursively. There are no RESKPOINTS_* variables; pass a path to AgentLogger(path) to use another file. The YAML is a shallow merge over defaults: if you provide an agent_logger block, include the platforms block too, or nothing is enabled (see limitations).

Platforms

PlatformOutputNotes
ConsoleHuman-readable line or JSONEnabled by default
FileJSONL appended to a pathDirectory is created at construction
WebhookHTTP POST with HMAC-SHA256 signatureSSRF checks at construction; allow_private for internal endpoints
DatadogLogs API v2, ddsource=reskpointsRequires datadog-api-client
Prometheusagent_action_total pushed per eventRequires prometheus-client
OpenTelemetryOne span per event, OTLP/HTTPSelectable from YAML (platforms.opentelemetry)
# reskpoints.yaml
agent_logger:
  platforms:
    opentelemetry:
      enabled: true
      endpoint: "http://localhost:4318"
      service_name: "my-agent"

Registering a platform programmatically still works when you need a custom configuration object: logger.platforms["opentelemetry"] = OpenTelemetryPlatform({...}).

CLI

reskpoints --config reskpoints.yaml log --agent-id a1 --action tool_call   --probability 0.9 --params '{"tool":"search"}'
reskpoints status
reskpoints test
reskpoints replay events.jsonl

--config is a global option and must come before the subcommand. replay re-applies sampling and masking.

Limitations