Files
Arjun Patel 8870741c3e ai conversation (#49)
* capture audio with alsa

* add brainstorm thoughts

* use basecamp project for managing this project

* add libcurl basic example

* write pcm data to file

* transcribe audio file with deepgram

* transcribe raw audio

* hit anthropic API for ai question

* create full flow with stt, anthropic, tts, and playback

This organizes some components like deepgram into own module, and also
allows gets the full flow to work every time we run the program.

* organize audio and intelligence modules

* organize header files into include directory

* docs: add readme

* docs: explain future work

* docs: add disclaimer about hardcoded audio params
2025-07-27 15:07:30 -07:00

87 lines
2.5 KiB
C

#include "intelligence.h"
#include "utils.h"
#include <curl/curl.h>
#include <string.h>
static char *find_ai_response(char *json_response) {
printf("Parsing response: %s \n", json_response);
char *start = strstr(json_response, "\"text\":\"");
if (!start)
return NULL;
start += 8; // Skip past "text":"
char *end = strchr(start, '"');
if (!end)
return NULL;
size_t len = end - start;
char *result = malloc(len + 1);
strncpy(result, start, len);
result[len] = '\0';
return result;
}
char *ai_ask(char *question) {
CURL *curl;
CURLcode res;
struct curl_slist *headers = NULL;
// Initialize response buffer
struct curl_response_data response = {0};
response.data = malloc(1);
response.size = 0;
// Create JSON payload
char json_payload[2048];
snprintf(json_payload, sizeof(json_payload),
"{"
"\"model\":\"claude-3-haiku-20240307\","
"\"max_tokens\":256,"
"\"messages\":[{\"role\":\"user\",\"content\":\"Make it one sentence answer: %s\"}]"
"}",
question);
curl = curl_easy_init();
if (curl) {
char *anthropic_api_key = getenv("ANTHROPIC_API_KEY");
if (!anthropic_api_key) {
printf("ANTHROPIC_API_KEY not set\n");
free(response.data);
curl_easy_cleanup(curl);
return NULL;
}
char auth_header[256];
snprintf(auth_header, sizeof(auth_header), "x-api-key: %s",
anthropic_api_key);
headers = curl_slist_append(headers, "content-type: application/json");
headers = curl_slist_append(headers, auth_header);
headers = curl_slist_append(headers, "anthropic-version: 2023-06-01");
curl_easy_setopt(curl, CURLOPT_URL,
"https://api.anthropic.com/v1/messages");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_POST, 1L);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_payload);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_callback_response);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
res = curl_easy_perform(curl);
if (res != CURLE_OK) {
fprintf(stderr, "curl failed: %s\n", curl_easy_strerror(res));
free(response.data);
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
return NULL;
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}
// Parse AI response from complete response
char *answer = find_ai_response(response.data);
free(response.data);
return answer;
}