fix: resolve omitted Optional inputs to None at the HTTP edge (#3051)
A predictor input declared `Optional[T]` / `T | None` is emitted as an
optional field in the OpenAPI schema (nullable, absent from `required`),
but whether it can actually be omitted at request time depended on a
Python-level detail: whether the parameter had a usable `__defaults__`
entry. A bare `value: Optional[str]` (no `= Input(...)`) built and served
fine, advertised the field as optional, then raised
`TypeError: missing 1 required positional argument` whenever a caller
omitted it.
Fix this in coglet's HTTP edge, where input validation already runs with
the OpenAPI schema in hand. After validation passes, inject an explicit
`null` for every property that is `nullable: true`, absent from
`required`, and has no `default` key. This mirrors the schema-generation
discriminator in pkg/schema/openapi.go and keeps the schema the source of
truth for what is optional. The worker is unchanged and needs no schema.
The rule safely skips `Optional[T] = Input(default=None)` (emits
`default: null`), real defaults, and required fields. Injection runs only
after successful validation, so missing required fields still 422.
Training inputs (TrainingInput) are covered via the same path. Union
optionals remain in `required` by design and are correctly skipped.
Tests:
- unit (input_validation.rs): inject for bare optional, optional list,
optional enum; skip explicit-default and required fields; never
override a present value.
- unit (service.rs): predict injects after Ok, does not inject when a
required field is missing, train path injects.
- integration: optional_input_no_default.txtar exercises a bare
`value: Optional[str]` via cog predict and POST /predictions.