eriquesouza Cursor commited on
Commit
2f56bf2
·
1 Parent(s): b7b030d

Preparar deploy no Hugging Face Spaces.

Browse files

Adiciona Dockerfile na porta 7860, caches em /tmp e guia de deploy no README.

Co-authored-by: Cursor <cursoragent@cursor.com>

Files changed (5) hide show
  1. .dockerignore +13 -0
  2. Dockerfile +22 -0
  3. README.md +57 -0
  4. agent.py +10 -1
  5. main.py +7 -2
.dockerignore ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .git
2
+ .gitignore
3
+ .env
4
+ .env.*
5
+ chroma_db/
6
+ __pycache__/
7
+ *.py[cod]
8
+ .venv/
9
+ venv/
10
+ .pytest_cache/
11
+ .ruff_cache/
12
+ *.md
13
+ !README.md
Dockerfile ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.11-slim
2
+
3
+ WORKDIR /app
4
+
5
+ # HF Spaces roda como usuário não-root; caches devem ir para /tmp.
6
+ ENV PORT=7860 \
7
+ CHROMA_PERSIST_DIR=/tmp/chroma_db \
8
+ HF_HOME=/tmp/hf_home \
9
+ TRANSFORMERS_CACHE=/tmp/hf_home \
10
+ SENTENCE_TRANSFORMERS_HOME=/tmp/hf_home \
11
+ XDG_CACHE_HOME=/tmp/cache \
12
+ PYTHONUNBUFFERED=1 \
13
+ PYTHONDONTWRITEBYTECODE=1
14
+
15
+ COPY requirements.txt .
16
+ RUN pip install --no-cache-dir -r requirements.txt
17
+
18
+ COPY . .
19
+
20
+ EXPOSE 7860
21
+
22
+ CMD ["sh", "-c", "uvicorn main:app --host 0.0.0.0 --port ${PORT}"]
README.md CHANGED
@@ -1,3 +1,13 @@
 
 
 
 
 
 
 
 
 
 
1
  # Agent Memory — Fase 1 (Baseline)
2
 
3
  PoC de **memória observável**: chat à esquerda, armazém de memórias à direita.
@@ -14,11 +24,58 @@ agent_memory/
14
  ├── models.py # Pydantic models
15
  ├── seeds.py # Memórias seed (falas de clientes fictícios)
16
  ├── requirements.txt
 
17
  ├── .env.example
18
  └── static/
19
  └── index.html # UI do armazém
20
  ```
21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  ## Setup
23
 
24
  ### 1. Criar ambiente
 
1
+ ---
2
+ title: Agent Memory
3
+ emoji: 🧠
4
+ colorFrom: blue
5
+ colorTo: purple
6
+ sdk: docker
7
+ app_port: 7860
8
+ pinned: false
9
+ ---
10
+
11
  # Agent Memory — Fase 1 (Baseline)
12
 
13
  PoC de **memória observável**: chat à esquerda, armazém de memórias à direita.
 
24
  ├── models.py # Pydantic models
25
  ├── seeds.py # Memórias seed (falas de clientes fictícios)
26
  ├── requirements.txt
27
+ ├── Dockerfile # Deploy em Hugging Face Spaces
28
  ├── .env.example
29
  └── static/
30
  └── index.html # UI do armazém
31
  ```
32
 
33
+ ## Deploy no Hugging Face Spaces
34
+
35
+ ### 1. Criar o Space
36
+
37
+ 1. Acesse [huggingface.co/new-space](https://huggingface.co/new-space)
38
+ 2. **Space name:** ex. `agent-memory`
39
+ 3. **SDK:** Docker
40
+ 4. **Hardware:** CPU basic (grátis)
41
+ 5. **Visibility:** Public ou Private
42
+
43
+ ### 2. Conectar ao GitHub (recomendado)
44
+
45
+ Na aba **Settings** do Space:
46
+
47
+ 1. **Repository** → conecte `EriqueSouza/agent_memory` (branch `claude_agent` ou `main`)
48
+ 2. Faça push deste repositório com o `Dockerfile` e o frontmatter YAML no `README.md`
49
+
50
+ Ou faça push direto para o git do Space:
51
+
52
+ ```bash
53
+ git remote add space https://huggingface.co/spaces/SEU_USUARIO/agent-memory
54
+ git push space claude_agent:main
55
+ ```
56
+
57
+ ### 3. Configurar secrets
58
+
59
+ Em **Settings → Repository secrets** do Space, adicione:
60
+
61
+ | Secret | Valor |
62
+ |--------|-------|
63
+ | `OPENROUTER_API_KEY` | sua chave OpenRouter |
64
+ | `OPENROUTER_MODEL` | ex. `nvidia/nemotron-3-super-120b-a12b` |
65
+ | `OPENROUTER_API_URL` | `https://openrouter.ai/api/v1` |
66
+
67
+ > O Space reinicia automaticamente após salvar os secrets.
68
+
69
+ ### 4. Acessar
70
+
71
+ URL pública: `https://huggingface.co/spaces/SEU_USUARIO/agent-memory`
72
+
73
+ A UI abre na raiz (`/`). O build inicial pode levar alguns minutos (download do modelo de embedding do ChromaDB).
74
+
75
+ **Limitações no tier gratuito:** disco efêmero — memórias criadas no chat somem se o Space reiniciar; os seeds são recarregados automaticamente.
76
+
77
+ ---
78
+
79
  ## Setup
80
 
81
  ### 1. Criar ambiente
agent.py CHANGED
@@ -15,6 +15,15 @@ from memory_store import MemoryStore
15
 
16
  load_dotenv()
17
 
 
 
 
 
 
 
 
 
 
18
  SYSTEM_PROMPT = """\
19
  You are a customer service assistant for an internet, TV, and telephony provider in Brazil.
20
  This is a memory-observability PoC: you help the current customer resolve their situation using \
@@ -127,7 +136,7 @@ class Agent:
127
  "response_format": {"type": "json_object"},
128
  },
129
  default_headers={
130
- "HTTP-Referer": "http://localhost:8000",
131
  "X-Title": "Agent Memory Phase 1",
132
  },
133
  )
 
15
 
16
  load_dotenv()
17
 
18
+
19
+ def _openrouter_referer() -> str:
20
+ if host := os.getenv("SPACE_HOST"):
21
+ return host
22
+ if space_id := os.getenv("SPACE_ID"):
23
+ return f"https://huggingface.co/spaces/{space_id}"
24
+ return "http://localhost:8000"
25
+
26
+
27
  SYSTEM_PROMPT = """\
28
  You are a customer service assistant for an internet, TV, and telephony provider in Brazil.
29
  This is a memory-observability PoC: you help the current customer resolve their situation using \
 
136
  "response_format": {"type": "json_object"},
137
  },
138
  default_headers={
139
+ "HTTP-Referer": _openrouter_referer(),
140
  "X-Title": "Agent Memory Phase 1",
141
  },
142
  )
main.py CHANGED
@@ -1,3 +1,5 @@
 
 
1
  from fastapi import FastAPI, HTTPException
2
  from fastapi.staticfiles import StaticFiles
3
  from fastapi.responses import FileResponse
@@ -9,7 +11,8 @@ from agent import Agent
9
  from seeds import SEED_MEMORIES
10
 
11
 
12
- memory_store = MemoryStore(persist_dir="./chroma_db")
 
13
  agent = Agent(memory_store=memory_store)
14
 
15
 
@@ -79,4 +82,6 @@ async def reset_memories():
79
 
80
  if __name__ == "__main__":
81
  import uvicorn
82
- uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
 
 
 
1
+ import os
2
+
3
  from fastapi import FastAPI, HTTPException
4
  from fastapi.staticfiles import StaticFiles
5
  from fastapi.responses import FileResponse
 
11
  from seeds import SEED_MEMORIES
12
 
13
 
14
+ PERSIST_DIR = os.getenv("CHROMA_PERSIST_DIR", "./chroma_db")
15
+ memory_store = MemoryStore(persist_dir=PERSIST_DIR)
16
  agent = Agent(memory_store=memory_store)
17
 
18
 
 
82
 
83
  if __name__ == "__main__":
84
  import uvicorn
85
+
86
+ port = int(os.getenv("PORT", "8000"))
87
+ uvicorn.run("main:app", host="0.0.0.0", port=port, reload=True)