1
1
import { Command } from '../types' ;
2
2
import { Configuration , OpenAIApi } from 'openai' ;
3
3
import 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 ( ) ) ;
4
11
5
12
const wait = ( ms : number ) => new Promise ( ( resolve ) => setTimeout ( resolve , ms ) ) ;
6
13
@@ -24,30 +31,14 @@ const grzesiu: Command = {
24
31
cooldown : COOLDOWN ,
25
32
async execute ( msg , args ) {
26
33
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 ( ' ' ) ;
44
35
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 ) ;
51
42
52
43
if ( ! messages . length ) {
53
44
return msg . channel . send ( `Niestety, Grzesiu nie miał nic do powiedzenia!` ) ;
@@ -66,6 +57,77 @@ export default grzesiu;
66
57
67
58
const getRandomInt = ( len : number ) => Math . floor ( Math . random ( ) * len ) ;
68
59
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
+
69
131
const getRandomIndices = ( num : number , max : number ) => {
70
132
const set = new Set < number > ( ) ;
71
133
while ( set . size < num ) set . add ( getRandomInt ( max ) ) ;
0 commit comments