Skip to content

Instantly share code, notes, and snippets.

@JogoShugh
Last active October 23, 2024 19:14
Show Gist options
  • Save JogoShugh/3f90b990477d34e478309fafb31a3bce to your computer and use it in GitHub Desktop.
Save JogoShugh/3f90b990477d34e478309fafb31a3bce to your computer and use it in GitHub Desktop.
Starborn AG Prototype

Goal

Leverage AI for building a prototype of a VUI / GUI for logging home gardening activities: planting, mulching, watering, weeding, harvesting, etc

image

Tools

  • Spring Boot with Spring AI, leveraging OpenAI's chat completions API
  • Kotlin language utilizing coroutines and an application-level CoroutineScope for background processing
  • Spring SSE Support for sending processed result events to the GUI for screen updating
  • HTMX library on the front end with its amazingly simple SSE support

Challenges

  • While the chat completions API supports the concept of Function Calling to let you send it a JSON schema of your function signatures and it attempts to produce an array of one or more "toolCalls" results, this does increase the system propmpt payload significantly, and complicates the process of parsing the streamed results.
  • Spring's SSE Emitter does not support, out of the box, 1 to N subscriptions.

Solutions

  • I utilized the Actson library found on Github for supporting parsing JSON objects "just-in-time", and calling emit with them via a Kotlin flow as soon as enough of the fragment from the overall response arrives. See this write up in Github for details so far.
  • To support a 1 to N subcriber model, I leveraged the SSE EventBus project from Github which allows this easily.
    • But, I also wanted to allow each subscriber to specify the Media Type they wanted to receive, since some programmatic subscribers will need JSON, while the GUI will just need simple plaintext or HTML fragments.
      • Began creating this PR to update SSE EventBus to leverage Spring's built in MediaType formatting support and provide an option to bypass the original custom approach in the library without breaking existing behavior.
      • See this write up for how I'm starting to use it in my project.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment