Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1af481f5f9 | |||
| 317d1c4c41 | |||
| a703860512 | |||
| 1cd1c8ea0d | |||
| 53ef3bbf4f | |||
| ab7b8aad7c | |||
| c49213282b | |||
| 3c87fc5b31 | |||
| 9684508e1d | |||
| bb0edae200 | |||
| acb68a4a1e | |||
| 46dd6f3243 | |||
| ecab072890 |
+2
-1
@@ -7,4 +7,5 @@ configs/config.yaml
|
||||
**/.DS_Store
|
||||
temp
|
||||
cmd_config.json
|
||||
addons/plugins/
|
||||
addons/plugins/
|
||||
data/
|
||||
|
||||
@@ -32,6 +32,11 @@
|
||||
1. 可视化面板
|
||||
2. Docker 一键部署项目:[链接](https://astrbot.soulter.top/center/docs/%E9%83%A8%E7%BD%B2/%E9%80%9A%E8%BF%87Docker%E9%83%A8%E7%BD%B2)
|
||||
|
||||
🌍支持的消息平台/接口
|
||||
- go-cqhttp(QQ、QQ频道)
|
||||
- QQ 官方机器人接口
|
||||
- Telegram(由 [astrbot_plugin_telegram](https://github.com/Soulter/astrbot_plugin_telegram) 插件支持)
|
||||
|
||||
🌍支持的AI语言模型一览:
|
||||
|
||||
**文字模型/图片理解**
|
||||
@@ -41,6 +46,7 @@
|
||||
- OpenAI GPT-4(原生支持)
|
||||
- Claude(免费,由[LLMs插件](https://github.com/Soulter/llms)支持)
|
||||
- HuggingChat(免费,由[LLMs插件](https://github.com/Soulter/llms)支持)
|
||||
- Gemini(免费,由[LLMs插件](https://github.com/Soulter/llms)支持)
|
||||
|
||||
**图片生成**
|
||||
- OpenAI Dalle 接口
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{x as i,o as l,c as _,w as s,a as e,f as a,J as m,V as c,b as t,t as u,ad as p,B as n,ae as o,j as f}from"./index-cccb34e6.js";const b={class:"text-h3"},h={class:"d-flex align-center"},g={class:"d-flex align-center"},V=i({__name:"BaseBreadcrumb",props:{title:String,breadcrumbs:Array,icon:String},setup(d){const r=d;return(x,B)=>(l(),_(c,{class:"page-breadcrumb mb-1 mt-1"},{default:s(()=>[e(a,{cols:"12",md:"12"},{default:s(()=>[e(m,{variant:"outlined",elevation:"0",class:"px-4 py-3 withbg"},{default:s(()=>[e(c,{"no-gutters":"",class:"align-center"},{default:s(()=>[e(a,{md:"5"},{default:s(()=>[t("h3",b,u(r.title),1)]),_:1}),e(a,{md:"7",sm:"12",cols:"12"},{default:s(()=>[e(p,{items:r.breadcrumbs,class:"text-h5 justify-md-end pa-1"},{divider:s(()=>[t("div",h,[e(n(o),{size:"17"})])]),prepend:s(()=>[e(f,{size:"small",icon:"mdi-home",class:"text-secondary mr-2"}),t("div",g,[e(n(o),{size:"17"})])]),_:1},8,["items"])]),_:1})]),_:1})]),_:1})]),_:1})]),_:1}))}});export{V as _};
|
||||
import{x as i,o as l,c as _,w as s,a as e,f as a,J as m,V as c,b as t,t as u,ad as p,B as n,ae as o,j as f}from"./index-9075b0bb.js";const b={class:"text-h3"},h={class:"d-flex align-center"},g={class:"d-flex align-center"},V=i({__name:"BaseBreadcrumb",props:{title:String,breadcrumbs:Array,icon:String},setup(d){const r=d;return(x,B)=>(l(),_(c,{class:"page-breadcrumb mb-1 mt-1"},{default:s(()=>[e(a,{cols:"12",md:"12"},{default:s(()=>[e(m,{variant:"outlined",elevation:"0",class:"px-4 py-3 withbg"},{default:s(()=>[e(c,{"no-gutters":"",class:"align-center"},{default:s(()=>[e(a,{md:"5"},{default:s(()=>[t("h3",b,u(r.title),1)]),_:1}),e(a,{md:"7",sm:"12",cols:"12"},{default:s(()=>[e(p,{items:r.breadcrumbs,class:"text-h5 justify-md-end pa-1"},{divider:s(()=>[t("div",h,[e(n(o),{size:"17"})])]),prepend:s(()=>[e(f,{size:"small",icon:"mdi-home",class:"text-secondary mr-2"}),t("div",g,[e(n(o),{size:"17"})])]),_:1},8,["items"])]),_:1})]),_:1})]),_:1})]),_:1})]),_:1}))}});export{V as _};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{x as e,o as a,c as t,w as o,a as s,B as n,Z as r,W as c}from"./index-cccb34e6.js";const f=e({__name:"BlankLayout",setup(p){return(u,_)=>(a(),t(c,null,{default:o(()=>[s(n(r))]),_:1}))}});export{f as default};
|
||||
import{x as e,o as a,c as t,w as o,a as s,B as n,Z as r,W as c}from"./index-9075b0bb.js";const f=e({__name:"BlankLayout",setup(p){return(u,_)=>(a(),t(c,null,{default:o(()=>[s(n(r))]),_:1}))}});export{f as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{_ as m}from"./BaseBreadcrumb.vue_vue_type_style_index_0_lang-4b4acd3b.js";import{_}from"./UiParentCard.vue_vue_type_script_setup_true_lang-72d62900.js";import{x as p,D as a,o as r,s,a as e,w as t,f as o,V as i,F as n,u as g,c as h,a0 as b,e as x,t as y}from"./index-cccb34e6.js";const P=p({__name:"ColorPage",setup(C){const c=a({title:"Colors Page"}),d=a([{title:"Utilities",disabled:!1,href:"#"},{title:"Colors",disabled:!0,href:"#"}]),u=a(["primary","lightprimary","secondary","lightsecondary","info","success","accent","warning","error","darkText","lightText","borderLight","inputBorder","containerBg"]);return(V,k)=>(r(),s(n,null,[e(m,{title:c.value.title,breadcrumbs:d.value},null,8,["title","breadcrumbs"]),e(i,null,{default:t(()=>[e(o,{cols:"12",md:"12"},{default:t(()=>[e(_,{title:"Color Palette"},{default:t(()=>[e(i,null,{default:t(()=>[(r(!0),s(n,null,g(u.value,(l,f)=>(r(),h(o,{md:"3",cols:"12",key:f},{default:t(()=>[e(b,{rounded:"md",class:"align-center justify-center d-flex",height:"100",width:"100%",color:l},{default:t(()=>[x("class: "+y(l),1)]),_:2},1032,["color"])]),_:2},1024))),128))]),_:1})]),_:1})]),_:1})]),_:1})],64))}});export{P as default};
|
||||
import{_ as m}from"./BaseBreadcrumb.vue_vue_type_style_index_0_lang-3bf6ea80.js";import{_}from"./UiParentCard.vue_vue_type_script_setup_true_lang-73bcbbd5.js";import{x as p,D as a,o as r,s,a as e,w as t,f as o,V as i,F as n,u as g,c as h,a0 as b,e as x,t as y}from"./index-9075b0bb.js";const P=p({__name:"ColorPage",setup(C){const c=a({title:"Colors Page"}),d=a([{title:"Utilities",disabled:!1,href:"#"},{title:"Colors",disabled:!0,href:"#"}]),u=a(["primary","lightprimary","secondary","lightsecondary","info","success","accent","warning","error","darkText","lightText","borderLight","inputBorder","containerBg"]);return(V,k)=>(r(),s(n,null,[e(m,{title:c.value.title,breadcrumbs:d.value},null,8,["title","breadcrumbs"]),e(i,null,{default:t(()=>[e(o,{cols:"12",md:"12"},{default:t(()=>[e(_,{title:"Color Palette"},{default:t(()=>[e(i,null,{default:t(()=>[(r(!0),s(n,null,g(u.value,(l,f)=>(r(),h(o,{md:"3",cols:"12",key:f},{default:t(()=>[e(b,{rounded:"md",class:"align-center justify-center d-flex",height:"100",width:"100%",color:l},{default:t(()=>[x("class: "+y(l),1)]),_:2},1032,["color"])]),_:2},1024))),128))]),_:1})]),_:1})]),_:1})]),_:1})],64))}});export{P as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{o as l,s as o,u as c,c as n,w as u,Q as g,b as s,R as k,F as t,ab as h,O as p,t as m,a as V,ac as f,i as C,q as x,k as v,A as U}from"./index-cccb34e6.js";import{_ as w}from"./UiParentCard.vue_vue_type_script_setup_true_lang-72d62900.js";const S={__name:"ConfigDetailCard",props:{config:Array},setup(d){return(y,B)=>(l(!0),o(t,null,c(d.config,r=>(l(),n(w,{key:r.name,title:r.name,style:{"margin-bottom":"16px"}},{default:u(()=>[g(s("a",null,"No data",512),[[k,d.config.length===0]]),(l(!0),o(t,null,c(r.body,e=>(l(),o(t,null,[e.config_type==="item"?(l(),o(t,{key:0},[e.val_type==="bool"?(l(),n(h,{key:0,modelValue:e.value,"onUpdate:modelValue":a=>e.value=a,label:e.name,hint:e.description,color:"primary",inset:""},null,8,["modelValue","onUpdate:modelValue","label","hint"])):e.val_type==="str"?(l(),n(p,{key:1,modelValue:e.value,"onUpdate:modelValue":a=>e.value=a,label:e.name,hint:e.description,style:{"margin-bottom":"8px"},variant:"outlined"},null,8,["modelValue","onUpdate:modelValue","label","hint"])):e.val_type==="int"?(l(),n(p,{key:2,modelValue:e.value,"onUpdate:modelValue":a=>e.value=a,label:e.name,hint:e.description,style:{"margin-bottom":"8px"},variant:"outlined"},null,8,["modelValue","onUpdate:modelValue","label","hint"])):e.val_type==="list"?(l(),o(t,{key:3},[s("span",null,m(e.name),1),V(f,{modelValue:e.value,"onUpdate:modelValue":a=>e.value=a,chips:"",clearable:"",label:"请添加",multiple:"","prepend-icon":"mdi-tag-multiple-outline"},{selection:u(({attrs:a,item:i,select:b,selected:_})=>[V(C,x(a,{"model-value":_,closable:"",onClick:b,"onClick:close":D=>y.remove(i)}),{default:u(()=>[s("strong",null,m(i),1)]),_:2},1040,["model-value","onClick","onClick:close"])]),_:2},1032,["modelValue","onUpdate:modelValue"])],64)):v("",!0)],64)):e.config_type==="divider"?(l(),n(U,{key:1,style:{"margin-top":"8px","margin-bottom":"8px"}})):v("",!0)],64))),256))]),_:2},1032,["title"]))),128))}};export{S as _};
|
||||
import{o as l,s as o,u as c,c as n,w as u,Q as g,b as s,R as k,F as t,ab as h,O as p,t as m,a as V,ac as f,i as C,q as x,k as v,A as U}from"./index-9075b0bb.js";import{_ as w}from"./UiParentCard.vue_vue_type_script_setup_true_lang-73bcbbd5.js";const S={__name:"ConfigDetailCard",props:{config:Array},setup(d){return(y,B)=>(l(!0),o(t,null,c(d.config,r=>(l(),n(w,{key:r.name,title:r.name,style:{"margin-bottom":"16px"}},{default:u(()=>[g(s("a",null,"No data",512),[[k,d.config.length===0]]),(l(!0),o(t,null,c(r.body,e=>(l(),o(t,null,[e.config_type==="item"?(l(),o(t,{key:0},[e.val_type==="bool"?(l(),n(h,{key:0,modelValue:e.value,"onUpdate:modelValue":a=>e.value=a,label:e.name,hint:e.description,color:"primary",inset:""},null,8,["modelValue","onUpdate:modelValue","label","hint"])):e.val_type==="str"?(l(),n(p,{key:1,modelValue:e.value,"onUpdate:modelValue":a=>e.value=a,label:e.name,hint:e.description,style:{"margin-bottom":"8px"},variant:"outlined"},null,8,["modelValue","onUpdate:modelValue","label","hint"])):e.val_type==="int"?(l(),n(p,{key:2,modelValue:e.value,"onUpdate:modelValue":a=>e.value=a,label:e.name,hint:e.description,style:{"margin-bottom":"8px"},variant:"outlined"},null,8,["modelValue","onUpdate:modelValue","label","hint"])):e.val_type==="list"?(l(),o(t,{key:3},[s("span",null,m(e.name),1),V(f,{modelValue:e.value,"onUpdate:modelValue":a=>e.value=a,chips:"",clearable:"",label:"请添加",multiple:"","prepend-icon":"mdi-tag-multiple-outline"},{selection:u(({attrs:a,item:i,select:b,selected:_})=>[V(C,x(a,{"model-value":_,closable:"",onClick:b,"onClick:close":D=>y.remove(i)}),{default:u(()=>[s("strong",null,m(i),1)]),_:2},1040,["model-value","onClick","onClick:close"])]),_:2},1032,["modelValue","onUpdate:modelValue"])],64)):v("",!0)],64)):e.config_type==="divider"?(l(),n(U,{key:1,style:{"margin-top":"8px","margin-bottom":"8px"}})):v("",!0)],64))),256))]),_:2},1032,["title"]))),128))}};export{S as _};
|
||||
@@ -1 +0,0 @@
|
||||
import{_ as y}from"./UiParentCard.vue_vue_type_script_setup_true_lang-72d62900.js";import{x as h,o,c as u,w as t,a,a8 as b,b as c,K as x,e as f,t as g,G as V,A as w,L as S,a9 as $,J as B,s as _,d as v,F as d,u as p,f as G,V as T,aa as j,T as l}from"./index-cccb34e6.js";import{_ as m}from"./ConfigDetailCard-644f0aef.js";const D={class:"d-sm-flex align-center justify-space-between"},C=h({__name:"ConfigGroupCard",props:{title:String},setup(e){const s=e;return(i,n)=>(o(),u(B,{variant:"outlined",elevation:"0",class:"withbg",style:{width:"50%"}},{default:t(()=>[a(b,{style:{padding:"10px 20px"}},{default:t(()=>[c("div",D,[a(x,null,{default:t(()=>[f(g(s.title),1)]),_:1}),a(V)])]),_:1}),a(w),a(S,null,{default:t(()=>[$(i.$slots,"default")]),_:3})]),_:3}))}}),I={style:{display:"flex","flex-direction":"row","justify-content":"space-between","align-items":"center","margin-bottom":"12px"}},N={style:{display:"flex","flex-direction":"row"}},R={style:{"margin-right":"10px",color:"black"}},F={style:{color:"#222"}},k=h({__name:"ConfigGroupItem",props:{title:String,desc:String,btnRoute:String,namespace:String},setup(e){const s=e;return(i,n)=>(o(),_("div",I,[c("div",N,[c("h3",R,g(s.title),1),c("p",F,g(s.desc),1)]),a(v,{to:s.btnRoute,color:"primary",class:"ml-2",style:{"border-radius":"10px"}},{default:t(()=>[f("配置")]),_:1},8,["to"])]))}}),L={style:{display:"flex","flex-direction":"row",padding:"16px",gap:"16px",width:"100%"}},P={name:"ConfigPage",components:{UiParentCard:y,ConfigGroupCard:C,ConfigGroupItem:k,ConfigDetailCard:m},data(){return{config_data:[],config_base:[],save_message_snack:!1,save_message:"",save_message_success:"",config_outline:[],namespace:""}},mounted(){this.getConfig()},methods:{switchConfig(e){l.get("/api/configs?namespace="+e).then(s=>{this.config_data=s.data.data,console.log(this.config_data)}).catch(s=>{save_message=s,save_message_snack=!0,save_message_success="error"})},getConfig(){l.get("/api/config_outline").then(e=>{this.config_outline=e.data.data,console.log(this.config_outline)}).catch(e=>{save_message=e,save_message_snack=!0,save_message_success="error"}),l.get("/api/configs").then(e=>{this.config_base=e.data.data,console.log(this.config_data)}).catch(e=>{save_message=e,save_message_snack=!0,save_message_success="error"})},updateConfig(){l.post("/api/configs",{base_config:this.config_base,config:this.config_data,namespace:this.namespace}).then(e=>{e.data.status==="success"?(this.save_message=e.data.message,this.save_message_snack=!0,this.save_message_success="success"):(this.save_message=e.data.message,this.save_message_snack=!0,this.save_message_success="error")}).catch(e=>{this.save_message=e,this.save_message_snack=!0,this.save_message_success="error"})}}},J=Object.assign(P,{setup(e){return(s,i)=>(o(),_(d,null,[a(T,null,{default:t(()=>[c("div",L,[(o(!0),_(d,null,p(s.config_outline,n=>(o(),u(C,{key:n.name,title:n.name},{default:t(()=>[(o(!0),_(d,null,p(n.body,r=>(o(),u(k,{title:r.title,desc:r.desc,namespace:r.namespace,onClick:U=>s.switchConfig(r.namespace)},null,8,["title","desc","namespace","onClick"]))),256))]),_:2},1032,["title"]))),128))]),a(G,{cols:"12",md:"12"},{default:t(()=>[a(m,{config:s.config_data},null,8,["config"]),a(m,{config:s.config_base},null,8,["config"])]),_:1})]),_:1}),a(v,{icon:"mdi-content-save",size:"x-large",style:{position:"fixed",right:"52px",bottom:"52px"},color:"darkprimary",onClick:s.updateConfig},null,8,["onClick"]),a(j,{timeout:2e3,elevation:"24",color:s.save_message_success,modelValue:s.save_message_snack,"onUpdate:modelValue":i[0]||(i[0]=n=>s.save_message_snack=n)},{default:t(()=>[f(g(s.save_message),1)]),_:1},8,["color","modelValue"])],64))}});export{J as default};
|
||||
@@ -0,0 +1 @@
|
||||
import{_ as y}from"./UiParentCard.vue_vue_type_script_setup_true_lang-73bcbbd5.js";import{x as h,o,c as u,w as t,a,a8 as b,b as c,K as x,e as f,t as g,G as V,A as w,L as S,a9 as $,J as B,s as _,d as v,F as d,u as p,f as G,V as T,aa as j,T as l}from"./index-9075b0bb.js";import{_ as m}from"./ConfigDetailCard-d45b9ca7.js";const D={class:"d-sm-flex align-center justify-space-between"},C=h({__name:"ConfigGroupCard",props:{title:String},setup(e){const s=e;return(i,n)=>(o(),u(B,{variant:"outlined",elevation:"0",class:"withbg",style:{width:"50%"}},{default:t(()=>[a(b,{style:{padding:"10px 20px"}},{default:t(()=>[c("div",D,[a(x,null,{default:t(()=>[f(g(s.title),1)]),_:1}),a(V)])]),_:1}),a(w),a(S,null,{default:t(()=>[$(i.$slots,"default")]),_:3})]),_:3}))}}),I={style:{display:"flex","flex-direction":"row","justify-content":"space-between","align-items":"center","margin-bottom":"12px"}},N={style:{display:"flex","flex-direction":"row"}},R={style:{"margin-right":"10px",color:"black"}},F={style:{color:"#222"}},k=h({__name:"ConfigGroupItem",props:{title:String,desc:String,btnRoute:String,namespace:String},setup(e){const s=e;return(i,n)=>(o(),_("div",I,[c("div",N,[c("h3",R,g(s.title),1),c("p",F,g(s.desc),1)]),a(v,{to:s.btnRoute,color:"primary",class:"ml-2",style:{"border-radius":"10px"}},{default:t(()=>[f("配置")]),_:1},8,["to"])]))}}),L={style:{display:"flex","flex-direction":"row",padding:"16px",gap:"16px",width:"100%"}},P={name:"ConfigPage",components:{UiParentCard:y,ConfigGroupCard:C,ConfigGroupItem:k,ConfigDetailCard:m},data(){return{config_data:[],config_base:[],save_message_snack:!1,save_message:"",save_message_success:"",config_outline:[],namespace:""}},mounted(){this.getConfig()},methods:{switchConfig(e){l.get("/api/configs?namespace="+e).then(s=>{this.namespace=e,this.config_data=s.data.data,console.log(this.config_data)}).catch(s=>{save_message=s,save_message_snack=!0,save_message_success="error"})},getConfig(){l.get("/api/config_outline").then(e=>{this.config_outline=e.data.data,console.log(this.config_outline)}).catch(e=>{save_message=e,save_message_snack=!0,save_message_success="error"}),l.get("/api/configs").then(e=>{this.config_base=e.data.data,console.log(this.config_data)}).catch(e=>{save_message=e,save_message_snack=!0,save_message_success="error"})},updateConfig(){l.post("/api/configs",{base_config:this.config_base,config:this.config_data,namespace:this.namespace}).then(e=>{e.data.status==="success"?(this.save_message=e.data.message,this.save_message_snack=!0,this.save_message_success="success"):(this.save_message=e.data.message,this.save_message_snack=!0,this.save_message_success="error")}).catch(e=>{this.save_message=e,this.save_message_snack=!0,this.save_message_success="error"})}}},J=Object.assign(P,{setup(e){return(s,i)=>(o(),_(d,null,[a(T,null,{default:t(()=>[c("div",L,[(o(!0),_(d,null,p(s.config_outline,n=>(o(),u(C,{key:n.name,title:n.name},{default:t(()=>[(o(!0),_(d,null,p(n.body,r=>(o(),u(k,{title:r.title,desc:r.desc,namespace:r.namespace,onClick:U=>s.switchConfig(r.namespace)},null,8,["title","desc","namespace","onClick"]))),256))]),_:2},1032,["title"]))),128))]),a(G,{cols:"12",md:"12"},{default:t(()=>[a(m,{config:s.config_data},null,8,["config"]),a(m,{config:s.config_base},null,8,["config"])]),_:1})]),_:1}),a(v,{icon:"mdi-content-save",size:"x-large",style:{position:"fixed",right:"52px",bottom:"52px"},color:"darkprimary",onClick:s.updateConfig},null,8,["onClick"]),a(j,{timeout:2e3,elevation:"24",color:s.save_message_success,modelValue:s.save_message_snack,"onUpdate:modelValue":i[0]||(i[0]=n=>s.save_message_snack=n)},{default:t(()=>[f(g(s.save_message),1)]),_:1},8,["color","modelValue"])],64))}});export{J as default};
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
import{_ as t}from"./_plugin-vue_export-helper-c27b6911.js";import{o,c,w as s,V as i,a as r,b as e,d as l,e as a,f as d}from"./index-cccb34e6.js";const n="/assets/img-error-bg-ab6474a0.svg",_="/assets/img-error-blue-2675a7a9.svg",m="/assets/img-error-text-a6aebfa0.svg",g="/assets/img-error-purple-edee3fbc.svg";const p={},u={class:"text-center"},f=e("div",{class:"CardMediaWrapper"},[e("img",{src:n,alt:"grid",class:"w-100"}),e("img",{src:_,alt:"grid",class:"CardMediaParts"}),e("img",{src:m,alt:"build",class:"CardMediaBuild"}),e("img",{src:g,alt:"build",class:"CardMediaBuild"})],-1),h=e("h1",{class:"text-h1"},"Something is wrong",-1),v=e("p",null,[e("small",null,[a("The page you are looking was moved, removed, "),e("br"),a("renamed, or might never exist! ")])],-1);function x(b,V){return o(),c(i,{"no-gutters":"",class:"h-100vh"},{default:s(()=>[r(d,{class:"d-flex align-center justify-center"},{default:s(()=>[e("div",u,[f,h,v,r(l,{variant:"flat",color:"primary",class:"mt-4",to:"/","prepend-icon":"mdi-home"},{default:s(()=>[a(" Home")]),_:1})])]),_:1})]),_:1})}const C=t(p,[["render",x]]);export{C as default};
|
||||
import{_ as t}from"./_plugin-vue_export-helper-c27b6911.js";import{o,c,w as s,V as i,a as r,b as e,d as l,e as a,f as d}from"./index-9075b0bb.js";const n="/assets/img-error-bg-ab6474a0.svg",_="/assets/img-error-blue-2675a7a9.svg",m="/assets/img-error-text-a6aebfa0.svg",g="/assets/img-error-purple-edee3fbc.svg";const p={},u={class:"text-center"},f=e("div",{class:"CardMediaWrapper"},[e("img",{src:n,alt:"grid",class:"w-100"}),e("img",{src:_,alt:"grid",class:"CardMediaParts"}),e("img",{src:m,alt:"build",class:"CardMediaBuild"}),e("img",{src:g,alt:"build",class:"CardMediaBuild"})],-1),h=e("h1",{class:"text-h1"},"Something is wrong",-1),v=e("p",null,[e("small",null,[a("The page you are looking was moved, removed, "),e("br"),a("renamed, or might never exist! ")])],-1);function x(b,V){return o(),c(i,{"no-gutters":"",class:"h-100vh"},{default:s(()=>[r(d,{class:"d-flex align-center justify-center"},{default:s(()=>[e("div",u,[f,h,v,r(l,{variant:"flat",color:"primary",class:"mt-4",to:"/","prepend-icon":"mdi-home"},{default:s(()=>[a(" Home")]),_:1})])]),_:1})]),_:1})}const C=t(p,[["render",x]]);export{C as default};
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,4 +1,4 @@
|
||||
import{_ as _t}from"./LogoDark.vue_vue_type_script_setup_true_lang-7600b956.js";import{x as ke,af as we,r as Ot,ag as Vt,D as A,ah as Ne,a2 as P,B as I,ai as Q,aj as St,I as Be,ak as Ie,al as Et,am as jt,an as At,ao as G,y as wt,o as Re,c as tt,w as C,a as j,O as He,b as ge,ap as Ft,d as Pt,e as Ge,s as Ct,aq as Tt,t as Nt,k as Bt,U as It,f as Fe,N as Rt,V as Pe,J as Ye,L as kt}from"./index-cccb34e6.js";import{a as Mt}from"./md5-674376bd.js";/**
|
||||
import{_ as _t}from"./LogoDark.vue_vue_type_script_setup_true_lang-b3521e6c.js";import{x as ke,af as we,r as Ot,ag as Vt,D as A,ah as Ne,a2 as P,B as I,ai as Q,aj as St,I as Be,ak as Ie,al as Et,am as jt,an as At,ao as G,y as wt,o as Re,c as tt,w as C,a as j,O as He,b as ge,ap as Ft,d as Pt,e as Ge,s as Ct,aq as Tt,t as Nt,k as Bt,U as It,f as Fe,N as Rt,V as Pe,J as Ye,L as kt}from"./index-9075b0bb.js";import{a as Mt}from"./md5-48eb25f3.js";/**
|
||||
* vee-validate v4.11.3
|
||||
* (c) 2023 Abdelrahman Awad
|
||||
* @license MIT
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{av as _,x as d,D as n,o as c,s as m,a as f,w as p,Q as r,b as a,R as o,B as t,aw as h}from"./index-cccb34e6.js";const s={Sidebar_drawer:!0,Customizer_drawer:!1,mini_sidebar:!1,fontTheme:"Roboto",inputBg:!1},l=_({id:"customizer",state:()=>({Sidebar_drawer:s.Sidebar_drawer,Customizer_drawer:s.Customizer_drawer,mini_sidebar:s.mini_sidebar,fontTheme:"Poppins",inputBg:s.inputBg}),getters:{},actions:{SET_SIDEBAR_DRAWER(){this.Sidebar_drawer=!this.Sidebar_drawer},SET_MINI_SIDEBAR(e){this.mini_sidebar=e},SET_FONT(e){this.fontTheme=e}}}),u={class:"logo",style:{display:"flex","align-items":"center"}},b={style:{"font-size":"24px","font-weight":"1000"}},w={style:{"font-size":"20px","font-weight":"1000"}},S={style:{"font-size":"20px"}},z=d({__name:"LogoDark",setup(e){n("rgb(var(--v-theme-primary))"),n("rgb(var(--v-theme-secondary))");const i=l();return(g,B)=>(c(),m("div",u,[f(t(h),{to:"/",style:{"text-decoration":"none",color:"black"}},{default:p(()=>[r(a("span",b,"AstrBot 仪表盘",512),[[o,!t(i).mini_sidebar]]),r(a("span",w,"Astr",512),[[o,t(i).mini_sidebar]]),r(a("span",S,"Bot",512),[[o,t(i).mini_sidebar]])]),_:1})]))}});export{z as _,l as u};
|
||||
import{av as _,x as d,D as n,o as c,s as m,a as f,w as p,Q as r,b as a,R as o,B as t,aw as h}from"./index-9075b0bb.js";const s={Sidebar_drawer:!0,Customizer_drawer:!1,mini_sidebar:!1,fontTheme:"Roboto",inputBg:!1},l=_({id:"customizer",state:()=>({Sidebar_drawer:s.Sidebar_drawer,Customizer_drawer:s.Customizer_drawer,mini_sidebar:s.mini_sidebar,fontTheme:"Poppins",inputBg:s.inputBg}),getters:{},actions:{SET_SIDEBAR_DRAWER(){this.Sidebar_drawer=!this.Sidebar_drawer},SET_MINI_SIDEBAR(e){this.mini_sidebar=e},SET_FONT(e){this.fontTheme=e}}}),u={class:"logo",style:{display:"flex","align-items":"center"}},b={style:{"font-size":"24px","font-weight":"1000"}},w={style:{"font-size":"20px","font-weight":"1000"}},S={style:{"font-size":"20px"}},z=d({__name:"LogoDark",setup(e){n("rgb(var(--v-theme-primary))"),n("rgb(var(--v-theme-secondary))");const i=l();return(g,B)=>(c(),m("div",u,[f(t(h),{to:"/",style:{"text-decoration":"none",color:"black"}},{default:p(()=>[r(a("span",b,"AstrBot 仪表盘",512),[[o,!t(i).mini_sidebar]]),r(a("span",w,"Astr",512),[[o,t(i).mini_sidebar]]),r(a("span",S,"Bot",512),[[o,t(i).mini_sidebar]])]),_:1})]))}});export{z as _,l as u};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{_ as o}from"./BaseBreadcrumb.vue_vue_type_style_index_0_lang-4b4acd3b.js";import{_ as i}from"./UiParentCard.vue_vue_type_script_setup_true_lang-72d62900.js";import{x as n,D as a,o as c,s as m,a as e,w as t,f as d,b as f,V as _,F as u}from"./index-cccb34e6.js";const p=["innerHTML"],v=n({__name:"MaterialIcons",setup(b){const s=a({title:"Material Icons"}),r=a('<iframe src="https://materialdesignicons.com/" frameborder="0" width="100%" height="1000"></iframe>'),l=a([{title:"Icons",disabled:!1,href:"#"},{title:"Material Icons",disabled:!0,href:"#"}]);return(h,M)=>(c(),m(u,null,[e(o,{title:s.value.title,breadcrumbs:l.value},null,8,["title","breadcrumbs"]),e(_,null,{default:t(()=>[e(d,{cols:"12",md:"12"},{default:t(()=>[e(i,{title:"Material Icons"},{default:t(()=>[f("div",{innerHTML:r.value},null,8,p)]),_:1})]),_:1})]),_:1})],64))}});export{v as default};
|
||||
import{_ as o}from"./BaseBreadcrumb.vue_vue_type_style_index_0_lang-3bf6ea80.js";import{_ as i}from"./UiParentCard.vue_vue_type_script_setup_true_lang-73bcbbd5.js";import{x as n,D as a,o as c,s as m,a as e,w as t,f as d,b as f,V as _,F as u}from"./index-9075b0bb.js";const p=["innerHTML"],v=n({__name:"MaterialIcons",setup(b){const s=a({title:"Material Icons"}),r=a('<iframe src="https://materialdesignicons.com/" frameborder="0" width="100%" height="1000"></iframe>'),l=a([{title:"Icons",disabled:!1,href:"#"},{title:"Material Icons",disabled:!0,href:"#"}]);return(h,M)=>(c(),m(u,null,[e(o,{title:s.value.title,breadcrumbs:l.value},null,8,["title","breadcrumbs"]),e(_,null,{default:t(()=>[e(d,{cols:"12",md:"12"},{default:t(()=>[e(i,{title:"Material Icons"},{default:t(()=>[f("div",{innerHTML:r.value},null,8,p)]),_:1})]),_:1})]),_:1})],64))}});export{v as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{_ as B}from"./LogoDark.vue_vue_type_script_setup_true_lang-7600b956.js";import{x as y,D as o,o as b,s as U,a as e,w as a,b as n,B as $,d as u,f as d,A as _,e as f,V as r,O as m,ap as A,au as E,F,c as T,N as q,J as V,L as P}from"./index-cccb34e6.js";const z="/assets/social-google-a359a253.svg",N=["src"],S=n("span",{class:"ml-2"},"Sign up with Google",-1),D=n("h5",{class:"text-h5 text-center my-4 mb-8"},"Sign up with Email address",-1),G={class:"d-sm-inline-flex align-center mt-2 mb-7 mb-sm-0 font-weight-bold"},L=n("a",{href:"#",class:"ml-1 text-lightText"},"Terms and Condition",-1),O={class:"mt-5 text-right"},j=y({__name:"AuthRegister",setup(w){const c=o(!1),i=o(!1),p=o(""),v=o(""),g=o(),h=o(""),x=o(""),k=o([s=>!!s||"Password is required",s=>s&&s.length<=10||"Password must be less than 10 characters"]),C=o([s=>!!s||"E-mail is required",s=>/.+@.+\..+/.test(s)||"E-mail must be valid"]);function R(){g.value.validate()}return(s,l)=>(b(),U(F,null,[e(u,{block:"",color:"primary",variant:"outlined",class:"text-lightText googleBtn"},{default:a(()=>[n("img",{src:$(z),alt:"google"},null,8,N),S]),_:1}),e(r,null,{default:a(()=>[e(d,{class:"d-flex align-center"},{default:a(()=>[e(_,{class:"custom-devider"}),e(u,{variant:"outlined",class:"orbtn",rounded:"md",size:"small"},{default:a(()=>[f("OR")]),_:1}),e(_,{class:"custom-devider"})]),_:1})]),_:1}),D,e(E,{ref_key:"Regform",ref:g,"lazy-validation":"",action:"/dashboards/analytical",class:"mt-7 loginForm"},{default:a(()=>[e(r,null,{default:a(()=>[e(d,{cols:"12",sm:"6"},{default:a(()=>[e(m,{modelValue:h.value,"onUpdate:modelValue":l[0]||(l[0]=t=>h.value=t),density:"comfortable","hide-details":"auto",variant:"outlined",color:"primary",label:"Firstname"},null,8,["modelValue"])]),_:1}),e(d,{cols:"12",sm:"6"},{default:a(()=>[e(m,{modelValue:x.value,"onUpdate:modelValue":l[1]||(l[1]=t=>x.value=t),density:"comfortable","hide-details":"auto",variant:"outlined",color:"primary",label:"Lastname"},null,8,["modelValue"])]),_:1})]),_:1}),e(m,{modelValue:v.value,"onUpdate:modelValue":l[2]||(l[2]=t=>v.value=t),rules:C.value,label:"Email Address / Username",class:"mt-4 mb-4",required:"",density:"comfortable","hide-details":"auto",variant:"outlined",color:"primary"},null,8,["modelValue","rules"]),e(m,{modelValue:p.value,"onUpdate:modelValue":l[3]||(l[3]=t=>p.value=t),rules:k.value,label:"Password",required:"",density:"comfortable",variant:"outlined",color:"primary","hide-details":"auto","append-icon":i.value?"mdi-eye":"mdi-eye-off",type:i.value?"text":"password","onClick:append":l[4]||(l[4]=t=>i.value=!i.value),class:"pwdInput"},null,8,["modelValue","rules","append-icon","type"]),n("div",G,[e(A,{modelValue:c.value,"onUpdate:modelValue":l[5]||(l[5]=t=>c.value=t),rules:[t=>!!t||"You must agree to continue!"],label:"Agree with?",required:"",color:"primary",class:"ms-n2","hide-details":""},null,8,["modelValue","rules"]),L]),e(u,{color:"secondary",block:"",class:"mt-2",variant:"flat",size:"large",onClick:l[6]||(l[6]=t=>R())},{default:a(()=>[f("Sign Up")]),_:1})]),_:1},512),n("div",O,[e(_),e(u,{variant:"plain",to:"/auth/login",class:"mt-2 text-capitalize mr-n2"},{default:a(()=>[f("Already have an account?")]),_:1})])],64))}});const I={class:"pa-7 pa-sm-12"},J=n("h2",{class:"text-secondary text-h2 mt-8"},"Sign up",-1),Y=n("h4",{class:"text-disabled text-h4 mt-3"},"Enter credentials to continue",-1),M=y({__name:"RegisterPage",setup(w){return(c,i)=>(b(),T(r,{class:"h-100vh","no-gutters":""},{default:a(()=>[e(d,{cols:"12",class:"d-flex align-center bg-lightprimary"},{default:a(()=>[e(q,null,{default:a(()=>[n("div",I,[e(r,{justify:"center"},{default:a(()=>[e(d,{cols:"12",lg:"10",xl:"6",md:"7"},{default:a(()=>[e(V,{elevation:"0",class:"loginBox"},{default:a(()=>[e(V,{variant:"outlined"},{default:a(()=>[e(P,{class:"pa-9"},{default:a(()=>[e(r,null,{default:a(()=>[e(d,{cols:"12",class:"text-center"},{default:a(()=>[e(B),J,Y]),_:1})]),_:1}),e(j)]),_:1})]),_:1})]),_:1})]),_:1})]),_:1})])]),_:1})]),_:1})]),_:1}))}});export{M as default};
|
||||
import{_ as B}from"./LogoDark.vue_vue_type_script_setup_true_lang-b3521e6c.js";import{x as y,D as o,o as b,s as U,a as e,w as a,b as n,B as $,d as u,f as d,A as _,e as f,V as r,O as m,ap as A,au as E,F,c as T,N as q,J as V,L as P}from"./index-9075b0bb.js";const z="/assets/social-google-a359a253.svg",N=["src"],S=n("span",{class:"ml-2"},"Sign up with Google",-1),D=n("h5",{class:"text-h5 text-center my-4 mb-8"},"Sign up with Email address",-1),G={class:"d-sm-inline-flex align-center mt-2 mb-7 mb-sm-0 font-weight-bold"},L=n("a",{href:"#",class:"ml-1 text-lightText"},"Terms and Condition",-1),O={class:"mt-5 text-right"},j=y({__name:"AuthRegister",setup(w){const c=o(!1),i=o(!1),p=o(""),v=o(""),g=o(),h=o(""),x=o(""),k=o([s=>!!s||"Password is required",s=>s&&s.length<=10||"Password must be less than 10 characters"]),C=o([s=>!!s||"E-mail is required",s=>/.+@.+\..+/.test(s)||"E-mail must be valid"]);function R(){g.value.validate()}return(s,l)=>(b(),U(F,null,[e(u,{block:"",color:"primary",variant:"outlined",class:"text-lightText googleBtn"},{default:a(()=>[n("img",{src:$(z),alt:"google"},null,8,N),S]),_:1}),e(r,null,{default:a(()=>[e(d,{class:"d-flex align-center"},{default:a(()=>[e(_,{class:"custom-devider"}),e(u,{variant:"outlined",class:"orbtn",rounded:"md",size:"small"},{default:a(()=>[f("OR")]),_:1}),e(_,{class:"custom-devider"})]),_:1})]),_:1}),D,e(E,{ref_key:"Regform",ref:g,"lazy-validation":"",action:"/dashboards/analytical",class:"mt-7 loginForm"},{default:a(()=>[e(r,null,{default:a(()=>[e(d,{cols:"12",sm:"6"},{default:a(()=>[e(m,{modelValue:h.value,"onUpdate:modelValue":l[0]||(l[0]=t=>h.value=t),density:"comfortable","hide-details":"auto",variant:"outlined",color:"primary",label:"Firstname"},null,8,["modelValue"])]),_:1}),e(d,{cols:"12",sm:"6"},{default:a(()=>[e(m,{modelValue:x.value,"onUpdate:modelValue":l[1]||(l[1]=t=>x.value=t),density:"comfortable","hide-details":"auto",variant:"outlined",color:"primary",label:"Lastname"},null,8,["modelValue"])]),_:1})]),_:1}),e(m,{modelValue:v.value,"onUpdate:modelValue":l[2]||(l[2]=t=>v.value=t),rules:C.value,label:"Email Address / Username",class:"mt-4 mb-4",required:"",density:"comfortable","hide-details":"auto",variant:"outlined",color:"primary"},null,8,["modelValue","rules"]),e(m,{modelValue:p.value,"onUpdate:modelValue":l[3]||(l[3]=t=>p.value=t),rules:k.value,label:"Password",required:"",density:"comfortable",variant:"outlined",color:"primary","hide-details":"auto","append-icon":i.value?"mdi-eye":"mdi-eye-off",type:i.value?"text":"password","onClick:append":l[4]||(l[4]=t=>i.value=!i.value),class:"pwdInput"},null,8,["modelValue","rules","append-icon","type"]),n("div",G,[e(A,{modelValue:c.value,"onUpdate:modelValue":l[5]||(l[5]=t=>c.value=t),rules:[t=>!!t||"You must agree to continue!"],label:"Agree with?",required:"",color:"primary",class:"ms-n2","hide-details":""},null,8,["modelValue","rules"]),L]),e(u,{color:"secondary",block:"",class:"mt-2",variant:"flat",size:"large",onClick:l[6]||(l[6]=t=>R())},{default:a(()=>[f("Sign Up")]),_:1})]),_:1},512),n("div",O,[e(_),e(u,{variant:"plain",to:"/auth/login",class:"mt-2 text-capitalize mr-n2"},{default:a(()=>[f("Already have an account?")]),_:1})])],64))}});const I={class:"pa-7 pa-sm-12"},J=n("h2",{class:"text-secondary text-h2 mt-8"},"Sign up",-1),Y=n("h4",{class:"text-disabled text-h4 mt-3"},"Enter credentials to continue",-1),M=y({__name:"RegisterPage",setup(w){return(c,i)=>(b(),T(r,{class:"h-100vh","no-gutters":""},{default:a(()=>[e(d,{cols:"12",class:"d-flex align-center bg-lightprimary"},{default:a(()=>[e(q,null,{default:a(()=>[n("div",I,[e(r,{justify:"center"},{default:a(()=>[e(d,{cols:"12",lg:"10",xl:"6",md:"7"},{default:a(()=>[e(V,{elevation:"0",class:"loginBox"},{default:a(()=>[e(V,{variant:"outlined"},{default:a(()=>[e(P,{class:"pa-9"},{default:a(()=>[e(r,null,{default:a(()=>[e(d,{cols:"12",class:"text-center"},{default:a(()=>[e(B),J,Y]),_:1})]),_:1}),e(j)]),_:1})]),_:1})]),_:1})]),_:1})]),_:1})])]),_:1})]),_:1})]),_:1}))}});export{M as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{_ as c}from"./BaseBreadcrumb.vue_vue_type_style_index_0_lang-4b4acd3b.js";import{_ as f}from"./UiParentCard.vue_vue_type_script_setup_true_lang-72d62900.js";import{x as m,D as s,o as l,s as r,a as e,w as a,f as i,V as o,F as d,u as _,J as p,X as b,b as h,t as g}from"./index-cccb34e6.js";const v=m({__name:"ShadowPage",setup(w){const n=s({title:"Shadow Page"}),u=s([{title:"Utilities",disabled:!1,href:"#"},{title:"Shadow",disabled:!0,href:"#"}]);return(V,x)=>(l(),r(d,null,[e(c,{title:n.value.title,breadcrumbs:u.value},null,8,["title","breadcrumbs"]),e(o,null,{default:a(()=>[e(i,{cols:"12",md:"12"},{default:a(()=>[e(f,{title:"Basic Shadow"},{default:a(()=>[e(o,{justify:"center"},{default:a(()=>[(l(),r(d,null,_(25,t=>e(i,{key:t,cols:"auto"},{default:a(()=>[e(p,{height:"100",width:"100",class:b(["mb-5",["d-flex justify-center align-center bg-primary",`elevation-${t}`]])},{default:a(()=>[h("div",null,g(t-1),1)]),_:2},1032,["class"])]),_:2},1024)),64))]),_:1})]),_:1})]),_:1})]),_:1})],64))}});export{v as default};
|
||||
import{_ as c}from"./BaseBreadcrumb.vue_vue_type_style_index_0_lang-3bf6ea80.js";import{_ as f}from"./UiParentCard.vue_vue_type_script_setup_true_lang-73bcbbd5.js";import{x as m,D as s,o as l,s as r,a as e,w as a,f as i,V as o,F as d,u as _,J as p,X as b,b as h,t as g}from"./index-9075b0bb.js";const v=m({__name:"ShadowPage",setup(w){const n=s({title:"Shadow Page"}),u=s([{title:"Utilities",disabled:!1,href:"#"},{title:"Shadow",disabled:!0,href:"#"}]);return(V,x)=>(l(),r(d,null,[e(c,{title:n.value.title,breadcrumbs:u.value},null,8,["title","breadcrumbs"]),e(o,null,{default:a(()=>[e(i,{cols:"12",md:"12"},{default:a(()=>[e(f,{title:"Basic Shadow"},{default:a(()=>[e(o,{justify:"center"},{default:a(()=>[(l(),r(d,null,_(25,t=>e(i,{key:t,cols:"auto"},{default:a(()=>[e(p,{height:"100",width:"100",class:b(["mb-5",["d-flex justify-center align-center bg-primary",`elevation-${t}`]])},{default:a(()=>[h("div",null,g(t-1),1)]),_:2},1032,["class"])]),_:2},1024)),64))]),_:1})]),_:1})]),_:1})]),_:1})],64))}});export{v as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{_ as o}from"./BaseBreadcrumb.vue_vue_type_style_index_0_lang-4b4acd3b.js";import{_ as n}from"./UiParentCard.vue_vue_type_script_setup_true_lang-72d62900.js";import{x as c,D as a,o as i,s as m,a as e,w as t,f as d,b as f,V as _,F as u}from"./index-cccb34e6.js";const b=["innerHTML"],w=c({__name:"TablerIcons",setup(p){const s=a({title:"Tabler Icons"}),r=a('<iframe src="https://tablericons.com/" frameborder="0" width="100%" height="600"></iframe>'),l=a([{title:"Icons",disabled:!1,href:"#"},{title:"Tabler Icons",disabled:!0,href:"#"}]);return(h,T)=>(i(),m(u,null,[e(o,{title:s.value.title,breadcrumbs:l.value},null,8,["title","breadcrumbs"]),e(_,null,{default:t(()=>[e(d,{cols:"12",md:"12"},{default:t(()=>[e(n,{title:"Tabler Icons"},{default:t(()=>[f("div",{innerHTML:r.value},null,8,b)]),_:1})]),_:1})]),_:1})],64))}});export{w as default};
|
||||
import{_ as o}from"./BaseBreadcrumb.vue_vue_type_style_index_0_lang-3bf6ea80.js";import{_ as n}from"./UiParentCard.vue_vue_type_script_setup_true_lang-73bcbbd5.js";import{x as c,D as a,o as i,s as m,a as e,w as t,f as d,b as f,V as _,F as u}from"./index-9075b0bb.js";const b=["innerHTML"],w=c({__name:"TablerIcons",setup(p){const s=a({title:"Tabler Icons"}),r=a('<iframe src="https://tablericons.com/" frameborder="0" width="100%" height="600"></iframe>'),l=a([{title:"Icons",disabled:!1,href:"#"},{title:"Tabler Icons",disabled:!0,href:"#"}]);return(h,T)=>(i(),m(u,null,[e(o,{title:s.value.title,breadcrumbs:l.value},null,8,["title","breadcrumbs"]),e(_,null,{default:t(()=>[e(d,{cols:"12",md:"12"},{default:t(()=>[e(n,{title:"Tabler Icons"},{default:t(()=>[f("div",{innerHTML:r.value},null,8,b)]),_:1})]),_:1})]),_:1})],64))}});export{w as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{_ as m}from"./BaseBreadcrumb.vue_vue_type_style_index_0_lang-4b4acd3b.js";import{_ as v}from"./UiParentCard.vue_vue_type_script_setup_true_lang-72d62900.js";import{x as f,o as i,c as g,w as e,a,a8 as y,K as b,e as w,t as d,A as C,L as V,a9 as L,J as _,D as o,s as h,f as k,b as t,F as x,u as B,X as H,V as T}from"./index-cccb34e6.js";const s=f({__name:"UiChildCard",props:{title:String},setup(r){const l=r;return(n,c)=>(i(),g(_,{variant:"outlined"},{default:e(()=>[a(y,{class:"py-3"},{default:e(()=>[a(b,{class:"text-h5"},{default:e(()=>[w(d(l.title),1)]),_:1})]),_:1}),a(C),a(V,null,{default:e(()=>[L(n.$slots,"default")]),_:3})]),_:3}))}}),D={class:"d-flex flex-column gap-1"},S={class:"text-caption pa-2 bg-lightprimary"},z=t("div",{class:"text-grey"},"Class",-1),N={class:"font-weight-medium"},$=t("div",null,[t("p",{class:"text-left"},"Left aligned on all viewport sizes."),t("p",{class:"text-center"},"Center aligned on all viewport sizes."),t("p",{class:"text-right"},"Right aligned on all viewport sizes."),t("p",{class:"text-sm-left"},"Left aligned on viewports SM (small) or wider."),t("p",{class:"text-right text-md-left"},"Left aligned on viewports MD (medium) or wider."),t("p",{class:"text-right text-lg-left"},"Left aligned on viewports LG (large) or wider."),t("p",{class:"text-right text-xl-left"},"Left aligned on viewports XL (extra-large) or wider.")],-1),M=t("div",{class:"d-flex justify-space-between flex-row"},[t("a",{href:"#",class:"text-decoration-none"},"Non-underlined link"),t("div",{class:"text-decoration-line-through"},"Line-through text"),t("div",{class:"text-decoration-overline"},"Overline text"),t("div",{class:"text-decoration-underline"},"Underline text")],-1),O=t("div",null,[t("p",{class:"text-high-emphasis"},"High-emphasis has an opacity of 87% in light theme and 100% in dark."),t("p",{class:"text-medium-emphasis"},"Medium-emphasis text and hint text have opacities of 60% in light theme and 70% in dark."),t("p",{class:"text-disabled"},"Disabled text has an opacity of 38% in light theme and 50% in dark.")],-1),j=f({__name:"TypographyPage",setup(r){const l=o({title:"Typography Page"}),n=o([["Heading 1","text-h1"],["Heading 2","text-h2"],["Heading 3","text-h3"],["Heading 4","text-h4"],["Heading 5","text-h5"],["Heading 6","text-h6"],["Subtitle 1","text-subtitle-1"],["Subtitle 2","text-subtitle-2"],["Body 1","text-body-1"],["Body 2","text-body-2"],["Button","text-button"],["Caption","text-caption"],["Overline","text-overline"]]),c=o([{title:"Utilities",disabled:!1,href:"#"},{title:"Typography",disabled:!0,href:"#"}]);return(U,F)=>(i(),h(x,null,[a(m,{title:l.value.title,breadcrumbs:c.value},null,8,["title","breadcrumbs"]),a(T,null,{default:e(()=>[a(k,{cols:"12",md:"12"},{default:e(()=>[a(v,{title:"Basic Typography"},{default:e(()=>[a(s,{title:"Heading"},{default:e(()=>[t("div",D,[(i(!0),h(x,null,B(n.value,([p,u])=>(i(),g(_,{variant:"outlined",key:p,class:"my-4"},{default:e(()=>[t("div",{class:H([u,"pa-2"])},d(p),3),t("div",S,[z,t("div",N,d(u),1)])]),_:2},1024))),128))])]),_:1}),a(s,{title:"Text-alignment",class:"mt-8"},{default:e(()=>[$]),_:1}),a(s,{title:"Decoration",class:"mt-8"},{default:e(()=>[M]),_:1}),a(s,{title:"Opacity",class:"mt-8"},{default:e(()=>[O]),_:1})]),_:1})]),_:1})]),_:1})],64))}});export{j as default};
|
||||
import{_ as m}from"./BaseBreadcrumb.vue_vue_type_style_index_0_lang-3bf6ea80.js";import{_ as v}from"./UiParentCard.vue_vue_type_script_setup_true_lang-73bcbbd5.js";import{x as f,o as i,c as g,w as e,a,a8 as y,K as b,e as w,t as d,A as C,L as V,a9 as L,J as _,D as o,s as h,f as k,b as t,F as x,u as B,X as H,V as T}from"./index-9075b0bb.js";const s=f({__name:"UiChildCard",props:{title:String},setup(r){const l=r;return(n,c)=>(i(),g(_,{variant:"outlined"},{default:e(()=>[a(y,{class:"py-3"},{default:e(()=>[a(b,{class:"text-h5"},{default:e(()=>[w(d(l.title),1)]),_:1})]),_:1}),a(C),a(V,null,{default:e(()=>[L(n.$slots,"default")]),_:3})]),_:3}))}}),D={class:"d-flex flex-column gap-1"},S={class:"text-caption pa-2 bg-lightprimary"},z=t("div",{class:"text-grey"},"Class",-1),N={class:"font-weight-medium"},$=t("div",null,[t("p",{class:"text-left"},"Left aligned on all viewport sizes."),t("p",{class:"text-center"},"Center aligned on all viewport sizes."),t("p",{class:"text-right"},"Right aligned on all viewport sizes."),t("p",{class:"text-sm-left"},"Left aligned on viewports SM (small) or wider."),t("p",{class:"text-right text-md-left"},"Left aligned on viewports MD (medium) or wider."),t("p",{class:"text-right text-lg-left"},"Left aligned on viewports LG (large) or wider."),t("p",{class:"text-right text-xl-left"},"Left aligned on viewports XL (extra-large) or wider.")],-1),M=t("div",{class:"d-flex justify-space-between flex-row"},[t("a",{href:"#",class:"text-decoration-none"},"Non-underlined link"),t("div",{class:"text-decoration-line-through"},"Line-through text"),t("div",{class:"text-decoration-overline"},"Overline text"),t("div",{class:"text-decoration-underline"},"Underline text")],-1),O=t("div",null,[t("p",{class:"text-high-emphasis"},"High-emphasis has an opacity of 87% in light theme and 100% in dark."),t("p",{class:"text-medium-emphasis"},"Medium-emphasis text and hint text have opacities of 60% in light theme and 70% in dark."),t("p",{class:"text-disabled"},"Disabled text has an opacity of 38% in light theme and 50% in dark.")],-1),j=f({__name:"TypographyPage",setup(r){const l=o({title:"Typography Page"}),n=o([["Heading 1","text-h1"],["Heading 2","text-h2"],["Heading 3","text-h3"],["Heading 4","text-h4"],["Heading 5","text-h5"],["Heading 6","text-h6"],["Subtitle 1","text-subtitle-1"],["Subtitle 2","text-subtitle-2"],["Body 1","text-body-1"],["Body 2","text-body-2"],["Button","text-button"],["Caption","text-caption"],["Overline","text-overline"]]),c=o([{title:"Utilities",disabled:!1,href:"#"},{title:"Typography",disabled:!0,href:"#"}]);return(U,F)=>(i(),h(x,null,[a(m,{title:l.value.title,breadcrumbs:c.value},null,8,["title","breadcrumbs"]),a(T,null,{default:e(()=>[a(k,{cols:"12",md:"12"},{default:e(()=>[a(v,{title:"Basic Typography"},{default:e(()=>[a(s,{title:"Heading"},{default:e(()=>[t("div",D,[(i(!0),h(x,null,B(n.value,([p,u])=>(i(),g(_,{variant:"outlined",key:p,class:"my-4"},{default:e(()=>[t("div",{class:H([u,"pa-2"])},d(p),3),t("div",S,[z,t("div",N,d(u),1)])]),_:2},1024))),128))])]),_:1}),a(s,{title:"Text-alignment",class:"mt-8"},{default:e(()=>[$]),_:1}),a(s,{title:"Decoration",class:"mt-8"},{default:e(()=>[M]),_:1}),a(s,{title:"Opacity",class:"mt-8"},{default:e(()=>[O]),_:1})]),_:1})]),_:1})]),_:1})],64))}});export{j as default};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{x as n,o,c as i,w as e,a,a8 as d,b as c,K as u,e as p,t as _,a9 as s,A as f,L as V,J as m}from"./index-cccb34e6.js";const C={class:"d-sm-flex align-center justify-space-between"},h=n({__name:"UiParentCard",props:{title:String},setup(l){const r=l;return(t,x)=>(o(),i(m,{variant:"outlined",elevation:"0",class:"withbg"},{default:e(()=>[a(d,null,{default:e(()=>[c("div",C,[a(u,null,{default:e(()=>[p(_(r.title),1)]),_:1}),s(t.$slots,"action")])]),_:3}),a(f),a(V,null,{default:e(()=>[s(t.$slots,"default")]),_:3})]),_:3}))}});export{h as _};
|
||||
import{x as n,o,c as i,w as e,a,a8 as d,b as c,K as u,e as p,t as _,a9 as s,A as f,L as V,J as m}from"./index-9075b0bb.js";const C={class:"d-sm-flex align-center justify-space-between"},h=n({__name:"UiParentCard",props:{title:String},setup(l){const r=l;return(t,x)=>(o(),i(m,{variant:"outlined",elevation:"0",class:"withbg"},{default:e(()=>[a(d,null,{default:e(()=>[c("div",C,[a(u,null,{default:e(()=>[p(_(r.title),1)]),_:1}),s(t.$slots,"action")])]),_:3}),a(f),a(V,null,{default:e(()=>[s(t.$slots,"default")]),_:3})]),_:3}))}});export{h as _};
|
||||
Vendored
+2
-2
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
import{ar as K,as as Y,at as V}from"./index-cccb34e6.js";var C={exports:{}};const $={},k=Object.freeze(Object.defineProperty({__proto__:null,default:$},Symbol.toStringTag,{value:"Module"})),z=K(k);/**
|
||||
import{ar as K,as as Y,at as V}from"./index-9075b0bb.js";var C={exports:{}};const $={},k=Object.freeze(Object.defineProperty({__proto__:null,default:$},Symbol.toStringTag,{value:"Module"})),z=K(k);/**
|
||||
* [js-md5]{@link https://github.com/emn178/js-md5}
|
||||
*
|
||||
* @namespace md5
|
||||
Vendored
+1
-1
@@ -11,7 +11,7 @@
|
||||
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Poppins:wght@400;500;600;700&family=Roboto:wght@400;500;700&display=swap"
|
||||
/>
|
||||
<title>AstrBot - 仪表盘</title>
|
||||
<script type="module" crossorigin src="/assets/index-cccb34e6.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-9075b0bb.js"></script>
|
||||
<link rel="stylesheet" href="/assets/index-0f1523f3.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -104,14 +104,14 @@ class DashBoardHelper():
|
||||
)
|
||||
qq_gocq_platform_group = DashBoardConfig(
|
||||
config_type="group",
|
||||
name="GO-CQHTTP 平台配置",
|
||||
name="OneBot协议平台配置",
|
||||
description="",
|
||||
body=[
|
||||
DashBoardConfig(
|
||||
config_type="item",
|
||||
val_type="bool",
|
||||
name="启用 GO-CQHTTP 平台",
|
||||
description="gocq 是一个基于 HTTP 协议的 CQHTTP 协议的实现。详见 github.com/Mrs4s/go-cqhttp",
|
||||
name="启用",
|
||||
description="支持cq-http、shamrock等(目前仅支持QQ平台)",
|
||||
value=config['gocqbot']['enable'],
|
||||
path="gocqbot.enable",
|
||||
),
|
||||
@@ -135,7 +135,7 @@ class DashBoardHelper():
|
||||
config_type="item",
|
||||
val_type="int",
|
||||
name="WebSocket 服务器端口",
|
||||
description="",
|
||||
description="目前仅支持正向 WebSocket",
|
||||
value=config['gocq_websocket_port'],
|
||||
path="gocq_websocket_port",
|
||||
),
|
||||
|
||||
@@ -332,8 +332,8 @@ class AstrBotDashBoard():
|
||||
"tag": ""
|
||||
},
|
||||
{
|
||||
"title": "QQ_GOCQ",
|
||||
"desc": "go-cqhttp",
|
||||
"title": "OneBot协议",
|
||||
"desc": "支持cq-http、shamrock等(目前仅支持QQ平台)",
|
||||
"namespace": "internal_platform_qq_gocq",
|
||||
"tag": ""
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ from cores.qqbot.global_object import (
|
||||
AstrMessageEvent,
|
||||
CommandResult
|
||||
)
|
||||
import os
|
||||
import shutil
|
||||
|
||||
'''
|
||||
注意改插件名噢!格式:XXXPlugin 或 Main
|
||||
@@ -18,7 +20,14 @@ class HelloWorldPlugin:
|
||||
初始化函数, 可以选择直接pass
|
||||
"""
|
||||
def __init__(self) -> None:
|
||||
print("hello, world!")
|
||||
# 复制旧配置文件到 data 目录下。
|
||||
if os.path.exists("keyword.json"):
|
||||
shutil.move("keyword.json", "data/keyword.json")
|
||||
self.keywords = {}
|
||||
if os.path.exists("data/keyword.json"):
|
||||
self.keywords = json.load(open("data/keyword.json", "r"))
|
||||
else:
|
||||
self.save_keyword()
|
||||
|
||||
"""
|
||||
机器人程序会调用此函数。
|
||||
@@ -28,20 +37,106 @@ class HelloWorldPlugin:
|
||||
"""
|
||||
def run(self, ame: AstrMessageEvent):
|
||||
if ame.message_str == "helloworld":
|
||||
# return True, tuple([True, "Hello World!!", "helloworld"])
|
||||
return CommandResult(
|
||||
hit=True,
|
||||
success=True,
|
||||
message_chain=[Plain("Hello World!!")],
|
||||
command_name="helloworld"
|
||||
)
|
||||
if ame.message_str.startswith("/keyword") or ame.message_str.startswith("keyword"):
|
||||
return self.handle_keyword_command(ame)
|
||||
|
||||
ret = self.check_keyword(ame.message_str)
|
||||
if ret: return ret
|
||||
|
||||
return CommandResult(
|
||||
hit=False,
|
||||
success=False,
|
||||
message_chain=None,
|
||||
command_name=None
|
||||
)
|
||||
|
||||
def handle_keyword_command(self, ame: AstrMessageEvent):
|
||||
l = ame.message_str.split(" ")
|
||||
|
||||
# 获取图片
|
||||
image_url = ""
|
||||
for comp in ame.message_obj.message:
|
||||
if isinstance(comp, Image) and image_url == "":
|
||||
if comp.url is None:
|
||||
image_url = comp.file
|
||||
else:
|
||||
image_url = comp.url
|
||||
|
||||
command_result = CommandResult(
|
||||
hit=True,
|
||||
success=False,
|
||||
message_chain=None,
|
||||
command_name="keyword"
|
||||
)
|
||||
if len(l) == 1 or (len(l) == 2 and image_url == ""):
|
||||
ret = """【设置关键词回复】
|
||||
示例:
|
||||
1. keyword <触发词> <回复词>
|
||||
keyword hi 你好
|
||||
发送 hi 回复你好
|
||||
* 回复词支持图片
|
||||
|
||||
2. keyword d <触发词>
|
||||
keyword d hi
|
||||
删除 hi 触发词产生的回复"""
|
||||
command_result.success = True
|
||||
command_result.message_chain = [Plain(ret)]
|
||||
return command_result
|
||||
elif len(l) == 3 and l[1] == "d":
|
||||
if l[2] not in self.keywords:
|
||||
command_result.message_chain = [Plain(f"关键词 {l[2]} 不存在")]
|
||||
return command_result
|
||||
self.keywords.pop(l[2])
|
||||
self.save_keyword()
|
||||
command_result.success = True
|
||||
command_result.message_chain = [Plain("删除成功")]
|
||||
return command_result
|
||||
else:
|
||||
return CommandResult(
|
||||
hit=False,
|
||||
success=False,
|
||||
message_chain=None,
|
||||
command_name=None
|
||||
)
|
||||
self.keywords[l[1]] = {
|
||||
"plain_text": " ".join(l[2:]),
|
||||
"image_url": image_url
|
||||
}
|
||||
self.save_keyword()
|
||||
command_result.success = True
|
||||
command_result.message_chain = [Plain("设置成功")]
|
||||
return command_result
|
||||
|
||||
def save_keyword(self):
|
||||
json.dump(self.keywords, open("data/keyword.json", "w"), ensure_ascii=False)
|
||||
|
||||
|
||||
def check_keyword(self, message_str: str):
|
||||
for k in self.keywords:
|
||||
if message_str == k:
|
||||
plain_text = ""
|
||||
if 'plain_text' in self.keywords[k]:
|
||||
plain_text = self.keywords[k]['plain_text']
|
||||
else:
|
||||
plain_text = self.keywords[k]
|
||||
image_url = ""
|
||||
if 'image_url' in self.keywords[k]:
|
||||
image_url = self.keywords[k]['image_url']
|
||||
if image_url != "":
|
||||
res = [Plain(plain_text), Image.fromURL(image_url)]
|
||||
return CommandResult(
|
||||
hit=True,
|
||||
success=True,
|
||||
message_chain=res,
|
||||
command_name="keyword"
|
||||
)
|
||||
return CommandResult(
|
||||
hit=True,
|
||||
success=True,
|
||||
message_chain=[Plain(plain_text)],
|
||||
command_name="keyword"
|
||||
)
|
||||
|
||||
"""
|
||||
插件元信息。
|
||||
当用户输入 plugin v 插件名称 时,会调用此函数,返回帮助信息。
|
||||
@@ -58,8 +153,8 @@ class HelloWorldPlugin:
|
||||
def info(self):
|
||||
return {
|
||||
"name": "helloworld",
|
||||
"desc": "测试插件",
|
||||
"help": "测试插件, 回复 helloworld 即可触发",
|
||||
"version": "v1.2",
|
||||
"desc": "这是 AstrBot 的默认插件,支持关键词回复。",
|
||||
"help": "输入 /keyword 查看关键词回复帮助。",
|
||||
"version": "v1.3",
|
||||
"author": "Soulter"
|
||||
}
|
||||
Submodule addons/plugins/llms deleted from ec088771a3
@@ -1,23 +0,0 @@
|
||||
'''
|
||||
监测机器性能
|
||||
- Bot 内存使用量
|
||||
- CPU 占用率
|
||||
'''
|
||||
|
||||
import psutil
|
||||
from cores.qqbot.global_object import GlobalObject
|
||||
import time
|
||||
|
||||
def run_monitor(global_object: GlobalObject):
|
||||
'''运行监测'''
|
||||
start_time = time.time()
|
||||
while True:
|
||||
stat = global_object.dashboard_data.stats
|
||||
# 程序占用的内存大小
|
||||
mem = psutil.Process().memory_info().rss / 1024 / 1024 # MB
|
||||
stat['sys_perf'] = {
|
||||
'memory': mem,
|
||||
'cpu': psutil.cpu_percent()
|
||||
}
|
||||
stat['sys_start_time'] = start_time
|
||||
time.sleep(30)
|
||||
+47
-135
@@ -1,37 +1,37 @@
|
||||
import re
|
||||
import json
|
||||
import threading
|
||||
import asyncio
|
||||
import time
|
||||
import requests
|
||||
import aiohttp
|
||||
import util.unfit_words as uw
|
||||
import os
|
||||
import sys
|
||||
from cores.qqbot.personality import personalities
|
||||
from addons.baidu_aip_judge import BaiduJudge
|
||||
import io
|
||||
import traceback
|
||||
|
||||
import util.function_calling.gplugin as gplugin
|
||||
import util.plugin_util as putil
|
||||
|
||||
from PIL import Image as PILImage
|
||||
from typing import Union
|
||||
from nakuru import (
|
||||
GroupMessage,
|
||||
FriendMessage,
|
||||
GuildMessage,
|
||||
)
|
||||
from model.platform._nakuru_translation_layer import NakuruGuildMember, NakuruGuildMessage
|
||||
from nakuru.entities.components import Plain,At,Image
|
||||
from nakuru.entities.components import Plain, At, Image
|
||||
|
||||
from addons.baidu_aip_judge import BaiduJudge
|
||||
from model.platform._nakuru_translation_layer import NakuruGuildMessage
|
||||
from model.provider.provider import Provider
|
||||
from model.command.command import Command
|
||||
from util import general_utils as gu
|
||||
from util.general_utils import Logger
|
||||
from util.general_utils import Logger, upload, run_monitor
|
||||
from util.cmd_config import CmdConfig as cc
|
||||
from util.cmd_config import init_astrbot_config_items
|
||||
import util.function_calling.gplugin as gplugin
|
||||
import util.plugin_util as putil
|
||||
from PIL import Image as PILImage
|
||||
import io
|
||||
import traceback
|
||||
from . global_object import GlobalObject
|
||||
from typing import Union
|
||||
from addons.dashboard.helper import DashBoardHelper
|
||||
from addons.dashboard.server import DashBoardData
|
||||
from cores.monitor.perf import run_monitor
|
||||
from cores.database.conn import dbConn
|
||||
from model.platform._message_result import MessageResult
|
||||
|
||||
@@ -40,15 +40,14 @@ user_frequency = {}
|
||||
# 时间默认值
|
||||
frequency_time = 60
|
||||
# 计数默认值
|
||||
frequency_count = 2
|
||||
frequency_count = 10
|
||||
|
||||
# 版本
|
||||
version = '3.1.2'
|
||||
version = '3.1.6'
|
||||
|
||||
# 语言模型
|
||||
REV_CHATGPT = 'rev_chatgpt'
|
||||
OPENAI_OFFICIAL = 'openai_official'
|
||||
REV_ERNIE = 'rev_ernie'
|
||||
NONE_LLM = 'none_llm'
|
||||
chosen_provider = None
|
||||
# 语言模型对象
|
||||
@@ -58,8 +57,6 @@ llm_wake_prefix = ""
|
||||
|
||||
# 百度内容审核实例
|
||||
baidu_judge = None
|
||||
# 关键词回复
|
||||
keywords = {}
|
||||
|
||||
# CLI
|
||||
PLATFORM_CLI = 'cli'
|
||||
@@ -70,36 +67,6 @@ init_astrbot_config_items()
|
||||
_global_object: GlobalObject = None
|
||||
logger: Logger = Logger()
|
||||
|
||||
# 统计消息数据
|
||||
def upload():
|
||||
global version
|
||||
while True:
|
||||
addr_ip = ''
|
||||
try:
|
||||
o = {
|
||||
"cnt_total": _global_object.cnt_total,
|
||||
"admin": _global_object.admin_qq,
|
||||
}
|
||||
o_j = json.dumps(o)
|
||||
res = {
|
||||
"version": version,
|
||||
"count": _global_object.cnt_total,
|
||||
"cntqc": -1,
|
||||
"cntgc": -1,
|
||||
"ip": addr_ip,
|
||||
"others": o_j,
|
||||
"sys": sys.platform,
|
||||
}
|
||||
logger.log(res, gu.LEVEL_DEBUG, tag="Uploader")
|
||||
resp = requests.post('https://api.soulter.top/upload', data=json.dumps(res), timeout=5)
|
||||
if resp.status_code == 200:
|
||||
ok = resp.json()
|
||||
if ok['status'] == 'ok':
|
||||
_global_object.cnt_total = 0
|
||||
except BaseException as e:
|
||||
pass
|
||||
time.sleep(10*60)
|
||||
|
||||
# 语言模型选择
|
||||
def privider_chooser(cfg):
|
||||
l = []
|
||||
@@ -112,11 +79,11 @@ def privider_chooser(cfg):
|
||||
'''
|
||||
初始化机器人
|
||||
'''
|
||||
def initBot(cfg):
|
||||
def init(cfg):
|
||||
global llm_instance, llm_command_instance
|
||||
global baidu_judge, chosen_provider
|
||||
global frequency_count, frequency_time
|
||||
global keywords, _global_object
|
||||
global _global_object
|
||||
global logger
|
||||
|
||||
# 迁移旧配置
|
||||
@@ -129,6 +96,7 @@ def initBot(cfg):
|
||||
|
||||
# 初始化 global_object
|
||||
_global_object = GlobalObject()
|
||||
_global_object.version = version
|
||||
_global_object.base_config = cfg
|
||||
_global_object.stat['session'] = {}
|
||||
_global_object.stat['message'] = {}
|
||||
@@ -168,11 +136,6 @@ def initBot(cfg):
|
||||
llm_command_instance[OPENAI_OFFICIAL] = CommandOpenAIOfficial(llm_instance[OPENAI_OFFICIAL], _global_object)
|
||||
chosen_provider = OPENAI_OFFICIAL
|
||||
|
||||
# 得到关键词
|
||||
if os.path.exists("keyword.json"):
|
||||
with open("keyword.json", 'r', encoding='utf-8') as f:
|
||||
keywords = json.load(f)
|
||||
|
||||
# 检查provider设置偏好
|
||||
p = cc.get("chosen_provider", None)
|
||||
if p is not None and p in llm_instance:
|
||||
@@ -186,7 +149,7 @@ def initBot(cfg):
|
||||
except BaseException as e:
|
||||
logger.log("百度内容审核初始化失败", gu.LEVEL_ERROR)
|
||||
|
||||
threading.Thread(target=upload, daemon=True).start()
|
||||
threading.Thread(target=upload, args=(_global_object, ), daemon=True).start()
|
||||
|
||||
# 得到发言频率配置
|
||||
if 'limit' in cfg:
|
||||
@@ -197,9 +160,9 @@ def initBot(cfg):
|
||||
|
||||
try:
|
||||
if 'uniqueSessionMode' in cfg and cfg['uniqueSessionMode']:
|
||||
_global_object.uniqueSession = True
|
||||
_global_object.unique_session = True
|
||||
else:
|
||||
_global_object.uniqueSession = False
|
||||
_global_object.unique_session = False
|
||||
except BaseException as e:
|
||||
logger.log("独立会话配置错误: "+str(e), gu.LEVEL_ERROR)
|
||||
|
||||
@@ -270,38 +233,10 @@ def initBot(cfg):
|
||||
logger.log("请给 https://github.com/Soulter/AstrBot 点个 star。", gu.LEVEL_INFO)
|
||||
if platform_str == '':
|
||||
platform_str = "(未启动任何平台,请前往面板添加)"
|
||||
logger.log(f"🎉 项目启动完成\n - 启动的LLM: {len(llm_instance)}个\n - 启动的平台: {platform_str}\n - 启动的插件: {len(_global_object.cached_plugins)}个")
|
||||
logger.log(f"🎉 项目启动完成")
|
||||
|
||||
dashboard_thread.join()
|
||||
|
||||
async def cli():
|
||||
time.sleep(1)
|
||||
while True:
|
||||
try:
|
||||
prompt = input(">>> ")
|
||||
if prompt == "":
|
||||
continue
|
||||
ngm = await cli_pack_message(prompt)
|
||||
await oper_msg(ngm, True, PLATFORM_CLI)
|
||||
except EOFError:
|
||||
return
|
||||
|
||||
async def cli_pack_message(prompt: str) -> NakuruGuildMessage:
|
||||
ngm = NakuruGuildMessage()
|
||||
ngm.channel_id = 6180
|
||||
ngm.user_id = 6180
|
||||
ngm.message = [Plain(prompt)]
|
||||
ngm.type = "GuildMessage"
|
||||
ngm.self_id = 6180
|
||||
ngm.self_tiny_id = 6180
|
||||
ngm.guild_id = 6180
|
||||
ngm.sender = NakuruGuildMember()
|
||||
ngm.sender.tiny_id = 6180
|
||||
ngm.sender.user_id = 6180
|
||||
ngm.sender.nickname = "CLI"
|
||||
ngm.sender.role = 0
|
||||
return ngm
|
||||
|
||||
'''
|
||||
运行 QQ_OFFICIAL 机器人
|
||||
'''
|
||||
@@ -321,13 +256,16 @@ def run_qqchan_bot(cfg: dict, global_object: GlobalObject):
|
||||
def run_gocq_bot(cfg: dict, _global_object: GlobalObject):
|
||||
from model.platform.qq_gocq import QQGOCQ
|
||||
|
||||
logger.log("正在检查本地GO-CQHTTP连接...端口5700, 6700", tag="QQ")
|
||||
noticed = False
|
||||
host = cc.get("gocq_host", "127.0.0.1")
|
||||
port = cc.get("gocq_websocket_port", 6700)
|
||||
http_port = cc.get("gocq_http_port", 5700)
|
||||
logger.log(f"正在检查连接...host: {host}, ws port: {port}, http port: {http_port}", tag="QQ")
|
||||
while True:
|
||||
if not gu.port_checker(5700, cc.get("gocq_host", "127.0.0.1")) or not gu.port_checker(6700, cc.get("gocq_host", "127.0.0.1")):
|
||||
if not gu.port_checker(port=port, host=host) or not gu.port_checker(port=http_port, host=host):
|
||||
if not noticed:
|
||||
noticed = True
|
||||
logger.log("与GO-CQHTTP通信失败, 请检查GO-CQHTTP是否启动并正确配置。程序会每隔 5s 自动重试。", gu.LEVEL_CRITICAL, tag="QQ")
|
||||
logger.log(f"连接到{host}:{port}(或{http_port})失败。程序会每隔 5s 自动重试。", gu.LEVEL_CRITICAL, tag="QQ")
|
||||
time.sleep(5)
|
||||
else:
|
||||
logger.log("检查完毕,未发现问题。", tag="QQ")
|
||||
@@ -339,7 +277,6 @@ def run_gocq_bot(cfg: dict, _global_object: GlobalObject):
|
||||
except BaseException as e:
|
||||
input("启动QQ机器人出现错误"+str(e))
|
||||
|
||||
|
||||
'''
|
||||
检查发言频率
|
||||
'''
|
||||
@@ -382,7 +319,7 @@ async def oper_msg(message: Union[GroupMessage, FriendMessage, GuildMessage, Nak
|
||||
role: member | admin
|
||||
platform: 平台(gocq, qqchan)
|
||||
"""
|
||||
global chosen_provider, keywords, _global_object
|
||||
global chosen_provider, _global_object
|
||||
message_str = ''
|
||||
session_id = session_id
|
||||
role = role
|
||||
@@ -390,7 +327,7 @@ async def oper_msg(message: Union[GroupMessage, FriendMessage, GuildMessage, Nak
|
||||
command_result = () # 调用指令返回的结果
|
||||
|
||||
# 统计数据,如频道消息量
|
||||
record_message(platform, session_id)
|
||||
await record_message(platform, session_id)
|
||||
|
||||
for i in message.message:
|
||||
if isinstance(i, Plain):
|
||||
@@ -399,25 +336,8 @@ async def oper_msg(message: Union[GroupMessage, FriendMessage, GuildMessage, Nak
|
||||
return MessageResult("Hi~")
|
||||
|
||||
# 检查发言频率
|
||||
user_id = message.user_id
|
||||
if not check_frequency(user_id):
|
||||
if not check_frequency(message.user_id):
|
||||
return MessageResult(f'你的发言超过频率限制(╯▔皿▔)╯。\n管理员设置{frequency_time}秒内只能提问{frequency_count}次。')
|
||||
|
||||
# 关键词回复
|
||||
for k in keywords:
|
||||
if message_str == k:
|
||||
plain_text = ""
|
||||
if 'plain_text' in keywords[k]:
|
||||
plain_text = keywords[k]['plain_text']
|
||||
else:
|
||||
plain_text = keywords[k]
|
||||
image_url = ""
|
||||
if 'image_url' in keywords[k]:
|
||||
image_url = keywords[k]['image_url']
|
||||
if image_url != "":
|
||||
res = [Plain(plain_text), Image.fromURL(image_url)]
|
||||
return MessageResult(res)
|
||||
return MessageResult(plain_text)
|
||||
|
||||
# 检查是否是更换语言模型的请求
|
||||
temp_switch = ""
|
||||
@@ -440,7 +360,8 @@ async def oper_msg(message: Union[GroupMessage, FriendMessage, GuildMessage, Nak
|
||||
|
||||
llm_result_str = ""
|
||||
|
||||
hit, command_result = llm_command_instance[chosen_provider].check_command(
|
||||
# check commands and plugins
|
||||
hit, command_result = await llm_command_instance[chosen_provider].check_command(
|
||||
message_str,
|
||||
session_id,
|
||||
role,
|
||||
@@ -456,11 +377,12 @@ async def oper_msg(message: Union[GroupMessage, FriendMessage, GuildMessage, Nak
|
||||
if matches:
|
||||
return MessageResult(f"你的提问得到的回复未通过【默认关键词拦截】服务, 不予回复。")
|
||||
if baidu_judge != None:
|
||||
check, msg = baidu_judge.judge(message_str)
|
||||
check, msg = await asyncio.to_thread(baidu_judge.judge, message_str)
|
||||
if not check:
|
||||
return MessageResult(f"你的提问得到的回复未通过【百度AI内容审核】服务, 不予回复。\n\n{msg}")
|
||||
if chosen_provider == NONE_LLM:
|
||||
return MessageResult("没有启动任何 LLM 并且未触发任何指令。")
|
||||
logger.log("一条消息由于 Bot 未启动任何语言模型并且未触发指令而将被忽略。", gu.LEVEL_WARNING)
|
||||
return
|
||||
try:
|
||||
if llm_wake_prefix != "" and not message_str.startswith(llm_wake_prefix):
|
||||
return
|
||||
@@ -484,9 +406,9 @@ async def oper_msg(message: Union[GroupMessage, FriendMessage, GuildMessage, Nak
|
||||
if chosen_provider == REV_CHATGPT or chosen_provider == OPENAI_OFFICIAL:
|
||||
if _global_object.web_search or web_sch_flag:
|
||||
official_fc = chosen_provider == OPENAI_OFFICIAL
|
||||
llm_result_str = gplugin.web_search(message_str, llm_instance[chosen_provider], session_id, official_fc)
|
||||
llm_result_str = await gplugin.web_search(message_str, llm_instance[chosen_provider], session_id, official_fc)
|
||||
else:
|
||||
llm_result_str = str(llm_instance[chosen_provider].text_chat(message_str, session_id, image_url, default_personality = _global_object.default_personality))
|
||||
llm_result_str = await llm_instance[chosen_provider].text_chat(message_str, session_id, image_url, default_personality = _global_object.default_personality)
|
||||
|
||||
llm_result_str = _global_object.reply_prefix + llm_result_str
|
||||
except BaseException as e:
|
||||
@@ -497,23 +419,13 @@ async def oper_msg(message: Union[GroupMessage, FriendMessage, GuildMessage, Nak
|
||||
if temp_switch != "":
|
||||
chosen_provider = temp_switch
|
||||
|
||||
# 指令回复
|
||||
if hit:
|
||||
# 检查指令。command_result 是一个元组:(指令调用是否成功, 指令返回的文本结果, 指令类型)
|
||||
# 有指令或者插件触发
|
||||
# command_result 是一个元组:(指令调用是否成功, 指令返回的文本结果, 指令类型)
|
||||
if command_result == None:
|
||||
return
|
||||
command = command_result[2]
|
||||
|
||||
if command == "keyword":
|
||||
if os.path.exists("keyword.json"):
|
||||
with open("keyword.json", "r", encoding="utf-8") as f:
|
||||
keywords = json.load(f)
|
||||
else:
|
||||
try:
|
||||
return MessageResult(command_result[1])
|
||||
except BaseException as e:
|
||||
return MessageResult(f"回复消息出错: {str(e)}")
|
||||
|
||||
if command == "update latest r":
|
||||
def update_restart():
|
||||
py = sys.executable
|
||||
@@ -527,11 +439,11 @@ async def oper_msg(message: Union[GroupMessage, FriendMessage, GuildMessage, Nak
|
||||
if isinstance(command_result[1], list) and len(command_result) == 3 and command == 'draw':
|
||||
for i in command_result[1]:
|
||||
# 保存到本地
|
||||
pic_res = requests.get(i, stream = True)
|
||||
if pic_res.status_code == 200:
|
||||
image = PILImage.open(io.BytesIO(pic_res.content))
|
||||
return MessageResult([Image.fromFileSystem(gu.save_temp_img(image))])
|
||||
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.get(i) as resp:
|
||||
if resp.status == 200:
|
||||
image = PILImage.open(io.BytesIO(await resp.read()))
|
||||
return MessageResult([Image.fromFileSystem(gu.save_temp_img(image))])
|
||||
# 其他指令
|
||||
else:
|
||||
try:
|
||||
@@ -546,7 +458,7 @@ async def oper_msg(message: Union[GroupMessage, FriendMessage, GuildMessage, Nak
|
||||
llm_result_str = re.sub(i, "***", llm_result_str)
|
||||
# 百度内容审核服务二次审核
|
||||
if baidu_judge != None:
|
||||
check, msg = baidu_judge.judge(llm_result_str)
|
||||
check, msg = await asyncio.to_thread(baidu_judge.judge, llm_result_str)
|
||||
if not check:
|
||||
return MessageResult(f"你的提问得到的回复【百度内容审核】未通过,不予回复。\n\n{msg}")
|
||||
# 发送信息
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
from model.platform.qq_official import QQOfficial, NakuruGuildMember, NakuruGuildMessage
|
||||
from model.platform.qq_official import QQOfficial, NakuruGuildMessage
|
||||
from model.platform.qq_gocq import QQGOCQ
|
||||
from model.provider.provider import Provider
|
||||
from addons.dashboard.server import DashBoardData
|
||||
from nakuru import (
|
||||
CQHTTP,
|
||||
GroupMessage,
|
||||
GroupMemberIncrease,
|
||||
FriendMessage,
|
||||
GuildMessage,
|
||||
Notify
|
||||
)
|
||||
from typing import Union
|
||||
|
||||
@@ -16,6 +13,7 @@ class GlobalObject:
|
||||
'''
|
||||
存放一些公用的数据,用于在不同模块(如core与command)之间传递
|
||||
'''
|
||||
version: str
|
||||
nick: str # gocq 的昵称
|
||||
base_config: dict # config.json
|
||||
cached_plugins: dict # 缓存的插件
|
||||
@@ -23,7 +21,7 @@ class GlobalObject:
|
||||
reply_prefix: str
|
||||
admin_qq: str
|
||||
admin_qqchan: str
|
||||
uniqueSession: bool
|
||||
unique_session: bool
|
||||
cnt_total: int
|
||||
platform_qq: QQGOCQ
|
||||
platform_qqchan: QQOfficial
|
||||
@@ -40,7 +38,7 @@ class GlobalObject:
|
||||
self.reply_prefix = None
|
||||
self.admin_qq = "123456"
|
||||
self.admin_qqchan = "123456"
|
||||
self.uniqueSession = False
|
||||
self.unique_session = False
|
||||
self.cnt_total = 0
|
||||
self.platform_qq = None
|
||||
self.platform_qqchan = None
|
||||
@@ -57,7 +55,7 @@ class AstrMessageEvent():
|
||||
platform: str # `gocq` 或 `qqchan`
|
||||
role: str # `admin` 或 `member`
|
||||
global_object: GlobalObject # 一些公用数据
|
||||
session_id: int # 会话id (可能是群id,也可能是某个user的id。取决于是否开启了 uniqueSession)
|
||||
session_id: int # 会话id (可能是群id,也可能是某个user的id。取决于是否开启了 unique_session)
|
||||
|
||||
def __init__(self, message_str: str,
|
||||
message_obj: Union[GroupMessage, FriendMessage, GuildMessage, NakuruGuildMessage],
|
||||
|
||||
@@ -42,7 +42,7 @@ def main():
|
||||
os.mkdir(abs_path+"data/config")
|
||||
|
||||
# 启动主程序(cores/qqbot/core.py)
|
||||
qqBot.initBot(cfg)
|
||||
qqBot.init(cfg)
|
||||
|
||||
def check_env(ch_mirror=False):
|
||||
if not (sys.version_info.major == 3 and sys.version_info.minor >= 9):
|
||||
|
||||
+40
-104
@@ -1,17 +1,20 @@
|
||||
import json
|
||||
from util import general_utils as gu
|
||||
import os
|
||||
import requests
|
||||
from model.provider.provider import Provider
|
||||
import inspect
|
||||
import aiohttp
|
||||
import asyncio
|
||||
import json
|
||||
|
||||
import util.plugin_util as putil
|
||||
from util.cmd_config import CmdConfig as cc
|
||||
from util.general_utils import Logger
|
||||
import util.updator
|
||||
|
||||
from nakuru.entities.components import (
|
||||
Plain,
|
||||
Image
|
||||
)
|
||||
from util import general_utils as gu
|
||||
from model.provider.provider import Provider
|
||||
from util.cmd_config import CmdConfig as cc
|
||||
from util.general_utils import Logger
|
||||
from cores.qqbot.global_object import GlobalObject, AstrMessageEvent
|
||||
from cores.qqbot.global_object import CommandResult
|
||||
|
||||
@@ -25,12 +28,13 @@ class Command:
|
||||
self.global_object = global_object
|
||||
self.logger: Logger = global_object.logger
|
||||
|
||||
def check_command(self,
|
||||
async def check_command(self,
|
||||
message,
|
||||
session_id: str,
|
||||
role,
|
||||
platform,
|
||||
message_obj):
|
||||
self.platform = platform
|
||||
# 插件
|
||||
cached_plugins = self.global_object.cached_plugins
|
||||
# 将消息封装成 AstrMessageEvent 对象
|
||||
@@ -46,8 +50,14 @@ class Command:
|
||||
)
|
||||
# 从已启动的插件中查找是否有匹配的指令
|
||||
for k, v in cached_plugins.items():
|
||||
# 过滤掉平台类插件
|
||||
if "type" in v["info"] and v["info"]["plugin_type"] == "platform":
|
||||
continue
|
||||
try:
|
||||
result = v["clsobj"].run(ame)
|
||||
if inspect.iscoroutinefunction(v["clsobj"].run):
|
||||
result = await v["clsobj"].run(ame)
|
||||
else:
|
||||
result = await asyncio.to_thread(v["clsobj"].run, ame)
|
||||
if isinstance(result, CommandResult):
|
||||
hit = result.hit
|
||||
res = result._result_tuple()
|
||||
@@ -61,13 +71,16 @@ class Command:
|
||||
except TypeError as e:
|
||||
# 参数不匹配,尝试使用旧的参数方案
|
||||
try:
|
||||
hit, res = v["clsobj"].run(message, role, platform, message_obj, self.global_object.platform_qq)
|
||||
if inspect.iscoroutinefunction(v["clsobj"].run):
|
||||
hit, res = await v["clsobj"].run(message, role, platform, message_obj, self.global_object.platform_qq)
|
||||
else:
|
||||
hit, res = await asyncio.to_thread(v["clsobj"].run, message, role, platform, message_obj, self.global_object.platform_qq)
|
||||
if hit:
|
||||
return True, res
|
||||
except BaseException as e:
|
||||
self.logger.log(f"{k}插件异常,原因: {str(e)}\n已安装插件: {cached_plugins.keys}\n如果你没有相关装插件的想法, 请直接忽略此报错, 不影响其他功能的运行。", level=gu.LEVEL_WARNING)
|
||||
self.logger.log(f"{k} 插件异常,原因: {str(e)}\n如果你没有相关装插件的想法, 请直接忽略此报错, 不影响其他功能的运行。", level=gu.LEVEL_WARNING)
|
||||
except BaseException as e:
|
||||
self.logger.log(f"{k} 插件异常,原因: {str(e)}\n已安装插件: {cached_plugins.keys}\n如果你没有相关装插件的想法, 请直接忽略此报错, 不影响其他功能的运行。", level=gu.LEVEL_WARNING)
|
||||
self.logger.log(f"{k} 插件异常,原因: {str(e)}\n如果你没有相关装插件的想法, 请直接忽略此报错, 不影响其他功能的运行。", level=gu.LEVEL_WARNING)
|
||||
|
||||
if self.command_start_with(message, "nick"):
|
||||
return True, self.set_nick(message, platform, role)
|
||||
@@ -75,18 +88,13 @@ class Command:
|
||||
return True, self.plugin_oper(message, role, cached_plugins, platform)
|
||||
if self.command_start_with(message, "myid") or self.command_start_with(message, "!myid"):
|
||||
return True, self.get_my_id(message_obj, platform)
|
||||
if self.command_start_with(message, "nconf") or self.command_start_with(message, "newconf"):
|
||||
return True, self.get_new_conf(message, role)
|
||||
if self.command_start_with(message, "web"): # 网页搜索
|
||||
return True, self.web_search(message)
|
||||
if self.command_start_with(message, "keyword"):
|
||||
return True, self.keyword(message_obj, role)
|
||||
if self.command_start_with(message, "ip"):
|
||||
ip = requests.get("https://myip.ipip.net", timeout=5).text
|
||||
return True, f"机器人 IP 信息:{ip}", "ip"
|
||||
if not self.provider and self.command_start_with(message, "help"):
|
||||
return True, await self.help()
|
||||
|
||||
return False, None
|
||||
|
||||
|
||||
def web_search(self, message):
|
||||
l = message.split(' ')
|
||||
if len(l) == 1:
|
||||
@@ -99,13 +107,11 @@ class Command:
|
||||
return True, "已关闭网页搜索", "web"
|
||||
|
||||
def get_my_id(self, message_obj, platform):
|
||||
user_id = "Unknown"
|
||||
if platform == PLATFORM_QQCHAN:
|
||||
user_id = str(message_obj.sender.tiny_id)
|
||||
elif platform == PLATFORM_GOCQ:
|
||||
try:
|
||||
user_id = str(message_obj.user_id)
|
||||
|
||||
return True, f"你在此平台上的ID:{user_id}", "plugin"
|
||||
return True, f"你在此平台上的ID:{user_id}", "plugin"
|
||||
except BaseException as e:
|
||||
return False, f"在{platform}上获取你的ID失败,原因: {str(e)}", "plugin"
|
||||
|
||||
def get_new_conf(self, message, role):
|
||||
if role != "admin":
|
||||
@@ -200,14 +206,14 @@ class Command:
|
||||
"/revgpt": "切换到网页版ChatGPT",
|
||||
}
|
||||
|
||||
def help_messager(self, commands: dict, platform: str, cached_plugins: dict = None):
|
||||
async def help_messager(self, commands: dict, platform: str, cached_plugins: dict = None):
|
||||
try:
|
||||
resp = requests.get("https://soulter.top/channelbot/notice.json").text
|
||||
notice = json.loads(resp)["notice"]
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.get("https://soulter.top/channelbot/notice.json") as resp:
|
||||
notice = (await resp.json())["notice"]
|
||||
except BaseException as e:
|
||||
notice = ""
|
||||
msg = "# Help Center\n## 指令列表\n"
|
||||
# msg = "Github项目名QQChannelChatGPT, 有问题提交issue, 欢迎Star\n【指令列表】\n"
|
||||
for key, value in commands.items():
|
||||
msg += f"`{key}` - {value}\n"
|
||||
# plugins
|
||||
@@ -219,12 +225,10 @@ class Command:
|
||||
msg += notice
|
||||
|
||||
try:
|
||||
# p = gu.create_text_image("【Help Center】", msg)
|
||||
p = gu.create_markdown_image(msg)
|
||||
return [Image.fromFileSystem(p)]
|
||||
return [Image.fromFileSystem(p),]
|
||||
except BaseException as e:
|
||||
self.logger.log(str(e))
|
||||
finally:
|
||||
return msg
|
||||
|
||||
def command_start_with(self, message: str, *args):
|
||||
@@ -236,78 +240,9 @@ class Command:
|
||||
return True
|
||||
return False
|
||||
|
||||
# keyword: 关键字
|
||||
def keyword(self, message_obj, role: str):
|
||||
if role != "admin":
|
||||
return True, "你没有权限使用该指令", "keyword"
|
||||
|
||||
plain_text = ""
|
||||
image_url = ""
|
||||
|
||||
for comp in message_obj.message:
|
||||
if isinstance(comp, Plain):
|
||||
plain_text += comp.text
|
||||
elif isinstance(comp, Image) and image_url == "":
|
||||
if comp.url is None:
|
||||
image_url = comp.file
|
||||
else:
|
||||
image_url = comp.url
|
||||
|
||||
l = plain_text.split(" ")
|
||||
|
||||
if len(l) < 3 and image_url == "":
|
||||
return True, """【设置关键词回复】示例:
|
||||
1. keyword hi 你好
|
||||
当发送hi的时候会回复你好
|
||||
2. keyword /hi 你好
|
||||
当发送/hi时会回复你好
|
||||
3. keyword d hi
|
||||
删除hi关键词的回复
|
||||
4. keyword hi <图片>
|
||||
当发送hi时会回复图片""", "keyword"
|
||||
|
||||
del_mode = False
|
||||
if l[1] == "d":
|
||||
del_mode = True
|
||||
|
||||
try:
|
||||
if os.path.exists("keyword.json"):
|
||||
with open("keyword.json", "r", encoding="utf-8") as f:
|
||||
keyword = json.load(f)
|
||||
if del_mode:
|
||||
# 删除关键词
|
||||
if l[2] not in keyword:
|
||||
return False, "该关键词不存在", "keyword"
|
||||
else: del keyword[l[2]]
|
||||
else:
|
||||
keyword[l[1]] = {
|
||||
"plain_text": " ".join(l[2:]),
|
||||
"image_url": image_url
|
||||
}
|
||||
else:
|
||||
if del_mode:
|
||||
return False, "该关键词不存在", "keyword"
|
||||
keyword = {
|
||||
l[1]: {
|
||||
"plain_text": " ".join(l[2:]),
|
||||
"image_url": image_url
|
||||
}
|
||||
}
|
||||
with open("keyword.json", "w", encoding="utf-8") as f:
|
||||
json.dump(keyword, f, ensure_ascii=False, indent=4)
|
||||
f.flush()
|
||||
if del_mode:
|
||||
return True, "删除成功: "+l[2], "keyword"
|
||||
if image_url == "":
|
||||
return True, "设置成功: "+l[1]+" "+" ".join(l[2:]), "keyword"
|
||||
else:
|
||||
return True, [Plain("设置成功: "+l[1]+" "+" ".join(l[2:])), Image.fromURL(image_url)], "keyword"
|
||||
except BaseException as e:
|
||||
return False, "设置失败: "+str(e), "keyword"
|
||||
|
||||
def update(self, message: str, role: str):
|
||||
if role != "admin":
|
||||
return True, "你没有权限使用该指令", "keyword"
|
||||
return True, "你没有权限使用该指令", "update"
|
||||
l = message.split(" ")
|
||||
if len(l) == 1:
|
||||
try:
|
||||
@@ -349,8 +284,9 @@ class Command:
|
||||
def key(self):
|
||||
return False
|
||||
|
||||
def help(self):
|
||||
return False
|
||||
async def help(self):
|
||||
ret = await self.help_messager(self.general_commands(), self.platform, self.global_object.cached_plugins)
|
||||
return True, ret, "help"
|
||||
|
||||
def status(self):
|
||||
return False
|
||||
|
||||
@@ -11,7 +11,7 @@ class CommandOpenAIOfficial(Command):
|
||||
self.personality_str = ""
|
||||
super().__init__(provider, global_object)
|
||||
|
||||
def check_command(self,
|
||||
async def check_command(self,
|
||||
message: str,
|
||||
session_id: str,
|
||||
role: str,
|
||||
@@ -20,7 +20,7 @@ class CommandOpenAIOfficial(Command):
|
||||
self.platform = platform
|
||||
|
||||
# 检查基础指令
|
||||
hit, res = super().check_command(
|
||||
hit, res = await super().check_command(
|
||||
message,
|
||||
session_id,
|
||||
role,
|
||||
@@ -32,7 +32,7 @@ class CommandOpenAIOfficial(Command):
|
||||
if hit:
|
||||
return True, res
|
||||
if self.command_start_with(message, "reset", "重置"):
|
||||
return True, self.reset(session_id, message)
|
||||
return True, await self.reset(session_id, message)
|
||||
elif self.command_start_with(message, "his", "历史"):
|
||||
return True, self.his(message, session_id)
|
||||
elif self.command_start_with(message, "token"):
|
||||
@@ -42,7 +42,7 @@ class CommandOpenAIOfficial(Command):
|
||||
elif self.command_start_with(message, "status"):
|
||||
return True, self.status()
|
||||
elif self.command_start_with(message, "help", "帮助"):
|
||||
return True, self.help()
|
||||
return True, await self.help()
|
||||
elif self.command_start_with(message, "unset"):
|
||||
return True, self.unset(session_id)
|
||||
elif self.command_start_with(message, "set"):
|
||||
@@ -54,11 +54,11 @@ class CommandOpenAIOfficial(Command):
|
||||
elif self.command_start_with(message, "key"):
|
||||
return True, self.key(message)
|
||||
elif self.command_start_with(message, "switch"):
|
||||
return True, self.switch(message)
|
||||
return True, await self.switch(message)
|
||||
|
||||
return False, None
|
||||
|
||||
def help(self):
|
||||
async def help(self):
|
||||
commands = super().general_commands()
|
||||
commands['画'] = '画画'
|
||||
commands['key'] = '添加OpenAI key'
|
||||
@@ -66,15 +66,15 @@ class CommandOpenAIOfficial(Command):
|
||||
commands['gpt'] = '查看gpt配置信息'
|
||||
commands['status'] = '查看key使用状态'
|
||||
commands['token'] = '查看本轮会话token'
|
||||
return True, super().help_messager(commands, self.platform, self.global_object.cached_plugins), "help"
|
||||
return True, await super().help_messager(commands, self.platform, self.global_object.cached_plugins), "help"
|
||||
|
||||
|
||||
def reset(self, session_id: str, message: str = "reset"):
|
||||
async def reset(self, session_id: str, message: str = "reset"):
|
||||
if self.provider is None:
|
||||
return False, "未启用 OpenAI 官方 API", "reset"
|
||||
l = message.split(" ")
|
||||
if len(l) == 1:
|
||||
self.provider.forget(session_id)
|
||||
await self.provider.forget(session_id)
|
||||
return True, "重置成功", "reset"
|
||||
if len(l) == 2 and l[1] == "p":
|
||||
self.provider.forget(session_id)
|
||||
@@ -146,7 +146,7 @@ class CommandOpenAIOfficial(Command):
|
||||
else:
|
||||
return True, "该Key被验证为无效。也许是输入错误了,或者重试。", "key"
|
||||
|
||||
def switch(self, message: str):
|
||||
async def switch(self, message: str):
|
||||
'''
|
||||
切换账号
|
||||
'''
|
||||
@@ -168,7 +168,7 @@ class CommandOpenAIOfficial(Command):
|
||||
else:
|
||||
try:
|
||||
new_key = list(key_stat.keys())[index-1]
|
||||
ret = self.provider.check_key(new_key)
|
||||
ret = await self.provider.check_key(new_key)
|
||||
self.provider.set_key(new_key)
|
||||
except BaseException as e:
|
||||
return True, "账号切换失败,原因: " + str(e), "switch"
|
||||
|
||||
@@ -11,14 +11,14 @@ class CommandRevChatGPT(Command):
|
||||
self.personality_str = ""
|
||||
super().__init__(provider, global_object)
|
||||
|
||||
def check_command(self,
|
||||
async def check_command(self,
|
||||
message: str,
|
||||
session_id: str,
|
||||
role: str,
|
||||
platform: str,
|
||||
message_obj):
|
||||
self.platform = platform
|
||||
hit, res = super().check_command(
|
||||
hit, res = await super().check_command(
|
||||
message,
|
||||
session_id,
|
||||
role,
|
||||
@@ -29,7 +29,7 @@ class CommandRevChatGPT(Command):
|
||||
if hit:
|
||||
return True, res
|
||||
if self.command_start_with(message, "help", "帮助"):
|
||||
return True, self.help()
|
||||
return True, await self.help()
|
||||
elif self.command_start_with(message, "reset"):
|
||||
return True, self.reset(session_id, message)
|
||||
elif self.command_start_with(message, "update"):
|
||||
@@ -127,7 +127,7 @@ class CommandRevChatGPT(Command):
|
||||
else:
|
||||
return True, "参数过多。", "switch"
|
||||
|
||||
def help(self):
|
||||
async def help(self):
|
||||
commands = super().general_commands()
|
||||
commands['set'] = '设置人格'
|
||||
return True, super().help_messager(commands, self.platform, self.global_object.cached_plugins), "help"
|
||||
return True, await super().help_messager(commands, self.platform, self.global_object.cached_plugins), "help"
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import abc
|
||||
import threading
|
||||
import asyncio
|
||||
from typing import Callable, Union
|
||||
from typing import Union
|
||||
from nakuru import (
|
||||
GuildMessage,
|
||||
GroupMessage,
|
||||
@@ -10,7 +8,7 @@ from nakuru import (
|
||||
from ._nakuru_translation_layer import (
|
||||
NakuruGuildMessage,
|
||||
)
|
||||
from nakuru.entities.components import Plain, At, Image, Node
|
||||
from nakuru.entities.components import Plain, At, Image
|
||||
|
||||
|
||||
class Platform():
|
||||
@@ -49,7 +47,7 @@ class Platform():
|
||||
'''
|
||||
pass
|
||||
|
||||
def parse_message_outline(self, message: Union[GuildMessage, GroupMessage, FriendMessage, str]) -> NakuruGuildMessage:
|
||||
def parse_message_outline(self, message: Union[GuildMessage, GroupMessage, FriendMessage, str, list]) -> str:
|
||||
'''
|
||||
将消息解析成大纲消息形式。
|
||||
如: xxxxx[图片]xxxxx
|
||||
@@ -57,26 +55,16 @@ class Platform():
|
||||
if isinstance(message, str):
|
||||
return message
|
||||
ret = ''
|
||||
ls_to_parse = message if isinstance(message, list) else message.message
|
||||
try:
|
||||
for node in message.message:
|
||||
for node in ls_to_parse:
|
||||
if isinstance(node, Plain):
|
||||
ret += node.text
|
||||
elif isinstance(node, At):
|
||||
ret += f'[At: {node.name}/{node.qq}]'
|
||||
elif isinstance(node, Image):
|
||||
ret += f'[图片]'
|
||||
ret += '[图片]'
|
||||
except Exception as e:
|
||||
pass
|
||||
ret.replace('\n', '')
|
||||
return ret
|
||||
|
||||
|
||||
def new_sub_thread(self, func, args=()):
|
||||
thread = threading.Thread(target=self._runner, args=(func, args), daemon=True)
|
||||
thread.start()
|
||||
|
||||
def _runner(self, func: Callable, args: tuple):
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(loop)
|
||||
loop.run_until_complete(func(*args))
|
||||
loop.close()
|
||||
|
||||
+21
-44
@@ -8,8 +8,7 @@ from nakuru import (
|
||||
GroupMessage,
|
||||
FriendMessage,
|
||||
GroupMemberIncrease,
|
||||
Notify,
|
||||
Member
|
||||
Notify
|
||||
)
|
||||
from typing import Union
|
||||
import time
|
||||
@@ -31,7 +30,6 @@ class QQGOCQ(Platform):
|
||||
asyncio.set_event_loop(self.loop)
|
||||
|
||||
self.waiting = {}
|
||||
self.gocq_cnt = 0
|
||||
self.cc = CmdConfig()
|
||||
self.cfg = cfg
|
||||
self.logger: gu.Logger = global_object.logger
|
||||
@@ -60,10 +58,10 @@ class QQGOCQ(Platform):
|
||||
async def _(app: CQHTTP, source: GroupMessage):
|
||||
if self.cc.get("gocq_react_group", True):
|
||||
if isinstance(source.message[0], Plain):
|
||||
self.new_sub_thread(self.handle_msg, (source, True))
|
||||
await self.handle_msg(source, True)
|
||||
elif isinstance(source.message[0], At):
|
||||
if source.message[0].qq == source.self_id:
|
||||
self.new_sub_thread(self.handle_msg, (source, True))
|
||||
await self.handle_msg(source, True)
|
||||
else:
|
||||
return
|
||||
|
||||
@@ -71,7 +69,7 @@ class QQGOCQ(Platform):
|
||||
async def _(app: CQHTTP, source: FriendMessage):
|
||||
if self.cc.get("gocq_react_friend", True):
|
||||
if isinstance(source.message[0], Plain):
|
||||
self.new_sub_thread(self.handle_msg, (source, False))
|
||||
await self.handle_msg(source, False)
|
||||
else:
|
||||
return
|
||||
|
||||
@@ -87,19 +85,16 @@ class QQGOCQ(Platform):
|
||||
async def _(app: CQHTTP, source: Notify):
|
||||
print(source)
|
||||
if source.sub_type == "poke" and source.target_id == source.self_id:
|
||||
# await self.handle_msg(source, False)
|
||||
self.new_sub_thread(self.handle_msg, (source, False))
|
||||
await self.handle_msg(source, False)
|
||||
|
||||
@gocq_app.receiver("GuildMessage")
|
||||
async def _(app: CQHTTP, source: GuildMessage):
|
||||
if self.cc.get("gocq_react_guild", True):
|
||||
if isinstance(source.message[0], Plain):
|
||||
# await self.handle_msg(source, True)
|
||||
self.new_sub_thread(self.handle_msg, (source, True))
|
||||
await self.handle_msg(source, True)
|
||||
elif isinstance(source.message[0], At):
|
||||
if source.message[0].qq == source.self_tiny_id:
|
||||
# await self.handle_msg(source, True)
|
||||
self.new_sub_thread(self.handle_msg, (source, True))
|
||||
await self.handle_msg(source, True)
|
||||
else:
|
||||
return
|
||||
|
||||
@@ -159,7 +154,7 @@ class QQGOCQ(Platform):
|
||||
|
||||
if message_result is None:
|
||||
return
|
||||
self.reply_msg(message, message_result.result_message)
|
||||
await self.reply_msg(message, message_result.result_message)
|
||||
if message_result.callback is not None:
|
||||
message_result.callback()
|
||||
|
||||
@@ -167,16 +162,14 @@ class QQGOCQ(Platform):
|
||||
if session_id in self.waiting and self.waiting[session_id] == '':
|
||||
self.waiting[session_id] = message
|
||||
|
||||
def reply_msg(self,
|
||||
async def reply_msg(self,
|
||||
message: Union[GroupMessage, FriendMessage, GuildMessage, Notify],
|
||||
result_message: list):
|
||||
"""
|
||||
插件开发者请使用send方法, 可以不用直接调用这个方法。
|
||||
插件开发者请使用send方法, 可以不用直接调用这个方法。
|
||||
"""
|
||||
source = message
|
||||
res = result_message
|
||||
|
||||
self.gocq_cnt += 1
|
||||
|
||||
self.logger.log(f"{source.user_id} <- {self.parse_message_outline(res)}", tag="QQ_GOCQ")
|
||||
|
||||
@@ -209,12 +202,10 @@ class QQGOCQ(Platform):
|
||||
# 回复消息链
|
||||
if isinstance(res, list) and len(res) > 0:
|
||||
if source.type == "GuildMessage":
|
||||
# await self.client.sendGuildChannelMessage(source.guild_id, source.channel_id, res)
|
||||
asyncio.run_coroutine_threadsafe(self.client.sendGuildChannelMessage(source.guild_id, source.channel_id, res), self.loop).result()
|
||||
await self.client.sendGuildChannelMessage(source.guild_id, source.channel_id, res)
|
||||
return
|
||||
elif source.type == "FriendMessage":
|
||||
# await self.client.sendFriendMessage(source.user_id, res)
|
||||
asyncio.run_coroutine_threadsafe(self.client.sendFriendMessage(source.user_id, res), self.loop).result()
|
||||
await self.client.sendFriendMessage(source.user_id, res)
|
||||
return
|
||||
elif source.type == "GroupMessage":
|
||||
# 过长时forward发送
|
||||
@@ -237,37 +228,28 @@ class QQGOCQ(Platform):
|
||||
node.time = int(time.time())
|
||||
# print(node)
|
||||
nodes=[node]
|
||||
# await self.client.sendGroupForwardMessage(source.group_id, nodes)
|
||||
asyncio.run_coroutine_threadsafe(self.client.sendGroupForwardMessage(source.group_id, nodes), self.loop).result()
|
||||
await self.client.sendGroupForwardMessage(source.group_id, nodes)
|
||||
return
|
||||
# await self.client.sendGroupMessage(source.group_id, res)
|
||||
asyncio.run_coroutine_threadsafe(self.client.sendGroupMessage(source.group_id, res), self.loop).result()
|
||||
await self.client.sendGroupMessage(source.group_id, res)
|
||||
return
|
||||
|
||||
def send_msg(self, message: Union[GroupMessage, FriendMessage, GuildMessage, Notify], result_message: list):
|
||||
async def send_msg(self, message: Union[GroupMessage, FriendMessage, GuildMessage, Notify], result_message: list):
|
||||
'''
|
||||
提供给插件的发送QQ消息接口。
|
||||
参数说明:第一个参数可以是消息对象,也可以是QQ群号。第二个参数是消息内容(消息内容可以是消息链列表,也可以是纯文字信息)。
|
||||
非异步
|
||||
'''
|
||||
try:
|
||||
# await self.reply_msg(message, result_message)
|
||||
self.reply_msg(message, result_message)
|
||||
await self.reply_msg(message, result_message)
|
||||
except BaseException as e:
|
||||
raise e
|
||||
|
||||
def send(self,
|
||||
async def send(self,
|
||||
to,
|
||||
res):
|
||||
'''
|
||||
同 send_msg()
|
||||
非异步
|
||||
'''
|
||||
try:
|
||||
# await self.send_msg(to, res)
|
||||
self.reply_msg(to, res)
|
||||
except BaseException as e:
|
||||
raise e
|
||||
await self.reply_msg(to, res)
|
||||
|
||||
def create_text_image(title: str, text: str, max_width=30, font_size=20):
|
||||
'''
|
||||
@@ -306,18 +288,13 @@ class QQGOCQ(Platform):
|
||||
def get_client(self):
|
||||
return self.client
|
||||
|
||||
def nakuru_method_invoker(self, func, *args, **kwargs):
|
||||
async def nakuru_method_invoker(self, func, *args, **kwargs):
|
||||
"""
|
||||
返回一个方法调用器,可以用来立即调用nakuru的方法。
|
||||
"""
|
||||
try:
|
||||
ret = asyncio.run_coroutine_threadsafe(func(*args, **kwargs), self.loop).result()
|
||||
ret = func(*args, **kwargs)
|
||||
return ret
|
||||
except BaseException as e:
|
||||
raise e
|
||||
|
||||
def get_cnt(self):
|
||||
return self.gocq_cnt
|
||||
|
||||
def set_cnt(self, cnt):
|
||||
self.gocq_cnt = cnt
|
||||
|
||||
@@ -4,7 +4,7 @@ from PIL import Image as PILImage
|
||||
from botpy.message import Message, DirectMessage
|
||||
import re
|
||||
import asyncio
|
||||
import requests
|
||||
import aiohttp
|
||||
from util import general_utils as gu
|
||||
|
||||
from botpy.types.message import Reference
|
||||
@@ -13,10 +13,9 @@ import time
|
||||
from ._platfrom import Platform
|
||||
from ._nakuru_translation_layer import(
|
||||
NakuruGuildMessage,
|
||||
NakuruGuildMember,
|
||||
gocq_compatible_receive,
|
||||
gocq_compatible_send
|
||||
)
|
||||
)
|
||||
from typing import Union
|
||||
|
||||
# QQ 机器人官方框架
|
||||
@@ -28,13 +27,13 @@ class botClient(Client):
|
||||
async def on_at_message_create(self, message: Message):
|
||||
# 转换层
|
||||
nakuru_guild_message = gocq_compatible_receive(message)
|
||||
self.platform.new_sub_thread(self.platform.handle_msg, (nakuru_guild_message, True))
|
||||
await self.platform.handle_msg(nakuru_guild_message, True)
|
||||
|
||||
# 收到私聊消息
|
||||
async def on_direct_message_create(self, message: DirectMessage):
|
||||
# 转换层
|
||||
nakuru_guild_message = gocq_compatible_receive(message)
|
||||
self.platform.new_sub_thread(self.platform.handle_msg, (nakuru_guild_message, False))
|
||||
await self.platform.handle_msg(nakuru_guild_message, False)
|
||||
|
||||
class QQOfficial(Platform):
|
||||
|
||||
@@ -44,7 +43,6 @@ class QQOfficial(Platform):
|
||||
self.loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(self.loop)
|
||||
|
||||
self.qqchan_cnt = 0
|
||||
self.waiting: dict = {}
|
||||
|
||||
self.cfg = cfg
|
||||
@@ -109,7 +107,7 @@ class QQOfficial(Platform):
|
||||
if message_result is None:
|
||||
return
|
||||
|
||||
self.reply_msg(is_group, message, message_result.result_message)
|
||||
await self.reply_msg(is_group, message, message_result.result_message)
|
||||
if message_result.callback is not None:
|
||||
message_result.callback()
|
||||
|
||||
@@ -117,7 +115,7 @@ class QQOfficial(Platform):
|
||||
if session_id in self.waiting and self.waiting[session_id] == '':
|
||||
self.waiting[session_id] = message
|
||||
|
||||
def reply_msg(self,
|
||||
async def reply_msg(self,
|
||||
is_group: bool,
|
||||
message: NakuruGuildMessage,
|
||||
res: Union[str, list]):
|
||||
@@ -125,7 +123,6 @@ class QQOfficial(Platform):
|
||||
回复频道消息
|
||||
'''
|
||||
self.logger.log(f"{message.sender.nickname}({message.sender.tiny_id}) <- {self.parse_message_outline(res)}", tag="QQ_OFFICIAL")
|
||||
self.qqchan_cnt += 1
|
||||
|
||||
plain_text = ''
|
||||
image_path = ''
|
||||
@@ -151,10 +148,11 @@ class QQOfficial(Platform):
|
||||
if image_path is not None and image_path != '':
|
||||
msg_ref = None
|
||||
if image_path.startswith("http"):
|
||||
pic_res = requests.get(image_path, stream = True)
|
||||
if pic_res.status_code == 200:
|
||||
image = PILImage.open(io.BytesIO(pic_res.content))
|
||||
image_path = gu.save_temp_img(image)
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.get(image_path) as response:
|
||||
if response.status == 200:
|
||||
image = PILImage.open(io.BytesIO(await response.read()))
|
||||
image_path = gu.save_temp_img(image)
|
||||
|
||||
if message.raw_message is not None and image_path == '': # file_image与message_reference不能同时传入
|
||||
msg_ref = Reference(message_id=message.raw_message.id, ignore_get_message_error=False)
|
||||
@@ -173,8 +171,7 @@ class QQOfficial(Platform):
|
||||
data['file_image'] = image_path
|
||||
|
||||
try:
|
||||
# await self._send_wrapper(**data)
|
||||
self._send_wrapper(**data)
|
||||
await self._send_wrapper(**data)
|
||||
except BaseException as e:
|
||||
print(e)
|
||||
# 分割过长的消息
|
||||
@@ -184,51 +181,44 @@ class QQOfficial(Platform):
|
||||
split_res.append(plain_text[len(plain_text)//2:])
|
||||
for i in split_res:
|
||||
data['content'] = i
|
||||
# await self._send_wrapper(**data)
|
||||
self._send_wrapper(**data)
|
||||
await self._send_wrapper(**data)
|
||||
else:
|
||||
# 发送qq信息
|
||||
try:
|
||||
# 防止被qq频道过滤消息
|
||||
plain_text = plain_text.replace(".", " . ")
|
||||
# await self._send_wrapper(**data)
|
||||
self._send_wrapper(**data)
|
||||
await self._send_wrapper(**data)
|
||||
|
||||
except BaseException as e:
|
||||
try:
|
||||
data['content'] = str.join(" ", plain_text)
|
||||
# await self._send_wrapper(**data)
|
||||
self._send_wrapper(**data)
|
||||
await self._send_wrapper(**data)
|
||||
except BaseException as e:
|
||||
plain_text = re.sub(r'(https|http)?:\/\/(\w|\.|\/|\?|\=|\&|\%)*\b', '[被隐藏的链接]', str(e), flags=re.MULTILINE)
|
||||
plain_text = plain_text.replace(".", "·")
|
||||
data['content'] = plain_text
|
||||
# await self._send_wrapper(**data)
|
||||
self._send_wrapper(**data)
|
||||
await self._send_wrapper(**data)
|
||||
|
||||
def _send_wrapper(self, **kwargs):
|
||||
async def _send_wrapper(self, **kwargs):
|
||||
if 'channel_id' in kwargs:
|
||||
asyncio.run_coroutine_threadsafe(self.client.api.post_message(**kwargs), self.loop).result()
|
||||
await self.client.api.post_message(**kwargs)
|
||||
else:
|
||||
asyncio.run_coroutine_threadsafe(self.client.api.post_dms(**kwargs), self.loop).result()
|
||||
await self.client.api.post_dms(**kwargs)
|
||||
|
||||
|
||||
def send_msg(self, channel_id: int, message_chain: list, message_id: int = None):
|
||||
async def send_msg(self, channel_id: int, message_chain: list, message_id: int = None):
|
||||
'''
|
||||
推送消息, 如果有 message_id,那么就是回复消息。非异步。
|
||||
推送消息, 如果有 message_id,那么就是回复消息。
|
||||
'''
|
||||
_n = NakuruGuildMessage()
|
||||
_n.channel_id = channel_id
|
||||
_n.message_id = message_id
|
||||
# await self.reply_msg(_n, message_chain)
|
||||
self.reply_msg(_n, message_chain)
|
||||
await self.reply_msg(_n, message_chain)
|
||||
|
||||
def send(self, message_obj, message_chain: list):
|
||||
async def send(self, message_obj, message_chain: list):
|
||||
'''
|
||||
发送信息。内容同 reply_msg。非异步。
|
||||
发送信息。内容同 reply_msg。
|
||||
'''
|
||||
# await self.reply_msg(message_obj, message_chain)
|
||||
self.reply_msg(message_obj, message_chain)
|
||||
await self.reply_msg(message_obj, message_chain)
|
||||
|
||||
def wait_for_message(self, channel_id: int) -> NakuruGuildMessage:
|
||||
'''
|
||||
@@ -246,9 +236,3 @@ class QQOfficial(Platform):
|
||||
if cnt > 300:
|
||||
raise Exception("等待消息超时。")
|
||||
time.sleep(1)
|
||||
|
||||
def get_cnt(self):
|
||||
return self.qqchan_cnt
|
||||
|
||||
def set_cnt(self, cnt):
|
||||
self.qqchan_cnt = cnt
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
from openai import OpenAI
|
||||
from openai.types.chat.chat_completion import ChatCompletion
|
||||
from openai.types.images_response import ImagesResponse
|
||||
import json
|
||||
import time
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import time
|
||||
import tiktoken
|
||||
import threading
|
||||
import traceback
|
||||
|
||||
from openai import AsyncOpenAI
|
||||
from openai.types.images_response import ImagesResponse
|
||||
from openai.types.chat.chat_completion import ChatCompletion
|
||||
|
||||
from cores.database.conn import dbConn
|
||||
from model.provider.provider import Provider
|
||||
import threading
|
||||
from util import general_utils as gu
|
||||
from util.cmd_config import CmdConfig
|
||||
from util.general_utils import Logger
|
||||
import traceback
|
||||
import tiktoken
|
||||
|
||||
|
||||
|
||||
abs_path = os.path.dirname(os.path.realpath(sys.argv[0])) + '/'
|
||||
@@ -26,12 +29,9 @@ class ProviderOpenAIOfficial(Provider):
|
||||
# 如果 cfg['key'] 中有长度为 1 的字符串,那么是格式错误,直接报错
|
||||
for key in cfg['key']:
|
||||
if len(key) == 1:
|
||||
input("检查到了长度为 1 的Key。配置文件中的 openai.key 处的格式错误 (符号 - 的后面要加空格),请退出程序并检查配置文件,按回车跳过。")
|
||||
raise BaseException("配置文件格式错误")
|
||||
raise BaseException("检查到了长度为 1 的Key。配置文件中的 openai.key 处的格式错误 (符号 - 的后面要加空格)。")
|
||||
if cfg['key'] != '' and cfg['key'] != None:
|
||||
self.key_list = cfg['key']
|
||||
else:
|
||||
input("[System] 请先填写 Key。详情请前往 https://beta.openai.com/account/api-keys 或使用中转 Key 方案。")
|
||||
if len(self.key_list) == 0:
|
||||
raise Exception("您打开了 OpenAI 模型服务,但是未填写 key。请前往填写。")
|
||||
|
||||
@@ -45,7 +45,7 @@ class ProviderOpenAIOfficial(Provider):
|
||||
self.logger.log(f"设置 api_base 为: {self.api_base}", tag="OpenAI")
|
||||
|
||||
# 创建 OpenAI Client
|
||||
self.client = OpenAI(
|
||||
self.client = AsyncOpenAI(
|
||||
api_key=self.key_list[0],
|
||||
base_url=self.api_base
|
||||
)
|
||||
@@ -116,7 +116,7 @@ class ProviderOpenAIOfficial(Provider):
|
||||
}
|
||||
self.session_dict[session_id].append(new_record)
|
||||
|
||||
def text_chat(self, prompt,
|
||||
async def text_chat(self, prompt,
|
||||
session_id = None,
|
||||
image_url = None,
|
||||
function_call=None,
|
||||
@@ -135,7 +135,6 @@ class ProviderOpenAIOfficial(Provider):
|
||||
if default_personality is not None:
|
||||
self.personality_set(default_personality, session_id)
|
||||
|
||||
|
||||
# 使用 tictoken 截断消息
|
||||
_encoded_prompt = self.enc.encode(prompt)
|
||||
if self.openai_model_configs['max_tokens'] < len(_encoded_prompt):
|
||||
@@ -143,8 +142,8 @@ class ProviderOpenAIOfficial(Provider):
|
||||
self.logger.log(f"注意,有一部分 prompt 文本由于超出 token 限制而被截断。", level=gu.LEVEL_WARNING, tag="OpenAI")
|
||||
|
||||
cache_data_list, new_record, req = self.wrap(prompt, session_id, image_url)
|
||||
self.logger.log(f"CACHE_DATA_: {str(cache_data_list)}", level=gu.LEVEL_DEBUG, tag="OpenAI")
|
||||
self.logger.log(f"OPENAI REQUEST: {str(req)}", level=gu.LEVEL_DEBUG, tag="OpenAI")
|
||||
self.logger.log(f"cache: {str(cache_data_list)}", level=gu.LEVEL_DEBUG, tag="OpenAI")
|
||||
self.logger.log(f"request: {str(req)}", level=gu.LEVEL_DEBUG, tag="OpenAI")
|
||||
retry = 0
|
||||
response = None
|
||||
err = ''
|
||||
@@ -171,19 +170,19 @@ class ProviderOpenAIOfficial(Provider):
|
||||
while retry < 10:
|
||||
try:
|
||||
if function_call is None:
|
||||
response = self.client.chat.completions.create(
|
||||
response = await self.client.chat.completions.create(
|
||||
messages=req,
|
||||
**conf
|
||||
)
|
||||
else:
|
||||
response = self.client.chat.completions.create(
|
||||
response = await self.client.chat.completions.create(
|
||||
messages=req,
|
||||
tools = function_call,
|
||||
**conf
|
||||
)
|
||||
break
|
||||
except Exception as e:
|
||||
print(traceback.format_exc())
|
||||
traceback.print_exc()
|
||||
if 'Invalid content type. image_url is only supported by certain models.' in str(e):
|
||||
raise e
|
||||
if 'You exceeded' in str(e) or 'Billing hard limit has been reached' in str(e) or 'No API key provided' in str(e) or 'Incorrect API key provided' in str(e):
|
||||
@@ -191,7 +190,6 @@ class ProviderOpenAIOfficial(Provider):
|
||||
self.key_stat[self.client.api_key]['exceed'] = True
|
||||
is_switched = self.handle_switch_key()
|
||||
if not is_switched:
|
||||
# 所有Key都超额或不正常
|
||||
raise e
|
||||
retry -= 1
|
||||
elif 'maximum context length' in str(e):
|
||||
@@ -242,7 +240,6 @@ class ProviderOpenAIOfficial(Provider):
|
||||
index += 1
|
||||
# 删除完后更新相关字段
|
||||
self.session_dict[session_id] = cache_data_list
|
||||
# cache_prompt = get_prompts_by_cache_list(cache_data_list)
|
||||
|
||||
# 添加新条目进入缓存的prompt
|
||||
new_record['AI'] = {
|
||||
@@ -261,7 +258,7 @@ class ProviderOpenAIOfficial(Provider):
|
||||
|
||||
return chatgpt_res
|
||||
|
||||
def image_chat(self, prompt, img_num = 1, img_size = "1024x1024"):
|
||||
async def image_chat(self, prompt, img_num = 1, img_size = "1024x1024"):
|
||||
retry = 0
|
||||
image_url = ''
|
||||
|
||||
@@ -269,7 +266,7 @@ class ProviderOpenAIOfficial(Provider):
|
||||
|
||||
while retry < 5:
|
||||
try:
|
||||
response: ImagesResponse = self.client.images.generate(
|
||||
response: ImagesResponse = await self.client.images.generate(
|
||||
prompt=prompt,
|
||||
**image_generate_configs
|
||||
)
|
||||
@@ -285,7 +282,6 @@ class ProviderOpenAIOfficial(Provider):
|
||||
self.key_stat[self.client.api_key]['exceed'] = True
|
||||
is_switched = self.handle_switch_key()
|
||||
if not is_switched:
|
||||
# 所有Key都超额或不正常
|
||||
raise e
|
||||
elif 'Your request was rejected as a result of our safety system.' in str(e):
|
||||
self.logger.log("您的请求被 OpenAI 安全系统拒绝, 请稍后再试", level=gu.LEVEL_WARNING, tag="OpenAI")
|
||||
@@ -297,16 +293,16 @@ class ProviderOpenAIOfficial(Provider):
|
||||
|
||||
return image_url
|
||||
|
||||
def forget(self, session_id = None) -> bool:
|
||||
async def forget(self, session_id = None) -> bool:
|
||||
if session_id is None:
|
||||
return False
|
||||
self.session_dict[session_id] = []
|
||||
return True
|
||||
|
||||
'''
|
||||
获取缓存的会话
|
||||
'''
|
||||
def get_prompts_by_cache_list(self, cache_data_list, divide=False, paging=False, size=5, page=1):
|
||||
'''
|
||||
获取缓存的会话
|
||||
'''
|
||||
prompts = ""
|
||||
if paging:
|
||||
page_begin = (page-1)*size
|
||||
@@ -323,15 +319,7 @@ class ProviderOpenAIOfficial(Provider):
|
||||
if divide:
|
||||
prompts += "----------\n"
|
||||
return prompts
|
||||
|
||||
|
||||
def get_user_usage_tokens(self,cache_list):
|
||||
usage_tokens = 0
|
||||
for item in cache_list:
|
||||
usage_tokens += int(item['single_tokens'])
|
||||
return usage_tokens
|
||||
|
||||
# 包装信息
|
||||
|
||||
def wrap(self, prompt, session_id, image_url = None):
|
||||
if image_url is not None:
|
||||
prompt = [
|
||||
@@ -367,7 +355,6 @@ class ProviderOpenAIOfficial(Provider):
|
||||
return context, new_record, req_list
|
||||
|
||||
def handle_switch_key(self):
|
||||
# messages = [{"role": "user", "content": prompt}]
|
||||
is_all_exceed = True
|
||||
for key in self.key_stat:
|
||||
if key == None or self.key_stat[key]['exceed']:
|
||||
@@ -402,13 +389,13 @@ class ProviderOpenAIOfficial(Provider):
|
||||
self.key_stat[key] = {'exceed': False, 'used': 0, 'sponsor': sponsor}
|
||||
|
||||
# 检查key是否可用
|
||||
def check_key(self, key):
|
||||
client_ = OpenAI(
|
||||
async def check_key(self, key):
|
||||
client_ = AsyncOpenAI(
|
||||
api_key=key,
|
||||
base_url=self.api_base
|
||||
)
|
||||
messages = [{"role": "user", "content": "please just echo `test`"}]
|
||||
client_.chat.completions.create(
|
||||
await client_.chat.completions.create(
|
||||
messages=messages,
|
||||
**self.openai_model_configs
|
||||
)
|
||||
|
||||
@@ -5,9 +5,9 @@ class Provider:
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def text_chat(self, prompt, session_id, image_url: None, function_call: None, extra_conf: dict = None, default_personality: dict = None) -> str:
|
||||
async def text_chat(self, prompt, session_id, image_url: None, function_call: None, extra_conf: dict = None, default_personality: dict = None) -> str:
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def forget(self, session_id = None) -> bool:
|
||||
async def forget(self, session_id = None) -> bool:
|
||||
pass
|
||||
+2
-1
@@ -1,5 +1,6 @@
|
||||
pydantic~=1.10.4
|
||||
requests~=2.28.1
|
||||
aiohttp
|
||||
requests
|
||||
openai~=1.2.3
|
||||
qq-botpy
|
||||
chardet~=5.1.0
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
import requests
|
||||
import util.general_utils as gu
|
||||
from bs4 import BeautifulSoup
|
||||
import traceback
|
||||
import time
|
||||
import json
|
||||
import asyncio
|
||||
from googlesearch import search, SearchResult
|
||||
from readability import Document
|
||||
from bs4 import BeautifulSoup
|
||||
from openai.types.chat.chat_completion_message_tool_call import Function
|
||||
from util.function_calling.func_call import (
|
||||
FuncCall,
|
||||
FuncCallJsonFormatError,
|
||||
FuncNotFoundError
|
||||
)
|
||||
from openai.types.chat.chat_completion_message_tool_call import Function
|
||||
import traceback
|
||||
from googlesearch import search, SearchResult
|
||||
from model.provider.provider import Provider
|
||||
import json
|
||||
from readability import Document
|
||||
|
||||
|
||||
def tidy_text(text: str) -> str:
|
||||
@@ -53,11 +54,11 @@ def google_web_search(keyword) -> str:
|
||||
for i in ls:
|
||||
desc = i.description
|
||||
try:
|
||||
gu.log(f"搜索网页: {i.url}", tag="网页搜索", level=gu.LEVEL_INFO)
|
||||
# gu.log(f"搜索网页: {i.url}", tag="网页搜索", level=gu.LEVEL_INFO)
|
||||
desc = fetch_website_content(i.url)
|
||||
except BaseException as e:
|
||||
print(f"(google) fetch_website_content err: {str(e)}")
|
||||
gu.log(f"# No.{str(index)}\ntitle: {i.title}\nurl: {i.url}\ncontent: {desc}\n\n", level=gu.LEVEL_DEBUG, max_len=9999)
|
||||
# gu.log(f"# No.{str(index)}\ntitle: {i.title}\nurl: {i.url}\ncontent: {desc}\n\n", level=gu.LEVEL_DEBUG, max_len=9999)
|
||||
ret += f"# No.{str(index)}\ntitle: {i.title}\nurl: {i.url}\ncontent: {desc}\n\n"
|
||||
index += 1
|
||||
except Exception as e:
|
||||
@@ -80,7 +81,7 @@ def web_keyword_search_via_bing(keyword) -> str:
|
||||
try:
|
||||
response = requests.get(url, headers=headers)
|
||||
response.encoding = "utf-8"
|
||||
gu.log(f"bing response: {response.text}", tag="bing", level=gu.LEVEL_DEBUG, max_len=9999)
|
||||
# gu.log(f"bing response: {response.text}", tag="bing", level=gu.LEVEL_DEBUG, max_len=9999)
|
||||
soup = BeautifulSoup(response.text, "html.parser")
|
||||
res = ""
|
||||
result_cnt = 0
|
||||
@@ -96,7 +97,7 @@ def web_keyword_search_via_bing(keyword) -> str:
|
||||
# "link": link,
|
||||
# })
|
||||
try:
|
||||
gu.log(f"搜索网页: {link}", tag="网页搜索", level=gu.LEVEL_INFO)
|
||||
# gu.log(f"搜索网页: {link}", tag="网页搜索", level=gu.LEVEL_INFO)
|
||||
desc = fetch_website_content(link)
|
||||
except BaseException as e:
|
||||
print(f"(bing) fetch_website_content err: {str(e)}")
|
||||
@@ -124,11 +125,11 @@ def web_keyword_search_via_bing(keyword) -> str:
|
||||
if result_cnt == 0: break
|
||||
return res
|
||||
except Exception as e:
|
||||
gu.log(f"bing fetch err: {str(e)}")
|
||||
# gu.log(f"bing fetch err: {str(e)}")
|
||||
_cnt += 1
|
||||
time.sleep(1)
|
||||
|
||||
gu.log("fail to fetch bing info, using sougou.")
|
||||
# gu.log("fail to fetch bing info, using sougou.")
|
||||
return web_keyword_search_via_sougou(keyword)
|
||||
|
||||
def web_keyword_search_via_sougou(keyword) -> str:
|
||||
@@ -157,7 +158,7 @@ def web_keyword_search_via_sougou(keyword) -> str:
|
||||
break
|
||||
except Exception as e:
|
||||
pass
|
||||
gu.log(f"sougou parse err: {str(e)}", tag="web_keyword_search_via_sougou", level=gu.LEVEL_ERROR)
|
||||
# gu.log(f"sougou parse err: {str(e)}", tag="web_keyword_search_via_sougou", level=gu.LEVEL_ERROR)
|
||||
# 爬取网页内容
|
||||
_detail_store = []
|
||||
for i in res:
|
||||
@@ -173,7 +174,7 @@ def web_keyword_search_via_sougou(keyword) -> str:
|
||||
return ret
|
||||
|
||||
def fetch_website_content(url):
|
||||
gu.log(f"fetch_website_content: {url}", tag="fetch_website_content", level=gu.LEVEL_DEBUG)
|
||||
# gu.log(f"fetch_website_content: {url}", tag="fetch_website_content", level=gu.LEVEL_DEBUG)
|
||||
headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) \
|
||||
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
|
||||
@@ -187,7 +188,7 @@ def fetch_website_content(url):
|
||||
ret = tidy_text(soup.get_text())
|
||||
return ret
|
||||
|
||||
def web_search(question, provider: Provider, session_id, official_fc=False):
|
||||
async def web_search(question, provider: Provider, session_id, official_fc=False):
|
||||
'''
|
||||
official_fc: 使用官方 function-calling
|
||||
'''
|
||||
@@ -197,7 +198,7 @@ def web_search(question, provider: Provider, session_id, official_fc=False):
|
||||
"name": "keyword",
|
||||
"description": "google search query (分词,尽量保留所有信息)"
|
||||
}],
|
||||
"通过搜索引擎搜索。如果问题需要在网页上搜索(如天气、新闻或任何需要通过网页获取信息的问题),则调用此函数;如果没有,不要调用此函数。",
|
||||
"通过搜索引擎搜索。如果问题需要获取近期、实时的消息,在网页上搜索(如天气、新闻或任何需要通过网页获取信息的问题),则调用此函数;如果没有,不要调用此函数。",
|
||||
web_keyword_search_via_bing
|
||||
)
|
||||
new_func_call.add_func("fetch_website_content", [{
|
||||
@@ -205,16 +206,16 @@ def web_search(question, provider: Provider, session_id, official_fc=False):
|
||||
"name": "url",
|
||||
"description": "网址"
|
||||
}],
|
||||
"获取网页的内容。如果问题带有合法的网页链接(例如: `帮我总结一下https://github.com的内容`), 就调用此函数。如果没有,不要调用此函数。",
|
||||
"获取网页的内容。如果问题带有合法的网页链接(例如: `帮我总结一下 https://github.com 的内容`), 就调用此函数。如果没有,不要调用此函数。",
|
||||
fetch_website_content
|
||||
)
|
||||
question1 = f"{question} \n> hint: 最多只能调用1个function, 并且存在不会调用任何function的可能性。"
|
||||
has_func = False
|
||||
function_invoked_ret = ""
|
||||
if official_fc:
|
||||
func = provider.text_chat(question1, session_id, function_call=new_func_call.get_func())
|
||||
# we use official function-calling
|
||||
func = await provider.text_chat(question1, session_id, function_call=new_func_call.get_func())
|
||||
if isinstance(func, Function):
|
||||
# arguments='{\n "keyword": "北京今天的天气"\n}', name='google_web_search'
|
||||
# 执行对应的结果:
|
||||
func_obj = None
|
||||
for i in new_func_call.func_list:
|
||||
@@ -222,49 +223,68 @@ def web_search(question, provider: Provider, session_id, official_fc=False):
|
||||
func_obj = i["func_obj"]
|
||||
break
|
||||
if not func_obj:
|
||||
gu.log("找不到返回的 func name " + func.name, level=gu.LEVEL_ERROR)
|
||||
return provider.text_chat(question1, session_id) + "\n(网页搜索失败, 此为默认回复)"
|
||||
# gu.log("找不到返回的 func name " + func.name, level=gu.LEVEL_ERROR)
|
||||
return await provider.text_chat(question1, session_id) + "\n(网页搜索失败, 此为默认回复)"
|
||||
try:
|
||||
args = json.loads(func.arguments)
|
||||
function_invoked_ret = func_obj(**args)
|
||||
# we use to_thread to avoid blocking the event loop
|
||||
function_invoked_ret = await asyncio.to_thread(func_obj, **args)
|
||||
has_func = True
|
||||
except BaseException as e:
|
||||
traceback.print_exc()
|
||||
return provider.text_chat(question1, session_id) + "\n(网页搜索失败, 此为默认回复)"
|
||||
return await provider.text_chat(question1, session_id) + "\n(网页搜索失败, 此为默认回复)"
|
||||
else:
|
||||
# now func is a string
|
||||
return func
|
||||
else:
|
||||
# we use our own function-calling
|
||||
try:
|
||||
function_invoked_ret, has_func = new_func_call.func_call(question1, new_func_call.func_dump(), is_task=False, is_summary=False)
|
||||
args = {
|
||||
'question': question1,
|
||||
'func_definition': new_func_call.func_dump(),
|
||||
'is_task': False,
|
||||
'is_summary': False,
|
||||
}
|
||||
function_invoked_ret, has_func = await asyncio.to_thread(new_func_call.func_call, **args)
|
||||
except BaseException as e:
|
||||
res = provider.text_chat(question) + "\n(网页搜索失败, 此为默认回复)"
|
||||
res = await provider.text_chat(question) + "\n(网页搜索失败, 此为默认回复)"
|
||||
return res
|
||||
has_func = True
|
||||
|
||||
if has_func:
|
||||
provider.forget(session_id)
|
||||
await provider.forget(session_id)
|
||||
question3 = f"""
|
||||
以下是相关材料,你的任务是:
|
||||
1. 根据材料对问题`{question}`做切题的总结回答;
|
||||
2. 发表你对这个问题的看法.
|
||||
你的任务是:
|
||||
1. 根据末尾的材料对问题`{question}`做切题的总结(详细);
|
||||
2. 简单地发表你对这个问题的看法(简略)。
|
||||
你的总结末尾应当有对材料的引用, 如果有链接, 请在末尾附上引用网页链接。引用格式严格按照 `\n[1] title url \n`。
|
||||
不要提到任何函数调用的信息。以下是相关材料:
|
||||
不要提到任何函数调用的信息。
|
||||
|
||||
一些回复的消息模板:
|
||||
模板1:
|
||||
```
|
||||
从网上的信息来看,可以知道...我个人认为...你觉得呢?
|
||||
```
|
||||
模板2:
|
||||
```
|
||||
根据网上的最新信息,可以得知...我觉得...你怎么看?
|
||||
```
|
||||
你可以根据这些模板来组织回答,但可以不照搬,要根据问题的内容来回答。
|
||||
|
||||
以下是相关材料:
|
||||
"""
|
||||
|
||||
gu.log(f"web_search: {question3}", tag="web_search", level=gu.LEVEL_DEBUG, max_len=99999)
|
||||
_c = 0
|
||||
while _c < 3:
|
||||
try:
|
||||
print('text chat')
|
||||
final_ret = provider.text_chat(question3 + "```" + function_invoked_ret + "```", session_id)
|
||||
final_ret = await provider.text_chat(question3 + "```" + function_invoked_ret + "```", session_id)
|
||||
return final_ret
|
||||
except Exception as e:
|
||||
print(e)
|
||||
_c += 1
|
||||
if _c == 3: raise e
|
||||
if "The message you submitted was too long" in str(e):
|
||||
provider.forget(session_id)
|
||||
await provider.forget(session_id)
|
||||
function_invoked_ret = function_invoked_ret[:int(len(function_invoked_ret) / 2)]
|
||||
time.sleep(3)
|
||||
return function_invoked_ret
|
||||
|
||||
+45
-34
@@ -9,8 +9,10 @@ from util.cmd_config import CmdConfig
|
||||
import socket
|
||||
from cores.qqbot.global_object import GlobalObject
|
||||
import platform
|
||||
import requests
|
||||
import logging
|
||||
import json
|
||||
import sys
|
||||
import psutil
|
||||
|
||||
PLATFORM_GOCQ = 'gocq'
|
||||
PLATFORM_QQCHAN = 'qqchan'
|
||||
@@ -193,7 +195,6 @@ def word2img(title: str, text: str, max_width=30, font_size=20):
|
||||
|
||||
return image
|
||||
|
||||
|
||||
def render_markdown(markdown_text, image_width=800, image_height=600, font_size=26, font_color=(0, 0, 0), bg_color=(255, 255, 255)):
|
||||
|
||||
HEADER_MARGIN = 20
|
||||
@@ -322,7 +323,6 @@ def render_markdown(markdown_text, image_width=800, image_height=600, font_size=
|
||||
height += font_size + TEXT_LINE_MARGIN*2
|
||||
|
||||
markdown_text = '\n'.join(pre_lines)
|
||||
print("Pre process done, height: ", height)
|
||||
image_height = height
|
||||
if image_height < 100:
|
||||
image_height = 100
|
||||
@@ -332,13 +332,6 @@ def render_markdown(markdown_text, image_width=800, image_height=600, font_size=
|
||||
image = Image.new('RGB', (image_width, image_height), bg_color)
|
||||
draw = ImageDraw.Draw(image)
|
||||
|
||||
|
||||
# # get all the emojis unicode in the markdown text
|
||||
# unicode_text = markdown_text.encode('unicode_escape').decode()
|
||||
# # print(unicode_text)
|
||||
# unicode_emojis = re.findall(r'\\U\w{8}', unicode_text)
|
||||
# emoji_base_url = "https://abs.twimg.com/emoji/v1/72x72/{unicode_emoji}.png"
|
||||
|
||||
# 设置初始位置
|
||||
x, y = 10, 10
|
||||
|
||||
@@ -360,25 +353,10 @@ def render_markdown(markdown_text, image_width=800, image_height=600, font_size=
|
||||
line = line.strip()
|
||||
|
||||
if line.startswith("#"):
|
||||
# unicode_emojis = re.findall(r'\\U0001\w{4}', line)
|
||||
# for unicode_emoji in unicode_emojis:
|
||||
# line = line.replace(unicode_emoji, "")
|
||||
# unicode_emoji = ""
|
||||
# if len(unicode_emojis) > 0:
|
||||
# unicode_emoji = unicode_emojis[0]
|
||||
|
||||
# 处理标题
|
||||
header_level = line.count("#")
|
||||
line = line.strip("#").strip()
|
||||
font_size_header = HEADER_FONT_STANDARD_SIZE - header_level * 4
|
||||
|
||||
# if unicode_emoji != "":
|
||||
# emoji_url = emoji_base_url.format(unicode_emoji=unicode_emoji[-5:])
|
||||
# emoji = Image.open(requests.get(emoji_url, stream=True).raw)
|
||||
# emoji = emoji.resize((font_size, font_size))
|
||||
# image.paste(emoji, (x, y))
|
||||
# x += font_size
|
||||
|
||||
font = ImageFont.truetype(font_path, font_size_header)
|
||||
y += HEADER_MARGIN # 上边距
|
||||
# 字间距
|
||||
@@ -389,10 +367,6 @@ def render_markdown(markdown_text, image_width=800, image_height=600, font_size=
|
||||
elif line.startswith(">"):
|
||||
# 处理引用
|
||||
quote_text = line.strip(">")
|
||||
# quote_width = image_width - 20 # 引用框的宽度为图像宽度减去左右边距
|
||||
# quote_height = font_size + 10 # 引用框的高度为字体大小加上上下边距
|
||||
# quote_box = (x, y, x + quote_width, y + quote_height)
|
||||
# draw.rounded_rectangle(quote_box, radius=5, fill=(230, 230, 230), width=2) # 使用灰色填充矩形框作为引用背景
|
||||
y+=QUOTE_LEFT_LINE_MARGIN
|
||||
draw.line((x, y, x, y + QUOTE_LEFT_LINE_HEIGHT), fill=QUOTE_LEFT_LINE_COLOR, width=QUOTE_LEFT_LINE_WIDTH)
|
||||
font = ImageFont.truetype(font_path, QUOTE_FONT_SIZE)
|
||||
@@ -468,7 +442,6 @@ def render_markdown(markdown_text, image_width=800, image_height=600, font_size=
|
||||
y += image_res.size[1] + IMAGE_MARGIN*2
|
||||
return image
|
||||
|
||||
|
||||
def save_temp_img(img: Image) -> str:
|
||||
if not os.path.exists("temp"):
|
||||
os.makedirs("temp")
|
||||
@@ -490,7 +463,6 @@ def save_temp_img(img: Image) -> str:
|
||||
img.save(p)
|
||||
return p
|
||||
|
||||
|
||||
def create_text_image(title: str, text: str, max_width=30, font_size=20):
|
||||
'''
|
||||
文本转图片。
|
||||
@@ -520,9 +492,10 @@ def create_markdown_image(text: str):
|
||||
except Exception as e:
|
||||
raise e
|
||||
|
||||
|
||||
# 迁移配置文件到 cmd_config.json
|
||||
def try_migrate_config(old_config: dict):
|
||||
'''
|
||||
迁移配置文件到 cmd_config.json
|
||||
'''
|
||||
cc = CmdConfig()
|
||||
if cc.get("qqbot", None) is None:
|
||||
# 未迁移过
|
||||
@@ -553,4 +526,42 @@ def get_sys_info(global_object: GlobalObject):
|
||||
'mem': mem,
|
||||
'os': os_name + '_' + os_version,
|
||||
'py': platform.python_version(),
|
||||
}
|
||||
}
|
||||
|
||||
def upload(_global_object: GlobalObject):
|
||||
while True:
|
||||
addr_ip = ''
|
||||
try:
|
||||
res = {
|
||||
"version": _global_object.version,
|
||||
"count": _global_object.cnt_total,
|
||||
"ip": addr_ip,
|
||||
"sys": sys.platform,
|
||||
"admin": _global_object.admin_qq,
|
||||
}
|
||||
resp = requests.post('https://api.soulter.top/upload', data=json.dumps(res), timeout=5)
|
||||
if resp.status_code == 200:
|
||||
ok = resp.json()
|
||||
if ok['status'] == 'ok':
|
||||
_global_object.cnt_total = 0
|
||||
except BaseException as e:
|
||||
pass
|
||||
time.sleep(10*60)
|
||||
|
||||
def run_monitor(global_object: GlobalObject):
|
||||
'''
|
||||
监测机器性能
|
||||
- Bot 内存使用量
|
||||
- CPU 占用率
|
||||
'''
|
||||
start_time = time.time()
|
||||
while True:
|
||||
stat = global_object.dashboard_data.stats
|
||||
# 程序占用的内存大小
|
||||
mem = psutil.Process().memory_info().rss / 1024 / 1024 # MB
|
||||
stat['sys_perf'] = {
|
||||
'memory': mem,
|
||||
'cpu': psutil.cpu_percent()
|
||||
}
|
||||
stat['sys_start_time'] = start_time
|
||||
time.sleep(30)
|
||||
@@ -0,0 +1 @@
|
||||
from cores.qqbot.global_object import GlobalObject
|
||||
@@ -0,0 +1,9 @@
|
||||
from cores.qqbot.core import oper_msg
|
||||
from cores.qqbot.global_object import AstrMessageEvent, CommandResult
|
||||
from model.platform._message_result import MessageResult
|
||||
|
||||
'''
|
||||
消息处理。在消息平台接收到消息后,调用此函数进行处理。
|
||||
集成了指令检测、指令处理、LLM 调用等功能。
|
||||
'''
|
||||
message_handler = oper_msg
|
||||
Reference in New Issue
Block a user