Scripted Agent WIP, only definitions
This commit is contained in:
1 parent
13e7c12e75
commit
5efe4f3325
4 files changed
+122
-1
No files matched your search
@@ -1,2 +1,3 @@
|
|||||||
from .character import CharacterAgent
|
from .character import CharacterAgent
|
||||||
from .expert import ExpertAgent
|
from .expert import ExpertAgent
|
||||||
|
from .scripted import ScriptedAgent
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import re
|
||||||
|
import json
|
||||||
|
import inspect
|
||||||
|
from string import Template
|
||||||
|
|
||||||
|
from inference import LlamaMessage, replicate_llama_completion, Models
|
||||||
|
from agent import Agent, AgentField
|
||||||
|
|
||||||
|
CLASS_DESCRIPTION = """
|
||||||
|
Scripted agents can be configured with custom Python actions.
|
||||||
|
The 'actions' config field has a list of action names. Each action is configured in a corresponding "action_name" with the name of the action, and contains: argument (object schema object), and body (python string source).
|
||||||
|
""".strip()
|
||||||
|
|
||||||
|
class ScriptedAgent(Agent):
|
||||||
|
identifier = "scripted"
|
||||||
|
description = CLASS_DESCRIPTION
|
||||||
|
schema_fields = [
|
||||||
|
AgentField('actions', 'array', default=[]),
|
||||||
|
]
|
||||||
|
|
||||||
|
def __init__(self, app, data):
|
||||||
|
Agent.__init__(self, app, data)
|
||||||
|
|
||||||
|
async def prompt(self, instruction, input=None, **kwargs):
|
||||||
|
raise Exception("Scripted agent cannot use prompts (Unimplemented)")
|
||||||
|
|
||||||
|
async def received_message(self, message):
|
||||||
|
raise Exception("Scripted agent cannot use chat (Unimplemented)")
|
||||||
|
|
||||||
|
async def execute_action(self, name: str, argument: dict):
|
||||||
|
raise Exception("No actions for this agent")
|
||||||
@@ -39,6 +39,7 @@ class App(ChatMixin):
|
|||||||
agent_mod.BasicAgent,
|
agent_mod.BasicAgent,
|
||||||
agents_mod.CharacterAgent,
|
agents_mod.CharacterAgent,
|
||||||
agents_mod.ExpertAgent,
|
agents_mod.ExpertAgent,
|
||||||
|
agents_mod.ScriptedAgent,
|
||||||
|
|
||||||
#agent_mod.LlamaAgent,
|
#agent_mod.LlamaAgent,
|
||||||
#agent_mod.CoderV1Agent,
|
#agent_mod.CoderV1Agent,
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
const agent = ref({});
|
const agent = ref({});
|
||||||
const kindInfo = ref({});
|
const kindInfo = ref({});
|
||||||
const configFields = ref([]);
|
const configFields = ref([]);
|
||||||
|
// Only used for scripted agents.
|
||||||
|
const actionDefinitions = ref([]);
|
||||||
|
|
||||||
|
|
||||||
// === State Management === //
|
// === State Management === //
|
||||||
@@ -40,9 +42,14 @@
|
|||||||
|
|
||||||
backend.sendAction("get-agent-kind-info", {kind: _agent.kind}).then(res => {
|
backend.sendAction("get-agent-kind-info", {kind: _agent.kind}).then(res => {
|
||||||
kindInfo.value.description = res.info.description;
|
kindInfo.value.description = res.info.description;
|
||||||
|
kindInfo.value.name = _agent.kind;
|
||||||
});
|
});
|
||||||
|
|
||||||
backend.sendAction('get-agent-config-fields', {agentId}).then(res => {
|
backend.sendAction('get-agent-config-fields', {agentId}).then(res => {
|
||||||
|
const dataObject = Object.fromEntries(res.fields.map(
|
||||||
|
field => [field.name, field.value]
|
||||||
|
));
|
||||||
|
|
||||||
configFields.value = res.fields.map(field => ({
|
configFields.value = res.fields.map(field => ({
|
||||||
name: field.name,
|
name: field.name,
|
||||||
type: field.type,
|
type: field.type,
|
||||||
@@ -50,6 +57,18 @@
|
|||||||
default: null,
|
default: null,
|
||||||
enabled: field.value != 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",
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,6 +205,59 @@
|
|||||||
backend.invalidateCache({agents: true});
|
backend.invalidateCache({agents: true});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// == Scripted Agent Actions == //
|
||||||
|
function createAction () {
|
||||||
|
const value = prompt(`Enter a new identifier for ${agent.value.name}`);
|
||||||
|
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');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 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,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
saveChanges();
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -243,6 +315,22 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
</section>
|
</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>
|
<section>
|
||||||
<div v-for="(configField, index) in configFields" :key="index">
|
<div v-for="(configField, index) in configFields" :key="index">
|
||||||
<span class="label">{{ configField.name }}</span>
|
<span class="label">{{ configField.name }}</span>
|
||||||
|
|||||||
Reference in new issue
Block a user