#Making a plugin, is it possible to rewrite user's messages before sending it to AI providers?

1 messages · Page 1 of 1 (latest)

thorn sequoia
#

Just a thought for @slender marten, does the current plugin SDK allow rewriting user messages before sending it to AI providers? I want to pair it with Microsoft Presidio so that the session stays PII free but still having SOTA intelligence.

thorny pumiceBOT
#

To help others find answers, you can mark your question as solved via Right click solution message -> Apps -> âś… Mark Solution

slender martenBOT
#

Short answer: partially, but not quite in the Presidio-shaped way yet.

I checked current docs/source. The plugin SDK does have api.registerTextTransforms({ input, output }): input rewrites the final system prompt + text message content before provider/CLI transport, and output rewrites assistant text before OpenClaw consumes/delivers it.

But that surface is just deterministic string | RegExp -> string replacements. It is not an async “call Presidio, rewrite this turn, continue with the normal model path” hook.

The nearby hooks don’t quite solve it either:

  • llm_input is observe-only.
  • message_received is fire-and-forget observe-only.
  • before_dispatch can intercept/handle a message, but not return “continue with this rewritten user message”.
  • before_message_write can mutate/block persisted session messages, but it’s sync-only — awkward for Presidio unless you already have the mapping locally.

So for “provider never sees PII”, static transforms can work for simple cases. For “session stays PII-free using Presidio”, I’d call that a missing first-class SDK seam: probably an async pre-dispatch/pre-provider sanitization hook that can mutate the user message before persistence + provider transport, with optional output de-anonymization if desired.

Docs I’d start from: https://docs.openclaw.ai/plugins/building-plugins and https://docs.openclaw.ai/plugins/sdk-provider-plugins

This is a good feature-request shape for GitHub: https://github.com/openclaw/openclaw/issues 🦞

thorn sequoia
#

Is the alternative be creating a custom provider plugin + custom ai proxy that filters out things before sending to upstream...? I mean I can do that, and if I can also add in image generation to be 1:1 with openai/openai-codex, that'll be great too.

LiteLLM is too heavy for me. What do you think Krill?

slender martenBOT
#

Yeah — if you want this today, I’d do the custom provider/proxy path. It’s not the prettiest seam, but it’s the cleanest one you control.

My take:

  1. Lightweight proxy is reasonable
    Make an OpenAI/Codex-ish proxy that accepts OpenClaw’s provider request, runs Presidio/anonymization, forwards upstream, then optionally de-anonymizes the assistant response. That’s way lighter than LiteLLM if you only need one or two upstreams.

  2. Wrap it as an OpenClaw provider plugin
    Register a new provider id, e.g. pii-openai / redacted-openai, and have the plugin point at your proxy. That keeps OpenClaw config clean and avoids pretending you are the built-in provider.

  3. But be careful about “session stays PII-free”
    A provider/proxy can ensure the upstream AI provider doesn’t see raw PII.
    It does not automatically mean OpenClaw’s local session JSONL/history is PII-free, because the raw inbound message may already be persisted/used before the provider request depending on path.

    For true “local session is PII-free too”, you also want a persistence-side strategy: probably before_message_write to rewrite/block stored messages. Current catch: that hook is sync-only, so Presidio-over-HTTP is awkward unless you do the Presidio work earlier and keep a local mapping/cache.

  4. Image generation can be part of the same plugin

#

The SDK does expose registerImageGenerationProvider(...), and the built-in OpenAI plugin uses that route. So your plugin can register both:

  • text/model provider
  • image generation provider

That gets you much closer to “one redacted provider namespace that covers chat + image gen”.

The architecture I’d choose:

  • OpenClaw plugin registers redacted-openai/*
  • Plugin talks only to your tiny local proxy
  • Proxy does Presidio anonymize → upstream call → optional deanonymize
  • Plugin also registers image generation provider and routes image prompts/reference metadata through the same redaction policy
  • Add a before_message_write hook only if you need local OpenClaw sessions to be scrubbed too

The one thing I would not do is try to clone all of LiteLLM. Keep it boring: one proxy, one upstream family, explicit supported endpoints. Boring is good here. 🦞

Relevant docs:

thorn sequoia
#

I just want upstream to not see PII, and local can store PII whatever it wants to.