Fix AG MITM
This commit is contained in:
@@ -12,20 +12,19 @@ export const FORMATS = {
|
||||
CURSOR: "cursor"
|
||||
};
|
||||
|
||||
// Map endpoint suffix → source format (takes priority over body-based detection)
|
||||
const ENDPOINT_FORMAT_MAP = {
|
||||
"/v1/responses": FORMATS.OPENAI_RESPONSES,
|
||||
"/v1/chat/completions": FORMATS.OPENAI,
|
||||
};
|
||||
|
||||
/**
|
||||
* Detect source format from request URL pathname.
|
||||
* Returns null if no matching endpoint found.
|
||||
* Detect source format from request URL pathname + body.
|
||||
* Returns null to fall back to body-based detection.
|
||||
*/
|
||||
export function detectFormatByEndpoint(pathname) {
|
||||
for (const [segment, format] of Object.entries(ENDPOINT_FORMAT_MAP)) {
|
||||
if (pathname.includes(segment)) return format;
|
||||
export function detectFormatByEndpoint(pathname, body) {
|
||||
// /v1/responses is always openai-responses
|
||||
if (pathname.includes("/v1/responses")) return FORMATS.OPENAI_RESPONSES;
|
||||
|
||||
// /v1/chat/completions + input[] → treat as openai (Cursor CLI sends Responses body via chat endpoint)
|
||||
if (pathname.includes("/v1/chat/completions") && Array.isArray(body?.input)) {
|
||||
return FORMATS.OPENAI;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -84,8 +84,10 @@ export function createSSEStream(options = {}) {
|
||||
|
||||
// Ensure OpenAI-required fields are present on streaming chunks (Letta compat)
|
||||
let fieldsInjected = false;
|
||||
if (!parsed.object) { parsed.object = "chat.completion.chunk"; fieldsInjected = true; }
|
||||
if (!parsed.created) { parsed.created = Math.floor(Date.now() / 1000); fieldsInjected = true; }
|
||||
if (parsed.choices !== undefined) {
|
||||
if (!parsed.object) { parsed.object = "chat.completion.chunk"; fieldsInjected = true; }
|
||||
if (!parsed.created) { parsed.created = Math.floor(Date.now() / 1000); fieldsInjected = true; }
|
||||
}
|
||||
|
||||
// Strip Azure-specific non-standard fields from streaming chunks
|
||||
if (parsed.prompt_filter_results !== undefined) {
|
||||
|
||||
@@ -196,13 +196,15 @@ export function extractUsage(chunk) {
|
||||
}
|
||||
|
||||
// Gemini format (Antigravity)
|
||||
if (chunk.usageMetadata && typeof chunk.usageMetadata === "object") {
|
||||
// Antigravity wraps usageMetadata inside response: { response: { usageMetadata: {...} } }
|
||||
const usageMeta = chunk.usageMetadata || chunk.response?.usageMetadata;
|
||||
if (usageMeta && typeof usageMeta === "object") {
|
||||
return normalizeUsage({
|
||||
prompt_tokens: chunk.usageMetadata?.promptTokenCount || 0,
|
||||
completion_tokens: chunk.usageMetadata?.candidatesTokenCount || 0,
|
||||
total_tokens: chunk.usageMetadata?.totalTokenCount,
|
||||
cached_tokens: chunk.usageMetadata?.cachedContentTokenCount,
|
||||
reasoning_tokens: chunk.usageMetadata?.thoughtsTokenCount
|
||||
prompt_tokens: usageMeta.promptTokenCount || 0,
|
||||
completion_tokens: usageMeta.candidatesTokenCount || 0,
|
||||
total_tokens: usageMeta.totalTokenCount,
|
||||
cached_tokens: usageMeta.cachedContentTokenCount,
|
||||
reasoning_tokens: usageMeta.thoughtsTokenCount
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user