supervaizer 0.10.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.
- supervaizer/__init__.py +97 -0
- supervaizer/__version__.py +10 -0
- supervaizer/account.py +308 -0
- supervaizer/account_service.py +93 -0
- supervaizer/admin/routes.py +1293 -0
- supervaizer/admin/static/js/job-start-form.js +373 -0
- supervaizer/admin/templates/agent_detail.html +145 -0
- supervaizer/admin/templates/agents.html +249 -0
- supervaizer/admin/templates/agents_grid.html +82 -0
- supervaizer/admin/templates/base.html +233 -0
- supervaizer/admin/templates/case_detail.html +230 -0
- supervaizer/admin/templates/cases_list.html +182 -0
- supervaizer/admin/templates/cases_table.html +134 -0
- supervaizer/admin/templates/console.html +389 -0
- supervaizer/admin/templates/dashboard.html +153 -0
- supervaizer/admin/templates/job_detail.html +192 -0
- supervaizer/admin/templates/job_start_test.html +109 -0
- supervaizer/admin/templates/jobs_list.html +180 -0
- supervaizer/admin/templates/jobs_table.html +122 -0
- supervaizer/admin/templates/navigation.html +163 -0
- supervaizer/admin/templates/recent_activity.html +81 -0
- supervaizer/admin/templates/server.html +105 -0
- supervaizer/admin/templates/server_status_cards.html +121 -0
- supervaizer/admin/templates/supervaize_instructions.html +212 -0
- supervaizer/agent.py +956 -0
- supervaizer/case.py +432 -0
- supervaizer/cli.py +395 -0
- supervaizer/common.py +324 -0
- supervaizer/deploy/__init__.py +16 -0
- supervaizer/deploy/cli.py +305 -0
- supervaizer/deploy/commands/__init__.py +9 -0
- supervaizer/deploy/commands/clean.py +294 -0
- supervaizer/deploy/commands/down.py +119 -0
- supervaizer/deploy/commands/local.py +460 -0
- supervaizer/deploy/commands/plan.py +167 -0
- supervaizer/deploy/commands/status.py +169 -0
- supervaizer/deploy/commands/up.py +281 -0
- supervaizer/deploy/docker.py +377 -0
- supervaizer/deploy/driver_factory.py +42 -0
- supervaizer/deploy/drivers/__init__.py +39 -0
- supervaizer/deploy/drivers/aws_app_runner.py +607 -0
- supervaizer/deploy/drivers/base.py +196 -0
- supervaizer/deploy/drivers/cloud_run.py +570 -0
- supervaizer/deploy/drivers/do_app_platform.py +504 -0
- supervaizer/deploy/health.py +404 -0
- supervaizer/deploy/state.py +210 -0
- supervaizer/deploy/templates/Dockerfile.template +44 -0
- supervaizer/deploy/templates/debug_env.py +69 -0
- supervaizer/deploy/templates/docker-compose.yml.template +37 -0
- supervaizer/deploy/templates/dockerignore.template +66 -0
- supervaizer/deploy/templates/entrypoint.sh +20 -0
- supervaizer/deploy/utils.py +52 -0
- supervaizer/event.py +181 -0
- supervaizer/examples/controller_template.py +196 -0
- supervaizer/instructions.py +145 -0
- supervaizer/job.py +392 -0
- supervaizer/job_service.py +156 -0
- supervaizer/lifecycle.py +417 -0
- supervaizer/parameter.py +233 -0
- supervaizer/protocol/__init__.py +11 -0
- supervaizer/protocol/a2a/__init__.py +21 -0
- supervaizer/protocol/a2a/model.py +227 -0
- supervaizer/protocol/a2a/routes.py +99 -0
- supervaizer/py.typed +1 -0
- supervaizer/routes.py +917 -0
- supervaizer/server.py +553 -0
- supervaizer/server_utils.py +54 -0
- supervaizer/storage.py +462 -0
- supervaizer/telemetry.py +81 -0
- supervaizer/utils/__init__.py +16 -0
- supervaizer/utils/version_check.py +56 -0
- supervaizer-0.10.5.dist-info/METADATA +317 -0
- supervaizer-0.10.5.dist-info/RECORD +76 -0
- supervaizer-0.10.5.dist-info/WHEEL +4 -0
- supervaizer-0.10.5.dist-info/entry_points.txt +2 -0
- supervaizer-0.10.5.dist-info/licenses/LICENSE.md +346 -0
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JobStartForm - Handles job parameter validation and submission
|
|
3
|
+
*
|
|
4
|
+
* This class provides methods to validate agent parameters and method fields
|
|
5
|
+
* before starting a job, using the new validation endpoints.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
class JobStartForm {
|
|
9
|
+
constructor(agentPath) {
|
|
10
|
+
this.agentPath = agentPath;
|
|
11
|
+
this.form = null;
|
|
12
|
+
this.errorContainer = null;
|
|
13
|
+
this.initialize();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
initialize() {
|
|
17
|
+
// Wait for DOM to be ready
|
|
18
|
+
if (document.readyState === 'loading') {
|
|
19
|
+
document.addEventListener('DOMContentLoaded', () => this.setupForm());
|
|
20
|
+
} else {
|
|
21
|
+
this.setupForm();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
setupForm() {
|
|
26
|
+
// Find the form and error container
|
|
27
|
+
this.form = document.querySelector('form[data-job-start]');
|
|
28
|
+
this.errorContainer = document.getElementById('validation-errors');
|
|
29
|
+
|
|
30
|
+
if (!this.form) {
|
|
31
|
+
console.warn('JobStartForm: No form found with data-job-start attribute');
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (!this.errorContainer) {
|
|
36
|
+
console.warn('JobStartForm: No validation-errors container found');
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Add submit handler
|
|
41
|
+
this.form.addEventListener('submit', (e) => this.handleSubmit(e));
|
|
42
|
+
|
|
43
|
+
// Add validation on field change
|
|
44
|
+
this.form.addEventListener('change', () => this.clearErrors());
|
|
45
|
+
|
|
46
|
+
console.log('JobStartForm initialized for', this.agentPath);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async handleSubmit(event) {
|
|
50
|
+
event.preventDefault();
|
|
51
|
+
|
|
52
|
+
// Clear previous errors
|
|
53
|
+
this.clearErrors();
|
|
54
|
+
|
|
55
|
+
// Validate both agent parameters and method fields
|
|
56
|
+
const [agentParamsValid, methodFieldsValid] = await Promise.all([
|
|
57
|
+
this.validateAgentParameters(),
|
|
58
|
+
this.validateMethodFields()
|
|
59
|
+
]);
|
|
60
|
+
|
|
61
|
+
if (agentParamsValid && methodFieldsValid) {
|
|
62
|
+
// All validation passed, submit the form
|
|
63
|
+
this.submitForm();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async validateAgentParameters() {
|
|
68
|
+
const encryptedParams = this.getEncryptedAgentParameters();
|
|
69
|
+
|
|
70
|
+
if (!encryptedParams) {
|
|
71
|
+
return true; // No agent parameters to validate
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
try {
|
|
75
|
+
const response = await fetch(
|
|
76
|
+
`${this.agentPath}/validate-agent-parameters`,
|
|
77
|
+
{
|
|
78
|
+
method: 'POST',
|
|
79
|
+
headers: {
|
|
80
|
+
'Content-Type': 'application/json',
|
|
81
|
+
'X-API-Key': this.getApiKey()
|
|
82
|
+
},
|
|
83
|
+
body: JSON.stringify({
|
|
84
|
+
encrypted_agent_parameters: encryptedParams,
|
|
85
|
+
}),
|
|
86
|
+
}
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
const result = await response.json();
|
|
90
|
+
|
|
91
|
+
if (!result.valid) {
|
|
92
|
+
this.displayAgentParameterErrors(result);
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return true;
|
|
97
|
+
} catch (error) {
|
|
98
|
+
console.error('Agent parameter validation failed:', error);
|
|
99
|
+
this.displayError('Agent parameter validation failed due to network error');
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async validateMethodFields() {
|
|
105
|
+
const formData = this.getFormData();
|
|
106
|
+
|
|
107
|
+
try {
|
|
108
|
+
const response = await fetch(
|
|
109
|
+
`${this.agentPath}/validate-method-fields`,
|
|
110
|
+
{
|
|
111
|
+
method: 'POST',
|
|
112
|
+
headers: {
|
|
113
|
+
'Content-Type': 'application/json',
|
|
114
|
+
'X-API-Key': this.getApiKey()
|
|
115
|
+
},
|
|
116
|
+
body: JSON.stringify({
|
|
117
|
+
method_name: 'job_start',
|
|
118
|
+
job_fields: formData,
|
|
119
|
+
}),
|
|
120
|
+
}
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
const result = await response.json();
|
|
124
|
+
|
|
125
|
+
if (!result.valid) {
|
|
126
|
+
this.displayMethodFieldErrors(result);
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return true;
|
|
131
|
+
} catch (error) {
|
|
132
|
+
console.error('Method field validation failed:', error);
|
|
133
|
+
this.displayError('Method field validation failed due to network error');
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
getFormData() {
|
|
139
|
+
const formData = {};
|
|
140
|
+
const formElements = this.form.elements;
|
|
141
|
+
|
|
142
|
+
for (let element of formElements) {
|
|
143
|
+
if (element.name && element.type !== 'submit') {
|
|
144
|
+
if (element.type === 'checkbox') {
|
|
145
|
+
formData[element.name] = element.checked;
|
|
146
|
+
} else if (element.type === 'radio') {
|
|
147
|
+
if (element.checked) {
|
|
148
|
+
formData[element.name] = element.value;
|
|
149
|
+
}
|
|
150
|
+
} else if (element.type === 'select-multiple') {
|
|
151
|
+
formData[element.name] = Array.from(element.selectedOptions).map(option => option.value);
|
|
152
|
+
} else {
|
|
153
|
+
formData[element.name] = element.value;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return formData;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
getEncryptedAgentParameters() {
|
|
162
|
+
// Look for encrypted agent parameters in hidden fields or data attributes
|
|
163
|
+
const encryptedField = this.form.querySelector('[name="encrypted_agent_parameters"]');
|
|
164
|
+
if (encryptedField) {
|
|
165
|
+
return encryptedField.value;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Check if agent parameters are stored in data attributes
|
|
169
|
+
const agentParamsData = this.form.dataset.agentParameters;
|
|
170
|
+
if (agentParamsData) {
|
|
171
|
+
try {
|
|
172
|
+
return JSON.parse(agentParamsData);
|
|
173
|
+
} catch (e) {
|
|
174
|
+
console.warn('Failed to parse agent parameters from data attribute');
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
getApiKey() {
|
|
182
|
+
// Get API key from form data, meta tag, or global variable
|
|
183
|
+
const apiKeyField = this.form.querySelector('[name="api_key"]');
|
|
184
|
+
if (apiKeyField) {
|
|
185
|
+
return apiKeyField.value;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const metaApiKey = document.querySelector('meta[name="api-key"]');
|
|
189
|
+
if (metaApiKey) {
|
|
190
|
+
return metaApiKey.content;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Check for global variable
|
|
194
|
+
if (typeof window.SUPERVAIZER_API_KEY !== 'undefined') {
|
|
195
|
+
return window.SUPERVAIZER_API_KEY;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return '';
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
displayAgentParameterErrors(validationResult) {
|
|
202
|
+
const errorSection = document.getElementById('agent-parameter-errors');
|
|
203
|
+
if (!errorSection) {
|
|
204
|
+
// Create error section if it doesn't exist
|
|
205
|
+
const section = document.createElement('div');
|
|
206
|
+
section.id = 'agent-parameter-errors';
|
|
207
|
+
section.className = 'mb-4';
|
|
208
|
+
this.errorContainer.appendChild(section);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const section = document.getElementById('agent-parameter-errors');
|
|
212
|
+
section.innerHTML = `
|
|
213
|
+
<div class="alert alert-warning">
|
|
214
|
+
<strong>Agent Configuration Issues:</strong> ${validationResult.message
|
|
215
|
+
}
|
|
216
|
+
<ul>
|
|
217
|
+
${validationResult.errors
|
|
218
|
+
.map((error) => `<li>${error}</li>`)
|
|
219
|
+
.join('')}
|
|
220
|
+
</ul>
|
|
221
|
+
</div>
|
|
222
|
+
`;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
displayMethodFieldErrors(validationResult) {
|
|
226
|
+
// Clear any existing field-specific errors
|
|
227
|
+
this.form.querySelectorAll('.is-invalid').forEach((field) => {
|
|
228
|
+
field.classList.remove('is-invalid');
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
// Display general error message
|
|
232
|
+
this.displayError(validationResult.message);
|
|
233
|
+
|
|
234
|
+
// Mark invalid fields and show specific error messages
|
|
235
|
+
Object.entries(validationResult.invalid_fields).forEach(([fieldName, errorMessage]) => {
|
|
236
|
+
const field = this.form.querySelector(`[name="${fieldName}"]`);
|
|
237
|
+
if (field) {
|
|
238
|
+
field.classList.add('is-invalid');
|
|
239
|
+
|
|
240
|
+
// Add error message below the field
|
|
241
|
+
let errorElement = field.parentNode.querySelector('.invalid-feedback');
|
|
242
|
+
if (!errorElement) {
|
|
243
|
+
errorElement = document.createElement('div');
|
|
244
|
+
errorElement.className = 'invalid-feedback';
|
|
245
|
+
field.parentNode.appendChild(errorElement);
|
|
246
|
+
}
|
|
247
|
+
errorElement.textContent = errorMessage;
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
displayError(message) {
|
|
253
|
+
this.errorContainer.innerHTML = `
|
|
254
|
+
<div class="alert alert-danger">
|
|
255
|
+
<strong>Validation Error:</strong> ${message}
|
|
256
|
+
</div>
|
|
257
|
+
`;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
clearErrors() {
|
|
261
|
+
this.errorContainer.innerHTML = '';
|
|
262
|
+
|
|
263
|
+
// Clear agent parameter errors
|
|
264
|
+
const agentErrorSection = document.getElementById('agent-parameter-errors');
|
|
265
|
+
if (agentErrorSection) {
|
|
266
|
+
agentErrorSection.innerHTML = '';
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Clear field errors
|
|
270
|
+
this.form.querySelectorAll('.is-invalid').forEach((field) => {
|
|
271
|
+
field.classList.remove('is-invalid');
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
// Clear invalid feedback messages
|
|
275
|
+
this.form.querySelectorAll('.invalid-feedback').forEach((feedback) => {
|
|
276
|
+
feedback.remove();
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
async submitForm() {
|
|
281
|
+
try {
|
|
282
|
+
const formData = this.getFormData();
|
|
283
|
+
const encryptedParams = this.getEncryptedAgentParameters();
|
|
284
|
+
|
|
285
|
+
const requestBody = {
|
|
286
|
+
job_context: {
|
|
287
|
+
// Add any job context data here
|
|
288
|
+
},
|
|
289
|
+
job_fields: formData
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
if (encryptedParams) {
|
|
293
|
+
requestBody.encrypted_agent_parameters = encryptedParams;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
const response = await fetch(`${this.agentPath}/jobs`, {
|
|
297
|
+
method: 'POST',
|
|
298
|
+
headers: {
|
|
299
|
+
'Content-Type': 'application/json',
|
|
300
|
+
'X-API-Key': this.getApiKey()
|
|
301
|
+
},
|
|
302
|
+
body: JSON.stringify(requestBody)
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
if (response.ok) {
|
|
306
|
+
const result = await response.json();
|
|
307
|
+
this.handleJobStarted(result);
|
|
308
|
+
} else {
|
|
309
|
+
const error = await response.json();
|
|
310
|
+
this.handleJobError(error);
|
|
311
|
+
}
|
|
312
|
+
} catch (error) {
|
|
313
|
+
console.error('Job submission failed:', error);
|
|
314
|
+
this.displayError('Failed to submit job due to network error');
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
handleJobStarted(jobData) {
|
|
319
|
+
// Clear form and show success message
|
|
320
|
+
this.form.reset();
|
|
321
|
+
this.clearErrors();
|
|
322
|
+
|
|
323
|
+
this.errorContainer.innerHTML = `
|
|
324
|
+
<div class="alert alert-success">
|
|
325
|
+
<strong>Job Started Successfully!</strong><br>
|
|
326
|
+
Job ID: ${jobData.id || 'Unknown'}<br>
|
|
327
|
+
Status: ${jobData.status || 'Unknown'}
|
|
328
|
+
</div>
|
|
329
|
+
`;
|
|
330
|
+
|
|
331
|
+
// Trigger any success callbacks
|
|
332
|
+
if (typeof this.onJobStarted === 'function') {
|
|
333
|
+
this.onJobStarted(jobData);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
handleJobError(error) {
|
|
338
|
+
this.displayError(`Job submission failed: ${error.detail || error.message || 'Unknown error'}`);
|
|
339
|
+
|
|
340
|
+
// Trigger any error callbacks
|
|
341
|
+
if (typeof this.onJobError === 'function') {
|
|
342
|
+
this.onJobError(error);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// Public methods for external use
|
|
347
|
+
setOnJobStarted(callback) {
|
|
348
|
+
this.onJobStarted = callback;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
setOnJobError(callback) {
|
|
352
|
+
this.onJobError = callback;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// Method to manually trigger validation
|
|
356
|
+
async validate() {
|
|
357
|
+
const [agentParamsValid, methodFieldsValid] = await Promise.all([
|
|
358
|
+
this.validateAgentParameters(),
|
|
359
|
+
this.validateMethodFields()
|
|
360
|
+
]);
|
|
361
|
+
return agentParamsValid && methodFieldsValid;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// Export for module systems
|
|
366
|
+
if (typeof module !== 'undefined' && module.exports) {
|
|
367
|
+
module.exports = JobStartForm;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// Make available globally
|
|
371
|
+
if (typeof window !== 'undefined') {
|
|
372
|
+
window.JobStartForm = JobStartForm;
|
|
373
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4 max-h-[80vh] overflow-y-auto">
|
|
2
|
+
<div class="sm:flex sm:items-start">
|
|
3
|
+
<div class="w-full">
|
|
4
|
+
<!-- Header -->
|
|
5
|
+
<div class="flex items-center justify-between mb-4">
|
|
6
|
+
<h3 class="text-lg leading-6 font-medium text-gray-900">Agent Details: {{ agent.name or agent.slug or "Unknown Agent" }}</h3>
|
|
7
|
+
<button
|
|
8
|
+
@click="open = false"
|
|
9
|
+
class="bg-white rounded-md text-gray-400 hover:text-gray-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
|
|
10
|
+
>
|
|
11
|
+
<span class="sr-only">Close</span>
|
|
12
|
+
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
13
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
|
14
|
+
</svg>
|
|
15
|
+
</button>
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
<!-- Debug Info (remove in production) -->
|
|
19
|
+
<div class="mb-4 p-4 bg-yellow-50 border border-yellow-200 rounded-md">
|
|
20
|
+
<h4 class="text-sm font-medium text-yellow-800">Debug Info:</h4>
|
|
21
|
+
<pre class="text-xs text-yellow-700 mt-2">{{ agent | tojson(indent=2) }}</pre>
|
|
22
|
+
</div>
|
|
23
|
+
|
|
24
|
+
<!-- Agent Information -->
|
|
25
|
+
<div class="grid grid-cols-1 gap-6 sm:grid-cols-2">
|
|
26
|
+
<div>
|
|
27
|
+
<h4 class="text-sm font-medium text-gray-900 mb-3">Basic Information</h4>
|
|
28
|
+
<dl class="space-y-2">
|
|
29
|
+
<div>
|
|
30
|
+
<dt class="text-xs font-medium text-gray-500 uppercase tracking-wider">Name</dt>
|
|
31
|
+
<dd class="text-sm text-gray-900">{{ agent.name or "Unnamed Agent" }}</dd>
|
|
32
|
+
</div>
|
|
33
|
+
<div>
|
|
34
|
+
<dt class="text-xs font-medium text-gray-500 uppercase tracking-wider">Type</dt>
|
|
35
|
+
<dd class="text-sm text-gray-900 capitalize">{{ agent.type or "conversational" }}</dd>
|
|
36
|
+
</div>
|
|
37
|
+
<div>
|
|
38
|
+
<dt class="text-xs font-medium text-gray-500 uppercase tracking-wider">Version</dt>
|
|
39
|
+
<dd class="text-sm text-gray-900">{{ agent.version or "1.0.0" }}</dd>
|
|
40
|
+
</div>
|
|
41
|
+
<div>
|
|
42
|
+
<dt class="text-xs font-medium text-gray-500 uppercase tracking-wider">Status</dt>
|
|
43
|
+
<dd>
|
|
44
|
+
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">
|
|
45
|
+
{{ agent.status or "Active" }}
|
|
46
|
+
</span>
|
|
47
|
+
</dd>
|
|
48
|
+
</div>
|
|
49
|
+
</dl>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
<div>
|
|
53
|
+
<h4 class="text-sm font-medium text-gray-900 mb-3">Configuration</h4>
|
|
54
|
+
<dl class="space-y-2">
|
|
55
|
+
<div>
|
|
56
|
+
<dt class="text-xs font-medium text-gray-500 uppercase tracking-wider">Model</dt>
|
|
57
|
+
<dd class="text-sm text-gray-900">{{ agent.model or "-" }}</dd>
|
|
58
|
+
</div>
|
|
59
|
+
<div>
|
|
60
|
+
<dt class="text-xs font-medium text-gray-500 uppercase tracking-wider">Provider</dt>
|
|
61
|
+
<dd class="text-sm text-gray-900">{{ agent.provider or "-" }}</dd>
|
|
62
|
+
</div>
|
|
63
|
+
<div>
|
|
64
|
+
<dt class="text-xs font-medium text-gray-500 uppercase tracking-wider">Max Tokens</dt>
|
|
65
|
+
<dd class="text-sm text-gray-900">{{ agent.max_tokens or "-" }}</dd>
|
|
66
|
+
</div>
|
|
67
|
+
<div>
|
|
68
|
+
<dt class="text-xs font-medium text-gray-500 uppercase tracking-wider">Temperature</dt>
|
|
69
|
+
<dd class="text-sm text-gray-900">{{ agent.temperature or "-" }}</dd>
|
|
70
|
+
</div>
|
|
71
|
+
</dl>
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
|
|
75
|
+
<!-- Description -->
|
|
76
|
+
{% if agent.description %}
|
|
77
|
+
<div class="mt-6">
|
|
78
|
+
<h4 class="text-sm font-medium text-gray-900 mb-3">Description</h4>
|
|
79
|
+
<div class="bg-gray-50 p-4 rounded-lg">
|
|
80
|
+
<p class="text-sm text-gray-700">{{ agent.description }}</p>
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
{% endif %}
|
|
84
|
+
|
|
85
|
+
<!-- System Prompt -->
|
|
86
|
+
{% if agent.system_prompt %}
|
|
87
|
+
<div class="mt-6">
|
|
88
|
+
<h4 class="text-sm font-medium text-gray-900 mb-3">System Prompt</h4>
|
|
89
|
+
<div class="bg-gray-50 p-4 rounded-lg">
|
|
90
|
+
<pre class="text-sm text-gray-700 whitespace-pre-wrap">{{ agent.system_prompt }}</pre>
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
{% endif %}
|
|
94
|
+
|
|
95
|
+
<!-- Tools -->
|
|
96
|
+
{% if agent.tools %}
|
|
97
|
+
<div class="mt-6">
|
|
98
|
+
<h4 class="text-sm font-medium text-gray-900 mb-3">Available Tools ({{ agent.tools | length }})</h4>
|
|
99
|
+
<div class="bg-white overflow-hidden shadow rounded-lg">
|
|
100
|
+
<ul role="list" class="divide-y divide-gray-200">
|
|
101
|
+
{% for tool in agent.tools %}
|
|
102
|
+
<li class="px-4 py-3">
|
|
103
|
+
<div class="flex items-center justify-between">
|
|
104
|
+
<div>
|
|
105
|
+
<p class="text-sm font-medium text-gray-900">{{ tool.name if tool is mapping else tool }}</p>
|
|
106
|
+
{% if tool is mapping and tool.description %}
|
|
107
|
+
<p class="text-sm text-gray-500">{{ tool.description }}</p>
|
|
108
|
+
{% endif %}
|
|
109
|
+
</div>
|
|
110
|
+
{% if tool is mapping and tool.enabled is defined %}
|
|
111
|
+
<span class="text-xs px-2 py-1 rounded-full {{ 'bg-green-100 text-green-800' if tool.enabled else 'bg-gray-100 text-gray-800' }}">
|
|
112
|
+
{{ "Enabled" if tool.enabled else "Disabled" }}
|
|
113
|
+
</span>
|
|
114
|
+
{% endif %}
|
|
115
|
+
</div>
|
|
116
|
+
</li>
|
|
117
|
+
{% endfor %}
|
|
118
|
+
</ul>
|
|
119
|
+
</div>
|
|
120
|
+
</div>
|
|
121
|
+
{% endif %}
|
|
122
|
+
|
|
123
|
+
<!-- Additional Configuration -->
|
|
124
|
+
{% if agent.config %}
|
|
125
|
+
<div class="mt-6">
|
|
126
|
+
<h4 class="text-sm font-medium text-gray-900 mb-3">Additional Configuration</h4>
|
|
127
|
+
<div class="bg-gray-50 p-4 rounded-lg">
|
|
128
|
+
<pre class="text-sm text-gray-700 whitespace-pre-wrap">{{ agent.config | tojson(indent=2) }}</pre>
|
|
129
|
+
</div>
|
|
130
|
+
</div>
|
|
131
|
+
{% endif %}
|
|
132
|
+
</div>
|
|
133
|
+
</div>
|
|
134
|
+
</div>
|
|
135
|
+
|
|
136
|
+
<!-- Modal Footer -->
|
|
137
|
+
<div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
|
|
138
|
+
<button
|
|
139
|
+
@click="open = false"
|
|
140
|
+
type="button"
|
|
141
|
+
class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm"
|
|
142
|
+
>
|
|
143
|
+
Close
|
|
144
|
+
</button>
|
|
145
|
+
</div>
|