JacobLinCool Codex commited on
Commit
a3e1f0c
·
verified ·
1 Parent(s): 18b8de2

fix: make example notes builder-facing

Browse files

Co-authored-by: Codex <noreply@openai.com>

README.md CHANGED
@@ -66,7 +66,7 @@ is intentionally kept out of the main user workflow.
66
  ## Field Notes Artifact
67
 
68
  The `field_notes` Gradio API endpoint and `Notes` button export a Markdown build note from the exact session state:
69
- builder profile, selected goals, idea board, cited Spaces, latest build plan, planner calls, and the share caption. This
70
  keeps the note tied to auditable app evidence instead of a separate hand-written summary.
71
 
72
  ## Chapter Artifact
 
66
  ## Field Notes Artifact
67
 
68
  The `field_notes` Gradio API endpoint and `Notes` button export a Markdown build note from the exact session state:
69
+ builder profile, selected goals, idea board, cited Spaces, latest build plan, advisor actions, and the share caption. This
70
  keeps the note tied to auditable app evidence instead of a separate hand-written summary.
71
 
72
  ## Chapter Artifact
hackathon_advisor/field_notes.py CHANGED
@@ -53,12 +53,12 @@ def build_field_notes_markdown(session: dict[str, Any], metadata: dict[str, Any]
53
  else:
54
  lines.append("No build plan has been generated yet.")
55
 
56
- lines.extend(["", "## Turn Trace", ""])
57
  if trace:
58
  for index, event in enumerate(trace, start=1):
59
- lines.extend(_trace_section(index, event))
60
  else:
61
- lines.append("No tool trace was recorded.")
62
 
63
  wood_map = last_artifact.get("wood_map") if isinstance(last_artifact.get("wood_map"), dict) else {}
64
  if wood_map:
@@ -122,14 +122,14 @@ def _idea_section(index: int, idea: dict[str, Any]) -> list[str]:
122
  return lines
123
 
124
 
125
- def _trace_section(index: int, event: dict[str, Any]) -> list[str]:
126
  tools = _list_of_dicts(event.get("tools"))
127
- tool_names = " -> ".join(_clean(tool.get("name")) for tool in tools if tool.get("name")) or "reply"
128
  lines = [
129
- f"### Turn {index}",
130
  "",
131
  f"- Input: {_clean(event.get('input'))}",
132
- f"- Tools: {tool_names}",
133
  ]
134
  verdict = _clean(event.get("verdict"))
135
  overall = event.get("overall")
@@ -141,7 +141,7 @@ def _trace_section(index: int, event: dict[str, Any]) -> list[str]:
141
  resolution = event.get("tool_resolution") if isinstance(event.get("tool_resolution"), dict) else {}
142
  call = resolution.get("call") if isinstance(resolution.get("call"), dict) else {}
143
  if call:
144
- lines.append(f"- Planner call: `{_clean(call.get('name'))}`")
145
  lines.append("")
146
  return lines
147
 
 
53
  else:
54
  lines.append("No build plan has been generated yet.")
55
 
56
+ lines.extend(["", "## Session Decisions", ""])
57
  if trace:
58
  for index, event in enumerate(trace, start=1):
59
+ lines.extend(_decision_section(index, event))
60
  else:
61
+ lines.append("No session decisions were recorded.")
62
 
63
  wood_map = last_artifact.get("wood_map") if isinstance(last_artifact.get("wood_map"), dict) else {}
64
  if wood_map:
 
122
  return lines
123
 
124
 
125
+ def _decision_section(index: int, event: dict[str, Any]) -> list[str]:
126
  tools = _list_of_dicts(event.get("tools"))
127
+ action_names = " -> ".join(_clean(tool.get("name")) for tool in tools if tool.get("name")) or "reply"
128
  lines = [
129
+ f"### Decision {index}",
130
  "",
131
  f"- Input: {_clean(event.get('input'))}",
132
+ f"- Advisor actions: {action_names}",
133
  ]
134
  verdict = _clean(event.get("verdict"))
135
  overall = event.get("overall")
 
141
  resolution = event.get("tool_resolution") if isinstance(event.get("tool_resolution"), dict) else {}
142
  call = resolution.get("call") if isinstance(resolution.get("call"), dict) else {}
143
  if call:
144
+ lines.append(f"- Recorded action: `{_clean(call.get('name'))}`")
145
  lines.append("")
146
  return lines
147
 
static/app.js CHANGED
@@ -385,7 +385,7 @@ function applyDemoSession(data) {
385
  session.profile = session.profile || {};
386
  session.goals = Array.isArray(session.goals) ? session.goals : [];
387
  session.last_response = data.response || session.last_response || "";
388
- session.ui_status = `Example loaded: ${data.turn_count || 0} advisor turns`;
389
  currentArtifact = data.artifact || session.last_artifact || null;
390
  ink.textContent = data.response || "Example session loaded.";
391
  ink.classList.remove("thinking");
 
385
  session.profile = session.profile || {};
386
  session.goals = Array.isArray(session.goals) ? session.goals : [];
387
  session.last_response = data.response || session.last_response || "";
388
+ session.ui_status = "Example idea board loaded with a plan and share page.";
389
  currentArtifact = data.artifact || session.last_artifact || null;
390
  ink.textContent = data.response || "Example session loaded.";
391
  ink.classList.remove("thinking");
tests/test_app.py CHANGED
@@ -73,7 +73,9 @@ def test_field_notes_endpoint_exports_markdown() -> None:
73
  assert "Skills: frontend" in payload
74
  assert "Goals: Build notes" in payload
75
  assert "Targets: Field Notes" not in payload
76
- assert "## Turn Trace" in payload
 
 
77
  assert "Write build notes from the exact decisions" in payload
78
 
79
 
 
73
  assert "Skills: frontend" in payload
74
  assert "Goals: Build notes" in payload
75
  assert "Targets: Field Notes" not in payload
76
+ assert "## Session Decisions" in payload
77
+ assert "## Turn Trace" not in payload
78
+ assert "Planner call" not in payload
79
  assert "Write build notes from the exact decisions" in payload
80
 
81
 
tests/test_field_notes.py CHANGED
@@ -31,8 +31,13 @@ def test_field_notes_markdown_contains_session_decisions() -> None:
31
  assert "A local-first archive cartographer for family photos" in markdown
32
  assert "## Build Plan" in markdown
33
  assert "Write build notes from the exact decisions" in markdown
 
 
 
34
  assert "Closest cited Spaces" in markdown
35
  assert "Page " in markdown
36
  assert "## Wood Map" in markdown
37
  assert "echo score" in markdown
38
- assert "Planner call: `make_plan`" in markdown
 
 
 
31
  assert "A local-first archive cartographer for family photos" in markdown
32
  assert "## Build Plan" in markdown
33
  assert "Write build notes from the exact decisions" in markdown
34
+ assert "## Session Decisions" in markdown
35
+ assert "### Decision 2" in markdown
36
+ assert "Recorded action: `make_plan`" in markdown
37
  assert "Closest cited Spaces" in markdown
38
  assert "Page " in markdown
39
  assert "## Wood Map" in markdown
40
  assert "echo score" in markdown
41
+ assert "## Turn Trace" not in markdown
42
+ assert "Planner call" not in markdown
43
+ assert "tool trace" not in markdown.lower()
tests/test_frontend_copy.py CHANGED
@@ -10,6 +10,7 @@ def test_main_interface_copy_is_builder_facing() -> None:
10
  assert "Closest project echoes" in html
11
  assert "Press Plan to draft build steps for the selected idea." in app_js
12
  assert "Loading an example idea board." in app_js
 
13
  assert "/api/artifact.png" in app_js
14
  assert "renderArtifactCanvas" not in app_js
15
  assert "canvas.toDataURL" not in app_js
@@ -25,6 +26,7 @@ def test_main_interface_copy_is_builder_facing() -> None:
25
  "Still riffling the inked pages.",
26
  "YOU VS THE WOOD",
27
  "current Wood",
 
28
  ]
29
  for phrase in stale_jargon:
30
  assert phrase not in combined
 
10
  assert "Closest project echoes" in html
11
  assert "Press Plan to draft build steps for the selected idea." in app_js
12
  assert "Loading an example idea board." in app_js
13
+ assert "Example idea board loaded with a plan and share page." in app_js
14
  assert "/api/artifact.png" in app_js
15
  assert "renderArtifactCanvas" not in app_js
16
  assert "canvas.toDataURL" not in app_js
 
26
  "Still riffling the inked pages.",
27
  "YOU VS THE WOOD",
28
  "current Wood",
29
+ "advisor turns",
30
  ]
31
  for phrase in stale_jargon:
32
  assert phrase not in combined