TOKEN (siehe Erste Schritte) und BASE, die Base URL der API.
curl
TOKEN=...
BASE=https://delicious-ai-app.wonderfulgrass-3eed3e5c.westeurope.azurecontainerapps.io/api/public/v1
H="Authorization: Bearer $TOKEN"
curl -s "$BASE/me" -H "$H" | jq
curl -s "$BASE/prompts" -H "$H" | jq '.prompts[] | {id, label}'
curl -s "$BASE/chats?pageSize=10" -H "$H" | jq '.chats[] | {id, title}'
CHAT=$(curl -s -X POST "$BASE/chats" -H "$H" | jq -r .id)
curl -s "$BASE/chats/$CHAT" -H "$H" | jq
curl -s -X DELETE "$BASE/chats/$CHAT" -H "$H" -o /dev/null -w '%{http_code}\n'
# Freitext
curl -N -X POST "$BASE/chats/$CHAT/messages" -H "$H" -H "Content-Type: application/json" \
-d '{"text": "Welche Artikel liefen gestern am besten?"}'
# aus einem Prompt
curl -N -X POST "$BASE/chats/$CHAT/messages" -H "$H" -H "Content-Type: application/json" \
-d '{"promptId": "ab12cd34ef56gh78ij90klmn"}'
TypeScript-Client
Minimaler Client für die JSON-Routen.api.ts
const BASE = "https://delicious-ai-app.wonderfulgrass-3eed3e5c.westeurope.azurecontainerapps.io/api/public/v1";
async function api<T>(path: string, token: string, init: RequestInit = {}): Promise<T> {
const response = await fetch(BASE + path, {
...init,
headers: {
Authorization: `Bearer ${token}`,
...(init.body ? { "Content-Type": "application/json" } : {}),
...init.headers,
},
});
if (!response.ok) {
const { code, message } = await response.json().catch(() => ({}));
throw Object.assign(new Error(message ?? response.statusText), { status: response.status, code });
}
return response.status === 204 ? (undefined as T) : response.json();
}
export const getMe = (token: string) => api("/me", token);
export const listPrompts = (token: string) => api("/prompts", token);
export const listChats = (token: string, page = 1) => api(`/chats?page=${page}`, token);
export const getChat = (token: string, id: string) => api(`/chats/${id}`, token);
export const createChat = (token: string) => api<{ id: string }>("/chats", token, { method: "POST" });
export const deleteChat = (token: string, id: string) => api(`/chats/${id}`, token, { method: "DELETE" });
Stream mit fetch lesen
Ohne AI SDK: Text-Deltas einsammeln, Tool-Parts bei Bedarf für eine Fortschrittsanzeige auswerten.
stream.ts
export async function ask(token: string, chatId: string, text: string, onText: (delta: string) => void) {
const response = await fetch(`${BASE}/chats/${chatId}/messages`, {
method: "POST",
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
body: JSON.stringify({ text }),
});
if (!response.ok || !response.body) throw new Error(`HTTP ${response.status}`);
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = "";
for (;;) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const events = buffer.split("\n\n");
buffer = events.pop() ?? "";
for (const event of events) {
const line = event.split("\n").find((l) => l.startsWith("data: "));
if (!line || line === "data: [DONE]") continue;
const part = JSON.parse(line.slice(6));
if (part.type === "text-delta") onText(part.delta);
if (part.type === "error") throw new Error(part.errorText);
}
}
}