-
-
-
-
-
-
-
-
-
-
-
-
- handleNumberChange(e.target.value)"
- class="number-input"
- />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/frontend/src/views/Agent.vue b/frontend/src/views/Agent.vue
index 5e1d02a..3e6fa15 100644
--- a/frontend/src/views/Agent.vue
+++ b/frontend/src/views/Agent.vue
@@ -5,6 +5,7 @@
} from "vue";
import TitleBar from '../components/TitleBar.vue';
+ import JsonEditor from '../components/JsonEditor.vue';
import * as backend from '../backend';
import * as ui from '../ui';
@@ -19,10 +20,16 @@
// Data
const agent = ref({});
const kindInfo = ref({});
- const configFields = ref([]);
+ const config = ref({
+ schema: {type: 'object'},
+ object: {}
+ });
const resources = ref([]);
const tools = ref([]);
- const modelList = ref([]);
+ const modelSchema = ref({
+ type: 'number', enum: [],
+ ui: {enumNames: {}},
+ });
// UI State
const addingTool = ref(null);
@@ -30,6 +37,10 @@
// === State Management === //
+ watch(() => config.value, newConfig => {
+ console.log(newConfig);
+ });
+
async function loadAgentData (agentname) {
const _agent = await backend.getAgent(agentname);
if (!_agent) {
@@ -51,18 +62,32 @@
});
backend.sendAction('get-agent-config-fields', {agentname}).then(res => {
- const dataObject = Object.fromEntries(res.fields.map(
- field => [field.name, field.value]
- ));
+ let value = {};
+ let properties = {};
- configFields.value = res.fields.map(field => ({
- name: field.name,
- type: field.type,
- value: field.value,
- kind: field.type,
- default: null,
- enabled: field.value != null,
- }));
+ for (let field of res.fields) {
+ let type = field.type;
+ if (typeof type == 'string')
+ type = {type: field.type};
+
+ // Special model type
+ if (type.type == 'model_id') {
+ type = modelSchema.value;
+ }
+
+ properties[field.name] = type;
+
+ // horde sends empty agent fields as null
+ if (field.value != null) {
+ value[field.name] = field.value;
+ // If a field is removed and had an initial value,
+ // null must be sent to remove upstream
+ type._initial = true;
+ }
+ }
+
+ config.value.schema.properties = properties;
+ config.value.object = value;
});
// Replace with a backend call
@@ -74,7 +99,15 @@
async function loadModels () {
let res = await backend.sendAction("get-models");
- modelList.value = res.models;
+
+ let values = [];
+ let names = [];
+ for (let model of res.models) {
+ values.push(model.id);
+ names.push(model.name);
+ }
+ modelSchema.value.enum = values;
+ modelSchema.value.ui.enumNames = names;
}
// This won't fire when immediately, the mounted callback will take care
@@ -87,7 +120,9 @@
loadModels();
});
+
// === Prompt === //
+
const promptInstructionEnabled = ref(false);
const promptInstruction = ref("");
const promptInput = ref("");
@@ -148,6 +183,8 @@
// === Configuration === //
+ const configObject = ref({});
+
async function updateIdentifier() {
const value = prompt(`Enter a new identifier for ${agent.value.name}`);
if (value) {
@@ -181,33 +218,19 @@
ui.alert("Cancelled name update");
}
}
- async function saveChanges() {
- const dataObject = {};
- for (let field of configFields.value) {
- if (field.enabled) {
- let value = field.value;
- if (field.kind == 'number') {
- try {
- value = parseFloat(value);
- } catch (e) {
- ui.alert("bad number at field " + field.name);
- return;
- }
- } else if (field.kind != 'string') {
- try {
- value = JSON.parse(value);
- } catch (e) {
- ui.alert("bad JSON value at field " + field.name);
- return;
- }
- }
- dataObject[field.name] = value;
+ async function saveConfig() {
+ let object = {...config.value.object};
+
+ // Collect removed properties
+ for (let [key, schema] of Object.entries(config.value.schema.properties)) {
+ if (object[key] === undefined && schema._initial) {
+ object[key] = null;
}
}
await backend.act("update-agent", {
agentname: agent.value.agentname,
- data: dataObject,
+ data: object,
}, {
alert: 'Agent updated',
cache: {agents: true},
@@ -301,19 +324,8 @@