Skip to content

Instantly share code, notes, and snippets.

@scarf005
Last active September 26, 2025 07:03
Show Gist options
  • Select an option

  • Save scarf005/fddcef68aefaba19bb512cc8a9258cf8 to your computer and use it in GitHub Desktop.

Select an option

Save scarf005/fddcef68aefaba19bb512cc8a9258cf8 to your computer and use it in GitHub Desktop.
force enables URL context in aistudio.google.com because some forsaken reason it's not enabled by default
// ==UserScript==
// @name aistudio search and URL context always ON
// @namespace https://github.com/scarf005
// @version 1.2
// @description force enables web search in aistudio.google.com because some forsaken reason it's not enabled by default
// @author scarf005
// @match https://aistudio.google.com/*
// @homepageURL https://gist.github.com/scarf005/fddcef68aefaba19bb512cc8a9258cf8
// @supportURL https://gist.github.com/scarf005/fddcef68aefaba19bb512cc8a9258cf8
// @downloadURL https://gist.github.com/scarf005/fddcef68aefaba19bb512cc8a9258cf8/raw/aistudio-urlcontext-on.user.js
// @grant GM.xmlhttpRequest
// @grant GM.addStyle
// ==/UserScript==
GM.addStyle(/*css*/`
a[data-plainified="true"] { color: IndianRed; }
`)
const ids = ["searchAsAToolTooltip", "browseAsAToolTooltip"]
const enableSearch = () => {
ids.forEach(id => {
const toggleButton = document.querySelector(`[data-test-id="${id}"] button[role="switch"][aria-checked="false"]`)
toggleButton?.click()
})
}
const observer = new MutationObserver(enableSearch)
observer.observe(document.body, { childList: true, subtree: true })
enableSearch()
/** @type {Object<string, string>} */
const cache = {}
const domParser = new DOMParser()
const request = (targetUrl, { method = 'GET' } = {}) => new Promise((resolve, reject) => {
GM.xmlhttpRequest({
method,
url: targetUrl,
onload: resolve,
onerror: reject,
})
})
/** @type {(a: string) => Promise<string>} */
const getFinalUrl = async (url) => {
if (cache[url]) {
return cache[url]
}
try {
// console.log(`Requesting to ${url}`)
const response1 = await request(url)
const doc = domParser.parseFromString(response1.responseText, 'text/html')
const intermediateLink = doc.querySelector('a[href*="vertexaisearch.cloud.google.com"]')
if (!intermediateLink) {
throw new Error('Intermediate vertexaisearch link not found')
}
// 2. 중간 링크에 HEAD 요청을 보내 최종 URL을 얻습니다. (Location 헤더 추적)
const response2 = await request(intermediateLink.href, { method: 'HEAD' })
const finalUrl = response2.finalUrl
console.log(`Resolved: ${url} -> ${finalUrl}`)
cache[url] = finalUrl
return finalUrl
} catch (error) {
console.error(`[AI Studio Link Plainifier] Failed to resolve ${url}:`, error)
cache[url] = url // 실패 시 재시도 방지를 위해 캐시합니다.
return url
}
}
/** @type {() => void} */
const replaceLinks = () => {
document.querySelectorAll('a[href*="vertexaisearch.cloud.google.com"]')
.forEach(async (link) => {
if (link.dataset.plainified) return
link.dataset.plainified = 'false' // 처리 중/완료 표시
const finalUrl = await getFinalUrl(link.href)
link.href = finalUrl
link.dataset.plainified = 'true'
})
}
setInterval(replaceLinks, 1000)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment