feat: wire chat to the agent loop (POST /chat)
Mirror to GitHub / mirror (push) Canceled after 0s

- api: /chat route runs runAgent (session-required, 503 when unconfigured)
- api: index.ts builds OpenRouterLlmClient + WpRestExecutor from env; loads .env
- web: useChat calls /chat with mock fallback; proxy /chat+/sites+/health
- .env.example: DATABASE_URL empty by default (in-memory dev)
- 111 unit tests green; smoke-tested signup+chat
This commit is contained in:
SinachPat
2026-08-17 17:19:33 +01:00
parent 69287ebec0
commit 060b181e71
8 changed files with 178 additions and 14 deletions
+21 -12
View File
@@ -8,6 +8,12 @@ function extractHeading(text: string): string | undefined {
return match?.[1];
}
function mockReply(text: string, heading: string | undefined): string {
return heading !== undefined
? `Done — I updated the homepage heading to “${heading}”. Preview it below.`
: 'Done — your change is ready to preview.';
}
export function useChat() {
const [messages, setMessages] = useState<ChatMessage[]>([]);
const [status, setStatus] = useState<ChatStatus>('idle');
@@ -17,18 +23,21 @@ export function useChat() {
const nextHeading = extractHeading(text);
setMessages((prev) => [...prev, { id: crypto.randomUUID(), role: 'user', text }]);
setStatus('working');
await new Promise((resolve) => setTimeout(resolve, 1200));
setMessages((prev) => [
...prev,
{
id: crypto.randomUUID(),
role: 'agent',
text:
nextHeading !== undefined
? `Done — I updated the homepage heading to “${nextHeading}”. Preview it below.`
: 'Done — your change is ready to preview.',
},
]);
try {
const res = await fetch('/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message: text }),
});
if (!res.ok) throw new Error('chat unavailable');
const body = (await res.json()) as { reply?: string };
setMessages((prev) => [...prev, { id: crypto.randomUUID(), role: 'agent', text: body.reply ?? 'Done' }]);
} catch {
await new Promise((resolve) => setTimeout(resolve, 1200));
setMessages((prev) => [...prev, { id: crypto.randomUUID(), role: 'agent', text: mockReply(text, nextHeading) }]);
}
if (nextHeading !== undefined) {
setHeading(nextHeading);
}
+3
View File
@@ -6,6 +6,9 @@ export default defineConfig({
server: {
proxy: {
'/auth': 'http://localhost:3000',
'/chat': 'http://localhost:3000',
'/sites': 'http://localhost:3000',
'/health': 'http://localhost:3000',
},
},
test: {