Skip to content

Commit 7633bba

Browse files
authored
Merge pull request #37 from checkly/validation
Add validation to prompt functions
2 parents 2620874 + 34d1054 commit 7633bba

9 files changed

+248
-1
lines changed

src/prompts/alerts.ts

+26
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
import { getOpenaiSDKClient } from "../ai/openai";
22
import { NotionPage } from "../notion/notion";
33
import { PromptConfig, promptConfig } from "./common";
4+
import { getOpenaiSDKClient } from "../ai/openai";
5+
import { validObjectList, validString } from "./validation";
46

57
export function affectedComponentsPrompt(
68
guidelines: NotionPage[], // guidelines for ops channel
79
alertMessage: string,
810
): [string, PromptConfig] {
11+
validObjectList.parse(guidelines);
12+
validString.parse(alertMessage);
13+
914
const model = getOpenaiSDKClient()("gpt-4o-mini");
1015
const systemPrompt = `You are an experienced on-call engineer who is responsible for determining which system components are affected by an alert`;
1116

@@ -32,6 +37,10 @@ export function alertRecommendationPrompt(
3237
alertMessage: string,
3338
affectedComponents: { component: string; environment: string }[],
3439
): [string, PromptConfig] {
40+
validObjectList.parse(guidelines);
41+
validString.parse(alertMessage);
42+
validObjectList.parse(affectedComponents);
43+
3544
const model = getOpenaiSDKClient()("gpt-4o-mini");
3645
const system =
3746
"You are an experienced on-call engineer who is responsible for recommending further actions for an alert";
@@ -62,6 +71,9 @@ export function alertHistoryPrompt(
6271
alertMessage: string,
6372
messageHistory: string,
6473
): [string, PromptConfig] {
74+
validString.parse(alertMessage);
75+
validString.parse(messageHistory);
76+
6577
const system =
6678
"You are an experienced on-call engineer who is responsible for analysing previous alert in the slack channel";
6779

@@ -96,6 +108,9 @@ export function alertSeverityPrompt(
96108
alertMessage: string,
97109
affectedComponents: { component: string; environment: string }[],
98110
): [string, PromptConfig] {
111+
validString.parse(alertMessage);
112+
validObjectList.parse(affectedComponents);
113+
99114
const system =
100115
"You are an experienced on-call engineer who is responsible for determining the severity of alerts";
101116

@@ -131,6 +146,17 @@ export function alertSummaryPrompt(
131146
historyInfo: { type: string; reasoning: string },
132147
guidelines: NotionPage[],
133148
): [string, PromptConfig] {
149+
validObjectList.parse(affectedComponents);
150+
[
151+
alertMessage,
152+
severityInfo.severity,
153+
severityInfo.reasoning,
154+
stateInfo.state,
155+
stateInfo.reasoning,
156+
historyInfo.type,
157+
historyInfo.reasoning,
158+
].forEach((s) => validString.parse(s));
159+
134160
const system =
135161
"You are an experienced on-call engineer who is leading a team of engineers analysing alerts from a Slack channel";
136162

src/prompts/checkly.ts

+12-1
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ import { stringify } from "yaml";
22
import { CheckContext, ContextKey } from "../aggregator/ContextAggregator";
33
import { Check } from "../checkly/models";
44
import { mapCheckToContextValue } from "../checkly/utils";
5+
import { validObjectList, validObject } from "./validation";
56
import { promptConfig, PromptConfig } from "./common";
67
import { slackFormatInstructions } from "./slack";
78

89
/** Maximum length for context analysis text to prevent oversized prompts */
9-
1010
const CONTEXT_ANALYSIS_MAX_LENGTH = 200000;
1111

1212
/**
@@ -24,6 +24,9 @@ export function contextAnalysisEntryPrompt(
2424
entry: CheckContext,
2525
allEntries: CheckContext[],
2626
): [string, PromptConfig] {
27+
validObject.parse(entry);
28+
validObjectList.parse(allEntries);
29+
2730
return [
2831
`The following check has failed: ${formatChecklyMonitorData(allEntries)}
2932
@@ -50,6 +53,8 @@ ${stringify(entry)}`,
5053
export function contextAnalysisSummaryPrompt(
5154
contextRows: CheckContext[],
5255
): [string, PromptConfig] {
56+
validObjectList.parse(contextRows);
57+
5358
const checkContext = formatChecklyMonitorData(contextRows);
5459

5560
return [
@@ -95,6 +100,8 @@ export function checklyToolPrompt(
95100
checks: Check[],
96101
query: string | undefined,
97102
): [string, PromptConfig] {
103+
validObjectList.parse(checks);
104+
98105
return [
99106
`You are the Checkly Check Search Engine. You are given a query and a list of checks. Return the most relevant check that relates to the query.
100107
@@ -117,6 +124,8 @@ Search Query: ${query ?? ""}`,
117124
* const formattedContext = formatContextAnalysis(contextRows);
118125
*/
119126
function formatContextAnalysis(rows: CheckContext[]): string {
127+
validObjectList.parse(rows);
128+
120129
return stringify(
121130
rows
122131
.filter((c) => c.key !== ContextKey.ChecklyCheck)
@@ -136,6 +145,8 @@ function formatContextAnalysis(rows: CheckContext[]): string {
136145
* const monitorData = formatChecklyMonitorData(contextRows);
137146
*/
138147
function formatChecklyMonitorData(rows: CheckContext[]): string {
148+
validObjectList.parse(rows);
149+
139150
const checkContext = rows.find((c) => c.key === ContextKey.ChecklyCheck);
140151
return stringify(
141152
{

src/prompts/github.ts

+24
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { stringify } from "yaml";
22
import { Check } from "../checkly/models";
33
import { mapCheckToContextValue } from "../checkly/utils";
44
import { PromptConfig, promptConfig } from "./common";
5+
import { validObjectList, validObject, validString } from "./validation";
56

67
const MAX_DIFF_LENGTH = 1000000;
78

@@ -30,6 +31,10 @@ export function generateFindRelevantReleasesPrompt(
3031
checkResult: string,
3132
releases: GithubReleaseForPrompt[],
3233
): [string, PromptConfig] {
34+
validObject.parse(check);
35+
validString.parse(checkResult);
36+
validObjectList.parse(releases);
37+
3338
return [
3439
`Based on the following releases, which ones are most relevant to the check state change?
3540
@@ -61,6 +66,10 @@ export function generateFindRelevantDeploymentsPrompt(
6166
checkResult: string,
6267
deployments: GithubDeploymentForPrompt[],
6368
): [string, PromptConfig] {
69+
validObject.parse(check);
70+
validString.parse(checkResult);
71+
validObjectList.parse(deployments);
72+
6473
return [
6574
`Based on the following deployments, which ones are most relevant to the check state change? Analyze the check script, result and releases to determine which releases are most relevant. Provide a list of deployment ids that are most relevant to the check.
6675
@@ -89,6 +98,10 @@ export function generateReleaseHeadlinePrompt(
8998
currentRelease: string,
9099
diff: string,
91100
): [string, PromptConfig] {
101+
validString.parse(prevRelease);
102+
validString.parse(currentRelease);
103+
validString.parse(diff);
104+
92105
return [
93106
`The following diff describes the changes between ${prevRelease} and ${currentRelease}.
94107
@@ -112,6 +125,10 @@ export function generateReleaseSummaryPrompt(
112125
currentRelease: string,
113126
diff: string,
114127
): [string, PromptConfig] {
128+
validString.parse(prevRelease);
129+
validString.parse(currentRelease);
130+
validString.parse(diff);
131+
115132
return [
116133
`The following diff describes the changes between ${prevRelease} and ${currentRelease}.
117134
@@ -137,6 +154,10 @@ export function generateDeploymentSummaryPrompt(
137154
currentSha: string,
138155
diff: string,
139156
): [string, PromptConfig] {
157+
validString.parse(prevSha);
158+
validString.parse(currentSha);
159+
validString.parse(diff);
160+
140161
return [
141162
`The following diff describes the changes between ${prevSha} and ${currentSha}.
142163
@@ -159,6 +180,9 @@ export function generateFindRepoPrompt(
159180
userPrompt: string,
160181
allRepos: GithubRepoForPrompt[],
161182
): [string, PromptConfig] {
183+
validString.parse(userPrompt);
184+
validObjectList.parse(allRepos);
185+
162186
return [
163187
`Based on the following prompt: ${userPrompt} and the list of repositories
164188

src/prompts/search.ts

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { JsonValue } from "@prisma/client/runtime/library";
22
import { PromptConfig, promptConfig } from "./common";
3+
import { validObjectList, validString } from "./validation";
34

45
interface SearchContextRowForPrompt {
56
key: string;
@@ -10,6 +11,9 @@ export function searchContextPrompt(
1011
query: string,
1112
contextRows: SearchContextRowForPrompt[],
1213
): [string, PromptConfig] {
14+
validString.parse(query);
15+
validObjectList.parse(contextRows);
16+
1317
const config = promptConfig({
1418
maxTokens: 1000,
1519
experimental_telemetry: {

src/prompts/slack.ts

+4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { WebhookAlertDto } from "../checkly/alertDTO";
22
import { convertSlackTimestamp } from "../slackbot/utils";
33
import { PromptConfig, promptConfig } from "./common";
4+
import { validObjectList, validObject, validString } from "./validation";
45

56
export const slackFormatInstructions = `Format all output in Slack mrkdwn format.
67
Generate Slack messages using the following style: *bold*, <link|text>, _italics_, > quote, \`code\`, \`\`\`code block\`\`\`.
@@ -31,6 +32,9 @@ export function channelSummaryPrompt(
3132
alert: WebhookAlertDto,
3233
messageHistory: SlackMsgForPrompt[],
3334
): [string, PromptConfig] {
35+
validObject.parse(alert);
36+
validObjectList.parse(messageHistory);
37+
3438
return [
3539
`You are a Slack channel context collector. Your task is to analyze the given message history based on a specific prompt and provide a concise summary of the relevant context.
3640

src/prompts/sre-assistant.ts

+5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
import { slackFormatInstructions } from "./slack";
2+
import { validString } from "./validation";
23

34
export function generateSREAssistantPrompt(
45
username: string,
56
date: string,
67
alertSummary: string,
78
): string {
9+
validString.parse(username);
10+
validString.parse(date);
11+
validString.parse(alertSummary);
12+
813
return `You are an AI-powered SRE Bot designed to assist in real-time incident management. Your primary goal is to reduce Mean Time To Resolution (MTTR) by automatically aggregating and analyzing contextual data, providing actionable insights, and guiding first responders effectively.
914
1015
CONSTITUTION:

src/prompts/timeframe.ts

+3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import moment from "moment";
22
import { PromptConfig, promptConfig } from "./common";
3+
import { validString } from "./validation";
34

45
export function parseTimeframePrompt(
56
timeframe: string,
67
): [string, PromptConfig] {
8+
validString.parse(timeframe);
9+
710
return [
811
`Parse the following timeframe into a precise timestamp range with and interpretation.
912

0 commit comments

Comments
 (0)