mirascope 2.0.0a2__py3-none-any.whl → 2.0.0a3__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.
Files changed (204) hide show
  1. mirascope/__init__.py +2 -2
  2. mirascope/api/__init__.py +6 -0
  3. mirascope/api/_generated/README.md +207 -0
  4. mirascope/api/_generated/__init__.py +85 -0
  5. mirascope/api/_generated/client.py +155 -0
  6. mirascope/api/_generated/core/__init__.py +52 -0
  7. mirascope/api/_generated/core/api_error.py +23 -0
  8. mirascope/api/_generated/core/client_wrapper.py +58 -0
  9. mirascope/api/_generated/core/datetime_utils.py +30 -0
  10. mirascope/api/_generated/core/file.py +70 -0
  11. mirascope/api/_generated/core/force_multipart.py +16 -0
  12. mirascope/api/_generated/core/http_client.py +619 -0
  13. mirascope/api/_generated/core/http_response.py +55 -0
  14. mirascope/api/_generated/core/jsonable_encoder.py +102 -0
  15. mirascope/api/_generated/core/pydantic_utilities.py +310 -0
  16. mirascope/api/_generated/core/query_encoder.py +60 -0
  17. mirascope/api/_generated/core/remove_none_from_dict.py +11 -0
  18. mirascope/api/_generated/core/request_options.py +35 -0
  19. mirascope/api/_generated/core/serialization.py +282 -0
  20. mirascope/api/_generated/docs/__init__.py +4 -0
  21. mirascope/api/_generated/docs/client.py +95 -0
  22. mirascope/api/_generated/docs/raw_client.py +132 -0
  23. mirascope/api/_generated/environment.py +9 -0
  24. mirascope/api/_generated/errors/__init__.py +7 -0
  25. mirascope/api/_generated/errors/bad_request_error.py +15 -0
  26. mirascope/api/_generated/health/__init__.py +7 -0
  27. mirascope/api/_generated/health/client.py +96 -0
  28. mirascope/api/_generated/health/raw_client.py +129 -0
  29. mirascope/api/_generated/health/types/__init__.py +8 -0
  30. mirascope/api/_generated/health/types/health_check_response.py +24 -0
  31. mirascope/api/_generated/health/types/health_check_response_status.py +5 -0
  32. mirascope/api/_generated/reference.md +167 -0
  33. mirascope/api/_generated/traces/__init__.py +55 -0
  34. mirascope/api/_generated/traces/client.py +162 -0
  35. mirascope/api/_generated/traces/raw_client.py +168 -0
  36. mirascope/api/_generated/traces/types/__init__.py +95 -0
  37. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item.py +36 -0
  38. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource.py +31 -0
  39. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item.py +25 -0
  40. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value.py +54 -0
  41. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_array_value.py +23 -0
  42. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_kvlist_value.py +28 -0
  43. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_kvlist_value_values_item.py +24 -0
  44. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item.py +35 -0
  45. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope.py +35 -0
  46. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item.py +27 -0
  47. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value.py +54 -0
  48. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_array_value.py +23 -0
  49. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_kvlist_value.py +28 -0
  50. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_kvlist_value_values_item.py +24 -0
  51. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item.py +60 -0
  52. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item.py +29 -0
  53. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value.py +54 -0
  54. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_array_value.py +23 -0
  55. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_kvlist_value.py +28 -0
  56. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_kvlist_value_values_item.py +24 -0
  57. mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_status.py +24 -0
  58. mirascope/api/_generated/traces/types/traces_create_response.py +27 -0
  59. mirascope/api/_generated/traces/types/traces_create_response_partial_success.py +28 -0
  60. mirascope/api/_generated/types/__init__.py +21 -0
  61. mirascope/api/_generated/types/http_api_decode_error.py +31 -0
  62. mirascope/api/_generated/types/http_api_decode_error_tag.py +5 -0
  63. mirascope/api/_generated/types/issue.py +44 -0
  64. mirascope/api/_generated/types/issue_tag.py +17 -0
  65. mirascope/api/_generated/types/property_key.py +7 -0
  66. mirascope/api/_generated/types/property_key_tag.py +29 -0
  67. mirascope/api/_generated/types/property_key_tag_tag.py +5 -0
  68. mirascope/api/client.py +255 -0
  69. mirascope/api/settings.py +81 -0
  70. mirascope/llm/__init__.py +41 -11
  71. mirascope/llm/calls/calls.py +81 -57
  72. mirascope/llm/calls/decorator.py +121 -115
  73. mirascope/llm/content/__init__.py +3 -2
  74. mirascope/llm/context/_utils.py +19 -6
  75. mirascope/llm/exceptions.py +30 -16
  76. mirascope/llm/formatting/_utils.py +9 -5
  77. mirascope/llm/formatting/format.py +2 -2
  78. mirascope/llm/formatting/from_call_args.py +2 -2
  79. mirascope/llm/messages/message.py +13 -5
  80. mirascope/llm/models/__init__.py +2 -2
  81. mirascope/llm/models/models.py +189 -81
  82. mirascope/llm/prompts/__init__.py +13 -12
  83. mirascope/llm/prompts/_utils.py +27 -24
  84. mirascope/llm/prompts/decorator.py +133 -204
  85. mirascope/llm/prompts/prompts.py +424 -0
  86. mirascope/llm/prompts/protocols.py +25 -59
  87. mirascope/llm/providers/__init__.py +38 -0
  88. mirascope/llm/{clients → providers}/_missing_import_stubs.py +8 -6
  89. mirascope/llm/providers/anthropic/__init__.py +24 -0
  90. mirascope/llm/{clients → providers}/anthropic/_utils/decode.py +5 -4
  91. mirascope/llm/{clients → providers}/anthropic/_utils/encode.py +31 -10
  92. mirascope/llm/providers/anthropic/model_id.py +40 -0
  93. mirascope/llm/{clients/anthropic/clients.py → providers/anthropic/provider.py} +33 -418
  94. mirascope/llm/{clients → providers}/base/__init__.py +3 -3
  95. mirascope/llm/{clients → providers}/base/_utils.py +10 -7
  96. mirascope/llm/{clients/base/client.py → providers/base/base_provider.py} +255 -126
  97. mirascope/llm/providers/google/__init__.py +21 -0
  98. mirascope/llm/{clients → providers}/google/_utils/decode.py +6 -4
  99. mirascope/llm/{clients → providers}/google/_utils/encode.py +30 -24
  100. mirascope/llm/providers/google/model_id.py +28 -0
  101. mirascope/llm/providers/google/provider.py +438 -0
  102. mirascope/llm/providers/load_provider.py +48 -0
  103. mirascope/llm/providers/mlx/__init__.py +24 -0
  104. mirascope/llm/providers/mlx/_utils.py +107 -0
  105. mirascope/llm/providers/mlx/encoding/__init__.py +8 -0
  106. mirascope/llm/providers/mlx/encoding/base.py +69 -0
  107. mirascope/llm/providers/mlx/encoding/transformers.py +131 -0
  108. mirascope/llm/providers/mlx/mlx.py +237 -0
  109. mirascope/llm/providers/mlx/model_id.py +17 -0
  110. mirascope/llm/providers/mlx/provider.py +411 -0
  111. mirascope/llm/providers/model_id.py +16 -0
  112. mirascope/llm/providers/openai/__init__.py +6 -0
  113. mirascope/llm/providers/openai/completions/__init__.py +20 -0
  114. mirascope/llm/{clients/openai/responses → providers/openai/completions}/_utils/__init__.py +2 -0
  115. mirascope/llm/{clients → providers}/openai/completions/_utils/decode.py +5 -3
  116. mirascope/llm/{clients → providers}/openai/completions/_utils/encode.py +33 -23
  117. mirascope/llm/providers/openai/completions/provider.py +456 -0
  118. mirascope/llm/providers/openai/model_id.py +31 -0
  119. mirascope/llm/providers/openai/model_info.py +246 -0
  120. mirascope/llm/providers/openai/provider.py +386 -0
  121. mirascope/llm/providers/openai/responses/__init__.py +21 -0
  122. mirascope/llm/{clients → providers}/openai/responses/_utils/decode.py +5 -3
  123. mirascope/llm/{clients → providers}/openai/responses/_utils/encode.py +28 -17
  124. mirascope/llm/providers/openai/responses/provider.py +470 -0
  125. mirascope/llm/{clients → providers}/openai/shared/_utils.py +7 -3
  126. mirascope/llm/providers/provider_id.py +13 -0
  127. mirascope/llm/providers/provider_registry.py +167 -0
  128. mirascope/llm/responses/base_response.py +10 -5
  129. mirascope/llm/responses/base_stream_response.py +10 -5
  130. mirascope/llm/responses/response.py +24 -13
  131. mirascope/llm/responses/root_response.py +7 -12
  132. mirascope/llm/responses/stream_response.py +35 -23
  133. mirascope/llm/tools/__init__.py +9 -2
  134. mirascope/llm/tools/_utils.py +12 -3
  135. mirascope/llm/tools/protocols.py +4 -4
  136. mirascope/llm/tools/tool_schema.py +44 -9
  137. mirascope/llm/tools/tools.py +10 -9
  138. mirascope/ops/__init__.py +156 -0
  139. mirascope/ops/_internal/__init__.py +5 -0
  140. mirascope/ops/_internal/closure.py +1118 -0
  141. mirascope/ops/_internal/configuration.py +126 -0
  142. mirascope/ops/_internal/context.py +76 -0
  143. mirascope/ops/_internal/exporters/__init__.py +26 -0
  144. mirascope/ops/_internal/exporters/exporters.py +342 -0
  145. mirascope/ops/_internal/exporters/processors.py +104 -0
  146. mirascope/ops/_internal/exporters/types.py +165 -0
  147. mirascope/ops/_internal/exporters/utils.py +29 -0
  148. mirascope/ops/_internal/instrumentation/__init__.py +8 -0
  149. mirascope/ops/_internal/instrumentation/llm/__init__.py +8 -0
  150. mirascope/ops/_internal/instrumentation/llm/encode.py +238 -0
  151. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/__init__.py +38 -0
  152. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_input_messages.py +31 -0
  153. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_output_messages.py +38 -0
  154. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_system_instructions.py +18 -0
  155. mirascope/ops/_internal/instrumentation/llm/gen_ai_types/shared.py +100 -0
  156. mirascope/ops/_internal/instrumentation/llm/llm.py +1288 -0
  157. mirascope/ops/_internal/propagation.py +198 -0
  158. mirascope/ops/_internal/protocols.py +51 -0
  159. mirascope/ops/_internal/session.py +139 -0
  160. mirascope/ops/_internal/spans.py +232 -0
  161. mirascope/ops/_internal/traced_calls.py +371 -0
  162. mirascope/ops/_internal/traced_functions.py +394 -0
  163. mirascope/ops/_internal/tracing.py +276 -0
  164. mirascope/ops/_internal/types.py +13 -0
  165. mirascope/ops/_internal/utils.py +75 -0
  166. mirascope/ops/_internal/versioned_calls.py +512 -0
  167. mirascope/ops/_internal/versioned_functions.py +346 -0
  168. mirascope/ops/_internal/versioning.py +303 -0
  169. mirascope/ops/exceptions.py +21 -0
  170. {mirascope-2.0.0a2.dist-info → mirascope-2.0.0a3.dist-info}/METADATA +76 -1
  171. mirascope-2.0.0a3.dist-info/RECORD +206 -0
  172. {mirascope-2.0.0a2.dist-info → mirascope-2.0.0a3.dist-info}/WHEEL +1 -1
  173. mirascope/graphs/__init__.py +0 -22
  174. mirascope/graphs/finite_state_machine.py +0 -625
  175. mirascope/llm/agents/__init__.py +0 -15
  176. mirascope/llm/agents/agent.py +0 -97
  177. mirascope/llm/agents/agent_template.py +0 -45
  178. mirascope/llm/agents/decorator.py +0 -176
  179. mirascope/llm/calls/base_call.py +0 -33
  180. mirascope/llm/clients/__init__.py +0 -34
  181. mirascope/llm/clients/anthropic/__init__.py +0 -25
  182. mirascope/llm/clients/anthropic/model_ids.py +0 -8
  183. mirascope/llm/clients/google/__init__.py +0 -20
  184. mirascope/llm/clients/google/clients.py +0 -853
  185. mirascope/llm/clients/google/model_ids.py +0 -15
  186. mirascope/llm/clients/openai/__init__.py +0 -25
  187. mirascope/llm/clients/openai/completions/__init__.py +0 -28
  188. mirascope/llm/clients/openai/completions/_utils/model_features.py +0 -81
  189. mirascope/llm/clients/openai/completions/clients.py +0 -833
  190. mirascope/llm/clients/openai/completions/model_ids.py +0 -8
  191. mirascope/llm/clients/openai/responses/__init__.py +0 -26
  192. mirascope/llm/clients/openai/responses/_utils/model_features.py +0 -87
  193. mirascope/llm/clients/openai/responses/clients.py +0 -832
  194. mirascope/llm/clients/openai/responses/model_ids.py +0 -8
  195. mirascope/llm/clients/providers.py +0 -175
  196. mirascope-2.0.0a2.dist-info/RECORD +0 -102
  197. /mirascope/llm/{clients → providers}/anthropic/_utils/__init__.py +0 -0
  198. /mirascope/llm/{clients → providers}/base/kwargs.py +0 -0
  199. /mirascope/llm/{clients → providers}/base/params.py +0 -0
  200. /mirascope/llm/{clients → providers}/google/_utils/__init__.py +0 -0
  201. /mirascope/llm/{clients → providers}/google/message.py +0 -0
  202. /mirascope/llm/{clients/openai/completions → providers/openai/responses}/_utils/__init__.py +0 -0
  203. /mirascope/llm/{clients → providers}/openai/shared/__init__.py +0 -0
  204. {mirascope-2.0.0a2.dist-info → mirascope-2.0.0a3.dist-info}/licenses/LICENSE +0 -0
@@ -1,196 +1,165 @@
1
1
  """The `prompt` decorator for writing messages as string templates."""
2
2
 
3
- from typing import overload
4
-
5
- from ..context import Context, DepsT
6
- from ..messages import (
7
- Message,
3
+ from collections.abc import Sequence
4
+ from typing import Generic, cast, overload
5
+
6
+ from ..context import DepsT
7
+ from ..formatting import Format, FormattableT
8
+ from ..tools import (
9
+ AsyncContextTool,
10
+ AsyncContextToolkit,
11
+ AsyncTool,
12
+ AsyncToolkit,
13
+ ContextTool,
14
+ ContextToolkit,
15
+ Tool,
16
+ Toolkit,
17
+ ToolT,
8
18
  )
9
19
  from ..types import P
10
20
  from . import _utils
11
- from .protocols import (
21
+ from .prompts import (
12
22
  AsyncContextPrompt,
13
- AsyncContextPromptable,
14
23
  AsyncPrompt,
15
- AsyncPromptable,
16
24
  ContextPrompt,
17
- ContextPromptable,
18
25
  Prompt,
19
- Promptable,
26
+ )
27
+ from .protocols import (
28
+ AsyncContextMessageTemplate,
29
+ AsyncMessageTemplate,
30
+ ContextMessageTemplate,
31
+ MessageTemplate,
20
32
  )
21
33
 
22
34
 
23
- class PromptDecorator:
24
- """Protocol for the `prompt` decorator when used without a template."""
35
+ class PromptDecorator(Generic[ToolT, FormattableT]):
36
+ """Decorator for converting a `MessageTemplate` into a `Prompt`.
25
37
 
26
- @overload
27
- def __call__(
38
+ Takes a raw prompt function that returns message content and wraps it with
39
+ tools and format support, creating a `Prompt` that can be called with a model.
40
+
41
+ The decorator automatically detects whether the function is async or context-aware
42
+ and creates the appropriate Prompt variant (Prompt, AsyncPrompt, ContextPrompt,
43
+ or AsyncContextPrompt).
44
+ """
45
+
46
+ tools: Sequence[ToolT] | None
47
+ """The tools that are included in the prompt, if any."""
48
+
49
+ format: type[FormattableT] | Format[FormattableT] | None
50
+ """The structured output format off the prompt, if any."""
51
+
52
+ def __init__(
28
53
  self,
29
- fn: ContextPromptable[P, DepsT],
30
- ) -> ContextPrompt[P, DepsT]:
31
- """Decorator for creating context prompts."""
32
- ...
54
+ tools: Sequence[ToolT] | None = None,
55
+ format: type[FormattableT] | Format[FormattableT] | None = None,
56
+ ) -> None:
57
+ """Initialize the decorator with optional tools and format."""
58
+ self.tools = tools
59
+ self.format = format
33
60
 
34
61
  @overload
35
62
  def __call__(
36
- self,
37
- fn: AsyncContextPromptable[P, DepsT],
38
- ) -> AsyncContextPrompt[P, DepsT]:
63
+ self: "PromptDecorator[AsyncTool | AsyncContextTool[DepsT], FormattableT]",
64
+ fn: AsyncContextMessageTemplate[P, DepsT],
65
+ ) -> AsyncContextPrompt[P, DepsT, FormattableT]:
39
66
  """Decorator for creating async context prompts."""
40
67
  ...
41
68
 
42
69
  @overload
43
70
  def __call__(
44
- self,
45
- fn: Promptable[P],
46
- ) -> Prompt[P]:
47
- """Decorator for creating prompts."""
71
+ self: "PromptDecorator[Tool | ContextTool[DepsT], FormattableT]",
72
+ fn: ContextMessageTemplate[P, DepsT],
73
+ ) -> ContextPrompt[P, DepsT, FormattableT]:
74
+ """Decorator for creating context prompts."""
48
75
  ...
49
76
 
50
77
  @overload
51
78
  def __call__(
52
- self,
53
- fn: AsyncPromptable[P],
54
- ) -> AsyncPrompt[P]:
79
+ self: "PromptDecorator[AsyncTool, FormattableT]",
80
+ fn: AsyncMessageTemplate[P],
81
+ ) -> AsyncPrompt[P, FormattableT]:
55
82
  """Decorator for creating async prompts."""
56
83
  ...
57
84
 
85
+ @overload
86
+ def __call__(
87
+ self: "PromptDecorator[Tool, FormattableT]",
88
+ fn: MessageTemplate[P],
89
+ ) -> Prompt[P, FormattableT]:
90
+ """Decorator for creating prompts."""
91
+ ...
92
+
58
93
  def __call__(
59
94
  self,
60
- fn: ContextPromptable[P, DepsT]
61
- | AsyncContextPromptable[P, DepsT]
62
- | Promptable[P]
63
- | AsyncPromptable[P],
95
+ fn: ContextMessageTemplate[P, DepsT]
96
+ | AsyncContextMessageTemplate[P, DepsT]
97
+ | MessageTemplate[P]
98
+ | AsyncMessageTemplate[P],
64
99
  ) -> (
65
- Prompt[P]
66
- | AsyncPrompt[P]
67
- | ContextPrompt[P, DepsT]
68
- | AsyncContextPrompt[P, DepsT]
100
+ Prompt[P, FormattableT]
101
+ | AsyncPrompt[P, FormattableT]
102
+ | ContextPrompt[P, DepsT, FormattableT]
103
+ | AsyncContextPrompt[P, DepsT, FormattableT]
69
104
  ):
70
- """Decorator for creating a prompt."""
105
+ """Decorator for creating a prompt with tools and format."""
71
106
  is_context = _utils.is_context_promptable(fn)
72
107
  is_async = _utils.is_async_promptable(fn)
73
108
 
74
- # NOTE: unused `fn` expressions work around a Pyright bug
75
- # TODO: Clean this up once the following Pyright bug is addressed:
76
- # https://github.com/microsoft/pyright/issues/10951
77
109
  if is_context and is_async:
78
- fn # pyright: ignore[reportUnusedExpression] # noqa: B018
79
-
80
- async def async_context_prompt(
81
- ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
82
- ) -> list[Message]:
83
- result = await fn(ctx, *args, **kwargs)
84
- return _utils.promote_to_messages(result)
85
-
86
- return async_context_prompt
110
+ tools = cast(
111
+ Sequence[AsyncTool | AsyncContextTool[DepsT]] | None, self.tools
112
+ )
113
+ return AsyncContextPrompt(
114
+ fn=fn,
115
+ toolkit=AsyncContextToolkit(tools=tools),
116
+ format=self.format,
117
+ )
87
118
  elif is_context:
88
- fn # pyright: ignore[reportUnusedExpression] # noqa: B018
89
-
90
- def context_prompt(
91
- ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
92
- ) -> list[Message]:
93
- result = fn(ctx, *args, **kwargs)
94
- return _utils.promote_to_messages(result)
95
-
96
- return context_prompt
119
+ tools = cast(Sequence[Tool | ContextTool[DepsT]] | None, self.tools)
120
+ return ContextPrompt(
121
+ fn=fn,
122
+ toolkit=ContextToolkit(tools=tools),
123
+ format=self.format,
124
+ )
97
125
  elif is_async:
98
- fn # pyright: ignore[reportUnusedExpression] # noqa: B018
99
-
100
- async def async_prompt(*args: P.args, **kwargs: P.kwargs) -> list[Message]:
101
- result = await fn(*args, **kwargs)
102
- return _utils.promote_to_messages(result)
103
-
104
- return async_prompt
126
+ tools = cast(Sequence[AsyncTool] | None, self.tools)
127
+ return AsyncPrompt(
128
+ fn=fn, toolkit=AsyncToolkit(tools=tools), format=self.format
129
+ )
105
130
  else:
106
- fn # pyright: ignore[reportUnusedExpression] # noqa: B018
107
-
108
- def prompt(*args: P.args, **kwargs: P.kwargs) -> list[Message]:
109
- result = fn(*args, **kwargs)
110
- return _utils.promote_to_messages(result)
111
-
112
- return prompt
113
-
114
-
115
- class PromptTemplateDecorator:
116
- """Protocol for the `prompt` decorator when used with a template."""
117
-
118
- @overload
119
- def __call__(
120
- self,
121
- fn: ContextPromptable[P, DepsT],
122
- ) -> ContextPrompt[P, DepsT]:
123
- """Decorator for creating context prompts from template functions."""
124
- ...
125
-
126
- @overload
127
- def __call__(
128
- self,
129
- fn: AsyncContextPromptable[P, DepsT],
130
- ) -> AsyncContextPrompt[P, DepsT]:
131
- """Decorator for creating async context prompts from template functions."""
132
- ...
133
-
134
- @overload
135
- def __call__(
136
- self,
137
- fn: Promptable[P],
138
- ) -> Prompt[P]:
139
- """Decorator for creating prompts from template functions."""
140
- ...
141
-
142
- @overload
143
- def __call__(
144
- self,
145
- fn: AsyncPromptable[P],
146
- ) -> AsyncPrompt[P]:
147
- """Decorator for creating async prompts from template functions."""
148
- ...
149
-
150
- def __call__(
151
- self,
152
- fn: ContextPromptable[P, DepsT]
153
- | AsyncContextPromptable[P, DepsT]
154
- | Promptable[P]
155
- | AsyncPromptable[P],
156
- ) -> (
157
- Prompt[P]
158
- | AsyncPrompt[P]
159
- | ContextPrompt[P, DepsT]
160
- | AsyncContextPrompt[P, DepsT]
161
- ):
162
- """Decorator for creating a prompt from a template function."""
163
- raise NotImplementedError()
131
+ tools = cast(Sequence[Tool] | None, self.tools)
132
+ return Prompt(fn=fn, toolkit=Toolkit(tools=tools), format=self.format)
164
133
 
165
134
 
166
135
  @overload
167
- def prompt(
168
- __fn: ContextPromptable[P, DepsT],
169
- ) -> ContextPrompt[P, DepsT]:
136
+ def prompt( # pyright: ignore[reportOverlappingOverload]
137
+ __fn: ContextMessageTemplate[P, DepsT],
138
+ ) -> ContextPrompt[P, DepsT, None]:
170
139
  """Create a decorator for sync ContextPrompt functions (no arguments)."""
171
140
  ...
172
141
 
173
142
 
174
143
  @overload
175
- def prompt(
176
- __fn: AsyncContextPromptable[P, DepsT],
177
- ) -> AsyncContextPrompt[P, DepsT]:
144
+ def prompt( # pyright: ignore[reportOverlappingOverload]
145
+ __fn: AsyncContextMessageTemplate[P, DepsT],
146
+ ) -> AsyncContextPrompt[P, DepsT, None]:
178
147
  """Create a decorator for async ContextPrompt functions (no arguments)."""
179
148
  ...
180
149
 
181
150
 
182
151
  @overload
183
152
  def prompt(
184
- __fn: Promptable[P],
185
- ) -> Prompt[P]:
153
+ __fn: MessageTemplate[P],
154
+ ) -> Prompt[P, None]:
186
155
  """Create a decorator for sync Prompt functions (no arguments)."""
187
156
  ...
188
157
 
189
158
 
190
159
  @overload
191
160
  def prompt(
192
- __fn: AsyncPromptable[P],
193
- ) -> AsyncPrompt[P]:
161
+ __fn: AsyncMessageTemplate[P],
162
+ ) -> AsyncPrompt[P, None]:
194
163
  """Create a decorator for async Prompt functions (no arguments)."""
195
164
  ...
196
165
 
@@ -198,89 +167,49 @@ def prompt(
198
167
  @overload
199
168
  def prompt(
200
169
  *,
201
- template: None = None,
202
- ) -> PromptDecorator:
203
- """Create a decorator for Prompt functions (no template)"""
170
+ tools: Sequence[ToolT] | None = None,
171
+ format: type[FormattableT] | Format[FormattableT] | None = None,
172
+ ) -> PromptDecorator[ToolT, FormattableT]:
173
+ """Create a decorator for Prompt functions with tools and format"""
204
174
 
205
175
 
206
- @overload
207
176
  def prompt(
208
- *,
209
- template: str,
210
- ) -> PromptTemplateDecorator:
211
- """Create a decorator for template functions."""
212
- ...
213
-
214
-
215
- def prompt(
216
- __fn: ContextPromptable[P, DepsT]
217
- | AsyncContextPromptable[P, DepsT]
218
- | Promptable[P]
219
- | AsyncPromptable[P]
177
+ __fn: AsyncContextMessageTemplate[P, DepsT]
178
+ | ContextMessageTemplate[P, DepsT]
179
+ | AsyncMessageTemplate[P]
180
+ | MessageTemplate[P]
220
181
  | None = None,
221
182
  *,
222
- template: str | None = None,
183
+ tools: Sequence[ToolT] | None = None,
184
+ format: type[FormattableT] | Format[FormattableT] | None = None,
223
185
  ) -> (
224
- ContextPrompt[P, DepsT]
225
- | AsyncContextPrompt[P, DepsT]
226
- | Prompt[P]
227
- | AsyncPrompt[P]
228
- | PromptDecorator
229
- | PromptTemplateDecorator
186
+ AsyncContextPrompt[P, DepsT, FormattableT]
187
+ | ContextPrompt[P, DepsT, FormattableT]
188
+ | AsyncPrompt[P, FormattableT]
189
+ | Prompt[P, FormattableT]
190
+ | PromptDecorator[ToolT, FormattableT]
230
191
  ):
231
- """Prompt decorator for turning functions (or "Prompts") into prompts.
232
-
233
- This decorator transforms a function into a Prompt, i.e. a function that
234
- returns `list[llm.Message]`. Its behavior depends on whether it's called with a spec
235
- string.
192
+ """Decorates a `MessageTemplate` to create a `Prompt` callable with a model.
236
193
 
237
- If the first parameter is named 'ctx' or typed as `llm.Context[T]`, it creates
238
- a ContextPrompt. Otherwise, it creates a regular Prompt.
194
+ This decorator transforms a raw prompt function (that returns message content)
195
+ into a `Prompt` object that can be invoked with a model to generate LLM responses.
239
196
 
240
- With a template string, it returns a PromptTemplateDecorator, in which case it uses
241
- the provided template to decorate an function with an empty body, and uses arguments
242
- to the function for variable substitution in the template. The resulting PromptTemplate
243
- returns messages based on the template.
244
-
245
- Without a template string, it returns a PromptFunctionalDecorator, which
246
- transforms a Prompt (a function returning either message content, or messages) into
247
- a PromptTemplate. The resulting prompt template either promotes the content into a
248
- list containing a single user message, or passes along the messages returned by the
249
- decorated function.
197
+ The decorator automatically detects the function type:
198
+ - If the first parameter is named `'ctx'` with type `llm.Context[T]`, creates a `ContextPrompt`
199
+ - If the function is async, creates an `AsyncPrompt` or `AsyncContextPrompt`
200
+ - Otherwise, creates a regular `Prompt`
250
201
 
251
202
  Args:
252
- template: A string template with placeholders using `{{ variable_name }}`
253
- and optional role markers like [SYSTEM], [USER], and [ASSISTANT].
203
+ __fn: The prompt function to decorate (optional, for decorator syntax without parens)
204
+ tools: Optional `Sequence` of tools to make available to the LLM
205
+ format: Optional response format class (`BaseModel`) or Format instance
254
206
 
255
207
  Returns:
256
- A PromptTemplateDecorator or PromptFunctionalDecorator that converts
257
- the decorated function into a prompt.
258
-
259
- Spec substitution rules:
260
- - [USER], [ASSISTANT], [SYSTEM] demarcate the start of a new message with that role
261
- - [MESSAGES] indicates the next variable contains a list of messages to include
262
- - `{{ variable }}` injects the variable as a string, unless annotated
263
- - Annotations: `{{ variable:annotation }}` where annotation is one of:
264
- image, images, audio, audios, document, documents
265
- - Single content annotations (image, audio, document) expect a file path,
266
- URL, base64 string, or bytes, which becomes a content part with inferred mime-type
267
- - Multiple content annotations (images, audios, documents) expect a list
268
- of strings or bytes, each becoming a content part with inferred mime-type
269
-
270
- Examples:
271
- ```python
272
- @llm.prompt
273
- def answer_question(question: str) -> str:
274
- return f"Answer this question: {question}"
275
-
276
- @llm.prompt
277
- def answer_with_context(ctx: llm.Context[str], question: str) -> str:
278
- return f"Using context {ctx.deps}, answer: {question}"
279
- ```
280
- """ # TODO(docs): Update this docstring
281
- if template:
282
- raise NotImplementedError()
283
- decorator = PromptDecorator()
208
+ A `Prompt` variant (Prompt, AsyncPrompt, ContextPrompt, or AsyncContextPrompt)
209
+ or a `PromptDecorator` if called with arguments
210
+ """
211
+ decorator = PromptDecorator(tools=tools, format=format)
284
212
  if __fn is None:
285
213
  return decorator
286
- return decorator(__fn)
214
+ # TODO: See if we can do without the pyright: ignores here
215
+ return decorator(__fn) # pyright: ignore[reportUnknownVariableType, reportCallIssue]