# Options
```toml
model = "flash3"
```

# Before All

```lua
local p_utils = require("pricing_utils")

local inputs = p_utils.load_inputs()

for _, input in ipairs(inputs) do
  input.rust_file_path = "src/data/data_" .. input.name .. ".rs"
  local provider_upper = string.upper(input.name:gsub("%W", "_"))
  local rust_content = "use crate::{ModelPricing, ProviderPricing};\n\n"
      .. "pub const " .. provider_upper .. ": ProviderPricing = ProviderPricing {\n"
      .. "\tname: \"" .. input.name .. "\",\n"
      .. "\tmodels: " .. provider_upper .. "_MODELS,\n"
      .. "};\n\n"
      .. "const " .. provider_upper .. "_MODELS: &[ModelPricing] = &[\n"
      .. "];\n"
  aip.file.ensure_exists(input.rust_file_path, rust_content, { content_when_empty = true })
end

return aip.flow.before_all_response({
  inputs = inputs
})
```

# Data

```lua

if not aip.path.exists(input.json_path) then
  return aip.flow.skip("No JSON found for " .. input.name .. " at " .. input.json_path)
end

if not input.do_json then
	return aip.flow.skip("do_json false")
end


local json_file = aip.file.load(input.json_path)

local rust_context = aip.udiffx.load_files_context(input.rust_file_path)
local udiffx_instr = aip.udiffx.file_changes_instruction()

return {
  json_content   = json_file.content,
  rust_context   = rust_context,
  rust_file_path = input.rust_file_path,
  provider_name  = input.name,
  udiffx_instr   = udiffx_instr,
}
```

# Instruction

{{{data.udiffx_instr}}}

Below is the source-of-truth JSON data for the provider `{{data.provider_name}}`. 
You must use this data to update (or create) the Rust pricing file `{{data.rust_file_path}}`.

### Source JSON

```json
{{data.json_content}}
```

### Current Rust File Context
{{#if data.rust_context}}
{{{data.rust_context}}}
{{else}}
(The file `{{data.rust_file_path}}` does not exist yet. You must create it using `FILE_NEW` following the template below.)

### Rust File Template
```rust
use crate::run::pricing::{ModelPricing, ProviderPricing};

pub const [PROVIDER_UPPER]: ProviderPricing = ProviderPricing {
	name: "{{data.provider_name}}",
	models: [PROVIDER_UPPER]_MODELS,
};

const [PROVIDER_UPPER]_MODELS: &[ModelPricing] = &[
    // Entries from JSON go here
];
```
*(Note: Replace `[PROVIDER_UPPER]` with the uppercase version of `{{data.provider_name}}`. For example, if provider is `openai`, use `OPENAI` and `OPENAI_MODELS`)*
{{/if}}

### Important Update Rules

1. Use `FILE_PATCH` to update the existing file or `FILE_NEW` to create it if it's missing.
2. The JSON data is the authoritative source for pricing values.
3. For each model in the JSON:
   - Map `name` to `ModelPricing.name`.
   - Map `input.cached` to `ModelPricing.input_cached` (use `Some(f64)` or `None`).
   - Map `input.normal` to `ModelPricing.input_normal`.
   - Map `output` to `ModelPricing.output_normal`.
   - Set `output_reasoning` to `None` unless it's already specified in the Rust file context with a value.
4. **Naming Conversions**:
   - For OpenAI: Remove the `openai-` prefix from the model name (e.g., `openai-gpt-4o` becomes `gpt-4o`).
   - For Gemini: Remove the `-preview` suffix (e.g., `gemini-2.5-pro-preview` becomes `gemini-2.5-pro`).
5. **Preserve exact formatting and all comments** present in the existing file.
6. Only update the model entries. Do not remove existing entries unless they are duplicate or clearly replaced by the JSON data.
7. Only return the `<FILE_CHANGES>` container.

# Output

```lua
local res = aip.udiffx.apply_file_changes(ai_response.content)

if res.changed_count == 0 then
  if res.failed_changes and #res.failed_changes > 0 then
    return { error = "Failed to apply changes for " .. input.name .. ": " .. aip.json.stringify(res.failed_changes) }
  else
    return "No changes needed for " .. input.name
  end
end

return "Updated " .. input.name
```
