django-agent-studio 0.1.0__py3-none-any.whl
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.
- django_agent_studio/__init__.py +12 -0
- django_agent_studio/api/__init__.py +4 -0
- django_agent_studio/api/permissions.py +160 -0
- django_agent_studio/api/serializers.py +606 -0
- django_agent_studio/api/urls.py +245 -0
- django_agent_studio/api/views.py +1548 -0
- django_agent_studio/apps.py +24 -0
- django_agent_studio/management/__init__.py +2 -0
- django_agent_studio/management/commands/__init__.py +2 -0
- django_agent_studio/static/agent-frontend/chat-widget-markdown.js +110 -0
- django_agent_studio/static/agent-frontend/chat-widget.css +1401 -0
- django_agent_studio/static/agent-frontend/chat-widget.js +319 -0
- django_agent_studio/templates/django_agent_studio/agent_list.html +101 -0
- django_agent_studio/templates/django_agent_studio/base.html +137 -0
- django_agent_studio/templates/django_agent_studio/builder.html +1443 -0
- django_agent_studio/templates/django_agent_studio/home.html +97 -0
- django_agent_studio/templates/django_agent_studio/test.html +126 -0
- django_agent_studio/urls.py +25 -0
- django_agent_studio/views.py +100 -0
- django_agent_studio-0.1.0.dist-info/METADATA +416 -0
- django_agent_studio-0.1.0.dist-info/RECORD +23 -0
- django_agent_studio-0.1.0.dist-info/WHEEL +5 -0
- django_agent_studio-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,606 @@
|
|
|
1
|
+
"""
|
|
2
|
+
API serializers for django_agent_studio.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from rest_framework import serializers
|
|
6
|
+
|
|
7
|
+
from django_agent_runtime.models import (
|
|
8
|
+
AgentDefinition,
|
|
9
|
+
AgentVersion,
|
|
10
|
+
AgentTool,
|
|
11
|
+
AgentKnowledge,
|
|
12
|
+
DiscoveredFunction,
|
|
13
|
+
DynamicTool,
|
|
14
|
+
DynamicToolExecution,
|
|
15
|
+
# Multi-agent system models
|
|
16
|
+
AgentSystem,
|
|
17
|
+
AgentSystemMember,
|
|
18
|
+
AgentSystemVersion,
|
|
19
|
+
AgentSystemSnapshot,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class AgentToolSerializer(serializers.ModelSerializer):
|
|
24
|
+
"""Serializer for AgentTool."""
|
|
25
|
+
|
|
26
|
+
class Meta:
|
|
27
|
+
model = AgentTool
|
|
28
|
+
fields = [
|
|
29
|
+
"id",
|
|
30
|
+
"name",
|
|
31
|
+
"tool_type",
|
|
32
|
+
"description",
|
|
33
|
+
"parameters_schema",
|
|
34
|
+
"builtin_ref",
|
|
35
|
+
"subagent",
|
|
36
|
+
"config",
|
|
37
|
+
"is_active",
|
|
38
|
+
"order",
|
|
39
|
+
]
|
|
40
|
+
read_only_fields = ["id"]
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class AgentKnowledgeSerializer(serializers.ModelSerializer):
|
|
44
|
+
"""Serializer for AgentKnowledge."""
|
|
45
|
+
|
|
46
|
+
class Meta:
|
|
47
|
+
model = AgentKnowledge
|
|
48
|
+
fields = [
|
|
49
|
+
"id",
|
|
50
|
+
"name",
|
|
51
|
+
"knowledge_type",
|
|
52
|
+
"content",
|
|
53
|
+
"file",
|
|
54
|
+
"url",
|
|
55
|
+
"dynamic_config",
|
|
56
|
+
"inclusion_mode",
|
|
57
|
+
"is_active",
|
|
58
|
+
"order",
|
|
59
|
+
"created_at",
|
|
60
|
+
"updated_at",
|
|
61
|
+
]
|
|
62
|
+
read_only_fields = ["id", "created_at", "updated_at"]
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class AgentVersionSerializer(serializers.ModelSerializer):
|
|
66
|
+
"""Serializer for AgentVersion."""
|
|
67
|
+
|
|
68
|
+
class Meta:
|
|
69
|
+
model = AgentVersion
|
|
70
|
+
fields = [
|
|
71
|
+
"id",
|
|
72
|
+
"version",
|
|
73
|
+
"system_prompt",
|
|
74
|
+
"model",
|
|
75
|
+
"model_settings",
|
|
76
|
+
"extra_config",
|
|
77
|
+
"is_active",
|
|
78
|
+
"is_draft",
|
|
79
|
+
"notes",
|
|
80
|
+
"created_at",
|
|
81
|
+
"published_at",
|
|
82
|
+
]
|
|
83
|
+
read_only_fields = ["id", "created_at", "published_at"]
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class AgentDefinitionListSerializer(serializers.ModelSerializer):
|
|
87
|
+
"""Serializer for listing AgentDefinitions."""
|
|
88
|
+
|
|
89
|
+
active_version = serializers.SerializerMethodField()
|
|
90
|
+
tools_count = serializers.SerializerMethodField()
|
|
91
|
+
knowledge_count = serializers.SerializerMethodField()
|
|
92
|
+
owner_email = serializers.EmailField(source='owner.email', read_only=True, allow_null=True)
|
|
93
|
+
|
|
94
|
+
class Meta:
|
|
95
|
+
model = AgentDefinition
|
|
96
|
+
fields = [
|
|
97
|
+
"id",
|
|
98
|
+
"slug",
|
|
99
|
+
"name",
|
|
100
|
+
"description",
|
|
101
|
+
"icon",
|
|
102
|
+
"parent",
|
|
103
|
+
"owner",
|
|
104
|
+
"owner_email",
|
|
105
|
+
"is_public",
|
|
106
|
+
"is_template",
|
|
107
|
+
"is_active",
|
|
108
|
+
"active_version",
|
|
109
|
+
"tools_count",
|
|
110
|
+
"knowledge_count",
|
|
111
|
+
"created_at",
|
|
112
|
+
"updated_at",
|
|
113
|
+
]
|
|
114
|
+
read_only_fields = ["id", "owner", "owner_email", "created_at", "updated_at"]
|
|
115
|
+
|
|
116
|
+
def get_active_version(self, obj):
|
|
117
|
+
version = obj.versions.filter(is_active=True).first()
|
|
118
|
+
if version:
|
|
119
|
+
return {"id": str(version.id), "version": version.version}
|
|
120
|
+
return None
|
|
121
|
+
|
|
122
|
+
def get_tools_count(self, obj):
|
|
123
|
+
return obj.tools.filter(is_active=True).count()
|
|
124
|
+
|
|
125
|
+
def get_knowledge_count(self, obj):
|
|
126
|
+
return obj.knowledge_sources.filter(is_active=True).count()
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class AgentDefinitionDetailSerializer(serializers.ModelSerializer):
|
|
130
|
+
"""Serializer for AgentDefinition detail view."""
|
|
131
|
+
|
|
132
|
+
versions = AgentVersionSerializer(many=True, read_only=True)
|
|
133
|
+
tools = AgentToolSerializer(many=True, read_only=True)
|
|
134
|
+
knowledge_sources = AgentKnowledgeSerializer(many=True, read_only=True)
|
|
135
|
+
effective_config = serializers.SerializerMethodField()
|
|
136
|
+
owner_email = serializers.EmailField(source='owner.email', read_only=True, allow_null=True)
|
|
137
|
+
|
|
138
|
+
class Meta:
|
|
139
|
+
model = AgentDefinition
|
|
140
|
+
fields = [
|
|
141
|
+
"id",
|
|
142
|
+
"slug",
|
|
143
|
+
"name",
|
|
144
|
+
"description",
|
|
145
|
+
"icon",
|
|
146
|
+
"parent",
|
|
147
|
+
"owner",
|
|
148
|
+
"owner_email",
|
|
149
|
+
"is_public",
|
|
150
|
+
"is_template",
|
|
151
|
+
"is_active",
|
|
152
|
+
"versions",
|
|
153
|
+
"tools",
|
|
154
|
+
"knowledge_sources",
|
|
155
|
+
"effective_config",
|
|
156
|
+
"created_at",
|
|
157
|
+
"updated_at",
|
|
158
|
+
]
|
|
159
|
+
read_only_fields = ["id", "owner", "owner_email", "created_at", "updated_at", "effective_config"]
|
|
160
|
+
|
|
161
|
+
def get_effective_config(self, obj):
|
|
162
|
+
return obj.get_effective_config()
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
class DiscoveredFunctionSerializer(serializers.ModelSerializer):
|
|
166
|
+
"""Serializer for DiscoveredFunction."""
|
|
167
|
+
|
|
168
|
+
class Meta:
|
|
169
|
+
model = DiscoveredFunction
|
|
170
|
+
fields = [
|
|
171
|
+
"id",
|
|
172
|
+
"name",
|
|
173
|
+
"module_path",
|
|
174
|
+
"function_path",
|
|
175
|
+
"function_type",
|
|
176
|
+
"class_name",
|
|
177
|
+
"file_path",
|
|
178
|
+
"line_number",
|
|
179
|
+
"signature",
|
|
180
|
+
"docstring",
|
|
181
|
+
"parameters",
|
|
182
|
+
"return_type",
|
|
183
|
+
"is_async",
|
|
184
|
+
"has_side_effects",
|
|
185
|
+
"is_private",
|
|
186
|
+
"is_selected",
|
|
187
|
+
"scan_session",
|
|
188
|
+
"discovered_at",
|
|
189
|
+
]
|
|
190
|
+
read_only_fields = [
|
|
191
|
+
"id", "discovered_at", "scan_session",
|
|
192
|
+
]
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
class DynamicToolSerializer(serializers.ModelSerializer):
|
|
196
|
+
"""Serializer for DynamicTool."""
|
|
197
|
+
|
|
198
|
+
class Meta:
|
|
199
|
+
model = DynamicTool
|
|
200
|
+
fields = [
|
|
201
|
+
"id",
|
|
202
|
+
"name",
|
|
203
|
+
"description",
|
|
204
|
+
"function_path",
|
|
205
|
+
"source_file",
|
|
206
|
+
"source_line",
|
|
207
|
+
"parameters_schema",
|
|
208
|
+
"execution_mode",
|
|
209
|
+
"timeout_seconds",
|
|
210
|
+
"is_safe",
|
|
211
|
+
"requires_confirmation",
|
|
212
|
+
"allowed_for_auto_execution",
|
|
213
|
+
"allowed_imports",
|
|
214
|
+
"blocked_imports",
|
|
215
|
+
"is_active",
|
|
216
|
+
"is_verified",
|
|
217
|
+
"version",
|
|
218
|
+
"created_at",
|
|
219
|
+
"updated_at",
|
|
220
|
+
"discovered_function",
|
|
221
|
+
]
|
|
222
|
+
read_only_fields = [
|
|
223
|
+
"id", "created_at", "updated_at", "version",
|
|
224
|
+
]
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
class DynamicToolExecutionSerializer(serializers.ModelSerializer):
|
|
228
|
+
"""Serializer for DynamicToolExecution."""
|
|
229
|
+
|
|
230
|
+
tool_name = serializers.CharField(source='tool.name', read_only=True)
|
|
231
|
+
|
|
232
|
+
class Meta:
|
|
233
|
+
model = DynamicToolExecution
|
|
234
|
+
fields = [
|
|
235
|
+
"id",
|
|
236
|
+
"tool",
|
|
237
|
+
"tool_name",
|
|
238
|
+
"agent_run_id",
|
|
239
|
+
"input_arguments",
|
|
240
|
+
"output_result",
|
|
241
|
+
"error_message",
|
|
242
|
+
"status",
|
|
243
|
+
"started_at",
|
|
244
|
+
"completed_at",
|
|
245
|
+
"duration_ms",
|
|
246
|
+
"was_sandboxed",
|
|
247
|
+
"user_confirmed",
|
|
248
|
+
]
|
|
249
|
+
read_only_fields = fields
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
class ProjectScanRequestSerializer(serializers.Serializer):
|
|
253
|
+
"""Serializer for project scan request."""
|
|
254
|
+
|
|
255
|
+
directory = serializers.CharField(
|
|
256
|
+
required=False,
|
|
257
|
+
help_text="Specific directory to scan (relative to project root)",
|
|
258
|
+
)
|
|
259
|
+
include_private = serializers.BooleanField(
|
|
260
|
+
default=False,
|
|
261
|
+
help_text="Include private functions (starting with _)",
|
|
262
|
+
)
|
|
263
|
+
include_tests = serializers.BooleanField(
|
|
264
|
+
default=False,
|
|
265
|
+
help_text="Include test files",
|
|
266
|
+
)
|
|
267
|
+
app_filter = serializers.ListField(
|
|
268
|
+
child=serializers.CharField(),
|
|
269
|
+
required=False,
|
|
270
|
+
help_text="List of app names to scan",
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
class GenerateToolsRequestSerializer(serializers.Serializer):
|
|
275
|
+
"""Serializer for tool generation request."""
|
|
276
|
+
|
|
277
|
+
function_ids = serializers.ListField(
|
|
278
|
+
child=serializers.UUIDField(),
|
|
279
|
+
help_text="List of DiscoveredFunction IDs to convert to tools",
|
|
280
|
+
)
|
|
281
|
+
name_prefix = serializers.CharField(
|
|
282
|
+
required=False,
|
|
283
|
+
default="",
|
|
284
|
+
help_text="Prefix to add to tool names",
|
|
285
|
+
)
|
|
286
|
+
requires_confirmation = serializers.BooleanField(
|
|
287
|
+
default=True,
|
|
288
|
+
help_text="Default value for requires_confirmation",
|
|
289
|
+
)
|
|
290
|
+
request_reason = serializers.CharField(
|
|
291
|
+
required=False,
|
|
292
|
+
default="",
|
|
293
|
+
help_text="Reason for requesting these tools (for approval workflow)",
|
|
294
|
+
)
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
# =============================================================================
|
|
298
|
+
# Approval Workflow Serializers
|
|
299
|
+
# =============================================================================
|
|
300
|
+
|
|
301
|
+
from django_agent_studio.models import (
|
|
302
|
+
UserDynamicToolAccess,
|
|
303
|
+
ToolApprovalRequest,
|
|
304
|
+
DynamicToolAccessLevel,
|
|
305
|
+
)
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
class UserDynamicToolAccessSerializer(serializers.ModelSerializer):
|
|
309
|
+
"""Serializer for UserDynamicToolAccess."""
|
|
310
|
+
|
|
311
|
+
user_email = serializers.EmailField(source='user.email', read_only=True)
|
|
312
|
+
user_name = serializers.CharField(source='user.get_full_name', read_only=True)
|
|
313
|
+
granted_by_email = serializers.EmailField(source='granted_by.email', read_only=True)
|
|
314
|
+
access_level_display = serializers.CharField(
|
|
315
|
+
source='get_access_level_display', read_only=True
|
|
316
|
+
)
|
|
317
|
+
|
|
318
|
+
class Meta:
|
|
319
|
+
model = UserDynamicToolAccess
|
|
320
|
+
fields = [
|
|
321
|
+
"id",
|
|
322
|
+
"user",
|
|
323
|
+
"user_email",
|
|
324
|
+
"user_name",
|
|
325
|
+
"access_level",
|
|
326
|
+
"access_level_display",
|
|
327
|
+
"restricted_to_agents",
|
|
328
|
+
"granted_by",
|
|
329
|
+
"granted_by_email",
|
|
330
|
+
"granted_at",
|
|
331
|
+
"updated_at",
|
|
332
|
+
"notes",
|
|
333
|
+
]
|
|
334
|
+
read_only_fields = ["id", "granted_at", "updated_at", "granted_by"]
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
class ToolApprovalRequestSerializer(serializers.ModelSerializer):
|
|
338
|
+
"""Serializer for ToolApprovalRequest."""
|
|
339
|
+
|
|
340
|
+
requester_email = serializers.EmailField(source='requester.email', read_only=True)
|
|
341
|
+
requester_name = serializers.CharField(source='requester.get_full_name', read_only=True)
|
|
342
|
+
reviewed_by_email = serializers.EmailField(
|
|
343
|
+
source='reviewed_by.email', read_only=True, allow_null=True
|
|
344
|
+
)
|
|
345
|
+
agent_name = serializers.CharField(source='agent.name', read_only=True)
|
|
346
|
+
function_path = serializers.CharField(
|
|
347
|
+
source='discovered_function.function_path', read_only=True
|
|
348
|
+
)
|
|
349
|
+
status_display = serializers.CharField(source='get_status_display', read_only=True)
|
|
350
|
+
|
|
351
|
+
class Meta:
|
|
352
|
+
model = ToolApprovalRequest
|
|
353
|
+
fields = [
|
|
354
|
+
"id",
|
|
355
|
+
"agent",
|
|
356
|
+
"agent_name",
|
|
357
|
+
"discovered_function",
|
|
358
|
+
"function_path",
|
|
359
|
+
"proposed_name",
|
|
360
|
+
"proposed_description",
|
|
361
|
+
"proposed_is_safe",
|
|
362
|
+
"proposed_requires_confirmation",
|
|
363
|
+
"proposed_timeout_seconds",
|
|
364
|
+
"requester",
|
|
365
|
+
"requester_email",
|
|
366
|
+
"requester_name",
|
|
367
|
+
"request_reason",
|
|
368
|
+
"status",
|
|
369
|
+
"status_display",
|
|
370
|
+
"reviewed_by",
|
|
371
|
+
"reviewed_by_email",
|
|
372
|
+
"reviewed_at",
|
|
373
|
+
"review_notes",
|
|
374
|
+
"created_tool",
|
|
375
|
+
"created_at",
|
|
376
|
+
"updated_at",
|
|
377
|
+
]
|
|
378
|
+
read_only_fields = [
|
|
379
|
+
"id", "requester", "status", "reviewed_by", "reviewed_at",
|
|
380
|
+
"created_tool", "created_at", "updated_at",
|
|
381
|
+
]
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
class ToolApprovalReviewSerializer(serializers.Serializer):
|
|
385
|
+
"""Serializer for reviewing a tool approval request."""
|
|
386
|
+
|
|
387
|
+
action = serializers.ChoiceField(
|
|
388
|
+
choices=['approve', 'reject'],
|
|
389
|
+
help_text="Action to take on the request",
|
|
390
|
+
)
|
|
391
|
+
review_notes = serializers.CharField(
|
|
392
|
+
required=False,
|
|
393
|
+
default="",
|
|
394
|
+
help_text="Notes about the review decision",
|
|
395
|
+
)
|
|
396
|
+
# Allow overriding proposed values on approval
|
|
397
|
+
override_name = serializers.CharField(required=False)
|
|
398
|
+
override_description = serializers.CharField(required=False)
|
|
399
|
+
override_is_safe = serializers.BooleanField(required=False)
|
|
400
|
+
override_requires_confirmation = serializers.BooleanField(required=False)
|
|
401
|
+
override_timeout_seconds = serializers.IntegerField(required=False, min_value=1)
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
class GrantAccessSerializer(serializers.Serializer):
|
|
405
|
+
"""Serializer for granting dynamic tool access to a user."""
|
|
406
|
+
|
|
407
|
+
user_id = serializers.IntegerField(help_text="User ID to grant access to")
|
|
408
|
+
access_level = serializers.ChoiceField(
|
|
409
|
+
choices=DynamicToolAccessLevel.choices,
|
|
410
|
+
help_text="Access level to grant",
|
|
411
|
+
)
|
|
412
|
+
restricted_to_agent_ids = serializers.ListField(
|
|
413
|
+
child=serializers.UUIDField(),
|
|
414
|
+
required=False,
|
|
415
|
+
help_text="Optional list of agent IDs to restrict access to",
|
|
416
|
+
)
|
|
417
|
+
notes = serializers.CharField(
|
|
418
|
+
required=False,
|
|
419
|
+
default="",
|
|
420
|
+
help_text="Notes about why access was granted",
|
|
421
|
+
)
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
# =============================================================================
|
|
425
|
+
# Multi-Agent System Serializers
|
|
426
|
+
# =============================================================================
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
class AgentSystemMemberSerializer(serializers.ModelSerializer):
|
|
430
|
+
"""Serializer for AgentSystemMember."""
|
|
431
|
+
|
|
432
|
+
agent_name = serializers.CharField(source='agent.name', read_only=True)
|
|
433
|
+
agent_slug = serializers.CharField(source='agent.slug', read_only=True)
|
|
434
|
+
role_display = serializers.CharField(source='get_role_display', read_only=True)
|
|
435
|
+
|
|
436
|
+
class Meta:
|
|
437
|
+
model = AgentSystemMember
|
|
438
|
+
fields = [
|
|
439
|
+
"id",
|
|
440
|
+
"agent",
|
|
441
|
+
"agent_name",
|
|
442
|
+
"agent_slug",
|
|
443
|
+
"role",
|
|
444
|
+
"role_display",
|
|
445
|
+
"notes",
|
|
446
|
+
"order",
|
|
447
|
+
]
|
|
448
|
+
read_only_fields = ["id"]
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
class AgentSystemSnapshotSerializer(serializers.ModelSerializer):
|
|
452
|
+
"""Serializer for AgentSystemSnapshot."""
|
|
453
|
+
|
|
454
|
+
agent_name = serializers.CharField(source='agent.name', read_only=True)
|
|
455
|
+
agent_slug = serializers.CharField(source='agent.slug', read_only=True)
|
|
456
|
+
revision_number = serializers.IntegerField(
|
|
457
|
+
source='pinned_revision.revision_number', read_only=True
|
|
458
|
+
)
|
|
459
|
+
|
|
460
|
+
class Meta:
|
|
461
|
+
model = AgentSystemSnapshot
|
|
462
|
+
fields = [
|
|
463
|
+
"id",
|
|
464
|
+
"agent",
|
|
465
|
+
"agent_name",
|
|
466
|
+
"agent_slug",
|
|
467
|
+
"pinned_revision",
|
|
468
|
+
"revision_number",
|
|
469
|
+
"tool_config_overrides",
|
|
470
|
+
]
|
|
471
|
+
read_only_fields = ["id"]
|
|
472
|
+
|
|
473
|
+
|
|
474
|
+
class AgentSystemVersionSerializer(serializers.ModelSerializer):
|
|
475
|
+
"""Serializer for AgentSystemVersion."""
|
|
476
|
+
|
|
477
|
+
snapshots = AgentSystemSnapshotSerializer(many=True, read_only=True)
|
|
478
|
+
created_by_email = serializers.EmailField(
|
|
479
|
+
source='created_by.email', read_only=True, allow_null=True
|
|
480
|
+
)
|
|
481
|
+
|
|
482
|
+
class Meta:
|
|
483
|
+
model = AgentSystemVersion
|
|
484
|
+
fields = [
|
|
485
|
+
"id",
|
|
486
|
+
"version",
|
|
487
|
+
"is_active",
|
|
488
|
+
"is_draft",
|
|
489
|
+
"notes",
|
|
490
|
+
"created_at",
|
|
491
|
+
"published_at",
|
|
492
|
+
"created_by",
|
|
493
|
+
"created_by_email",
|
|
494
|
+
"snapshots",
|
|
495
|
+
]
|
|
496
|
+
read_only_fields = ["id", "created_at", "published_at", "created_by"]
|
|
497
|
+
|
|
498
|
+
|
|
499
|
+
class AgentSystemListSerializer(serializers.ModelSerializer):
|
|
500
|
+
"""Serializer for listing AgentSystems."""
|
|
501
|
+
|
|
502
|
+
entry_agent_name = serializers.CharField(source='entry_agent.name', read_only=True)
|
|
503
|
+
entry_agent_slug = serializers.CharField(source='entry_agent.slug', read_only=True)
|
|
504
|
+
member_count = serializers.SerializerMethodField()
|
|
505
|
+
active_version = serializers.SerializerMethodField()
|
|
506
|
+
|
|
507
|
+
class Meta:
|
|
508
|
+
model = AgentSystem
|
|
509
|
+
fields = [
|
|
510
|
+
"id",
|
|
511
|
+
"slug",
|
|
512
|
+
"name",
|
|
513
|
+
"description",
|
|
514
|
+
"entry_agent",
|
|
515
|
+
"entry_agent_name",
|
|
516
|
+
"entry_agent_slug",
|
|
517
|
+
"is_active",
|
|
518
|
+
"member_count",
|
|
519
|
+
"active_version",
|
|
520
|
+
"created_at",
|
|
521
|
+
"updated_at",
|
|
522
|
+
]
|
|
523
|
+
read_only_fields = ["id", "created_at", "updated_at"]
|
|
524
|
+
|
|
525
|
+
def get_member_count(self, obj):
|
|
526
|
+
return obj.members.count()
|
|
527
|
+
|
|
528
|
+
def get_active_version(self, obj):
|
|
529
|
+
version = obj.versions.filter(is_active=True).first()
|
|
530
|
+
if version:
|
|
531
|
+
return {"id": str(version.id), "version": version.version}
|
|
532
|
+
return None
|
|
533
|
+
|
|
534
|
+
|
|
535
|
+
class AgentSystemDetailSerializer(serializers.ModelSerializer):
|
|
536
|
+
"""Serializer for AgentSystem detail view."""
|
|
537
|
+
|
|
538
|
+
entry_agent_name = serializers.CharField(source='entry_agent.name', read_only=True)
|
|
539
|
+
entry_agent_slug = serializers.CharField(source='entry_agent.slug', read_only=True)
|
|
540
|
+
members = AgentSystemMemberSerializer(many=True, read_only=True)
|
|
541
|
+
versions = AgentSystemVersionSerializer(many=True, read_only=True)
|
|
542
|
+
dependency_graph = serializers.SerializerMethodField()
|
|
543
|
+
|
|
544
|
+
class Meta:
|
|
545
|
+
model = AgentSystem
|
|
546
|
+
fields = [
|
|
547
|
+
"id",
|
|
548
|
+
"slug",
|
|
549
|
+
"name",
|
|
550
|
+
"description",
|
|
551
|
+
"entry_agent",
|
|
552
|
+
"entry_agent_name",
|
|
553
|
+
"entry_agent_slug",
|
|
554
|
+
"is_active",
|
|
555
|
+
"members",
|
|
556
|
+
"versions",
|
|
557
|
+
"dependency_graph",
|
|
558
|
+
"created_at",
|
|
559
|
+
"updated_at",
|
|
560
|
+
]
|
|
561
|
+
read_only_fields = ["id", "created_at", "updated_at"]
|
|
562
|
+
|
|
563
|
+
def get_dependency_graph(self, obj):
|
|
564
|
+
return obj.get_dependency_graph()
|
|
565
|
+
|
|
566
|
+
|
|
567
|
+
class AgentSystemCreateSerializer(serializers.Serializer):
|
|
568
|
+
"""Serializer for creating an AgentSystem."""
|
|
569
|
+
|
|
570
|
+
slug = serializers.SlugField(max_length=100)
|
|
571
|
+
name = serializers.CharField(max_length=255)
|
|
572
|
+
description = serializers.CharField(required=False, default="")
|
|
573
|
+
entry_agent_id = serializers.UUIDField(help_text="ID of the entry point agent")
|
|
574
|
+
auto_discover = serializers.BooleanField(
|
|
575
|
+
default=True,
|
|
576
|
+
help_text="Automatically discover and add all reachable sub-agents",
|
|
577
|
+
)
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
class AddMemberSerializer(serializers.Serializer):
|
|
581
|
+
"""Serializer for adding a member to a system."""
|
|
582
|
+
|
|
583
|
+
agent_id = serializers.UUIDField(help_text="ID of the agent to add")
|
|
584
|
+
role = serializers.ChoiceField(
|
|
585
|
+
choices=AgentSystemMember.Role.choices,
|
|
586
|
+
default=AgentSystemMember.Role.SPECIALIST,
|
|
587
|
+
)
|
|
588
|
+
notes = serializers.CharField(required=False, default="")
|
|
589
|
+
|
|
590
|
+
|
|
591
|
+
class PublishVersionSerializer(serializers.Serializer):
|
|
592
|
+
"""Serializer for publishing a system version."""
|
|
593
|
+
|
|
594
|
+
version = serializers.CharField(
|
|
595
|
+
max_length=50,
|
|
596
|
+
help_text="Version string (e.g., '1.0.0', '2024-01-15')",
|
|
597
|
+
)
|
|
598
|
+
notes = serializers.CharField(
|
|
599
|
+
required=False,
|
|
600
|
+
default="",
|
|
601
|
+
help_text="Release notes for this version",
|
|
602
|
+
)
|
|
603
|
+
make_active = serializers.BooleanField(
|
|
604
|
+
default=False,
|
|
605
|
+
help_text="Whether to make this the active version immediately",
|
|
606
|
+
)
|