Empowering Creative Writing with AI: An Introduction to the Cloudflare AI Challenge Markdown Editor
Tags: cloudflarechallenge, devchallenge, ai, webdev
Published: 2024-04-14 19:59:51

*This is a submission for the [Cloudflare AI Challenge](https://dev.to/devteam/join-us-for-the-cloudflare-ai-challenge-3000-in-prizes-5f99).*

## What I Built

I built tool to allow write your posts with AI assistance. Genuinely it's basic markdown editor, but with handful AI tools around it!

- AI assistant - chat with AI, ask about anything, you can select preferred model
- AI title generator - generating propose of title based on your text summary
- AI cover generator - generating propose of cover based on your text summary 

I tried it myself, and creating titles or covers from my post is handy! 🤓

What's crucial is that I wanted to avoid creating an app for generating posts, instead, I aim to encourage people to write on their own. **Let's be pilots, and keep AI as co-pilot.**

## Demo

[Link to app](pokemon-guess.pages.dev)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/26pf3mel47ieij0srcqt.png)



## My Code

{% embed https://github.com/pavelee/cloudflare-challange-post-ai %}

## Journey

It was really full of fun project! 🥳

AI apps still have some magic within! 🤓

I am quite impressed with Cloudflare for releasing such an excellent feature, using models is pretty easy. The documentation is clear 👏

I deployed app on Cloudflare Pages. Typically I use Vercel could 😅, but I wanted to give it a try. Deploying was pretty ok, with some troubles. After reading docs I was able to deploy Next.js to Pages 👏 Cool! 😎

My first problem was storage 💾, my goal was to allow user keep their work and chat history. Firstly I thought to use supabase but I noticed that Cloudflare has a KV! KV is a simple key-value storage. Great for this kind of an app! 🤓 

My second problem was data structure. I needed nested object, called "project" 🫣 and KV is flat 🌏 storage. Solution was to storage it as a JSON! 😅 Not an optimal way but it is a pretty enough to develop the app!

My third problem was generating title for the post. I couldn't pass the whole text to "text generation" model because it was too huge 🫣. Solution was to use "summary model" as a proxy! 🤓

What I proud of 

- I was able to host the whole project on Cloudflare infrastructure! 👏
- storage configuration

I created interface: 

```js
export interface Storage<T> {
  get: (key: string) => Promise<T>;
  set: (key: string, value: string) => Promise<void>;
  remove: (key: string) => Promise<void>;
}
```

then I implemented "KVStorage" and configured it inside the config file

```js
import { KVStorage } from "../util/storage/KVStorage";
import { Storage } from "../util/storage/Storage";

const cloudfrareKey = process.env.CLOUDDLARE_KV_API_KEY;
const cfAccountId = process.env.CLOUDFLARE_ACCOUNT_ID;
const cloudflareKvNamespaceId = process.env.CLOUDFLARE_KV_NAMESPACE_ID;

if (!cloudfrareKey || !cfAccountId || !cloudflareKvNamespaceId) {
  throw new Error("Cloudflare key or account ID is missing");
}

export const storage: Storage<string> = new KVStorage<string>(
  cfAccountId,
  cloudflareKvNamespaceId,
  cloudfrareKey
);
```

In the app I am using storage object that implement interface so you can easily change to other storage! 🥳

**Multiple Models and/or Triple Task Types**

### AI Assistant

Based on text generation models, user can choose from:

- meta/llama-2-7b-chat-fp16
- thebloke/openhermes-2.5-mistral-7b-awq
- mistral/mistral-7b-instruct-v0.1
- tiiuae/falcon-7b-instruct
- google/gemma-2b-it-lora
- nousresearch/hermes-2-pro-mistral-7b
- thebloke/llama-2-13b-chat-awq
- qwen/qwen1.5-14b-chat-awq

### AI Title Generator

First I use "bart-large-cnn" to summary text:

- facebook/bart-large-cnn

Then I use "nousresearch/hermes-2-pro-mistral-7b" to generate title

### AI Cover Generator

First I use "bart-large-cnn" to summary text:

- facebook/bart-large-cnn

then user can use one of models:

- lykon/dreamshaper-8-lcm
- runwayml/stable-diffusion-v1-5-img2img
- runwayml/stable-diffusion-v1-5-inpainting
- stabilityai/stable-diffusion-xl-base-1.0
- bytedance/stable-diffusion-xl-lightning