yugbirla commited on
Commit
3befc15
·
1 Parent(s): 7be4ee1

Restore graph view actions in user app

Browse files
app/deployment/hf_status.py CHANGED
@@ -5908,3 +5908,134 @@ async function sendMessage() {
5908
  html = html.replace("</body>", js + "\n</body>")
5909
 
5910
  return html
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5908
  html = html.replace("</body>", js + "\n</body>")
5909
 
5910
  return html
5911
+
5912
+
5913
+
5914
+ # =====================================================
5915
+ # Phase 36 override: restore graph actions in user app
5916
+ # =====================================================
5917
+
5918
+ try:
5919
+ _phase36_previous_get_product_app_html = get_product_app_html
5920
+ except NameError:
5921
+ _phase36_previous_get_product_app_html = None
5922
+
5923
+
5924
+ def get_product_app_html() -> str:
5925
+ if _phase36_previous_get_product_app_html is None:
5926
+ return "<h1>GraphResearcher App</h1><p>App UI is unavailable.</p>"
5927
+
5928
+ html = _phase36_previous_get_product_app_html()
5929
+
5930
+ graph_section = """
5931
+ <div class="panel-section" id="graphActionsPhase36">
5932
+ <h3>Graph View</h3>
5933
+ <button class="green" onclick="buildGraphPhase36()">Build / Rebuild Graph</button>
5934
+ <button class="secondary" onclick="openGraphViewerPhase36()">View Graph</button>
5935
+ <p class="small" style="color:#64748b;margin-top:8px;">
5936
+ Open the entity-relation graph created from the selected document.
5937
+ </p>
5938
+ </div>
5939
+ """
5940
+
5941
+ if "id=\"graphActionsPhase36\"" not in html:
5942
+ if '<div class="panel-section">' in html and "Advanced Settings" in html:
5943
+ html = html.replace(
5944
+ '<div class="panel-section">\n <h3>Advanced Settings</h3>',
5945
+ graph_section + '\n <div class="panel-section">\n <h3>Advanced Settings</h3>',
5946
+ 1
5947
+ )
5948
+ elif "</aside>" in html:
5949
+ html = html.replace("</aside>", graph_section + "\n </aside>", 1)
5950
+
5951
+ sidebar_buttons = """
5952
+ <button class="full secondary" onclick="buildGraphPhase36()">Build / Rebuild Graph</button>
5953
+ <button class="full secondary" onclick="openGraphViewerPhase36()">View Graph</button>
5954
+ """
5955
+
5956
+ if "openGraphViewerPhase36" not in html.split("</aside>", 1)[0]:
5957
+ if "Clear Workspace Cache" in html:
5958
+ html = html.replace(
5959
+ '<button class="full secondary" onclick="clearWorkspaceCache()">Clear Workspace Cache</button>',
5960
+ '<button class="full secondary" onclick="clearWorkspaceCache()">Clear Workspace Cache</button>\n' + sidebar_buttons,
5961
+ 1
5962
+ )
5963
+ elif '<button class="full secondary" onclick="window.location.href=\'/\'">Home</button>' in html:
5964
+ html = html.replace(
5965
+ '<button class="full secondary" onclick="window.location.href=\'/\'">Home</button>',
5966
+ '<button class="full secondary" onclick="window.location.href=\'/\'">Home</button>\n' + sidebar_buttons,
5967
+ 1
5968
+ )
5969
+
5970
+ js = """
5971
+ <script>
5972
+ /*
5973
+ Phase 36: restore View Graph in the normal user app.
5974
+ This is not a developer-only feature. It helps users inspect the document entity-relation graph.
5975
+ */
5976
+
5977
+ async function buildGraphPhase36() {
5978
+ const doc = getSelectedDocument();
5979
+
5980
+ if (!doc) {
5981
+ alert('Select a document first.');
5982
+ return;
5983
+ }
5984
+
5985
+ setStatus('Building graph...');
5986
+
5987
+ try {
5988
+ const response = await fetch(`/documents/${doc.id}/graph/build`, {
5989
+ method: 'POST'
5990
+ });
5991
+
5992
+ const data = await response.json();
5993
+
5994
+ if (!response.ok) {
5995
+ throw new Error(JSON.stringify(data));
5996
+ }
5997
+
5998
+ doc.graphStatus = 'graph built';
5999
+ doc.graphData = {
6000
+ entities: data.total_entities ?? data.entity_count ?? null,
6001
+ relations: data.total_relations ?? data.relation_count ?? null
6002
+ };
6003
+
6004
+ saveDocuments();
6005
+ renderDocuments();
6006
+
6007
+ const metricsBox = document.getElementById('metricsBox');
6008
+ if (metricsBox) {
6009
+ metricsBox.innerHTML = `
6010
+ <span class="metric">graph built</span>
6011
+ <span class="metric">entities: ${doc.graphData.entities ?? 'NA'}</span>
6012
+ <span class="metric">relations: ${doc.graphData.relations ?? 'NA'}</span>
6013
+ `;
6014
+ }
6015
+
6016
+ setStatus('Graph ready');
6017
+ alert('Graph built. Click View Graph to open it.');
6018
+
6019
+ } catch (error) {
6020
+ setStatus('Graph build failed');
6021
+ alert('Graph build failed. Re-index or re-upload the document if Hugging Face rebuilt recently. Error: ' + error.message);
6022
+ }
6023
+ }
6024
+
6025
+ function openGraphViewerPhase36() {
6026
+ const doc = getSelectedDocument();
6027
+
6028
+ if (!doc) {
6029
+ alert('Select a document first.');
6030
+ return;
6031
+ }
6032
+
6033
+ window.open(`/documents/${doc.id}/graph/view`, '_blank');
6034
+ }
6035
+ </script>
6036
+ """
6037
+
6038
+ if "Phase 36: restore View Graph" not in html:
6039
+ html = html.replace("</body>", js + "\n</body>")
6040
+
6041
+ return html
scripts/phase36_restore_view_graph.py ADDED
@@ -0,0 +1,151 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pathlib import Path
2
+
3
+ # Clean BOM
4
+ for path in Path("app").rglob("*.py"):
5
+ text = path.read_text(encoding="utf-8-sig")
6
+ text = text.replace("\ufeff", "")
7
+ path.write_text(text, encoding="utf-8")
8
+
9
+ hf_path = Path("app/deployment/hf_status.py")
10
+ text = hf_path.read_text(encoding="utf-8-sig")
11
+ text = text.replace("\ufeff", "")
12
+
13
+ append_code = r'''
14
+ # =====================================================
15
+ # Phase 36 override: restore graph actions in user app
16
+ # =====================================================
17
+
18
+ try:
19
+ _phase36_previous_get_product_app_html = get_product_app_html
20
+ except NameError:
21
+ _phase36_previous_get_product_app_html = None
22
+
23
+
24
+ def get_product_app_html() -> str:
25
+ if _phase36_previous_get_product_app_html is None:
26
+ return "<h1>GraphResearcher App</h1><p>App UI is unavailable.</p>"
27
+
28
+ html = _phase36_previous_get_product_app_html()
29
+
30
+ graph_section = """
31
+ <div class="panel-section" id="graphActionsPhase36">
32
+ <h3>Graph View</h3>
33
+ <button class="green" onclick="buildGraphPhase36()">Build / Rebuild Graph</button>
34
+ <button class="secondary" onclick="openGraphViewerPhase36()">View Graph</button>
35
+ <p class="small" style="color:#64748b;margin-top:8px;">
36
+ Open the entity-relation graph created from the selected document.
37
+ </p>
38
+ </div>
39
+ """
40
+
41
+ if "id=\"graphActionsPhase36\"" not in html:
42
+ if '<div class="panel-section">' in html and "Advanced Settings" in html:
43
+ html = html.replace(
44
+ '<div class="panel-section">\n <h3>Advanced Settings</h3>',
45
+ graph_section + '\n <div class="panel-section">\n <h3>Advanced Settings</h3>',
46
+ 1
47
+ )
48
+ elif "</aside>" in html:
49
+ html = html.replace("</aside>", graph_section + "\n </aside>", 1)
50
+
51
+ sidebar_buttons = """
52
+ <button class="full secondary" onclick="buildGraphPhase36()">Build / Rebuild Graph</button>
53
+ <button class="full secondary" onclick="openGraphViewerPhase36()">View Graph</button>
54
+ """
55
+
56
+ if "openGraphViewerPhase36" not in html.split("</aside>", 1)[0]:
57
+ if "Clear Workspace Cache" in html:
58
+ html = html.replace(
59
+ '<button class="full secondary" onclick="clearWorkspaceCache()">Clear Workspace Cache</button>',
60
+ '<button class="full secondary" onclick="clearWorkspaceCache()">Clear Workspace Cache</button>\n' + sidebar_buttons,
61
+ 1
62
+ )
63
+ elif '<button class="full secondary" onclick="window.location.href=\'/\'">Home</button>' in html:
64
+ html = html.replace(
65
+ '<button class="full secondary" onclick="window.location.href=\'/\'">Home</button>',
66
+ '<button class="full secondary" onclick="window.location.href=\'/\'">Home</button>\n' + sidebar_buttons,
67
+ 1
68
+ )
69
+
70
+ js = """
71
+ <script>
72
+ /*
73
+ Phase 36: restore View Graph in the normal user app.
74
+ This is not a developer-only feature. It helps users inspect the document entity-relation graph.
75
+ */
76
+
77
+ async function buildGraphPhase36() {
78
+ const doc = getSelectedDocument();
79
+
80
+ if (!doc) {
81
+ alert('Select a document first.');
82
+ return;
83
+ }
84
+
85
+ setStatus('Building graph...');
86
+
87
+ try {
88
+ const response = await fetch(`/documents/${doc.id}/graph/build`, {
89
+ method: 'POST'
90
+ });
91
+
92
+ const data = await response.json();
93
+
94
+ if (!response.ok) {
95
+ throw new Error(JSON.stringify(data));
96
+ }
97
+
98
+ doc.graphStatus = 'graph built';
99
+ doc.graphData = {
100
+ entities: data.total_entities ?? data.entity_count ?? null,
101
+ relations: data.total_relations ?? data.relation_count ?? null
102
+ };
103
+
104
+ saveDocuments();
105
+ renderDocuments();
106
+
107
+ const metricsBox = document.getElementById('metricsBox');
108
+ if (metricsBox) {
109
+ metricsBox.innerHTML = `
110
+ <span class="metric">graph built</span>
111
+ <span class="metric">entities: ${doc.graphData.entities ?? 'NA'}</span>
112
+ <span class="metric">relations: ${doc.graphData.relations ?? 'NA'}</span>
113
+ `;
114
+ }
115
+
116
+ setStatus('Graph ready');
117
+ alert('Graph built. Click View Graph to open it.');
118
+
119
+ } catch (error) {
120
+ setStatus('Graph build failed');
121
+ alert('Graph build failed. Re-index or re-upload the document if Hugging Face rebuilt recently. Error: ' + error.message);
122
+ }
123
+ }
124
+
125
+ function openGraphViewerPhase36() {
126
+ const doc = getSelectedDocument();
127
+
128
+ if (!doc) {
129
+ alert('Select a document first.');
130
+ return;
131
+ }
132
+
133
+ window.open(`/documents/${doc.id}/graph/view`, '_blank');
134
+ }
135
+ </script>
136
+ """
137
+
138
+ if "Phase 36: restore View Graph" not in html:
139
+ html = html.replace("</body>", js + "\n</body>")
140
+
141
+ return html
142
+ '''
143
+
144
+ if "Phase 36 override: restore graph actions in user app" not in text:
145
+ text += "\n\n" + append_code
146
+ print("Phase 36 restore View Graph patch added.")
147
+ else:
148
+ print("Phase 36 patch already exists.")
149
+
150
+ hf_path.write_text(text, encoding="utf-8")
151
+ print("Done.")