idun-agent-schema 0.1.0__tar.gz → 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of idun-agent-schema might be problematic. Click here for more details.
- {idun_agent_schema-0.1.0 → idun_agent_schema-0.1.1}/.gitignore +6 -1
- {idun_agent_schema-0.1.0 → idun_agent_schema-0.1.1}/PKG-INFO +1 -3
- {idun_agent_schema-0.1.0 → idun_agent_schema-0.1.1}/README.md +0 -2
- {idun_agent_schema-0.1.0 → idun_agent_schema-0.1.1}/pyproject.toml +1 -3
- {idun_agent_schema-0.1.0 → idun_agent_schema-0.1.1}/src/idun_agent_schema/__init__.py +0 -2
- {idun_agent_schema-0.1.0 → idun_agent_schema-0.1.1}/src/idun_agent_schema/engine/__init__.py +0 -2
- {idun_agent_schema-0.1.0 → idun_agent_schema-0.1.1}/src/idun_agent_schema/engine/agent.py +0 -2
- idun_agent_schema-0.1.1/src/idun_agent_schema/engine/api.py +29 -0
- {idun_agent_schema-0.1.0 → idun_agent_schema-0.1.1}/src/idun_agent_schema/engine/config.py +1 -3
- idun_agent_schema-0.1.1/src/idun_agent_schema/engine/haystack.py +13 -0
- {idun_agent_schema-0.1.0 → idun_agent_schema-0.1.1}/src/idun_agent_schema/engine/langgraph.py +7 -2
- {idun_agent_schema-0.1.0 → idun_agent_schema-0.1.1}/src/idun_agent_schema/engine/server.py +0 -2
- {idun_agent_schema-0.1.0 → idun_agent_schema-0.1.1}/src/idun_agent_schema/manager/__init__.py +0 -2
- {idun_agent_schema-0.1.0 → idun_agent_schema-0.1.1}/src/idun_agent_schema/manager/api.py +30 -2
- {idun_agent_schema-0.1.0 → idun_agent_schema-0.1.1}/src/idun_agent_schema/manager/deployments.py +0 -2
- {idun_agent_schema-0.1.0 → idun_agent_schema-0.1.1}/src/idun_agent_schema/manager/deps.py +0 -2
- {idun_agent_schema-0.1.0 → idun_agent_schema-0.1.1}/src/idun_agent_schema/manager/domain.py +17 -2
- {idun_agent_schema-0.1.0 → idun_agent_schema-0.1.1}/src/idun_agent_schema/manager/dto.py +24 -2
- {idun_agent_schema-0.1.0 → idun_agent_schema-0.1.1}/src/idun_agent_schema/manager/errors.py +0 -2
- {idun_agent_schema-0.1.0 → idun_agent_schema-0.1.1}/src/idun_agent_schema/manager/settings.py +28 -6
- idun_agent_schema-0.1.1/src/idun_agent_schema/py.typed +0 -0
- {idun_agent_schema-0.1.0 → idun_agent_schema-0.1.1}/src/idun_agent_schema/shared/__init__.py +1 -1
- {idun_agent_schema-0.1.0 → idun_agent_schema-0.1.1}/src/idun_agent_schema/shared/observability.py +0 -2
- idun_agent_schema-0.1.0/src/idun_agent_schema/engine/api.py +0 -15
- idun_agent_schema-0.1.0/src/idun_agent_schema/py.typed +0 -2
|
@@ -5,7 +5,7 @@ __pycache__/
|
|
|
5
5
|
|
|
6
6
|
# C extensions
|
|
7
7
|
*.so
|
|
8
|
-
|
|
8
|
+
.DS_Store
|
|
9
9
|
# Distribution / packaging
|
|
10
10
|
.Python
|
|
11
11
|
build/
|
|
@@ -199,3 +199,8 @@ poetry.lock
|
|
|
199
199
|
|
|
200
200
|
# Environment variables
|
|
201
201
|
.env
|
|
202
|
+
|
|
203
|
+
# Custom Gitignore for Idun
|
|
204
|
+
*.db-wal
|
|
205
|
+
.DS_Store
|
|
206
|
+
*.DS_Store
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: idun-agent-schema
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.1
|
|
4
4
|
Summary: Centralized Pydantic schema library for Idun Agent Engine and Manager
|
|
5
5
|
Project-URL: Homepage, https://github.com/geoffreyharrazi/idun-agent-platform
|
|
6
6
|
Project-URL: Repository, https://github.com/geoffreyharrazi/idun-agent-platform
|
|
@@ -36,5 +36,3 @@ from idun_agent_schema.manager.api import AgentCreateRequest
|
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
This package re-exports stable schema namespaces to avoid breaking existing imports. Prefer importing from this package directly going forward.
|
|
39
|
-
|
|
40
|
-
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "idun-agent-schema"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.1"
|
|
4
4
|
description = "Centralized Pydantic schema library for Idun Agent Engine and Manager"
|
|
5
5
|
authors = [{ name = "Idun Team", email = "team@idun.com" }]
|
|
6
6
|
readme = "README.md"
|
|
@@ -72,5 +72,3 @@ show_error_codes = true
|
|
|
72
72
|
[tool.pytest.ini_options]
|
|
73
73
|
addopts = "-ra -q --strict-markers --disable-warnings"
|
|
74
74
|
testpaths = ["tests"]
|
|
75
|
-
|
|
76
|
-
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""Schemas for engine HTTP API request/response payloads."""
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ChatRequest(BaseModel):
|
|
7
|
+
"""Request payload for synchronous and streaming chat endpoints.
|
|
8
|
+
|
|
9
|
+
Attributes:
|
|
10
|
+
session_id: Client-provided session identifier for routing state.
|
|
11
|
+
query: Natural language prompt or input for the agent.
|
|
12
|
+
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
session_id: str
|
|
16
|
+
query: str
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class ChatResponse(BaseModel):
|
|
20
|
+
"""Response payload for chat endpoints.
|
|
21
|
+
|
|
22
|
+
Attributes:
|
|
23
|
+
session_id: Echoed session identifier.
|
|
24
|
+
response: Agent's textual response.
|
|
25
|
+
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
session_id: str
|
|
29
|
+
response: str
|
|
@@ -12,7 +12,7 @@ from .server import ServerConfig
|
|
|
12
12
|
class AgentConfig(BaseModel):
|
|
13
13
|
"""Configuration for agent specification and settings."""
|
|
14
14
|
|
|
15
|
-
type: Literal["langgraph", "ADK", "CREWAI"] = Field(default="langgraph")
|
|
15
|
+
type: Literal["langgraph", "ADK", "CREWAI", "haystack"] = Field(default="langgraph")
|
|
16
16
|
config: BaseAgentConfig | LangGraphAgentConfig = Field(
|
|
17
17
|
default_factory=BaseAgentConfig
|
|
18
18
|
)
|
|
@@ -23,5 +23,3 @@ class EngineConfig(BaseModel):
|
|
|
23
23
|
|
|
24
24
|
server: ServerConfig = Field(default_factory=ServerConfig)
|
|
25
25
|
agent: AgentConfig
|
|
26
|
-
|
|
27
|
-
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""Configuration models for Haystack agents."""
|
|
2
|
+
|
|
3
|
+
from typing import Literal
|
|
4
|
+
|
|
5
|
+
from idun_agent_engine.core.engine_config import BaseAgentConfig
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class HaystackAgentConfig(BaseAgentConfig):
|
|
9
|
+
"""Configuration model for Haystack Agents."""
|
|
10
|
+
|
|
11
|
+
type: Literal["haystack"] = "haystack"
|
|
12
|
+
component_type: Literal["pipeline", "agent"]
|
|
13
|
+
component_definition: str
|
{idun_agent_schema-0.1.0 → idun_agent_schema-0.1.1}/src/idun_agent_schema/engine/langgraph.py
RENAMED
|
@@ -17,12 +17,19 @@ class SqliteCheckpointConfig(BaseModel):
|
|
|
17
17
|
@field_validator("db_url")
|
|
18
18
|
@classmethod
|
|
19
19
|
def db_url_must_be_sqlite(cls, v: str) -> str:
|
|
20
|
+
"""Ensure the provided database URL uses the sqlite scheme.
|
|
21
|
+
|
|
22
|
+
Raises:
|
|
23
|
+
ValueError: If the URL does not start with 'sqlite:///'.
|
|
24
|
+
|
|
25
|
+
"""
|
|
20
26
|
if not v.startswith("sqlite:///"):
|
|
21
27
|
raise ValueError("SQLite DB URL must start with 'sqlite:///'")
|
|
22
28
|
return v
|
|
23
29
|
|
|
24
30
|
@property
|
|
25
31
|
def db_path(self) -> str:
|
|
32
|
+
"""Return filesystem path component derived from the sqlite URL."""
|
|
26
33
|
path = urlparse(self.db_url).path
|
|
27
34
|
if self.db_url.startswith("sqlite:///"):
|
|
28
35
|
return path.lstrip("/")
|
|
@@ -38,5 +45,3 @@ class LangGraphAgentConfig(BaseAgentConfig):
|
|
|
38
45
|
graph_definition: str
|
|
39
46
|
checkpointer: CheckpointConfig | None = None
|
|
40
47
|
store: dict[str, Any] | None = None
|
|
41
|
-
|
|
42
|
-
|
|
@@ -10,6 +10,8 @@ from .domain import AgentFramework, AgentStatus
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class AgentCreateRequest(BaseModel):
|
|
13
|
+
"""Request payload to create a new agent."""
|
|
14
|
+
|
|
13
15
|
name: str = Field(..., min_length=1, max_length=255)
|
|
14
16
|
description: str | None = Field(None, max_length=1000)
|
|
15
17
|
framework: AgentFramework
|
|
@@ -19,6 +21,8 @@ class AgentCreateRequest(BaseModel):
|
|
|
19
21
|
|
|
20
22
|
|
|
21
23
|
class AgentUpdateRequest(BaseModel):
|
|
24
|
+
"""Request payload to update an existing agent (partial)."""
|
|
25
|
+
|
|
22
26
|
name: str | None = Field(None, min_length=1, max_length=255)
|
|
23
27
|
description: str | None = Field(None, max_length=1000)
|
|
24
28
|
config: dict[str, Any] | None = None
|
|
@@ -27,11 +31,15 @@ class AgentUpdateRequest(BaseModel):
|
|
|
27
31
|
|
|
28
32
|
|
|
29
33
|
class AgentRunRequest(BaseModel):
|
|
34
|
+
"""Request payload to execute an agent run."""
|
|
35
|
+
|
|
30
36
|
input_data: dict[str, Any]
|
|
31
37
|
trace_id: str | None = Field(None, max_length=100)
|
|
32
38
|
|
|
33
39
|
|
|
34
40
|
class AgentResponse(BaseModel):
|
|
41
|
+
"""Response shape for a single agent resource."""
|
|
42
|
+
|
|
35
43
|
id: UUID
|
|
36
44
|
name: str
|
|
37
45
|
description: str | None
|
|
@@ -50,10 +58,14 @@ class AgentResponse(BaseModel):
|
|
|
50
58
|
avg_response_time_ms: float | None
|
|
51
59
|
|
|
52
60
|
class Config:
|
|
61
|
+
"""Pydantic configuration for ORM compatibility."""
|
|
62
|
+
|
|
53
63
|
from_attributes = True
|
|
54
64
|
|
|
55
65
|
|
|
56
66
|
class AgentSummaryResponse(BaseModel):
|
|
67
|
+
"""Reduced agent fields for listing views."""
|
|
68
|
+
|
|
57
69
|
id: UUID
|
|
58
70
|
name: str
|
|
59
71
|
description: str | None
|
|
@@ -67,10 +79,14 @@ class AgentSummaryResponse(BaseModel):
|
|
|
67
79
|
success_rate: float | None
|
|
68
80
|
|
|
69
81
|
class Config:
|
|
82
|
+
"""Pydantic configuration for ORM compatibility."""
|
|
83
|
+
|
|
70
84
|
from_attributes = True
|
|
71
85
|
|
|
72
86
|
|
|
73
87
|
class AgentRunResponse(BaseModel):
|
|
88
|
+
"""Detailed run record returned after execution."""
|
|
89
|
+
|
|
74
90
|
id: UUID
|
|
75
91
|
agent_id: UUID
|
|
76
92
|
tenant_id: UUID
|
|
@@ -87,10 +103,14 @@ class AgentRunResponse(BaseModel):
|
|
|
87
103
|
span_id: str | None
|
|
88
104
|
|
|
89
105
|
class Config:
|
|
106
|
+
"""Pydantic configuration for ORM compatibility."""
|
|
107
|
+
|
|
90
108
|
from_attributes = True
|
|
91
109
|
|
|
92
110
|
|
|
93
111
|
class AgentRunSummaryResponse(BaseModel):
|
|
112
|
+
"""Reduced run fields for list views."""
|
|
113
|
+
|
|
94
114
|
id: UUID
|
|
95
115
|
agent_id: UUID
|
|
96
116
|
status: str
|
|
@@ -101,10 +121,14 @@ class AgentRunSummaryResponse(BaseModel):
|
|
|
101
121
|
cost_usd: float | None
|
|
102
122
|
|
|
103
123
|
class Config:
|
|
124
|
+
"""Pydantic configuration for ORM compatibility."""
|
|
125
|
+
|
|
104
126
|
from_attributes = True
|
|
105
127
|
|
|
106
128
|
|
|
107
129
|
class PaginatedResponse(BaseModel):
|
|
130
|
+
"""Base pagination container used by list endpoints."""
|
|
131
|
+
|
|
108
132
|
total: int
|
|
109
133
|
limit: int
|
|
110
134
|
offset: int
|
|
@@ -112,19 +136,23 @@ class PaginatedResponse(BaseModel):
|
|
|
112
136
|
|
|
113
137
|
|
|
114
138
|
class PaginatedAgentsResponse(PaginatedResponse):
|
|
139
|
+
"""Paginated list of agents."""
|
|
140
|
+
|
|
115
141
|
items: list[AgentSummaryResponse]
|
|
116
142
|
|
|
117
143
|
|
|
118
144
|
class PaginatedRunsResponse(PaginatedResponse):
|
|
145
|
+
"""Paginated list of agent runs."""
|
|
146
|
+
|
|
119
147
|
items: list[AgentRunSummaryResponse]
|
|
120
148
|
|
|
121
149
|
|
|
122
150
|
class AgentStatsResponse(BaseModel):
|
|
151
|
+
"""Aggregated statistics across all agents."""
|
|
152
|
+
|
|
123
153
|
total_agents: int
|
|
124
154
|
active_agents: int
|
|
125
155
|
total_runs_today: int
|
|
126
156
|
total_runs_this_month: int
|
|
127
157
|
avg_success_rate: float | None
|
|
128
158
|
avg_response_time_ms: float | None
|
|
129
|
-
|
|
130
|
-
|
|
@@ -58,6 +58,7 @@ class AgentEntity(BaseModel):
|
|
|
58
58
|
avg_response_time_ms: float | None = Field(None, ge=0)
|
|
59
59
|
|
|
60
60
|
def activate(self) -> None:
|
|
61
|
+
"""Transition agent from DRAFT to ACTIVE and set deployment time."""
|
|
61
62
|
if self.status == AgentStatus.DRAFT:
|
|
62
63
|
self.status = AgentStatus.ACTIVE
|
|
63
64
|
self.deployed_at = datetime.now(UTC)
|
|
@@ -65,12 +66,14 @@ class AgentEntity(BaseModel):
|
|
|
65
66
|
raise ValueError(f"Cannot activate agent in {self.status} status")
|
|
66
67
|
|
|
67
68
|
def deactivate(self) -> None:
|
|
69
|
+
"""Transition agent from ACTIVE to INACTIVE."""
|
|
68
70
|
if self.status == AgentStatus.ACTIVE:
|
|
69
71
|
self.status = AgentStatus.INACTIVE
|
|
70
72
|
else:
|
|
71
73
|
raise ValueError(f"Cannot deactivate agent in {self.status} status")
|
|
72
74
|
|
|
73
75
|
def update_metrics(self, success: bool, response_time_ms: float) -> None:
|
|
76
|
+
"""Update running success rate and average response time metrics."""
|
|
74
77
|
self.total_runs += 1
|
|
75
78
|
|
|
76
79
|
if self.success_rate is None:
|
|
@@ -88,6 +91,7 @@ class AgentEntity(BaseModel):
|
|
|
88
91
|
self.avg_response_time_ms = (total_time + response_time_ms) / self.total_runs
|
|
89
92
|
|
|
90
93
|
def can_be_deployed(self) -> bool:
|
|
94
|
+
"""Return True if the agent is eligible for deployment."""
|
|
91
95
|
return (
|
|
92
96
|
self.status in [AgentStatus.DRAFT, AgentStatus.INACTIVE]
|
|
93
97
|
and bool(self.name)
|
|
@@ -122,22 +126,26 @@ class AgentRunEntity(BaseModel):
|
|
|
122
126
|
span_id: str | None = None
|
|
123
127
|
|
|
124
128
|
def complete(self, output_data: dict[str, Any], response_time_ms: float) -> None:
|
|
129
|
+
"""Mark run as completed with outputs and timing."""
|
|
125
130
|
self.status = "completed"
|
|
126
131
|
self.output_data = output_data
|
|
127
132
|
self.completed_at = datetime.now(UTC)
|
|
128
133
|
self.response_time_ms = response_time_ms
|
|
129
134
|
|
|
130
135
|
def fail(self, error_message: str) -> None:
|
|
136
|
+
"""Mark run as failed with an error message."""
|
|
131
137
|
self.status = "failed"
|
|
132
138
|
self.error_message = error_message
|
|
133
139
|
self.completed_at = datetime.now(UTC)
|
|
134
140
|
|
|
135
141
|
@property
|
|
136
142
|
def is_completed(self) -> bool:
|
|
143
|
+
"""Return True if this run has finished (completed or failed)."""
|
|
137
144
|
return self.status in ["completed", "failed"]
|
|
138
145
|
|
|
139
146
|
@property
|
|
140
147
|
def was_successful(self) -> bool:
|
|
148
|
+
"""Return True if the run completed successfully."""
|
|
141
149
|
return self.status == "completed"
|
|
142
150
|
|
|
143
151
|
|
|
@@ -192,17 +200,21 @@ class TenantEntity(BaseModel):
|
|
|
192
200
|
suspended_at: datetime | None = None
|
|
193
201
|
|
|
194
202
|
def can_create_agent(self) -> bool:
|
|
203
|
+
"""Return True if tenant has capacity to create a new agent."""
|
|
195
204
|
return self.status == TenantStatus.ACTIVE and self.current_agents < self.max_agents
|
|
196
205
|
|
|
197
206
|
def can_run_agent(self) -> bool:
|
|
207
|
+
"""Return True if tenant is below monthly run quota."""
|
|
198
208
|
return self.status == TenantStatus.ACTIVE and self.current_runs_this_month < self.max_runs_per_month
|
|
199
209
|
|
|
200
210
|
def suspend(self, reason: str) -> None:
|
|
211
|
+
"""Suspend tenant and record the reason."""
|
|
201
212
|
self.status = TenantStatus.SUSPENDED
|
|
202
213
|
self.suspended_at = datetime.utcnow()
|
|
203
214
|
self.settings["suspension_reason"] = reason
|
|
204
215
|
|
|
205
216
|
def reactivate(self) -> None:
|
|
217
|
+
"""Reactivate a previously suspended tenant."""
|
|
206
218
|
if self.status == TenantStatus.SUSPENDED:
|
|
207
219
|
self.status = TenantStatus.ACTIVE
|
|
208
220
|
self.suspended_at = None
|
|
@@ -210,6 +222,7 @@ class TenantEntity(BaseModel):
|
|
|
210
222
|
del self.settings["suspension_reason"]
|
|
211
223
|
|
|
212
224
|
def upgrade_plan(self, new_plan: TenantPlan) -> None:
|
|
225
|
+
"""Upgrade plan and adjust quotas accordingly."""
|
|
213
226
|
self.plan = new_plan
|
|
214
227
|
if new_plan == TenantPlan.STARTER:
|
|
215
228
|
self.max_agents = 20
|
|
@@ -225,11 +238,13 @@ class TenantEntity(BaseModel):
|
|
|
225
238
|
self.max_storage_mb = 100000
|
|
226
239
|
|
|
227
240
|
def increment_usage(self, agents: int = 0, runs: int = 0, storage_mb: float = 0) -> None:
|
|
241
|
+
"""Increment tracked usage counters."""
|
|
228
242
|
self.current_agents += agents
|
|
229
243
|
self.current_runs_this_month += runs
|
|
230
244
|
self.current_storage_mb += storage_mb
|
|
231
245
|
|
|
232
246
|
def reset_monthly_usage(self) -> None:
|
|
247
|
+
"""Reset monthly run counter at billing cycle start."""
|
|
233
248
|
self.current_runs_this_month = 0
|
|
234
249
|
|
|
235
250
|
|
|
@@ -253,9 +268,9 @@ class TenantUserEntity(BaseModel):
|
|
|
253
268
|
last_active_at: datetime | None = None
|
|
254
269
|
|
|
255
270
|
def has_permission(self, permission: str) -> bool:
|
|
271
|
+
"""Return True if the user has an explicit permission or is owner."""
|
|
256
272
|
return permission in self.permissions or self.role == "owner"
|
|
257
273
|
|
|
258
274
|
def is_admin(self) -> bool:
|
|
275
|
+
"""Return True if the user is an admin or owner."""
|
|
259
276
|
return self.role in ["owner", "admin"]
|
|
260
|
-
|
|
261
|
-
|
|
@@ -10,6 +10,8 @@ from .domain import AgentFramework, TenantPlan
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class AgentCreateDTO(BaseModel):
|
|
13
|
+
"""DTO for creating an agent in the application layer."""
|
|
14
|
+
|
|
13
15
|
name: str = Field(..., min_length=1, max_length=255)
|
|
14
16
|
description: str | None = Field(None, max_length=1000)
|
|
15
17
|
framework: AgentFramework
|
|
@@ -20,6 +22,8 @@ class AgentCreateDTO(BaseModel):
|
|
|
20
22
|
|
|
21
23
|
|
|
22
24
|
class AgentUpdateDTO(BaseModel):
|
|
25
|
+
"""DTO for updating an existing agent."""
|
|
26
|
+
|
|
23
27
|
name: str | None = Field(None, min_length=1, max_length=255)
|
|
24
28
|
description: str | None = Field(None, max_length=1000)
|
|
25
29
|
config: dict[str, Any] | None = None
|
|
@@ -28,6 +32,8 @@ class AgentUpdateDTO(BaseModel):
|
|
|
28
32
|
|
|
29
33
|
|
|
30
34
|
class AgentDeploymentDTO(BaseModel):
|
|
35
|
+
"""DTO describing deployment details for an agent."""
|
|
36
|
+
|
|
31
37
|
agent_id: UUID
|
|
32
38
|
container_id: str
|
|
33
39
|
endpoint: str
|
|
@@ -37,6 +43,8 @@ class AgentDeploymentDTO(BaseModel):
|
|
|
37
43
|
|
|
38
44
|
|
|
39
45
|
class AgentHealthDTO(BaseModel):
|
|
46
|
+
"""DTO representing health metrics for an agent instance."""
|
|
47
|
+
|
|
40
48
|
agent_id: UUID
|
|
41
49
|
status: str
|
|
42
50
|
uptime: str | None = None
|
|
@@ -47,6 +55,8 @@ class AgentHealthDTO(BaseModel):
|
|
|
47
55
|
|
|
48
56
|
|
|
49
57
|
class AgentRunCreateDTO(BaseModel):
|
|
58
|
+
"""DTO for creating a new agent run."""
|
|
59
|
+
|
|
50
60
|
agent_id: UUID
|
|
51
61
|
tenant_id: UUID
|
|
52
62
|
input_data: dict[str, Any]
|
|
@@ -54,6 +64,8 @@ class AgentRunCreateDTO(BaseModel):
|
|
|
54
64
|
|
|
55
65
|
|
|
56
66
|
class AgentMetricsDTO(BaseModel):
|
|
67
|
+
"""DTO for aggregated performance metrics of an agent."""
|
|
68
|
+
|
|
57
69
|
agent_id: UUID
|
|
58
70
|
total_runs: int
|
|
59
71
|
success_rate: float | None = Field(None, ge=0.0, le=1.0)
|
|
@@ -62,6 +74,8 @@ class AgentMetricsDTO(BaseModel):
|
|
|
62
74
|
|
|
63
75
|
|
|
64
76
|
class TenantCreateDTO(BaseModel):
|
|
77
|
+
"""DTO for creating a tenant."""
|
|
78
|
+
|
|
65
79
|
name: str = Field(..., min_length=1, max_length=255)
|
|
66
80
|
slug: str = Field(..., min_length=1, max_length=100)
|
|
67
81
|
email: str = Field(..., description="Primary contact email")
|
|
@@ -70,6 +84,8 @@ class TenantCreateDTO(BaseModel):
|
|
|
70
84
|
|
|
71
85
|
|
|
72
86
|
class TenantUpdateDTO(BaseModel):
|
|
87
|
+
"""DTO for updating tenant metadata and settings."""
|
|
88
|
+
|
|
73
89
|
name: str | None = Field(None, min_length=1, max_length=255)
|
|
74
90
|
email: str | None = None
|
|
75
91
|
website: str | None = None
|
|
@@ -77,6 +93,8 @@ class TenantUpdateDTO(BaseModel):
|
|
|
77
93
|
|
|
78
94
|
|
|
79
95
|
class TenantUsageDTO(BaseModel):
|
|
96
|
+
"""DTO summarizing a tenant's resource usage and quotas."""
|
|
97
|
+
|
|
80
98
|
tenant_id: UUID
|
|
81
99
|
current_agents: int
|
|
82
100
|
max_agents: int
|
|
@@ -88,12 +106,16 @@ class TenantUsageDTO(BaseModel):
|
|
|
88
106
|
|
|
89
107
|
|
|
90
108
|
class TenantQuotaDTO(BaseModel):
|
|
109
|
+
"""DTO for updating tenant quotas."""
|
|
110
|
+
|
|
91
111
|
max_agents: int | None = None
|
|
92
112
|
max_runs_per_month: int | None = None
|
|
93
113
|
max_storage_mb: int | None = None
|
|
94
114
|
|
|
95
115
|
|
|
96
116
|
class TenantUserCreateDTO(BaseModel):
|
|
117
|
+
"""DTO for adding a user to a tenant."""
|
|
118
|
+
|
|
97
119
|
tenant_id: UUID
|
|
98
120
|
user_id: str
|
|
99
121
|
email: str
|
|
@@ -102,8 +124,8 @@ class TenantUserCreateDTO(BaseModel):
|
|
|
102
124
|
|
|
103
125
|
|
|
104
126
|
class TenantUserUpdateDTO(BaseModel):
|
|
127
|
+
"""DTO for updating tenant user fields."""
|
|
128
|
+
|
|
105
129
|
role: str | None = None
|
|
106
130
|
permissions: list[str] | None = None
|
|
107
131
|
is_active: bool | None = None
|
|
108
|
-
|
|
109
|
-
|
{idun_agent_schema-0.1.0 → idun_agent_schema-0.1.1}/src/idun_agent_schema/manager/settings.py
RENAMED
|
@@ -7,7 +7,11 @@ from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class DatabaseSettings(BaseSettings):
|
|
10
|
-
|
|
10
|
+
"""Database configuration settings for the Manager service."""
|
|
11
|
+
|
|
12
|
+
url: str = Field(
|
|
13
|
+
default="postgresql+asyncpg://postgres:postgres@localhost:55432/idun_agents"
|
|
14
|
+
)
|
|
11
15
|
echo: bool = Field(default=False)
|
|
12
16
|
pool_size: int = Field(default=10)
|
|
13
17
|
max_overflow: int = Field(default=20)
|
|
@@ -17,6 +21,8 @@ class DatabaseSettings(BaseSettings):
|
|
|
17
21
|
|
|
18
22
|
|
|
19
23
|
class RedisSettings(BaseSettings):
|
|
24
|
+
"""Redis cache settings."""
|
|
25
|
+
|
|
20
26
|
url: str = Field(default="redis://localhost:6379/0")
|
|
21
27
|
max_connections: int = Field(default=20)
|
|
22
28
|
|
|
@@ -24,6 +30,8 @@ class RedisSettings(BaseSettings):
|
|
|
24
30
|
|
|
25
31
|
|
|
26
32
|
class AuthSettings(BaseSettings):
|
|
33
|
+
"""Authentication and OIDC-related configuration."""
|
|
34
|
+
|
|
27
35
|
provider_type: Literal["okta", "auth0", "entra", "google"] = Field(default="auth0")
|
|
28
36
|
issuer: str = Field(default="")
|
|
29
37
|
client_id: str = Field(default="")
|
|
@@ -62,11 +70,14 @@ class AuthSettings(BaseSettings):
|
|
|
62
70
|
return None
|
|
63
71
|
return v
|
|
64
72
|
|
|
65
|
-
model_config = SettingsConfigDict(
|
|
73
|
+
model_config = SettingsConfigDict(
|
|
74
|
+
env_prefix="AUTH_", env_file=".env", extra="ignore"
|
|
75
|
+
)
|
|
66
76
|
|
|
67
77
|
@field_validator("issuer")
|
|
68
78
|
@classmethod
|
|
69
79
|
def validate_issuer(cls, v: str) -> str:
|
|
80
|
+
"""Validate that issuer is either empty or a URL."""
|
|
70
81
|
if not v:
|
|
71
82
|
return v
|
|
72
83
|
if not v.startswith("http"):
|
|
@@ -75,6 +86,8 @@ class AuthSettings(BaseSettings):
|
|
|
75
86
|
|
|
76
87
|
|
|
77
88
|
class ObservabilitySettings(BaseSettings):
|
|
89
|
+
"""OpenTelemetry and logging settings."""
|
|
90
|
+
|
|
78
91
|
otel_service_name: str = Field(default="idun-agent-manager")
|
|
79
92
|
otel_exporter_endpoint: str | None = Field(default=None)
|
|
80
93
|
otel_exporter_headers: str | None = Field(default=None)
|
|
@@ -85,6 +98,8 @@ class ObservabilitySettings(BaseSettings):
|
|
|
85
98
|
|
|
86
99
|
|
|
87
100
|
class CelerySettings(BaseSettings):
|
|
101
|
+
"""Celery broker/result backend settings."""
|
|
102
|
+
|
|
88
103
|
broker_url: str = Field(default="redis://localhost:6379/1")
|
|
89
104
|
result_backend: str = Field(default="redis://localhost:6379/2")
|
|
90
105
|
task_serializer: str = Field(default="json")
|
|
@@ -96,23 +111,31 @@ class CelerySettings(BaseSettings):
|
|
|
96
111
|
|
|
97
112
|
|
|
98
113
|
class APISettings(BaseSettings):
|
|
114
|
+
"""API metadata, CORS, and rate limiting settings."""
|
|
115
|
+
|
|
99
116
|
title: str = Field(default="Idun Agent Manager API")
|
|
100
117
|
description: str = Field(default="Modern FastAPI backend for managing AI agents")
|
|
101
118
|
version: str = Field(default="0.1.0")
|
|
102
119
|
docs_url: str = Field(default="/docs")
|
|
103
120
|
redoc_url: str = Field(default="/redoc")
|
|
104
121
|
openapi_url: str = Field(default="/openapi.json")
|
|
105
|
-
cors_origins: list[str] = Field(
|
|
122
|
+
cors_origins: list[str] = Field(
|
|
123
|
+
default=["http://localhost:3000", "http://localhost:8080"]
|
|
124
|
+
)
|
|
106
125
|
cors_methods: list[str] = Field(default=["*"])
|
|
107
126
|
cors_headers: list[str] = Field(default=["*"])
|
|
108
127
|
rate_limit_enabled: bool = Field(default=True)
|
|
109
128
|
rate_limit_requests: int = Field(default=100)
|
|
110
129
|
rate_limit_window: int = Field(default=60)
|
|
111
130
|
|
|
112
|
-
model_config = SettingsConfigDict(
|
|
131
|
+
model_config = SettingsConfigDict(
|
|
132
|
+
env_prefix="API_", env_file=".env", extra="ignore"
|
|
133
|
+
)
|
|
113
134
|
|
|
114
135
|
|
|
115
136
|
class Settings(BaseSettings):
|
|
137
|
+
"""Top-level application settings composed of sub-settings."""
|
|
138
|
+
|
|
116
139
|
environment: str = Field(default="development")
|
|
117
140
|
debug: bool = Field(default=False)
|
|
118
141
|
testing: bool = Field(default=False)
|
|
@@ -120,6 +143,7 @@ class Settings(BaseSettings):
|
|
|
120
143
|
port: int = Field(default=8000)
|
|
121
144
|
workers: int = Field(default=1)
|
|
122
145
|
reload: bool = Field(default=False)
|
|
146
|
+
is_development: bool = Field(default=True)
|
|
123
147
|
|
|
124
148
|
database: DatabaseSettings = Field(default_factory=DatabaseSettings)
|
|
125
149
|
redis: RedisSettings = Field(default_factory=RedisSettings)
|
|
@@ -135,5 +159,3 @@ class Settings(BaseSettings):
|
|
|
135
159
|
case_sensitive=False,
|
|
136
160
|
extra="ignore",
|
|
137
161
|
)
|
|
138
|
-
|
|
139
|
-
|
|
File without changes
|