-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathslack-bot.yaml
131 lines (117 loc) · 5 KB
/
slack-bot.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# Copyright 2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# This example requires the following Slack permission scopes:
# - channels:history,
# - groups:history
# - mpim:history
# - im:history
# - chat:write
globals:
slackToken: "${slack_token}"
slackAppId: "${slack_app_id}"
pipeline:
- type: processor.genericjson
- type: output.logger
config:
message: "Slack event received: {{ data|json_encode }}"
# Check if the message is Slack webhook validation call
- type: processor.setvariable
stopIf: |
{% if 'challenge' in data %}1{% endif %}
output: slack_abort
config:
value: "1"
# Parse the incoming Slack message by removing the IRC-like nick from the message
- type: processor.setvariable
runIf: |
{% if 'api_app_id' in data and data.event.type == 'app_mention' %}1{% endif %}
output: slack_message_text
config:
value: |
{{ data.event.text|regex_replace('^<[^>]+> ', '')|remove_mrkdwn }}
# Parse the incoming Slack message by removing the IRC-like nick from the message
- type: processor.setvariable
# Check if this is our bot message from events API
stopIf: |
{% if 'type' in data and data.event.type == 'message' and data.event.app_id %}1{% endif %}
runIf: |
{% if 'type' in data and data.event.type == 'message' %}1{% endif %}
output: slack_message_text
config:
value: |
{{ data.event.text|regex_replace('^<[^>]+> ', '')|remove_mrkdwn }}
# Fetch existing conversation history from Slack to pass back to Vertex PaLM for context
- type: processor.slack
runIf: "{% if slack_message_text %}1{% endif %}"
output: slack_thread
config:
api: conversations.replies
token: "{{ slackToken }}"
request:
channel: "{{ data.event.channel }}"
ts: "{% if data.event.thread_ts %}{{ data.event.thread_ts }}{% else %}{{ data.event.ts }}{% endif %}"
# See if this conservation thread has any our app ID mentioned, if so, assume it's a follow up thread
- type: processor.setvariable
runIf: |
{% if slack_message_text %}1{% endif %}
output: slack_should_reply
config:
fromJson: true
value: |
{% set app_thread = [(data.event.type == 'app_mention')] %}{% for message in slack_thread.messages %}{% if message.app_id == slackAppId %}{% set _ = app_thread.append(true) %}{% endif %}{% endfor %}{{ app_thread|last|json_encode }}
# Process the returned conversation history messages into suitable format for Vertex
- type: processor.setvariable
runIf: |
{% if slack_message_text and slack_should_reply %}1{% endif %}
output: slack_messages
config:
fromJson: true
value: |
{%- set messages = [] -%}{%- for message in slack_thread.messages -%}{%- set _ = messages.append({"author":"AI" if data.event.user != message.user else "USER","content":message.text|regex_replace('^<[^>]+> ', '')|remove_mrkdwn}) -%}{%- endfor -%}{% set _ = messages.append({"author":"USER","content":slack_message_text}) %}{{ messages|json_encode }}
# Call Vertex AI Generative AI with the thread messages to make a chat reply
- type: processor.vertexgenai
runIf: |
{% if slack_message_text and slack_should_reply %}1{% endif %}
output: vertex_response
config:
location: "${vertex_region}"
modelId: "${vertex_model}"
request:
instances:
- messagesExpr: slack_messages
context: |
You are a helpful Slack bot that offers concise answers to all kinds of issues.
You keep your answers under 100 words.
parameters:
temperature: 0.3
topP: 0.8
topK: 40
maxOutputTokens: 200 # in some documentation, this appears as maxDecodeSteps, which has been renamed to maxOutputTokens
# Log the response
- type: output.logger
runIf: |
{% if slack_message_text and slack_should_reply %}1{% endif %}
config:
message: "Vertex GenAI response: {{ vertex_response|json_encode }}"
# Post Vertex AI reply to the correct thread
- type: output.slack
runIf: "{% if slack_message_text and slack_should_reply and vertex_response.predictions|length > 0 %}1{% endif %}"
config:
token: "{{ slackToken }}"
api: chat.postMessage
request:
channel: "{{ data.event.channel }}"
thread_ts: "{% if data.event.thread_ts %}{{ data.event.thread_ts }}{% else %}{{ data.event.ts }}{% endif %}"
text: |
{{ ((vertex_response.predictions|first).candidates|first).content }}