Skip to content

Commit

Permalink
- feature: default agent settings (#78)
Browse files Browse the repository at this point in the history
* - feature: added default agent setting

* - fix: default agent race
  • Loading branch information
agallardol authored Nov 9, 2023
1 parent ce00320 commit 1309729
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 19 deletions.
72 changes: 56 additions & 16 deletions apps/shinkai-visor/src/components/create-job/create-job.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { z } from 'zod';

import { useQuery } from '../../hooks/use-query';
import { useAuth } from '../../store/auth/auth';
import { useSettings } from '../../store/settings/settings';
import { FileInput } from '../file-input/file-input';
import { Header } from '../header/header';
import { Button } from '../ui/button';
Expand Down Expand Up @@ -44,9 +45,10 @@ type FormSchemaType = z.infer<typeof formSchema>;
export const CreateJob = () => {
const history = useHistory();
const intl = useIntl();
const location = useLocation<{ files: File[], agentName: string }>();
const location = useLocation<{ files: File[]; agentName: string }>();
const query = useQuery();
const auth = useAuth((state) => state.auth);
const settings = useSettings((state) => state.settings);
const form = useForm<FormSchemaType>({
resolver: zodResolver(formSchema),
defaultValues: {
Expand All @@ -72,26 +74,59 @@ export const CreateJob = () => {
history.replace(`/inboxes/${jobId}`);
},
});
const extensions = [".eml", ".html", ".json", ".md", ".msg", ".rst", ".rtf", ".txt", ".xml", ".jpeg", ".png", ".csv", ".doc", ".docx", ".epub", ".odt", ".pdf", ".ppt", ".pptx", ".tsv", ".xlsx"];

//TODO: Replace this assigment with a configured default agent
useEffect(() => {
if (agents?.length) {
const defaultAgentId = agents[0].id;
form.setValue('agent', defaultAgentId);
}
}, [agents, form]);
const extensions = [
'.eml',
'.html',
'.json',
'.md',
'.msg',
'.rst',
'.rtf',
'.txt',
'.xml',
'.jpeg',
'.png',
'.csv',
'.doc',
'.docx',
'.epub',
'.odt',
'.pdf',
'.ppt',
'.pptx',
'.tsv',
'.xlsx',
];
useEffect(() => {
form.setValue('files', location?.state?.files || []);
}, [location, form]);
useEffect(() => {
if (location?.state?.agentName) {
const agent = agents.find(agent => (agent.full_identity_name as any)?.subidentity_name === location.state.agentName);
if (agent) {
form.setValue('agent', agent.id);
}
if (!location?.state?.agentName) {
return;
}
const agent = agents.find(
(agent) =>
(agent.full_identity_name as any)?.subidentity_name ===
location.state.agentName
);
if (agent) {
form.setValue('agent', agent.id);
}
}, [form, location, agents]);
useEffect(() => {
if (form.getValues().agent) {
return;
}
let defaultAgentId = '';
defaultAgentId =
defaultAgentId ||
(settings?.defaultAgentId &&
agents.find((agent) => agent.id === settings.defaultAgentId)
? settings.defaultAgentId
: '');
defaultAgentId = defaultAgentId || (agents?.length ? agents[0].id : '');
form.setValue('agent', defaultAgentId);
}, [form, location, agents, settings]);
const submit = (values: FormSchemaType) => {
if (!auth) return;
let content = values.content;
Expand Down Expand Up @@ -170,7 +205,12 @@ export const CreateJob = () => {
<FormattedMessage id="file.one" />
</FormLabel>
<FormControl>
<FileInput extensions={extensions} multiple onValueChange={field.onChange} value={field.value}/>
<FileInput
extensions={extensions}
multiple
onValueChange={field.onChange}
value={field.value}
/>
</FormControl>
<FormMessage />
</FormItem>
Expand Down
104 changes: 103 additions & 1 deletion apps/shinkai-visor/src/components/settings/settings.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,124 @@
import { zodResolver } from '@hookform/resolvers/zod';
import { useAgents } from '@shinkai_network/shinkai-node-state/lib/queries/getAgents/useGetAgents';
import { FileKey, SettingsIcon } from 'lucide-react';
import { useEffect } from 'react';
import { useForm, useWatch } from 'react-hook-form';
import { FormattedMessage } from 'react-intl';
import { useHistory } from 'react-router';
import { z } from 'zod';

import { useAuth } from '../../store/auth/auth';
import { useSettings } from '../../store/settings/settings';
import { Header } from '../header/header';
import { Button } from '../ui/button';
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '../ui/form';
import {
Select,
SelectContent,
SelectItem,
SelectPortal,
SelectTrigger,
SelectValue,
} from '../ui/select';

const formSchema = z.object({
defaultAgentId: z.string().optional(),
});

type FormSchemaType = z.infer<typeof formSchema>;

export const Settings = () => {
const history = useHistory();
const auth = useAuth((authStore) => authStore.auth);
const { settings, setSettings } = useSettings(
(settingsStore) => settingsStore
);
const form = useForm<FormSchemaType>({
resolver: zodResolver(formSchema),
defaultValues: {
defaultAgentId: '',
},
});
const defaultAgentId = useWatch<FormSchemaType>({ name: 'defaultAgentId', control: form.control });
const { agents } = useAgents({
sender: auth?.shinkai_identity ?? '',
senderSubidentity: `${auth?.profile}`,
shinkaiIdentity: auth?.shinkai_identity ?? '',
my_device_encryption_sk: auth?.profile_encryption_sk ?? '',
my_device_identity_sk: auth?.profile_identity_sk ?? '',
node_encryption_pk: auth?.node_encryption_pk ?? '',
profile_encryption_sk: auth?.profile_encryption_sk ?? '',
profile_identity_sk: auth?.profile_identity_sk ?? '',
});
const exportConnection = () => {
history.push('settings/export-connection');
};
useEffect(() => {
if (defaultAgentId) {
setSettings({ defaultAgentId })
}
}, [defaultAgentId, setSettings]);
useEffect(() => {
form.setValue('defaultAgentId', settings?.defaultAgentId);
}, [settings, form]);
return (
<div className="flex flex-col space-y-3">
<Header
icon={<SettingsIcon />}
title={<FormattedMessage id="setting.other"></FormattedMessage>}
/>
<div>
<div className="flex flex-col space-y-2">
<Form {...form}>
<form
className="grow flex flex-col space-y-2 justify-between overflow-hidden"
>
<FormField
control={form.control}
name="defaultAgentId"
render={({ field }) => (
<FormItem>
<FormLabel>
<FormattedMessage id="default-agent" />
</FormLabel>
<Select
defaultValue={field.value}
name={field.name}
onValueChange={field.onChange}
value={field.value}
>
<FormControl>
<SelectTrigger>
<SelectValue />
</SelectTrigger>
</FormControl>
<SelectPortal>
<SelectContent>
{agents?.map((agent) => (
<SelectItem key={agent.id} value={agent.id}>
{
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(agent.full_identity_name as any)
?.subidentity_name
}
</SelectItem>
))}
</SelectContent>
</SelectPortal>
</Select>
<FormMessage />
</FormItem>
)}
/>
</form>
</Form>

<Button className="w-full" onClick={() => exportConnection()}>
<FileKey className="mr-2 h-4 w-4" />
<FormattedMessage id="export-connection" />
Expand Down
3 changes: 2 additions & 1 deletion apps/shinkai-visor/src/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,5 +85,6 @@
"name.one": "Name",
"edit": "Edit",
"togethercomputer": "Together AI",
"alphanumeric_with_underscore": "It just accepts alphanumeric characters and underscores"
"alphanumeric_with_underscore": "It just accepts alphanumeric characters and underscores",
"default-agent": "Default agent"
}
3 changes: 2 additions & 1 deletion apps/shinkai-visor/src/lang/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,5 +85,6 @@
"name.one": "Nombre",
"edit": "Editar",
"togethercomputer": "Together AI",
"alphanumeric_with_underscore": "Solo se permiten caracteres alfanuméricos y guiones bajos"
"alphanumeric_with_underscore": "Solo se permiten caracteres alfanuméricos y guiones bajos",
"default-agent": "Agente por defecto"
}
28 changes: 28 additions & 0 deletions apps/shinkai-visor/src/store/settings/settings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { create } from "zustand";
import { devtools, persist } from "zustand/middleware";

import { ChromeStorage } from "../persistor/chrome-storage";

type SettingsData = {
defaultAgentId: string | undefined;
};

type SettingsStore = {
settings: SettingsData | null;
setSettings: (settings: SettingsData) => void;
};

export const useSettings = create<SettingsStore>()(
devtools(
persist(
(set) => ({
settings: null,
setSettings: (settings: SettingsData) => set({ settings }),
}),
{
name: "settings",
storage: new ChromeStorage(),
}
)
)
);

0 comments on commit 1309729

Please sign in to comment.