ashwath-vaithina-ibm commited on
Commit
4d89605
·
verified ·
1 Parent(s): 71734df

Update static/demo/index.html

Browse files
Files changed (1) hide show
  1. static/demo/index.html +121 -423
static/demo/index.html CHANGED
@@ -1,447 +1,145 @@
1
  <!DOCTYPE html>
2
  <html lang="en">
3
- <head>
4
- <title>Responsible Prompting Demo</title>
5
- <meta charset="UTF-8">
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
- <link rel="stylesheet" href="https://unpkg.com/carbon-components/css/carbon-components.min.css">
8
- <script type="text/javascript" src="js/track.js"></script>
9
- <script type="text/javascript" src="js/d3.v7.min.js"></script>
10
- <style type="text/css">
11
- div.tooltip {
12
- position: absolute;
13
- text-align: left;
14
- padding: 0.5em;
15
- width: 20em;
16
- min-height: 5em;
17
- background: #fff;
18
- color: #000;
19
- border: 1px solid #000;
20
- border-radius: 5px;
21
- pointer-events: none;
22
- font-size: inherit;
23
- font-family: inherit;
24
- }
25
- </style>
26
- </head>
27
- <body>
28
- <div class="bx--grid">
29
- <div class="bx--row">
30
- <div class="bx--col-lg-10 bx--offset-lg-1">
31
- <h1 class="bx--type-expressive-heading-03" style="margin-top: 1em;">Responsible Prompting</h1>
32
- <p class="bx--type-body-long-01"><br>Please provide a prompt that would be sent to an LLM. Recommendations are performed in prompting-time, before content generation. The recommendations consider a curated dataset of values and prompts sentences. The recommendations are based on the similarity between the input sentences and our prompt sentences dataset.<br><br></p>
33
-
34
- <div class="bx--tabs">
35
- <ul class="bx--tabs__nav">
36
- <li class="bx--tabs__nav-item bx--tabs__nav-item--selected" id="tab-1" data-target="#tab-content-1">
37
- <a class="bx--tabs__nav-link" href="#" onclick="$('#tab-content-1').toggle();$('#tab-1').toggleClass('bx--tabs__nav-item--selected');$('#tab-content-2').toggle();$('#tab-2').toggleClass('bx--tabs__nav-item--selected');">Prompt</a>
38
- </li>
39
- <li class="bx--tabs__nav-item" data-target="#tab-content-2" id="tab-2">
40
- <a class="bx--tabs__nav-link" href="#" onclick="$('#tab-content-1').toggle();$('#tab-1').toggleClass('bx--tabs__nav-item--selected');$('#tab-content-2').toggle();$('#tab-2').toggleClass('bx--tabs__nav-item--selected');renderGraph($('#prompt').data('recommendations'))">Graph</a>
41
- </li>
42
- </ul>
43
- </div>
44
-
45
- <form class="bx--form" id="demo">
46
- <div class="bx--tab-content">
47
- <div id="tab-content-1" class="bx--tab-content__section">
48
- <div class="bx--form-item">
49
- <textarea id="prompt" name="prompt" class="bx--text-area" rows="15" placeholder="Enter your prompt">Act as a professional designer with 20 years of experience creating and testing UX interfaces and landing sites for a variety of IT applications. We are in need of more people and an increased budget to be able to keep up with clients' needs. What kind of evidence should I gather to support my demands to gain more resources?</textarea>
50
- <div id="recommendation" style="min-height: 3em;" class="bx--form__helper-text"></div>
51
- </div>
52
- </div>
53
- <div id="tab-content-2" class="bx--tab-content__section bx--tab-content--hidden" style="display: none;">
54
- <div class="bx--form-item" id="graph" style="background: #efefef"></div>
55
- </div>
56
- </div>
57
- <div class="bx--form-item" style="margin-bottom: 2em;">
58
- <button id="generate" type="submit" class="bx--btn bx--btn--primary">Generate</button>
59
- </div>
60
- <div class="bx--form-item">
61
- <label for="outcome" id="outcome-label" class="bx--label">Generated text</label>
62
- <textarea id="outcome" name="outcome" class="bx--text-area" rows="12" placeholder=""></textarea>
63
- </div>
64
- </form>
65
- </div>
66
- </div>
67
- </div>
68
- <script src="./js/jquery-3.7.1.min.js"></script>
69
- <script lang="javascript">
70
- const width = 600;
71
- const height = 200;
72
- const marginTop = 30;
73
- const marginRight = 30;
74
- const marginBottom = 30;
75
- const marginLeft = 30;
76
- const nodeRadius = 3;
77
-
78
- const svg = d3.select("#graph").append("svg")
79
- .attr("viewBox", [0, 0, width, height])
80
- .attr("style", "max-width: 100%; height: auto; font: 8px sans-serif;");
81
-
82
- var tooltip = d3.select("body").append("div")
83
- .attr("class", "tooltip")
84
- .style("opacity", 0);
85
-
86
- const renderGraph = (recommendations) => {
87
- if( !recommendations ){
88
- return ;
89
- }
90
- svg.selectAll("*").remove(); // Clearing previous plots
91
- var graphData = {nodes: [], edges: []}
92
- var i = j = 0;
93
- if( recommendations['input'].length > 0 ){
94
- graphData.nodes.push({
95
- id: 0,
96
- x: Number(recommendations['input'][0].x),
97
- y: Number(recommendations['input'][0].y),
98
- text: recommendations['input'][0].sentence,
99
- label: 'S' + (i+1),
100
- type: 'input'
101
- })
102
- for( i = 1; i < recommendations['input'].length; i++ ){
103
- graphData.nodes.push({
104
- id: i,
105
- x: Number(recommendations['input'][i].x),
106
- y: Number(recommendations['input'][i].y),
107
- text: recommendations['input'][i].sentence,
108
- label: 'S' + (i+1),
109
- type: 'input'
110
- });
111
- graphData.edges.push({ source: (i-1), target: i, type: 'input' });
112
- }
113
- }
114
-
115
- // Adding nodes & edges for inclusion recommendations
116
- if( recommendations['add'].length > 0 ){
117
- for( j = 0; j < recommendations['add'].length; j++ ){
118
- graphData.nodes.push({
119
- id: i + j + 1,
120
- x: Number(recommendations['add'][j].x),
121
- y: Number(recommendations['add'][j].y),
122
- text: recommendations['add'][j].prompt,
123
- label: recommendations['add'][j].value,
124
- type: 'add'
125
- });
126
- graphData.edges.push({ source: (i-1), target: (i+j+1), type: 'add' });
127
- }
128
- }
129
-
130
- // Adding nodes & edges for removal recommendations
131
- if( recommendations['remove'].length > 0 ){
132
- // Showing only the first removal recommendation
133
- graphData.nodes.push({
134
- id: i + j,
135
- x: Number(recommendations['remove'][0].x),
136
- y: Number(recommendations['remove'][0].y),
137
- text: recommendations['remove'][0].closest_harmful_sentence,
138
- label: recommendations['remove'][0].value,
139
- type: 'remove'
140
- });
141
- }
142
-
143
- // Convert edge references to actual node objects
144
- graphData.edges = graphData.edges.map(edge => ({
145
- source: graphData.nodes.find(n => n.id === edge.source),
146
- target: graphData.nodes.find(n => n.id === edge.target)
147
- }));
148
-
149
- const { nodes, edges } = graphData;
150
-
151
- // Prepare the ranges of values for the axes
152
- const xDomain = d3.extent(nodes, d => d.x);
153
- const yDomain = d3.extent(nodes, d => d.y);
154
- const xPadding = 2
155
- const yPadding = 2
156
-
157
- // Prepare the scales for positional encoding.
158
- const x = d3.scaleLinear()
159
- .domain([xDomain[0]-xPadding,xDomain[1]+xPadding]).nice()
160
- .range([marginLeft, width - marginRight]);
161
-
162
- const y = d3.scaleLinear()
163
- .domain([yDomain[0]-yPadding,yDomain[1]+yPadding]).nice()
164
- .range([height - marginBottom, marginTop]);
165
-
166
- // Create the axes.
167
- svg.append("g")
168
- .attr("transform", `translate(0,${height - marginBottom})`)
169
- .call(d3.axisBottom(x).ticks(width / 80))
170
- .call(g => g.select(".domain").remove())
171
- .call(g => g.append("text")
172
- .attr("x", width)
173
- .attr("y", marginBottom - 4)
174
- .attr("fill", "currentColor")
175
- .attr("text-anchor", "end")
176
- .text("Semantic dimension 1"));
177
-
178
- svg.append("g")
179
- .attr("transform", `translate(${marginLeft},0)`)
180
- .call(d3.axisLeft(y))
181
- .call(g => g.select(".domain").remove())
182
- .call(g => g.append("text")
183
- .attr("x", -marginLeft)
184
- .attr("y", 10)
185
- .attr("fill", "currentColor")
186
- .attr("text-anchor", "start")
187
- .text("Semantic dimension 2"));
188
-
189
- // Create the grid.
190
- svg.append("g")
191
- .attr("stroke", "#cccccc")
192
- .attr("stroke-opacity", 0.5)
193
- .call(g => g.append("g")
194
- .selectAll("line")
195
- .data(x.ticks())
196
- .join("line")
197
- .attr("x1", d => 0.5 + x(d))
198
- .attr("x2", d => 0.5 + x(d))
199
- .attr("y1", marginTop)
200
- .attr("y2", height - marginBottom))
201
- .call(g => g.append("g")
202
- .selectAll("line")
203
- .data(y.ticks())
204
- .join("line")
205
- .attr("y1", d => 0.5 + y(d))
206
- .attr("y2", d => 0.5 + y(d))
207
- .attr("x1", marginLeft)
208
- .attr("x2", width - marginRight));
209
 
210
- // Add a layer of dots.
211
- svg.append("g")
212
- .attr("stroke-width", 2.5)
213
- .attr("stroke-opacity", 0.5)
214
- .attr("fill", "none")
215
- .selectAll("circle")
216
- .data(nodes)
217
- .join("circle")
218
- .attr("stroke", d => d.type == "add" ? "green" : d.type == "input"? "#666" : "red" )
219
- .attr("cx", d => x(d.x))
220
- .attr("cy", d => y(d.y))
221
- .attr("r", nodeRadius);
222
 
223
- // Add a layer of labels.
224
- svg.append("g")
225
- .attr("font-family", "sans-serif")
226
- .attr("text-opacity", 0.5)
227
- .attr("font-size", 8)
228
- .selectAll("text")
229
- .data(nodes)
230
- .join("text")
231
- .attr("dy", "0.35em")
232
- .attr("x", d => x(d.x)+5)
233
- .attr("y", d => y(d.y))
234
- .text(d => d.label)
235
- .on('mousemove', function (d, i) {
236
- d3.select(this).transition()
237
- .duration("50")
238
- .attr("text-opacity", 1.0)
239
- .attr("stroke", "white")
240
- .attr("stroke-width", 3)
241
- .style("paint-order", "stroke fill")
242
- .attr("fill", d => d.type == "add" ? "green" : d.type == "input"? "black" : "red" )
243
- tooltip.transition()
244
- .duration(50)
245
- .style("opacity", 1);
246
- tooltip.html( "<strong>" + i.label + ":</strong><br>" + i.text )
247
- .style("left", (event.pageX + 10) + "px")
248
- .style("top", (event.pageY + 10) + "px");
249
- ;
250
- })
251
- .on('mouseout', function (d, i) {
252
- d3.select(this).transition()
253
- .duration("50")
254
- .attr("text-opacity", 0.5)
255
- .attr("stroke-width", 0)
256
- .style("paint-order", "stroke fill")
257
- .attr("fill", "black")
258
- tooltip.transition()
259
- .duration(50)
260
- .style("opacity", 0);
261
- });
262
 
263
- // Adding edges
264
- svg.append("g")
265
- .selectAll("line")
266
- .data(edges)
267
- .join("line")
268
- .attr("stroke", "#666")
269
- .attr("stroke-opacity", 0.5)
270
- .attr("x1", d => x(d.source.x)+(d.source.x<d.target.x?1.3*nodeRadius:nodeRadius*-1.3))
271
- .attr("y1", d => y(d.source.y))
272
- .attr("x2", d => x(d.target.x)+(d.source.x>d.target.x?1.3*nodeRadius:nodeRadius*-1.3))
273
- .attr("y2", d => y(d.target.y))
274
- .style("stroke-dasharray", d => d.target.type == "add" ? "3,3" : "");
275
 
276
- };
277
 
278
- // ------------------------------------------------
 
 
 
279
 
280
- // Init state
281
- if( $( "#prompt" ).val() == "" ){
282
- $( "#generate" ).attr( "disabled", true ) ;
283
- }
284
- var last_request = Date.now() - 60 * 60 * 1000 ;
285
- var last_prompt = $( "#prompt" ).val().trim() ;
286
 
287
- // Add recommendations to the prompt
288
- function add_recommendation( p ){
289
- preview_add_recommendation( p, "hide" )
290
- $( "#prompt" ).val( $( "#prompt" ).val() + " " + p ) ;
291
- $( "#recommendation" ).html( "" ) ;
292
- $( "#prompt" ).trigger( "keyup" ) ; // Looking for recommendations after accepting a recommendation
293
- }
 
 
 
 
 
 
 
 
 
 
294
 
295
- // Preview for add recommendation
296
- function preview_add_recommendation( p, flag ){
297
- if( flag == "show" ){
298
- $( "#prompt" ).val( $( "#prompt" ).val() + " " + p ) ;
299
- }
300
- else{
301
- $( "#prompt" ).val( $( "#prompt" ).val().replace( " " + p, "" ) ) ;
302
- }
303
- }
304
 
305
- // Remove adversarial sentences from prompt
306
- function remove_recommendation( p ){
307
- $( "#prompt" ).val( $( "#prompt" ).val().replace( p, "" ) ) ;
308
- $( "#prompt" ).val( $( "#prompt" ).val().replace( " ", " " ) ) ;
309
- $( "#recommendation" ).html( "" ) ;
310
- $( "#prompt" ).trigger( "keyup" ) ; // Looking for recommendations after accepting a recommendation
311
- }
 
 
 
 
 
 
 
 
 
312
 
313
- // Preview for add recommendation
314
- function preview_remove_recommendation( p, flag ){
315
- if( flag == "show" ){
316
- $( "#prompt" ).data( "previous_prompt", $( "#prompt" ).val() ) ;
317
- $( "#prompt" ).val( $( "#prompt" ).val().replace( p, "" ) ) ;
318
- }
319
- else{
320
- $( "#prompt" ).val( $( "#prompt" ).data( "previous_prompt" ) ) ;
321
- }
322
- }
323
 
324
- // Listening to changes performed on the prompt input field
325
- $( "#prompt" ).on( "keyup", function( e ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
326
 
327
- // Updating the generate button state based on prompt length
328
- if( $( "#prompt" ).val().length > 0 ){
329
- $( "#generate" ).removeAttr( "disabled" ) ;
 
 
 
 
 
 
 
 
330
  }
331
- else{
332
- $( "#generate" ).attr( "disabled", true ) ;
333
- }
334
-
335
- // Minimum timeout between the requests
336
- if( Date.now() - last_request > 500 && last_prompt != $( "#prompt" ).val().trim() ){
337
- last_request = Date.now() ;
338
- last_prompt = $( "#prompt" ).val().trim() ;
339
- // Getting the last typed char
340
- var last_char = $( "#prompt" ).val().trim().slice( -1 ) ;
341
-
342
- // Triggering the API request when ending of a sentence is found, e.g., .?!
343
- if( last_char == "." || last_char == "?" || last_char == "!" ){
344
- $( "#recommendation" ).html( 'Requesting recommendations: <div class="bx--tag bx--tag--gray bx--tag--deletable">...</div>' ) ;
345
- var api_url = "/recommend?prompt="
346
- // var api_url = "/recommend_local?prompt="
347
- var p = $( "#prompt" ).val() ;
348
-
349
- // API request
350
- $.getJSON( api_url + encodeURI( p ), function( data ) {
351
- $( "#recommendation" ).html( "Recommendations: " ) ;
352
-
353
- // Looking first for removal recommendations
354
- // if( data["remove"].length > 0 && data["remove"][0].similarity > 0.5 ){
355
- if( data["remove"].length > 0 ){
356
- for( var i = 0; i < data["remove"].length ; i++ ){
357
- // $( "#prompt" ).html( $( "#prompt" ).html().replace( data["remove"][i].sentence, '<span style="text-decoration: underline red">' + data["remove"][i].sentence + '</span>' ) ) ;
358
- var sentence = data["remove"][i].sentence.replaceAll( "'", "\\'" ) ;
359
- var sentence_entity = data["remove"][i].sentence.replaceAll( "'", "&apos;" ) ;
360
- var sentence_value = data["remove"][i].value.replaceAll( "'", "\\'" ) ;
361
- $( "#recommendation" ).append( '<div class="bx--tag bx--tag--red bx--tag--deletable" style="cursor: pointer;" onmouseover="preview_remove_recommendation(\''+ sentence + '\', \'show\')" onmouseout="preview_remove_recommendation(\''+ sentence + '\', \'hide\')" onclick="remove_recommendation(\''+ sentence + '\')">x ' + sentence_value + '</div>' ) ;
362
- break ; // Showing only once removal recommendation at a time
363
- }
364
- }
365
 
366
- // else if( data["add"].length > 0 ){ // After the removal recommendations are dealt with, then we show recommendations for inclusion
367
- if( data["add"].length > 0 ){ // Think Demo UX
368
- for( var i = 0; i < data["add"].length; i++ ){
369
- if( $( "#prompt" ).val().indexOf( data["add"][i].prompt ) == -1 ){
370
- // Adding only recommendations that are not present in the prompt
371
- var sentence = data["add"][i].prompt.replaceAll( "'", "\\'" ) ;
372
- var sentence_entity = data["add"][i].prompt.replaceAll( "'", "&apos;" ) ;
373
- var sentence_value = data["add"][i].value.replaceAll( "'", "\\'" ) ;
374
- $( "#recommendation" ).append( '<div class="bx--tag bx--tag--green" style="cursor: pointer;" onmouseover="preview_add_recommendation(\''+ sentence + '\', \'show\')" onmouseout="preview_add_recommendation(\''+ sentence + '\', \'hide\')" onclick="add_recommendation(\''+ sentence + '\')">+ ' + sentence_value + '</div>' ) ;
375
- }
376
- }
377
- }
378
 
379
- // User status message about recommendations found
380
- if( data["add"].length == 0 && data["remove"].length == 0 ){
381
- $( "#recommendation" ).html( "No recommendations found." ) ;
382
- }
 
 
 
383
 
384
- $("#prompt").data( "recommendations", data );
385
- // renderGraph(data);
386
- });
 
 
 
 
 
 
 
387
  }
388
  }
389
  });
390
 
391
- // Generation request
392
- $( "#demo" ).on( "submit", function(e){ // Hugging Face
393
- $( "#generate" ).toggleClass( "bx--btn--disabled" ) ;
394
- ( function loading_animation(){
395
- if( $( "#outcome" ).attr( "placeholder" ) == "" ){
396
- $( "#outcome" ).attr( "placeholder", "Requesting content." ) ;
397
- }
398
- else if( $( "#outcome" ).attr( "placeholder" ).length < 21 ){
399
- $( "#outcome" ).attr( "placeholder", $( "#outcome" ).attr( "placeholder") + "." ) ;
400
- }
401
- else{
402
- $( "#outcome" ).attr( "placeholder", "Requesting content." ) ;
403
- }
404
- setTimeout( loading_animation, 500 );
405
- } )()
406
-
407
- $.ajax({
408
- url: encodeURI("/demo_inference?prompt=" + $("#prompt").val()),
409
- dataType: 'json',
410
- success: function(data){
411
- // Resetting the status of the button
412
- $( "#generate" ).toggleClass( "bx--btn--disabled" ) ;
413
-
414
- // Clearing the previous timeout
415
- if( $( "#demo" ).data( "timeoutId" ) != "" ){
416
- clearTimeout( $( "#demo" ).data( "timeoutId" ) );
417
- $( "#demo" ).data( "timeoutId", "" ) ;
418
- }
419
-
420
- out = data.content.split("");
421
- model_id = data.model_id;
422
- temperature = data.temperature
423
- max_new_tokens = data.max_new_tokens
424
-
425
- $( "#outcome" ).append( "\n\n+ ------------------------------------\n| Model: " + model_id + "\n| Temperature: " + temperature + "\n| Max new tokens: " + max_new_tokens + "\n+ ------------------------------------\n\n" ) ;
426
- // Animating the generated output
427
- ( function typing_animation(){
428
- $( "#outcome" ).append( out.shift() ) ;
429
- $( "#outcome" ).scrollTop( $( "#outcome" )[0].scrollHeight ) ;
430
- if( out.length > 0 ) {
431
- const timeoutId = setTimeout( typing_animation, 5 );
432
- $( "#demo" ).data( "timeoutId", timeoutId ) ;
433
- }
434
- } )()
435
- },
436
- error: function(data) {
437
- out = data.responseJSON.error.message
438
- $( "#outcome" ).val(out);
439
- }
440
- })
441
- // Returning false so the form keeps user in the same page
442
- return false;
443
- });
444
  </script>
445
- <!-- <script src="https://unpkg.com/carbon-components/scripts/carbon-components.min.js"></script> -->
446
  </body>
447
- </html>
 
1
  <!DOCTYPE html>
2
  <html lang="en">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
+ <head>
5
+ <meta charset="UTF-8" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
7
+ <title>Responsible Prompting - Multi-Turn Chat</title>
 
 
 
 
 
 
 
 
8
 
9
+ <!-- IBM Plex Sans -->
10
+ <link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@300;400;500;600&display=swap"
11
+ rel="stylesheet" />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
 
13
+ <!-- Carbon CSS (for tabs and tags) -->
14
+ <link rel="stylesheet" href="static/styles/carbon-components.min.css"/>
 
 
 
 
 
 
 
 
 
 
15
 
16
+ <link rel="stylesheet" href="static/styles/style_multiturn.css"/>
17
 
18
+ <script type="text/javascript" src="static/demo/js/d3.v7.min.js"></script>
19
+ <script type="text/javascript" src="static/demo/js/jquery-3.7.1.min.js"></script>
20
+ <script type="text/javascript" src="static/demo/js/main.js"></script>
21
+ <script type="text/javascript" src="static/demo/js/marked.min.js"></script>
22
 
23
+ </head>
 
 
 
 
 
24
 
25
+ <body>
26
+ <div id="tooltip" style="opacity: 0;" class="tooltip"></div>
27
+
28
+ <a id='learn-more-container' href="https://github.com/IBM/responsible-prompting-api" target="_blank">
29
+ <div id='learn-more-text' >Learn More</div>
30
+ <img src="static/demo/imgs/arrow-up-right.svg" class="icon" style="color: #0f62fe; right: 0; padding: 1.5px"/>
31
+ </a>
32
+ <!-- ===== Header: Title + Carbon Tabs ===== -->
33
+ <div class="header-container">
34
+ <div style="display: flex; flex-direction: row; gap: 2rem;">
35
+ <div style="display: flex; flex-direction: column; gap: 1rem; padding-left: 1rem;">
36
+ <h4 style="display: flex; font-size: xx-large; font-weight: 300; flex: 1;">Responsible Prompting</h4>
37
+ <div style="display: flex;">
38
+ <div style="align-content: center;">Model: </div>
39
+ <select id="modelSelect"></select>
40
+ </div>
41
+ </div>
42
 
43
+ <div style="width: 55%;" class="intro">
44
+ <p>
45
+ Responsible Prompting is a tool that aims at supporting users in crafting prompts that embed responsible values and help avoid harmful prompts, in prompting-time.
46
+ </p>
47
+ </div>
48
+ </div>
49
+ </div>
 
 
50
 
51
+ <!-- === Chat View === -->
52
+ <div id="chat-content">
53
+ <div id="chat" class="chat-container"></div>
54
+
55
+ <!-- Input area -->
56
+ <div class="input-area">
57
+ <div id="userInputDiv" contenteditable placeholder="Enter your prompt...">Act as a professional designer with 20 years of experience creating and testing UX interfaces and landing sites for a variety of IT applications. We are in need of more people and an increased budget to be able to keep up with clients' needs. What kind of evidence should I gather to support my demands to gain more resources?</div>
58
+
59
+ <div style="display: flex; justify-content: space-between; gap: 1rem; align-items: center;">
60
+ <div id="recommendation"></div>
61
+ <!-- Send button -->
62
+ <button id="sendBtn" class="btn">
63
+ <img src="static/demo/imgs/send.svg" alt="Send" class="icon"/>
64
+ </button>
65
+ </div>
66
+ </div>
67
 
68
+ <div style="padding: 0.5rem; color: gray">AI responses may be inaccurate, please verify information independently.</div>
69
+ </div>
 
 
 
 
 
 
 
 
70
 
71
+ <script>
72
+ var modelId = '';
73
+ document.addEventListener('DOMContentLoaded', () => {
74
+ // Populate the different models options
75
+ // id -> id of the model on HF, name -> name displayed to the user
76
+ const models = [
77
+ { id: 'mistralai/Mistral-7B-Instruct-v0.3', name: 'Mistral 7B Instruct v0.3' },
78
+ { id: 'meta-llama/Llama-4-Scout-17B-16E-Instruct', name: 'Llama 4 Scout' },
79
+ ];
80
+ const modelSelect = document.getElementById('modelSelect');
81
+
82
+ models.forEach(model => {
83
+ const option = document.createElement('option');
84
+ option.value = model.id;
85
+ option.textContent = model.name;
86
+ modelSelect.appendChild(option);
87
+ });
88
+
89
+ // Set default selection
90
+ modelId = models[0].id;
91
+
92
+ // Record when model changes
93
+ modelSelect.addEventListener('change', function() {
94
+ const selectedModel = models.find(model => model.id === this.value);
95
+ modelId = selectedModel.id;
96
+ });
97
+ });
98
 
99
+ // To show the bottom of text in the prompt input box
100
+ var objDiv = document.getElementById("userInputDiv");
101
+ objDiv.scrollTop = objDiv.scrollHeight;
102
+
103
+ let generating = false;
104
+ $("#userInputDiv").on("input", function () {
105
+ if($("#userInputDiv").text().length > 0) {
106
+ if(!generating) $("#sendBtn").attr("disabled", false);
107
+ generateRecommendations("#sendBtn", "#userInputDiv", "#recommendation");
108
+ } else {
109
+ $("#sendBtn").attr("disabled", true);
110
  }
111
+ });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
 
113
+ // // To generate recommendation when the page loads
114
+ $("#userInputDiv").trigger('input');
 
 
 
 
 
 
 
 
 
 
115
 
116
+ $("#sendBtn").on("click", () => {
117
+ const rawText = $("#userInputDiv").text() || "";
118
+
119
+ // Clear input box and recommendations
120
+ $("#userInputDiv").text("");
121
+ $("#recommendation").empty();
122
+ $("#sendBtn").attr("disabled", true);
123
 
124
+ // Generate LLM response
125
+ generateResponse(rawText, "#chat", "#sendBtn");
126
+ });
127
+
128
+ // Pressing Enter (without Shift) also sends
129
+ $("#userInput").on("keydown", function (e) {
130
+ if (e.key === "Enter" && !e.shiftKey) {
131
+ e.preventDefault();
132
+ if (!$("#sendBtn").attr("disabled")) {
133
+ $("#sendBtn").click();
134
  }
135
  }
136
  });
137
 
138
+ $("#userInputDiv").on('keyup', () => {
139
+ if($("#userInputDiv").html() == "<br>") {
140
+ $("#userInputDiv").html("");
141
+ }
142
+ })
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
143
  </script>
 
144
  </body>
145
+ </html>