bookly/static/index.html
Cody Borders 30cdea2aac Build Bookly customer support agent
A FastAPI + vanilla JS chat app fronting an Anthropic Claude agent for
order status, returns, and policy questions.

Architecture:
- agent.py: system prompt, runtime reminder injection, output validation,
  agentic tool-use loop with prompt caching on the system prompt block
- tools.py: four tools (lookup_order, check_return_eligibility,
  initiate_return, lookup_policy) with per-session SessionGuardState
  enforcing protocol ordering on the tool side
- mock_data.py: orders, return policy, and FAQ entries used as the single
  source of truth by both the prompt and the tools
- server.py: FastAPI app exposing /api/chat, /health, and the static UI
- static/: vanilla HTML/CSS/JS chat UI, no build step
- tests/: 30 tests covering tool-side enforcement, the privacy boundary,
  output validation, and the agent loop with a mocked Anthropic client
- deploy/: systemd unit and nginx site config for production
2026-04-14 22:17:59 -07:00

31 lines
899 B
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Bookly Support</title>
<link rel="stylesheet" href="/static/style.css" />
</head>
<body>
<main class="chat">
<header class="chat__header">
<h1>Bookly Support</h1>
<p class="chat__subtitle">Order status, returns, and policy questions</p>
</header>
<div id="messages" class="chat__messages" aria-live="polite"></div>
<form id="composer" class="chat__composer" autocomplete="off">
<input
id="input"
class="chat__input"
type="text"
placeholder="Ask about an order or a return..."
maxlength="4000"
required
/>
<button id="send" class="chat__send" type="submit">Send</button>
</form>
</main>
<script src="/static/chat.js"></script>
</body>
</html>