Skip to content

Commit e13f86d

Browse files
rolanbadrislamovCocossoul
authored andcommitted
feat: add agent decorators
1 parent 552dac7 commit e13f86d

10 files changed

Lines changed: 422 additions & 0 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ The Python SDK offers a clean, type-safe API following Python best practices whi
1010

1111
### Key Features
1212

13+
- **Agent Decorators**
1314
- **AI Core Integration**
1415
- **Audit Log Service**
1516
- **Destination Service**
@@ -58,6 +59,7 @@ The SDK automatically resolves configuration from multiple sources with the foll
5859

5960
Each module has comprehensive usage guides:
6061

62+
- [Agent Decorators](src/sap_cloud_sdk/agent_decorators/user-guide.md)
6163
- [AuditLog](src/sap_cloud_sdk/core/auditlog/user-guide.md)
6264
- [Destination](src/sap_cloud_sdk/destination/user-guide.md)
6365
- [DMS](src/sap_cloud_sdk/dms/user-guide.md)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
"""SAP Cloud SDK for Python - Agent Decorators module.
2+
3+
Decorator-based configuration-as-code for SAP AI agents. Developers
4+
annotate functions with decorators to expose configuration fields
5+
(prompts, models, settings) to a low-code UI.
6+
7+
Usage:
8+
from sap_cloud_sdk.agent_decorators import (
9+
prompt_section,
10+
agent_config,
11+
agent_model,
12+
)
13+
14+
@prompt_section(
15+
key="prompts.system",
16+
label="System Prompt",
17+
description="Main system prompt for the agent",
18+
)
19+
def system_prompt() -> str:
20+
return "You are a helpful assistant."
21+
"""
22+
23+
from sap_cloud_sdk.agent_decorators.decorators import (
24+
agent_config,
25+
agent_model,
26+
prompt_section,
27+
)
28+
from sap_cloud_sdk.agent_decorators.exceptions import (
29+
AgentDecoratorError,
30+
)
31+
32+
__all__ = [
33+
# Decorators
34+
"prompt_section",
35+
"agent_config",
36+
"agent_model",
37+
# Exceptions
38+
"AgentDecoratorError",
39+
]
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
"""Decorator functions for exposing agent configuration fields.
2+
3+
Each decorator is a marker — it annotates a zero-argument function
4+
whose return value is the coded default for a configuration field.
5+
External tooling discovers these markers in source text and extracts
6+
their arguments and return values.
7+
8+
At decoration time only the *key* is validated; the function is
9+
returned unchanged.
10+
"""
11+
12+
from typing import Any, Callable, Optional
13+
14+
from .exceptions import AgentDecoratorError
15+
16+
17+
def _validate_key(key: str) -> None:
18+
"""Validate a decorator key.
19+
20+
Raises:
21+
AgentDecoratorError: If the key is empty or whitespace-only.
22+
"""
23+
if not key or not key.strip():
24+
raise AgentDecoratorError(
25+
f"Decorator key must be a non-empty string, got {key!r}"
26+
)
27+
28+
29+
def prompt_section(
30+
key: str,
31+
label: str,
32+
description: str,
33+
validation: Optional[dict[str, Any]] = None,
34+
) -> Callable:
35+
"""Expose a prompt section for editing.
36+
37+
Args:
38+
key: Unique identifier for this prompt (e.g. ``"prompts.system"``).
39+
label: Human-readable label shown in the UI.
40+
description: Help text explaining what this prompt does.
41+
validation: Optional validation rules as a dict
42+
(e.g. ``{"format": "text", "max_length": 500}``).
43+
44+
Returns:
45+
A decorator that validates the key and returns the function unchanged.
46+
47+
Raises:
48+
AgentDecoratorError: If the key is empty or whitespace-only.
49+
50+
Example::
51+
52+
@prompt_section(
53+
key="prompts.identity",
54+
label="Agent Identity",
55+
description="Core identity and role definition",
56+
validation={"format": "text", "max_length": 500},
57+
)
58+
def get_identity_prompt() -> str:
59+
return "You are an expert assistant..."
60+
"""
61+
_validate_key(key)
62+
63+
def decorator(fn: Callable[[], str]) -> Callable[[], str]:
64+
return fn
65+
66+
return decorator
67+
68+
69+
def agent_config(
70+
key: str,
71+
label: str,
72+
description: str,
73+
) -> Callable:
74+
"""Expose an agent configuration value for editing.
75+
76+
Args:
77+
key: Unique identifier (e.g. ``"config.temperature"``).
78+
label: Human-readable label.
79+
description: Help text.
80+
81+
Returns:
82+
A decorator that validates the key and returns the function unchanged.
83+
84+
Raises:
85+
AgentDecoratorError: If the key is empty or whitespace-only.
86+
87+
Example::
88+
89+
@agent_config(
90+
key="config.temperature",
91+
label="Temperature",
92+
description="The temperature setting for the language model",
93+
)
94+
def get_temperature() -> float:
95+
return 0.7
96+
"""
97+
_validate_key(key)
98+
99+
def decorator(fn: Callable) -> Callable:
100+
return fn
101+
102+
return decorator
103+
104+
105+
def agent_model(
106+
key: str,
107+
label: str,
108+
description: str = "",
109+
) -> Callable:
110+
"""Expose an agent model selection for editing.
111+
112+
Args:
113+
key: Unique identifier (e.g. ``"config.model"``).
114+
label: Human-readable label.
115+
description: Help text (optional).
116+
117+
Returns:
118+
A decorator that validates the key and returns the function unchanged.
119+
120+
Raises:
121+
AgentDecoratorError: If the key is empty or whitespace-only.
122+
123+
Example::
124+
125+
@agent_model(
126+
key="config.model",
127+
label="LLM Model",
128+
description="The language model powering this agent",
129+
)
130+
def get_model_name() -> str:
131+
return "sap/gpt-4o"
132+
"""
133+
_validate_key(key)
134+
135+
def decorator(fn: Callable) -> Callable:
136+
return fn
137+
138+
return decorator
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
"""Custom exceptions for SAP Agent Decorators."""
2+
3+
4+
class AgentDecoratorError(Exception):
5+
"""Base exception for agent decorator operations."""
6+
7+
pass

src/sap_cloud_sdk/agent_decorators/py.typed

Whitespace-only changes.
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# Agent Decorators User Guide
2+
3+
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.
4+
5+
## Installation
6+
7+
The agent decorators module is part of the Cloud SDK for Python and is automatically available when the SDK is installed.
8+
9+
## Import
10+
11+
```python
12+
from sap_cloud_sdk.agent_decorators import (
13+
prompt_section,
14+
agent_config,
15+
agent_model,
16+
)
17+
```
18+
19+
## Quick Start
20+
21+
```python
22+
from sap_cloud_sdk.agent_decorators import prompt_section, agent_model
23+
24+
# Define a prompt with a coded default
25+
@prompt_section(
26+
key="prompts.system",
27+
label="System Prompt",
28+
description="Main system prompt for the agent",
29+
)
30+
def system_prompt() -> str:
31+
return "You are a helpful assistant."
32+
33+
# Define the model selection
34+
@agent_model(key="config.model", label="LLM Model")
35+
def model_name() -> str:
36+
return "gpt-4"
37+
```
38+
39+
## Decorators
40+
41+
### @prompt_section
42+
43+
Expose a prompt section for editing.
44+
45+
```python
46+
from sap_cloud_sdk.agent_decorators import prompt_section
47+
48+
@prompt_section(
49+
key="prompts.identity",
50+
label="Agent Identity",
51+
description="Core identity and role definition",
52+
validation={"format": "text", "max_length": 500},
53+
)
54+
def identity_prompt() -> str:
55+
return "You are an expert assistant specializing in SAP systems."
56+
```
57+
58+
### @agent_config
59+
60+
Expose a configuration value for editing.
61+
62+
```python
63+
from sap_cloud_sdk.agent_decorators import agent_config
64+
65+
@agent_config(
66+
key="config.temperature",
67+
label="Temperature",
68+
description="Controls randomness (0.0 = deterministic, 1.0 = creative)",
69+
)
70+
def temperature() -> float:
71+
return 0.7
72+
```
73+
74+
### @agent_model
75+
76+
Expose a model selection. The `description` parameter is optional.
77+
78+
```python
79+
from sap_cloud_sdk.agent_decorators import agent_model
80+
81+
@agent_model(
82+
key="config.model",
83+
label="Default Model",
84+
description="The LLM model to use",
85+
)
86+
def default_model() -> str:
87+
return "gpt-4"
88+
```
89+
90+
## Error Handling
91+
92+
```python
93+
from sap_cloud_sdk.agent_decorators.exceptions import AgentDecoratorError
94+
95+
try:
96+
@prompt_section(key="", label="L", description="D")
97+
def bad():
98+
return ""
99+
except AgentDecoratorError as e:
100+
# Raised when decorator arguments are invalid (e.g. empty key)
101+
print(f"Decorator error: {e}")
102+
```

tests/agent_decorators/__init__.py

Whitespace-only changes.

tests/agent_decorators/unit/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)