console
layui.use(function(){
var table = layui.table, element = layui.element, form = layui.form,
$ = layui.$,laytpl = layui.laytpl,layer = layui.layer;
form.set({ autocomplete: 'off' });
// 已知数据渲染
var tb_kn = table.render({
elem: '#ID-table-1', height: 140,
cols: [[ //标题栏
{type: 'numbers'},
{field: 'id', title: 'ID', width: 80, sort: true},
{field: 'msg', title: '内容'},
]],
data: [{id:0,'msg':'你好'}],
skin: 'line',
//even: true,
});
//表单渲染
laytpl($('#model_tpl').html()).render([
{name:'temperature',title:'模型温度',min:'0',max:'1',step:'0.1',val: '0.7',tip:'增加温度将使模型回答更具创造性'},
{name:'num-predict',title:'最大标记数',min:'-2',max:'128',step:'1',val:'-2',tip:'生成预测最大标记数。默认128,-1无限生成,-2填充上下文'},
{name:'top-k',title:'多样性概率',min:'0',max:'100',step:'1',val:'40',tip:'减少生成无意义内容的概率,较高的值(例如,100)将产生更多样化的答案,而较低的值(例如,10)将更加保守'},
{name:'top-p',title:'多样性-微调',min:'0',max:'1',step:'0.1',val:'0.9',tip:'减少生成无意义内容的概率,较高的值(例如,100)将产生更多样化的答案,而较低的值(例如,10)将更加保守'},
{name:'tfs_z',title:'采样减少',min:'1',max:'2',step:'0.1',val:'1',tip:'无尾采样用于减少输出中不太可能的令牌的影响。更高的值(例如2.0)将更多地减少影响,而1.0的值将禁用此设置。(默认值:1)'},
{name:'repeat_last_n',title:'回溯距离',min:'-1',max:'100',step:'1',val:'64',tip:'设置模型回溯的距离,以防止重复。(默认值:64,0=禁用,-1=令牌窗口大小)'},
{name:'repeat_penalty',title:'惩罚重复力度',min:'0',max:'1.5',step:'0.1',val:'1.1',tip:'设置惩罚重复的力度。较高的值(例如1.5)将更严厉地惩罚重复,而较低的值(如0.9)将更宽容。(默认值:1.1)'},
{name:'mirostat_tau',title:'学习速率',min:'0',max:'1',step:'0.1',val:'0.1',tip:'影响算法对生成文本反馈的响应速度。较低的学习率将导致较慢的调整,而较高的学习率会使算法更具响应性。(默认值:0.1)。'},
{name:'mirostat_eta',title:'输出平衡',min:'0',max:'10',step:'0.1',val:'5',tip:'控制输出的连贯性和多样性之间的平衡。较低的值将导致文本更加集中和连贯。(默认值:5.0)'},
// {name:'temperature',title:'模型温度',min:'0',max:'1',step:'0.1',tip:'提示'},
],function(str) {
layui.$('#model_param').append(str);
form.render($('input[type="number"]'));
element.render('progress', $('.layui-progress-bar'));
});
//代码高亮
layui.code({
elem: '.code-model-info', highlighter: 'hljs', lang: 'json',
codeStyle: 'height: 210px;', previewStyle: 'word-wrap: break-word;',
codeRender: function (code, opts) {
return hljs.highlight(code, {language: opts.lang}).value;
}
});
//数字和进度条组合
$('input[type="number"]').on('change',function(){
var el = $(this);
if(el.attr('lay-affix') === 'number'){
var n = el.attr('name'), max = el.attr('max'), min = el.attr('min'), v = el.val();
element.progress(n + '-bar', Math.ceil(((v-min)/(max-min))*100) + '%');
}
})
form.on('input-affix', function(data){
var elem = data.elem, el = $(elem),affix = data.affix;
if(affix === 'number'){
var n = el.attr('name'), max = el.attr('max'), min = el.attr('min'), v = el.val();
element.progress(n + '-bar', Math.ceil(((v-min)/(max-min))*100) + '%');
}
});
$('#btn_add').on('click',function(){
layer.prompt({title: '请输入知识文本', formType: 2}, function(value, index, elem){
if(value === '') return elem.focus();
layer.close(index);
var id = tb_kn.config.id, ds = table.getData(id);
ds.push({id:ds.length,msg:value});
table.reloadData(id, {data: ds });
});
})
//表单渲染
laytpl($('#chat_tpl').html()).render([
{role:'system',content:'系统提示'},
{role:'user',content:'你好'},
{role:'load',content:'加载'},
],function(str) {
layui.$('#chat_view').append(str);
setTimeout(()=>{
layui.$('#chat_view').children().last().remove();
laytpl($('#chat_tpl').html()).render([
{role:'assistant',content:'在呢'}
],function(str) {
layui.$('#chat_view').append(str + '<hr>');
});
},1000);
});
// console.log(tb_kn)
let load_ = true;
$('#chat_send').on('click',function(){
let el = $('#chat_msg'), v = el.val();
if(v === '') return el.focus();
el.attr('disabled',true).val('');
laytpl($('#chat_tpl').html()).render([
{role:'user',content:v},
{role:'load',content:'加载'},
],function(str) {
layui.$('#chat_view').append(str);
setTimeout(()=>{
el.attr('disabled',false);
layui.$('#chat_view').children().last().remove();
laytpl($('#chat_tpl').html()).render([
{role:'assistant',content:v + '<br> 请说'}
],function(str) {
layui.$('#chat_view').append(str + '<hr>');
});
},1000);
});
})
});
<div class="layui-bg-gray" style="padding: 6px;">
<div class="layui-row layui-col-space4">
<div class="layui-col-sm6">
<div class="layui-card">
<div class="layui-card-header">本地AI-spring调用ollama模型信息</div>
<div class="layui-card-body">
<form class="layui-form" action="" lay-filter="form-all">
<fieldset class="layui-elem-field layui-field-title">
<legend>ollama</legend>
</fieldset>
<div class="layui-form-item">
<label class="layui-form-label">ollama地址</label>
<div class="layui-input-block">
<input type="text" name="username" placeholder="默认 localhost:11434" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">AI模型</label>
<div class="layui-input-block">
<input type="radio" name="model" value="llama2" title="llama2" checked>
<input type="radio" name="model" value="mistral" title="mistral">
<input type="radio" name="model" value="phi" title="phi">
<input type="radio" name="model" value="deepseek" title="deepseek">
</div>
</div>
<div class="layui-collapse" lay-accordion>
<div class="layui-colla-item">
<div class="layui-colla-title">模型信息</div>
<div class="layui-colla-content">
<pre class="layui-code code-model-info" lay-options="{}">{"modelfile":""}</pre>
</div>
</div>
<div class="layui-colla-item">
<div class="layui-colla-title">模型参数</div>
<div class="layui-colla-content layui-show" id="model_param" style="height:450px;overflow:auto">
<div class="layui-form-item">
<blockquote class="layui-elem-quote layui-quote-nm" style="height:40px;overflow:auto">
暂未设置参数:numa、num_batch、num_gqa、num_gpu、main_gpu、low_vram、f16_kv、logits_all、
vocab_only、use_mmap、use_mlock、embedding_only、rope_frequency_base、
rope_frequency_scale、num_keep、typical_p、presence_penalty、frequency_penalty、
penalize_newline
</blockquote>
</div>
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">聊天提示</label>
<div class="layui-input-block">
<textarea name="system-tip" rows="3" placeholder="定义 AI 生成响应的上下文和指令。您应该提供精心设计的提示,以便人工智能可以生成相关且准确的响应" class="layui-textarea"
>根据以下对话、相关背景和后续问题,回答用户当前提出的问题。根据需要,按照用户说明,仅返回您对上述信息问题的回答。</textarea>
</div>
</div>
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">查询拒绝响应</label>
<div class="layui-input-block">
<textarea name="refute-tip" rows="2" placeholder="处于 查询 模式时,当未找到上下文时,您可能希望返回自定义拒绝响应。" class="layui-textarea"
>没有相关信息来回答您的查询。</textarea>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">随机数种子</label>
<div class="layui-input-inline">
<input type="number" name="seed" class="layui-input" value="0" lay-affix="number">
</div>
<div class="layui-form-mid layui-text-em">
<i class="layui-icon layui-icon-tips" title="设置用于生成的随机数种子。将其设置为特定数字将使模型为同一提示生成相同的文本。(默认值:0)"></i>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">令牌大小</label>
<div class="layui-input-inline">
<input type="number" name="num_ctx" class="layui-input" value="2048" lay-affix="number">
</div>
<div class="layui-form-mid layui-text-em">
<i class="layui-icon layui-icon-tips" title="设置用于生成下一个令牌的上下文窗口的大小。(默认值:2048)"></i>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">控制困惑
<i class="layui-icon layui-icon-tips" title="启用Mirostat采样以控制困惑。(默认值:0,0=禁用,1=Mirostat,2=Mirostat2.0)"></i>
</label>
<div class="layui-input-block">
<input type="radio" name="mirostat" value="0" title="禁用" checked>
<input type="radio" name="mirostat" value="1" title="Mirostat">
<input type="radio" name="mirostat" value="2" title="Mirostat2.0">
</div>
</div>
<!-- 动态插入元素 -->
</div>
</div>
</div>
</form>
</div>
</div>
</div>
<div class="layui-col-sm6">
<div class="layui-card">
<div class="layui-card-header">聊天信息</div>
<div class="layui-card-body">
<fieldset class="layui-elem-field">
<legend>知识库信息
<button type="button" class="layui-btn layui-btn-xs" id="btn_add">
<i class="layui-icon layui-icon-add-1"></i>
</button>
</legend>
<div class="layui-field-box">
<table class="layui-hide" id="ID-table-1"></table>
</div>
</fieldset>
<fieldset class="layui-elem-field">
<legend>聊天</legend>
<div class="layui-field-box" id="chat_view" style="height:340px;overflow: auto;">
</div>
</fieldset>
<div class="layui-btn-group">
<button type="button" class="layui-btn layui-btn-sm layui-btn-normal" id="chat_send">
<i class="layui-icon layui-icon-chat"></i>发送
</button>
</div>
<textarea id="chat_msg" rows="2" placeholder="请输入" class="layui-textarea"
></textarea>
</div>
</div>
</div>
</div>
</div>
</div>
<script id="model_tpl" type="text/html">
{{# layui.each(d, function(index, item){ }}
<div class="layui-form-item">
<label class="layui-form-label">{{= item.title }}</label>
<div class="layui-input-inline">
<input type="number" name="{{= item.name }}" class="layui-input" lay-affix="number"
min="{{= item.min || '0' }}" step="{{= item.step || '1' }}"
max="{{= item.max || '100' }}" value="{{= item.val || '' }}">
<div class="layui-progress" lay-filter="{{= item.name }}-bar">
<div class="layui-progress-bar"
lay-percent="{{= item.val ? Math.ceil(((item.val-item.min)/(item.max-item.min))*100) : '0' }}%"
style="width:{{= item.val ? Math.ceil(((item.val-item.min)/(item.max-item.min))*100) : '0' }}%"></div>
</div>
</div>
<div class="layui-form-mid layui-text-em">
<i class="layui-icon layui-icon-tips" title="{{= item.tip }}"></i>
{{= (item.min || '0') + ' 到 ' + (item.max || '100') }}
</div>
</div>
{{# }); }}
</script>
<script id="chat_tpl" type="text/html">
{{# layui.each(d, function(index, item){ }}
{{# if(item){ }}
<div class="layui-row layui-col-space1" style="margin-bottom: 10px">
{{# if(item.role === 'user'){ }}
<div class="layui-col-xs11">
<div style="background: deepskyblue;padding: 6px;border-radius: .9375rem .3125rem 1.25rem .9375rem;">
{{- item.content }}</div>
</div>
<div class="layui-col-xs1">
<i class="layui-icon layui-icon-friends" style="float:right;color:deepskyblue"></i>
</div>
{{# }else if(item.role === 'system'){ }}
<div class="layui-col-xs1"><i class="layui-icon layui-icon-set-fill" style="color:aqua"></i></div>
<div class="layui-col-xs11">
<div style="background: aqua;padding: 6px;border-radius: .3125rem .9375rem .9375rem 1.25rem;">
{{- item.content }}</div>
</div>
{{# }else{ }}
<div class="layui-col-xs1"><i class="layui-icon layui-icon-reply-fill"></i></div>
<div class="layui-col-xs11">
<div style="background: aliceblue;padding: 6px;border-radius: .3125rem .9375rem .9375rem 1.25rem;">
{{# if(item.role === 'assistant'){ }}
{{# if(item.content.indexOf('think>')){ }}
{{- item.content.replace('think>','pre style="color:grey;">').replace('think>','pre><hr>') }}
{{# }else{ }}
{{- item.content }}
{{# } }}
{{# }else{ }}
<i class="layui-icon layui-anim layui-anim-rotate layui-anim-loop"></i>
{{# } }}
</div></div>
{{# } }}
</div>
{{# } }}
{{# }); }}
</script>