Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
fa7561fc9b
commit
f55d9f40cb
|
|
@ -1 +1 @@
|
|||
904445041c98f13f525a69d24965e32da257b58a
|
||||
aef1b75346b177cdfa96b644912e1be60696b4fd
|
||||
|
|
|
|||
|
|
@ -76,6 +76,10 @@ module Routing
|
|||
project_release_url(entity.project, entity, *args)
|
||||
end
|
||||
|
||||
def project_wiki_page_url(entity, *args)
|
||||
project_wiki_url(entity.project, entity.canonical_slug, *args)
|
||||
end
|
||||
|
||||
def edit_milestone_path(entity, *args)
|
||||
if entity.resource_parent.is_a?(Group)
|
||||
edit_group_milestone_path(entity.resource_parent, entity, *args)
|
||||
|
|
|
|||
|
|
@ -12,12 +12,12 @@ module Noteable
|
|||
class_methods do
|
||||
# `Noteable` class names that support replying to individual notes.
|
||||
def replyable_types
|
||||
%w[Issue MergeRequest AbuseReport]
|
||||
%w[Issue MergeRequest AbuseReport WikiPage::Meta]
|
||||
end
|
||||
|
||||
# `Noteable` class names that support resolvable notes.
|
||||
def resolvable_types
|
||||
%w[Issue MergeRequest DesignManagement::Design AbuseReport]
|
||||
%w[Issue MergeRequest DesignManagement::Design AbuseReport WikiPage::Meta]
|
||||
end
|
||||
|
||||
# `Noteable` class names that support creating/forwarding individual notes.
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ class DiscussionNote < Note
|
|||
|
||||
# Names of all implementers of `Noteable` that support discussions.
|
||||
def self.noteable_types
|
||||
%w[MergeRequest Issue Commit Snippet]
|
||||
%w[MergeRequest Issue Commit Snippet WikiPage::Meta]
|
||||
end
|
||||
|
||||
validates :noteable_type, inclusion: { in: noteable_types }
|
||||
|
|
|
|||
|
|
@ -361,6 +361,10 @@ class Note < ApplicationRecord
|
|||
noteable.is_a?(PersonalSnippet)
|
||||
end
|
||||
|
||||
def for_wiki_page?
|
||||
noteable_type == "WikiPage::Meta"
|
||||
end
|
||||
|
||||
def for_project_noteable?
|
||||
!(for_personal_snippet? || for_abuse_report? || group_level_issue?)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
class WikiPage
|
||||
class Meta < ApplicationRecord
|
||||
include HasWikiPageMetaAttributes
|
||||
include Mentionable
|
||||
include Noteable
|
||||
|
||||
self.table_name = 'wiki_page_meta'
|
||||
|
||||
|
|
@ -10,15 +12,14 @@ class WikiPage
|
|||
belongs_to :namespace, optional: true
|
||||
|
||||
has_many :slugs, class_name: 'WikiPage::Slug', foreign_key: 'wiki_page_meta_id', inverse_of: :wiki_page_meta
|
||||
has_many :notes, as: :noteable
|
||||
has_many :user_mentions, class_name: 'Wikis::UserMention', foreign_key: 'wiki_page_meta_id',
|
||||
inverse_of: :wiki_page_meta
|
||||
|
||||
validate :project_or_namespace_present?
|
||||
|
||||
alias_method :resource_parent, :project
|
||||
|
||||
def container_key
|
||||
namespace.present? ? :namespace_id : :project_id
|
||||
end
|
||||
|
||||
def container
|
||||
project || namespace
|
||||
end
|
||||
|
|
@ -28,6 +29,14 @@ class WikiPage
|
|||
self.namespace = value if value.is_a?(Namespace)
|
||||
end
|
||||
|
||||
def for_group_wiki?
|
||||
namespace_id.present?
|
||||
end
|
||||
|
||||
def container_key
|
||||
for_group_wiki? ? :namespace_id : :project_id
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def project_or_namespace_present?
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Wikis
|
||||
class UserMention < UserMention
|
||||
self.table_name = 'wiki_page_meta_user_mentions'
|
||||
|
||||
belongs_to :wiki_page_meta, class_name: 'WikiPage::Meta', optional: false
|
||||
belongs_to :note, optional: false
|
||||
|
||||
before_validation :set_namespace_id_from_note, on: :create
|
||||
|
||||
private
|
||||
|
||||
def set_namespace_id_from_note
|
||||
self.namespace_id ||= note&.namespace_id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -11,4 +11,4 @@ GITLAB_PATH = File.expand_path('../', __dir__)
|
|||
require_relative '../config/boot'
|
||||
require 'gitlab/backup/cli'
|
||||
|
||||
Gitlab::Backup::Cli::Runner.start(ARGV)
|
||||
Gitlab::Backup::Cli.start(ARGV)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
table_name: wiki_page_meta_user_mentions
|
||||
classes:
|
||||
- Wikis::UserMention
|
||||
feature_categories:
|
||||
- wiki
|
||||
description: User mentions in wiki page notes
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/163305
|
||||
milestone: '17.5'
|
||||
gitlab_schema: gitlab_main_cell
|
||||
sharding_key:
|
||||
namespace_id: namespaces
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# See https://docs.gitlab.com/ee/development/migration_style_guide.html
|
||||
# for more information on how to write migrations for GitLab.
|
||||
|
||||
class CreateWikiPageUserMentions < Gitlab::Database::Migration[2.2]
|
||||
enable_lock_retries!
|
||||
|
||||
milestone '17.5'
|
||||
|
||||
def up
|
||||
create_table :wiki_page_meta_user_mentions do |t| # rubocop:disable Migration/EnsureFactoryForTable -- No factory needed
|
||||
t.bigint :wiki_page_meta_id, null: false
|
||||
t.bigint :note_id, null: false
|
||||
t.bigint :namespace_id, null: false
|
||||
t.bigint :mentioned_users_ids, array: true, default: nil
|
||||
t.bigint :mentioned_projects_ids, array: true, default: nil
|
||||
t.bigint :mentioned_groups_ids, array: true, default: nil
|
||||
|
||||
t.index :note_id
|
||||
t.index :namespace_id
|
||||
t.index [:wiki_page_meta_id, :note_id],
|
||||
unique: true,
|
||||
name: :index_wiki_meta_user_mentions_on_wiki_page_meta_id_and_note_id
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
drop_table :wiki_page_meta_user_mentions, if_exists: true
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddWikiPageMetaForeignKeyToWikiPageMetaUserMentions < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.5'
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
add_concurrent_foreign_key :wiki_page_meta_user_mentions, :wiki_page_meta, column: :wiki_page_meta_id,
|
||||
on_delete: :cascade
|
||||
end
|
||||
|
||||
def down
|
||||
with_lock_retries do
|
||||
remove_foreign_key :wiki_page_meta_user_mentions, column: :wiki_page_meta_id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddNotesForeignKeyToWikiPageMetaUserMentions < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.5'
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
add_concurrent_foreign_key :wiki_page_meta_user_mentions, :notes, column: :note_id, on_delete: :cascade
|
||||
end
|
||||
|
||||
def down
|
||||
with_lock_retries do
|
||||
remove_foreign_key :wiki_page_meta_user_mentions, column: :note_id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddNamespacesForeignKeyToWikiPageMetaUserMentions < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.5'
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
add_concurrent_foreign_key :wiki_page_meta_user_mentions, :namespaces, column: :namespace_id, on_delete: :cascade
|
||||
end
|
||||
|
||||
def down
|
||||
with_lock_retries do
|
||||
remove_foreign_key :wiki_page_meta_user_mentions, column: :namespace_id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
9ee63c7a0b13f8eabca033494d551c498d8320144f6acec53b2bd6263e1b5152
|
||||
|
|
@ -0,0 +1 @@
|
|||
ec9255f62950f75064ad2cd65c9fef6a1b4c136d4bb86238b24ed567098fb28e
|
||||
|
|
@ -0,0 +1 @@
|
|||
caa78be456eebea5d9fc8cbcc0d0daa56e11f3e633f5327014702814919a073c
|
||||
|
|
@ -0,0 +1 @@
|
|||
b844c5179a55387b9c0f631a9172b7b62fae98e38d8c86532dbcac2365f8a1c7
|
||||
|
|
@ -20647,6 +20647,25 @@ CREATE SEQUENCE wiki_page_meta_id_seq
|
|||
|
||||
ALTER SEQUENCE wiki_page_meta_id_seq OWNED BY wiki_page_meta.id;
|
||||
|
||||
CREATE TABLE wiki_page_meta_user_mentions (
|
||||
id bigint NOT NULL,
|
||||
wiki_page_meta_id bigint NOT NULL,
|
||||
note_id bigint NOT NULL,
|
||||
namespace_id bigint NOT NULL,
|
||||
mentioned_users_ids bigint[],
|
||||
mentioned_projects_ids bigint[],
|
||||
mentioned_groups_ids bigint[]
|
||||
);
|
||||
|
||||
CREATE SEQUENCE wiki_page_meta_user_mentions_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
ALTER SEQUENCE wiki_page_meta_user_mentions_id_seq OWNED BY wiki_page_meta_user_mentions.id;
|
||||
|
||||
CREATE TABLE wiki_page_slugs (
|
||||
id bigint NOT NULL,
|
||||
canonical boolean DEFAULT false NOT NULL,
|
||||
|
|
@ -22812,6 +22831,8 @@ ALTER TABLE ONLY webauthn_registrations ALTER COLUMN id SET DEFAULT nextval('web
|
|||
|
||||
ALTER TABLE ONLY wiki_page_meta ALTER COLUMN id SET DEFAULT nextval('wiki_page_meta_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY wiki_page_meta_user_mentions ALTER COLUMN id SET DEFAULT nextval('wiki_page_meta_user_mentions_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY wiki_page_slugs ALTER COLUMN id SET DEFAULT nextval('wiki_page_slugs_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY wiki_repository_states ALTER COLUMN id SET DEFAULT nextval('wiki_repository_states_id_seq'::regclass);
|
||||
|
|
@ -25622,6 +25643,9 @@ ALTER TABLE ONLY webauthn_registrations
|
|||
ALTER TABLE ONLY wiki_page_meta
|
||||
ADD CONSTRAINT wiki_page_meta_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY wiki_page_meta_user_mentions
|
||||
ADD CONSTRAINT wiki_page_meta_user_mentions_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY wiki_page_slugs
|
||||
ADD CONSTRAINT wiki_page_slugs_pkey PRIMARY KEY (id);
|
||||
|
||||
|
|
@ -31239,10 +31263,16 @@ CREATE UNIQUE INDEX index_webauthn_registrations_on_credential_xid ON webauthn_r
|
|||
|
||||
CREATE INDEX index_webauthn_registrations_on_user_id ON webauthn_registrations USING btree (user_id);
|
||||
|
||||
CREATE UNIQUE INDEX index_wiki_meta_user_mentions_on_wiki_page_meta_id_and_note_id ON wiki_page_meta_user_mentions USING btree (wiki_page_meta_id, note_id);
|
||||
|
||||
CREATE INDEX index_wiki_page_meta_on_namespace_id ON wiki_page_meta USING btree (namespace_id);
|
||||
|
||||
CREATE INDEX index_wiki_page_meta_on_project_id ON wiki_page_meta USING btree (project_id);
|
||||
|
||||
CREATE INDEX index_wiki_page_meta_user_mentions_on_namespace_id ON wiki_page_meta_user_mentions USING btree (namespace_id);
|
||||
|
||||
CREATE INDEX index_wiki_page_meta_user_mentions_on_note_id ON wiki_page_meta_user_mentions USING btree (note_id);
|
||||
|
||||
CREATE INDEX index_wiki_page_slugs_on_project_id ON wiki_page_slugs USING btree (project_id);
|
||||
|
||||
CREATE UNIQUE INDEX index_wiki_page_slugs_on_slug_and_wiki_page_meta_id ON wiki_page_slugs USING btree (slug, wiki_page_meta_id);
|
||||
|
|
@ -34208,6 +34238,9 @@ ALTER TABLE ONLY users
|
|||
ALTER TABLE ONLY analytics_devops_adoption_snapshots
|
||||
ADD CONSTRAINT fk_78c9eac821 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY wiki_page_meta_user_mentions
|
||||
ADD CONSTRAINT fk_7954f34107 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY topics
|
||||
ADD CONSTRAINT fk_79ae18bd4b FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
|
||||
|
||||
|
|
@ -34601,12 +34634,18 @@ ALTER TABLE ONLY uploads
|
|||
ALTER TABLE ONLY deployments
|
||||
ADD CONSTRAINT fk_b9a3851b82 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY wiki_page_meta_user_mentions
|
||||
ADD CONSTRAINT fk_ba8a9d7f95 FOREIGN KEY (note_id) REFERENCES notes(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY project_compliance_standards_adherence
|
||||
ADD CONSTRAINT fk_baf6f6f878 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE p_ci_runner_machine_builds
|
||||
ADD CONSTRAINT fk_bb490f12fe_p FOREIGN KEY (partition_id, build_id) REFERENCES p_ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY wiki_page_meta_user_mentions
|
||||
ADD CONSTRAINT fk_bc155eba89 FOREIGN KEY (wiki_page_meta_id) REFERENCES wiki_page_meta(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY security_orchestration_policy_rule_schedules
|
||||
ADD CONSTRAINT fk_bcbb90477f FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
||||
|
|
|
|||
|
|
@ -55,12 +55,10 @@ Install one of the following GitLab-approved LLM models:
|
|||
|
||||
### Use a serving architecture
|
||||
|
||||
You should use one of the following serving architectures with your
|
||||
installed LLM:
|
||||
To host your models, you should use:
|
||||
|
||||
- [vLLM](https://docs.vllm.ai/en/stable/)
|
||||
- [TensorRT-LLM](https://docs.mistral.ai/deployment/self-deployment/overview/)
|
||||
- [Ollama and litellm](litellm_proxy_setup.md)
|
||||
- For non-cloud on-premise deployments, [vLLM](https://docs.vllm.ai/en/stable/).
|
||||
- For cloud deployments, AWS Bedrock as a cloud provider.
|
||||
|
||||
## Configure your GitLab instance
|
||||
|
||||
|
|
@ -128,15 +126,7 @@ Find the GitLab official Docker image at:
|
|||
- [Release process for self-hosted AI Gateway](https://gitlab.com/gitlab-org/modelops/applied-ml/code-suggestions/ai-assist/-/blob/main/docs/release.md).
|
||||
|
||||
Use the image tag that corresponds to your GitLab version. For example, if the
|
||||
GitLab version is `v17.4.0`, use `self-hosted-v17.4.0-ee` tag.
|
||||
|
||||
For version `v17.3.0-ee`, use image tag `gitlab-v17.3.0`.
|
||||
|
||||
WARNING:
|
||||
Docker for Windows is not officially supported. There are known issues with volume
|
||||
permissions, and potentially other unknown issues. If you are trying to run on Docker
|
||||
for Windows, see the [getting help page](https://about.gitlab.com/get-help/) for links
|
||||
to community resources (such as IRC or forums) to seek help from other users.
|
||||
GitLab version is `v17.5.0`, use `self-hosted-v17.5.0-ee` tag.
|
||||
|
||||
#### Set up the volumes location
|
||||
|
||||
|
|
@ -151,77 +141,19 @@ sudo mkdir -p /srv/gitlab-agw
|
|||
If you're running Docker with a user other than `root`, ensure appropriate
|
||||
permissions have been granted to that directory.
|
||||
|
||||
#### Optional: Download documentation index
|
||||
|
||||
NOTE:
|
||||
This only applies to AI Gateway image tag `gitlab-17.3.0-ee` and earlier. For images with tag `self-hosted-v17.4.0-ee` and later, documentation search is embedded into the Docker image.
|
||||
|
||||
To improve results when asking GitLab Duo Chat questions about GitLab, you can
|
||||
index GitLab documentation and provide it as a file to the AI Gateway.
|
||||
|
||||
To index the documentation in your local installation, run:
|
||||
|
||||
```shell
|
||||
pip install requests langchain langchain_text_splitters
|
||||
python3 scripts/custom_models/create_index.py -o <path_to_created_index/docs.db>
|
||||
```
|
||||
|
||||
This creates a file `docs.db` at the specified path.
|
||||
|
||||
You can also create an index for a specific GitLab version:
|
||||
|
||||
```shell
|
||||
python3 scripts/custom_models/create_index.py --version_tag="{gitlab-version}"
|
||||
```
|
||||
|
||||
#### Start a container from the image
|
||||
|
||||
For Docker images with version `self-hosted-17.4.0-ee` and later, run the following:
|
||||
|
||||
```shell
|
||||
docker run -e AIGW_GITLAB_URL=<your_gitlab_instance> <image>
|
||||
docker run -e AIGW_GITLAB_URL=<your_gitlab_instance> \
|
||||
-e AIGW_GITLAB_API_URL=https://<your_gitlab_domain>/api/v4/ \
|
||||
<image>
|
||||
```
|
||||
|
||||
For Docker images with version `gitlab-17.3.0-ee` and `gitlab-17.2.0`, run:
|
||||
|
||||
```shell
|
||||
docker run -e AIGW_CUSTOM_MODELS__ENABLED=true \
|
||||
-v path/to/created/index/docs.db:/app/tmp/docs.db \
|
||||
-e AIGW_FASTAPI__OPENAPI_URL="/openapi.json" \
|
||||
-e AIGW_AUTH__BYPASS_EXTERNAL=true \
|
||||
-e AIGW_FASTAPI__DOCS_URL="/docs"\
|
||||
-e AIGW_FASTAPI__API_PORT=5052 \
|
||||
<image>
|
||||
```
|
||||
|
||||
The arguments `AIGW_FASTAPI__OPENAPI_URL` and `AIGW_FASTAPI__DOCS_URL` are not
|
||||
mandatory, but are useful for debugging. From the host, accessing `http://localhost:5052/docs`
|
||||
From the container host, accessing `http://localhost:5052/docs`
|
||||
should open the AI Gateway API documentation.
|
||||
|
||||
### Install by using Docker Engine
|
||||
|
||||
1. For the AI Gateway to access the API, it must know where the GitLab instance
|
||||
is located. To do this, set the environment variables `AIGW_GITLAB_URL` and
|
||||
`AIGW_GITLAB_API_URL`:
|
||||
|
||||
```shell
|
||||
AIGW_GITLAB_URL=https://<your_gitlab_domain>
|
||||
AIGW_GITLAB_API_URL=https://<your_gitlab_domain>/api/v4/
|
||||
```
|
||||
|
||||
1. [Configure the GitLab instance](#configure-your-gitlab-instance).
|
||||
|
||||
1. After you've set up the environment variables, [run the image](#start-a-container-from-the-image).
|
||||
|
||||
1. Track the initialization process:
|
||||
|
||||
```shell
|
||||
sudo docker logs -f gitlab-aigw
|
||||
```
|
||||
|
||||
After starting the container, visit `gitlab-aigw.example.com`. It might take
|
||||
a while before the Docker container starts to respond to queries.
|
||||
|
||||
### Install by using the AI Gateway Helm chart
|
||||
|
||||
Prerequisites:
|
||||
|
|
|
|||
|
|
@ -487,7 +487,7 @@ Requires `current_user` and `group_ids` fields. Query based on the permissions t
|
|||
}
|
||||
```
|
||||
|
||||
##### `by_confidentiality`
|
||||
##### `by_project_confidentiality`
|
||||
|
||||
Requires `confidential`, `author_id`, `assignee_id`, `project_id` fields. Query with `confidential` in options.
|
||||
|
||||
|
|
|
|||
|
|
@ -729,6 +729,10 @@ Gitlab::Llm::Anthropic::Client.new(user, unit_primitive: 'your_feature')
|
|||
|
||||
In addition to standard logging in the GitLab Rails Monolith instance, specialized logging is available for features based on large language models (LLMs).
|
||||
|
||||
### Logged events
|
||||
|
||||
Currently logged events are documented [here](logged_events.md).
|
||||
|
||||
### Implementation
|
||||
|
||||
#### Logger Class
|
||||
|
|
@ -745,7 +749,7 @@ A feature flag named `expanded_ai_logging` controls the logging of sensitive dat
|
|||
Use the `conditional_info` helper method for conditional logging based on the feature flag status:
|
||||
|
||||
- If the feature flag is enabled for the current user, it logs the information on `info` level (logs are accessible in Kibana).
|
||||
- If the feature flag is disabled for the current user, it logs the information on `debug` level (logs are not accessible in Kibana).
|
||||
- If the feature flag is disabled for the current user, it logs the information on `info` level, but without optional parameters (logs are accessible in Kibana, but only obligatory fields).
|
||||
|
||||
### Best Practices
|
||||
|
||||
|
|
@ -759,14 +763,14 @@ When implementing logging for LLM features, consider the following:
|
|||
### Example Usage
|
||||
|
||||
```ruby
|
||||
# Logging non-sensitive information
|
||||
Gitlab::Llm::Logger.build.info("LLM feature initialized")
|
||||
# including concern that handles logging
|
||||
include Gitlab::Llm::Concerns::Logger
|
||||
|
||||
# Logging potentially sensitive information
|
||||
Gitlab::Llm::Logger.build.conditional_info(user, message:"User prompt processed: #{sanitized_prompt}")
|
||||
log_conditional_info(user, message:"User prompt processed", event_name: 'ai_event', ai_component: 'abstraction_layer', prompt: sanitized_prompt)
|
||||
|
||||
# Logging application error information
|
||||
Gitlab::Llm::Logger.build.error(user, message: "System application error: #{sanitized_error_message}")
|
||||
log_error(user, message: "System application error", event_name: 'ai_event', ai_component: 'abstraction_layer', error_message: sanitized_error_message)
|
||||
```
|
||||
|
||||
**Important**: Please familiarize yourself with our [Data Retention Policy](../../user/gitlab_duo/data_usage.md#data-retention) and remember
|
||||
|
|
|
|||
|
|
@ -0,0 +1,720 @@
|
|||
---
|
||||
stage: AI-powered
|
||||
group: AI Framework
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Logged events
|
||||
|
||||
In addition to standard logging in the GitLab Rails Monolith instance, specialized logging is available for features based on large language models (LLMs).
|
||||
|
||||
## Events logged
|
||||
|
||||
<!-- markdownlint-disable -->
|
||||
<!-- vale off -->
|
||||
|
||||
### Returning from Service due to validation
|
||||
|
||||
- Description: user not permitted to perform action
|
||||
- Class: `Llm::BaseService`
|
||||
- Ai_event_name: permission_denied
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- none
|
||||
- Part of the system: abstraction_layer
|
||||
- Expanded logging?: no
|
||||
- Rails: yes
|
||||
- Sidekiq: no
|
||||
|
||||
### Enqueuing CompletionWorker
|
||||
|
||||
- Description: scheduling completion worker in sidekiq
|
||||
- Class: `Llm::BaseService`
|
||||
- Ai_event_name: worker_enqueued
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- user_id: message.user.id
|
||||
- resource_id: message.resource&.id
|
||||
- resource_class: message.resource&.class&.name
|
||||
- request_id: message.request_id
|
||||
- action_name: message.ai_action
|
||||
- options: job_options
|
||||
- Part of the system: abstraction_layer
|
||||
- Expanded logging?: yes
|
||||
- Rails: yes
|
||||
- Sidekiq: no
|
||||
|
||||
### aborting: missing resource
|
||||
|
||||
- Description: If there is no resource for slash command
|
||||
- Class: `Llm::ChatService`
|
||||
- Ai_event_name: missing_resource
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- none
|
||||
- Part of the system: duo_chat
|
||||
- Expanded logging?: no
|
||||
- Rails: yes
|
||||
- Sidekiq: no
|
||||
|
||||
### Performing CompletionService
|
||||
|
||||
- Description: performing completion
|
||||
- Class: `Llm::Internal::CompletionService`
|
||||
- Ai_event_name: completion_service_performed
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- user_id: prompt_message.user.to_gid
|
||||
- resource_id: prompt_message.resource&.to_gid
|
||||
- action_name: prompt_message.ai_action
|
||||
- request_id: prompt_message.request_id
|
||||
- client_subscription_id: prompt_message.client_subscription_id
|
||||
- completion_service_name: completion_class_name
|
||||
- Part of the system: abstraction_layer
|
||||
- Expanded logging?: yes
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Answer from LLM response
|
||||
|
||||
- Description: Get answer from response
|
||||
- Class: `Gitlab::Llm::Chain::Answer`
|
||||
- Ai_event_name: answer_received
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- llm_answer_content: content
|
||||
- Part of the system: duo_chat
|
||||
- Expanded logging?: yes
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Final answer
|
||||
|
||||
- Description: Get final answer from response
|
||||
- Class: `Gitlab::Llm::Chain::Answer`
|
||||
- Ai_event_name: final_answer_received
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- llm_answer_content: content
|
||||
- Part of the system: duo_chat
|
||||
- Expanded logging?: yes
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Default final answer
|
||||
|
||||
- Description: Default final answer: I'm sorry, I couldn't respond in time. Please try a more specific request or enter /clear to start a new chat.
|
||||
- Class: `Gitlab::Llm::Chain::Answer`
|
||||
- Ai_event_name: default_final_answer_received
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- error_code: "A6000"
|
||||
- Part of the system: duo_chat
|
||||
- Expanded logging?: yes
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Error message/ "Error"
|
||||
|
||||
- Description: when answering with an error
|
||||
- Class: `Gitlab::Llm::Chain::Answer`
|
||||
- Ai_event_name: error_returned
|
||||
- Level: error
|
||||
- Arguments:
|
||||
- error: content
|
||||
- error_code: error_code
|
||||
- source: source
|
||||
- Part of the system: duo_chat
|
||||
- Expanded logging?: no
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Received response from AI Gateway
|
||||
|
||||
- Description: when response from AIGW is returned
|
||||
- Class: `Gitlab::Llm::AiGateway::Client`
|
||||
- Ai_event_name: response_received
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- response_from_llm: response_body
|
||||
- Part of the system: abstraction_layer
|
||||
- Expanded logging?: yes
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Received error from AI gateway
|
||||
|
||||
- Description: when error is returned from AIGW for streaming command
|
||||
- Class: `Gitlab::Llm::AiGateway::Client`
|
||||
- Ai_event_name: error_response_received
|
||||
- Level: error
|
||||
- Arguments:
|
||||
- response_from_llm: parsed_response.dig('detail'
|
||||
- 0
|
||||
- 'msg')
|
||||
- Part of the system: abstraction_layer
|
||||
- Expanded logging?: no
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Performing request to AI Gateway
|
||||
|
||||
- Description: before performing request to the AI GW
|
||||
- Class: `Gitlab::Llm::AiGateway::Client`
|
||||
- Ai_event_name: performing_request
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- url: url
|
||||
- body: body
|
||||
- timeout: timeout
|
||||
- stream: stream
|
||||
- Part of the system: abstraction_layer
|
||||
- Expanded logging?: yes
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Creating user access token
|
||||
|
||||
- Description: creating short-lived token in AIGW
|
||||
- Class: `Gitlab::Llm::AiGateway::CodeSuggestionsClient`
|
||||
- Ai_event_name: user_token_created
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- none
|
||||
- Part of the system: code suggestions
|
||||
- Expanded logging?: no
|
||||
- Rails: yes
|
||||
- Sidekiq: no
|
||||
|
||||
### Received response from Anthropic
|
||||
|
||||
- Description: Received response
|
||||
- Class: `Gitlab::Llm::Anthropic::Client`
|
||||
- Ai_event_name: response_received
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- ai_request_type: request_type
|
||||
- unit_primitive: unit_primitive
|
||||
- Part of the system: abstraction_layer
|
||||
- Expanded logging?: no
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Response content
|
||||
|
||||
- Description: Content of response
|
||||
- Class: `Gitlab::Llm::Anthropic::Client`
|
||||
- Ai_event_name: response_received
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- ai_request_type: request_type
|
||||
- unit_primitive: unit_primitive
|
||||
- response_from_llm: response_body
|
||||
- Part of the system: abstraction_layer
|
||||
- Expanded logging?: yes
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Performing request to Anthropic
|
||||
|
||||
- Description: performing completion request
|
||||
- Class: `Gitlab::Llm::Anthropic::Client`
|
||||
- Ai_event_name: performing_request
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- options: options
|
||||
- ai_request_type: request_type
|
||||
- unit_primitive: unit_primitive
|
||||
- Part of the system: abstraction_layer
|
||||
- Expanded logging?: no
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Searching docs from AI Gateway
|
||||
|
||||
- Description: performing search docs request
|
||||
- Class: `Gitlab::Llm::AiGateway::DocsClient`
|
||||
- Ai_event_name: performing_request
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- options: options
|
||||
- Part of the system: duo_chat
|
||||
- Expanded logging?: no
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Searched docs content from AI Gateway
|
||||
|
||||
- Description: response from AIGW with docs
|
||||
- Class: `Gitlab::Llm::AiGateway::DocsClient`
|
||||
- Ai_event_name: response_received
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- response_from_llm: response
|
||||
- Part of the system: duo_chat
|
||||
- Expanded logging?: yes
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Json parsing error during Question Categorization
|
||||
|
||||
- Description: logged when json is not parsable
|
||||
- Class: `Gitlab::Llm::Anthropic::Completions::CategorizeQuestions`
|
||||
- Ai_event_name: error
|
||||
- Level: error
|
||||
- Arguments:
|
||||
- none
|
||||
- Part of the system: duo_chat
|
||||
- Expanded logging?: no
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Response did not contain defined categories
|
||||
|
||||
- Description: logged when response is not containing one of the defined categories
|
||||
- Class: `Gitlab::Llm::Anthropic::Completions::CategorizeQuestions`
|
||||
- Ai_event_name: error
|
||||
- Level: error
|
||||
- Arguments:
|
||||
- none
|
||||
- Part of the system: duo_chat
|
||||
- Expanded logging?: no
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Picked tool
|
||||
|
||||
- Description: information about tool picked by chat
|
||||
- Class: `Gitlab::Llm::Chain::Agents::ZeroShot::Executor`
|
||||
- Ai_event_name: picked_tool
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- duo_chat_tool: tool_class.to_s
|
||||
- Part of the system: duo_chat
|
||||
- Expanded logging?: no
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Made request to AI Client
|
||||
|
||||
- Description: making request for chat
|
||||
- Class: `Gitlab::Llm::Chain::Requests::AiGateway`
|
||||
- Ai_event_name: response_received
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- prompt: prompt[:prompt]
|
||||
- response_from_llm: response
|
||||
- unit_primitive: unit_primitive
|
||||
- Part of the system: duo_chat
|
||||
- Expanded logging?: yes
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Streaming error
|
||||
|
||||
- Description: Error returned when streaming
|
||||
- Class: `Gitlab::Llm::Chain::Requests::Anthropic`
|
||||
- Ai_event_name: error_response_received
|
||||
- Level: error
|
||||
- Arguments:
|
||||
- error: data&.dig("error")
|
||||
- Part of the system: abstraction_layer
|
||||
- Expanded logging?: no
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Got Final Result for documentation question content
|
||||
|
||||
- Description: got result for documentation question - content
|
||||
- Class: `Gitlab::Llm::Chain::Tools::EmbeddingsCompletion`
|
||||
- Ai_event_name: response_received
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- prompt: final_prompt[:prompt]
|
||||
- response_from_llm: final_prompt_result
|
||||
- Part of the system: duo_chat
|
||||
- Expanded logging?: yes
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Streaming error
|
||||
|
||||
- Description: when error is returned from AIGW for streaming command in docs question
|
||||
- Class: `Gitlab::Llm::Chain::Tools::EmbeddingsCompletion`
|
||||
- Ai_event_name: error_response_received
|
||||
- Level: error
|
||||
- Arguments:
|
||||
- error: error.message
|
||||
- Part of the system: duo_chat
|
||||
- Expanded logging?: no
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Answer already received from tool
|
||||
|
||||
- Description: when tool was already picked up (content: You already have the answer from #{self.class::NAME} tool, read carefully.)
|
||||
- Class: `Gitlab::Llm::Chain::Tools::Tool`
|
||||
- Ai_event_name: incorrect_response_received
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- error_message: content
|
||||
- Part of the system: duo_chat
|
||||
- Expanded logging?: yes
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Tool cycling detected
|
||||
|
||||
- Description: When tool is picked up again
|
||||
- Class: `Gitlab::Llm::Chain::Tools::Tool`
|
||||
- Ai_event_name: incorrect_response_received
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- picked_tool: cls.class.to_s
|
||||
- Part of the system: duo_chat
|
||||
- Expanded logging?: no
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Calling TanukiBot
|
||||
|
||||
- Description: performing documentation request
|
||||
- Class: `Gitlab::Llm::Chain::Tools::GitlabDocumentation::Executor`
|
||||
- Ai_event_name: documentation_question_initial_request
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- none
|
||||
- Part of the system: duo_chat
|
||||
- Expanded logging?: no
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Error finding #{resource_name}
|
||||
|
||||
- Description: when resource (issue/epic/mr) is not found
|
||||
- Class: `Gitlab::Llm::Chain::Tools::Identifier`
|
||||
- Ai_event_name: incorrect_response_received
|
||||
- Level: error
|
||||
- Arguments:
|
||||
- error_message: authorizer.message
|
||||
- Part of the system: duo_chat
|
||||
- Expanded logging?: no
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Answer received from LLM
|
||||
|
||||
- Description: response from identifier
|
||||
- Class: `Gitlab::Llm::Chain::Tools::Identifier`
|
||||
- Ai_event_name: response_received
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- response_from_llm: content
|
||||
- Part of the system: duo_chat
|
||||
- Expanded logging?: yes
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Json parsing error
|
||||
|
||||
- Description: when json is malformed (Observation: JSON has an invalid format. Please retry)
|
||||
- Class: `Gitlab::Llm::Chain::Tools::Identifier`
|
||||
- Ai_event_name: error
|
||||
- Level: error
|
||||
- Arguments:
|
||||
- none
|
||||
- Part of the system: duo_chat
|
||||
- Expanded logging?: no
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Resource already identified
|
||||
|
||||
- Description: already identified resource (You already have identified the #{resource_name} #{resource.to_global_id}, read carefully.)
|
||||
- Class: `Gitlab::Llm::Chain::Tools::Identifier`
|
||||
- Ai_event_name: incorrect_response_received
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- error_message: content
|
||||
- Part of the system: duo_chat
|
||||
- Expanded logging?: yes
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Supported Issuable Typees Ability Allowed
|
||||
|
||||
- Description: logging the ability (policy.can?) for the issue/epic
|
||||
- Class: `Gitlab::Llm::Chain::Tools::SummarizeComments::Executor`
|
||||
- Ai_event_name: permission
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- allowed: ability
|
||||
- Part of the system: feature
|
||||
- Expanded logging?: yes
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Supported Issuable Typees Ability Allowed
|
||||
|
||||
- Description: logging the ability (policy.can?) for the issue/epic
|
||||
- Class: `Gitlab::Llm::Chain::Tools::SummarizeComments::ExecutorOld`
|
||||
- Ai_event_name: permission
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- allowed: ability
|
||||
- Part of the system: feature
|
||||
- Expanded logging?: yes
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Answer content for summarize_comments
|
||||
|
||||
- Description: Answer for summarize comments feature
|
||||
- Class: `Gitlab::Llm::Chain::Tools::SummarizeComments::ExecutorOld`
|
||||
- Ai_event_name: response_received
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- response_from_llm: content
|
||||
- Part of the system: feature
|
||||
- Expanded logging?: yes
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Content of the prompt from chat request
|
||||
|
||||
- Description: chat-related request
|
||||
- Class: `Gitlab::Llm::Chain::Concerns::AiDependent`
|
||||
- Ai_event_name: prompt_content
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- prompt: prompt_text
|
||||
- Part of the system: duo_chat
|
||||
- Expanded logging?: yes
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### "Too many requests, will retry in #{delay} seconds"
|
||||
|
||||
- Description: When entered in exponential backoff loop
|
||||
- Class: `Gitlab::Llm::Chain::Concerns::ExponentialBackoff`
|
||||
- Ai_event_name: retrying_request
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- none
|
||||
- Part of the system: abstraction_layer
|
||||
- Expanded logging?: no
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Resource not found
|
||||
|
||||
- Description: Resource not found/not authorized
|
||||
- Class: `Gitlab::Llm::Utils::Authorizer`
|
||||
- Ai_event_name: permission_denied
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- error_code: "M3003"
|
||||
- Part of the system: abstraction_layer
|
||||
- Expanded logging?: no
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### No access to Duo Chat
|
||||
|
||||
- Description: No access to duo chat
|
||||
- Class: `Gitlab::Llm::Utils::Authorizer`
|
||||
- Ai_event_name: permission_denied
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- error_code: "M3004"
|
||||
- Part of the system: abstraction_layer
|
||||
- Expanded logging?: no
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### AI is disabled
|
||||
|
||||
- Description: AI is not enabled for container
|
||||
- Class: `Gitlab::Llm::Utils::Authorizer`
|
||||
- Ai_event_name: permission_denied
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- error_code: "M3002"
|
||||
- Part of the system: abstraction_layer
|
||||
- Expanded logging?: no
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Performing request to Vertex
|
||||
|
||||
- Description: performing request
|
||||
- Class: `Gitlab::Llm::VertexAi::Client`
|
||||
- Ai_event_name: performing_request
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- unit_primitive: unit_primitive
|
||||
- options: config
|
||||
- Part of the system: abstraction_layer
|
||||
- Expanded logging?: no
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Response content
|
||||
|
||||
- Description: response from aigw - vertex -content
|
||||
- Class: `Gitlab::Llm::VertexAi::Client`
|
||||
- Ai_event_name: response_received
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- unit_primitive: unit_primitive
|
||||
- response_from_llm: response.to_json
|
||||
- Part of the system: abstraction_layer
|
||||
- Expanded logging?: yes
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Received response from Vertex
|
||||
|
||||
- Description: response from aigw - vertex
|
||||
- Class: `Gitlab::Llm::VertexAi::Client`
|
||||
- Ai_event_name: response_received
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- unit_primitive: unit_primitive
|
||||
- Part of the system: abstraction_layer
|
||||
- Expanded logging?: no
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Empty response from Vertex
|
||||
|
||||
- Description: empty response from aigw - vertex
|
||||
- Class: `Gitlab::Llm::VertexAi::Client`
|
||||
- Ai_event_name: empty_response_received
|
||||
- Level: error
|
||||
- Arguments:
|
||||
- unit_primitive: unit_primitive
|
||||
- Part of the system: abstraction_layer
|
||||
- Expanded logging?: no
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Surface an unknown event as a final answer to the user
|
||||
|
||||
- Description: unknown event
|
||||
- Class: `Gitlab::Llm::Chain::Agents::SingleActionExecutor`
|
||||
- Ai_event_name: unknown_event
|
||||
- Level: warn
|
||||
- Arguments:
|
||||
- none
|
||||
- Part of the system: duo_chat
|
||||
- Expanded logging?: no
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Failed to find a tool in GitLab Rails
|
||||
|
||||
- Description: failed to find a tool
|
||||
- Class: `Gitlab::Llm::Chain::Agents::SingleActionExecutor`
|
||||
- Ai_event_name: tool_not_find
|
||||
- Level: error
|
||||
- Arguments:
|
||||
- tool_name: tool_name
|
||||
- Part of the system: duo_chat
|
||||
- Expanded logging?: no
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Received an event from v2/chat/agent
|
||||
|
||||
- Description: Received event
|
||||
- Class: `Gitlab::Duo::Chat::StepExecutor`
|
||||
- Ai_event_name: event_received
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- event: event
|
||||
- Part of the system: duo_chat
|
||||
- Expanded logging?: yes
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Failed to update observation
|
||||
|
||||
- Description: Failed to update observation
|
||||
- Class: `Gitlab::Duo::Chat::StepExecutor`
|
||||
- Ai_event_name: agent_steps_empty
|
||||
- Level: error
|
||||
- Arguments:
|
||||
- none
|
||||
- Part of the system: duo_chat
|
||||
- Expanded logging?: no
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Request to v2/chat/agent
|
||||
|
||||
- Description: request
|
||||
- Class: `Gitlab::Duo::Chat::StepExecutor`
|
||||
- Ai_event_name: performing_request
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- params: params
|
||||
- Part of the system: duo_chat
|
||||
- Expanded logging?: yes
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Finished streaming from v2/chat/agent
|
||||
|
||||
- Description: finished streaming
|
||||
- Class: `Gitlab::Duo::Chat::StepExecutor`
|
||||
- Ai_event_name: streaming_finished
|
||||
- Level: info
|
||||
- Arguments:
|
||||
- none
|
||||
- Part of the system: duo_chat
|
||||
- Expanded logging?: no
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Received error from Duo Chat Agent
|
||||
|
||||
- Description: Error returned when streaming
|
||||
- Class: `Gitlab::Duo::Chat::StepExecutor`
|
||||
- Ai_event_name: error_returned
|
||||
- Level: error
|
||||
- Arguments:
|
||||
- status: response.code
|
||||
- Part of the system: duo_chat
|
||||
- Expanded logging?: no
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Failed to parse a chunk from Duo Chat Agent
|
||||
|
||||
- Description: failed to parse a chunk
|
||||
- Class: `Gitlab::Duo::Chat::AgentEventParser`
|
||||
- Ai_event_name: parsing_error
|
||||
- Level: warn
|
||||
- Arguments:
|
||||
- event_json_size: event_json.length
|
||||
- Part of the system: duo_chat
|
||||
- Expanded logging?: no
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
### Failed to find the event class in GitLab-Rails
|
||||
|
||||
- Description: no event class
|
||||
- Class: `Gitlab::Duo::Chat::AgentEventParser`
|
||||
- Ai_event_name: parsing_error
|
||||
- Level: error
|
||||
- Arguments:
|
||||
- event_type: event['type']
|
||||
- Part of the system: duo_chat
|
||||
- Expanded logging?: no
|
||||
- Rails: no
|
||||
- Sidekiq: yes
|
||||
|
||||
<!-- markdownlint-enable -->
|
||||
<!-- vale on -->
|
||||
|
|
@ -319,7 +319,7 @@ such as move unresolved threads to an issue or prevent merging until all threads
|
|||
|
||||
DETAILS:
|
||||
**Tier:** For a limited time, Ultimate. On October 17, 2024, Ultimate with [GitLab Duo Enterprise](https://about.gitlab.com/gitlab-duo/#pricing).
|
||||
**Offering:** GitLab.com, Self-managed
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
|
||||
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/10344) in GitLab 16.0 as an [experiment](../../policy/experiment-beta-support.md#experiment).
|
||||
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/454550) to GitLab Duo and promoted to [beta](../../policy/experiment-beta-support.md#beta) in GitLab 17.3 [with a flag](../../administration/feature_flags.md) named `summarize_notes_with_duo`. Disabled by default.
|
||||
|
|
@ -329,7 +329,6 @@ Generate a summary of discussions on an issue.
|
|||
|
||||
Prerequisites:
|
||||
|
||||
- You must belong to at least one group with the [experiment and beta features setting](../gitlab_duo/turn_on_off.md#turn-on-beta-and-experimental-features) enabled.
|
||||
- You must have permission to view the issue.
|
||||
|
||||
To generate a summary of issue discussions:
|
||||
|
|
@ -340,7 +339,5 @@ To generate a summary of issue discussions:
|
|||
The comments in the issue are summarized in as many as 10 list items.
|
||||
You can ask follow up questions based on the response.
|
||||
|
||||
Provide feedback on this beta feature in [issue 407779](https://gitlab.com/gitlab-org/gitlab/-/issues/407779).
|
||||
|
||||
**Data usage**: When you use this feature, the text of all comments on the issue are sent to
|
||||
the large [language model listed on the GitLab Duo page](../gitlab_duo/index.md#discussion-summary).
|
||||
|
|
|
|||
|
|
@ -44,6 +44,17 @@ DETAILS:
|
|||
- <i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Watch overview](https://www.youtube.com/watch?v=ZQBAuf-CTAY&list=PLFGfElNsQthYDx0A_FaNNfUm9NHsK6zED)
|
||||
- [View documentation](../gitlab_duo_chat/index.md).
|
||||
|
||||
### Discussion Summary
|
||||
|
||||
DETAILS:
|
||||
**Tier:** For a limited time, Ultimate. On October 17, 2024, Ultimate with [GitLab Duo Enterprise](https://about.gitlab.com/gitlab-duo/#pricing).
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
|
||||
- Helps everyone get up to speed by summarizing the lengthy conversations in an issue.
|
||||
- LLM: Anthropic [Claude 3.5 Sonnet](https://console.cloud.google.com/vertex-ai/publishers/anthropic/model-garden/claude-3-5-sonnet)
|
||||
- <i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Watch overview](https://www.youtube.com/watch?v=IcdxLfTIUgc)
|
||||
- [View documentation](../discussions/index.md#summarize-issue-discussions-with-duo-chat).
|
||||
|
||||
### Code Suggestions
|
||||
|
||||
DETAILS:
|
||||
|
|
@ -137,17 +148,6 @@ DETAILS:
|
|||
- Track the progress of AI adoption.
|
||||
- [View documentation](../analytics/ai_impact_analytics.md).
|
||||
|
||||
### Discussion summary
|
||||
|
||||
DETAILS:
|
||||
**Tier:** For a limited time, Ultimate. On October 17, 2024, Ultimate with [GitLab Duo Enterprise](https://about.gitlab.com/gitlab-duo/#pricing).
|
||||
**Offering:** GitLab.com, Self-managed
|
||||
|
||||
- Helps everyone get up to speed by summarizing the lengthy conversations in an issue.
|
||||
- LLM: Anthropic [Claude 3.5 Sonnet](https://console.cloud.google.com/vertex-ai/publishers/anthropic/model-garden/claude-3-5-sonnet)
|
||||
- <i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Watch overview](https://www.youtube.com/watch?v=IcdxLfTIUgc)
|
||||
- [View documentation](../discussions/index.md#summarize-issue-discussions-with-duo-chat).
|
||||
|
||||
## Beta features
|
||||
|
||||
### Self-Hosted Models
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
# Namespaces
|
||||
|
||||
In GitLab, a namespace provides a place to organize projects. Projects in a namespace are separate
|
||||
from other namespaces, enabling you to use the same project name in different namespaces.
|
||||
Namespaces organize projects in GitLab. Because each namespace is separate,
|
||||
you can use the same project name in multiple namespaces.
|
||||
|
||||
## Types of namespaces
|
||||
|
||||
|
|
@ -26,9 +26,9 @@ GitLab has two types of namespaces:
|
|||
- You can configure settings specifically for each subgroup and project.
|
||||
- You can manage the group or subgroup URL independently of the name.
|
||||
|
||||
## Determine which type of namespace you're viewing
|
||||
## Determine which type of namespace you're in
|
||||
|
||||
To determine whether you're viewing a group or personal namespace, you can view the URL. For example:
|
||||
To determine whether you're in a group or personal namespace, you can view the URL. For example:
|
||||
|
||||
| Namespace for | URL | Namespace |
|
||||
| ------------- | --- | --------- |
|
||||
|
|
@ -36,9 +36,9 @@ To determine whether you're viewing a group or personal namespace, you can view
|
|||
| A group named `alex-team`. | `https://gitlab.example.com/alex-team` | `alex-team` |
|
||||
| A group named `alex-team` with a subgroup named `marketing`. | `https://gitlab.example.com/alex-team/marketing` | `alex-team/marketing` |
|
||||
|
||||
## Naming limitations for namespaces
|
||||
## Name limitations
|
||||
|
||||
When you choose a name for your namespace, keep in mind the [character limitations](../reserved_names.md#limitations-on-usernames-project-and-group-names-and-slugs) and [reserved group names](../reserved_names.md#reserved-group-names).
|
||||
|
||||
NOTE:
|
||||
Namespaces with a period (`.`) cause issues with validating SSL certificates and the source path when [publishing Terraform modules](../packages/terraform_module_registry/index.md#publish-a-terraform-module).
|
||||
Namespaces with a period (`.`) cause issues with SSL certificate validation and the source path when [publishing Terraform modules](../packages/terraform_module_registry/index.md#publish-a-terraform-module).
|
||||
|
|
|
|||
|
|
@ -53,6 +53,10 @@ Code generation requests take longer than code completion requests, but provide
|
|||
[View a click-through demo](https://gitlab.navattic.com/code-suggestions).
|
||||
<!-- Video published on 2023-12-09 --> <!-- Demo published on 2024-02-01 -->
|
||||
|
||||
<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
|
||||
[View a code completion vs. code generation comparison demo](https://www.youtube.com/watch?v=9dsyqMt9yg4).
|
||||
<!-- Video published on 2024-09-26 -->
|
||||
|
||||
## Use Code Suggestions
|
||||
|
||||
Prerequisites:
|
||||
|
|
|
|||
|
|
@ -29,6 +29,21 @@ module Gitlab
|
|||
|
||||
Error = Class.new(StandardError)
|
||||
|
||||
# Entrypoint for the application
|
||||
# Run any initialization logic from here
|
||||
def self.start(argv)
|
||||
# Set a custom process name
|
||||
update_process_title!
|
||||
|
||||
Gitlab::Backup::Cli::Runner.start(argv)
|
||||
end
|
||||
|
||||
def self.update_process_title!(status_message = nil)
|
||||
process_title = status_message ? "gitlab-backup-cli: #{status_message}" : "gitlab-backup-cli"
|
||||
|
||||
Process.setproctitle(process_title)
|
||||
end
|
||||
|
||||
def self.rails_environment!
|
||||
require File.join(GITLAB_PATH, 'config/application')
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ module Gitlab
|
|||
|
||||
desc 'all', 'Creates a backup including repositories, database and local files'
|
||||
def all
|
||||
Gitlab::Backup::Cli.update_process_title!('backup all')
|
||||
|
||||
duration = measure_duration do
|
||||
Gitlab::Backup::Cli::Output.info("Initializing environment...")
|
||||
Gitlab::Backup::Cli.rails_environment!
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ module Gitlab
|
|||
|
||||
desc 'all BACKUP_ID', 'Restores a backup including repositories, database and local files'
|
||||
def all(backup_id)
|
||||
Gitlab::Backup::Cli.update_process_title!("restore all from #{backup_id}")
|
||||
|
||||
duration = measure_duration do
|
||||
Gitlab::Backup::Cli::Output.info("Initializing environment...")
|
||||
Gitlab::Backup::Cli.rails_environment!
|
||||
|
|
|
|||
|
|
@ -1,7 +1,54 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe Gitlab::Backup::Cli do
|
||||
subject(:cli) { described_class }
|
||||
|
||||
around do |example|
|
||||
previous_title = get_process_title
|
||||
example.run
|
||||
Process.setproctitle(previous_title)
|
||||
end
|
||||
|
||||
it "has a version number" do
|
||||
expect(Gitlab::Backup::Cli::VERSION).not_to be nil
|
||||
end
|
||||
|
||||
describe '.start' do
|
||||
it 'sets the process title', :silence_output do
|
||||
cli.start([])
|
||||
|
||||
expect(get_process_title).to eq('gitlab-backup-cli')
|
||||
end
|
||||
|
||||
it 'delegates to Runner.start' do
|
||||
argv = ['version']
|
||||
|
||||
expect(Gitlab::Backup::Cli::Runner).to receive(:start).with(argv)
|
||||
|
||||
cli.start(argv)
|
||||
end
|
||||
end
|
||||
|
||||
describe '.update_process_title!' do
|
||||
context 'without any parameters' do
|
||||
it 'sets a process title to `gitlab-backup-cli`' do
|
||||
cli.update_process_title!
|
||||
|
||||
expect(get_process_title).to eq('gitlab-backup-cli')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with parameters' do
|
||||
it 'sets a process title to `gitlab-backup-cli: ` including provided content' do
|
||||
cli.update_process_title!('context info')
|
||||
|
||||
expect(get_process_title).to eq('gitlab-backup-cli: context info')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def get_process_title
|
||||
ps = `ps -p #{Process.pid} -o command`
|
||||
ps.split("\n").last.strip
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -101,6 +101,8 @@ module Gitlab
|
|||
instance.gitlab_snippet_url(note.noteable, anchor: dom_id(note), **options)
|
||||
elsif note.for_abuse_report?
|
||||
instance.admin_abuse_report_url(note.noteable, anchor: dom_id(note), **options)
|
||||
elsif note.for_wiki_page?
|
||||
instance.project_wiki_page_url(note.noteable, anchor: dom_id(note), **options)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ FactoryBot.define do
|
|||
factory :note_on_personal_snippet, traits: [:on_personal_snippet]
|
||||
factory :note_on_design, traits: [:on_design]
|
||||
factory :note_on_alert, traits: [:on_alert]
|
||||
factory :note_on_wiki_page, traits: [:on_wiki_page]
|
||||
factory :system_note, traits: [:system]
|
||||
|
||||
factory :discussion_note, class: 'DiscussionNote'
|
||||
|
|
@ -39,6 +40,8 @@ FactoryBot.define do
|
|||
|
||||
factory :discussion_note_on_project_snippet, traits: [:on_project_snippet], class: 'DiscussionNote'
|
||||
|
||||
factory :discussion_note_on_wiki_page, traits: [:on_wiki_page], class: 'DiscussionNote'
|
||||
|
||||
factory :legacy_diff_note_on_commit, traits: [:on_commit, :legacy_diff_note], class: 'LegacyDiffNote'
|
||||
|
||||
factory :legacy_diff_note_on_merge_request, traits: [:on_merge_request, :legacy_diff_note], class: 'LegacyDiffNote' do
|
||||
|
|
@ -140,6 +143,10 @@ FactoryBot.define do
|
|||
noteable { association(:work_item, :group_level) }
|
||||
end
|
||||
|
||||
trait :on_project_level_wiki do
|
||||
noteable { association(:wiki_page_meta, project: project) }
|
||||
end
|
||||
|
||||
trait :on_merge_request do
|
||||
noteable { association(:merge_request, source_project: project) }
|
||||
end
|
||||
|
|
@ -171,6 +178,10 @@ FactoryBot.define do
|
|||
noteable { association(:alert_management_alert, project: project) }
|
||||
end
|
||||
|
||||
trait :on_wiki_page do
|
||||
noteable { association(:wiki_page_meta, project: project) }
|
||||
end
|
||||
|
||||
trait :resolved do
|
||||
resolved_at { Time.now }
|
||||
resolved_by { association(:user) }
|
||||
|
|
|
|||
|
|
@ -80,6 +80,22 @@ RSpec.describe Gitlab::UrlBuilder do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when passing a wiki note' do
|
||||
let_it_be(:wiki_page_slug) { create(:wiki_page_slug, canonical: true) }
|
||||
let(:wiki_page_meta) { wiki_page_slug.reload.wiki_page_meta }
|
||||
let(:note) { build_stubbed(:note, noteable: wiki_page_meta, project: wiki_page_meta.project) }
|
||||
|
||||
let(:path) { "/#{note.project.full_path}/-/wikis/#{note.noteable.canonical_slug}#note_#{note.id}" }
|
||||
|
||||
it 'returns the full URL' do
|
||||
expect(subject.build(note)).to eq("#{Gitlab.config.gitlab.url}#{path}")
|
||||
end
|
||||
|
||||
it 'returns only the path if only_path is given' do
|
||||
expect(subject.build(note, only_path: true)).to eq(path)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when passing a compare' do
|
||||
# NOTE: The Compare requires an actual repository, which isn't available
|
||||
# with the `build_stubbed` strategy used by the table tests above
|
||||
|
|
|
|||
|
|
@ -105,6 +105,14 @@ RSpec.describe Note, feature_category: :team_planning do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when noteable is a wiki page' do
|
||||
subject { build(:note, noteable: build_stubbed(:wiki_page_meta), project: nil, namespace: nil) }
|
||||
|
||||
it 'is not valid without project or namespace' do
|
||||
is_expected.to be_invalid
|
||||
end
|
||||
end
|
||||
|
||||
describe 'max notes limit' do
|
||||
let_it_be(:noteable) { create(:issue) }
|
||||
let_it_be(:existing_note) { create(:note, project: noteable.project, noteable: noteable) }
|
||||
|
|
@ -1396,6 +1404,12 @@ RSpec.describe Note, feature_category: :team_planning do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#for_wiki_page?' do
|
||||
it 'returns true for a wiki_page' do
|
||||
expect(build(:note_on_wiki_page).for_wiki_page?).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
describe '#for_design' do
|
||||
it 'is true when the noteable is a design' do
|
||||
note = build(:note, noteable: build(:design))
|
||||
|
|
|
|||
|
|
@ -10,6 +10,15 @@ RSpec.describe WikiPage::Meta, feature_category: :wiki do
|
|||
it { is_expected.to belong_to(:project) }
|
||||
it { is_expected.to have_many(:slugs) }
|
||||
it { is_expected.to have_many(:events) }
|
||||
it { is_expected.to have_many(:notes) }
|
||||
|
||||
it do
|
||||
is_expected
|
||||
.to have_many(:user_mentions)
|
||||
.class_name('Wikis::UserMention')
|
||||
.with_foreign_key('wiki_page_meta_id')
|
||||
.inverse_of('wiki_page_meta')
|
||||
end
|
||||
|
||||
it 'can find slugs' do
|
||||
meta = create(:wiki_page_meta)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Wikis::UserMention, feature_category: :wiki do
|
||||
describe 'associations' do
|
||||
it { is_expected.to belong_to(:wiki_page_meta).optional(false) }
|
||||
it { is_expected.to belong_to(:note).optional(false) }
|
||||
end
|
||||
|
||||
it_behaves_like 'has user mentions'
|
||||
end
|
||||
Loading…
Reference in New Issue