Responses API
endpoint سازگار با OpenAI Responses؛ قابلیتها (structured outputs، stateful، file_search، reasoning) مدل/provider-gated
نمای کلی
POST /v1/responses یک endpoint سازگار با OpenAI Responses است. با تغییر base URL، API Key و model در OpenAI SDK میتوانید از AiFO استفاده کنید. Gateway از providerهای OpenAI و OpenRouter پشتیبانی میکند، اما ادعای parity کامل با OpenAI Responses را ندارد.
- ورودی متنی (string) و structured با input_text
- input_image با image_url (https یا data URL)
- input_file.file_id متعلق به AiFO (file_…) — نه شناسهٔ provider با پیشوند file-
- Structured outputs از طریق text.format (مثلاً json_schema) — passthrough به upstream
- OpenAI stateful: store / previous_response_id و GET/DELETE /v1/responses/:id (proxy به upstream)
- streaming با eventهای بومی Responses (از جمله رویدادهای reasoning بدون strip)
- OpenAI: object reasoning opaque passthrough؛ itemهای type=reasoning برای replay؛ include مثل reasoning.encrypted_content
- OpenRouter: فقط reasoning.effort؛ item type=reasoning در input → unsupported_feature
- function tools و hosted tools: web_search / web_search_preview؛ روی OpenRouter همچنین web_fetch؛ file_search فقط OpenAI (vector_store_ids passthrough)
- include، max_tool_calls و parallel_tool_calls برای کنترل هزینه و citations
- مدلهای بدون responses.endpoint=supported → unsupported_endpoint
Structured outputs
برای خروجی ساختیافته، text.format را مطابق OpenAI Responses بفرستید. AiFO schema را validate یا اجرا نمیکند؛ object را opaque به upstream پاس میدهد. پشتیبانی وابسته به مدل/provider است.
{
"model": "gpt-4o-mini",
"input": "Extract the person's name and age",
"text": {
"format": {
"type": "json_schema",
"name": "person",
"schema": {
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "number" }
},
"required": ["name", "age"],
"additionalProperties": false
},
"strict": true
}
}
}Stateful Responses (OpenAI)
روی مدلهای OpenAI با capability stateful، میتوانید store: true بفرستید و در درخواست بعدی previous_response_id را پاس دهید. وضعیت در upstream OpenAI نگه داشته میشود؛ AiFO persistence مکالمه ندارد. بازیابی و حذف هم فقط proxy به OpenAI است: GET و DELETE /v1/responses/:id.
curl https://api.aifoapp.ir/v1/responses \
-H "Authorization: Bearer aifo_sk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o-mini",
"input": "نام من آرمین است.",
"store": true
}'
# سپس با previous_response_id ادامه دهید:
curl https://api.aifoapp.ir/v1/responses \
-H "Authorization: Bearer aifo_sk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o-mini",
"input": "اسم من چیست؟",
"previous_response_id": "resp_..."
}'
# بازیابی / حذف (فقط OpenAI upstream):
# GET https://api.aifoapp.ir/v1/responses/resp_...
# DELETE https://api.aifoapp.ir/v1/responses/resp_... File search (OpenAI)
tool از نوع file_search فقط روی OpenAI (با capability hostedTools.fileSearch) پشتیبانی میشود. vector_store_ids باید متعلق به حساب upstream OpenAI باشند (پیشوند vs_…). AiFO vector store نمیسازد، CRUD /v1/vector_stores ندارد و RAG داخلی اجرا نمیکند — فقط passthrough.
curl https://api.aifoapp.ir/v1/responses \
-H "Authorization: Bearer aifo_sk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o-mini",
"input": "خلاصه اسناد مرتبط با قرارداد را بگو",
"tools": [{
"type": "file_search",
"vector_store_ids": ["vs_..."]
}]
}' Reasoning
فیلد reasoning وابسته به provider است. روی OpenAI، object بهصورت opaque پاس میشود (effort، summary، include مثل reasoning.encrypted_content) و itemهای type=reasoning در input برای replay پشتیبانی میشوند. روی OpenRouter فقط reasoning.effort پذیرفته میشود؛ item type=reasoning در input رد میشود.
curl https://api.aifoapp.ir/v1/responses \
-H "Authorization: Bearer aifo_sk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "o4-mini",
"input": "یک معما حل کن",
"reasoning": { "effort": "medium", "summary": "auto" },
"include": ["reasoning.encrypted_content"]
}' Web search
برای جستجوی وب، tool میزبانیشدهٔ web_search را در tools بفرستید. AiFO خودش موتور search اجرا نمیکند؛ درخواست به OpenAI یا OpenRouter proxy میشود. روی OpenRouter، type به openrouter:web_search بازنویسی میشود. برای دیدن منابع، include را با web_search_call.action.sources ست کنید. هزینهٔ چندبارهٔ search ممکن است بالا برود — max_tool_calls و search_context_size: low|medium را در نظر بگیرید.
curl https://api.aifoapp.ir/v1/responses \
-H "Authorization: Bearer aifo_sk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o-mini",
"input": "آخرین قیمت بیتکوین چقدر است؟",
"tools": [{ "type": "web_search", "search_context_size": "medium" }],
"include": ["web_search_call.action.sources"],
"max_tool_calls": 3
}' نمونهٔ OpenAI
curl https://api.aifoapp.ir/v1/responses \
-H "Authorization: Bearer aifo_sk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o-mini",
"input": "سلام! یک جمله کوتاه بنویس."
}' نمونهٔ OpenRouter (از طریق AiFO)
مدلهایی مثل openai/gpt-4o-mini روی OpenRouter وقتی responses.endpoint در پروفایل مؤثر supported باشد، از همان /v1/responses AiFO قابل فراخوانیاند. مدلهای بدون این قابلیت با unsupported_endpoint رد میشوند.
curl https://api.aifoapp.ir/v1/responses \
-H "Authorization: Bearer aifo_sk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-4o-mini",
"input": "Reply with exactly: ok"
}' فایل AiFO در Responses
پس از آپلود با POST /v1/files، شناسهٔ file_… را در input_file بفرستید. Gateway قبل از wallet reserve فایل را از MinIO خصوصی میخواند و به صورت inline file_data برای OpenAI یا OpenRouter ارسال میکند. شناسهٔ AiFO هرگز خام به provider نمیرسد.
{
"model": "openai/gpt-4o-mini",
"input": [{
"role": "user",
"content": [
{ "type": "input_text", "text": "خلاصه این PDF را بگو" },
{ "type": "input_file", "file_id": "file_..." }
]
}]
}Streaming
با stream:true رویدادهای بومی Responses (مثل response.created، response.output_text.delta، response.completed) بهصورت SSE فوروارد میشوند. درخواست نامعتبر قبل از reserve و قبل از ارسال headerهای SSE رد میشود.
محدودیتها و تفاوت provider
- OpenAI + OpenRouter (beta، model-gated)؛ بدون claim parity کامل
- OpenAI: store / previous_response_id / GET·DELETE responses و reasoning item replay بهصورت upstream passthrough
- OpenRouter: reasoning فقط effort؛ بدون reasoning input items؛ بدون store/previous_response_id
- بدون MCP، computer_use، code_interpreter، یا persistence مکالمه در AiFO
- file_search روی OpenAI: passthrough با vector_store_ids متعلق به upstream (بدون vector DB داخلی AiFO)؛ روی OpenRouter unsupported
- بدون آپلود به OpenAI Files API یا provider file mapping؛ بدون CRUD /v1/vector_stores در gateway