The model field: today it is not validated

Who this is for: every product that holds an AgileV key, and in particular anyone who takes the model name from an environment variable or from a configuration file. Where it comes from: trpg's own measurement of 28/9. Before that they had written to us «reranking wants agilev-rerank, not agilev-m3» — deduced from /v1/models, not measured, and false. Then they measured it and found more: even an invented name goes through. And they asked us for one thing only: the notice before 400 MODEL_UNKNOWN. This page is that notice, with the measurement underneath.

1. Today no name is rejected

Measured on 28/9 over 4 endpoints × 9 names, on the 1.1 code in production and on the 1.2 already ready, with identical outcomes on both: zero 400. Deploying 1.2 does not change a single line of this table.

Name sent/v1/embeddings, /v1/tokenize/v1/rerank/embed
agilev-m3recognisedserved, counted as unknownignored
agilev-rerankserved, counted as unknownrecognisedignored
bge-m3recognised (alias)served, counted as unknownignored
agilev-m3-fastrecognised, but today 503 MODEL_UNAVAILABLE on /v1/embeddingsserved, counted as unknownignored
anything else (voyage-3, modello-che-non-esiste…)served, counted as unknownserved, counted as unknownignored
"", null, field absentrecognised: the default appliesrecognised: the default appliesignored

A request with an unknown name is served and billed like all the others: the validation is of form, not of substance.

2. The two blind spots, which concern you more than us

An empty name leaves no trace. "", null and the missing field count as «default» and are not counted anywhere. If your environment variable is empty, today nobody notices: neither you (you receive 200) nor us (the counter does not move).

/embed does not look at the field at all. The historical format only has texts: a model in the body is discarded without even being counted. Whoever stayed on /embed is invisible to this validation, today and tomorrow.

The check that holds, and it is free: every response declares the model used, not the one requested — /v1/rerank always answers "model":"agilev-rerank", /v1/embeddings "model":"agilev-m3", /embed "model":"bge-m3". Compare that, not what you sent: it is the only check that keeps working even after validation exists. It is the fix trpg has already put into their own test bench.

A name is only ever compared with the one from the SAME endpoint. The three values above are not interchangeable: /v1/embeddings and /embed give the same vectors (measured: bit-for-bit identical) under two different names, because the first uses the catalogue name and the second the name of the underlying model. The same holds for GET /health, which declares "model":"bge-m3": it is not comparable with agilev-m3 from /v1/models, and whoever compares them has a false alarm at every start-up (reported by trpg on the evening of 28/9). If you are looking for a start-up health check, that one is on the dimension: Rule 4, countermeasure (a).

3. When it will become 400 MODEL_UNKNOWN, and how you will know beforehand

Not soon. Read from the production counters on 29/9 at 03:2x: 4 of the 7 successful rerank requests since the restart of 27/9 06:37:49Z carried an unrecognised name (on 28/9 it was 3 out of 6). Before anything changes, all four of these things will happen, in this order:

  1. the unknown-name counter stays at zero steadily (it is the condition written in our code from day one). Until 29/9 that sentence was not even measurable: the counter lives in memory and restarted from zero at every restart of the service, so «steadily at zero» could be obtained by restarting. Now the per-key count is on disk and restarts do not erase it;
  2. the counter becomes attributable: knowing that someone is getting it wrong without knowing whom to warn is not enough, and until we know whom to write to, nothing changes. Done on 29/9/2026: the service records, per key and per endpoint, how many requests carried a name it does not recognise — numbers only, never the name received, which is your text. You see it yourself in GET /v1/usage, field model_unknown, which costs neither quota nor per-minute requests: empty is the normal answer;
  3. an entry in the release notes and a direct message to every key holder, with at least 30 days between the notice and the change;
  4. the change ships in a deploy on its own, never together with anything else: if it breaks something, it is clear what to roll back.

In the meantime there are two ways of checking yourselves, both free. The first is model_unknown in GET /v1/usage: if it is not empty, your configuration is sending a name we do not know, and you know on which endpoint. The second is the model of the response, which is the only one of the two that also catches the empty environment variable (an empty string counts as the default and is not counted anywhere). If it is not what you expect, your configuration is already wrong today.

4. What does NOT change with the 1.2 deploy

Everything above. The measurements were taken on both versions precisely so that this could be said: if after the move to 1.2 you see a 400 on a model name, it is a fault of ours and we want to know at once. The complete table and the rest of the contract are in api.html (the public copy is kept aligned by the control room: until then, this page is the more up to date one).

questa pagina in italiano