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,73 @@
|
|
|
1
|
+
"""Message and message content types.
|
|
2
|
+
|
|
3
|
+
Includes message types for different roles (e.g., human, AI, system), as well as types
|
|
4
|
+
for message content blocks (e.g., text, image, audio) and tool calls.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from coco_core.messages import (
|
|
8
|
+
AIMessage,
|
|
9
|
+
AIMessageChunk,
|
|
10
|
+
Annotation,
|
|
11
|
+
AnyMessage,
|
|
12
|
+
AudioContentBlock,
|
|
13
|
+
Citation,
|
|
14
|
+
ContentBlock,
|
|
15
|
+
DataContentBlock,
|
|
16
|
+
FileContentBlock,
|
|
17
|
+
HumanMessage,
|
|
18
|
+
ImageContentBlock,
|
|
19
|
+
InputTokenDetails,
|
|
20
|
+
InvalidToolCall,
|
|
21
|
+
MessageLikeRepresentation,
|
|
22
|
+
NonStandardAnnotation,
|
|
23
|
+
NonStandardContentBlock,
|
|
24
|
+
OutputTokenDetails,
|
|
25
|
+
PlainTextContentBlock,
|
|
26
|
+
ReasoningContentBlock,
|
|
27
|
+
RemoveMessage,
|
|
28
|
+
ServerToolCall,
|
|
29
|
+
ServerToolCallChunk,
|
|
30
|
+
ServerToolResult,
|
|
31
|
+
SystemMessage,
|
|
32
|
+
TextContentBlock,
|
|
33
|
+
ToolCall,
|
|
34
|
+
ToolCallChunk,
|
|
35
|
+
ToolMessage,
|
|
36
|
+
UsageMetadata,
|
|
37
|
+
VideoContentBlock,
|
|
38
|
+
trim_messages,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
__all__ = [
|
|
42
|
+
"AIMessage",
|
|
43
|
+
"AIMessageChunk",
|
|
44
|
+
"Annotation",
|
|
45
|
+
"AnyMessage",
|
|
46
|
+
"AudioContentBlock",
|
|
47
|
+
"Citation",
|
|
48
|
+
"ContentBlock",
|
|
49
|
+
"DataContentBlock",
|
|
50
|
+
"FileContentBlock",
|
|
51
|
+
"HumanMessage",
|
|
52
|
+
"ImageContentBlock",
|
|
53
|
+
"InputTokenDetails",
|
|
54
|
+
"InvalidToolCall",
|
|
55
|
+
"MessageLikeRepresentation",
|
|
56
|
+
"NonStandardAnnotation",
|
|
57
|
+
"NonStandardContentBlock",
|
|
58
|
+
"OutputTokenDetails",
|
|
59
|
+
"PlainTextContentBlock",
|
|
60
|
+
"ReasoningContentBlock",
|
|
61
|
+
"RemoveMessage",
|
|
62
|
+
"ServerToolCall",
|
|
63
|
+
"ServerToolCallChunk",
|
|
64
|
+
"ServerToolResult",
|
|
65
|
+
"SystemMessage",
|
|
66
|
+
"TextContentBlock",
|
|
67
|
+
"ToolCall",
|
|
68
|
+
"ToolCallChunk",
|
|
69
|
+
"ToolMessage",
|
|
70
|
+
"UsageMetadata",
|
|
71
|
+
"VideoContentBlock",
|
|
72
|
+
"trim_messages",
|
|
73
|
+
]
|
coco/py.typed
ADDED
|
File without changes
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""Base abstraction and in-memory implementation of rate limiters.
|
|
2
|
+
|
|
3
|
+
These rate limiters can be used to limit the rate of requests to an API.
|
|
4
|
+
|
|
5
|
+
The rate limiters can be used together with `BaseChatModel`.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from coco_core.rate_limiters import BaseRateLimiter, InMemoryRateLimiter
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"BaseRateLimiter",
|
|
12
|
+
"InMemoryRateLimiter",
|
|
13
|
+
]
|
coco/tools/__init__.py
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""Tools."""
|
|
2
|
+
|
|
3
|
+
from coco_core.tools import (
|
|
4
|
+
BaseTool,
|
|
5
|
+
InjectedToolArg,
|
|
6
|
+
InjectedToolCallId,
|
|
7
|
+
ToolException,
|
|
8
|
+
tool,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
from coco.tools.tool_node import InjectedState, InjectedStore, ToolRuntime
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"BaseTool",
|
|
15
|
+
"InjectedState",
|
|
16
|
+
"InjectedStore",
|
|
17
|
+
"InjectedToolArg",
|
|
18
|
+
"InjectedToolCallId",
|
|
19
|
+
"ToolException",
|
|
20
|
+
"ToolRuntime",
|
|
21
|
+
"tool",
|
|
22
|
+
]
|
coco/tools/tool_node.py
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""Utils file included for backwards compat imports."""
|
|
2
|
+
|
|
3
|
+
from coco_graph.prebuilt import InjectedState, InjectedStore, ToolRuntime
|
|
4
|
+
from coco_graph.prebuilt.tool_node import (
|
|
5
|
+
ToolCallRequest,
|
|
6
|
+
ToolCallWithContext,
|
|
7
|
+
ToolCallWrapper,
|
|
8
|
+
)
|
|
9
|
+
from coco_graph.prebuilt.tool_node import (
|
|
10
|
+
ToolNode as _ToolNode, # noqa: F401
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"InjectedState",
|
|
15
|
+
"InjectedStore",
|
|
16
|
+
"ToolCallRequest",
|
|
17
|
+
"ToolCallWithContext",
|
|
18
|
+
"ToolCallWrapper",
|
|
19
|
+
"ToolRuntime",
|
|
20
|
+
]
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""Claude (Anthropic) partner package for Coco."""
|
|
2
|
+
|
|
3
|
+
from coco_anthropic._version import __version__
|
|
4
|
+
from coco_anthropic.chat_models import (
|
|
5
|
+
ChatAnthropic,
|
|
6
|
+
convert_to_anthropic_tool,
|
|
7
|
+
)
|
|
8
|
+
from coco_anthropic.llms import AnthropicLLM
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"AnthropicLLM",
|
|
12
|
+
"ChatAnthropic",
|
|
13
|
+
"__version__",
|
|
14
|
+
"convert_to_anthropic_tool",
|
|
15
|
+
]
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""Helpers for creating Anthropic API clients.
|
|
2
|
+
|
|
3
|
+
This module allows for the caching of httpx clients to avoid creating new instances
|
|
4
|
+
for each instance of ChatAnthropic.
|
|
5
|
+
|
|
6
|
+
Logic is largely replicated from anthropic._base_client.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import asyncio
|
|
12
|
+
import os
|
|
13
|
+
from functools import lru_cache
|
|
14
|
+
from typing import Any
|
|
15
|
+
|
|
16
|
+
import anthropic
|
|
17
|
+
|
|
18
|
+
_NOT_GIVEN: Any = object()
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class _SyncHttpxClientWrapper(anthropic.DefaultHttpxClient):
|
|
22
|
+
"""Borrowed from anthropic._base_client."""
|
|
23
|
+
|
|
24
|
+
def __del__(self) -> None:
|
|
25
|
+
try:
|
|
26
|
+
if self.is_closed:
|
|
27
|
+
return
|
|
28
|
+
self.close()
|
|
29
|
+
except Exception: # noqa: S110
|
|
30
|
+
pass
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class _AsyncHttpxClientWrapper(anthropic.DefaultAsyncHttpxClient):
|
|
34
|
+
"""Borrowed from anthropic._base_client."""
|
|
35
|
+
|
|
36
|
+
def __del__(self) -> None:
|
|
37
|
+
try:
|
|
38
|
+
if self.is_closed:
|
|
39
|
+
return
|
|
40
|
+
# TODO(someday): support non asyncio runtimes here
|
|
41
|
+
asyncio.get_running_loop().create_task(self.aclose())
|
|
42
|
+
except Exception: # noqa: S110
|
|
43
|
+
pass
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@lru_cache
|
|
47
|
+
def _get_default_httpx_client(
|
|
48
|
+
*,
|
|
49
|
+
base_url: str | None,
|
|
50
|
+
timeout: Any = _NOT_GIVEN,
|
|
51
|
+
anthropic_proxy: str | None = None,
|
|
52
|
+
) -> _SyncHttpxClientWrapper:
|
|
53
|
+
kwargs: dict[str, Any] = {
|
|
54
|
+
"base_url": base_url
|
|
55
|
+
or os.environ.get("ANTHROPIC_BASE_URL")
|
|
56
|
+
or "https://api.anthropic.com",
|
|
57
|
+
}
|
|
58
|
+
if timeout is not _NOT_GIVEN:
|
|
59
|
+
kwargs["timeout"] = timeout
|
|
60
|
+
if anthropic_proxy is not None:
|
|
61
|
+
kwargs["proxy"] = anthropic_proxy
|
|
62
|
+
return _SyncHttpxClientWrapper(**kwargs)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@lru_cache
|
|
66
|
+
def _get_default_async_httpx_client(
|
|
67
|
+
*,
|
|
68
|
+
base_url: str | None,
|
|
69
|
+
timeout: Any = _NOT_GIVEN,
|
|
70
|
+
anthropic_proxy: str | None = None,
|
|
71
|
+
) -> _AsyncHttpxClientWrapper:
|
|
72
|
+
kwargs: dict[str, Any] = {
|
|
73
|
+
"base_url": base_url
|
|
74
|
+
or os.environ.get("ANTHROPIC_BASE_URL")
|
|
75
|
+
or "https://api.anthropic.com",
|
|
76
|
+
}
|
|
77
|
+
if timeout is not _NOT_GIVEN:
|
|
78
|
+
kwargs["timeout"] = timeout
|
|
79
|
+
if anthropic_proxy is not None:
|
|
80
|
+
kwargs["proxy"] = anthropic_proxy
|
|
81
|
+
return _AsyncHttpxClientWrapper(**kwargs)
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from typing import Any, cast
|
|
5
|
+
|
|
6
|
+
from coco_core.messages import content as types
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def _unwrap_non_standard(block: dict) -> dict:
|
|
10
|
+
"""Unwrap a provider-native dictionary from a standard content block."""
|
|
11
|
+
if block.get("type") == "non_standard" and isinstance(
|
|
12
|
+
value := block.get("value"),
|
|
13
|
+
dict,
|
|
14
|
+
):
|
|
15
|
+
return value
|
|
16
|
+
return block
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _convert_annotation_from_v1(annotation: types.Annotation) -> dict[str, Any]:
|
|
20
|
+
"""Convert Coco annotation format to Anthropic's native citation format."""
|
|
21
|
+
if annotation["type"] == "non_standard_annotation":
|
|
22
|
+
return annotation["value"]
|
|
23
|
+
|
|
24
|
+
if annotation["type"] == "citation":
|
|
25
|
+
if "url" in annotation:
|
|
26
|
+
# web_search_result_location
|
|
27
|
+
out: dict[str, Any] = {}
|
|
28
|
+
if cited_text := annotation.get("cited_text"):
|
|
29
|
+
out["cited_text"] = cited_text
|
|
30
|
+
if "encrypted_index" in annotation.get("extras", {}):
|
|
31
|
+
out["encrypted_index"] = annotation.get("extras", {})["encrypted_index"]
|
|
32
|
+
if "title" in annotation:
|
|
33
|
+
out["title"] = annotation["title"]
|
|
34
|
+
out["type"] = "web_search_result_location"
|
|
35
|
+
out["url"] = annotation.get("url")
|
|
36
|
+
|
|
37
|
+
for key, value in annotation.get("extras", {}).items():
|
|
38
|
+
if key not in out:
|
|
39
|
+
out[key] = value
|
|
40
|
+
|
|
41
|
+
return out
|
|
42
|
+
|
|
43
|
+
if "start_char_index" in annotation.get("extras", {}):
|
|
44
|
+
# char_location
|
|
45
|
+
out = {"type": "char_location"}
|
|
46
|
+
for field in ["cited_text"]:
|
|
47
|
+
if value := annotation.get(field):
|
|
48
|
+
out[field] = value
|
|
49
|
+
if title := annotation.get("title"):
|
|
50
|
+
out["document_title"] = title
|
|
51
|
+
|
|
52
|
+
for key, value in annotation.get("extras", {}).items():
|
|
53
|
+
out[key] = value
|
|
54
|
+
out = {k: out[k] for k in sorted(out)}
|
|
55
|
+
|
|
56
|
+
return out
|
|
57
|
+
|
|
58
|
+
if "search_result_index" in annotation.get("extras", {}):
|
|
59
|
+
# search_result_location
|
|
60
|
+
out = {"type": "search_result_location"}
|
|
61
|
+
for field in ["cited_text", "title"]:
|
|
62
|
+
if value := annotation.get(field):
|
|
63
|
+
out[field] = value
|
|
64
|
+
|
|
65
|
+
for key, value in annotation.get("extras", {}).items():
|
|
66
|
+
out[key] = value
|
|
67
|
+
|
|
68
|
+
return out
|
|
69
|
+
|
|
70
|
+
if "start_block_index" in annotation.get("extras", {}):
|
|
71
|
+
# content_block_location
|
|
72
|
+
out = {}
|
|
73
|
+
if cited_text := annotation.get("cited_text"):
|
|
74
|
+
out["cited_text"] = cited_text
|
|
75
|
+
if "document_index" in annotation.get("extras", {}):
|
|
76
|
+
out["document_index"] = annotation.get("extras", {})["document_index"]
|
|
77
|
+
if "title" in annotation:
|
|
78
|
+
out["document_title"] = annotation["title"]
|
|
79
|
+
|
|
80
|
+
for key, value in annotation.get("extras", {}).items():
|
|
81
|
+
if key not in out:
|
|
82
|
+
out[key] = value
|
|
83
|
+
|
|
84
|
+
out["type"] = "content_block_location"
|
|
85
|
+
return out
|
|
86
|
+
|
|
87
|
+
if "start_page_number" in annotation.get("extras", {}):
|
|
88
|
+
# page_location
|
|
89
|
+
out = {"type": "page_location"}
|
|
90
|
+
for field in ["cited_text"]:
|
|
91
|
+
if value := annotation.get(field):
|
|
92
|
+
out[field] = value
|
|
93
|
+
if title := annotation.get("title"):
|
|
94
|
+
out["document_title"] = title
|
|
95
|
+
|
|
96
|
+
for key, value in annotation.get("extras", {}).items():
|
|
97
|
+
out[key] = value
|
|
98
|
+
|
|
99
|
+
return out
|
|
100
|
+
|
|
101
|
+
return cast(dict[str, Any], annotation)
|
|
102
|
+
|
|
103
|
+
return cast(dict[str, Any], annotation)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def _convert_from_v1_to_anthropic(
|
|
107
|
+
content: list[types.ContentBlock],
|
|
108
|
+
tool_calls: list[types.ToolCall],
|
|
109
|
+
model_provider: str | None,
|
|
110
|
+
) -> list[dict[str, Any]]:
|
|
111
|
+
new_content: list = []
|
|
112
|
+
for block in content:
|
|
113
|
+
if block["type"] == "text":
|
|
114
|
+
if model_provider == "anthropic" and "annotations" in block:
|
|
115
|
+
new_block: dict[str, Any] = {"type": "text"}
|
|
116
|
+
new_block["citations"] = [
|
|
117
|
+
_convert_annotation_from_v1(a) for a in block["annotations"]
|
|
118
|
+
]
|
|
119
|
+
if "text" in block:
|
|
120
|
+
new_block["text"] = block["text"]
|
|
121
|
+
else:
|
|
122
|
+
new_block = {"text": block.get("text", ""), "type": "text"}
|
|
123
|
+
new_content.append(new_block)
|
|
124
|
+
|
|
125
|
+
elif block["type"] == "tool_call":
|
|
126
|
+
tool_use_block = {
|
|
127
|
+
"type": "tool_use",
|
|
128
|
+
"name": block.get("name", ""),
|
|
129
|
+
"input": block.get("args", {}),
|
|
130
|
+
"id": block.get("id", ""),
|
|
131
|
+
}
|
|
132
|
+
if "caller" in block.get("extras", {}):
|
|
133
|
+
tool_use_block["caller"] = block["extras"]["caller"]
|
|
134
|
+
new_content.append(tool_use_block)
|
|
135
|
+
|
|
136
|
+
elif block["type"] == "tool_call_chunk":
|
|
137
|
+
if isinstance(block["args"], str):
|
|
138
|
+
try:
|
|
139
|
+
input_ = json.loads(block["args"] or "{}")
|
|
140
|
+
except json.JSONDecodeError:
|
|
141
|
+
input_ = {}
|
|
142
|
+
else:
|
|
143
|
+
input_ = block.get("args") or {}
|
|
144
|
+
new_content.append(
|
|
145
|
+
{
|
|
146
|
+
"type": "tool_use",
|
|
147
|
+
"name": block.get("name", ""),
|
|
148
|
+
"input": input_,
|
|
149
|
+
"id": block.get("id", ""),
|
|
150
|
+
}
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
elif block["type"] == "invalid_tool_call":
|
|
154
|
+
tool_call_id = block.get("id")
|
|
155
|
+
tool_name = block.get("name")
|
|
156
|
+
if (
|
|
157
|
+
model_provider == "anthropic"
|
|
158
|
+
and isinstance(tool_call_id, str)
|
|
159
|
+
and tool_call_id
|
|
160
|
+
and isinstance(tool_name, str)
|
|
161
|
+
and tool_name
|
|
162
|
+
):
|
|
163
|
+
new_content.append(
|
|
164
|
+
{
|
|
165
|
+
"type": "tool_use",
|
|
166
|
+
"name": tool_name,
|
|
167
|
+
"input": {},
|
|
168
|
+
"id": tool_call_id,
|
|
169
|
+
}
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
elif block["type"] == "reasoning" and model_provider == "anthropic":
|
|
173
|
+
new_block = {}
|
|
174
|
+
if "reasoning" in block:
|
|
175
|
+
new_block["thinking"] = block["reasoning"]
|
|
176
|
+
new_block["type"] = "thinking"
|
|
177
|
+
if signature := block.get("extras", {}).get("signature"):
|
|
178
|
+
new_block["signature"] = signature
|
|
179
|
+
|
|
180
|
+
new_content.append(new_block)
|
|
181
|
+
|
|
182
|
+
elif block["type"] == "server_tool_call" and model_provider == "anthropic":
|
|
183
|
+
new_block = {}
|
|
184
|
+
if "id" in block:
|
|
185
|
+
new_block["id"] = block["id"]
|
|
186
|
+
new_block["input"] = block.get("args", {})
|
|
187
|
+
if partial_json := block.get("extras", {}).get("partial_json"):
|
|
188
|
+
new_block["input"] = {}
|
|
189
|
+
new_block["partial_json"] = partial_json
|
|
190
|
+
else:
|
|
191
|
+
pass
|
|
192
|
+
if block.get("name") == "code_interpreter":
|
|
193
|
+
new_block["name"] = "code_execution"
|
|
194
|
+
elif block.get("name") == "remote_mcp":
|
|
195
|
+
if "tool_name" in block.get("extras", {}):
|
|
196
|
+
new_block["name"] = block["extras"]["tool_name"]
|
|
197
|
+
if "server_name" in block.get("extras", {}):
|
|
198
|
+
new_block["server_name"] = block["extras"]["server_name"]
|
|
199
|
+
else:
|
|
200
|
+
new_block["name"] = block.get("name", "")
|
|
201
|
+
if block.get("name") == "remote_mcp":
|
|
202
|
+
new_block["type"] = "mcp_tool_use"
|
|
203
|
+
else:
|
|
204
|
+
new_block["type"] = "server_tool_use"
|
|
205
|
+
new_content.append(new_block)
|
|
206
|
+
|
|
207
|
+
elif block["type"] == "server_tool_result" and model_provider == "anthropic":
|
|
208
|
+
new_block = {}
|
|
209
|
+
if "output" in block:
|
|
210
|
+
new_block["content"] = block["output"]
|
|
211
|
+
server_tool_result_type = block.get("extras", {}).get("block_type", "")
|
|
212
|
+
if server_tool_result_type == "mcp_tool_result":
|
|
213
|
+
new_block["is_error"] = block.get("status") == "error"
|
|
214
|
+
if "tool_call_id" in block:
|
|
215
|
+
new_block["tool_use_id"] = block["tool_call_id"]
|
|
216
|
+
new_block["type"] = server_tool_result_type
|
|
217
|
+
new_content.append(new_block)
|
|
218
|
+
|
|
219
|
+
elif (
|
|
220
|
+
block["type"] == "non_standard"
|
|
221
|
+
and "value" in block
|
|
222
|
+
and model_provider == "anthropic"
|
|
223
|
+
):
|
|
224
|
+
new_content.append(block["value"])
|
|
225
|
+
else:
|
|
226
|
+
new_content.append(block)
|
|
227
|
+
|
|
228
|
+
return new_content
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"""Adapt to the installed `anthropic` SDK major version.
|
|
2
|
+
|
|
3
|
+
`trustcoco-anthropic` supports `anthropic` 0.x and 1.x. Two differences between
|
|
4
|
+
them reach this package, and each is resolved here by reading the answer off the
|
|
5
|
+
installed SDK rather than off its version string:
|
|
6
|
+
|
|
7
|
+
- **Sampling parameters.** `anthropic>=1` dropped `temperature`, `top_p` and
|
|
8
|
+
`top_k` from its message-creation methods, since current models do not use
|
|
9
|
+
them. The API still honors them for older models, so they are relocated to
|
|
10
|
+
`extra_body`, which the SDK merges into the request JSON as-is. The wire
|
|
11
|
+
payload is identical on both majors.
|
|
12
|
+
|
|
13
|
+
- **Raw responses.** `.with_raw_response` on the async client returns
|
|
14
|
+
`AsyncAPIResponse`, whose `parse()` is a coroutine; `anthropic<1` returned
|
|
15
|
+
`LegacyAPIResponse` with a synchronous `parse()`.
|
|
16
|
+
|
|
17
|
+
`anthropic>=1` also moved its HTTP layer from `httpx` to
|
|
18
|
+
[`httpx2`](https://github.com/pydantic/httpx2), but that does not surface here:
|
|
19
|
+
this package hands the SDK only primitives (a `base_url` string, a float
|
|
20
|
+
`timeout`, a `proxy` URL string) and subclasses `anthropic.DefaultHttpxClient`,
|
|
21
|
+
which already points at the right library, so no `httpx` type crosses the
|
|
22
|
+
boundary. Only the unit tests inject `httpx` objects, and they resolve the
|
|
23
|
+
matching library themselves in `tests/unit_tests/_httpx_compat.py`.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
from __future__ import annotations
|
|
27
|
+
|
|
28
|
+
import inspect
|
|
29
|
+
import logging
|
|
30
|
+
import re
|
|
31
|
+
from collections.abc import Mapping
|
|
32
|
+
from functools import lru_cache
|
|
33
|
+
from typing import Any
|
|
34
|
+
|
|
35
|
+
import anthropic
|
|
36
|
+
|
|
37
|
+
logger = logging.getLogger(__name__)
|
|
38
|
+
|
|
39
|
+
# Sampling parameters `anthropic>=1` no longer accepts as named arguments.
|
|
40
|
+
_SAMPLING_PARAMS = ("temperature", "top_p", "top_k")
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _sdk_major_version() -> int | None:
|
|
44
|
+
"""Major version of the installed `anthropic` SDK, or `None` if unreadable.
|
|
45
|
+
|
|
46
|
+
Tolerates tag-derived strings such as `v1.0.0`, which build tooling
|
|
47
|
+
sometimes leaves unstripped, by reading the first integer run.
|
|
48
|
+
"""
|
|
49
|
+
match = re.match(r"\D*(\d+)", str(getattr(anthropic, "__version__", "")))
|
|
50
|
+
return int(match.group(1)) if match else None
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@lru_cache(maxsize=1)
|
|
54
|
+
def _unsupported_sampling_params() -> frozenset[str]:
|
|
55
|
+
"""Sampling parameters the installed SDK's message methods no longer accept.
|
|
56
|
+
|
|
57
|
+
Derived from the signature of `Messages.create`, which `beta.messages` and
|
|
58
|
+
the async resources track. No client is instantiated, so this is safe to
|
|
59
|
+
call during payload construction without resolved credentials.
|
|
60
|
+
"""
|
|
61
|
+
try:
|
|
62
|
+
from anthropic.resources.messages import Messages
|
|
63
|
+
|
|
64
|
+
accepted = inspect.signature(Messages.create).parameters
|
|
65
|
+
except (ImportError, AttributeError, TypeError, ValueError):
|
|
66
|
+
# The SDK moved the resource or the signature is unreadable. Guess from
|
|
67
|
+
# the major version rather than failing: a wrong guess costs a TypeError
|
|
68
|
+
# on the first request, an exception here breaks every import.
|
|
69
|
+
major = _sdk_major_version()
|
|
70
|
+
logger.warning(
|
|
71
|
+
"Could not introspect the anthropic SDK's `Messages.create` "
|
|
72
|
+
"signature; falling back to its major version (%r) to decide "
|
|
73
|
+
"whether `temperature`/`top_p`/`top_k` are still accepted.",
|
|
74
|
+
major,
|
|
75
|
+
)
|
|
76
|
+
if major is not None and major >= 1:
|
|
77
|
+
return frozenset(_SAMPLING_PARAMS)
|
|
78
|
+
return frozenset()
|
|
79
|
+
|
|
80
|
+
return frozenset(p for p in _SAMPLING_PARAMS if p not in accepted)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _route_unsupported_sampling_params(payload: dict[str, Any]) -> dict[str, Any]:
|
|
84
|
+
"""Move sampling params the installed SDK rejects into `extra_body`.
|
|
85
|
+
|
|
86
|
+
A no-op on `anthropic<1`, where the message methods still accept them as
|
|
87
|
+
named arguments. Values the caller already set in `extra_body` win, since
|
|
88
|
+
that is the SDK's documented escape hatch and a deliberate choice.
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
payload: Request payload, modified in place.
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
The same payload.
|
|
95
|
+
"""
|
|
96
|
+
unsupported = _unsupported_sampling_params()
|
|
97
|
+
if not unsupported:
|
|
98
|
+
return payload
|
|
99
|
+
|
|
100
|
+
extra_body = payload.get("extra_body")
|
|
101
|
+
if extra_body is not None and not isinstance(extra_body, Mapping):
|
|
102
|
+
# A value the SDK would reject anyway. Leave the payload untouched
|
|
103
|
+
# rather than relocating params into something that cannot hold them.
|
|
104
|
+
return payload
|
|
105
|
+
|
|
106
|
+
relocated = {k: payload.pop(k) for k in unsupported if k in payload}
|
|
107
|
+
if not relocated:
|
|
108
|
+
return payload
|
|
109
|
+
|
|
110
|
+
payload["extra_body"] = {**relocated, **(extra_body or {})}
|
|
111
|
+
return payload
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
async def _aparse(raw_response: Any) -> Any:
|
|
115
|
+
"""Parse a raw SDK response from the async client.
|
|
116
|
+
|
|
117
|
+
`anthropic>=1` returns `AsyncAPIResponse`, whose `parse()` is a coroutine;
|
|
118
|
+
`anthropic<1` returned `LegacyAPIResponse`, whose `parse()` was
|
|
119
|
+
synchronous.
|
|
120
|
+
"""
|
|
121
|
+
parsed = raw_response.parse()
|
|
122
|
+
if inspect.isawaitable(parsed):
|
|
123
|
+
return await parsed
|
|
124
|
+
return parsed
|