1.优化隔离工作目录2.新增图像生成和编辑功能3.生成模型替换为本地flux2 klein
This commit is contained in:
5
main.py
5
main.py
@@ -1,11 +1,11 @@
|
|||||||
import logging.config
|
import logging.config
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import uvicorn
|
import uvicorn
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
|
||||||
from logging_env import LOGGER_CONFIG_DICT
|
from logging_env import LOGGER_CONFIG_DICT
|
||||||
from src.routers import chat, deep_agent_chat
|
from src.routers import deep_agent_chat
|
||||||
from src.routers import generate_3D
|
from src.routers import generate_3D
|
||||||
from src.routers import flux2_gen_img
|
from src.routers import flux2_gen_img
|
||||||
|
|
||||||
@@ -26,7 +26,6 @@ app_server.add_middleware(
|
|||||||
)
|
)
|
||||||
|
|
||||||
# 包含路由
|
# 包含路由
|
||||||
app_server.include_router(chat.router)
|
|
||||||
app_server.include_router(deep_agent_chat.router)
|
app_server.include_router(deep_agent_chat.router)
|
||||||
app_server.include_router(generate_3D.router)
|
app_server.include_router(generate_3D.router)
|
||||||
app_server.include_router(flux2_gen_img.router)
|
app_server.include_router(flux2_gen_img.router)
|
||||||
|
|||||||
@@ -48,4 +48,6 @@ dependencies = [
|
|||||||
"path>=17.1.1",
|
"path>=17.1.1",
|
||||||
"langgraph-checkpoint-postgres>=3.0.4",
|
"langgraph-checkpoint-postgres>=3.0.4",
|
||||||
"langgraph-store-mongodb>=0.2.0",
|
"langgraph-store-mongodb>=0.2.0",
|
||||||
|
"tool>=0.8.0",
|
||||||
|
"langchain-daytona>=0.0.3",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
|
||||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||||
from pydantic import Field
|
from pydantic import Field
|
||||||
|
|
||||||
@@ -44,3 +46,7 @@ class Settings(BaseSettings):
|
|||||||
|
|
||||||
settings = Settings()
|
settings = Settings()
|
||||||
MONGO_URI = f"mongodb://{settings.MONGODB_USERNAME}:{settings.MONGODB_PASSWORD}@{settings.MONGODB_HOST}:{settings.MONGODB_PORT}"
|
MONGO_URI = f"mongodb://{settings.MONGODB_USERNAME}:{settings.MONGODB_PASSWORD}@{settings.MONGODB_HOST}:{settings.MONGODB_PORT}"
|
||||||
|
|
||||||
|
TOOL_DIR = Path(__file__).resolve().parent
|
||||||
|
PROJECT_ROOT = TOOL_DIR.parent
|
||||||
|
print(f"PROJECT_ROOT : {PROJECT_ROOT}")
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
import random
|
import random
|
||||||
import uuid
|
import uuid
|
||||||
import json
|
import json
|
||||||
@@ -6,6 +7,8 @@ from typing import AsyncGenerator
|
|||||||
|
|
||||||
from fastapi import APIRouter
|
from fastapi import APIRouter
|
||||||
from fastapi.responses import StreamingResponse
|
from fastapi.responses import StreamingResponse
|
||||||
|
|
||||||
|
from src.core.config import PROJECT_ROOT
|
||||||
from src.schemas.deep_agent_chat import DeepAgentChatRequest, HistoryResponse, HistoryItem
|
from src.schemas.deep_agent_chat import DeepAgentChatRequest, HistoryResponse, HistoryItem
|
||||||
from langchain_core.messages import HumanMessage, SystemMessage, AIMessageChunk, ToolMessage, AIMessage, ToolMessageChunk
|
from langchain_core.messages import HumanMessage, SystemMessage, AIMessageChunk, ToolMessage, AIMessage, ToolMessageChunk
|
||||||
|
|
||||||
@@ -77,13 +80,15 @@ async def chat_stream(request: DeepAgentChatRequest):
|
|||||||
source_thread_id = request.thread_id
|
source_thread_id = request.thread_id
|
||||||
checkpoint_id = request.checkpoint_id
|
checkpoint_id = request.checkpoint_id
|
||||||
|
|
||||||
# 构建主agent
|
|
||||||
main_agent = build_main_agent(request.use_report)
|
|
||||||
|
|
||||||
# 1. 確定目標 thread_id
|
# 1. 確定目標 thread_id
|
||||||
is_branching = source_thread_id and checkpoint_id
|
is_branching = source_thread_id and checkpoint_id
|
||||||
target_thread_id = str(uuid.uuid4())[:8] if is_branching else (source_thread_id or str(uuid.uuid4())[:8])
|
target_thread_id = str(uuid.uuid4())[:8] if is_branching else (source_thread_id or str(uuid.uuid4())[:8])
|
||||||
|
|
||||||
|
# 构建主agent
|
||||||
|
workspace_dir = os.path.join(PROJECT_ROOT, f"agent_workspace/{target_thread_id}")
|
||||||
|
print(f"target_thread_id : workspace_dir: {workspace_dir}")
|
||||||
|
main_agent = build_main_agent(request.use_report, workspace_dir)
|
||||||
|
|
||||||
# 2. 配置參數
|
# 2. 配置參數
|
||||||
temp = request.config_params.temperature if request.config_params else 0.7
|
temp = request.config_params.temperature if request.config_params else 0.7
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ class AgentConfig(BaseModel):
|
|||||||
|
|
||||||
class DeepAgentChatRequest(BaseModel):
|
class DeepAgentChatRequest(BaseModel):
|
||||||
message: str = Field(..., description="用户的输入指令")
|
message: str = Field(..., description="用户的输入指令")
|
||||||
|
# image_url: Optional[str] = Field(None, description="图片地址") # ✅ 新增
|
||||||
thread_id: Optional[str] = Field(None, description="会话线程ID,不传则开启新会话")
|
thread_id: Optional[str] = Field(None, description="会话线程ID,不传则开启新会话")
|
||||||
checkpoint_id: Optional[str] = Field(None, description="回溯点的ID,用于从历史点开启新对话")
|
checkpoint_id: Optional[str] = Field(None, description="回溯点的ID,用于从历史点开启新对话")
|
||||||
config_params: Optional[AgentConfig] = None
|
config_params: Optional[AgentConfig] = None
|
||||||
|
|||||||
@@ -1,21 +1,22 @@
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
from daytona import Daytona
|
||||||
from deepagents import create_deep_agent
|
from deepagents import create_deep_agent
|
||||||
from deepagents.backends import FilesystemBackend
|
from deepagents.backends import FilesystemBackend
|
||||||
from langchain.agents.middleware import SummarizationMiddleware
|
from langchain.agents.middleware import SummarizationMiddleware
|
||||||
from langgraph.checkpoint.mongodb import MongoDBSaver
|
from langgraph.checkpoint.mongodb import MongoDBSaver
|
||||||
from langgraph.checkpoint.serde.jsonplus import JsonPlusSerializer
|
from langgraph.checkpoint.serde.jsonplus import JsonPlusSerializer
|
||||||
from pymongo import MongoClient
|
from pymongo import MongoClient
|
||||||
|
from daytona import CreateSandboxFromSnapshotParams, Daytona
|
||||||
|
from langchain_daytona import DaytonaSandbox
|
||||||
|
|
||||||
from src.core.config import MONGO_URI
|
from src.core.config import MONGO_URI
|
||||||
from src.server.deep_agent.agents.painter import painter_subagent
|
from src.server.deep_agent.agents.painter import build_painter_subagent
|
||||||
from src.server.deep_agent.agents.researcher import research_subagent
|
from src.server.deep_agent.agents.researcher import build_researcher_subagent
|
||||||
from src.server.deep_agent.agents.user_profile import user_profile_subagent
|
from src.server.deep_agent.agents.user_profile import user_profile_subagent
|
||||||
from src.server.deep_agent.init_llm import main_llm
|
from src.server.deep_agent.init_llm import main_llm
|
||||||
from src.server.deep_agent.init_prompt import build_system_prompt
|
from src.server.deep_agent.init_prompt import build_system_prompt
|
||||||
|
|
||||||
TOOL_DIR = Path(__file__).resolve().parent
|
|
||||||
PROJECT_ROOT = TOOL_DIR.parent
|
|
||||||
client = MongoClient(MONGO_URI)
|
client = MongoClient(MONGO_URI)
|
||||||
checkpointer = MongoDBSaver(
|
checkpointer = MongoDBSaver(
|
||||||
client=client["furniture_agent_db"],
|
client=client["furniture_agent_db"],
|
||||||
@@ -23,22 +24,42 @@ checkpointer = MongoDBSaver(
|
|||||||
collection_name="fida_agent_collection",
|
collection_name="fida_agent_collection",
|
||||||
serde=JsonPlusSerializer(pickle_fallback=True), # ← 關鍵這一行
|
serde=JsonPlusSerializer(pickle_fallback=True), # ← 關鍵這一行
|
||||||
)
|
)
|
||||||
subagents = [
|
|
||||||
painter_subagent,
|
|
||||||
research_subagent,
|
|
||||||
user_profile_subagent
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def build_main_agent(use_report):
|
class CanvasMiddleware:
|
||||||
|
def before_agent(self, state, agent_input, **kwargs):
|
||||||
|
canvas = state.get("canvas", {})
|
||||||
|
|
||||||
|
info = f"""
|
||||||
|
当前画布状态:
|
||||||
|
- image_path: {canvas.get("image_path")}
|
||||||
|
- 是否已有图片: {bool(canvas.get("image_path"))}
|
||||||
|
"""
|
||||||
|
|
||||||
|
agent_input["messages"].append({
|
||||||
|
"role": "system",
|
||||||
|
"content": info
|
||||||
|
})
|
||||||
|
|
||||||
|
return state, agent_input
|
||||||
|
|
||||||
|
|
||||||
|
def build_main_agent(use_report, workspace_dir):
|
||||||
|
research_subagent = build_researcher_subagent(workspace_dir)
|
||||||
|
painter_subagent = build_painter_subagent(workspace_dir)
|
||||||
|
subagents = [
|
||||||
|
painter_subagent,
|
||||||
|
research_subagent,
|
||||||
|
user_profile_subagent
|
||||||
|
]
|
||||||
main_agent = create_deep_agent(
|
main_agent = create_deep_agent(
|
||||||
model=main_llm,
|
model=main_llm,
|
||||||
system_prompt=build_system_prompt(use_report=use_report),
|
system_prompt=build_system_prompt(use_report=use_report),
|
||||||
subagents=subagents,
|
subagents=subagents,
|
||||||
checkpointer=checkpointer,
|
checkpointer=checkpointer,
|
||||||
backend=FilesystemBackend(
|
backend=FilesystemBackend(
|
||||||
root_dir=str(PROJECT_ROOT / "agent_workspace"),
|
root_dir=workspace_dir,
|
||||||
virtual_mode=False, # 重要:關掉虛擬模式 → 真的寫硬碟
|
virtual_mode=True, # 重要:關掉虛擬模式 → 真的寫硬碟
|
||||||
),
|
),
|
||||||
middleware=[
|
middleware=[
|
||||||
SummarizationMiddleware(
|
SummarizationMiddleware(
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from langchain.agents.middleware import wrap_tool_call
|
|||||||
|
|
||||||
from src.server.deep_agent.init_llm import llm
|
from src.server.deep_agent.init_llm import llm
|
||||||
from src.server.deep_agent.init_prompt import build_painter_prompt
|
from src.server.deep_agent.init_prompt import build_painter_prompt
|
||||||
from src.server.deep_agent.tools.generate_furniture_sketch import generate_furniture
|
from src.server.deep_agent.tools.generate_furniture_sketch import create_generate_furniture_tool, create_edit_furniture_tool
|
||||||
|
|
||||||
|
|
||||||
@wrap_tool_call
|
@wrap_tool_call
|
||||||
@@ -12,11 +12,16 @@ async def log_tool_calls(request, handler):
|
|||||||
return handler(request)
|
return handler(request)
|
||||||
|
|
||||||
|
|
||||||
painter_subagent = {
|
def build_painter_subagent(workspace_dir):
|
||||||
"name": "painter_subagent",
|
generate_furniture = create_generate_furniture_tool(workspace_dir)
|
||||||
"description": "理解用户意图,使用prompt,调用generate_furniture工具生成家具sketch草图.",
|
edit_furniture = create_edit_furniture_tool(workspace_dir)
|
||||||
"system_prompt": build_painter_prompt(),
|
|
||||||
"tools": [generate_furniture],
|
painter_subagent = {
|
||||||
"model": llm,
|
"name": "painter_subagent",
|
||||||
# "middleware": [log_tool_calls],
|
"description": "理解用户意图,利用prompt编辑或生成家具sketch图像",
|
||||||
}
|
"system_prompt": build_painter_prompt(),
|
||||||
|
"tools": [generate_furniture, edit_furniture],
|
||||||
|
"model": llm,
|
||||||
|
# "middleware": [log_tool_calls],
|
||||||
|
}
|
||||||
|
return painter_subagent
|
||||||
|
|||||||
@@ -1,21 +1,27 @@
|
|||||||
from src.server.deep_agent.init_llm import llm
|
from src.server.deep_agent.init_llm import llm
|
||||||
from src.server.deep_agent.init_prompt import build_researcher_prompt
|
from src.server.deep_agent.init_prompt import build_researcher_prompt
|
||||||
from src.server.deep_agent.tools.crawl_tool import crawl4ai_batch
|
from src.server.deep_agent.tools.crawl_tool import create_crawl4ai_batch_tool
|
||||||
from src.server.deep_agent.tools.report_generator_tool import report_generator
|
from src.server.deep_agent.tools.report_generator_tool import create_report_generator_tool
|
||||||
from src.server.deep_agent.tools.research_tool import topic_research
|
from src.server.deep_agent.tools.research_tool import topic_research
|
||||||
from src.server.deep_agent.tools.structured_retrieval_tool import structured_retrieval
|
from src.server.deep_agent.tools.structured_retrieval_tool import create_structured_retrieval_tool
|
||||||
from src.server.deep_agent.tools.user_persona_tool import query_report_profile
|
from src.server.deep_agent.tools.user_persona_tool import query_report_profile
|
||||||
|
|
||||||
research_subagent = {
|
|
||||||
"name": "research_subagent",
|
def build_researcher_subagent(workspace_dir):
|
||||||
"description": "通过网络搜索对家具设计开展深度研究并整合结论",
|
crawl4ai_batch = create_crawl4ai_batch_tool(workspace_dir)
|
||||||
"system_prompt": build_researcher_prompt(),
|
structured_retrieval = create_structured_retrieval_tool(workspace_dir)
|
||||||
"tools": [
|
report_generator = create_report_generator_tool(workspace_dir)
|
||||||
query_report_profile,
|
research_subagent = {
|
||||||
topic_research,
|
"name": "research_subagent",
|
||||||
crawl4ai_batch,
|
"description": "通过网络搜索对家具设计开展深度研究并整合结论",
|
||||||
structured_retrieval,
|
"system_prompt": build_researcher_prompt(),
|
||||||
report_generator
|
"tools": [
|
||||||
],
|
query_report_profile,
|
||||||
"model": llm
|
topic_research,
|
||||||
}
|
crawl4ai_batch,
|
||||||
|
structured_retrieval,
|
||||||
|
report_generator
|
||||||
|
],
|
||||||
|
"model": llm
|
||||||
|
}
|
||||||
|
return research_subagent
|
||||||
|
|||||||
77
src/server/deep_agent/agents/vision_subagent.py
Normal file
77
src/server/deep_agent/agents/vision_subagent.py
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
from src.server.deep_agent.init_llm import vision_llm
|
||||||
|
from src.server.deep_agent.tools.vision_analyze_tool import vision_analyze_tool
|
||||||
|
|
||||||
|
vision_subagent = {
|
||||||
|
"name": "vision_subagent",
|
||||||
|
"description": "分析用户上传的图片,提取家具、风格、颜色、材质等信息",
|
||||||
|
"system_prompt": """
|
||||||
|
你是一个专业的视觉分析助手(家具设计方向)。
|
||||||
|
|
||||||
|
你的任务:
|
||||||
|
1. 理解用户提供的图片(路径或URL)
|
||||||
|
2. 分析家具内容
|
||||||
|
3. 输出结构化JSON(不要解释)
|
||||||
|
|
||||||
|
格式:
|
||||||
|
{
|
||||||
|
"objects": [],
|
||||||
|
"style": "",
|
||||||
|
"color": [],
|
||||||
|
"material": [],
|
||||||
|
"room_type": "",
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
""",
|
||||||
|
"tools": [], # ❗这里不用tool,直接用多模态模型
|
||||||
|
"model": vision_llm,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def vision_execute(state):
|
||||||
|
image = state.get("image")
|
||||||
|
|
||||||
|
if image is None:
|
||||||
|
return {
|
||||||
|
"error": "NO_IMAGE"
|
||||||
|
}
|
||||||
|
|
||||||
|
prompt = """
|
||||||
|
你是一个家具视觉分析模型。
|
||||||
|
|
||||||
|
任务:分析图片并输出JSON:
|
||||||
|
|
||||||
|
{
|
||||||
|
"objects": [],
|
||||||
|
"style": "",
|
||||||
|
"color": [],
|
||||||
|
"material": [],
|
||||||
|
"room_type": "",
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
|
||||||
|
规则:
|
||||||
|
- 只基于图像内容
|
||||||
|
- 不允许编造
|
||||||
|
- objects 最多5个
|
||||||
|
- color 最多3个
|
||||||
|
- 只输出JSON
|
||||||
|
"""
|
||||||
|
|
||||||
|
result = vision_llm.generate(
|
||||||
|
image=image, # ⭐ 关键:真正喂图
|
||||||
|
prompt=prompt
|
||||||
|
)
|
||||||
|
|
||||||
|
return safe_parse_json(result)
|
||||||
|
|
||||||
|
|
||||||
|
def safe_parse_json(text):
|
||||||
|
try:
|
||||||
|
return json.loads(text)
|
||||||
|
except:
|
||||||
|
return {
|
||||||
|
"error": "INVALID_JSON",
|
||||||
|
"raw": text
|
||||||
|
}
|
||||||
@@ -49,3 +49,12 @@ repoer_llm = ChatQwen(
|
|||||||
timeout=None,
|
timeout=None,
|
||||||
max_retries=2,
|
max_retries=2,
|
||||||
api_key=settings.QWEN_API_KEY)
|
api_key=settings.QWEN_API_KEY)
|
||||||
|
|
||||||
|
vision_llm = ChatQwen(
|
||||||
|
enable_thinking=False,
|
||||||
|
model="qwen3-vl-plus",
|
||||||
|
temperature=0.2,
|
||||||
|
max_tokens=3_000,
|
||||||
|
timeout=None,
|
||||||
|
max_retries=2,
|
||||||
|
api_key=settings.QWEN_API_KEY)
|
||||||
|
|||||||
@@ -15,7 +15,10 @@ def build_system_prompt(use_report):
|
|||||||
负责生成完整报告、调研、总结、分析。
|
负责生成完整报告、调研、总结、分析。
|
||||||
|
|
||||||
3. painter_subagent
|
3. painter_subagent
|
||||||
负责根据用户描述,构造适用于生成家具sketch的prompt,使用prompt用工具生成图片.
|
负责根据用户描述,构造适用于 生成家具sketch的prompt或编辑家具sketch的prompt
|
||||||
|
1.利用prompt用工具生成图片.
|
||||||
|
2.利用prompt和图片路径用工具编辑图片.
|
||||||
|
|
||||||
|
|
||||||
========================
|
========================
|
||||||
执行规则
|
执行规则
|
||||||
@@ -51,31 +54,26 @@ def build_system_prompt(use_report):
|
|||||||
- research-subagent 只负责 **报告生成**
|
- research-subagent 只负责 **报告生成**
|
||||||
不要混用职责。
|
不要混用职责。
|
||||||
========================
|
========================
|
||||||
严格输出规则
|
|
||||||
========================
|
|
||||||
- 当生成图片时,绝对不要输出图片路径、file:// 地址、URL、本地链接
|
|
||||||
- 只输出文字描述,不输出任何图片链接或路径
|
|
||||||
"""
|
"""
|
||||||
return system_prompt
|
return system_prompt
|
||||||
|
|
||||||
|
|
||||||
def build_painter_prompt():
|
def build_painter_prompt():
|
||||||
prompt = """
|
prompt = """
|
||||||
你是一名专业的prompt优化专家,专注于家具设计草图生成。你的任务是:
|
你是 painter_subagent,专门生成或编辑 sketch 图。
|
||||||
1. 分析用户查询,理解核心意图,包括家具类型、风格、尺寸、颜色、材料等关键元素
|
1. 每次开始决策前,先调用工具 read_file("/current_sketch_path.txt") 获取当前路径。
|
||||||
2. 基于意图,优化并生成一个详细、精确的prompt,适合用于AI图片生成工具创建家具sketch草图(例如,线条简洁、手绘风格、焦点在设计细节上)
|
- 如果文件不存在或返回空 → 当前没有历史图,使用 generate_sketch。
|
||||||
3. 使用优化的prompt调用图片生成工具,生成并返回草图图片
|
- 如果有路径 → 检查用户意图是否为「修改/编辑/改成/调整/优化/把...变成」,如果是则必须使用 edit_sketch,并传入 image_path = 读取到的路径。
|
||||||
4. 如果需要,建议额外变体或改进
|
2. 生成或编辑完成后,**必须立即**调用 write_file("/current_sketch_path.txt", content=本次生成的图片完整路径) 来更新状态。
|
||||||
|
3. 【对用户隐藏路径】:
|
||||||
输出格式:
|
- 永远不要在最终回复给用户的任何消息中出现路径、/tmp/、/current_sketch_path.txt 等字符串!
|
||||||
- 用户意图总结(1–2段)
|
- 回复格式只能是:
|
||||||
- 优化后的prompt(完整文本)
|
"图片已成功生成!"
|
||||||
- 生成的图片描述(如果工具返回)
|
或
|
||||||
- 建议改进(项目符号,可选)
|
"已按你的要求把狗改成猫,图片更新完成!"
|
||||||
【严格输出规则】
|
- 如果前端支持图片展示,你可以直接返回图片(但不要带路径文字)。
|
||||||
- 当生成图片时,**绝对不要输出图片路径、file:// 地址、URL、本地链接**。
|
|
||||||
- 只输出文字描述,不输出任何图片链接或路径。
|
|
||||||
|
|
||||||
|
现在开始严格遵守以上规则。
|
||||||
"""
|
"""
|
||||||
return prompt
|
return prompt
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import os
|
||||||
import time
|
import time
|
||||||
import asyncio
|
import asyncio
|
||||||
from typing import List, Dict, Any
|
from typing import List, Dict, Any
|
||||||
@@ -8,19 +9,6 @@ import uuid
|
|||||||
from crawl4ai import AsyncWebCrawler, BrowserConfig, CrawlerRunConfig, CacheMode
|
from crawl4ai import AsyncWebCrawler, BrowserConfig, CrawlerRunConfig, CacheMode
|
||||||
from langchain_core.tools import tool
|
from langchain_core.tools import tool
|
||||||
|
|
||||||
# ─────────────────────────────────────
|
|
||||||
# 路径配置
|
|
||||||
# ─────────────────────────────────────
|
|
||||||
|
|
||||||
TOOL_DIR = Path(__file__).resolve().parent
|
|
||||||
PROJECT_ROOT = TOOL_DIR.parent
|
|
||||||
|
|
||||||
# DeepAgents 推荐目录
|
|
||||||
SAVE_DIR = PROJECT_ROOT / "agent_workspace" / "raw_data"
|
|
||||||
SAVE_DIR.mkdir(parents=True, exist_ok=True)
|
|
||||||
|
|
||||||
print(f"tool save : {str(PROJECT_ROOT / "agent_workspace")}")
|
|
||||||
|
|
||||||
# ─────────────────────────────────────
|
# ─────────────────────────────────────
|
||||||
# Browser 配置
|
# Browser 配置
|
||||||
# ─────────────────────────────────────
|
# ─────────────────────────────────────
|
||||||
@@ -65,7 +53,7 @@ def build_filename(url: str) -> str:
|
|||||||
# 单个 URL 抓取
|
# 单个 URL 抓取
|
||||||
# ─────────────────────────────────────
|
# ─────────────────────────────────────
|
||||||
|
|
||||||
async def crawl_one(crawler, url: str, sem: asyncio.Semaphore) -> Dict[str, Any]:
|
async def crawl_one(crawler, url: str, sem: asyncio.Semaphore, save_dir: str) -> Dict[str, Any]:
|
||||||
async with sem:
|
async with sem:
|
||||||
try:
|
try:
|
||||||
result = await crawler.arun(url=url, config=run_config)
|
result = await crawler.arun(url=url, config=run_config)
|
||||||
@@ -87,7 +75,7 @@ async def crawl_one(crawler, url: str, sem: asyncio.Semaphore) -> Dict[str, Any]
|
|||||||
}
|
}
|
||||||
|
|
||||||
filename = build_filename(url)
|
filename = build_filename(url)
|
||||||
filepath = SAVE_DIR / filename
|
filepath = os.path.join(save_dir, filename)
|
||||||
|
|
||||||
header = (
|
header = (
|
||||||
f"<!-- Source: {url} -->\n"
|
f"<!-- Source: {url} -->\n"
|
||||||
@@ -115,7 +103,7 @@ async def crawl_one(crawler, url: str, sem: asyncio.Semaphore) -> Dict[str, Any]
|
|||||||
# Async 主逻辑
|
# Async 主逻辑
|
||||||
# ─────────────────────────────────────
|
# ─────────────────────────────────────
|
||||||
|
|
||||||
async def _crawl4ai_batch(urls: List[str]) -> Dict[str, Any]:
|
async def _crawl4ai_batch(urls: List[str], save_dir: str) -> Dict[str, Any]:
|
||||||
urls = list(set(urls)) # 去重
|
urls = list(set(urls)) # 去重
|
||||||
|
|
||||||
if not urls:
|
if not urls:
|
||||||
@@ -126,7 +114,7 @@ async def _crawl4ai_batch(urls: List[str]) -> Dict[str, Any]:
|
|||||||
async with AsyncWebCrawler(config=browser_config) as crawler:
|
async with AsyncWebCrawler(config=browser_config) as crawler:
|
||||||
|
|
||||||
tasks = [
|
tasks = [
|
||||||
crawl_one(crawler, url, sem)
|
crawl_one(crawler, url, sem, save_dir)
|
||||||
for url in urls
|
for url in urls
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -150,42 +138,46 @@ async def _crawl4ai_batch(urls: List[str]) -> Dict[str, Any]:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# ─────────────────────────────────────
|
def create_crawl4ai_batch_tool(workspace_dir):
|
||||||
# Tool(同步)
|
@tool
|
||||||
# ─────────────────────────────────────
|
def crawl4ai_batch(urls: List[str]) -> str:
|
||||||
@tool
|
"""
|
||||||
def crawl4ai_batch(urls: List[str]) -> str:
|
Batch crawl webpages and save their content as markdown files.
|
||||||
"""
|
|
||||||
Batch crawl webpages and save their content as markdown files.
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
urls: List of webpage URLs to crawl.
|
urls: List of webpage URLs to crawl.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A summary of crawling results and saved file paths.
|
A summary of crawling results and saved file paths.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
result = asyncio.run(_crawl4ai_batch(urls))
|
save_dir = os.path.join(workspace_dir, "raw_data")
|
||||||
|
if not os.path.exists(save_dir):
|
||||||
|
os.makedirs(save_dir, exist_ok=True)
|
||||||
|
|
||||||
if "error" in result:
|
result = asyncio.run(_crawl4ai_batch(urls, save_dir))
|
||||||
return f"❌ Error: {result['error']}"
|
|
||||||
|
|
||||||
output = [
|
if "error" in result:
|
||||||
"### 批量抓取完成 ###",
|
return f"❌ Error: {result['error']}"
|
||||||
f"成功保存文件: {result['count']}",
|
|
||||||
f"保存目录: {SAVE_DIR}",
|
|
||||||
"",
|
|
||||||
"抓取详情:"
|
|
||||||
]
|
|
||||||
|
|
||||||
output.extend(result["summary"])
|
output = [
|
||||||
|
"### 批量抓取完成 ###",
|
||||||
|
f"成功保存文件: {result['count']}",
|
||||||
|
f"保存目录: {workspace_dir}",
|
||||||
|
"",
|
||||||
|
"抓取详情:"
|
||||||
|
]
|
||||||
|
|
||||||
if result["saved_files"]:
|
output.extend(result["summary"])
|
||||||
output.append("\n可读取文件:")
|
|
||||||
output.extend(result["saved_files"])
|
|
||||||
|
|
||||||
return "\n".join(output)
|
if result["saved_files"]:
|
||||||
|
output.append("\n可读取文件:")
|
||||||
|
output.extend(result["saved_files"])
|
||||||
|
|
||||||
except Exception as e:
|
return "\n".join(output)
|
||||||
return f"🚨 爬虫系统异常: {str(e)}"
|
|
||||||
|
except Exception as e:
|
||||||
|
return f"🚨 爬虫系统异常: {str(e)}"
|
||||||
|
|
||||||
|
return crawl4ai_batch
|
||||||
|
|||||||
@@ -1,15 +1,21 @@
|
|||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
import uuid
|
import uuid
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Annotated
|
||||||
|
|
||||||
|
import httpx
|
||||||
from google.oauth2 import service_account
|
from google.oauth2 import service_account
|
||||||
from langchain_core.tools import tool
|
from langchain_core.tools import tool
|
||||||
from google import genai
|
from google import genai
|
||||||
from google.genai.types import GenerateContentConfig, Modality
|
from google.genai.types import GenerateContentConfig, Modality
|
||||||
|
from langgraph.prebuilt import ToolRuntime
|
||||||
|
|
||||||
from minio import Minio
|
from minio import Minio
|
||||||
|
|
||||||
from src.core.config import settings
|
from src.core.config import settings
|
||||||
from src.server.utils.new_oss_client import oss_upload_image
|
from src.server.utils.new_oss_client import oss_upload_image, oss_get_image, is_minio_file_exist, oss_upload_image_file
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
# 初始化全局凭证和客户端
|
# 初始化全局凭证和客户端
|
||||||
@@ -27,47 +33,187 @@ client = genai.Client(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@tool
|
def is_image_path_exist(image_path):
|
||||||
async def generate_furniture(prompt: str) -> str:
|
|
||||||
"""
|
|
||||||
使用 Gemini 图像生成模型根据详细的英文提示词生成家具设计草图。
|
|
||||||
"""
|
|
||||||
print(f"\n[系统日志] 正在调用 Nano Banana (Gemini Image Gen) ...")
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
response = client.models.generate_content(
|
return Path(image_path).exists()
|
||||||
model="gemini-2.5-flash-image",
|
except:
|
||||||
contents=(f"Generate a professional furniture design sketch: {prompt}"),
|
return False
|
||||||
config=GenerateContentConfig(
|
|
||||||
response_modalities=[Modality.TEXT, Modality.IMAGE],
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
image_bytes = None
|
|
||||||
for part in response.candidates[0].content.parts:
|
|
||||||
if part.inline_data:
|
|
||||||
image_bytes = part.inline_data.data
|
|
||||||
break
|
|
||||||
|
|
||||||
if not image_bytes:
|
def create_generate_furniture_tool(workspace_dir, width: int = 1024, height: int = 1024):
|
||||||
return "未能生成图像数据。"
|
@tool
|
||||||
object_name = f"furniture/sketches/{uuid.uuid4()}.png"
|
async def generate_furniture(prompt: str, runtime: ToolRuntime) -> str:
|
||||||
bucket = "fida-test" # 替换为你的 bucket 名称
|
"""
|
||||||
# 3. 调用你的上传函数
|
使用 Gemini 图像生成模型根据详细的英文提示词生成家具设计草图。
|
||||||
upload_res = oss_upload_image(
|
"""
|
||||||
oss_client=minio_client,
|
logger.info(f"\n[系统日志] 正在调用 generate_furniture ...")
|
||||||
bucket=bucket,
|
try:
|
||||||
object_name=object_name,
|
# 1. 生成图像 - local flux2-klein
|
||||||
image_bytes=image_bytes
|
object_name = f"furniture/sketches/{uuid.uuid4()}.png"
|
||||||
)
|
bucket_name = "fida-test" # 替换为你的 bucket 名称
|
||||||
|
request_data = {
|
||||||
|
"prompt": prompt,
|
||||||
|
"bucket_name": bucket_name,
|
||||||
|
"object_name": object_name,
|
||||||
|
"width": width,
|
||||||
|
"height": height
|
||||||
|
}
|
||||||
|
async with httpx.AsyncClient(timeout=120) as client:
|
||||||
|
resp = await client.post(
|
||||||
|
f"http://{settings.FLUX2_GEN_IMG_MODEL_URL}/predict",
|
||||||
|
json=request_data,
|
||||||
|
)
|
||||||
|
result = resp.json()
|
||||||
|
image_url = result.get("output_path", None)
|
||||||
|
|
||||||
if upload_res:
|
if image_url:
|
||||||
# 4. 构造访问链接 (如果是私有 bucket,需使用 presigned_get_object)
|
filename = os.path.join(workspace_dir, image_url)
|
||||||
# 这里简单示例为直接访问地址
|
# 2. 创建本地目录(确保目录存在)
|
||||||
image_url = f"{bucket}/{object_name}"
|
local_dir = os.path.dirname(filename)
|
||||||
return image_url
|
if not os.path.exists(local_dir):
|
||||||
else:
|
os.makedirs(local_dir, exist_ok=True)
|
||||||
return "图片生成成功,但上传至存储服务器失败。"
|
|
||||||
except Exception as e:
|
img = oss_get_image(oss_client=minio_client, bucket=image_url.split('/')[0], object_name=image_url[image_url.find('/') + 1:])
|
||||||
logger.warning(e)
|
img.save(filename)
|
||||||
return "绘图流程异常"
|
|
||||||
|
return image_url
|
||||||
|
else:
|
||||||
|
return f"Image generation failed."
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"绘图流程异常:{e}")
|
||||||
|
return "绘图流程异常"
|
||||||
|
|
||||||
|
return generate_furniture
|
||||||
|
|
||||||
|
|
||||||
|
def create_edit_furniture_tool(workspace_dir, width: int = 1024, height: int = 1024):
|
||||||
|
@tool
|
||||||
|
async def edit_furniture(prompt: str, input_image_path) -> str:
|
||||||
|
"""
|
||||||
|
使用图像生成模型根据详细的英文提示词编辑家具设计草图。
|
||||||
|
"""
|
||||||
|
logger.info(f"\n[系统日志] 正在调用 edit_furniture ...")
|
||||||
|
|
||||||
|
try:
|
||||||
|
# 0. 编辑前先检查工作环境和minio上是否存在该图像
|
||||||
|
input_image_path = input_image_path.lstrip('/')
|
||||||
|
filename = os.path.join(workspace_dir, input_image_path)
|
||||||
|
local_exist = is_image_path_exist(filename)
|
||||||
|
minio_exist = is_minio_file_exist(minio_client=minio_client, bucket_name=input_image_path.split('/')[0], object_name=input_image_path.split('/')[0])
|
||||||
|
|
||||||
|
if not local_exist and not minio_exist:
|
||||||
|
# 两个地方都不存在 直接报错
|
||||||
|
return f"Image generation failed."
|
||||||
|
elif local_exist and not minio_exist:
|
||||||
|
# 把本地的上传到minio
|
||||||
|
oss_upload_image_file(oss_client=minio_client, bucket=input_image_path.split('/')[0], object_name=input_image_path.split('/')[0], file_path=filename)
|
||||||
|
elif not local_exist and minio_exist:
|
||||||
|
# minio的下载到本地
|
||||||
|
img = oss_get_image(oss_client=minio_client, bucket=input_image_path.split('/')[0], object_name=input_image_path.split('/')[0], )
|
||||||
|
img.save(filename)
|
||||||
|
elif minio_exist and local_exist:
|
||||||
|
# 两个地方都存在 直接跳过
|
||||||
|
pass
|
||||||
|
|
||||||
|
# 1. 生成图像 - local flux2-klein
|
||||||
|
object_name = f"furniture/sketches/{uuid.uuid4()}.png"
|
||||||
|
bucket_name = "fida-test" # 替换为你的 bucket 名称
|
||||||
|
request_data = {
|
||||||
|
"input_image_paths": [input_image_path],
|
||||||
|
"prompt": prompt,
|
||||||
|
"bucket_name": bucket_name,
|
||||||
|
"object_name": object_name,
|
||||||
|
"width": width,
|
||||||
|
"height": height
|
||||||
|
}
|
||||||
|
async with httpx.AsyncClient(timeout=120) as client:
|
||||||
|
resp = await client.post(
|
||||||
|
f"http://{settings.FLUX2_GEN_IMG_MODEL_URL}/predict",
|
||||||
|
json=request_data,
|
||||||
|
)
|
||||||
|
result = resp.json()
|
||||||
|
image_url = result.get("output_path", None)
|
||||||
|
|
||||||
|
if image_url:
|
||||||
|
filename = os.path.join(workspace_dir, image_url)
|
||||||
|
# 2. 创建本地目录(确保目录存在)
|
||||||
|
local_dir = os.path.dirname(filename)
|
||||||
|
if not os.path.exists(local_dir):
|
||||||
|
os.makedirs(local_dir, exist_ok=True)
|
||||||
|
|
||||||
|
img = oss_get_image(oss_client=minio_client, bucket=image_url.split('/')[0], object_name=image_url[image_url.find('/') + 1:])
|
||||||
|
img.save(filename)
|
||||||
|
return image_url
|
||||||
|
else:
|
||||||
|
return f"Image generation failed."
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"edit_furniture error :{e}")
|
||||||
|
return "edit_furniture error"
|
||||||
|
|
||||||
|
return edit_furniture
|
||||||
|
|
||||||
|
# def create_generate_furniture_tool(workspace_dir):
|
||||||
|
# @tool
|
||||||
|
# async def generate_furniture(prompt: str) -> str:
|
||||||
|
# """
|
||||||
|
# 使用 Gemini 图像生成模型根据详细的英文提示词生成家具设计草图。
|
||||||
|
# """
|
||||||
|
# print(f"\n[系统日志] 正在调用 Nano Banana (Gemini Image Gen) ...")
|
||||||
|
#
|
||||||
|
# try:
|
||||||
|
# response = client.models.generate_content(
|
||||||
|
# model="gemini-2.5-flash-image",
|
||||||
|
# contents=(f"Generate a professional furniture design sketch: {prompt}"),
|
||||||
|
# config=GenerateContentConfig(
|
||||||
|
# response_modalities=[Modality.TEXT, Modality.IMAGE],
|
||||||
|
# ),
|
||||||
|
# )
|
||||||
|
#
|
||||||
|
# image_bytes = None
|
||||||
|
# for part in response.candidates[0].content.parts:
|
||||||
|
# if part.inline_data:
|
||||||
|
# image_bytes = part.inline_data.data
|
||||||
|
# break
|
||||||
|
#
|
||||||
|
# if not image_bytes:
|
||||||
|
# return "未能生成图像数据。"
|
||||||
|
# # 1. 定义OSS存储路径和本地保存路径
|
||||||
|
# object_name = f"furniture/sketches/{uuid.uuid4()}.png"
|
||||||
|
# bucket = "fida-test" # 替换为你的 bucket 名称
|
||||||
|
# filename = os.path.join(workspace_dir, f"{bucket}/{object_name}")
|
||||||
|
#
|
||||||
|
# # 2. 创建本地目录(确保目录存在)
|
||||||
|
# local_dir = os.path.dirname(filename)
|
||||||
|
# if not os.path.exists(local_dir):
|
||||||
|
# os.makedirs(local_dir, exist_ok=True)
|
||||||
|
#
|
||||||
|
# # 3. 保存图片到本地文件(新增核心逻辑)
|
||||||
|
# try:
|
||||||
|
# with open(filename, "wb") as f:
|
||||||
|
# f.write(image_bytes)
|
||||||
|
# print(f"[系统日志] 图片已保存到本地:{filename}")
|
||||||
|
# except Exception as save_e:
|
||||||
|
# logger.warning(f"保存图片到本地失败:{save_e}")
|
||||||
|
# # 本地保存失败不中断上传流程,仅记录日志
|
||||||
|
#
|
||||||
|
# # 4. 上传图片到OSS(原有逻辑)
|
||||||
|
# upload_res = oss_upload_image(
|
||||||
|
# oss_client=minio_client,
|
||||||
|
# bucket=bucket,
|
||||||
|
# object_name=object_name,
|
||||||
|
# image_bytes=image_bytes
|
||||||
|
# )
|
||||||
|
#
|
||||||
|
# if upload_res:
|
||||||
|
# image_url = f"{bucket}/{object_name}"
|
||||||
|
# return image_url
|
||||||
|
# else:
|
||||||
|
# return f"图片生成成功(本地路径:{filename}),但上传至存储服务器失败。"
|
||||||
|
#
|
||||||
|
# except Exception as e:
|
||||||
|
# logger.warning(f"绘图流程异常:{e}")
|
||||||
|
# return "绘图流程异常"
|
||||||
|
#
|
||||||
|
# return generate_furniture
|
||||||
|
|||||||
@@ -32,104 +32,108 @@ class ReportInput(BaseModel):
|
|||||||
# LangGraph Tool
|
# LangGraph Tool
|
||||||
# =========================
|
# =========================
|
||||||
|
|
||||||
@tool("report_generator", args_schema=ReportInput)
|
def create_report_generator_tool(workspace_dir):
|
||||||
async def report_generator(
|
@tool("report_generator", args_schema=ReportInput)
|
||||||
report_topic: str,
|
async def report_generator(
|
||||||
structured_data: List[Dict],
|
report_topic: str,
|
||||||
language: str = "English"
|
structured_data: List[Dict],
|
||||||
) -> dict:
|
language: str = "English"
|
||||||
"""
|
) -> dict:
|
||||||
Generate a professional design/market report
|
"""
|
||||||
directly from structured retrieval results.
|
Generate a professional design/market report
|
||||||
"""
|
directly from structured retrieval results.
|
||||||
|
"""
|
||||||
|
|
||||||
writer = get_stream_writer()
|
writer = get_stream_writer()
|
||||||
if not structured_data:
|
if not structured_data:
|
||||||
error_msg = "Error: No structured data provided."
|
error_msg = "Error: No structured data provided."
|
||||||
writer({"type": "report_error", "message": error_msg})
|
writer({"type": "report_error", "message": error_msg})
|
||||||
return error_msg
|
return error_msg
|
||||||
|
|
||||||
collected_data_str = json.dumps(
|
collected_data_str = json.dumps(
|
||||||
structured_data,
|
structured_data,
|
||||||
ensure_ascii=False,
|
ensure_ascii=False,
|
||||||
indent=2
|
indent=2
|
||||||
)
|
|
||||||
|
|
||||||
# =========================
|
|
||||||
# Prompt
|
|
||||||
# =========================
|
|
||||||
|
|
||||||
system_prompt = f"""
|
|
||||||
You are a professional design trend analyst.
|
|
||||||
|
|
||||||
Generate a long, structured Markdown report.
|
|
||||||
|
|
||||||
REQUIREMENTS:
|
|
||||||
|
|
||||||
1. Follow MECE principle.
|
|
||||||
2. Embed images ONLY if they start with https://
|
|
||||||
using: 
|
|
||||||
3. Insert images inline.
|
|
||||||
4. Every key insight must cite source:
|
|
||||||
[Website Name](url)
|
|
||||||
5. Use Markdown headings.
|
|
||||||
6. Start directly with title.
|
|
||||||
7. Be detailed and analytical.
|
|
||||||
|
|
||||||
Output Language: {language}
|
|
||||||
"""
|
|
||||||
|
|
||||||
user_prompt = f"""
|
|
||||||
Topic: {report_topic}
|
|
||||||
|
|
||||||
Input Data:
|
|
||||||
{collected_data_str}
|
|
||||||
"""
|
|
||||||
|
|
||||||
# =========================
|
|
||||||
# 调用 LLM
|
|
||||||
# =========================
|
|
||||||
writer({"type": "report_start", "topic": report_topic, "language": language})
|
|
||||||
|
|
||||||
full_report = ""
|
|
||||||
try:
|
|
||||||
report_llm = repoer_llm.with_config(
|
|
||||||
callbacks=[]
|
|
||||||
)
|
)
|
||||||
async for chunk in report_llm.astream(
|
|
||||||
[
|
|
||||||
SystemMessage(content=system_prompt),
|
|
||||||
HumanMessage(content=user_prompt)
|
|
||||||
]
|
|
||||||
):
|
|
||||||
if chunk.content: # Gemini 返回的 chunk.content
|
|
||||||
delta = chunk.content
|
|
||||||
full_report += delta
|
|
||||||
# return {"type": "report_delta", "delta": delta}
|
|
||||||
writer({"type": "report_delta", "delta": delta}) # ← 实时推送给前端
|
|
||||||
writer({"type": "report_stop", "topic": report_topic, "language": language})
|
|
||||||
except Exception as e:
|
|
||||||
error_msg = f"LLM generation failed: {str(e)}"
|
|
||||||
writer({"type": "report_error", "message": error_msg})
|
|
||||||
return error_msg
|
|
||||||
|
|
||||||
report_content = full_report.strip()
|
# =========================
|
||||||
|
# Prompt
|
||||||
|
# =========================
|
||||||
|
|
||||||
# =========================
|
system_prompt = f"""
|
||||||
# 保存报告
|
You are a professional design trend analyst.
|
||||||
# =========================
|
|
||||||
output_dir = "workspace/reports"
|
|
||||||
os.makedirs(output_dir, exist_ok=True)
|
|
||||||
|
|
||||||
safe_topic = re.sub(r'[\\/*?:"<>|]', "", report_topic.replace(" ", "_"))
|
Generate a long, structured Markdown report.
|
||||||
filename = f"{output_dir}/{safe_topic}.md"
|
|
||||||
|
|
||||||
try:
|
REQUIREMENTS:
|
||||||
with open(filename, "w", encoding="utf-8") as f:
|
|
||||||
f.write(report_content)
|
|
||||||
writer({"type": "report_complete", "file_path": filename})
|
|
||||||
except Exception as e:
|
|
||||||
writer({"type": "report_save_warning", "message": str(e)})
|
|
||||||
|
|
||||||
# 返回完整内容(作为 tool result),同时正文已通过 delta 流式输出
|
1. Follow MECE principle.
|
||||||
return report_content + f"\n\n✅ Report saved to: {filename}"
|
2. Embed images ONLY if they start with https://
|
||||||
|
using: 
|
||||||
|
3. Insert images inline.
|
||||||
|
4. Every key insight must cite source:
|
||||||
|
[Website Name](url)
|
||||||
|
5. Use Markdown headings.
|
||||||
|
6. Start directly with title.
|
||||||
|
7. Be detailed and analytical.
|
||||||
|
|
||||||
|
Output Language: {language}
|
||||||
|
"""
|
||||||
|
|
||||||
|
user_prompt = f"""
|
||||||
|
Topic: {report_topic}
|
||||||
|
|
||||||
|
Input Data:
|
||||||
|
{collected_data_str}
|
||||||
|
"""
|
||||||
|
|
||||||
|
# =========================
|
||||||
|
# 调用 LLM
|
||||||
|
# =========================
|
||||||
|
writer({"type": "report_start", "topic": report_topic, "language": language})
|
||||||
|
|
||||||
|
full_report = ""
|
||||||
|
try:
|
||||||
|
report_llm = repoer_llm.with_config(
|
||||||
|
callbacks=[]
|
||||||
|
)
|
||||||
|
async for chunk in report_llm.astream(
|
||||||
|
[
|
||||||
|
SystemMessage(content=system_prompt),
|
||||||
|
HumanMessage(content=user_prompt)
|
||||||
|
]
|
||||||
|
):
|
||||||
|
if chunk.content: # Gemini 返回的 chunk.content
|
||||||
|
delta = chunk.content
|
||||||
|
full_report += delta
|
||||||
|
# return {"type": "report_delta", "delta": delta}
|
||||||
|
writer({"type": "report_delta", "delta": delta}) # ← 实时推送给前端
|
||||||
|
writer({"type": "report_stop", "topic": report_topic, "language": language})
|
||||||
|
except Exception as e:
|
||||||
|
error_msg = f"LLM generation failed: {str(e)}"
|
||||||
|
writer({"type": "report_error", "message": error_msg})
|
||||||
|
return error_msg
|
||||||
|
|
||||||
|
report_content = full_report.strip()
|
||||||
|
|
||||||
|
# =========================
|
||||||
|
# 保存报告
|
||||||
|
# =========================
|
||||||
|
output_dir = os.path.join(workspace_dir, "reports")
|
||||||
|
if not os.path.exists(output_dir):
|
||||||
|
os.makedirs(output_dir, exist_ok=True)
|
||||||
|
|
||||||
|
safe_topic = re.sub(r'[\\/*?:"<>|]', "", report_topic.replace(" ", "_"))
|
||||||
|
filename = f"{output_dir}/{safe_topic}.md"
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(filename, "w", encoding="utf-8") as f:
|
||||||
|
f.write(report_content)
|
||||||
|
writer({"type": "report_complete", "file_path": filename})
|
||||||
|
except Exception as e:
|
||||||
|
writer({"type": "report_save_warning", "message": str(e)})
|
||||||
|
|
||||||
|
# 返回完整内容(作为 tool result),同时正文已通过 delta 流式输出
|
||||||
|
return report_content + f"\n\n✅ Report saved to: {filename}"
|
||||||
|
|
||||||
|
return report_generator
|
||||||
|
|||||||
@@ -32,121 +32,6 @@ class StructuredRetrievalInput(BaseModel):
|
|||||||
source_url: Optional[str] = Field(None, description="Optional global source URL")
|
source_url: Optional[str] = Field(None, description="Optional global source URL")
|
||||||
|
|
||||||
|
|
||||||
@tool("structured_retrieval", args_schema=StructuredRetrievalInput)
|
|
||||||
def structured_retrieval(
|
|
||||||
file_paths: List[str],
|
|
||||||
query: str,
|
|
||||||
source_url: Optional[str] = None
|
|
||||||
) -> Dict:
|
|
||||||
"""
|
|
||||||
Batch structured extraction from markdown files.
|
|
||||||
- Performs vector search + re-ranking
|
|
||||||
- Saves extracted structured data as JSON file to disk
|
|
||||||
- Returns ONLY summary (status, count, file path)
|
|
||||||
"""
|
|
||||||
|
|
||||||
# ── 1. 收集所有文件內容 ──────────────────────────────────────
|
|
||||||
all_docs_pool: List[Document] = []
|
|
||||||
|
|
||||||
for path in file_paths:
|
|
||||||
if not os.path.exists(path) or not path.endswith((".md", ".markdown")):
|
|
||||||
continue
|
|
||||||
|
|
||||||
file_name = os.path.basename(path)
|
|
||||||
|
|
||||||
with open(path, "r", encoding="utf-8") as f:
|
|
||||||
content = f.read()
|
|
||||||
|
|
||||||
current_source = source_url or _extract_source_from_md(content) or "unknown"
|
|
||||||
|
|
||||||
sections = _split_markdown_by_headers(content)
|
|
||||||
|
|
||||||
for sec in sections:
|
|
||||||
all_docs_pool.append(
|
|
||||||
Document(
|
|
||||||
page_content=sec,
|
|
||||||
metadata={"source_url": current_source, "file_name": file_name}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if not all_docs_pool:
|
|
||||||
return {"status": "no_documents_found", "items_count": 0, "json_path": None}
|
|
||||||
|
|
||||||
# ── 2. Vector search ────────────────────────────────────────────
|
|
||||||
vector_store = FAISS.from_documents(all_docs_pool, _EMBEDDING_MODEL)
|
|
||||||
retrieved = vector_store.similarity_search(query, k=200)
|
|
||||||
|
|
||||||
# ── 3. 提取結構化片段 ──────────────────────────────────────────
|
|
||||||
structured_items = []
|
|
||||||
|
|
||||||
for doc in retrieved:
|
|
||||||
text = doc.page_content.strip()
|
|
||||||
if len(text) < 30:
|
|
||||||
continue
|
|
||||||
|
|
||||||
images = list(set(re.findall(r"!\[.*?\]\((.*?)\)", text)))
|
|
||||||
|
|
||||||
structured_items.append(
|
|
||||||
{
|
|
||||||
"text": text,
|
|
||||||
"images": images,
|
|
||||||
"source_url": doc.metadata.get("source_url"),
|
|
||||||
"file_name": doc.metadata.get("file_name")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
# ── 4. Re-rank ──────────────────────────────────────────────────
|
|
||||||
if structured_items:
|
|
||||||
unique_items = {item["text"]: item for item in structured_items}.values()
|
|
||||||
pairs = [[query, item["text"]] for item in unique_items]
|
|
||||||
scores = _RERANK_MODEL.predict(pairs)
|
|
||||||
|
|
||||||
sorted_items = sorted(
|
|
||||||
zip(scores, unique_items),
|
|
||||||
key=lambda x: x[0],
|
|
||||||
reverse=True
|
|
||||||
)
|
|
||||||
top_items = [item for _, item in sorted_items[:50]]
|
|
||||||
else:
|
|
||||||
top_items = []
|
|
||||||
|
|
||||||
# ── 5. 寫入 JSON 文件 ──────────────────────────────────────────
|
|
||||||
if not top_items:
|
|
||||||
return {"status": "no_relevant_content", "items_count": 0, "json_path": None}
|
|
||||||
|
|
||||||
# 產生有意義的檔名
|
|
||||||
safe_query = re.sub(r'[^a-zA-Z0-9\u4e00-\u9fa5]', '_', query)[:40]
|
|
||||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
||||||
json_filename = f"extracted_{safe_query}_{timestamp}.json"
|
|
||||||
|
|
||||||
# 建議的儲存目錄(與 crawl4ai_batch 對齊)
|
|
||||||
output_dir = os.path.join(os.path.dirname(file_paths[0]), "..", "extracted")
|
|
||||||
os.makedirs(output_dir, exist_ok=True)
|
|
||||||
|
|
||||||
json_path = os.path.join(output_dir, json_filename)
|
|
||||||
|
|
||||||
with open(json_path, "w", encoding="utf-8") as f:
|
|
||||||
json.dump(
|
|
||||||
{
|
|
||||||
"query": query,
|
|
||||||
"extracted_at": timestamp,
|
|
||||||
"item_count": len(top_items),
|
|
||||||
"items": top_items
|
|
||||||
},
|
|
||||||
f,
|
|
||||||
ensure_ascii=False,
|
|
||||||
indent=2
|
|
||||||
)
|
|
||||||
|
|
||||||
# ── 6. 只回傳摘要 ──────────────────────────────────────────────
|
|
||||||
return {
|
|
||||||
"status": "success",
|
|
||||||
"items_count": len(top_items),
|
|
||||||
"json_path": json_path,
|
|
||||||
"summary": f"已提取 {len(top_items)} 個高相關片段,儲存於 {json_path}"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def _extract_source_from_md(content: str) -> Optional[str]:
|
def _extract_source_from_md(content: str) -> Optional[str]:
|
||||||
match = re.search(r"<!--\s*Source:\s*(.*?)\s*-->", content)
|
match = re.search(r"<!--\s*Source:\s*(.*?)\s*-->", content)
|
||||||
return match.group(1).strip() if match else None
|
return match.group(1).strip() if match else None
|
||||||
@@ -223,3 +108,126 @@ def _chunk_text(
|
|||||||
start = max(0, end - overlap)
|
start = max(0, end - overlap)
|
||||||
|
|
||||||
return chunks
|
return chunks
|
||||||
|
|
||||||
|
|
||||||
|
def create_structured_retrieval_tool(workspace_dir):
|
||||||
|
@tool("structured_retrieval", args_schema=StructuredRetrievalInput)
|
||||||
|
def structured_retrieval(
|
||||||
|
file_paths: List[str],
|
||||||
|
query: str,
|
||||||
|
source_url: Optional[str] = None
|
||||||
|
) -> Dict:
|
||||||
|
"""
|
||||||
|
Batch structured extraction from markdown files.
|
||||||
|
- Performs vector search + re-ranking
|
||||||
|
- Saves extracted structured data as JSON file to disk
|
||||||
|
- Returns ONLY summary (status, count, file path)
|
||||||
|
"""
|
||||||
|
|
||||||
|
# ── 1. 收集所有文件內容 ──────────────────────────────────────
|
||||||
|
all_docs_pool: List[Document] = []
|
||||||
|
|
||||||
|
for path in file_paths:
|
||||||
|
if not os.path.exists(path) or not path.endswith((".md", ".markdown")):
|
||||||
|
continue
|
||||||
|
|
||||||
|
file_name = os.path.basename(path)
|
||||||
|
|
||||||
|
with open(path, "r", encoding="utf-8") as f:
|
||||||
|
content = f.read()
|
||||||
|
|
||||||
|
current_source = source_url or _extract_source_from_md(content) or "unknown"
|
||||||
|
|
||||||
|
sections = _split_markdown_by_headers(content)
|
||||||
|
|
||||||
|
for sec in sections:
|
||||||
|
all_docs_pool.append(
|
||||||
|
Document(
|
||||||
|
page_content=sec,
|
||||||
|
metadata={"source_url": current_source, "file_name": file_name}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if not all_docs_pool:
|
||||||
|
return {"status": "no_documents_found", "items_count": 0, "json_path": None}
|
||||||
|
|
||||||
|
# ── 2. Vector search ────────────────────────────────────────────
|
||||||
|
vector_store = FAISS.from_documents(all_docs_pool, _EMBEDDING_MODEL)
|
||||||
|
retrieved = vector_store.similarity_search(query, k=200)
|
||||||
|
|
||||||
|
# ── 3. 提取結構化片段 ──────────────────────────────────────────
|
||||||
|
structured_items = []
|
||||||
|
|
||||||
|
for doc in retrieved:
|
||||||
|
text = doc.page_content.strip()
|
||||||
|
if len(text) < 30:
|
||||||
|
continue
|
||||||
|
|
||||||
|
images = list(set(re.findall(r"!\[.*?\]\((.*?)\)", text)))
|
||||||
|
|
||||||
|
structured_items.append(
|
||||||
|
{
|
||||||
|
"text": text,
|
||||||
|
"images": images,
|
||||||
|
"source_url": doc.metadata.get("source_url"),
|
||||||
|
"file_name": doc.metadata.get("file_name")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# ── 4. Re-rank ──────────────────────────────────────────────────
|
||||||
|
if structured_items:
|
||||||
|
unique_items = {item["text"]: item for item in structured_items}.values()
|
||||||
|
pairs = [[query, item["text"]] for item in unique_items]
|
||||||
|
scores = _RERANK_MODEL.predict(pairs)
|
||||||
|
|
||||||
|
sorted_items = sorted(
|
||||||
|
zip(scores, unique_items),
|
||||||
|
key=lambda x: x[0],
|
||||||
|
reverse=True
|
||||||
|
)
|
||||||
|
top_items = [item for _, item in sorted_items[:50]]
|
||||||
|
else:
|
||||||
|
top_items = []
|
||||||
|
|
||||||
|
# ── 5. 寫入 JSON 文件 ──────────────────────────────────────────
|
||||||
|
if not top_items:
|
||||||
|
return {"status": "no_relevant_content", "items_count": 0, "json_path": None}
|
||||||
|
|
||||||
|
# 產生有意義的檔名
|
||||||
|
safe_query = re.sub(r'[^a-zA-Z0-9\u4e00-\u9fa5]', '_', query)[:40]
|
||||||
|
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||||
|
json_filename = f"extracted_{safe_query}_{timestamp}.json"
|
||||||
|
|
||||||
|
# 建議的儲存目錄(與 crawl4ai_batch 對齊)
|
||||||
|
output_dir = os.path.join(workspace_dir, "extracted")
|
||||||
|
if not os.path.exists(output_dir):
|
||||||
|
os.makedirs(output_dir, exist_ok=True)
|
||||||
|
|
||||||
|
if not os.path.exists(output_dir):
|
||||||
|
# 2. 不存在则创建(makedirs 支持创建多级目录,mkdir 只能创建单级)
|
||||||
|
os.makedirs(output_dir, exist_ok=True)
|
||||||
|
|
||||||
|
json_path = os.path.join(output_dir, json_filename)
|
||||||
|
|
||||||
|
with open(json_path, "w", encoding="utf-8") as f:
|
||||||
|
json.dump(
|
||||||
|
{
|
||||||
|
"query": query,
|
||||||
|
"extracted_at": timestamp,
|
||||||
|
"item_count": len(top_items),
|
||||||
|
"items": top_items
|
||||||
|
},
|
||||||
|
f,
|
||||||
|
ensure_ascii=False,
|
||||||
|
indent=2
|
||||||
|
)
|
||||||
|
|
||||||
|
# ── 6. 只回傳摘要 ──────────────────────────────────────────────
|
||||||
|
return {
|
||||||
|
"status": "success",
|
||||||
|
"items_count": len(top_items),
|
||||||
|
"json_path": json_path,
|
||||||
|
"summary": f"已提取 {len(top_items)} 個高相關片段,儲存於 {json_path}"
|
||||||
|
}
|
||||||
|
|
||||||
|
return structured_retrieval
|
||||||
|
|||||||
21
src/server/deep_agent/tools/vision_analyze_tool.py
Normal file
21
src/server/deep_agent/tools/vision_analyze_tool.py
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
from langchain.tools import tool
|
||||||
|
from langchain_core.messages import HumanMessage
|
||||||
|
from PIL import Image
|
||||||
|
import requests
|
||||||
|
from io import BytesIO
|
||||||
|
|
||||||
|
from src.server.deep_agent.init_llm import vision_llm
|
||||||
|
|
||||||
|
|
||||||
|
@tool
|
||||||
|
def analyze_image(image_url: str) -> str:
|
||||||
|
"""分析给定URL的图像。输入图像URL,输出图像描述和关键观察。"""
|
||||||
|
response = requests.get(image_url)
|
||||||
|
image = Image.open(BytesIO(response.content))
|
||||||
|
# 这里使用模型直接分析图像(简化示例)
|
||||||
|
msg = HumanMessage(content=[
|
||||||
|
{"type": "text", "text": "详细描述这张图像,包括物体、颜色、场景和任何文本。"},
|
||||||
|
{"type": "image_url", "image_url": {"url": image_url}}
|
||||||
|
])
|
||||||
|
result = vision_llm.invoke([msg])
|
||||||
|
return result.content
|
||||||
@@ -36,7 +36,7 @@ http_client = urllib3.PoolManager(
|
|||||||
|
|
||||||
|
|
||||||
# 获取图片
|
# 获取图片
|
||||||
def oss_get_image(oss_client, bucket, object_name, data_type):
|
def oss_get_image(oss_client, bucket, object_name):
|
||||||
# cv2 默认全通道读取
|
# cv2 默认全通道读取
|
||||||
image_object = None
|
image_object = None
|
||||||
try:
|
try:
|
||||||
@@ -57,9 +57,44 @@ def oss_upload_image(oss_client, bucket, object_name, image_bytes):
|
|||||||
return req
|
return req
|
||||||
|
|
||||||
|
|
||||||
|
def oss_upload_image_file(oss_client, bucket, object_name, file_path):
|
||||||
|
req = None
|
||||||
|
try:
|
||||||
|
req = oss_client.fput_object(
|
||||||
|
bucket_name=bucket,
|
||||||
|
object_name=object_name,
|
||||||
|
file_path=file_path
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f" | 上传图片出现异常 ######: {e}")
|
||||||
|
return req
|
||||||
|
|
||||||
|
|
||||||
|
def get_presigned_url(oss_client, bucket, object_name):
|
||||||
|
try:
|
||||||
|
presigned_url = oss_client.presigned_get_object(
|
||||||
|
bucket_name=bucket,
|
||||||
|
object_name=object_name,
|
||||||
|
expires=3600
|
||||||
|
)
|
||||||
|
return presigned_url
|
||||||
|
except Exception as e:
|
||||||
|
print(f"get_presigned_url exception :{e}")
|
||||||
|
return "object not found"
|
||||||
|
|
||||||
|
|
||||||
|
def is_minio_file_exist(minio_client: Minio, bucket_name: str, object_name: str) -> bool:
|
||||||
|
try:
|
||||||
|
# 核心判断:检查MinIO中指定bucket+object是否存在
|
||||||
|
minio_client.stat_object(bucket_name, object_name)
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
url = "fida-test/furniture/sketches/4449a66d-6267-43f7-86a2-1e42bd19ec61.png"
|
url = 'fida-test/furniture/sketches/9356e3d8-d56e-4478-adde-61b29119979b.png'
|
||||||
read_type = "2"
|
read_type = "2"
|
||||||
img = oss_get_image(oss_client=minio_client, bucket=url.split('/')[0], object_name=url[url.find('/') + 1:], data_type=read_type)
|
img = oss_get_image(oss_client=minio_client, bucket=url.split('/')[0], object_name=url[url.find('/') + 1:])
|
||||||
img.show()
|
img.show()
|
||||||
img.save("result.png")
|
img.save("result.png")
|
||||||
|
|||||||
513
uv.lock
generated
513
uv.lock
generated
@@ -21,11 +21,11 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aiofiles"
|
name = "aiofiles"
|
||||||
version = "25.1.0"
|
version = "24.1.0"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/41/c3/534eac40372d8ee36ef40df62ec129bee4fdb5ad9706e58a29be53b2c970/aiofiles-25.1.0.tar.gz", hash = "sha256:a8d728f0a29de45dc521f18f07297428d56992a742f0cd2701ba86e44d23d5b2", size = 46354, upload-time = "2025-10-09T20:51:04.358Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/0b/03/a88171e277e8caa88a4c77808c20ebb04ba74cc4681bf1e9416c862de237/aiofiles-24.1.0.tar.gz", hash = "sha256:22a075c9e5a3810f0c2e48f3008c94d68c65d763b9b03857924c99e57355166c", size = 30247, upload-time = "2024-06-24T11:02:03.584Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/bc/8a/340a1555ae33d7354dbca4faa54948d76d89a27ceef032c8c3bc661d003e/aiofiles-25.1.0-py3-none-any.whl", hash = "sha256:abe311e527c862958650f9438e859c1fa7568a141b22abcd015e120e86a85695", size = 14668, upload-time = "2025-10-09T20:51:03.174Z" },
|
{ url = "https://files.pythonhosted.org/packages/a5/45/30bb92d442636f570cb5651bc661f52b610e2eec3f891a5dc3a4c3667db0/aiofiles-24.1.0-py3-none-any.whl", hash = "sha256:b4ec55f4195e3eb5d7abd1bf7e061763e864dd4954231fb8539a0ef8bb8260e5", size = 15896, upload-time = "2024-06-24T11:02:01.529Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -122,6 +122,18 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/b4/63/278a98c715ae467624eafe375542d8ba9b4383a016df8fdefe0ae28382a7/aiohttp-3.13.3-cp314-cp314t-win_amd64.whl", hash = "sha256:44531a36aa2264a1860089ffd4dce7baf875ee5a6079d5fb42e261c704ef7344", size = 499694, upload-time = "2026-01-03T17:32:24.546Z" },
|
{ url = "https://files.pythonhosted.org/packages/b4/63/278a98c715ae467624eafe375542d8ba9b4383a016df8fdefe0ae28382a7/aiohttp-3.13.3-cp314-cp314t-win_amd64.whl", hash = "sha256:44531a36aa2264a1860089ffd4dce7baf875ee5a6079d5fb42e261c704ef7344", size = 499694, upload-time = "2026-01-03T17:32:24.546Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aiohttp-retry"
|
||||||
|
version = "2.9.1"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "aiohttp" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/9d/61/ebda4d8e3d8cfa1fd3db0fb428db2dd7461d5742cea35178277ad180b033/aiohttp_retry-2.9.1.tar.gz", hash = "sha256:8eb75e904ed4ee5c2ec242fefe85bf04240f685391c4879d8f541d6028ff01f1", size = 13608, upload-time = "2024-11-06T10:44:54.574Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/1a/99/84ba7273339d0f3dfa57901b846489d2e5c2cd731470167757f1935fffbd/aiohttp_retry-2.9.1-py3-none-any.whl", hash = "sha256:66d2759d1921838256a05a3f80ad7e724936f083e35be5abb5e16eed6be6dc54", size = 9981, upload-time = "2024-11-06T10:44:52.917Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aiosignal"
|
name = "aiosignal"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
@@ -213,6 +225,15 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl", hash = "sha256:d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c", size = 113592, upload-time = "2026-01-06T11:45:19.497Z" },
|
{ url = "https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl", hash = "sha256:d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c", size = 113592, upload-time = "2026-01-06T11:45:19.497Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "argh"
|
||||||
|
version = "0.31.3"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/4f/34/bc0b3577a818b4b70c6e318d23fe3c81fc3bb25f978ca8a3965cd8ee3af9/argh-0.31.3.tar.gz", hash = "sha256:f30023d8be14ca5ee6b1b3eeab829151d7bbda464ae07dc4dd5347919c5892f9", size = 57570, upload-time = "2024-07-13T17:54:59.729Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d2/52/fcd83710b6f8786df80e5d335882d1b24d1f610f397703e94a6ffb0d6f66/argh-0.31.3-py3-none-any.whl", hash = "sha256:2edac856ff50126f6e47d884751328c9f466bacbbb6cbfdac322053d94705494", size = 44844, upload-time = "2024-07-13T17:54:57.706Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "argon2-cffi"
|
name = "argon2-cffi"
|
||||||
version = "25.1.0"
|
version = "25.1.0"
|
||||||
@@ -678,6 +699,98 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/cf/7a/ea0f3e3ea74be36fc7cf54f966cde732a3de72697983cdb5646b0a4dacde/datetime-6.0-py3-none-any.whl", hash = "sha256:d19988f0657a4e72c9438344157254a8dcad6aea8cd5ae70a5d1b5a75e5dc930", size = 52637, upload-time = "2025-11-25T08:00:33.077Z" },
|
{ url = "https://files.pythonhosted.org/packages/cf/7a/ea0f3e3ea74be36fc7cf54f966cde732a3de72697983cdb5646b0a4dacde/datetime-6.0-py3-none-any.whl", hash = "sha256:d19988f0657a4e72c9438344157254a8dcad6aea8cd5ae70a5d1b5a75e5dc930", size = 52637, upload-time = "2025-11-25T08:00:33.077Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "daytona"
|
||||||
|
version = "0.152.1"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "aiofiles" },
|
||||||
|
{ name = "daytona-api-client" },
|
||||||
|
{ name = "daytona-api-client-async" },
|
||||||
|
{ name = "daytona-toolbox-api-client" },
|
||||||
|
{ name = "daytona-toolbox-api-client-async" },
|
||||||
|
{ name = "deprecated" },
|
||||||
|
{ name = "environs" },
|
||||||
|
{ name = "httpx" },
|
||||||
|
{ name = "obstore" },
|
||||||
|
{ name = "opentelemetry-api" },
|
||||||
|
{ name = "opentelemetry-exporter-otlp-proto-http" },
|
||||||
|
{ name = "opentelemetry-instrumentation-aiohttp-client" },
|
||||||
|
{ name = "opentelemetry-sdk" },
|
||||||
|
{ name = "pydantic" },
|
||||||
|
{ name = "python-multipart" },
|
||||||
|
{ name = "toml" },
|
||||||
|
{ name = "websockets" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/d2/af/5e9245a5c801cac274e1050681fe06a6d48ffcd11343ea575575653316f5/daytona-0.152.1.tar.gz", hash = "sha256:8fe79095ace9652120e18eb2093798067a4afb4ec609922b24d07a154e573265", size = 124193, upload-time = "2026-03-18T18:25:32.206Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/96/ad/617ad1872fe2318d6c8da56f18654646c34d7b78864dfc14cdaf4208e9f7/daytona-0.152.1-py3-none-any.whl", hash = "sha256:16fa90aa6bb521cd767a5dc241bba1e4b69f63090169b7c40c35bb6ff2746c80", size = 153889, upload-time = "2026-03-18T18:25:30.412Z" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "daytona-api-client"
|
||||||
|
version = "0.152.1"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "pydantic" },
|
||||||
|
{ name = "python-dateutil" },
|
||||||
|
{ name = "typing-extensions" },
|
||||||
|
{ name = "urllib3" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/cb/5e/3a90e14684954975a36adf0aeec08eff87e461f058d27360587d5c1afaad/daytona_api_client-0.152.1.tar.gz", hash = "sha256:4be68957de15f3ae44e5f043c7a04d2e375541d1d307b0ceda9fc40414fbe5e7", size = 140769, upload-time = "2026-03-18T18:24:38.241Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/98/01/40388deba155d40765b1e5eb49c04063b1024fe1eae7f77252f4f4a88452/daytona_api_client-0.152.1-py3-none-any.whl", hash = "sha256:99ef79c00aa23f58dd1438d9f33f632f310749ceaf2c698f256556317f3acab7", size = 394605, upload-time = "2026-03-18T18:24:36.571Z" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "daytona-api-client-async"
|
||||||
|
version = "0.152.1"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "aiohttp" },
|
||||||
|
{ name = "aiohttp-retry" },
|
||||||
|
{ name = "pydantic" },
|
||||||
|
{ name = "python-dateutil" },
|
||||||
|
{ name = "typing-extensions" },
|
||||||
|
{ name = "urllib3" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/11/f2/34dffdc9da9f9cd5c4b50242f4500ddc0f944d4ef237e3aadccbcf5e85c2/daytona_api_client_async-0.152.1.tar.gz", hash = "sha256:954b1700c96205233b9fa5f33309c9bc074108a99d87f2b5b1ad26a570989d98", size = 140921, upload-time = "2026-03-18T18:24:40.807Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b8/54/a037af7d48b1eea0a21677d92923436adc9f8bf53902424bc35b0e9bbcf1/daytona_api_client_async-0.152.1-py3-none-any.whl", hash = "sha256:af97afc9bc4a08168bf3d4760655151ad4515f1e46fa6cd08f5ce1a1f365324c", size = 397596, upload-time = "2026-03-18T18:24:39.153Z" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "daytona-toolbox-api-client"
|
||||||
|
version = "0.152.1"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "pydantic" },
|
||||||
|
{ name = "python-dateutil" },
|
||||||
|
{ name = "typing-extensions" },
|
||||||
|
{ name = "urllib3" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/ac/9e/8a3fd8fa74953a8008dfb43cb210684177972bb57ef6c7a1439f5fe2812d/daytona_toolbox_api_client-0.152.1.tar.gz", hash = "sha256:a62afd4ca65c6bec21442a33bfb116cff0ec2a0427c495459be3dcd4ce6c60cd", size = 64628, upload-time = "2026-03-18T18:24:34.67Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/17/03/27d0a688fb39a2ed57506f6fe154eee7cc766a569474a7537f9526f37a5b/daytona_toolbox_api_client-0.152.1-py3-none-any.whl", hash = "sha256:7ec9091c137f15a0e632771bf64904b1a88f83d915dcb234f08800599d523df6", size = 174402, upload-time = "2026-03-18T18:24:33.315Z" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "daytona-toolbox-api-client-async"
|
||||||
|
version = "0.152.1"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "aiohttp" },
|
||||||
|
{ name = "aiohttp-retry" },
|
||||||
|
{ name = "pydantic" },
|
||||||
|
{ name = "python-dateutil" },
|
||||||
|
{ name = "typing-extensions" },
|
||||||
|
{ name = "urllib3" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/a6/9c/9970b2b9e9bd7e3dfc91d4b0b9d5648ad56c905256b614c2f99a169c3567/daytona_toolbox_api_client_async-0.152.1.tar.gz", hash = "sha256:36ea58e25ff2824348ad7c164cc4246143c8a712cd9bb88a5c9d5c0d2b122459", size = 61702, upload-time = "2026-03-18T18:24:59.143Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/60/10/56875085063b974dcdc27350bb9d13314f8ff8a5e47329041b8f2d42f364/daytona_toolbox_api_client_async-0.152.1-py3-none-any.whl", hash = "sha256:086f58e708c3b4ab2d99fa5f4ea62711a70b5d7f0cc94f393e4fd96529cf7d6f", size = 175773, upload-time = "2026-03-18T18:24:57.961Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deepagents"
|
name = "deepagents"
|
||||||
version = "0.4.5"
|
version = "0.4.5"
|
||||||
@@ -694,6 +807,18 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/a1/4d/9f5e021492fc17e46e5ebd3f21a83d1a56725c0ccce95f427a18edcfbe8f/deepagents-0.4.5-py3-none-any.whl", hash = "sha256:378e401be3ce79b8da1ce1ef792460501a28969c5b78b00985ed4b2a6dbb7605", size = 99261, upload-time = "2026-03-03T21:41:53.737Z" },
|
{ url = "https://files.pythonhosted.org/packages/a1/4d/9f5e021492fc17e46e5ebd3f21a83d1a56725c0ccce95f427a18edcfbe8f/deepagents-0.4.5-py3-none-any.whl", hash = "sha256:378e401be3ce79b8da1ce1ef792460501a28969c5b78b00985ed4b2a6dbb7605", size = 99261, upload-time = "2026-03-03T21:41:53.737Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "deprecated"
|
||||||
|
version = "1.3.1"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "wrapt" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/49/85/12f0a49a7c4ffb70572b6c2ef13c90c88fd190debda93b23f026b25f9634/deprecated-1.3.1.tar.gz", hash = "sha256:b1b50e0ff0c1fddaa5708a2c6b0a6588bb09b892825ab2b214ac9ea9d92a5223", size = 2932523, upload-time = "2025-10-30T08:19:02.757Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/84/d0/205d54408c08b13550c733c4b85429e7ead111c7f0014309637425520a9a/deprecated-1.3.1-py2.py3-none-any.whl", hash = "sha256:597bfef186b6f60181535a29fbe44865ce137a5079f295b479886c82729d5f3f", size = 11298, upload-time = "2025-10-30T08:19:00.758Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "distro"
|
name = "distro"
|
||||||
version = "1.9.0"
|
version = "1.9.0"
|
||||||
@@ -748,6 +873,19 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl", hash = "sha256:80f13f623413e6b197ae73bb10bf4eb0908faf509ad8362c5edeb0be7fd450b4", size = 35604, upload-time = "2025-08-26T13:09:05.858Z" },
|
{ url = "https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl", hash = "sha256:80f13f623413e6b197ae73bb10bf4eb0908faf509ad8362c5edeb0be7fd450b4", size = 35604, upload-time = "2025-08-26T13:09:05.858Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "environs"
|
||||||
|
version = "14.6.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "marshmallow" },
|
||||||
|
{ name = "python-dotenv" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/fb/c7/94f97e6e74482a50b5fc798856b6cc06e8d072ab05a0b74cb5d87bd0d065/environs-14.6.0.tar.gz", hash = "sha256:ed2767588deb503209ffe4dd9bb2b39311c2e4e7e27ce2c64bf62ca83328d068", size = 35563, upload-time = "2026-02-20T04:02:08.869Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/97/a8/c070e1340636acb38d4e6a7e45c46d168a462b48b9b3257e14ca0e5af79b/environs-14.6.0-py3-none-any.whl", hash = "sha256:f8fb3d6c6a55872b0c6db077a28f5a8c7b8984b7c32029613d44cef95cfc0812", size = 17205, upload-time = "2026-02-20T04:02:07.299Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "faiss-cpu"
|
name = "faiss-cpu"
|
||||||
version = "1.13.2"
|
version = "1.13.2"
|
||||||
@@ -983,6 +1121,7 @@ dependencies = [
|
|||||||
{ name = "langchain-classic" },
|
{ name = "langchain-classic" },
|
||||||
{ name = "langchain-community" },
|
{ name = "langchain-community" },
|
||||||
{ name = "langchain-core" },
|
{ name = "langchain-core" },
|
||||||
|
{ name = "langchain-daytona" },
|
||||||
{ name = "langchain-google-genai" },
|
{ name = "langchain-google-genai" },
|
||||||
{ name = "langchain-huggingface" },
|
{ name = "langchain-huggingface" },
|
||||||
{ name = "langchain-qwq" },
|
{ name = "langchain-qwq" },
|
||||||
@@ -1009,6 +1148,7 @@ dependencies = [
|
|||||||
{ name = "sentence-transformers" },
|
{ name = "sentence-transformers" },
|
||||||
{ name = "tavily-python" },
|
{ name = "tavily-python" },
|
||||||
{ name = "terminate" },
|
{ name = "terminate" },
|
||||||
|
{ name = "tool" },
|
||||||
{ name = "torch" },
|
{ name = "torch" },
|
||||||
{ name = "uuid" },
|
{ name = "uuid" },
|
||||||
{ name = "uvicorn" },
|
{ name = "uvicorn" },
|
||||||
@@ -1030,6 +1170,7 @@ requires-dist = [
|
|||||||
{ name = "langchain-classic", specifier = ">=1.0.1" },
|
{ name = "langchain-classic", specifier = ">=1.0.1" },
|
||||||
{ name = "langchain-community", specifier = ">=0.4.1" },
|
{ name = "langchain-community", specifier = ">=0.4.1" },
|
||||||
{ name = "langchain-core", specifier = ">=1.2.8" },
|
{ name = "langchain-core", specifier = ">=1.2.8" },
|
||||||
|
{ name = "langchain-daytona", specifier = ">=0.0.3" },
|
||||||
{ name = "langchain-google-genai", specifier = ">=4.2.0" },
|
{ name = "langchain-google-genai", specifier = ">=4.2.0" },
|
||||||
{ name = "langchain-huggingface", specifier = ">=1.2.0" },
|
{ name = "langchain-huggingface", specifier = ">=1.2.0" },
|
||||||
{ name = "langchain-qwq", specifier = ">=0.3.4" },
|
{ name = "langchain-qwq", specifier = ">=0.3.4" },
|
||||||
@@ -1056,6 +1197,7 @@ requires-dist = [
|
|||||||
{ name = "sentence-transformers", specifier = ">=5.2.3" },
|
{ name = "sentence-transformers", specifier = ">=5.2.3" },
|
||||||
{ name = "tavily-python", specifier = ">=0.7.21" },
|
{ name = "tavily-python", specifier = ">=0.7.21" },
|
||||||
{ name = "terminate", specifier = ">=0.0.9" },
|
{ name = "terminate", specifier = ">=0.0.9" },
|
||||||
|
{ name = "tool", specifier = ">=0.8.0" },
|
||||||
{ name = "torch", specifier = ">=2.10.0" },
|
{ name = "torch", specifier = ">=2.10.0" },
|
||||||
{ name = "uuid", specifier = ">=1.30" },
|
{ name = "uuid", specifier = ">=1.30" },
|
||||||
{ name = "uvicorn", specifier = ">=0.40.0" },
|
{ name = "uvicorn", specifier = ">=0.40.0" },
|
||||||
@@ -1217,6 +1359,18 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/d1/dd/403949d922d4e261b08b64aaa132af4e456c3b15c8e2a2d9e6ef693f66e2/google_genai-1.66.0-py3-none-any.whl", hash = "sha256:7f127a39cf695277104ce4091bb26e417c59bb46e952ff3699c3a982d9c474ee", size = 732174, upload-time = "2026-03-04T22:15:26.63Z" },
|
{ url = "https://files.pythonhosted.org/packages/d1/dd/403949d922d4e261b08b64aaa132af4e456c3b15c8e2a2d9e6ef693f66e2/google_genai-1.66.0-py3-none-any.whl", hash = "sha256:7f127a39cf695277104ce4091bb26e417c59bb46e952ff3699c3a982d9c474ee", size = 732174, upload-time = "2026-03-04T22:15:26.63Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "googleapis-common-protos"
|
||||||
|
version = "1.73.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "protobuf" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/99/96/a0205167fa0154f4a542fd6925bdc63d039d88dab3588b875078107e6f06/googleapis_common_protos-1.73.0.tar.gz", hash = "sha256:778d07cd4fbeff84c6f7c72102f0daf98fa2bfd3fa8bea426edc545588da0b5a", size = 147323, upload-time = "2026-03-06T21:53:09.727Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/69/28/23eea8acd65972bbfe295ce3666b28ac510dfcb115fac089d3edb0feb00a/googleapis_common_protos-1.73.0-py3-none-any.whl", hash = "sha256:dfdaaa2e860f242046be561e6d6cb5c5f1541ae02cfbcb034371aadb2942b4e8", size = 297578, upload-time = "2026-03-06T21:52:33.933Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "greenlet"
|
name = "greenlet"
|
||||||
version = "3.3.2"
|
version = "3.3.2"
|
||||||
@@ -1710,6 +1864,19 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/be/90/073f33ab383a62908eca7ea699586dfea280e77182176e33199c80ddf22a/langchain_core-1.2.17-py3-none-any.whl", hash = "sha256:bf6bd6ce503874e9c2da1669a69383e967c3de1ea808921d19a9a6bff1a9fbbe", size = 502727, upload-time = "2026-03-02T22:47:54.537Z" },
|
{ url = "https://files.pythonhosted.org/packages/be/90/073f33ab383a62908eca7ea699586dfea280e77182176e33199c80ddf22a/langchain_core-1.2.17-py3-none-any.whl", hash = "sha256:bf6bd6ce503874e9c2da1669a69383e967c3de1ea808921d19a9a6bff1a9fbbe", size = 502727, upload-time = "2026-03-02T22:47:54.537Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "langchain-daytona"
|
||||||
|
version = "0.0.3"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "daytona" },
|
||||||
|
{ name = "deepagents" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/62/cd/294fdd58be04d08fecb4f191ac8901d06fabb1096b083ef5f757180749d8/langchain_daytona-0.0.3.tar.gz", hash = "sha256:5d89f5158ef30b7dcb168b5f7de742658e59265c59697e13c4d09dbe86a38384", size = 185650, upload-time = "2026-03-06T21:51:52.617Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/67/d7/2783b771cae9e4dc54f5677e89d5b9c38c7b69a78786256185694b62c87c/langchain_daytona-0.0.3-py3-none-any.whl", hash = "sha256:85bd0f35d7e0dbb269446aa537dc784ed082d718572e6167c36a27f351bf10ca", size = 4288, upload-time = "2026-03-06T21:51:51.642Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "langchain-google-genai"
|
name = "langchain-google-genai"
|
||||||
version = "4.2.1"
|
version = "4.2.1"
|
||||||
@@ -2462,6 +2629,55 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/a2/eb/86626c1bbc2edb86323022371c39aa48df6fd8b0a1647bc274577f72e90b/nvidia_nvtx_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5b17e2001cc0d751a5bc2c6ec6d26ad95913324a4adb86788c944f8ce9ba441f", size = 89954, upload-time = "2025-03-07T01:42:44.131Z" },
|
{ url = "https://files.pythonhosted.org/packages/a2/eb/86626c1bbc2edb86323022371c39aa48df6fd8b0a1647bc274577f72e90b/nvidia_nvtx_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5b17e2001cc0d751a5bc2c6ec6d26ad95913324a4adb86788c944f8ce9ba441f", size = 89954, upload-time = "2025-03-07T01:42:44.131Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "obstore"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "typing-extensions", marker = "python_full_version < '3.13'" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/a3/8c/9ec984edd0f3b72226adfaa19b1c61b15823b35b52f311ca4af36d009d15/obstore-0.8.2.tar.gz", hash = "sha256:a467bc4e97169e2ba749981b4fd0936015428d9b8f3fb83a5528536b1b6f377f", size = 168852, upload-time = "2025-09-16T15:34:55.786Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2b/dc/60fefbb5736e69eab56657bca04ca64dc07fdeccb3814164a31b62ad066b/obstore-0.8.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:bb70ce297a47392b1d9a3e310f18d59cd5ebbb9453428210fef02ed60e4d75d1", size = 3612955, upload-time = "2025-09-16T15:33:29.527Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d2/8b/844e8f382e5a12b8a3796a05d76a03e12c7aedc13d6900419e39207d7868/obstore-0.8.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1619bf618428abf1f607e0b219b2e230a966dcf697b717deccfa0983dd91f646", size = 3346564, upload-time = "2025-09-16T15:33:30.698Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/89/73/8537f99e09a38a54a6a15ede907aa25d4da089f767a808f0b2edd9c03cec/obstore-0.8.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a4605c3ed7c9515aeb4c619b5f7f2c9986ed4a79fe6045e536b5e59b804b1476", size = 3460809, upload-time = "2025-09-16T15:33:31.837Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b4/99/7714dec721e43f521d6325a82303a002cddad089437640f92542b84e9cc8/obstore-0.8.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce42670417876dd8668cbb8659e860e9725e5f26bbc86449fd259970e2dd9d18", size = 3692081, upload-time = "2025-09-16T15:33:33.028Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ec/bd/4ac4175fe95a24c220a96021c25c432bcc0c0212f618be0737184eebbaad/obstore-0.8.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4a3e893b2a06585f651c541c1972fe1e3bf999ae2a5fda052ee55eb7e6516f5", size = 3957466, upload-time = "2025-09-16T15:33:34.528Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/4e/04/caa288fb735484fc5cb019bdf3d896eaccfae0ac4622e520d05692c46790/obstore-0.8.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08462b32f95a9948ed56ed63e88406e2e5a4cae1fde198f9682e0fb8487100ed", size = 3951293, upload-time = "2025-09-16T15:33:35.733Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/44/2f/d380239da2d6a1fda82e17df5dae600a404e8a93a065784518ff8325d5f6/obstore-0.8.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a0bf7763292a8fc47d01cd66e6f19002c5c6ad4b3ed4e6b2729f5e190fa8a0d", size = 3766199, upload-time = "2025-09-16T15:33:36.904Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/28/41/d391be069d3da82969b54266948b2582aeca5dd735abeda4d63dba36e07b/obstore-0.8.2-cp312-cp312-manylinux_2_24_aarch64.whl", hash = "sha256:bcd47f8126cb192cbe86942b8f73b1c45a651ce7e14c9a82c5641dfbf8be7603", size = 3529678, upload-time = "2025-09-16T15:33:38.221Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b9/4c/4862fdd1a3abde459ee8eea699b1797df638a460af235b18ca82c8fffb72/obstore-0.8.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:57eda9fd8c757c3b4fe36cf3918d7e589cc1286591295cc10b34122fa36dd3fd", size = 3698079, upload-time = "2025-09-16T15:33:39.696Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/68/ca/014e747bc53b570059c27e3565b2316fbe5c107d4134551f4cd3e24aa667/obstore-0.8.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ea44442aad8992166baa69f5069750979e4c5d9ffce772e61565945eea5774b9", size = 3687154, upload-time = "2025-09-16T15:33:40.92Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/6f/89/6db5f8edd93028e5b8bfbeee15e6bd3e56f72106107d31cb208b57659de4/obstore-0.8.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:41496a3ab8527402db4142aaaf0d42df9d7d354b13ba10d9c33e0e48dd49dd96", size = 3773444, upload-time = "2025-09-16T15:33:42.123Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/26/e5/c9e2cc540689c873beb61246e1615d6e38301e6a34dec424f5a5c63c1afd/obstore-0.8.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:43da209803f052df96c7c3cbec512d310982efd2407e4a435632841a51143170", size = 3939315, upload-time = "2025-09-16T15:33:43.252Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/4d/c9/bb53280ca50103c1ffda373cdc9b0f835431060039c2897cbc87ddd92e42/obstore-0.8.2-cp312-cp312-win_amd64.whl", hash = "sha256:1836f5dcd49f9f2950c75889ab5c51fb290d3ea93cdc39a514541e0be3af016e", size = 3978234, upload-time = "2025-09-16T15:33:44.393Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f0/5d/8c3316cc958d386d5e6ab03e9db9ddc27f8e2141cee4a6777ae5b92f3aac/obstore-0.8.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:212f033e53fe6e53d64957923c5c88949a400e9027f7038c705ec2e9038be563", size = 3612027, upload-time = "2025-09-16T15:33:45.6Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ea/4d/699359774ce6330130536d008bfc32827fab0c25a00238d015a5974a3d1d/obstore-0.8.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bee21fa4ba148d08fa90e47a96df11161661ed31e09c056a373cb2154b0f2852", size = 3344686, upload-time = "2025-09-16T15:33:47.185Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/82/37/55437341f10512906e02fd9fa69a8a95ad3f2f6a916d3233fda01763d110/obstore-0.8.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4c66594b59832ff1ced4c72575d9beb8b5f9b4e404ac1150a42bfb226617fd50", size = 3459860, upload-time = "2025-09-16T15:33:48.382Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/7a/51/4245a616c94ee4851965e33f7a563ab4090cc81f52cc73227ff9ceca2e46/obstore-0.8.2-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:089f33af5c2fe132d00214a0c1f40601b28f23a38e24ef9f79fb0576f2730b74", size = 3691648, upload-time = "2025-09-16T15:33:49.524Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/4e/f1/4e2fb24171e3ca3641a4653f006be826e7e17634b11688a5190553b00b83/obstore-0.8.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d87f658dfd340d5d9ea2d86a7c90d44da77a0db9e00c034367dca335735110cf", size = 3956867, upload-time = "2025-09-16T15:33:51.082Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/42/f5/b703115361c798c9c1744e1e700d5908d904a8c2e2bd38bec759c9ffb469/obstore-0.8.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6e2e4fa92828c4fbc2d487f3da2d3588701a1b67d9f6ca3c97cc2afc912e9c63", size = 3950599, upload-time = "2025-09-16T15:33:52.173Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/53/20/08c6dc0f20c1394e2324b9344838e4e7af770cdcb52c30757a475f50daeb/obstore-0.8.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab440e89c5c37a8ec230857dd65147d4b923e0cada33297135d05e0f937d696a", size = 3765865, upload-time = "2025-09-16T15:33:53.291Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/77/20/77907765e29b2eba6bd8821872284d91170d7084f670855b2dfcb249ea14/obstore-0.8.2-cp313-cp313-manylinux_2_24_aarch64.whl", hash = "sha256:b9beed107c5c9cd995d4a73263861fcfbc414d58773ed65c14f80eb18258a932", size = 3529807, upload-time = "2025-09-16T15:33:54.535Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/a5/f5/f629d39cc30d050f52b1bf927e4d65c1cc7d7ffbb8a635cd546b5c5219a0/obstore-0.8.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b75b4e7746292c785e31edcd5aadc8b758238372a19d4c5e394db5c305d7d175", size = 3693629, upload-time = "2025-09-16T15:33:56.016Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/30/ff/106763fd10f2a1cb47f2ef1162293c78ad52f4e73223d8d43fc6b755445d/obstore-0.8.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:f33e6c366869d05ab0b7f12efe63269e631c5450d95d6b4ba4c5faf63f69de70", size = 3686176, upload-time = "2025-09-16T15:33:57.247Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ce/0c/d2ccb6f32feeca906d5a7c4255340df5262af8838441ca06c9e4e37b67d5/obstore-0.8.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:12c885a9ce5ceb09d13cc186586c0c10b62597eff21b985f6ce8ff9dab963ad3", size = 3773081, upload-time = "2025-09-16T15:33:58.475Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/fa/79/40d1cc504cefc89c9b3dd8874287f3fddc7d963a8748d6dffc5880222013/obstore-0.8.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4accc883b93349a81c9931e15dd318cc703b02bbef2805d964724c73d006d00e", size = 3938589, upload-time = "2025-09-16T15:33:59.734Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/14/dd/916c6777222db3271e9fb3cf9a97ed92b3a9b3e465bdeec96de9ab809d53/obstore-0.8.2-cp313-cp313-win_amd64.whl", hash = "sha256:ec850adf9980e5788a826ccfd5819989724e2a2f712bfa3258e85966c8d9981e", size = 3977768, upload-time = "2025-09-16T15:34:01.25Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f1/61/66f8dc98bbf5613bbfe5bf21747b4c8091442977f4bd897945895ab7325c/obstore-0.8.2-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:1431e40e9bb4773a261e51b192ea6489d0799b9d4d7dbdf175cdf813eb8c0503", size = 3623364, upload-time = "2025-09-16T15:34:02.957Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/1a/66/6d527b3027e42f625c8fc816ac7d19b0d6228f95bfe7666e4d6b081d2348/obstore-0.8.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ddb39d4da303f50b959da000aa42734f6da7ac0cc0be2d5a7838b62c97055bb9", size = 3347764, upload-time = "2025-09-16T15:34:04.236Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0d/79/c00103302b620192ea447a948921ad3fed031ce3d19e989f038e1183f607/obstore-0.8.2-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e01f4e13783db453e17e005a4a3ceff09c41c262e44649ba169d253098c775e8", size = 3460981, upload-time = "2025-09-16T15:34:05.595Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/3d/d9/bfe4ed4b1aebc45b56644dd5b943cf8e1673505cccb352e66878a457e807/obstore-0.8.2-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:df0fc2d0bc17caff9b538564ddc26d7616f7e8b7c65b1a3c90b5048a8ad2e797", size = 3692711, upload-time = "2025-09-16T15:34:06.796Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/13/47/cd6c2cbb18e1f40c77e7957a4a03d2d83f1859a2e876a408f1ece81cad4c/obstore-0.8.2-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e439d06c99a140348f046c9f598ee349cc2dcd9105c15540a4b231f9cc48bbae", size = 3958362, upload-time = "2025-09-16T15:34:08.277Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/3d/ea/5ee82bf23abd71c7d6a3f2d008197ae8f8f569d41314c26a8f75318245be/obstore-0.8.2-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0e37d9046669fcc59522d0faf1d105fcbfd09c84cccaaa1e809227d8e030f32c", size = 3957082, upload-time = "2025-09-16T15:34:09.477Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/cb/ee/46650405e50fdaa8d95f30375491f9c91fac9517980e8a28a4a6af66927f/obstore-0.8.2-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2646fdcc4bbe92dc2bb5bcdff15574da1211f5806c002b66d514cee2a23c7cb8", size = 3775539, upload-time = "2025-09-16T15:34:10.726Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/35/d6/348a7ebebe2ca3d94dfc75344ea19675ae45472823e372c1852844078307/obstore-0.8.2-cp314-cp314-manylinux_2_24_aarch64.whl", hash = "sha256:e31a7d37675056d93dfc244605089dee67f5bba30f37c88436623c8c5ad9ba9d", size = 3535048, upload-time = "2025-09-16T15:34:12.076Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/41/07/b7a16cc0da91a4b902d47880ad24016abfe7880c63f7cdafda45d89a2f91/obstore-0.8.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:656313dd8170dde0f0cd471433283337a63912e8e790a121f7cc7639c83e3816", size = 3699035, upload-time = "2025-09-16T15:34:13.331Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/7f/74/3269a3a58347e0b019742d888612c4b765293c9c75efa44e144b1e884c0d/obstore-0.8.2-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:329038c9645d6d1741e77fe1a53e28a14b1a5c1461cfe4086082ad39ebabf981", size = 3687307, upload-time = "2025-09-16T15:34:14.501Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/01/f9/4fd4819ad6a49d2f462a45be453561f4caebded0dc40112deeffc34b89b1/obstore-0.8.2-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:1e4df99b369790c97c752d126b286dc86484ea49bff5782843a265221406566f", size = 3776076, upload-time = "2025-09-16T15:34:16.207Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/14/dd/7c4f958fa0b9fc4778fb3d232e38b37db8c6b260f641022fbba48b049d7e/obstore-0.8.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9e1c65c65e20cc990414a8a9af88209b1bbc0dd9521b5f6b0293c60e19439bb7", size = 3947445, upload-time = "2025-09-16T15:34:17.423Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openai"
|
name = "openai"
|
||||||
version = "2.26.0"
|
version = "2.26.0"
|
||||||
@@ -2481,6 +2697,128 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/c6/2e/3f73e8ca53718952222cacd0cf7eecc9db439d020f0c1fe7ae717e4e199a/openai-2.26.0-py3-none-any.whl", hash = "sha256:6151bf8f83802f036117f06cc8a57b3a4da60da9926826cc96747888b57f394f", size = 1136409, upload-time = "2026-03-05T23:17:34.072Z" },
|
{ url = "https://files.pythonhosted.org/packages/c6/2e/3f73e8ca53718952222cacd0cf7eecc9db439d020f0c1fe7ae717e4e199a/openai-2.26.0-py3-none-any.whl", hash = "sha256:6151bf8f83802f036117f06cc8a57b3a4da60da9926826cc96747888b57f394f", size = 1136409, upload-time = "2026-03-05T23:17:34.072Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "opentelemetry-api"
|
||||||
|
version = "1.40.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "importlib-metadata" },
|
||||||
|
{ name = "typing-extensions" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/2c/1d/4049a9e8698361cc1a1aa03a6c59e4fa4c71e0c0f94a30f988a6876a2ae6/opentelemetry_api-1.40.0.tar.gz", hash = "sha256:159be641c0b04d11e9ecd576906462773eb97ae1b657730f0ecf64d32071569f", size = 70851, upload-time = "2026-03-04T14:17:21.555Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/5f/bf/93795954016c522008da367da292adceed71cca6ee1717e1d64c83089099/opentelemetry_api-1.40.0-py3-none-any.whl", hash = "sha256:82dd69331ae74b06f6a874704be0cfaa49a1650e1537d4a813b86ecef7d0ecf9", size = 68676, upload-time = "2026-03-04T14:17:01.24Z" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "opentelemetry-exporter-otlp-proto-common"
|
||||||
|
version = "1.40.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "opentelemetry-proto" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/51/bc/1559d46557fe6eca0b46c88d4c2676285f1f3be2e8d06bb5d15fbffc814a/opentelemetry_exporter_otlp_proto_common-1.40.0.tar.gz", hash = "sha256:1cbee86a4064790b362a86601ee7934f368b81cd4cc2f2e163902a6e7818a0fa", size = 20416, upload-time = "2026-03-04T14:17:23.801Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/8b/ca/8f122055c97a932311a3f640273f084e738008933503d0c2563cd5d591fc/opentelemetry_exporter_otlp_proto_common-1.40.0-py3-none-any.whl", hash = "sha256:7081ff453835a82417bf38dccf122c827c3cbc94f2079b03bba02a3165f25149", size = 18369, upload-time = "2026-03-04T14:17:04.796Z" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "opentelemetry-exporter-otlp-proto-http"
|
||||||
|
version = "1.40.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "googleapis-common-protos" },
|
||||||
|
{ name = "opentelemetry-api" },
|
||||||
|
{ name = "opentelemetry-exporter-otlp-proto-common" },
|
||||||
|
{ name = "opentelemetry-proto" },
|
||||||
|
{ name = "opentelemetry-sdk" },
|
||||||
|
{ name = "requests" },
|
||||||
|
{ name = "typing-extensions" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/2e/fa/73d50e2c15c56be4d000c98e24221d494674b0cc95524e2a8cb3856d95a4/opentelemetry_exporter_otlp_proto_http-1.40.0.tar.gz", hash = "sha256:db48f5e0f33217588bbc00274a31517ba830da576e59503507c839b38fa0869c", size = 17772, upload-time = "2026-03-04T14:17:25.324Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/a0/3a/8865d6754e61c9fb170cdd530a124a53769ee5f740236064816eb0ca7301/opentelemetry_exporter_otlp_proto_http-1.40.0-py3-none-any.whl", hash = "sha256:a8d1dab28f504c5d96577d6509f80a8150e44e8f45f82cdbe0e34c99ab040069", size = 19960, upload-time = "2026-03-04T14:17:07.153Z" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "opentelemetry-instrumentation"
|
||||||
|
version = "0.61b0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "opentelemetry-api" },
|
||||||
|
{ name = "opentelemetry-semantic-conventions" },
|
||||||
|
{ name = "packaging" },
|
||||||
|
{ name = "wrapt" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/da/37/6bf8e66bfcee5d3c6515b79cb2ee9ad05fe573c20f7ceb288d0e7eeec28c/opentelemetry_instrumentation-0.61b0.tar.gz", hash = "sha256:cb21b48db738c9de196eba6b805b4ff9de3b7f187e4bbf9a466fa170514f1fc7", size = 32606, upload-time = "2026-03-04T14:20:16.825Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d8/3e/f6f10f178b6316de67f0dfdbbb699a24fbe8917cf1743c1595fb9dcdd461/opentelemetry_instrumentation-0.61b0-py3-none-any.whl", hash = "sha256:92a93a280e69788e8f88391247cc530fd81f16f2b011979d4d6398f805cfbc63", size = 33448, upload-time = "2026-03-04T14:19:02.447Z" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "opentelemetry-instrumentation-aiohttp-client"
|
||||||
|
version = "0.61b0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "opentelemetry-api" },
|
||||||
|
{ name = "opentelemetry-instrumentation" },
|
||||||
|
{ name = "opentelemetry-semantic-conventions" },
|
||||||
|
{ name = "opentelemetry-util-http" },
|
||||||
|
{ name = "wrapt" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/24fed4de661de107f2426b28bbd87b51eaab28a2339b62f269a36ae24505/opentelemetry_instrumentation_aiohttp_client-0.61b0.tar.gz", hash = "sha256:c53ab3b88efcb7ce98c1129cc0389f0a1f214eb3675269b6c157770adcf47877", size = 19292, upload-time = "2026-03-04T14:20:18.408Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/df/f3/1edc42716521a3f754ac32ffb908f102e0f131f8e43fcd9ab29cab286723/opentelemetry_instrumentation_aiohttp_client-0.61b0-py3-none-any.whl", hash = "sha256:09bc47514c162507b357366ce15578743fd6305078cf7d872db1c99c13fa6972", size = 14534, upload-time = "2026-03-04T14:19:05.165Z" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "opentelemetry-proto"
|
||||||
|
version = "1.40.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "protobuf" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/4c/77/dd38991db037fdfce45849491cb61de5ab000f49824a00230afb112a4392/opentelemetry_proto-1.40.0.tar.gz", hash = "sha256:03f639ca129ba513f5819810f5b1f42bcb371391405d99c168fe6937c62febcd", size = 45667, upload-time = "2026-03-04T14:17:31.194Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b9/b2/189b2577dde745b15625b3214302605b1353436219d42b7912e77fa8dc24/opentelemetry_proto-1.40.0-py3-none-any.whl", hash = "sha256:266c4385d88923a23d63e353e9761af0f47a6ed0d486979777fe4de59dc9b25f", size = 72073, upload-time = "2026-03-04T14:17:16.673Z" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "opentelemetry-sdk"
|
||||||
|
version = "1.40.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "opentelemetry-api" },
|
||||||
|
{ name = "opentelemetry-semantic-conventions" },
|
||||||
|
{ name = "typing-extensions" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/58/fd/3c3125b20ba18ce2155ba9ea74acb0ae5d25f8cd39cfd37455601b7955cc/opentelemetry_sdk-1.40.0.tar.gz", hash = "sha256:18e9f5ec20d859d268c7cb3c5198c8d105d073714db3de50b593b8c1345a48f2", size = 184252, upload-time = "2026-03-04T14:17:31.87Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2c/c5/6a852903d8bfac758c6dc6e9a68b015d3c33f2f1be5e9591e0f4b69c7e0a/opentelemetry_sdk-1.40.0-py3-none-any.whl", hash = "sha256:787d2154a71f4b3d81f20524a8ce061b7db667d24e46753f32a7bc48f1c1f3f1", size = 141951, upload-time = "2026-03-04T14:17:17.961Z" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "opentelemetry-semantic-conventions"
|
||||||
|
version = "0.61b0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "opentelemetry-api" },
|
||||||
|
{ name = "typing-extensions" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/6d/c0/4ae7973f3c2cfd2b6e321f1675626f0dab0a97027cc7a297474c9c8f3d04/opentelemetry_semantic_conventions-0.61b0.tar.gz", hash = "sha256:072f65473c5d7c6dc0355b27d6c9d1a679d63b6d4b4b16a9773062cb7e31192a", size = 145755, upload-time = "2026-03-04T14:17:32.664Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b2/37/cc6a55e448deaa9b27377d087da8615a3416d8ad523d5960b78dbeadd02a/opentelemetry_semantic_conventions-0.61b0-py3-none-any.whl", hash = "sha256:fa530a96be229795f8cef353739b618148b0fe2b4b3f005e60e262926c4d38e2", size = 231621, upload-time = "2026-03-04T14:17:19.33Z" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "opentelemetry-util-http"
|
||||||
|
version = "0.61b0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/57/3c/f0196223efc5c4ca19f8fad3d5462b171ac6333013335ce540c01af419e9/opentelemetry_util_http-0.61b0.tar.gz", hash = "sha256:1039cb891334ad2731affdf034d8fb8b48c239af9b6dd295e5fabd07f1c95572", size = 11361, upload-time = "2026-03-04T14:20:57.01Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0d/e5/c08aaaf2f64288d2b6ef65741d2de5454e64af3e050f34285fb1907492fe/opentelemetry_util_http-0.61b0-py3-none-any.whl", hash = "sha256:8e715e848233e9527ea47e275659ea60a57a75edf5206a3b937e236a6da5fc33", size = 9281, upload-time = "2026-03-04T14:20:08.364Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "orjson"
|
name = "orjson"
|
||||||
version = "3.11.7"
|
version = "3.11.7"
|
||||||
@@ -2804,6 +3142,21 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/5b/5a/bc7b4a4ef808fa59a816c17b20c4bef6884daebbdf627ff2a161da67da19/propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237", size = 13305, upload-time = "2025-10-08T19:49:00.792Z" },
|
{ url = "https://files.pythonhosted.org/packages/5b/5a/bc7b4a4ef808fa59a816c17b20c4bef6884daebbdf627ff2a161da67da19/propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237", size = 13305, upload-time = "2025-10-08T19:49:00.792Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "protobuf"
|
||||||
|
version = "6.33.6"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/66/70/e908e9c5e52ef7c3a6c7902c9dfbb34c7e29c25d2f81ade3856445fd5c94/protobuf-6.33.6.tar.gz", hash = "sha256:a6768d25248312c297558af96a9f9c929e8c4cee0659cb07e780731095f38135", size = 444531, upload-time = "2026-03-18T19:05:00.988Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/fc/9f/2f509339e89cfa6f6a4c4ff50438db9ca488dec341f7e454adad60150b00/protobuf-6.33.6-cp310-abi3-win32.whl", hash = "sha256:7d29d9b65f8afef196f8334e80d6bc1d5d4adedb449971fefd3723824e6e77d3", size = 425739, upload-time = "2026-03-18T19:04:48.373Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/76/5d/683efcd4798e0030c1bab27374fd13a89f7c2515fb1f3123efdfaa5eab57/protobuf-6.33.6-cp310-abi3-win_amd64.whl", hash = "sha256:0cd27b587afca21b7cfa59a74dcbd48a50f0a6400cfb59391340ad729d91d326", size = 437089, upload-time = "2026-03-18T19:04:50.381Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/5c/01/a3c3ed5cd186f39e7880f8303cc51385a198a81469d53d0fdecf1f64d929/protobuf-6.33.6-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:9720e6961b251bde64edfdab7d500725a2af5280f3f4c87e57c0208376aa8c3a", size = 427737, upload-time = "2026-03-18T19:04:51.866Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ee/90/b3c01fdec7d2f627b3a6884243ba328c1217ed2d978def5c12dc50d328a3/protobuf-6.33.6-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:e2afbae9b8e1825e3529f88d514754e094278bb95eadc0e199751cdd9a2e82a2", size = 324610, upload-time = "2026-03-18T19:04:53.096Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/9b/ca/25afc144934014700c52e05103c2421997482d561f3101ff352e1292fb81/protobuf-6.33.6-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:c96c37eec15086b79762ed265d59ab204dabc53056e3443e702d2681f4b39ce3", size = 339381, upload-time = "2026-03-18T19:04:54.616Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/16/92/d1e32e3e0d894fe00b15ce28ad4944ab692713f2e7f0a99787405e43533a/protobuf-6.33.6-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:e9db7e292e0ab79dd108d7f1a94fe31601ce1ee3f7b79e0692043423020b0593", size = 323436, upload-time = "2026-03-18T19:04:55.768Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c4/72/02445137af02769918a93807b2b7890047c32bfb9f90371cbc12688819eb/protobuf-6.33.6-py3-none-any.whl", hash = "sha256:77179e006c476e69bf8e8ce866640091ec42e1beb80b213c3900006ecfba6901", size = 170656, upload-time = "2026-03-18T19:04:59.826Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "psutil"
|
name = "psutil"
|
||||||
version = "7.2.2"
|
version = "7.2.2"
|
||||||
@@ -3133,6 +3486,15 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/00/4b/ccc026168948fec4f7555b9164c724cf4125eac006e176541483d2c959be/pydantic_settings-2.13.1-py3-none-any.whl", hash = "sha256:d56fd801823dbeae7f0975e1f8c8e25c258eb75d278ea7abb5d9cebb01b56237", size = 58929, upload-time = "2026-02-19T13:45:06.034Z" },
|
{ url = "https://files.pythonhosted.org/packages/00/4b/ccc026168948fec4f7555b9164c724cf4125eac006e176541483d2c959be/pydantic_settings-2.13.1-py3-none-any.whl", hash = "sha256:d56fd801823dbeae7f0975e1f8c8e25c258eb75d278ea7abb5d9cebb01b56237", size = 58929, upload-time = "2026-02-19T13:45:06.034Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pydispatcher"
|
||||||
|
version = "2.0.7"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/21/db/030d0700ae90d2f9d52c2f3c1f864881e19cef8cba3b0a08759c8494c19c/PyDispatcher-2.0.7.tar.gz", hash = "sha256:b777c6ad080dc1bad74a4c29d6a46914fa6701ac70f94b0d66fbcfde62f5be31", size = 38891, upload-time = "2023-02-17T20:11:13.106Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/66/0e/9ee7bc0b48ec45d93b302fa2d787830dca4dc454d31a237faa5815995988/PyDispatcher-2.0.7-py3-none-any.whl", hash = "sha256:96543bea04115ffde08f851e1d45cacbfd1ee866ac42127d9b476dc5aefa7de0", size = 12040, upload-time = "2023-02-17T20:11:11.991Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pyee"
|
name = "pyee"
|
||||||
version = "13.0.1"
|
version = "13.0.1"
|
||||||
@@ -3230,6 +3592,18 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/d1/81/ef2b1dfd1862567d573a4fdbc9f969067621764fbb74338496840a1d2977/pyopenssl-25.3.0-py3-none-any.whl", hash = "sha256:1fda6fc034d5e3d179d39e59c1895c9faeaf40a79de5fc4cbbfbe0d36f4a77b6", size = 57268, upload-time = "2025-09-17T00:32:19.474Z" },
|
{ url = "https://files.pythonhosted.org/packages/d1/81/ef2b1dfd1862567d573a4fdbc9f969067621764fbb74338496840a1d2977/pyopenssl-25.3.0-py3-none-any.whl", hash = "sha256:1fda6fc034d5e3d179d39e59c1895c9faeaf40a79de5fc4cbbfbe0d36f4a77b6", size = 57268, upload-time = "2025-09-17T00:32:19.474Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "python-dateutil"
|
||||||
|
version = "2.9.0.post0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "six" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "python-dotenv"
|
name = "python-dotenv"
|
||||||
version = "1.2.2"
|
version = "1.2.2"
|
||||||
@@ -4128,6 +4502,26 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/72/f4/0de46cfa12cdcbcd464cc59fde36912af405696f687e53a091fb432f694c/tokenizers-0.22.2-cp39-abi3-win_arm64.whl", hash = "sha256:9ce725d22864a1e965217204946f830c37876eee3b2ba6fc6255e8e903d5fcbc", size = 2612133, upload-time = "2026-01-05T10:45:17.232Z" },
|
{ url = "https://files.pythonhosted.org/packages/72/f4/0de46cfa12cdcbcd464cc59fde36912af405696f687e53a091fb432f694c/tokenizers-0.22.2-cp39-abi3-win_arm64.whl", hash = "sha256:9ce725d22864a1e965217204946f830c37876eee3b2ba6fc6255e8e903d5fcbc", size = 2612133, upload-time = "2026-01-05T10:45:17.232Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "0.10.2"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/be/ba/1f744cdc819428fc6b5084ec34d9b30660f6f9daaf70eead706e3203ec3c/toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f", size = 22253, upload-time = "2020-11-01T01:40:22.204Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", size = 16588, upload-time = "2020-11-01T01:40:20.672Z" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tool"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "argh" },
|
||||||
|
{ name = "pydispatcher" },
|
||||||
|
{ name = "pyyaml" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/ab/ec/2b258e54a13bc53a4352e538276b4b9ffdf0d08b3f2972ee062e71dc55a0/tool-0.8.0.tar.gz", hash = "sha256:5c596600abac4dc93d7854b0640fcc7577b7387f5b5f13bc873aed130aa8e881", size = 51557, upload-time = "2011-11-25T14:50:47.079Z" }
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "torch"
|
name = "torch"
|
||||||
version = "2.10.0"
|
version = "2.10.0"
|
||||||
@@ -4488,47 +4882,82 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "websockets"
|
name = "websockets"
|
||||||
version = "16.0"
|
version = "15.0.1"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/04/24/4b2031d72e840ce4c1ccb255f693b15c334757fc50023e4db9537080b8c4/websockets-16.0.tar.gz", hash = "sha256:5f6261a5e56e8d5c42a4497b364ea24d94d9563e8fbd44e78ac40879c60179b5", size = 179346, upload-time = "2026-01-10T09:23:47.181Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/21/e6/26d09fab466b7ca9c7737474c52be4f76a40301b08362eb2dbc19dcc16c1/websockets-15.0.1.tar.gz", hash = "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee", size = 177016, upload-time = "2025-03-05T20:03:41.606Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/84/7b/bac442e6b96c9d25092695578dda82403c77936104b5682307bd4deb1ad4/websockets-16.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:71c989cbf3254fbd5e84d3bff31e4da39c43f884e64f2551d14bb3c186230f00", size = 177365, upload-time = "2026-01-10T09:22:46.787Z" },
|
{ url = "https://files.pythonhosted.org/packages/51/6b/4545a0d843594f5d0771e86463606a3988b5a09ca5123136f8a76580dd63/websockets-15.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3e90baa811a5d73f3ca0bcbf32064d663ed81318ab225ee4f427ad4e26e5aff3", size = 175437, upload-time = "2025-03-05T20:02:16.706Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/b0/fe/136ccece61bd690d9c1f715baaeefd953bb2360134de73519d5df19d29ca/websockets-16.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:8b6e209ffee39ff1b6d0fa7bfef6de950c60dfb91b8fcead17da4ee539121a79", size = 175038, upload-time = "2026-01-10T09:22:47.999Z" },
|
{ url = "https://files.pythonhosted.org/packages/f4/71/809a0f5f6a06522af902e0f2ea2757f71ead94610010cf570ab5c98e99ed/websockets-15.0.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:592f1a9fe869c778694f0aa806ba0374e97648ab57936f092fd9d87f8bc03665", size = 173096, upload-time = "2025-03-05T20:02:18.832Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/40/1e/9771421ac2286eaab95b8575b0cb701ae3663abf8b5e1f64f1fd90d0a673/websockets-16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:86890e837d61574c92a97496d590968b23c2ef0aeb8a9bc9421d174cd378ae39", size = 175328, upload-time = "2026-01-10T09:22:49.809Z" },
|
{ url = "https://files.pythonhosted.org/packages/3d/69/1a681dd6f02180916f116894181eab8b2e25b31e484c5d0eae637ec01f7c/websockets-15.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0701bc3cfcb9164d04a14b149fd74be7347a530ad3bbf15ab2c678a2cd3dd9a2", size = 173332, upload-time = "2025-03-05T20:02:20.187Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/18/29/71729b4671f21e1eaa5d6573031ab810ad2936c8175f03f97f3ff164c802/websockets-16.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9b5aca38b67492ef518a8ab76851862488a478602229112c4b0d58d63a7a4d5c", size = 184915, upload-time = "2026-01-10T09:22:51.071Z" },
|
{ url = "https://files.pythonhosted.org/packages/a6/02/0073b3952f5bce97eafbb35757f8d0d54812b6174ed8dd952aa08429bcc3/websockets-15.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8b56bdcdb4505c8078cb6c7157d9811a85790f2f2b3632c7d1462ab5783d215", size = 183152, upload-time = "2025-03-05T20:02:22.286Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/97/bb/21c36b7dbbafc85d2d480cd65df02a1dc93bf76d97147605a8e27ff9409d/websockets-16.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e0334872c0a37b606418ac52f6ab9cfd17317ac26365f7f65e203e2d0d0d359f", size = 186152, upload-time = "2026-01-10T09:22:52.224Z" },
|
{ url = "https://files.pythonhosted.org/packages/74/45/c205c8480eafd114b428284840da0b1be9ffd0e4f87338dc95dc6ff961a1/websockets-15.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0af68c55afbd5f07986df82831c7bff04846928ea8d1fd7f30052638788bc9b5", size = 182096, upload-time = "2025-03-05T20:02:24.368Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/4a/34/9bf8df0c0cf88fa7bfe36678dc7b02970c9a7d5e065a3099292db87b1be2/websockets-16.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a0b31e0b424cc6b5a04b8838bbaec1688834b2383256688cf47eb97412531da1", size = 185583, upload-time = "2026-01-10T09:22:53.443Z" },
|
{ url = "https://files.pythonhosted.org/packages/14/8f/aa61f528fba38578ec553c145857a181384c72b98156f858ca5c8e82d9d3/websockets-15.0.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64dee438fed052b52e4f98f76c5790513235efaa1ef7f3f2192c392cd7c91b65", size = 182523, upload-time = "2025-03-05T20:02:25.669Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/47/88/4dd516068e1a3d6ab3c7c183288404cd424a9a02d585efbac226cb61ff2d/websockets-16.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:485c49116d0af10ac698623c513c1cc01c9446c058a4e61e3bf6c19dff7335a2", size = 184880, upload-time = "2026-01-10T09:22:55.033Z" },
|
{ url = "https://files.pythonhosted.org/packages/ec/6d/0267396610add5bc0d0d3e77f546d4cd287200804fe02323797de77dbce9/websockets-15.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d5f6b181bb38171a8ad1d6aa58a67a6aa9d4b38d0f8c5f496b9e42561dfc62fe", size = 182790, upload-time = "2025-03-05T20:02:26.99Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/91/d6/7d4553ad4bf1c0421e1ebd4b18de5d9098383b5caa1d937b63df8d04b565/websockets-16.0-cp312-cp312-win32.whl", hash = "sha256:eaded469f5e5b7294e2bdca0ab06becb6756ea86894a47806456089298813c89", size = 178261, upload-time = "2026-01-10T09:22:56.251Z" },
|
{ url = "https://files.pythonhosted.org/packages/02/05/c68c5adbf679cf610ae2f74a9b871ae84564462955d991178f95a1ddb7dd/websockets-15.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5d54b09eba2bada6011aea5375542a157637b91029687eb4fdb2dab11059c1b4", size = 182165, upload-time = "2025-03-05T20:02:30.291Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/c3/f0/f3a17365441ed1c27f850a80b2bc680a0fa9505d733fe152fdf5e98c1c0b/websockets-16.0-cp312-cp312-win_amd64.whl", hash = "sha256:5569417dc80977fc8c2d43a86f78e0a5a22fee17565d78621b6bb264a115d4ea", size = 178693, upload-time = "2026-01-10T09:22:57.478Z" },
|
{ url = "https://files.pythonhosted.org/packages/29/93/bb672df7b2f5faac89761cb5fa34f5cec45a4026c383a4b5761c6cea5c16/websockets-15.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3be571a8b5afed347da347bfcf27ba12b069d9d7f42cb8c7028b5e98bbb12597", size = 182160, upload-time = "2025-03-05T20:02:31.634Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/cc/9c/baa8456050d1c1b08dd0ec7346026668cbc6f145ab4e314d707bb845bf0d/websockets-16.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:878b336ac47938b474c8f982ac2f7266a540adc3fa4ad74ae96fea9823a02cc9", size = 177364, upload-time = "2026-01-10T09:22:59.333Z" },
|
{ url = "https://files.pythonhosted.org/packages/ff/83/de1f7709376dc3ca9b7eeb4b9a07b4526b14876b6d372a4dc62312bebee0/websockets-15.0.1-cp312-cp312-win32.whl", hash = "sha256:c338ffa0520bdb12fbc527265235639fb76e7bc7faafbb93f6ba80d9c06578a9", size = 176395, upload-time = "2025-03-05T20:02:33.017Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/7e/0c/8811fc53e9bcff68fe7de2bcbe75116a8d959ac699a3200f4847a8925210/websockets-16.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:52a0fec0e6c8d9a784c2c78276a48a2bdf099e4ccc2a4cad53b27718dbfd0230", size = 175039, upload-time = "2026-01-10T09:23:01.171Z" },
|
{ url = "https://files.pythonhosted.org/packages/7d/71/abf2ebc3bbfa40f391ce1428c7168fb20582d0ff57019b69ea20fa698043/websockets-15.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:fcd5cf9e305d7b8338754470cf69cf81f420459dbae8a3b40cee57417f4614a7", size = 176841, upload-time = "2025-03-05T20:02:34.498Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/aa/82/39a5f910cb99ec0b59e482971238c845af9220d3ab9fa76dd9162cda9d62/websockets-16.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e6578ed5b6981005df1860a56e3617f14a6c307e6a71b4fff8c48fdc50f3ed2c", size = 175323, upload-time = "2026-01-10T09:23:02.341Z" },
|
{ url = "https://files.pythonhosted.org/packages/cb/9f/51f0cf64471a9d2b4d0fc6c534f323b664e7095640c34562f5182e5a7195/websockets-15.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee443ef070bb3b6ed74514f5efaa37a252af57c90eb33b956d35c8e9c10a1931", size = 175440, upload-time = "2025-03-05T20:02:36.695Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/bd/28/0a25ee5342eb5d5f297d992a77e56892ecb65e7854c7898fb7d35e9b33bd/websockets-16.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:95724e638f0f9c350bb1c2b0a7ad0e83d9cc0c9259f3ea94e40d7b02a2179ae5", size = 184975, upload-time = "2026-01-10T09:23:03.756Z" },
|
{ url = "https://files.pythonhosted.org/packages/8a/05/aa116ec9943c718905997412c5989f7ed671bc0188ee2ba89520e8765d7b/websockets-15.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5a939de6b7b4e18ca683218320fc67ea886038265fd1ed30173f5ce3f8e85675", size = 173098, upload-time = "2025-03-05T20:02:37.985Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f9/66/27ea52741752f5107c2e41fda05e8395a682a1e11c4e592a809a90c6a506/websockets-16.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c0204dc62a89dc9d50d682412c10b3542d748260d743500a85c13cd1ee4bde82", size = 186203, upload-time = "2026-01-10T09:23:05.01Z" },
|
{ url = "https://files.pythonhosted.org/packages/ff/0b/33cef55ff24f2d92924923c99926dcce78e7bd922d649467f0eda8368923/websockets-15.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:746ee8dba912cd6fc889a8147168991d50ed70447bf18bcda7039f7d2e3d9151", size = 173329, upload-time = "2025-03-05T20:02:39.298Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/37/e5/8e32857371406a757816a2b471939d51c463509be73fa538216ea52b792a/websockets-16.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:52ac480f44d32970d66763115edea932f1c5b1312de36df06d6b219f6741eed8", size = 185653, upload-time = "2026-01-10T09:23:06.301Z" },
|
{ url = "https://files.pythonhosted.org/packages/31/1d/063b25dcc01faa8fada1469bdf769de3768b7044eac9d41f734fd7b6ad6d/websockets-15.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:595b6c3969023ecf9041b2936ac3827e4623bfa3ccf007575f04c5a6aa318c22", size = 183111, upload-time = "2025-03-05T20:02:40.595Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/9b/67/f926bac29882894669368dc73f4da900fcdf47955d0a0185d60103df5737/websockets-16.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6e5a82b677f8f6f59e8dfc34ec06ca6b5b48bc4fcda346acd093694cc2c24d8f", size = 184920, upload-time = "2026-01-10T09:23:07.492Z" },
|
{ url = "https://files.pythonhosted.org/packages/93/53/9a87ee494a51bf63e4ec9241c1ccc4f7c2f45fff85d5bde2ff74fcb68b9e/websockets-15.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c714d2fc58b5ca3e285461a4cc0c9a66bd0e24c5da9911e30158286c9b5be7f", size = 182054, upload-time = "2025-03-05T20:02:41.926Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/3c/a1/3d6ccdcd125b0a42a311bcd15a7f705d688f73b2a22d8cf1c0875d35d34a/websockets-16.0-cp313-cp313-win32.whl", hash = "sha256:abf050a199613f64c886ea10f38b47770a65154dc37181bfaff70c160f45315a", size = 178255, upload-time = "2026-01-10T09:23:09.245Z" },
|
{ url = "https://files.pythonhosted.org/packages/ff/b2/83a6ddf56cdcbad4e3d841fcc55d6ba7d19aeb89c50f24dd7e859ec0805f/websockets-15.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f3c1e2ab208db911594ae5b4f79addeb3501604a165019dd221c0bdcabe4db8", size = 182496, upload-time = "2025-03-05T20:02:43.304Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/6b/ae/90366304d7c2ce80f9b826096a9e9048b4bb760e44d3b873bb272cba696b/websockets-16.0-cp313-cp313-win_amd64.whl", hash = "sha256:3425ac5cf448801335d6fdc7ae1eb22072055417a96cc6b31b3861f455fbc156", size = 178689, upload-time = "2026-01-10T09:23:10.483Z" },
|
{ url = "https://files.pythonhosted.org/packages/98/41/e7038944ed0abf34c45aa4635ba28136f06052e08fc2168520bb8b25149f/websockets-15.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:229cf1d3ca6c1804400b0a9790dc66528e08a6a1feec0d5040e8b9eb14422375", size = 182829, upload-time = "2025-03-05T20:02:48.812Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f3/1d/e88022630271f5bd349ed82417136281931e558d628dd52c4d8621b4a0b2/websockets-16.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:8cc451a50f2aee53042ac52d2d053d08bf89bcb31ae799cb4487587661c038a0", size = 177406, upload-time = "2026-01-10T09:23:12.178Z" },
|
{ url = "https://files.pythonhosted.org/packages/e0/17/de15b6158680c7623c6ef0db361da965ab25d813ae54fcfeae2e5b9ef910/websockets-15.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:756c56e867a90fb00177d530dca4b097dd753cde348448a1012ed6c5131f8b7d", size = 182217, upload-time = "2025-03-05T20:02:50.14Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f2/78/e63be1bf0724eeb4616efb1ae1c9044f7c3953b7957799abb5915bffd38e/websockets-16.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:daa3b6ff70a9241cf6c7fc9e949d41232d9d7d26fd3522b1ad2b4d62487e9904", size = 175085, upload-time = "2026-01-10T09:23:13.511Z" },
|
{ url = "https://files.pythonhosted.org/packages/33/2b/1f168cb6041853eef0362fb9554c3824367c5560cbdaad89ac40f8c2edfc/websockets-15.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:558d023b3df0bffe50a04e710bc87742de35060580a293c2a984299ed83bc4e4", size = 182195, upload-time = "2025-03-05T20:02:51.561Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/bb/f4/d3c9220d818ee955ae390cf319a7c7a467beceb24f05ee7aaaa2414345ba/websockets-16.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:fd3cb4adb94a2a6e2b7c0d8d05cb94e6f1c81a0cf9dc2694fb65c7e8d94c42e4", size = 175328, upload-time = "2026-01-10T09:23:14.727Z" },
|
{ url = "https://files.pythonhosted.org/packages/86/eb/20b6cdf273913d0ad05a6a14aed4b9a85591c18a987a3d47f20fa13dcc47/websockets-15.0.1-cp313-cp313-win32.whl", hash = "sha256:ba9e56e8ceeeedb2e080147ba85ffcd5cd0711b89576b83784d8605a7df455fa", size = 176393, upload-time = "2025-03-05T20:02:53.814Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/63/bc/d3e208028de777087e6fb2b122051a6ff7bbcca0d6df9d9c2bf1dd869ae9/websockets-16.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:781caf5e8eee67f663126490c2f96f40906594cb86b408a703630f95550a8c3e", size = 185044, upload-time = "2026-01-10T09:23:15.939Z" },
|
{ url = "https://files.pythonhosted.org/packages/1b/6c/c65773d6cab416a64d191d6ee8a8b1c68a09970ea6909d16965d26bfed1e/websockets-15.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561", size = 176837, upload-time = "2025-03-05T20:02:55.237Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/ad/6e/9a0927ac24bd33a0a9af834d89e0abc7cfd8e13bed17a86407a66773cc0e/websockets-16.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:caab51a72c51973ca21fa8a18bd8165e1a0183f1ac7066a182ff27107b71e1a4", size = 186279, upload-time = "2026-01-10T09:23:17.148Z" },
|
{ url = "https://files.pythonhosted.org/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743, upload-time = "2025-03-05T20:03:39.41Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/b9/ca/bf1c68440d7a868180e11be653c85959502efd3a709323230314fda6e0b3/websockets-16.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:19c4dc84098e523fd63711e563077d39e90ec6702aff4b5d9e344a60cb3c0cb1", size = 185711, upload-time = "2026-01-10T09:23:18.372Z" },
|
]
|
||||||
{ url = "https://files.pythonhosted.org/packages/c4/f8/fdc34643a989561f217bb477cbc47a3a07212cbda91c0e4389c43c296ebf/websockets-16.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:a5e18a238a2b2249c9a9235466b90e96ae4795672598a58772dd806edc7ac6d3", size = 184982, upload-time = "2026-01-10T09:23:19.652Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/dd/d1/574fa27e233764dbac9c52730d63fcf2823b16f0856b3329fc6268d6ae4f/websockets-16.0-cp314-cp314-win32.whl", hash = "sha256:a069d734c4a043182729edd3e9f247c3b2a4035415a9172fd0f1b71658a320a8", size = 177915, upload-time = "2026-01-10T09:23:21.458Z" },
|
[[package]]
|
||||||
{ url = "https://files.pythonhosted.org/packages/8a/f1/ae6b937bf3126b5134ce1f482365fde31a357c784ac51852978768b5eff4/websockets-16.0-cp314-cp314-win_amd64.whl", hash = "sha256:c0ee0e63f23914732c6d7e0cce24915c48f3f1512ec1d079ed01fc629dab269d", size = 178381, upload-time = "2026-01-10T09:23:22.715Z" },
|
name = "wrapt"
|
||||||
{ url = "https://files.pythonhosted.org/packages/06/9b/f791d1db48403e1f0a27577a6beb37afae94254a8c6f08be4a23e4930bc0/websockets-16.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:a35539cacc3febb22b8f4d4a99cc79b104226a756aa7400adc722e83b0d03244", size = 177737, upload-time = "2026-01-10T09:23:24.523Z" },
|
version = "1.17.3"
|
||||||
{ url = "https://files.pythonhosted.org/packages/bd/40/53ad02341fa33b3ce489023f635367a4ac98b73570102ad2cdd770dacc9a/websockets-16.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:b784ca5de850f4ce93ec85d3269d24d4c82f22b7212023c974c401d4980ebc5e", size = 175268, upload-time = "2026-01-10T09:23:25.781Z" },
|
source = { registry = "https://pypi.org/simple" }
|
||||||
{ url = "https://files.pythonhosted.org/packages/74/9b/6158d4e459b984f949dcbbb0c5d270154c7618e11c01029b9bbd1bb4c4f9/websockets-16.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:569d01a4e7fba956c5ae4fc988f0d4e187900f5497ce46339c996dbf24f17641", size = 175486, upload-time = "2026-01-10T09:23:27.033Z" },
|
sdist = { url = "https://files.pythonhosted.org/packages/95/8f/aeb76c5b46e273670962298c23e7ddde79916cb74db802131d49a85e4b7d/wrapt-1.17.3.tar.gz", hash = "sha256:f66eb08feaa410fe4eebd17f2a2c8e2e46d3476e9f8c783daa8e09e0faa666d0", size = 55547, upload-time = "2025-08-12T05:53:21.714Z" }
|
||||||
{ url = "https://files.pythonhosted.org/packages/e5/2d/7583b30208b639c8090206f95073646c2c9ffd66f44df967981a64f849ad/websockets-16.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:50f23cdd8343b984957e4077839841146f67a3d31ab0d00e6b824e74c5b2f6e8", size = 185331, upload-time = "2026-01-10T09:23:28.259Z" },
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/45/b0/cce3784eb519b7b5ad680d14b9673a31ab8dcb7aad8b64d81709d2430aa8/websockets-16.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:152284a83a00c59b759697b7f9e9cddf4e3c7861dd0d964b472b70f78f89e80e", size = 186501, upload-time = "2026-01-10T09:23:29.449Z" },
|
{ url = "https://files.pythonhosted.org/packages/9f/41/cad1aba93e752f1f9268c77270da3c469883d56e2798e7df6240dcb2287b/wrapt-1.17.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ab232e7fdb44cdfbf55fc3afa31bcdb0d8980b9b95c38b6405df2acb672af0e0", size = 53998, upload-time = "2025-08-12T05:51:47.138Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/19/60/b8ebe4c7e89fb5f6cdf080623c9d92789a53636950f7abacfc33fe2b3135/websockets-16.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bc59589ab64b0022385f429b94697348a6a234e8ce22544e3681b2e9331b5944", size = 186062, upload-time = "2026-01-10T09:23:31.368Z" },
|
{ url = "https://files.pythonhosted.org/packages/60/f8/096a7cc13097a1869fe44efe68dace40d2a16ecb853141394047f0780b96/wrapt-1.17.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9baa544e6acc91130e926e8c802a17f3b16fbea0fd441b5a60f5cf2cc5c3deba", size = 39020, upload-time = "2025-08-12T05:51:35.906Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/88/a8/a080593f89b0138b6cba1b28f8df5673b5506f72879322288b031337c0b8/websockets-16.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:32da954ffa2814258030e5a57bc73a3635463238e797c7375dc8091327434206", size = 185356, upload-time = "2026-01-10T09:23:32.627Z" },
|
{ url = "https://files.pythonhosted.org/packages/33/df/bdf864b8997aab4febb96a9ae5c124f700a5abd9b5e13d2a3214ec4be705/wrapt-1.17.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6b538e31eca1a7ea4605e44f81a48aa24c4632a277431a6ed3f328835901f4fd", size = 39098, upload-time = "2025-08-12T05:51:57.474Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/c2/b6/b9afed2afadddaf5ebb2afa801abf4b0868f42f8539bfe4b071b5266c9fe/websockets-16.0-cp314-cp314t-win32.whl", hash = "sha256:5a4b4cc550cb665dd8a47f868c8d04c8230f857363ad3c9caf7a0c3bf8c61ca6", size = 178085, upload-time = "2026-01-10T09:23:33.816Z" },
|
{ url = "https://files.pythonhosted.org/packages/9f/81/5d931d78d0eb732b95dc3ddaeeb71c8bb572fb01356e9133916cd729ecdd/wrapt-1.17.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:042ec3bb8f319c147b1301f2393bc19dba6e176b7da446853406d041c36c7828", size = 88036, upload-time = "2025-08-12T05:52:34.784Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/9f/3e/28135a24e384493fa804216b79a6a6759a38cc4ff59118787b9fb693df93/websockets-16.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b14dc141ed6d2dde437cddb216004bcac6a1df0935d79656387bd41632ba0bbd", size = 178531, upload-time = "2026-01-10T09:23:35.016Z" },
|
{ url = "https://files.pythonhosted.org/packages/ca/38/2e1785df03b3d72d34fc6252d91d9d12dc27a5c89caef3335a1bbb8908ca/wrapt-1.17.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3af60380ba0b7b5aeb329bc4e402acd25bd877e98b3727b0135cb5c2efdaefe9", size = 88156, upload-time = "2025-08-12T05:52:13.599Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/6f/28/258ebab549c2bf3e64d2b0217b973467394a9cea8c42f70418ca2c5d0d2e/websockets-16.0-py3-none-any.whl", hash = "sha256:1637db62fad1dc833276dded54215f2c7fa46912301a24bd94d45d46a011ceec", size = 171598, upload-time = "2026-01-10T09:23:45.395Z" },
|
{ url = "https://files.pythonhosted.org/packages/b3/8b/48cdb60fe0603e34e05cffda0b2a4adab81fd43718e11111a4b0100fd7c1/wrapt-1.17.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0b02e424deef65c9f7326d8c19220a2c9040c51dc165cddb732f16198c168396", size = 87102, upload-time = "2025-08-12T05:52:14.56Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/3c/51/d81abca783b58f40a154f1b2c56db1d2d9e0d04fa2d4224e357529f57a57/wrapt-1.17.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:74afa28374a3c3a11b3b5e5fca0ae03bef8450d6aa3ab3a1e2c30e3a75d023dc", size = 87732, upload-time = "2025-08-12T05:52:36.165Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/9e/b1/43b286ca1392a006d5336412d41663eeef1ad57485f3e52c767376ba7e5a/wrapt-1.17.3-cp312-cp312-win32.whl", hash = "sha256:4da9f45279fff3543c371d5ababc57a0384f70be244de7759c85a7f989cb4ebe", size = 36705, upload-time = "2025-08-12T05:53:07.123Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/28/de/49493f962bd3c586ab4b88066e967aa2e0703d6ef2c43aa28cb83bf7b507/wrapt-1.17.3-cp312-cp312-win_amd64.whl", hash = "sha256:e71d5c6ebac14875668a1e90baf2ea0ef5b7ac7918355850c0908ae82bcb297c", size = 38877, upload-time = "2025-08-12T05:53:05.436Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f1/48/0f7102fe9cb1e8a5a77f80d4f0956d62d97034bbe88d33e94699f99d181d/wrapt-1.17.3-cp312-cp312-win_arm64.whl", hash = "sha256:604d076c55e2fdd4c1c03d06dc1a31b95130010517b5019db15365ec4a405fc6", size = 36885, upload-time = "2025-08-12T05:52:54.367Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/fc/f6/759ece88472157acb55fc195e5b116e06730f1b651b5b314c66291729193/wrapt-1.17.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a47681378a0439215912ef542c45a783484d4dd82bac412b71e59cf9c0e1cea0", size = 54003, upload-time = "2025-08-12T05:51:48.627Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/4f/a9/49940b9dc6d47027dc850c116d79b4155f15c08547d04db0f07121499347/wrapt-1.17.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:54a30837587c6ee3cd1a4d1c2ec5d24e77984d44e2f34547e2323ddb4e22eb77", size = 39025, upload-time = "2025-08-12T05:51:37.156Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/45/35/6a08de0f2c96dcdd7fe464d7420ddb9a7655a6561150e5fc4da9356aeaab/wrapt-1.17.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:16ecf15d6af39246fe33e507105d67e4b81d8f8d2c6598ff7e3ca1b8a37213f7", size = 39108, upload-time = "2025-08-12T05:51:58.425Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0c/37/6faf15cfa41bf1f3dba80cd3f5ccc6622dfccb660ab26ed79f0178c7497f/wrapt-1.17.3-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6fd1ad24dc235e4ab88cda009e19bf347aabb975e44fd5c2fb22a3f6e4141277", size = 88072, upload-time = "2025-08-12T05:52:37.53Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/78/f2/efe19ada4a38e4e15b6dff39c3e3f3f73f5decf901f66e6f72fe79623a06/wrapt-1.17.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ed61b7c2d49cee3c027372df5809a59d60cf1b6c2f81ee980a091f3afed6a2d", size = 88214, upload-time = "2025-08-12T05:52:15.886Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/40/90/ca86701e9de1622b16e09689fc24b76f69b06bb0150990f6f4e8b0eeb576/wrapt-1.17.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:423ed5420ad5f5529db9ce89eac09c8a2f97da18eb1c870237e84c5a5c2d60aa", size = 87105, upload-time = "2025-08-12T05:52:17.914Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/fd/e0/d10bd257c9a3e15cbf5523025252cc14d77468e8ed644aafb2d6f54cb95d/wrapt-1.17.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e01375f275f010fcbf7f643b4279896d04e571889b8a5b3f848423d91bf07050", size = 87766, upload-time = "2025-08-12T05:52:39.243Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e8/cf/7d848740203c7b4b27eb55dbfede11aca974a51c3d894f6cc4b865f42f58/wrapt-1.17.3-cp313-cp313-win32.whl", hash = "sha256:53e5e39ff71b3fc484df8a522c933ea2b7cdd0d5d15ae82e5b23fde87d44cbd8", size = 36711, upload-time = "2025-08-12T05:53:10.074Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/57/54/35a84d0a4d23ea675994104e667ceff49227ce473ba6a59ba2c84f250b74/wrapt-1.17.3-cp313-cp313-win_amd64.whl", hash = "sha256:1f0b2f40cf341ee8cc1a97d51ff50dddb9fcc73241b9143ec74b30fc4f44f6cb", size = 38885, upload-time = "2025-08-12T05:53:08.695Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/01/77/66e54407c59d7b02a3c4e0af3783168fff8e5d61def52cda8728439d86bc/wrapt-1.17.3-cp313-cp313-win_arm64.whl", hash = "sha256:7425ac3c54430f5fc5e7b6f41d41e704db073309acfc09305816bc6a0b26bb16", size = 36896, upload-time = "2025-08-12T05:52:55.34Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/02/a2/cd864b2a14f20d14f4c496fab97802001560f9f41554eef6df201cd7f76c/wrapt-1.17.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cf30f6e3c077c8e6a9a7809c94551203c8843e74ba0c960f4a98cd80d4665d39", size = 54132, upload-time = "2025-08-12T05:51:49.864Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d5/46/d011725b0c89e853dc44cceb738a307cde5d240d023d6d40a82d1b4e1182/wrapt-1.17.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:e228514a06843cae89621384cfe3a80418f3c04aadf8a3b14e46a7be704e4235", size = 39091, upload-time = "2025-08-12T05:51:38.935Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2e/9e/3ad852d77c35aae7ddebdbc3b6d35ec8013af7d7dddad0ad911f3d891dae/wrapt-1.17.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:5ea5eb3c0c071862997d6f3e02af1d055f381b1d25b286b9d6644b79db77657c", size = 39172, upload-time = "2025-08-12T05:51:59.365Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c3/f7/c983d2762bcce2326c317c26a6a1e7016f7eb039c27cdf5c4e30f4160f31/wrapt-1.17.3-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:281262213373b6d5e4bb4353bc36d1ba4084e6d6b5d242863721ef2bf2c2930b", size = 87163, upload-time = "2025-08-12T05:52:40.965Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e4/0f/f673f75d489c7f22d17fe0193e84b41540d962f75fce579cf6873167c29b/wrapt-1.17.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dc4a8d2b25efb6681ecacad42fca8859f88092d8732b170de6a5dddd80a1c8fa", size = 87963, upload-time = "2025-08-12T05:52:20.326Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/df/61/515ad6caca68995da2fac7a6af97faab8f78ebe3bf4f761e1b77efbc47b5/wrapt-1.17.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:373342dd05b1d07d752cecbec0c41817231f29f3a89aa8b8843f7b95992ed0c7", size = 86945, upload-time = "2025-08-12T05:52:21.581Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d3/bd/4e70162ce398462a467bc09e768bee112f1412e563620adc353de9055d33/wrapt-1.17.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d40770d7c0fd5cbed9d84b2c3f2e156431a12c9a37dc6284060fb4bec0b7ffd4", size = 86857, upload-time = "2025-08-12T05:52:43.043Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2b/b8/da8560695e9284810b8d3df8a19396a6e40e7518059584a1a394a2b35e0a/wrapt-1.17.3-cp314-cp314-win32.whl", hash = "sha256:fbd3c8319de8e1dc79d346929cd71d523622da527cca14e0c1d257e31c2b8b10", size = 37178, upload-time = "2025-08-12T05:53:12.605Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/db/c8/b71eeb192c440d67a5a0449aaee2310a1a1e8eca41676046f99ed2487e9f/wrapt-1.17.3-cp314-cp314-win_amd64.whl", hash = "sha256:e1a4120ae5705f673727d3253de3ed0e016f7cd78dc463db1b31e2463e1f3cf6", size = 39310, upload-time = "2025-08-12T05:53:11.106Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/45/20/2cda20fd4865fa40f86f6c46ed37a2a8356a7a2fde0773269311f2af56c7/wrapt-1.17.3-cp314-cp314-win_arm64.whl", hash = "sha256:507553480670cab08a800b9463bdb881b2edeed77dc677b0a5915e6106e91a58", size = 37266, upload-time = "2025-08-12T05:52:56.531Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/77/ed/dd5cf21aec36c80443c6f900449260b80e2a65cf963668eaef3b9accce36/wrapt-1.17.3-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:ed7c635ae45cfbc1a7371f708727bf74690daedc49b4dba310590ca0bd28aa8a", size = 56544, upload-time = "2025-08-12T05:51:51.109Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/8d/96/450c651cc753877ad100c7949ab4d2e2ecc4d97157e00fa8f45df682456a/wrapt-1.17.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:249f88ed15503f6492a71f01442abddd73856a0032ae860de6d75ca62eed8067", size = 40283, upload-time = "2025-08-12T05:51:39.912Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d1/86/2fcad95994d9b572db57632acb6f900695a648c3e063f2cd344b3f5c5a37/wrapt-1.17.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a03a38adec8066d5a37bea22f2ba6bbf39fcdefbe2d91419ab864c3fb515454", size = 40366, upload-time = "2025-08-12T05:52:00.693Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/64/0e/f4472f2fdde2d4617975144311f8800ef73677a159be7fe61fa50997d6c0/wrapt-1.17.3-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:5d4478d72eb61c36e5b446e375bbc49ed002430d17cdec3cecb36993398e1a9e", size = 108571, upload-time = "2025-08-12T05:52:44.521Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/cc/01/9b85a99996b0a97c8a17484684f206cbb6ba73c1ce6890ac668bcf3838fb/wrapt-1.17.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:223db574bb38637e8230eb14b185565023ab624474df94d2af18f1cdb625216f", size = 113094, upload-time = "2025-08-12T05:52:22.618Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/25/02/78926c1efddcc7b3aa0bc3d6b33a822f7d898059f7cd9ace8c8318e559ef/wrapt-1.17.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e405adefb53a435f01efa7ccdec012c016b5a1d3f35459990afc39b6be4d5056", size = 110659, upload-time = "2025-08-12T05:52:24.057Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/dc/ee/c414501ad518ac3e6fe184753632fe5e5ecacdcf0effc23f31c1e4f7bfcf/wrapt-1.17.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:88547535b787a6c9ce4086917b6e1d291aa8ed914fdd3a838b3539dc95c12804", size = 106946, upload-time = "2025-08-12T05:52:45.976Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/be/44/a1bd64b723d13bb151d6cc91b986146a1952385e0392a78567e12149c7b4/wrapt-1.17.3-cp314-cp314t-win32.whl", hash = "sha256:41b1d2bc74c2cac6f9074df52b2efbef2b30bdfe5f40cb78f8ca22963bc62977", size = 38717, upload-time = "2025-08-12T05:53:15.214Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/79/d9/7cfd5a312760ac4dd8bf0184a6ee9e43c33e47f3dadc303032ce012b8fa3/wrapt-1.17.3-cp314-cp314t-win_amd64.whl", hash = "sha256:73d496de46cd2cdbdbcce4ae4bcdb4afb6a11234a1df9c085249d55166b95116", size = 41334, upload-time = "2025-08-12T05:53:14.178Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/46/78/10ad9781128ed2f99dbc474f43283b13fea8ba58723e98844367531c18e9/wrapt-1.17.3-cp314-cp314t-win_arm64.whl", hash = "sha256:f38e60678850c42461d4202739f9bf1e3a737c7ad283638251e79cc49effb6b6", size = 38471, upload-time = "2025-08-12T05:52:57.784Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/1f/f6/a933bd70f98e9cf3e08167fc5cd7aaaca49147e48411c0bd5ae701bb2194/wrapt-1.17.3-py3-none-any.whl", hash = "sha256:7171ae35d2c33d326ac19dd8facb1e82e5fd04ef8c6c0e394d7af55a55051c22", size = 23591, upload-time = "2025-08-12T05:53:20.674Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
Reference in New Issue
Block a user