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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ The Python SDK offers a clean, type-safe API following Python best practices whi

### Key Features

- **Agent Decorators**
- **AI Core Integration**
- **Audit Log Service**
- **Destination Service**
Expand Down Expand Up @@ -58,6 +59,7 @@ The SDK automatically resolves configuration from multiple sources with the foll

Each module has comprehensive usage guides:

- [Agent Decorators](src/sap_cloud_sdk/agent_decorators/user-guide.md)
- [AuditLog](src/sap_cloud_sdk/core/auditlog/user-guide.md)
- [Destination](src/sap_cloud_sdk/destination/user-guide.md)
- [DMS](src/sap_cloud_sdk/dms/user-guide.md)
Expand Down
39 changes: 39 additions & 0 deletions src/sap_cloud_sdk/agent_decorators/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"""SAP Cloud SDK for Python - Agent Decorators module.

Decorator-based configuration-as-code for SAP AI agents. Developers
annotate functions with decorators to expose configuration fields
(prompts, models, settings) to a low-code UI.

Usage:
from sap_cloud_sdk.agent_decorators import (
prompt_section,
agent_config,
agent_model,
)

@prompt_section(
key="prompts.system",
label="System Prompt",
description="Main system prompt for the agent",
)
def system_prompt() -> str:
return "You are a helpful assistant."
"""

from sap_cloud_sdk.agent_decorators.decorators import (
agent_config,
agent_model,
prompt_section,
)
from sap_cloud_sdk.agent_decorators.exceptions import (
AgentDecoratorError,
)

__all__ = [
# Decorators
"prompt_section",
"agent_config",
"agent_model",
# Exceptions
"AgentDecoratorError",
]
138 changes: 138 additions & 0 deletions src/sap_cloud_sdk/agent_decorators/decorators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
"""Decorator functions for exposing agent configuration fields.

Each decorator is a marker — it annotates a zero-argument function
whose return value is the coded default for a configuration field.
External tooling discovers these markers in source text and extracts
their arguments and return values.

At decoration time only the *key* is validated; the function is
returned unchanged.
"""

from typing import Any, Callable, Optional

from .exceptions import AgentDecoratorError


def _validate_key(key: str) -> None:
"""Validate a decorator key.

Raises:
AgentDecoratorError: If the key is empty or whitespace-only.
"""
if not key or not key.strip():
raise AgentDecoratorError(
f"Decorator key must be a non-empty string, got {key!r}"
)


def prompt_section(
key: str,
label: str,
description: str,
validation: Optional[dict[str, Any]] = None,
) -> Callable:
"""Expose a prompt section for editing.

Args:
key: Unique identifier for this prompt (e.g. ``"prompts.system"``).
label: Human-readable label shown in the UI.
description: Help text explaining what this prompt does.
validation: Optional validation rules as a dict
(e.g. ``{"format": "text", "max_length": 500}``).

Returns:
A decorator that validates the key and returns the function unchanged.

Raises:
AgentDecoratorError: If the key is empty or whitespace-only.

Example::

@prompt_section(
key="prompts.identity",
label="Agent Identity",
description="Core identity and role definition",
validation={"format": "text", "max_length": 500},
)
def get_identity_prompt() -> str:
return "You are an expert assistant..."
"""
_validate_key(key)

def decorator(fn: Callable[[], str]) -> Callable[[], str]:
return fn

return decorator


def agent_config(
key: str,
label: str,
description: str,
) -> Callable:
"""Expose an agent configuration value for editing.

Args:
key: Unique identifier (e.g. ``"config.temperature"``).
label: Human-readable label.
description: Help text.

Returns:
A decorator that validates the key and returns the function unchanged.

Raises:
AgentDecoratorError: If the key is empty or whitespace-only.

Example::

@agent_config(
key="config.temperature",
label="Temperature",
description="The temperature setting for the language model",
)
def get_temperature() -> float:
return 0.7
"""
_validate_key(key)

def decorator(fn: Callable) -> Callable:
return fn

return decorator


def agent_model(
key: str,
label: str,
description: str = "",
) -> Callable:
"""Expose an agent model selection for editing.

Args:
key: Unique identifier (e.g. ``"config.model"``).
label: Human-readable label.
description: Help text (optional).

Returns:
A decorator that validates the key and returns the function unchanged.

Raises:
AgentDecoratorError: If the key is empty or whitespace-only.

Example::

@agent_model(
key="config.model",
label="LLM Model",
description="The language model powering this agent",
)
def get_model_name() -> str:
return "sap/gpt-4o"
"""
_validate_key(key)

def decorator(fn: Callable) -> Callable:
return fn

return decorator
7 changes: 7 additions & 0 deletions src/sap_cloud_sdk/agent_decorators/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
"""Custom exceptions for SAP Agent Decorators."""


class AgentDecoratorError(Exception):
"""Base exception for agent decorator operations."""

pass
Empty file.
102 changes: 102 additions & 0 deletions src/sap_cloud_sdk/agent_decorators/user-guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# Agent Decorators User Guide

This module provides a decorator-based configuration-as-code system for SAP AI agents. Developers annotate functions with decorators to expose configuration fields — prompts, model selections, and agent settings — to a low-code UI. External tooling discovers these markers in source text and extracts their arguments and return values.

## Installation

The agent decorators module is part of the Cloud SDK for Python and is automatically available when the SDK is installed.

## Import

```python
from sap_cloud_sdk.agent_decorators import (
prompt_section,
agent_config,
agent_model,
)
```

## Quick Start

```python
from sap_cloud_sdk.agent_decorators import prompt_section, agent_model

# Define a prompt with a coded default
@prompt_section(
key="prompts.system",
label="System Prompt",
description="Main system prompt for the agent",
)
def system_prompt() -> str:
return "You are a helpful assistant."

# Define the model selection
@agent_model(key="config.model", label="LLM Model")
def model_name() -> str:
return "gpt-4"
```

## Decorators

### @prompt_section

Expose a prompt section for editing.

```python
from sap_cloud_sdk.agent_decorators import prompt_section

@prompt_section(
key="prompts.identity",
label="Agent Identity",
description="Core identity and role definition",
validation={"format": "text", "max_length": 500},
)
def identity_prompt() -> str:
return "You are an expert assistant specializing in SAP systems."
```

### @agent_config

Expose a configuration value for editing.

```python
from sap_cloud_sdk.agent_decorators import agent_config

@agent_config(
key="config.temperature",
label="Temperature",
description="Controls randomness (0.0 = deterministic, 1.0 = creative)",
)
def temperature() -> float:
return 0.7
```

### @agent_model

Expose a model selection. The `description` parameter is optional.

```python
from sap_cloud_sdk.agent_decorators import agent_model

@agent_model(
key="config.model",
label="Default Model",
description="The LLM model to use",
)
def default_model() -> str:
return "gpt-4"
```

## Error Handling

```python
from sap_cloud_sdk.agent_decorators.exceptions import AgentDecoratorError

try:
@prompt_section(key="", label="L", description="D")
def bad():
return ""
except AgentDecoratorError as e:
# Raised when decorator arguments are invalid (e.g. empty key)
print(f"Decorator error: {e}")
```
Empty file.
Empty file.
Loading
Loading