Condukt.Redactor behaviour (Condukt v0.16.5)

Copy Markdown View Source

Behaviour for redacting sensitive data before it is sent to an LLM provider.

A redactor is invoked on outbound message text — user input and tool results — right before the conversation is handed to the LLM. Assistant output and the system prompt are left untouched: the LLM has already seen its own prior responses, and the system prompt is authored by the developer.

Redactors are configured per session at start_link/1 via the :redactor option. The value can be a module or a {module, opts} tuple. When nil (the default), no redaction is performed.

MyApp.Agent.start_link(redactor: Condukt.Redactors.Regex)

MyApp.Agent.start_link(redactor: {Condukt.Redactors.Regex, patterns: my_patterns})

Implementing a redactor

defmodule MyApp.Redactor do
  @behaviour Condukt.Redactor

  @impl true
  def redact(text, _opts) do
    String.replace(text, ~r/\bsecret-[a-z0-9]+\b/, "[REDACTED]")
  end
end

Redaction in this version is outbound-only: the original text remains in the session's stored history. Each turn re-runs the redactor on the messages that are about to be sent, so secrets never leave the BEAM process.

Summary

Callbacks

Returns text with sensitive substrings replaced.

Functions

Applies a redactor spec to a single string.

Returns messages with redaction applied to user input and tool results.

Callbacks

redact(text, opts)

@callback redact(text :: String.t(), opts :: keyword()) :: String.t()

Returns text with sensitive substrings replaced.

opts is the keyword list provided alongside the module in a {module, opts} spec, or [] when the spec is a bare module.

Functions

apply(module, text)

Applies a redactor spec to a single string.

The spec is a module implementing the behaviour, a {module, opts} tuple, a list of redactor specs, or nil. Returns text unchanged when spec is nil or an empty list.

redact_messages(spec, messages)

Returns messages with redaction applied to user input and tool results.

Assistant messages and any non-textual content blocks are returned unchanged. Tool result content that is not a binary is JSON-encoded before redaction so embedded secrets in structured output are still caught.