Nothing on the wire said which Mem0 surface made a call. Both SDKs sent only an
auth header, so the platform saw python-httpx and axios and attributed every
plugin, wrapper and direct API user to one undifferentiated bucket. Version was
unknowable, which is what gates every deprecation decision.
Three headers, and the rules on them are the point:
- X-Mem0-Source and X-Application are SET-ONCE. Whichever layer is outermost
sets them; nothing below overwrites. A plugin wrapping the SDK keeps its own
identity instead of being renamed by the transport underneath it.
- X-Mem0-Client is APPEND-ONLY. A plugin calling the Python SDK produces
`mem0-plugin/0.3.1, mem0-python/2.0.19`, so neither layer can erase the other.
Deliberately not User-Agent: proxies rewrite it, and we have already met a WAF
that 403s on it.
The plugin core also hoists `source` out of metadata to the top level, which is
where the backend actually reads it. It sat in metadata, which get_event_source
never consults, so all six plugins arrived indistinguishable from a raw SDK call
no matter what they set. The harness tag stays in metadata as hook provenance.
pi-agent had PI_AGENT as a PostHog property only and never sent it on the wire.
vercel-ai-sdk sent nothing at all from its raw fetch calls.
Values must exist in the platform's EventSource enum or they bucket to OTHERS,
so integrations/AGENTS.md now states the contract and the "adding an
integration" checklist requires landing the platform value in the same week.
Pairs with mem0ai/platform#3602, which recognizes these values.
TypeScript changes are not typechecked locally — deps are not installed for
those packages. CI covers them.
Claude-Session: https://claude.ai/code/session_01C7tEmH86HAr7GoAAKCEHZb