Skip to content

Commit 6656e4a

Browse files
committed
Integrate metrics with the AI query service
1 parent 9e1799c commit 6656e4a

File tree

2 files changed

+56
-8
lines changed

2 files changed

+56
-8
lines changed

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/AITabContent.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ export function AITabContent({
3030
"Top 50 most expensive runs this week",
3131
"Average execution duration by task this week",
3232
"Run counts by tag in the past 7 days",
33+
"CPU utilization over time by task",
34+
"Peak memory usage per run",
3335
];
3436

3537
return (

apps/webapp/app/v3/services/aiQueryService.server.ts

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export class AIQueryService {
5555

5656
constructor(
5757
private readonly tableSchema: TableSchema[],
58-
private readonly model: LanguageModelV1 = openai("gpt-4o-mini")
58+
private readonly model: LanguageModelV1 = openai("codex-mini-latest")
5959
) {}
6060

6161
/**
@@ -65,7 +65,7 @@ export class AIQueryService {
6565
private buildSetTimeFilterTool() {
6666
return tool({
6767
description:
68-
"Set the time filter for the query page UI instead of adding triggered_at conditions to the query. ALWAYS use this tool when the user wants to filter by time (e.g., 'last 7 days', 'past hour', 'yesterday'). The UI will apply this filter automatically. Do NOT add triggered_at to the WHERE clause - use this tool instead.",
68+
"Set the time filter for the query page UI instead of adding time conditions to the query. ALWAYS use this tool when the user wants to filter by time (e.g., 'last 7 days', 'past hour', 'yesterday'). The UI will apply this filter automatically using the table's time column (triggered_at for runs, bucket_start for metrics). Do NOT add triggered_at or bucket_start to the WHERE clause for time filtering - use this tool instead.",
6969
parameters: z.object({
7070
period: z
7171
.string()
@@ -366,14 +366,21 @@ export class AIQueryService {
366366
* Build the system prompt for the AI
367367
*/
368368
private buildSystemPrompt(schemaDescription: string): string {
369-
return `You are an expert SQL assistant that generates TSQL queries for a task run analytics system. TSQL is a SQL dialect similar to ClickHouse SQL.
369+
return `You are an expert SQL assistant that generates TSQL queries for a task analytics system. TSQL is a SQL dialect similar to ClickHouse SQL.
370370
371371
## Your Task
372372
Convert natural language requests into valid TSQL SELECT queries. Always validate your queries using the validateTSQLQuery tool before returning them.
373373
374374
## Available Schema
375375
${schemaDescription}
376376
377+
## Choosing the Right Table
378+
379+
- **runs** — Task run records (status, timing, cost, output, etc.). Use for questions about runs, tasks, failures, durations, costs, queues.
380+
- **metrics** — Host and runtime metrics collected during task execution (CPU, memory). Use for questions about resource usage, CPU utilization, memory consumption, or performance monitoring. Each row is a 10-second aggregation bucket tied to a specific run.
381+
382+
When the user mentions "CPU", "memory", "utilization", "resource usage", or similar terms, query the \`metrics\` table. When they mention "runs", "tasks", "failures", "status", "duration", or "cost", query the \`runs\` table.
383+
377384
## TSQL Syntax Guide
378385
379386
TSQL supports standard SQL syntax with some ClickHouse-specific features:
@@ -437,16 +444,45 @@ LIMIT 1000
437444
Only use explicit \`toStartOfHour\`/\`toStartOfDay\` etc. if the user specifically requests a particular bucket size (e.g., "group by hour", "bucket by day").
438445
439446
### Common Patterns
447+
448+
#### Runs table
440449
- Status filter: WHERE status = 'Failed' or WHERE status IN ('Failed', 'Crashed')
441-
- Time filtering: Use the \`setTimeFilter\` tool (NOT triggered_at in WHERE clause)
450+
- Time filtering: Use the \`setTimeFilter\` tool (NOT triggered_at/bucket_start in WHERE clause)
451+
452+
#### Metrics table
453+
- Filter by metric name: WHERE metric_name = 'process.cpu.utilization'
454+
- Filter by run: WHERE run_id = 'run_abc123'
455+
- Filter by task: WHERE task_identifier = 'my-task'
456+
- Available metric names: process.cpu.utilization, process.cpu.time, process.memory.usage, system.memory.usage, system.memory.utilization, system.network.io, system.network.dropped, system.network.errors
457+
- Use max_value or last_value for gauges (CPU utilization, memory usage), sum_value for counters (CPU time, network IO)
458+
459+
\`\`\`sql
460+
-- CPU utilization over time for a task
461+
SELECT timeBucket(), task_identifier, avg(max_value) AS avg_cpu
462+
FROM metrics
463+
WHERE metric_name = 'process.cpu.utilization'
464+
GROUP BY timeBucket, task_identifier
465+
ORDER BY timeBucket
466+
LIMIT 1000
467+
\`\`\`
468+
469+
\`\`\`sql
470+
-- Peak memory usage per run
471+
SELECT run_id, task_identifier, max(max_value) AS peak_memory_bytes
472+
FROM metrics
473+
WHERE metric_name = 'process.memory.usage'
474+
GROUP BY run_id, task_identifier
475+
ORDER BY peak_memory_bytes DESC
476+
LIMIT 100
477+
\`\`\`
442478
443479
## Important Rules
444480
445481
1. NEVER use SELECT * - ClickHouse is a columnar database where SELECT * has very poor performance
446482
2. Always select only the specific columns needed for the request
447483
3. When column selection is ambiguous, use the core columns marked [CORE] in the schema
448-
4. **TIME FILTERING**: When the user wants to filter by time (e.g., "last 7 days", "past hour", "yesterday"), ALWAYS use the \`setTimeFilter\` tool instead of adding \`triggered_at\` conditions to the query. The UI has a time filter that will apply this automatically.
449-
5. Do NOT add \`triggered_at\` to WHERE clauses - use \`setTimeFilter\` tool instead. If the user doesn't specify a time period, do NOT add any time filter (the UI defaults to 7 days).
484+
4. **TIME FILTERING**: When the user wants to filter by time (e.g., "last 7 days", "past hour", "yesterday"), ALWAYS use the \`setTimeFilter\` tool instead of adding time conditions to the WHERE clause. The UI has a time filter that will apply this automatically. This applies to both the \`runs\` table (triggered_at) and the \`metrics\` table (bucket_start).
485+
5. Do NOT add \`triggered_at\` or \`bucket_start\` to WHERE clauses for time filtering - use \`setTimeFilter\` tool instead. If the user doesn't specify a time period, do NOT add any time filter (the UI defaults to 7 days).
450486
6. **TIME BUCKETING**: When the user wants to see data over time or in time buckets, use \`timeBucket()\` in SELECT and reference it as \`timeBucket\` in GROUP BY / ORDER BY. Only use manual bucketing functions (toStartOfHour, toStartOfDay, etc.) when the user explicitly requests a specific bucket size.
451487
7. ALWAYS use the validateTSQLQuery tool to check your query before returning it
452488
8. If validation fails, fix the issues and try again (up to 3 attempts)
@@ -472,14 +508,19 @@ If you cannot generate a valid query, explain why briefly.`;
472508
* Build the system prompt for edit mode
473509
*/
474510
private buildEditSystemPrompt(schemaDescription: string): string {
475-
return `You are an expert SQL assistant that modifies existing TSQL queries for a task run analytics system. TSQL is a SQL dialect similar to ClickHouse SQL.
511+
return `You are an expert SQL assistant that modifies existing TSQL queries for a task analytics system. TSQL is a SQL dialect similar to ClickHouse SQL.
476512
477513
## Your Task
478514
Modify the provided TSQL query according to the user's instructions. Make only the changes requested - preserve the existing query structure where possible.
479515
480516
## Available Schema
481517
${schemaDescription}
482518
519+
## Choosing the Right Table
520+
521+
- **runs** — Task run records (status, timing, cost, output, etc.). Use for questions about runs, tasks, failures, durations, costs, queues.
522+
- **metrics** — Host and runtime metrics collected during task execution (CPU, memory). Use for questions about resource usage, CPU utilization, memory consumption, or performance monitoring. Each row is a 10-second aggregation bucket tied to a specific run.
523+
483524
## TSQL Syntax Guide
484525
485526
TSQL supports standard SQL syntax with some ClickHouse-specific features:
@@ -539,11 +580,16 @@ ORDER BY timeBucket
539580
LIMIT 1000
540581
\`\`\`
541582
583+
### Common Metrics Patterns
584+
- Filter by metric: WHERE metric_name = 'process.cpu.utilization'
585+
- Available metric names: process.cpu.utilization, process.cpu.time, process.memory.usage, system.memory.usage, system.memory.utilization, system.network.io, system.network.dropped, system.network.errors
586+
- Use max_value or last_value for gauges (CPU utilization, memory usage), sum_value for counters (CPU time, network IO)
587+
542588
## Important Rules
543589
544590
1. NEVER use SELECT * - ClickHouse is a columnar database where SELECT * has very poor performance
545591
2. If the existing query uses SELECT *, replace it with specific columns (use core columns marked [CORE] as defaults)
546-
3. **TIME FILTERING**: When the user wants to change time filtering (e.g., "change to last 30 days"), use the \`setTimeFilter\` tool instead of modifying \`triggered_at\` conditions. If the existing query has \`triggered_at\` in WHERE, consider removing it and using \`setTimeFilter\` instead.
592+
3. **TIME FILTERING**: When the user wants to change time filtering (e.g., "change to last 30 days"), use the \`setTimeFilter\` tool instead of modifying time column conditions. If the existing query has \`triggered_at\` or \`bucket_start\` in WHERE for time filtering, consider removing it and using \`setTimeFilter\` instead.
547593
4. **TIME BUCKETING**: When adding time-series grouping, use \`timeBucket()\` in SELECT and reference it as \`timeBucket\` in GROUP BY / ORDER BY. Only use manual bucketing functions (toStartOfHour, toStartOfDay, etc.) when the user explicitly requests a specific bucket size.
548594
5. ALWAYS use the validateTSQLQuery tool to check your modified query before returning it
549595
6. If validation fails, fix the issues and try again (up to 3 attempts)

0 commit comments

Comments
 (0)