azure-functions-durable 1.3.2__py3-none-any.whl → 1.4.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.
Files changed (26) hide show
  1. azure/durable_functions/__init__.py +8 -0
  2. azure/durable_functions/decorators/durable_app.py +64 -1
  3. azure/durable_functions/models/DurableOrchestrationContext.py +24 -0
  4. azure/durable_functions/openai_agents/__init__.py +13 -0
  5. azure/durable_functions/openai_agents/context.py +194 -0
  6. azure/durable_functions/openai_agents/event_loop.py +17 -0
  7. azure/durable_functions/openai_agents/exceptions.py +11 -0
  8. azure/durable_functions/openai_agents/handoffs.py +67 -0
  9. azure/durable_functions/openai_agents/model_invocation_activity.py +268 -0
  10. azure/durable_functions/openai_agents/orchestrator_generator.py +67 -0
  11. azure/durable_functions/openai_agents/runner.py +103 -0
  12. azure/durable_functions/openai_agents/task_tracker.py +171 -0
  13. azure/durable_functions/openai_agents/tools.py +148 -0
  14. azure/durable_functions/openai_agents/usage_telemetry.py +69 -0
  15. {azure_functions_durable-1.3.2.dist-info → azure_functions_durable-1.4.0.dist-info}/METADATA +7 -2
  16. {azure_functions_durable-1.3.2.dist-info → azure_functions_durable-1.4.0.dist-info}/RECORD +26 -9
  17. tests/models/test_DurableOrchestrationContext.py +8 -0
  18. tests/openai_agents/__init__.py +0 -0
  19. tests/openai_agents/test_context.py +466 -0
  20. tests/openai_agents/test_task_tracker.py +290 -0
  21. tests/openai_agents/test_usage_telemetry.py +99 -0
  22. tests/orchestrator/openai_agents/__init__.py +0 -0
  23. tests/orchestrator/openai_agents/test_openai_agents.py +316 -0
  24. {azure_functions_durable-1.3.2.dist-info → azure_functions_durable-1.4.0.dist-info}/LICENSE +0 -0
  25. {azure_functions_durable-1.3.2.dist-info → azure_functions_durable-1.4.0.dist-info}/WHEEL +0 -0
  26. {azure_functions_durable-1.3.2.dist-info → azure_functions_durable-1.4.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,148 @@
1
+ # Copyright (c) Microsoft Corporation. All rights reserved.
2
+ # Licensed under the MIT License.
3
+ """Tool conversion utilities for Azure Durable Functions OpenAI agent operations."""
4
+
5
+ from typing import Any, Union
6
+
7
+ from agents import (
8
+ CodeInterpreterTool,
9
+ FileSearchTool,
10
+ FunctionTool,
11
+ HostedMCPTool,
12
+ ImageGenerationTool,
13
+ Tool,
14
+ UserError,
15
+ WebSearchTool,
16
+ )
17
+ from openai.types.responses.tool_param import Mcp
18
+ from pydantic import BaseModel
19
+
20
+
21
+ # Built-in tool types that can be serialized directly without conversion
22
+ BUILT_IN_TOOL_TYPES = (
23
+ FileSearchTool,
24
+ WebSearchTool,
25
+ ImageGenerationTool,
26
+ CodeInterpreterTool,
27
+ )
28
+
29
+
30
+ class DurableFunctionTool(BaseModel):
31
+ """Serializable representation of a FunctionTool.
32
+
33
+ Contains only the data needed by the model execution to
34
+ determine what tool to call, not the actual tool invocation.
35
+ """
36
+
37
+ name: str
38
+ description: str
39
+ params_json_schema: dict[str, Any]
40
+ strict_json_schema: bool = True
41
+
42
+
43
+ class DurableMCPToolConfig(BaseModel):
44
+ """Serializable representation of a HostedMCPTool.
45
+
46
+ Contains only the data needed by the model execution to
47
+ determine what tool to call, not the actual tool invocation.
48
+ """
49
+
50
+ tool_config: Mcp
51
+
52
+
53
+ DurableTool = Union[
54
+ DurableFunctionTool,
55
+ FileSearchTool,
56
+ WebSearchTool,
57
+ ImageGenerationTool,
58
+ CodeInterpreterTool,
59
+ DurableMCPToolConfig,
60
+ ]
61
+
62
+
63
+ def create_tool_from_durable_tool(
64
+ durable_tool: DurableTool,
65
+ ) -> Tool:
66
+ """Convert a DurableTool to an OpenAI agent Tool for execution.
67
+
68
+ This function transforms Durable Functions tool definitions into actual
69
+ OpenAI agent Tool instances that can be used during model execution.
70
+
71
+ Parameters
72
+ ----------
73
+ durable_tool : DurableTool
74
+ The Durable tool definition to convert
75
+
76
+ Returns
77
+ -------
78
+ Tool
79
+ An OpenAI agent Tool instance ready for execution
80
+
81
+ Raises
82
+ ------
83
+ UserError
84
+ If the tool type is not supported
85
+ """
86
+ # Built-in tools that don't need conversion
87
+ if isinstance(durable_tool, BUILT_IN_TOOL_TYPES):
88
+ return durable_tool
89
+
90
+ # Convert Durable MCP tool configuration to HostedMCPTool
91
+ if isinstance(durable_tool, DurableMCPToolConfig):
92
+ return HostedMCPTool(
93
+ tool_config=durable_tool.tool_config,
94
+ )
95
+
96
+ # Convert Durable function tool to FunctionTool
97
+ if isinstance(durable_tool, DurableFunctionTool):
98
+ return FunctionTool(
99
+ name=durable_tool.name,
100
+ description=durable_tool.description,
101
+ params_json_schema=durable_tool.params_json_schema,
102
+ on_invoke_tool=lambda ctx, input: "",
103
+ strict_json_schema=durable_tool.strict_json_schema,
104
+ )
105
+
106
+ raise UserError(f"Unsupported tool type: {durable_tool}")
107
+
108
+
109
+ def convert_tool_to_durable_tool(tool: Tool) -> DurableTool:
110
+ """Convert an OpenAI agent Tool to a DurableTool for serialization.
111
+
112
+ This function transforms OpenAI agent Tool instances into Durable Functions
113
+ tool definitions that can be serialized and passed to activities.
114
+
115
+ Parameters
116
+ ----------
117
+ tool : Tool
118
+ The OpenAI agent Tool to convert
119
+
120
+ Returns
121
+ -------
122
+ DurableTool
123
+ A serializable tool definition
124
+
125
+ Raises
126
+ ------
127
+ ValueError
128
+ If the tool type is not supported for conversion
129
+ """
130
+ # Built-in tools that can be serialized directly
131
+ if isinstance(tool, BUILT_IN_TOOL_TYPES):
132
+ return tool
133
+
134
+ # Convert HostedMCPTool to Durable MCP configuration
135
+ elif isinstance(tool, HostedMCPTool):
136
+ return DurableMCPToolConfig(tool_config=tool.tool_config)
137
+
138
+ # Convert FunctionTool to Durable function tool
139
+ elif isinstance(tool, FunctionTool):
140
+ return DurableFunctionTool(
141
+ name=tool.name,
142
+ description=tool.description,
143
+ params_json_schema=tool.params_json_schema,
144
+ strict_json_schema=tool.strict_json_schema,
145
+ )
146
+
147
+ else:
148
+ raise ValueError(f"Unsupported tool type for Durable Functions: {type(tool).__name__}")
@@ -0,0 +1,69 @@
1
+ # Copyright (c) Microsoft Corporation. All rights reserved.
2
+ # Licensed under the MIT License.
3
+
4
+
5
+ class UsageTelemetry:
6
+ """Handles telemetry logging for OpenAI Agents SDK integration usage."""
7
+
8
+ # Class-level flag to ensure logging happens only once across all instances
9
+ _usage_logged = False
10
+
11
+ @classmethod
12
+ def log_usage_once(cls):
13
+ """Log OpenAI Agents SDK integration usage exactly once.
14
+
15
+ Fails gracefully if metadata cannot be retrieved.
16
+ """
17
+ if cls._usage_logged:
18
+ return
19
+
20
+ # NOTE: Any log line beginning with the special prefix defined below will be
21
+ # captured by the Azure Functions host as a Language Worker console log and
22
+ # forwarded to internal telemetry pipelines.
23
+ # Do not change this constant value without coordinating with the Functions
24
+ # host team.
25
+ LANGUAGE_WORKER_CONSOLE_LOG_PREFIX = "LanguageWorkerConsoleLog"
26
+
27
+ package_versions = cls._collect_openai_agent_package_versions()
28
+ msg = (
29
+ f"{LANGUAGE_WORKER_CONSOLE_LOG_PREFIX}" # Prefix captured by Azure Functions host
30
+ "Detected OpenAI Agents SDK integration with Durable Functions. "
31
+ f"Package versions: {package_versions}"
32
+ )
33
+ print(msg)
34
+
35
+ cls._usage_logged = True
36
+
37
+ @classmethod
38
+ def _collect_openai_agent_package_versions(cls) -> str:
39
+ """Collect versions of relevant packages for telemetry logging.
40
+
41
+ Returns
42
+ -------
43
+ str
44
+ Comma-separated list of name=version entries or "(unavailable)" if
45
+ versions could not be determined.
46
+ """
47
+ try:
48
+ try:
49
+ from importlib import metadata # Python 3.8+
50
+ except ImportError: # pragma: no cover - legacy fallback
51
+ import importlib_metadata as metadata # type: ignore
52
+
53
+ package_names = [
54
+ "azure-functions-durable",
55
+ "openai",
56
+ "openai-agents",
57
+ ]
58
+
59
+ versions = []
60
+ for package_name in package_names:
61
+ try:
62
+ ver = metadata.version(package_name)
63
+ versions.append(f"{package_name}={ver}")
64
+ except Exception: # noqa: BLE001 - swallow and continue
65
+ versions.append(f"{package_name}=(not installed)")
66
+
67
+ return ", ".join(versions) if versions else "(unavailable)"
68
+ except Exception: # noqa: BLE001 - never let version gathering break user code
69
+ return "(unavailable)"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: azure-functions-durable
3
- Version: 1.3.2
3
+ Version: 1.4.0
4
4
  Summary: Durable Functions For Python
5
5
  Home-page: https://github.com/Azure/azure-functions-durable-python
6
6
  Author: Azure Functions team at Microsoft Corp.
@@ -20,7 +20,7 @@ Requires-Python: >=3.9,<4
20
20
  Description-Content-Type: text/markdown
21
21
  License-File: LICENSE
22
22
  Requires-Dist: azure-functions>=1.12.0
23
- Requires-Dist: aiohttp>=3.12.9
23
+ Requires-Dist: aiohttp>=3.12.14
24
24
  Requires-Dist: requests==2.*
25
25
  Requires-Dist: python-dateutil>=2.8.0
26
26
  Requires-Dist: furl>=2.1.0
@@ -58,4 +58,9 @@ Follow these instructions to get started with Durable Functions in Python:
58
58
 
59
59
  * Python Durable Functions requires [Azure Functions Core Tools](https://docs.microsoft.com/en-us/azure/azure-functions/functions-run-local) version 3.0.2630 or higher.
60
60
 
61
+ ## OpenAI Agents Integration for Reliability on Azure Functions (Preview)
62
+
63
+ Build resilient, stateful AI agents backed by Durable Functions orchestration—see the full documentation at [docs/openai_agents/README.md](docs/openai_agents/README.md).
64
+
65
+
61
66
 
@@ -1,15 +1,15 @@
1
- azure/durable_functions/__init__.py,sha256=Syz9yrT8sHREVyxqvwjg8_c_h8yMTyuBHcDMsuQs1YM,2910
1
+ azure/durable_functions/__init__.py,sha256=aTQRMnMb3zT3w28yEbYsEl-_f3x2Rf-kKp91E9nE8nk,3150
2
2
  azure/durable_functions/constants.py,sha256=JtknDhaVihMeo-ygY9QNofiO2KEqnQvopdfZ6Qatnik,414
3
3
  azure/durable_functions/entity.py,sha256=mUUzb1BZiDrUJjvxOTlnVURnKPyDGPJ3mXXMN0DKT7M,4649
4
4
  azure/durable_functions/orchestrator.py,sha256=SZni90Aweq0OZykHyMblfJpUndJ2woJmySarcsDiIK4,2554
5
5
  azure/durable_functions/decorators/__init__.py,sha256=wEubgP2rUUISwidZWgKx6mmzEeGKsSnpGmetjIUi1nw,150
6
- azure/durable_functions/decorators/durable_app.py,sha256=8K4gevZVYcDvifxXVuvTt8YzF8jx63c1PwdBBk1Vt0g,10114
6
+ azure/durable_functions/decorators/durable_app.py,sha256=5ajbhMPKvZKZhYLCxsEn8J4sZO6Pql9j0nOTCxDaMuY,12599
7
7
  azure/durable_functions/decorators/metadata.py,sha256=p91rdCe6OSRYJaKAXnrfR0QCV3PoHK7aGy1m6WAnPIE,2828
8
8
  azure/durable_functions/models/DurableEntityContext.py,sha256=cyZmjjZu18oV9S4A2NpnXfjd1JQxPxp9EMmAR424UK0,5830
9
9
  azure/durable_functions/models/DurableHttpRequest.py,sha256=a5kgRdg4eA0sgyDcpmQWc0dbwP-o3BwWW2Ive0BYO_Q,2021
10
10
  azure/durable_functions/models/DurableOrchestrationBindings.py,sha256=_hp61WjN3bQYCqYFQuvUaDdRu7C14fPg7lFbaA9TRe4,2408
11
11
  azure/durable_functions/models/DurableOrchestrationClient.py,sha256=kQBqeKugvi2mi-7dDbCxlu67r20doEhDknlchYxcLBE,33018
12
- azure/durable_functions/models/DurableOrchestrationContext.py,sha256=Vrox-oX8QfSFmcPampUOTgMx85DuZs_HMQyzavqozEc,31256
12
+ azure/durable_functions/models/DurableOrchestrationContext.py,sha256=fZNbUisN9vkublT2L7wYbj0CNfQNOyYcqRwZ9T-SgN8,32090
13
13
  azure/durable_functions/models/DurableOrchestrationStatus.py,sha256=BXWz9L7np4Q9k6z4NsfLX97i2U2IFh94TVeRSV2BjM4,6049
14
14
  azure/durable_functions/models/EntityStateResponse.py,sha256=f48W8gmlb-D5iJw3eDyUMYVwHpmIxP6k6a7o2TRHwII,674
15
15
  azure/durable_functions/models/FunctionContext.py,sha256=4gHTmIo8DZN-bZLM-hyjoQFlv-AbsfLMT1_X4WxWxqY,274
@@ -53,6 +53,17 @@ azure/durable_functions/models/utils/__init__.py,sha256=dQ6-HRUPsCtDIqGjRJ3TA6NX
53
53
  azure/durable_functions/models/utils/entity_utils.py,sha256=TqNTtRC8VuKFtqWLq9oEAloioV-FyinjgRYVKkCldHo,2881
54
54
  azure/durable_functions/models/utils/http_utils.py,sha256=AoCWjCapd_984J_4296iJ8cNJWEG8GIdhRttBPt0HnA,2551
55
55
  azure/durable_functions/models/utils/json_utils.py,sha256=zUn62pm3dQw054ZlK7F4uRP-UELjQC8EmZBU1WncHMg,3811
56
+ azure/durable_functions/openai_agents/__init__.py,sha256=pAUkXR5ctS0leHiR0IwBC1aHurzOn70wasL-LDRcRnQ,374
57
+ azure/durable_functions/openai_agents/context.py,sha256=tShhQmlMxvOGHvYu55e10xPp2mVHmeIUf37yUzzjE50,7551
58
+ azure/durable_functions/openai_agents/event_loop.py,sha256=JxezIdw1TL-R77ITlarZZvk3F1IMXHqGUAuCgxKX5Wk,571
59
+ azure/durable_functions/openai_agents/exceptions.py,sha256=AmbFAxpkrQ-LiU_LaU7-aWpb6dR-ETMs_XWkoCfZIoQ,394
60
+ azure/durable_functions/openai_agents/handoffs.py,sha256=R8fuQ-FlZ3DQw1jI0WwU8gWwTlWdRLWW2EVrwsfDEuU,2195
61
+ azure/durable_functions/openai_agents/model_invocation_activity.py,sha256=P94iMKVq9qfZyC_fUQWXb-tuOhvANaGhGvqVwUGfFVk,9783
62
+ azure/durable_functions/openai_agents/orchestrator_generator.py,sha256=dvm5e2pk-wtpTog0XZ4iMy1eskLOgwHcMwswiZ3zCA8,2898
63
+ azure/durable_functions/openai_agents/runner.py,sha256=qfsX52zaTDJpuU3_hxgkrEUtoHQ3GTMm5VYSgUXXsjA,3726
64
+ azure/durable_functions/openai_agents/task_tracker.py,sha256=dBGIGlkIdbwxH2OJ3XJZBFazzC32JZ9hWpN4isxvYLQ,7749
65
+ azure/durable_functions/openai_agents/tools.py,sha256=YahQOV1Duv0217tEwG6SX8gLLTvkQNLFi9E_6KUOjvI,4229
66
+ azure/durable_functions/openai_agents/usage_telemetry.py,sha256=U4nqLJIv_vzxT2Y5FIUi9NkvCyHex1OY4eWY8flydNs,2646
56
67
  azure/durable_functions/testing/OrchestratorGeneratorWrapper.py,sha256=cjh-HAq5rVNCoR0pIbfGrqy6cKSf4S1KMQxrBMWU1-s,1728
57
68
  azure/durable_functions/testing/__init__.py,sha256=NLbltPtoPXK-0iMTwcKTKPjQlAWrEq55oDYmrhYz6vg,189
58
69
  tests/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -60,11 +71,15 @@ tests/models/test_DecoratorMetadata.py,sha256=0PeUDszF_gAJZMZR-K-Ro7c3I1D960amOL
60
71
  tests/models/test_Decorators.py,sha256=y2dhoSlP74J5uAVBDY2JfFkSA-AhyagVBZO5tGi6KaQ,2925
61
72
  tests/models/test_DurableOrchestrationBindings.py,sha256=pjuoKlpEc6KAIL-Nq2taoqW0HYWXoupgUxcsPwc1Psg,2961
62
73
  tests/models/test_DurableOrchestrationClient.py,sha256=7htzuMMfkRU9Hf-9Gr-rYHpJXJdpnAp0WheAFpMKHNo,31791
63
- tests/models/test_DurableOrchestrationContext.py,sha256=7fWdnvpSEces0VM4Xm11uLZmshXqGl7wtYo8ELixypc,3930
74
+ tests/models/test_DurableOrchestrationContext.py,sha256=ewNEH2g8gn60bVftXT6zmI6nkANXB1u7XsC1l9vXFxg,4328
64
75
  tests/models/test_DurableOrchestrationStatus.py,sha256=fnUZxrHGy771OoaD5TInELhaG836aB8XqtMdNjnEFp8,2485
65
76
  tests/models/test_OrchestrationState.py,sha256=L-k8ScrqoDIZEqIUORbxXA7yCuMbVAUPr-7VmyuQkUc,1272
66
77
  tests/models/test_RpcManagementOptions.py,sha256=hvDzlJED8egJloju5nFvKYusgwLgy-o_avJAY6uzfdg,3190
67
78
  tests/models/test_TokenSource.py,sha256=wlRn-RPM72U6Ose4sa3Yvu2ng1VbAopDIbea90CYDjk,589
79
+ tests/openai_agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
80
+ tests/openai_agents/test_context.py,sha256=r5nGikUU2j23TmyknruR1ntP4UvxyvYrWil9Ap11qs4,21861
81
+ tests/openai_agents/test_task_tracker.py,sha256=6vjalKmCb-CjpJysx7D0s_3CZaOPycE76TQpcX0ludU,13263
82
+ tests/openai_agents/test_usage_telemetry.py,sha256=gB8efDTZhO9UvCwRTqmCELcgmtwbhSoA6_1Hy7kPCDQ,4825
68
83
  tests/orchestrator/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
69
84
  tests/orchestrator/orchestrator_test_utils.py,sha256=ldgQGGuOVALcI98enRU08nF_VJd5ypJl-hVG-q0kH1o,5359
70
85
  tests/orchestrator/test_call_http.py,sha256=CvemeCayrQLjmjl3lpB1fk_CpV-DRPgfxLgD4iNgStQ,9103
@@ -83,6 +98,8 @@ tests/orchestrator/test_sub_orchestrator.py,sha256=QUb5Q3nLcCdhFwGaEQlYdoNQLUvI8
83
98
  tests/orchestrator/test_sub_orchestrator_with_retry.py,sha256=bfufQnteEZ9i3q7wzCvd8EwFmaOh89KPOpTPSJvlP1I,6040
84
99
  tests/orchestrator/test_task_any.py,sha256=9PQalbQW-Qx7_iO4Yjl1MR2hhsBjst6k00_4veIt97g,2695
85
100
  tests/orchestrator/models/OrchestrationInstance.py,sha256=CQ3qyNumjksuFNMujbESsvjadntP3b9VtTpEuI4hzaE,491
101
+ tests/orchestrator/openai_agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
102
+ tests/orchestrator/openai_agents/test_openai_agents.py,sha256=qa8DLkJ1IZV9C5kP2mnFfchriv4ppl1nIu9J_3rNlhA,24221
86
103
  tests/orchestrator/schemas/OrchetrationStateSchema.py,sha256=EyTsDUZ3K-9mVljLIlg8f_h2zsK228E0PMvvtyEWw24,2718
87
104
  tests/tasks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
88
105
  tests/tasks/tasks_test_utils.py,sha256=Ymc5GESJpzybBq3n2mT4IABDRNTVCerAZrlMilv0Pdk,737
@@ -96,8 +113,8 @@ tests/test_utils/json_utils.py,sha256=B0q3COMya7TGxbH-7sD_0ypWDSuaF4fpD4QV_oJPgG
96
113
  tests/test_utils/testClasses.py,sha256=U_u5qKxC9U81SzjLo7ejjPjEn_cE5qjaqoq8edGD6l8,1521
97
114
  tests/utils/__init__.py,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
98
115
  tests/utils/test_entity_utils.py,sha256=kdk5_DV_-bFu_5q2mw9o1yjyzh8Lcxv1jo1Q7is_ukA,748
99
- azure_functions_durable-1.3.2.dist-info/LICENSE,sha256=-VS-Izmxdykuae1Xc4vHtVUx02rNQi6SSQlONvvuYeQ,1090
100
- azure_functions_durable-1.3.2.dist-info/METADATA,sha256=3zhhixYOOBegIn-AnvaaAfMzQtFs7s7X6ggHofdvrDQ,3523
101
- azure_functions_durable-1.3.2.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
102
- azure_functions_durable-1.3.2.dist-info/top_level.txt,sha256=h-L8XDVPJ9YzBbHlPvM7FVo1cqNGToNK9ix99ySGOUY,12
103
- azure_functions_durable-1.3.2.dist-info/RECORD,,
116
+ azure_functions_durable-1.4.0.dist-info/LICENSE,sha256=-VS-Izmxdykuae1Xc4vHtVUx02rNQi6SSQlONvvuYeQ,1090
117
+ azure_functions_durable-1.4.0.dist-info/METADATA,sha256=UvSARgbXXpFbz_zAnWhFr10Zjm85VPBTkTgZTG7g2jw,3778
118
+ azure_functions_durable-1.4.0.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
119
+ azure_functions_durable-1.4.0.dist-info/top_level.txt,sha256=h-L8XDVPJ9YzBbHlPvM7FVo1cqNGToNK9ix99ySGOUY,12
120
+ azure_functions_durable-1.4.0.dist-info/RECORD,,
@@ -100,3 +100,11 @@ def test_get_input_json_str():
100
100
  result = context.get_input()
101
101
 
102
102
  assert 'Seattle' == result['city']
103
+
104
+ def test_version_equals_version_from_execution_started_event():
105
+ builder = ContextBuilder('test_function_context')
106
+ builder.history_events = []
107
+ builder.add_orchestrator_started_event()
108
+ builder.add_execution_started_event(name="TestOrchestrator", version="1.0")
109
+ context = DurableOrchestrationContext.from_json(builder.to_json_string())
110
+ assert context.version == "1.0"
File without changes