# OpenAI, Anthropic, and text rendering `ContextPack` is provider neutral. Render only after selection and policy evaluation so the same pack and manifest can be inspected independently of an SDK. ## Role mapping in the 0.1 series | Cognoxium role | `to_openai()` | `to_anthropic()` | `to_text()` | | --- | --- | --- | --- | | `system` | `system` input message | Appended to top-level `system` text | `[system] ...` | | `developer` | `developer` input message | Appended to top-level `system` text | `[developer] ...` | | `user` | `user` input message | `user` message | `[user] ...` | | `assistant` | `assistant` input message | `assistant` message | `[assistant] ...` | | `tool` | `user` with `[tool result]` prefix | `user` with `[tool result]` prefix | `[tool] ...` | Tool-call IDs and provider-specific tool-result objects are not preserved in the 0.1 series. Use a custom `Renderer` when your application requires those fields. ## Inspect the generated shapes ```{testcode} import cognoxium as cx pack = cx.CognitionFrame.from_records([ {"id": "policy", "payload": "Be concise.", "role": "system", "sources": ["app://policy"], "trust": "trusted", "retention": "required", "created_at": "2026-01-01T00:00:00Z"}, {"id": "tool", "payload": "42", "role": "tool", "sources": ["tool://calculator"], "created_at": "2026-01-01T00:01:00Z"}, ]).pack(budget=100) openai_input = pack.to_openai() anthropic_input = pack.to_anthropic() print(openai_input[0]["role"], openai_input[0]["content"][0]["type"]) print(openai_input[1]["role"], openai_input[1]["content"][0]["text"]) print(anthropic_input["system"]) print(anthropic_input["messages"][0]["role"]) ``` ```{testoutput} system input_text user [tool result] 42 Be concise. user ``` `to_openai()` returns a list of input-message mappings. `to_anthropic()` returns a mapping with `system` and `messages`. Provider SDKs evolve independently; compare these shapes with the SDK version your application pins before sending a production request. ## Payload mapping - Text renders as its text value. - JSON renders as its canonical compact JSON string. - Reference renders as its URI. - Binary cannot enter a 0.1-series pack: optional/preferred items are excluded, while required items raise `UnsupportedContent`. No renderer fetches a Reference URI. Resolving, authenticating, and authorizing a reference is the host application's responsibility. ## Custom renderers Call `pack.render(renderer)`. A custom renderer receives the immutable pack and should raise `UnsupportedContent` rather than silently stringifying a payload it cannot represent. See {doc}`plugins`.