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.
@@ -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
+ )