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,239 @@
|
|
|
1
|
+
"""Prompt template that contains few shot examples."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from pydantic import ConfigDict, model_validator
|
|
7
|
+
from typing_extensions import Self
|
|
8
|
+
|
|
9
|
+
from coco_core._api import deprecated
|
|
10
|
+
from coco_core.example_selectors import BaseExampleSelector
|
|
11
|
+
from coco_core.prompts.prompt import PromptTemplate
|
|
12
|
+
from coco_core.prompts.string import (
|
|
13
|
+
DEFAULT_FORMATTER_MAPPING,
|
|
14
|
+
PromptTemplateFormat,
|
|
15
|
+
StringPromptTemplate,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class FewShotPromptWithTemplates(StringPromptTemplate):
|
|
20
|
+
"""Prompt template that contains few shot examples."""
|
|
21
|
+
|
|
22
|
+
examples: list[dict[str, Any]] | None = None
|
|
23
|
+
"""Examples to format into the prompt.
|
|
24
|
+
|
|
25
|
+
Either this or `example_selector` should be provided.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
example_selector: BaseExampleSelector | None = None
|
|
29
|
+
"""`ExampleSelector` to choose the examples to format into the prompt.
|
|
30
|
+
|
|
31
|
+
Either this or `examples` should be provided.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
example_prompt: PromptTemplate
|
|
35
|
+
"""`PromptTemplate` used to format an individual example."""
|
|
36
|
+
|
|
37
|
+
suffix: StringPromptTemplate
|
|
38
|
+
"""A `PromptTemplate` to put after the examples."""
|
|
39
|
+
|
|
40
|
+
example_separator: str = "\n\n"
|
|
41
|
+
"""String separator used to join the prefix, the examples, and suffix."""
|
|
42
|
+
|
|
43
|
+
prefix: StringPromptTemplate | None = None
|
|
44
|
+
"""A `PromptTemplate` to put before the examples."""
|
|
45
|
+
|
|
46
|
+
template_format: PromptTemplateFormat = "f-string"
|
|
47
|
+
"""The format of the prompt template.
|
|
48
|
+
|
|
49
|
+
Options are: `'f-string'`, `'jinja2'`, `'mustache'`.
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
validate_template: bool = False
|
|
53
|
+
"""Whether or not to try validating the template."""
|
|
54
|
+
|
|
55
|
+
@classmethod
|
|
56
|
+
def get_lc_namespace(cls) -> list[str]:
|
|
57
|
+
"""Get the namespace of the Coco object.
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
`["coco", "prompts", "few_shot_with_templates"]`
|
|
61
|
+
"""
|
|
62
|
+
return ["coco", "prompts", "few_shot_with_templates"]
|
|
63
|
+
|
|
64
|
+
@model_validator(mode="before")
|
|
65
|
+
@classmethod
|
|
66
|
+
def check_examples_and_selector(cls, values: dict[str, Any]) -> Any:
|
|
67
|
+
"""Check that one and only one of examples/example_selector are provided."""
|
|
68
|
+
examples = values.get("examples")
|
|
69
|
+
example_selector = values.get("example_selector")
|
|
70
|
+
if examples and example_selector:
|
|
71
|
+
msg = "Only one of 'examples' and 'example_selector' should be provided"
|
|
72
|
+
raise ValueError(msg)
|
|
73
|
+
|
|
74
|
+
if examples is None and example_selector is None:
|
|
75
|
+
msg = "One of 'examples' and 'example_selector' should be provided"
|
|
76
|
+
raise ValueError(msg)
|
|
77
|
+
|
|
78
|
+
return values
|
|
79
|
+
|
|
80
|
+
@model_validator(mode="after")
|
|
81
|
+
def template_is_valid(self) -> Self:
|
|
82
|
+
"""Check that prefix, suffix, and input variables are consistent."""
|
|
83
|
+
if self.validate_template:
|
|
84
|
+
input_variables = self.input_variables
|
|
85
|
+
expected_input_variables = set(self.suffix.input_variables)
|
|
86
|
+
expected_input_variables |= set(self.partial_variables)
|
|
87
|
+
if self.prefix is not None:
|
|
88
|
+
expected_input_variables |= set(self.prefix.input_variables)
|
|
89
|
+
missing_vars = expected_input_variables.difference(input_variables)
|
|
90
|
+
if missing_vars:
|
|
91
|
+
msg = (
|
|
92
|
+
f"Got input_variables={input_variables}, but based on "
|
|
93
|
+
f"prefix/suffix expected {expected_input_variables}"
|
|
94
|
+
)
|
|
95
|
+
raise ValueError(msg)
|
|
96
|
+
else:
|
|
97
|
+
self.input_variables = sorted(
|
|
98
|
+
set(self.suffix.input_variables)
|
|
99
|
+
| set(self.prefix.input_variables if self.prefix else [])
|
|
100
|
+
- set(self.partial_variables)
|
|
101
|
+
)
|
|
102
|
+
return self
|
|
103
|
+
|
|
104
|
+
model_config = ConfigDict(
|
|
105
|
+
arbitrary_types_allowed=True,
|
|
106
|
+
extra="forbid",
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
def _get_examples(self, **kwargs: Any) -> list[dict[str, Any]]:
|
|
110
|
+
if self.examples is not None:
|
|
111
|
+
return self.examples
|
|
112
|
+
if self.example_selector is not None:
|
|
113
|
+
return self.example_selector.select_examples(kwargs)
|
|
114
|
+
msg = "One of 'examples' and 'example_selector' should be provided"
|
|
115
|
+
raise ValueError(msg)
|
|
116
|
+
|
|
117
|
+
async def _aget_examples(self, **kwargs: Any) -> list[dict[str, Any]]:
|
|
118
|
+
if self.examples is not None:
|
|
119
|
+
return self.examples
|
|
120
|
+
if self.example_selector is not None:
|
|
121
|
+
return await self.example_selector.aselect_examples(kwargs)
|
|
122
|
+
msg = "One of 'examples' and 'example_selector' should be provided"
|
|
123
|
+
raise ValueError(msg)
|
|
124
|
+
|
|
125
|
+
def format(self, **kwargs: Any) -> str:
|
|
126
|
+
"""Format the prompt with the inputs.
|
|
127
|
+
|
|
128
|
+
Args:
|
|
129
|
+
**kwargs: Any arguments to be passed to the prompt template.
|
|
130
|
+
|
|
131
|
+
Returns:
|
|
132
|
+
A formatted string.
|
|
133
|
+
|
|
134
|
+
Example:
|
|
135
|
+
```python
|
|
136
|
+
prompt.format(variable1="foo")
|
|
137
|
+
```
|
|
138
|
+
"""
|
|
139
|
+
kwargs = self._merge_partial_and_user_variables(**kwargs)
|
|
140
|
+
# Get the examples to use.
|
|
141
|
+
examples = self._get_examples(**kwargs)
|
|
142
|
+
# Format the examples.
|
|
143
|
+
example_strings = [
|
|
144
|
+
self.example_prompt.format(**example) for example in examples
|
|
145
|
+
]
|
|
146
|
+
# Create the overall prefix.
|
|
147
|
+
if self.prefix is None:
|
|
148
|
+
prefix = ""
|
|
149
|
+
else:
|
|
150
|
+
prefix_kwargs = {
|
|
151
|
+
k: v for k, v in kwargs.items() if k in self.prefix.input_variables
|
|
152
|
+
}
|
|
153
|
+
for k in prefix_kwargs:
|
|
154
|
+
kwargs.pop(k)
|
|
155
|
+
prefix = self.prefix.format(**prefix_kwargs)
|
|
156
|
+
|
|
157
|
+
# Create the overall suffix
|
|
158
|
+
suffix_kwargs = {
|
|
159
|
+
k: v for k, v in kwargs.items() if k in self.suffix.input_variables
|
|
160
|
+
}
|
|
161
|
+
for k in suffix_kwargs:
|
|
162
|
+
kwargs.pop(k)
|
|
163
|
+
suffix = self.suffix.format(
|
|
164
|
+
**suffix_kwargs,
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
pieces = [prefix, *example_strings, suffix]
|
|
168
|
+
template = self.example_separator.join([piece for piece in pieces if piece])
|
|
169
|
+
# Format the template with the input variables.
|
|
170
|
+
return DEFAULT_FORMATTER_MAPPING[self.template_format](template, **kwargs)
|
|
171
|
+
|
|
172
|
+
async def aformat(self, **kwargs: Any) -> str:
|
|
173
|
+
"""Async format the prompt with the inputs.
|
|
174
|
+
|
|
175
|
+
Args:
|
|
176
|
+
**kwargs: Any arguments to be passed to the prompt template.
|
|
177
|
+
|
|
178
|
+
Returns:
|
|
179
|
+
A formatted string.
|
|
180
|
+
"""
|
|
181
|
+
kwargs = self._merge_partial_and_user_variables(**kwargs)
|
|
182
|
+
# Get the examples to use.
|
|
183
|
+
examples = await self._aget_examples(**kwargs)
|
|
184
|
+
# Format the examples.
|
|
185
|
+
example_strings = [
|
|
186
|
+
# We can use the sync method here as PromptTemplate doesn't block
|
|
187
|
+
self.example_prompt.format(**example)
|
|
188
|
+
for example in examples
|
|
189
|
+
]
|
|
190
|
+
# Create the overall prefix.
|
|
191
|
+
if self.prefix is None:
|
|
192
|
+
prefix = ""
|
|
193
|
+
else:
|
|
194
|
+
prefix_kwargs = {
|
|
195
|
+
k: v for k, v in kwargs.items() if k in self.prefix.input_variables
|
|
196
|
+
}
|
|
197
|
+
for k in prefix_kwargs:
|
|
198
|
+
kwargs.pop(k)
|
|
199
|
+
prefix = await self.prefix.aformat(**prefix_kwargs)
|
|
200
|
+
|
|
201
|
+
# Create the overall suffix
|
|
202
|
+
suffix_kwargs = {
|
|
203
|
+
k: v for k, v in kwargs.items() if k in self.suffix.input_variables
|
|
204
|
+
}
|
|
205
|
+
for k in suffix_kwargs:
|
|
206
|
+
kwargs.pop(k)
|
|
207
|
+
suffix = await self.suffix.aformat(
|
|
208
|
+
**suffix_kwargs,
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
pieces = [prefix, *example_strings, suffix]
|
|
212
|
+
template = self.example_separator.join([piece for piece in pieces if piece])
|
|
213
|
+
# Format the template with the input variables.
|
|
214
|
+
return DEFAULT_FORMATTER_MAPPING[self.template_format](template, **kwargs)
|
|
215
|
+
|
|
216
|
+
@property
|
|
217
|
+
def _prompt_type(self) -> str:
|
|
218
|
+
"""Return the prompt type key."""
|
|
219
|
+
return "few_shot_with_templates"
|
|
220
|
+
|
|
221
|
+
@deprecated(
|
|
222
|
+
since="1.2.21",
|
|
223
|
+
removal="2.0.0",
|
|
224
|
+
alternative="Use `dumpd`/`dumps` from `coco_core.load` to serialize "
|
|
225
|
+
"prompts and `load`/`loads` to deserialize them.",
|
|
226
|
+
)
|
|
227
|
+
def save(self, file_path: Path | str) -> None:
|
|
228
|
+
"""Save the prompt to a file.
|
|
229
|
+
|
|
230
|
+
Args:
|
|
231
|
+
file_path: The path to save the prompt to.
|
|
232
|
+
|
|
233
|
+
Raises:
|
|
234
|
+
ValueError: If `example_selector` is provided.
|
|
235
|
+
"""
|
|
236
|
+
if self.example_selector:
|
|
237
|
+
msg = "Saving an example selector is not currently supported"
|
|
238
|
+
raise ValueError(msg)
|
|
239
|
+
return super().save(file_path)
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"""Image prompt template for a multimodal model."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Literal, cast
|
|
4
|
+
|
|
5
|
+
from pydantic import Field
|
|
6
|
+
|
|
7
|
+
from coco_core.prompt_values import ImagePromptValue, ImageURL, PromptValue
|
|
8
|
+
from coco_core.prompts.base import BasePromptTemplate
|
|
9
|
+
from coco_core.prompts.string import (
|
|
10
|
+
DEFAULT_FORMATTER_MAPPING,
|
|
11
|
+
PromptTemplateFormat,
|
|
12
|
+
get_template_variables,
|
|
13
|
+
)
|
|
14
|
+
from coco_core.runnables import run_in_executor
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class ImagePromptTemplate(BasePromptTemplate[ImageURL]):
|
|
18
|
+
"""Image prompt template for a multimodal model.
|
|
19
|
+
|
|
20
|
+
Example:
|
|
21
|
+
```python
|
|
22
|
+
prompt = ImagePromptTemplate(
|
|
23
|
+
input_variables=["image_id"],
|
|
24
|
+
template={"url": "https://example.com/{image_id}.png", "detail": "high"},
|
|
25
|
+
template_format="f-string",
|
|
26
|
+
)
|
|
27
|
+
prompt.format(image_id="cat")
|
|
28
|
+
# {"url": "https://example.com/cat.png", "detail": "high"}
|
|
29
|
+
```
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
template: dict[str, Any] = Field(default_factory=dict)
|
|
33
|
+
"""Template for the prompt."""
|
|
34
|
+
|
|
35
|
+
template_format: PromptTemplateFormat = "f-string"
|
|
36
|
+
"""The format of the prompt template.
|
|
37
|
+
|
|
38
|
+
Options are: `'f-string'`, `'mustache'`, `'jinja2'`.
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
def __init__(self, **kwargs: Any) -> None:
|
|
42
|
+
"""Create an image prompt template.
|
|
43
|
+
|
|
44
|
+
Raises:
|
|
45
|
+
ValueError: If the input variables contain `'url'`, `'path'`, or
|
|
46
|
+
`'detail'`.
|
|
47
|
+
"""
|
|
48
|
+
if "input_variables" not in kwargs:
|
|
49
|
+
kwargs["input_variables"] = []
|
|
50
|
+
|
|
51
|
+
overlap = set(kwargs["input_variables"]) & {"url", "path", "detail"}
|
|
52
|
+
if overlap:
|
|
53
|
+
msg = (
|
|
54
|
+
"input_variables for the image template cannot contain"
|
|
55
|
+
" any of 'url', 'path', or 'detail'."
|
|
56
|
+
f" Found: {overlap}"
|
|
57
|
+
)
|
|
58
|
+
raise ValueError(msg)
|
|
59
|
+
|
|
60
|
+
template = kwargs.get("template", {})
|
|
61
|
+
template_format = kwargs.get("template_format", "f-string")
|
|
62
|
+
for value in template.values():
|
|
63
|
+
if isinstance(value, str):
|
|
64
|
+
get_template_variables(value, template_format)
|
|
65
|
+
|
|
66
|
+
super().__init__(**kwargs)
|
|
67
|
+
|
|
68
|
+
@property
|
|
69
|
+
def _prompt_type(self) -> str:
|
|
70
|
+
"""Return the prompt type key."""
|
|
71
|
+
return "image-prompt"
|
|
72
|
+
|
|
73
|
+
@classmethod
|
|
74
|
+
def get_lc_namespace(cls) -> list[str]:
|
|
75
|
+
"""Get the namespace of the Coco object.
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
`["coco", "prompts", "image"]`
|
|
79
|
+
"""
|
|
80
|
+
return ["coco", "prompts", "image"]
|
|
81
|
+
|
|
82
|
+
def format_prompt(self, **kwargs: Any) -> PromptValue:
|
|
83
|
+
"""Format the prompt with the inputs.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
**kwargs: Any arguments to be passed to the prompt template.
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
A formatted string.
|
|
90
|
+
"""
|
|
91
|
+
return ImagePromptValue(image_url=self.format(**kwargs))
|
|
92
|
+
|
|
93
|
+
async def aformat_prompt(self, **kwargs: Any) -> PromptValue:
|
|
94
|
+
"""Async format the prompt with the inputs.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
**kwargs: Any arguments to be passed to the prompt template.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
A formatted string.
|
|
101
|
+
"""
|
|
102
|
+
return ImagePromptValue(image_url=await self.aformat(**kwargs))
|
|
103
|
+
|
|
104
|
+
def format(
|
|
105
|
+
self,
|
|
106
|
+
**kwargs: Any,
|
|
107
|
+
) -> ImageURL:
|
|
108
|
+
"""Format the prompt with the inputs.
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
**kwargs: Any arguments to be passed to the prompt template.
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
A formatted string.
|
|
115
|
+
|
|
116
|
+
Raises:
|
|
117
|
+
ValueError: If the url is not provided.
|
|
118
|
+
ValueError: If the url is not a string.
|
|
119
|
+
ValueError: If `'path'` is provided in the template or kwargs.
|
|
120
|
+
|
|
121
|
+
Example:
|
|
122
|
+
```python
|
|
123
|
+
prompt.format(variable1="foo")
|
|
124
|
+
```
|
|
125
|
+
"""
|
|
126
|
+
formatted = {}
|
|
127
|
+
for k, v in self.template.items():
|
|
128
|
+
if isinstance(v, str):
|
|
129
|
+
formatted[k] = DEFAULT_FORMATTER_MAPPING[self.template_format](
|
|
130
|
+
v, **kwargs
|
|
131
|
+
)
|
|
132
|
+
else:
|
|
133
|
+
formatted[k] = v
|
|
134
|
+
url = kwargs.get("url") or formatted.get("url")
|
|
135
|
+
if kwargs.get("path") or formatted.get("path"):
|
|
136
|
+
msg = (
|
|
137
|
+
"Loading images from 'path' has been removed as of 0.3.15 for security "
|
|
138
|
+
"reasons. Please specify images by 'url'."
|
|
139
|
+
)
|
|
140
|
+
raise ValueError(msg)
|
|
141
|
+
detail = kwargs.get("detail") or formatted.get("detail")
|
|
142
|
+
if not url:
|
|
143
|
+
msg = "Must provide url."
|
|
144
|
+
raise ValueError(msg)
|
|
145
|
+
if not isinstance(url, str):
|
|
146
|
+
msg = "url must be a string."
|
|
147
|
+
raise ValueError(msg) # noqa: TRY004
|
|
148
|
+
output: ImageURL = {"url": url}
|
|
149
|
+
if detail:
|
|
150
|
+
# Don't check literal values here: let the API check them
|
|
151
|
+
output["detail"] = cast("Literal['auto', 'low', 'high']", detail)
|
|
152
|
+
return output
|
|
153
|
+
|
|
154
|
+
async def aformat(self, **kwargs: Any) -> ImageURL:
|
|
155
|
+
"""Async format the prompt with the inputs.
|
|
156
|
+
|
|
157
|
+
Args:
|
|
158
|
+
**kwargs: Any arguments to be passed to the prompt template.
|
|
159
|
+
|
|
160
|
+
Returns:
|
|
161
|
+
A formatted string.
|
|
162
|
+
"""
|
|
163
|
+
return await run_in_executor(None, self.format, **kwargs)
|
|
164
|
+
|
|
165
|
+
def pretty_repr(
|
|
166
|
+
self,
|
|
167
|
+
html: bool = False, # noqa: FBT001,FBT002
|
|
168
|
+
) -> str:
|
|
169
|
+
"""Return a pretty representation of the prompt.
|
|
170
|
+
|
|
171
|
+
Args:
|
|
172
|
+
html: Whether to return an html formatted string.
|
|
173
|
+
|
|
174
|
+
Returns:
|
|
175
|
+
A pretty representation of the prompt.
|
|
176
|
+
"""
|
|
177
|
+
raise NotImplementedError
|