diff --git a/generated_types.json b/generated_types.json index d784dc0ce..be5cc0892 100644 --- a/generated_types.json +++ b/generated_types.json @@ -88,7 +88,8 @@ "org_member", "project_log", "org_project", - "org_audit_logs" + "org_audit_logs", + "project_group" ], "description": "The object type that the ACL applies to" }, @@ -4558,6 +4559,9 @@ }, "required": ["event_type", "action"] }, + { + "$ref": "#/components/schemas/WindowedAutomationConfig" + }, { "$ref": "#/components/schemas/TopicAutomationConfig" }, @@ -7090,6 +7094,224 @@ } ], "description": "Options for the view in the app" + }, + "WindowedAutomationConfig": { + "type": "object", + "properties": { + "event_type": { + "type": "string", + "enum": ["windowed"], + "description": "The type of automation." + }, + "status": { + "$ref": "#/components/schemas/AutomationStatus" + }, + "threshold": { + "type": "object", + "properties": { + "calculation": { + "oneOf": [ + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["btql"] + }, + "btql_query": { + "type": "string", + "minLength": 1, + "description": "A project-scoped BTQL or SQL query without runtime-owned evaluation time bounds" + }, + "output": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["scalar"] + }, + "value_column": { + "type": "string", + "minLength": 1, + "description": "The numeric result column produced by the query" + } + }, + "required": ["type", "value_column"] + } + }, + "required": ["type", "btql_query", "output"] + } + ], + "description": "The calculation evaluated for each window" + }, + "policy": { + "type": "object", + "properties": { + "condition": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["threshold"] + }, + "operator": { + "type": "string", + "enum": ["lt", "lte", "gt", "gte", "eq", "neq"] + }, + "threshold": { + "type": "number" + } + }, + "required": ["type", "operator", "threshold"] + }, + "pending_seconds": { + "type": "integer", + "minimum": 0, + "maximum": 2592000, + "description": "How long the condition must remain breached before firing" + }, + "no_data_behavior": { + "type": "string", + "enum": ["keep_last", "resolve", "alert"], + "description": "How the lifecycle changes when the calculation returns no data" + }, + "renotify_interval_seconds": { + "type": ["integer", "null"], + "minimum": 1, + "maximum": 2592000, + "description": "Optional reminder interval while the automation is firing" + }, + "notify_on_recovery": { + "type": "boolean", + "default": true, + "description": "Whether to deliver actions when a firing automation recovers" + } + }, + "required": [ + "condition", + "pending_seconds", + "no_data_behavior" + ], + "description": "The lifecycle policy applied to each calculation result" + } + }, + "required": ["calculation", "policy"], + "description": "Optional calculation and lifecycle policy that gate scheduled delivery" + }, + "window": { + "type": "object", + "properties": { + "window_seconds": { + "type": "integer", + "minimum": 1, + "maximum": 2592000, + "description": "How much recent data each scheduled run covers" + }, + "schedule": { + "oneOf": [ + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["interval"] + }, + "evaluation_interval_seconds": { + "type": "integer", + "minimum": 1, + "maximum": 2592000, + "description": "How often the automation runs" + } + }, + "required": ["type", "evaluation_interval_seconds"] + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["cron"] + }, + "cron_expression": { + "type": "string", + "minLength": 1, + "description": "A standard five-field cron expression (minute hour day-of-month month day-of-week) controlling when the automation runs" + }, + "timezone": { + "type": ["string", "null"], + "minLength": 1, + "description": "IANA timezone used to interpret the cron expression (defaults to UTC)" + } + }, + "required": ["type", "cron_expression"] + } + ], + "description": "How often the windowed automation runs: at a fixed interval or on a cron schedule" + }, + "evaluation_delay_seconds": { + "type": "integer", + "minimum": 0, + "maximum": 2592000, + "description": "How far behind the present each evaluation window ends" + } + }, + "required": [ + "window_seconds", + "schedule", + "evaluation_delay_seconds" + ] + }, + "actions": { + "type": "array", + "items": { + "oneOf": [ + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["webhook"], + "description": "The type of action to take" + }, + "url": { + "type": "string", + "description": "The webhook URL to send the request to" + } + }, + "required": ["type", "url"] + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["slack"], + "description": "The type of action to take" + }, + "workspace_id": { + "type": "string", + "description": "The Slack workspace ID to post to" + }, + "channel": { + "type": "string", + "description": "The Slack channel ID to post to" + }, + "message_template": { + "type": "string", + "description": "Custom message template for the alert" + } + }, + "required": ["type", "workspace_id", "channel"] + } + ], + "description": "A delivery action available to an automation" + }, + "minItems": 1, + "maxItems": 20, + "description": "The delivery actions to run on each schedule or threshold lifecycle transition" + } + }, + "required": ["event_type", "window", "actions"] } }, "parameters": {} diff --git a/js/src/generated_types.ts b/js/src/generated_types.ts index 273d0a04c..797f75d7f 100644 --- a/js/src/generated_types.ts +++ b/js/src/generated_types.ts @@ -1,4 +1,4 @@ -// Auto-generated file (content hash ecb294cff7f76552) -- do not modify +// Auto-generated file (content hash 7d0333cc2dc03e50) -- do not modify import { z } from "zod/v3"; @@ -16,6 +16,7 @@ export const AclObjectType = z.union([ "project_log", "org_project", "org_audit_logs", + "project_group", ]), z.null(), ]); @@ -1630,6 +1631,65 @@ export const Project = z.object({ settings: ProjectSettings.optional(), }); export type ProjectType = z.infer; +export const WindowedAutomationConfig = z.object({ + event_type: z.literal("windowed"), + status: AutomationStatus.optional(), + threshold: z + .object({ + calculation: z.object({ + type: z.literal("btql"), + btql_query: z.string().min(1), + output: z.object({ + type: z.literal("scalar"), + value_column: z.string().min(1), + }), + }), + policy: z.object({ + condition: z.object({ + type: z.literal("threshold"), + operator: z.enum(["lt", "lte", "gt", "gte", "eq", "neq"]), + threshold: z.number(), + }), + pending_seconds: z.number().int().gte(0).lte(2592000), + no_data_behavior: z.enum(["keep_last", "resolve", "alert"]), + renotify_interval_seconds: z.union([z.number(), z.null()]).optional(), + notify_on_recovery: z.boolean().optional().default(true), + }), + }) + .optional(), + window: z.object({ + window_seconds: z.number().int().gte(1).lte(2592000), + schedule: z.union([ + z.object({ + type: z.literal("interval"), + evaluation_interval_seconds: z.number().int().gte(1).lte(2592000), + }), + z.object({ + type: z.literal("cron"), + cron_expression: z.string().min(1), + timezone: z.union([z.string(), z.null()]).optional(), + }), + ]), + evaluation_delay_seconds: z.number().int().gte(0).lte(2592000), + }), + actions: z + .array( + z.union([ + z.object({ type: z.literal("webhook"), url: z.string() }), + z.object({ + type: z.literal("slack"), + workspace_id: z.string(), + channel: z.string(), + message_template: z.string().optional(), + }), + ]), + ) + .min(1) + .max(20), +}); +export type WindowedAutomationConfigType = z.infer< + typeof WindowedAutomationConfig +>; export const TopicAutomationFacetModel = z.union([ z.enum(["brain-facet-latest", "brain-facet-1", "brain-facet-2"]), z.null(), @@ -1776,6 +1836,7 @@ export const ProjectAutomation = z.object({ }), ]), }), + WindowedAutomationConfig, TopicAutomationConfig, TopicDigestAutomationConfig, ]),