Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
c1da780
feat(cli): add AgenticCheck construct for AI-powered monitoring
thebiglabasky Mar 20, 2026
a77f117
feat(cli): force runParallel for agentic checks
thebiglabasky Mar 20, 2026
5a24001
Revert "feat(cli): force runParallel for agentic checks"
thebiglabasky Apr 6, 2026
583e799
feat(cli): restrict AgenticCheck props to platform-supported fields
thebiglabasky Apr 6, 2026
e24774d
feat(cli): add agentRuntime to AgenticCheck for skills and env var ac…
thebiglabasky Apr 6, 2026
3b24c1c
feat(cli): add code generation support for AgenticCheck
thebiglabasky Apr 6, 2026
4fc6783
test(cli): add unit tests for AgenticCheckCodegen
thebiglabasky Apr 6, 2026
06812d2
docs(cli): add AgenticCheck examples for AI context and boilerplate
thebiglabasky Apr 6, 2026
d768e20
test(cli): add e2e deploy round-trip for AgenticCheck
thebiglabasky Apr 6, 2026
3affc51
docs(cli): add Agentic Check reference for the AI skill
thebiglabasky Apr 6, 2026
c8c922e
fix: regen ai context and fix NO_RETRIES
thebiglabasky Apr 7, 2026
29d72af
docs(cli): correct AgenticCheck skill installation guidance
thebiglabasky Apr 7, 2026
c8e1088
Merge branch 'main' into herve/AI-114/agentic-check-cli-construct
thebiglabasky Apr 7, 2026
8fed994
ci: temporary debug step to fingerprint the e2e Checkly account
thebiglabasky Apr 7, 2026
13f6988
ci: remove temporary e2e account fingerprint debug step
thebiglabasky Apr 7, 2026
4768324
Merge branch 'main' into herve/AI-114/agentic-check-cli-construct
thebiglabasky Apr 7, 2026
36e9198
Merge branch 'main' into herve/AI-114/agentic-check-cli-construct
thebiglabasky Apr 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions examples/boilerplate-project-js/__checks__/agentic.check.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const { AgenticCheck } = require('checkly/constructs')

// Agentic checks are AI-powered: instead of writing code, you describe what
// the check should do in natural language and the agent figures out how.
// Read more at: https://www.checklyhq.com/docs/agentic-checks/

new AgenticCheck('checkly-pricing-page', {
name: 'Checkly pricing page',
prompt:
'Navigate to https://www.checklyhq.com/pricing and verify that at least three plan tiers are displayed on the page.',
// Agentic checks currently run from a single location and follow their own
// frequency cadence (30, 60, 120, 180, 360, 720 or 1440 minutes). The
// construct hardcodes the location and validates the frequency for you.
frequency: 60,
})
15 changes: 15 additions & 0 deletions examples/boilerplate-project/__checks__/agentic.check.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { AgenticCheck } from 'checkly/constructs'

// Agentic checks are AI-powered: instead of writing code, you describe what
// the check should do in natural language and the agent figures out how.
// Read more at: https://www.checklyhq.com/docs/agentic-checks/

new AgenticCheck('checkly-pricing-page', {
name: 'Checkly pricing page',
prompt:
'Navigate to https://www.checklyhq.com/pricing and verify that at least three plan tiers are displayed on the page.',
// Agentic checks currently run from a single location and follow their own
// frequency cadence (30, 60, 120, 180, 360, 720 or 1440 minutes). The
// construct hardcodes the location and validates the frequency for you.
frequency: 60,
})
63 changes: 63 additions & 0 deletions packages/cli/e2e/__tests__/deploy.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,69 @@ describe('deploy', { timeout: 45_000 }, () => {
})
})

describe('deploy-agentic-project', () => {
let fixt: FixtureSandbox

beforeAll(async () => {
fixt = await FixtureSandbox.create({
source: path.join(__dirname, 'fixtures', 'deploy-agentic-project'),
})
}, 180_000)

afterAll(async () => {
await fixt?.destroy()
})

it('Should preview an agentic check deployment', async () => {
// Use --preview so the test doesn't depend on the e2e account being
// entitled to actually create agentic checks. The plan still goes
// through full server-side validation, so we get coverage of the
// deploy round-trip without leaving resources behind.
const { stdout } = await runDeploy(fixt, ['--preview'], {
env: {
PROJECT_LOGICAL_ID: projectLogicalId,
PRIVATE_LOCATION_SLUG_NAME: privateLocationSlugname,
CHECKLY_CLI_VERSION: undefined,
},
})

expect(stdout).toContain(
`Create:
AgenticCheck: agentic-pricing-check
AgenticCheck: agentic-runtime-check
`)
})

it('Should deploy and re-read an agentic check', async () => {
const { stderr, stdout } = await runDeploy(fixt, ['--force'], {
env: {
PROJECT_LOGICAL_ID: projectLogicalId,
PRIVATE_LOCATION_SLUG_NAME: privateLocationSlugname,
CHECKLY_CLI_VERSION: undefined,
},
})

expect(stderr).toBe('')
expect(stdout).not.toContain('Notice: replacing version')

const checks = await getAllResources('checks')
const pricingCheck = checks.find(({ name }: { name: string }) =>
name === 'Agentic Pricing Check')
const runtimeCheck = checks.find(({ name }: { name: string }) =>
name === 'Agentic Runtime Check')

expect(pricingCheck).toBeDefined()
expect(pricingCheck.checkType).toEqual('AGENTIC')
// The construct hardcodes a single location for agentic checks.
expect(pricingCheck.locations).toEqual(['us-east-1'])
expect(pricingCheck.tags).toEqual(expect.arrayContaining(['e2e', 'agentic']))

expect(runtimeCheck).toBeDefined()
expect(runtimeCheck.checkType).toEqual('AGENTIC')
expect(runtimeCheck.locations).toEqual(['us-east-1'])
})
})

describe('test-only-project', () => {
let fixt: FixtureSandbox

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* eslint-disable */
import { AgenticCheck, Frequency } from 'checkly/constructs'

new AgenticCheck('agentic-pricing-check', {
name: 'Agentic Pricing Check',
prompt:
'Navigate to https://www.checklyhq.com/pricing and verify that at least three plan tiers are displayed on the page.',
activated: false,
muted: true,
frequency: Frequency.EVERY_1H,
tags: ['e2e', 'agentic'],
})

new AgenticCheck('agentic-runtime-check', {
name: 'Agentic Runtime Check',
prompt:
'Navigate to https://www.checklyhq.com and verify the homepage loads with the main heading visible.',
activated: false,
muted: true,
frequency: 60,
agentRuntime: {
skills: ['addyosmani/web-quality-skills'],
environmentVariables: [
'ENVIRONMENT_URL',
{ name: 'TEST_USER_EMAIL', description: 'Login email for the test account' },
],
},
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const config = {
projectName: 'Deploy Agentic Project',
logicalId: process.env.PROJECT_LOGICAL_ID,
repoUrl: 'https://github.com/checkly/checkly-cli',
}
export default config
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "project",
"version": "1.0.0",
"dependencies": {
"jiti": "^2.6.1"
}
}
57 changes: 57 additions & 0 deletions packages/cli/src/ai-context/context.fixtures.json
Original file line number Diff line number Diff line change
Expand Up @@ -824,6 +824,63 @@
"privateLocations": []
}
},
{
"logicalId": "example-agentic-check",
"physicalId": "dddddddd-dddd-dddd-dddd-dddddddddddd",
"type": "check",
"member": true,
"pending": true,
"payload": {
"id": "dddddddd-dddd-dddd-dddd-dddddddddddd",
"checkType": "AGENTIC",
"name": "Example Agentic Check",
"frequency": 60,
"frequencyOffset": 0,
"activated": true,
"muted": false,
"shouldFail": false,
"locations": [
"us-east-1"
],
"accountId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
"created_at": "2025-10-28T17:25:17.037Z",
"updated_at": null,
"tags": [
"app:webshop"
],
"alertSettings": {
"reminders": {
"amount": 0,
"interval": 5
},
"escalationType": "RUN_BASED",
"runBasedEscalation": {
"failedRunThreshold": 1
},
"timeBasedEscalation": {
"minutesFailingThreshold": 5
},
"parallelRunFailureThreshold": {
"enabled": false,
"percentage": 10
}
},
"useGlobalAlertSettings": true,
"groupId": null,
"groupOrder": null,
"retryStrategy": null,
"runParallel": false,
"triggerIncident": false,
"prompt": "Navigate to https://www.checklyhq.com/pricing and verify that at least three plan tiers are displayed on the page.",
"agenticCheckData": {
"skills": [],
"selectedEnvironmentVariables": [],
"assertionRules": []
},
"alertChannelSubscriptions": [],
"privateLocations": []
}
},
{
"logicalId": "example-maintenance-window",
"physicalId": 1000001,
Expand Down
9 changes: 9 additions & 0 deletions packages/cli/src/ai-context/context.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
export const REFERENCES = [
{
id: 'configure-agentic-checks',
description: 'Agentic Check construct (`AgenticCheck`) for AI-powered prompt-driven monitoring with skill and env var allowlists',
},
{
id: 'configure-api-checks',
description: 'Api Check construct (`ApiCheck`), assertions, and authentication setup scripts',
Expand Down Expand Up @@ -147,6 +151,11 @@ export default defineConfig({
`,
reference: 'https://www.checklyhq.com/docs/constructs/project/',
},
AGENTIC_CHECK: {
templateString: '<!-- EXAMPLE: AGENTIC_CHECK -->',
exampleConfigPath: 'resources/agentic-checks/example-agentic-check.check.ts',
reference: 'https://www.checklyhq.com/docs/constructs/agentic-check/',
},
BROWSER_CHECK: {
templateString: '<!-- EXAMPLE: BROWSER_CHECK -->',
exampleConfigPath:
Expand Down
52 changes: 52 additions & 0 deletions packages/cli/src/ai-context/references/configure-agentic-checks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Agentic Checks

- Import the `AgenticCheck` construct from `checkly/constructs`.
- Agentic checks are AI-powered: instead of writing code, you describe what the check should do in natural language with the `prompt` property. The agent decides how to satisfy the prompt at runtime.
- Write prompts as concrete imperative steps, not vague goals. Tell the agent which URL to navigate to and what specific signals confirm success — for example, "Navigate to https://example.com/pricing and verify that at least three plan tiers are displayed", not "Check that pricing works".
- Keep prompts under 10000 characters. The construct will fail validation otherwise.
- **Frequency is restricted.** Only `30`, `60`, `120`, `180`, `360`, `720`, or `1440` minutes are accepted (matching `Frequency.EVERY_30M`, `EVERY_1H`, `EVERY_2H`, `EVERY_3H`, `EVERY_6H`, `EVERY_12H`, `EVERY_24H`). Anything else fails validation.
- **Locations are not configurable.** Agentic checks currently run from a single fixed location. The construct hardcodes it — do not pass `locations` or `privateLocations`.
- **Several common check fields are intentionally omitted** from `AgenticCheckProps`: `runParallel`, `retryStrategy`, `shouldFail`, `doubleCheck`, `triggerIncident`, and `groupId`. The platform does not yet honor these for agentic checks. Setting them in the construct is a TypeScript error.
- **Important:** The target URL must be publicly accessible. Checks run on Checkly's cloud infrastructure, not locally. If the user is developing against localhost, suggest a tunneling tool (ngrok, cloudflare tunnel) or a preview/staging deployment.
- **Plan-gated:** Agentic checks require the `AGENTIC_CHECKS` entitlement on the account. Run `npx checkly skills manage` to check entitlements before using.

## `agentRuntime` — security boundary for skills and env vars

`agentRuntime` is the explicit allowlist of resources the agent may use at execution time. Anything not declared in `agentRuntime` is **unavailable** to the agent. Treat it as a security boundary: the smaller the runtime surface, the smaller the blast radius of any prompt injection.

```typescript
agentRuntime: {
// Additional skills to load on top of the runner's defaults (the
// `playwright-cli` skill is preloaded automatically — you don't need
// to declare it). Each entry is passed verbatim to `npx skills add`
// on the runner, so any third-party skill published to https://skills.sh
// works — not just Checkly's own. Supported identifier forms:
// - full URL form: 'https://skills.sh/microsoft/playwright-cli/playwright-cli'
// - owner/repo form: 'addyosmani/web-quality-skills'
// - plain name: 'cost-optimization'
skills: ['addyosmani/web-quality-skills'],

// Environment variables the agent is allowed to read at runtime.
// Anything not listed here is hidden from the agent process — even
// if it's defined at the project or check level.
environmentVariables: [
// Bare string form: variable name only.
'ENVIRONMENT_URL',
// Object form: pair the variable with a description so the agent
// can decide when to read it. Descriptions are passed to the model
// and are truncated to 200 characters.
{ name: 'TEST_USER_EMAIL', description: 'Login email for the test account' },
],
},
```

- Only declare env vars the agent **needs**. Adding a variable to `environmentVariables` exposes it to the model and to anything the model invokes via skills.
- Descriptions are not just documentation — they steer the model's decisions. Use them to disambiguate variables that have non-obvious names.
- The runner installs each skill via `npx skills add` at the start of every check run. The CLI does not validate the skill identifier at deploy time, so a typo will not surface until the first run.
- The `playwright-cli` skill is preloaded for every agentic check. Only declare additional skills here.

## Assertion rules

The agent generates its own assertion rules on the first successful run, and the platform persists them server-side. **The CLI construct does not expose assertion rules** — do not try to set them. They survive across deploys: importing an existing agentic check via `checkly import` will not surface them in the generated TypeScript, and a subsequent deploy of that file will not erase them on the backend.

<!-- EXAMPLE: AGENTIC_CHECK -->
2 changes: 1 addition & 1 deletion packages/cli/src/ai-context/skill.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: checkly
description: Set up, create, test and manage monitoring checks using the Checkly CLI. Use when working with API Checks, Browser Checks, URL Monitors, ICMP Monitors, Playwright Check Suites, Heartbeat Monitors, Alert Channels, Dashboards, or Status Pages.
description: Set up, create, test and manage monitoring checks using the Checkly CLI. Use when working with Agentic Checks, API Checks, Browser Checks, URL Monitors, ICMP Monitors, Playwright Check Suites, Heartbeat Monitors, Alert Channels, Dashboards, or Status Pages.
allowed-tools: Bash(npx:checkly:*) Bash(npm:install:*)
metadata:
author: checkly
Expand Down
1 change: 1 addition & 0 deletions packages/cli/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const CheckTypes = {
ICMP: 'ICMP',
DNS: 'DNS',
URL: 'URL',
AGENTIC: 'AGENTIC',
} as const

export type CheckType = typeof CheckTypes[keyof typeof CheckTypes]
Expand Down
Loading
Loading