From 4b803e18ed3218bcf4aaf18158f096dfd4de9cf5 Mon Sep 17 00:00:00 2001 From: bincooo Date: Sat, 28 Sep 2024 17:58:45 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E5=88=A0=E5=87=8F=E9=83=A8?= =?UTF-8?q?=E5=88=86=E6=A0=87=E8=AE=B0=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- flags.md | 196 +------------------------------------- internal/common/parser.go | 167 +------------------------------- 2 files changed, 6 insertions(+), 357 deletions(-) diff --git a/flags.md b/flags.md index 996f638d..0e3577a7 100644 --- a/flags.md +++ b/flags.md @@ -41,17 +41,12 @@ flag: echo } ``` -#### 注释,只为了标注说明,没有实际作用 -```text - -``` - #### cdata,避免属性/标签体中使用<>箭括号解析问题 ```text ``` -#### bing 模型 开启 notebook 模式 +#### 开启 notebook 模式 ```text flag: notebook @@ -62,195 +57,6 @@ attribute: ``` -#### 正则替换 -```text -flag: regex - -attribute: - order: (int) 优先级,值越大优先级越大 - miss: (int) 跳过 `messages` 行,从尾部开始往回数 -``` -例子: -```text -```((?!```).)+```: - ->>>>> -效果是除了system对话和倒数的2行外,将所有的markdown 代码块删除 - ->>>>> -{ - "messages": [ - { - "content": "```((?!```).)+```: 你是一个猫娘xxx...", - "role": "system" - }, - { - "content": "好的喵\n```\n年龄: 15\n身高: 150\n服饰: xxx```", - "role": "assistant" - }, - { - "content": "研读书籍,准备明天的测验", - "role": "user" - }, - - ... ... - ], - "model": "coze", - "stream": false -} - -最终效果 ->>>>> -{ - "messages": [ - { - "content": "你是一个猫娘xxx...", - "role": "system" - }, - { - "content": "好的喵\n", - "role": "assistant" - }, - { - "content": "研读书籍,准备明天的测验", - "role": "user" - }, - - ... ... - ], - "model": "coze", - "stream": false -} -``` - -#### 深度插入 -```text -flag: @-*\d+ 正数向下数,负数向上数 - -attribute: - miss: (bool) 超出 `messages` 长度时是否忽略 true/false, 为false时会拼接到第一条或者最后一条 - role: (string) 留空或没有属性会在索引下的消息体末尾拼接,有值则在索引位置插入消息体:{ "role": role, "content": body } -``` - -例子: -```text -<@1 miss=true> hello ~ - ->>>>> -{ - "messages": [ - { - "content": "<@1 miss=false> hello ~ 你是一个猫娘xxx...", - "role": "system" - }, - { - "content": "好的喵\n```\n年龄: 15\n身高: 150\n服饰: xxx```", - "role": "assistant" - }, - { - "content": "研读书籍,准备明天的测验", - "role": "user" - }, - - ... ... - ], - "model": "coze", - "stream": false -} - -最终效果 ->>>>> -{ - "messages": [ - { - "content": "你是一个猫娘xxx...", - "role": "system" - }, - { - "content": "好的喵\n```\n年龄: 15\n身高: 150\n服饰: xxx```", - "role": "assistant" - }, - { - "content": "研读书籍,准备明天的测验\n\n hello ~ ", - "role": "user" - }, - - ... ... - ], - "model": "coze", - "stream": false -} -``` - - -#### 流响应标记处理 (正则替换) -```text -flag: matcher - -attribute: - find: (int) 标记 - len: (int) 缓存长度 -``` - -例子: -```text - (.+)]]>:![image]($1) - ->>>>> -{ - "messages": [ - { - "content": " (.+)]]>:![image](https://files.catbox.moe/$1) 我说Hi,你回复笑脸.jpg", - "role": "system" - }, - { - "content": "Hi", - "role": "user" - } - ], - "model": "coze", - "stream": false -} - -最终效果 ->>>>> -{ - "messages": [ - { - "content": "我说Hi,你回复笑脸.jpg", - "role": "system" - }, - { - "content": "Hi", - "role": "user" - } - ], - "model": "coze", - "stream": false -} - -请求响应时: -{ - "id": "chatcmpl-completion", - "object": "chat.completion", - "created": 1710635684, - "model": "coze", - "choices": [ - { - "index": 0, - "message": { - "role": "assistant", - "content": "![image](https://files.catbox.moe/笑脸.jpg)", - "tool_calls": null - }, - "delta": null, - "finish_reason": "stop" - } - ], - "error": null -} -``` - #### 历史记录 (会放置到第一个user或assistant的前面) ```text flag: histories diff --git a/internal/common/parser.go b/internal/common/parser.go index e3f6a857..0eed3ba4 100644 --- a/internal/common/parser.go +++ b/internal/common/parser.go @@ -11,7 +11,6 @@ import ( regexp "github.com/dlclark/regexp2" "github.com/dop251/goja" "github.com/gin-gonic/gin" - "sort" "strconv" "strings" ) @@ -400,88 +399,7 @@ func XmlFlags(ctx *gin.Context, completion *pkg.ChatCompletion, cb func(str stri token := ctx.GetString("token") handles := xmlFlagsToContents(ctx, completion.Messages, IsClaude(ctx, token, completion.Model)) - abs := func(n int) int { - if n < 0 { - return -n - } - return n - } - for _, h := range handles { - // 正则替换 - if h['t'] == "regex" { - s := split(h['v']) - if len(s) < 2 { - continue - } - - cmp := strings.TrimSpace(s[0]) - value := strings.TrimSpace(s[1]) - if cmp == "" { - continue - } - - // 忽略尾部n条 - pos, _ := strconv.Atoi(h['m']) - if pos > -1 { - pos = len(completion.Messages) - 1 - pos - if pos < 0 { - pos = 0 - } - } else { - pos = len(completion.Messages) - } - - c, err := regexp.Compile(cmp, regexp.Compiled) - if err != nil { - logger.Warn("compile failed: "+cmp, err) - continue - } - for idx, message := range completion.Messages { - if idx < pos && !message.Is("role", "system") { - replace, e := c.Replace(message.GetString("content"), value, -1, -1) - if e != nil { - logger.Warn("compile failed: "+cmp, e) - continue - } - message["content"] = replace - } - } - } - - // 深度插入 - if h['t'] == "insert" { - i, _ := strconv.Atoi(h['i']) - messageL := len(completion.Messages) - if h['m'] == "true" && messageL-1 < abs(i) { - continue - } - - pos := 0 - if i > -1 { - // 正插 - pos = i - if pos >= messageL { - pos = messageL - 1 - } - } else { - // 反插 - pos = messageL + i - if pos < 0 { - pos = 0 - } - } - - completion.Messages = append(completion.Messages[:pos+1], append([]pkg.Keyv[interface{}]{ - {"role": h['r'], "content": h['v']}, - }, completion.Messages[pos+1:]...)...) - } - - // matcher 流响应干预 - if h['t'] == "matcher" { - matchers = handleMatcher(h, matchers) - } - // 历史记录 if h['t'] == "histories" { content := strings.TrimSpace(h['v']) @@ -647,10 +565,7 @@ func handleMatcher(h map[uint8]string, matchers []Matcher) []Matcher { func xmlFlagsToContents(ctx *gin.Context, messages []pkg.Keyv[interface{}], isc bool) (handles []map[uint8]string) { var ( parser = NewParser([]string{ - "regex", - `r:@-*\d+`, "debug", - "matcher", "pad", // bing中使用的标记:填充引导对话,尝试避免道歉 "notebook", // notebook模式 "histories", @@ -682,78 +597,6 @@ func xmlFlagsToContents(ctx *gin.Context, messages []pkg.Keyv[interface{}], isc continue } - // 自由深度插入 - // inserts: 深度插入, i 是深度索引,v 是插入内容, o 是指令 - if !isc && node.t == XML_TYPE_X && node.tag[0] == '@' { - c, _ := regexp.Compile(`@-*\d+`, regexp.Compiled) - if matched, _ := c.MatchString(node.tag); matched { - // 消息上下文次数少于插入深度时,是否忽略 - // 如不忽略,将放置在头部或者尾部 - miss := "true" - if it, ok := node.attr["miss"]; ok { - if v, o := it.(bool); !o || !v { - miss = "false" - } - } - // 插入元素 - r := "user" - if it, ok := node.attr["role"]; ok { - switch str := it.(string); str { - case "user", "system", "assistant": - r = str - } - } - handles = append(handles, map[uint8]string{'i': node.tag[1:], 'r': r, 'v': node.content, 'm': miss, 't': "insert"}) - clean(content[node.index:node.end]) - } - continue - } - - // 正则替换 - // regex: v 是正则内容 - if node.t == XML_TYPE_X && node.tag == "regex" { - order := "0" // 优先级 - if o, ok := node.attr["order"]; ok { - order = fmt.Sprintf("%v", o) - } - - miss := "-1" - if m, ok := node.attr["miss"]; ok { - miss = fmt.Sprintf("%v", m) - } - - if !isc || miss != "-1" { - handles = append(handles, map[uint8]string{'m': miss, 'o': order, 'v': node.content, 't': "regex"}) - clean(content[node.index:node.end]) - } - continue - } - - if node.t == XML_TYPE_X && node.tag == "matcher" { - find := "" - if f, ok := node.attr["find"]; ok { - find = f.(string) - } - if find == "" { - clean(content[node.index:node.end]) - continue - } - - findLen := "5" - if l, ok := node.attr["len"]; ok { - findLen = fmt.Sprintf("%v", l) - } - - end := "" - if l, ok := node.attr["end"]; ok { - end = fmt.Sprintf("%v", l) - } - - handles = append(handles, map[uint8]string{'f': find, 'l': findLen, 'v': node.content, 'e': end, 't': "matcher"}) - clean(content[node.index:node.end]) - continue - } - // 开启 bing 的 pad 标记:填充引导对话,尝试避免道歉 if node.t == XML_TYPE_X && node.tag == "pad" { ctx.Set("pad", true) @@ -854,11 +697,11 @@ func xmlFlagsToContents(ctx *gin.Context, messages []pkg.Keyv[interface{}], isc } } - if len(handles) > 0 { - sort.Slice(handles, func(i, j int) bool { - return handles[i]['o'] > handles[j]['o'] - }) - } + //if len(handles) > 0 { + // sort.Slice(handles, func(i, j int) bool { + // return handles[i]['o'] > handles[j]['o'] + // }) + //} return }