6 个赞
好事儿啊
1 个赞
的确能用了,不是429了
1 个赞
很早就恢复了,不能用的时间加起来不到一天,那段时间本来不能搜索的1206也出现了搜索开关(但只是摆设没有实际作用),应该只是程序员写出bug了
还以为谷歌不让白嫖 关闭了免费账号的联网权限
2 个赞
免费每月1000次,对谷歌来说没什么成本,大部分人也用不到这么多。
2 个赞
那不好说, 之前出了个35刀/1000的谷歌搜索功能, 现在不知道是不是和这个集成到一起了
google是大善人
你这是什么工具,默认联网吗?没看到联网开关
我这是open-webui,配置了个联网的函数
import json
import random
import httpx
import requests
from typing import List, AsyncGenerator, Callable, Awaitable
from pydantic import BaseModel, Field
class Pipe:
class Valves(BaseModel):
GOOGLE_API_KEYS_STR: str = Field(
default="", description="API Keys for Google, use ',' to split"
)
OPEN_SAFETY: bool = Field(default=False, description="Gemini safety settings")
OPEN_SEARCH: bool = Field(
default=True, description="Enable open search for models"
)
def __init__(self):
self.type = "manifold"
self.name = ""
self.valves = self.Valves()
self.base_url = "https://generativelanguage.googleapis.com/v1beta"
self.OPEN_SEARCH_MODELS = ["gemini-2.0-flash-exp"]
self.emitter = None
def get_google_models(self) -> List[dict]:
return [
{"id": "gemini-2.0-flash-exp", "name": "gemini-2.0-flash-exp-WebSearch"}
]
async def emit_status(
self,
message: str = "",
done: bool = False,
):
await self.emitter(
{
"type": "status",
"data": {
"description": message,
"done": done,
},
}
)
def pipes(self) -> List[dict]:
return self.get_google_models()
async def pipe(
self,
body: dict,
__event_emitter__: Callable[[dict], Awaitable[None]] = None,
) -> AsyncGenerator[str, None]:
self.emitter = __event_emitter__
self.GOOGLE_API_KEYS_LIST = self.valves.GOOGLE_API_KEYS_STR.split(",")
self.GOOGLE_API_KEY = random.choice(self.GOOGLE_API_KEYS_LIST)
if not self.GOOGLE_API_KEY:
yield "Error: GOOGLE_API_KEY is not set"
try:
model_id = body["model"]
if "." in model_id:
model_id = model_id.split(".", 1)[1]
messages = body["messages"]
stream = body.get("stream", False)
# Prepare the request payload
contents = []
request_data = {
"generationConfig": {
"temperature": body.get("temperature", 0.7),
"topP": body.get("top_p", 0.9),
"topK": body.get("top_k", 40),
"maxOutputTokens": body.get("max_tokens", 8192),
"stopSequences": body.get("stop", []),
},
}
for message in messages:
if message["role"] == "system":
request_data["system_instruction"] = {
"parts": [{"text": message["content"]}]
}
if message["role"] != "system":
if isinstance(message.get("content"), str):
contents.append(
{
"role": (
"user" if message["role"] == "user" else "model"
),
"parts": [{"text": message["content"]}],
}
)
if isinstance(message.get("content"), list):
parts = []
for content in message["content"]:
if content["type"] == "text":
parts.append({"text": content["text"]})
elif content["type"] == "image_url":
image_url = content["image_url"]["url"]
if image_url.startswith("data:image"):
image_data = image_url.split(",")[1]
parts.append(
{
"inline_data": {
"mime_type": "image/jpeg",
"data": image_data,
}
}
)
else:
parts.append({"image_url": image_url})
contents.append({"role": message["role"], "parts": parts})
else:
contents.append(
{
"role": (
"user" if message["role"] == "user" else "model"
),
"parts": [{"text": message["content"]}],
}
)
request_data["contents"] = contents
if self.valves.OPEN_SEARCH and model_id in self.OPEN_SEARCH_MODELS:
request_data["tools"] = [{"googleSearch": {}}]
await self.emit_status(message="🔍 我好像在搜索……")
else:
await self.emit_status(message="🚀 我好像在思考……")
if self.valves.OPEN_SAFETY:
request_data["safetySettings"] = [
{"category": "HARM_CATEGORY_HARASSMENT", "threshold": "BLOCK_NONE"},
{
"category": "HARM_CATEGORY_HATE_SPEECH",
"threshold": "BLOCK_NONE",
},
{
"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
"threshold": "BLOCK_NONE",
},
{
"category": "HARM_CATEGORY_DANGEROUS_CONTENT",
"threshold": "BLOCK_NONE",
},
]
params = {"key": self.GOOGLE_API_KEY}
if stream:
url = f"{self.base_url}/models/{model_id}:streamGenerateContent"
params["alt"] = "sse"
else:
url = f"{self.base_url}/models/{model_id}:generateContent"
headers = {"Content-Type": "application/json"}
async with httpx.AsyncClient() as client:
if stream:
url = f"{self.base_url}/models/{model_id}:streamGenerateContent"
params = {"key": self.GOOGLE_API_KEY, "alt": "sse"}
async with client.stream(
"POST", url, json=request_data, headers=headers, params=params
) as response:
if response.status_code != 200:
yield f"Error: HTTP {response.status_code}: {response.text}"
return
async for line in response.aiter_lines():
if line.startswith("data: "):
try:
data = json.loads(line[6:])
if "candidates" in data and data["candidates"]:
text = data["candidates"][0]["content"][
"parts"
][0]["text"]
yield text
except json.JSONDecodeError:
continue
except Exception as e:
yield f"Error parsing stream: {str(e)}"
await self.emit_status(message="🎉 生成成功", done=True)
else:
url = f"{self.base_url}/models/{model_id}:generateContent"
params = {"key": self.GOOGLE_API_KEY}
response = await client.post(
url, json=request_data, headers=headers, params=params
)
if response.status_code != 200:
yield f"Error: HTTP {response.status_code}: {response.text}"
return
data = response.json()
if "candidates" in data and data["candidates"]:
yield data["candidates"][0]["content"]["parts"][0]["text"]
else:
yield "No response data"
await self.emit_status(message="🎉 生成成功", done=True)
except Exception as e:
yield f"Error: {str(e)}"
3 个赞
加了这个函数 就能联网搜索吗
1 个赞
然后得自己设置密钥
这个界面好看,今天想搭建一下的,搭建到一半,VPS挂了,听大佬说,这个占用资源挺大的。
這個是在請求中加入tools嗎
還是開一個新的模型
好奇是因為我想用newapi負載均衡
相關issue
羡慕了
我这是家里的服务器集群 , 云服务器买不起
那也挺好的,只要能用,就可以了。目的不就是为了用吗?
直接在open-webui的函数里面加上这个
然后请求会直接走google官方