Wikifiction.ai Case Study - Pt 5
Improving system integration and preparing for a new launch.
Table of Contents:
Introduction:
After six months of active development and feature additions, I felt it was time to share what I’ve been working on. Driven by the need to determine if wikifiction.ai was feasible beyond a pet project, I needed to reach a second MVP. ?By the middle of July, I was posting daily on three social media accounts to build a backlog of content. With many of the new features in place and functioning as intended, it was time to focus on final modifications to the application before considering a second public release. This period marked a shift from adding features to refining and optimizing existing ones, ensuring the app was not just functional but reasonably bug-free and user-friendly. My aim was to address several key areas, including the demo mode, system integration, and backend improvements to achieve this second MVP.
Challenges:
It is safe to say that this entire phase revolved primarily around a single challenge: integrating the creator subdomain with the larger MediaWiki site. Until this point, the primary interface a user had with wikifiction.ai was on a subdomain where the Lambda scripts were kicked off. Integrating the creator with the MediaWiki site was what I had my sights set on, which required learning an entirely new skill set yet again, consisting of JavaScript, PHP, and CSS.
Decisions:
There were two major decisions in this phase, beginning with the decision to restructure the credit system. While I still didn’t know if the site could support itself financially, I needed to be realistic that with all the other options available in AI, there was not a compelling reason for a user to purchase credits to create content on wikifiction.ai. This led to the decision to strip out the half-baked credit system I had in place, as well as to remove the 24-hour limit on the demo mode. As a last-ditch effort to maintain some semblance of ability to sustain itself, I decided to include a way for users to donate. To service this, I selected buymeacoffee.com as it seemed the simplest to set up.
The second, and more challenging, decision was to attempt to integrate the site using a custom MediaWiki skin. Despite my initial hesitation, I chose to develop this custom skin to provide a consistent look and feel for the user. A majority of the creator subdomain was simply navigation and modal elements for user flows. These modal elements are similar to pop-ups, as they appear over the main content of a page to guide users through tasks without leaving the page. Both navigation and modal elements would fit nicely into a custom skin. The only real page content outside of this was the input form for the creation prompt, which could be handled as a custom MediaWiki page.
A third desire I had was to enhance my logging capabilities. After so many months, there were many new AI models that I had implemented, all of which had different costs associated with them. Up until this point I was tracking these costs by hardcoding the math directly into each API call to maintain an accurate log of costs, but this was not a proper solution that could stand up for long as the site continued to grow in complexity. I decided to invest time into building helper scripts that were solely dedicated to communicating with AI models and calculating their costs, as well as calculating the costs of various AWS elements being used such as Lambda itself. By abstracting the cost calculations into a single helper script, I only needed to make one update whenever model prices changed, which significantly streamlined the process.
Additionally, while I had a way to quickly remove problematic articles from the site, I lacked a way to reinstate them. I decided that having a reinstatement script was a requirement for the next MVP.
Solutions:
Building a custom skin for MediaWiki was a challenge I had been avoiding for months. I always had it in my mind that I wanted to consolidate the creator with MediaWiki, but up until this point I had assumed I wouldn’t embark on that journey until I knew the project could support itself. I knew that at minimum I wanted to remove the 24-hour limit on the demo mode, and I wanted to remove the half-baked solution I had for implementing a credit system that allowed users to purchase balance for creating longer articles. Pulling out the unused credit system was very simple as far as coding went. In fact, it helped clean up my code quite a bit. Implementing the donation model was a bit trickier. The site I used to accept donations, buymeacoffee.com, has a webhook system that allows me to call an endpoint on my domain when a donation occurs. I use this not only to send a thank you email but also to track who donated and when. Based on this information, I am able to prompt users to donate with a pop-up, as well as preventing that pop-up for users who have donated within a recent period of time.
To create the custom MediaWiki skin, I developed a solution relying on a combination of custom pages, a custom wikifiction.ai extension, and a custom skin based off the standard Vector skin. I will not go into details on how this was implemented as it entailed essentially rebuilding my frontend in PHP, JavaScript, and CSS. Needless to say, it was a large challenge for me without a strong background in these technologies, and even though the custom skin is implemented I still have several JavaScript conflicts. These conflicts forced me to leave certain elements as iframes that still utilize the flutter implementation.
The smaller tasks were much more straightforward and in line with the knowledge I had gained to this point. Adding a proper logging system with separate helper scripts was a delicate process, but now all API calls to generative AI engines go through a helper script that determines which model is being used and modifies the queries appropriately. It also captures feedback about the API call and calculates associated costs accordingly. A second helper script is used to calculate the cost of AWS resources, although it is not comprehensive as some services have pricing models complex enough that the development effort outweighed the benefit. Lastly, I built a script to reinstate pages that had previously been removed. This was very straightforward, with the only challenge being to ensure duplicate titles were assigned a new URL appropriately.
New Tools Used:
Reflections:
The refinements to the user experience in this phase made me feel much more comfortable sharing the site publicly. The logging additions also made me more comfortable in being able to track expenses to ensure I have appropriate details to review in the future when analyzing where expenses were and what optimizations to focus on.
The decision to develop new skills in JavaScript, PHP, and CSS was both challenging and rewarding. Despite the difficulties, the successful implementation of the MediaWiki skin led me to a broader understanding of the development landscape. PHP, CSS, and JavaScript are all still heavily used in today’s web landscape. According to w3techs.com, as of today, JavaScript and CSS are used in over 95% of websites, and PHP is used in over 75%.
Conclusion:
By the beginning of September 2024, after about eight months of development, wikifiction.ai was ready for its second MVP release. The successful integration of the demo mode, the custom MediaWiki skin, and the enhanced logging system prepared the site for a more thorough feasibility test.
Looking back, it's been a challenging yet rewarding process of trial and error, and learning. I’ve constantly been out of my comfort zone and learning new skills including backend development, frontend development, working with generative AI, serverless cloud architecture, and more. Each phase of development brought a unique set of obstacles and opportunities to reassess the project’s direction.
The coming months will reveal whether wikifiction.ai can transition from a passion project to a sustainable platform. Whether it finds a dedicated user base or remains an experiment in what I consider early-stage LLMs, I’ve already gained invaluable experience that will shape my approach for future endeavors.
Whatever comes next, I'm thankful for the experience and excited to see where it leads. Thank you for taking the time to follow my journey. I hope you found something valuable along the way.
December Addendum:
It has been two months since these articles were drafted, and I feel it’s only right to fully wrap this up with a note on a few changes that have happened since. A majority of this time was spent on three items: Writing these articles, learning how to make a promotional video, and another semi-annual trip home for the holiday season. There were, however, a handful of smaller changes made to the site itself.
To support multiple languages for the short story generator, I needed to ensure three components supported each language – the text generator needed to recognize the desired language, the text-to-speech tool required at least one compatible voice, and FFMPEG, the multimedia framework used for backend processing, had to support the language’s script. The short stories can now be generated, voiced, and captioned in 15 languages including English. The trickiest part of this process was finding and storing language-specific fonts in S3 and loading them as needed.
Integrating the remaining front-end pages into MediaWiki was a challenging process. Managing multiple JS scripts was particularly difficult, as I struggled to configure the MediaWiki ResourceLoader to ensure they loaded in the correct order and only after the Document Object Model (DOM) was fully loaded. Despite these difficulties, removing the iframes from the site was a significant improvement as the iframes had introduced a couple negative user experiences, such as occasional problems with focus when users alt-tabbed to the site.
An ongoing issue I’ve had with audio quality is that the more I manipulate audio clips with FFMPEG, the more likely distortion or degraded audio creeps in. Converting MP3 files to Opus format proved helpful in reducing this distortion. I applied this conversion to the function that caused the most significant quality issues - speeding up audio as needed to ensure videos don’t extend beyond 90 seconds. This made a noticeable improvement, and in the future I plan to refactor the code to apply this change more broadly.