Skip to content

Commit 18a55e9

Browse files
committed
added findPlaces and findPeople functions to Google Gemeni example
1 parent a6c08a1 commit 18a55e9

File tree

1 file changed

+78
-9
lines changed

1 file changed

+78
-9
lines changed

gemini_commandline/Main.hs

Lines changed: 78 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,21 @@
33
{-# LANGUAGE ScopedTypeVariables #-}
44

55
import System.Environment (getArgs, getEnv)
6-
import qualified Data.Aeson as Aeson -- Used for Aeson.encode, Aeson.object etc.
7-
import Data.Aeson (FromJSON, ToJSON, eitherDecode) -- Specific functions needed
8-
import GHC.Generics (Generic) -- Needed for deriving ToJSON/FromJSON
6+
import qualified Data.Aeson as Aeson
7+
import Data.Aeson (FromJSON, ToJSON, eitherDecode)
8+
import GHC.Generics (Generic)
99
import Network.HTTP.Client.TLS (tlsManagerSettings)
1010
import Network.HTTP.Client (newManager, httpLbs, parseRequest, Manager, Request(..), RequestBody(..), Response(..), responseStatus)
1111
import Network.HTTP.Types.Status (statusCode)
12-
import qualified Data.Text as T
12+
-- Replace qualified import with explicit import list:
13+
import Data.Text (Text, pack, unpack, splitOn, strip, null)
1314
import Data.Text.Encoding (encodeUtf8)
1415
import Control.Exception (SomeException, handle)
1516

1617
-- --- Request Data Types ---
1718

1819
data RequestPart = RequestPart
19-
{ reqText :: T.Text -- Using reqText to avoid name clash with Response Part's text
20+
{ reqText :: Text -- Using reqText to avoid name clash with Response Part's text
2021
} deriving (Show, Generic)
2122

2223
instance ToJSON RequestPart where
@@ -81,14 +82,14 @@ completion :: String -- ^ Google API Key
8182
-> IO (Either String String) -- ^ Left error message or Right completion text
8283
completion apiKey manager promptText = do
8384
initialRequest <- parseRequest "https://generativelanguage.googleapis.com/v1/models/gemini-2.0-flash:generateContent"
84-
let reqContent = RequestContent { reqParts = [RequestPart { reqText = T.pack promptText }] }
85+
let reqContent = RequestContent { reqParts = [RequestPart { reqText = pack promptText }] }
8586
let genConfig = GenerationConfig { temperature = 0.1, maxOutputTokens = 800 }
8687
let apiRequest = GeminiApiRequest { contents = [reqContent], generationConfig = genConfig }
8788

8889
let request = initialRequest
8990
{ requestHeaders =
9091
[ ("Content-Type", "application/json")
91-
, ("x-goog-api-key", encodeUtf8 $ T.pack apiKey)
92+
, ("x-goog-api-key", encodeUtf8 $ pack apiKey)
9293
]
9394
, method = "POST"
9495
, requestBody = RequestBodyLBS $ Aeson.encode apiRequest
@@ -119,15 +120,83 @@ completion apiKey manager promptText = do
119120
let err = "Error: API request failed with status " ++ show (statusCode status) ++ "\nBody: " ++ show body
120121
return $ Left err
121122

123+
-- | Extracts potential place names from text using the Gemini API.
124+
findPlaces :: String -- ^ Google API Key
125+
-> Manager -- ^ HTTP Manager
126+
-> String -- ^ The input text to analyze (Renamed from text)
127+
-> IO (Either String [String]) -- ^ Left error or Right list of places
128+
findPlaces apiKey manager inputText = do
129+
-- Renamed parameter text -> inputText
130+
let prompt = "Extract only the place names strictly separated by commas from the following text. Do not include any explanation or introduction. Example: London,Paris,Tokyo\n\nText:\"" ++ inputText ++ "\""
131+
apiResult <- completion apiKey manager prompt
132+
133+
return $ case apiResult of
134+
Left err -> Left ("API call failed in findPlaces: " ++ err)
135+
Right responseText ->
136+
let -- Use Text functions directly (removed T. prefix)
137+
rawParts = splitOn (pack ",") (pack responseText)
138+
strippedParts = map strip rawParts
139+
nonEmptyParts = filter (not . Data.Text.null) strippedParts -- Use Data.Text.null to be explicit if Text type is inferred
140+
-- Convert final list back to [String]
141+
places = map unpack nonEmptyParts
142+
in Right places
143+
144+
-- | Extracts potential person names from text using the Gemini API.
145+
findPeople :: String -- ^ Google API Key
146+
-> Manager -- ^ HTTP Manager
147+
-> String -- ^ The input text to analyze (Renamed from text)
148+
-> IO (Either String [String]) -- ^ Left error or Right list of people
149+
findPeople apiKey manager inputText = do
150+
-- Renamed parameter text -> inputText
151+
let prompt = "Extract only the person names strictly separated by commas from the following text. Do not include any explanation or introduction. Example: Alice,Bob,Charlie\n\nText:\"" ++ inputText ++ "\""
152+
apiResult <- completion apiKey manager prompt
153+
154+
return $ case apiResult of
155+
Left err -> Left ("API call failed in findPeople: " ++ err)
156+
Right responseText ->
157+
let -- Use Text functions directly (removed T. prefix)
158+
rawParts = splitOn (pack ",") (pack responseText)
159+
strippedParts = map strip rawParts
160+
nonEmptyParts = filter (not . Data.Text.null) strippedParts -- Use Data.Text.null to be explicit
161+
people = map unpack nonEmptyParts
162+
in Right people
163+
122164
-- --- Main Function ---
123165

124166
main :: IO ()
125167
main = do
126168
args <- getArgs
127169
case args of
128-
[] -> putStrLn "Error: Please provide a prompt as a command line argument."
170+
-- If no args, run demo extraction on sample text
171+
[] -> do
172+
putStrLn "No prompt provided. Running demo extraction on sample text:"
173+
let sampleText = "Dr. Evelyn Reed went to London last week with her colleague Bob Smith. They visited the Tower Bridge and met someone near Paris, Texas."
174+
putStrLn $ "Sample Text: \"" ++ sampleText ++ "\"\n"
175+
176+
apiKeyResult <- lookupEnv "GOOGLE_API_KEY"
177+
case apiKeyResult of
178+
Nothing -> putStrLn "Error: GOOGLE_API_KEY environment variable not set."
179+
Just apiKey -> do
180+
manager <- newManager tlsManagerSettings
181+
182+
-- Find Places
183+
putStrLn "Attempting to find places..."
184+
placesResult <- findPlaces apiKey manager sampleText
185+
case placesResult of
186+
Left err -> putStrLn $ "Error finding places: " ++ err
187+
Right places -> putStrLn $ "Found Places: " ++ show places
188+
189+
putStrLn "\nAttempting to find people..."
190+
-- Find People
191+
peopleResult <- findPeople apiKey manager sampleText
192+
case peopleResult of
193+
Left err -> putStrLn $ "Error finding people: " ++ err
194+
Right people -> putStrLn $ "Found People: " ++ show people
195+
196+
-- If args provided, run original completion behavior
129197
(promptArg:_) -> do
130-
apiKeyResult <- lookupEnv "GOOGLE_API_KEY" -- Using lookupEnv for safer handling
198+
putStrLn "Prompt provided. Running direct completion:"
199+
apiKeyResult <- lookupEnv "GOOGLE_API_KEY"
131200
case apiKeyResult of
132201
Nothing -> putStrLn "Error: GOOGLE_API_KEY environment variable not set."
133202
Just apiKey -> do

0 commit comments

Comments
 (0)