@@ -15,8 +15,58 @@ import (
15
15
16
16
var prependerPool tpool.Pool [deque.Deque [string ]]
17
17
18
- func (br * Brain ) Think (ctx context.Context , tag string , prefix []string ) iter.Seq [func (id * []byte , suf * []byte ) error ] {
19
- panic ("unimplemented" )
18
+ func (br * Brain ) Think (ctx context.Context , tag string , prompt []string ) iter.Seq [func (id * []byte , suf * []byte ) error ] {
19
+ return func (yield func (func (id , suf * []byte ) error ) bool ) {
20
+ erf := func (err error ) { yield (func (id , suf * []byte ) error { return err }) }
21
+ conn , err := br .db .Take (ctx )
22
+ defer br .db .Put (conn )
23
+ if err != nil {
24
+ erf (fmt .Errorf ("couldn't get connection to speak: %w" , err ))
25
+ return
26
+ }
27
+ var s * sqlite.Stmt
28
+ if len (prompt ) != 0 {
29
+ s , err = conn .Prepare (`SELECT id, suffix FROM knowledge WHERE tag = :tag AND prefix >= :lower AND prefix < :upper AND LIKELY(deleted IS NULL)` )
30
+ if err != nil {
31
+ erf (fmt .Errorf ("couldn't prepare term selection: %w" , err ))
32
+ return
33
+ }
34
+ b := prefix (make ([]byte , 0 , 128 ), prompt )
35
+ b , d := searchbounds (b )
36
+ s .SetBytes (":lower" , b )
37
+ s .SetBytes (":upper" , d )
38
+ } else {
39
+ s , err = conn .Prepare (`SELECT id, suffix FROM knowledge WHERE tag = :tag AND prefix = x'00' AND LIKELY(deleted IS NULL)` )
40
+ if err != nil {
41
+ erf (fmt .Errorf ("couldn't prepare first term selection: %w" , err ))
42
+ return
43
+ }
44
+ }
45
+ s .SetText (":tag" , tag )
46
+ f := func (id , suf * []byte ) error {
47
+ * id = bytecol (* id , s , 0 )
48
+ * suf = bytecol (* suf , s , 1 )
49
+ return nil
50
+ }
51
+ for {
52
+ ok , err := s .Step ()
53
+ if err != nil {
54
+ erf (fmt .Errorf ("couldn't step term selection: %w" , err ))
55
+ return
56
+ }
57
+ if ! ok || ! yield (f ) {
58
+ break
59
+ }
60
+ }
61
+ }
62
+ }
63
+
64
+ func bytecol (d []byte , s * sqlite.Stmt , col int ) []byte {
65
+ n := s .ColumnLen (col )
66
+ if cap (d ) < n {
67
+ d = make ([]byte , n )
68
+ }
69
+ return d [:s .ColumnBytes (col , d [:n ])]
20
70
}
21
71
22
72
// Speak generates a full message and appends it to w.
0 commit comments