Skip to content

Commit

Permalink
API-FrontEnd Alignment 2 (#22)
Browse files Browse the repository at this point in the history
Features:
* Save sessions to Firestore

API:
* Add GET /session/list endpoint
* Add GET /message endpoint
* Add POST /tool/execute endpoint: for manual tool execution using natural language prompts.
* Add /version endpoint

Other:
* Improved logging: using Queue to queue log messages and send them in a separate thread.
* Add back previously removed tools: print_all_files_in_path.py, summarize_all_code_in_path.py
  * For SummarizeCode: Add output truncation for GPT-3 (16k tokens context window, we pass max 8k for better results) based on tokens
* Update AutoGen to latest version
* Update Python deps
* Add tests (total coverage now is 84.74% (+2.90%))
  • Loading branch information
bonk1t authored Feb 4, 2024
1 parent 5829eeb commit 34db92b
Show file tree
Hide file tree
Showing 71 changed files with 2,587 additions and 758 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ settings.json

.env

*.log.jsonl

# UI folder
nalgonda/ui/*
nalgonda/data/agency_data/*
2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ai-in-hand-platform-ui",
"version": "1.0.0",
"version": "0.1.0",
"private": true,
"description": "AI in Hand Platform - Build and Test Your AI Workforce",
"author": "AI in Hand Team",
Expand Down
206 changes: 149 additions & 57 deletions frontend/src/components/atoms.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {
ArrowPathIcon,
ArrowDownRightIcon,
PencilIcon,
UserGroupIcon,
UsersIcon,
} from "@heroicons/react/24/outline";
import React, { ReactNode, useEffect, useRef, useState } from "react";
import Icon from "./icons";
Expand Down Expand Up @@ -616,6 +618,14 @@ export const ModelSelector = ({
null
);
const [editIndex, setEditIndex] = useState<number | null>(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);

const [models, setModels] = useState<IModelConfig[]>([]);
const serverUrl = getServerUrl();

const { user } = React.useContext(appContext);
const listModelsUrl = `${serverUrl}/models?user_id=${user?.email}`;

const sanitizeModelConfig = (config: IModelConfig) => {
const sanitizedConfig: IModelConfig = { model: config.model };
Expand All @@ -628,6 +638,7 @@ export const ModelSelector = ({

const handleRemoveConfig = (index: number) => {
const updatedConfigs = configs.filter((_, i) => i !== index);

setConfigs(updatedConfigs);
};

Expand All @@ -637,6 +648,78 @@ export const ModelSelector = ({
setIsModalVisible(true);
};

const fetchModels = () => {
setError(null);
setLoading(true);
// const fetch;
const payLoad = {
method: "GET",
headers: {
"Content-Type": "application/json",
},
};

const onSuccess = (data: any) => {
if (data && data.status) {
// message.success(data.message);
setModels(data.data);
} else {
message.error(data.message);
}
setLoading(false);
};
const onError = (err: any) => {
setError(err);
message.error(err.message);
setLoading(false);
};
fetchJSON(listModelsUrl, payLoad, onSuccess, onError);
};

useEffect(() => {
fetchModels();
}, []);

const modelItems: MenuProps["items"] =
models.length > 0
? models.map((model: IModelConfig, index: number) => ({
key: index,
label: model.model,
value: index,
}))
: [
{
key: -1,
label: "No models found",
value: 0,
},
];

const modelOnClick: MenuProps["onClick"] = ({ key }) => {
const selectedIndex = parseInt(key.toString());
let selectedModel = models[selectedIndex];
selectedModel = sanitizeModelConfig(selectedModel);
const updatedConfigs = [...configs, selectedModel];
setConfigs(updatedConfigs);
};

const AddModelsDropDown = () => {
return (
<Dropdown
menu={{ items: modelItems, onClick: modelOnClick }}
placement="bottomRight"
trigger={["click"]}
>
<div
className="inline-flex mr-1 mb-1 p-1 px-2 rounded border hover:border-accent duration-300 hover:text-accent"
role="button"
>
add <PlusIcon className="w-4 h-4 inline-block mt-1" />
</div>
</Dropdown>
);
};

const handleOk = () => {
if (newModelConfig?.model.trim()) {
const sanitizedConfig = sanitizeModelConfig(newModelConfig);
Expand Down Expand Up @@ -707,24 +790,7 @@ export const ModelSelector = ({
<div className={`${className}`}>
<div className="flex flex-wrap">
{modelButtons}
<div
className="inline-flex mr-1 mb-1 p-1 px-2 rounded border hover:border-accent duration-300 hover:text-accent"
role="button"
onClick={() =>
showModal(
{
model: "",
api_key: "",
base_url: "",
api_type: "",
api_version: "",
},
null
)
}
>
add <PlusIcon className="w-4 h-4 inline-block mt-1" />
</div>
<AddModelsDropDown />
</div>
<Modal
title={`${editIndex !== null ? "Edit" : "Add"} Model Configuration`}
Expand Down Expand Up @@ -900,22 +966,20 @@ export const AgentFlowSpecView = ({
// Event handlers for updating local state and propagating changes

const onControlChange = (value: any, key: string) => {
if (key === "llm_config") {
if (value.config_list.length === 0) {
value = false;
}
}
const updatedFlowSpec = {
...localFlowSpec,
config: { ...localFlowSpec.config, [key]: value },
};
console.log(updatedFlowSpec.config.llm_config);
setLocalFlowSpec(updatedFlowSpec);
setFlowSpec(updatedFlowSpec);
};

const onDebouncedControlChange = React.useCallback(
debounce((value: any, key: string) => {
onControlChange(value, key);
console.log("debounce");
}, 3000),
[onControlChange]
);

const llm_config = localFlowSpec.config.llm_config || { config_list: [] };

return (
Expand Down Expand Up @@ -1006,15 +1070,15 @@ export const AgentFlowSpecView = ({
title="System Message"
className="mt-4"
description="Free text to control agent behavior"
value={flowSpec.config.system_message}
value={flowSpec.config.instructions}
control={
<TextArea
className="mt-2 w-full"
value={flowSpec.config.system_message}
value={flowSpec.config.instructions}
rows={3}
onChange={(e) => {
// onDebouncedControlChange(e.target.value, "system_message");
onControlChange(e.target.value, "system_message");
// onDebouncedControlChange(e.target.value, "instructions");
onControlChange(e.target.value, "instructions");
}}
/>
}
Expand Down Expand Up @@ -1315,8 +1379,7 @@ const GroupChatFlowSpecView = ({
flowSpecs: IAgentFlowSpec[];
}) => {
const [showAgentModal, setShowAgentModal] = React.useState(false);
const [selectedAgent, setSelectedAgent] =
React.useState<IAgentFlowSpec | null>(null);
const [selectedAgent, setSelectedAgent] = React.useState<number | null>(null);

const handleRemoveAgent = (index: number) => {
const updatedAgents = flowSpec?.groupchat_config.agents.filter(
Expand Down Expand Up @@ -1348,6 +1411,24 @@ const GroupChatFlowSpecView = ({
}
};

const handleAgentUpdate = (updatedAgent: IAgentFlowSpec, index: number) => {
const updatedAgents = flowSpec?.groupchat_config.agents.map((agent, i) => {
if (i === index) {
return updatedAgent;
}
return agent;
});
if (flowSpec?.groupchat_config && updatedAgents) {
setFlowSpec({
...flowSpec,
groupchat_config: {
...flowSpec?.groupchat_config,
agents: updatedAgents,
},
});
}
};

const agentItems: MenuProps["items"] = flowSpecs.map(
(flowSpec: IAgentFlowSpec, index: number) => ({
key: index,
Expand All @@ -1367,13 +1448,11 @@ const GroupChatFlowSpecView = ({
<Dropdown
menu={{ items: agentItems, onClick: agentOnClick }}
placement="bottomRight"
trigger={["click"]}
>
<div
className="inline-flex mr-1 mb-1 p-1 px-2 rounded border hover:border-accent duration-300 hover:text-accent"
role="button"
onClick={(e) => {
// add agent to flowSpec?.groupchat_config.agents
}}
>
add <PlusIcon className="w-4 h-4 inline-block mt-1" />
</div>
Expand All @@ -1390,8 +1469,7 @@ const GroupChatFlowSpecView = ({
className="mr-1 mb-1 p-1 px-2 rounded border"
role="button"
onClick={() => {
// setShowAgentModal(true);
setSelectedAgent(flowSpec);
setSelectedAgent(index);
// setShowAgentModal(true);
}}
>
Expand All @@ -1417,40 +1495,47 @@ const GroupChatFlowSpecView = ({
);

useEffect(() => {
if (selectedAgent) {
if (selectedAgent !== null) {
// showAgentModal = true;
setShowAgentModal(true);
}
}, [selectedAgent]);

return (
<div className="mb-4">
<AgentModal
agent={selectedAgent}
setAgent={setSelectedAgent}
showAgentModal={showAgentModal}
setShowAgentModal={setShowAgentModal}
/>
{showAgentModal &&
selectedAgent !== null &&
flowSpec?.groupchat_config && (
<AgentModal
agent={flowSpec?.groupchat_config.agents[selectedAgent]}
showAgentModal={showAgentModal}
setShowAgentModal={setShowAgentModal}
handler={(agent: IAgentFlowSpec | null) => {
if (agent) {
handleAgentUpdate(agent, selectedAgent);
console.log("updating agent at index", selectedAgent, agent);
}
setSelectedAgent(null);
}}
/>
)}
<GroupView title="Group Chat Agents">
<div className="flex flex-wrap mt-3">
{agentsView}
<AgentDropDown />
</div>
</GroupView>
<div className="h-2"> </div>
</div>
);
};

const AgentModal = ({
agent,
setAgent,
showAgentModal,
setShowAgentModal,
handler,
}: {
agent: IAgentFlowSpec | null;
setAgent: (agent: IAgentFlowSpec | null) => void;
showAgentModal: boolean;
setShowAgentModal: (show: boolean) => void;
handler?: (agent: IAgentFlowSpec | null) => void;
Expand Down Expand Up @@ -1503,14 +1588,12 @@ const AgentModal = ({
width={800}
open={showAgentModal}
onOk={() => {
setAgent(localAgent);
setShowAgentModal(false);
if (handler) {
handler(localAgent);
}
setShowAgentModal(false);
}}
onCancel={() => {
// setAgent(null);
setShowAgentModal(false);
}}
>
Expand All @@ -1520,7 +1603,7 @@ const AgentModal = ({
<div className="text-sm text-secondary mt-2">
Modify current agent{" "}
</div>
{agent.type === "groupchat" && (
{localAgent && localAgent.type === "groupchat" && (
<div>
{" "}
Group Chat
Expand All @@ -1531,11 +1614,13 @@ const AgentModal = ({
/>
</div>
)}
<AgentFlowSpecView
title=""
flowSpec={localAgent || agent}
setFlowSpec={setLocalAgent}
/>
{localAgent && (
<AgentFlowSpecView
title=""
flowSpec={localAgent}
setFlowSpec={setLocalAgent}
/>
)}
</>
)}

Expand Down Expand Up @@ -1582,6 +1667,11 @@ export const AgentSelector = ({
>
{flowSpec && (
<div className=" ">
{flowSpec.type === "groupchat" ? (
<UserGroupIcon className="w-5 h-5 inline-block mr-2" />
) : (
<UsersIcon className="w-5 h-5 inline-block mr-2" />
)}
{flowSpec.config.name}
<div className="mt-2 text-secondary text-sm">
{" "}
Expand All @@ -1603,9 +1693,11 @@ export const AgentSelector = ({
<>
<AgentModal
agent={flowSpec}
setAgent={setFlowSpec}
showAgentModal={isModalVisible}
setShowAgentModal={setIsModalVisible}
handler={(agent: IAgentFlowSpec | null) => {
setFlowSpec(agent);
}}
/>
</>
}
Expand Down
Loading

0 comments on commit 34db92b

Please sign in to comment.