feat(frontend): agent resource sections

This commit is contained in:
Shivering Ocelot committed 2026-06-06 21:56:12 -05:00
1 parent a10224d21e
commit 6134c026a6
3 files changed
+80 -78

No files matched your search

+7 -3
View File
@@ -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(
+8
View File
@@ -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),
+65 -75
View File
@@ -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",
async function saveAddingTool() {
let resource = {
kind: 'tool',
key: addingTool.value.name,
value: JSON.parse(addingTool.value.value),
};
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,
addingTool.value = null;
let res = await backend.sendAction("save-agent-resource", {
agentId: agent.value.id,
...resource
});
}
saveAction(def);
} else {
ui.alert('Action creation cancelled');
}
}
// 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;
tools.value.push(resource);
}
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>