Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create & manage LanguageModels and APIService (+add Llama 3) #389

Merged
merged 72 commits into from
Jun 24, 2024

Conversation

stephan-buckmaster
Copy link
Contributor

@stephan-buckmaster stephan-buckmaster commented Jun 5, 2024

This PR builds on #334 which introduced the ability to add new Assistants

This continues #385 (closed) My last comment there, #385 (comment) (@krschacht)

This PR:

  • Adds LanguageModels
  • Adds APIService
  • Populates an OpenAI and Anthropic APIService for all existing users along with the corresponding LanguageModels
  • Adds on the UI work in /settings to manage these new models
  • Pre-populates Groq & Llama 3 as a new default model
  • Lots of test coverage for all of this

Copy link
Contributor

@krschacht krschacht left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just did a quick skim through this and flagged a few small items that I noticed.

To reply to your other comment:

Thanks for the feedback.

It's a good point that it looks heavy, that language models and API services are separated. Indeed I had them combined initially. Then I looked at the database schema and it wasn't normalized; then I used the app the next day and it was annoying to look up the port and access token. So once one has a API server setup I think it's natural to have that reflected in one database table, and one UI section. Its often effort to locate the access-token (again)

I also agree they should be separate. My comment was slightly different. I was proposing we do keep them the same, but currently you edit an Assistant and you assign a LanguageModel and an API. I was proposing instead that from Assistant you just assign a LanguageModel, and then you edit a LanguageModel to assign it to an API. But APIs would still be their own entities and they would each of their own section within the Settings and you could still assign multiple LanguageModels to the same API so you wouldn’t have to keep specifying the port & token repeatedly.

I feel the assistants should not be as prominent, get that much space.

Yea, after I saw your two new sections it made me realize that Assistants should just be a top-level menu item and then clicking that would list the individual assistants. Eventually it won’t make sense to show all the assistants in the left side, in the settings.

In terms of the display you suggest, I'll work on item 1,3.

Item 2: So you're saying instead of cards, just have in effect, a paragraph, per entry. Then an Edit link if applicable.

I was proposing to just have a row per entry and then either an “Edit” link on the row or maybe the whole row is just clickable.

Item 4: The "system" entries (have user_id=NULL) wouldn't be editable by any user, in my mind. So they wouldn't get shown in a form.

Oh, yes. Good point. I guess I would propose then: when you click on a system entry, it’s a show page (no form, no edit link anywhere). And when you click on a user one then it takes you to the form, and clicking save on the form just refreshes and keeps you on the form. I don’t think we need to toggle back & forth between an edit & show for user ones.

The one issue I’m aware of with this approach is that the top-right corner toast notification which says “Saved” is not quite prominent enough. I’ve observed people click save and not realize it saved. I plan to move that to the center of the screen and have it slide in a more visually prominent way.

@@ -0,0 +1,5 @@
class AddAPIServiceIdToAssistants < ActiveRecord::Migration[7.1]
def change
add_column :assistants, :api_service_id, :bigint, null: true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should do this as an add_reference so it knows it’s a foreign key. That adds the DB constraint.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

app/models/api_service.rb Outdated Show resolved Hide resolved
app/models/user.rb Outdated Show resolved Hide resolved
db/schema.rb Show resolved Hide resolved
@krschacht
Copy link
Contributor

@stephan-buckmaster Recent changes of mine created some new conflicts on this branch. Let me know if you want help resolving those; I can take a pass at it. I was just about to do it but I stopped myself b/c I don't want to push a commit to your branch and risk colliding with you. Just let me know if you want help with those conflicts.

@stephan-buckmaster
Copy link
Contributor Author

The merge conflicts look managable. I'll let you know, @krschacht

@stephan-buckmaster
Copy link
Contributor Author

I believe I got through all your suggestions @krschacht.

Still no tests (there's a few harmless failures).
Let me know if you see anything off, while I work on those ...

@krschacht
Copy link
Contributor

krschacht commented Jun 24, 2024

@stephan-buckmaster I did a full pass through the PR today and I think it's ready to merge in. I made some changes locally as I was reviewing and just pushed up a big commit ("Final pass changes") that blends them all. Here are my notes, just in case you're curious:

  • Made controllers actions all redirect back to index
  • Changed how settings nav links are rendered (using the settings/application_controller ivar)
  • Remove the custom .delete! methods since we have a built-in .deleted! one already
  • Renamed language_models.description to language_models.name
  • Added back the API key instructions to the new form
  • Changed api_service.driver to be an enum field (active record gives you a .keys method for free to get an array of all possibilities)
  • Moved the create_without_validations back to the migration since it's really a one-time thing
  • Updated a few places we need to use .effective_token rather than .token
  • Made some visual little changes to the new settings sections (headers, links, etc)

Oh, and you had a driver called "Built On" on the API Services, what was that? I think the user should have to select openai or anthropic, right? I removed it but I can revert if I'm mistaken.

I really think it's ready for me to click "merge", but just since I've been staring at this for a few hours I'll do a user-facing run-through one more time tomorrow before and then click merge in the morning. I don't like to merge into main before calling it a night. :)

Oh, the one thing I haven't done is actually create a Grok account and try adding Llama3 myself! I'll give that a try tomorrow.

@krschacht krschacht changed the title Continued support for open LLMs: adding APIService model Create & manage LanguageModels and APIService (+add Llama 3) Jun 24, 2024
@krschacht krschacht merged commit a67433f into AllYourBot:main Jun 24, 2024
6 checks passed
@krschacht
Copy link
Contributor

krschacht commented Jun 24, 2024

@stephan-buckmaster And it's merged! Whew. This project was quite a big lift.

Today I tried adding Llama 3 myself, through Groq, and fixed a couple small bugs with that. It works so well that I went ahead and made Llama3 a new default within the app and pre-created Groq for people (alongside OpenAI and Anthropic).

A few loose ends that I want to capture while it's top of mind:

  1. I'm going to do some more UI work on the settings section of the app
  2. When creating a new language model, you had a driver called "built on". Do we need this option? I removed it but I want to confirm that I didn't break something.
  3. As I was playing with Groq I realized that the LanguageModel model should probably also have token_limit (for input) and supports_tools (boolean) since the AI backend should also consider these properties
  4. You left a comment in another thread about adding new APIs via migrations. I agree this feels quite hacky. Do you have any better ideas? I just did it again with the Llama 3 addition.
  5. Within this PR we just merged in I went ahead and left the self.create_without_validation method in LanguageModel. I saw you fixed up a couple bugs yesterday after my big commit so thank you for that. Could we move it back into the migration? I didn't quite understand why it broke when I tried to move it back there.

@krschacht
Copy link
Contributor

@stephan-buckmaster You might appreciate hearing this: after upgrading my personal server to this latest PR, my APIs stopped working. I checked the API keys and they were copied over incorrectly. user.openai_key got copied over as {"p":"Qhq8i6vTyEoEUzqwmcbBQkj6ut/LUvZhdPbIQvR7wcmYq0cMKIshZFN4ufHwSR9KxntMnMBNbYrPGUXxRMU8IZb8iinEH6lhBBN7r0y46kmCDfktc6uc1sE+GLSjBkf6cfSgUJAJz6v+2K9u","h":{"iv":"AOUUAmbvsuDZMUFJ","at":"gHCXP8+k0tpyaoRuPWtzKA=="}}

I've been digging in for the last couple hours trying to figure out what happened. I realized quickly that this is the raw database value in it's encrypted form (user has encrypts :openai_key) and I got stuck thinking this was a migration issue, like maybe DB encryption wasn't enabled in migrations because of a rails initialization issue.

Finally, I realized that we removed encrypts :openai_key from the User table in this same PR which does the migration to copy that value over! This was the fix I just committed:

4764a7b

Lesson learned! I don't have a ton of experience thinking about encrypted database contents so this was a new one to me.

One reflection I've had on this whole PR is that it probably would have been worth us merging it in as several PRs along the way. However, the challenge with that is that all of the pieces were really tightly coupled together and the whole architecture was a bit in flux at each stage of the game. Maybe once we had really settled on the scope and had a big PR with lots of work, it probably would have been worth breaking off pieces at a time and landing them. One PR could have just added the models and populated the data, without all the views and the integration with AI backend. Then another one could update the views. Etc. Not a big deal, we got it done either way, but just an interesting reflection.

@stephan-buckmaster
Copy link
Contributor Author

  1. Ok
  2. About "Built-in." That is obsolete because we assigned them directly now
  3. Ok, not something I am familiar with
  4. I feel users can configure their own, just need to know what to do when a new model comes out. They have so many options now. E.g. They can have "OpenAI cheap" "OpenAI premium" .... then when prices change assign what works.
  5. Sure, it can go back, it is used in two migrations though, so doesn't look good

About the encryption -- that is quite something, I tried it out, and found now problem, and then deleted the "encrypts" on User.

The feature seemed easier to begin with, then became larger. It might be good to plan features in more detail prior to implemenation.

One nice thing to add here would be a "check connection" button for API Services, because that can be difficult to know from the outside.

@krschacht
Copy link
Contributor

Great! I handled the migration cleanup. I need to think more about how to help people upgrade/add new LLM models. I would like it to be a little more automated than that since not everyone keeps on top of every AI's companies latest announcements like we probably do. :) I've been thinking about some other mechanism within the app to announce new features so maybe it's related to that. I may setup some managed endpoint that I run, which every instance of the open source app can hit in order to get "announcements" which get displayed in some small, clean way in the UI. I'll keep thinking.

Good point about the "check connection" button.

I went ahead and created tasks for all of these things so I can keep track things:
https://github.com/AllYourBot/hostedgpt/issues?q=sort%3Aupdated-desc+is%3Aopen+label%3A%22LLM+foundation%22

I'm probably going to tackle function/tool calling next since I've been actively working in that area anyway. If you want to take on any of these, just let me know! I know you're traveling and have contributed a lot so no pressure, I just wanted to keep you in the loop.

ceicke pushed a commit to ceicke/hostedgpt that referenced this pull request Jun 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants