Reject model IDs unsafe for headers and clarify supported capabilities
This commit is contained in:
parent
ec9a2b173a
commit
7754377b3e
3 changed files with 22 additions and 5 deletions
|
|
@ -3,9 +3,9 @@
|
|||
Use [uniGPT](https://unigpt.uni-graz.at), the University of Graz's AI
|
||||
assistant, inside the [pi](https://pi.dev) coding agent.
|
||||
|
||||
Once set up, every model your uniGPT account offers appears in pi's model
|
||||
picker, including GPT-4o, GPT-4.1, and the GPT-5 and GPT-6 families. Tools,
|
||||
streaming responses, and image input all work.
|
||||
Models exposed by your uniGPT API key appear in pi's model picker.
|
||||
Streaming and tool calls are supported; recognized vision models also
|
||||
support image input.
|
||||
|
||||
## What you need
|
||||
|
||||
|
|
|
|||
|
|
@ -53,8 +53,11 @@ function isRecord(value: unknown): value is Record<string, unknown> {
|
|||
}
|
||||
|
||||
function isValidId(id: unknown): id is string {
|
||||
// IDs become an HTTP header value, so reject padding and control characters.
|
||||
return typeof id === "string" && id.length > 0 && id.trim() === id && !/[\u0000-\u001f\u007f]/.test(id);
|
||||
// Fetch header values must fit Latin-1; also reject padding and control characters.
|
||||
return typeof id === "string"
|
||||
&& id.length > 0
|
||||
&& id.trim() === id
|
||||
&& !/[\u0000-\u001f\u007f\u0100-\uffff]/.test(id);
|
||||
}
|
||||
|
||||
export interface ParsedCatalog {
|
||||
|
|
|
|||
|
|
@ -58,6 +58,20 @@ test("skips unusable entries but rejects malformed or entirely unusable catalogs
|
|||
}
|
||||
});
|
||||
|
||||
test("catalog IDs must fit Fetch's Latin-1 header values", () => {
|
||||
const valid = ["gpt-4o", "model-\u00ff"];
|
||||
const invalid = ["model-\u0100", "model-\u{1f600}", "model-\ud800"];
|
||||
const parsed = parseCatalog({ data: [...valid, ...invalid].map((id) => ({ id })) });
|
||||
assert.deepEqual(parsed, { ids: valid, skipped: invalid.length });
|
||||
for (const id of parsed.ids) {
|
||||
const headers = new Headers(makeModel(id, BASE_URL).headers);
|
||||
assert.equal(headers.get("deployment-id"), id);
|
||||
}
|
||||
for (const id of invalid) {
|
||||
assert.throws(() => parseCatalog({ data: [{ id }] }), /without any valid model IDs/);
|
||||
}
|
||||
});
|
||||
|
||||
const known: Record<string, ModelMetadata> = {
|
||||
"model-a": { name: "Model A", input: ["text", "image"], contextWindow: 272_000, maxTokens: 128_000 },
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue