Concepts

Data model

Executions, actions, events, and how they relate. Read this before writing non-trivial instrumentation.

Five concepts make up every integration. Understanding them individually — and how they relate — is the difference between a Klent integration that gives you audit-grade traces and one that gives you noise.

Agent

An opaque identifier you choose. Examples: support-agent, billing-agent-v2, <internal feature name>-<version>. Klent does not track agents as first-class rows; the identifier is simply recorded on each execution so you can filter on it.

Treat agent_id as stable. Rename it only when the agent's intent or tool surface changes materially — the same way you would bump a major version of an API.

Execution

A session of agent activity. One execution per user request, per cron fire, per webhook invocation, per background job — whatever the smallest unit of "the agent did something end-to-end" is for your product.

An execution has:

  • id — the correlation key you thread through your code.
  • agent_id — which agent ran.
  • statusrunning, completed, failed, or cancelled.
  • started_at / ended_at — wall-clock bounds.
  • metadata — arbitrary JSON (user ID, tenant, feature flag, trace ID).

You are responsible for creating executions. Klent does not infer them.

Action

A proposed tool or API call. Actions are not stored as rows — they are the subject of evaluateAction. The evaluation of an action produces a decision event.

Every action has:

  • A tool name — the key the LLM picked (send_email, transfer_funds, …).
  • An input payload — the arguments the LLM generated.

Evaluate every action before executing it. Evaluate actions even in systems where you do not yet have policies — the decision events give you the "intent" signal in your observability timeline for free.

Event

An append-only record on an execution's timeline. Events are immutable once written. The current event types:

TypeWho writes itMeaning
decisionYou or KlentThe agent (or the policy engine) reached a conclusion (allow / modify).
action_requestedYouThe LLM asked to call a tool.
action_executedYouA tool call finished successfully.
action_blockedKlentA policy denied an action in evaluateAction.
action_steeredKlentA steer policy redirected an action to a different tool.
pending_approvalKlentAn approve policy parked the action awaiting a human reviewer.
approval_voteKlentOne reviewer cast a vote on a pending action. Meaningful when required_approvals > 1.
approval_resolvedKlentA pending action reached its terminal state (approved or rejected).
errorYouA tool call threw or a step failed.

Klent writes the policy-engine events automatically. Everything else (action_requested, action_executed, error) is yours to log via logEvent. The runTool / runAnthropicAgent / runOpenAIAgent helpers in Auto-instrumentation emit them for you.

Policy

A rule evaluated against an action. A policy has one or more conditions (AND-ed) and one of five effects:

  • allow — let the action through (useful for short-circuiting later denies).
  • deny — block the action.
  • modify — let it through with field substitutions applied to the input.
  • approve — park the action until a human resolves it from the dashboard (HITL).
  • steer — redirect the action to a different tool entirely.

Policies are stored per project, can be enabled: false to inert them without deletion, and run in either enforce or shadow (dry-run) mode. They evaluate in creation order and the first match wins.

See Policy engine for the full semantics.

Relationships

project ─┬─ many executions ─── many events
         ├─ many policies
         ├─ many pending_actions    (rows produced by `approve` policies)
         ├─ many alert_rules ─── many webhook_deliveries
         ├─ many api_keys
         └─ many members (users with a role)

Every row in every table carries a project_id. Multi-tenancy is enforced at the SQL level — the API middleware attaches the project ID from the caller's API key to the context, and every query filters by it.

What not to log

  • LLM prompts and completions. They can be large and contain user PII. Log the shape of the interaction (tool, input keys, decision) and, if you need the full conversation, store it elsewhere keyed by execution.id.
  • Tool output bodies. Same reasoning. Store an ID or a hash.
  • Anything you would not put in an audit log. Events are immutable and exportable; treat them with the same discretion as a finance ledger.