bentosmau commited on
Commit
c69a8c3
·
1 Parent(s): c8ed262

Add a functional AI chatbot using Gradio and OpenAI

Browse files

Integrate Gradio and OpenAI to create a conversational AI chatbot with streaming responses and conversation history, updating `app.py`, `replit.md`, `chat-app/README.md`, and dependency files.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: e3ff2484-bbd8-4aba-bea0-1940769b874a
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: aa4da6a9-2b45-4fbd-afc1-90fc22861497
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/1739408b-93a5-479b-a658-30f2493b0467/e3ff2484-bbd8-4aba-bea0-1940769b874a/17Q9XjF
Replit-Helium-Checkpoint-Created: true

Files changed (8) hide show
  1. .replit +26 -1
  2. chat-app/README.md +34 -0
  3. chat-app/app.py +98 -0
  4. chat-app/requirements.txt +2 -0
  5. main.py +6 -0
  6. pyproject.toml +9 -0
  7. replit.md +38 -57
  8. uv.lock +0 -0
.replit CHANGED
@@ -1,4 +1,4 @@
1
- modules = ["nodejs-24"]
2
 
3
  [[artifacts]]
4
  id = "artifacts/api-server"
@@ -17,6 +17,27 @@ env = { "CI" = "true" }
17
  [workflows]
18
  runButton = "Project"
19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  [agent]
21
  stack = "PNPM_WORKSPACE"
22
  expertMode = true
@@ -24,3 +45,7 @@ expertMode = true
24
  [postMerge]
25
  path = "scripts/post-merge.sh"
26
  timeoutMs = 20000
 
 
 
 
 
1
+ modules = ["nodejs-24", "python-3.11"]
2
 
3
  [[artifacts]]
4
  id = "artifacts/api-server"
 
17
  [workflows]
18
  runButton = "Project"
19
 
20
+ [[workflows.workflow]]
21
+ name = "Project"
22
+ mode = "parallel"
23
+ author = "agent"
24
+
25
+ [[workflows.workflow.tasks]]
26
+ task = "workflow.run"
27
+ args = "Start application"
28
+
29
+ [[workflows.workflow]]
30
+ name = "Start application"
31
+ author = "agent"
32
+
33
+ [[workflows.workflow.tasks]]
34
+ task = "shell.exec"
35
+ args = "PORT=5000 python chat-app/app.py"
36
+ waitForPort = 5000
37
+
38
+ [workflows.workflow.metadata]
39
+ outputType = "webview"
40
+
41
  [agent]
42
  stack = "PNPM_WORKSPACE"
43
  expertMode = true
 
45
  [postMerge]
46
  path = "scripts/post-merge.sh"
47
  timeoutMs = 20000
48
+
49
+ [nix]
50
+ channel = "stable-25_05"
51
+ packages = ["ffmpeg-full"]
chat-app/README.md ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Mi IA Chat
3
+ emoji: 🤖
4
+ colorFrom: blue
5
+ colorTo: indigo
6
+ sdk: gradio
7
+ sdk_version: "4.44.0"
8
+ app_file: app.py
9
+ pinned: false
10
+ license: mit
11
+ ---
12
+
13
+ # Mi IA Chat
14
+
15
+ Asistente de inteligencia artificial conversacional construido con Gradio y OpenAI.
16
+
17
+ ## Características
18
+
19
+ - Chat conversacional con IA avanzada
20
+ - Streaming de respuestas en tiempo real
21
+ - Historial de conversación
22
+ - Interfaz limpia y moderna
23
+
24
+ ## Cómo ejecutar localmente
25
+
26
+ ```bash
27
+ pip install -r requirements.txt
28
+ python app.py
29
+ ```
30
+
31
+ ## Variables de entorno necesarias
32
+
33
+ - `AI_INTEGRATIONS_OPENAI_BASE_URL` - URL base de la API
34
+ - `AI_INTEGRATIONS_OPENAI_API_KEY` - Clave API (o usa tu propia clave de OpenAI como `OPENAI_API_KEY`)
chat-app/app.py ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import gradio as gr
3
+ from openai import OpenAI
4
+
5
+ client = OpenAI(
6
+ base_url=os.environ.get("AI_INTEGRATIONS_OPENAI_BASE_URL"),
7
+ api_key=os.environ.get("AI_INTEGRATIONS_OPENAI_API_KEY", "dummy"),
8
+ )
9
+
10
+ SYSTEM_PROMPT = """Eres un asistente de IA inteligente y útil, similar a ChatGPT o Gemini.
11
+ Respondes en el mismo idioma que el usuario.
12
+ Eres amable, preciso y detallado en tus respuestas."""
13
+
14
+ def responder(mensaje, historial):
15
+ mensajes = [{"role": "system", "content": SYSTEM_PROMPT}]
16
+ for turno in historial:
17
+ mensajes.append({"role": "user", "content": turno[0]})
18
+ if turno[1]:
19
+ mensajes.append({"role": "assistant", "content": turno[1]})
20
+ mensajes.append({"role": "user", "content": mensaje})
21
+
22
+ respuesta_parcial = ""
23
+ historial = historial + [[mensaje, ""]]
24
+
25
+ stream = client.chat.completions.create(
26
+ model="gpt-5.2",
27
+ messages=mensajes,
28
+ stream=True,
29
+ max_completion_tokens=8192,
30
+ )
31
+
32
+ for chunk in stream:
33
+ contenido = chunk.choices[0].delta.content or ""
34
+ respuesta_parcial += contenido
35
+ historial[-1][1] = respuesta_parcial
36
+ yield historial, ""
37
+
38
+ with gr.Blocks(title="Mi IA Chat") as demo:
39
+ gr.Markdown(
40
+ """
41
+ # 🤖 Mi IA Chat
42
+ ### Asistente de inteligencia artificial conversacional
43
+ """
44
+ )
45
+
46
+ chatbot = gr.Chatbot(
47
+ show_label=False,
48
+ height=500,
49
+ avatar_images=(None, "https://api.dicebear.com/7.x/bottts/svg?seed=ai"),
50
+ )
51
+
52
+ with gr.Row():
53
+ entrada = gr.Textbox(
54
+ placeholder="Escribe tu mensaje aquí...",
55
+ show_label=False,
56
+ scale=9,
57
+ container=False,
58
+ autofocus=True,
59
+ )
60
+ btn_enviar = gr.Button("Enviar", scale=1, variant="primary")
61
+
62
+ with gr.Row():
63
+ btn_limpiar = gr.Button("🗑️ Limpiar conversación", size="sm")
64
+
65
+ gr.Examples(
66
+ examples=[
67
+ "¿Cuál es la diferencia entre machine learning e inteligencia artificial?",
68
+ "Explícame cómo funciona una red neuronal de forma sencilla",
69
+ "¿Puedes escribir un poema sobre la tecnología?",
70
+ "¿Cuáles son las mejores prácticas en programación Python?",
71
+ ],
72
+ inputs=entrada,
73
+ label="Ejemplos de preguntas",
74
+ )
75
+
76
+ entrada.submit(
77
+ fn=responder,
78
+ inputs=[entrada, chatbot],
79
+ outputs=[chatbot, entrada],
80
+ )
81
+ btn_enviar.click(
82
+ fn=responder,
83
+ inputs=[entrada, chatbot],
84
+ outputs=[chatbot, entrada],
85
+ )
86
+ btn_limpiar.click(
87
+ fn=lambda: ([], ""),
88
+ outputs=[chatbot, entrada],
89
+ )
90
+
91
+ if __name__ == "__main__":
92
+ port = int(os.environ.get("PORT", 5000))
93
+ demo.launch(
94
+ server_name="0.0.0.0",
95
+ server_port=port,
96
+ share=False,
97
+ theme=gr.themes.Soft(primary_hue="blue"),
98
+ )
chat-app/requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ gradio>=4.44.0
2
+ openai>=1.50.0
main.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ def main():
2
+ print("Hello from repl-nix-workspace!")
3
+
4
+
5
+ if __name__ == "__main__":
6
+ main()
pyproject.toml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ [project]
2
+ name = "repl-nix-workspace"
3
+ version = "0.1.0"
4
+ description = "Add your description here"
5
+ requires-python = ">=3.11"
6
+ dependencies = [
7
+ "gradio>=6.9.0",
8
+ "openai>=2.28.0",
9
+ ]
replit.md CHANGED
@@ -2,7 +2,7 @@
2
 
3
  ## Overview
4
 
5
- pnpm workspace monorepo using TypeScript. Each package manages its own dependencies.
6
 
7
  ## Stack
8
 
@@ -15,82 +15,63 @@ pnpm workspace monorepo using TypeScript. Each package manages its own dependenc
15
  - **Validation**: Zod (`zod/v4`), `drizzle-zod`
16
  - **API codegen**: Orval (from OpenAPI spec)
17
  - **Build**: esbuild (CJS bundle)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
  ## Structure
20
 
21
  ```text
22
  artifacts-monorepo/
23
- ├── artifacts/ # Deployable applications
 
 
 
 
24
  │ └── api-server/ # Express API server
25
  ├── lib/ # Shared libraries
26
  │ ├── api-spec/ # OpenAPI spec + Orval codegen config
27
  │ ├── api-client-react/ # Generated React Query hooks
28
  │ ├── api-zod/ # Generated Zod schemas from OpenAPI
29
  │ └── db/ # Drizzle ORM schema + DB connection
30
- ├── scripts/ # Utility scripts (single workspace package)
31
- └── src/ # Individual .ts scripts, run via `pnpm --filter @workspace/scripts run <script>`
32
- ├── pnpm-workspace.yaml # pnpm workspace (artifacts/*, lib/*, lib/integrations/*, scripts)
33
- ├── tsconfig.base.json # Shared TS options (composite, bundler resolution, es2022)
34
- ├── tsconfig.json # Root TS project references
35
- └── package.json # Root package with hoisted devDeps
36
  ```
37
 
38
- ## TypeScript & Composite Projects
39
-
40
- Every package extends `tsconfig.base.json` which sets `composite: true`. The root `tsconfig.json` lists all packages as project references. This means:
41
-
42
- - **Always typecheck from the root** — run `pnpm run typecheck` (which runs `tsc --build --emitDeclarationOnly`). This builds the full dependency graph so that cross-package imports resolve correctly. Running `tsc` inside a single package will fail if its dependencies haven't been built yet.
43
- - **`emitDeclarationOnly`** — we only emit `.d.ts` files during typecheck; actual JS bundling is handled by esbuild/tsx/vite...etc, not `tsc`.
44
- - **Project references** — when package A depends on package B, A's `tsconfig.json` must list B in its `references` array. `tsc --build` uses this to determine build order and skip up-to-date packages.
45
-
46
- ## Root Scripts
47
-
48
- - `pnpm run build` — runs `typecheck` first, then recursively runs `build` in all packages that define it
49
- - `pnpm run typecheck` — runs `tsc --build --emitDeclarationOnly` using project references
50
-
51
  ## Packages
52
 
53
  ### `artifacts/api-server` (`@workspace/api-server`)
54
 
55
- Express 5 API server. Routes live in `src/routes/` and use `@workspace/api-zod` for request and response validation and `@workspace/db` for persistence.
56
-
57
- - Entry: `src/index.ts` — reads `PORT`, starts Express
58
- - App setup: `src/app.ts` — mounts CORS, JSON/urlencoded parsing, routes at `/api`
59
- - Routes: `src/routes/index.ts` mounts sub-routers; `src/routes/health.ts` exposes `GET /health` (full path: `/api/health`)
60
- - Depends on: `@workspace/db`, `@workspace/api-zod`
61
- - `pnpm --filter @workspace/api-server run dev` — run the dev server
62
- - `pnpm --filter @workspace/api-server run build` — production esbuild bundle (`dist/index.cjs`)
63
- - Build bundles an allowlist of deps (express, cors, pg, drizzle-orm, zod, etc.) and externalizes the rest
64
 
65
  ### `lib/db` (`@workspace/db`)
66
 
67
- Database layer using Drizzle ORM with PostgreSQL. Exports a Drizzle client instance and schema models.
68
-
69
- - `src/index.ts` — creates a `Pool` + Drizzle instance, exports schema
70
- - `src/schema/index.ts` — barrel re-export of all models
71
- - `src/schema/<modelname>.ts` — table definitions with `drizzle-zod` insert schemas (no models definitions exist right now)
72
- - `drizzle.config.ts` — Drizzle Kit config (requires `DATABASE_URL`, automatically provided by Replit)
73
- - Exports: `.` (pool, db, schema), `./schema` (schema only)
74
-
75
- Production migrations are handled by Replit when publishing. In development, we just use `pnpm --filter @workspace/db run push`, and we fallback to `pnpm --filter @workspace/db run push-force`.
76
 
77
  ### `lib/api-spec` (`@workspace/api-spec`)
78
 
79
- Owns the OpenAPI 3.1 spec (`openapi.yaml`) and the Orval config (`orval.config.ts`). Running codegen produces output into two sibling packages:
80
-
81
- 1. `lib/api-client-react/src/generated/` — React Query hooks + fetch client
82
- 2. `lib/api-zod/src/generated/` — Zod schemas
83
-
84
- Run codegen: `pnpm --filter @workspace/api-spec run codegen`
85
-
86
- ### `lib/api-zod` (`@workspace/api-zod`)
87
-
88
- Generated Zod schemas from the OpenAPI spec (e.g. `HealthCheckResponse`). Used by `api-server` for response validation.
89
-
90
- ### `lib/api-client-react` (`@workspace/api-client-react`)
91
-
92
- Generated React Query hooks and fetch client from the OpenAPI spec (e.g. `useHealthCheck`, `healthCheck`).
93
-
94
- ### `scripts` (`@workspace/scripts`)
95
-
96
- Utility scripts package. Each script is a `.ts` file in `src/` with a corresponding npm script in `package.json`. Run scripts via `pnpm --filter @workspace/scripts run <script>`. Scripts can import any workspace package (e.g., `@workspace/db`) by adding it as a dependency in `scripts/package.json`.
 
2
 
3
  ## Overview
4
 
5
+ pnpm workspace monorepo usando TypeScript para el backend + app Python/Gradio para el chatbot de IA.
6
 
7
  ## Stack
8
 
 
15
  - **Validation**: Zod (`zod/v4`), `drizzle-zod`
16
  - **API codegen**: Orval (from OpenAPI spec)
17
  - **Build**: esbuild (CJS bundle)
18
+ - **Python version**: 3.11
19
+ - **Chat AI**: Gradio + OpenAI (vía Replit AI Integrations)
20
+
21
+ ## Aplicación Principal: Chat IA
22
+
23
+ La aplicación de chat está en `chat-app/`:
24
+
25
+ - `chat-app/app.py` — App Gradio con chat conversacional estilo ChatGPT/Gemini
26
+ - `chat-app/requirements.txt` — Dependencias Python (gradio, openai)
27
+ - `chat-app/README.md` — Configuración para Hugging Face Spaces
28
+
29
+ ### Ejecutar localmente
30
+
31
+ ```bash
32
+ PORT=5000 python chat-app/app.py
33
+ ```
34
+
35
+ ### Publicar en Hugging Face Spaces
36
+
37
+ 1. Crea una cuenta en [huggingface.co](https://huggingface.co)
38
+ 2. Ve a Settings → Access Tokens → New token (con permiso `write`)
39
+ 3. Crea un nuevo Space en Hugging Face (tipo: Gradio)
40
+ 4. Sube los archivos de `chat-app/` al Space
41
+ 5. Agrega tu API key en los Secrets del Space:
42
+ - `AI_INTEGRATIONS_OPENAI_BASE_URL`
43
+ - `AI_INTEGRATIONS_OPENAI_API_KEY`
44
+ - O bien, usa `OPENAI_API_KEY` con tu propia clave de OpenAI
45
 
46
  ## Structure
47
 
48
  ```text
49
  artifacts-monorepo/
50
+ ├── chat-app/ # App Python/Gradio - Chatbot de IA
51
+ │ ├── app.py # Aplicación principal Gradio
52
+ │ ├── requirements.txt # Dependencias Python
53
+ │ └── README.md # Configuración Hugging Face Spaces
54
+ ├── artifacts/ # Deployable applications (Node.js)
55
  │ └── api-server/ # Express API server
56
  ├── lib/ # Shared libraries
57
  │ ├── api-spec/ # OpenAPI spec + Orval codegen config
58
  │ ├── api-client-react/ # Generated React Query hooks
59
  │ ├── api-zod/ # Generated Zod schemas from OpenAPI
60
  │ └── db/ # Drizzle ORM schema + DB connection
61
+ ├── scripts/ # Utility scripts
62
+ └── package.json # Root package
 
 
 
 
63
  ```
64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  ## Packages
66
 
67
  ### `artifacts/api-server` (`@workspace/api-server`)
68
 
69
+ Express 5 API server (Node.js backend).
 
 
 
 
 
 
 
 
70
 
71
  ### `lib/db` (`@workspace/db`)
72
 
73
+ Database layer using Drizzle ORM with PostgreSQL.
 
 
 
 
 
 
 
 
74
 
75
  ### `lib/api-spec` (`@workspace/api-spec`)
76
 
77
+ OpenAPI 3.1 spec and Orval codegen config.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
uv.lock ADDED
The diff for this file is too large to render. See raw diff