Skip to content

Commit 20f499e

Browse files
authored
Guess the number (#17)
* does this fix it? * debug * more debug * record the duration my damn self * fix type * no sleep * back up less * better number lookup * fix export * advance the offset * sdg * asdfg * back up a bit * say it don't mail it * fix question logging * cleanup
1 parent 036309e commit 20f499e

File tree

7 files changed

+72
-62
lines changed

7 files changed

+72
-62
lines changed

app/Actions.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import Data.Traversable
3636
import Guess (guessingGame)
3737
import Listener (ListenerMonad, ListenerState (dbPool, mailbox), quitNow, readMail, say, speak, writeToMailBox)
3838
import MatchHelper (dropNonLetters, fuzzyMatch, isMatch, lowerCase)
39-
import OllamaApi (answerQuestion, writeToMailBox')
39+
import OllamaApi (answerQuestion)
4040
import RecordNote (readNote, recordNote)
4141
import Reminders (setReminder)
4242
import SayDateTime (currentDay, currentTime)

app/Listener.hs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,9 @@ listenPatiently = listenWithThreshold 0.70
162162
listen :: ListenerMonad String
163163
listen = do
164164
env <- ask
165-
listenWithThreshold (activationThreshold env)
165+
words <- listenWithThreshold (activationThreshold env)
166+
liftIO $ print $ "words: " ++ words
167+
return words
166168

167169
-- repeatedly reads from the capture file, looking for voice boundaries (start and stop)
168170
-- when we find a voice boundary, we splice off that chunk of audio
@@ -195,7 +197,7 @@ listenWithThreshold threshold = do
195197
liftIO $ do
196198
let se = getStartEnd (voiceStart boundary) (voiceEnd boundary)
197199
(start, end) = fromMaybe (0.0, 0.0) se -- this default should never happen
198-
writeBoundedWave (path listener) capfilepath (start - 0.25) end (audioRate env) -- back up a 1/4 second to make sure we don't lose anything
200+
writeBoundedWave (path listener) capfilepath (start - 0.2) end (audioRate env) -- maybe ? back up a 2/10 second to make sure we don't lose anything
199201
transcript <- sendAudio ("http://" ++ whisperHost env ++ "/") (whisperPort env) capfilepath
200202
when (debug env) (liftIO $ print transcript)
201203
return transcript
@@ -263,14 +265,17 @@ say msg =
263265
config <- ask
264266
dur <- liftIO $ sayText (sileroHost config) (sileroPort config) msg
265267
endTime <- liftIO getCurrentTime
266-
let offset = timeOffset listenerState + dur + sleepSeconds config -- advance the offset to skip over the time when the computer was talking
268+
let dur = diffUTCTime endTime startTime
269+
durSeconds = realToFrac $ nominalDiffTimeToSeconds dur
270+
offset = timeOffset listenerState + durSeconds + sleepSeconds config -- advance the offset to skip over the time when the computer was talking
271+
liftIO $ print $ "duration: " ++ (show durSeconds)
267272
put
268273
listenerState
269274
{ timeOffset = offset,
270275
voiceStartTime = Nothing,
271276
voiceEndTime = Nothing
272277
}
273-
return dur
278+
return durSeconds
274279

275280
trim :: String -> String
276281
trim s = T.unpack $ T.strip $ T.pack s

app/Main.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ runJob config startState = do
6565
runListenerMonad commandLoop config startState
6666
print "ending program, killing recorder thread"
6767
killThread recorderThread
68-
run config -- dirty hack because things sometimes crash
68+
runJob config startState -- dirty hack because things sometimes crash
6969

7070
makeDbConfig :: EnvConfig -> Maybe PostgresConf
7171
makeDbConfig config = do

app/MatchHelper.hs

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -27,34 +27,9 @@ isMatch s r = not (null (scan r s))
2727
dropNonNumbers :: String -> String
2828
dropNonNumbers = filter isNumber
2929

30-
-- nums :: [String]
31-
-- nums = ["", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty"]
32-
33-
-- teens :: [String]
34-
-- teens = ["", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety", "hundred"]
35-
36-
-- numsToString :: Int -> String
37-
-- numsToString i
38-
-- | i <= 20 = nums !! i
39-
-- | i < 100 = teens !! ((i `div` 10) - 1) ++ " " ++ nums !! (i `mod` 10)
40-
41-
-- numsToString' :: Integer -> String
42-
-- numsToString' i =
43-
-- let ii = fromInteger i
44-
-- in numsToString ii
45-
4630
strip :: String -> String
4731
strip s = T.unpack $ T.strip (T.pack s) -- I know this shouldn't be required due to OverloadedStrings, and yet
4832

49-
nummap :: M.Map String Integer
50-
nummap =
51-
let numnum = map toInteger [1 .. 99]
52-
numstrs = map (strip . convertNumber) numnum
53-
in M.fromList (zip numstrs numnum)
54-
55-
lookupNum :: String -> Maybe Integer
56-
lookupNum i = M.lookup i nummap
57-
5833
parseInt :: String -> Maybe Integer
5934
parseInt str = readMaybe $ dropNonNumbers str
6035

app/SpokenNumbers.hs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
{-# LANGUAGE QuasiQuotes #-}
22

3-
module SpokenNumbers (convertNumber, convertNString, convertAllNumbers, readUnit) where
3+
module SpokenNumbers (convertNumber, convertNString, convertAllNumbers, readUnit, lookupNum) where
44

5+
import Data.Char
6+
import qualified Data.Map as M
57
import qualified Data.Text as T
68
import Text.Numerals
79
import Text.Regex.PCRE.Heavy (Regex, gsub, re)
@@ -32,3 +34,26 @@ convertNString nstr =
3234

3335
convertAllNumbers :: String -> String
3436
convertAllNumbers = gsub [re|([0-9,]+)|] convertNString
37+
38+
punctToSpace :: String -> String
39+
punctToSpace str = gsub [re|([^a-z,]+)|] " " str
40+
41+
makeLower :: String -> String
42+
makeLower = map toLower
43+
44+
trim :: String -> String
45+
trim = f . f
46+
where
47+
f = reverse . dropWhile isSpace
48+
49+
nummap :: M.Map String Integer
50+
nummap =
51+
let nm = map convertNumber [0 .. 100]
52+
nmLower = map makeLower nm
53+
regnums = map punctToSpace nmLower
54+
in M.fromList $ zip regnums [0 .. 100]
55+
56+
lookupNum :: String -> Maybe Integer
57+
lookupNum s =
58+
let needle = trim $ punctToSpace $ makeLower s
59+
in M.lookup needle nummap

lib/Guess.hs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,35 +6,36 @@ module Guess where
66
import Control.Concurrent (threadDelay)
77
import Control.Monad.State (liftIO)
88
import Data.Char (isNumber, toLower)
9-
import Listener (ListenerMonad, listen, writeToMailBox)
9+
import Listener (ListenerMonad, listen, listenPatiently, say, writeToMailBox)
1010
import MatchHelper (parseInt, readInt)
1111
import System.Random (Random (randomRs), newStdGen)
1212

1313
listenForInteger :: ListenerMonad (Maybe Integer)
14-
listenForInteger = readInt <$> listen
14+
listenForInteger = readInt <$> listenPatiently
1515

1616
guess :: Integer -> ListenerMonad ()
1717
guess secret = do
18-
writeToMailBox "Guess the number: "
18+
say "Guess the number: "
1919
liftIO $ threadDelay 250000
2020
guessedNumber <- listenForInteger
2121
case guessedNumber of
2222
Nothing -> do
23-
writeToMailBox "I couldn't understand you."
23+
say "I couldn't understand you."
2424
guess secret
2525
Just gnum ->
2626
if gnum > secret
2727
then do
28-
writeToMailBox "Too high."
28+
say "Too high."
2929
guess secret
3030
else
3131
if gnum < secret
3232
then do
33-
writeToMailBox "Too low."
33+
say "Too low."
3434
guess secret
3535
else do
36-
writeToMailBox "You got it!"
37-
writeToMailBox "Thanks for playing!"
36+
say "You got it!"
37+
say "Thanks for playing!"
38+
return ()
3839

3940
guessingGame :: ListenerMonad ()
4041
guessingGame = do

lib/OllamaApi.hs

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,27 @@
55
{-# LANGUAGE OverloadedStrings #-}
66
{-# LANGUAGE ScopedTypeVariables #-}
77

8-
module OllamaApi (writeToMailBox', answerQuestion, extractAnswer, makeResponseChunk, jsonChunks, chunker) where
8+
module OllamaApi (answerQuestion, extractAnswer, makeResponseChunk, jsonChunks, chunker) where
99

1010
import ChatLogger
11-
import Conduit (ConduitM, ConduitT, MonadResource, awaitForever, concatC, concatMapAccumC, concatMapC, concatMapCE, filterC, leftover, mapAccumWhileC, mapC, mapCE, mapM_C, runConduit, runConduitRes, sinkLazy, sourceLazy, yield, (.|))
11+
import Conduit
12+
( ConduitM,
13+
ConduitT,
14+
MonadIO (liftIO),
15+
MonadResource,
16+
awaitForever,
17+
filterC,
18+
leftover,
19+
mapC,
20+
mapM_C,
21+
runConduit,
22+
runResourceT,
23+
yield,
24+
(.|),
25+
)
1226
import ConfigParser
27+
( EnvConfig (ollamaHost, ollamaPort, sileroHost, sileroPort),
28+
)
1329
import Control.Concurrent (forkIO)
1430
import Control.Concurrent.STM (STM, TQueue, atomically, readTVar, writeTQueue, writeTVar)
1531
import Control.Exception (throwIO)
@@ -40,11 +56,10 @@ import Database.Persist.Postgresql (ConnectionPool, Entity (Entity))
4056
import GHC.Generics (Generic)
4157
import Listener
4258
import Network.HTTP.Conduit
43-
( Request (method, port, requestBody, requestHeaders, responseTimeout, secure),
44-
RequestBody (RequestBodyBS, RequestBodyLBS),
59+
( Request (method, port, requestBody),
60+
RequestBody (RequestBodyLBS),
4561
Response (responseBody),
4662
http,
47-
httpLbs,
4863
newManager,
4964
parseRequest,
5065
responseTimeoutMicro,
@@ -99,25 +114,14 @@ isPunct c =
99114
makeResponseChunk :: B.ByteString -> Maybe OllamaResponse
100115
makeResponseChunk = decode . BLS.fromStrict
101116

102-
writeToMailBox' :: MonadResource m => TQueue String -> Maybe ConnectionPool -> Maybe QueryId -> String -> m ()
103-
writeToMailBox' mbox dbPool queryId msg =
104-
liftResourceT $
105-
liftIO $ do
106-
mapM_ (\qid -> addAnswer dbPool (Answer qid msg)) queryId
107-
atomically $ writeTQueue mbox msg
108-
109-
talker :: MonadResource m => String -> Int -> String -> m ()
110-
talker sileroHost sileroPort mesg = do
117+
talker :: MonadResource m => String -> Int -> Maybe ConnectionPool -> Maybe QueryId -> String -> m ()
118+
talker sileroHost sileroPort connectionPool qid mesg = do
111119
liftResourceT $ do
112-
liftIO $ sayText sileroHost sileroPort mesg -- TODO: return a list of the durations somewhere so we can advance the time in the listener
120+
liftIO $ do
121+
mapM_ (\qid -> addAnswer connectionPool (Answer qid mesg)) qid
122+
sayText sileroHost sileroPort mesg -- TODO: return a list of the durations somewhere so we can advance the time in the listener
113123
return ()
114124

115-
getDbStuff :: Maybe QueryId -> Maybe ConnectionPool -> Maybe (QueryId, ConnectionPool)
116-
getDbStuff q d = do
117-
q' <- q
118-
d' <- d
119-
return (q', d')
120-
121125
chunker :: Monad m => (String -> m ()) -> ConduitT B.ByteString c m ()
122126
chunker chunkAction =
123127
jsonChunks '}'
@@ -140,7 +144,7 @@ answerQuestion qid question = do
140144
body = RequestBodyLBS $ encode payload
141145
request' = request {method = "POST", requestBody = body, port = apiPort}
142146
request'' = setRequestResponseTimeout (responseTimeoutMicro (500 * 1000000)) request'
143-
talker' = talker (sileroHost env) (sileroPort env)
147+
talker' = talker (sileroHost env) (sileroPort env) (dbPool st) qid
144148
manager <- newManager tlsManagerSettings
145149
runResourceT $ do
146150
rsp <- http request'' manager

0 commit comments

Comments
 (0)