Skip to content

Commit

Permalink
Set minimum stack with stack cookie and warn user if stack too small
Browse files Browse the repository at this point in the history
  • Loading branch information
sacredbanana committed Mar 4, 2024
1 parent 2159e9c commit 701c9e8
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 14 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
- Fix crash when config.json doesn't exist
- Fix crash when selecting the root menu items
- Adjust screen colours to enhance visibility
- Improved error handling for connection errors
- Use a stack cookie to set minimum stack size to 32768 bytes (AmigaOS 3.1.4 or higher required)
- Shows a warning if the stack size is smaller than 32768 bytes

## 1.4.2 (2024-01-31)

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ Since `translator.library` **v43** is not available as a standalone install, you

## Launching **AmigaGPT**
* Launch the application by double-clicking the AmigaGPT icon
* You may also launch the app in the command line but before you do, run the command `STACK 20000` to give the program 20kb of stack since the default stack size for apps launched from the shell is 4kb and this is not enough for **AmigaGPT** and will cause random crashes due to stack overflow. This is not required when you launch the app by double clicking the icon since the stack size is saved in the icon
* You may also launch the app in the command line but before you do, run the command `STACK 32768` to give the program 32kb of stack since the default stack size for apps launched from the shell is 4kb and this is not enough for **AmigaGPT** and will cause random crashes due to stack overflow. This is not required when you launch the app by double clicking the icon since the stack size is saved in the icon

## Usage

Expand Down
37 changes: 30 additions & 7 deletions src/gui.c
Original file line number Diff line number Diff line change
Expand Up @@ -1661,6 +1661,14 @@ static void sendChatMessage() {
if (config.chatSystem != NULL && (config.chatSystem) > 0)
addTextToConversation(currentConversation, config.chatSystem, "system");
responses = postChatMessageToOpenAI(currentConversation, config.chatModel, config.openAiApiKey, TRUE);
if (responses == NULL) {
displayError("Could not connect to OpenAI");
SetGadgetAttrs(sendMessageButton, mainWindow, NULL, GA_Disabled, FALSE, TAG_DONE);
SetGadgetAttrs(newChatButton, mainWindow, NULL, GA_Disabled, FALSE, TAG_DONE);
SetGadgetAttrs(deleteChatButton, mainWindow, NULL, GA_Disabled, FALSE, TAG_DONE);
FreeVec(receivedMessage);
return;
}
if (config.chatSystem != NULL && strlen(config.chatSystem) > 0) {
struct MinNode *chatSystemNode = RemTail(currentConversation);
FreeVec(chatSystemNode);
Expand Down Expand Up @@ -1731,6 +1739,13 @@ static void sendChatMessage() {
updateStatusBar("Generating conversation title...", 7);
addTextToConversation(currentConversation, "generate a short title for this conversation and don't enclose the title in quotes or prefix the response with anything", "user");
responses = postChatMessageToOpenAI(currentConversation, config.chatModel, config.openAiApiKey, FALSE);
if (responses == NULL) {
displayError("Could not connect to OpenAI");
SetGadgetAttrs(sendMessageButton, mainWindow, NULL, GA_Disabled, FALSE, TAG_DONE);
SetGadgetAttrs(newChatButton, mainWindow, NULL, GA_Disabled, FALSE, TAG_DONE);
SetGadgetAttrs(deleteChatButton, mainWindow, NULL, GA_Disabled, FALSE, TAG_DONE);
return;
}
if (responses[0] != NULL) {
STRPTR responseString = getMessageContentFromJson(responses[0], FALSE);
formatText(responseString);
Expand Down Expand Up @@ -3002,6 +3017,15 @@ static void createImage() {

const enum ImageSize imageSize = config.imageModel == DALL_E_2 ? config.imageSizeDallE2 : config.imageSizeDallE3;
response = postImageCreationRequestToOpenAI(textUTF_8, config.imageModel, imageSize, config.openAiApiKey);
if (response == NULL) {
displayError("Error connecting. Please try again.");
SetGadgetAttrs(createImageButton, mainWindow, NULL, GA_Disabled, FALSE, TAG_DONE);
SetGadgetAttrs(newImageButton, mainWindow, NULL, GA_Disabled, FALSE, TAG_DONE);
SetGadgetAttrs(deleteImageButton, mainWindow, NULL, GA_Disabled, FALSE, TAG_DONE);
SetGadgetAttrs(textInputTextEditor, mainWindow, NULL, GA_Disabled, FALSE, TAG_DONE);
updateStatusBar("Error", 6);
return;
}
struct json_object *error;

if (json_object_object_get_ex(response, "error", &error)) {
Expand All @@ -3011,15 +3035,11 @@ static void createImage() {
SetGadgetAttrs(textInputTextEditor, mainWindow, NULL, GA_TEXTEDITOR_Contents, text, TAG_DONE);
json_object_put(response);
SetGadgetAttrs(createImageButton, mainWindow, NULL, GA_Disabled, FALSE, TAG_DONE);
SetGadgetAttrs(openSmallImageButton, mainWindow, NULL, GA_Disabled, FALSE, TAG_DONE);
SetGadgetAttrs(openMediumImageButton, mainWindow, NULL, GA_Disabled, FALSE, TAG_DONE);
SetGadgetAttrs(openLargeImageButton, mainWindow, NULL, GA_Disabled, FALSE, TAG_DONE);
SetGadgetAttrs(openOriginalImageButton, mainWindow, NULL, GA_Disabled, FALSE, TAG_DONE);
SetGadgetAttrs(saveCopyButton, mainWindow, NULL, GA_Disabled, FALSE, TAG_DONE);
SetGadgetAttrs(newImageButton, mainWindow, NULL, GA_Disabled, FALSE, TAG_DONE);
SetGadgetAttrs(deleteImageButton, mainWindow, NULL, GA_Disabled, FALSE, TAG_DONE);
SetGadgetAttrs(textInputTextEditor, mainWindow, NULL, GA_Disabled, FALSE, TAG_DONE);
updateStatusBar("Ready", 5);
updateStatusBar("Error", 6);
json_object_put(response);
return;
}

Expand Down Expand Up @@ -3080,7 +3100,10 @@ static void createImage() {
struct json_object **responses = postChatMessageToOpenAI(imageNameConversation, config.chatModel, config.openAiApiKey, FALSE);

struct GeneratedImage *generatedImage = AllocVec(sizeof(struct GeneratedImage), MEMF_ANY);
if (responses[0] != NULL) {
if (responses == NULL) {
displayError("Failed to generate image name. Using ID instead.");
updateStatusBar("Error", 6);
} else if (responses[0] != NULL) {
STRPTR responseString = getMessageContentFromJson(responses[0], FALSE);
formatText(responseString);
generatedImage->name = AllocVec(strlen(responseString) + 1, MEMF_ANY | MEMF_CLEAR);
Expand Down
20 changes: 20 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include "gui.h"
#include "config.h"

CONST_STRPTR stack = "$STACK: 32768";

#ifdef __AMIGAOS4__
struct Library *ApplicationBase;
extern struct ExecIFace *IExec;
Expand Down Expand Up @@ -70,6 +72,24 @@ LONG main(int argc, char **argv) {
#endif
readConfig();

ULONG *upper, *lower, total;
struct Task *task = FindTask(NULL);

// For CLI tasks, stack bounds are determined differently
if (((struct Process *)task)->pr_CLI) {
upper = (ULONG *)((struct Process *)task)->pr_ReturnAddr + sizeof(ULONG);
total = *(ULONG *)((struct Process *)task)->pr_ReturnAddr;
lower = upper - total;
} else {
upper = (ULONG *)((struct Process *)task)->pr_Task.tc_SPUpper;
lower = (ULONG *)((struct Process *)task)->pr_Task.tc_SPLower;
total = upper - lower;
}

if (total < 32768) {
printf("Warning: The stack size is too small. Please increase it to at least 32768 bytes to avoid crashes.\n");
}

if (initVideo() == RETURN_ERROR) {
printf("Failed to initialize video\n");
cleanExit(RETURN_ERROR);
Expand Down
6 changes: 3 additions & 3 deletions src/openai.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ static ULONG createSSLConnection(CONST_STRPTR host, UWORD port) {
* @param model the model to use
* @param openAiApiKey the OpenAI API key
* @param stream whether to stream the response or not
* @return a pointer to a new array of json_object containing the response(s) -- Free it with json_object_put() for all responses then FreeVec() for the array when you are done using it
* @return a pointer to a new array of json_object containing the response(s) or NULL -- Free it with json_object_put() for all responses then FreeVec() for the array when you are done using it
**/
struct json_object** postChatMessageToOpenAI(struct MinList *conversation, enum Model model, CONST_STRPTR openAiApiKey, BOOL stream) {
struct json_object **responses = AllocVec(sizeof(struct json_object *) * RESPONSE_ARRAY_BUFFER_LENGTH, MEMF_ANY | MEMF_CLEAR);
Expand Down Expand Up @@ -504,7 +504,7 @@ struct json_object** postChatMessageToOpenAI(struct MinList *conversation, enum
* @param imageModel the image model to use
* @param imageSize the size of the image to create
* @param openAiApiKey the OpenAI API key
* @return a pointer to a new json_object containing the response -- Free it with json_object_put when you are done using it
* @return a pointer to a new json_object containing the response or NULL -- Free it with json_object_put when you are done using it
**/
struct json_object* postImageCreationRequestToOpenAI(CONST_STRPTR prompt, enum ImageModel imageModel, enum ImageSize ImageSize, CONST_STRPTR openAiApiKey) {
struct json_object *response;
Expand All @@ -522,7 +522,7 @@ struct json_object* postImageCreationRequestToOpenAI(CONST_STRPTR prompt, enum I
json_object_object_add(obj, "model", json_object_new_string(IMAGE_MODEL_NAMES[imageModel]));
json_object_object_add(obj, "prompt", json_object_new_string(prompt));
json_object_object_add(obj, "size", json_object_new_string(IMAGE_SIZE_NAMES[ImageSize]));
STRPTR jsonString = json_object_to_json_string(obj);
CONST_STRPTR jsonString = json_object_to_json_string(obj);

snprintf(writeBuffer, WRITE_BUFFER_LENGTH, "POST /v1/images/generations HTTP/1.1\r\n"
"Host: api.openai.com\r\n"
Expand Down
4 changes: 2 additions & 2 deletions src/openai.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ LONG initOpenAIConnector();
* @param model the model to use
* @param openAiApiKey the OpenAI API key
* @param stream whether to stream the response or not
* @return a pointer to a new array of json_object containing the response(s) -- Free it with json_object_put() for all responses then FreeVec() for the array when you are done using it
* @return a pointer to a new array of json_object containing the response(s) or NULL -- Free it with json_object_put() for all responses then FreeVec() for the array when you are done using it
**/
struct json_object** postChatMessageToOpenAI(struct MinList *conversation, enum Model model, CONST_STRPTR openAiApiKey, BOOL stream);

Expand All @@ -97,7 +97,7 @@ struct json_object** postChatMessageToOpenAI(struct MinList *conversation, enum
* @param imageModel the image model to use
* @param imageSize the size of the image to create
* @param openAiApiKey the OpenAI API key
* @return a pointer to a new json_object containing the response -- Free it with json_object_put when you are done using it
* @return a pointer to a new json_object containing the response or NULL -- Free it with json_object_put when you are done using it
**/
struct json_object* postImageCreationRequestToOpenAI(CONST_STRPTR prompt, enum ImageModel imageModel, enum ImageSize ImageSize, CONST_STRPTR openAiApiKey);

Expand Down
2 changes: 1 addition & 1 deletion src/version.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#define APP_VERSION "1.4.3"
#define BUILD_NUMBER "2720"
#define BUILD_NUMBER "2730"
#define APP_NAME "AmigaGPT"

0 comments on commit 701c9e8

Please sign in to comment.