Skip to content

Add backend support for generating descriptions through AI

Donald Cook requested to merge dc/experiment-to-markdown into master

What does this MR do and why?

Fill out selected template with provided content.

Backend for https://gitlab.com/gitlab-org/gitlab/-/issues/406791/

How to set up and validate locally

  • Enable the feature flags

    Feature.enable(:openai_experimentation)
    Feature.enable(:generate_description)
  • graphql query 1 - with existing template:

mutation {
  aiAction(input: {
    generateDescription: {
      resourceId: "gid://gitlab/Issue/82111", 
      content: "Explain how a rabbit fits into a magician's hat",
      descriptionTemplateName: "bug"
    }
  })
  {
    clientMutationId
  }
}
template
<!---
Please read this!

Before opening a new issue, make sure to search for keywords in the issues
filtered by the "regression" or "type::bug" label:

- https://gitlab.com/gitlab-org/gitlab/issues?label_name%5B%5D=regression
- https://gitlab.com/gitlab-org/gitlab/issues?label_name%5B%5D=type::bug

and verify the issue you're about to submit isn't a duplicate.
--->

### Summary

<!-- Summarize the bug encountered concisely. -->

### Steps to reproduce

<!-- Describe how one can reproduce the issue - this is very important. Please use an ordered list. -->

### Example Project

<!-- If possible, please create an example project here on GitLab.com that exhibits the problematic 
behavior, and link to it here in the bug report. If you are using an older version of GitLab, this 
will also determine whether the bug is fixed in a more recent version. -->

### What is the current *bug* behavior?

<!-- Describe what actually happens. -->

### What is the expected *correct* behavior?

<!-- Describe what you should see instead. -->

### Relevant logs and/or screenshots

<!-- Paste any relevant logs - please use code blocks (```) to format console output, logs, and code
 as it's tough to read otherwise. -->

### Output of checks

<!-- If you are reporting a bug on GitLab.com, uncomment below -->

<!-- This bug happens on GitLab.com -->
<!-- /label ~"reproduced on GitLab.com" -->

#### Results of GitLab environment info

<!--  Input any relevant GitLab environment information if needed. -->

<details>
<summary>Expand for output related to GitLab environment info</summary>

<pre>

(For installations with omnibus-gitlab package run and paste the output of:
`sudo gitlab-rake gitlab:env:info`)

(For installations from source run and paste the output of:
`sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production`)

</pre>
</details>

#### Results of GitLab application Check

<!--  Input any relevant GitLab application check information if needed. -->

<details>
<summary>Expand for output related to the GitLab application check</summary>
<pre>

(For installations with omnibus-gitlab package run and paste the output of:
`sudo gitlab-rake gitlab:check SANITIZE=true`)

(For installations from source run and paste the output of:
`sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production SANITIZE=true`)

(we will only investigate if the tests are passing)

</pre>
</details>

### Possible fixes

<!-- If you can, link to the line of code that might be responsible for the problem. -->

/label ~"type::bug"
  • In the rails-background-jobs log the job is enqueued
2023-05-02_17:14:33.44053 rails-background-jobs : {"severity":"INFO","time":"2023-05-02T17:14:33.439Z","retry":25,"queue":"default","backtrace":true,"version":0,"args":["1","82111","[FILTERED]","[FILTERED]","[FILTERED]"],"class":"Llm::CompletionWorker","jid":"62a3b4b3b15a1ebd5b49c359","created_at":"2023-05-02T17:14:33.435Z","correlation_id":"01GZEQAVFFT2X72753ZPSR4ATC","meta.caller_id":"graphql:unknown","meta.remote_ip":"127.0.0.1","meta.feature_category":"team_planning","meta.user":"root","meta.user_id":1,"meta.client_id":"user/1","meta.root_caller_id":"graphql:unknown","worker_data_consistency":"delayed","wal_locations":{},"wal_location_source":"primary","idempotency_key":"resque:gitlab:duplicate:default:a1ce38bcba0a4ae7bf8e6d70428f6ca4884522eff97c45a4cfd75c60ab1f4a92","size_limiter":"validated","enqueued_at":"2023-05-02T17:14:33.438Z","job_size_bytes":124,"pid":48121,"message":"Llm::CompletionWorker JID-62a3b4b3b15a1ebd5b49c359: start","job_status":"start","scheduling_latency_s":0.000756}
  • rails-background-jobs log worker completed:
2023-05-02_17:14:54.71929 rails-background-jobs : {"severity":"INFO","time":"2023-05-02T17:14:54.718Z","retry":25,"queue":"default","backtrace":true,"version":0,"args":["1","82111","[FILTERED]","[FILTERED]","[FILTERED]"],"class":"Llm::CompletionWorker","jid":"62a3b4b3b15a1ebd5b49c359","created_at":"2023-05-02T17:14:33.435Z","correlation_id":"01GZEQAVFFT2X72753ZPSR4ATC","meta.caller_id":"graphql:unknown","meta.remote_ip":"127.0.0.1","meta.feature_category":"team_planning","meta.user":"root","meta.user_id":1,"meta.client_id":"user/1","meta.root_caller_id":"graphql:unknown","worker_data_consistency":"delayed","wal_locations":{},"wal_location_source":"primary","idempotency_key":"resque:gitlab:duplicate:default:a1ce38bcba0a4ae7bf8e6d70428f6ca4884522eff97c45a4cfd75c60ab1f4a92","size_limiter":"validated","enqueued_at":"2023-05-02T17:14:33.438Z","job_size_bytes":124,"pid":48121,"message":"Llm::CompletionWorker JID-62a3b4b3b15a1ebd5b49c359: done: 21.279749 sec","job_status":"done","scheduling_latency_s":0.000756,"redis_calls":14,"redis_duration_s":0.0017879999999999999,"redis_read_bytes":1234,"redis_write_bytes":3273,"redis_cache_calls":10,"redis_cache_duration_s":0.000881,"redis_cache_read_bytes":1229,"redis_cache_write_bytes":1057,"redis_queues_calls":2,"redis_queues_duration_s":0.000115,"redis_queues_read_bytes":2,"redis_queues_write_bytes":186,"redis_action_cable_calls":2,"redis_action_cable_duration_s":0.000792,"redis_action_cable_read_bytes":3,"redis_action_cable_write_bytes":2030,"db_count":9,"db_write_count":0,"db_cached_count":1,"db_replica_count":0,"db_primary_count":9,"db_main_count":9,"db_ci_count":0,"db_main_replica_count":0,"db_ci_replica_count":0,"db_replica_cached_count":0,"db_primary_cached_count":1,"db_main_cached_count":1,"db_ci_cached_count":0,"db_main_replica_cached_count":0,"db_ci_replica_cached_count":0,"db_replica_wal_count":0,"db_primary_wal_count":0,"db_main_wal_count":0,"db_ci_wal_count":0,"db_main_replica_wal_count":0,"db_ci_replica_wal_count":0,"db_replica_wal_cached_count":0,"db_primary_wal_cached_count":0,"db_main_wal_cached_count":0,"db_ci_wal_cached_count":0,"db_main_replica_wal_cached_count":0,"db_ci_replica_wal_cached_count":0,"db_replica_duration_s":0.0,"db_primary_duration_s":0.01,"db_main_duration_s":0.01,"db_ci_duration_s":0.0,"db_main_replica_duration_s":0.0,"db_ci_replica_duration_s":0.0,"external_http_count":1,"external_http_duration_s":20.159373000000414,"external_http_slow_requests":[{"method":"POST","host":"api.openai.com","port":443,"path":"/v1/chat/completions","duration_s":20.159}],"cpu_s":0.989524,"worker_id":"sidekiq_0","rate_limiting_gates":[],"duration_s":21.279749,"completed_at":"2023-05-02T17:14:54.718Z","load_balancing_strategy":"primary_no_wal","db_duration_s":0.035414}
  • development log, action cable broadcast:
[ActionCable] Broadcasting to graphql-event::aiCompletionResponse:resourceId:Z2lkOi8vZ2l0bGFiL0lzc3VlLzgyMTEx:userId:Z2lkOi8vZ2l0bGFiL1VzZXIvMQ: "{\"wal_locations\":{},\"payload\":{\"id\":\"91401998-99b4-429a-a89a-4e20444daf29\",\"model_name\":\"Issue\",\"response_body\":\"Title: How a Rabbit Fits into a Magician's Hat\\n\\nIntroduction: \\nMagicians have been using rabbits in their performances for centuries. The classic trick of pulling...
Output I got for bug template
Template format:
### Summary
Explain how a rabbit fits into a magician's hat

### Steps to follow
1. The magician shows the audience an empty hat, turning it upside down to prove there's nothing inside.
2. The magician then reaches into his pocket and pulls out a rabbit.
3. The magician places the rabbit into the hat and then pulls it out again, to the amazement of the audience.
4. The trick is performed by using a false bottom in the hat. The rabbit is placed in a hidden compartment, and when the magician reaches inside the hat, he pulls out the false bottom, making it appear as if the rabbit was inside the hat all along.

### Example
N/A

### What is the current *bug* behavior?
N/A

### What is the expected *correct* behavior?
N/A

### Relevant logs and/or screenshots
N/A

### Output of checks
N/A

### Possible fixes
  • graphql query 2 - with non-existing template:
mutation {
  aiAction(input: {
    generateDescription: {
      resourceId: "gid://gitlab/Issue/82111", 
      content: "Explain how a rabbit fits into a magician's hat",
      descriptionTemplateName: "qwerty"
    }
  })
  {
    clientMutationId
  }
}
Output I got for non-existent template
Title: How a Rabbit Fits into a Magician's Hat

Introduction:
Magicians have been performing the classic "pulling a rabbit out of a hat" trick for centuries. The trick is simple in concept, but the execution requires some careful planning and preparation. In this article, we will explore how a rabbit fits into a magician's hat.

Body:
The first step in performing the trick is to choose the right type of hat. Magicians typically use a top hat or a bowler hat, as these hats have a wide brim that can conceal the rabbit. The hat should be large enough to comfortably fit the rabbit, but not so large that the audience will suspect that something is amiss.

Next, the magician will need to prepare the rabbit for the trick. This involves training the rabbit to stay calm and still while in the hat. The rabbit may also need to be fitted with a harness or some other type of restraint to prevent it from moving around too much.

When it's time to perform the trick, the magician will hold the hat in one hand and the rabbit in the other. They will then carefully place the rabbit into the hat, making sure that it is comfortable and secure. The magician will then cover the hat with a cloth or their hand to create a sense of anticipation.

Finally, the magician will dramatically pull the rabbit out of the hat, much to the delight of the audience. The rabbit will be unharmed and can be returned to its cage or carrier after the trick is over.

Conclusion:
Pulling a rabbit out of a hat is a classic magic trick that never fails to impress audiences. By carefully choosing the right hat, preparing the rabbit, and executing the trick with precision, magicians are able to create a sense of wonder and amazement that is sure to leave a lasting impression.

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Alexandru Croitor

Merge request reports