Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: add workflows #25

Merged
merged 11 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Template Build
on:
push:
branches: ['master']
pull_request:
branches: ['master']
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Bun
uses: oven-sh/setup-bun@v2

- name: Template Install dependencies
run: bun install

- name: Template Test Build
# When fails, please check your build
run: |
bun run build
25 changes: 25 additions & 0 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Template Check
on:
push:
branches: ["master"]
pull_request:
branches: ["master"]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Bun
uses: oven-sh/setup-bun@v2

- name: Template Install dependencies
run: bun install

- name: Template Check
run: bun run ci:check
25 changes: 25 additions & 0 deletions .github/workflows/format.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Template Format
on:
push:
branches: ["master"]
pull_request:
branches: ["master"]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Bun
uses: oven-sh/setup-bun@v2

- name: Template Install dependencies
run: bun install

- name: Template Format
run: bun run ci:format
25 changes: 25 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Template Lint
on:
push:
branches: ["master"]
pull_request:
branches: ["master"]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Bun
uses: oven-sh/setup-bun@v2

- name: Template Install dependencies
run: bun install

- name: Template Lint
run: bun run ci:lint
73 changes: 34 additions & 39 deletions app/components/Agent.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,34 @@
import { useState, useEffect, useCallback } from "react";

import Navbar from "./Navbar";
import { ActionEntry, AgentMessage, Language, StreamEntry } from "../types";
import Stream from "./Stream";
import ChatInput from "./ChatInput";
import Footer from "./Footer";
import AgentProfile from "./AgentProfile";
import AgentStats from "./AgentStats";
import useChat from "../hooks/useChat";
import { useCallback, useEffect, useState } from 'react';

import useChat from '../hooks/useChat';
import type {
ActionEntry,
AgentMessage,
Language,
StreamEntry,
} from '../types';
import AgentProfile from './AgentProfile';
import AgentStats from './AgentStats';
import ChatInput from './ChatInput';
import Footer from './Footer';
import Navbar from './Navbar';
import Stream from './Stream';

export default function Agent() {
const [streamEntries, setStreamEntries] = useState<StreamEntry[]>([]);
const [userInput, setUserInput] = useState("");
const [userInput, setUserInput] = useState('');
const [isThinking, setIsThinking] = useState(true);
const [loadingDots, setLoadingDots] = useState("");
const [loadingDots, setLoadingDots] = useState('');
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
const [currentLanguage, setCurrentLanguage] = useState<Language>("en");
const [currentLanguage, setCurrentLanguage] = useState<Language>('en');
const [isLiveDotVisible, setIsLiveDotVisible] = useState(true);
const [isChatMode, setIsChatMode] = useState(false);

const handleSuccess = useCallback((messages: AgentMessage[]) => {
const message = messages.find((res) => res.event === "agent");
const message = messages.find((res) => res.event === 'agent');
const streamEntry = {
timestamp: new Date(),
content: message?.data || "",
content: message?.data || '',
};
setIsThinking(false);
setStreamEntries((prev) => [...prev, streamEntry]);
Expand All @@ -38,7 +43,7 @@ export default function Agent() {
useEffect(() => {
const streamInterval = setInterval(() => {
if (!isLoading && !isChatMode) {
postChat("same a one liner that is inspiring");
postChat('same a one liner that is inspiring');
}
}, 1500);

Expand All @@ -50,7 +55,7 @@ export default function Agent() {
// enables dot animation for "agent is thinking..."
useEffect(() => {
const dotsInterval = setInterval(() => {
setLoadingDots((prev) => (prev.length >= 3 ? "" : prev + "."));
setLoadingDots((prev) => (prev.length >= 3 ? '' : `${prev}.`));
}, 500);

return () => clearInterval(dotsInterval);
Expand All @@ -68,33 +73,35 @@ export default function Agent() {
const handleSubmit = useCallback(
async (e: React.FormEvent) => {
e.preventDefault();
if (!userInput.trim()) return;
if (!userInput.trim()) {
return;
}

// disable live stream
setIsChatMode(true);
setUserInput("");
setUserInput('');

const userMessage: ActionEntry = {
timestamp: new Date(),
type: "user",
type: 'user',
content: userInput.trim(),
};

setStreamEntries((prev) => [...prev, userMessage]);

postChat(userInput);
},
[postChat, userInput]
[postChat, userInput],
);

const handleKeyPress = useCallback(
(e: React.KeyboardEvent<HTMLTextAreaElement>) => {
if (e.key === "Enter" && !e.shiftKey) {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
handleSubmit(e);
}
},
[handleSubmit]
[handleSubmit],
);

const handleLanguageChange = useCallback((lang: Language) => {
Expand All @@ -103,7 +110,7 @@ export default function Agent() {
}, []);

return (
<div className="flex flex-col h-screen bg-black font-mono text-[#5788FA] relative overflow-hidden">
<div className="relative flex h-screen flex-col overflow-hidden bg-black font-mono text-[#5788FA]">
<Navbar
isMobileMenuOpen={isMobileMenuOpen}
setIsMobileMenuOpen={setIsMobileMenuOpen}
Expand All @@ -112,28 +119,16 @@ export default function Agent() {
currentLanguage={currentLanguage}
/>

<div className="flex flex-grow overflow-hidden relative">
<div className="relative flex flex-grow overflow-hidden">
<div
className={`
${isMobileMenuOpen ? "translate-x-0" : "-translate-x-full"}
lg:translate-x-0
fixed lg:relative
w-full lg:w-1/3
h-full
bg-black
z-20 lg:z-0
transition-transform
duration-300
p-2 lg:border-r lg:border-[#5788FA]/50
flex flex-col
overflow-y-auto
`}
${isMobileMenuOpen ? 'translate-x-0' : '-translate-x-full'} fixed z-20 flex h-full w-full flex-col overflow-y-auto bg-black p-2 transition-transform duration-300 lg:relative lg:z-0 lg:w-1/3 lg:translate-x-0 lg:border-[#5788FA]/50 lg:border-r `}
>
<AgentProfile currentLanguage={currentLanguage} />
<AgentStats currentLanguage={currentLanguage} />
</div>

<div className="flex-grow flex flex-col w-full lg:w-2/3">
<div className="flex w-full flex-grow flex-col lg:w-2/3">
<Stream
currentLanguage={currentLanguage}
streamEntries={streamEntries}
Expand Down
33 changes: 17 additions & 16 deletions app/components/AgentProfile.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { Language } from "../types";
import { AGENT_NAME, AGENT_WALLET_ADDRESS, notoSansThai } from "../constants";
import { translations } from "../translations";
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { AGENT_NAME, AGENT_WALLET_ADDRESS, notoSansThai } from '../constants';
import { translations } from '../translations';
import type { Language } from '../types';

type AgentProfileProps = {
currentLanguage: Language;
Expand All @@ -20,7 +20,7 @@ export default function AgentProfile({ currentLanguage }: AgentProfileProps) {
setTimeout(() => setShowToast(false), 2000); // Hide toast after 2 seconds
})
.catch((err) => {
console.error("Failed to copy wallet address: ", err);
console.error('Failed to copy wallet address: ', err);
});
}, []);

Expand All @@ -37,24 +37,24 @@ export default function AgentProfile({ currentLanguage }: AgentProfileProps) {

const normalizedX = Math.min(
Math.max((dx / maxDistance) * 30 + 50, 20),
80
80,
);
const normalizedY = Math.min(
Math.max((dy / maxDistance) * 30 + 50, 20),
80
80,
);

setEyePosition({ x: normalizedX, y: normalizedY });
}
};

window.addEventListener("mousemove", handleMouseMove);
return () => window.removeEventListener("mousemove", handleMouseMove);
window.addEventListener('mousemove', handleMouseMove);
return () => window.removeEventListener('mousemove', handleMouseMove);
}, []);

const formattedAddress = useMemo(() => {
return `${AGENT_WALLET_ADDRESS.slice(0, 6)}...${AGENT_WALLET_ADDRESS.slice(
-4
-4,
)}`;
}, []);

Expand All @@ -81,16 +81,17 @@ export default function AgentProfile({ currentLanguage }: AgentProfileProps) {
</svg>

<div className="flex flex-col justify-center space-y-2">
<h2 className="text-xl font-bold text-[#5788FA]">{AGENT_NAME}</h2>
<div className="relative inline-flex items-center group">
<h2 className="font-bold text-[#5788FA] text-xl">{AGENT_NAME}</h2>
<div className="group relative inline-flex items-center">
<button
type="button"
onClick={copyToClipboard}
className="text-sm text-[#5788FA] hover:text-[#3D7BFF] transition-colors"
className="text-[#5788FA] text-sm transition-colors hover:text-[#3D7BFF]"
>
{formattedAddress}
</button>
{showToast && (
<div className="absolute top-full left-0 mt-2 bg-[#5788FA] text-zinc-950 text-xs px-2 py-1 rounded-xs">
<div className="absolute top-full left-0 mt-2 rounded-xs bg-[#5788FA] px-2 py-1 text-xs text-zinc-950">
Copied
</div>
)}
Expand All @@ -99,8 +100,8 @@ export default function AgentProfile({ currentLanguage }: AgentProfileProps) {
</div>

<p
className={`text-base text-[#5788FA] ${
currentLanguage === "th" ? notoSansThai.className : ""
className={`text-[#5788FA] text-base ${
currentLanguage === 'th' ? notoSansThai.className : ''
}`}
>
{translations[currentLanguage].profile.bio}
Expand Down
Loading