aigencydev commited on
Commit
15d3960
Β·
verified Β·
1 Parent(s): 48933e4

Fix: Python 3.11 pin (audioop), correct AIGENCY API protocol, session chat_id, image flow

Browse files
Files changed (2) hide show
  1. README.md +1 -0
  2. app.py +73 -63
README.md CHANGED
@@ -5,6 +5,7 @@ colorFrom: indigo
5
  colorTo: pink
6
  sdk: gradio
7
  sdk_version: 4.44.0
 
8
  app_file: app.py
9
  pinned: true
10
  license: other
 
5
  colorTo: pink
6
  sdk: gradio
7
  sdk_version: 4.44.0
8
+ python_version: 3.11
9
  app_file: app.py
10
  pinned: true
11
  license: other
app.py CHANGED
@@ -3,9 +3,10 @@
3
  This Gradio app proxies user prompts to the eCloud production AIGENCY V4 API.
4
 
5
  Setup (when deploying to HuggingFace Spaces):
6
- 1. Add `AIGENCY_API_TOKEN` as a Space secret (Space settings β†’ Secrets).
7
- 2. Optionally add `AIGENCY_API_BASE` (default https://aigency.dev/api/v2)
8
- and `AIGENCY_ASSISTANT` (default alparslan-v4).
 
9
 
10
  The Space supports text and image-with-text input (one image per request,
11
  ≀ 30 MB, image/* MIME).
@@ -14,10 +15,6 @@ from __future__ import annotations
14
 
15
  import io
16
  import os
17
- import time
18
- import json
19
- import base64
20
- import mimetypes
21
 
22
  import gradio as gr
23
  import requests
@@ -26,13 +23,24 @@ from PIL import Image
26
  # ── Config ─────────────────────────────────────────────────────────
27
  API_BASE = os.environ.get("AIGENCY_API_BASE", "https://aigency.dev/api/v2")
28
  API_TOKEN = os.environ.get("AIGENCY_API_TOKEN", "") # set via Space secret
29
- ASSISTANT = os.environ.get("AIGENCY_ASSISTANT", "alparslan-v4")
 
30
  TIMEOUT = 60 # seconds
31
  DEMO_BANNER = (
32
  "AIGENCY V4 β€” sovereign, multimodal, Turkish-first AI Β· "
33
  "128B parameters Β· 278K context Β· KVKK-resident"
34
  )
35
 
 
 
 
 
 
 
 
 
 
 
36
 
37
  # ── Bench numbers (static, mirrored from the model card) ───────────
38
  BENCH = [
@@ -61,86 +69,84 @@ BENCH = [
61
  ]
62
 
63
 
64
- def headers():
65
- return {"Authorization": f"Bearer {API_TOKEN}"}
66
-
67
-
68
- PLACEHOLDER_MSG = (
69
- "πŸ”’ The interactive chat is being activated.\n\n"
70
- "While the demo is finalised, you can already:\n"
71
- " Β· Browse the **Benchmark Leaderboard** tab β€” 22 benchmarks, 13,344 calls\n"
72
- " Β· Read the [model card](https://huggingface.co/aigencydev/AIGENCY-V4)\n"
73
- " Β· Inspect the [evaluation dataset](https://huggingface.co/datasets/aigencydev/aigency-v4-evaluation)\n"
74
- " Β· Read the whitepaper (32 pages, EN/TR) on [GitHub](https://github.com/ecloud-bh/aigency-v4-whitepaper)\n\n"
75
- "For production access: **info@e-cloud.web.tr Β· ai@aigency.dev**"
76
- )
77
-
78
-
79
- # ── Two-step API protocol ─────────────────────────────────────────
80
- def new_chat() -> str:
81
- r = requests.post(
82
- f"{API_BASE}/chat/newChat",
83
- headers=headers(),
84
- json={"assistant_slug": ASSISTANT},
85
- timeout=TIMEOUT,
86
- )
87
  r.raise_for_status()
88
- return r.json()["chat_id"]
 
89
 
90
 
91
- def send_text(chat_id: str, prompt: str) -> str:
92
- r = requests.post(
93
- f"{API_BASE}/chat/sendMessage",
94
- headers=headers(),
95
- json={"chat_id": chat_id, "message": prompt},
96
- timeout=TIMEOUT,
97
- )
98
  r.raise_for_status()
99
  return r.json().get("message", "")
100
 
101
 
102
- def send_with_image(chat_id: str, prompt: str, image: Image.Image) -> str:
103
  buf = io.BytesIO()
104
  image.save(buf, format="PNG")
105
  buf.seek(0)
 
106
  files = {
107
- "attachements": ("image.png", buf, "image/png"), # canonical typo
 
 
108
  }
109
- data = {"chat_id": chat_id, "message": prompt}
110
- r = requests.post(
111
- f"{API_BASE}/chat/sendMessage",
112
- headers=headers(),
113
- files=files,
114
- data=data,
115
- timeout=TIMEOUT,
116
- )
117
  r.raise_for_status()
118
  return r.json().get("message", "")
119
 
120
 
121
- # ── Gradio handlers ────────────────────────────────────────────────
122
- def chat(prompt, image, history):
123
  history = history or []
 
 
124
  if not prompt.strip():
125
- return history, ""
 
126
  if not API_TOKEN:
127
  history.append((prompt, PLACEHOLDER_MSG))
128
- return history, ""
 
129
  try:
130
- chat_id = new_chat()
131
- if image is not None:
132
- answer = send_with_image(chat_id, prompt, image)
 
 
 
 
 
 
 
133
  else:
134
- answer = send_text(chat_id, prompt)
 
 
 
 
135
  except Exception as e:
136
  answer = f"Error: {e}"
 
137
  history.append((prompt, answer))
138
- return history, ""
 
 
 
 
139
 
140
 
141
  def make_leaderboard():
142
- rows = [(name, f"{val:.2%}", note) for name, val, note in BENCH]
143
- return rows
144
 
145
 
146
  # ── UI ─────────────────────────────────────────────────────────────
@@ -168,6 +174,7 @@ Responses are served live by the production API.
168
 
169
  with gr.Blocks(title="AIGENCY V4 Demo", theme=gr.themes.Soft()) as demo:
170
  gr.Markdown(f"# AIGENCY V4\n\n*{DEMO_BANNER}*")
 
171
 
172
  with gr.Tab("Chat"):
173
  with gr.Row():
@@ -185,9 +192,12 @@ with gr.Blocks(title="AIGENCY V4 Demo", theme=gr.themes.Soft()) as demo:
185
  )
186
  with gr.Column(scale=1):
187
  img = gr.Image(label="Optional image", type="pil", height=200)
188
- send = gr.Button("Send", variant="primary")
189
- send.click(chat, [msg, img, chatbot], [chatbot, msg])
190
- msg.submit(chat, [msg, img, chatbot], [chatbot, msg])
 
 
 
191
 
192
  with gr.Tab("Benchmark Leaderboard"):
193
  gr.Markdown(
 
3
  This Gradio app proxies user prompts to the eCloud production AIGENCY V4 API.
4
 
5
  Setup (when deploying to HuggingFace Spaces):
6
+ 1. Add `AIGENCY_API_TOKEN` as a Space secret (Space settings β†’ Variables and secrets).
7
+ 2. Optionally add `AIGENCY_API_BASE` (default https://aigency.dev/api/v2)
8
+ `AIGENCY_ASSISTANT_ID` (default 277)
9
+ `AIGENCY_ASSISTANT_SLUG` (default alparslan-v4).
10
 
11
  The Space supports text and image-with-text input (one image per request,
12
  ≀ 30 MB, image/* MIME).
 
15
 
16
  import io
17
  import os
 
 
 
 
18
 
19
  import gradio as gr
20
  import requests
 
23
  # ── Config ─────────────────────────────────────────────────────────
24
  API_BASE = os.environ.get("AIGENCY_API_BASE", "https://aigency.dev/api/v2")
25
  API_TOKEN = os.environ.get("AIGENCY_API_TOKEN", "") # set via Space secret
26
+ ASSISTANT_ID = int(os.environ.get("AIGENCY_ASSISTANT_ID", "277"))
27
+ ASSISTANT_SLUG = os.environ.get("AIGENCY_ASSISTANT_SLUG", "alparslan-v4")
28
  TIMEOUT = 60 # seconds
29
  DEMO_BANNER = (
30
  "AIGENCY V4 β€” sovereign, multimodal, Turkish-first AI Β· "
31
  "128B parameters Β· 278K context Β· KVKK-resident"
32
  )
33
 
34
+ PLACEHOLDER_MSG = (
35
+ "πŸ”’ The interactive chat is being activated.\n\n"
36
+ "While the demo is finalised, you can already:\n"
37
+ " Β· Browse the **Benchmark Leaderboard** tab β€” 22 benchmarks, 13,344 calls\n"
38
+ " Β· Read the [model card](https://huggingface.co/aigencydev/AIGENCY-V4)\n"
39
+ " Β· Inspect the [evaluation dataset](https://huggingface.co/datasets/aigencydev/aigency-v4-evaluation)\n"
40
+ " Β· Read the whitepaper (32 pages, EN/TR) on [GitHub](https://github.com/ecloud-bh/aigency-v4-whitepaper)\n\n"
41
+ "For production access: **info@e-cloud.web.tr Β· ai@aigency.dev**"
42
+ )
43
+
44
 
45
  # ── Bench numbers (static, mirrored from the model card) ───────────
46
  BENCH = [
 
69
  ]
70
 
71
 
72
+ # ── Two-step API protocol (token in URL path) ─────────────────────
73
+ def new_chat(message: str) -> tuple[str, str]:
74
+ """Open a chat. Returns (chat_id, first_response)."""
75
+ url = f"{API_BASE}/newChat/{ASSISTANT_ID}/{API_TOKEN}"
76
+ r = requests.post(url, json={"message": message}, timeout=TIMEOUT)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  r.raise_for_status()
78
+ body = r.json()
79
+ return body.get("chat_id", ""), body.get("message", "")
80
 
81
 
82
+ def send_message(chat_id: str, message: str) -> str:
83
+ url = f"{API_BASE}/sendMessage/{API_TOKEN}"
84
+ files = {
85
+ "chat_id": (None, str(chat_id)),
86
+ "message": (None, message),
87
+ }
88
+ r = requests.post(url, files=files, timeout=TIMEOUT)
89
  r.raise_for_status()
90
  return r.json().get("message", "")
91
 
92
 
93
+ def send_with_image(chat_id: str, message: str, image: Image.Image) -> str:
94
  buf = io.BytesIO()
95
  image.save(buf, format="PNG")
96
  buf.seek(0)
97
+ url = f"{API_BASE}/sendMessage/{API_TOKEN}"
98
  files = {
99
+ "chat_id": (None, str(chat_id)),
100
+ "message": (None, message),
101
+ "attachements": ("image.png", buf.getvalue(), "image/png"), # canonical typo
102
  }
103
+ r = requests.post(url, files=files, timeout=TIMEOUT)
 
 
 
 
 
 
 
104
  r.raise_for_status()
105
  return r.json().get("message", "")
106
 
107
 
108
+ # ── Gradio handler with session-scoped chat_id ─────────────────────
109
+ def chat(prompt, image, history, chat_id_state):
110
  history = history or []
111
+ chat_id = chat_id_state or ""
112
+
113
  if not prompt.strip():
114
+ return history, "", chat_id
115
+
116
  if not API_TOKEN:
117
  history.append((prompt, PLACEHOLDER_MSG))
118
+ return history, "", chat_id
119
+
120
  try:
121
+ if not chat_id:
122
+ # Open a new conversation; the seed message can be the user's first prompt
123
+ if image is None:
124
+ cid, answer = new_chat(prompt)
125
+ chat_id = cid
126
+ else:
127
+ # newChat doesn't accept attachments β€” open with a brief seed, then send image
128
+ cid, _ = new_chat("Bir gΓΆrsel inceleyeceksin.")
129
+ chat_id = cid
130
+ answer = send_with_image(chat_id, prompt, image)
131
  else:
132
+ # Continue existing conversation
133
+ if image is None:
134
+ answer = send_message(chat_id, prompt)
135
+ else:
136
+ answer = send_with_image(chat_id, prompt, image)
137
  except Exception as e:
138
  answer = f"Error: {e}"
139
+
140
  history.append((prompt, answer))
141
+ return history, "", chat_id
142
+
143
+
144
+ def reset_session():
145
+ return [], "", ""
146
 
147
 
148
  def make_leaderboard():
149
+ return [(name, f"{val:.2%}", note) for name, val, note in BENCH]
 
150
 
151
 
152
  # ── UI ─────────────────────────────────────────────────────────────
 
174
 
175
  with gr.Blocks(title="AIGENCY V4 Demo", theme=gr.themes.Soft()) as demo:
176
  gr.Markdown(f"# AIGENCY V4\n\n*{DEMO_BANNER}*")
177
+ chat_id_state = gr.State("")
178
 
179
  with gr.Tab("Chat"):
180
  with gr.Row():
 
192
  )
193
  with gr.Column(scale=1):
194
  img = gr.Image(label="Optional image", type="pil", height=200)
195
+ with gr.Row():
196
+ send = gr.Button("Send", variant="primary")
197
+ clear = gr.Button("New conversation")
198
+ send.click(chat, [msg, img, chatbot, chat_id_state], [chatbot, msg, chat_id_state])
199
+ msg.submit(chat, [msg, img, chatbot, chat_id_state], [chatbot, msg, chat_id_state])
200
+ clear.click(reset_session, [], [chatbot, msg, chat_id_state])
201
 
202
  with gr.Tab("Benchmark Leaderboard"):
203
  gr.Markdown(