diff --git a/apps/shinkai-visor/src/components/inbox-input/inbox-input.tsx b/apps/shinkai-visor/src/components/inbox-input/inbox-input.tsx
index ad706eda9..757956fd9 100644
--- a/apps/shinkai-visor/src/components/inbox-input/inbox-input.tsx
+++ b/apps/shinkai-visor/src/components/inbox-input/inbox-input.tsx
@@ -1,10 +1,11 @@
 import { zodResolver } from '@hookform/resolvers/zod';
-import { Loader2, Send } from 'lucide-react';
+import { Send } from 'lucide-react';
 import { useForm } from 'react-hook-form';
 import { useIntl } from 'react-intl';
 import { z } from 'zod';
 
 import { Button } from '../ui/button';
+import DotsLoader from '../ui/dots-loader';
 import {
   Form,
   FormControl,
@@ -15,7 +16,7 @@ import {
 import { Input } from '../ui/input';
 
 const formSchema = z.object({
-  message: z.string().nonempty(),
+  message: z.string().min(1),
 });
 
 type InboxInputFieldType = z.infer<typeof formSchema>;
@@ -60,7 +61,6 @@ export const InboxInput = (props: InboxInputProps) => {
               <FormItem>
                 <FormControl>
                   <Input
-                    disabled={props.loading}
                     placeholder={intl.formatMessage({
                       id: 'tmwtd',
                     })}
@@ -75,12 +75,12 @@ export const InboxInput = (props: InboxInputProps) => {
         </div>
         <Button
           className="grow-0"
-          disabled={!form.formState.isValid || props.disabled}
+          disabled={!form.formState.isValid || props.disabled || props.loading}
         >
           {props.loading ? (
-            <Loader2 className="h-4 w-4 animate-spin" />
+            <DotsLoader className="w-6 h-4"></DotsLoader>
           ) : (
-            <Send className="w-4 h-4" />
+            <Send className="w-6 h-4" />
           )}
         </Button>
       </form>
diff --git a/apps/shinkai-visor/src/components/inbox/inbox.tsx b/apps/shinkai-visor/src/components/inbox/inbox.tsx
index 2bd597484..006312c2e 100644
--- a/apps/shinkai-visor/src/components/inbox/inbox.tsx
+++ b/apps/shinkai-visor/src/components/inbox/inbox.tsx
@@ -57,6 +57,7 @@ export const Inbox = () => {
   const fromPreviousMessagesRef = useRef<boolean>(false);
   const [decodedInboxId, setDecodedInboxId] = useState<string>('');
   const [isJobInbox, setIsJobInbox] = useState<boolean>(false);
+  const [isJobProcessing, setIsJobProcessing] = useState<boolean>(false);
   const fetchPreviousMessages = useCallback(async () => {
     const firstMessage = data?.pages?.[0]?.[0];
     fromPreviousMessagesRef.current = true;
@@ -78,6 +79,10 @@ export const Inbox = () => {
       chatContainerElement.scrollTop = currentHeight - previousHeight;
     }
   }, [fetchPreviousMessages, hasPreviousPage]);
+  const scrollToBottom = () => {
+    if (!chatContainerRef.current) return;
+    chatContainerRef.current.scrollTop = chatContainerRef.current.scrollHeight;
+  };
   useEffect(() => {
     const chatContainerElement = chatContainerRef.current;
     if (!chatContainerElement) return;
@@ -96,16 +101,23 @@ export const Inbox = () => {
       setIsJobInbox(checkIsJobInbox(decodedInboxId));
     }
   }, [decodedInboxId]);
-  const scrollToBottom = () => {
-    if (!chatContainerRef.current) return;
-    chatContainerRef.current.scrollTop = chatContainerRef.current.scrollHeight;
-  };
   useEffect(() => {
     if (!fromPreviousMessagesRef.current) {
       scrollToBottom();
     }
   }, [data?.pages]);
-
+  useEffect(() => {
+    const [firstMessagePage] = data?.pages || [];
+    const lastMessage = ([...firstMessagePage || []]).pop();
+    if (lastMessage) {
+      const isLocal = isLocalMessage(
+        lastMessage,
+        auth?.shinkai_identity ?? '',
+        auth?.profile ?? ''
+      );
+      setIsJobProcessing(isJobInbox && (isSendingMessage || isLocal));
+    }
+  }, [data?.pages, auth, isSendingMessage, isJobInbox]);
   const submitSendMessage = (value: string) => {
     if (!auth) return;
     fromPreviousMessagesRef.current = false;
@@ -266,7 +278,7 @@ export const Inbox = () => {
       </ScrollArea>
       <InboxInput
         disabled={isSendingMessage}
-        loading={isSendingMessage}
+        loading={isJobProcessing}
         onSubmit={(value) => submitSendMessage(value)}
       ></InboxInput>
     </div>
diff --git a/apps/shinkai-visor/src/components/ui/dots-loader.tsx b/apps/shinkai-visor/src/components/ui/dots-loader.tsx
new file mode 100644
index 000000000..c3f9b07bf
--- /dev/null
+++ b/apps/shinkai-visor/src/components/ui/dots-loader.tsx
@@ -0,0 +1,13 @@
+const DotsLoader = ({ className }: { className?: string }) => {
+  return (
+    <div className={`${className} flex flex-col justify-center`}>
+      <div className="flex flex-row space-x-1 items-center justify-center">
+        <div className="h-1 w-1 rounded-full bg-slate-100 animate-bounce [animation-delay:-0.3s]"></div>
+        <div className="h-1 w-1 rounded-full bg-slate-100 animate-bounce [animation-delay:-0.15s]"></div>
+        <div className="h-1 w-1 rounded-full bg-slate-100 animate-bounce"></div>
+      </div>
+    </div>
+  );
+};
+
+export default DotsLoader;
diff --git a/apps/shinkai-visor/tailwind.config.js b/apps/shinkai-visor/tailwind.config.js
index 205677ca1..d0e183145 100644
--- a/apps/shinkai-visor/tailwind.config.js
+++ b/apps/shinkai-visor/tailwind.config.js
@@ -88,12 +88,10 @@ module.exports = {
           from: { height: 'var(--radix-accordion-content-height)' },
           to: { height: 0 },
         },
-        keyframes: {
-          breath: {
-            '0%, 100%': { transform: 'opacity: 1' },
-            '50%': { transform: 'opacity: .5' },
-          }
-        }
+        breath: {
+          '0%, 100%': { transform: 'opacity: 1' },
+          '50%': { transform: 'opacity: .5' },
+        },
       },
       animation: {
         'accordion-down': 'accordion-down 0.2s ease-out',