Agent (hey)¶
The ml-container-creator hey command starts a conversational AI agent that helps you understand your project configuration, troubleshoot deployment issues, plan workflows, get optimization recommendations, and execute do/ scripts with explicit user confirmation. It's powered by Amazon Bedrock (Claude Sonnet) and can operate as both an advisor and an autonomous executor — planning and running do/ script chains via --goal mode.
Prerequisites¶
- Python 3.10+ with agent dependencies installed. The simplest path is:
This provisions a dedicated virtual environment at
.mlcc/hey-venv/, installs the packages fromsrc/agent/requirements-agent.txt(usinguvwhen available, otherwisepython3 -m venv+pip), and recordsvenv_pathin.mlcc/agent-config.json. Subsequentmcc heyinvocations automatically use that environment. Re-runmcc hey initany time to upgrade the packages.
To install manually instead:
- AWS credentials configured with Bedrock access (the agent callsConverseStream)
- Bootstrap profile set up via ml-container-creator bootstrap
Tip
Run ml-container-creator hey --offline to verify your environment without incurring any Bedrock costs.
Quick Start¶
# Inside a project directory — project-aware conversation
cd my-vllm-project/
ml-container-creator hey
# Outside a project directory — getting-started guidance
cd ~/
ml-container-creator hey
# Static health check only (no Bedrock, no cost)
ml-container-creator hey --offline
# Plan and execute toward a goal
ml-container-creator hey --goal "build and push my container"
# Fully autonomous goal execution
ml-container-creator hey --goal "validate my configuration" --auto
# Preview the plan without executing anything
ml-container-creator hey --goal "stage and deploy Qwen3-4B" --dry-run
Modes¶
Project Mode (inside a project directory)¶
When do/config exists in the current directory, the agent enters project mode:
- Loads your full project context:
do/config,do/ic/*.conf,do/training/config.yaml, Dockerfile, adapters, and bootstrap profile - Runs an environment health check at startup (prerequisites, AWS credentials, MCP server availability)
- Answers questions specific to your configuration
- Makes recommendations referencing your exact file paths and variable names
Getting-Started Mode (outside a project directory)¶
When no do/config is found, the agent enters getting-started mode:
- Checks if you've bootstrapped (
~/.ml-container-creator/config.json) - Validates prerequisites (Node.js, Python, AWS credentials, pip packages)
- Walks you through first-time setup and project creation
- Explains what the tool does and how the lifecycle works
Goal Mode¶
Goal mode turns hey into an autonomous executor. Provide a natural-language objective and the agent plans, resolves unknowns, and chains do/ scripts to completion.
Quick start¶
# Preview the plan without running anything
python3 src/agent/agent.py --goal "build and push my container" --dry-run
# Run the plan with per-step confirmation on costly steps
python3 src/agent/agent.py --goal "build and push my container"
# Fully autonomous — auto-answers unknowns, runs read-only steps without prompting
python3 src/agent/agent.py --goal "validate my configuration" --auto
How it works¶
-
GoalPlanner converts the objective into an ordered list of
do/script steps. Each step is stamped with a confirmation class:auto(read-only, runs without prompting) orconfirm(costly or mutating, always pauses fory/N). -
QuestionResolver fills in any unknowns from project context (
do/config, IC confs), the capability matrix, and instance-sizer defaults. Under--auto, unknowns that can be resolved from context are filled silently. Infrastructure identifiers (endpoint names, ARNs, bucket names) are never invented — if they're missing from context, the agent asks once. -
ChainRunner walks the plan step by step. On step failure: stop, diagnose, prompt [R]etry / [S]kip / [A]bort.
Confirmation policy¶
Every do/ script has a permission class that governs whether the agent may run it and whether it pauses for approval first. The model is three-state:
| Class | Behavior |
|---|---|
auto |
Runs without prompting (safe, read-only, or idempotent). |
confirm |
Pauses for a y/N approval before running (mutating, costly, or destructive). |
denied |
Blocked entirely — never runs, even if a plan step references it. |
A script's class is resolved from script_classes in config/agent.json and your project-local .mlcc/agent-config.json. Any script not listed in script_classes falls back to default_class (default: "confirm"). The system is opt-out, not opt-in: unlisted scripts are permitted but require confirmation, unless you set default_class to "denied" to lock the agent down to an explicit allow-list.
Default classes (from src/agent/execution_config.py — the source of truth):
| Class | Default scripts |
|---|---|
auto |
do/test, do/status, do/logs, do/validate, do/export, do/ci |
confirm |
do/stage, do/build, do/push, do/submit, do/deploy, do/tune, do/train, do/adapter, do/clean, do/register, do/optimize, do/benchmark |
is_permitted(script) returns true unless the resolved class is denied. The mode field provides a global override: mode: "all" forces every script to confirm (safe default for unfamiliar projects); mode: "none" runs everything as auto (CI/scripted use); mode: "default" (the default) consults each script's class.
Editing permissions — mcc hey config permissions¶
The fastest way to review and change per-script permissions is the interactive TUI:
It renders a scrollable table of all known do/ scripts with their current permission state:
mcc hey config permissions (.mlcc/agent-config.json)
Script Permission
─────────────────────────────────────────────────
❯ do/stage [ CONFIRM ]
do/submit [ CONFIRM ]
do/deploy [ CONFIRM ]
do/test [ AUTO ]
...
─────────────────────────────────────────────────
↑↓ navigate SPACE cycle: CONFIRM→AUTO→DENIED ENTER save ESC cancel
- ↑ / ↓ — move the cursor between scripts
- SPACE — cycle the highlighted script's state:
CONFIRM → AUTO → DENIED → CONFIRM(color-coded green/yellow/red) - ENTER — save changes and exit
- ESC / q — cancel without saving
On save, your selections are merged into .mlcc/agent-config.json under confirmation.script_classes (the project directory comes from --project-dir, or the current working directory). Existing keys — venv_path, mode, unrelated settings — are preserved. The TUI writes the snake_case script_classes key and drops any legacy camelCase scriptClasses.
Override manually instead by editing .mlcc/agent-config.json directly:
// .mlcc/agent-config.json
{
"venv_path": ".mlcc/hey-venv",
"confirmation": {
"mode": "default",
"default_class": "confirm",
"script_classes": {
"do/test": "auto",
"do/status": "auto",
"do/deploy": "confirm",
"do/clean": "denied"
}
}
}
In this example, do/test and do/status run without prompting, do/deploy pauses for approval, do/clean is blocked entirely, and every other script inherits default_class (confirm).
Note
The project-level .mlcc/agent-config.json schema is all-snake-case (venv_path, script_classes, default_class). Older config files using the legacy camelCase scriptClasses key still load correctly — the loader reads script_classes first and falls back to scriptClasses. A legacy permitted_scripts allow-list is also still honored: known scripts absent from the list are synthesized as denied to preserve the old opt-in behavior.
--dry-run as a test harness¶
--dry-run runs the full planner and resolver but substitutes a DryRunReporter for the executor. Zero do/ scripts run, zero AWS calls. A deterministic plan.json is written to the project directory.
# Reproducible: same inputs → same plan.json
python3 src/agent/agent.py --goal "stage and deploy Qwen3-4B" --dry-run
cat plan.json | jq '.steps[].script'
Useful for golden-file tests: assert on the plan structure without spending on actual jobs.
Executing a saved plan (--from-plan)¶
--from-plan skips the GoalPlanner entirely and executes a previously reviewed plan.json. This saves the planning LLM call and guarantees the executed plan is exactly what you reviewed:
mcc hey --goal "stage and deploy Qwen3-4B" --dry-run # review plan.json
mcc hey --from-plan # execute ./plan.json
Each step's script is validated against permitted_scripts; steps referencing a non-permitted script are skipped with a warning and the rest continue. --from-plan is mutually exclusive with --goal, defaults to ./plan.json when no path is given, and honors --dry-run (re-display the plan without executing) and --auto (skip confirmation prompts).
What It Can Help With¶
- Instance selection: "What instance should I use for Llama-3.1-8B with LoRA?" → queries instance catalog, calculates VRAM, recommends with math
- Config explanation: "What does IC_ENV_VLLM_MAX_MODEL_LEN do?" → explains the variable, shows your current value, recommends what it should be
- Troubleshooting: "I'm getting OOM on deploy" → identifies pattern (CUDA graph overhead, LoRA pre-allocation), suggests specific fix
- Workflow planning: "Plan a deployment workflow for my model" → generates step-by-step plan, offers to save as
TODO.md - Feature status: "Is SGLang LoRA supported?" → queries capability matrix, gives honest "no" with alternatives
- Project summary: "What's my current config?" → reads and summarizes your entire project state
- Optimization: "How can I improve throughput?" → recommends FP8 quantization, batch settings, context length tuning
Note
The agent calls MCP servers (instance-sizer, model-picker, base-image-picker, etc.) to get factual data before answering. It does not guess instance specs or model parameters.
Flags¶
| Flag | Description |
|---|---|
--offline / -o |
Print environment health check and project summary, then exit. No Bedrock calls, no cost. |
--project-dir <dir> |
Override project directory (default: current working directory). |
--goal '<objective>' |
Plan a sequence of do/ steps to achieve a natural-language objective. Produces an ordered plan; pairs with --auto for autonomous execution. |
--auto |
Self-answer clarifying questions from project context and instance-sizer defaults, then chain-execute the plan. Pauses only at confirm-class scripts (costly or mutating). |
--dry-run |
Run the planner and resolver, write plan.json, but execute zero do/ scripts. Deterministic output for CI/testing. |
--from-plan [file] |
Execute a saved plan.json without re-planning (skips the GoalPlanner LLM call). Defaults to ./plan.json in the project directory when no path is given. Mutually exclusive with --goal; honors --dry-run and --auto. |
Commands During Conversation¶
| Command | Effect |
|---|---|
reload |
Re-read project files (use after editing config mid-session) |
exit / quit / bye / q |
End session gracefully (prints cost summary) |
| Ctrl+C | Interrupt current response or end session |
Customizing Agent Knowledge¶
Create a .mlcc-agent-context.md file in your project root to inject team-specific knowledge:
<!-- .mlcc-agent-context.md -->
# Team Conventions
- We always use FP8 quantization for cost optimization
- Our max_model_len policy is 4096 (higher requires VP approval)
- Preferred instance family: g5 (approved in our AWS account)
- Adapters are named: tuned-<technique>-<dataset>-<date>
- All deployments go through the staging endpoint first
The agent reads this file at startup and incorporates it into all recommendations. Use it for:
- Naming conventions and deployment patterns
- Instance/region preferences and constraints
- Known issues specific to your environment
- Cost policies and approval requirements
Cost¶
Each session uses Amazon Bedrock Claude Sonnet. Token usage and estimated cost are displayed when you exit:
Session Summary
────────────────────────────────────────
Turns: 8
Input tokens: ~12,400
Output tokens: ~3,200
Estimated cost: ~$0.0852
A typical 10-turn session costs ~\(0.05–\)0.10. Use --offline for zero-cost quick reference.
Warning
Cost tracking is approximate. Actual billing comes from your AWS account's Bedrock usage metrics.
Limitations¶
- Runs
do/scripts subject to their permission class. Scripts classeddenied(or resolved todeniedviadefault_class) are refused;confirm-class scripts pause for approval;auto-class scripts run without prompting. Adjust per-script permissions withmcc hey config permissionsor by editing.mlcc/agent-config.json. - Session state is not persisted — each
heyinvocation starts fresh. UseTODO.mdoutput to capture plans. - Knowledge is version-bound — the agent knows about features in the installed version. Custom forks or unreleased changes aren't reflected unless you add them via
.mlcc-agent-context.md. - Requires internet — Bedrock access needed for interactive mode. Use
--offlinefor air-gapped environments.