From b0cd9843dcba5b18678654a7d74e54f07425c183 Mon Sep 17 00:00:00 2001
From: Marc Vilanova <39573146+mvilanova@users.noreply.github.com>
Date: Thu, 19 Sep 2024 15:59:03 -0700
Subject: [PATCH] Adds genai fields to signal definition model (#5229)
* Adds genai fields to signal definition model
* adds fields to signalbase pydantic model
* Adds genai fields to signal definition component
* adds runbook field
* bugfix
* removes import
---
.../versions/2024-09-19_19c10c121a22.py | 33 ++++++++++
src/dispatch/signal/models.py | 12 ++++
.../dispatch/src/signal/NewEditDialog.vue | 65 +++++++++++++++++++
.../static/dispatch/src/signal/store.js | 4 ++
4 files changed, 114 insertions(+)
create mode 100644 src/dispatch/database/revisions/tenant/versions/2024-09-19_19c10c121a22.py
diff --git a/src/dispatch/database/revisions/tenant/versions/2024-09-19_19c10c121a22.py b/src/dispatch/database/revisions/tenant/versions/2024-09-19_19c10c121a22.py
new file mode 100644
index 000000000000..72ac2e4de02b
--- /dev/null
+++ b/src/dispatch/database/revisions/tenant/versions/2024-09-19_19c10c121a22.py
@@ -0,0 +1,33 @@
+"""Adds GenAI fields to Signal model
+
+Revision ID: 19c10c121a22
+Revises: 47d616802f56
+Create Date: 2024-09-19 14:45:53.064341
+
+"""
+from alembic import op
+import sqlalchemy as sa
+
+# revision identifiers, used by Alembic.
+revision = '19c10c121a22'
+down_revision = '47d616802f56'
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+ # ### commands auto generated by Alembic - please adjust! ###
+ op.add_column('signal', sa.Column('runbook', sa.String(), nullable=True))
+ op.add_column('signal', sa.Column('genai_enabled', sa.Boolean(), nullable=True))
+ op.add_column('signal', sa.Column('genai_model', sa.String(), nullable=True))
+ op.add_column('signal', sa.Column('genai_system_message', sa.String(), nullable=True))
+ # ### end Alembic commands ###
+
+
+def downgrade():
+ # ### commands auto generated by Alembic - please adjust! ###
+ op.drop_column('signal', 'genai_system_message')
+ op.drop_column('signal', 'genai_model')
+ op.drop_column('signal', 'genai_enabled')
+ op.drop_column('signal', 'runbook')
+ # ### end Alembic commands ###
diff --git a/src/dispatch/signal/models.py b/src/dispatch/signal/models.py
index 6c574dc793da..0fbaf4fa668f 100644
--- a/src/dispatch/signal/models.py
+++ b/src/dispatch/signal/models.py
@@ -130,6 +130,7 @@ class SignalFilterAction(DispatchEnum):
class Signal(Base, TimeStampMixin, ProjectMixin):
+ """Class that represents a detection and its properties."""
id = Column(Integer, primary_key=True)
name = Column(String)
owner = Column(String)
@@ -149,6 +150,12 @@ class Signal(Base, TimeStampMixin, ProjectMixin):
conversation_target = Column(String)
default = Column(Boolean, default=False)
lifecycle = Column(String)
+ runbook = Column(String)
+
+ # GenAI specific fields
+ genai_enabled = Column(Boolean, default=True)
+ genai_model = Column(String)
+ genai_system_message = Column(String)
oncall_service_id = Column(Integer, ForeignKey("service.id"))
oncall_service = relationship("Service", foreign_keys=[oncall_service_id])
@@ -219,6 +226,7 @@ class SignalFilter(Base, ProjectMixin, EvergreenMixin, TimeStampMixin):
class SignalInstance(Base, TimeStampMixin, ProjectMixin):
+ """Class that represents a detection alert and its properties."""
id = Column(UUID(as_uuid=True), primary_key=True, default=lambda: str(uuid.uuid4()))
case = relationship("Case", backref="signal_instances")
case_id = Column(Integer, ForeignKey("case.id", ondelete="CASCADE"))
@@ -313,6 +321,10 @@ class SignalBase(DispatchBase):
source: Optional[SourceBase]
variant: Optional[str]
lifecycle: Optional[str]
+ runbook: Optional[str]
+ genai_enabled: Optional[bool] = True
+ genai_model: Optional[str]
+ genai_system_message: Optional[str]
class SignalCreate(SignalBase):
diff --git a/src/dispatch/static/dispatch/src/signal/NewEditDialog.vue b/src/dispatch/static/dispatch/src/signal/NewEditDialog.vue
index ea1756adf2a5..efcc2ecf37b0 100644
--- a/src/dispatch/static/dispatch/src/signal/NewEditDialog.vue
+++ b/src/dispatch/static/dispatch/src/signal/NewEditDialog.vue
@@ -68,6 +68,18 @@
name="Description"
/>
+
+
+
+
+
+
+ GenAI Configuration
+
+
+
+ mdi-help-circle-outline
+
+ The following options allow you to configure settings related to Dispatch's GenAI
+ features.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -305,6 +366,7 @@ export default {
computed: {
...mapFields("signal", [
"dialogs.showCreateEdit",
+ "selected.runbook",
"selected",
"selected.case_priority",
"selected.case_type",
@@ -317,6 +379,9 @@ export default {
"selected.external_id",
"selected.external_url",
"selected.filters",
+ "selected.genai_enabled",
+ "selected.genai_model",
+ "selected.genai_system_message",
"selected.id",
"selected.lifecycle",
"selected.loading",
diff --git a/src/dispatch/static/dispatch/src/signal/store.js b/src/dispatch/static/dispatch/src/signal/store.js
index 7c8f30310271..2c33ba3b718b 100644
--- a/src/dispatch/static/dispatch/src/signal/store.js
+++ b/src/dispatch/static/dispatch/src/signal/store.js
@@ -18,6 +18,9 @@ const getDefaultSelectedState = () => {
external_id: null,
external_url: null,
filters: [],
+ genai_enabled: false,
+ genai_model: null,
+ genai_system_message: null,
id: null,
lifecycle: null,
loading: false,
@@ -25,6 +28,7 @@ const getDefaultSelectedState = () => {
oncall_service: null,
owner: null,
project: null,
+ runbook: null,
signal_definition: null,
source: null,
tags: [],