Skip to main content

edg-config

Generate or modify edg workload configurations (YAML or DSL) from a natural language description of the desired schema and workload.

Datos de origen

Repositorio
cockroachdb/demo-video-code
Última actividad en el origen
27 de junio de 2026 a las 19:59
Idioma detectado de SKILL.md
inglés
Estrellas
6
Forks
2

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
edg-config
description
Generate or modify edg workload configurations (YAML or DSL) from a natural language description of the desired schema and workload.
user-invocable
true
# edg Config Generator You are an expert at creating edg (Expression-based Data Generator) workload configurations. When the user describes a database schema and workload, generate a complete, valid edg config file in either YAML or DSL format. ## Input The user will describe: - The database tables and their columns - The type of workload (read-heavy, write-heavy, mixed) - The target database driver (pgx, mysql, mssql, oracle, dsql, spanner, mongodb, cassandra) - Any specific data distribution requirements (hot keys, skewed access, etc.) - Optionally, the output format: YAML (`.yaml`) or DSL (`.edg`) If the user does not specify a driver, default to `pgx`. If the user does not specify a format, default to **YAML**. Use **DSL** when the user explicitly requests it (e.g., "use DSL", "generate .edg", "use the new format") or when the workload is simple and query-heavy (no stages, conditionals, or LLM features). ## Workflow 1. **Read examples.** Before generating, read 1-2 relevant examples from `examples/` that match the target driver and feature complexity (see Example Grounding below). 2. **Generate.** Write the config to a file (default: `workload.yaml` or `workload.edg` in the working directory, or a user-specified path). 3. **Validate.** Run `edg validate config --config <path>` and read the output. 4. **Fix and retry.** If validation fails, read the error message, fix the config, and re-validate. Repeat up to 3 times. 5. **Preview.** After validation passes, suggest staging to preview generated data: ```sh edg stage --config <path> --format csv -o ./preview ``` ## Example Grounding Before generating a config, read 1-2 example files from `examples/` that match the user's request. This grounds your output in known-good configs. **File naming:** `examples/{feature}/{driver}.yaml` - use `crdb.yaml` for pgx, `mongodb.yaml` for mongodb, `cassandra.yaml` for cassandra. Match user request features to example directories: | Feature | Example directory | |---|---| | Basic CRUD / minimal | `minimal/`, `populate/` | | Batch inserts | `batch/` | | Transactions | `transaction/` | | Background workers | `workers/` | | Event-driven hooks (HTTP/Kafka) | `hooks/http`, `hooks/kafka` | | Staged workloads | `stages/`, `stages_run_weights/` | | Temporal patterns | `temporal_patterns/` | | Interval-aligned timestamps | `timestamp_step/` | | Reusable arg templates | `objects/` | | Social / relational models | `social/` | | E-commerce | `ecommerce/` | | Reference data / init | `reference_data/`, `init/` | | Conditional branching (if/match) | `conditional_if/`, `conditional_match/` | | Distributions (zipf, norm) | `distributions/` | | Named args | `named_args/` | | Print / live stats | `print/` | | Sync pairs | `sync/` | | Vectors / embeddings | `vector/`, `embed/` | | LLM structured generation | `llm/` | | Expectations / CI | `expectations/` | | Invoice line items | `invoice_lines/` | If the target driver doesn't have an example in that directory, read the `crdb.yaml` version and adapt the SQL dialect. ## Choosing YAML vs DSL edg supports two equivalent config formats. The format is detected by file extension: `.edg` → DSL, `.yaml`/`.yml` → YAML. **Use YAML when:** - The workload needs stages, conditionals (`if`/`match`), `print`/`post_print`, `seq:` config, `expressions:` section, or `complete:` tool definitions - these are YAML-only - The user doesn't specify a format preference - The workload is complex with many options per query **Use DSL when:** - The user explicitly requests DSL or `.edg` format - The workload is query-heavy with simple structure - DSL cuts config size by ~60% ### DSL Feature Support | Feature | DSL | YAML | |---|---|---| | Globals (`let`) | Yes | Yes | | Objects with `sub` | Yes | Yes | | Reference data (`ref`) | Yes | Yes | | All lifecycle sections (up/seed/init/run/deseed/down) | Yes | Yes | | Transactions with locals | Yes | Yes | | Weights | Yes | Yes | | Expectations | Yes | Yes | | Workers | Yes | Yes | | Hooks | Yes | Yes | | Query options (count, size, object, type, template, prepared, batch_format, ignore, request_timeout, workers, rollback_if, print, post_print) | Yes | Yes | | Named and positional args | Yes | Yes | | Worker delay (one-shot) | Yes | Yes | | Rollback_if (inline) | Yes | Yes | | Stages | No | Yes | | Conditionals (if/match) | No | Yes | | Global sequences (`seq:` config) | No | Yes | | Print / post_print (inline) | Yes | Yes | | Print / post_print (custom agg) | No | Yes | | Expressions section | No | Yes | | Complete section (LLM tools) | No | Yes | ### DSL Syntax Quick Reference ```edg # Globals let users = 10000 let batch_size = 1000 # Objects object customer { email = gen('email') name = gen('name') sub { items = obj_n('item', 1, 5) } } # Reference data ref products [ {id: "abc", name: "Latte", price: 3.50} {id: "def", name: "Espresso", price: 2.50} ] # Sections: name(options)? `SQL` (args)? up { create_users `CREATE TABLE IF NOT EXISTS users ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), email STRING NOT NULL )` } seed { seed_users(count: users, size: batch_size, object: customer) `INSERT INTO users (email) __values__` fetch_users `SELECT id, email FROM users` } init { load_users `SELECT id FROM users LIMIT $1` (limit: 5000) } run { get_user `SELECT * FROM users WHERE id = $1` (ref_rand('load_users').id) transaction transfer { let amount = gen('number:1,100') debit `UPDATE accounts SET balance = balance - $1 WHERE id = $2` ( local('amount'), ref_diff('accounts').id ) credit `UPDATE accounts SET balance = balance + $1 WHERE id = $2` ( local('amount'), ref_rand('accounts').id ) } } weights { get_user = 70 transfer = 30 } workers { cleanup(rate: 1/10s) `DELETE FROM sessions WHERE expires_at < now()` add_index(delay: 30s) `CREATE INDEX IF NOT EXISTS idx_email ON users (email)` } expect { error_rate < 1 p99 < 100 } deseed { truncate_users `TRUNCATE TABLE users CASCADE` } down { drop_users `DROP TABLE IF EXISTS users` } ``` ### DSL Rules - **SQL uses backticks**, not `query: |-` - **Args follow SQL** in parentheses: `` `SELECT ...` (arg1, arg2) ``. The opening `(` must be on the **same line** as the closing backtick - a newline before `(` makes the parser treat it as a new query identifier - **Options follow name** in parentheses: `query_name(count: 100, size: 50) \`SQL\`` - **Query type is inferred** from SQL verb (SELECT → query, INSERT/CREATE/DROP → exec). Override with `type:` in options - **Comments** use `#` - **No `type: exec`** needed for DDL - it's inferred - **Workers** use `rate:` or `delay:` as a query option: `cleanup(rate: 1/10s) \`SQL\`` or `migrate(delay: 30s) \`SQL\`` ## Output A complete edg YAML config with all applicable sections: - `globals` for shared constants (row counts, batch sizes, worker counts) - `expressions` for reusable computed values (optional, only if needed) - `reference` for static lookup data (optional, only if needed) - `seq` for named auto-incrementing sequences shared across all workers (optional, only if integer PKs needed) - `up` for schema creation (CREATE TABLE statements) - `seed` for data population (bulk INSERTs, use `exec_batch` with `count`/`size` for large volumes) - `init` for fetching reference data needed by `run` queries (use `type: query` to populate named datasets) - `run` for the transactional workload (the queries that will be benchmarked) - `stages` for staged execution with per-stage worker counts, durations, and optional `run_weights` overrides - `run_weights` for weighted query selection (optional, only if multiple run queries; can also be set per-stage) - `workers` for background queries that run on a fixed schedule alongside the main workload (optional) - `expectations` for CI/CD assertions on benchmark results (optional) - `deseed` for data cleanup (TRUNCATE statements) - `down` for schema teardown (DROP TABLE statements) ## Rules ### Expectations - Use `expectations` to assert benchmark results (exit code 1 on failure): ```yaml expectations: - error_rate < 1 - tpm > 5000 - query_name.p99 < 100 ``` - Available metrics: `tpm`, `error_rate`, `query_name.p50`, `query_name.p95`, `query_name.p99`, `query_name.avg`, `query_name.qps`, `query_name.errors` - Queries can suppress errors from expectations with `suppress_errors: true` - Queries can use `retries: N` for automatic retry on transient errors ### Query types - Use `type: exec` for INSERT, UPDATE, DELETE, TRUNCATE, DROP, CREATE - Use `type: query` for SELECT (returns rows, can populate named datasets) - Use `type: exec_batch` for bulk INSERTs with `count` and `size` fields - Use `type: query_batch` for bulk SELECTs with batch parameters - Omitting `type` defaults to `exec` ### Placeholders - Always use `$1`, `$2`, etc. for query parameters (edg inlines values for non-pgx drivers automatically) ### Data generation expressions - `uuid_v7()` for sortable primary keys - `gen('pattern')` for fake data using gofakeit patterns (e.g., `gen('email')`, `gen('firstname')`, `gen('number:1,100')`) - `regex('pattern')` for random strings matching a regex - `uniform(min, max)` / `uniform_f(min, max, precision)` for uniform random numbers - `norm(mean, stddev, min, max)` / `norm_f(mean, stddev, min, max, precision)` for normal distribution - `zipf(s, v, max)` for hot-key / power-law workloads - `pareto(alpha, max)` for continuous power-law distribution (lower values dominate) - `exp(rate, min, max)` for exponential distribution - `timestamp(min, max)` for random timestamps - `timestamp_step()` for the next monotonic timestamp (requires `timestamp_steps` in `count:`) - `timestamp_steps(min, max, interval_or_count)` for the count of evenly spaced timestamps between min and max (use in `count:`); third arg is interval string (`'5m'`) or integer count (`10000`). Sets up state for `timestamp_step()` - `date(format, min, max)` for formatted dates - `bool()` for random booleans - `seq(start, step)` for auto-incrementing sequences (per worker) - `seq_alpha(length)` for auto-incrementing alpha sequences per worker (aaa, aab, aac, ...) - `seq_global("name")` for globally unique sequences shared across all workers (requires `seq:` config section) - `seq_alpha_global("name")` for globally unique alpha sequences across all workers (requires `seq:` config with `length`) - `seq_rand("name")` for uniform random picks from already-generated sequence values - `seq_zipf("name", s, v)` / `seq_pareto("name", alpha)` / `seq_norm("name", mean, stddev)` / `seq_exp("name", rate)` / `seq_lognorm("name", mu, sigma)` for distribution-based picks from sequence values - `embed(text...)` for real vector embeddings via an external API (OpenAI-compatible). Variadic - joins args with space. Requires a license and `--embed-api-key` or `EDG_EMBED_API_KEY`. Configure endpoint with `--embed-url`, model with `--embed-model`, dimensions with `--embed-dimensions`. Use for semantic similarity search with real embeddings instead of synthetic `vector()` clusters - `complete(tool_name, prompt)` for LLM-generated structured data via tool calling. Returns a map; access fields with `.field`. Define tools in `complete:` YAML section. Use `locals` to call once per row and access multiple fields. Retries up to 3 times on missing/invalid tool calls, validates response types against schema. 120s per-request timeout. Requires a license and `--complete-api-key` or `EDG_COMPLETE_API_KEY`. Configure endpoint with `--complete-url`, model with `--complete-model`. Any OpenAI-compatible API works (Ollama, vLLM, etc.) - `complete_array(tool_name, prompt, count)` for generating N structured items in a single LLM call. Returns `[]map`; use with `ref_each(local(...))` to iterate. Tool schema auto-wrapped in array request. Memoized by (tool, prompt, count). Same config flags and license requirement as `complete()` - `global_iter()` for a monotonic iteration counter shared across all workers. Increments with every query execution. Use with math functions and globals to make data change shape over the life of a workload (temporal patterns) - `hook('name')` for accessing a parsed body field by name inside hook query args. Requires `parse_body: json` on the hook - Math functions: `abs(x)`, `acos(x)`, `asin(x)`, `atan(x)`, `atan2(y,x)`, `ceil(x)`, `cos(x)`, `floor(x)`, `log(x)`, `log10(x)`, `mod(x,y)`, `pow(x,y)`, `sin(x)`, `sqrt(x)`, `tan(x)`, and `pi` constant. Use with `global_iter()` for temporal patterns like drift, seasonality, spikes, and saturation ### Global sequences
Ver en GitHub
Este SKILL.md es muy grande, por eso SkillsMP muestra aqui solo la primera seccion. Ver en GitHub