Skip to content

Commit 1b533a3

Browse files
committed
Replacing html type with text in all agents save for the resourceagent for the pre-approved html resources
1 parent 8fa21c9 commit 1b533a3

File tree

6 files changed

+68
-68
lines changed

6 files changed

+68
-68
lines changed

server/routes/chat/DEagent.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -96,23 +96,23 @@ export async function extract_DE_search_terms_from_query(
9696
return await validate_DE_response(response, ds, dataset_db_output.db_rows)
9797
}
9898
} else {
99-
return { type: 'html', html: 'Differential gene expression not supported for this dataset' }
99+
return { type: 'text', text: 'Differential gene expression not supported for this dataset' }
100100
}
101101
}
102102

103103
async function validate_DE_response(response: string, ds: any, db_rows: DbRows[]) {
104104
const response_type = safeParseLlmJson(response)
105-
let html = ''
105+
let text = ''
106106
let group1: any
107107
let samples1lst: any
108108
const name1 = generate_group_name(response_type.group1, db_rows)
109109
if (!response_type.group1) {
110-
html += 'group1 not present in DE output'
110+
text += 'group1 not present in DE output'
111111
} else {
112112
// Validate filter terms
113113
const validated_filters = validate_filter(response_type.group1, ds, name1)
114-
if (validated_filters.html.length > 0) {
115-
html += validated_filters.html
114+
if (validated_filters.text.length > 0) {
115+
text += validated_filters.text
116116
} else {
117117
const samples1 = await get_samples({ filter: validated_filters.simplefilter }, ds, true) // true is to bypass permission check
118118
samples1lst = samples1.map((item: any) => ({
@@ -130,11 +130,11 @@ async function validate_DE_response(response: string, ds: any, db_rows: DbRows[]
130130
let samples2lst: any
131131
const name2 = generate_group_name(response_type.group2, db_rows)
132132
if (!response_type.group2) {
133-
html += 'group2 not present in DE output'
133+
text += 'group2 not present in DE output'
134134
} else {
135135
const validated_filters = validate_filter(response_type.group2, ds, name2)
136-
if (validated_filters.html.length > 0) {
137-
html += validated_filters.html
136+
if (validated_filters.text.length > 0) {
137+
text += validated_filters.text
138138
} else {
139139
const samples2 = await get_samples({ filter: validated_filters.simplefilter }, ds, true) // true is to bypass permission check
140140
samples2lst = samples2.map((item: any) => ({
@@ -155,16 +155,16 @@ async function validate_DE_response(response: string, ds: any, db_rows: DbRows[]
155155
if (response_type.method == 'edgeR' || response_type.method == 'limma' || response_type.method == 'wilcoxon') {
156156
settings = { volcano: { method: response_type.method } }
157157
} else {
158-
html += 'Unknown DE method: ' + response_type.method
158+
text += 'Unknown DE method: ' + response_type.method
159159
}
160160
}
161161

162-
if (html.length > 0) {
163-
html = removeLastOccurrence(
164-
html,
162+
if (text.length > 0) {
163+
text = removeLastOccurrence(
164+
text,
165165
'For now, the maximum number of filter terms supported through the chatbot is ' + num_filter_cutoff // Remove duplicated statements in error message
166166
)
167-
return { type: 'html', html: html }
167+
return { type: 'text', text }
168168
} else {
169169
const pp_plot_json: any = { childType: 'volcano', termType: 'geneExpression', chartType: 'differentialAnalysis' }
170170
const groups = [group1, group2]

server/routes/chat/filter.ts

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ export const FILTER_DESCRIPTION =
5151
'"stop" an optional filter which is defined when a higher cutoff is defined in the user input for the numeric variable. '
5252

5353
function sortSameCategoricalFilterKeys(filters: any[], ds: any): any {
54-
let html = ''
54+
let text = ''
5555
const keys = filters.map(f => f.term)
56-
if (new Set(keys).size == keys.length) return { filters: filters, html: html } // All filter terms have separate keys
56+
if (new Set(keys).size == keys.length) return { filters: filters, text } // All filter terms have separate keys
5757

5858
const seen = new Set<string>()
5959
const categorical_filter_terms_with_multiple_fields = new Set<string>()
@@ -70,7 +70,7 @@ function sortSameCategoricalFilterKeys(filters: any[], ds: any): any {
7070
ds.cohort.termdb.q.termjsonByOneid(key.toUpperCase()) ||
7171
ds.cohort.termdb.q.termjsonByOneid(key.toLowerCase())
7272
if (!term) {
73-
html += 'invalid filter id:' + key
73+
text += 'invalid filter id:' + key
7474
} else {
7575
if (term.type == 'categorical') {
7676
const multiple_fields = filters.filter(x => x.term == key)
@@ -97,29 +97,29 @@ function sortSameCategoricalFilterKeys(filters: any[], ds: any): any {
9797
}
9898
}
9999
}
100-
return { filters: sorted_filter, html: html }
100+
return { filters: sorted_filter, text }
101101
}
102102

103103
export function validate_filter(filters: FilterTerm[], ds: any, group_name: string): any {
104104
if (!Array.isArray(filters)) throw 'filter is not array'
105105
const sorted_filters = sortSameCategoricalFilterKeys(filters, ds)
106-
let filter_result: { simplefilter?: any; html: string } = { html: sorted_filters.html }
106+
let filter_result: { simplefilter?: any; text: string } = { text: sorted_filters.text }
107107
if (sorted_filters.filters.length <= 2) {
108108
// If number of filter terms <=2 then simply a single iteration of generate_filter_term() is sufficient
109109
const generated = generate_filter_term(sorted_filters.filters, ds)
110110
filter_result.simplefilter = generated.simplefilter
111-
filter_result.html += generated.html
111+
filter_result.text += generated.text
112112
} else {
113113
if (sorted_filters.filters.length > num_filter_cutoff) {
114-
filter_result.html +=
114+
filter_result.text +=
115115
'For now, the maximum number of filter terms supported through the chatbot is ' + num_filter_cutoff
116116
if (group_name.length > 0) {
117117
// Group name is blank for summary filter, this is case for groups
118-
filter_result.html +=
118+
filter_result.text +=
119119
' . The number of filter terms for group ' + group_name + ' is ' + sorted_filters.filters.length + '\n' // Added temporary logic to restrict the number of filter terms to num_filter_cutoff.
120120
} else {
121121
// For summary filter prompts which do not have a group
122-
filter_result.html += 'The number of filter terms for this query is ' + sorted_filters.filters.length
122+
filter_result.text += 'The number of filter terms for this query is ' + sorted_filters.filters.length
123123
}
124124
} else {
125125
// When number of filter terms is greater than 2, then in each iteration the first two terms are taken and a filter object is created which is passed in the following iteration as a filter term
@@ -135,11 +135,11 @@ export function validate_filter(filters: FilterTerm[], ds: any, group_name: stri
135135
}
136136
}
137137
}
138-
return { simplefilter: filter_result.simplefilter, html: filter_result.html }
138+
return { simplefilter: filter_result.simplefilter, text: filter_result.text }
139139
}
140140

141141
function generate_filter_term(filters: any, ds: any) {
142-
let invalid_html = ''
142+
let invalid_text = ''
143143
const localfilter: any = { type: 'tvslst', in: true, lst: [] as any[] }
144144
for (const f of filters) {
145145
if (f.type == 'tvslst') {
@@ -150,7 +150,7 @@ function generate_filter_term(filters: any, ds: any) {
150150
ds.cohort.termdb.q.termjsonByOneid(f.term.toUpperCase()) ||
151151
ds.cohort.termdb.q.termjsonByOneid(f.term.toLowerCase())
152152
if (!term) {
153-
invalid_html += 'invalid filter id:' + f.term
153+
invalid_text += 'invalid filter id:' + f.term
154154
} else {
155155
if (f.join) {
156156
localfilter.join = f.join
@@ -164,7 +164,7 @@ function generate_filter_term(filters: any, ds: any) {
164164
if (ck.toLowerCase() == category.toLowerCase()) cat = ck
165165
else if (term.values[ck].label?.toLowerCase() == category.toLowerCase()) cat = ck
166166
}
167-
if (!cat) invalid_html += 'invalid category from ' + JSON.stringify({ term: f.term, category })
167+
if (!cat) invalid_text += 'invalid category from ' + JSON.stringify({ term: f.term, category })
168168
else values.push({ key: cat })
169169
}
170170
localfilter.lst.push({
@@ -193,7 +193,7 @@ function generate_filter_term(filters: any, ds: any) {
193193
range.start = Number(f.start)
194194
range.stop = Number(f.stop)
195195
} else {
196-
invalid_html += 'Neither greater or lesser defined'
196+
invalid_text += 'Neither greater or lesser defined'
197197
}
198198
numeric.tvs.ranges.push(range)
199199
localfilter.lst.push(numeric)
@@ -203,7 +203,7 @@ function generate_filter_term(filters: any, ds: any) {
203203
}
204204
if (filters.length > 1 && !localfilter.join) {
205205
localfilter.join = 'and' // Hardcoding and when the LLM is not able to detect the connection
206-
//invalid_html += 'Connection (and/or) between the filter terms is not clear, please try to rephrase your question'
206+
//invalid_text += 'Connection (and/or) between the filter terms is not clear, please try to rephrase your question'
207207
}
208-
return { simplefilter: localfilter, html: invalid_html }
208+
return { simplefilter: localfilter, text: invalid_text }
209209
}

server/routes/chat/matrixagent.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -79,16 +79,16 @@ export async function extract_matrix_search_terms_from_query(
7979
function validate_matrix_response(response: string, common_genes: string[], dataset_json: any, ds: any) {
8080
const response_type = safeParseLlmJson(response)
8181
const pp_plot_json: any = { chartType: 'matrix' }
82-
let html = ''
82+
let text = ''
8383

84-
if (response_type.html) html = response_type.html
84+
if (response_type.text) text = response_type.text
8585

8686
// Must have at least one of terms or geneNames
8787
if (
8888
(!response_type.terms || response_type.terms.length == 0) &&
8989
(!response_type.geneNames || response_type.geneNames.length == 0)
9090
) {
91-
html += 'At least one clinical term or gene name is required for a matrix plot'
91+
text += 'At least one clinical term or gene name is required for a matrix plot'
9292
}
9393

9494
// Validate dictionary terms — use shorthand { id } at tw top level
@@ -97,7 +97,7 @@ function validate_matrix_response(response: string, common_genes: string[], data
9797
for (const t of response_type.terms) {
9898
const term: any = ds.cohort.termdb.q.termjsonByOneid(t)
9999
if (!term) {
100-
html += 'invalid term id:' + t + ' '
100+
text += 'invalid term id:' + t + ' '
101101
} else {
102102
twLst.push({ id: term.id })
103103
}
@@ -110,7 +110,7 @@ function validate_matrix_response(response: string, common_genes: string[], data
110110
for (const g of response_type.geneNames) {
111111
const gene_hits = common_genes.filter(gene => gene == g.toLowerCase())
112112
if (gene_hits.length == 0) {
113-
html += 'invalid gene name:' + g + ' '
113+
text += 'invalid gene name:' + g + ' '
114114
} else {
115115
const geneName = g.toUpperCase()
116116
if (dataset_json.hasGeneExpression) {
@@ -125,15 +125,15 @@ function validate_matrix_response(response: string, common_genes: string[], data
125125
// Validate filters
126126
if (response_type.simpleFilter && response_type.simpleFilter.length > 0) {
127127
const validated_filters = validate_filter(response_type.simpleFilter, ds, '')
128-
if (validated_filters.html.length > 0) {
129-
html += validated_filters.html
128+
if (validated_filters.text.length > 0) {
129+
text += validated_filters.text
130130
} else {
131131
pp_plot_json.filter = validated_filters.simplefilter
132132
}
133133
}
134134

135-
if (html.length > 0) {
136-
return { type: 'html', html: html }
135+
if (text.length > 0) {
136+
return { type: 'text', text }
137137
} else {
138138
// Structure as termgroups matching what matrix.js expects:
139139
// termgroups: [{ name: '', lst: [ { term: {...} }, ... ] }]

server/routes/chat/samplescatteragent.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export async function extract_samplescatter_terms_from_query(
1313
testing: boolean
1414
) {
1515
if (!dataset_json.prebuiltPlots || dataset_json.prebuiltPlots.length == 0) {
16-
return { type: 'html', html: 'No pre-built scatter plots (t-SNE/UMAP) are available for this dataset' }
16+
return { type: 'text', text: 'No pre-built scatter plots (t-SNE/UMAP) are available for this dataset' }
1717
}
1818

1919
const Schema = {
@@ -99,20 +99,20 @@ export async function extract_samplescatter_terms_from_query(
9999

100100
function validate_samplescatter_response(response: string, common_genes: string[], dataset_json: any, ds: any) {
101101
const response_type = safeParseLlmJson(response)
102-
let html = ''
102+
let text = ''
103103

104-
if (response_type.html) html = response_type.html
104+
if (response_type.text) text = response_type.text
105105

106106
// Validate plotName against prebuiltPlots
107107
if (!response_type.plotName) {
108-
html += 'plotName is required for sample scatter output'
108+
text += 'plotName is required for sample scatter output'
109109
} else {
110110
const matchedPlot = dataset_json.prebuiltPlots.find(
111111
(p: any) => p.name.toLowerCase() == response_type.plotName.toLowerCase()
112112
)
113113
if (!matchedPlot) {
114114
const availablePlots = dataset_json.prebuiltPlots.map((p: any) => p.name).join(', ')
115-
html += 'Unknown plot name: ' + response_type.plotName + '. Available plots are: ' + availablePlots
115+
text += 'Unknown plot name: ' + response_type.plotName + '. Available plots are: ' + availablePlots
116116
}
117117
}
118118

@@ -133,8 +133,8 @@ function validate_samplescatter_response(response: string, common_genes: string[
133133
return
134134
}
135135
const termValidation = validate_term(termName, common_genes, dataset_json, ds)
136-
if (termValidation.html.length > 0) {
137-
html += termValidation.html
136+
if (termValidation.text.length > 0) {
137+
text += termValidation.text
138138
} else {
139139
const tw: any = { ...termValidation.term_type }
140140
if (termValidation.category == 'float' || termValidation.category == 'integer') {
@@ -151,15 +151,15 @@ function validate_samplescatter_response(response: string, common_genes: string[
151151
// Validate filters
152152
if (response_type.simpleFilter && response_type.simpleFilter.length > 0) {
153153
const validated_filters = validate_filter(response_type.simpleFilter, ds, '')
154-
if (validated_filters.html.length > 0) {
155-
html += validated_filters.html
154+
if (validated_filters.text.length > 0) {
155+
text += validated_filters.text
156156
} else {
157157
pp_plot_json.filter = validated_filters.simplefilter
158158
}
159159
}
160160

161-
if (html.length > 0) {
162-
return { type: 'html', html: html }
161+
if (text.length > 0) {
162+
return { type: 'text', text }
163163
} else {
164164
return { type: 'plot', plot: pp_plot_json }
165165
}

server/routes/chat/summaryagent.ts

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -123,16 +123,16 @@ export async function extract_summary_terms(
123123
function validate_summary_response(response: string, common_genes: string[], dataset_json: any, ds: any) {
124124
const response_type = safeParseLlmJson(response)
125125
const pp_plot_json: any = { chartType: 'summary' }
126-
let html = ''
127-
if (response_type.html) html = response_type.html
126+
let text = ''
127+
if (response_type.text) text = response_type.text
128128
if (!response_type.term) {
129-
html += 'term type is not present in summary output'
130-
return { type: 'html', html: html }
129+
text += 'term type is not present in summary output'
130+
return { type: 'text', text }
131131
}
132132
const term1_validation = validate_term(response_type.term, common_genes, dataset_json, ds)
133-
if (term1_validation.html.length > 0) {
134-
html += term1_validation.html
135-
return { type: 'html', html: html }
133+
if (term1_validation.text.length > 0) {
134+
text += term1_validation.text
135+
return { type: 'text', text }
136136
} else {
137137
pp_plot_json.term = term1_validation.term_type
138138
if (term1_validation.category == 'float' || term1_validation.category == 'integer') {
@@ -143,9 +143,9 @@ function validate_summary_response(response: string, common_genes: string[], dat
143143

144144
if (response_type.term2) {
145145
const term2_validation = validate_term(response_type.term2, common_genes, dataset_json, ds)
146-
if (term2_validation.html.length > 0) {
147-
html += term2_validation.html
148-
return { type: 'html', html: html }
146+
if (term2_validation.text.length > 0) {
147+
text += term2_validation.text
148+
return { type: 'text', text }
149149
} else {
150150
pp_plot_json.term2 = term2_validation.term_type
151151
if (term2_validation.category == 'float' || term2_validation.category == 'integer') {
@@ -164,8 +164,8 @@ function validate_summary_response(response: string, common_genes: string[], dat
164164
const resolved = resolveChildType(pp_plot_json.category, pp_plot_json.category2, llmChildType)
165165

166166
if (resolved.error) {
167-
html += resolved.error
168-
return { type: 'html', html: html }
167+
text += resolved.error
168+
return { type: 'text', text }
169169
} else {
170170
pp_plot_json.childType = resolved.childType
171171
// For two numeric variables displayed as violin/boxplot, discretize term2
@@ -185,9 +185,9 @@ function validate_summary_response(response: string, common_genes: string[], dat
185185

186186
if (response_type.simpleFilter && response_type.simpleFilter.length > 0) {
187187
const validated_filters = validate_filter(response_type.simpleFilter, ds, '')
188-
if (validated_filters.html.length > 0) {
189-
html += validated_filters.html
190-
return { type: 'html', html: html }
188+
if (validated_filters.text.length > 0) {
189+
text += validated_filters.text
190+
return { type: 'text', text }
191191
} else {
192192
pp_plot_json.filter = validated_filters.simplefilter
193193
}

server/routes/chat/utils.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ export function extractGenesFromPrompt(prompt: string, genes_list: string[]): st
161161
}
162162

163163
export function validate_term(response_term: string, common_genes: string[], dataset_json: any, ds: any) {
164-
let html = ''
164+
let text = ''
165165
let term_type: any
166166
let category: string = ''
167167
const term: any =
@@ -172,21 +172,21 @@ export function validate_term(response_term: string, common_genes: string[], dat
172172
const gene_hits = common_genes.filter(gene => gene == response_term.toLowerCase())
173173
if (gene_hits.length == 0) {
174174
// Neither a clinical term nor a gene
175-
html += 'invalid term id:' + response_term
175+
text += 'invalid term id:' + response_term
176176
} else {
177177
if (dataset_json.hasGeneExpression) {
178178
// Check to see if dataset support gene expression
179179
term_type = { term: { gene: response_term.toUpperCase(), type: 'geneExpression' } }
180180
category = 'float'
181181
} else {
182-
html += 'Dataset does not support gene expression'
182+
text += 'Dataset does not support gene expression'
183183
}
184184
}
185185
} else {
186186
term_type = { id: term.id }
187187
category = term.type
188188
}
189-
return { term_type: term_type, html: html, category: category }
189+
return { term_type, text, category }
190190
}
191191

192192
export async function parse_geneset_db(genedb: string) {

0 commit comments

Comments
 (0)