From fc07f3979671e84ec29f4f1bc1d84358e3a1174d Mon Sep 17 00:00:00 2001 From: Hazem Krimi Date: Mon, 13 Jan 2025 21:32:20 +0100 Subject: [PATCH] Consume the api locally --- client/src/App.css | 4 ++-- client/src/App.jsx | 46 ++++++++++++++++++++++++++++++++++++--------- client/src/main.jsx | 4 +--- server/main.go | 4 ++-- 4 files changed, 42 insertions(+), 16 deletions(-) diff --git a/client/src/App.css b/client/src/App.css index 10c92bd..38e0009 100644 --- a/client/src/App.css +++ b/client/src/App.css @@ -1,5 +1,4 @@ .container { - max-width: 500px; margin: auto; padding: 1rem; letter-spacing: 0.25rem; @@ -23,12 +22,13 @@ .enter:before { content: '\21b5'; + display: inline-block; } .enter:after { content: ''; display: block; - clear: both; + clear: right; } .tab:before { diff --git a/client/src/App.jsx b/client/src/App.jsx index eb5321b..8386901 100644 --- a/client/src/App.jsx +++ b/client/src/App.jsx @@ -2,35 +2,57 @@ import { useEffect, useState } from 'react'; import './App.css'; const KEYS_TO_DISABLE = ['Backspace', 'Shift', 'Alt', 'Control', 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', 'Escape', 'Delete', 'PageDown', 'PageUp', 'Home', 'End', 'Insert', 'WakeUp', 'Pause', 'ScrollLock', 'ContextMenu', 'BrowserForward', 'BrowserBack', 'CapsLock', 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight']; -const SNIPPET = 'ctx := context.Background();\nconsole.log("hello");\nfunction() {\n\talert(123);\n}'; function App() { + const [code, setCode] = useState(''); + const [loaded, setLoaded] = useState(false); const [characters, setCharacters] = useState([]); + useEffect(() => { + (async function() { + const response = await fetch('http://localhost:5000/generate?lang=golang&lines=10'); + const reader = response.body.getReader(); + const decoder = new TextDecoder(); + + while(true) { + const {value, done} = await reader.read(); + + setCode(prev => prev + decoder.decode(value)); + + if (done) { + setLoaded(true); + break; + } + } + })(); + }, []); + useEffect(() => { function handleKeyPress(event) { event.preventDefault(); - if (characters.length === SNIPPET.length) return; + if (!loaded) return; + if (characters.length === code.length) return; if (KEYS_TO_DISABLE.includes(event.key)) return; - if (SNIPPET[characters.length] === '\n') + if (code[characters.length] === '\n') return setCharacters( characters.concat(event.key === 'Enter') ); - if (SNIPPET[characters.length] === '\t') + if (code[characters.length] === '\t') return setCharacters( characters.concat(event.key === 'Tab') ); setCharacters( - characters.concat(event.key === SNIPPET[characters.length]) + characters.concat(event.key === code[characters.length]) ); } window.addEventListener('keydown', handleKeyPress); return () => window.removeEventListener('keydown', handleKeyPress); - }, [characters]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [loaded, characters]); function renderCharacterClassName(index) { if (index === characters.length) return 'highlight' @@ -40,16 +62,22 @@ function App() { return 'correct' } + // TODO: Remove rendering of spacing characters and render a cursor with the highlight instead. + // TODO: Or look into pretty printing libraries. function renderSpacingCharacter(char) { - if (/^\t$/.test(char)) return 'tab' if (/^\n$/.test(char)) return 'enter' + if (/^\t$/.test(char)) return 'tab' if (/^\s$/.test(char)) return 'space' return '' } - return
{SNIPPET.split('').map((char, index) => ( - {char} + function renderClassName(index, char) { + return `${renderCharacterClassName(index)} ${renderSpacingCharacter(char)}`.trim(); + } + + return
{code.split('').map((char, index) => ( + {char} ))}
; } diff --git a/client/src/main.jsx b/client/src/main.jsx index c358781..b274c5c 100644 --- a/client/src/main.jsx +++ b/client/src/main.jsx @@ -1,10 +1,8 @@ -import { StrictMode } from 'react'; import { createRoot } from 'react-dom/client'; import './index.css'; import App from './App.jsx'; +// TODO: Bring back string mode when building and deploying createRoot(document.getElementById('root')).render( - - , ); diff --git a/server/main.go b/server/main.go index 4bbdd68..e4c9a0e 100644 --- a/server/main.go +++ b/server/main.go @@ -41,9 +41,9 @@ func main() { ollamaCtx := context.Background() content := []llms.MessageContent{ - llms.TextParts(llms.ChatMessageTypeSystem, `You are only a code generator. You must not respond with anything else but code and do not format with code fences.`), + llms.TextParts(llms.ChatMessageTypeSystem, `You are only a code generator. You must not respond with anything else but code and do not format with code fences. Always use tabs instead of spaces.`), llms.TextParts(llms.ChatMessageTypeHuman, fmt.Sprintf(` - Generate max %d lines of code without any unncessary formatting from a well known open source project in the %s programming language. First line should always be a code comment in this format: Language/Project`, lines, lang)), + Generate max %d lines of code without any unncessary formatting from a well known open source project in the %s programming language. First line should always be a code comment in the used language in this format: "// Language/Project"`, lines, lang)), } if _, err := llm.GenerateContent(ollamaCtx, content, llms.WithStreamingFunc(func(streamCtx context.Context, chunk []byte) error {