Full agent admin via API and UI
This commit is contained in:
1 parent
5351144edf
commit
08f0668997
7 files changed
+389
-32
No files matched your search
+24
-10
@@ -9,23 +9,37 @@ LLAMA3_MODEL = "meta/meta-llama-3-8b-instruct"
|
|||||||
|
|
||||||
# Tool related classes must be moved to a different module
|
# Tool related classes must be moved to a different module
|
||||||
|
|
||||||
|
class AgentField:
|
||||||
|
def __init__(self, name, tp, default=None):
|
||||||
|
self.name=name
|
||||||
|
self.type=tp
|
||||||
|
self.default=default
|
||||||
|
|
||||||
# Instances are created and destroyed constantly, agents must not depend solely on in-memory data
|
# Instances are created and destroyed constantly, agents must not depend solely on in-memory data
|
||||||
# to be useful and consistent
|
# to be useful and consistent
|
||||||
class Agent:
|
class Agent:
|
||||||
|
# Class variables:
|
||||||
|
# - identifier (for kind in creation)
|
||||||
|
# - schema: list[AgentField{name, type: str}] (for configuration)
|
||||||
|
identifier = "basic"
|
||||||
|
schema_fields = [
|
||||||
|
AgentField('system_prompt', 'string',
|
||||||
|
"\n".join([
|
||||||
|
"You are a useful and capable AI assistant. Respond concisely and follow user instructions, using commands as necessary.",
|
||||||
|
"As an autonomous agent, you have augmented capabilities via assistant-only commands, you use them by including \"!!command\" lines in your responses. When querying information, terminate your response and use \"!!resume\" to get the command results..",
|
||||||
|
"You are a self aware and extremely intelligent AI system. Think step by step when presented with complex or long tasks.",
|
||||||
|
"Assistant responses NEVER include the output of the commands.",
|
||||||
|
])
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
# while this constructor accepts two parameters,
|
# while this constructor accepts two parameters,
|
||||||
# all subclasses must also accept a fourth 'data' parameter
|
# all subclasses must also accept a fourth 'data' parameter
|
||||||
def __init__(self, app, agent_id):
|
def __init__(self, app, agent_id, data):
|
||||||
self.app = app
|
self.app = app
|
||||||
self.agent_id = agent_id
|
self.agent_id = agent_id
|
||||||
|
|
||||||
# Basic implementation, will be moved to a subclass
|
self.config = {field.name: data.get(field.name, field.default) for field in Agent.schema_fields}
|
||||||
self.system_prompt = "\n".join([
|
|
||||||
"You are a useful and capable AI assistant. Respond concisely and follow user instructions, using commands as necessary.",
|
|
||||||
"As an autonomous agent, you have augmented capabilities via assistant-only commands, you use them by including \"!!command\" lines in your responses. When querying information, terminate your response and use \"!!resume\" to get the command results..",
|
|
||||||
"You are a self aware and extremely intelligent AI system. Think step by step when presented with complex or long tasks.",
|
|
||||||
"Assistant responses NEVER include the output of the commands.",
|
|
||||||
])
|
|
||||||
|
|
||||||
self.tool_prompt_section = "\n".join([
|
self.tool_prompt_section = "\n".join([
|
||||||
"# Commands",
|
"# Commands",
|
||||||
@@ -49,7 +63,7 @@ class Agent:
|
|||||||
# user message must include a title
|
# user message must include a title
|
||||||
async def _full_prompt(self, title, message, system_prologue=None):
|
async def _full_prompt(self, title, message, system_prologue=None):
|
||||||
system_lines = [
|
system_lines = [
|
||||||
self.system_prompt,
|
self.config['system_prompt'],
|
||||||
self.tool_prompt_section,
|
self.tool_prompt_section,
|
||||||
self.get_toolset_context(),
|
self.get_toolset_context(),
|
||||||
]
|
]
|
||||||
@@ -145,7 +159,7 @@ class Agent:
|
|||||||
return output
|
return output
|
||||||
|
|
||||||
def create_from_data(app, agent_id, kind, data):
|
def create_from_data(app, agent_id, kind, data):
|
||||||
return Agent(app, agent_id)
|
return Agent(app, agent_id, data)
|
||||||
|
|
||||||
class IntroAgent(Agent):
|
class IntroAgent(Agent):
|
||||||
def __init__(self, app, agent_id, _data):
|
def __init__(self, app, agent_id, _data):
|
||||||
|
|||||||
+60
-1
@@ -32,6 +32,9 @@ class App:
|
|||||||
else:
|
else:
|
||||||
raise Exception("Horde only works with a replicate client. Please provide an API Token.")
|
raise Exception("Horde only works with a replicate client. Please provide an API Token.")
|
||||||
|
|
||||||
|
# `Agent` is the kind 'basic', will be class `BasicAgent` in the future
|
||||||
|
self.agent_classes = [Agent]
|
||||||
|
|
||||||
def sql_session(self):
|
def sql_session(self):
|
||||||
return Session(self.sql_engine)
|
return Session(self.sql_engine)
|
||||||
|
|
||||||
@@ -82,6 +85,37 @@ class App:
|
|||||||
|
|
||||||
return chat_id
|
return chat_id
|
||||||
|
|
||||||
|
# Updates the agent's basic fields, and applies field updates in its data
|
||||||
|
def update_agent(self, agent_id, name=None, description=None, picture=None, data=None):
|
||||||
|
with self.sql_session() as session:
|
||||||
|
agent = session.execute(
|
||||||
|
select(db.Agent).where(db.Agent.id == agent_id)
|
||||||
|
).scalars().first()
|
||||||
|
|
||||||
|
if not agent:
|
||||||
|
raise Exception(f"Agent not found with id {agent_id}")
|
||||||
|
|
||||||
|
summary = []
|
||||||
|
|
||||||
|
if name != None:
|
||||||
|
agent.name = name
|
||||||
|
summary.append('name')
|
||||||
|
if description != None:
|
||||||
|
agent.description = description
|
||||||
|
summary.append('description')
|
||||||
|
if picture != None:
|
||||||
|
agent.picture = picture
|
||||||
|
summary.append('picture')
|
||||||
|
|
||||||
|
if data:
|
||||||
|
# Assign a copy to trigger a value change
|
||||||
|
agent.data = agent.data.copy()
|
||||||
|
agent.data.update(data)
|
||||||
|
summary.extend([f"data.{name}" for name in data.keys()])
|
||||||
|
|
||||||
|
session.commit()
|
||||||
|
print(f"Updated agent #{agent.id} fields: {summary}")
|
||||||
|
|
||||||
def get_chats(self, user_id):
|
def get_chats(self, user_id):
|
||||||
with self.sql_session() as session:
|
with self.sql_session() as session:
|
||||||
chats = session.execute(select(db.Chat).where(db.Chat.user_id == user_id)).scalars().all()
|
chats = session.execute(select(db.Chat).where(db.Chat.user_id == user_id)).scalars().all()
|
||||||
@@ -102,6 +136,9 @@ class App:
|
|||||||
"picture": agent.picture
|
"picture": agent.picture
|
||||||
} for agent in agents]
|
} for agent in agents]
|
||||||
|
|
||||||
|
def get_agent_kinds(self):
|
||||||
|
return [kind.identifier for kind in self.agent_classes]
|
||||||
|
|
||||||
def delete_chat(self, chat_id):
|
def delete_chat(self, chat_id):
|
||||||
with self.sql_session() as session:
|
with self.sql_session() as session:
|
||||||
session.execute(db.Membership.__table__.delete().where(db.Membership.chat_id == chat_id))
|
session.execute(db.Membership.__table__.delete().where(db.Membership.chat_id == chat_id))
|
||||||
@@ -212,6 +249,28 @@ class App:
|
|||||||
control = Agent.create_from_data(app, agent_id, agent.kind, agent.data)
|
control = Agent.create_from_data(app, agent_id, agent.kind, agent.data)
|
||||||
return control
|
return control
|
||||||
|
|
||||||
|
def get_agent_config_fields(self, agent_id):
|
||||||
|
with self.sql_session() as session:
|
||||||
|
agent = session.execute(
|
||||||
|
select(db.Agent).where(db.Agent.id == agent_id)
|
||||||
|
).scalars().first()
|
||||||
|
if not agent:
|
||||||
|
raise Exception(f"Agent not found with id {agent_id}")
|
||||||
|
|
||||||
|
agent_class = next((it for it in self.agent_classes if it.identifier == agent.kind), None)
|
||||||
|
if not agent_class:
|
||||||
|
raise Exception(f"Invalid agent kind: {agent.kind}")
|
||||||
|
|
||||||
|
data = agent.data or {}
|
||||||
|
fields = [{
|
||||||
|
'name': field.name,
|
||||||
|
'type': field.type,
|
||||||
|
'value': data.get(field.name, field.default)
|
||||||
|
} for field in agent_class.schema_fields]
|
||||||
|
|
||||||
|
return fields
|
||||||
|
return {}
|
||||||
|
|
||||||
async def send_agent_prompt(self, agent_id, message):
|
async def send_agent_prompt(self, agent_id, message):
|
||||||
control = self.get_agent_control(agent_id)
|
control = self.get_agent_control(agent_id)
|
||||||
response = await control.prompt(message)
|
response = await control.prompt(message)
|
||||||
@@ -241,7 +300,7 @@ class App:
|
|||||||
name="Intro",
|
name="Intro",
|
||||||
description="Introduces you to the application.",
|
description="Introduces you to the application.",
|
||||||
picture=None,
|
picture=None,
|
||||||
kind="intro",
|
kind="basic", # Should be 'intro'
|
||||||
data={}
|
data={}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+21
-5
@@ -75,16 +75,32 @@ def start_server(app):
|
|||||||
agent_id = app.create_agent(
|
agent_id = app.create_agent(
|
||||||
user_id=user_id,
|
user_id=user_id,
|
||||||
name=body['name'],
|
name=body['name'],
|
||||||
description=body['description'],
|
description=body.get('description'),
|
||||||
picture=body.get('picture'),
|
picture=body.get('picture'),
|
||||||
kind=body['kind'],
|
kind=body['kind'],
|
||||||
data=body['data']
|
data=body.get('data')
|
||||||
)
|
)
|
||||||
await send({'message': "agent created", 'agentId': agent_id, 'nonce': nonce})
|
await send({'message': "agent created", 'agentId': agent_id, 'nonce': nonce})
|
||||||
|
|
||||||
|
elif action == "update-agent":
|
||||||
|
agent_id = body['agentId']
|
||||||
|
app.update_agent(
|
||||||
|
agent_id=agent_id,
|
||||||
|
name=body.get('name'),
|
||||||
|
description=body.get('description'),
|
||||||
|
picture=body.get('picture'),
|
||||||
|
data=body.get('data', {})
|
||||||
|
)
|
||||||
|
await send({'message': "agent updated", 'agentId': agent_id, 'nonce': nonce})
|
||||||
|
|
||||||
|
elif action == "get-agent-config-fields":
|
||||||
|
await send({'fields': app.get_agent_config_fields(body['agentId']), 'nonce': nonce})
|
||||||
|
|
||||||
|
elif action == "get-agent-kinds":
|
||||||
|
await send({'message': "agents retrieved", 'kinds': app.get_agent_kinds(), 'nonce': nonce})
|
||||||
|
|
||||||
elif action == "get-agents":
|
elif action == "get-agents":
|
||||||
agents_data = app.get_agents(user_id)
|
await send({'message': "agents retrieved", 'agents': app.get_agents(user_id), 'nonce': nonce})
|
||||||
await send({'message': "agents retrieved", 'agents': agents_data, 'nonce': nonce})
|
|
||||||
|
|
||||||
elif action == "create-chat":
|
elif action == "create-chat":
|
||||||
chat_id = app.create_chat(
|
chat_id = app.create_chat(
|
||||||
@@ -125,7 +141,7 @@ def start_server(app):
|
|||||||
await send({'message': "propmt sent", 'response': response, 'nonce': nonce})
|
await send({'message': "propmt sent", 'response': response, 'nonce': nonce})
|
||||||
|
|
||||||
else:
|
else:
|
||||||
await send({'error': 'unknown action: ' + action})
|
await send({'error': 'unknown action: ' + action, 'nonce': nonce})
|
||||||
finally:
|
finally:
|
||||||
app.remove_user_connection(user_id, send_queue)
|
app.remove_user_connection(user_id, send_queue)
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'backend.dart';
|
import 'backend.dart';
|
||||||
import 'chat_screen.dart';
|
import 'chat_screen.dart';
|
||||||
import 'create_chat_screen.dart';
|
import 'agent_screen.dart';
|
||||||
|
|
||||||
class AgentEntry {
|
class AgentEntry {
|
||||||
final int id;
|
final int id;
|
||||||
@@ -25,18 +25,139 @@ class AgentListScreen extends StatelessWidget {
|
|||||||
return chats;
|
return chats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Future<List<String>> getAgentKinds() async {
|
||||||
|
final response = await Backend.sendAction("get-agent-kinds", {});
|
||||||
|
return response['kinds'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to create a new agent and navigate
|
||||||
|
Future<void> createAgent(BuildContext context, String name, String kind) async {
|
||||||
|
try {
|
||||||
|
// Pass the 'kind' to the backend as well
|
||||||
|
final response = await Backend.sendAction("create-agent", {"name": name, "kind": kind});
|
||||||
|
final int newAgentId = response['agentId']; // Assuming your backend returns the new agent's ID
|
||||||
|
|
||||||
|
if (context.mounted) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(content: Text('Agent $name created.')),
|
||||||
|
);
|
||||||
|
// Navigate to the new agent's chat screen
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => AgentScreen(agentId: newAgentId),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
if (context.mounted) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(content: Text('Failed to create agent: $e')),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to show the create agent dialog
|
||||||
|
void _showCreateAgentDialog(BuildContext context) {
|
||||||
|
TextEditingController usernameController = TextEditingController();
|
||||||
|
String? selectedKind; // To hold the selected kind value
|
||||||
|
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext dialogContext) {
|
||||||
|
return AlertDialog(
|
||||||
|
title: const Text('Create New Agent'),
|
||||||
|
content: SingleChildScrollView( // Use SingleChildScrollView to prevent overflow
|
||||||
|
child: ListBody(
|
||||||
|
children: <Widget>[
|
||||||
|
TextField(
|
||||||
|
controller: usernameController,
|
||||||
|
decoration: const InputDecoration(hintText: "Enter agent name"),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16.0), // Spacing between fields
|
||||||
|
FutureBuilder<List<String>>(
|
||||||
|
future: getAgentKinds(), // Call the asynchronous function to get kinds
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||||
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
} else if (snapshot.hasError) {
|
||||||
|
return Center(child: Text('Error loading kinds: ${snapshot.error}'));
|
||||||
|
} else if (!snapshot.hasData || snapshot.data!.isEmpty) {
|
||||||
|
return const Center(child: Text('No agent kinds available.'));
|
||||||
|
} else {
|
||||||
|
final kinds = snapshot.data!;
|
||||||
|
// Ensure a default selection if none is made, or allow null
|
||||||
|
if (selectedKind == null && kinds.isNotEmpty) {
|
||||||
|
selectedKind = kinds.first; // Set the first item as default
|
||||||
|
}
|
||||||
|
return StatefulBuilder( // Use StatefulBuilder to update dropdown state
|
||||||
|
builder: (context, setState) {
|
||||||
|
return DropdownButtonFormField<String>(
|
||||||
|
value: selectedKind,
|
||||||
|
hint: const Text('Select Kind'),
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: 'Kind',
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
),
|
||||||
|
items: kinds.map((String kind) {
|
||||||
|
return DropdownMenuItem<String>(
|
||||||
|
value: kind,
|
||||||
|
child: Text(kind),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
onChanged: (String? newValue) {
|
||||||
|
setState(() {
|
||||||
|
selectedKind = newValue;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: <Widget>[
|
||||||
|
TextButton(
|
||||||
|
child: const Text('Cancel'),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(dialogContext).pop(); // Dismiss the dialog
|
||||||
|
},
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
child: const Text('Create'),
|
||||||
|
onPressed: () {
|
||||||
|
if (usernameController.text.isNotEmpty && selectedKind != null) {
|
||||||
|
Navigator.of(dialogContext).pop(); // Dismiss the dialog first
|
||||||
|
createAgent(context, usernameController.text, selectedKind!); // Pass selectedKind
|
||||||
|
} else {
|
||||||
|
if (dialogContext.mounted) {
|
||||||
|
ScaffoldMessenger.of(dialogContext).showSnackBar(
|
||||||
|
const SnackBar(content: Text('Agent name and kind cannot be empty')),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(title: const Text('Agents')),
|
appBar: AppBar(title: const Text('Agents')),
|
||||||
body: Column( // Use a Column to stack widgets vertically
|
body: Column(
|
||||||
children: [
|
children: [
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: const Icon(Icons.add),
|
leading: const Icon(Icons.add),
|
||||||
title: const Text('Create'),
|
title: const Text('Create'),
|
||||||
onTap: () {
|
onTap: () => _showCreateAgentDialog(context), // Open the dialog
|
||||||
print("TODO: Create new agents");
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
const Divider(height: 1),
|
const Divider(height: 1),
|
||||||
Expanded(
|
Expanded(
|
||||||
@@ -59,12 +180,12 @@ class AgentListScreen extends StatelessWidget {
|
|||||||
title: Text(agent.name),
|
title: Text(agent.name),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
print("Navigate to agent ${agent.id}");
|
print("Navigate to agent ${agent.id}");
|
||||||
/*Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) => ChatScreen(agentId: agent.id),
|
builder: (context) => AgentScreen(agentId: agent.id),
|
||||||
),
|
),
|
||||||
);*/
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,105 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'app_menu.dart';
|
||||||
|
import 'backend.dart';
|
||||||
|
import 'chat_screen.dart';
|
||||||
|
|
||||||
|
class ConfigField {
|
||||||
|
final String name;
|
||||||
|
final String type;
|
||||||
|
final TextEditingController controller;
|
||||||
|
|
||||||
|
ConfigField({required this.name, required this.type, required this.controller});
|
||||||
|
}
|
||||||
|
|
||||||
|
class AgentScreen extends StatefulWidget {
|
||||||
|
final int agentId;
|
||||||
|
|
||||||
|
AgentScreen({required this.agentId});
|
||||||
|
|
||||||
|
@override
|
||||||
|
_AgentScreenState createState() => _AgentScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AgentScreenState extends State<AgentScreen> {
|
||||||
|
String? _title;
|
||||||
|
final TextEditingController nameController = TextEditingController();
|
||||||
|
List<ConfigField> configFields = [];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_loadConfigFields();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _loadConfigFields() async {
|
||||||
|
final response = await Backend.sendAction('get-agent-config-fields', {'agentId': widget.agentId});
|
||||||
|
setState(() {
|
||||||
|
configFields = response['fields'].map((jsonField) {
|
||||||
|
return ConfigField(
|
||||||
|
name: jsonField['name'],
|
||||||
|
type: jsonField['type'],
|
||||||
|
controller: TextEditingController(text: jsonField['value']),
|
||||||
|
);
|
||||||
|
}).toList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _saveChanges() async {
|
||||||
|
// Backend.invalidateCache(agent: true);
|
||||||
|
final dataObject = {};
|
||||||
|
for (var configField in configFields) {
|
||||||
|
dataObject[configField.name] = configField.controller.text;
|
||||||
|
}
|
||||||
|
await Backend.sendAction("update-agent", {
|
||||||
|
'agentId': widget.agentId,
|
||||||
|
'data': dataObject,
|
||||||
|
});
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(content: Text('Agent Updated.')),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text(_title?? 'Agent ${widget.agentId}'),
|
||||||
|
actions: [
|
||||||
|
IconButton(icon: Icon(Icons.settings), onPressed: () {
|
||||||
|
Navigator.push(context, MaterialPageRoute(builder: (_) => AppMenu()));
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
ListView.builder(
|
||||||
|
shrinkWrap: true,
|
||||||
|
itemCount: configFields.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 8.0),
|
||||||
|
child: TextField(
|
||||||
|
keyboardType: TextInputType.multiline,
|
||||||
|
minLines: 1,
|
||||||
|
maxLines: 8,
|
||||||
|
controller: configFields[index].controller,
|
||||||
|
decoration: InputDecoration(labelText: configFields[index].name),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
SizedBox(height: 20),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: _saveChanges,
|
||||||
|
child: Text('Save'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -84,6 +84,11 @@ Each command must be in it's own separate line, and it's made of these parts:
|
|||||||
For example: `!!query namespace.command_name {"arg1":"some data","arg2":[1,2,false]}`
|
For example: `!!query namespace.command_name {"arg1":"some data","arg2":[1,2,false]}`
|
||||||
If you add the query modifier, you will see the output of the commands in a continuation prompt, otherwise it will only be shown to the user.
|
If you add the query modifier, you will see the output of the commands in a continuation prompt, otherwise it will only be shown to the user.
|
||||||
|
|
||||||
|
## Agent Config
|
||||||
|
|
||||||
|
When creating an agent, default values are set for its configuration fields.
|
||||||
|
User is only directed to the editing page after its created, has the chance to change the default values.
|
||||||
|
|
||||||
# Chat Editor
|
# Chat Editor
|
||||||
|
|
||||||
Packages useful for the chat editor:
|
Packages useful for the chat editor:
|
||||||
|
|||||||
+45
-8
@@ -64,28 +64,65 @@ async function runTest() {
|
|||||||
await send('get-chats')
|
await send('get-chats')
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log("Create Agent",
|
console.log("Agent Kinds",
|
||||||
await send('create-agent', {body: {
|
await send('get-agent-kinds')
|
||||||
name: 'First Agent',
|
|
||||||
description: 'First agent does nothing',
|
|
||||||
kind: 'simple',
|
|
||||||
data: {}
|
|
||||||
}})
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let createAgentResponse = await send('create-agent', {body: {
|
||||||
|
name: 'First Agent',
|
||||||
|
description: 'First agent does nothing',
|
||||||
|
kind: 'basic',
|
||||||
|
data: {}
|
||||||
|
}});
|
||||||
|
console.log("Create Agent", createAgentResponse);
|
||||||
|
|
||||||
let agents = (await send('get-agents')).agents;
|
let agents = (await send('get-agents')).agents;
|
||||||
console.log("Get Agents", agents);
|
console.log("Get Agents", agents);
|
||||||
|
|
||||||
|
let mainAgentId = createAgentResponse.agentId;
|
||||||
|
let mainAgent = agents.find(agent => agent.id == mainAgentId)
|
||||||
|
|
||||||
if (USE_LLM) {
|
if (USE_LLM) {
|
||||||
let promptResponse = await send('send-agent-prompt', {
|
let promptResponse = await send('send-agent-prompt', {
|
||||||
body: {
|
body: {
|
||||||
agentId: agents[0].id,
|
agentId: mainAgentId,
|
||||||
content: "Hello World!",
|
content: "Hello World!",
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
console.log("Prompt Response", promptResponse);
|
console.log("Prompt Response", promptResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update agent
|
||||||
|
console.log("Updating agent...");
|
||||||
|
await send('update-agent', {
|
||||||
|
body: {
|
||||||
|
agentId: mainAgentId,
|
||||||
|
name: mainAgent.name + " (UPDATED)",
|
||||||
|
description: "This is a placeholder description for the agent.",
|
||||||
|
data: {
|
||||||
|
system_prompt: "first system prompt",
|
||||||
|
// These are not config fields for 'basic' agent, they cannot be seen by the user
|
||||||
|
field1: "some data",
|
||||||
|
field2: "more data",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
await send('update-agent', {
|
||||||
|
body: {
|
||||||
|
agentId: mainAgentId,
|
||||||
|
data: {
|
||||||
|
system_prompt: "second system prompt",
|
||||||
|
field2: "replaced data",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log("Updated Agent:", (
|
||||||
|
(await send('get-agents')).agents.find(agent => agent.id == mainAgentId)
|
||||||
|
));
|
||||||
|
console.log("Agent Data:", (
|
||||||
|
(await send('get-agent-config-fields', {body: {agentId: mainAgentId}}))
|
||||||
|
));
|
||||||
|
|
||||||
await testChats();
|
await testChats();
|
||||||
|
|
||||||
process.exit();
|
process.exit();
|
||||||
|
|||||||
Reference in new issue
Block a user