mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-13 10:15:40 +00:00
fix(cliproxy): propagate agy entitlement failure metadata
This commit is contained in:
1 parent
7c4545eb1b
commit
506b61eca6
2 files changed
+63
No files matched your search
@@ -698,6 +698,14 @@ async function fetchAvailableModels(
|
|||||||
error: 'Invalid quota response from provider',
|
error: 'Invalid quota response from provider',
|
||||||
errorCode: 'provider_unavailable',
|
errorCode: 'provider_unavailable',
|
||||||
retryable: true,
|
retryable: true,
|
||||||
|
entitlement: buildProviderEntitlementEvidence({
|
||||||
|
normalizedTier: 'unknown',
|
||||||
|
source: 'runtime_inference',
|
||||||
|
confidence: 'low',
|
||||||
|
accessState: 'unknown',
|
||||||
|
capacityState: 'temporarily_unavailable',
|
||||||
|
notes: 'Provider returned a 2xx response with an empty or invalid quota payload.',
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -814,6 +822,7 @@ export async function fetchAccountQuota(
|
|||||||
httpStatus: lastProjectResult.httpStatus,
|
httpStatus: lastProjectResult.httpStatus,
|
||||||
needsReauth: lastProjectResult.needsReauth,
|
needsReauth: lastProjectResult.needsReauth,
|
||||||
isUnprovisioned: lastProjectResult.isUnprovisioned,
|
isUnprovisioned: lastProjectResult.isUnprovisioned,
|
||||||
|
entitlement: lastProjectResult.entitlement,
|
||||||
isExpired: authData.isExpired,
|
isExpired: authData.isExpired,
|
||||||
expiresAt: authData.expiresAt || undefined,
|
expiresAt: authData.expiresAt || undefined,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -28,4 +28,58 @@ describe('Antigravity quota failure metadata', () => {
|
|||||||
capacityState: 'rate_limited',
|
capacityState: 'rate_limited',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('preserves entitlement evidence when project lookup fails before quota fetch', async () => {
|
||||||
|
const moduleId = Date.now() + Math.random();
|
||||||
|
const { fetchAccountQuota } = await import(`../../../src/cliproxy/quota-fetcher?agy-early=${moduleId}`);
|
||||||
|
const { getProviderAuthDir } = await import(
|
||||||
|
`../../../src/cliproxy/config-generator?agy-config=${moduleId}`
|
||||||
|
);
|
||||||
|
const fs = await import('node:fs');
|
||||||
|
const os = await import('node:os');
|
||||||
|
const path = await import('node:path');
|
||||||
|
|
||||||
|
const tempHome = fs.mkdtempSync(path.join(os.tmpdir(), 'ccs-agy-failure-'));
|
||||||
|
const originalCcsHome = process.env.CCS_HOME;
|
||||||
|
process.env.CCS_HOME = tempHome;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const authDir = getProviderAuthDir('agy');
|
||||||
|
fs.mkdirSync(authDir, { recursive: true });
|
||||||
|
fs.writeFileSync(
|
||||||
|
path.join(authDir, 'antigravity-user@example.com.json'),
|
||||||
|
JSON.stringify({
|
||||||
|
type: 'antigravity',
|
||||||
|
email: 'user@example.com',
|
||||||
|
project_id: 'project-x',
|
||||||
|
access_token: 'token',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const originalFetch = globalThis.fetch;
|
||||||
|
globalThis.fetch = (async () =>
|
||||||
|
new Response(JSON.stringify({ error: { message: 'forbidden' } }), {
|
||||||
|
status: 403,
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
})) as typeof fetch;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await fetchAccountQuota('agy', 'user@example.com');
|
||||||
|
expect(result.success).toBe(false);
|
||||||
|
expect(result.entitlement).toMatchObject({
|
||||||
|
accessState: 'not_entitled',
|
||||||
|
capacityState: 'unknown',
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
globalThis.fetch = originalFetch;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (originalCcsHome === undefined) {
|
||||||
|
delete process.env.CCS_HOME;
|
||||||
|
} else {
|
||||||
|
process.env.CCS_HOME = originalCcsHome;
|
||||||
|
}
|
||||||
|
fs.rmSync(tempHome, { recursive: true, force: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
Reference in new issue
Block a user