Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/check-version-bump.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ jobs:

CHANGED_FILES=$(git diff --name-only "$BASE_SHA" "$HEAD_SHA")

if echo "$CHANGED_FILES" | grep -q "^src/"; then
if echo "$CHANGED_FILES" | grep -qE "^src/.*\.(py|pyi|proto)$"; then
BASE_VERSION=$(git show "$BASE_SHA:pyproject.toml" | grep "^version = " | cut -d'"' -f2)
HEAD_VERSION=$(git show "$HEAD_SHA:pyproject.toml" | grep "^version = " | cut -d'"' -f2)

if [ "$BASE_VERSION" = "$HEAD_VERSION" ]; then
echo "ERROR: Files under src/ were modified but the version in pyproject.toml was not bumped (still $HEAD_VERSION)."
echo "ERROR: Source files under src/ were modified but the version in pyproject.toml was not bumped (still $HEAD_VERSION)."
exit 1
fi

Expand All @@ -42,5 +42,5 @@ jobs:

echo "Version bump OK: $BASE_VERSION → $HEAD_VERSION"
else
echo "No src/ changes. Version bump not required."
echo "No source file changes under src/. Version bump not required."
fi
11 changes: 4 additions & 7 deletions .github/workflows/checks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,8 @@ jobs:
with:
python-version: ${{ env.PYTHON_VERSION }}

- name: "Run Ruff Linter"
run: uv run ruff check --output-format=github .
- name: "Install dependencies"
run: uv sync --all-extras

- name: "Run Ruff Formatter Check"
run: uv run ruff format --check --diff .

- name: "Run ty Type Check"
run: uv run ty check --output-format github --python-version ${{ env.PYTHON_VERSION }} .
- name: "Run pre-commit hooks"
run: uvx pre-commit run --all-files
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,4 @@ mocks/

# Generated files
PULL_REQUEST.md
RELEASE.md
RELEASE.md
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "sap-cloud-sdk"
version = "0.25.1"
version = "0.25.2"
description = "SAP Cloud SDK for Python"
readme = "README.md"
license = "Apache-2.0"
Expand Down
2 changes: 1 addition & 1 deletion src/sap_cloud_sdk/agent_memory/py.typed
Original file line number Diff line number Diff line change
@@ -1 +1 @@
# Marker file for PEP 561 to indicate the 'agent_memory' package is typed.
# Marker file for PEP 561 to indicate the 'agent_memory' package is typed.
2 changes: 0 additions & 2 deletions src/sap_cloud_sdk/agentgateway/user-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,5 +157,3 @@ class AgentGatewayClient:
**kwargs,
) -> str
```


2 changes: 1 addition & 1 deletion tests/agent_memory/integration/agentmemory.feature
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,4 @@ Feature: Agent Memory Service Integration (v1 API)
Scenario: Filter messages by metadata substring
Given a message exists with agent "test-agent" invoker "test-user" group "conv-filter" role "USER" content "filter-test-message" and metadata "filter-marker"
When I list messages filtered by metadata containing "filter-marker"
Then the result should contain the message with content "filter-test-message"
Then the result should contain the message with content "filter-test-message"
3 changes: 2 additions & 1 deletion tests/agent_memory/integration/test_agentmemory_bdd.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from pytest_bdd import given, scenario, then, when

from sap_cloud_sdk.agent_memory.client import AgentMemoryClient
from sap_cloud_sdk.agent_memory import MessageRole

# -- Scenarios -----------------------------------------------------------------

Expand Down Expand Up @@ -258,7 +259,7 @@ def add_message(context):
"test-agent",
"test-user",
"conv-1",
"USER",
MessageRole.USER,
"Hello!",
)

Expand Down
1 change: 1 addition & 0 deletions tests/agentgateway/integration/test_agw_bdd.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ def call_get_user_auth(context: ScenarioContext, agw_client: AgentGatewayClient)
def call_get_user_auth_callable(context: ScenarioContext, agw_client: AgentGatewayClient):
"""Call get_user_auth with a callable and store the result."""
token = context.user_token
assert token is not None
context.last_result = run(
agw_client.get_user_auth(user_token=lambda: token)
)
Expand Down
23 changes: 11 additions & 12 deletions tests/core/integration/telemetry/_agent.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,9 @@
"""LangGraph test agent used by the telemetry integration tests."""

import os
from dataclasses import dataclass
from typing import Annotated

import pytest

from langchain_core.messages import BaseMessage
from langgraph.graph.message import add_messages


@dataclass
class State:
messages: Annotated[list[BaseMessage], add_messages]


def build_langgraph_agent():
"""Build a minimal single-node LangGraph agent backed by LiteLLM via AI Core.
Expand All @@ -23,11 +13,20 @@ def build_langgraph_agent():
"sap/<model>" prefix to route through the SAP AI Core provider.
"""
try:
from langchain_litellm import ChatLiteLLM
from langgraph.graph import END, StateGraph
from dataclasses import dataclass
from typing import Annotated

from langchain_core.messages import BaseMessage
from langchain_litellm import ChatLiteLLM # ty: ignore[unresolved-import]
from langgraph.graph import END, StateGraph # ty: ignore[unresolved-import]
from langgraph.graph.message import add_messages # ty: ignore[unresolved-import]
except ImportError:
pytest.skip("langchain-litellm or langgraph not installed")

@dataclass
class State:
messages: Annotated[list[BaseMessage], add_messages]

model_name = os.environ.get("AICORE_MODEL") or "anthropic--claude-4.5-sonnet"
llm = ChatLiteLLM(model=f"sap/{model_name}")

Expand Down
2 changes: 1 addition & 1 deletion tests/core/integration/telemetry/test_telemetry_bdd.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ def _llm_call():
Uses ChatLiteLLM so Traceloop's LangChain instrumentor fires and emits a span
with gen_ai.usage.* token counts.
"""
from langchain_litellm import ChatLiteLLM
from langchain_litellm import ChatLiteLLM # ty: ignore[unresolved-import]
from langchain_core.messages import HumanMessage as LCHumanMessage
model_name = os.environ.get("AICORE_MODEL", "anthropic--claude-4.5-sonnet")
llm = ChatLiteLLM(model=f"sap/{model_name}")
Expand Down
3 changes: 2 additions & 1 deletion tests/core/unit/data_anonymization/test_http_transport.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Unit tests for the HTTP transport."""

import base64
from collections.abc import Mapping
from pathlib import Path
import importlib
import types
Expand Down Expand Up @@ -55,7 +56,7 @@ def __init__(
self.status_code = status_code
self._json_data = json_data
self.text = text
self.headers = headers or {}
self.headers: Mapping[str, str] = headers or {}
self.content = content

def json(self):
Expand Down
1 change: 0 additions & 1 deletion tests/destination/integration/destination.feature
Original file line number Diff line number Diff line change
Expand Up @@ -316,4 +316,3 @@ Feature: Destination Service Integration
# Then the destination creation should be successful
# When I get subaccount destination "test-dest-sub-isolation" with "PROVIDER_ONLY" access strategy
# Then the destination should not be found

2 changes: 1 addition & 1 deletion tests/dms/integration/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def dms_client():
client = create_client(instance="default")
return client
except Exception as e:
pytest.skip(f"DMS integration tests require credentials: {e}") # ty: ignore[invalid-argument-type, too-many-positional-arguments]
pytest.skip(f"DMS integration tests require credentials: {e}")


def _setup_cloud_mode():
Expand Down
2 changes: 1 addition & 1 deletion tests/dms/integration/test_dms_bdd.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def select_version_repo(context: DMSTestContext, dms_client: DMSClient):
version_repo = r
break
if version_repo is None:
pytest.skip("No version-enabled repository available") # ty: ignore[invalid-argument-type, too-many-positional-arguments]
pytest.skip("No version-enabled repository available")
context.repo = version_repo
context.repo_id = version_repo.id

Expand Down
1 change: 0 additions & 1 deletion tests/extensibility/unit/test_ums_caching.py
Original file line number Diff line number Diff line change
Expand Up @@ -334,4 +334,3 @@ def test_cache_hit_refreshes_lru_position(self):
assert ("tenant-new", "default") in transport._cache
finally:
patcher.stop()

1 change: 0 additions & 1 deletion tests/extensibility/unit/test_ums_pagination.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,4 +340,3 @@ def test_missing_page_info_stops_pagination(self):
def test_max_pages_constant(self):
"""Safety limit constant is 100."""
assert _MAX_PAGES == 100

1 change: 0 additions & 1 deletion tests/extensibility/unit/test_ums_parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -459,4 +459,3 @@ def test_tools_key_missing(self):
}
result = _transform_ums_response(data, "default")
assert result.mcp_servers == []

Loading