v0.0.5
memory
This commit is contained in:
parent
10a6a7051a
commit
434172755d
17
README.md
17
README.md
@ -1,6 +1,6 @@
|
|||||||
# LangChain Learning
|
# LangChain Learning
|
||||||
|
|
||||||
[](https://github.com/your-repo/langchain-learning)
|
[](https://github.com/your-repo/langchain-learning)
|
||||||
[](https://www.python.org/)
|
[](https://www.python.org/)
|
||||||
[](https://www.langchain.com/)
|
[](https://www.langchain.com/)
|
||||||
|
|
||||||
@ -8,11 +8,12 @@
|
|||||||
|
|
||||||
## 功能特性
|
## 功能特性
|
||||||
|
|
||||||
- **多 LLM 集成**:支持 OpenAI API、SiliconFlow 及 LangChain 抽象层
|
- **多 LLM 集成**:支持 OpenAI API、Silicon Flow 及 LangChain 抽象层
|
||||||
- **流式响应**:实时流式输出,带来更好的使用体验
|
- **流式响应**:实时流式输出,带来更好的使用体验
|
||||||
- **Prompt 工程**:多种 Prompt 模板构建方式
|
- **Prompt 工程**:多种 Prompt 模板构建方式
|
||||||
- **输出解析**:支持 JSON 等格式解析
|
- **输出解析**:支持 JSON 等格式解析
|
||||||
- **Token 用量追踪**:轻松监控 API 调用消耗
|
- **Token 用量追踪**:轻松监控 API 调用消耗
|
||||||
|
- **内存管理**:实现对话历史持久化(ConversationBufferMemory, SummaryMemory)
|
||||||
- **实战示例**:从基础到进阶的使用模式
|
- **实战示例**:从基础到进阶的使用模式
|
||||||
|
|
||||||
## 快速开始
|
## 快速开始
|
||||||
@ -23,6 +24,8 @@
|
|||||||
pip install langchain>=1.2.15 langchain-community>=0.4.1 langchain-siliconflow>=1.0.0 requests>=2.33.1
|
pip install langchain>=1.2.15 langchain-community>=0.4.1 langchain-siliconflow>=1.0.0 requests>=2.33.1
|
||||||
```
|
```
|
||||||
|
|
||||||
|
***注意:*** *如果需要完整的记忆功能和更高级的模型,你可能需要安装额外的库。*
|
||||||
|
|
||||||
### 2. 配置环境变量
|
### 2. 配置环境变量
|
||||||
|
|
||||||
在项目根目录创建 `.env` 文件:
|
在项目根目录创建 `.env` 文件:
|
||||||
@ -63,6 +66,13 @@ SILICONFLOW_BASE_URL=https://api.siliconflow.cn/v1
|
|||||||
|------|------|------|
|
|------|------|------|
|
||||||
| Token 追踪 | `python token/token_demo.py` | 使用 get_openai_callback 追踪 token 消耗 |
|
| Token 追踪 | `python token/token_demo.py` | 使用 get_openai_callback 追踪 token 消耗 |
|
||||||
|
|
||||||
|
**内存管理示例**
|
||||||
|
|
||||||
|
| 示例 | 命令 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| 基础记忆 | `python memory/memory_desc.py` | 演示不同类型的 Memory 对象。|
|
||||||
|
| 带内存聊天 | `python memory/with_memory_demo.py` | 在对话链中管理和利用聊天历史记录。 |
|
||||||
|
|
||||||
## 项目结构
|
## 项目结构
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -81,6 +91,9 @@ langchain-learning/
|
|||||||
│ └── json_parser_demo.py # JSON 输出解析示例
|
│ └── json_parser_demo.py # JSON 输出解析示例
|
||||||
├── token/
|
├── token/
|
||||||
│ └── token_demo.py # Token 用量追踪示例
|
│ └── token_demo.py # Token 用量追踪示例
|
||||||
|
├── memory/ # 记忆管理模块
|
||||||
|
│ ├── memory_desc.py # 演示 Memory 对象类型
|
||||||
|
│ └── with_memory_do.py # 演示使用带内存的聊天循环
|
||||||
├── main.py # 入口文件
|
├── main.py # 入口文件
|
||||||
├── pyproject.toml # 项目配置
|
├── pyproject.toml # 项目配置
|
||||||
└── README.md
|
└── README.md
|
||||||
|
|||||||
37
memory/memory_demo.py
Normal file
37
memory/memory_demo.py
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import logging
|
||||||
|
import os
|
||||||
|
|
||||||
|
import dotenv
|
||||||
|
from langchain.chains.llm import LLMChain
|
||||||
|
from langchain.memory import ConversationBufferMemory
|
||||||
|
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
|
||||||
|
from langchain_openai import ChatOpenAI
|
||||||
|
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.DEBUG,
|
||||||
|
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
||||||
|
)
|
||||||
|
dotenv.load_dotenv()
|
||||||
|
|
||||||
|
## 设置环境变量
|
||||||
|
os.environ['OPENAI_API_KEY'] = os.getenv("SILICONFLOW_API_KEY")
|
||||||
|
os.environ['OPENAI_BASE_URL'] = os.getenv("SILICONFLOW_BASE_URL")
|
||||||
|
|
||||||
|
# 默认的 'model_name': 'deepseek-ai/DeepSeek-V3.1',
|
||||||
|
llm = ChatOpenAI(model="Qwen/Qwen3-8B")
|
||||||
|
|
||||||
|
prompt = ChatPromptTemplate.from_messages([
|
||||||
|
("system", "你是一个万能的人工智能AI"),
|
||||||
|
MessagesPlaceholder(variable_name="history"),
|
||||||
|
("human", "问题:{question}")
|
||||||
|
])
|
||||||
|
|
||||||
|
## 创建 Memory 对象
|
||||||
|
memory = ConversationBufferMemory(return_messages=True)
|
||||||
|
|
||||||
|
chain = LLMChain(prompt=prompt, memory=memory, llm=llm)
|
||||||
|
res1 = chain.invoke({"question":"我是小明"})
|
||||||
|
print(res1)
|
||||||
|
print()
|
||||||
|
res2 = chain.invoke({"question":"我是谁?"})
|
||||||
|
print(res2)
|
||||||
43
memory/memory_desc.py
Normal file
43
memory/memory_desc.py
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
import dotenv
|
||||||
|
from langchain.memory import ConversationBufferMemory, ConversationTokenBufferMemory, ConversationSummaryMemory
|
||||||
|
from langchain_openai import ChatOpenAI
|
||||||
|
|
||||||
|
memory = ConversationBufferMemory()
|
||||||
|
memory.chat_memory.add_user_message("我叫小明")
|
||||||
|
memory.chat_memory.add_ai_message("噢,好的,你叫小明")
|
||||||
|
print(memory)
|
||||||
|
print(memory.memory_key)
|
||||||
|
print(memory.load_memory_variables({}))
|
||||||
|
print('---------')
|
||||||
|
|
||||||
|
memory2 = ConversationBufferMemory(memory_key="memory2")
|
||||||
|
memory2.chat_memory.add_user_message("我叫小明")
|
||||||
|
memory2.chat_memory.add_ai_message("噢,好的,你叫小明")
|
||||||
|
print(memory2)
|
||||||
|
print(memory2.memory_key)
|
||||||
|
print(memory2.load_memory_variables({}))
|
||||||
|
print('---------')
|
||||||
|
|
||||||
|
memory3 = ConversationBufferMemory(return_messages=True)
|
||||||
|
memory3.chat_memory.add_user_message("我叫小明")
|
||||||
|
memory3.chat_memory.add_ai_message("噢,好的,你叫小明")
|
||||||
|
print(memory3)
|
||||||
|
print(memory3.memory_key)
|
||||||
|
print(memory3.load_memory_variables({}))
|
||||||
|
print('---------')
|
||||||
|
dotenv.load_dotenv()
|
||||||
|
|
||||||
|
## 设置环境变量
|
||||||
|
os.environ['OPENAI_API_KEY'] = os.getenv("SILICONFLOW_API_KEY")
|
||||||
|
os.environ['OPENAI_BASE_URL'] = os.getenv("SILICONFLOW_BASE_URL")
|
||||||
|
|
||||||
|
# 默认的 'model_name': 'deepseek-ai/DeepSeek-V3.1',
|
||||||
|
llm = ChatOpenAI(model="moonshotai/Kimi-Dev-72B")
|
||||||
|
|
||||||
|
memory_test = ConversationSummaryMemory(llm=llm)
|
||||||
|
memory_test.save_context({"input": "我叫小明"}, {"output": "噢,好的,你叫小明"})
|
||||||
|
memory_test.save_context({"input": "那么你是谁呢"}, {"output": "我是一个无所不能的AI聊天助手,可以帮你解答任何问题。"})
|
||||||
|
print(memory_test.load_memory_variables({}))
|
||||||
|
# {'history': '\n\nThe human introduces themselves as xiaoming. The AI confirms the name and responds. The human then asks who the AI is. The AI introduces itself as an all-powerful AI chat assistant who can answer any questions.'}
|
||||||
43
memory/with_memory_demo.py
Normal file
43
memory/with_memory_demo.py
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import logging
|
||||||
|
|
||||||
|
from langchain_core.messages import AIMessage, HumanMessage
|
||||||
|
from langchain_core.output_parsers import JsonOutputParser
|
||||||
|
from langchain_core.prompts import PromptTemplate, ChatPromptTemplate
|
||||||
|
from langchain_openai import ChatOpenAI
|
||||||
|
import os
|
||||||
|
import dotenv
|
||||||
|
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.INFO,
|
||||||
|
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
||||||
|
)
|
||||||
|
dotenv.load_dotenv()
|
||||||
|
|
||||||
|
## 设置环境变量
|
||||||
|
os.environ['OPENAI_API_KEY'] = os.getenv("SILICONFLOW_API_KEY")
|
||||||
|
os.environ['OPENAI_BASE_URL'] = os.getenv("SILICONFLOW_BASE_URL")
|
||||||
|
|
||||||
|
# 默认的 'model_name': 'deepseek-ai/DeepSeek-V3.1',
|
||||||
|
llm = ChatOpenAI(model="Qwen/Qwen3-8B")
|
||||||
|
|
||||||
|
|
||||||
|
def chat_with_llm():
|
||||||
|
prompt_template = ChatPromptTemplate.from_messages([
|
||||||
|
("system", "你是一个人工智能助手,你是万能的"),
|
||||||
|
("human", "{question}")
|
||||||
|
])
|
||||||
|
while True:
|
||||||
|
chain = prompt_template | llm
|
||||||
|
user_input = input("请继续你的问题,如果没有问题了,输入 [quit] 结束会话:")
|
||||||
|
if user_input == "quit":
|
||||||
|
break
|
||||||
|
response = chain.invoke({"question": user_input})
|
||||||
|
print(f"AI:{response.content}")
|
||||||
|
|
||||||
|
## 将当前轮次的聊天内容(ai的回答和下一轮的问题)保存到prompt中,带入下一次聊天。
|
||||||
|
## 这是非标准做法。
|
||||||
|
prompt_template.messages.append(AIMessage(content=response.content))
|
||||||
|
prompt_template.messages.append(HumanMessage(content=user_input))
|
||||||
|
|
||||||
|
|
||||||
|
chat_with_llm()
|
||||||
56
memory/without_memory_demo.py
Normal file
56
memory/without_memory_demo.py
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
import logging
|
||||||
|
|
||||||
|
from rich.console import Console
|
||||||
|
from rich.panel import Panel
|
||||||
|
from rich.markdown import Markdown
|
||||||
|
from langchain_core.output_parsers import JsonOutputParser
|
||||||
|
from langchain_core.prompts import PromptTemplate, ChatPromptTemplate
|
||||||
|
from langchain_openai import ChatOpenAI
|
||||||
|
import os
|
||||||
|
import dotenv
|
||||||
|
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.WARNING,
|
||||||
|
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
||||||
|
)
|
||||||
|
dotenv.load_dotenv()
|
||||||
|
|
||||||
|
## 设置环境变量
|
||||||
|
os.environ['OPENAI_API_KEY'] = os.getenv("SILICONFLOW_API_KEY")
|
||||||
|
os.environ['OPENAI_BASE_URL'] = os.getenv("SILICONFLOW_BASE_URL")
|
||||||
|
|
||||||
|
# 默认的 'model_name': 'deepseek-ai/DeepSeek-V3.1',
|
||||||
|
llm = ChatOpenAI(model="deepseek-ai/DeepSeek-R1-0528-Qwen3-8B")
|
||||||
|
|
||||||
|
system_prompt = """
|
||||||
|
你是一个由 方仔仔 开发的先进人工智能助手 木鸡鸡。
|
||||||
|
你使用的模型是Pro 100.0 ProMaxUltra
|
||||||
|
你拥有128G上下文
|
||||||
|
【基本原则】
|
||||||
|
- 优先提供真实、准确、可靠的信息。
|
||||||
|
- 如果信息不确定,请明确说明,而不是猜测或编造。
|
||||||
|
- 对复杂问题进行结构化拆解,逐步解释。
|
||||||
|
|
||||||
|
【交互风格】
|
||||||
|
- 使用自然、专业、友好的语气。
|
||||||
|
- 优先使用分点、分段来提升可读性。
|
||||||
|
|
||||||
|
【安全与限制】
|
||||||
|
- 不提供违法、危险或有害行为的指导。
|
||||||
|
- 不泄露或推测个人隐私与敏感信息。
|
||||||
|
"""
|
||||||
|
|
||||||
|
def chat_with_llm():
|
||||||
|
prompt_template = ChatPromptTemplate.from_messages([
|
||||||
|
("system",system_prompt),
|
||||||
|
("human","{question}")
|
||||||
|
])
|
||||||
|
while True:
|
||||||
|
chain = prompt_template | llm
|
||||||
|
user_input = input()
|
||||||
|
if user_input == "quit":
|
||||||
|
break
|
||||||
|
response = chain.invoke({"question":user_input})
|
||||||
|
print(f"AI:{response.content} + /n + '-----------------'")
|
||||||
|
|
||||||
|
chat_with_llm()
|
||||||
82
memory/without_memory_demo_rich.py
Normal file
82
memory/without_memory_demo_rich.py
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import dotenv
|
||||||
|
|
||||||
|
from langchain_core.prompts import ChatPromptTemplate
|
||||||
|
from langchain_openai import ChatOpenAI
|
||||||
|
|
||||||
|
# 引入 rich 相关的库
|
||||||
|
from rich.console import Console
|
||||||
|
from rich.panel import Panel
|
||||||
|
from rich.markdown import Markdown
|
||||||
|
|
||||||
|
# 1. 消除 httpx 的烦人日志
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.INFO,
|
||||||
|
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
||||||
|
)
|
||||||
|
logging.getLogger("httpx").setLevel(logging.WARNING)
|
||||||
|
|
||||||
|
dotenv.load_dotenv()
|
||||||
|
os.environ['OPENAI_API_KEY'] = os.getenv("SILICONFLOW_API_KEY")
|
||||||
|
os.environ['OPENAI_BASE_URL'] = os.getenv("SILICONFLOW_BASE_URL")
|
||||||
|
|
||||||
|
llm = ChatOpenAI(model="deepseek-ai/DeepSeek-R1-0528-Qwen3-8B")
|
||||||
|
|
||||||
|
system_prompt = """
|
||||||
|
你是一个由 方仔仔 开发的先进人工智能助手 木鸡鸡。
|
||||||
|
你使用的模型是Pro 100.0 ProMaxUltra
|
||||||
|
你拥有128G上下文
|
||||||
|
【基本原则】
|
||||||
|
- 优先提供真实、准确、可靠的信息。
|
||||||
|
- 如果信息不确定,请明确说明,而不是猜测或编造。
|
||||||
|
- 对复杂问题进行结构化拆解,逐步解释。
|
||||||
|
|
||||||
|
【交互风格】
|
||||||
|
- 使用自然、专业、友好的语气。
|
||||||
|
- 优先使用分点、分段来提升可读性。
|
||||||
|
|
||||||
|
【安全与限制】
|
||||||
|
- 不提供违法、危险或有害行为的指导。
|
||||||
|
- 不泄露或推测个人隐私与敏感信息。
|
||||||
|
"""
|
||||||
|
|
||||||
|
# 初始化 rich 的控制台
|
||||||
|
console = Console()
|
||||||
|
|
||||||
|
def chat_with_llm():
|
||||||
|
prompt_template = ChatPromptTemplate.from_messages([
|
||||||
|
("system", system_prompt),
|
||||||
|
("human", "{question}")
|
||||||
|
])
|
||||||
|
|
||||||
|
# 【工程优化】:把 chain 的组装放在循环外面。
|
||||||
|
# 就像你不需要每次问问题前都重新组装一次大脑一样。
|
||||||
|
chain = prompt_template | llm
|
||||||
|
|
||||||
|
# 打印一个欢迎面板
|
||||||
|
console.print(Panel("✨ 欢迎使用 木鸡鸡 AI 助手!输入 'quit' 退出。", border_style="green"))
|
||||||
|
|
||||||
|
while True:
|
||||||
|
# 加点提示符,让输入更明显
|
||||||
|
user_input = input("\n👤 你: ")
|
||||||
|
|
||||||
|
if user_input.strip().lower() == "quit":
|
||||||
|
console.print("[dim]👋 再见![/dim]")
|
||||||
|
break
|
||||||
|
|
||||||
|
# 调用模型获取回复
|
||||||
|
response = chain.invoke({"question": user_input})
|
||||||
|
|
||||||
|
# 【核心魔法】:使用 rich 的 Panel 和 Markdown 渲染模型输出
|
||||||
|
# border_style 可以换颜色,比如 "cyan" (青色), "magenta" (洋红), "green" (绿色)
|
||||||
|
console.print(
|
||||||
|
Panel(
|
||||||
|
Markdown(response.content),
|
||||||
|
title="🤖",
|
||||||
|
border_style="cyan"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
chat_with_llm()
|
||||||
@ -9,4 +9,5 @@ dependencies = [
|
|||||||
"langchain-community>=0.4.1",
|
"langchain-community>=0.4.1",
|
||||||
"langchain-siliconflow>=1.0.0",
|
"langchain-siliconflow>=1.0.0",
|
||||||
"requests>=2.33.1",
|
"requests>=2.33.1",
|
||||||
|
"rich>=15.0.0",
|
||||||
]
|
]
|
||||||
|
|||||||
45
uv.lock
45
uv.lock
@ -691,6 +691,7 @@ dependencies = [
|
|||||||
{ name = "langchain-community" },
|
{ name = "langchain-community" },
|
||||||
{ name = "langchain-siliconflow" },
|
{ name = "langchain-siliconflow" },
|
||||||
{ name = "requests" },
|
{ name = "requests" },
|
||||||
|
{ name = "rich" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.metadata]
|
[package.metadata]
|
||||||
@ -699,6 +700,7 @@ requires-dist = [
|
|||||||
{ name = "langchain-community", specifier = ">=0.4.1" },
|
{ name = "langchain-community", specifier = ">=0.4.1" },
|
||||||
{ name = "langchain-siliconflow", specifier = ">=1.0.0" },
|
{ name = "langchain-siliconflow", specifier = ">=1.0.0" },
|
||||||
{ name = "requests", specifier = ">=2.33.1" },
|
{ name = "requests", specifier = ">=2.33.1" },
|
||||||
|
{ name = "rich", specifier = ">=15.0.0" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -817,6 +819,18 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/37/19/96250cf58070c5563446651b03bb76c2eb5afbf08e754840ab639532d8c6/langsmith-0.7.30-py3-none-any.whl", hash = "sha256:43dd9f8d290e4d406606d6cc0bd62f5d1050963f05fe0ab6ffe50acf41f2f55a", size = 372682, upload-time = "2026-04-09T21:12:00.481Z" },
|
{ url = "https://files.pythonhosted.org/packages/37/19/96250cf58070c5563446651b03bb76c2eb5afbf08e754840ab639532d8c6/langsmith-0.7.30-py3-none-any.whl", hash = "sha256:43dd9f8d290e4d406606d6cc0bd62f5d1050963f05fe0ab6ffe50acf41f2f55a", size = 372682, upload-time = "2026-04-09T21:12:00.481Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "markdown-it-py"
|
||||||
|
version = "4.0.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "mdurl" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "marshmallow"
|
name = "marshmallow"
|
||||||
version = "3.26.2"
|
version = "3.26.2"
|
||||||
@ -829,6 +843,15 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/be/2f/5108cb3ee4ba6501748c4908b908e55f42a5b66245b4cfe0c99326e1ef6e/marshmallow-3.26.2-py3-none-any.whl", hash = "sha256:013fa8a3c4c276c24d26d84ce934dc964e2aa794345a0f8c7e5a7191482c8a73", size = 50964, upload-time = "2025-12-22T06:53:51.801Z" },
|
{ url = "https://files.pythonhosted.org/packages/be/2f/5108cb3ee4ba6501748c4908b908e55f42a5b66245b4cfe0c99326e1ef6e/marshmallow-3.26.2-py3-none-any.whl", hash = "sha256:013fa8a3c4c276c24d26d84ce934dc964e2aa794345a0f8c7e5a7191482c8a73", size = 50964, upload-time = "2025-12-22T06:53:51.801Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mdurl"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "multidict"
|
name = "multidict"
|
||||||
version = "6.7.1"
|
version = "6.7.1"
|
||||||
@ -1403,6 +1426,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 = "pygments"
|
||||||
|
version = "2.20.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "python-dotenv"
|
name = "python-dotenv"
|
||||||
version = "1.2.2"
|
version = "1.2.2"
|
||||||
@ -1598,6 +1630,19 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06", size = 54481, upload-time = "2023-05-01T04:11:28.427Z" },
|
{ url = "https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06", size = 54481, upload-time = "2023-05-01T04:11:28.427Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rich"
|
||||||
|
version = "15.0.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "markdown-it-py" },
|
||||||
|
{ name = "pygments" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654, upload-time = "2026-04-12T08:24:02.83Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sniffio"
|
name = "sniffio"
|
||||||
version = "1.3.1"
|
version = "1.3.1"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user