Skip to content

Commit cbe01bd

Browse files
Copilotphrocker
andcommitted
Complete Python agent implementation with full API integration
Co-authored-by: phrocker <1781585+phrocker@users.noreply.github.com>
1 parent 55efc8c commit cbe01bd

28 files changed

Lines changed: 1530 additions & 40 deletions

python-agent/README.md

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
# Sentrius Python Agent
2+
3+
This Python agent provides the same APIs and operations as the Java agent, enabling integration with the Sentrius platform for authentication, registration, heartbeat monitoring, and provenance event submission.
4+
5+
## Features
6+
7+
- **Keycloak Integration**: Full authentication support using Keycloak JWT tokens
8+
- **Agent Registration**: Automatic registration with the Sentrius API server
9+
- **Heartbeat Monitoring**: Continuous heartbeat mechanism to maintain connection
10+
- **Provenance Events**: Submit detailed provenance events for audit trails
11+
- **RSA Encryption**: Secure communication using ephemeral RSA keys
12+
- **Configurable**: Support for both YAML configuration files and environment variables
13+
- **Extensible**: Base agent framework for creating custom agents
14+
15+
## Architecture
16+
17+
The Python agent mirrors the Java agent architecture with these key components:
18+
19+
### Services
20+
- **KeycloakService**: Handles authentication and token management
21+
- **AgentClientService**: Manages API communication with Sentrius server
22+
- **EphemeralKeyGen**: RSA key generation and cryptographic operations
23+
- **SentriusAgent**: Main agent framework coordinating all services
24+
25+
### Agent Framework
26+
- **BaseAgent**: Abstract base class for all agents
27+
- **SQLAgent**: Example implementation for SQL operations
28+
29+
## Configuration
30+
31+
### YAML Configuration
32+
```yaml
33+
keycloak:
34+
server_url: "http://localhost:8080"
35+
realm: "sentrius"
36+
client_id: "python-agent"
37+
client_secret: "your-client-secret"
38+
39+
agent:
40+
name_prefix: "python-agent"
41+
agent_type: "python"
42+
callback_url: "http://localhost:8081"
43+
api_url: "http://localhost:8080"
44+
heartbeat_interval: 30
45+
46+
llm:
47+
enabled: false
48+
provider: "openai"
49+
model: "gpt-3.5-turbo"
50+
api_key: null
51+
endpoint: null
52+
```
53+
54+
### Environment Variables
55+
```bash
56+
KEYCLOAK_SERVER_URL=http://localhost:8080
57+
KEYCLOAK_REALM=sentrius
58+
KEYCLOAK_CLIENT_ID=python-agent
59+
KEYCLOAK_CLIENT_SECRET=your-client-secret
60+
AGENT_NAME_PREFIX=python-agent
61+
AGENT_API_URL=http://localhost:8080
62+
AGENT_CALLBACK_URL=http://localhost:8081
63+
AGENT_HEARTBEAT_INTERVAL=30
64+
```
65+
66+
## Usage
67+
68+
### Running the SQL Agent
69+
```bash
70+
# With configuration file
71+
python main.py sql_agent --config config.yaml
72+
73+
# With default configuration (uses environment variables)
74+
python main.py sql_agent
75+
```
76+
77+
### Creating Custom Agents
78+
```python
79+
from agents.base import BaseAgent
80+
81+
class MyCustomAgent(BaseAgent):
82+
def __init__(self, config_path=None):
83+
super().__init__("My Custom Agent", config_path=config_path)
84+
85+
def execute_task(self):
86+
# Your custom agent logic here
87+
self.submit_provenance(
88+
event_type="CUSTOM_TASK",
89+
details={"task": "custom_operation"}
90+
)
91+
```
92+
93+
## API Operations
94+
95+
The Python agent supports all the same API operations as the Java agent:
96+
97+
### Agent Registration
98+
- **Endpoint**: `POST /api/v1/agent/register`
99+
- **Purpose**: Register the agent with the Sentrius API server
100+
- **Authentication**: Keycloak JWT token required
101+
102+
### Heartbeat
103+
- **Endpoint**: `POST /api/v1/agent/heartbeat`
104+
- **Purpose**: Send periodic status updates to maintain connection
105+
- **Frequency**: Configurable (default: 30 seconds)
106+
107+
### Provenance Submission
108+
- **Endpoint**: `POST /api/v1/agent/provenance/submit`
109+
- **Purpose**: Submit detailed provenance events for audit trails
110+
- **Data**: Event type, timestamp, agent ID, and custom details
111+
112+
## Dependencies
113+
114+
- `requests`: HTTP client for API communication
115+
- `PyJWT`: JWT token handling
116+
- `cryptography`: RSA key generation and encryption
117+
- `pyyaml`: YAML configuration parsing
118+
- `langchain`: LLM integration (for SQL agent)
119+
120+
## Installation
121+
122+
```bash
123+
pip install -r requirements.txt
124+
```
125+
126+
## Testing
127+
128+
Run the test suite:
129+
```bash
130+
python tests/test_services.py
131+
```
132+
133+
## Security
134+
135+
- Uses ephemeral RSA key pairs for secure communication
136+
- Validates JWT tokens using Keycloak public keys
137+
- Supports encrypted data exchange with the API server
138+
- Maintains secure token management throughout agent lifecycle
139+
140+
## Integration with Java Ecosystem
141+
142+
This Python agent is designed to work seamlessly with the existing Java-based Sentrius infrastructure:
143+
144+
- Compatible with the same API endpoints
145+
- Uses identical authentication mechanisms
146+
- Submits provenance events in the same format
147+
- Supports the same agent lifecycle management
148+
- Can be launched using the same agent launcher service
149+
150+
## Example Provenance Events
151+
152+
The agent automatically submits various provenance events:
153+
154+
```json
155+
{
156+
"event_type": "AGENT_REGISTRATION",
157+
"timestamp": "2024-01-01T12:00:00.000Z",
158+
"agent_id": "python-agent-abc123",
159+
"details": {
160+
"agent_id": "python-agent-abc123",
161+
"callback_url": "http://localhost:8081",
162+
"agent_type": "python"
163+
}
164+
}
165+
```
166+
167+
```json
168+
{
169+
"event_type": "SQL_QUERY_SUCCESS",
170+
"timestamp": "2024-01-01T12:01:00.000Z",
171+
"agent_id": "python-agent-abc123",
172+
"details": {
173+
"question_number": 1,
174+
"question": "What are the top 5 customers by revenue?",
175+
"response_length": 245
176+
}
177+
}
178+
```
164 Bytes
Binary file not shown.
3.56 KB
Binary file not shown.

python-agent/agents/base.py

Lines changed: 77 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,84 @@
11
from abc import ABC, abstractmethod
2+
from typing import Dict, Any, Optional
3+
import logging
4+
5+
from services.sentrius_agent import SentriusAgent
6+
from services.config import SentriusAgentConfig
7+
8+
logger = logging.getLogger(__name__)
9+
210

311
class BaseAgent(ABC):
4-
"""Abstract base class for all agents."""
5-
def __init__(self, name: str, config: dict):
12+
"""Abstract base class for all agents with Sentrius API integration."""
13+
14+
def __init__(self, name: str, config_path: Optional[str] = None, config: Optional[SentriusAgentConfig] = None):
615
self.name = name
7-
self.config = config
16+
17+
# Load configuration
18+
if config:
19+
self.config = config
20+
elif config_path:
21+
self.config = SentriusAgentConfig.from_yaml(config_path)
22+
else:
23+
self.config = SentriusAgentConfig.from_env()
24+
25+
# Initialize Sentrius agent
26+
self.sentrius_agent = SentriusAgent(self.config)
27+
28+
logger.info(f"Initialized {self.__class__.__name__}: {self.name}")
829

930
@abstractmethod
10-
def run(self):
11-
"""Method to execute the agent's task."""
31+
def execute_task(self):
32+
"""Method to execute the agent's specific task."""
1233
pass
34+
35+
def run(self):
36+
"""Main run method that handles agent lifecycle."""
37+
try:
38+
with self.sentrius_agent:
39+
logger.info(f"Starting {self.name} agent")
40+
41+
# Submit start event
42+
self.sentrius_agent.submit_provenance_event(
43+
event_type="AGENT_START",
44+
details={
45+
"agent_name": self.name,
46+
"agent_class": self.__class__.__name__
47+
}
48+
)
49+
50+
# Execute the specific task
51+
self.execute_task()
52+
53+
# Submit completion event
54+
self.sentrius_agent.submit_provenance_event(
55+
event_type="AGENT_COMPLETE",
56+
details={
57+
"agent_name": self.name,
58+
"status": "completed"
59+
}
60+
)
61+
62+
logger.info(f"{self.name} agent completed successfully")
63+
64+
except Exception as e:
65+
logger.error(f"{self.name} agent failed: {e}")
66+
67+
# Submit error event
68+
try:
69+
self.sentrius_agent.submit_provenance_event(
70+
event_type="AGENT_ERROR",
71+
details={
72+
"agent_name": self.name,
73+
"error": str(e),
74+
"error_type": type(e).__name__
75+
}
76+
)
77+
except:
78+
pass # Don't fail if we can't submit error event
79+
80+
raise
81+
82+
def submit_provenance(self, event_type: str, details: Dict[str, Any]):
83+
"""Submit a provenance event."""
84+
self.sentrius_agent.submit_provenance_event(event_type, details)
174 Bytes
Binary file not shown.
Binary file not shown.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# SQL Agent Configuration
2+
# Sentrius Agent Configuration
3+
keycloak:
4+
server_url: "http://localhost:8080"
5+
realm: "sentrius"
6+
client_id: "python-agent"
7+
client_secret: "your-client-secret"
8+
9+
agent:
10+
name_prefix: "sql-agent"
11+
agent_type: "python"
12+
callback_url: "http://localhost:8081"
13+
api_url: "http://localhost:8080"
14+
heartbeat_interval: 30
15+
16+
llm:
17+
enabled: false
18+
provider: "openai"
19+
model: "gpt-3.5-turbo"
20+
api_key: null
21+
endpoint: null
22+
23+
# SQL-specific configuration
24+
database_url: "postgresql://user:password@localhost:5432/database"
25+
questions_file: "agents/sql_agent/questions.yaml"
26+
model_name: "gpt-3.5-turbo"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Sample questions for SQL Agent
2+
- "What are the top 5 customers by revenue?"
3+
- "How many orders were placed last month?"
4+
- "What is the average order value?"
5+
- "Which products are running low on inventory?"

0 commit comments

Comments
 (0)