From 16ee68eaa3be7ee6345f31323f6ed1aa9bc7f452 Mon Sep 17 00:00:00 2001 From: Ben Appleby Date: Sun, 12 Apr 2026 00:03:25 -0700 Subject: [PATCH] docs: add system message customization section to Python README Document the three system message modes (append, customize, replace) in the Python SDK README, matching the coverage in the .NET README. Includes Python-specific transform callback support for the customize mode. --- python/README.md | 83 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-) diff --git a/python/README.md b/python/README.md index a023c6102..30c8c6365 100644 --- a/python/README.md +++ b/python/README.md @@ -163,7 +163,7 @@ These are passed as keyword arguments to `create_session()`: - `reasoning_effort` (str): Reasoning effort level for models that support it ("low", "medium", "high", "xhigh"). Use `list_models()` to check which models support this option. - `session_id` (str): Custom session ID - `tools` (list): Custom tools exposed to the CLI -- `system_message` (SystemMessageConfig): System message configuration +- `system_message` (SystemMessageConfig): System message configuration. See [System Message Customization](#system-message-customization) section. - `streaming` (bool): Enable streaming delta events - `provider` (ProviderConfig): Custom API provider configuration (BYOK). See [Custom Providers](#custom-providers) section. - `infinite_sessions` (InfiniteSessionConfig): Automatic context compaction configuration @@ -495,6 +495,87 @@ async with await client.create_session( > - For Azure OpenAI endpoints (`*.openai.azure.com`), you **must** use `type: "azure"`, not `type: "openai"`. > - The `base_url` should be just the host (e.g., `https://my-resource.openai.azure.com`). Do **not** include `/openai/v1` in the URL - the SDK handles path construction automatically. +## System Message Customization + +Control the system prompt using `system_message` in session config: + +```python +async with await client.create_session( + on_permission_request=PermissionHandler.approve_all, + model="gpt-5", + system_message={ + "mode": "append", + "content": """ + +- Always check for security vulnerabilities +- Suggest performance improvements when applicable + +""", + }, +) as session: + ... +``` + +### Customize Mode + +Use `mode: "customize"` to selectively override individual sections of the prompt while preserving the rest: + +```python +async with await client.create_session( + on_permission_request=PermissionHandler.approve_all, + model="gpt-5", + system_message={ + "mode": "customize", + "sections": { + "tone": {"action": "replace", "content": "Respond in a warm, professional tone. Be thorough in explanations."}, + "code_change_rules": {"action": "remove"}, + "guidelines": {"action": "append", "content": "\n* Always cite data sources"}, + }, + "content": "Focus on financial analysis and reporting.", + }, +) as session: + ... +``` + +Available section IDs: `"identity"`, `"tone"`, `"tool_efficiency"`, `"environment_context"`, `"code_change_rules"`, `"guidelines"`, `"safety"`, `"tool_instructions"`, `"custom_instructions"`, `"last_instructions"`. + +Each section override supports four string actions: `"replace"`, `"remove"`, `"append"`, and `"prepend"`. Unknown section IDs are handled gracefully: content is appended to additional instructions, and `"remove"` overrides are silently ignored. + +You can also pass a transform callback as the `action` instead of a string. The callback receives the current section content and returns the new content (sync or async): + +```python +def redact_paths(content: str) -> str: + return content.replace("/home/user", "/***") + +async with await client.create_session( + on_permission_request=PermissionHandler.approve_all, + model="gpt-5", + system_message={ + "mode": "customize", + "sections": { + "environment_context": {"action": redact_paths}, + }, + }, +) as session: + ... +``` + +### Replace Mode + +For full control (removes all SDK guardrails including security restrictions), use `mode: "replace"`: + +```python +async with await client.create_session( + on_permission_request=PermissionHandler.approve_all, + model="gpt-5", + system_message={ + "mode": "replace", + "content": "You are a helpful assistant.", + }, +) as session: + ... +``` + ## Telemetry The SDK supports OpenTelemetry for distributed tracing. Provide a `telemetry` config to enable trace export and automatic W3C Trace Context propagation.