PeacebinfLow commited on
Commit
d102c3d
·
verified ·
1 Parent(s): c6771de

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +145 -229
app.py CHANGED
@@ -1,275 +1,191 @@
1
- import json
2
  import os
3
  import gradio as gr
 
4
 
5
  from src.dataset_client import DatasetAPIClient
6
- from src.state_machine import StateMachine, State
7
- from src.command_parser import CommandParser, ParsedCommand
8
  from src.card_generator import CardGenerator
9
- from src.yaml_validator import validate_card_yaml
10
 
11
 
12
- # =========================
13
- # Config
14
- # =========================
15
-
16
- # Optional Space variable (recommended):
17
- # MIN DSEYE_DATASET = PeacebinfLow/mindseye-lab-ledger
18
  DATASET_ID = os.getenv("MINDSEYE_DATASET", "PeacebinfLow/mindseye-lab-ledger").strip()
19
-
20
- # Optional: config name if you ever introduce configs
21
  DATASET_CONFIG = os.getenv("MINDSEYE_CONFIG", "default").strip()
22
 
23
- # Prevent giant history explosions
24
- MAX_HISTORY_JSON_CHARS = int(os.getenv("MINDSEYE_MAX_HISTORY_JSON_CHARS", "12000"))
25
-
26
-
27
- # =========================
28
- # Runtime components
29
- # =========================
30
-
31
- client = DatasetAPIClient(dataset=DATASET_ID)
32
  sm = StateMachine()
 
33
  parser = CommandParser()
34
- generator = CardGenerator(template_dir="templates")
35
-
36
-
37
- # =========================
38
- # Helpers
39
- # =========================
40
-
41
- def _bounded_json(obj, max_chars: int = 12000) -> str:
42
- """Pretty JSON but truncated."""
43
- try:
44
- s = json.dumps(obj, indent=2, ensure_ascii=False)
45
- except Exception:
46
- s = json.dumps({"error": "Could not serialize JSON"}, indent=2)
47
- if len(s) > max_chars:
48
- return s[:max_chars] + "\n...(truncated)"
49
- return s
50
-
51
 
52
- def export_last_card(card_yaml: str):
53
- """Write latest YAML into artifacts and return filepath for Gradio File component."""
54
- os.makedirs("artifacts", exist_ok=True)
55
- path = os.path.join("artifacts", "mindseye_card.yaml")
56
- with open(path, "w", encoding="utf-8") as f:
57
- f.write(card_yaml or "")
58
- return path
59
 
 
 
 
 
 
 
 
 
60
 
61
- HELP_TEXT = """### Commands
62
 
63
- **Core**
64
- - `MODE <STATE>`: Switch active state
65
- - `RESET`: Return to CORE_OS and clear context
66
- - `STATE`: Show current state
67
- - `HELP`: Show help text
68
 
69
- **Dataset**
70
- - `SPLITS`: List dataset splits
71
- - `FIRST <split> <limit>`: Get first rows preview
72
- - `ROWS <split> <offset> <length>`: Get rows window
73
- - `SEARCH <split> <query>`: Full-text search
74
- - `FILTER <split> <where>`: SQL-like filter
75
-
76
- **Cards**
77
- - `CARD <TYPE>`: Force card type (CONCEPT/FLOW/SPEC/TEST/BUILD)
78
- - `EXPORT`: Export latest YAML card as a file
79
-
80
- **Examples**
81
- - `MODE LEDGER_CORE`
82
- - `SEARCH train WORKFLOW_`
83
- - `FILTER train event_type = 'WORKFLOW_COMPLETED'`
84
- - `ROWS train 0 25`
85
- """
86
-
87
-
88
- def process_command(command: str, history_md: str, forced_state: str, forced_card_type: str):
89
- command = (command or "").strip()
90
- history_md = history_md or ""
91
-
92
- # Quick state dropdown override (optional)
93
- if forced_state and forced_state in [s.value for s in State]:
94
- # set state without adding noisy history unless it truly changes
95
- if forced_state != sm.current_state.value:
96
- sm.set_state(forced_state)
97
-
98
- parsed: ParsedCommand = parser.parse(command)
99
 
 
100
  dataset_result = None
101
 
102
- # Core commands
103
- if parsed.kind == "HELP":
104
- # Display help but still return a card
105
- dataset_result = {"help": HELP_TEXT}
106
-
107
- elif parsed.kind == "STATE":
108
- dataset_result = {"state": sm.current_state.value, "history_depth": len(sm.history)}
109
-
110
- elif parsed.kind == "MODE":
111
- sm.transition(f"MODE {parsed.arg1 or ''}")
112
-
113
- elif parsed.kind == "RESET":
114
- sm.transition("RESET")
115
-
116
- elif parsed.kind == "CARD":
117
- # store override
118
- sm.context["forced_card_type"] = (parsed.arg1 or "").upper()
119
-
120
- # Dataset operations
121
- try:
122
- if parsed.kind == "SPLITS":
123
- dataset_result = {"splits": client.list_splits()}
124
-
125
- elif parsed.kind == "FIRST":
126
- split = parsed.arg1 or "train"
127
- limit = int(parsed.arg2 or 100)
128
- dataset_result = client.get_first_rows(split=split, limit=limit, config=DATASET_CONFIG)
129
-
130
- elif parsed.kind == "ROWS":
131
- split = parsed.arg1 or "train"
132
- offset = int(parsed.arg2 or 0)
133
- length = int(parsed.arg3 or 25)
134
- dataset_result = client.get_rows(split=split, offset=offset, length=length, config=DATASET_CONFIG)
135
-
136
- elif parsed.kind == "SEARCH":
137
- split = parsed.arg1 or "train"
138
- query = parsed.rest or ""
139
- dataset_result = client.search_dataset(query=query, split=split, config=DATASET_CONFIG)
140
-
141
- elif parsed.kind == "FILTER":
142
- split = parsed.arg1 or "train"
143
- where = parsed.rest or ""
144
- dataset_result = client.filter_dataset(where=where, split=split, config=DATASET_CONFIG)
145
-
146
- except Exception as e:
147
- dataset_result = {
148
- "error": str(e),
149
- "dataset": DATASET_ID,
150
- "config": DATASET_CONFIG,
151
- "parsed": parsed.to_dict(),
152
- "state": sm.current_state.value,
153
- }
154
-
155
- # Card type resolution
156
- if forced_card_type and forced_card_type != "AUTO":
157
- card_type = forced_card_type
158
- else:
159
- card_type = sm.get_output_type()
160
-
161
- # Hard override via CARD command
162
- if sm.context.get("forced_card_type"):
163
- card_type = sm.context["forced_card_type"]
164
-
165
- # Generate YAML card
166
- card_yaml = generator.generate(
167
- state=sm.current_state.value,
168
- card_type=card_type,
169
- dataset_result=dataset_result,
170
- lock_on=True,
171
- version="1.0.0",
172
- card_id="HUGGINGFACE_SPACE_RUNTIME",
173
- )
174
-
175
- # Validate YAML shape (non-fatal; annotate)
176
- valid, errors = validate_card_yaml(card_yaml)
177
- if not valid:
178
- card_yaml += "\n\n# VALIDATION_ERRORS:\n"
179
- for err in errors:
180
- card_yaml += f"# - {err}\n"
181
-
182
- # History
183
- new_history = history_md
184
- if command:
185
- new_history += f"\n\n> `{command}`\n\n```yaml\n{card_yaml}\n```\n"
186
- if dataset_result is not None:
187
- new_history += (
188
- "\n<details><summary>Raw JSON</summary>\n\n```json\n"
189
- + _bounded_json(dataset_result, MAX_HISTORY_JSON_CHARS)
190
- + "\n```\n</details>\n"
191
- )
192
 
193
- # Return updated UI state dropdown value too (sync)
194
- return card_yaml, dataset_result, new_history, sm.current_state.value
 
 
 
 
 
 
 
 
195
 
 
 
196
 
197
- # =========================
198
- # UI
199
- # =========================
200
 
201
- with gr.Blocks(theme=gr.themes.Monochrome()) as demo:
202
- gr.Markdown("# 🧠 MindsEye Lab — Stateful OS Runtime")
203
  gr.Markdown(
 
 
204
  f"**Dataset:** `{DATASET_ID}` • **Config:** `{DATASET_CONFIG}`"
205
  )
206
 
207
  with gr.Row():
208
- with gr.Column(scale=2):
209
  command_input = gr.Textbox(
210
  label="Command",
211
- placeholder="MODE LEDGER_CORE | SEARCH train WORKFLOW_ | FILTER train event_type = 'WORKFLOW_COMPLETED'",
212
  lines=1,
213
  )
214
- with gr.Row():
215
- submit_btn = gr.Button("Execute", variant="primary")
216
- help_btn = gr.Button("HELP")
217
- reset_btn = gr.Button("RESET")
218
- export_btn = gr.Button("EXPORT")
219
-
220
  with gr.Column(scale=1):
221
- state_selector = gr.Dropdown(
222
- choices=[s.value for s in State],
223
- label="Quick State Switch",
224
- value=sm.current_state.value,
225
- )
226
- card_type_selector = gr.Dropdown(
227
- choices=["AUTO", "CONCEPT", "FLOW", "SPEC", "TEST", "BUILD"],
228
- label="Card Type",
229
- value="AUTO",
230
- )
231
 
232
- card_output = gr.Code(label="YAML Card Response", language="yaml", lines=28)
233
 
234
  with gr.Accordion("Dataset Results (Raw JSON)", open=False):
235
  dataset_output = gr.JSON(label="Query Results")
236
 
237
- history_output = gr.Markdown(label="Session History", value="")
238
-
239
- export_file = gr.File(label="Exported YAML")
240
 
241
- def _help_click():
242
- return process_command("HELP", history_output.value or "", state_selector.value, card_type_selector.value)
243
-
244
- def _reset_click():
245
- return process_command("RESET", history_output.value or "", state_selector.value, card_type_selector.value)
246
-
247
- def _export_click(card_yaml: str):
248
- return export_last_card(card_yaml)
249
-
250
- # Buttons
251
  submit_btn.click(
252
  fn=process_command,
253
- inputs=[command_input, history_output, state_selector, card_type_selector],
254
- outputs=[card_output, dataset_output, history_output, state_selector],
255
- )
256
-
257
- help_btn.click(
258
- fn=lambda: process_command("HELP", history_output.value or "", state_selector.value, card_type_selector.value),
259
- inputs=[],
260
- outputs=[card_output, dataset_output, history_output, state_selector],
261
- )
262
-
263
- reset_btn.click(
264
- fn=lambda: process_command("RESET", history_output.value or "", state_selector.value, card_type_selector.value),
265
- inputs=[],
266
- outputs=[card_output, dataset_output, history_output, state_selector],
267
  )
268
 
269
- export_btn.click(
270
- fn=_export_click,
271
- inputs=[card_output],
272
- outputs=[export_file],
273
  )
274
 
275
- demo.launch()
 
 
 
1
  import os
2
  import gradio as gr
3
+ from typing import List, Tuple, Optional
4
 
5
  from src.dataset_client import DatasetAPIClient
6
+ from src.state_machine import StateMachine, State, CardType
 
7
  from src.card_generator import CardGenerator
8
+ from src.command_parser import CommandParser
9
 
10
 
 
 
 
 
 
 
11
  DATASET_ID = os.getenv("MINDSEYE_DATASET", "PeacebinfLow/mindseye-lab-ledger").strip()
 
 
12
  DATASET_CONFIG = os.getenv("MINDSEYE_CONFIG", "default").strip()
13
 
14
+ client = DatasetAPIClient(dataset=DATASET_ID, config=DATASET_CONFIG)
 
 
 
 
 
 
 
 
15
  sm = StateMachine()
16
+ gen = CardGenerator()
17
  parser = CommandParser()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
 
 
 
 
 
 
 
19
 
20
+ HELP_TEXT = (
21
+ "Commands:\n"
22
+ "- MODE <STATE> | CARD <TYPE> | RUN <query> | TEST | LEDGER | RESET | STATE | HELP\n\n"
23
+ "Dataset ops:\n"
24
+ "- RUN <query> -> search train\n"
25
+ "- TEST -> first rows\n"
26
+ "- LEDGER -> rows page\n"
27
+ )
28
 
 
29
 
30
+ def process_command(command: str, history: List[Tuple[str, str]]):
31
+ history = history or []
32
+ parsed = parser.parse(command)
 
 
33
 
34
+ if not parsed["valid"]:
35
+ card = gen.generate_error_card(sm.current_state, parsed.get("error", "Invalid command"))
36
+ history.append((command, card))
37
+ return card, None, history
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
 
39
+ result = sm.transition(command)
40
  dataset_result = None
41
 
42
+ cmd = parsed["command"]
43
+ arg = parsed.get("argument") or ""
44
+
45
+ # Handle HELP/STATE explicitly
46
+ if cmd == "HELP":
47
+ card = gen.generate(
48
+ state=sm.current_state,
49
+ card_type=CardType.CONCEPT,
50
+ title="Help",
51
+ description="Available commands and usage.",
52
+ content={"HELP": HELP_TEXT, "STATE": sm.current_state.value},
53
+ )
54
+ history.append((command, card))
55
+ return card, {"help": HELP_TEXT}, history
56
+
57
+ if cmd == "STATE":
58
+ card = gen.generate(
59
+ state=sm.current_state,
60
+ card_type=CardType.SPEC,
61
+ title="Runtime State",
62
+ description="Current runtime state snapshot.",
63
+ content={"STATE": sm.current_state.value, "HISTORY_DEPTH": len(sm.history)},
64
+ )
65
+ history.append((command, card))
66
+ return card, {"state": sm.current_state.value}, history
67
+
68
+ # Dataset query commands
69
+ if cmd == "RUN":
70
+ if arg:
71
+ dataset_result = client.search_dataset(query=arg, split="train")
72
+ else:
73
+ dataset_result = {"error": "RUN requires a query string", "rows": []}
74
+
75
+ elif cmd == "TEST":
76
+ dataset_result = client.get_first_rows(split="train", limit=10)
77
+
78
+ elif cmd == "LEDGER":
79
+ dataset_result = client.get_rows(split="train", offset=0, length=25)
80
+
81
+ # Card type selection
82
+ card_type = sm.get_output_card_type()
83
+
84
+ # Build card content depending on action
85
+ if result["action"] == "transition":
86
+ allowed = [ct.value for ct in sm.STATE_CARD_MAPPING[sm.current_state]]
87
+ card = gen.generate(
88
+ state=sm.current_state,
89
+ card_type=card_type,
90
+ title=f"{sm.current_state.value} Module",
91
+ description=f"Entered {sm.current_state.value}",
92
+ content={"STATE_INFO": sm.current_state.value, "AVAILABLE_CARDS": allowed},
93
+ dataset_result=dataset_result,
94
+ context_links=[f"{sm.current_state.value}.overview"],
95
+ next_actions=["RUN <query>", "TEST", "LEDGER", "RESET"],
96
+ )
97
+
98
+ elif result["action"] == "query":
99
+ rows = dataset_result.get("rows", []) if isinstance(dataset_result, dict) else []
100
+ card = gen.generate(
101
+ state=sm.current_state,
102
+ card_type=CardType.SPEC,
103
+ title="Dataset Query Results",
104
+ description=f"Query executed: {command}",
105
+ content={"QUERY": command, "RESULTS_COUNT": len(rows), "SAMPLE": rows[:3]},
106
+ dataset_result=dataset_result,
107
+ context_links=["LEDGER_CORE.query_engine"],
108
+ next_actions=["RUN <new-query>", "RESET"],
109
+ )
110
+
111
+ elif result["action"] == "filter":
112
+ card = gen.generate(
113
+ state=sm.current_state,
114
+ card_type=CardType.SPEC,
115
+ title="Card Filter Set",
116
+ description=f"Forced card type: {result.get('card_type')}",
117
+ content={"FILTER": result},
118
+ next_actions=["RUN <query>", "MODE <state>", "RESET"],
119
+ )
120
+
121
+ elif result["action"] == "reset":
122
+ card = gen.generate(
123
+ state=sm.current_state,
124
+ card_type=CardType.CONCEPT,
125
+ title="Reset",
126
+ description="Returned to CORE_OS and cleared runtime context.",
127
+ content={"RESET": True},
128
+ next_actions=["MODE LEDGER_CORE", "RUN <query>", "HELP"],
129
+ )
 
 
130
 
131
+ else:
132
+ card = gen.generate(
133
+ state=sm.current_state,
134
+ card_type=card_type,
135
+ title="Command Processed",
136
+ description=f"Action: {result.get('action')}",
137
+ content={"RESULT": result},
138
+ dataset_result=dataset_result,
139
+ next_actions=["HELP", "RESET"],
140
+ )
141
 
142
+ history.append((command, card))
143
+ return card, dataset_result, history
144
 
 
 
 
145
 
146
+ with gr.Blocks(title="MindsEye Lab", theme=gr.themes.Monochrome()) as app:
 
147
  gr.Markdown(
148
+ "# 🧠 MindsEye Lab - Stateful OS Runtime\n"
149
+ "Deterministic runtime that queries a dataset and emits locked YAML cards.\n\n"
150
  f"**Dataset:** `{DATASET_ID}` • **Config:** `{DATASET_CONFIG}`"
151
  )
152
 
153
  with gr.Row():
154
+ with gr.Column(scale=3):
155
  command_input = gr.Textbox(
156
  label="Command",
157
+ placeholder="MODE LEDGER_CORE | RUN WORKFLOW_ | TEST | LEDGER | RESET",
158
  lines=1,
159
  )
 
 
 
 
 
 
160
  with gr.Column(scale=1):
161
+ submit_btn = gr.Button("Execute", variant="primary")
162
+
163
+ gr.Markdown("### Quick Commands")
164
+ with gr.Row():
165
+ gr.Button("MODE LEDGER_CORE").click(lambda: "MODE LEDGER_CORE", None, command_input)
166
+ gr.Button("MODE BUILD_SPACE").click(lambda: "MODE BUILD_SPACE", None, command_input)
167
+ gr.Button("TEST").click(lambda: "TEST", None, command_input)
168
+ gr.Button("LEDGER").click(lambda: "LEDGER", None, command_input)
169
+ gr.Button("RESET").click(lambda: "RESET", None, command_input)
 
170
 
171
+ card_output = gr.Code(label="YAML Card Response", language="yaml", lines=30)
172
 
173
  with gr.Accordion("Dataset Results (Raw JSON)", open=False):
174
  dataset_output = gr.JSON(label="Query Results")
175
 
176
+ chat = gr.Chatbot(label="Session History", height=320)
 
 
177
 
 
 
 
 
 
 
 
 
 
 
178
  submit_btn.click(
179
  fn=process_command,
180
+ inputs=[command_input, chat],
181
+ outputs=[card_output, dataset_output, chat],
 
 
 
 
 
 
 
 
 
 
 
 
182
  )
183
 
184
+ command_input.submit(
185
+ fn=process_command,
186
+ inputs=[command_input, chat],
187
+ outputs=[card_output, dataset_output, chat],
188
  )
189
 
190
+ if __name__ == "__main__":
191
+ app.launch()