Devlog Entry #1 - Can Djot be Real?

·

6 min read

A few months ago I set out to build Djot - a subset of Djitsu, which is an app I've been working on since January 2020.

Today I've released Djot v0.4.6 which for me marks a minor maturity for Djot as a product - there is still a lot to be desired and many things planned for Djot itself, but it's becoming more stable and useful with every update since I initially released it a couple of months ago.

Now I want to start a new journey building an app inside Djot - as Djot is designed to be not just a toy to experiment with some code, but rather a fully fledged platform/framework/environment to write and launch fully featured apps (and sites), I'd like to demonstrate that by creating an actual app inside Djot - hopefully an app that is useful beyond mere demonstration for Djot.

The goal of this journey is to share the way I develop software in general, and how I use Djot to build an actual app, and hopefully get you interested in joining me in discovering Djot and helping me build it and create something awesome along the way.

Project: Djot Assistant

OpenAI recently released a new API for assistants which is awesome because ever since BabyAGI and AutoGPT came along this new tech of AIs that have access to tools and can perform actions is very enticing and its proponents see a lot of potential in it.

What I'd like to do with Project: Djot Assistant (* temporary codename for the project - feel free to suggest a different name) is to create a custom interface in which I can create and define new assistants, and use them both inside Djot to help me do whatever they'll be able to (potentially: anything you can imagine), and externally via an API (via OpenAI API or perhaps we'll release the web version of Djot and will enable a custom API end-points to access the assistants).

I'd like to outline a few basic requirements which I think I'll want to develop:

  • Ability to create new or edit existing assistants configurations

  • Ability to chat with said assistants

  • Ability to define custom tools for the assistants to use - for example navigate and interact with the local filesystem, browse the web, access external APIs

Hopefully OpenAI API will continue functioning throughout the development of this app and we won't have any further CEOs coming/going from there as migrating to a different AI api isn't currently planned - although integrating additional AIs sure'd be nice feature to have down the road.

Let's start.

Blank Slate

I'll be starting from almost entirely blank slate - this is how Djot looks like when you fire up a new Djot.

I'm saying almost blank slate becuase I have some prior art to get started from - I've toyed with OpenAI API inside Djot already and created a small Code Reviewer that you can drag files in to and it will spew it's opinion on your (in)abilities to code.

It has some basic OpenAI API integration using direct HTTPS requests (rather than using the OpenAI JS library), and it supports streaming requests (as waiting for a response via non-steraming request is really unpleasant and feels unresponsive).

So I'll be copying those and the useMemoryState hook which is just a tiny hook which allows me to use a useState like behaviour but with the added benefit that anything stored in it will persist to local storage.

🐤
Can't copy files. Can't share/import files. This is a feature that I want to integrate very soon to djot - either by providing a way to share/publish djots, or by allowing to import from the local filesystem, or potentially both. But also the ability to plainly copy and paste files from the file navigator.

Where do we begin?

Let's start with creating an assistant as dictated in the OpenAI API docs, I guess and roll from there.

Recreating OpenAI API Classes

About an hour an some into the process, and so far I've managed to start recreating the OpenAI API classes. Why? Because I don't want to bake in the OpenAI API library directly into Djot as part of its built-in dependencies, but I want to have a convenient experience using the API's and have it match as closely as possible to the official library in case I'll want to share or reuse it down the line.

🐤
Not having folders support in the file navigator is a bummer. Folders are a must ASAP I guess.

Breakdown of what's on my screen:

  • Several files are already there - as can be seen the OpenAI API classes are very prominent and currently are kind of alone

  • In the demo code area (bottom part of the window) I'm testing the in-progress API classes - the first thing I've implemented is the chat completions API, and I'm testing both streaming and non-streaming version - here you can see the non-streaming response from the OpenAI API in the right side of the screen in the demo preview area

🦆
Using the per-file Demo Code allows me to quickly write and test the functionality I'm developing - here specifically I'm using a Self Invoking Function as a result since the demo code expects a single value returned

The index.tsx (main file) currently looks like this and doesn't have much functionality or content:

Assistant created!

After tinkering a bit with the code the first assistant is created - we can see in the demo preview area the response from the OpenAI API to the request.

Now let's list the assistants to see that we have it available and the list function in our class works as expected:

Works like a charm - response from OpenAI API is as expected, and we see the previously created assistant listed (as the first and last assistent listed, as it's my first foray into ChatGPT assistants since it was announced).

Wrapping Up

For now I must wrap this up as I hear dinner being announced, and the current state with the somewhat working OpenAI API classes (despite them silently ignoring errors, which I'll have to deal with later on as it's annoying tracking them down in the devtools console).

Going further I'll want to start adding a built-in database into Djot tied to the user - this is one of the reasons I picked up this task in the first place - to keep the various settings, options, and whatever else we'll need in a Firestore collection.