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
coco_anthropic/llms.py
ADDED
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
"""Anthropic LLM wrapper. Chat models are in `chat_models.py`."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import re
|
|
6
|
+
from collections.abc import AsyncIterator, Callable, Iterator, Mapping
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
import anthropic
|
|
10
|
+
from coco_core._api.deprecation import deprecated
|
|
11
|
+
from coco_core.callbacks import (
|
|
12
|
+
AsyncCallbackManagerForLLMRun,
|
|
13
|
+
CallbackManagerForLLMRun,
|
|
14
|
+
)
|
|
15
|
+
from coco_core.language_models import BaseLanguageModel, LangSmithParams
|
|
16
|
+
from coco_core.language_models.llms import LLM
|
|
17
|
+
from coco_core.outputs import GenerationChunk
|
|
18
|
+
from coco_core.prompt_values import PromptValue
|
|
19
|
+
from coco_core.utils import get_pydantic_field_names
|
|
20
|
+
from coco_core.utils.utils import _build_model_kwargs, from_env, secret_from_env
|
|
21
|
+
from pydantic import ConfigDict, Field, SecretStr, model_validator
|
|
22
|
+
from typing_extensions import Self
|
|
23
|
+
|
|
24
|
+
from coco_anthropic._sdk_compat import _route_unsupported_sampling_params
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class _AnthropicCommon(BaseLanguageModel):
|
|
28
|
+
client: Any = None
|
|
29
|
+
|
|
30
|
+
async_client: Any = None
|
|
31
|
+
|
|
32
|
+
model: str = Field(default="claude-sonnet-4-5", alias="model_name")
|
|
33
|
+
"""Model name to use."""
|
|
34
|
+
|
|
35
|
+
max_tokens: int = Field(default=1024, alias="max_tokens_to_sample")
|
|
36
|
+
"""Denotes the number of tokens to predict per generation."""
|
|
37
|
+
|
|
38
|
+
temperature: float | None = None
|
|
39
|
+
"""A non-negative float that tunes the degree of randomness in generation."""
|
|
40
|
+
|
|
41
|
+
top_k: int | None = None
|
|
42
|
+
"""Number of most likely tokens to consider at each step."""
|
|
43
|
+
|
|
44
|
+
top_p: float | None = None
|
|
45
|
+
"""Total probability mass of tokens to consider at each step."""
|
|
46
|
+
|
|
47
|
+
streaming: bool = False
|
|
48
|
+
"""Whether to stream the results."""
|
|
49
|
+
|
|
50
|
+
default_request_timeout: float | None = None
|
|
51
|
+
"""Timeout for requests to Anthropic Completion API. Default is 600 seconds."""
|
|
52
|
+
|
|
53
|
+
max_retries: int = 2
|
|
54
|
+
"""Number of retries allowed for requests sent to the Anthropic Completion API."""
|
|
55
|
+
|
|
56
|
+
anthropic_api_url: str | None = Field(
|
|
57
|
+
alias="base_url",
|
|
58
|
+
default_factory=from_env(
|
|
59
|
+
"ANTHROPIC_API_URL",
|
|
60
|
+
default="https://api.anthropic.com",
|
|
61
|
+
),
|
|
62
|
+
)
|
|
63
|
+
"""Base URL for API requests. Only specify if using a proxy or service emulator.
|
|
64
|
+
|
|
65
|
+
If a value isn't passed in, will attempt to read the value from
|
|
66
|
+
`ANTHROPIC_API_URL`. If not set, the default value `https://api.anthropic.com`
|
|
67
|
+
will be used.
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
anthropic_api_key: SecretStr = Field(
|
|
71
|
+
alias="api_key",
|
|
72
|
+
default_factory=secret_from_env("ANTHROPIC_API_KEY", default=""),
|
|
73
|
+
)
|
|
74
|
+
"""Automatically read from env var `ANTHROPIC_API_KEY` if not provided."""
|
|
75
|
+
|
|
76
|
+
HUMAN_PROMPT: str | None = None
|
|
77
|
+
|
|
78
|
+
AI_PROMPT: str | None = None
|
|
79
|
+
|
|
80
|
+
count_tokens: Callable[[str], int] | None = None
|
|
81
|
+
|
|
82
|
+
model_kwargs: dict[str, Any] = Field(default_factory=dict)
|
|
83
|
+
|
|
84
|
+
@model_validator(mode="before")
|
|
85
|
+
@classmethod
|
|
86
|
+
def build_extra(cls, values: dict) -> Any:
|
|
87
|
+
all_required_field_names = get_pydantic_field_names(cls)
|
|
88
|
+
return _build_model_kwargs(values, all_required_field_names)
|
|
89
|
+
|
|
90
|
+
@model_validator(mode="after")
|
|
91
|
+
def validate_environment(self) -> Self:
|
|
92
|
+
"""Validate that api key and python package exists in environment."""
|
|
93
|
+
self.client = anthropic.Anthropic(
|
|
94
|
+
base_url=self.anthropic_api_url,
|
|
95
|
+
api_key=self.anthropic_api_key.get_secret_value(),
|
|
96
|
+
timeout=self.default_request_timeout,
|
|
97
|
+
max_retries=self.max_retries,
|
|
98
|
+
)
|
|
99
|
+
self.async_client = anthropic.AsyncAnthropic(
|
|
100
|
+
base_url=self.anthropic_api_url,
|
|
101
|
+
api_key=self.anthropic_api_key.get_secret_value(),
|
|
102
|
+
timeout=self.default_request_timeout,
|
|
103
|
+
max_retries=self.max_retries,
|
|
104
|
+
)
|
|
105
|
+
# Keep for backward compatibility but not used in Messages API
|
|
106
|
+
self.HUMAN_PROMPT = getattr(anthropic, "HUMAN_PROMPT", None)
|
|
107
|
+
self.AI_PROMPT = getattr(anthropic, "AI_PROMPT", None)
|
|
108
|
+
return self
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
def _default_params(self) -> Mapping[str, Any]:
|
|
112
|
+
"""Get the default parameters for calling Anthropic API."""
|
|
113
|
+
d = {
|
|
114
|
+
"max_tokens": self.max_tokens,
|
|
115
|
+
"model": self.model,
|
|
116
|
+
}
|
|
117
|
+
if self.temperature is not None:
|
|
118
|
+
d["temperature"] = self.temperature
|
|
119
|
+
if self.top_k is not None:
|
|
120
|
+
d["top_k"] = self.top_k
|
|
121
|
+
if self.top_p is not None:
|
|
122
|
+
d["top_p"] = self.top_p
|
|
123
|
+
return {**d, **self.model_kwargs}
|
|
124
|
+
|
|
125
|
+
@property
|
|
126
|
+
def _identifying_params(self) -> Mapping[str, Any]:
|
|
127
|
+
"""Get the identifying parameters."""
|
|
128
|
+
return {**self._default_params}
|
|
129
|
+
|
|
130
|
+
def _get_anthropic_stop(self, stop: list[str] | None = None) -> list[str]:
|
|
131
|
+
if stop is None:
|
|
132
|
+
stop = []
|
|
133
|
+
return stop
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
@deprecated(since="0.1.0", removal="2.0.0", alternative="ChatAnthropic")
|
|
137
|
+
class AnthropicLLM(LLM, _AnthropicCommon):
|
|
138
|
+
"""Anthropic text completion large language model (legacy LLM).
|
|
139
|
+
|
|
140
|
+
To use, you should have the environment variable `ANTHROPIC_API_KEY`
|
|
141
|
+
set with your API key, or pass it as a named parameter to the constructor.
|
|
142
|
+
|
|
143
|
+
Example:
|
|
144
|
+
```python
|
|
145
|
+
from coco_anthropic import AnthropicLLM
|
|
146
|
+
|
|
147
|
+
model = AnthropicLLM(model="claude-sonnet-4-5")
|
|
148
|
+
```
|
|
149
|
+
"""
|
|
150
|
+
|
|
151
|
+
model_config = ConfigDict(
|
|
152
|
+
populate_by_name=True,
|
|
153
|
+
arbitrary_types_allowed=True,
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
@property
|
|
157
|
+
def _llm_type(self) -> str:
|
|
158
|
+
"""Return type of llm."""
|
|
159
|
+
return "anthropic-llm"
|
|
160
|
+
|
|
161
|
+
@property
|
|
162
|
+
def lc_secrets(self) -> dict[str, str]:
|
|
163
|
+
"""Return a mapping of secret keys to environment variables."""
|
|
164
|
+
return {"anthropic_api_key": "ANTHROPIC_API_KEY"}
|
|
165
|
+
|
|
166
|
+
@classmethod
|
|
167
|
+
def is_lc_serializable(cls) -> bool:
|
|
168
|
+
"""Whether this class can be serialized by coco."""
|
|
169
|
+
return True
|
|
170
|
+
|
|
171
|
+
@property
|
|
172
|
+
def _identifying_params(self) -> dict[str, Any]:
|
|
173
|
+
"""Get the identifying parameters."""
|
|
174
|
+
return {
|
|
175
|
+
"model": self.model,
|
|
176
|
+
"max_tokens": self.max_tokens,
|
|
177
|
+
"temperature": self.temperature,
|
|
178
|
+
"top_k": self.top_k,
|
|
179
|
+
"top_p": self.top_p,
|
|
180
|
+
"model_kwargs": self.model_kwargs,
|
|
181
|
+
"streaming": self.streaming,
|
|
182
|
+
"default_request_timeout": self.default_request_timeout,
|
|
183
|
+
"max_retries": self.max_retries,
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
def _get_ls_params(
|
|
187
|
+
self,
|
|
188
|
+
stop: list[str] | None = None,
|
|
189
|
+
**kwargs: Any,
|
|
190
|
+
) -> LangSmithParams:
|
|
191
|
+
"""Get standard params for tracing."""
|
|
192
|
+
params = super()._get_ls_params(stop=stop, **kwargs)
|
|
193
|
+
identifying_params = self._identifying_params
|
|
194
|
+
if max_tokens := kwargs.get(
|
|
195
|
+
"max_tokens",
|
|
196
|
+
identifying_params.get("max_tokens"),
|
|
197
|
+
):
|
|
198
|
+
params["ls_max_tokens"] = max_tokens
|
|
199
|
+
return params
|
|
200
|
+
|
|
201
|
+
def _format_messages(self, prompt: str) -> list[dict[str, str]]:
|
|
202
|
+
"""Convert prompt to Messages API format."""
|
|
203
|
+
messages = []
|
|
204
|
+
|
|
205
|
+
# Handle legacy prompts that might have HUMAN_PROMPT/AI_PROMPT markers
|
|
206
|
+
if self.HUMAN_PROMPT and self.HUMAN_PROMPT in prompt:
|
|
207
|
+
# Split on human/assistant turns
|
|
208
|
+
parts = prompt.split(self.HUMAN_PROMPT)
|
|
209
|
+
|
|
210
|
+
for _, part in enumerate(parts):
|
|
211
|
+
if not part.strip():
|
|
212
|
+
continue
|
|
213
|
+
|
|
214
|
+
if self.AI_PROMPT and self.AI_PROMPT in part:
|
|
215
|
+
# Split human and assistant parts
|
|
216
|
+
human_part, assistant_part = part.split(self.AI_PROMPT, 1)
|
|
217
|
+
if human_part.strip():
|
|
218
|
+
messages.append({"role": "user", "content": human_part.strip()})
|
|
219
|
+
if assistant_part.strip():
|
|
220
|
+
messages.append(
|
|
221
|
+
{"role": "assistant", "content": assistant_part.strip()}
|
|
222
|
+
)
|
|
223
|
+
# Just human content
|
|
224
|
+
elif part.strip():
|
|
225
|
+
messages.append({"role": "user", "content": part.strip()})
|
|
226
|
+
else:
|
|
227
|
+
# Handle modern format or plain text
|
|
228
|
+
# Clean prompt for Messages API
|
|
229
|
+
content = re.sub(r"^\n*Human:\s*", "", prompt)
|
|
230
|
+
content = re.sub(r"\n*Assistant:\s*.*$", "", content)
|
|
231
|
+
if content.strip():
|
|
232
|
+
messages.append({"role": "user", "content": content.strip()})
|
|
233
|
+
|
|
234
|
+
# Ensure we have at least one message
|
|
235
|
+
if not messages:
|
|
236
|
+
messages = [{"role": "user", "content": prompt.strip() or "Hello"}]
|
|
237
|
+
|
|
238
|
+
return messages
|
|
239
|
+
|
|
240
|
+
def _call(
|
|
241
|
+
self,
|
|
242
|
+
prompt: str,
|
|
243
|
+
stop: list[str] | None = None,
|
|
244
|
+
run_manager: CallbackManagerForLLMRun | None = None,
|
|
245
|
+
**kwargs: Any,
|
|
246
|
+
) -> str:
|
|
247
|
+
r"""Call out to Anthropic's completion endpoint.
|
|
248
|
+
|
|
249
|
+
Args:
|
|
250
|
+
prompt: The prompt to pass into the model.
|
|
251
|
+
stop: Optional list of stop words to use when generating.
|
|
252
|
+
run_manager: Optional callback manager for LLM run.
|
|
253
|
+
kwargs: Additional keyword arguments to pass to the model.
|
|
254
|
+
|
|
255
|
+
Returns:
|
|
256
|
+
The string generated by the model.
|
|
257
|
+
|
|
258
|
+
Example:
|
|
259
|
+
```python
|
|
260
|
+
prompt = "What are the biggest risks facing humanity?"
|
|
261
|
+
prompt = f"\n\nHuman: {prompt}\n\nAssistant:"
|
|
262
|
+
response = model.invoke(prompt)
|
|
263
|
+
```
|
|
264
|
+
"""
|
|
265
|
+
if self.streaming:
|
|
266
|
+
completion = ""
|
|
267
|
+
for chunk in self._stream(
|
|
268
|
+
prompt=prompt,
|
|
269
|
+
stop=stop,
|
|
270
|
+
run_manager=run_manager,
|
|
271
|
+
**kwargs,
|
|
272
|
+
):
|
|
273
|
+
completion += chunk.text
|
|
274
|
+
return completion
|
|
275
|
+
|
|
276
|
+
stop = self._get_anthropic_stop(stop)
|
|
277
|
+
params = {**self._default_params, **kwargs}
|
|
278
|
+
|
|
279
|
+
# Remove parameters not supported by Messages API
|
|
280
|
+
params = {k: v for k, v in params.items() if k != "max_tokens_to_sample"}
|
|
281
|
+
params = _route_unsupported_sampling_params(params)
|
|
282
|
+
|
|
283
|
+
response = self.client.messages.create(
|
|
284
|
+
messages=self._format_messages(prompt),
|
|
285
|
+
stop_sequences=stop if stop else None,
|
|
286
|
+
**params,
|
|
287
|
+
)
|
|
288
|
+
return response.content[0].text
|
|
289
|
+
|
|
290
|
+
def convert_prompt(self, prompt: PromptValue) -> str:
|
|
291
|
+
"""Convert a `PromptValue` to a string."""
|
|
292
|
+
return prompt.to_string()
|
|
293
|
+
|
|
294
|
+
async def _acall(
|
|
295
|
+
self,
|
|
296
|
+
prompt: str,
|
|
297
|
+
stop: list[str] | None = None,
|
|
298
|
+
run_manager: AsyncCallbackManagerForLLMRun | None = None,
|
|
299
|
+
**kwargs: Any,
|
|
300
|
+
) -> str:
|
|
301
|
+
"""Call out to Anthropic's completion endpoint asynchronously."""
|
|
302
|
+
if self.streaming:
|
|
303
|
+
completion = ""
|
|
304
|
+
async for chunk in self._astream(
|
|
305
|
+
prompt=prompt,
|
|
306
|
+
stop=stop,
|
|
307
|
+
run_manager=run_manager,
|
|
308
|
+
**kwargs,
|
|
309
|
+
):
|
|
310
|
+
completion += chunk.text
|
|
311
|
+
return completion
|
|
312
|
+
|
|
313
|
+
stop = self._get_anthropic_stop(stop)
|
|
314
|
+
params = {**self._default_params, **kwargs}
|
|
315
|
+
|
|
316
|
+
# Remove parameters not supported by Messages API
|
|
317
|
+
params = {k: v for k, v in params.items() if k != "max_tokens_to_sample"}
|
|
318
|
+
params = _route_unsupported_sampling_params(params)
|
|
319
|
+
|
|
320
|
+
response = await self.async_client.messages.create(
|
|
321
|
+
messages=self._format_messages(prompt),
|
|
322
|
+
stop_sequences=stop if stop else None,
|
|
323
|
+
**params,
|
|
324
|
+
)
|
|
325
|
+
return response.content[0].text
|
|
326
|
+
|
|
327
|
+
def _stream(
|
|
328
|
+
self,
|
|
329
|
+
prompt: str,
|
|
330
|
+
stop: list[str] | None = None,
|
|
331
|
+
run_manager: CallbackManagerForLLMRun | None = None,
|
|
332
|
+
**kwargs: Any,
|
|
333
|
+
) -> Iterator[GenerationChunk]:
|
|
334
|
+
r"""Call Anthropic completion_stream and return the resulting generator.
|
|
335
|
+
|
|
336
|
+
Args:
|
|
337
|
+
prompt: The prompt to pass into the model.
|
|
338
|
+
stop: Optional list of stop words to use when generating.
|
|
339
|
+
run_manager: Optional callback manager for LLM run.
|
|
340
|
+
kwargs: Additional keyword arguments to pass to the model.
|
|
341
|
+
|
|
342
|
+
Returns:
|
|
343
|
+
A generator representing the stream of tokens from Anthropic.
|
|
344
|
+
|
|
345
|
+
Example:
|
|
346
|
+
```python
|
|
347
|
+
prompt = "Write a poem about a stream."
|
|
348
|
+
prompt = f"\n\nHuman: {prompt}\n\nAssistant:"
|
|
349
|
+
generator = anthropic.stream(prompt)
|
|
350
|
+
for token in generator:
|
|
351
|
+
yield token
|
|
352
|
+
```
|
|
353
|
+
"""
|
|
354
|
+
stop = self._get_anthropic_stop(stop)
|
|
355
|
+
params = {**self._default_params, **kwargs}
|
|
356
|
+
|
|
357
|
+
# Remove parameters not supported by Messages API
|
|
358
|
+
params = {k: v for k, v in params.items() if k != "max_tokens_to_sample"}
|
|
359
|
+
params = _route_unsupported_sampling_params(params)
|
|
360
|
+
|
|
361
|
+
with self.client.messages.stream(
|
|
362
|
+
messages=self._format_messages(prompt),
|
|
363
|
+
stop_sequences=stop if stop else None,
|
|
364
|
+
**params,
|
|
365
|
+
) as stream:
|
|
366
|
+
for event in stream:
|
|
367
|
+
if event.type == "content_block_delta" and hasattr(event.delta, "text"):
|
|
368
|
+
chunk = GenerationChunk(text=event.delta.text)
|
|
369
|
+
if run_manager:
|
|
370
|
+
run_manager.on_llm_new_token(chunk.text, chunk=chunk)
|
|
371
|
+
yield chunk
|
|
372
|
+
|
|
373
|
+
async def _astream(
|
|
374
|
+
self,
|
|
375
|
+
prompt: str,
|
|
376
|
+
stop: list[str] | None = None,
|
|
377
|
+
run_manager: AsyncCallbackManagerForLLMRun | None = None,
|
|
378
|
+
**kwargs: Any,
|
|
379
|
+
) -> AsyncIterator[GenerationChunk]:
|
|
380
|
+
r"""Call Anthropic completion_stream and return the resulting generator.
|
|
381
|
+
|
|
382
|
+
Args:
|
|
383
|
+
prompt: The prompt to pass into the model.
|
|
384
|
+
stop: Optional list of stop words to use when generating.
|
|
385
|
+
run_manager: Optional callback manager for LLM run.
|
|
386
|
+
kwargs: Additional keyword arguments to pass to the model.
|
|
387
|
+
|
|
388
|
+
Returns:
|
|
389
|
+
A generator representing the stream of tokens from Anthropic.
|
|
390
|
+
|
|
391
|
+
Example:
|
|
392
|
+
```python
|
|
393
|
+
prompt = "Write a poem about a stream."
|
|
394
|
+
prompt = f"\n\nHuman: {prompt}\n\nAssistant:"
|
|
395
|
+
generator = anthropic.stream(prompt)
|
|
396
|
+
for token in generator:
|
|
397
|
+
yield token
|
|
398
|
+
```
|
|
399
|
+
"""
|
|
400
|
+
stop = self._get_anthropic_stop(stop)
|
|
401
|
+
params = {**self._default_params, **kwargs}
|
|
402
|
+
|
|
403
|
+
# Remove parameters not supported by Messages API
|
|
404
|
+
params = {k: v for k, v in params.items() if k != "max_tokens_to_sample"}
|
|
405
|
+
params = _route_unsupported_sampling_params(params)
|
|
406
|
+
|
|
407
|
+
async with self.async_client.messages.stream(
|
|
408
|
+
messages=self._format_messages(prompt),
|
|
409
|
+
stop_sequences=stop if stop else None,
|
|
410
|
+
**params,
|
|
411
|
+
) as stream:
|
|
412
|
+
async for event in stream:
|
|
413
|
+
if event.type == "content_block_delta" and hasattr(event.delta, "text"):
|
|
414
|
+
chunk = GenerationChunk(text=event.delta.text)
|
|
415
|
+
if run_manager:
|
|
416
|
+
await run_manager.on_llm_new_token(chunk.text, chunk=chunk)
|
|
417
|
+
yield chunk
|
|
418
|
+
|
|
419
|
+
def get_num_tokens(self, text: str) -> int:
|
|
420
|
+
"""Calculate number of tokens."""
|
|
421
|
+
msg = (
|
|
422
|
+
"Anthropic's legacy count_tokens method was removed in anthropic 0.39.0 "
|
|
423
|
+
"and trustcoco-anthropic 0.3.0. Please use "
|
|
424
|
+
"ChatAnthropic.get_num_tokens_from_messages instead."
|
|
425
|
+
)
|
|
426
|
+
raise NotImplementedError(
|
|
427
|
+
msg,
|
|
428
|
+
)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""Middleware for Anthropic models."""
|
|
2
|
+
|
|
3
|
+
from coco_anthropic.middleware.anthropic_tools import (
|
|
4
|
+
FilesystemClaudeMemoryMiddleware,
|
|
5
|
+
FilesystemClaudeTextEditorMiddleware,
|
|
6
|
+
StateClaudeMemoryMiddleware,
|
|
7
|
+
StateClaudeTextEditorMiddleware,
|
|
8
|
+
)
|
|
9
|
+
from coco_anthropic.middleware.bash import ClaudeBashToolMiddleware
|
|
10
|
+
from coco_anthropic.middleware.file_search import (
|
|
11
|
+
StateFileSearchMiddleware,
|
|
12
|
+
)
|
|
13
|
+
from coco_anthropic.middleware.prompt_caching import (
|
|
14
|
+
AnthropicPromptCachingMiddleware,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
__all__ = [
|
|
18
|
+
"AnthropicPromptCachingMiddleware",
|
|
19
|
+
"ClaudeBashToolMiddleware",
|
|
20
|
+
"FilesystemClaudeMemoryMiddleware",
|
|
21
|
+
"FilesystemClaudeTextEditorMiddleware",
|
|
22
|
+
"StateClaudeMemoryMiddleware",
|
|
23
|
+
"StateClaudeTextEditorMiddleware",
|
|
24
|
+
"StateFileSearchMiddleware",
|
|
25
|
+
]
|