xiaoxx970 / chatgpt-in-terminal

Use ChatGPT in terminal
MIT License
201 stars 27 forks source link

在输入未被定义的斜杠命令时的处理逻辑 #33

Closed Ace-Radom closed 1 year ago

Ace-Radom commented 1 year ago

在隔壁实现的一个新功能 你可以考虑一下要不要加到这来

现在输入未定义的斜杠命令的时候都是直接输出help page 但我加上一点提示会更好……?你可以考虑一下

image

我写了一套逻辑 在出现未识别的命令时判断哪一个命令和他最像 如果找到了就提示用户 没有就不提示

size_t min_levenshtein_distance = strlen( __slashcmd );
int most_similar_cmd_index = -1;
for ( int i = 0 ; i < sizeof( slash_commands ) / sizeof( char* ) - 1 ; i++ )
{
    size_t this_levenshtein_distance = get_levenshtein_distance( __slashcmd , slash_commands[i] );
    // levenshtein distance between __slashcmd and this slash command
    if ( minn( min_levenshtein_distance , this_levenshtein_distance ) < min_levenshtein_distance )
    {
        if ( get_jaccard_similarity( __slashcmd , slash_commands[i] ) >= 0.75 )
        {
            min_levenshtein_distance = this_levenshtein_distance;
            most_similar_cmd_index = i;
        } // update most similar index only if the jaccard similarity of these two greater than 75%
    }
}

原理也比较简单 比较这个未识别的命令和所有命令并判断他们是否是目前最相似的【levenshtein距离最短 jaccard相似度大于75%】如果是就把索引存下来之后输出 levenshtein和jaccard算法我记得python里有现成的实现

你可以考虑一下

xiaoxx970 commented 1 year ago

我一直觉得这个功能应该很复杂,不过要是有现成算法的话我觉得加上挺好的

Ace-Radom commented 1 year ago

看了一下 jaccard相似度非常好求 毕竟python有原生的集合类型求并集和交集很方便【不用像C里面那样玩指针】 但levenshtein确实是有库我没记错 但是是第三方的 https://pypi.org/project/Levenshtein/ 而且这个库说实话就这里这个需求有点……不太必要?何况levenshtein虽然算法相对复杂但实现还是挺简单的

#define minn( x , y ) ( x < y ? x : y )

size_t get_levenshtein_distance( const char* __s1 , const char* __s2 ){
    int s1_len = strlen( __s1 );
    int s2_len = strlen( __s2 );

    int v[s1_len+1][s2_len+1];
    memset( v , 0 , sizeof( v ) );
    for ( int i = 0 ; i <= s1_len ; i++ )
    {
        for ( int j = 0 ; j <= s2_len ; j++ )
        {
            if ( i == 0 )
                v[i][j] = j;
            else if ( j == 0 )
                v[i][j] = i;
            else if ( __s1[i-1] == __s2[j-1] )
                v[i][j] = v[i-1][j-1];
            else
                v[i][j] = minn( v[i-1][j-1] , minn( v[i][j-1] , v[i-1][j] ) ) + 1;
        }
    }
    return v[s1_len][s2_len];
}

我在C下的实现代码也就这点 你可以先看一下 我稍后写好了去开一个PR

娘原来py的二维数组那么烦的吗

Ace-Radom commented 1 year ago

额说个比较难绷的事

image

我写这一块的时候还没看到你上面command handle的部分改了 然后之后也忘了改 导致现在这个 CustomCompleter.commands 变成未定义名了 你看是不是可能要push一个热修了

xiaoxx970 commented 1 year ago

哈?你用的是哪个版本,我在merge前同步过main分支了,应该没问题的

Ace-Radom commented 1 year ago

就是主仓库的main分支 在本机上pull之后用 chat.py 启动 出来的这个问题 https://github.com/xiaoxx970/chatgpt-in-terminal/blob/ca474af90cc7ac1cae746646bdf7734f446bb3e3/gpt_term/main.py#L916-L920 就是这里 迭代所有命令的时候还用的是老的 CustomCompleter.commands 刚刚测试了一下pip上upgrade的版本也有相同的问题(

xiaoxx970 commented 1 year ago

诶哟我去真是,赶快改改

Ace-Radom commented 1 year ago

还是有问题……是应该没改全 我fork里改好了马上开个pr

xiaoxx970 commented 1 year ago

啊没想到是我想简单了,这修bug就更新了2个版本

Ace-Radom commented 1 year ago

没事现在应该是好了 测试下来没问题:joy: