mindroot 8.6.0__py3-none-any.whl → 8.8.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.

Potentially problematic release.


This version of mindroot might be problematic. Click here for more details.

@@ -10,6 +10,7 @@ import './indexed-agents.js';
10
10
  class AgentForm extends BaseEl {
11
11
  static properties = {
12
12
  agent: { type: Object },
13
+ agents: { type: Array },
13
14
  newAgent: { type: Boolean },
14
15
  loading: { type: Boolean },
15
16
  personas: { type: Array },
@@ -19,7 +20,8 @@ class AgentForm extends BaseEl {
19
20
  pendingPlugins: { type: Array },
20
21
  showInstructionsEditor: { type: Boolean },
21
22
  showTechnicalInstructionsEditor: { type: Boolean },
22
- indexedAgentsVisible: { type: Boolean }
23
+ indexedAgentsVisible: { type: Boolean },
24
+ selectedAgentName: { type: String }
23
25
  };
24
26
 
25
27
  static styles = css`
@@ -28,6 +30,36 @@ class AgentForm extends BaseEl {
28
30
  margin-top: 20px;
29
31
  }
30
32
 
33
+ .agent-selector {
34
+ display: flex;
35
+ gap: 10px;
36
+ align-items: center;
37
+ margin-bottom: 20px;
38
+ }
39
+
40
+ .agent-selector select {
41
+ flex: 1;
42
+ padding: 8px;
43
+ background: rgba(255, 255, 255, 0.05);
44
+ border: 1px solid rgba(255, 255, 255, 0.1);
45
+ border-radius: 4px;
46
+ color: #f0f0f0;
47
+ }
48
+
49
+ .btn-secondary {
50
+ padding: 8px 16px;
51
+ border: 1px solid #2196F3;
52
+ border-radius: 4px;
53
+ background: rgba(255, 255, 255, 0.05);
54
+ color: #2196F3;
55
+ cursor: pointer;
56
+ transition: all 0.2s;
57
+ }
58
+
59
+ .btn-secondary:hover {
60
+ background: rgba(33, 150, 243, 0.1);
61
+ }
62
+
31
63
  .agent-form {
32
64
  padding: 15px;
33
65
  border: 1px solid rgba(255, 255, 255, 0.1);
@@ -51,7 +83,7 @@ class AgentForm extends BaseEl {
51
83
  }
52
84
 
53
85
  summary::before {
54
- content: "\u25b6";
86
+ content: "";
55
87
  display: inline-block;
56
88
  margin-right: 5px;
57
89
  transition: transform 0.2s;
@@ -295,6 +327,13 @@ class AgentForm extends BaseEl {
295
327
  opacity: 0.5;
296
328
  cursor: not-allowed;
297
329
  }
330
+
331
+ .no-agent-message {
332
+ text-align: center;
333
+ padding: 40px;
334
+ color: #999;
335
+ font-style: italic;
336
+ }
298
337
  `;
299
338
 
300
339
  constructor() {
@@ -306,18 +345,14 @@ class AgentForm extends BaseEl {
306
345
  this.loading = false;
307
346
  this.plugins = [];
308
347
  this.providerMapping = {}; // Map display names to module names
309
- this.agent = {
310
- commands: [],
311
- name: '',
312
- hashver: '',
313
- preferred_providers: [],
314
- thinking_level: 'off', // Default to medium
315
- persona: '',
316
- recommended_plugins: []
317
- };
348
+ this.agent = null;
349
+ this.agents = [];
318
350
  this.showTechnicalInstructionsEditor = false;
319
351
  this.newAgent = false;
320
352
  this.pendingPlugins = [];
353
+ this.selectedAgentName = '';
354
+
355
+ this.fetchAgents();
321
356
  this.fetchPersonas();
322
357
  this.resetEditors();
323
358
  this.fetchCommands();
@@ -325,8 +360,67 @@ class AgentForm extends BaseEl {
325
360
  this.fetchPlugins();
326
361
  }
327
362
 
363
+ async fetchAgents() {
364
+ try {
365
+ const response = await fetch('/agents/local');
366
+ if (!response.ok) throw new Error('Failed to fetch agents');
367
+ this.agents = await response.json();
368
+ } catch (error) {
369
+ showNotification('error', `Error loading agents: ${error.message}`);
370
+ }
371
+ }
372
+
373
+ async handleAgentChange(event) {
374
+ const agentName = event.target.value;
375
+ this.selectedAgentName = agentName;
376
+
377
+ if (agentName) {
378
+ try {
379
+ const response = await fetch(`/agents/local/${agentName}`);
380
+ if (!response.ok) throw new Error('Failed to fetch agent');
381
+ const agent = await response.json();
382
+ this.agent = agent;
383
+ this.newAgent = false;
384
+ this.resetEditors();
385
+ this.dispatchEvent(new CustomEvent('agent-selected', {
386
+ detail: agent,
387
+ bubbles: true,
388
+ composed: true
389
+ }));
390
+ } catch (error) {
391
+ showNotification('error', `Error loading agent: ${error.message}`);
392
+ }
393
+ } else {
394
+ this.agent = null;
395
+ this.newAgent = false;
396
+ }
397
+ }
398
+
399
+ handleNewAgent() {
400
+ this.agent = {
401
+ name: '',
402
+ hashver: '',
403
+ commands: [],
404
+ preferred_providers: [],
405
+ thinking_level: 'off',
406
+ persona: '',
407
+ recommended_plugins: [],
408
+ instructions: '',
409
+ technicalInstructions: ''
410
+ };
411
+ this.newAgent = true;
412
+ this.selectedAgentName = '';
413
+ this.resetEditors();
414
+
415
+ // Update the select to show no selection
416
+ const select = this.shadowRoot.querySelector('.agent-selector select');
417
+ if (select) {
418
+ select.value = '';
419
+ }
420
+ }
421
+
328
422
  async fetchMissingCommands() {
329
- if (!this.agent.name) return;
423
+ if (!this.agent?.name) return;
330
424
 
331
425
  // Skip API call for new agents that haven't been saved yet
332
426
  if (this.newAgent) {
@@ -367,11 +461,11 @@ class AgentForm extends BaseEl {
367
461
  console.log('Agent updated:', this.agent);
368
462
  // Force select element to update
369
463
  const select = this.shadowRoot.querySelector('select[name="persona"]');
370
- if (select && this.agent.persona) {
464
+ if (select && this.agent?.persona) {
371
465
  select.value = this.agent.persona;
372
466
  }
373
467
 
374
- if (this.agent.name) {
468
+ if (this.agent?.name) {
375
469
  this.fetchMissingCommands();
376
470
  this.checkRecommendedPlugins();
377
471
  }
@@ -404,7 +498,7 @@ class AgentForm extends BaseEl {
404
498
  if (!response.ok) throw new Error('Failed to fetch personas');
405
499
  this.personas = await response.json();
406
500
  console.log('Fetched personas:', this.personas);
407
- console.log('Current agent persona:', this.agent.persona);
501
+ console.log('Current agent persona:', this.agent?.persona);
408
502
  } catch (error) {
409
503
  showNotification('error', `Error loading personas: ${error.message}`);
410
504
  }
@@ -447,7 +541,7 @@ class AgentForm extends BaseEl {
447
541
 
448
542
 
449
543
  async checkRecommendedPlugins() {
450
- if (!this.agent.name || !this.agent.recommended_plugins || this.agent.recommended_plugins.length === 0) {
544
+ if (!this.agent?.name || !this.agent?.recommended_plugins || this.agent.recommended_plugins.length === 0) {
451
545
  this.pendingPlugins = [];
452
546
  return;
453
547
  }
@@ -523,7 +617,7 @@ class AgentForm extends BaseEl {
523
617
 
524
618
  handleInputChange(event) {
525
619
  const { name, value, type, checked } = event.target;
526
-
620
+ console.log({name, value, type})
527
621
  if (name === 'commands') {
528
622
  if (!Array.isArray(this.agent.commands)) {
529
623
  this.agent.commands = [];
@@ -549,13 +643,15 @@ class AgentForm extends BaseEl {
549
643
  } else {
550
644
  this.agent.recommended_plugins = this.agent.recommended_plugins.filter(plugin => plugin !== value);
551
645
  }
646
+
552
647
  this.agent = { ...this.agent };
553
648
  return;
554
649
  }
555
-
650
+ console.log('before',this.agent)
556
651
  // Handle all other inputs
557
652
  const inputValue = type === 'checkbox' ? checked : value;
558
653
  this.agent = { ...this.agent, [name]: inputValue };
654
+ console.log('after', this.agent)
559
655
  }
560
656
 
561
657
  handlePreferredProviderChange(e) {
@@ -589,9 +685,9 @@ class AgentForm extends BaseEl {
589
685
  const personaSelect = this.shadowRoot.querySelector('select[name="persona"]');
590
686
  const instructionsTextarea = this.shadowRoot.querySelector('textarea[name="instructions"]');
591
687
 
592
- const currentName = nameInput?.value || this.agent.name;
593
- const currentPersona = personaSelect?.value || this.agent.persona;
594
- const currentInstructions = instructionsTextarea?.value || this.agent.instructions;
688
+ const currentName = nameInput?.value || this.agent?.name;
689
+ const currentPersona = personaSelect?.value || this.agent?.persona;
690
+ const currentInstructions = instructionsTextarea?.value || this.agent?.instructions;
595
691
 
596
692
  if (!currentName?.trim()) {
597
693
  showNotification('error', 'Name is required');
@@ -608,34 +704,25 @@ class AgentForm extends BaseEl {
608
704
  return true;
609
705
  }
610
706
 
611
- async handleSubmit(event) { // Complete replacement of method
707
+ async handleSubmit(event) {
612
708
  event?.preventDefault();
613
709
 
614
- // Check if this is a partial save (from instruction save buttons)
615
- const isPartialSave = event?.submitter?.classList.contains('partial-save') ||
616
- (event?.target?.classList.contains('icon-button') &&
617
- (this.showInstructionsEditor || this.showTechnicalInstructionsEditor));
618
-
619
- // Store current form state before any operations
620
- const formState = {
621
- name: this.agent.name,
622
- persona: this.agent.persona,
623
- instructions: this.agent.instructions,
624
- technicalInstructions: this.agent.technicalInstructions,
625
- commands: [...(this.agent.commands || [])],
626
- recommended_plugins: [...(this.agent.recommended_plugins || [])],
627
- preferred_providers: [...(this.agent.preferred_providers || [])]
628
- };
710
+ // Update agent with current textarea values if editors are open
711
+ if (this.showInstructionsEditor) {
712
+ const instructionsTextarea = this.shadowRoot.querySelector('textarea[name="instructions"]');
713
+ if (instructionsTextarea) {
714
+ this.agent.instructions = instructionsTextarea.value;
715
+ }
716
+ }
717
+ if (this.showTechnicalInstructionsEditor) {
718
+ const techInstructionsTextarea = this.shadowRoot.querySelector('textarea[name="technicalInstructions"]');
719
+ if (techInstructionsTextarea) {
720
+ this.agent.technicalInstructions = techInstructionsTextarea.value;
721
+ }
722
+ }
629
723
 
630
- // Skip full validation for partial saves
631
- if (!isPartialSave && !this.validateForm()) {
632
- // Restore form state on validation error
633
- this.agent = {
634
- ...this.agent,
635
- ...formState
636
- };
637
- // Force update to refresh the form
638
- this.requestUpdate();
724
+ // Validate form
725
+ if (!this.validateForm()) {
639
726
  return;
640
727
  }
641
728
 
@@ -651,6 +738,7 @@ class AgentForm extends BaseEl {
651
738
  const method = this.newAgent ? 'POST' : 'PUT';
652
739
  const url = this.newAgent ? '/agents/local' : `/agents/local/${this.agent.name}`;
653
740
 
741
+ // Collect commands from toggle switches
654
742
  const cmdSwitches = this.shadowRoot.querySelectorAll('.toggle-command')
655
743
  console.log({cmdSwitches})
656
744
  let cmdsOn = []
@@ -663,14 +751,13 @@ class AgentForm extends BaseEl {
663
751
  if (cmdsOn.length > 0) {
664
752
  this.agent.commands = cmdsOn
665
753
  }
666
- for (let cmd in this.missingCommands) {
667
- if (!this.agent.commands.includes(cmd)) {
668
- this.agent.commands.push(cmd)
669
- }
670
- }
754
+
755
+ // Add missing commands
756
+ // Note: Missing commands stay in missing commands section, not added to regular commands
671
757
 
672
758
  console.log('Saving, commands are:', this.agent.commands)
673
759
 
760
+ // Collect service models
674
761
  const selectedModelsEls = this.shadowRoot.querySelectorAll('.service-model-select');
675
762
  console.log('Selected models:', selectedModelsEls, this.agent.service_models);
676
763
  for (const select of selectedModelsEls) {
@@ -710,46 +797,44 @@ class AgentForm extends BaseEl {
710
797
  throw new Error('Failed to save agent');
711
798
  }
712
799
 
713
- // Get the saved agent data from response and update local state
714
- const savedAgent = await response.json();
800
+ // Server just returns {status: 'success'}, not the agent data
801
+ const result = await response.json();
802
+ console.log('Save result:', result);
715
803
 
716
- // Merge saved data with current form state to preserve unsaved changes in other fields
717
- this.agent = {
718
- ...this.agent, // Keep current form state
719
- ...savedAgent, // Update with saved data
720
- // But preserve any current form values that might not have been saved
721
- name: this.shadowRoot.querySelector('input[name="name"]')?.value || savedAgent.name,
722
- persona: this.shadowRoot.querySelector('select[name="persona"]')?.value || savedAgent.persona,
723
- instructions: this.shadowRoot.querySelector('textarea[name="instructions"]')?.value || savedAgent.instructions,
724
- technicalInstructions: this.shadowRoot.querySelector('textarea[name="technicalInstructions"]')?.value || savedAgent.technicalInstructions,
725
- thinking_level: this.shadowRoot.querySelector('select[name="thinking_level"]')?.value || savedAgent.thinking_level
726
- };
804
+ // Don't replace the agent object - keep the current form data
805
+ // Just update the hashver if the server returned it
806
+ if (result.hashver) {
807
+ this.agent.hashver = result.hashver;
808
+ }
727
809
 
728
- // Reset editors after partial save (from icon buttons)
729
- if (isPartialSave) {
730
- this.showInstructionsEditor = false;
731
- this.showTechnicalInstructionsEditor = false;
810
+ // If this was a new agent, update the UI state
811
+ if (this.newAgent) {
812
+ this.newAgent = false;
813
+ this.selectedAgentName = this.agent.name; // Use the current agent name
814
+ await this.fetchAgents(); // Refresh agent list
815
+ // Update the dropdown to show the new agent
816
+ const select = this.shadowRoot.querySelector('.agent-selector select');
817
+ if (select) {
818
+ select.value = this.agent.name;
819
+ }
732
820
  }
821
+
822
+ // Force a re-render to ensure UI is in sync
823
+ this.requestUpdate();
824
+
825
+ // Keep editors open if they were open
826
+ // User can close them manually if desired
733
827
 
734
828
  showNotification('success', `Agent ${this.agent.name} saved successfully`);
735
829
 
736
- // Dispatch event with merged data to preserve form state
830
+ // Dispatch event
737
831
  this.dispatchEvent(new CustomEvent('agent-saved', {
738
- detail: this.agent, // Send the merged agent data, not just savedAgent
832
+ detail: { ...this.agent },
739
833
  bubbles: true,
740
834
  composed: true
741
835
  }));
742
836
  } catch (error) {
743
837
  showNotification('error', `Error saving agent: ${error.message}`);
744
-
745
- // Restore form state on error
746
- this.agent = {
747
- ...this.agent,
748
- ...formState
749
- };
750
-
751
- // Force update to refresh the form with restored data
752
- this.requestUpdate();
753
838
  } finally {
754
839
  this.loading = false;
755
840
  }
@@ -757,8 +842,10 @@ class AgentForm extends BaseEl {
757
842
 
758
843
  renderRequiredPlugins() {
759
844
  // Ensure required_plugins is always an array
760
- if (!Array.isArray(this.agent.recommended_plugins)) {
761
- this.agent.recommended_plugins = [];
845
+ if (!Array.isArray(this.agent?.recommended_plugins)) {
846
+ if (this.agent) {
847
+ this.agent.recommended_plugins = [];
848
+ }
762
849
  }
763
850
 
764
851
  if (!this.plugins || this.plugins.length === 0) {
@@ -787,7 +874,7 @@ class AgentForm extends BaseEl {
787
874
  <div class="command-name">${source}</div>
788
875
  </div>
789
876
  <toggle-switch
790
- .checked=${Boolean(this.agent.recommended_plugins.includes(source))}
877
+ .checked=${Boolean(this.agent?.recommended_plugins?.includes(source))}
791
878
  id="${toggleId}"
792
879
  @toggle-change=${(e) => this.handleInputChange({
793
880
  target: {
@@ -822,7 +909,7 @@ class AgentForm extends BaseEl {
822
909
  </div>
823
910
  <toggle-switch
824
911
  class="toggle-command"
825
- .checked=${this.agent.commands?.includes(command.name) || false}
912
+ .checked=${this.agent?.commands?.includes(command.name) || false}
826
913
  id="cmd-${command.name}"
827
914
  @toggle-change=${(e) => this.handleInputChange({
828
915
  target: {
@@ -841,51 +928,53 @@ class AgentForm extends BaseEl {
841
928
  `);
842
929
  }
843
930
 
844
- renderServiceModels() {
845
- if (this.serviceModels === undefined || Object.keys(this.serviceModels).length === 0) {
846
- return html`<div>Loading service models...</div>`;
847
- }
931
+ renderServiceModels() {
932
+ if (this.serviceModels === undefined || Object.keys(this.serviceModels).length === 0) {
933
+ return html`<div>Loading service models...</div>`;
934
+ }
848
935
 
849
- console.log('Service models:', this.serviceModels);
850
- console.log('Agent service models:', this.agent.service_models);
851
- return html`
852
- <div class="commands-category">
853
- <h4>Service Models</h4>
854
- <div class="commands-grid">
855
- ${Object.entries(this.serviceModels).map(([serviceName, providers]) => html`
856
- <div class="command-item">
857
- <div class="command-info">
858
- <div class="command-name">${serviceName}</div>
859
- </div>
860
- <select name="${serviceName}"
861
- class="service-model-select"
862
- @change=${this.handleInputChange}>
863
- ${Object.entries(providers).map(([provider, models]) => html`
864
- <optgroup label="${provider}">
865
- ${models.map(model => html`
866
- <option
867
- ?selected=${this.agent.service_models &&
868
- this.agent.service_models[serviceName] &&
869
- this.agent.service_models[serviceName].provider == provider &&
870
- this.agent.service_models[serviceName].model == model}
871
- value="${provider}__${model}">${model}</option>
872
- `)}
873
- </optgroup>
874
- `)}
875
- </select>
936
+ console.log('Service models:', this.serviceModels);
937
+ console.log('Agent service models:', this.agent?.service_models);
938
+ return html`
939
+ <div class="commands-category">
940
+ <h4>Service Models</h4>
941
+ <div class="commands-grid">
942
+ ${Object.entries(this.serviceModels).map(([serviceName, providers]) => html`
943
+ <div class="command-item">
944
+ <div class="command-info">
945
+ <div class="command-name">${serviceName}</div>
876
946
  </div>
877
- `)}
878
- </div>
879
- `
880
- }
947
+ <select name="${serviceName}"
948
+ class="service-model-select"
949
+ @change=${this.handleInputChange}>
950
+ ${Object.entries(providers).map(([provider, models]) => html`
951
+ <optgroup label="${provider}">
952
+ ${models.map(model => html`
953
+ <option
954
+ ?selected=${this.agent?.service_models &&
955
+ this.agent.service_models[serviceName] &&
956
+ this.agent.service_models[serviceName].provider == provider &&
957
+ this.agent.service_models[serviceName].model == model}
958
+ value="${provider}__${model}">${model}</option>
959
+ `)}
960
+ </optgroup>
961
+ `)}
962
+ </select>
963
+ </div>
964
+ `)}
965
+ </div>
966
+ `
967
+ }
881
968
 
882
969
 
883
970
  renderPreferredProviders() {
884
971
  // Ensure preferred_providers is always an array
885
- if (!Array.isArray(this.agent.preferred_providers)) {
886
- this.agent.preferred_providers = [];
972
+ if (!Array.isArray(this.agent?.preferred_providers)) {
973
+ if (this.agent) {
974
+ this.agent.preferred_providers = [];
975
+ }
887
976
  }
888
- console.log('Preferred providers:', this.agent.preferred_providers);
977
+ console.log('Preferred providers:', this.agent?.preferred_providers);
889
978
  return html`
890
979
  <div class="commands-category">
891
980
  <h4>Preferred Providers</h4>
@@ -901,7 +990,7 @@ renderServiceModels() {
901
990
  <div class="command-name">${plugin.name}</div>
902
991
  </div>
903
992
  <toggle-switch
904
- .checked=${this.agent.preferred_providers?.includes(plugin.name) || false}
993
+ .checked=${this.agent?.preferred_providers?.includes(plugin.name) || false}
905
994
  id="${toggleId}"
906
995
  @toggle-change=${(e) => this.handlePreferredProviderChange({
907
996
  detail: {
@@ -942,162 +1031,185 @@ renderServiceModels() {
942
1031
 
943
1032
  _render() {
944
1033
  return html`
945
- <form class="agent-form" @submit=${this.handleSubmit}>
946
- <div class="form-group">
947
- <label class="required">Name:</label>
948
- <input type="text" name="name"
949
- .value=${this.agent.name || ''}
950
- @input=${this.handleInputChange}>
951
- </div>
1034
+ <div class="agent-selector">
1035
+ <select @change=${this.handleAgentChange}
1036
+ .value=${this.selectedAgentName || ''}>
1037
+ <option value="">Select an agent</option>
1038
+ ${this.agents.map(agent => html`
1039
+ <option value=${agent.name} ?selected=${agent.name === this.selectedAgentName}>${agent.name}</option>
1040
+ `)}
1041
+ </select>
1042
+ <button class="btn btn-secondary" @click=${this.handleNewAgent}>
1043
+ New Agent
1044
+ </button>
1045
+ </div>
952
1046
 
953
- <div class="form-group">
954
- <label class="required">Persona:</label>
955
- <select name="persona"
956
- value=${this.agent.persona || ''}
957
- @change=${this.handleInputChange}>
958
- <option value="">Select a persona</option>
959
- ${this.personas.map(persona => html`
960
- <option value="${persona.name}" ?selected=${persona.name === this.agent.persona}>${persona.name}</option>
961
- `)}
962
- </select>
963
- </div>
1047
+ ${this.agent ? html`
1048
+ <form class="agent-form" @submit=${this.handleSubmit}>
1049
+ <div class="form-group">
1050
+ <label class="required">Name:</label>
1051
+ <input type="text" name="name"
1052
+ .value=${this.agent.name || ''}
1053
+ @input=${this.handleInputChange}>
1054
+ </div>
964
1055
 
965
- <div class="form-group">
966
- <div class="form-group-header">
967
- <label class="required">Instructions:</label>
968
- <div class="form-group-actions">
969
- ${this.showInstructionsEditor ? html`
970
- <button type="button" class="icon-button partial-save" @click=${async (e) => { e.preventDefault(); await this.handleSubmit(e); }}>
971
- <span class="material-icons">save</span>
972
- </button>
973
- ` : html`
974
- <button type="button" class="icon-button" @click=${() => this.showInstructionsEditor = true}>
975
- <span class="material-icons">edit</span>
976
- </button>
977
- `}
978
- </div>
1056
+ <div class="form-group">
1057
+ <label class="required">Persona:</label>
1058
+ <select name="persona"
1059
+ value=${this.agent.persona || ''}
1060
+ @change=${this.handleInputChange}>
1061
+ <option value="">Select a persona</option>
1062
+ ${this.personas.map(persona => html`
1063
+ <option value="${persona.name}" ?selected=${persona.name === this.agent.persona}>${persona.name}</option>
1064
+ `)}
1065
+ </select>
979
1066
  </div>
980
- ${this.showInstructionsEditor ? html`
981
- <textarea name="instructions"
982
- .value=${this.agent.instructions || ''}
983
- @input=${this.handleInputChange}></textarea>
984
- ` : html`
985
- <div class="markdown-preview">
986
- ${unsafeHTML(this.renderMarkdown(this.agent.instructions || ''))}
987
- </div>
988
- `}
989
- </div>
990
1067
 
991
- <div class="form-group">
992
- <div class="form-group-header">
993
- <label>Technical Instructions:</label>
994
- <div class="form-group-actions">
995
- ${this.showTechnicalInstructionsEditor ? html`
996
- <button type="button" class="icon-button partial-save" @click=${async (e) => { e.preventDefault(); await this.handleSubmit(e); }}>
997
- <span class="material-icons">save</span>
998
- </button>
999
- ` : html`
1000
- <button type="button" class="icon-button" @click=${() => this.showTechnicalInstructionsEditor = true}>
1001
- <span class="material-icons">edit</span>
1002
- </button>
1003
- `}
1068
+ <div class="form-group">
1069
+ <div class="form-group-header">
1070
+ <label class="required">Instructions:</label>
1071
+ <div class="form-group-actions">
1072
+ ${this.showInstructionsEditor ? html`
1073
+ <button type="button" class="icon-button" @click=${this.handleSubmit}>
1074
+ <span class="material-icons">save</span>
1075
+ </button>
1076
+ ` : html`
1077
+ <button type="button" class="icon-button" @click=${() => {
1078
+ this.showInstructionsEditor = true;
1079
+ }}>
1080
+ <span class="material-icons">edit</span>
1081
+ </button>
1082
+ `}
1083
+ </div>
1004
1084
  </div>
1085
+ ${this.showInstructionsEditor ? html`
1086
+ <textarea name="instructions"
1087
+ .value=${this.agent.instructions || ''}
1088
+ @input=${this.handleInputChange}></textarea>
1089
+ ` : html`
1090
+ <div class="markdown-preview">
1091
+ ${unsafeHTML(this.renderMarkdown(this.agent.instructions || ''))}
1092
+ </div>
1093
+ `}
1005
1094
  </div>
1006
- ${this.showTechnicalInstructionsEditor ? html`
1007
- <textarea name="technicalInstructions"
1008
- .value=${this.agent.technicalInstructions || ''}
1009
- @input=${this.handleInputChange}></textarea>
1010
- ` : html`
1011
- <div class="markdown-preview">
1012
- ${unsafeHTML(this.renderMarkdown(this.agent.technicalInstructions || ''))}
1095
+
1096
+ <div class="form-group">
1097
+ <div class="form-group-header">
1098
+ <label>Technical Instructions:</label>
1099
+ <div class="form-group-actions">
1100
+ ${this.showTechnicalInstructionsEditor ? html`
1101
+ <button type="button" class="icon-button" @click=${this.handleSubmit}>
1102
+ <span class="material-icons">save</span>
1103
+ </button>
1104
+ ` : html`
1105
+ <button type="button" class="icon-button" @click=${() => {
1106
+ this.showTechnicalInstructionsEditor = true;
1107
+ }}>
1108
+ <span class="material-icons">edit</span>
1109
+ </button>
1110
+ `}
1111
+ </div>
1013
1112
  </div>
1014
- `}
1015
- </div>
1113
+ ${this.showTechnicalInstructionsEditor ? html`
1114
+ <textarea name="technicalInstructions"
1115
+ .value=${this.agent.technicalInstructions || ''}
1116
+ @input=${this.handleInputChange}></textarea>
1117
+ ` : html`
1118
+ <div class="markdown-preview">
1119
+ ${unsafeHTML(this.renderMarkdown(this.agent.technicalInstructions || ''))}
1120
+ </div>
1121
+ `}
1122
+ </div>
1016
1123
 
1017
- <div class="form-group">
1018
- <label>
1019
- Uncensored:
1020
- <toggle-switch
1021
- .checked=${this.agent.uncensored || false}
1022
- @toggle-change=${(e) => this.handleInputChange({
1023
- target: {
1024
- name: 'uncensored',
1025
- type: 'checkbox',
1026
- checked: e.detail.checked
1027
- }
1028
- })}>
1029
- </toggle-switch>
1030
- </label>
1031
- </div>
1124
+ <div class="form-group">
1125
+ <label>
1126
+ Uncensored:
1127
+ <toggle-switch
1128
+ .checked=${this.agent.uncensored || false}
1129
+ @toggle-change=${(e) => this.handleInputChange({
1130
+ target: {
1131
+ name: 'uncensored',
1132
+ type: 'checkbox',
1133
+ checked: e.detail.checked
1134
+ }
1135
+ })}>
1136
+ </toggle-switch>
1137
+ </label>
1138
+ </div>
1032
1139
 
1033
- <div class="form-group reasoning-level-group">
1034
- <label>Reasoning Effort:</label>
1035
- <select name="thinking_level"
1036
- value=${this.agent.thinking_level || 'off'}
1037
- @change=${this.handleInputChange}>
1038
- <option value="off"
1039
- ?selected=${(this.agent.thinking_level || 'off') === 'off'}>
1040
- Off
1041
- </option>
1042
- <option value="low"
1043
- ?selected=${(this.agent.thinking_level || 'off') === 'low'}>
1044
- Low
1045
- </option>
1046
- <option value="medium"
1047
- ?selected=${(this.agent.thinking_level || 'off') === 'medium'}>
1048
- Medium
1049
- </option>
1050
- <option value="high"
1051
- ?selected=${(this.agent.thinking_level || 'off') === 'high'}>
1052
- High
1053
- </option>
1054
- </select>
1055
- </div>
1056
-
1057
- ${this.renderPendingPlugins()}
1058
-
1059
- <div class="form-group commands-section">
1060
- <details>
1061
- <summary>Preferred Providers</summary>
1062
- ${this.renderPreferredProviders()}
1063
- </details>
1064
- </div>
1065
-
1066
- <div class="form-group commands-section">
1067
- <details>
1068
- <summary>Select Models</summary>
1069
- ${this.renderServiceModels()}
1070
- </details>
1071
- </div>
1072
-
1073
- <div class="form-group commands-section">
1074
- <details>
1075
- <summary>Recommended Plugins</summary>
1076
- ${this.renderRequiredPlugins()}
1077
- </details>
1078
- </div>
1140
+ <div class="form-group reasoning-level-group">
1141
+ <label>Reasoning Effort:</label>
1142
+ <select name="thinking_level"
1143
+ value=${this.agent.thinking_level || 'off'}
1144
+ @change=${this.handleInputChange}>
1145
+ <option value="off"
1146
+ ?selected=${(this.agent.thinking_level || 'off') === 'off'}>
1147
+ Off
1148
+ </option>
1149
+ <option value="low"
1150
+ ?selected=${(this.agent.thinking_level || 'off') === 'low'}>
1151
+ Low
1152
+ </option>
1153
+ <option value="medium"
1154
+ ?selected=${(this.agent.thinking_level || 'off') === 'medium'}>
1155
+ Medium
1156
+ </option>
1157
+ <option value="high"
1158
+ ?selected=${(this.agent.thinking_level || 'off') === 'high'}>
1159
+ High
1160
+ </option>
1161
+ </select>
1162
+ </div>
1163
+
1164
+ ${this.renderPendingPlugins()}
1079
1165
 
1080
- ${this.agent.name && this.missingCommands && Object.keys(this.missingCommands).length > 0 ? html`
1081
1166
  <div class="form-group commands-section">
1082
1167
  <details>
1083
- <summary>Missing Commands (${Object.keys(this.missingCommands).length})</summary>
1084
- <missing-commands .agentName=${this.agent.name}></missing-commands>
1168
+ <summary>Preferred Providers</summary>
1169
+ ${this.renderPreferredProviders()}
1170
+ </details>
1171
+ </div>
1172
+
1173
+ <div class="form-group commands-section">
1174
+ <details>
1175
+ <summary>Select Models</summary>
1176
+ ${this.renderServiceModels()}
1177
+ </details>
1178
+ </div>
1179
+
1180
+ <div class="form-group commands-section">
1181
+ <details>
1182
+ <summary>Recommended Plugins</summary>
1183
+ ${this.renderRequiredPlugins()}
1085
1184
  </details>
1086
1185
  </div>
1087
- ` : ''}
1088
1186
 
1089
- <div class="form-group commands-section">
1090
- <details><summary>Available Commands</summary>
1091
- ${this.renderCommands()}
1092
- </details>
1093
- </div>
1187
+ ${this.agent.name && this.missingCommands && Object.keys(this.missingCommands).length > 0 ? html`
1188
+ <div class="form-group commands-section">
1189
+ <details>
1190
+ <summary>Missing Commands (${Object.keys(this.missingCommands).length})</summary>
1191
+ <missing-commands .agentName=${this.agent.name}></missing-commands>
1192
+ </details>
1193
+ </div>
1194
+ ` : ''}
1094
1195
 
1095
- <div class="agent-insert-end"></div>
1096
- <button class="btn" type="submit" ?disabled=${this.loading}>
1097
- ${this.loading ? 'Saving...' : 'Save'}
1098
- </button>
1099
-
1100
- </form>
1196
+ <div class="form-group commands-section">
1197
+ <details><summary>Available Commands</summary>
1198
+ ${this.renderCommands()}
1199
+ </details>
1200
+ </div>
1201
+
1202
+ <div class="agent-insert-end"></div>
1203
+ <button class="btn" type="submit" ?disabled=${this.loading}>
1204
+ ${this.loading ? 'Saving...' : 'Save'}
1205
+ </button>
1206
+
1207
+ </form>
1208
+ ` : html`
1209
+ <div class="no-agent-message">
1210
+ Select an agent from the dropdown above or click "New Agent" to create one.
1211
+ </div>
1212
+ `}
1101
1213
  `;
1102
1214
  }
1103
1215
  }