AgentOS takes metadata.sdk from agent_data.sdk, which Agno's BaseExternalAgent already writes on every session it creates, and lays it over the response when you read the session. Nothing new is stored. Sessions from earlier releases get the label with no migration, records that still use the older agent_data.framework key are read too, and the metadata in your database stays exactly as you saved it.

Runs don't record their SDK, so the run reads take it from the parent session, and RunSchema gains a metadata field to carry it. That field also returns what the run stored, such as the attempt count of a retried run.
# real output: each run's metadata from GET /sessions/claude-session/runs, after a ClaudeAgent run that retried once (stand-in Claude SDK)
[{"attempts": 2, "sdk": "claude-agent-sdk"}]Native agent sessions get no sdk key, and team and workflow sessions return their metadata as before. If you stored your own metadata["sdk"] on an external agent's session, the response shows the adapter's value and your stored value stays in the database. GET /agents/{agent_id}/runs does not carry the label yet.
See the cookbook, and learn more about identifying the harness and model in the documentation.
Frequently asked questions
Read metadata.sdk on GET /sessions, GET /sessions/{session_id} or GET /sessions/{session_id}/runs. CodexAgent sessions carry "codex" and ClaudeAgent sessions carry "claude-agent-sdk". A native agent session has no sdk key.
No. AgentOS builds the label at read time from the agent_data that external agents already save with each session, including the older agent_data.framework key, and leaves the stored metadata untouched.
Whatever metadata the run stored. For a ClaudeAgent or CodexAgent run that was retried, that includes attempts, plus any warnings the run recorded.
No. AgentOS only adds the label to agent sessions, and a member run whose agent_id differs from the session's agent does not inherit it.



