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 + + + + + + + + + + + + + + + + + + @@ -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: [],