django-agent-studio 0.3.3__py3-none-any.whl → 0.3.5__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.
Files changed (22) hide show
  1. django_agent_studio/agents/dynamic.py +164 -4
  2. django_agent_studio/api/serializers.py +27 -8
  3. django_agent_studio/branding.py +103 -0
  4. django_agent_studio/static/agent-frontend/chat-widget.css +52 -0
  5. django_agent_studio/static/agent-frontend/chat-widget.js +222 -206
  6. django_agent_studio/static/django_agent_studio/js/builder.js +58 -58
  7. django_agent_studio/static/django_agent_studio/js/builder.js.map +1 -1
  8. django_agent_studio/static/django_agent_studio/js/style.css +1 -1
  9. django_agent_studio/templates/django_agent_studio/agent_list.html +31 -28
  10. django_agent_studio/templates/django_agent_studio/base.html +116 -28
  11. django_agent_studio/templates/django_agent_studio/builder.html +1 -1
  12. django_agent_studio/templates/django_agent_studio/collaborators.html +83 -95
  13. django_agent_studio/templates/django_agent_studio/home.html +66 -48
  14. django_agent_studio/templates/django_agent_studio/system_create.html +22 -24
  15. django_agent_studio/templates/django_agent_studio/system_list.html +38 -30
  16. django_agent_studio/templates/django_agent_studio/system_test.html +27 -21
  17. django_agent_studio/templates/django_agent_studio/test.html +22 -17
  18. {django_agent_studio-0.3.3.dist-info → django_agent_studio-0.3.5.dist-info}/METADATA +1 -1
  19. {django_agent_studio-0.3.3.dist-info → django_agent_studio-0.3.5.dist-info}/RECORD +22 -21
  20. {django_agent_studio-0.3.3.dist-info → django_agent_studio-0.3.5.dist-info}/WHEEL +0 -0
  21. {django_agent_studio-0.3.3.dist-info → django_agent_studio-0.3.5.dist-info}/licenses/LICENSE +0 -0
  22. {django_agent_studio-0.3.3.dist-info → django_agent_studio-0.3.5.dist-info}/top_level.txt +0 -0
@@ -1,51 +1,51 @@
1
1
  {% extends "django_agent_studio/base.html" %}
2
2
 
3
- {% block title %}Collaborators - {{ object_name }} - Agent Studio{% endblock %}
3
+ {% block title %}Collaborators - {{ object_name }} - {{ studio_app_name }}{% endblock %}
4
4
 
5
5
  {% block breadcrumbs %}
6
6
  <nav class="flex items-center space-x-2 ml-4 text-sm">
7
- <span class="text-gray-400">/</span>
7
+ <span class="text-white/40">/</span>
8
8
  {% if object_type == 'agent' %}
9
- <a href="{% url 'agent_studio:agent_list' %}" class="text-gray-500 hover:text-gray-700">My Agents</a>
10
- <span class="text-gray-400">/</span>
11
- <a href="{% url 'agent_studio:agent_edit' object.id %}" class="text-gray-500 hover:text-gray-700">{{ object_name }}</a>
9
+ <a href="{% url 'agent_studio:agent_list' %}" class="text-white/60 hover:text-white/90 transition-colors">My Agents</a>
10
+ <span class="text-white/40">/</span>
11
+ <a href="{% url 'agent_studio:agent_edit' object.id %}" class="text-white/60 hover:text-white/90 transition-colors">{{ object_name }}</a>
12
12
  {% else %}
13
- <a href="{% url 'agent_studio:system_list' %}" class="text-gray-500 hover:text-gray-700">My Systems</a>
14
- <span class="text-gray-400">/</span>
15
- <a href="{% url 'agent_studio:system_test' object.id %}" class="text-gray-500 hover:text-gray-700">{{ object_name }}</a>
13
+ <a href="{% url 'agent_studio:system_list' %}" class="text-white/60 hover:text-white/90 transition-colors">My Systems</a>
14
+ <span class="text-white/40">/</span>
15
+ <a href="{% url 'agent_studio:system_test' object.id %}" class="text-white/60 hover:text-white/90 transition-colors">{{ object_name }}</a>
16
16
  {% endif %}
17
- <span class="text-gray-400">/</span>
18
- <span class="text-gray-600">Collaborators</span>
17
+ <span class="text-white/40">/</span>
18
+ <span class="text-white/70">Collaborators</span>
19
19
  </nav>
20
20
  {% endblock %}
21
21
 
22
22
  {% block content %}
23
- <div class="h-full p-6 overflow-auto">
23
+ <div class="h-full p-6 overflow-auto bg-gradient-to-br from-slate-50 to-slate-100">
24
24
  <div class="max-w-4xl mx-auto">
25
25
  <!-- Header -->
26
26
  <div class="flex items-center justify-between mb-6">
27
27
  <div>
28
- <h1 class="text-2xl font-bold text-gray-900">👥 Collaborators</h1>
29
- <p class="text-gray-500 mt-1">Manage who can access {{ object_name }}</p>
28
+ <h1 class="text-2xl font-bold text-navy">👥 Collaborators</h1>
29
+ <p class="text-slate-500 mt-1">Manage who can access {{ object_name }}</p>
30
30
  </div>
31
31
  </div>
32
32
 
33
33
  {% if object_type == 'system' and member_agents %}
34
34
  <!-- System: Show included agents -->
35
- <div class="bg-blue-50 border border-blue-200 rounded-lg p-4 mb-6">
36
- <h3 class="font-semibold text-blue-800 mb-2">
37
- <i class="pi pi-info-circle mr-2"></i>Included Agents
35
+ <div class="bg-cyan/5 border border-cyan/30 rounded-xl p-4 mb-6">
36
+ <h3 class="font-semibold text-navy mb-2">
37
+ <i class="pi pi-info-circle mr-2 text-cyan"></i>Included Agents
38
38
  </h3>
39
- <p class="text-sm text-blue-700 mb-3">
39
+ <p class="text-sm text-slate-600 mb-3">
40
40
  Collaborators on this system automatically get access to all agents below:
41
41
  </p>
42
42
  <div class="flex flex-wrap gap-2">
43
43
  {% for agent in member_agents %}
44
44
  <a href="{% url 'agent_studio:agent_collaborators' agent.id %}"
45
- class="inline-flex items-center px-3 py-1.5 bg-white border border-blue-200 rounded-lg text-sm text-blue-700 hover:bg-blue-100 transition-colors">
46
- <i class="pi pi-android mr-1.5"></i>
45
+ class="inline-flex items-center px-3 py-1.5 bg-white border border-cyan/30 rounded-lg text-sm text-navy hover:bg-cyan/10 transition-colors">
46
+ <i class="pi pi-android mr-1.5 text-cyan"></i>
47
47
  {{ agent.name }}
48
- <span class="ml-1.5 text-xs text-blue-500">({{ agent.role }})</span>
48
+ <span class="ml-1.5 text-xs text-slate-400">({{ agent.role }})</span>
49
49
  </a>
50
50
  {% endfor %}
51
51
  </div>
@@ -54,7 +54,7 @@
54
54
 
55
55
  {% if object_type == 'agent' and parent_systems %}
56
56
  <!-- Agent: Show parent systems -->
57
- <div class="bg-amber-50 border border-amber-200 rounded-lg p-4 mb-6">
57
+ <div class="bg-amber-50 border border-amber-200 rounded-xl p-4 mb-6">
58
58
  <h3 class="font-semibold text-amber-800 mb-2">
59
59
  <i class="pi pi-info-circle mr-2"></i>Inherited Access
60
60
  </h3>
@@ -75,77 +75,77 @@
75
75
  {% endif %}
76
76
 
77
77
  <!-- Owner Info -->
78
- <div class="bg-white border border-gray-200 rounded-lg p-4 mb-6">
78
+ <div class="bg-white border border-slate-200 rounded-xl p-4 mb-6 shadow-sm">
79
79
  <div class="flex items-center justify-between">
80
80
  <div class="flex items-center space-x-3">
81
- <div class="w-10 h-10 bg-primary-100 rounded-full flex items-center justify-center">
82
- <span class="text-primary-600 font-semibold">{{ owner_initial }}</span>
81
+ <div class="w-10 h-10 bg-navy/10 rounded-full flex items-center justify-center">
82
+ <span class="text-navy font-semibold">{{ owner_initial }}</span>
83
83
  </div>
84
84
  <div>
85
- <p class="font-medium text-gray-800">{{ owner_email }}</p>
86
- <p class="text-sm text-gray-500">Owner</p>
85
+ <p class="font-medium text-navy">{{ owner_email }}</p>
86
+ <p class="text-sm text-slate-500">Owner</p>
87
87
  </div>
88
88
  </div>
89
- <span class="bg-primary-100 text-primary-700 px-3 py-1 rounded-full text-sm font-medium">Owner</span>
89
+ <span class="bg-navy/10 text-navy px-3 py-1 rounded-full text-sm font-medium">Owner</span>
90
90
  </div>
91
91
  </div>
92
92
 
93
93
  <!-- Add Collaborator Form -->
94
94
  {% if can_admin %}
95
- <div class="bg-white border border-gray-200 rounded-lg p-4 mb-6">
96
- <h3 class="font-semibold text-gray-800 mb-4">Add Collaborator</h3>
95
+ <div class="bg-white border border-slate-200 rounded-xl p-5 mb-6 shadow-sm">
96
+ <h3 class="font-semibold text-navy mb-4">Add Collaborator</h3>
97
97
  <form @submit.prevent="addCollaborator" class="flex items-end space-x-4">
98
98
  <div class="flex-1 relative">
99
- <label class="block text-sm font-medium text-gray-700 mb-1">Search User</label>
99
+ <label class="block text-sm font-medium text-navy mb-1">Search User</label>
100
100
  <input type="text" v-model="searchQuery" @input="searchUsers" @focus="showResults = true"
101
- class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500"
101
+ class="w-full px-4 py-2.5 border border-slate-200 rounded-lg focus:ring-2 focus:ring-cyan/30 focus:border-cyan transition-all"
102
102
  placeholder="Type to search by name or email..."
103
103
  autocomplete="off">
104
104
  <!-- Search Results Dropdown -->
105
105
  <div v-if="showResults && (searchResults.length > 0 || searchQuery.length >= 2)"
106
- class="absolute z-10 w-full mt-1 bg-white border border-gray-200 rounded-lg shadow-lg max-h-60 overflow-auto">
107
- <div v-if="searching" class="p-3 text-center text-gray-500">
106
+ class="absolute z-10 w-full mt-1 bg-white border border-slate-200 rounded-xl shadow-lg max-h-60 overflow-auto">
107
+ <div v-if="searching" class="p-3 text-center text-slate-500">
108
108
  <i class="pi pi-spin pi-spinner mr-2"></i>Searching...
109
109
  </div>
110
- <div v-else-if="searchResults.length === 0 && searchQuery.length >= 2" class="p-3 text-center text-gray-500">
110
+ <div v-else-if="searchResults.length === 0 && searchQuery.length >= 2" class="p-3 text-center text-slate-500">
111
111
  No users found
112
112
  </div>
113
113
  <div v-else>
114
114
  <button v-for="user in searchResults" :key="user.id" type="button"
115
115
  @click="selectUser(user)"
116
- class="w-full px-3 py-2 text-left hover:bg-gray-50 flex items-center space-x-3 border-b border-gray-100 last:border-0">
117
- <div class="w-8 h-8 bg-primary-100 rounded-full flex items-center justify-center flex-shrink-0">
118
- <span class="text-primary-600 font-semibold text-sm">[[ user.name.charAt(0).toUpperCase() ]]</span>
116
+ class="w-full px-3 py-2 text-left hover:bg-cyan/5 flex items-center space-x-3 border-b border-slate-100 last:border-0 transition-colors">
117
+ <div class="w-8 h-8 bg-cyan/10 rounded-full flex items-center justify-center flex-shrink-0">
118
+ <span class="text-navy font-semibold text-sm">[[ user.name.charAt(0).toUpperCase() ]]</span>
119
119
  </div>
120
120
  <div class="min-w-0 flex-1">
121
- <p class="font-medium text-gray-800 truncate">[[ user.name ]]</p>
122
- <p class="text-sm text-gray-500 truncate">[[ user.email ]]</p>
121
+ <p class="font-medium text-navy truncate">[[ user.name ]]</p>
122
+ <p class="text-sm text-slate-500 truncate">[[ user.email ]]</p>
123
123
  </div>
124
124
  </button>
125
125
  </div>
126
126
  </div>
127
127
  <!-- Selected User Display -->
128
- <div v-if="selectedUser" class="mt-2 flex items-center space-x-2 bg-primary-50 border border-primary-200 rounded-lg px-3 py-2">
129
- <div class="w-6 h-6 bg-primary-100 rounded-full flex items-center justify-center">
130
- <span class="text-primary-600 font-semibold text-xs">[[ selectedUser.name.charAt(0).toUpperCase() ]]</span>
128
+ <div v-if="selectedUser" class="mt-2 flex items-center space-x-2 bg-cyan/10 border border-cyan/30 rounded-lg px-3 py-2">
129
+ <div class="w-6 h-6 bg-cyan/20 rounded-full flex items-center justify-center">
130
+ <span class="text-navy font-semibold text-xs">[[ selectedUser.name.charAt(0).toUpperCase() ]]</span>
131
131
  </div>
132
- <span class="text-sm text-primary-800 flex-1">[[ selectedUser.display ]]</span>
133
- <button type="button" @click="clearSelection" class="text-primary-600 hover:text-primary-800">
132
+ <span class="text-sm text-navy flex-1">[[ selectedUser.display ]]</span>
133
+ <button type="button" @click="clearSelection" class="text-navy/60 hover:text-navy">
134
134
  <i class="pi pi-times text-sm"></i>
135
135
  </button>
136
136
  </div>
137
137
  </div>
138
138
  <div class="w-40">
139
- <label class="block text-sm font-medium text-gray-700 mb-1">Role</label>
139
+ <label class="block text-sm font-medium text-navy mb-1">Role</label>
140
140
  <select v-model="newRole"
141
- class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500">
141
+ class="w-full px-4 py-2.5 border border-slate-200 rounded-lg focus:ring-2 focus:ring-cyan/30 focus:border-cyan transition-all">
142
142
  <option value="viewer">Viewer</option>
143
143
  <option value="editor">Editor</option>
144
144
  <option value="admin">Admin</option>
145
145
  </select>
146
146
  </div>
147
147
  <button type="submit" :disabled="adding || !selectedUser"
148
- class="bg-primary-600 hover:bg-primary-700 text-white px-4 py-2 rounded-lg flex items-center space-x-2 transition-colors disabled:opacity-50">
148
+ class="bg-cyan hover:bg-cyan-dark text-navy px-5 py-2.5 rounded-xl flex items-center space-x-2 transition-all disabled:opacity-50 font-medium hover:shadow-md">
149
149
  <i class="pi pi-plus"></i>
150
150
  <span>[[ adding ? 'Adding...' : 'Add' ]]</span>
151
151
  </button>
@@ -155,49 +155,51 @@
155
155
  {% endif %}
156
156
 
157
157
  <!-- Collaborators List -->
158
- <div class="bg-white border border-gray-200 rounded-lg overflow-hidden">
159
- <div class="px-4 py-3 border-b border-gray-200 bg-gray-50">
160
- <h3 class="font-semibold text-gray-800">Collaborators ([[ collaborators.length ]])</h3>
158
+ <div class="bg-white border border-slate-200 rounded-xl overflow-hidden shadow-sm">
159
+ <div class="px-5 py-3 border-b border-slate-100 bg-slate-50/50">
160
+ <h3 class="font-semibold text-navy">Collaborators ([[ collaborators.length ]])</h3>
161
161
  </div>
162
162
 
163
- <div v-if="loading" class="p-8 text-center text-gray-500">
164
- <i class="pi pi-spin pi-spinner text-2xl"></i>
163
+ <div v-if="loading" class="p-8 text-center text-slate-500">
164
+ <i class="pi pi-spin pi-spinner text-2xl text-cyan"></i>
165
165
  <p class="mt-2">Loading collaborators...</p>
166
166
  </div>
167
167
 
168
- <div v-else-if="collaborators.length === 0" class="p-8 text-center text-gray-500">
169
- <i class="pi pi-users text-4xl mb-2"></i>
170
- <p>No collaborators yet</p>
171
- <p class="text-sm">Add collaborators to share access to this {{ object_type }}</p>
168
+ <div v-else-if="collaborators.length === 0" class="p-8 text-center">
169
+ <div class="w-12 h-12 bg-slate-100 rounded-full flex items-center justify-center mx-auto mb-3">
170
+ <i class="pi pi-users text-2xl text-slate-400"></i>
171
+ </div>
172
+ <p class="text-slate-500">No collaborators yet</p>
173
+ <p class="text-sm text-slate-400">Add collaborators to share access to this {{ object_type }}</p>
172
174
  </div>
173
175
 
174
- <div v-else class="divide-y divide-gray-100">
176
+ <div v-else class="divide-y divide-slate-100">
175
177
  <div v-for="collab in collaborators" :key="collab.id"
176
- class="p-4 flex items-center justify-between hover:bg-gray-50">
178
+ class="p-4 flex items-center justify-between hover:bg-slate-50/50 transition-colors">
177
179
  <div class="flex items-center space-x-3">
178
- <div class="w-10 h-10 bg-gray-100 rounded-full flex items-center justify-center">
179
- <span class="text-gray-600 font-semibold">[[ getInitial(collab.user_email) ]]</span>
180
+ <div class="w-10 h-10 bg-slate-100 rounded-full flex items-center justify-center">
181
+ <span class="text-slate-600 font-semibold">[[ getInitial(collab.user_email) ]]</span>
180
182
  </div>
181
183
  <div>
182
- <p class="font-medium text-gray-800">[[ collab.user_name || collab.user_email ]]</p>
183
- <p class="text-sm text-gray-500">[[ collab.user_email ]]</p>
184
+ <p class="font-medium text-navy">[[ collab.user_name || collab.user_email ]]</p>
185
+ <p class="text-sm text-slate-500">[[ collab.user_email ]]</p>
184
186
  </div>
185
187
  </div>
186
188
  <div class="flex items-center space-x-3">
187
189
  {% if can_admin %}
188
190
  <select v-model="collab.role" @change="updateRole(collab)"
189
- class="px-3 py-1.5 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-primary-500">
191
+ class="px-3 py-1.5 border border-slate-200 rounded-lg text-sm focus:ring-2 focus:ring-cyan/30 focus:border-cyan transition-all">
190
192
  <option value="viewer">Viewer</option>
191
193
  <option value="editor">Editor</option>
192
194
  <option value="admin">Admin</option>
193
195
  </select>
194
196
  <button @click="removeCollaborator(collab)"
195
- class="text-red-600 hover:text-red-700 p-1.5 hover:bg-red-50 rounded"
197
+ class="text-red-500 hover:text-red-600 p-1.5 hover:bg-red-50 rounded-lg transition-colors"
196
198
  title="Remove collaborator">
197
199
  <i class="pi pi-trash"></i>
198
200
  </button>
199
201
  {% else %}
200
- <span class="px-3 py-1.5 bg-gray-100 text-gray-700 rounded-lg text-sm">[[ collab.role_display ]]</span>
202
+ <span class="px-3 py-1.5 bg-slate-100 text-slate-700 rounded-lg text-sm">[[ collab.role_display ]]</span>
201
203
  {% endif %}
202
204
  </div>
203
205
  </div>
@@ -205,26 +207,26 @@
205
207
  </div>
206
208
 
207
209
  <!-- Role Descriptions -->
208
- <div class="mt-6 bg-gray-50 border border-gray-200 rounded-lg p-4">
209
- <h4 class="font-medium text-gray-800 mb-3">Role Permissions</h4>
210
+ <div class="mt-6 bg-white border border-slate-200 rounded-xl p-5 shadow-sm">
211
+ <h4 class="font-medium text-navy mb-3">Role Permissions</h4>
210
212
  <div class="grid grid-cols-1 md:grid-cols-3 gap-4 text-sm">
211
- <div>
212
- <p class="font-medium text-gray-700">Viewer</p>
213
- <p class="text-gray-500">Can view and test the {{ object_type }}</p>
213
+ <div class="p-3 bg-slate-50 rounded-lg">
214
+ <p class="font-medium text-navy">Viewer</p>
215
+ <p class="text-slate-500">Can view and test the {{ object_type }}</p>
214
216
  </div>
215
- <div>
216
- <p class="font-medium text-gray-700">Editor</p>
217
- <p class="text-gray-500">Can view, test, and edit the {{ object_type }}</p>
217
+ <div class="p-3 bg-slate-50 rounded-lg">
218
+ <p class="font-medium text-navy">Editor</p>
219
+ <p class="text-slate-500">Can view, test, and edit the {{ object_type }}</p>
218
220
  </div>
219
- <div>
220
- <p class="font-medium text-gray-700">Admin</p>
221
- <p class="text-gray-500">Can view, test, edit, and manage collaborators</p>
221
+ <div class="p-3 bg-slate-50 rounded-lg">
222
+ <p class="font-medium text-navy">Admin</p>
223
+ <p class="text-slate-500">Can view, test, edit, and manage collaborators</p>
222
224
  </div>
223
225
  </div>
224
226
  {% if object_type == 'system' %}
225
- <div class="mt-4 pt-4 border-t border-gray-200">
226
- <p class="text-sm text-gray-600">
227
- <i class="pi pi-info-circle mr-1"></i>
227
+ <div class="mt-4 pt-4 border-t border-slate-100">
228
+ <p class="text-sm text-slate-600">
229
+ <i class="pi pi-info-circle mr-1 text-cyan"></i>
228
230
  <strong>Note:</strong> System collaborators automatically get the same access level to all agents in this system.
229
231
  </p>
230
232
  </div>
@@ -250,14 +252,12 @@ createApp({
250
252
  return {
251
253
  collaborators: [],
252
254
  loading: true,
253
- // Search state
254
255
  searchQuery: '',
255
256
  searchResults: [],
256
257
  selectedUser: null,
257
258
  showResults: false,
258
259
  searching: false,
259
260
  searchTimeout: null,
260
- // Form state
261
261
  newRole: 'viewer',
262
262
  adding: false,
263
263
  addError: null,
@@ -268,14 +268,11 @@ createApp({
268
268
  this.loading = true;
269
269
  try {
270
270
  const response = await fetch(apiUrl, {
271
- headers: {
272
- 'Content-Type': 'application/json',
273
- },
271
+ headers: { 'Content-Type': 'application/json' },
274
272
  credentials: 'same-origin',
275
273
  });
276
274
  if (response.ok) {
277
275
  const data = await response.json();
278
- // Handle both paginated and non-paginated responses
279
276
  this.collaborators = data.results !== undefined ? data.results : data;
280
277
  }
281
278
  } catch (error) {
@@ -285,15 +282,12 @@ createApp({
285
282
  }
286
283
  },
287
284
  searchUsers() {
288
- // Debounce search
289
285
  clearTimeout(this.searchTimeout);
290
286
  this.showResults = true;
291
-
292
287
  if (this.searchQuery.length < 2) {
293
288
  this.searchResults = [];
294
289
  return;
295
290
  }
296
-
297
291
  this.searchTimeout = setTimeout(async () => {
298
292
  this.searching = true;
299
293
  try {
@@ -322,7 +316,6 @@ createApp({
322
316
  },
323
317
  async addCollaborator() {
324
318
  if (!this.selectedUser) return;
325
-
326
319
  this.adding = true;
327
320
  this.addError = null;
328
321
  try {
@@ -365,7 +358,6 @@ createApp({
365
358
  body: JSON.stringify({ role: collab.role }),
366
359
  });
367
360
  if (!response.ok) {
368
- // Revert on error
369
361
  await this.loadCollaborators();
370
362
  }
371
363
  } catch (error) {
@@ -378,9 +370,7 @@ createApp({
378
370
  try {
379
371
  const response = await fetch(`${apiUrl}${collab.id}/`, {
380
372
  method: 'DELETE',
381
- headers: {
382
- 'X-CSRFToken': this.getCsrfToken(),
383
- },
373
+ headers: { 'X-CSRFToken': this.getCsrfToken() },
384
374
  credentials: 'same-origin',
385
375
  });
386
376
  if (response.ok) {
@@ -405,7 +395,6 @@ createApp({
405
395
  },
406
396
  mounted() {
407
397
  this.loadCollaborators();
408
- // Close search results when clicking outside
409
398
  document.addEventListener('click', (e) => {
410
399
  if (!e.target.closest('.relative')) {
411
400
  this.showResults = false;
@@ -415,4 +404,3 @@ createApp({
415
404
  }).use(primevue.config.default).mount('#app');
416
405
  </script>
417
406
  {% endblock %}
418
-
@@ -1,88 +1,100 @@
1
1
  {% extends "django_agent_studio/base.html" %}
2
2
 
3
- {% block title %}Agent Studio - Home{% endblock %}
3
+ {% block title %}{{ studio_app_name }} - Home{% endblock %}
4
4
 
5
5
  {% block content %}
6
- <div class="h-full p-6 overflow-auto">
6
+ <div class="h-full p-6 overflow-auto bg-gradient-to-br from-slate-50 to-slate-100">
7
7
  <div class="max-w-6xl mx-auto">
8
8
  <!-- Welcome Section -->
9
9
  <div class="mb-8">
10
- <h1 class="text-3xl font-bold text-gray-900 mb-2">Welcome to Agent Studio</h1>
11
- <p class="text-gray-600">Build, customize, and manage your AI agents in one place.</p>
10
+ <h1 class="text-3xl font-bold text-navy mb-2">Welcome to Agent Studio</h1>
11
+ <p class="text-slate-600">Build, customize, and manage your AI agents in one place.</p>
12
12
  </div>
13
13
 
14
14
  <!-- Quick Actions -->
15
15
  <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-4 mb-8">
16
16
  <a href="{% url 'agent_studio:system_create' %}"
17
- class="bg-indigo-600 hover:bg-indigo-700 text-white rounded-lg p-5 transition-colors">
17
+ class="bg-navy hover:bg-navy-light text-white rounded-xl p-5 transition-all hover:shadow-lg hover:-translate-y-0.5 group">
18
18
  <div class="flex items-center space-x-3 mb-2">
19
- <span class="text-2xl">🔗</span>
19
+ <span class="text-2xl group-hover:scale-110 transition-transform">🔗</span>
20
20
  <span class="text-lg font-semibold">New System</span>
21
21
  </div>
22
- <p class="text-indigo-100 text-sm">Create a multi-agent system</p>
22
+ <p class="text-white/70 text-sm">Create a multi-agent system</p>
23
23
  </a>
24
24
 
25
25
  <a href="{% url 'agent_studio:agent_create' %}"
26
- class="bg-primary-600 hover:bg-primary-700 text-white rounded-lg p-5 transition-colors">
26
+ class="bg-cyan text-navy rounded-xl p-5 transition-all hover:shadow-lg hover:-translate-y-0.5 group hover:bg-cyan-dark">
27
27
  <div class="flex items-center space-x-3 mb-2">
28
- <span class="text-2xl">✨</span>
28
+ <span class="text-2xl group-hover:scale-110 transition-transform">✨</span>
29
29
  <span class="text-lg font-semibold">New Agent</span>
30
30
  </div>
31
- <p class="text-primary-100 text-sm">Build a custom AI agent</p>
31
+ <p class="text-navy/70 text-sm">Build a custom AI agent</p>
32
32
  </a>
33
33
 
34
34
  <a href="{% url 'agent_studio:system_list' %}"
35
- class="bg-white hover:bg-gray-50 border border-gray-200 rounded-lg p-5 transition-colors">
35
+ class="bg-white hover:bg-slate-50 border border-slate-200 rounded-xl p-5 transition-all hover:shadow-md hover:border-cyan group">
36
36
  <div class="flex items-center space-x-3 mb-2">
37
- <span class="text-2xl">🔗</span>
38
- <span class="text-lg font-semibold text-gray-800">My Systems</span>
37
+ <span class="text-2xl group-hover:scale-110 transition-transform">🔗</span>
38
+ <span class="text-lg font-semibold text-navy">My Systems</span>
39
39
  </div>
40
- <p class="text-gray-600 text-sm">View multi-agent systems</p>
40
+ <p class="text-slate-600 text-sm">View multi-agent systems</p>
41
41
  </a>
42
42
 
43
43
  <a href="{% url 'agent_studio:agent_list' %}"
44
- class="bg-white hover:bg-gray-50 border border-gray-200 rounded-lg p-5 transition-colors">
44
+ class="bg-white hover:bg-slate-50 border border-slate-200 rounded-xl p-5 transition-all hover:shadow-md hover:border-cyan group">
45
45
  <div class="flex items-center space-x-3 mb-2">
46
- <span class="text-2xl">📋</span>
47
- <span class="text-lg font-semibold text-gray-800">My Agents</span>
46
+ <span class="text-2xl group-hover:scale-110 transition-transform">📋</span>
47
+ <span class="text-lg font-semibold text-navy">My Agents</span>
48
48
  </div>
49
- <p class="text-gray-600 text-sm">View and manage agents</p>
49
+ <p class="text-slate-600 text-sm">View and manage agents</p>
50
50
  </a>
51
51
 
52
- <div class="bg-white hover:bg-gray-50 border border-gray-200 rounded-lg p-5 transition-colors cursor-pointer opacity-60">
52
+ <div class="bg-white/50 border border-slate-200 border-dashed rounded-xl p-5 opacity-60 cursor-not-allowed">
53
53
  <div class="flex items-center space-x-3 mb-2">
54
54
  <span class="text-2xl">📚</span>
55
- <span class="text-lg font-semibold text-gray-800">Templates</span>
55
+ <span class="text-lg font-semibold text-slate-500">Templates</span>
56
56
  </div>
57
- <p class="text-gray-600 text-sm">Coming soon</p>
57
+ <p class="text-slate-400 text-sm">Coming soon</p>
58
58
  </div>
59
59
  </div>
60
60
 
61
61
  <!-- Recent Systems -->
62
62
  <div class="mb-8">
63
- <h2 class="text-xl font-semibold text-gray-800 mb-4">Recent Systems</h2>
63
+ <div class="flex items-center justify-between mb-4">
64
+ <h2 class="text-xl font-semibold text-navy">Recent Systems</h2>
65
+ <a href="{% url 'agent_studio:system_list' %}" class="text-sm text-cyan hover:text-cyan-dark font-medium">View all →</a>
66
+ </div>
64
67
  {% if recent_systems %}
65
68
  <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
66
69
  {% for system in recent_systems %}
67
70
  <a href="{% url 'agent_studio:system_test' system.id %}"
68
- class="bg-white border border-gray-200 rounded-lg p-4 hover:border-indigo-300 hover:shadow-sm transition-all">
69
- <div class="flex items-center space-x-3 mb-2">
70
- <span class="text-xl">🔗</span>
71
- <span class="font-medium text-gray-800">{{ system.name }}</span>
71
+ class="bg-white border border-slate-200 rounded-xl p-5 hover:border-cyan hover:shadow-md transition-all group">
72
+ <div class="flex items-center space-x-3 mb-3">
73
+ <div class="w-10 h-10 bg-navy/10 rounded-lg flex items-center justify-center group-hover:bg-cyan/20 transition-colors">
74
+ <span class="text-xl">🔗</span>
75
+ </div>
76
+ <span class="font-semibold text-navy">{{ system.name }}</span>
72
77
  </div>
73
- <p class="text-sm text-gray-500 line-clamp-2">{{ system.description|default:"No description" }}</p>
74
- <div class="mt-2 flex items-center space-x-2 text-xs text-gray-400">
75
- <span>Entry: {{ system.entry_agent.icon|default:"🤖" }} {{ system.entry_agent.name }}</span>
76
- </div>
77
- <div class="mt-2 text-xs text-gray-400">
78
- Updated {{ system.updated_at|timesince }} ago
78
+ <p class="text-sm text-slate-500 line-clamp-2 mb-3">{{ system.description|default:"No description" }}</p>
79
+ <div class="flex items-center justify-between text-xs text-slate-400">
80
+ <span class="flex items-center gap-1">
81
+ <span>{{ system.entry_agent.icon|default:"🤖" }}</span>
82
+ <span>{{ system.entry_agent.name }}</span>
83
+ </span>
84
+ <span>{{ system.updated_at|timesince }} ago</span>
79
85
  </div>
80
86
  </a>
81
87
  {% endfor %}
82
88
  </div>
83
89
  {% else %}
84
- <div class="bg-gray-50 border border-gray-200 rounded-lg p-6 text-center">
85
- <p class="text-gray-500 text-sm">No systems yet. Systems combine multiple agents to work together.</p>
90
+ <div class="bg-white border border-slate-200 border-dashed rounded-xl p-8 text-center">
91
+ <div class="w-12 h-12 bg-slate-100 rounded-full flex items-center justify-center mx-auto mb-3">
92
+ <span class="text-2xl">🔗</span>
93
+ </div>
94
+ <p class="text-slate-500 text-sm mb-3">No systems yet. Systems combine multiple agents to work together.</p>
95
+ <a href="{% url 'agent_studio:system_create' %}" class="inline-flex items-center gap-2 text-sm font-medium text-cyan hover:text-cyan-dark">
96
+ Create your first system →
97
+ </a>
86
98
  </div>
87
99
  {% endif %}
88
100
  </div>
@@ -90,17 +102,22 @@
90
102
  <!-- Recent Agents -->
91
103
  {% if recent_agents %}
92
104
  <div class="mb-8">
93
- <h2 class="text-xl font-semibold text-gray-800 mb-4">Recent Agents</h2>
105
+ <div class="flex items-center justify-between mb-4">
106
+ <h2 class="text-xl font-semibold text-navy">Recent Agents</h2>
107
+ <a href="{% url 'agent_studio:agent_list' %}" class="text-sm text-cyan hover:text-cyan-dark font-medium">View all →</a>
108
+ </div>
94
109
  <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
95
110
  {% for agent in recent_agents %}
96
111
  <a href="{% url 'agent_studio:agent_edit' agent.id %}"
97
- class="bg-white border border-gray-200 rounded-lg p-4 hover:border-primary-300 hover:shadow-sm transition-all">
98
- <div class="flex items-center space-x-3 mb-2">
99
- <span class="text-xl">{{ agent.icon|default:"🤖" }}</span>
100
- <span class="font-medium text-gray-800">{{ agent.name }}</span>
112
+ class="bg-white border border-slate-200 rounded-xl p-5 hover:border-cyan hover:shadow-md transition-all group">
113
+ <div class="flex items-center space-x-3 mb-3">
114
+ <div class="w-10 h-10 bg-cyan/10 rounded-lg flex items-center justify-center group-hover:bg-cyan/20 transition-colors">
115
+ <span class="text-xl">{{ agent.icon|default:"🤖" }}</span>
116
+ </div>
117
+ <span class="font-semibold text-navy">{{ agent.name }}</span>
101
118
  </div>
102
- <p class="text-sm text-gray-500 line-clamp-2">{{ agent.description|default:"No description" }}</p>
103
- <div class="mt-3 text-xs text-gray-400">
119
+ <p class="text-sm text-slate-500 line-clamp-2 mb-3">{{ agent.description|default:"No description" }}</p>
120
+ <div class="text-xs text-slate-400">
104
121
  Updated {{ agent.updated_at|timesince }} ago
105
122
  </div>
106
123
  </a>
@@ -112,15 +129,17 @@
112
129
  <!-- Template Agents -->
113
130
  {% if template_agents %}
114
131
  <div>
115
- <h2 class="text-xl font-semibold text-gray-800 mb-4">Popular Templates</h2>
132
+ <h2 class="text-xl font-semibold text-navy mb-4">Popular Templates</h2>
116
133
  <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
117
134
  {% for agent in template_agents %}
118
- <div class="bg-white border border-gray-200 rounded-lg p-4 hover:border-primary-300 hover:shadow-sm transition-all cursor-pointer">
119
- <div class="flex items-center space-x-3 mb-2">
120
- <span class="text-xl">{{ agent.icon|default:"📄" }}</span>
121
- <span class="font-medium text-gray-800">{{ agent.name }}</span>
135
+ <div class="bg-white border border-slate-200 rounded-xl p-5 hover:border-cyan hover:shadow-md transition-all cursor-pointer group">
136
+ <div class="flex items-center space-x-3 mb-3">
137
+ <div class="w-10 h-10 bg-slate-100 rounded-lg flex items-center justify-center group-hover:bg-cyan/10 transition-colors">
138
+ <span class="text-xl">{{ agent.icon|default:"📄" }}</span>
139
+ </div>
140
+ <span class="font-semibold text-navy">{{ agent.name }}</span>
122
141
  </div>
123
- <p class="text-sm text-gray-500 line-clamp-2">{{ agent.description|default:"No description" }}</p>
142
+ <p class="text-sm text-slate-500 line-clamp-2">{{ agent.description|default:"No description" }}</p>
124
143
  </div>
125
144
  {% endfor %}
126
145
  </div>
@@ -141,4 +160,3 @@ createApp({
141
160
  }).use(primevue.config.default).mount('#app');
142
161
  </script>
143
162
  {% endblock %}
144
-