mirror of
https://github.com/geoffsee/open-gsio.git
synced 2025-09-08 22:56:46 +00:00
Compare commits
20 Commits
smart-land
...
dependabot
Author | SHA1 | Date | |
---|---|---|---|
![]() |
bf8113b65c | ||
![]() |
4edee1e191 | ||
![]() |
734f48d4a7 | ||
![]() |
66363cdf39 | ||
![]() |
36f8fcee87 | ||
![]() |
f055cd39fe | ||
![]() |
0183503425 | ||
![]() |
a7ad06093a | ||
![]() |
c26d2467f4 | ||
![]() |
818e0e672a | ||
![]() |
48655474e3 | ||
![]() |
ffabfd4ce5 | ||
![]() |
fa5b7466bc | ||
![]() |
6cc5e038a7 | ||
![]() |
e72198628c | ||
![]() |
c0428094c8 | ||
![]() |
3901337163 | ||
![]() |
0ff8b5c03e | ||
![]() |
858282929c | ||
![]() |
06b6a68b9b |
@@ -46,7 +46,6 @@ describe('AssistantSdk', () => {
|
|||||||
|
|
||||||
expect(prompt).toContain('# Assistant Knowledge');
|
expect(prompt).toContain('# Assistant Knowledge');
|
||||||
expect(prompt).toContain('### Date: ');
|
expect(prompt).toContain('### Date: ');
|
||||||
expect(prompt).toContain('### Web Host: ');
|
|
||||||
expect(prompt).toContain('### User Location: ');
|
expect(prompt).toContain('### User Location: ');
|
||||||
expect(prompt).toContain('### Timezone: ');
|
expect(prompt).toContain('### Timezone: ');
|
||||||
});
|
});
|
||||||
|
@@ -23,7 +23,7 @@ export class AssistantSdk {
|
|||||||
|
|
||||||
return `# Assistant Knowledge
|
return `# Assistant Knowledge
|
||||||
## Assistant Name
|
## Assistant Name
|
||||||
### yachtpit-ai
|
### open-gsio
|
||||||
## Current Context
|
## Current Context
|
||||||
### Date: ${currentDate} ${currentTime}
|
### Date: ${currentDate} ${currentTime}
|
||||||
${maxTokens ? `### Max Response Length: ${maxTokens} tokens (maximum)` : ''}
|
${maxTokens ? `### Max Response Length: ${maxTokens} tokens (maximum)` : ''}
|
||||||
|
@@ -50,7 +50,7 @@
|
|||||||
"marked-katex-extension": "^5.1.4",
|
"marked-katex-extension": "^5.1.4",
|
||||||
"mobx": "^6.13.5",
|
"mobx": "^6.13.5",
|
||||||
"mobx-react-lite": "^4.0.7",
|
"mobx-react-lite": "^4.0.7",
|
||||||
"mobx-state-tree": "^6.0.1",
|
"mobx-state-tree": "^7.0.2",
|
||||||
"qrcode.react": "^4.1.0",
|
"qrcode.react": "^4.1.0",
|
||||||
"react": "^19.1.0",
|
"react": "^19.1.0",
|
||||||
"react-dom": "^19.1.0",
|
"react-dom": "^19.1.0",
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { execSync } from 'node:child_process';
|
import { execSync, execFileSync } from 'node:child_process';
|
||||||
import {
|
import {
|
||||||
existsSync,
|
existsSync,
|
||||||
readdirSync,
|
readdirSync,
|
||||||
@@ -175,7 +175,7 @@ function optimizeWasmSize() {
|
|||||||
|
|
||||||
if (sizeInMb > 30) {
|
if (sizeInMb > 30) {
|
||||||
logger.info(`WASM size is ${sizeInMb.toFixed(2)}MB, optimizing...`);
|
logger.info(`WASM size is ${sizeInMb.toFixed(2)}MB, optimizing...`);
|
||||||
execSync(`wasm-opt -Oz -o ${wasmPath} ${wasmPath}`, {
|
execFileSync('wasm-opt', ['-Oz', '-o', wasmPath, wasmPath], {
|
||||||
encoding: 'utf-8',
|
encoding: 'utf-8',
|
||||||
});
|
});
|
||||||
logger.info(`✅ WASM size optimized`);
|
logger.info(`✅ WASM size optimized`);
|
||||||
|
@@ -171,7 +171,7 @@ const InputMenu: React.FC<{ isDisabled?: boolean }> = observer(({ isDisabled })
|
|||||||
bg="background.tertiary"
|
bg="background.tertiary"
|
||||||
color="text.primary"
|
color="text.primary"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
clientChatStore.setActiveConversation('conversation:new');
|
clientChatStore.reset();
|
||||||
onClose();
|
onClose();
|
||||||
}}
|
}}
|
||||||
_hover={{ bg: 'rgba(0, 0, 0, 0.05)' }}
|
_hover={{ bg: 'rgba(0, 0, 0, 0.05)' }}
|
||||||
|
@@ -49,7 +49,7 @@ const InputTextArea: React.FC<InputTextAreaProps> = observer(
|
|||||||
color="text.primary"
|
color="text.primary"
|
||||||
borderRadius="20px"
|
borderRadius="20px"
|
||||||
border="none"
|
border="none"
|
||||||
placeholder="To Gilligan's island!"
|
placeholder="Free my mind..."
|
||||||
_placeholder={{
|
_placeholder={{
|
||||||
color: 'gray.400',
|
color: 'gray.400',
|
||||||
textWrap: 'nowrap',
|
textWrap: 'nowrap',
|
||||||
|
@@ -9,7 +9,7 @@ export function formatConversationMarkdown(messages: Instance<typeof IMessage>[]
|
|||||||
if (message.role === 'user') {
|
if (message.role === 'user') {
|
||||||
return `**You**: ${message.content}`;
|
return `**You**: ${message.content}`;
|
||||||
} else if (message.role === 'assistant') {
|
} else if (message.role === 'assistant') {
|
||||||
return `**yachtpit-ai**: ${message.content}`;
|
return `**open-gsio**: ${message.content}`;
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
})
|
})
|
||||||
|
@@ -51,7 +51,7 @@ const MessageBubble = observer(({ msg, scrollRef }) => {
|
|||||||
const [isEditing, setIsEditing] = useState(false);
|
const [isEditing, setIsEditing] = useState(false);
|
||||||
const [isHovered, setIsHovered] = useState(false);
|
const [isHovered, setIsHovered] = useState(false);
|
||||||
const isUser = msg.role === 'user';
|
const isUser = msg.role === 'user';
|
||||||
const senderName = isUser ? 'You' : 'yachtpit-ai';
|
const senderName = isUser ? 'You' : 'open-gsio';
|
||||||
const isLoading = !msg.content || !(msg.content.trim().length > 0);
|
const isLoading = !msg.content || !(msg.content.trim().length > 0);
|
||||||
const messageRef = useRef();
|
const messageRef = useRef();
|
||||||
|
|
||||||
|
@@ -104,7 +104,7 @@ describe('MessageBubble', () => {
|
|||||||
it('should render assistant message correctly', () => {
|
it('should render assistant message correctly', () => {
|
||||||
render(<MessageBubble msg={mockAssistantMessage} scrollRef={mockScrollRef} />);
|
render(<MessageBubble msg={mockAssistantMessage} scrollRef={mockScrollRef} />);
|
||||||
|
|
||||||
expect(screen.getByText('yachtpit-ai')).toBeInTheDocument();
|
expect(screen.getByText('open-gsio')).toBeInTheDocument();
|
||||||
expect(screen.getByTestId('message-content')).toHaveTextContent('Assistant response');
|
expect(screen.getByTestId('message-content')).toHaveTextContent('Assistant response');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -3,16 +3,13 @@ import React, { useEffect, useState } from 'react';
|
|||||||
|
|
||||||
import { useComponent } from '../contexts/ComponentContext.tsx';
|
import { useComponent } from '../contexts/ComponentContext.tsx';
|
||||||
|
|
||||||
import { BevyScene } from './BevyScene.tsx';
|
// import { BevyScene } from './BevyScene.tsx';
|
||||||
import Tweakbox from './Tweakbox.tsx';
|
import Tweakbox from './Tweakbox.tsx';
|
||||||
|
|
||||||
export const LandingComponent: React.FC = () => {
|
export const LandingComponent: React.FC = () => {
|
||||||
const [speed, setSpeed] = useState(0.2);
|
|
||||||
const [intensity, setIntensity] = useState(0.99);
|
const [intensity, setIntensity] = useState(0.99);
|
||||||
const [glow, setGlow] = useState(false);
|
const [mapActive, setMapActive] = useState(false);
|
||||||
const [bevyScene, setBevyScene] = useState(true);
|
const [aiActive, setAiActive] = useState(true);
|
||||||
const [mapActive, setMapActive] = useState(true);
|
|
||||||
const [aiActive, setAiActive] = useState(false);
|
|
||||||
|
|
||||||
const component = useComponent();
|
const component = useComponent();
|
||||||
const { setEnabledComponent } = component;
|
const { setEnabledComponent } = component;
|
||||||
@@ -27,22 +24,8 @@ export const LandingComponent: React.FC = () => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box as="section" bg="background.primary" overflow="hidden">
|
||||||
as="section"
|
<Box position="fixed" right={0} maxWidth="300px" minWidth="200px" zIndex={1000}>
|
||||||
bg="background.primary"
|
|
||||||
w="100%"
|
|
||||||
h="100vh"
|
|
||||||
overflow="hidden"
|
|
||||||
position="relative"
|
|
||||||
>
|
|
||||||
<Box
|
|
||||||
position="fixed"
|
|
||||||
bottom="100x"
|
|
||||||
right="12px"
|
|
||||||
maxWidth="300px"
|
|
||||||
minWidth="200px"
|
|
||||||
zIndex={1000}
|
|
||||||
>
|
|
||||||
<Tweakbox
|
<Tweakbox
|
||||||
sliders={{
|
sliders={{
|
||||||
intensity: {
|
intensity: {
|
||||||
@@ -56,13 +39,6 @@ export const LandingComponent: React.FC = () => {
|
|||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
switches={{
|
switches={{
|
||||||
bevyScene: {
|
|
||||||
value: bevyScene,
|
|
||||||
onChange(enabled) {
|
|
||||||
setBevyScene(enabled);
|
|
||||||
},
|
|
||||||
label: 'Instruments',
|
|
||||||
},
|
|
||||||
GpsMap: {
|
GpsMap: {
|
||||||
value: mapActive,
|
value: mapActive,
|
||||||
onChange(enabled) {
|
onChange(enabled) {
|
||||||
@@ -74,7 +50,7 @@ export const LandingComponent: React.FC = () => {
|
|||||||
}
|
}
|
||||||
setMapActive(enabled);
|
setMapActive(enabled);
|
||||||
},
|
},
|
||||||
label: 'Map',
|
label: 'GPS',
|
||||||
},
|
},
|
||||||
AI: {
|
AI: {
|
||||||
value: aiActive,
|
value: aiActive,
|
||||||
@@ -92,7 +68,7 @@ export const LandingComponent: React.FC = () => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
<BevyScene speed={speed} intensity={intensity} glow={glow} visible={bevyScene} />
|
{/*<BevyScene speed={speed} intensity={intensity} glow={glow} visible={bevyScene} />*/}
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@@ -37,7 +37,7 @@ const key =
|
|||||||
function Map(props: { visible: boolean }) {
|
function Map(props: { visible: boolean }) {
|
||||||
return (
|
return (
|
||||||
/* Full-screen wrapper — fills the viewport and becomes the positioning context */
|
/* Full-screen wrapper — fills the viewport and becomes the positioning context */
|
||||||
<Box w="100%" h="100vh" position="relative" overflow="hidden">
|
<Box position={'absolute'} top={0} w="100vw" h={'100vh'} overflow="hidden">
|
||||||
{/* Button bar — absolutely positioned inside the wrapper */}
|
{/* Button bar — absolutely positioned inside the wrapper */}
|
||||||
|
|
||||||
<MapNext mapboxPublicKey={atob(key)} />
|
<MapNext mapboxPublicKey={atob(key)} />
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { Box, Button, HStack, Input } from '@chakra-ui/react';
|
import { Box } from '@chakra-ui/react';
|
||||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import Map, {
|
import Map, {
|
||||||
FullscreenControl,
|
FullscreenControl,
|
||||||
@@ -118,11 +118,10 @@ Type '{ city: string; population: string; image: string; state: string; latitude
|
|||||||
right: 0,
|
right: 0,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<GeolocateControl position="top-left" />
|
<GeolocateControl position="top-left" style={{ marginTop: '6rem' }} />
|
||||||
<FullscreenControl position="top-left" />
|
<FullscreenControl position="top-left" />
|
||||||
<NavigationControl position="top-left" />
|
<NavigationControl position="top-left" />
|
||||||
<ScaleControl position="top-left" />
|
<ScaleControl position="top-left" />
|
||||||
|
|
||||||
{pins}
|
{pins}
|
||||||
|
|
||||||
{popupInfo && (
|
{popupInfo && (
|
||||||
|
@@ -6,7 +6,7 @@ import { useIsMobile } from '../components/contexts/MobileContext';
|
|||||||
function Content({ children }) {
|
function Content({ children }) {
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
return (
|
return (
|
||||||
<Flex flexDirection="column" w="100%" h="100vh" p={!isMobile ? 4 : 1}>
|
<Flex flexDirection="column" w="100%" h="100vh">
|
||||||
{children}
|
{children}
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
|
@@ -1,4 +1,6 @@
|
|||||||
// runs before anything else
|
// runs before anything else
|
||||||
|
import { registerSW } from 'virtual:pwa-register';
|
||||||
|
|
||||||
import UserOptionsStore from '../stores/UserOptionsStore';
|
import UserOptionsStore from '../stores/UserOptionsStore';
|
||||||
|
|
||||||
UserOptionsStore.initialize();
|
UserOptionsStore.initialize();
|
||||||
@@ -6,7 +8,11 @@ UserOptionsStore.initialize();
|
|||||||
try {
|
try {
|
||||||
const isLocal = window.location.hostname.includes('localhost');
|
const isLocal = window.location.hostname.includes('localhost');
|
||||||
if (!isLocal) {
|
if (!isLocal) {
|
||||||
navigator.serviceWorker.register('/service-worker.js');
|
if ('serviceWorker' in navigator) {
|
||||||
|
// && !/localhost/.test(window.location)) {
|
||||||
|
registerSW();
|
||||||
|
}
|
||||||
|
// navigator.serviceWorker.register('/service-worker.js');
|
||||||
} else {
|
} else {
|
||||||
(async () => {
|
(async () => {
|
||||||
await navigator.serviceWorker.getRegistrations().then(registrations => {
|
await navigator.serviceWorker.getRegistrations().then(registrations => {
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { Box, Grid, GridItem, Stack } from '@chakra-ui/react';
|
import { Box } from '@chakra-ui/react';
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
|
|
||||||
import Chat from '../../components/chat/Chat.tsx';
|
import Chat from '../../components/chat/Chat.tsx';
|
||||||
@@ -22,27 +22,26 @@ export default function IndexPage() {
|
|||||||
const component = useComponent();
|
const component = useComponent();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid templateColumns="repeat(2, 1fr)" height="100%" width="100%" gap={0}>
|
<Box height="100%" width="100%">
|
||||||
<GridItem>
|
<LandingComponent />
|
||||||
<LandingComponent />
|
|
||||||
</GridItem>
|
<Box
|
||||||
<GridItem p={2}>
|
display={component.enabledComponent === 'ai' ? undefined : 'none'}
|
||||||
<Box
|
width="100%"
|
||||||
display={component.enabledComponent === 'ai' ? undefined : 'none'}
|
height="100%"
|
||||||
width="100%"
|
overflowY="scroll"
|
||||||
height="100%"
|
padding={'unset'}
|
||||||
overflowY="scroll"
|
>
|
||||||
>
|
<Chat />
|
||||||
<Chat />
|
</Box>
|
||||||
</Box>
|
<Box
|
||||||
<Box
|
display={component.enabledComponent === 'gpsmap' ? undefined : 'none'}
|
||||||
display={component.enabledComponent === 'gpsmap' ? undefined : 'none'}
|
width="100%"
|
||||||
width="100%"
|
height="100%"
|
||||||
height="100%"
|
padding={'unset'}
|
||||||
>
|
>
|
||||||
<ReactMap visible={component.enabledComponent === 'gpsmap'} />
|
<ReactMap visible={component.enabledComponent === 'gpsmap'} />
|
||||||
</Box>
|
</Box>
|
||||||
</GridItem>
|
</Box>
|
||||||
</Grid>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
export const welcome_home_text = `
|
export const welcome_home_text = `
|
||||||
# yachtpit-ai
|
# open-gsio
|
||||||
---
|
---
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
@@ -22,10 +22,6 @@ const prebuildPlugin = () => ({
|
|||||||
console.log('Generated robots.txt -> public/robots.txt');
|
console.log('Generated robots.txt -> public/robots.txt');
|
||||||
child_process.execSync('bun run generate:fonts');
|
child_process.execSync('bun run generate:fonts');
|
||||||
console.log('Copied fonts -> public/static/fonts');
|
console.log('Copied fonts -> public/static/fonts');
|
||||||
child_process.execSync('bun run generate:bevy:bundle', {
|
|
||||||
stdio: 'inherit',
|
|
||||||
});
|
|
||||||
console.log('Bundled bevy app -> public/yachtpit.html');
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
"@open-gsio/services": "workspace:*",
|
"@open-gsio/services": "workspace:*",
|
||||||
"itty-router": "^5.0.18",
|
"itty-router": "^5.0.18",
|
||||||
"mobx": "^6.13.5",
|
"mobx": "^6.13.5",
|
||||||
"mobx-state-tree": "^6.0.1",
|
"mobx-state-tree": "^7.0.2",
|
||||||
"vitest": "^3.1.4",
|
"vitest": "^3.1.4",
|
||||||
"vite": "^6.3.5"
|
"vite": "^6.3.5"
|
||||||
}
|
}
|
||||||
|
@@ -20,6 +20,6 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"typescript": "^5.7.2",
|
"typescript": "^5.7.2",
|
||||||
"mobx-state-tree": "^6.0.1"
|
"mobx-state-tree": "^7.0.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -21,7 +21,7 @@
|
|||||||
"itty-router": "^5.0.18",
|
"itty-router": "^5.0.18",
|
||||||
"jsdom": "^24.0.0",
|
"jsdom": "^24.0.0",
|
||||||
"mobx": "^6.13.5",
|
"mobx": "^6.13.5",
|
||||||
"mobx-state-tree": "^6.0.1",
|
"mobx-state-tree": "^7.0.2",
|
||||||
"moo": "^0.5.2",
|
"moo": "^0.5.2",
|
||||||
"typescript": "^5.7.2",
|
"typescript": "^5.7.2",
|
||||||
"vike": "0.4.235",
|
"vike": "0.4.235",
|
||||||
|
@@ -30,7 +30,7 @@
|
|||||||
"itty-router": "^5.0.18",
|
"itty-router": "^5.0.18",
|
||||||
"jsdom": "^24.0.0",
|
"jsdom": "^24.0.0",
|
||||||
"mobx": "^6.13.5",
|
"mobx": "^6.13.5",
|
||||||
"mobx-state-tree": "^6.0.1",
|
"mobx-state-tree": "^7.0.2",
|
||||||
"moo": "^0.5.2",
|
"moo": "^0.5.2",
|
||||||
"openai": "^5.0.1",
|
"openai": "^5.0.1",
|
||||||
"typescript": "^5.7.2",
|
"typescript": "^5.7.2",
|
||||||
|
Reference in New Issue
Block a user