feat(frontend): agent resource sections
This commit is contained in:
1 parent
a10224d21e
commit
6134c026a6
3 files changed
+82
-80
No files matched your search
+7
-3
@@ -285,9 +285,13 @@ class App(ChatMixin):
|
||||
|
||||
# --- Resource Management ---
|
||||
|
||||
async def get_agent_resource(self, agent_id, kind, key):
|
||||
resource = await db.AgentResource.get_or_none(agent_id=agent_id, kind=kind, key=key)
|
||||
return resource.value if resource else None
|
||||
async def get_agent_resources(self, agent_id, kind=None, key=None):
|
||||
filter = {"agent_id": agent_id}
|
||||
if kind: filter['kind'] = kind
|
||||
if key: filter['key'] = key
|
||||
|
||||
values = await db.AgentResource.filter(**filter)
|
||||
return values
|
||||
|
||||
async def save_agent_resource(self, agent_id, kind, key, value):
|
||||
await db.AgentResource.update_or_create(
|
||||
|
||||
@@ -223,6 +223,14 @@ async def start_server(app):
|
||||
elif action == "get-agents":
|
||||
await send({'message': "agents retrieved", 'agents': await app.get_agents(user_id), 'nonce': nonce})
|
||||
|
||||
elif action == "get-agent-resources":
|
||||
values = await app.get_agent_resources(body['agentId'], body.get('kind'), body.get('key'))
|
||||
await send({'resources': [{'kind': r.kind, 'key': r.key, 'value': r.value} for r in values], 'nonce': nonce})
|
||||
|
||||
elif action == "save-agent-resource":
|
||||
await app.save_agent_resource(body['agentId'], body['kind'], body['key'], body['value'])
|
||||
await send({'message': "resource saved", 'nonce': nonce})
|
||||
|
||||
elif action == "get-agent-runs":
|
||||
await send({
|
||||
'runs': await app.get_agent_runs(agent_id=body.get('agentId'), user_id=user_id),
|
||||
|
||||
@@ -16,13 +16,17 @@
|
||||
},
|
||||
});
|
||||
|
||||
// Data
|
||||
const agent = ref({});
|
||||
const kindInfo = ref({});
|
||||
const configFields = ref([]);
|
||||
// Only used for scripted agents.
|
||||
const actionDefinitions = ref([]);
|
||||
const resources = ref([]);
|
||||
const tools = ref([]);
|
||||
const modelList = ref([]);
|
||||
|
||||
// UI State
|
||||
const addingTool = ref(null);
|
||||
const addingResource = ref(null);
|
||||
|
||||
// === State Management === //
|
||||
|
||||
@@ -59,18 +63,12 @@
|
||||
default: null,
|
||||
enabled: field.value != null,
|
||||
}));
|
||||
});
|
||||
|
||||
if (dataObject.actions) {
|
||||
actionDefinitions.value = dataObject.actions.map(name => {
|
||||
const fieldName = 'action_' + name;
|
||||
const fieldData = dataObject[fieldName];
|
||||
return {
|
||||
name,
|
||||
argument: fieldData ? JSON.stringify(fieldData.argument) : "{}",
|
||||
body: fieldData && fieldData.body || "pass",
|
||||
}
|
||||
});
|
||||
}
|
||||
// Replace with a backend call
|
||||
backend.sendAction('get-agent-resources', {agentId}).then(res => {
|
||||
tools.value = res.resources.filter(r => r.kind == 'tool');
|
||||
resources.value = res.resources.filter(r => !['tool', 'config'].includes(r.kind));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -230,57 +228,34 @@
|
||||
}
|
||||
}
|
||||
|
||||
// == Scripted Agent Actions == //
|
||||
function createAction () {
|
||||
const value = prompt(`Enter an identifier for the new action`);
|
||||
if (value) {
|
||||
const def = {
|
||||
name: value,
|
||||
argument: "{}",
|
||||
body: "pass",
|
||||
};
|
||||
const actionsField = configFields.value.find(field => field.name == 'actions');
|
||||
if (actionsField) {
|
||||
actionsField.value.push(def.name);
|
||||
} else {
|
||||
configFields.value.push({
|
||||
name: def.name,
|
||||
value: [def.name],
|
||||
enabled: true,
|
||||
});
|
||||
}
|
||||
saveAction(def);
|
||||
} else {
|
||||
ui.alert('Action creation cancelled');
|
||||
}
|
||||
async function saveAddingTool() {
|
||||
let resource = {
|
||||
kind: 'tool',
|
||||
key: addingTool.value.name,
|
||||
value: JSON.parse(addingTool.value.value),
|
||||
};
|
||||
addingTool.value = null;
|
||||
|
||||
let res = await backend.sendAction("save-agent-resource", {
|
||||
agentId: agent.value.id,
|
||||
...resource
|
||||
});
|
||||
tools.value.push(resource);
|
||||
}
|
||||
// Update the config fields relevant to the action and saves changes automatically. Doesn't update 'actions'.
|
||||
function saveAction (actionDef) {
|
||||
let argSchema;
|
||||
try {
|
||||
argSchema = JSON.parse(actionDef.argument);
|
||||
} catch (e) {
|
||||
ui.alert("Bad Argument JSON: " + e.message);
|
||||
return;
|
||||
}
|
||||
|
||||
const fieldName = 'action_' + actionDef.name;
|
||||
const actionField = configFields.value.find(field => field.name == fieldName);
|
||||
if (actionField) {
|
||||
actionField.arguments = argSchema;
|
||||
actionField.body = actionDef.body;
|
||||
} else {
|
||||
configFields.value.push({
|
||||
name: fieldName,
|
||||
value: {
|
||||
argument: argSchema,
|
||||
body: actionDef.body,
|
||||
},
|
||||
enabled: true,
|
||||
});
|
||||
}
|
||||
async function saveAddingResource() {
|
||||
let resource = {
|
||||
kind: addingResource.value.kind,
|
||||
key: addingResource.value.key,
|
||||
value: JSON.parse(addingResource.value.value),
|
||||
};
|
||||
addingResource.value = null;
|
||||
|
||||
saveChanges();
|
||||
let res = await backend.sendAction("save-agent-resource", {
|
||||
agentId: agent.value.id,
|
||||
...resource
|
||||
});
|
||||
resources.value.push(resource);
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -339,22 +314,6 @@
|
||||
</div>
|
||||
|
||||
</section>
|
||||
<template v-if="actionDefinitions && kindInfo.name == 'scripted'">
|
||||
<section v-for="(actionDef, index) in actionDefinitions" :key="index">
|
||||
<h3>Action {{actionDef.name}}</h3>
|
||||
<span class="label">argument</span>
|
||||
<br>
|
||||
<textarea v-model="actionDef.argument" class="config-input"/>
|
||||
<br>
|
||||
<span class="label">body</span>
|
||||
<br>
|
||||
<textarea v-model="actionDef.body" class="config-input"/>
|
||||
<button @click="saveAction(actionDef)">Save Action</button>
|
||||
</section>
|
||||
<section>
|
||||
<button @click="createAction()">Create Action</button>
|
||||
</section>
|
||||
</template>
|
||||
<section>
|
||||
<div v-for="(configField, index) in configFields" :key="index">
|
||||
<span class="label">{{ configField.name }}</span>
|
||||
@@ -370,6 +329,37 @@
|
||||
|
||||
<button type="submit" @click="saveChanges()">Save</button>
|
||||
</section>
|
||||
<section>
|
||||
<h3>Tools</h3>
|
||||
<div v-for="(resource, index) in tools">
|
||||
<div class="label">{{ resource.key }}</div>
|
||||
<pre>{{ JSON.stringify(resource.value, null, 2) }}</pre>
|
||||
</div>
|
||||
<section v-if="addingTool">
|
||||
<input v-model="addingTool.name" placeholder="name"><br>
|
||||
<textarea v-model="addingTool.value" placeholder="{}"></textarea>
|
||||
<br>
|
||||
<button @click="saveAddingTool()">Save</button>
|
||||
<button @click="addingTool=null">Cancel</button>
|
||||
</section>
|
||||
<div v-else><button @click="addingTool={}">Add Tool</button></div>
|
||||
</section>
|
||||
<section>
|
||||
<h3>Resources</h3>
|
||||
<div v-for="resource in resources">
|
||||
<div class="label">{{ resource.kind }}:{{ resource.key }}</div>
|
||||
<pre>{{ JSON.stringify(resource.value, null, 2) }}</pre>
|
||||
</div>
|
||||
<section v-if="addingResource">
|
||||
<input v-model="addingResource.kind" placeholder="kind/domain"><br>
|
||||
<input v-model="addingResource.key" placeholder="key"><br>
|
||||
<textarea v-model="addingResource.value" placeholder="value"></textarea>
|
||||
<br>
|
||||
<button @click="saveAddingResource()">Save</button>
|
||||
<button @click="addingResource=null">Cancel</button>
|
||||
</section>
|
||||
<div v-else><button @click="addingResource={}">Add Resource</button></div>
|
||||
</section>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in new issue
Block a user