EnglishFrançais

8 · LLM-driven commands

Three commands let you collaborate with an LLM on Amalgame code:

Command Direction
amc migrate <file|dir> other language → Amalgame
amc generate "<prompt>" natural language → Amalgame
amc explain <file.am> Amalgame → natural language

All three share the same provider stack, the same on-disk prompt header, the same --dry-run cost estimation. They came in together with the v0.4.0 release.

If you've never run them: skim the Quick start and the Provider selection sections, then come back when you need the detail. The full design rationale is in docs/proposals/amc-migrate.md.

Quick start

# Translate one file
amc migrate src/user_service.ts

# Translate a whole directory (writes <stem>.am next to each source)
amc migrate src/

# Generate a fresh program from a prompt
amc generate "an HTTP server with /health and /version routes" -o api.am

# Explain a .am file in plain English
amc explain src/lsp.am

# Same, but in French
amc explain src/lsp.am --lang French

The output of migrate and generate is automatically validated with amc --check. If it fails, the file is still written so you can inspect / fix it manually, but the exit code is non-zero.

Provider selection

Five providers ship out of the box:

Provider Backend Auto-selected when
claude shells out to the local claude CLI (Claude Code) (default fallback)
claude-api POST api.anthropic.com/v1/messages ANTHROPIC_API_KEY is set
chatgpt POST api.openai.com/v1/chat/completions OPENAI_API_KEY is set
gemini POST generativelanguage.googleapis.com/v1beta/... GEMINI_API_KEY is set
custom shells out to $AMC_CUSTOM_PROVIDER_CMD (stdin = prompt, stdout = response) never (opt-in only)

Auto-selection precedence, when --provider isn't passed:

  1. ANTHROPIC_API_KEYclaude-api
  2. OPENAI_API_KEYchatgpt
  3. GEMINI_API_KEYgemini
  4. fallback → claude (CLI)

Override explicitly:

amc migrate file.cs --provider chatgpt --model gpt-4o
amc generate "..." --provider gemini --model gemini-1.5-pro
amc explain file.am --provider custom

For custom, point at any script that reads a prompt from stdin and writes the response to stdout:

export AMC_CUSTOM_PROVIDER_CMD="ollama run codellama"
amc migrate file.go --provider custom

Cost reporting

Two flavours, depending on whether the call has happened yet.

Pre-flight estimate (--dry-run) — based on a 4-char-per-token heuristic and hardcoded model price tables:

$ amc migrate src/api.ts --dry-run
[migrate] would migrate: src/api.ts (TypeScript, 240 lines)
[migrate] would write:   src/api.am
[migrate] provider:      claude-api
[migrate] estimated cost: ~6862 in + ~1000 out -> ~$0.05 (claude-sonnet-4-6)

Real cost (since v0.4.3) — printed after a successful migration, pulled from the usage object on the API response. No ~, no heuristic — exact tokens billed:

$ amc migrate src/api.ts
[migrate] processing src/api.ts (TypeScript, 240 lines, provider=claude-api)...
[migrate] wrote src/api.am
[migrate] cost: 6431 in + 982 out = $0.04 (claude-sonnet-4-6)
[migrate] check passed

Provider extraction paths:

CLI shell-out (claude, custom) reports nothing since the bill is on your subscription / local model. The result has InputTokens = -1 which the formatter treats as "skip the cost line".

Result cache (amc migrate only)

Re-running amc migrate on an unchanged source with the same system prompt skips the LLM call entirely. The cache lives at ~/.cache/amalgame/migrate/<sha256>.am and is keyed on SHA-256(source + system prompt). So:

Change Effect
Source edited new hash → re-call LLM
amc upgraded with new conventions new hash → re-call
grammar.ebnf updated new hash → re-call
Nothing changed cache hit → reuse output

--no-cache bypasses both lookup and store.

On-disk prompt docs

The system prompt for all three commands embeds Amalgame's grammar reference (docs/language/grammar.ebnf) and language tour (docs/guide/02-language-tour.md) so the LLM has authoritative syntax. The lookup order:

  1. <exec-dir>/../share/amalgame/docs/... (Linux/macOS install layout — populated by install.sh and the release tarballs)
  2. <exec-dir>/docs/... (Windows / portable install)
  3. ./docs/... (source checkout / development)

If none of those is reachable, the commands degrade gracefully to an inline conventions block — still functional, but the model loses access to the canonical grammar. Run amc migrate --prompt-only on any file to dump the assembled system+user prompt and inspect what the LLM actually sees.

Streaming output (generate and explain)

For long generations, --stream flows the response straight to stdout as it's produced. Constraints (rejected upfront with clean errors):

amc generate "implement quicksort with pivot tuning" --stream

Flag matrix

Flag migrate generate explain
<positional> file or dir prompt file
-o / --output ✓ (single-file)
--lang ✓ (source language hint) ✓ (output language)
--provider
--model
--dry-run
--prompt-only
--stream
--no-check ✓ (with -o) — (no output validation)
--no-cache — (no cache)
--max-lines ✓ (default 2000)
--force

Known limitations

Troubleshooting

Symptom Likely fix
claude CLI not found on PATH Install Claude Code, or use --provider claude-api (needs ANTHROPIC_API_KEY).
ANTHROPIC_API_KEY not set export ANTHROPIC_API_KEY=sk-ant-.... Same shape for OPENAI / GEMINI.
provider 'X' not supported Typo, or you tried v3 streaming on an API provider. Check amc migrate --help.
HTTP 401 / 403 from API Wrong key or expired. Verify with curl -H "x-api-key: $ANTHROPIC_API_KEY" https://api.anthropic.com/v1/models.
HTTP 429 Rate limited. Wait, or downgrade --model.
check failed (typechecker errors in the migrated file) Inspect the .am (it was still written). Common cause: an Amalgame limitation the LLM didn't dodge — see "Known limitations" above.
Migration is slow Default model on claude CLI is Opus. Pass --model claude-sonnet-4-6 for ~3× speed-up.

Where to look in the code