rdubwiley commited on
Commit
c258563
·
verified ·
1 Parent(s): 7182ecf

Deploy Agenda Parser

Browse files
samples/baycity-928.titles.json ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "orig": "1 Proclamation - Pride Month - June 2026",
4
+ "name": "Proclamation - Pride Month - June 2026."
5
+ },
6
+ {
7
+ "orig": "2 FY 26/27 Budget Presentation",
8
+ "name": "FY 26/27 Budget Presentation."
9
+ },
10
+ {
11
+ "orig": "1 MINUTES",
12
+ "name": "City Commission (5/18/26) and Work Session (5/26/26)."
13
+ },
14
+ {
15
+ "orig": "2 ACCOUNTS & CLAIMS",
16
+ "name": "City Manager presenting Accounts and Claims in the amount of $788,294.23 and Investments and Wire Transfers in the amount of $1,212,663.41 (5/26/26), and Accounts and Claims in the amount of $582,328.31 and Investments and Wire Transfers in the amount of $809,185.98 (6/1/26)."
17
+ },
18
+ {
19
+ "orig": "3 PAYROLL",
20
+ "name": "City Manager presenting Payroll in the amount of $1,363,127.22 (5/21/26)."
21
+ },
22
+ {
23
+ "orig": "4 REPORTS OF OFFICERS",
24
+ "name": "REPORTS OF OFFICERS"
25
+ },
26
+ {
27
+ "orig": "5 REPORTS OF COMMITTEES",
28
+ "name": "REPORTS OF COMMITTEES"
29
+ },
30
+ {
31
+ "orig": "6 RESOLUTIONS",
32
+ "name": "RESOLUTIONS"
33
+ },
34
+ {
35
+ "orig": "1 Breaking Bread - to allocate $9,162.50 to meet unm",
36
+ "name": "Commissioner Tenney's resolution allocating $9,162.50 to pay for the unmet costs of the Breaking Bread Village's Pulse Series."
37
+ },
38
+ {
39
+ "orig": "2 Budget Amendments",
40
+ "name": "City Manager recommending budget amendments in the amount of $25,133 for the Fiscal Year 2025/2026 budget."
41
+ }
42
+ ]
samples/oakland-1570.titles.json ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "orig": "a. Proclamation - Family Reunification and Preservati",
4
+ "name": "Proclamation - Family Reunification and Preservation Day"
5
+ },
6
+ {
7
+ "orig": "b. Presentation - Oakland Community Health Network Up",
8
+ "name": "Presentation - Oakland Community Health Network Update"
9
+ },
10
+ {
11
+ "orig": "a. Appointment to SEMCOG's Finance and Budget Committ",
12
+ "name": "Appointment to SEMCOG's Finance and Budget Committee"
13
+ },
14
+ {
15
+ "orig": "10. Public Comment",
16
+ "name": "Public Comment (three minutes max per speaker, related only to items on the agenda)"
17
+ },
18
+ {
19
+ "orig": "a. Fiscal Year 2026 Appropriation with the City of Ro",
20
+ "name": "Board of Commissioners - Fiscal Year 2026 Appropriation with the City of Rochester for Tri-Party Road Improvement Program – Project No. 58601"
21
+ },
22
+ {
23
+ "orig": "b. Authorize the Issuance of Bonds for the Pontiac Wo",
24
+ "name": "Water Resources Commissioner - Authorize the Issuance of Bonds for the Pontiac Woodward Loop Sewage Disposal Improvement Project"
25
+ },
26
+ {
27
+ "orig": "c. Grant Acceptance with U.S. Environmental Protectio",
28
+ "name": "Water Resources Commissioner - Grant Acceptance with U.S. Environmental Protection Agency for the RainSmart Rebates Program"
29
+ },
30
+ {
31
+ "orig": "d. Contract Amendment with Auger, Klein and Aller Arc",
32
+ "name": "Water Resources Commissioner - Contract Amendment with Auger, Klein and Aller Architects"
33
+ },
34
+ {
35
+ "orig": "e. Funding for In-Line Skating Rink at Harding Park w",
36
+ "name": "Board of Commissioners - Funding for In-Line Skating Rink at Harding Park with the City of Ferndale"
37
+ },
38
+ {
39
+ "orig": "f. Fiscal Year 2026 Appropriation for Local Road Impr",
40
+ "name": "Board of Commissioners - Fiscal Year 2026 Appropriation for Local Road Improvement Program"
41
+ },
42
+ {
43
+ "orig": "a. Sponsorship of the Village of Wolverine Lake 39th",
44
+ "name": "Board of Commissioners - Sponsorship of the Village of Wolverine Lake 39th Annual Fireworks Display"
45
+ },
46
+ {
47
+ "orig": "b. FY 2026 Second Quarter Financial Forecast and Budg",
48
+ "name": "Fiscal Services - FY 2026 Second Quarter Financial Forecast and Budget Amendments"
49
+ },
50
+ {
51
+ "orig": "c. Reallocation of American Rescue Plan Act Local Fis",
52
+ "name": "Executive's Office - Reallocation of American Rescue Plan Act Local Fiscal Recovery Funds"
53
+ },
54
+ {
55
+ "orig": "a. Interlocal Agreement with Bloomfield Hills Schools",
56
+ "name": "Parks & Recreation - Interlocal Agreement with Bloomfield Hills Schools for Transition Services and Operational Continuity at Discovery Oaks and Bloomfield Oaks"
57
+ },
58
+ {
59
+ "orig": "b. Memorandum of Understanding with the Huron-Clinton",
60
+ "name": "Parks & Recreation - Memorandum of Understanding with the Huron-Clinton Metropolitan Authority for the 2026 Water Safety and Swim Lesson Partnership"
61
+ },
62
+ {
63
+ "orig": "c. Grant Acceptance from the State of Michigan for th",
64
+ "name": "Parks & Recreation - Grant Acceptance from the State of Michigan for the FY 2026 Great Lakes Management Grant Program"
65
+ },
66
+ {
67
+ "orig": "d. Grant Acceptance from the State of Michigan for th",
68
+ "name": "Parks & Recreation - Grant Acceptance from the State of Michigan for the FY 2026 Invasive Species Grant Program"
69
+ },
70
+ {
71
+ "orig": "a. Grant Application to the Department of Housing and",
72
+ "name": "Health & Human Services - Neighborhood and Housing Development - Grant Application to the Department of Housing and Urban Development for the Program Year 2026 Annual Action Plan"
73
+ },
74
+ {
75
+ "orig": "b. Request to Create One (1) GF/GP FTE Office Support",
76
+ "name": "Circuit Court - Request to Create One (1) GF/GP FTE Office Support Clerk Senior for Personal Protection Order Office"
77
+ },
78
+ {
79
+ "orig": "c. Grant Acceptance from the Michigan State Housing D",
80
+ "name": "Health & Human Services - Neighborhood and Housing Development - Grant Acceptance from the Michigan State Housing Development Authority for the FY 2026 Enhancement Grant"
81
+ },
82
+ {
83
+ "orig": "d. Amendment #1 to the Oakland Schools FY 2025 Home V",
84
+ "name": "Health & Human Services - Health Division - Amendment #1 to the Oakland Schools FY 2025 Home Visitation Grant Program"
85
+ },
86
+ {
87
+ "orig": "e. Request for Staffing Modification within the Healt",
88
+ "name": "Health & Human Services - Health Division - Request for Staffing Modification within the Health Division for the Deletion of Seven (7) Special Revenue Positions"
89
+ },
90
+ {
91
+ "orig": "f. Amendment #4 to the FY 2026 Local Health Departmen",
92
+ "name": "Health & Human Services - Health Division - Amendment #4 to the FY 2026 Local Health Department Agreement from the Michigan Department of Health and Human Services"
93
+ },
94
+ {
95
+ "orig": "g. Grant Application to the Michigan Department of Co",
96
+ "name": "Public Services - Pretrial & Justice Services - Grant Application to the Michigan Department of Corrections for the FY 2027 Community Corrections Comprehensive Plan Program"
97
+ },
98
+ {
99
+ "orig": "h. Memorandum of Understanding with the United States",
100
+ "name": "Sheriff’s Office - Memorandum of Understanding with the United States Capitol Police for Security Services for Members of Congress"
101
+ },
102
+ {
103
+ "orig": "i. Amendment #1 to the FY 2026 Emergency Response Sup",
104
+ "name": "Sheriff’s Office - Amendment #1 to the FY 2026 Emergency Response Support Program for the Rochester Hills Splash Pad Shooting from Oakland County Health Network"
105
+ },
106
+ {
107
+ "orig": "j. Amendment #3 to the Interlocal Agreement with Oakl",
108
+ "name": "Sheriff’s Office - Amendment #3 to the Interlocal Agreement with Oakland Community Health Network for Jail Alliance with Support Program"
109
+ },
110
+ {
111
+ "orig": "a. Appointment to the Land Bank Authority",
112
+ "name": "Board of Commissioners - Appointment to the Land Bank Authority"
113
+ },
114
+ {
115
+ "orig": "18. Public Comment",
116
+ "name": "Public Comment (three minutes max per speaker, any topic)"
117
+ }
118
+ ]
webapp/backend.py CHANGED
@@ -122,14 +122,49 @@ def list_samples() -> list[dict]:
122
 
123
 
124
  def ingest_sample(sample_id: str) -> dict:
125
- """Parse a bundled sample agenda packet (same return shape as upload_packet)."""
126
- s = _SAMPLE_BY_ID.get((sample_id or "").strip())
 
 
 
 
 
 
 
127
  if s is None:
128
  return {"error": f"Unknown sample '{sample_id}'."}
129
  path = _SAMPLES_DIR / s["file"]
130
  if not path.exists():
131
  return {"error": f"Sample '{sample_id}' is not bundled on this server."}
132
- return upload_packet(path.read_bytes(), s["file"], s["agenda_pages"])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
 
134
 
135
  # --------------------------------------------------------------------------- #
 
122
 
123
 
124
  def ingest_sample(sample_id: str) -> dict:
125
+ """Parse a bundled sample agenda packet (same return shape as upload_packet).
126
+
127
+ If a pre-baked ``{id}.titles.json`` sidecar is bundled (the enhanced-title logic
128
+ run once offline), its full titles are applied to the parsed items so samples show
129
+ complete titles immediately — no per-click LLM window. Users can still run "Improve
130
+ titles" or edit by hand afterward.
131
+ """
132
+ sid = (sample_id or "").strip()
133
+ s = _SAMPLE_BY_ID.get(sid)
134
  if s is None:
135
  return {"error": f"Unknown sample '{sample_id}'."}
136
  path = _SAMPLES_DIR / s["file"]
137
  if not path.exists():
138
  return {"error": f"Sample '{sample_id}' is not bundled on this server."}
139
+ res = upload_packet(path.read_bytes(), s["file"], s["agenda_pages"])
140
+ _apply_sample_titles(sid, res.get("items", []))
141
+ return res
142
+
143
+
144
+ def _apply_sample_titles(sample_id: str, items: list[dict]) -> None:
145
+ """Overwrite parsed item names from a pre-baked ``{id}.titles.json`` sidecar.
146
+
147
+ The sidecar is a list of ``{"orig": "<number> <name>", "name": "<full title>"}``;
148
+ we match each parsed item by its exact ``"<number> <name>"`` line and replace the
149
+ name. Missing/garbled sidecar is non-fatal (items keep their bookmark titles).
150
+ """
151
+ import json
152
+
153
+ path = _SAMPLES_DIR / f"{sample_id}.titles.json"
154
+ if not path.exists():
155
+ return
156
+ try:
157
+ overrides = {
158
+ o["orig"]: o["name"]
159
+ for o in json.loads(path.read_text())
160
+ if isinstance(o, dict) and o.get("orig") and o.get("name")
161
+ }
162
+ except Exception: # noqa: BLE001 - a bad sidecar just means no overrides
163
+ return
164
+ for it in items:
165
+ key = f"{it.get('number', '')} {it.get('name', '')}".strip()
166
+ if key in overrides:
167
+ it["name"] = overrides[key]
168
 
169
 
170
  # --------------------------------------------------------------------------- #