django-agent-studio 0.3.1__py3-none-any.whl → 0.3.2__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.
@@ -60,11 +60,16 @@
60
60
  </div>
61
61
  </div>
62
62
  <div class="flex items-center space-x-3">
63
- <a href="{% url 'agent_studio:system_list' %}"
63
+ <a href="{% url 'agent_studio:system_collaborators' system.id %}"
64
+ class="text-gray-600 hover:text-gray-800 px-3 py-1.5 border border-gray-300 rounded-lg text-sm"
65
+ title="Manage collaborators">
66
+ <i class="pi pi-users"></i>
67
+ </a>
68
+ <a href="{% url 'agent_studio:system_list' %}"
64
69
  class="text-gray-600 hover:text-gray-800 px-3 py-1.5 border border-gray-300 rounded-lg text-sm">
65
70
  ← Back to Systems
66
71
  </a>
67
- <button @click="clearChat"
72
+ <button @click="clearChat"
68
73
  class="text-gray-600 hover:text-gray-800 px-3 py-1.5 border border-gray-300 rounded-lg text-sm">
69
74
  Clear Chat
70
75
  </button>
@@ -59,11 +59,16 @@
59
59
  </div>
60
60
  </div>
61
61
  <div class="flex items-center space-x-3">
62
- <a href="{% url 'agent_studio:agent_edit' agent.id %}"
62
+ <a href="{% url 'agent_studio:agent_collaborators' agent.id %}"
63
+ class="text-gray-600 hover:text-gray-800 px-3 py-1.5 border border-gray-300 rounded-lg text-sm"
64
+ title="Manage collaborators">
65
+ <i class="pi pi-users"></i>
66
+ </a>
67
+ <a href="{% url 'agent_studio:agent_edit' agent.id %}"
63
68
  class="text-gray-600 hover:text-gray-800 px-3 py-1.5 border border-gray-300 rounded-lg text-sm">
64
69
  ← Back to Editor
65
70
  </a>
66
- <button @click="clearChat"
71
+ <button @click="clearChat"
67
72
  class="text-gray-600 hover:text-gray-800 px-3 py-1.5 border border-gray-300 rounded-lg text-sm">
68
73
  Clear Chat
69
74
  </button>
@@ -15,13 +15,16 @@ urlpatterns = [
15
15
 
16
16
  # Systems (multi-agent systems)
17
17
  path("systems/", views.SystemListView.as_view(), name="system_list"),
18
+ path("systems/create/", views.SystemCreateView.as_view(), name="system_create"),
18
19
  path("systems/<uuid:system_id>/test/", views.SystemTestView.as_view(), name="system_test"),
20
+ path("systems/<uuid:system_id>/collaborators/", views.SystemCollaboratorsView.as_view(), name="system_collaborators"),
19
21
 
20
22
  # Agent builder/editor
21
23
  path("agents/", views.AgentListView.as_view(), name="agent_list"),
22
24
  path("agents/new/", views.AgentBuilderView.as_view(), name="agent_create"),
23
25
  path("agents/<uuid:agent_id>/", views.AgentBuilderView.as_view(), name="agent_edit"),
24
26
  path("agents/<uuid:agent_id>/test/", views.AgentTestView.as_view(), name="agent_test"),
27
+ path("agents/<uuid:agent_id>/collaborators/", views.AgentCollaboratorsView.as_view(), name="agent_collaborators"),
25
28
 
26
29
  # API endpoints
27
30
  path("api/", include(api_urls)),
@@ -6,7 +6,14 @@ from django.db.models import Q
6
6
  from django.views.generic import TemplateView, ListView
7
7
  from django.contrib.auth.mixins import LoginRequiredMixin
8
8
 
9
- from django_agent_runtime.models import AgentDefinition, AgentSystem
9
+ from django_agent_runtime.models import (
10
+ AgentDefinition,
11
+ AgentSystem,
12
+ AgentSystemMember,
13
+ AgentCollaborator,
14
+ SystemCollaborator,
15
+ CollaboratorRole,
16
+ )
10
17
 
11
18
 
12
19
  class AgentAccessMixin:
@@ -14,25 +21,170 @@ class AgentAccessMixin:
14
21
  Mixin that provides consistent agent access logic.
15
22
 
16
23
  - Superusers can access all agents
17
- - Regular users can access their own agents
24
+ - Owners can access their own agents
25
+ - Collaborators can access agents they've been granted access to
26
+ - Users with system access can access agents in that system
18
27
  """
19
28
 
20
29
  def get_user_agents_queryset(self):
21
30
  """Get queryset of agents accessible to the current user."""
22
31
  if self.request.user.is_superuser:
23
32
  return AgentDefinition.objects.all()
24
- return AgentDefinition.objects.filter(owner=self.request.user)
25
33
 
26
- def get_agent_for_user(self, agent_id):
34
+ user = self.request.user
35
+
36
+ # Get system IDs the user has access to (owner or collaborator)
37
+ accessible_system_ids = AgentSystem.objects.filter(
38
+ Q(owner=user) | Q(collaborators__user=user)
39
+ ).values_list('id', flat=True)
40
+
41
+ # Get agent IDs that are members of accessible systems
42
+ agents_via_systems = AgentSystemMember.objects.filter(
43
+ system_id__in=accessible_system_ids
44
+ ).values_list('agent_id', flat=True)
45
+
46
+ return AgentDefinition.objects.filter(
47
+ Q(owner=user) |
48
+ Q(collaborators__user=user) |
49
+ Q(id__in=agents_via_systems)
50
+ ).distinct()
51
+
52
+ def get_agent_for_user(self, agent_id, require_edit=False):
27
53
  """
28
54
  Get a specific agent if the user has access.
29
55
 
30
- - Superusers can access any agent
31
- - Regular users can access their own agents
56
+ Args:
57
+ agent_id: The agent's ID
58
+ require_edit: If True, requires edit permission (editor or admin role)
59
+
60
+ Returns:
61
+ AgentDefinition if user has access
62
+
63
+ Raises:
64
+ AgentDefinition.DoesNotExist if no access
32
65
  """
33
66
  if self.request.user.is_superuser:
34
67
  return AgentDefinition.objects.get(id=agent_id)
35
- return AgentDefinition.objects.get(id=agent_id, owner=self.request.user)
68
+
69
+ agent = AgentDefinition.objects.get(id=agent_id)
70
+ user = self.request.user
71
+
72
+ # Owner always has full access
73
+ if agent.owner == user:
74
+ return agent
75
+
76
+ # Check direct collaborator access
77
+ try:
78
+ collab = AgentCollaborator.objects.get(agent=agent, user=user)
79
+ if require_edit and not collab.can_edit:
80
+ raise AgentDefinition.DoesNotExist("Edit permission required")
81
+ return agent
82
+ except AgentCollaborator.DoesNotExist:
83
+ pass
84
+
85
+ # Check if user has access via a system that contains this agent
86
+ agent_system_ids = AgentSystemMember.objects.filter(
87
+ agent=agent
88
+ ).values_list('system_id', flat=True)
89
+
90
+ if agent_system_ids:
91
+ # Check for system owner or collaborator access
92
+ system_collab = SystemCollaborator.objects.filter(
93
+ system_id__in=agent_system_ids, user=user
94
+ ).first()
95
+ if system_collab:
96
+ if require_edit and not system_collab.can_edit:
97
+ raise AgentDefinition.DoesNotExist("Edit permission required")
98
+ return agent
99
+
100
+ # Check if user owns any of these systems
101
+ if AgentSystem.objects.filter(id__in=agent_system_ids, owner=user).exists():
102
+ return agent
103
+
104
+ raise AgentDefinition.DoesNotExist("No access to this agent")
105
+
106
+ def get_agent_role(self, agent):
107
+ """
108
+ Get the user's role for an agent.
109
+
110
+ Returns:
111
+ 'owner', 'admin', 'editor', 'viewer', or None
112
+ Also returns tuple (role, source) where source is 'direct' or 'system:<name>'
113
+ """
114
+ user = self.request.user
115
+ if user.is_superuser or agent.owner == user:
116
+ return 'owner'
117
+
118
+ # Check direct collaborator
119
+ try:
120
+ collab = AgentCollaborator.objects.get(agent=agent, user=user)
121
+ return collab.role
122
+ except AgentCollaborator.DoesNotExist:
123
+ pass
124
+
125
+ # Check system-level access
126
+ agent_systems = AgentSystemMember.objects.filter(
127
+ agent=agent
128
+ ).select_related('system')
129
+
130
+ for member in agent_systems:
131
+ system = member.system
132
+ if system.owner == user:
133
+ return 'owner'
134
+ try:
135
+ sys_collab = SystemCollaborator.objects.get(system=system, user=user)
136
+ return sys_collab.role
137
+ except SystemCollaborator.DoesNotExist:
138
+ continue
139
+
140
+ return None
141
+
142
+ def get_agent_access_info(self, agent):
143
+ """
144
+ Get detailed access info for an agent.
145
+
146
+ Returns dict with:
147
+ - role: 'owner', 'admin', 'editor', 'viewer', or None
148
+ - source: 'direct', 'system', or None
149
+ - system_name: Name of system granting access (if source is 'system')
150
+ """
151
+ user = self.request.user
152
+ if user.is_superuser or agent.owner == user:
153
+ return {'role': 'owner', 'source': 'direct', 'system_name': None}
154
+
155
+ # Check direct collaborator
156
+ try:
157
+ collab = AgentCollaborator.objects.get(agent=agent, user=user)
158
+ return {'role': collab.role, 'source': 'direct', 'system_name': None}
159
+ except AgentCollaborator.DoesNotExist:
160
+ pass
161
+
162
+ # Check system-level access
163
+ agent_systems = AgentSystemMember.objects.filter(
164
+ agent=agent
165
+ ).select_related('system')
166
+
167
+ for member in agent_systems:
168
+ system = member.system
169
+ if system.owner == user:
170
+ return {'role': 'owner', 'source': 'system', 'system_name': system.name}
171
+ try:
172
+ sys_collab = SystemCollaborator.objects.get(system=system, user=user)
173
+ return {'role': sys_collab.role, 'source': 'system', 'system_name': system.name}
174
+ except SystemCollaborator.DoesNotExist:
175
+ continue
176
+
177
+ return {'role': None, 'source': None, 'system_name': None}
178
+
179
+ def can_edit_agent(self, agent):
180
+ """Check if user can edit the agent."""
181
+ role = self.get_agent_role(agent)
182
+ return role in ['owner', 'admin', 'editor']
183
+
184
+ def can_admin_agent(self, agent):
185
+ """Check if user can manage collaborators on the agent."""
186
+ role = self.get_agent_role(agent)
187
+ return role in ['owner', 'admin']
36
188
 
37
189
 
38
190
  class SystemAccessMixin:
@@ -40,27 +192,76 @@ class SystemAccessMixin:
40
192
  Mixin that provides consistent system access logic.
41
193
 
42
194
  - Superusers can access all systems
43
- - Regular users can access their own systems
195
+ - Owners can access their own systems
196
+ - Collaborators can access systems they've been granted access to
44
197
  """
45
198
 
46
199
  def get_user_systems_queryset(self):
47
200
  """Get queryset of systems accessible to the current user."""
48
201
  if self.request.user.is_superuser:
49
202
  return AgentSystem.objects.all()
50
- return AgentSystem.objects.filter(owner=self.request.user)
203
+ # Include owned systems and systems where user is a collaborator
204
+ return AgentSystem.objects.filter(
205
+ Q(owner=self.request.user) |
206
+ Q(collaborators__user=self.request.user)
207
+ ).distinct()
51
208
 
52
- def get_system_for_user(self, system_id):
209
+ def get_system_for_user(self, system_id, require_edit=False):
53
210
  """
54
211
  Get a specific system if the user has access.
55
212
 
56
- - Superusers can access any system
57
- - Regular users can access their own systems
213
+ Args:
214
+ system_id: The system's ID
215
+ require_edit: If True, requires edit permission (editor or admin role)
216
+
217
+ Returns:
218
+ AgentSystem if user has access
219
+
220
+ Raises:
221
+ AgentSystem.DoesNotExist if no access
58
222
  """
59
223
  if self.request.user.is_superuser:
60
224
  return AgentSystem.objects.select_related('entry_agent').get(id=system_id)
61
- return AgentSystem.objects.select_related('entry_agent').get(
62
- id=system_id, owner=self.request.user
63
- )
225
+
226
+ system = AgentSystem.objects.select_related('entry_agent').get(id=system_id)
227
+
228
+ # Owner always has full access
229
+ if system.owner == self.request.user:
230
+ return system
231
+
232
+ # Check collaborator access
233
+ try:
234
+ collab = SystemCollaborator.objects.get(system=system, user=self.request.user)
235
+ if require_edit and not collab.can_edit:
236
+ raise AgentSystem.DoesNotExist("Edit permission required")
237
+ return system
238
+ except SystemCollaborator.DoesNotExist:
239
+ raise AgentSystem.DoesNotExist("No access to this system")
240
+
241
+ def get_system_role(self, system):
242
+ """
243
+ Get the user's role for a system.
244
+
245
+ Returns:
246
+ 'owner', 'admin', 'editor', 'viewer', or None
247
+ """
248
+ if self.request.user.is_superuser or system.owner == self.request.user:
249
+ return 'owner'
250
+ try:
251
+ collab = SystemCollaborator.objects.get(system=system, user=self.request.user)
252
+ return collab.role
253
+ except SystemCollaborator.DoesNotExist:
254
+ return None
255
+
256
+ def can_edit_system(self, system):
257
+ """Check if user can edit the system."""
258
+ role = self.get_system_role(system)
259
+ return role in ['owner', 'admin', 'editor']
260
+
261
+ def can_admin_system(self, system):
262
+ """Check if user can manage collaborators on the system."""
263
+ role = self.get_system_role(system)
264
+ return role in ['owner', 'admin']
64
265
 
65
266
 
66
267
  class StudioHomeView(LoginRequiredMixin, AgentAccessMixin, SystemAccessMixin, TemplateView):
@@ -144,6 +345,18 @@ class SystemListView(LoginRequiredMixin, SystemAccessMixin, ListView):
144
345
  ).prefetch_related('members__agent').order_by("-updated_at")
145
346
 
146
347
 
348
+ class SystemCreateView(LoginRequiredMixin, AgentAccessMixin, TemplateView):
349
+ """Create a new multi-agent system."""
350
+
351
+ template_name = "django_agent_studio/system_create.html"
352
+
353
+ def get_context_data(self, **kwargs):
354
+ context = super().get_context_data(**kwargs)
355
+ # Get user's agents for the entry agent dropdown
356
+ context["agents"] = self.get_user_agents_queryset().order_by("name")
357
+ return context
358
+
359
+
147
360
  class SystemTestView(LoginRequiredMixin, SystemAccessMixin, TemplateView):
148
361
  """
149
362
  Full-screen system testing interface.
@@ -161,3 +374,81 @@ class SystemTestView(LoginRequiredMixin, SystemAccessMixin, TemplateView):
161
374
  context["agent"] = system.entry_agent # The entry point agent
162
375
  return context
163
376
 
377
+
378
+ class AgentCollaboratorsView(LoginRequiredMixin, AgentAccessMixin, TemplateView):
379
+ """Manage collaborators for an agent."""
380
+
381
+ template_name = "django_agent_studio/collaborators.html"
382
+
383
+ def get_context_data(self, **kwargs):
384
+ context = super().get_context_data(**kwargs)
385
+ agent_id = kwargs.get("agent_id")
386
+ agent = self.get_agent_for_user(agent_id)
387
+
388
+ context["object"] = agent
389
+ context["object_name"] = agent.name
390
+ context["object_type"] = "agent"
391
+ context["can_admin"] = self.can_admin_agent(agent)
392
+
393
+ # Owner info
394
+ if agent.owner:
395
+ context["owner_email"] = agent.owner.email
396
+ context["owner_initial"] = agent.owner.email[0].upper() if agent.owner.email else "?"
397
+ else:
398
+ context["owner_email"] = "No owner"
399
+ context["owner_initial"] = "?"
400
+
401
+ # Get systems this agent belongs to (for showing inherited access info)
402
+ agent_systems = AgentSystemMember.objects.filter(
403
+ agent=agent
404
+ ).select_related('system', 'system__owner')
405
+ context["parent_systems"] = [
406
+ {
407
+ 'id': str(member.system.id),
408
+ 'name': member.system.name,
409
+ 'role': member.role,
410
+ }
411
+ for member in agent_systems
412
+ ]
413
+
414
+ return context
415
+
416
+
417
+ class SystemCollaboratorsView(LoginRequiredMixin, SystemAccessMixin, TemplateView):
418
+ """Manage collaborators for a system."""
419
+
420
+ template_name = "django_agent_studio/collaborators.html"
421
+
422
+ def get_context_data(self, **kwargs):
423
+ context = super().get_context_data(**kwargs)
424
+ system_id = kwargs.get("system_id")
425
+ system = self.get_system_for_user(system_id)
426
+
427
+ context["object"] = system
428
+ context["object_name"] = system.name
429
+ context["object_type"] = "system"
430
+ context["can_admin"] = self.can_admin_system(system)
431
+
432
+ # Owner info
433
+ if system.owner:
434
+ context["owner_email"] = system.owner.email
435
+ context["owner_initial"] = system.owner.email[0].upper() if system.owner.email else "?"
436
+ else:
437
+ context["owner_email"] = "No owner"
438
+ context["owner_initial"] = "?"
439
+
440
+ # Get agents in this system (for showing what agents are included)
441
+ system_members = AgentSystemMember.objects.filter(
442
+ system=system
443
+ ).select_related('agent')
444
+ context["member_agents"] = [
445
+ {
446
+ 'id': str(member.agent.id),
447
+ 'name': member.agent.name,
448
+ 'role': member.role,
449
+ }
450
+ for member in system_members
451
+ ]
452
+
453
+ return context
454
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-agent-studio
3
- Version: 0.3.1
3
+ Version: 0.3.2
4
4
  Summary: Visual agent builder and management studio for Django - build custom GPTs with a two-pane interface
5
5
  Author: Chris Barry
6
6
  License: Business Source License 1.1
@@ -126,6 +126,7 @@ A visual agent builder and management interface for Django applications. Create,
126
126
 
127
127
  | Version | Date | Changes |
128
128
  |---------|------|---------|
129
+ | **0.3.2** | 2026-01-30 | **Multi-User Access Control** - Collaborator management UI, user search autocomplete, supports both email and username-based User models, system creation from homepage, permission inheritance display |
129
130
  | **0.3.1** | 2026-01-30 | **Bug Fixes** - Fixed duplicate message emit in dynamic agents, fixed escapejs encoding in templates, added 800px max-width constraint to system test view |
130
131
  | **0.3.0** | 2026-01-29 | **System Listing & Navigation** - Browse and test multi-agent systems from homepage, fixed URL routing for My Systems/My Agents links, system creation now supports optional entry agent |
131
132
  | **0.2.0** | 2026-01-28 | **Multi-Agent Systems** - System management UI, shared memory configuration, memory privacy controls, builder tools for managing agent systems |
@@ -1,15 +1,15 @@
1
1
  django_agent_studio/__init__.py,sha256=E2vGoil7ZmwTebaB5ap9Lt0ptAzqYB5xJpyi4bFbqL8,378
2
2
  django_agent_studio/apps.py,sha256=L89QWn4XOvPBs2z6qHAhaE4uZQpasJntYD75aSd2p_k,607
3
- django_agent_studio/urls.py,sha256=4Lge5RtvBNZlpt4UWvKvJgQdgX2_6jRyCrfy8GzIjnY,942
4
- django_agent_studio/views.py,sha256=K1fBnGgplJneNBZxQm5zfVz0NLC_OkaJ4jqWT3NqSPI,5327
3
+ django_agent_studio/urls.py,sha256=xlL1ZkVxbLXnorAgvL3onUpCtGmzsxp5aQputRzTui8,1269
4
+ django_agent_studio/views.py,sha256=IXYSWu-nDunVTQtWiq0fO89UsZQ9--25LtvLDye1wNg,15565
5
5
  django_agent_studio/agents/__init__.py,sha256=VYL_ato0DtggIo4BGRkyiz9cm1ARPXhhTQFzoG__NVM,800
6
6
  django_agent_studio/agents/builder.py,sha256=dRPQk5-AhUsTBOFxv8H4Uk2X2PfK631jjVJZ1w13GtM,146777
7
7
  django_agent_studio/agents/dynamic.py,sha256=b2bwvwF9DOjEds4c0748mjKzCWbymcSlR4B9nP9Bk4Q,25367
8
8
  django_agent_studio/api/__init__.py,sha256=vtBwuvBENyFFhFqCWyFsI6cYu4N9ZGqSMmHIRhr9a_U,45
9
9
  django_agent_studio/api/permissions.py,sha256=MutmA8TxZb4ZwGfeEoolK-QI04Gbcxs7DPNzkXe_Bss,5302
10
- django_agent_studio/api/serializers.py,sha256=0JJ7J-Rx_iDiZRZF8ja_kiUyRDcpDhRp-O-i1ifw9Zk,18870
11
- django_agent_studio/api/urls.py,sha256=KYdkpyYCvxRN0nfUs1188apGYMpJT5FcG8kxwYhRAIE,8800
12
- django_agent_studio/api/views.py,sha256=BqqxgPjnZUwYU6IVcagohg1mN4npinxPy4aBUkSsL0E,75071
10
+ django_agent_studio/api/serializers.py,sha256=qIQ74JzOdJRp_Sh2xtETuRwtRThcpn3EYS14rvAKdHA,23593
11
+ django_agent_studio/api/urls.py,sha256=xfL3AbTP0GKRYarDExvUoXuz0txhgNCumgjVehSfmTY,9893
12
+ django_agent_studio/api/views.py,sha256=fECFWpu08ibQpOR-sL7AVCoTh4Ox6cYUEm4lh5GAPsE,90869
13
13
  django_agent_studio/management/__init__.py,sha256=6O9RHMN_xMDrEzKWytpai6QqgTXZVqwRg4h9mIQWtA8,52
14
14
  django_agent_studio/management/commands/__init__.py,sha256=6O9RHMN_xMDrEzKWytpai6QqgTXZVqwRg4h9mIQWtA8,52
15
15
  django_agent_studio/migrations/0001_initial.py,sha256=ThIhf1X6ZaACQd-5GjJG-MDjIm6ETl0Nc2hcYK0L2Wg,4292
@@ -24,15 +24,17 @@ django_agent_studio/static/agent-frontend/chat-widget.js,sha256=Yla8YlsmMtdXZRjN
24
24
  django_agent_studio/static/django_agent_studio/js/builder.js,sha256=eEUw2z-pNdoU3xv3NhLQ-uDZV7tsf8Bawseg7B7dpCo,413948
25
25
  django_agent_studio/static/django_agent_studio/js/builder.js.map,sha256=sVkeGyZsBWEr4MKhqAfd3B4JL5n7D6eKc_4ZYUsbKO8,1633363
26
26
  django_agent_studio/static/django_agent_studio/js/style.css,sha256=rigQJy_oHIhgb1_7DwAQ_8G002gQnT0AXUtwxImWj1o,1626515
27
- django_agent_studio/templates/django_agent_studio/agent_list.html,sha256=Qw2Jz39qrde69mI4EjhfWyc5elyKcpFYhicrLqOJZzU,4521
27
+ django_agent_studio/templates/django_agent_studio/agent_list.html,sha256=pIW6cRQ-i_hKWB_qDUuSBbzZw2qL_qJumhrW8C4Rs14,4931
28
28
  django_agent_studio/templates/django_agent_studio/base.html,sha256=wSgwaqK1DAIIyYeZWsVvPlpAZyZHBEx3_NGtdRo0J3A,6019
29
29
  django_agent_studio/templates/django_agent_studio/builder.html,sha256=yPzb0Pdp0d7Sp7gVkJd7OouDq-toKCA8i7OJLU9x6Z8,1542
30
- django_agent_studio/templates/django_agent_studio/home.html,sha256=2YQXJww0JzSRakVt2uMKeSOcAXsF7QT3ef0U14pa-50,6470
31
- django_agent_studio/templates/django_agent_studio/system_list.html,sha256=IRWVQHsqtolfSDDPpOSKQNd6a1u9U9iQvTzFJWbm8DE,4026
32
- django_agent_studio/templates/django_agent_studio/system_test.html,sha256=kQAgUTMqAXjYFIcelxq34J2YXmFANWmd4Bz0UoU3fPs,3945
33
- django_agent_studio/templates/django_agent_studio/test.html,sha256=C4qxjrG8USjO_NBpVnyaDibsxJ9A6kwUHEAKYXN7Jh0,3797
34
- django_agent_studio-0.3.1.dist-info/licenses/LICENSE,sha256=WIh21lpD7d7xCUtLysKK-kbfW4SG7GNPf_k7_Xm_sZg,3851
35
- django_agent_studio-0.3.1.dist-info/METADATA,sha256=p7UkoDYVrWfniMIG9O23Ds_GmzWlz_a5fXDkd6mjYF8,16670
36
- django_agent_studio-0.3.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
37
- django_agent_studio-0.3.1.dist-info/top_level.txt,sha256=O1kqZzXPOsJlqnPSAcB2fH5WpJNY8ZNfHEJzX9_SZ0A,20
38
- django_agent_studio-0.3.1.dist-info/RECORD,,
30
+ django_agent_studio/templates/django_agent_studio/collaborators.html,sha256=qPV0YG8V8eFCdK3e--kgxh3iT4jPHAXCxkSzOBkx7bg,19482
31
+ django_agent_studio/templates/django_agent_studio/home.html,sha256=ebA-U1HseIzY5pPeXKluzI8vsKOh1owkKZxhys27Yns,6914
32
+ django_agent_studio/templates/django_agent_studio/system_create.html,sha256=MOhKMuiR2Iley0J7gvFk9yxLT51BqPrOhk0PbJ-QXjo,6392
33
+ django_agent_studio/templates/django_agent_studio/system_list.html,sha256=CN2o3nFpsZHwv6Wva1DkzYaAZnK204Q6FAqVH08L6_0,4666
34
+ django_agent_studio/templates/django_agent_studio/system_test.html,sha256=CANXocxO1dG2JZSSHrEIYWQovapBA2GVQ9U8MIBzRg4,4238
35
+ django_agent_studio/templates/django_agent_studio/test.html,sha256=y2BjAwq0zxjdoMEM8K_rH0zCjcj1DL-Jj2BIQTJorxA,4088
36
+ django_agent_studio-0.3.2.dist-info/licenses/LICENSE,sha256=WIh21lpD7d7xCUtLysKK-kbfW4SG7GNPf_k7_Xm_sZg,3851
37
+ django_agent_studio-0.3.2.dist-info/METADATA,sha256=NLLNO4VvoR9E0xXQdnEX5m_ffQac5pKQdvbSE4HGmjM,16899
38
+ django_agent_studio-0.3.2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
39
+ django_agent_studio-0.3.2.dist-info/top_level.txt,sha256=O1kqZzXPOsJlqnPSAcB2fH5WpJNY8ZNfHEJzX9_SZ0A,20
40
+ django_agent_studio-0.3.2.dist-info/RECORD,,