This commit is contained in:
yumoqing 2024-04-08 18:12:29 +08:00
parent 7d45d9b71f
commit d6c2363da2
5 changed files with 58 additions and 34 deletions

BIN
bricks/.DS_Store vendored

Binary file not shown.

View File

@ -83,7 +83,7 @@ bricks.str2data = function(s, d){
return d[key]; return d[key];
} }
return s.replace(regex, (k, key, typ) => { return s.replace(regex, (k, key, typ) => {
if (d.hasOwnProperty(key){ if (d.hasOwnProperty(key)){
var f = funcs[typ]; var f = funcs[typ];
if (f){ if (f){
return f(d[key]); return f(d[key]);

View File

@ -277,3 +277,6 @@ body {
margin-bottom: 10px; margin-bottom: 10px;
background-color:#44fefe; background-color:#44fefe;
} }
.llm_title {
background-color:#fafafa;
}

View File

@ -201,26 +201,26 @@ bricks.HttpResponse = class extends bricks.HttpText {
} }
} }
bricks.HttpResponseStream = class extends bricks.HttpText { bricks.HttpResponseStream = class extends bricks.HttpResponse {
async get_result_data(resp){ async handle_chunk(resp, handler){
const reader = resp.body.getReader(); const reader = resp.body.getReader();
const decoder = new TextDecoder('utf-8'); const decoder = new TextDecoder('utf-8');
let result = await reader.read(); let result = await reader.read();
var buffer = ''; var buff_ = '';
while (!result.done) { while (!result.done) {
const text = decoder.decode(result.value); const text = decoder.decode(result.value);
buffer += text; buff_ += text;
const newline = /\r?\n/gm; const newline = /\r?\n/gm;
var rez = newline.exec(buffer); var rez = newline.exec(buff_);
while (rez){ while (rez){
yield buffer.substring(0, rez.index); handler(buff_.substring(0, rez.index));
buffer = buffer.substring(newline.lastIndex); buff_ = buff_.substr(newline.lastIndex);
rez = newline.exec(buffer); rez = newline.exec(buff_);
} }
result = await reader.read() result = await reader.read()
} }
if (buffer != ''){ if (buff_ != ''){
yield bufffer; handler(buff_);
} }
} }
} }

View File

@ -1,11 +1,14 @@
var bricks = window.bricks || {} var bricks = window.bricks || {}
bricks.LlmDialog = class extends bricks.VScrollPanel { bricks.LlmDialog = class extends bricks.VBox {
/* /*
{ {
"url": "url":
"model", "model",
"mapi":
"user_msg_css" "user_msg_css"
"llm_icon"
"title_ccs"
"llm_msg_css" "llm_msg_css"
} }
method: method:
@ -14,46 +17,64 @@ bricks.LlmDialog = class extends bricks.VScrollPanel {
llm_answer event.params = assistant answer content llm_answer event.params = assistant answer content
*/ */
constructor(opts){ constructor(opts){
opts.height = opts.height || '100%';
super(opts); super(opts);
this.title_w = new bricks.HBox({cheight:2});
this.title_w.add_widget(new bricks.Icon({
url:this.llm_icon||bricks_resource('imgs/llm.png')
}));
this.title_w.set_css(this.title_ccs||'llm_title');
var t_w = new bricks.Text({text:this.model});
this.title_w.add_widget(t_w);
this.add_widget(this.title_w);
var filler = new bricks.Filler({});
this.body = new bricks.VScrollPanel({height:'100%'});
filler.add_widget(this.body);
this.add_widget(filler);
this.messages = []; this.messages = [];
} }
set_prompt(prompt){ async set_prompt(prompt){
var w = bricks.MdWidget({mdtext:prompt}); var w = new bricks.MdWidget({mdtext:prompt});
w.set_css(this.user_msg_css||'user_msg'); w.set_css(this.user_msg_css||'user_msg');
this.add_widget(w); this.body.add_widget(w);
this.llm_request(prompt); await this.llm_request(prompt);
}
llm_request(prompt){
var d = {
messages:this.messages,
model:this.model,
prompt:prompt
}
var hr = bricks.HttpResponseStream();
var w = bricks.MdWidget({mdtext:''});
w.set_css(this.llm_msg_css||'llm_msg');
this.add_widget(w);
for await (const line of hr.get(this.url, {params=d})) {
this.processLine(line, w);
} }
async llm_request(prompt){
this.messages.push({ this.messages.push({
role:'user', role:'user',
content:prompt content:prompt
}); });
var d = {
messages:this.messages,
mapi:this.mapi,
prompt:prompt,
model:this.model,
}
var hr = new bricks.HttpResponseStream();
var resp = await hr.post(this.url, {params:d});
await hr.handle_chunk(resp, this.processLine.bind(this));
this.messages.push({ this.messages.push({
role:'assistant', role:'assistant',
content:w.md_content content:this.llm_msg_w.md_content
}); });
this.llm_msg_w = null;
var d = { var d = {
model:this.model, model:this.model,
messages:this.messages messages:this.messages
} }
this.dispatch('llm_answered', d); this.dispatch('llm_answered', d);
} }
processLine(l, w){ processLine(l){
var d = JSON.parse(); var d = JSON.parse(l);
var txt = w.md_content + d.content; if (!this.llm_msg_w) {
w.set_content(txt); this.llm_msg_w = new bricks.MdWidget({mdtext:d.content});
this.llm_msg_w.set_css(this.llm_msg_css||'llm_msg');
this.body.add_widget(this.llm_msg_w);
return;
}
var txt = this.llm_msg_w.md_content + d.content;
this.llm_msg_w.set_content(txt);
this.body.dom_element.scrollTop = this.body.dom_element.scrollHeight;
} }
} }