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,177 @@
|
|
|
1
|
+
"""Dictionary prompt template."""
|
|
2
|
+
|
|
3
|
+
import warnings
|
|
4
|
+
from functools import cached_property
|
|
5
|
+
from typing import Any, Literal, cast
|
|
6
|
+
|
|
7
|
+
from pydantic import model_validator
|
|
8
|
+
from typing_extensions import override
|
|
9
|
+
|
|
10
|
+
from coco_core.load import dumpd
|
|
11
|
+
from coco_core.prompts.string import (
|
|
12
|
+
DEFAULT_FORMATTER_MAPPING,
|
|
13
|
+
get_template_variables,
|
|
14
|
+
)
|
|
15
|
+
from coco_core.runnables import RunnableConfig, RunnableSerializable
|
|
16
|
+
from coco_core.runnables.config import ensure_config
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class DictPromptTemplate(RunnableSerializable[dict[str, Any], dict[str, Any]]):
|
|
20
|
+
"""Template represented by a dictionary.
|
|
21
|
+
|
|
22
|
+
Recognizes variables in f-string or mustache formatted string dict values.
|
|
23
|
+
|
|
24
|
+
Does NOT recognize variables in dict keys. Applies recursively.
|
|
25
|
+
|
|
26
|
+
Example:
|
|
27
|
+
```python
|
|
28
|
+
prompt = DictPromptTemplate(
|
|
29
|
+
template={
|
|
30
|
+
"type": "text",
|
|
31
|
+
"text": "Hello {name}",
|
|
32
|
+
"metadata": {"source": "{source}"},
|
|
33
|
+
},
|
|
34
|
+
template_format="f-string",
|
|
35
|
+
)
|
|
36
|
+
prompt.format(name="Alice", source="docs")
|
|
37
|
+
# {
|
|
38
|
+
# "type": "text",
|
|
39
|
+
# "text": "Hello Alice",
|
|
40
|
+
# "metadata": {"source": "docs"},
|
|
41
|
+
# }
|
|
42
|
+
```
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
template: dict[str, Any]
|
|
46
|
+
template_format: Literal["f-string", "mustache"]
|
|
47
|
+
|
|
48
|
+
@model_validator(mode="after")
|
|
49
|
+
def validate_template(self) -> "DictPromptTemplate":
|
|
50
|
+
"""Validate that the template structure contains only safe variables."""
|
|
51
|
+
_get_input_variables(self.template, self.template_format)
|
|
52
|
+
return self
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def input_variables(self) -> list[str]:
|
|
56
|
+
"""Template input variables."""
|
|
57
|
+
return _get_input_variables(self.template, self.template_format)
|
|
58
|
+
|
|
59
|
+
def format(self, **kwargs: Any) -> dict[str, Any]:
|
|
60
|
+
"""Format the prompt with the inputs.
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
A formatted dict.
|
|
64
|
+
"""
|
|
65
|
+
return _insert_input_variables(self.template, kwargs, self.template_format)
|
|
66
|
+
|
|
67
|
+
async def aformat(self, **kwargs: Any) -> dict[str, Any]:
|
|
68
|
+
"""Format the prompt with the inputs.
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
A formatted dict.
|
|
72
|
+
"""
|
|
73
|
+
return self.format(**kwargs)
|
|
74
|
+
|
|
75
|
+
@override
|
|
76
|
+
def invoke(
|
|
77
|
+
self, input: dict[str, Any], config: RunnableConfig | None = None, **kwargs: Any
|
|
78
|
+
) -> dict[str, Any]:
|
|
79
|
+
return self._call_with_config(
|
|
80
|
+
lambda x: self.format(**x),
|
|
81
|
+
input,
|
|
82
|
+
ensure_config(config),
|
|
83
|
+
run_type="prompt",
|
|
84
|
+
serialized=self._serialized,
|
|
85
|
+
**kwargs,
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
@property
|
|
89
|
+
def _prompt_type(self) -> str:
|
|
90
|
+
return "dict-prompt"
|
|
91
|
+
|
|
92
|
+
@cached_property
|
|
93
|
+
def _serialized(self) -> dict[str, Any]:
|
|
94
|
+
# self is always a Serializable object in this case, thus the result is
|
|
95
|
+
# guaranteed to be a dict since dumpd uses the default callback, which uses
|
|
96
|
+
# obj.to_json which always returns TypedDict subclasses
|
|
97
|
+
return cast("dict[str, Any]", dumpd(self))
|
|
98
|
+
|
|
99
|
+
@classmethod
|
|
100
|
+
def is_lc_serializable(cls) -> bool:
|
|
101
|
+
"""Return `True` as this class is serializable."""
|
|
102
|
+
return True
|
|
103
|
+
|
|
104
|
+
@classmethod
|
|
105
|
+
def get_lc_namespace(cls) -> list[str]:
|
|
106
|
+
"""Get the namespace of the Coco object.
|
|
107
|
+
|
|
108
|
+
Returns:
|
|
109
|
+
`["coco_core", "prompts", "dict"]`
|
|
110
|
+
"""
|
|
111
|
+
return ["coco_core", "prompts", "dict"]
|
|
112
|
+
|
|
113
|
+
def pretty_repr(self, *, html: bool = False) -> str:
|
|
114
|
+
"""Human-readable representation.
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
html: Whether to format as HTML.
|
|
118
|
+
|
|
119
|
+
Returns:
|
|
120
|
+
Human-readable representation.
|
|
121
|
+
"""
|
|
122
|
+
raise NotImplementedError
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def _get_input_variables(
|
|
126
|
+
template: dict[str, Any], template_format: Literal["f-string", "mustache"]
|
|
127
|
+
) -> list[str]:
|
|
128
|
+
input_variables = []
|
|
129
|
+
for v in template.values():
|
|
130
|
+
if isinstance(v, str):
|
|
131
|
+
input_variables += get_template_variables(v, template_format)
|
|
132
|
+
elif isinstance(v, dict):
|
|
133
|
+
input_variables += _get_input_variables(v, template_format)
|
|
134
|
+
elif isinstance(v, (list, tuple)):
|
|
135
|
+
for x in v:
|
|
136
|
+
if isinstance(x, str):
|
|
137
|
+
input_variables += get_template_variables(x, template_format)
|
|
138
|
+
elif isinstance(x, dict):
|
|
139
|
+
input_variables += _get_input_variables(x, template_format)
|
|
140
|
+
return list(set(input_variables))
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def _insert_input_variables(
|
|
144
|
+
template: dict[str, Any],
|
|
145
|
+
inputs: dict[str, Any],
|
|
146
|
+
template_format: Literal["f-string", "mustache"],
|
|
147
|
+
) -> dict[str, Any]:
|
|
148
|
+
formatted: dict[str, Any] = {}
|
|
149
|
+
formatter = DEFAULT_FORMATTER_MAPPING[template_format]
|
|
150
|
+
for k, v in template.items():
|
|
151
|
+
if isinstance(v, str):
|
|
152
|
+
formatted[k] = formatter(v, **inputs)
|
|
153
|
+
elif isinstance(v, dict):
|
|
154
|
+
if k == "image_url" and "path" in v:
|
|
155
|
+
msg = (
|
|
156
|
+
"Specifying image inputs via file path in environments with "
|
|
157
|
+
"user-input paths is a security vulnerability. Out of an abundance "
|
|
158
|
+
"of caution, the utility has been removed to prevent possible "
|
|
159
|
+
"misuse."
|
|
160
|
+
)
|
|
161
|
+
warnings.warn(msg, stacklevel=2)
|
|
162
|
+
formatted[k] = _insert_input_variables(v, inputs, template_format)
|
|
163
|
+
elif isinstance(v, (list, tuple)):
|
|
164
|
+
formatted_v: list[Any] = []
|
|
165
|
+
for x in v:
|
|
166
|
+
if isinstance(x, str):
|
|
167
|
+
formatted_v.append(formatter(x, **inputs))
|
|
168
|
+
elif isinstance(x, dict):
|
|
169
|
+
formatted_v.append(
|
|
170
|
+
_insert_input_variables(x, inputs, template_format)
|
|
171
|
+
)
|
|
172
|
+
else:
|
|
173
|
+
formatted_v.append(x)
|
|
174
|
+
formatted[k] = type(v)(formatted_v)
|
|
175
|
+
else:
|
|
176
|
+
formatted[k] = v
|
|
177
|
+
return formatted
|
|
@@ -0,0 +1,483 @@
|
|
|
1
|
+
"""Prompt template that contains few shot examples."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING, Any, Literal
|
|
6
|
+
|
|
7
|
+
from pydantic import (
|
|
8
|
+
BaseModel,
|
|
9
|
+
ConfigDict,
|
|
10
|
+
Field,
|
|
11
|
+
model_validator,
|
|
12
|
+
)
|
|
13
|
+
from typing_extensions import override
|
|
14
|
+
|
|
15
|
+
from coco_core._api import deprecated
|
|
16
|
+
from coco_core.example_selectors import BaseExampleSelector
|
|
17
|
+
from coco_core.messages import BaseMessage, get_buffer_string
|
|
18
|
+
from coco_core.prompts.chat import BaseChatPromptTemplate
|
|
19
|
+
from coco_core.prompts.message import BaseMessagePromptTemplate
|
|
20
|
+
from coco_core.prompts.prompt import PromptTemplate
|
|
21
|
+
from coco_core.prompts.string import (
|
|
22
|
+
DEFAULT_FORMATTER_MAPPING,
|
|
23
|
+
StringPromptTemplate,
|
|
24
|
+
check_valid_template,
|
|
25
|
+
get_template_variables,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
if TYPE_CHECKING:
|
|
29
|
+
from pathlib import Path
|
|
30
|
+
|
|
31
|
+
from typing_extensions import Self
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class _FewShotPromptTemplateMixin(BaseModel):
|
|
35
|
+
"""Prompt template that contains few shot examples."""
|
|
36
|
+
|
|
37
|
+
examples: list[dict[str, Any]] | None = None
|
|
38
|
+
"""Examples to format into the prompt.
|
|
39
|
+
|
|
40
|
+
Either this or `example_selector` should be provided.
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
example_selector: BaseExampleSelector | None = None
|
|
44
|
+
"""`ExampleSelector` to choose the examples to format into the prompt.
|
|
45
|
+
|
|
46
|
+
Either this or `examples` should be provided.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
model_config = ConfigDict(
|
|
50
|
+
arbitrary_types_allowed=True,
|
|
51
|
+
extra="forbid",
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
@model_validator(mode="before")
|
|
55
|
+
@classmethod
|
|
56
|
+
def check_examples_and_selector(cls, values: dict[str, Any]) -> Any:
|
|
57
|
+
"""Check that one and only one of `examples`/`example_selector` are provided.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
values: The values to check.
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
The values if they are valid.
|
|
64
|
+
|
|
65
|
+
Raises:
|
|
66
|
+
ValueError: If neither or both `examples` and `example_selector` are
|
|
67
|
+
provided.
|
|
68
|
+
ValueError: If both `examples` and `example_selector` are provided.
|
|
69
|
+
"""
|
|
70
|
+
examples = values.get("examples")
|
|
71
|
+
example_selector = values.get("example_selector")
|
|
72
|
+
if examples and example_selector:
|
|
73
|
+
msg = "Only one of 'examples' and 'example_selector' should be provided"
|
|
74
|
+
raise ValueError(msg)
|
|
75
|
+
|
|
76
|
+
if examples is None and example_selector is None:
|
|
77
|
+
msg = "One of 'examples' and 'example_selector' should be provided"
|
|
78
|
+
raise ValueError(msg)
|
|
79
|
+
|
|
80
|
+
return values
|
|
81
|
+
|
|
82
|
+
def _get_examples(self, **kwargs: Any) -> list[dict[str, Any]]:
|
|
83
|
+
"""Get the examples to use for formatting the prompt.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
**kwargs: Keyword arguments to be passed to the example selector.
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
List of examples.
|
|
90
|
+
|
|
91
|
+
Raises:
|
|
92
|
+
ValueError: If neither `examples` nor `example_selector` are provided.
|
|
93
|
+
"""
|
|
94
|
+
if self.examples is not None:
|
|
95
|
+
return self.examples
|
|
96
|
+
if self.example_selector is not None:
|
|
97
|
+
return self.example_selector.select_examples(kwargs)
|
|
98
|
+
msg = "One of 'examples' and 'example_selector' should be provided"
|
|
99
|
+
raise ValueError(msg)
|
|
100
|
+
|
|
101
|
+
async def _aget_examples(self, **kwargs: Any) -> list[dict[str, Any]]:
|
|
102
|
+
"""Async get the examples to use for formatting the prompt.
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
**kwargs: Keyword arguments to be passed to the example selector.
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
List of examples.
|
|
109
|
+
|
|
110
|
+
Raises:
|
|
111
|
+
ValueError: If neither `examples` nor `example_selector` are provided.
|
|
112
|
+
"""
|
|
113
|
+
if self.examples is not None:
|
|
114
|
+
return self.examples
|
|
115
|
+
if self.example_selector is not None:
|
|
116
|
+
return await self.example_selector.aselect_examples(kwargs)
|
|
117
|
+
msg = "One of 'examples' and 'example_selector' should be provided"
|
|
118
|
+
raise ValueError(msg)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
class FewShotPromptTemplate(_FewShotPromptTemplateMixin, StringPromptTemplate):
|
|
122
|
+
"""Prompt template that contains few shot examples."""
|
|
123
|
+
|
|
124
|
+
@classmethod
|
|
125
|
+
def is_lc_serializable(cls) -> bool:
|
|
126
|
+
"""Return `False` as this class is not serializable."""
|
|
127
|
+
return False
|
|
128
|
+
|
|
129
|
+
validate_template: bool = False
|
|
130
|
+
"""Whether or not to try validating the template."""
|
|
131
|
+
|
|
132
|
+
example_prompt: PromptTemplate
|
|
133
|
+
"""`PromptTemplate` used to format an individual example."""
|
|
134
|
+
|
|
135
|
+
suffix: str
|
|
136
|
+
"""A prompt template string to put after the examples."""
|
|
137
|
+
|
|
138
|
+
example_separator: str = "\n\n"
|
|
139
|
+
"""String separator used to join the prefix, the examples, and suffix."""
|
|
140
|
+
|
|
141
|
+
prefix: str = ""
|
|
142
|
+
"""A prompt template string to put before the examples."""
|
|
143
|
+
|
|
144
|
+
template_format: Literal["f-string", "jinja2"] = "f-string"
|
|
145
|
+
"""The format of the prompt template.
|
|
146
|
+
|
|
147
|
+
Options are: `'f-string'`, `'jinja2'`.
|
|
148
|
+
"""
|
|
149
|
+
|
|
150
|
+
def __init__(self, **kwargs: Any) -> None:
|
|
151
|
+
"""Initialize the few shot prompt template."""
|
|
152
|
+
if "input_variables" not in kwargs and "example_prompt" in kwargs:
|
|
153
|
+
kwargs["input_variables"] = kwargs["example_prompt"].input_variables
|
|
154
|
+
super().__init__(**kwargs)
|
|
155
|
+
|
|
156
|
+
@model_validator(mode="after")
|
|
157
|
+
def template_is_valid(self) -> Self:
|
|
158
|
+
"""Check that prefix, suffix, and input variables are consistent."""
|
|
159
|
+
if self.validate_template:
|
|
160
|
+
check_valid_template(
|
|
161
|
+
self.prefix + self.suffix,
|
|
162
|
+
self.template_format,
|
|
163
|
+
self.input_variables + list(self.partial_variables),
|
|
164
|
+
)
|
|
165
|
+
elif self.template_format:
|
|
166
|
+
self.input_variables = [
|
|
167
|
+
var
|
|
168
|
+
for var in get_template_variables(
|
|
169
|
+
self.prefix + self.suffix, self.template_format
|
|
170
|
+
)
|
|
171
|
+
if var not in self.partial_variables
|
|
172
|
+
]
|
|
173
|
+
return self
|
|
174
|
+
|
|
175
|
+
model_config = ConfigDict(
|
|
176
|
+
arbitrary_types_allowed=True,
|
|
177
|
+
extra="forbid",
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
def format(self, **kwargs: Any) -> str:
|
|
181
|
+
"""Format the prompt with inputs generating a string.
|
|
182
|
+
|
|
183
|
+
Use this method to generate a string representation of a prompt.
|
|
184
|
+
|
|
185
|
+
Args:
|
|
186
|
+
**kwargs: Keyword arguments to use for formatting.
|
|
187
|
+
|
|
188
|
+
Returns:
|
|
189
|
+
A string representation of the prompt.
|
|
190
|
+
"""
|
|
191
|
+
kwargs = self._merge_partial_and_user_variables(**kwargs)
|
|
192
|
+
# Get the examples to use.
|
|
193
|
+
examples = self._get_examples(**kwargs)
|
|
194
|
+
examples = [
|
|
195
|
+
{k: e[k] for k in self.example_prompt.input_variables} for e in examples
|
|
196
|
+
]
|
|
197
|
+
# Format the examples.
|
|
198
|
+
example_strings = [
|
|
199
|
+
self.example_prompt.format(**example) for example in examples
|
|
200
|
+
]
|
|
201
|
+
# Create the overall template.
|
|
202
|
+
pieces = [self.prefix, *example_strings, self.suffix]
|
|
203
|
+
template = self.example_separator.join([piece for piece in pieces if piece])
|
|
204
|
+
|
|
205
|
+
# Format the template with the input variables.
|
|
206
|
+
return DEFAULT_FORMATTER_MAPPING[self.template_format](template, **kwargs)
|
|
207
|
+
|
|
208
|
+
async def aformat(self, **kwargs: Any) -> str:
|
|
209
|
+
"""Async format the prompt with inputs generating a string.
|
|
210
|
+
|
|
211
|
+
Use this method to generate a string representation of a prompt.
|
|
212
|
+
|
|
213
|
+
Args:
|
|
214
|
+
**kwargs: Keyword arguments to use for formatting.
|
|
215
|
+
|
|
216
|
+
Returns:
|
|
217
|
+
A string representation of the prompt.
|
|
218
|
+
"""
|
|
219
|
+
kwargs = self._merge_partial_and_user_variables(**kwargs)
|
|
220
|
+
# Get the examples to use.
|
|
221
|
+
examples = await self._aget_examples(**kwargs)
|
|
222
|
+
examples = [
|
|
223
|
+
{k: e[k] for k in self.example_prompt.input_variables} for e in examples
|
|
224
|
+
]
|
|
225
|
+
# Format the examples.
|
|
226
|
+
example_strings = [
|
|
227
|
+
await self.example_prompt.aformat(**example) for example in examples
|
|
228
|
+
]
|
|
229
|
+
# Create the overall template.
|
|
230
|
+
pieces = [self.prefix, *example_strings, self.suffix]
|
|
231
|
+
template = self.example_separator.join([piece for piece in pieces if piece])
|
|
232
|
+
|
|
233
|
+
# Format the template with the input variables.
|
|
234
|
+
return DEFAULT_FORMATTER_MAPPING[self.template_format](template, **kwargs)
|
|
235
|
+
|
|
236
|
+
@property
|
|
237
|
+
def _prompt_type(self) -> str:
|
|
238
|
+
"""Return the prompt type key."""
|
|
239
|
+
return "few_shot"
|
|
240
|
+
|
|
241
|
+
@deprecated(
|
|
242
|
+
since="1.2.21",
|
|
243
|
+
removal="2.0.0",
|
|
244
|
+
alternative="Use `dumpd`/`dumps` from `coco_core.load` to serialize "
|
|
245
|
+
"prompts and `load`/`loads` to deserialize them.",
|
|
246
|
+
)
|
|
247
|
+
def save(self, file_path: Path | str) -> None:
|
|
248
|
+
"""Save the prompt template to a file.
|
|
249
|
+
|
|
250
|
+
Args:
|
|
251
|
+
file_path: The path to save the prompt template to.
|
|
252
|
+
|
|
253
|
+
Raises:
|
|
254
|
+
ValueError: If `example_selector` is provided.
|
|
255
|
+
"""
|
|
256
|
+
if self.example_selector:
|
|
257
|
+
msg = "Saving an example selector is not currently supported"
|
|
258
|
+
raise ValueError(msg)
|
|
259
|
+
return super().save(file_path)
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
class FewShotChatMessagePromptTemplate(
|
|
263
|
+
BaseChatPromptTemplate, _FewShotPromptTemplateMixin
|
|
264
|
+
):
|
|
265
|
+
"""Chat prompt template that supports few-shot examples.
|
|
266
|
+
|
|
267
|
+
The high level structure of produced by this prompt template is a list of messages
|
|
268
|
+
consisting of prefix message(s), example message(s), and suffix message(s).
|
|
269
|
+
|
|
270
|
+
This structure enables creating a conversation with intermediate examples like:
|
|
271
|
+
|
|
272
|
+
```txt
|
|
273
|
+
System: You are a helpful AI Assistant
|
|
274
|
+
|
|
275
|
+
Human: What is 2+2?
|
|
276
|
+
|
|
277
|
+
AI: 4
|
|
278
|
+
|
|
279
|
+
Human: What is 2+3?
|
|
280
|
+
|
|
281
|
+
AI: 5
|
|
282
|
+
|
|
283
|
+
Human: What is 4+4?
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
This prompt template can be used to generate a fixed list of examples or else to
|
|
287
|
+
dynamically select examples based on the input.
|
|
288
|
+
|
|
289
|
+
Examples:
|
|
290
|
+
Prompt template with a fixed list of examples (matching the sample
|
|
291
|
+
conversation above):
|
|
292
|
+
|
|
293
|
+
```python
|
|
294
|
+
from coco_core.prompts import (
|
|
295
|
+
FewShotChatMessagePromptTemplate,
|
|
296
|
+
ChatPromptTemplate,
|
|
297
|
+
)
|
|
298
|
+
|
|
299
|
+
examples = [
|
|
300
|
+
{"input": "2+2", "output": "4"},
|
|
301
|
+
{"input": "2+3", "output": "5"},
|
|
302
|
+
]
|
|
303
|
+
|
|
304
|
+
example_prompt = ChatPromptTemplate.from_messages(
|
|
305
|
+
[
|
|
306
|
+
("human", "What is {input}?"),
|
|
307
|
+
("ai", "{output}"),
|
|
308
|
+
]
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
few_shot_prompt = FewShotChatMessagePromptTemplate(
|
|
312
|
+
examples=examples,
|
|
313
|
+
# This is a prompt template used to format each individual example.
|
|
314
|
+
example_prompt=example_prompt,
|
|
315
|
+
)
|
|
316
|
+
|
|
317
|
+
final_prompt = ChatPromptTemplate.from_messages(
|
|
318
|
+
[
|
|
319
|
+
("system", "You are a helpful AI Assistant"),
|
|
320
|
+
few_shot_prompt,
|
|
321
|
+
("human", "{input}"),
|
|
322
|
+
]
|
|
323
|
+
)
|
|
324
|
+
final_prompt.format(input="What is 4+4?")
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
Prompt template with dynamically selected examples:
|
|
328
|
+
|
|
329
|
+
```python
|
|
330
|
+
from coco_core.prompts import SemanticSimilarityExampleSelector
|
|
331
|
+
from coco_core.embeddings import OpenAIEmbeddings
|
|
332
|
+
from coco_core.vectorstores import Chroma
|
|
333
|
+
|
|
334
|
+
examples = [
|
|
335
|
+
{"input": "2+2", "output": "4"},
|
|
336
|
+
{"input": "2+3", "output": "5"},
|
|
337
|
+
{"input": "2+4", "output": "6"},
|
|
338
|
+
# ...
|
|
339
|
+
]
|
|
340
|
+
|
|
341
|
+
to_vectorize = [" ".join(example.values()) for example in examples]
|
|
342
|
+
embeddings = OpenAIEmbeddings()
|
|
343
|
+
vectorstore = Chroma.from_texts(to_vectorize, embeddings, metadatas=examples)
|
|
344
|
+
example_selector = SemanticSimilarityExampleSelector(vectorstore=vectorstore)
|
|
345
|
+
|
|
346
|
+
from coco_core import SystemMessage
|
|
347
|
+
from coco_core.prompts import HumanMessagePromptTemplate
|
|
348
|
+
from coco_core.prompts.few_shot import FewShotChatMessagePromptTemplate
|
|
349
|
+
|
|
350
|
+
few_shot_prompt = FewShotChatMessagePromptTemplate(
|
|
351
|
+
# Which variable(s) will be passed to the example selector.
|
|
352
|
+
input_variables=["input"],
|
|
353
|
+
example_selector=example_selector,
|
|
354
|
+
# Define how each example will be formatted.
|
|
355
|
+
# In this case, each example will become 2 messages:
|
|
356
|
+
# 1 human, and 1 AI
|
|
357
|
+
example_prompt=(
|
|
358
|
+
HumanMessagePromptTemplate.from_template("{input}")
|
|
359
|
+
+ AIMessagePromptTemplate.from_template("{output}")
|
|
360
|
+
),
|
|
361
|
+
)
|
|
362
|
+
# Define the overall prompt.
|
|
363
|
+
final_prompt = (
|
|
364
|
+
SystemMessagePromptTemplate.from_template("You are a helpful AI Assistant")
|
|
365
|
+
+ few_shot_prompt
|
|
366
|
+
+ HumanMessagePromptTemplate.from_template("{input}")
|
|
367
|
+
)
|
|
368
|
+
# Show the prompt
|
|
369
|
+
print(final_prompt.format_messages(input="What's 3+3?")) # noqa: T201
|
|
370
|
+
|
|
371
|
+
# Use within an LLM
|
|
372
|
+
from coco_anthropic import ChatAnthropic
|
|
373
|
+
|
|
374
|
+
chain = final_prompt | ChatAnthropic(model="claude-sonnet-5")
|
|
375
|
+
chain.invoke({"input": "What's 3+3?"})
|
|
376
|
+
```
|
|
377
|
+
"""
|
|
378
|
+
|
|
379
|
+
input_variables: list[str] = Field(default_factory=list)
|
|
380
|
+
"""A list of the names of the variables the prompt template will use to pass to
|
|
381
|
+
the `example_selector`, if provided.
|
|
382
|
+
"""
|
|
383
|
+
|
|
384
|
+
example_prompt: BaseMessagePromptTemplate | BaseChatPromptTemplate
|
|
385
|
+
"""The class to format each example."""
|
|
386
|
+
|
|
387
|
+
@classmethod
|
|
388
|
+
def is_lc_serializable(cls) -> bool:
|
|
389
|
+
"""Return `False` as this class is not serializable."""
|
|
390
|
+
return False
|
|
391
|
+
|
|
392
|
+
model_config = ConfigDict(
|
|
393
|
+
arbitrary_types_allowed=True,
|
|
394
|
+
extra="forbid",
|
|
395
|
+
)
|
|
396
|
+
|
|
397
|
+
def format_messages(self, **kwargs: Any) -> list[BaseMessage]:
|
|
398
|
+
"""Format kwargs into a list of messages.
|
|
399
|
+
|
|
400
|
+
Args:
|
|
401
|
+
**kwargs: Keyword arguments to use for filling in templates in messages.
|
|
402
|
+
|
|
403
|
+
Returns:
|
|
404
|
+
A list of formatted messages with all template variables filled in.
|
|
405
|
+
"""
|
|
406
|
+
# Get the examples to use.
|
|
407
|
+
examples = self._get_examples(**kwargs)
|
|
408
|
+
examples = [
|
|
409
|
+
{k: e[k] for k in self.example_prompt.input_variables} for e in examples
|
|
410
|
+
]
|
|
411
|
+
# Format the examples.
|
|
412
|
+
return [
|
|
413
|
+
message
|
|
414
|
+
for example in examples
|
|
415
|
+
for message in self.example_prompt.format_messages(**example)
|
|
416
|
+
]
|
|
417
|
+
|
|
418
|
+
async def aformat_messages(self, **kwargs: Any) -> list[BaseMessage]:
|
|
419
|
+
"""Async format kwargs into a list of messages.
|
|
420
|
+
|
|
421
|
+
Args:
|
|
422
|
+
**kwargs: Keyword arguments to use for filling in templates in messages.
|
|
423
|
+
|
|
424
|
+
Returns:
|
|
425
|
+
A list of formatted messages with all template variables filled in.
|
|
426
|
+
"""
|
|
427
|
+
# Get the examples to use.
|
|
428
|
+
examples = await self._aget_examples(**kwargs)
|
|
429
|
+
examples = [
|
|
430
|
+
{k: e[k] for k in self.example_prompt.input_variables} for e in examples
|
|
431
|
+
]
|
|
432
|
+
# Format the examples.
|
|
433
|
+
return [
|
|
434
|
+
message
|
|
435
|
+
for example in examples
|
|
436
|
+
for message in await self.example_prompt.aformat_messages(**example)
|
|
437
|
+
]
|
|
438
|
+
|
|
439
|
+
def format(self, **kwargs: Any) -> str:
|
|
440
|
+
"""Format the prompt with inputs generating a string.
|
|
441
|
+
|
|
442
|
+
Use this method to generate a string representation of a prompt consisting of
|
|
443
|
+
chat messages.
|
|
444
|
+
|
|
445
|
+
Useful for feeding into a string-based completion language model or debugging.
|
|
446
|
+
|
|
447
|
+
Args:
|
|
448
|
+
**kwargs: Keyword arguments to use for formatting.
|
|
449
|
+
|
|
450
|
+
Returns:
|
|
451
|
+
A string representation of the prompt
|
|
452
|
+
"""
|
|
453
|
+
messages = self.format_messages(**kwargs)
|
|
454
|
+
return get_buffer_string(messages)
|
|
455
|
+
|
|
456
|
+
async def aformat(self, **kwargs: Any) -> str:
|
|
457
|
+
"""Async format the prompt with inputs generating a string.
|
|
458
|
+
|
|
459
|
+
Use this method to generate a string representation of a prompt consisting of
|
|
460
|
+
chat messages.
|
|
461
|
+
|
|
462
|
+
Useful for feeding into a string-based completion language model or debugging.
|
|
463
|
+
|
|
464
|
+
Args:
|
|
465
|
+
**kwargs: Keyword arguments to use for formatting.
|
|
466
|
+
|
|
467
|
+
Returns:
|
|
468
|
+
A string representation of the prompt
|
|
469
|
+
"""
|
|
470
|
+
messages = await self.aformat_messages(**kwargs)
|
|
471
|
+
return get_buffer_string(messages)
|
|
472
|
+
|
|
473
|
+
@override
|
|
474
|
+
def pretty_repr(self, html: bool = False) -> str:
|
|
475
|
+
"""Return a pretty representation of the prompt template.
|
|
476
|
+
|
|
477
|
+
Args:
|
|
478
|
+
html: Whether or not to return an HTML formatted string.
|
|
479
|
+
|
|
480
|
+
Returns:
|
|
481
|
+
A pretty representation of the prompt template.
|
|
482
|
+
"""
|
|
483
|
+
raise NotImplementedError
|