Skip to content

Releases: SAP/cloud-sdk-python

v0.36.0 - Jul 16, 2026

Choose a tag to compare

@cassiofariasmachado cassiofariasmachado released this 16 Jul 18:53
eb6648d

What's New

  • Agent Memory multitenancy (sap_cloud_sdk.agent_memory): per-tenant binding support — the runtime provisions one dedicated service instance per tenant and mounts it at /etc/secrets/appfnd/hana-agent-memory/<tenant-subdomain>/. Each AgentMemoryClient loads credentials from the correct binding at construction time.
    • AccessStrategy enum with two values: SUBSCRIBER (default) and PROVIDER. Configured once at create_client() — not per individual method call.
    • create_client(access_strategy=..., tenant=...)SUBSCRIBER with tenant="acme-corp" loads the subscriber binding; PROVIDER loads the default binding.
    • _load_config_for_instance(instance) in config.py — loads any named binding instance from /etc/secrets/appfnd/hana-agent-memory/<instance>/ or CLOUD_SDK_CFG_HANA_AGENT_MEMORY_<INSTANCE>_* env vars.
    • Simplified AgentMemoryClient: single _transport field; strategy and tenant validated at construction; no per-call overrides on individual methods.
    • logger.warning() emitted at construction when AccessStrategy.PROVIDER is used, surfacing the no-isolation risk.

Breaking Changes

⚠️ Important: Existing calls to create_client() with no args will raise AgentMemoryValidationError — the default strategy is SUBSCRIBER and requires a tenant. Individual methods no longer accept access_strategy or tenant parameters.

Migration:

# Before
client = create_client()
client.list_memories(agent_id="x", invoker_id="u")

# After — subscriber (bindings provisioned per tenant at runtime)
client = create_client(tenant="my-subdomain")
client.list_memories(agent_id="x", invoker_id="u")

# After — provider (no tenant isolation, emits logger.warning)
client = create_client(access_strategy=AccessStrategy.PROVIDER)
client.list_memories(agent_id="x", invoker_id="u")

Contributors

v0.35.0 - Jul 13, 2026

Choose a tag to compare

@LucasAlvesSoares LucasAlvesSoares released this 13 Jul 14:46
d35af86

What's New

  • sap.service.display_name resource attribute: the SDK now reads SAP_SERVICE_DISPLAY_NAME from the environment and adds it to resource attributes. Omitted when the variable is unset or empty

Contributors

v0.34.0 - Jul 13, 2026

Choose a tag to compare

@cassiofariasmachado cassiofariasmachado released this 13 Jul 14:04
26d90d5

What's New

  • LangGraph checkpointer factory (sap_cloud_sdk.agent_memory.factory.langgraph_checkpoint): new create_checkpointer() function returns a LangGraph BaseCheckpointSaver for short-term session memory in LangGraph and LangChain agents.
    • create_checkpointer() — returns InMemorySaver (plain in-memory, no eviction).
    • create_checkpointer(ttl_seconds=N) — returns TimedInMemorySaver, which evicts threads inactive for longer than N seconds via a background daemon sweep (60 s interval).
    • Raises ImportError with an actionable install message (pip install "sap-cloud-sdk[langgraph]") when langgraph is not installed.
  • New optional dependency group langgraph: pip install "sap-cloud-sdk[langgraph]" pulls in langgraph>=1.0.0.

Improvements

  • Agent Memory user guide expanded with a dedicated LangGraph Checkpointer section covering: prerequisites, import path, usage with StateGraph.compile(), usage with LangChain create_agent(), thread TTL configuration, and exposing TTL as an operator-adjustable field via @agent_config.

Contributors

v0.33.2 - July 09, 2026

Choose a tag to compare

@jplbrun jplbrun released this 09 Jul 14:41
05be4e4

Improvements

Internal cross-module SDK calls are now correctly attributed in usage metrics. When one module calls another under the hood (e.g. Agent Gateway resolving destinations, or Extensibility/Audit Log/Data Anonymization reading destination config), the emitted sap.cloud_sdk.source attribute is now set to the calling module instead of user-facing — so internal usage is no longer double-counted as direct customer activity.

Contributors

  • Application Foundation Toolkit Libraries Team

v0.33.1 - July 07, 2026

Choose a tag to compare

@LucasAlvesSoares LucasAlvesSoares released this 07 Jul 20:59
c232dc0

Bug Fixes

Replaced opentelemetry-processor-baggage with built-in BaggageSpanProcessor that snapshots baggage override keys at on_start and re-applies them at on_end, after framework callbacks have run. opentelemetry-processor-baggage has been removed as a dependency. As a result, Traceloop no longer overrides keys such as gen_ai.conversation.id.

Contributors

v0.33.0 - July 06, 2026

Choose a tag to compare

@NicoleMGomes NicoleMGomes released this 06 Jul 16:07
d19427f

What's New

  • DestinationClient.get_service_instance_id(): new method that reads the destination service instance ID from mounted secrets (/etc/secrets/appfnd/destination/default/instanceid) with env var fallback (CLOUD_SDK_CFG_DESTINATION_DEFAULT_INSTANCEID). Instrumented with Operation.DESTINATION_GET_SERVICE_INSTANCE_ID telemetry.
  • AgentGatewayClient.get_ias_client_id(): new method that returns the IAS client ID. Auto-detects agent type — Customer agents read client_id from the mounted credentials file; LoB agents fetch the sap-managed-runtime-ias-{landscape} destination and return the clientId property. Instrumented with Operation.AGENTGATEWAY_GET_IAS_CLIENT_ID telemetry.
  • ConsumptionOptions.skip_token_retrieval: new boolean field (default False). When True, passes $skipTokenRetrieval=true to the Destination Service v2 API, skipping the OAuth2 token exchange and returning only destination configuration properties.

Contributors

@NicoleMGomes

v0.32.1 - July 06, 2026

Choose a tag to compare

@NicoleMGomes NicoleMGomes released this 06 Jul 12:10
2b64465

Bug Fixes

  • mcp_tool_to_langchain type coercion (agentgateway/converters.py): The Pydantic
    args schema generated for LangChain tools now uses the correct Python type for each
    field instead of hard-coding str for everything.

    Previously, every property in input_schema was mapped to str (or str | None),
    regardless of its declared JSON Schema "type". This caused Pydantic to silently coerce
    non-string LLM arguments — e.g. limit=10"10", active=True"True"
    before forwarding them to call_tool. MCP servers expecting native JSON types then
    rejected the call.

    The mapping is now:

    JSON Schema type Python type
    "string" str
    "integer" int
    "number" float
    "boolean" bool
    "array" list
    "object" dict
    missing / other Any

    Optional fields (absent from "required") are typed as T | None with a None
    default, as before.

Contributors

v0.32.0 - June 30, 2026

Choose a tag to compare

@NicoleMGomes NicoleMGomes released this 30 Jun 17:52
6c042e1

What's New

  • Content filtering and Prompt Shield module (sap_cloud_sdk.aicore.filtering): New subpackage that applies SAP AI Core Orchestration v2 content filtering to every sap/* LiteLLM model call. Filtering is enabled by default when set_aicore_config() is called.

    New public types:

    • Severity — Azure Content Safety threshold enum (STRICT=0, LOW=2, MEDIUM=4, OFF=6).
    • AzureContentFilter — configures per-category thresholds (hate, violence, sexual, self_harm) plus optional prompt_shield (jailbreak + indirect-injection detection).
    • LlamaGuard38bFilter — opt-in Llama Guard 3 8B filter with per-category boolean toggles.
    • ContentFilter — abstract base for custom provider implementations.
    • InputFiltering / OutputFiltering — direction-specific filter stacks.
    • ContentFiltering — top-level configuration container passed to set_filtering().

    New exception types:

    • ContentFilteredError — raised when a filter blocks input or output; exposes direction ("input" or "output"), details (severity scores), and request_id.
    • OrchestrationError — base class for all orchestration-module errors.
  • set_filtering(config?) and disable_filtering() (sap_cloud_sdk.aicore): New public functions to install or remove a ContentFiltering configuration at runtime. set_filtering() with no argument re-applies env-var-driven defaults.

  • completion() and acompletion() (sap_cloud_sdk.aicore): Thin sync/async wrappers around litellm.completion / litellm.acompletion that normalise input-filter rejections (HTTP 400) and output-filter rejections (finish_reason="content_filter") into a single ContentFilteredError type, so callers need only one except clause.

  • set_aicore_config() now auto-activates filtering: After loading credentials, set_aicore_config() automatically calls set_filtering() to install filtering at Severity.MEDIUM on all categories with Prompt Shield enabled. Set AICORE_FILTER_ENABLED=false before calling set_aicore_config() to opt out.

Contributors

v0.31.0 - June 29, 2026

Choose a tag to compare

@NicoleMGomes NicoleMGomes released this 29 Jun 13:52
2a20efb

What's New

  • ExtensibilityClient.call_hook_agw() (extensibility/client.py): New async method
    that invokes extensibility hooks via the Agent Gateway MCP tool interface instead of
    direct HTTP. Auth and endpoint resolution are handled internally — no manual URL or token
    configuration is required.

    result = await client.call_hook_agw(
        hook=hook,
        user_token="my-user-token",
        message=my_message,
        tenant_subdomain="my-tenant",
    )

    The method discovers the n8n execute_workflow and get_execution MCP tools via AGW,
    triggers the workflow, then polls every 500 ms until completion or timeout.

Improvements

  • Error hierarchy clarification (extensibility/client.py): TransportError is now
    raised strictly for network-level failures (HTTP errors, response decode errors). All
    workflow-level failures — terminal execution status, timeout, n8n JSON-RPC errors,
    isError results, and no-content responses — now consistently raise ExtensibilityError.

  • extensibility user-guide (extensibility/user-guide.md): Updated with
    call_hook_agw() reference, AGW usage example, and the updated exception hierarchy.

Contributors

v0.30.0 - June 29, 2026

Choose a tag to compare

@NicoleMGomes NicoleMGomes released this 29 Jun 12:53
2c8f6ae

What's New

  • A2A agent card discovery (agentgateway module): new AgentGatewayClient.list_agent_cards() method discovers A2A agents registered via BTP Destination Service fragments (label agw.a2a.server) and fetches each agent's card from {fragment_url}/.well-known/agent-card.json.

  • AgentCard dataclass: holds the full parsed JSON payload returned by the agent card endpoint (raw: dict).

  • Agent dataclass: represents a discovered A2A agent with ord_id: str (from the fragment's ordId property) and agent_card: AgentCard.

  • AgentCardFilter dataclass: optional filter for list_agent_cards. Accepts agent_names (matched against the name field in the fetched agent card JSON, applied post-fetch) and ord_ids (extracted from the fragment URL, applied pre-fetch) — both default to empty lists (no filter). Filters are applied with AND semantics.

Improvements

  • _fragments.py (new internal module): centralises all BTP Destination Service fragment operations previously spread across _lob.py. Exports list_mcp_fragments, list_a2a_fragments, get_ias_fragment_name, get_ias_user_fragment_name, and label constants (LABEL_KEY, MCP_LABEL_VALUE, IAS_LABEL_VALUE, IAS_USER_LABEL_VALUE, A2A_LABEL_VALUE).

Contributors