coco-framework 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- coco/__init__.py +3 -0
- coco/agents/__init__.py +9 -0
- coco/agents/_subagent_transformer.py +307 -0
- coco/agents/factory.py +2164 -0
- coco/agents/middleware/__init__.py +100 -0
- coco/agents/middleware/_execution.py +385 -0
- coco/agents/middleware/_redaction.py +454 -0
- coco/agents/middleware/_retry.py +134 -0
- coco/agents/middleware/_trace_policy.py +61 -0
- coco/agents/middleware/context_editing.py +306 -0
- coco/agents/middleware/file_search.py +433 -0
- coco/agents/middleware/human_in_the_loop.py +680 -0
- coco/agents/middleware/internal_call_transformer.py +108 -0
- coco/agents/middleware/model_call_limit.py +267 -0
- coco/agents/middleware/model_fallback.py +417 -0
- coco/agents/middleware/model_retry.py +327 -0
- coco/agents/middleware/pii.py +878 -0
- coco/agents/middleware/provider_tool_search.py +307 -0
- coco/agents/middleware/shell_tool.py +949 -0
- coco/agents/middleware/summarization.py +910 -0
- coco/agents/middleware/todo.py +357 -0
- coco/agents/middleware/tool_call_limit.py +495 -0
- coco/agents/middleware/tool_emulator.py +251 -0
- coco/agents/middleware/tool_error.py +209 -0
- coco/agents/middleware/tool_retry.py +421 -0
- coco/agents/middleware/tool_selection.py +515 -0
- coco/agents/middleware/types.py +2201 -0
- coco/agents/structured_output.py +472 -0
- coco/chat_models/__init__.py +7 -0
- coco/chat_models/base.py +1082 -0
- coco/embeddings/__init__.py +18 -0
- coco/embeddings/base.py +279 -0
- coco/mcp/__init__.py +36 -0
- coco/mcp/adapter.py +245 -0
- coco/mcp/elicitation.py +394 -0
- coco/mcp/tools.py +307 -0
- coco/messages/__init__.py +73 -0
- coco/py.typed +0 -0
- coco/rate_limiters/__init__.py +13 -0
- coco/tools/__init__.py +22 -0
- coco/tools/tool_node.py +20 -0
- coco_anthropic/__init__.py +15 -0
- coco_anthropic/_client_utils.py +81 -0
- coco_anthropic/_compat.py +228 -0
- coco_anthropic/_sdk_compat.py +124 -0
- coco_anthropic/_version.py +3 -0
- coco_anthropic/chat_models.py +3349 -0
- coco_anthropic/data/__init__.py +1 -0
- coco_anthropic/data/_profiles.py +491 -0
- coco_anthropic/data/profile_augmentations.toml +69 -0
- coco_anthropic/experimental.py +140 -0
- coco_anthropic/llms.py +428 -0
- coco_anthropic/middleware/__init__.py +25 -0
- coco_anthropic/middleware/anthropic_tools.py +1197 -0
- coco_anthropic/middleware/bash.py +84 -0
- coco_anthropic/middleware/file_search.py +360 -0
- coco_anthropic/middleware/prompt_caching.py +276 -0
- coco_anthropic/output_parsers.py +93 -0
- coco_anthropic/py.typed +0 -0
- coco_core/__init__.py +20 -0
- coco_core/_api/__init__.py +87 -0
- coco_core/_api/beta_decorator.py +266 -0
- coco_core/_api/deprecation.py +637 -0
- coco_core/_api/internal.py +23 -0
- coco_core/_api/path.py +50 -0
- coco_core/_import_utils.py +41 -0
- coco_core/_protocol.py +625 -0
- coco_core/_security/__init__.py +36 -0
- coco_core/_security/_exceptions.py +9 -0
- coco_core/_security/_policy.py +313 -0
- coco_core/_security/_ssrf_protection.py +155 -0
- coco_core/_security/_transport.py +254 -0
- coco_core/agents.py +258 -0
- coco_core/caches.py +272 -0
- coco_core/callbacks/__init__.py +132 -0
- coco_core/callbacks/base.py +1229 -0
- coco_core/callbacks/file.py +266 -0
- coco_core/callbacks/manager.py +2826 -0
- coco_core/callbacks/stdout.py +123 -0
- coco_core/callbacks/streaming_stdout.py +154 -0
- coco_core/callbacks/usage.py +124 -0
- coco_core/chat_history.py +267 -0
- coco_core/chat_loaders.py +26 -0
- coco_core/chat_sessions.py +19 -0
- coco_core/cross_encoders.py +18 -0
- coco_core/document_loaders/__init__.py +36 -0
- coco_core/document_loaders/base.py +155 -0
- coco_core/document_loaders/blob_loaders.py +38 -0
- coco_core/documents/__init__.py +55 -0
- coco_core/documents/base.py +347 -0
- coco_core/documents/compressor.py +74 -0
- coco_core/documents/transformers.py +79 -0
- coco_core/embeddings/__init__.py +31 -0
- coco_core/embeddings/embeddings.py +78 -0
- coco_core/embeddings/fake.py +129 -0
- coco_core/env.py +22 -0
- coco_core/example_selectors/__init__.py +47 -0
- coco_core/example_selectors/base.py +60 -0
- coco_core/example_selectors/length_based.py +131 -0
- coco_core/example_selectors/semantic_similarity.py +366 -0
- coco_core/exceptions.py +166 -0
- coco_core/globals.py +72 -0
- coco_core/indexing/__init__.py +53 -0
- coco_core/indexing/api.py +954 -0
- coco_core/indexing/base.py +661 -0
- coco_core/indexing/in_memory.py +104 -0
- coco_core/language_models/__init__.py +116 -0
- coco_core/language_models/_compat_bridge.py +844 -0
- coco_core/language_models/_utils.py +343 -0
- coco_core/language_models/base.py +500 -0
- coco_core/language_models/chat_model_stream.py +1525 -0
- coco_core/language_models/chat_models.py +2748 -0
- coco_core/language_models/fake.py +137 -0
- coco_core/language_models/fake_chat_models.py +396 -0
- coco_core/language_models/llms.py +1569 -0
- coco_core/language_models/model_profile.py +183 -0
- coco_core/load/__init__.py +44 -0
- coco_core/load/_validation.py +191 -0
- coco_core/load/dump.py +120 -0
- coco_core/load/load.py +828 -0
- coco_core/load/mapping.py +1097 -0
- coco_core/load/serializable.py +406 -0
- coco_core/messages/__init__.py +198 -0
- coco_core/messages/ai.py +854 -0
- coco_core/messages/base.py +518 -0
- coco_core/messages/block_translators/__init__.py +112 -0
- coco_core/messages/block_translators/anthropic.py +534 -0
- coco_core/messages/block_translators/bedrock.py +108 -0
- coco_core/messages/block_translators/bedrock_converse.py +329 -0
- coco_core/messages/block_translators/coco_v0.py +303 -0
- coco_core/messages/block_translators/google_genai.py +610 -0
- coco_core/messages/block_translators/google_vertexai.py +21 -0
- coco_core/messages/block_translators/groq.py +157 -0
- coco_core/messages/block_translators/openai.py +1089 -0
- coco_core/messages/chat.py +64 -0
- coco_core/messages/content.py +1488 -0
- coco_core/messages/function.py +62 -0
- coco_core/messages/human.py +70 -0
- coco_core/messages/modifier.py +33 -0
- coco_core/messages/system.py +70 -0
- coco_core/messages/tool.py +418 -0
- coco_core/messages/utils.py +2442 -0
- coco_core/output_parsers/__init__.py +101 -0
- coco_core/output_parsers/base.py +361 -0
- coco_core/output_parsers/format_instructions.py +16 -0
- coco_core/output_parsers/json.py +139 -0
- coco_core/output_parsers/list.py +249 -0
- coco_core/output_parsers/openai_functions.py +324 -0
- coco_core/output_parsers/openai_tools.py +383 -0
- coco_core/output_parsers/pydantic.py +141 -0
- coco_core/output_parsers/string.py +63 -0
- coco_core/output_parsers/transform.py +175 -0
- coco_core/output_parsers/xml.py +301 -0
- coco_core/outputs/__init__.py +66 -0
- coco_core/outputs/chat_generation.py +147 -0
- coco_core/outputs/chat_result.py +39 -0
- coco_core/outputs/generation.py +80 -0
- coco_core/outputs/llm_result.py +112 -0
- coco_core/outputs/run_info.py +22 -0
- coco_core/prompt_values.py +161 -0
- coco_core/prompts/__init__.py +101 -0
- coco_core/prompts/base.py +508 -0
- coco_core/prompts/chat.py +1495 -0
- coco_core/prompts/dict.py +177 -0
- coco_core/prompts/few_shot.py +483 -0
- coco_core/prompts/few_shot_with_templates.py +239 -0
- coco_core/prompts/image.py +177 -0
- coco_core/prompts/loading.py +296 -0
- coco_core/prompts/message.py +97 -0
- coco_core/prompts/prompt.py +312 -0
- coco_core/prompts/string.py +399 -0
- coco_core/prompts/structured.py +214 -0
- coco_core/py.typed +0 -0
- coco_core/rate_limiters.py +254 -0
- coco_core/retrievers.py +328 -0
- coco_core/runnables/__init__.py +136 -0
- coco_core/runnables/base.py +6725 -0
- coco_core/runnables/branch.py +457 -0
- coco_core/runnables/config.py +712 -0
- coco_core/runnables/configurable.py +710 -0
- coco_core/runnables/fallbacks.py +663 -0
- coco_core/runnables/graph.py +741 -0
- coco_core/runnables/graph_ascii.py +366 -0
- coco_core/runnables/graph_mermaid.py +503 -0
- coco_core/runnables/graph_png.py +215 -0
- coco_core/runnables/history.py +631 -0
- coco_core/runnables/passthrough.py +849 -0
- coco_core/runnables/retry.py +379 -0
- coco_core/runnables/router.py +239 -0
- coco_core/runnables/schema.py +188 -0
- coco_core/runnables/utils.py +798 -0
- coco_core/stores.py +291 -0
- coco_core/structured_query.py +203 -0
- coco_core/sys_info.py +154 -0
- coco_core/tools/__init__.py +95 -0
- coco_core/tools/base.py +1948 -0
- coco_core/tools/convert.py +497 -0
- coco_core/tools/render.py +67 -0
- coco_core/tools/retriever.py +94 -0
- coco_core/tools/simple.py +208 -0
- coco_core/tools/structured.py +322 -0
- coco_core/tracers/__init__.py +47 -0
- coco_core/tracers/_compat.py +95 -0
- coco_core/tracers/_context.py +337 -0
- coco_core/tracers/_streaming.py +53 -0
- coco_core/tracers/base.py +955 -0
- coco_core/tracers/coco.py +279 -0
- coco_core/tracers/context.py +205 -0
- coco_core/tracers/core.py +766 -0
- coco_core/tracers/event_stream.py +1101 -0
- coco_core/tracers/log_stream.py +765 -0
- coco_core/tracers/memory_stream.py +200 -0
- coco_core/tracers/root_listeners.py +130 -0
- coco_core/tracers/run_collector.py +40 -0
- coco_core/tracers/schemas.py +14 -0
- coco_core/tracers/stdout.py +205 -0
- coco_core/utils/__init__.py +111 -0
- coco_core/utils/_gateway.py +274 -0
- coco_core/utils/_merge.py +218 -0
- coco_core/utils/aiter.py +357 -0
- coco_core/utils/env.py +86 -0
- coco_core/utils/formatting.py +80 -0
- coco_core/utils/function_calling.py +869 -0
- coco_core/utils/html.py +132 -0
- coco_core/utils/image.py +15 -0
- coco_core/utils/input.py +82 -0
- coco_core/utils/interactive_env.py +12 -0
- coco_core/utils/iter.py +229 -0
- coco_core/utils/json.py +230 -0
- coco_core/utils/json_schema.py +273 -0
- coco_core/utils/mustache.py +706 -0
- coco_core/utils/pydantic.py +631 -0
- coco_core/utils/strings.py +69 -0
- coco_core/utils/usage.py +61 -0
- coco_core/utils/utils.py +528 -0
- coco_core/utils/uuid.py +57 -0
- coco_core/vectorstores/__init__.py +53 -0
- coco_core/vectorstores/base.py +1111 -0
- coco_core/vectorstores/in_memory.py +546 -0
- coco_core/vectorstores/utils.py +163 -0
- coco_core/version.py +3 -0
- coco_framework-0.1.0.dist-info/METADATA +184 -0
- coco_framework-0.1.0.dist-info/RECORD +400 -0
- coco_framework-0.1.0.dist-info/WHEEL +4 -0
- coco_framework-0.1.0.dist-info/licenses/LICENSE +24 -0
- coco_framework-0.1.0.dist-info/licenses/NOTICE +15 -0
- coco_graph/_internal/__init__.py +4 -0
- coco_graph/_internal/_cache.py +31 -0
- coco_graph/_internal/_config.py +474 -0
- coco_graph/_internal/_constants.py +140 -0
- coco_graph/_internal/_fields.py +213 -0
- coco_graph/_internal/_future.py +220 -0
- coco_graph/_internal/_pydantic.py +275 -0
- coco_graph/_internal/_queue.py +124 -0
- coco_graph/_internal/_replay.py +90 -0
- coco_graph/_internal/_retry.py +29 -0
- coco_graph/_internal/_runnable.py +969 -0
- coco_graph/_internal/_scratchpad.py +19 -0
- coco_graph/_internal/_serde.py +253 -0
- coco_graph/_internal/_timeout.py +25 -0
- coco_graph/_internal/_typing.py +54 -0
- coco_graph/cache/base/__init__.py +48 -0
- coco_graph/cache/base/py.typed +0 -0
- coco_graph/cache/memory/__init__.py +73 -0
- coco_graph/cache/redis/__init__.py +144 -0
- coco_graph/cache/sqlite/__init__.py +120 -0
- coco_graph/callbacks.py +394 -0
- coco_graph/channels/__init__.py +29 -0
- coco_graph/channels/any_value.py +72 -0
- coco_graph/channels/base.py +121 -0
- coco_graph/channels/binop.py +155 -0
- coco_graph/channels/delta.py +202 -0
- coco_graph/channels/ephemeral_value.py +79 -0
- coco_graph/channels/last_value.py +151 -0
- coco_graph/channels/named_barrier_value.py +167 -0
- coco_graph/channels/topic.py +94 -0
- coco_graph/channels/untracked_value.py +73 -0
- coco_graph/checkpoint/base/__init__.py +861 -0
- coco_graph/checkpoint/base/id.py +109 -0
- coco_graph/checkpoint/base/py.typed +0 -0
- coco_graph/checkpoint/memory/__init__.py +698 -0
- coco_graph/checkpoint/memory/py.typed +0 -0
- coco_graph/checkpoint/postgres/__init__.py +602 -0
- coco_graph/checkpoint/postgres/_ainternal.py +23 -0
- coco_graph/checkpoint/postgres/_internal.py +21 -0
- coco_graph/checkpoint/postgres/aio.py +691 -0
- coco_graph/checkpoint/postgres/base.py +666 -0
- coco_graph/checkpoint/postgres/py.typed +0 -0
- coco_graph/checkpoint/postgres/shallow.py +967 -0
- coco_graph/checkpoint/serde/__init__.py +0 -0
- coco_graph/checkpoint/serde/_msgpack.py +97 -0
- coco_graph/checkpoint/serde/base.py +64 -0
- coco_graph/checkpoint/serde/encrypted.py +80 -0
- coco_graph/checkpoint/serde/event_hooks.py +52 -0
- coco_graph/checkpoint/serde/jsonplus.py +883 -0
- coco_graph/checkpoint/serde/py.typed +0 -0
- coco_graph/checkpoint/serde/types.py +68 -0
- coco_graph/checkpoint/sqlite/__init__.py +645 -0
- coco_graph/checkpoint/sqlite/_delta.py +172 -0
- coco_graph/checkpoint/sqlite/aio.py +738 -0
- coco_graph/checkpoint/sqlite/py.typed +0 -0
- coco_graph/checkpoint/sqlite/utils.py +116 -0
- coco_graph/config.py +196 -0
- coco_graph/constants.py +64 -0
- coco_graph/errors.py +241 -0
- coco_graph/func/__init__.py +620 -0
- coco_graph/graph/__init__.py +12 -0
- coco_graph/graph/_branch.py +225 -0
- coco_graph/graph/_node.py +103 -0
- coco_graph/graph/message.py +437 -0
- coco_graph/graph/state.py +1978 -0
- coco_graph/graph/ui.py +227 -0
- coco_graph/managed/__init__.py +3 -0
- coco_graph/managed/base.py +31 -0
- coco_graph/managed/is_last_step.py +24 -0
- coco_graph/prebuilt/__init__.py +23 -0
- coco_graph/prebuilt/_tool_call_stream.py +117 -0
- coco_graph/prebuilt/_tool_call_transformer.py +165 -0
- coco_graph/prebuilt/chat_agent_executor.py +1015 -0
- coco_graph/prebuilt/interrupt.py +105 -0
- coco_graph/prebuilt/py.typed +0 -0
- coco_graph/prebuilt/tool_node.py +2030 -0
- coco_graph/prebuilt/tool_validator.py +221 -0
- coco_graph/pregel/__init__.py +3 -0
- coco_graph/pregel/_algo.py +1460 -0
- coco_graph/pregel/_call.py +298 -0
- coco_graph/pregel/_checkpoint.py +331 -0
- coco_graph/pregel/_config.py +0 -0
- coco_graph/pregel/_draw.py +294 -0
- coco_graph/pregel/_executor.py +223 -0
- coco_graph/pregel/_io.py +174 -0
- coco_graph/pregel/_log.py +3 -0
- coco_graph/pregel/_loop.py +1988 -0
- coco_graph/pregel/_messages.py +461 -0
- coco_graph/pregel/_read.py +312 -0
- coco_graph/pregel/_retry.py +854 -0
- coco_graph/pregel/_runner.py +941 -0
- coco_graph/pregel/_tools.py +268 -0
- coco_graph/pregel/_utils.py +221 -0
- coco_graph/pregel/_validate.py +120 -0
- coco_graph/pregel/_write.py +192 -0
- coco_graph/pregel/debug.py +302 -0
- coco_graph/pregel/main.py +4364 -0
- coco_graph/pregel/protocol.py +288 -0
- coco_graph/pregel/types.py +38 -0
- coco_graph/py.typed +0 -0
- coco_graph/runtime.py +350 -0
- coco_graph/store/base/__init__.py +1322 -0
- coco_graph/store/base/batch.py +371 -0
- coco_graph/store/base/embed.py +436 -0
- coco_graph/store/base/py.typed +0 -0
- coco_graph/store/memory/__init__.py +592 -0
- coco_graph/store/memory/py.typed +0 -0
- coco_graph/store/postgres/__init__.py +4 -0
- coco_graph/store/postgres/aio.py +592 -0
- coco_graph/store/postgres/base.py +1480 -0
- coco_graph/store/postgres/py.typed +0 -0
- coco_graph/store/sqlite/__init__.py +4 -0
- coco_graph/store/sqlite/aio.py +632 -0
- coco_graph/store/sqlite/base.py +1514 -0
- coco_graph/stream/__init__.py +45 -0
- coco_graph/stream/_convert.py +32 -0
- coco_graph/stream/_mux.py +523 -0
- coco_graph/stream/_types.py +330 -0
- coco_graph/stream/run_stream.py +735 -0
- coco_graph/stream/stream_channel.py +341 -0
- coco_graph/stream/transformers.py +1039 -0
- coco_graph/types.py +1079 -0
- coco_graph/typing.py +48 -0
- coco_graph/utils/__init__.py +1 -0
- coco_graph/utils/config.py +4 -0
- coco_graph/utils/runnable.py +3 -0
- coco_graph/version.py +13 -0
- coco_graph/warnings.py +69 -0
- coco_openai/__init__.py +20 -0
- coco_openai/_compat.py +45 -0
- coco_openai/_version.py +3 -0
- coco_openai/chat_models/__init__.py +6 -0
- coco_openai/chat_models/_client_utils.py +684 -0
- coco_openai/chat_models/_compat.py +525 -0
- coco_openai/chat_models/azure.py +1227 -0
- coco_openai/chat_models/base.py +5654 -0
- coco_openai/chat_models/codex.py +557 -0
- coco_openai/chatgpt_oauth.py +1063 -0
- coco_openai/data/__init__.py +1 -0
- coco_openai/data/_profiles.py +1655 -0
- coco_openai/data/profile_augmentations.toml +127 -0
- coco_openai/embeddings/__init__.py +6 -0
- coco_openai/embeddings/azure.py +240 -0
- coco_openai/embeddings/base.py +820 -0
- coco_openai/llms/__init__.py +6 -0
- coco_openai/llms/azure.py +249 -0
- coco_openai/llms/base.py +919 -0
- coco_openai/middleware/__init__.py +11 -0
- coco_openai/middleware/openai_moderation.py +484 -0
- coco_openai/output_parsers/__init__.py +9 -0
- coco_openai/output_parsers/tools.py +9 -0
- coco_openai/py.typed +0 -0
- coco_openai/tools/__init__.py +5 -0
- coco_openai/tools/custom_tool.py +111 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# type: ignore
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import asyncio
|
|
5
|
+
import queue
|
|
6
|
+
import threading
|
|
7
|
+
import types
|
|
8
|
+
from collections import deque
|
|
9
|
+
from time import monotonic
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class AsyncQueue(asyncio.Queue):
|
|
13
|
+
"""Async unbounded FIFO queue with a wait() method.
|
|
14
|
+
|
|
15
|
+
Subclassed from asyncio.Queue, adding a wait() method."""
|
|
16
|
+
|
|
17
|
+
async def wait(self) -> None:
|
|
18
|
+
"""If queue is empty, wait until an item is available.
|
|
19
|
+
|
|
20
|
+
Copied from Queue.get(), removing the call to .get_nowait(),
|
|
21
|
+
ie. this doesn't consume the item, just waits for it.
|
|
22
|
+
"""
|
|
23
|
+
while self.empty():
|
|
24
|
+
getter = self._get_loop().create_future()
|
|
25
|
+
self._getters.append(getter)
|
|
26
|
+
try:
|
|
27
|
+
await getter
|
|
28
|
+
except BaseException:
|
|
29
|
+
getter.cancel() # Just in case getter is not done yet.
|
|
30
|
+
try:
|
|
31
|
+
# Clean self._getters from canceled getters.
|
|
32
|
+
self._getters.remove(getter)
|
|
33
|
+
except ValueError:
|
|
34
|
+
# The getter could be removed from self._getters by a
|
|
35
|
+
# previous put_nowait call.
|
|
36
|
+
pass
|
|
37
|
+
if not self.empty() and not getter.cancelled():
|
|
38
|
+
# We were woken up by put_nowait(), but can't take
|
|
39
|
+
# the call. Wake up the next in line.
|
|
40
|
+
self._wakeup_next(self._getters)
|
|
41
|
+
raise
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class Semaphore(threading.Semaphore):
|
|
45
|
+
"""Semaphore subclass with a wait() method."""
|
|
46
|
+
|
|
47
|
+
def wait(self, blocking: bool = True, timeout: float | None = None):
|
|
48
|
+
"""Block until the semaphore can be acquired, but don't acquire it."""
|
|
49
|
+
if not blocking and timeout is not None:
|
|
50
|
+
raise ValueError("can't specify timeout for non-blocking acquire")
|
|
51
|
+
rc = False
|
|
52
|
+
endtime = None
|
|
53
|
+
with self._cond:
|
|
54
|
+
while self._value == 0:
|
|
55
|
+
if not blocking:
|
|
56
|
+
break
|
|
57
|
+
if timeout is not None:
|
|
58
|
+
if endtime is None:
|
|
59
|
+
endtime = monotonic() + timeout
|
|
60
|
+
else:
|
|
61
|
+
timeout = endtime - monotonic()
|
|
62
|
+
if timeout <= 0:
|
|
63
|
+
break
|
|
64
|
+
self._cond.wait(timeout)
|
|
65
|
+
else:
|
|
66
|
+
rc = True
|
|
67
|
+
return rc
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class SyncQueue:
|
|
71
|
+
"""Unbounded FIFO queue with a wait() method.
|
|
72
|
+
Adapted from pure Python implementation of queue.SimpleQueue.
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
def __init__(self):
|
|
76
|
+
self._queue = deque()
|
|
77
|
+
self._count = Semaphore(0)
|
|
78
|
+
|
|
79
|
+
def put(self, item, block=True, timeout=None):
|
|
80
|
+
"""Put the item on the queue.
|
|
81
|
+
|
|
82
|
+
The optional 'block' and 'timeout' arguments are ignored, as this method
|
|
83
|
+
never blocks. They are provided for compatibility with the Queue class.
|
|
84
|
+
"""
|
|
85
|
+
self._queue.append(item)
|
|
86
|
+
self._count.release()
|
|
87
|
+
|
|
88
|
+
def get(self, block=False, timeout=None):
|
|
89
|
+
"""Remove and return an item from the queue.
|
|
90
|
+
|
|
91
|
+
If optional args 'block' is true and 'timeout' is None (the default),
|
|
92
|
+
block if necessary until an item is available. If 'timeout' is
|
|
93
|
+
a non-negative number, it blocks at most 'timeout' seconds and raises
|
|
94
|
+
the Empty exception if no item was available within that time.
|
|
95
|
+
Otherwise ('block' is false), return an item if one is immediately
|
|
96
|
+
available, else raise the Empty exception ('timeout' is ignored
|
|
97
|
+
in that case).
|
|
98
|
+
"""
|
|
99
|
+
if timeout is not None and timeout < 0:
|
|
100
|
+
raise ValueError("'timeout' must be a non-negative number")
|
|
101
|
+
if not self._count.acquire(block, timeout):
|
|
102
|
+
raise queue.Empty
|
|
103
|
+
try:
|
|
104
|
+
return self._queue.popleft()
|
|
105
|
+
except IndexError:
|
|
106
|
+
raise queue.Empty
|
|
107
|
+
|
|
108
|
+
def wait(self, block=True, timeout=None):
|
|
109
|
+
"""If queue is empty, wait until an item maybe is available,
|
|
110
|
+
but don't consume it.
|
|
111
|
+
"""
|
|
112
|
+
if timeout is not None and timeout < 0:
|
|
113
|
+
raise ValueError("'timeout' must be a non-negative number")
|
|
114
|
+
self._count.wait(block, timeout)
|
|
115
|
+
|
|
116
|
+
def empty(self):
|
|
117
|
+
"""Return True if the queue is empty, False otherwise (not reliable!)."""
|
|
118
|
+
return len(self._queue) == 0
|
|
119
|
+
|
|
120
|
+
def qsize(self):
|
|
121
|
+
"""Return the approximate size of the queue (not reliable!)."""
|
|
122
|
+
return len(self._queue)
|
|
123
|
+
|
|
124
|
+
__class_getitem__ = classmethod(types.GenericAlias)
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"""Replay state for subgraph checkpoint loading during time-travel."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
6
|
+
|
|
7
|
+
from coco_graph._internal._constants import NS_END
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from coco_core.runnables import RunnableConfig
|
|
11
|
+
from coco_graph.checkpoint.base import BaseCheckpointSaver, CheckpointTuple
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ReplayState:
|
|
15
|
+
"""Tracks which subgraphs have already loaded their pre-replay checkpoint.
|
|
16
|
+
|
|
17
|
+
During a parent replay, each subgraph's first invocation should restore the
|
|
18
|
+
checkpoint from before the replay point. Subsequent invocations of the same
|
|
19
|
+
subgraph (e.g. in a loop) should use normal checkpoint loading so they pick
|
|
20
|
+
up freshly created checkpoints.
|
|
21
|
+
|
|
22
|
+
The single `ReplayState` instance is shared by reference across all derived
|
|
23
|
+
configs within one parent execution.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
__slots__ = ("checkpoint_id", "_visited_ns")
|
|
27
|
+
|
|
28
|
+
def __init__(self, checkpoint_id: str) -> None:
|
|
29
|
+
self.checkpoint_id = checkpoint_id
|
|
30
|
+
# DO NOT CHANGE THIS VARIABLE – it may need to be rehydrated
|
|
31
|
+
# in other runtimes
|
|
32
|
+
self._visited_ns: set[str] = set()
|
|
33
|
+
|
|
34
|
+
def _is_first_visit(self, checkpoint_ns: str) -> bool:
|
|
35
|
+
"""Return True the first time a subgraph namespace is seen.
|
|
36
|
+
|
|
37
|
+
The task-id suffix is stripped so that the same logical subgraph
|
|
38
|
+
(e.g. ``"sub_node"``) is recognized across loop iterations even
|
|
39
|
+
though each iteration has a different task id.
|
|
40
|
+
"""
|
|
41
|
+
# "sub_node:task_id" -> "sub_node"
|
|
42
|
+
stable_ns = (
|
|
43
|
+
checkpoint_ns.rsplit(NS_END, 1)[0]
|
|
44
|
+
if NS_END in checkpoint_ns
|
|
45
|
+
else checkpoint_ns
|
|
46
|
+
)
|
|
47
|
+
if stable_ns in self._visited_ns:
|
|
48
|
+
return False
|
|
49
|
+
self._visited_ns.add(stable_ns)
|
|
50
|
+
return True
|
|
51
|
+
|
|
52
|
+
def get_checkpoint(
|
|
53
|
+
self,
|
|
54
|
+
checkpoint_ns: str,
|
|
55
|
+
checkpointer: BaseCheckpointSaver,
|
|
56
|
+
checkpoint_config: RunnableConfig,
|
|
57
|
+
) -> CheckpointTuple | None:
|
|
58
|
+
"""Load the right checkpoint for a subgraph during replay.
|
|
59
|
+
|
|
60
|
+
On the first call for a given subgraph namespace, returns the latest
|
|
61
|
+
checkpoint created *before* the replay point. On subsequent calls
|
|
62
|
+
(e.g. the same subgraph in a later loop iteration), falls back to
|
|
63
|
+
normal latest-checkpoint loading.
|
|
64
|
+
"""
|
|
65
|
+
if self._is_first_visit(checkpoint_ns):
|
|
66
|
+
for saved in checkpointer.list(
|
|
67
|
+
checkpoint_config,
|
|
68
|
+
before={"configurable": {"checkpoint_id": self.checkpoint_id}},
|
|
69
|
+
limit=1,
|
|
70
|
+
):
|
|
71
|
+
return saved
|
|
72
|
+
return None
|
|
73
|
+
return checkpointer.get_tuple(checkpoint_config)
|
|
74
|
+
|
|
75
|
+
async def aget_checkpoint(
|
|
76
|
+
self,
|
|
77
|
+
checkpoint_ns: str,
|
|
78
|
+
checkpointer: BaseCheckpointSaver,
|
|
79
|
+
checkpoint_config: RunnableConfig,
|
|
80
|
+
) -> CheckpointTuple | None:
|
|
81
|
+
"""Async version of `get_checkpoint`."""
|
|
82
|
+
if self._is_first_visit(checkpoint_ns):
|
|
83
|
+
async for saved in checkpointer.alist(
|
|
84
|
+
checkpoint_config,
|
|
85
|
+
before={"configurable": {"checkpoint_id": self.checkpoint_id}},
|
|
86
|
+
limit=1,
|
|
87
|
+
):
|
|
88
|
+
return saved
|
|
89
|
+
return None
|
|
90
|
+
return await checkpointer.aget_tuple(checkpoint_config)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
def default_retry_on(exc: Exception) -> bool:
|
|
2
|
+
import httpx
|
|
3
|
+
import requests
|
|
4
|
+
|
|
5
|
+
if isinstance(exc, ConnectionError):
|
|
6
|
+
return True
|
|
7
|
+
if isinstance(exc, httpx.HTTPStatusError):
|
|
8
|
+
return 500 <= exc.response.status_code < 600
|
|
9
|
+
if isinstance(exc, requests.HTTPError):
|
|
10
|
+
return 500 <= exc.response.status_code < 600 if exc.response else True
|
|
11
|
+
if isinstance(
|
|
12
|
+
exc,
|
|
13
|
+
(
|
|
14
|
+
ValueError,
|
|
15
|
+
TypeError,
|
|
16
|
+
ArithmeticError,
|
|
17
|
+
ImportError,
|
|
18
|
+
LookupError,
|
|
19
|
+
NameError,
|
|
20
|
+
SyntaxError,
|
|
21
|
+
RuntimeError,
|
|
22
|
+
ReferenceError,
|
|
23
|
+
StopIteration,
|
|
24
|
+
StopAsyncIteration,
|
|
25
|
+
OSError,
|
|
26
|
+
),
|
|
27
|
+
):
|
|
28
|
+
return False
|
|
29
|
+
return True
|