11import { Command } from '../types' ;
22import { Configuration , OpenAIApi } from 'openai' ;
33import grzesJson from '../../grzes.json' ;
4+ import Natural from 'natural' ;
5+
6+ const tokenizer = new Natural . AggressiveTokenizerPl ( ) ;
7+ const tfidf = grzesJson . reduce ( ( tfidf , line ) => {
8+ tfidf . addDocument ( tokenizer . tokenize ( line ) ) ;
9+ return tfidf ;
10+ } , new Natural . TfIdf ( ) ) ;
411
512const wait = ( ms : number ) => new Promise ( ( resolve ) => setTimeout ( resolve , ms ) ) ;
613
@@ -24,30 +31,14 @@ const grzesiu: Command = {
2431 cooldown : COOLDOWN ,
2532 async execute ( msg , args ) {
2633 const username = ( msg . member ?. displayName || msg . author . username ) . trim ( ) . split ( / \s / ) [ 0 ] ;
27- const prompt = await generateGrzesiuPrompt ( username , args . join ( ' ' ) ) ;
28-
29- const engine = 'text-davinci-001' ;
30- // const engine = 'text-babbage-001';
31- const response = await openai . createCompletion ( engine , {
32- prompt,
33- temperature : 1 ,
34- max_tokens : RESPONSE_TOKENS ,
35- top_p : 1 ,
36- frequency_penalty : 0 ,
37- presence_penalty : 2 ,
38- best_of : 4 ,
39- } ) ;
40-
41- if ( ! response . data . choices ?. [ 0 ] ?. text ) {
42- return msg . channel . send ( `Niestety, Grzesiu nie miał nic do powiedzenia!` ) ;
43- }
34+ const question = args . join ( ' ' ) ;
4435
45- const messages = response . data . choices [ 0 ] . text
46- . split ( '\n' )
47- . map ( ( l ) => l . trim ( ) )
48- . filter ( ( l ) => l . startsWith ( ` ${ GRZESIU_NAME } :` ) )
49- . flatMap ( ( l ) => l . split ( ` ${ GRZESIU_NAME } :` ) )
50- . filter ( ( l ) => l . trim ( ) . length > 0 ) ;
36+ const generators = {
37+ getGrzesiuAnswerFromOpenAI ,
38+ getRandomGrzesiuAnswers ,
39+ } ;
40+
41+ const messages = await generators . getRandomGrzesiuAnswers ( username , question ) ;
5142
5243 if ( ! messages . length ) {
5344 return msg . channel . send ( `Niestety, Grzesiu nie miał nic do powiedzenia!` ) ;
@@ -66,6 +57,77 @@ export default grzesiu;
6657
6758const getRandomInt = ( len : number ) => Math . floor ( Math . random ( ) * len ) ;
6859
60+ interface GrzesiuGenerator {
61+ ( username : string , question : string ) : Promise < string [ ] > ;
62+ }
63+
64+ // random
65+ const getRandomGrzesiuAnswers : GrzesiuGenerator = async ( _username , question ) => {
66+ const g = grzesJson
67+ . map ( ( l ) => l . trim ( ) )
68+ . filter ( ( line ) => ! BANNED_PATTERNS . test ( line ) && line . length > 0 ) ;
69+
70+ const potentialItems =
71+ question . trim ( ) . length > 0
72+ ? g . filter ( ( l , idx ) => {
73+ const coeff = ( tfidf . tfidf ( question , idx ) as unknown as number ) || 1 ;
74+ return coeff * Natural . DiceCoefficient ( question , l ) > 0.35 ;
75+ } )
76+ : [ ] ;
77+
78+ const initialIndex =
79+ potentialItems . length > 0 ? g . indexOf ( potentialItems [ getRandomInt ( potentialItems . length ) ] ) : - 1 ;
80+
81+ const MAX_LINES = 5 ;
82+ const numberOfLines = 5 - Math . floor ( Math . log2 ( Math . floor ( Math . random ( ) * 2 ** MAX_LINES ) + 1 ) ) ;
83+
84+ const lines = [ ] ;
85+ let idx = initialIndex === - 1 ? getRandomInt ( g . length ) : initialIndex ;
86+
87+ for ( let i = 0 ; i < numberOfLines ; ++ i ) {
88+ lines . push ( g [ idx ] ) ;
89+
90+ if ( Math . random ( ) < 0.9 && idx < g . length ) {
91+ ++ idx ;
92+ } else {
93+ idx = getRandomInt ( g . length ) ;
94+ }
95+ }
96+
97+ return lines ;
98+ } ;
99+
100+ // openAI
101+ const getGrzesiuAnswerFromOpenAI : GrzesiuGenerator = async ( username , question ) => {
102+ const prompt = await generateGrzesiuPrompt ( username , question ) ;
103+
104+ const engine = 'text-davinci-001' ;
105+ // const engine = 'text-babbage-001';
106+ const response = await openai . createCompletion ( engine , {
107+ prompt,
108+ temperature : 1 ,
109+ max_tokens : RESPONSE_TOKENS ,
110+ top_p : 1 ,
111+ frequency_penalty : 0 ,
112+ presence_penalty : 2 ,
113+ best_of : 4 ,
114+ } ) ;
115+
116+ console . log ( response ) ;
117+
118+ if ( ! response . data . choices ?. [ 0 ] ?. text ) {
119+ return [ ] ;
120+ }
121+
122+ const messages = response . data . choices [ 0 ] . text
123+ . split ( '\n' )
124+ . map ( ( l ) => l . trim ( ) )
125+ . filter ( ( l ) => l . startsWith ( `${ GRZESIU_NAME } :` ) )
126+ . flatMap ( ( l ) => l . split ( `${ GRZESIU_NAME } :` ) )
127+ . filter ( ( l ) => l . trim ( ) . length > 0 ) ;
128+ return messages ;
129+ } ;
130+
69131const getRandomIndices = ( num : number , max : number ) => {
70132 const set = new Set < number > ( ) ;
71133 while ( set . size < num ) set . add ( getRandomInt ( max ) ) ;
0 commit comments