Spaces:
Sleeping
Sleeping
Add OpenAI compatibility fallback
Browse files
README.md
CHANGED
|
@@ -25,6 +25,7 @@ Use a free Python container host and keep the service public:
|
|
| 25 |
3. Set `MINDVIS_REPO=/app/mindVisualizer`.
|
| 26 |
4. Set `CORS_ORIGINS=https://pixedar.github.io,http://localhost:3000`.
|
| 27 |
5. In the GitHub Pages build, set `NEXT_PUBLIC_MINDVIS_API_URL=https://your-backend-url`.
|
|
|
|
| 28 |
|
| 29 |
Current Space:
|
| 30 |
|
|
|
|
| 25 |
3. Set `MINDVIS_REPO=/app/mindVisualizer`.
|
| 26 |
4. Set `CORS_ORIGINS=https://pixedar.github.io,http://localhost:3000`.
|
| 27 |
5. In the GitHub Pages build, set `NEXT_PUBLIC_MINDVIS_API_URL=https://your-backend-url`.
|
| 28 |
+
6. Optional: set `OPENAI_API_KEY` as a Space secret and `OPENAI_MODEL` as a Space variable.
|
| 29 |
|
| 30 |
Current Space:
|
| 31 |
|
app.py
CHANGED
|
@@ -129,9 +129,7 @@ def explain(req: ExplainRequest):
|
|
| 129 |
|
| 130 |
text = ""
|
| 131 |
if req.callLlm and os.environ.get("OPENAI_API_KEY"):
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
text = ROIFlowLLM(debug=False).interpret_roi_flow(context)
|
| 135 |
|
| 136 |
if not text:
|
| 137 |
analysis = analyzer.analyze_flow_pattern(delta)
|
|
@@ -166,3 +164,46 @@ def denormalized(points: np.ndarray, amin: np.ndarray, span: np.ndarray) -> np.n
|
|
| 166 |
|
| 167 |
def normalized(points: np.ndarray, amin: np.ndarray, span: np.ndarray) -> np.ndarray:
|
| 168 |
return (points.astype(np.float32) - amin[None, :]) / span[None, :]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 129 |
|
| 130 |
text = ""
|
| 131 |
if req.callLlm and os.environ.get("OPENAI_API_KEY"):
|
| 132 |
+
text = call_openai_interpreter(context)
|
|
|
|
|
|
|
| 133 |
|
| 134 |
if not text:
|
| 135 |
analysis = analyzer.analyze_flow_pattern(delta)
|
|
|
|
| 164 |
|
| 165 |
def normalized(points: np.ndarray, amin: np.ndarray, span: np.ndarray) -> np.ndarray:
|
| 166 |
return (points.astype(np.float32) - amin[None, :]) / span[None, :]
|
| 167 |
+
|
| 168 |
+
|
| 169 |
+
def call_openai_interpreter(context: str) -> str:
|
| 170 |
+
from openai import OpenAI
|
| 171 |
+
|
| 172 |
+
model = os.environ.get("OPENAI_MODEL", "gpt-4o-mini")
|
| 173 |
+
instructions = (
|
| 174 |
+
"You are a neuroscientist interpreting brain state dynamics from a "
|
| 175 |
+
"manifold flow simulation. The user traced a path through a learned "
|
| 176 |
+
"neural manifold. You are given how each ROI's contribution changed "
|
| 177 |
+
"along this path.\n\n"
|
| 178 |
+
"The delta values do not mean simple activation. They measure how each "
|
| 179 |
+
"ROI's contribution to the overall brain state shifted. Positive means "
|
| 180 |
+
"the region became a stronger contributor; negative means it became a "
|
| 181 |
+
"weaker contributor.\n\n"
|
| 182 |
+
"Do not list every ROI. Synthesize the spatial pattern, directionality, "
|
| 183 |
+
"and network shift into one coherent interpretation. Keep the response "
|
| 184 |
+
"to 2 concise paragraphs."
|
| 185 |
+
)
|
| 186 |
+
|
| 187 |
+
try:
|
| 188 |
+
client = OpenAI(timeout=60.0)
|
| 189 |
+
if hasattr(client, "responses"):
|
| 190 |
+
response = client.responses.create(
|
| 191 |
+
model=model,
|
| 192 |
+
instructions=instructions,
|
| 193 |
+
input=context,
|
| 194 |
+
max_output_tokens=900,
|
| 195 |
+
)
|
| 196 |
+
return (response.output_text or "").strip()
|
| 197 |
+
|
| 198 |
+
response = client.chat.completions.create(
|
| 199 |
+
model=model,
|
| 200 |
+
messages=[
|
| 201 |
+
{"role": "system", "content": instructions},
|
| 202 |
+
{"role": "user", "content": context},
|
| 203 |
+
],
|
| 204 |
+
max_tokens=900,
|
| 205 |
+
temperature=0.3,
|
| 206 |
+
)
|
| 207 |
+
return (response.choices[0].message.content or "").strip()
|
| 208 |
+
except Exception as exc:
|
| 209 |
+
return f"[GPT ERROR] {exc}"
|