Spaces:
Running
Running
Upload 5 files
Browse files- README.md +11 -13
- chat-engine.jsx +42 -12
- debug-panel.jsx +3 -3
- variant-terminal.jsx +3 -3
README.md
CHANGED
|
@@ -1,11 +1,10 @@
|
|
| 1 |
---
|
| 2 |
-
title:
|
| 3 |
-
emoji:
|
| 4 |
colorFrom: gray
|
| 5 |
colorTo: yellow
|
| 6 |
sdk: static
|
| 7 |
pinned: false
|
| 8 |
-
short_description: Dog-loving baseline chatbot. A zero-backend static demo
|
| 9 |
---
|
| 10 |
|
| 11 |
# This is Fetch
|
|
@@ -17,21 +16,20 @@ Space. It runs entirely in the browser β no GPU, no Python, no backend.
|
|
| 17 |
|
| 18 |
## How it works
|
| 19 |
|
| 20 |
-
Fetch answers using
|
| 21 |
|
|
|
|
|
|
|
| 22 |
- A small **keyword lookup** table (dogs, breeds, care, trivia, reactions).
|
| 23 |
If the user's question contains a known keyword, the matching fact is
|
| 24 |
returned verbatim.
|
| 25 |
-
- Three **fallback replies** cover
|
| 26 |
-
- **Four-turn context** is kept in memory for the session.
|
| 27 |
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
static build. Static Spaces don't run Python or serve models, so the
|
| 31 |
-
deterministic keyword-lookup path is the honest option here.
|
| 32 |
|
| 33 |
-
|
| 34 |
-
|
| 35 |
|
| 36 |
## Files
|
| 37 |
|
|
@@ -48,4 +46,4 @@ Gradio Space instead (`sdk: gradio`, CPU hardware is fine).
|
|
| 48 |
## Credits
|
| 49 |
|
| 50 |
Design and frontend: a set of explorations for *This is Fetch*.
|
| 51 |
-
Reference model: [facebook/blenderbot-400M-distill](https://huggingface.co/facebook/blenderbot-400M-distill).
|
|
|
|
| 1 |
---
|
| 2 |
+
title: This is Fetch
|
| 3 |
+
emoji: π
|
| 4 |
colorFrom: gray
|
| 5 |
colorTo: yellow
|
| 6 |
sdk: static
|
| 7 |
pinned: false
|
|
|
|
| 8 |
---
|
| 9 |
|
| 10 |
# This is Fetch
|
|
|
|
| 16 |
|
| 17 |
## How it works
|
| 18 |
|
| 19 |
+
Fetch answers using a layered response pipeline:
|
| 20 |
|
| 21 |
+
- A lightweight **intent matcher** that handles greetings, small talk, and
|
| 22 |
+
questions like "what can you do".
|
| 23 |
- A small **keyword lookup** table (dogs, breeds, care, trivia, reactions).
|
| 24 |
If the user's question contains a known keyword, the matching fact is
|
| 25 |
returned verbatim.
|
| 26 |
+
- Three **fallback replies** cover everything else.
|
|
|
|
| 27 |
|
| 28 |
+
There is no model running in this build. Static Spaces don't run Python or
|
| 29 |
+
serve models, so the deterministic response pipeline is the honest option here.
|
|
|
|
|
|
|
| 30 |
|
| 31 |
+
The generative version, powered by Meta's BlenderBot-400M-distill, runs
|
| 32 |
+
separately as a [Docker Space](https://huggingface.co/spaces/ElisaTrippetti/Fetch-Good-Boi).
|
| 33 |
|
| 34 |
## Files
|
| 35 |
|
|
|
|
| 46 |
## Credits
|
| 47 |
|
| 48 |
Design and frontend: a set of explorations for *This is Fetch*.
|
| 49 |
+
Reference model: [facebook/blenderbot-400M-distill](https://huggingface.co/facebook/blenderbot-400M-distill).
|
chat-engine.jsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
// chat-engine.jsx β shared chat logic for all Fetch variants.
|
| 2 |
-
//
|
| 3 |
-
// Two backends: "claude" (window.claude.complete) and "local" (
|
| 4 |
-
//
|
| 5 |
|
| 6 |
const KNOWLEDGE_BASE = [
|
| 7 |
["domesticate", "Dogs have been domesticated for at least 15,000 years, making them the oldest domesticated animal."],
|
|
@@ -34,6 +34,33 @@ const FALLBACKS = [
|
|
| 34 |
"I'm not sure about that, but dogs are great!",
|
| 35 |
];
|
| 36 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
const SUGGESTIONS = [
|
| 38 |
"Tell me about border collies",
|
| 39 |
"How good is a dog's sense of smell?",
|
|
@@ -93,6 +120,9 @@ function buildPrompt(history, userInput, fact, personality) {
|
|
| 93 |
}
|
| 94 |
|
| 95 |
async function generateReply({ userInput, history, backend, personality }) {
|
|
|
|
|
|
|
|
|
|
| 96 |
const fact = retrieveFact(userInput);
|
| 97 |
|
| 98 |
if (backend === "claude" && typeof window !== "undefined" && window.claude?.complete) {
|
|
@@ -170,18 +200,18 @@ function useFetchChat({ backend = "claude", personality = "subtle" } = {}) {
|
|
| 170 |
return { messages, pending, debug, send, reset };
|
| 171 |
}
|
| 172 |
|
| 173 |
-
//
|
| 174 |
function useRotatingSuggestions({ visible = 3, intervalMs = 4200 } = {}) {
|
| 175 |
-
const [
|
|
|
|
|
|
|
| 176 |
React.useEffect(() => {
|
| 177 |
-
const id = setInterval(() =>
|
|
|
|
|
|
|
|
|
|
| 178 |
return () => clearInterval(id);
|
| 179 |
-
}, [intervalMs]);
|
| 180 |
-
const current = React.useMemo(() => {
|
| 181 |
-
const out = [];
|
| 182 |
-
for (let i = 0; i < visible; i++) out.push(SUGGESTIONS[(offset + i) % SUGGESTIONS.length]);
|
| 183 |
-
return out;
|
| 184 |
-
}, [offset, visible]);
|
| 185 |
return current;
|
| 186 |
}
|
| 187 |
|
|
|
|
| 1 |
// chat-engine.jsx β shared chat logic for all Fetch variants.
|
| 2 |
+
// Response pipeline: intent matching β keyword lookup β fallbacks.
|
| 3 |
+
// Two backends: "claude" (window.claude.complete) and "local" (intent
|
| 4 |
+
// matching + keyword lookup + fallbacks β the path HF Static Spaces take).
|
| 5 |
|
| 6 |
const KNOWLEDGE_BASE = [
|
| 7 |
["domesticate", "Dogs have been domesticated for at least 15,000 years, making them the oldest domesticated animal."],
|
|
|
|
| 34 |
"I'm not sure about that, but dogs are great!",
|
| 35 |
];
|
| 36 |
|
| 37 |
+
const INTENTS = [
|
| 38 |
+
{
|
| 39 |
+
patterns: [/\b(hi|hello|hey)\b/i, /good (morning|afternoon|evening)/i],
|
| 40 |
+
response: "Hi! I'm Fetch Pup. Ask me something about dogs, or try the suggestions below.",
|
| 41 |
+
},
|
| 42 |
+
{
|
| 43 |
+
patterns: [/how are you/i, /how('s| is) it going/i, /what'?s up/i],
|
| 44 |
+
response: "Tail's wagging, thanks for asking! Got a dog question for me?",
|
| 45 |
+
},
|
| 46 |
+
{
|
| 47 |
+
patterns: [/what can you do/i, /what do you (know|do)/i, /\bhelp\b/i],
|
| 48 |
+
response: "I know a bunch of dog facts. Ask a question or try the suggestions β I'll do my best.",
|
| 49 |
+
},
|
| 50 |
+
{
|
| 51 |
+
patterns: [/who are you/i, /what are you/i],
|
| 52 |
+
response: "I'm Fetch Pup β a static chatbot demo. No model running, just intent matching and keyword lookup. But I know my dogs!",
|
| 53 |
+
},
|
| 54 |
+
];
|
| 55 |
+
|
| 56 |
+
function matchIntent(query) {
|
| 57 |
+
const q = query || "";
|
| 58 |
+
for (const intent of INTENTS) {
|
| 59 |
+
if (intent.patterns.some(p => p.test(q))) return intent.response;
|
| 60 |
+
}
|
| 61 |
+
return null;
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
const SUGGESTIONS = [
|
| 65 |
"Tell me about border collies",
|
| 66 |
"How good is a dog's sense of smell?",
|
|
|
|
| 120 |
}
|
| 121 |
|
| 122 |
async function generateReply({ userInput, history, backend, personality }) {
|
| 123 |
+
const intent = matchIntent(userInput);
|
| 124 |
+
if (intent) return { text: intent, fact: null };
|
| 125 |
+
|
| 126 |
const fact = retrieveFact(userInput);
|
| 127 |
|
| 128 |
if (backend === "claude" && typeof window !== "undefined" && window.claude?.complete) {
|
|
|
|
| 200 |
return { messages, pending, debug, send, reset };
|
| 201 |
}
|
| 202 |
|
| 203 |
+
// Suggestion carousel β picks 3 at random on each interval tick.
|
| 204 |
function useRotatingSuggestions({ visible = 3, intervalMs = 4200 } = {}) {
|
| 205 |
+
const [current, setCurrent] = React.useState(() =>
|
| 206 |
+
[...SUGGESTIONS].sort(() => Math.random() - 0.5).slice(0, visible)
|
| 207 |
+
);
|
| 208 |
React.useEffect(() => {
|
| 209 |
+
const id = setInterval(() =>
|
| 210 |
+
setCurrent([...SUGGESTIONS].sort(() => Math.random() - 0.5).slice(0, visible)),
|
| 211 |
+
intervalMs
|
| 212 |
+
);
|
| 213 |
return () => clearInterval(id);
|
| 214 |
+
}, [visible, intervalMs]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 215 |
return current;
|
| 216 |
}
|
| 217 |
|
debug-panel.jsx
CHANGED
|
@@ -125,9 +125,9 @@ function DebugAbout({ palette }) {
|
|
| 125 |
return (
|
| 126 |
<div style={{ lineHeight: 1.6, color: palette.fg, display: "flex", flexDirection: "column", gap: 10 }}>
|
| 127 |
<div>Fetch Pup is a static browser demo β there is no model running.</div>
|
| 128 |
-
<div>Responses come from
|
| 129 |
-
<div>The generative version, powered by Meta's BlenderBot-400M-distill, runs separately as a
|
| 130 |
-
<div style={{ color: palette.dim }}>
|
| 131 |
</div>
|
| 132 |
);
|
| 133 |
}
|
|
|
|
| 125 |
return (
|
| 126 |
<div style={{ lineHeight: 1.6, color: palette.fg, display: "flex", flexDirection: "column", gap: 10 }}>
|
| 127 |
<div>Fetch Pup is a static browser demo β there is no model running.</div>
|
| 128 |
+
<div>Responses come from two layers: an intent matcher that handles greetings and small talk, and a keyword lookup table that returns dog facts verbatim. If neither matches, you get one of three fallback replies.</div>
|
| 129 |
+
<div>The generative version, powered by Meta's BlenderBot-400M-distill, runs separately as a <a href="https://huggingface.co/spaces/ElisaTrippetti/Fetch-Good-Boi" target="_blank" rel="noopener noreferrer" style={{ color: palette.accent, textDecoration: "underline" }}>Docker Space</a>.</div>
|
| 130 |
+
<div style={{ color: palette.dim }}>Designed with Claude Design Β· Built with Claude Code</div>
|
| 131 |
</div>
|
| 132 |
);
|
| 133 |
}
|
variant-terminal.jsx
CHANGED
|
@@ -91,9 +91,9 @@ function TerminalVariant({ backend, personality, density, accent, fontPair, bubb
|
|
| 91 |
margin: 0, fontFamily: "inherit", color: palette.dim,
|
| 92 |
whiteSpace: "pre-wrap", marginBottom: 16,
|
| 93 |
}}>
|
| 94 |
-
{`// fetch pup
|
| 95 |
-
//
|
| 96 |
-
//
|
| 97 |
`}
|
| 98 |
</pre>
|
| 99 |
|
|
|
|
| 91 |
margin: 0, fontFamily: "inherit", color: palette.dim,
|
| 92 |
whiteSpace: "pre-wrap", marginBottom: 16,
|
| 93 |
}}>
|
| 94 |
+
{`// hey! i'm fetch pup β a dog-loving chatbot demo and learning baseline.
|
| 95 |
+
// i do intent matching, keyword lookup, and fallbacks β no model, all browser.
|
| 96 |
+
// ask me something, or try the suggestions below.
|
| 97 |
`}
|
| 98 |
</pre>
|
| 99 |
|