mirror of
https://github.com/hwchase17/langchain.git
synced 2026-07-01 14:47:02 +00:00
feat(openai): support apply_patch built-in tool (#37157)
[Docs](https://github.com/langchain-ai/docs/pull/4370) Fixes #37031 Adds support for OpenAI Responses API `apply_patch` built-in tool. This PR: - Adds `apply_patch` to the OpenAI well-known tools list so `bind_tools([{"type": "apply_patch"}])` works. - Preserves `apply_patch_call` and `apply_patch_call_output` items when converting OpenAI Responses API outputs into LangChain `AIMessage.content`. - Preserves the same item types in streaming `AIMessageChunk` conversion. - Supports round-trip input conversion for `apply_patch_call` and `apply_patch_call_output`. - Adds unit tests for core tool passthrough, non-streaming conversion, streaming conversion, and round-trip input conversion. ## Testing - `cd libs/core && uv run --group test pytest tests/unit_tests/utils/test_function_calling.py -k "apply_patch" -vv` - `cd libs/partners/openai && uv run --group test pytest tests/unit_tests/chat_models/test_base.py -k "apply_patch" -vv` - `cd libs/core && uv run --all-groups ruff check langchain_core/utils/function_calling.py tests/unit_tests/utils/test_function_calling.py` - `cd libs/partners/openai && uv run --all-groups ruff check langchain_openai/chat_models/base.py tests/unit_tests/chat_models/test_base.py` --------- Co-authored-by: Mason Daugherty <github@mdrxy.com> Co-authored-by: Mason Daugherty <mason@langchain.dev>
This commit is contained in:
@@ -508,6 +508,7 @@ _WellKnownOpenAITools = (
|
||||
"web_search_preview",
|
||||
"web_search",
|
||||
"tool_search",
|
||||
"apply_patch",
|
||||
"namespace",
|
||||
)
|
||||
|
||||
@@ -546,7 +547,7 @@ def convert_to_openai_tool(
|
||||
|
||||
Return OpenAI Responses API-style tools unchanged. This includes
|
||||
any dict with `"type"` in `"file_search"`, `"function"`,
|
||||
`"computer_use_preview"`, `"web_search_preview"`.
|
||||
`"computer_use_preview"`, `"web_search_preview"`, `"apply_patch"`.
|
||||
|
||||
!!! warning "Behavior changed in `langchain-core` 0.3.63"
|
||||
|
||||
|
||||
@@ -1245,6 +1245,15 @@ def test_convert_to_openai_function_json_schema_missing_title_includes_schema()
|
||||
convert_to_openai_function(schema_without_title)
|
||||
|
||||
|
||||
def test_convert_to_openai_tool_apply_patch_passthrough() -> None:
|
||||
"""Test apply_patch is passed through as an OpenAI built-in tool."""
|
||||
tool = {"type": "apply_patch"}
|
||||
|
||||
result = convert_to_openai_tool(tool)
|
||||
|
||||
assert result == tool
|
||||
|
||||
|
||||
def test_convert_to_openai_tool_computer_passthrough() -> None:
|
||||
"""Test that the 'computer' tool type is passed through unchanged."""
|
||||
computer_tool = {
|
||||
|
||||
2
libs/langchain_v1/uv.lock
generated
2
libs/langchain_v1/uv.lock
generated
@@ -2225,7 +2225,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "langchain-core"
|
||||
version = "1.4.1"
|
||||
version = "1.4.2"
|
||||
source = { editable = "../core" }
|
||||
dependencies = [
|
||||
{ name = "jsonpatch" },
|
||||
|
||||
@@ -105,6 +105,8 @@ def _convert_to_v03_ai_message(
|
||||
"image_generation_call",
|
||||
"tool_search_call",
|
||||
"tool_search_output",
|
||||
"apply_patch_call",
|
||||
"apply_patch_call_output",
|
||||
):
|
||||
# Store built-in tool calls in additional_kwargs
|
||||
if "tool_outputs" not in message.additional_kwargs:
|
||||
@@ -285,11 +287,11 @@ def _consolidate_calls(items: Iterable[dict[str, Any]]) -> Iterator[dict[str, An
|
||||
|
||||
try:
|
||||
nxt = next(items) # look-ahead one element
|
||||
except StopIteration: # no “result” - just yield the call back
|
||||
except StopIteration: # no "result" - just yield the call back
|
||||
yield current
|
||||
break
|
||||
|
||||
# If this really is the matching “result” - collapse
|
||||
# If this really is the matching "result" - collapse
|
||||
if nxt.get("type") == "server_tool_result" and nxt.get(
|
||||
"tool_call_id"
|
||||
) == current.get("id"):
|
||||
|
||||
@@ -192,6 +192,7 @@ WellKnownTools = (
|
||||
"mcp",
|
||||
"image_generation",
|
||||
"tool_search",
|
||||
"apply_patch",
|
||||
)
|
||||
|
||||
|
||||
@@ -4490,6 +4491,8 @@ def _construct_responses_api_input(messages: Sequence[BaseMessage]) -> list:
|
||||
"mcp_approval_request",
|
||||
"tool_search_call",
|
||||
"tool_search_output",
|
||||
"apply_patch_call",
|
||||
"apply_patch_call_output",
|
||||
):
|
||||
input_.append(_pop_index_and_sub_index(block))
|
||||
elif block_type == "image_generation_call":
|
||||
@@ -4535,7 +4538,11 @@ def _construct_responses_api_input(messages: Sequence[BaseMessage]) -> list:
|
||||
elif msg["role"] in ("user", "system", "developer"):
|
||||
if isinstance(msg["content"], list):
|
||||
new_blocks = []
|
||||
non_message_item_types = ("mcp_approval_response", "tool_search_output")
|
||||
non_message_item_types = (
|
||||
"mcp_approval_response",
|
||||
"tool_search_output",
|
||||
"apply_patch_call_output",
|
||||
)
|
||||
for block in msg["content"]:
|
||||
if block["type"] in ("text", "image_url", "file"):
|
||||
new_blocks.append(
|
||||
@@ -4704,6 +4711,8 @@ def _construct_lc_result_from_responses_api(
|
||||
"image_generation_call",
|
||||
"tool_search_call",
|
||||
"tool_search_output",
|
||||
"apply_patch_call",
|
||||
"apply_patch_call_output",
|
||||
):
|
||||
content_blocks.append(output.model_dump(exclude_none=True, mode="json"))
|
||||
|
||||
@@ -4958,6 +4967,8 @@ def _convert_responses_chunk_to_generation_chunk(
|
||||
"image_generation_call",
|
||||
"tool_search_call",
|
||||
"tool_search_output",
|
||||
"apply_patch_call",
|
||||
"apply_patch_call_output",
|
||||
):
|
||||
_advance(chunk.output_index)
|
||||
tool_output = chunk.item.model_dump(exclude_none=True, mode="json")
|
||||
|
||||
BIN
libs/partners/openai/tests/cassettes/test_apply_patch.yaml.gz
Normal file
BIN
libs/partners/openai/tests/cassettes/test_apply_patch.yaml.gz
Normal file
Binary file not shown.
@@ -200,6 +200,62 @@ async def test_web_search_async() -> None:
|
||||
assert tool_output["type"] == "web_search_call"
|
||||
|
||||
|
||||
@pytest.mark.default_cassette("test_apply_patch.yaml.gz")
|
||||
@pytest.mark.vcr
|
||||
def test_apply_patch() -> None:
|
||||
"""Test the apply_patch built-in tool end-to-end.
|
||||
|
||||
apply_patch is a client-executed tool: the model proposes a file operation
|
||||
via an `apply_patch_call` block, the client applies it, and the result is
|
||||
returned as an ``apply_patch_call_output`` block. Requires a model that
|
||||
supports the tool.
|
||||
"""
|
||||
prompt = "Create a new file named hello.txt containing the line: hello world"
|
||||
llm = ChatOpenAI(model="gpt-5.1", output_version="responses/v1")
|
||||
tool = {"type": "apply_patch"}
|
||||
|
||||
# Non-streaming: the model should emit an apply_patch_call block.
|
||||
response = llm.invoke(prompt, tools=[tool])
|
||||
assert isinstance(response, AIMessage)
|
||||
calls = [
|
||||
block
|
||||
for block in response.content
|
||||
if isinstance(block, dict) and block["type"] == "apply_patch_call"
|
||||
]
|
||||
assert len(calls) == 1
|
||||
call = calls[0]
|
||||
assert call["call_id"]
|
||||
assert call["operation"]["type"] in ("create_file", "update_file", "delete_file")
|
||||
|
||||
# Streaming: the apply_patch_call block survives chunk aggregation.
|
||||
aggregated: BaseMessageChunk | None = None
|
||||
for chunk in llm.stream(prompt, tools=[tool]):
|
||||
assert isinstance(chunk, AIMessageChunk)
|
||||
aggregated = chunk if aggregated is None else aggregated + chunk
|
||||
assert isinstance(aggregated, AIMessageChunk)
|
||||
assert any(
|
||||
isinstance(block, dict) and block["type"] == "apply_patch_call"
|
||||
for block in aggregated.content
|
||||
)
|
||||
|
||||
# Round-trip: return an apply_patch_call_output and continue the conversation.
|
||||
output_message = HumanMessage(
|
||||
content=[
|
||||
{
|
||||
"type": "apply_patch_call_output",
|
||||
"call_id": call["call_id"],
|
||||
"status": "completed",
|
||||
"output": f"Created {call['operation']['path']}",
|
||||
}
|
||||
]
|
||||
)
|
||||
follow_up = llm.invoke(
|
||||
[HumanMessage(prompt), response, output_message],
|
||||
tools=[tool],
|
||||
)
|
||||
assert isinstance(follow_up, AIMessage)
|
||||
|
||||
|
||||
@pytest.mark.default_cassette("test_function_calling.yaml.gz")
|
||||
@pytest.mark.vcr
|
||||
@pytest.mark.parametrize("output_version", ["v0", "responses/v1", "v1"])
|
||||
|
||||
@@ -35,8 +35,14 @@ from langchain_core.runnables import RunnableLambda
|
||||
from langchain_core.runnables.base import RunnableBinding, RunnableSequence
|
||||
from langchain_core.tracers.base import BaseTracer
|
||||
from langchain_core.tracers.schemas import Run
|
||||
from openai.types.responses import ResponseOutputMessage, ResponseReasoningItem
|
||||
from openai.types.responses import (
|
||||
ResponseApplyPatchToolCall,
|
||||
ResponseApplyPatchToolCallOutput,
|
||||
ResponseOutputMessage,
|
||||
ResponseReasoningItem,
|
||||
)
|
||||
from openai.types.responses.response import IncompleteDetails, Response
|
||||
from openai.types.responses.response_apply_patch_tool_call import OperationCreateFile
|
||||
from openai.types.responses.response_error import ResponseError
|
||||
from openai.types.responses.response_file_search_tool_call import (
|
||||
ResponseFileSearchToolCall,
|
||||
@@ -71,6 +77,7 @@ from langchain_openai.chat_models.base import (
|
||||
_construct_responses_api_input,
|
||||
_convert_dict_to_message,
|
||||
_convert_message_to_dict,
|
||||
_convert_responses_chunk_to_generation_chunk,
|
||||
_convert_to_openai_response_format,
|
||||
_create_usage_metadata,
|
||||
_create_usage_metadata_responses,
|
||||
@@ -1924,6 +1931,178 @@ def test__construct_lc_result_from_responses_api_no_usage_metadata() -> None:
|
||||
assert cast(AIMessage, result.generations[0].message).usage_metadata is None
|
||||
|
||||
|
||||
def test__construct_lc_result_from_responses_api_apply_patch_response() -> None:
|
||||
"""Test a response with apply_patch output."""
|
||||
response = Response(
|
||||
id="resp_123",
|
||||
created_at=1234567890,
|
||||
model="gpt-4o",
|
||||
object="response",
|
||||
parallel_tool_calls=True,
|
||||
tools=[],
|
||||
tool_choice="auto",
|
||||
output=[
|
||||
ResponseApplyPatchToolCall(
|
||||
id="apply_patch_123",
|
||||
type="apply_patch_call",
|
||||
call_id="call_123",
|
||||
operation=OperationCreateFile(
|
||||
type="create_file",
|
||||
path="hello.txt",
|
||||
diff="+hello\n",
|
||||
),
|
||||
status="completed",
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
result = _construct_lc_result_from_responses_api(response)
|
||||
|
||||
message = cast(AIMessage, result.generations[0].message)
|
||||
assert message.content == [
|
||||
{
|
||||
"type": "apply_patch_call",
|
||||
"id": "apply_patch_123",
|
||||
"call_id": "call_123",
|
||||
"operation": {
|
||||
"type": "create_file",
|
||||
"path": "hello.txt",
|
||||
"diff": "+hello\n",
|
||||
},
|
||||
"status": "completed",
|
||||
}
|
||||
]
|
||||
assert message.tool_calls == []
|
||||
assert message.invalid_tool_calls == []
|
||||
|
||||
|
||||
def test__construct_lc_result_from_responses_api_apply_patch_call_output() -> None:
|
||||
"""Test a response with apply_patch_call_output output."""
|
||||
response = Response(
|
||||
id="resp_123",
|
||||
created_at=1234567890,
|
||||
model="gpt-4o",
|
||||
object="response",
|
||||
parallel_tool_calls=True,
|
||||
tools=[],
|
||||
tool_choice="auto",
|
||||
output=[
|
||||
ResponseApplyPatchToolCallOutput(
|
||||
id="apply_patch_output_123",
|
||||
type="apply_patch_call_output",
|
||||
call_id="call_123",
|
||||
status="completed",
|
||||
output="Created hello.txt",
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
result = _construct_lc_result_from_responses_api(response)
|
||||
|
||||
message = result.generations[0].message
|
||||
assert message.content == [
|
||||
{
|
||||
"type": "apply_patch_call_output",
|
||||
"id": "apply_patch_output_123",
|
||||
"call_id": "call_123",
|
||||
"status": "completed",
|
||||
"output": "Created hello.txt",
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
def test__construct_responses_api_input_apply_patch_round_trip() -> None:
|
||||
"""Test apply_patch content blocks are preserved when sent back as input."""
|
||||
messages = [
|
||||
AIMessage(
|
||||
content=[
|
||||
{
|
||||
"type": "apply_patch_call",
|
||||
"call_id": "call_123",
|
||||
"operation": {
|
||||
"type": "create_file",
|
||||
"path": "hello.txt",
|
||||
"diff": "+hello\\n",
|
||||
},
|
||||
"status": "completed",
|
||||
}
|
||||
]
|
||||
),
|
||||
HumanMessage(
|
||||
content=[
|
||||
{
|
||||
"type": "apply_patch_call_output",
|
||||
"call_id": "call_123",
|
||||
"status": "completed",
|
||||
"output": "Created hello.txt",
|
||||
}
|
||||
]
|
||||
),
|
||||
]
|
||||
|
||||
result = _construct_responses_api_input(messages)
|
||||
|
||||
assert result == [
|
||||
{
|
||||
"type": "apply_patch_call",
|
||||
"call_id": "call_123",
|
||||
"operation": {
|
||||
"type": "create_file",
|
||||
"path": "hello.txt",
|
||||
"diff": "+hello\\n",
|
||||
},
|
||||
"status": "completed",
|
||||
},
|
||||
{
|
||||
"type": "apply_patch_call_output",
|
||||
"call_id": "call_123",
|
||||
"status": "completed",
|
||||
"output": "Created hello.txt",
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def test__convert_responses_chunk_to_generation_chunk_apply_patch_response() -> None:
|
||||
"""Test streamed apply_patch output item is preserved in message chunks."""
|
||||
chunk = MagicMock()
|
||||
chunk.type = "response.output_item.done"
|
||||
chunk.output_index = 0
|
||||
chunk.item = ResponseApplyPatchToolCall(
|
||||
id="apply_patch_123",
|
||||
type="apply_patch_call",
|
||||
call_id="call_123",
|
||||
operation=OperationCreateFile(
|
||||
type="create_file",
|
||||
path="hello.txt",
|
||||
diff="+hello\n",
|
||||
),
|
||||
status="completed",
|
||||
)
|
||||
|
||||
_, _, _, generation_chunk = _convert_responses_chunk_to_generation_chunk(
|
||||
chunk,
|
||||
current_index=-1,
|
||||
current_output_index=-1,
|
||||
current_sub_index=-1,
|
||||
)
|
||||
|
||||
assert generation_chunk is not None
|
||||
assert generation_chunk.message.content == [
|
||||
{
|
||||
"type": "apply_patch_call",
|
||||
"id": "apply_patch_123",
|
||||
"call_id": "call_123",
|
||||
"operation": {
|
||||
"type": "create_file",
|
||||
"path": "hello.txt",
|
||||
"diff": "+hello\n",
|
||||
},
|
||||
"status": "completed",
|
||||
"index": 0,
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
def test__construct_lc_result_from_responses_api_web_search_response() -> None:
|
||||
"""Test a response with web search output."""
|
||||
from openai.types.responses.response_function_web_search import (
|
||||
@@ -2747,6 +2926,57 @@ def test_compat_responses_v03() -> None:
|
||||
assert message_v03_output is not message_v03
|
||||
|
||||
|
||||
def test_compat_responses_v03_apply_patch_tool_outputs() -> None:
|
||||
message = AIMessage(
|
||||
content=[
|
||||
{"type": "text", "text": "Done.", "id": "msg_123"},
|
||||
{
|
||||
"type": "apply_patch_call",
|
||||
"id": "apply_patch_123",
|
||||
"call_id": "call_123",
|
||||
"operation": {
|
||||
"type": "create_file",
|
||||
"path": "hello.txt",
|
||||
"diff": "+hello\n",
|
||||
},
|
||||
"status": "completed",
|
||||
},
|
||||
{
|
||||
"type": "apply_patch_call_output",
|
||||
"id": "apply_patch_output_123",
|
||||
"call_id": "call_123",
|
||||
"status": "completed",
|
||||
"output": "Created hello.txt",
|
||||
},
|
||||
],
|
||||
id="resp_123",
|
||||
)
|
||||
|
||||
message_v03_output = _convert_to_v03_ai_message(message)
|
||||
|
||||
assert message_v03_output.content == [{"type": "text", "text": "Done."}]
|
||||
assert message_v03_output.additional_kwargs["tool_outputs"] == [
|
||||
{
|
||||
"type": "apply_patch_call",
|
||||
"id": "apply_patch_123",
|
||||
"call_id": "call_123",
|
||||
"operation": {
|
||||
"type": "create_file",
|
||||
"path": "hello.txt",
|
||||
"diff": "+hello\n",
|
||||
},
|
||||
"status": "completed",
|
||||
},
|
||||
{
|
||||
"type": "apply_patch_call_output",
|
||||
"id": "apply_patch_output_123",
|
||||
"call_id": "call_123",
|
||||
"status": "completed",
|
||||
"output": "Created hello.txt",
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("message_v1", "expected"),
|
||||
[
|
||||
@@ -3695,6 +3925,18 @@ def test_get_request_payload_responses_api_input_file_blocks_passthrough() -> No
|
||||
]
|
||||
|
||||
|
||||
def test_apply_patch_passthrough() -> None:
|
||||
"""Test that apply_patch dict is passed through as a built-in tool."""
|
||||
llm = ChatOpenAI(model="gpt-4o", api_key=SecretStr("test-api-key"))
|
||||
bound = llm.bind_tools([{"type": "apply_patch"}])
|
||||
payload = bound._get_request_payload( # type: ignore[attr-defined]
|
||||
"test",
|
||||
**bound.kwargs, # type: ignore[attr-defined]
|
||||
)
|
||||
assert {"type": "apply_patch"} in payload["tools"]
|
||||
assert "input" in payload
|
||||
|
||||
|
||||
def test_tool_search_passthrough() -> None:
|
||||
"""Test that tool_search dict is passed through as a built-in tool."""
|
||||
llm = ChatOpenAI(model="gpt-4o")
|
||||
|
||||
86
libs/partners/openai/uv.lock
generated
86
libs/partners/openai/uv.lock
generated
@@ -559,7 +559,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "langchain"
|
||||
version = "1.3.1"
|
||||
version = "1.3.4"
|
||||
source = { editable = "../../langchain_v1" }
|
||||
dependencies = [
|
||||
{ name = "langchain-core" },
|
||||
@@ -587,7 +587,7 @@ requires-dist = [
|
||||
{ name = "langchain-perplexity", marker = "extra == 'perplexity'" },
|
||||
{ name = "langchain-together", marker = "extra == 'together'" },
|
||||
{ name = "langchain-xai", marker = "extra == 'xai'" },
|
||||
{ name = "langgraph", specifier = ">=1.2.0,<1.3.0" },
|
||||
{ name = "langgraph", specifier = ">=1.2.4,<1.3.0" },
|
||||
{ name = "pydantic", specifier = ">=2.7.4,<3.0.0" },
|
||||
]
|
||||
provides-extras = ["community", "anthropic", "openai", "azure-ai", "google-vertexai", "google-genai", "fireworks", "ollama", "together", "mistralai", "huggingface", "groq", "aws", "baseten", "deepseek", "xai", "perplexity"]
|
||||
@@ -624,7 +624,7 @@ typing = [
|
||||
|
||||
[[package]]
|
||||
name = "langchain-core"
|
||||
version = "1.4.0"
|
||||
version = "1.4.2"
|
||||
source = { editable = "../../core" }
|
||||
dependencies = [
|
||||
{ name = "jsonpatch" },
|
||||
@@ -773,14 +773,14 @@ typing = [
|
||||
|
||||
[[package]]
|
||||
name = "langchain-protocol"
|
||||
version = "0.0.14"
|
||||
version = "0.0.16"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/05/bf/efb5e2ed832e4d6d45590e25a9e5191986b291b543bc6a807b48bee070b0/langchain_protocol-0.0.14.tar.gz", hash = "sha256:bc1e8553122e6ede310280462d5813023a172ff2785ccbbdec54d43f3a15e5f2", size = 5862, upload-time = "2026-04-29T16:40:18.657Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/36/e7/8300ba22d968653051fd06e3117d783872dddf3dcebdd6b1d386836eb43c/langchain_protocol-0.0.16.tar.gz", hash = "sha256:806c7cdd951b1c4f692fa40fce60821ff0f221d4360e27673ddf2c2b99c2b7ff", size = 5969, upload-time = "2026-05-28T23:05:11.121Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/c2/e9/06c47ecb2aff08f83dfa30058da3bf86be64862c19569043ed5331bbeecd/langchain_protocol-0.0.14-py3-none-any.whl", hash = "sha256:ffc35089779bd8ca217015180cef5e660fc3b074efdaa0f2e95df73583f1a047", size = 6984, upload-time = "2026-04-29T16:40:17.841Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1f/9c/06dfcc88d02a6364e8d864c421ddd3736305cb0a6c853f75c302c80fe17c/langchain_protocol-0.0.16-py3-none-any.whl", hash = "sha256:3658c142c5d0fb3a023a4be442ce4c15c6d626aab6135eb79a76dc64ad19c3c3", size = 7037, upload-time = "2026-05-28T23:05:10.163Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -830,7 +830,7 @@ typing = [
|
||||
|
||||
[[package]]
|
||||
name = "langgraph"
|
||||
version = "1.2.0"
|
||||
version = "1.2.4"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "langchain-core" },
|
||||
@@ -840,9 +840,9 @@ dependencies = [
|
||||
{ name = "pydantic" },
|
||||
{ name = "xxhash" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/58/61/d5d25e783035aa307d289b37e082258a6061c0fb4caa4a284f3bf1e87169/langgraph-1.2.0.tar.gz", hash = "sha256:4a9baaf62afc5d5f63144a50095140a34b9aa9b7cea695d25326d564775348e7", size = 690248, upload-time = "2026-05-12T03:46:39.164Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/1c/43/dac5a2621c1e57f8eb7f0703f6f6fe34a5caf62f8f0fb4d2bb395bb454ea/langgraph-1.2.4.tar.gz", hash = "sha256:5df076973a2d23efb13eceb279d1e5b46feebcbbeded0a86a2ef669abd9e4399", size = 720374, upload-time = "2026-06-02T17:07:37.347Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/f6/e8/e3304ac0015c2bdb04ad9785e4ed65c788855ce7857ce6104dd2f5d322db/langgraph-1.2.0-py3-none-any.whl", hash = "sha256:03fd5895a8d4b70db1ff63ebc3bacead29dd20cd794a8b1a483e7ec9018f7a65", size = 234262, upload-time = "2026-05-12T03:46:37.971Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/48/9e/31ca236104966d7bb14ea9e93cfd73350aea8c41008ddf057b65794ed10d/langgraph-1.2.4-py3-none-any.whl", hash = "sha256:ffe3e1e31dce28907640f82525858470f293506d2b272d07ea3b3ce97974b067", size = 245402, upload-time = "2026-06-02T17:07:35.977Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -873,15 +873,18 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "langgraph-sdk"
|
||||
version = "0.3.3"
|
||||
version = "0.4.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "httpx" },
|
||||
{ name = "langchain-core" },
|
||||
{ name = "langchain-protocol" },
|
||||
{ name = "orjson" },
|
||||
{ name = "websockets" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/c3/0f/ed0634c222eed48a31ba48eab6881f94ad690d65e44fe7ca838240a260c1/langgraph_sdk-0.3.3.tar.gz", hash = "sha256:c34c3dce3b6848755eb61f0c94369d1ba04aceeb1b76015db1ea7362c544fb26", size = 130589, upload-time = "2026-01-13T00:30:43.894Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b4/2b/bd8ac26d4e97f6df88ef05ce5b6a38945a3903e1025d926f4752aa88aa97/langgraph_sdk-0.4.2.tar.gz", hash = "sha256:b88f0f5f6328ac0680d6790614a905b2bcfa257f2276dba4e38f0e86db0aa738", size = 348327, upload-time = "2026-06-01T17:51:19.856Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/6e/be/4ad511bacfdd854afb12974f407cb30010dceb982dc20c55491867b34526/langgraph_sdk-0.3.3-py3-none-any.whl", hash = "sha256:a52ebaf09d91143e55378bb2d0b033ed98f57f48c9ad35c8f81493b88705fc7b", size = 67021, upload-time = "2026-01-13T00:30:42.264Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a0/05/aac507337cceae773c2cc9ab91eb6301963af7aeeb55b4217a00e15aff17/langgraph_sdk-0.4.2-py3-none-any.whl", hash = "sha256:75fa5096c1177ce39c847096a8fe3745ffd480ddb412995f836e9f5f884c43dd", size = 160521, upload-time = "2026-06-01T17:51:18.849Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2271,6 +2274,65 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/33/e8/e40370e6d74ddba47f002a32919d91310d6074130fe4e17dabcafc15cbf1/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", size = 79067, upload-time = "2024-11-01T14:07:11.845Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "websockets"
|
||||
version = "15.0.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
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 = [
|
||||
{ url = "https://files.pythonhosted.org/packages/1e/da/6462a9f510c0c49837bbc9345aca92d767a56c1fb2939e1579df1e1cdcf7/websockets-15.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d63efaa0cd96cf0c5fe4d581521d9fa87744540d4bc999ae6e08595a1014b45b", size = 175423, upload-time = "2025-03-05T20:01:35.363Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1c/9f/9d11c1a4eb046a9e106483b9ff69bce7ac880443f00e5ce64261b47b07e7/websockets-15.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ac60e3b188ec7574cb761b08d50fcedf9d77f1530352db4eef1707fe9dee7205", size = 173080, upload-time = "2025-03-05T20:01:37.304Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d5/4f/b462242432d93ea45f297b6179c7333dd0402b855a912a04e7fc61c0d71f/websockets-15.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5756779642579d902eed757b21b0164cd6fe338506a8083eb58af5c372e39d9a", size = 173329, upload-time = "2025-03-05T20:01:39.668Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6e/0c/6afa1f4644d7ed50284ac59cc70ef8abd44ccf7d45850d989ea7310538d0/websockets-15.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fdfe3e2a29e4db3659dbd5bbf04560cea53dd9610273917799f1cde46aa725e", size = 182312, upload-time = "2025-03-05T20:01:41.815Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/dd/d4/ffc8bd1350b229ca7a4db2a3e1c482cf87cea1baccd0ef3e72bc720caeec/websockets-15.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c2529b320eb9e35af0fa3016c187dffb84a3ecc572bcee7c3ce302bfeba52bf", size = 181319, upload-time = "2025-03-05T20:01:43.967Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/97/3a/5323a6bb94917af13bbb34009fac01e55c51dfde354f63692bf2533ffbc2/websockets-15.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac1e5c9054fe23226fb11e05a6e630837f074174c4c2f0fe442996112a6de4fb", size = 181631, upload-time = "2025-03-05T20:01:46.104Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a6/cc/1aeb0f7cee59ef065724041bb7ed667b6ab1eeffe5141696cccec2687b66/websockets-15.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5df592cd503496351d6dc14f7cdad49f268d8e618f80dce0cd5a36b93c3fc08d", size = 182016, upload-time = "2025-03-05T20:01:47.603Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/79/f9/c86f8f7af208e4161a7f7e02774e9d0a81c632ae76db2ff22549e1718a51/websockets-15.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0a34631031a8f05657e8e90903e656959234f3a04552259458aac0b0f9ae6fd9", size = 181426, upload-time = "2025-03-05T20:01:48.949Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c7/b9/828b0bc6753db905b91df6ae477c0b14a141090df64fb17f8a9d7e3516cf/websockets-15.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3d00075aa65772e7ce9e990cab3ff1de702aa09be3940d1dc88d5abf1ab8a09c", size = 181360, upload-time = "2025-03-05T20:01:50.938Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/89/fb/250f5533ec468ba6327055b7d98b9df056fb1ce623b8b6aaafb30b55d02e/websockets-15.0.1-cp310-cp310-win32.whl", hash = "sha256:1234d4ef35db82f5446dca8e35a7da7964d02c127b095e172e54397fb6a6c256", size = 176388, upload-time = "2025-03-05T20:01:52.213Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1c/46/aca7082012768bb98e5608f01658ff3ac8437e563eca41cf068bd5849a5e/websockets-15.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:39c1fec2c11dc8d89bba6b2bf1556af381611a173ac2b511cf7231622058af41", size = 176830, upload-time = "2025-03-05T20:01:53.922Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9f/32/18fcd5919c293a398db67443acd33fde142f283853076049824fc58e6f75/websockets-15.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:823c248b690b2fd9303ba00c4f66cd5e2d8c3ba4aa968b2779be9532a4dad431", size = 175423, upload-time = "2025-03-05T20:01:56.276Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/76/70/ba1ad96b07869275ef42e2ce21f07a5b0148936688c2baf7e4a1f60d5058/websockets-15.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678999709e68425ae2593acf2e3ebcbcf2e69885a5ee78f9eb80e6e371f1bf57", size = 173082, upload-time = "2025-03-05T20:01:57.563Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/86/f2/10b55821dd40eb696ce4704a87d57774696f9451108cff0d2824c97e0f97/websockets-15.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d50fd1ee42388dcfb2b3676132c78116490976f1300da28eb629272d5d93e905", size = 173330, upload-time = "2025-03-05T20:01:59.063Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a5/90/1c37ae8b8a113d3daf1065222b6af61cc44102da95388ac0018fcb7d93d9/websockets-15.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d99e5546bf73dbad5bf3547174cd6cb8ba7273062a23808ffea025ecb1cf8562", size = 182878, upload-time = "2025-03-05T20:02:00.305Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8e/8d/96e8e288b2a41dffafb78e8904ea7367ee4f891dafc2ab8d87e2124cb3d3/websockets-15.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66dd88c918e3287efc22409d426c8f729688d89a0c587c88971a0faa2c2f3792", size = 181883, upload-time = "2025-03-05T20:02:03.148Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/93/1f/5d6dbf551766308f6f50f8baf8e9860be6182911e8106da7a7f73785f4c4/websockets-15.0.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8dd8327c795b3e3f219760fa603dcae1dcc148172290a8ab15158cf85a953413", size = 182252, upload-time = "2025-03-05T20:02:05.29Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d4/78/2d4fed9123e6620cbf1706c0de8a1632e1a28e7774d94346d7de1bba2ca3/websockets-15.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8fdc51055e6ff4adeb88d58a11042ec9a5eae317a0a53d12c062c8a8865909e8", size = 182521, upload-time = "2025-03-05T20:02:07.458Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e7/3b/66d4c1b444dd1a9823c4a81f50231b921bab54eee2f69e70319b4e21f1ca/websockets-15.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:693f0192126df6c2327cce3baa7c06f2a117575e32ab2308f7f8216c29d9e2e3", size = 181958, upload-time = "2025-03-05T20:02:09.842Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/08/ff/e9eed2ee5fed6f76fdd6032ca5cd38c57ca9661430bb3d5fb2872dc8703c/websockets-15.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:54479983bd5fb469c38f2f5c7e3a24f9a4e70594cd68cd1fa6b9340dadaff7cf", size = 181918, upload-time = "2025-03-05T20:02:11.968Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d8/75/994634a49b7e12532be6a42103597b71098fd25900f7437d6055ed39930a/websockets-15.0.1-cp311-cp311-win32.whl", hash = "sha256:16b6c1b3e57799b9d38427dda63edcbe4926352c47cf88588c0be4ace18dac85", size = 176388, upload-time = "2025-03-05T20:02:13.32Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/98/93/e36c73f78400a65f5e236cd376713c34182e6663f6889cd45a4a04d8f203/websockets-15.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:27ccee0071a0e75d22cb35849b1db43f2ecd3e161041ac1ee9d2352ddf72f065", size = 176828, upload-time = "2025-03-05T20:02:14.585Z" },
|
||||
{ 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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/02/9e/d40f779fa16f74d3468357197af8d6ad07e7c5a27ea1ca74ceb38986f77a/websockets-15.0.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0c9e74d766f2818bb95f84c25be4dea09841ac0f734d1966f415e4edfc4ef1c3", size = 173109, upload-time = "2025-03-05T20:03:17.769Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bc/cd/5b887b8585a593073fd92f7c23ecd3985cd2c3175025a91b0d69b0551372/websockets-15.0.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1009ee0c7739c08a0cd59de430d6de452a55e42d6b522de7aa15e6f67db0b8e1", size = 173343, upload-time = "2025-03-05T20:03:19.094Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fe/ae/d34f7556890341e900a95acf4886833646306269f899d58ad62f588bf410/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76d1f20b1c7a2fa82367e04982e708723ba0e7b8d43aa643d3dcd404d74f1475", size = 174599, upload-time = "2025-03-05T20:03:21.1Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/71/e6/5fd43993a87db364ec60fc1d608273a1a465c0caba69176dd160e197ce42/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f29d80eb9a9263b8d109135351caf568cc3f80b9928bccde535c235de55c22d9", size = 174207, upload-time = "2025-03-05T20:03:23.221Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/fb/c492d6daa5ec067c2988ac80c61359ace5c4c674c532985ac5a123436cec/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b359ed09954d7c18bbc1680f380c7301f92c60bf924171629c5db97febb12f04", size = 174155, upload-time = "2025-03-05T20:03:25.321Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/68/a1/dcb68430b1d00b698ae7a7e0194433bce4f07ded185f0ee5fb21e2a2e91e/websockets-15.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:cad21560da69f4ce7658ca2cb83138fb4cf695a2ba3e475e0559e05991aa8122", size = 176884, upload-time = "2025-03-05T20:03:27.934Z" },
|
||||
{ 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" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wrapt"
|
||||
version = "1.17.3"
|
||||
|
||||
Reference in New Issue
Block a user